aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEd Maste <emaste@FreeBSD.org>2021-09-08 01:05:51 +0000
committerEd Maste <emaste@FreeBSD.org>2021-09-08 01:05:51 +0000
commit19261079b74319502c6ffa1249920079f0f69a72 (patch)
treea07fb2205e0cea7dee1ffbcc945d9d5b97124714
parentc5128c48df3c2f3828432aff2ea536bb9c887e14 (diff)
parent66719ee573ac2290622db642f6e89ab35b179f3d (diff)
downloadsrc-19261079b74319502c6ffa1249920079f0f69a72.tar.gz
src-19261079b74319502c6ffa1249920079f0f69a72.zip
openssh: update to OpenSSH v8.7p1
Some notable changes, from upstream's release notes: - sshd(8): Remove support for obsolete "host/port" syntax. - ssh(1): When prompting whether to record a new host key, accept the key fingerprint as a synonym for "yes". - ssh-keygen(1): when acting as a CA and signing certificates with an RSA key, default to using the rsa-sha2-512 signature algorithm. - ssh(1), sshd(8), ssh-keygen(1): this release removes the "ssh-rsa" (RSA/SHA1) algorithm from those accepted for certificate signatures. - ssh-sk-helper(8): this is a new binary. It is used by the FIDO/U2F support to provide address-space isolation for token middleware libraries (including the internal one). - ssh(1): this release enables UpdateHostkeys by default subject to some conservative preconditions. - scp(1): this release changes the behaviour of remote to remote copies (e.g. "scp host-a:/path host-b:") to transfer through the local host by default. - scp(1): experimental support for transfers using the SFTP protocol as a replacement for the venerable SCP/RCP protocol that it has traditionally used. Additional integration work is needed to support FIDO/U2F in the base system. Deprecation Notice ------------------ OpenSSH will disable the ssh-rsa signature scheme by default in the next release. Reviewed by: imp MFC after: 1 month Relnotes: Yes Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D29985
-rw-r--r--crypto/openssh/.depend354
-rw-r--r--crypto/openssh/.github/ci-status.md4
-rwxr-xr-xcrypto/openssh/.github/configs170
-rwxr-xr-xcrypto/openssh/.github/configure.sh6
-rwxr-xr-xcrypto/openssh/.github/run_test.sh34
-rwxr-xr-xcrypto/openssh/.github/setup_ci.sh115
-rw-r--r--crypto/openssh/.github/workflows/c-cpp.yml76
-rw-r--r--crypto/openssh/.github/workflows/selfhosted.yml93
-rw-r--r--crypto/openssh/.github/workflows/upstream.yml43
-rw-r--r--crypto/openssh/.gitignore8
-rw-r--r--crypto/openssh/.skipped-commit-ids18
-rw-r--r--crypto/openssh/CREDITS2
-rw-r--r--crypto/openssh/ChangeLog15891
-rw-r--r--crypto/openssh/FREEBSD-vendor4
-rw-r--r--crypto/openssh/INSTALL79
-rw-r--r--crypto/openssh/LICENCE64
-rw-r--r--crypto/openssh/Makefile.in328
-rw-r--r--crypto/openssh/OVERVIEW7
-rw-r--r--crypto/openssh/PROTOCOL89
-rw-r--r--crypto/openssh/PROTOCOL.agent6
-rw-r--r--crypto/openssh/PROTOCOL.certkeys35
-rw-r--r--crypto/openssh/PROTOCOL.chacha20poly13054
-rw-r--r--crypto/openssh/PROTOCOL.key9
-rw-r--r--crypto/openssh/PROTOCOL.mux4
-rw-r--r--crypto/openssh/PROTOCOL.sshsig100
-rw-r--r--crypto/openssh/PROTOCOL.u2f309
-rw-r--r--crypto/openssh/README36
-rw-r--r--crypto/openssh/README.dns8
-rw-r--r--crypto/openssh/README.md84
-rw-r--r--crypto/openssh/README.platform16
-rw-r--r--crypto/openssh/README.privsep11
-rw-r--r--crypto/openssh/aclocal.m4193
-rw-r--r--crypto/openssh/addr.c423
-rw-r--r--crypto/openssh/addr.h60
-rw-r--r--crypto/openssh/addrmatch.c351
-rw-r--r--crypto/openssh/atomicio.c32
-rw-r--r--crypto/openssh/atomicio.h4
-rw-r--r--crypto/openssh/audit-bsm.c41
-rw-r--r--crypto/openssh/audit-linux.c4
-rw-r--r--crypto/openssh/audit.c2
-rw-r--r--crypto/openssh/audit.h4
-rw-r--r--crypto/openssh/auth-bsdauth.c2
-rw-r--r--crypto/openssh/auth-krb5.c19
-rw-r--r--crypto/openssh/auth-options.c194
-rw-r--r--crypto/openssh/auth-options.h13
-rw-r--r--crypto/openssh/auth-pam.c119
-rw-r--r--crypto/openssh/auth-pam.h2
-rw-r--r--crypto/openssh/auth-passwd.c6
-rw-r--r--crypto/openssh/auth-rhosts.c19
-rw-r--r--crypto/openssh/auth-skey.c107
-rw-r--r--crypto/openssh/auth.c303
-rw-r--r--crypto/openssh/auth.h36
-rw-r--r--crypto/openssh/auth2-chall.c43
-rw-r--r--crypto/openssh/auth2-gss.c29
-rw-r--r--crypto/openssh/auth2-hostbased.c71
-rw-r--r--crypto/openssh/auth2-kbdint.c8
-rw-r--r--crypto/openssh/auth2-none.c4
-rw-r--r--crypto/openssh/auth2-passwd.c9
-rw-r--r--crypto/openssh/auth2-pubkey.c264
-rw-r--r--crypto/openssh/auth2.c209
-rw-r--r--crypto/openssh/authfd.c178
-rw-r--r--crypto/openssh/authfd.h12
-rw-r--r--crypto/openssh/authfile.c265
-rw-r--r--crypto/openssh/authfile.h10
-rw-r--r--crypto/openssh/blacklist.c6
-rw-r--r--crypto/openssh/buildpkg.sh.in8
-rw-r--r--crypto/openssh/canohost.c12
-rw-r--r--crypto/openssh/chacha.h4
-rw-r--r--crypto/openssh/channels.c761
-rw-r--r--crypto/openssh/channels.h38
-rw-r--r--crypto/openssh/cipher-chachapoly-libcrypto.c166
-rw-r--r--crypto/openssh/cipher-chachapoly.c32
-rw-r--r--crypto/openssh/cipher-chachapoly.h13
-rw-r--r--crypto/openssh/cipher.c48
-rw-r--r--crypto/openssh/cipher.h5
-rw-r--r--crypto/openssh/clientloop.c1074
-rw-r--r--crypto/openssh/clientloop.h5
-rw-r--r--crypto/openssh/compat.c92
-rw-r--r--crypto/openssh/compat.h20
-rwxr-xr-xcrypto/openssh/config.guess882
-rw-r--r--crypto/openssh/config.h241
-rwxr-xr-xcrypto/openssh/config.sub2528
-rw-r--r--crypto/openssh/configure.ac970
-rw-r--r--crypto/openssh/contrib/Makefile6
-rw-r--r--crypto/openssh/contrib/cygwin/README4
-rw-r--r--crypto/openssh/contrib/cygwin/ssh-host-config59
-rw-r--r--[-rwxr-xr-x]crypto/openssh/contrib/findssl.sh0
-rw-r--r--crypto/openssh/contrib/gnome-ssh-askpass1.c7
-rw-r--r--crypto/openssh/contrib/gnome-ssh-askpass2.c210
-rw-r--r--crypto/openssh/contrib/gnome-ssh-askpass3.c305
-rw-r--r--[-rwxr-xr-x]crypto/openssh/contrib/redhat/gnome-ssh-askpass.sh0
-rw-r--r--crypto/openssh/contrib/redhat/openssh.spec55
-rw-r--r--[-rwxr-xr-x]crypto/openssh/contrib/solaris/README0
-rw-r--r--crypto/openssh/contrib/ssh-copy-id303
-rw-r--r--crypto/openssh/contrib/ssh-copy-id.111
-rw-r--r--crypto/openssh/contrib/suse/openssh.spec6
-rw-r--r--crypto/openssh/crc32.c105
-rw-r--r--crypto/openssh/crc32.h30
-rw-r--r--crypto/openssh/crypto_api.h20
-rw-r--r--crypto/openssh/defines.h54
-rw-r--r--crypto/openssh/dh.c39
-rw-r--r--crypto/openssh/dh.h10
-rw-r--r--crypto/openssh/digest-libc.c33
-rw-r--r--crypto/openssh/digest-openssl.c19
-rw-r--r--crypto/openssh/dispatch.c6
-rw-r--r--crypto/openssh/dispatch.h9
-rw-r--r--crypto/openssh/dns.c72
-rw-r--r--crypto/openssh/dns.h3
-rw-r--r--crypto/openssh/entropy.c175
-rw-r--r--crypto/openssh/fatal.c7
-rw-r--r--crypto/openssh/groupaccess.c5
-rw-r--r--crypto/openssh/gss-genr.c19
-rw-r--r--crypto/openssh/gss-serv.c4
-rw-r--r--crypto/openssh/hash.c36
-rw-r--r--crypto/openssh/hmac.c7
-rw-r--r--crypto/openssh/hostfile.c269
-rw-r--r--crypto/openssh/hostfile.h27
-rw-r--r--crypto/openssh/int32_minmax.inc0
-rw-r--r--crypto/openssh/kex.c490
-rw-r--r--crypto/openssh/kex.h92
-rw-r--r--crypto/openssh/kexc25519.c182
-rw-r--r--crypto/openssh/kexc25519c.c169
-rw-r--r--crypto/openssh/kexc25519s.c158
-rw-r--r--crypto/openssh/kexdh.c205
-rw-r--r--crypto/openssh/kexdhc.c224
-rw-r--r--crypto/openssh/kexdhs.c222
-rw-r--r--crypto/openssh/kexecdh.c239
-rw-r--r--crypto/openssh/kexecdhc.c222
-rw-r--r--crypto/openssh/kexecdhs.c203
-rw-r--r--crypto/openssh/kexgen.c346
-rw-r--r--crypto/openssh/kexgex.c30
-rw-r--r--crypto/openssh/kexgexc.c123
-rw-r--r--crypto/openssh/kexgexs.c119
-rw-r--r--crypto/openssh/kexsntrup761x25519.c251
-rw-r--r--crypto/openssh/krl.c223
-rw-r--r--crypto/openssh/krl.h5
-rw-r--r--crypto/openssh/log.c219
-rw-r--r--crypto/openssh/log.h93
-rw-r--r--crypto/openssh/loginrec.c13
-rw-r--r--crypto/openssh/loginrec.h7
-rw-r--r--crypto/openssh/logintest.c60
-rw-r--r--crypto/openssh/m4/openssh.m4200
-rw-r--r--crypto/openssh/mac.c7
-rw-r--r--crypto/openssh/match.c34
-rw-r--r--crypto/openssh/match.h7
-rw-r--r--crypto/openssh/misc.c962
-rw-r--r--crypto/openssh/misc.h75
-rw-r--r--crypto/openssh/moduli876
-rw-r--r--crypto/openssh/moduli.c29
-rw-r--r--crypto/openssh/monitor.c708
-rw-r--r--crypto/openssh/monitor.h13
-rw-r--r--crypto/openssh/monitor_fdpass.c24
-rw-r--r--crypto/openssh/monitor_wrap.c305
-rw-r--r--crypto/openssh/monitor_wrap.h26
-rw-r--r--crypto/openssh/msg.c18
-rw-r--r--crypto/openssh/mux.c640
-rw-r--r--crypto/openssh/myproposal.h144
-rw-r--r--crypto/openssh/nchan.c77
-rw-r--r--crypto/openssh/opacket.c320
-rw-r--r--crypto/openssh/opacket.h154
-rw-r--r--crypto/openssh/openbsd-compat/Makefile.in11
-rw-r--r--crypto/openssh/openbsd-compat/arc4random.c12
-rw-r--r--crypto/openssh/openbsd-compat/base64.c2
-rw-r--r--crypto/openssh/openbsd-compat/bcrypt_pbkdf.c4
-rw-r--r--crypto/openssh/openbsd-compat/bsd-closefrom.c88
-rw-r--r--crypto/openssh/openbsd-compat/bsd-cygwin_util.c149
-rw-r--r--crypto/openssh/openbsd-compat/bsd-cygwin_util.h1
-rw-r--r--crypto/openssh/openbsd-compat/bsd-misc.c113
-rw-r--r--crypto/openssh/openbsd-compat/bsd-misc.h41
-rw-r--r--crypto/openssh/openbsd-compat/bsd-openpty.c17
-rw-r--r--crypto/openssh/openbsd-compat/bsd-poll.h2
-rw-r--r--crypto/openssh/openbsd-compat/bsd-pselect.c205
-rw-r--r--crypto/openssh/openbsd-compat/bsd-setres_id.c12
-rw-r--r--crypto/openssh/openbsd-compat/bsd-signal.c29
-rw-r--r--crypto/openssh/openbsd-compat/bsd-signal.h7
-rw-r--r--crypto/openssh/openbsd-compat/bsd-snprintf.c18
-rw-r--r--crypto/openssh/openbsd-compat/bsd-statvfs.c10
-rw-r--r--crypto/openssh/openbsd-compat/bsd-waitpid.h2
-rw-r--r--crypto/openssh/openbsd-compat/explicit_bzero.c10
-rw-r--r--crypto/openssh/openbsd-compat/fnmatch.c495
-rw-r--r--crypto/openssh/openbsd-compat/fnmatch.h66
-rw-r--r--crypto/openssh/openbsd-compat/getopt_long.c2
-rw-r--r--crypto/openssh/openbsd-compat/glob.c157
-rw-r--r--crypto/openssh/openbsd-compat/glob.h9
-rw-r--r--crypto/openssh/openbsd-compat/libressl-api-compat.c6
-rw-r--r--crypto/openssh/openbsd-compat/memmem.c196
-rw-r--r--crypto/openssh/openbsd-compat/mktemp.c4
-rw-r--r--crypto/openssh/openbsd-compat/openbsd-compat.h42
-rw-r--r--crypto/openssh/openbsd-compat/openssl-compat.c22
-rw-r--r--crypto/openssh/openbsd-compat/openssl-compat.h59
-rw-r--r--crypto/openssh/openbsd-compat/port-aix.c25
-rw-r--r--crypto/openssh/openbsd-compat/port-aix.h7
-rw-r--r--crypto/openssh/openbsd-compat/port-irix.c2
-rw-r--r--crypto/openssh/openbsd-compat/port-linux.c25
-rw-r--r--crypto/openssh/openbsd-compat/port-net.c18
-rw-r--r--crypto/openssh/openbsd-compat/port-prngd.c164
-rw-r--r--crypto/openssh/openbsd-compat/port-solaris.c14
-rw-r--r--crypto/openssh/openbsd-compat/port-uw.c2
-rw-r--r--crypto/openssh/openbsd-compat/pwcache.c4
-rw-r--r--crypto/openssh/openbsd-compat/regress/Makefile.in4
-rw-r--r--crypto/openssh/openbsd-compat/regress/closefromtest.c4
-rw-r--r--crypto/openssh/openbsd-compat/regress/opensslvertest.c2
-rw-r--r--crypto/openssh/openbsd-compat/regress/snprintftest.c5
-rw-r--r--crypto/openssh/openbsd-compat/regress/strduptest.c2
-rw-r--r--crypto/openssh/openbsd-compat/regress/strtonumtest.c2
-rw-r--r--crypto/openssh/openbsd-compat/regress/utimensattest.c120
-rw-r--r--crypto/openssh/openbsd-compat/rmd160.c378
-rw-r--r--crypto/openssh/openbsd-compat/rmd160.h61
-rw-r--r--crypto/openssh/openbsd-compat/setenv.c2
-rw-r--r--crypto/openssh/openbsd-compat/setproctitle.c1
-rw-r--r--crypto/openssh/openbsd-compat/sha1.c13
-rw-r--r--crypto/openssh/openbsd-compat/sha2.c336
-rw-r--r--crypto/openssh/openbsd-compat/sha2.h138
-rw-r--r--crypto/openssh/openbsd-compat/strtonum.c6
-rw-r--r--crypto/openssh/openbsd-compat/sys-queue.h376
-rw-r--r--crypto/openssh/packet.c264
-rw-r--r--crypto/openssh/packet.h14
-rw-r--r--crypto/openssh/pathnames.h9
-rw-r--r--crypto/openssh/platform.c1
-rw-r--r--crypto/openssh/progressmeter.c60
-rw-r--r--crypto/openssh/progressmeter.h3
-rw-r--r--crypto/openssh/readconf.c1338
-rw-r--r--crypto/openssh/readconf.h37
-rw-r--r--crypto/openssh/readpass.c191
-rw-r--r--crypto/openssh/regress/Makefile75
-rw-r--r--crypto/openssh/regress/README.regress80
-rw-r--r--[-rwxr-xr-x]crypto/openssh/regress/addrmatch.sh16
-rw-r--r--crypto/openssh/regress/agent-getpeereid.sh6
-rw-r--r--[-rwxr-xr-x]crypto/openssh/regress/agent-pkcs11.sh99
-rw-r--r--crypto/openssh/regress/agent-ptrace.sh2
-rw-r--r--crypto/openssh/regress/agent-subprocess.sh22
-rw-r--r--crypto/openssh/regress/agent-timeout.sh12
-rw-r--r--crypto/openssh/regress/agent.sh124
-rw-r--r--crypto/openssh/regress/allow-deny-users.sh8
-rw-r--r--crypto/openssh/regress/banner.sh6
-rw-r--r--[-rwxr-xr-x]crypto/openssh/regress/cert-file.sh4
-rw-r--r--[-rwxr-xr-x]crypto/openssh/regress/cert-hostkey.sh36
-rw-r--r--[-rwxr-xr-x]crypto/openssh/regress/cert-userkey.sh53
-rw-r--r--crypto/openssh/regress/cfginclude.sh24
-rw-r--r--crypto/openssh/regress/cfgmatch.sh55
-rw-r--r--[-rwxr-xr-x]crypto/openssh/regress/cfgparse.sh0
-rw-r--r--[-rwxr-xr-x]crypto/openssh/regress/conch-ciphers.sh4
-rw-r--r--crypto/openssh/regress/connect-privsep.sh5
-rw-r--r--crypto/openssh/regress/connect.sh11
-rw-r--r--[-rwxr-xr-x]crypto/openssh/regress/dhgex.sh14
-rw-r--r--crypto/openssh/regress/ed25519_openssh.prv7
-rw-r--r--crypto/openssh/regress/ed25519_openssh.pub1
-rw-r--r--[-rwxr-xr-x]crypto/openssh/regress/forward-control.sh6
-rw-r--r--crypto/openssh/regress/forwarding.sh44
-rw-r--r--[-rwxr-xr-x]crypto/openssh/regress/host-expand.sh0
-rw-r--r--[-rwxr-xr-x]crypto/openssh/regress/hostkey-agent.sh10
-rw-r--r--[-rwxr-xr-x]crypto/openssh/regress/hostkey-rotate.sh80
-rw-r--r--[-rwxr-xr-x]crypto/openssh/regress/integrity.sh8
-rw-r--r--[-rwxr-xr-x]crypto/openssh/regress/kextype.sh0
-rw-r--r--[-rwxr-xr-x]crypto/openssh/regress/key-options.sh10
-rw-r--r--crypto/openssh/regress/keygen-change.sh7
-rw-r--r--crypto/openssh/regress/keygen-comment.sh52
-rw-r--r--[-rwxr-xr-x]crypto/openssh/regress/keygen-convert.sh54
-rw-r--r--[-rwxr-xr-x]crypto/openssh/regress/keygen-knownhosts.sh0
-rw-r--r--crypto/openssh/regress/keygen-moduli.sh17
-rw-r--r--crypto/openssh/regress/keygen-sshfp.sh29
-rw-r--r--[-rwxr-xr-x]crypto/openssh/regress/keys-command.sh11
-rw-r--r--crypto/openssh/regress/keyscan.sh17
-rw-r--r--[-rwxr-xr-x]crypto/openssh/regress/keytype.sh57
-rw-r--r--crypto/openssh/regress/knownhosts-command.sh53
-rw-r--r--[-rwxr-xr-x]crypto/openssh/regress/krl.sh41
-rw-r--r--[-rwxr-xr-x]crypto/openssh/regress/limit-keytype.sh69
-rw-r--r--[-rwxr-xr-x]crypto/openssh/regress/localcommand.sh0
-rw-r--r--crypto/openssh/regress/misc/Makefile2
-rw-r--r--crypto/openssh/regress/misc/fuzz-harness/Makefile51
-rw-r--r--crypto/openssh/regress/misc/fuzz-harness/agent_fuzz.cc15
-rw-r--r--crypto/openssh/regress/misc/fuzz-harness/agent_fuzz_helper.c177
-rw-r--r--crypto/openssh/regress/misc/fuzz-harness/fixed-keys.h119
-rw-r--r--crypto/openssh/regress/misc/fuzz-harness/kex_fuzz.cc461
-rw-r--r--crypto/openssh/regress/misc/fuzz-harness/privkey_fuzz.cc21
-rw-r--r--crypto/openssh/regress/misc/fuzz-harness/sig_fuzz.cc24
-rw-r--r--crypto/openssh/regress/misc/fuzz-harness/ssh-sk-null.cc51
-rw-r--r--crypto/openssh/regress/misc/fuzz-harness/sshsig_fuzz.cc37
-rw-r--r--crypto/openssh/regress/misc/fuzz-harness/sshsigopt_fuzz.cc29
-rw-r--r--crypto/openssh/regress/misc/fuzz-harness/testdata/README4
-rwxr-xr-xcrypto/openssh/regress/misc/fuzz-harness/testdata/create-agent-corpus.sh44
-rw-r--r--crypto/openssh/regress/misc/fuzz-harness/testdata/id_dsa21
-rw-r--r--crypto/openssh/regress/misc/fuzz-harness/testdata/id_dsa-cert.pub1
-rw-r--r--crypto/openssh/regress/misc/fuzz-harness/testdata/id_dsa.pub1
-rw-r--r--crypto/openssh/regress/misc/fuzz-harness/testdata/id_ecdsa8
-rw-r--r--crypto/openssh/regress/misc/fuzz-harness/testdata/id_ecdsa-cert.pub1
-rw-r--r--crypto/openssh/regress/misc/fuzz-harness/testdata/id_ecdsa.pub1
-rw-r--r--crypto/openssh/regress/misc/fuzz-harness/testdata/id_ecdsa_sk14
-rw-r--r--crypto/openssh/regress/misc/fuzz-harness/testdata/id_ecdsa_sk-cert.pub1
-rw-r--r--crypto/openssh/regress/misc/fuzz-harness/testdata/id_ecdsa_sk.pub1
-rw-r--r--crypto/openssh/regress/misc/fuzz-harness/testdata/id_ed255197
-rw-r--r--crypto/openssh/regress/misc/fuzz-harness/testdata/id_ed25519-cert.pub1
-rw-r--r--crypto/openssh/regress/misc/fuzz-harness/testdata/id_ed25519.pub2
-rw-r--r--crypto/openssh/regress/misc/fuzz-harness/testdata/id_ed25519_sk8
-rw-r--r--crypto/openssh/regress/misc/fuzz-harness/testdata/id_ed25519_sk-cert.pub1
-rw-r--r--crypto/openssh/regress/misc/fuzz-harness/testdata/id_ed25519_sk.pub1
-rw-r--r--crypto/openssh/regress/misc/fuzz-harness/testdata/id_rsa27
-rw-r--r--crypto/openssh/regress/misc/fuzz-harness/testdata/id_rsa-cert.pub1
-rw-r--r--crypto/openssh/regress/misc/fuzz-harness/testdata/id_rsa.pub1
-rw-r--r--crypto/openssh/regress/misc/kexfuzz/Makefile88
-rw-r--r--crypto/openssh/regress/misc/kexfuzz/README34
-rw-r--r--crypto/openssh/regress/misc/kexfuzz/kexfuzz.c459
-rw-r--r--crypto/openssh/regress/misc/sk-dummy/fatal.c27
-rw-r--r--crypto/openssh/regress/misc/sk-dummy/sk-dummy.c539
-rw-r--r--[-rwxr-xr-x]crypto/openssh/regress/modpipe.c0
-rw-r--r--crypto/openssh/regress/multiplex.sh32
-rw-r--r--[-rwxr-xr-x]crypto/openssh/regress/multipubkey.sh19
-rw-r--r--crypto/openssh/regress/netcat.c46
-rw-r--r--crypto/openssh/regress/percent.sh119
-rw-r--r--[-rwxr-xr-x]crypto/openssh/regress/portnum.sh0
-rw-r--r--[-rwxr-xr-x]crypto/openssh/regress/principals-command.sh16
-rw-r--r--crypto/openssh/regress/proxy-connect.sh10
-rw-r--r--[-rwxr-xr-x]crypto/openssh/regress/putty-ciphers.sh4
-rw-r--r--[-rwxr-xr-x]crypto/openssh/regress/putty-kex.sh4
-rw-r--r--[-rwxr-xr-x]crypto/openssh/regress/putty-transfer.sh10
-rw-r--r--crypto/openssh/regress/reconfigure.sh24
-rw-r--r--crypto/openssh/regress/reexec.sh5
-rw-r--r--crypto/openssh/regress/rekey.sh8
-rw-r--r--crypto/openssh/regress/scp-ssh-wrapper.sh14
-rw-r--r--crypto/openssh/regress/scp-uri.sh81
-rw-r--r--crypto/openssh/regress/scp.sh183
-rw-r--r--crypto/openssh/regress/scp3.sh60
-rw-r--r--crypto/openssh/regress/servcfginclude.sh188
-rw-r--r--crypto/openssh/regress/sftp-badcmds.sh4
-rw-r--r--[-rwxr-xr-x]crypto/openssh/regress/sftp-chroot.sh7
-rw-r--r--crypto/openssh/regress/sftp-cmds.sh4
-rw-r--r--crypto/openssh/regress/sftp-perm.sh18
-rwxr-xr-xcrypto/openssh/regress/ssh2putty.sh8
-rw-r--r--crypto/openssh/regress/sshcfgparse.sh68
-rw-r--r--crypto/openssh/regress/sshfp-connect.sh66
-rw-r--r--crypto/openssh/regress/sshsig.sh236
-rw-r--r--crypto/openssh/regress/test-exec.sh280
-rw-r--r--crypto/openssh/regress/unittests/Makefile4
-rw-r--r--crypto/openssh/regress/unittests/Makefile.inc38
-rw-r--r--crypto/openssh/regress/unittests/authopt/tests.c10
-rw-r--r--crypto/openssh/regress/unittests/bitmap/tests.c4
-rw-r--r--crypto/openssh/regress/unittests/conversion/Makefile3
-rw-r--r--crypto/openssh/regress/unittests/conversion/tests.c32
-rw-r--r--crypto/openssh/regress/unittests/hostkeys/Makefile12
-rw-r--r--[-rwxr-xr-x]crypto/openssh/regress/unittests/hostkeys/mktestdata.sh0
-rw-r--r--crypto/openssh/regress/unittests/hostkeys/test_iterate.c119
-rw-r--r--crypto/openssh/regress/unittests/kex/Makefile31
-rw-r--r--crypto/openssh/regress/unittests/kex/test_kex.c29
-rw-r--r--crypto/openssh/regress/unittests/match/Makefile4
-rw-r--r--crypto/openssh/regress/unittests/match/tests.c4
-rw-r--r--crypto/openssh/regress/unittests/misc/test_argv.c187
-rw-r--r--crypto/openssh/regress/unittests/misc/test_convtime.c59
-rw-r--r--crypto/openssh/regress/unittests/misc/test_expand.c90
-rw-r--r--crypto/openssh/regress/unittests/misc/test_parse.c86
-rw-r--r--crypto/openssh/regress/unittests/misc/test_strdelim.c202
-rw-r--r--crypto/openssh/regress/unittests/misc/tests.c38
-rw-r--r--crypto/openssh/regress/unittests/sshbuf/Makefile10
-rw-r--r--crypto/openssh/regress/unittests/sshbuf/test_sshbuf_fuzz.c9
-rw-r--r--crypto/openssh/regress/unittests/sshbuf/test_sshbuf_getput_basic.c231
-rw-r--r--crypto/openssh/regress/unittests/sshbuf/test_sshbuf_getput_crypto.c160
-rw-r--r--crypto/openssh/regress/unittests/sshbuf/test_sshbuf_getput_fuzz.c31
-rw-r--r--crypto/openssh/regress/unittests/sshbuf/test_sshbuf_misc.c71
-rw-r--r--crypto/openssh/regress/unittests/sshbuf/tests.c2
-rw-r--r--crypto/openssh/regress/unittests/sshkey/Makefile14
-rw-r--r--crypto/openssh/regress/unittests/sshkey/common.c17
-rwxr-xr-xcrypto/openssh/regress/unittests/sshkey/mktestdata.sh85
-rw-r--r--crypto/openssh/regress/unittests/sshkey/test_file.c141
-rw-r--r--crypto/openssh/regress/unittests/sshkey/test_fuzz.c78
-rw-r--r--crypto/openssh/regress/unittests/sshkey/test_sshkey.c55
-rw-r--r--crypto/openssh/regress/unittests/sshkey/testdata/dsa_n33
-rw-r--r--crypto/openssh/regress/unittests/sshkey/testdata/ecdsa_n13
-rw-r--r--crypto/openssh/regress/unittests/sshkey/testdata/ecdsa_sk113
-rw-r--r--crypto/openssh/regress/unittests/sshkey/testdata/ecdsa_sk1-cert.fp1
-rw-r--r--crypto/openssh/regress/unittests/sshkey/testdata/ecdsa_sk1-cert.pub1
-rw-r--r--crypto/openssh/regress/unittests/sshkey/testdata/ecdsa_sk1.fp1
-rw-r--r--crypto/openssh/regress/unittests/sshkey/testdata/ecdsa_sk1.fp.bb1
-rw-r--r--crypto/openssh/regress/unittests/sshkey/testdata/ecdsa_sk1.pub1
-rw-r--r--crypto/openssh/regress/unittests/sshkey/testdata/ecdsa_sk1_pw14
-rw-r--r--crypto/openssh/regress/unittests/sshkey/testdata/ecdsa_sk213
-rw-r--r--crypto/openssh/regress/unittests/sshkey/testdata/ecdsa_sk2.fp1
-rw-r--r--crypto/openssh/regress/unittests/sshkey/testdata/ecdsa_sk2.fp.bb1
-rw-r--r--crypto/openssh/regress/unittests/sshkey/testdata/ecdsa_sk2.pub1
-rw-r--r--crypto/openssh/regress/unittests/sshkey/testdata/ed25519_1_pw12
-rw-r--r--crypto/openssh/regress/unittests/sshkey/testdata/ed25519_sk18
-rw-r--r--crypto/openssh/regress/unittests/sshkey/testdata/ed25519_sk1-cert.fp1
-rw-r--r--crypto/openssh/regress/unittests/sshkey/testdata/ed25519_sk1-cert.pub1
-rw-r--r--crypto/openssh/regress/unittests/sshkey/testdata/ed25519_sk1.fp1
-rw-r--r--crypto/openssh/regress/unittests/sshkey/testdata/ed25519_sk1.fp.bb1
-rw-r--r--crypto/openssh/regress/unittests/sshkey/testdata/ed25519_sk1.pub1
-rw-r--r--crypto/openssh/regress/unittests/sshkey/testdata/ed25519_sk1_pw9
-rw-r--r--crypto/openssh/regress/unittests/sshkey/testdata/ed25519_sk28
-rw-r--r--crypto/openssh/regress/unittests/sshkey/testdata/ed25519_sk2.fp1
-rw-r--r--crypto/openssh/regress/unittests/sshkey/testdata/ed25519_sk2.fp.bb1
-rw-r--r--crypto/openssh/regress/unittests/sshkey/testdata/ed25519_sk2.pub1
-rw-r--r--crypto/openssh/regress/unittests/sshkey/testdata/rsa1_1bin533 -> 0 bytes
-rw-r--r--crypto/openssh/regress/unittests/sshkey/testdata/rsa1_1.fp1
-rw-r--r--crypto/openssh/regress/unittests/sshkey/testdata/rsa1_1.fp.bb1
-rw-r--r--crypto/openssh/regress/unittests/sshkey/testdata/rsa1_1.param.n1
-rw-r--r--crypto/openssh/regress/unittests/sshkey/testdata/rsa1_1.pub1
-rw-r--r--crypto/openssh/regress/unittests/sshkey/testdata/rsa1_1_pwbin533 -> 0 bytes
-rw-r--r--crypto/openssh/regress/unittests/sshkey/testdata/rsa1_2bin981 -> 0 bytes
-rw-r--r--crypto/openssh/regress/unittests/sshkey/testdata/rsa1_2.fp1
-rw-r--r--crypto/openssh/regress/unittests/sshkey/testdata/rsa1_2.fp.bb1
-rw-r--r--crypto/openssh/regress/unittests/sshkey/testdata/rsa1_2.param.n1
-rw-r--r--crypto/openssh/regress/unittests/sshkey/testdata/rsa1_2.pub1
-rw-r--r--crypto/openssh/regress/unittests/sshkey/testdata/rsa_n31
-rw-r--r--crypto/openssh/regress/unittests/sshkey/tests.c5
-rw-r--r--crypto/openssh/regress/unittests/sshsig/Makefile25
-rwxr-xr-xcrypto/openssh/regress/unittests/sshsig/mktestdata.sh42
-rw-r--r--crypto/openssh/regress/unittests/sshsig/testdata/dsa12
-rw-r--r--crypto/openssh/regress/unittests/sshsig/testdata/dsa.pub1
-rw-r--r--crypto/openssh/regress/unittests/sshsig/testdata/dsa.sig13
-rw-r--r--crypto/openssh/regress/unittests/sshsig/testdata/ecdsa5
-rw-r--r--crypto/openssh/regress/unittests/sshsig/testdata/ecdsa.pub1
-rw-r--r--crypto/openssh/regress/unittests/sshsig/testdata/ecdsa.sig7
-rw-r--r--crypto/openssh/regress/unittests/sshsig/testdata/ecdsa_sk13
-rw-r--r--crypto/openssh/regress/unittests/sshsig/testdata/ecdsa_sk.pub1
-rw-r--r--crypto/openssh/regress/unittests/sshsig/testdata/ecdsa_sk.sig8
-rw-r--r--crypto/openssh/regress/unittests/sshsig/testdata/ecdsa_sk_webauthn.pub1
-rw-r--r--crypto/openssh/regress/unittests/sshsig/testdata/ecdsa_sk_webauthn.sig13
-rw-r--r--crypto/openssh/regress/unittests/sshsig/testdata/ed255197
-rw-r--r--crypto/openssh/regress/unittests/sshsig/testdata/ed25519.pub1
-rw-r--r--crypto/openssh/regress/unittests/sshsig/testdata/ed25519.sig6
-rw-r--r--crypto/openssh/regress/unittests/sshsig/testdata/ed25519_sk8
-rw-r--r--crypto/openssh/regress/unittests/sshsig/testdata/ed25519_sk.pub1
-rw-r--r--crypto/openssh/regress/unittests/sshsig/testdata/ed25519_sk.sig7
-rw-r--r--crypto/openssh/regress/unittests/sshsig/testdata/namespace1
-rw-r--r--crypto/openssh/regress/unittests/sshsig/testdata/rsa39
-rw-r--r--crypto/openssh/regress/unittests/sshsig/testdata/rsa.pub1
-rw-r--r--crypto/openssh/regress/unittests/sshsig/testdata/rsa.sig19
-rw-r--r--crypto/openssh/regress/unittests/sshsig/testdata/signed-data1
-rw-r--r--crypto/openssh/regress/unittests/sshsig/tests.c139
-rw-r--r--crypto/openssh/regress/unittests/sshsig/webauthn.html766
-rw-r--r--crypto/openssh/regress/unittests/test_helper/test_helper.c60
-rw-r--r--crypto/openssh/regress/unittests/test_helper/test_helper.h8
-rw-r--r--crypto/openssh/regress/unittests/utf8/tests.c2
-rwxr-xr-xcrypto/openssh/regress/valgrind-unit.sh2
-rw-r--r--crypto/openssh/sandbox-darwin.c2
-rw-r--r--crypto/openssh/sandbox-pledge.c8
-rw-r--r--crypto/openssh/sandbox-rlimit.c18
-rw-r--r--crypto/openssh/sandbox-seccomp-filter.c76
-rw-r--r--crypto/openssh/sandbox-systrace.c7
-rw-r--r--crypto/openssh/scp.187
-rw-r--r--crypto/openssh/scp.c679
-rw-r--r--crypto/openssh/servconf.c1165
-rw-r--r--crypto/openssh/servconf.h63
-rw-r--r--crypto/openssh/serverloop.c566
-rw-r--r--crypto/openssh/session.c461
-rw-r--r--crypto/openssh/sftp-client.c1162
-rw-r--r--crypto/openssh/sftp-client.h64
-rw-r--r--crypto/openssh/sftp-common.c5
-rw-r--r--crypto/openssh/sftp-glob.c4
-rw-r--r--crypto/openssh/sftp-realpath.c (renamed from crypto/openssh/openbsd-compat/realpath.c)13
-rw-r--r--crypto/openssh/sftp-server-main.c5
-rw-r--r--crypto/openssh/sftp-server.832
-rw-r--r--crypto/openssh/sftp-server.c491
-rw-r--r--crypto/openssh/sftp.1126
-rw-r--r--crypto/openssh/sftp.c304
-rw-r--r--crypto/openssh/sk-api.h98
-rw-r--r--crypto/openssh/sk-usbhid.c1267
-rw-r--r--crypto/openssh/sntrup761.c1273
-rw-r--r--crypto/openssh/sntrup761.sh85
-rw-r--r--crypto/openssh/srclimit.c140
-rw-r--r--crypto/openssh/srclimit.h18
-rw-r--r--crypto/openssh/ssh-add.181
-rw-r--r--crypto/openssh/ssh-add.c315
-rw-r--r--crypto/openssh/ssh-agent.1178
-rw-r--r--crypto/openssh/ssh-agent.c697
-rw-r--r--crypto/openssh/ssh-dss.c8
-rw-r--r--crypto/openssh/ssh-ecdsa-sk.c324
-rw-r--r--crypto/openssh/ssh-ecdsa.c14
-rw-r--r--crypto/openssh/ssh-ed25519-sk.c163
-rw-r--r--crypto/openssh/ssh-ed25519.c23
-rw-r--r--crypto/openssh/ssh-gss.h4
-rw-r--r--crypto/openssh/ssh-keygen.1717
-rw-r--r--crypto/openssh/ssh-keygen.c2111
-rw-r--r--crypto/openssh/ssh-keyscan.16
-rw-r--r--crypto/openssh/ssh-keyscan.c105
-rw-r--r--crypto/openssh/ssh-keysign.86
-rw-r--r--crypto/openssh/ssh-keysign.c77
-rw-r--r--crypto/openssh/ssh-pkcs11-client.c212
-rw-r--r--crypto/openssh/ssh-pkcs11-helper.829
-rw-r--r--crypto/openssh/ssh-pkcs11-helper.c210
-rw-r--r--crypto/openssh/ssh-pkcs11.c1724
-rw-r--r--crypto/openssh/ssh-pkcs11.h20
-rw-r--r--crypto/openssh/ssh-sk-client.c448
-rw-r--r--crypto/openssh/ssh-sk-helper.866
-rw-r--r--crypto/openssh/ssh-sk-helper.c364
-rw-r--r--crypto/openssh/ssh-sk.c826
-rw-r--r--crypto/openssh/ssh-sk.h69
-rw-r--r--crypto/openssh/ssh-xmss.c27
-rw-r--r--crypto/openssh/ssh.1166
-rw-r--r--crypto/openssh/ssh.c925
-rw-r--r--crypto/openssh/ssh.h11
-rw-r--r--crypto/openssh/ssh2.h4
-rw-r--r--crypto/openssh/ssh_api.c234
-rw-r--r--crypto/openssh/ssh_config6
-rw-r--r--crypto/openssh/ssh_config.5651
-rw-r--r--crypto/openssh/ssh_namespace.h223
-rw-r--r--crypto/openssh/sshbuf-getput-basic.c171
-rw-r--r--crypto/openssh/sshbuf-getput-crypto.c76
-rw-r--r--crypto/openssh/sshbuf-io.c117
-rw-r--r--crypto/openssh/sshbuf-misc.c152
-rw-r--r--crypto/openssh/sshbuf.c22
-rw-r--r--crypto/openssh/sshbuf.h79
-rw-r--r--crypto/openssh/sshconnect.c882
-rw-r--r--crypto/openssh/sshconnect.h63
-rw-r--r--crypto/openssh/sshconnect2.c942
-rw-r--r--crypto/openssh/sshd.8115
-rw-r--r--crypto/openssh/sshd.c975
-rw-r--r--crypto/openssh/sshd_config12
-rw-r--r--crypto/openssh/sshd_config.5351
-rw-r--r--crypto/openssh/ssherr.c6
-rw-r--r--crypto/openssh/ssherr.h4
-rw-r--r--crypto/openssh/sshkey-xmss.c160
-rw-r--r--crypto/openssh/sshkey-xmss.h16
-rw-r--r--crypto/openssh/sshkey.c1498
-rw-r--r--crypto/openssh/sshkey.h103
-rw-r--r--crypto/openssh/sshlogin.c9
-rw-r--r--crypto/openssh/sshpty.c23
-rw-r--r--crypto/openssh/sshsig.c1098
-rw-r--r--crypto/openssh/sshsig.h107
-rw-r--r--crypto/openssh/ttymodes.c44
-rw-r--r--crypto/openssh/uidswap.c40
-rw-r--r--crypto/openssh/umac.c10
-rw-r--r--crypto/openssh/umac.h6
-rw-r--r--crypto/openssh/utf8.c27
-rw-r--r--crypto/openssh/utf8.h11
-rw-r--r--crypto/openssh/uuencode.c95
-rw-r--r--crypto/openssh/uuencode.h29
-rw-r--r--crypto/openssh/version.h6
-rw-r--r--crypto/openssh/xmalloc.c31
-rw-r--r--crypto/openssh/xmalloc.h8
-rw-r--r--crypto/openssh/xmss_commons.c2
-rw-r--r--crypto/openssh/xmss_fast.c2
-rw-r--r--crypto/openssh/xmss_hash.c2
-rw-r--r--crypto/openssh/xmss_hash_address.c2
-rw-r--r--crypto/openssh/xmss_wots.c2
-rw-r--r--lib/libpam/modules/pam_ssh/pam_ssh.c2
-rw-r--r--secure/lib/libssh/Makefile19
-rw-r--r--secure/usr.bin/scp/Makefile2
-rw-r--r--secure/usr.bin/ssh-add/Makefile2
-rw-r--r--secure/usr.bin/ssh-keygen/Makefile3
-rw-r--r--secure/usr.sbin/sshd/Makefile2
539 files changed, 53562 insertions, 25097 deletions
diff --git a/crypto/openssh/.depend b/crypto/openssh/.depend
index 2b29e3879da1..a94a82d0e6f7 100644
--- a/crypto/openssh/.depend
+++ b/crypto/openssh/.depend
@@ -1,175 +1,183 @@
-# DO NOT DELETE
+# Automatically generated by makedepend.
+# Run "make depend" to rebuild.
-addrmatch.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/rmd160.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/getopt.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h match.h log.h
-atomicio.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/rmd160.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/getopt.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h atomicio.h
-audit-bsm.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/rmd160.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/getopt.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h
-audit-linux.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/rmd160.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/getopt.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h
-audit.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/rmd160.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/getopt.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h
-auth-bsdauth.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/rmd160.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/getopt.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h
-auth-krb5.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/rmd160.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/getopt.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h xmalloc.h ssh.h packet.h openbsd-compat/sys-queue.h dispatch.h opacket.h log.h sshbuf.h sshkey.h misc.h servconf.h uidswap.h hostfile.h auth.h auth-pam.h audit.h loginrec.h
-auth-options.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/rmd160.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/getopt.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h openbsd-compat/sys-queue.h xmalloc.h ssherr.h log.h sshbuf.h misc.h sshkey.h match.h ssh2.h auth-options.h
-auth-pam.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/rmd160.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/getopt.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h
-auth-passwd.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/rmd160.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/getopt.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h packet.h openbsd-compat/sys-queue.h dispatch.h opacket.h sshbuf.h ssherr.h log.h misc.h servconf.h sshkey.h hostfile.h auth.h auth-pam.h audit.h loginrec.h auth-options.h
-auth-rhosts.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/rmd160.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/getopt.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h packet.h openbsd-compat/sys-queue.h dispatch.h opacket.h uidswap.h pathnames.h log.h misc.h sshbuf.h sshkey.h servconf.h canohost.h hostfile.h auth.h auth-pam.h audit.h loginrec.h
-auth-shadow.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/rmd160.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/getopt.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h
-auth-sia.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/rmd160.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/getopt.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h
-auth-skey.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/rmd160.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/getopt.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h
-auth.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/rmd160.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/getopt.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h xmalloc.h match.h groupaccess.h log.h sshbuf.h misc.h servconf.h sshkey.h hostfile.h auth.h auth-pam.h audit.h loginrec.h auth-options.h canohost.h uidswap.h packet.h openbsd-compat/sys-queue.h dispatch.h opacket.h
-auth.o: authfile.h monitor_wrap.h ssherr.h compat.h channels.h
-auth2-chall.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/rmd160.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/getopt.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h xmalloc.h ssh2.h sshkey.h hostfile.h auth.h auth-pam.h audit.h loginrec.h sshbuf.h packet.h openbsd-compat/sys-queue.h dispatch.h opacket.h ssherr.h log.h misc.h servconf.h
-auth2-gss.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/rmd160.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/getopt.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h
-auth2-hostbased.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/rmd160.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/getopt.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h xmalloc.h ssh2.h packet.h openbsd-compat/sys-queue.h dispatch.h opacket.h sshbuf.h log.h misc.h servconf.h compat.h sshkey.h hostfile.h auth.h auth-pam.h audit.h loginrec.h canohost.h monitor_wrap.h
-auth2-hostbased.o: pathnames.h ssherr.h match.h
-auth2-kbdint.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/rmd160.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/getopt.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h xmalloc.h packet.h openbsd-compat/sys-queue.h dispatch.h opacket.h hostfile.h auth.h auth-pam.h audit.h loginrec.h log.h misc.h servconf.h ssherr.h
-auth2-none.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/rmd160.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/getopt.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h atomicio.h xmalloc.h sshkey.h hostfile.h auth.h auth-pam.h audit.h loginrec.h packet.h openbsd-compat/sys-queue.h dispatch.h opacket.h log.h misc.h servconf.h compat.h ssh2.h ssherr.h monitor_wrap.h
-auth2-passwd.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/rmd160.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/getopt.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h packet.h openbsd-compat/sys-queue.h dispatch.h opacket.h ssherr.h log.h sshkey.h hostfile.h auth.h auth-pam.h audit.h loginrec.h monitor_wrap.h misc.h servconf.h
-auth2-pubkey.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/rmd160.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/getopt.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h xmalloc.h ssh.h ssh2.h packet.h openbsd-compat/sys-queue.h dispatch.h opacket.h sshbuf.h log.h misc.h servconf.h compat.h sshkey.h hostfile.h auth.h auth-pam.h audit.h loginrec.h pathnames.h uidswap.h
-auth2-pubkey.o: auth-options.h canohost.h monitor_wrap.h authfile.h match.h ssherr.h channels.h session.h
-auth2.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/rmd160.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/getopt.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h atomicio.h xmalloc.h ssh2.h packet.h openbsd-compat/sys-queue.h dispatch.h opacket.h log.h sshbuf.h misc.h servconf.h compat.h sshkey.h hostfile.h auth.h auth-pam.h audit.h loginrec.h pathnames.h ssherr.h
-auth2.o: monitor_wrap.h digest.h
-authfd.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/rmd160.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/getopt.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h xmalloc.h ssh.h sshbuf.h sshkey.h authfd.h cipher.h cipher-chachapoly.h chacha.h poly1305.h cipher-aesctr.h rijndael.h compat.h log.h atomicio.h misc.h ssherr.h
-authfile.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/rmd160.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/getopt.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h cipher.h cipher-chachapoly.h chacha.h poly1305.h cipher-aesctr.h rijndael.h ssh.h log.h authfile.h misc.h atomicio.h sshkey.h sshbuf.h ssherr.h krl.h
-bitmap.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/rmd160.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/getopt.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h bitmap.h
-canohost.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/rmd160.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/getopt.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h xmalloc.h packet.h openbsd-compat/sys-queue.h dispatch.h opacket.h log.h canohost.h misc.h
-chacha.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/rmd160.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/getopt.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h chacha.h
-channels.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/rmd160.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/getopt.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h openbsd-compat/sys-queue.h xmalloc.h ssh.h ssh2.h ssherr.h sshbuf.h packet.h dispatch.h opacket.h log.h misc.h channels.h compat.h canohost.h sshkey.h authfd.h pathnames.h match.h
-cipher-aes.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/rmd160.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/getopt.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h openbsd-compat/openssl-compat.h
-cipher-aesctr.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/rmd160.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/getopt.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h cipher-aesctr.h rijndael.h
-cipher-chachapoly.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/rmd160.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/getopt.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h log.h sshbuf.h ssherr.h cipher-chachapoly.h chacha.h poly1305.h
-cipher-ctr.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/rmd160.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/getopt.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h
-cipher.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/rmd160.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/getopt.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h cipher.h cipher-chachapoly.h chacha.h poly1305.h cipher-aesctr.h rijndael.h misc.h sshbuf.h ssherr.h digest.h openbsd-compat/openssl-compat.h
-cleanup.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/rmd160.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/getopt.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h log.h
-clientloop.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/rmd160.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/getopt.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h openbsd-compat/sys-queue.h xmalloc.h ssh.h ssh2.h packet.h dispatch.h opacket.h sshbuf.h compat.h channels.h sshkey.h cipher.h cipher-chachapoly.h chacha.h poly1305.h cipher-aesctr.h rijndael.h kex.h mac.h
-clientloop.o: myproposal.h log.h misc.h readconf.h clientloop.h sshconnect.h authfd.h atomicio.h sshpty.h match.h msg.h ssherr.h hostfile.h
-compat.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/rmd160.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/getopt.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h xmalloc.h packet.h openbsd-compat/sys-queue.h dispatch.h opacket.h compat.h log.h match.h kex.h mac.h
-crc32.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/rmd160.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/getopt.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h crc32.h
-dh.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/rmd160.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/getopt.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h
-digest-libc.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/rmd160.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/getopt.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h ssherr.h sshbuf.h digest.h
-digest-openssl.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/rmd160.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/getopt.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h
-dispatch.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/rmd160.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/getopt.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h ssh2.h log.h dispatch.h packet.h openbsd-compat/sys-queue.h opacket.h compat.h ssherr.h
-dns.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/rmd160.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/getopt.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h xmalloc.h sshkey.h ssherr.h dns.h log.h digest.h
-ed25519.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/rmd160.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/getopt.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h crypto_api.h ge25519.h fe25519.h sc25519.h
-entropy.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/rmd160.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/getopt.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h
-fatal.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/rmd160.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/getopt.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h log.h
-fe25519.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/rmd160.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/getopt.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h fe25519.h crypto_api.h
-ge25519.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/rmd160.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/getopt.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h fe25519.h crypto_api.h sc25519.h ge25519.h ge25519_base.data
-groupaccess.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/rmd160.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/getopt.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h xmalloc.h groupaccess.h match.h log.h
-gss-genr.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/rmd160.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/getopt.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h
-gss-serv-krb5.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/rmd160.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/getopt.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h
-gss-serv.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/rmd160.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/getopt.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h
-hash.o: crypto_api.h includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/rmd160.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/getopt.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h digest.h log.h ssherr.h
-hmac.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/rmd160.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/getopt.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h sshbuf.h digest.h hmac.h
-hostfile.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/rmd160.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/getopt.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h xmalloc.h match.h sshkey.h hostfile.h log.h misc.h ssherr.h digest.h hmac.h
-kex.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/rmd160.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/getopt.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h ssh2.h packet.h openbsd-compat/sys-queue.h dispatch.h opacket.h compat.h cipher.h cipher-chachapoly.h chacha.h poly1305.h cipher-aesctr.h rijndael.h sshkey.h kex.h mac.h log.h match.h misc.h monitor.h ssherr.h sshbuf.h
-kex.o: digest.h
-kexc25519.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/rmd160.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/getopt.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h sshbuf.h ssh2.h sshkey.h cipher.h cipher-chachapoly.h chacha.h poly1305.h cipher-aesctr.h rijndael.h kex.h mac.h log.h digest.h ssherr.h
-kexc25519c.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/rmd160.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/getopt.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h sshkey.h cipher.h cipher-chachapoly.h chacha.h poly1305.h cipher-aesctr.h rijndael.h kex.h mac.h log.h packet.h openbsd-compat/sys-queue.h dispatch.h opacket.h ssh2.h sshbuf.h digest.h ssherr.h
-kexc25519s.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/rmd160.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/getopt.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h sshkey.h cipher.h cipher-chachapoly.h chacha.h poly1305.h cipher-aesctr.h rijndael.h digest.h kex.h mac.h log.h packet.h openbsd-compat/sys-queue.h dispatch.h opacket.h ssh2.h sshbuf.h ssherr.h
-kexdh.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/rmd160.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/getopt.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h
-kexdhc.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/rmd160.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/getopt.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h
-kexdhs.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/rmd160.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/getopt.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h
-kexecdh.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/rmd160.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/getopt.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h
-kexecdhc.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/rmd160.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/getopt.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h
-kexecdhs.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/rmd160.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/getopt.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h
-kexgex.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/rmd160.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/getopt.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h
-kexgexc.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/rmd160.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/getopt.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h
-kexgexs.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/rmd160.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/getopt.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h
-krl.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/rmd160.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/getopt.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h ./openbsd-compat/sys-tree.h openbsd-compat/sys-queue.h sshbuf.h ssherr.h sshkey.h authfile.h misc.h log.h digest.h bitmap.h krl.h
-log.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/rmd160.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/getopt.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h log.h
-loginrec.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/rmd160.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/getopt.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h xmalloc.h sshkey.h hostfile.h ssh.h loginrec.h log.h atomicio.h packet.h openbsd-compat/sys-queue.h dispatch.h opacket.h canohost.h auth.h auth-pam.h audit.h sshbuf.h ssherr.h
-logintest.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/rmd160.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/getopt.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h loginrec.h
-mac.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/rmd160.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/getopt.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h digest.h hmac.h umac.h mac.h misc.h ssherr.h sshbuf.h openbsd-compat/openssl-compat.h
-match.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/rmd160.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/getopt.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h xmalloc.h match.h misc.h
-md5crypt.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/rmd160.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/getopt.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h
-misc.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/rmd160.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/getopt.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h xmalloc.h misc.h log.h ssh.h sshbuf.h ssherr.h
-moduli.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/rmd160.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/getopt.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h
-monitor.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/rmd160.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/getopt.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h ./openbsd-compat/sys-tree.h openbsd-compat/sys-queue.h openbsd-compat/openssl-compat.h atomicio.h xmalloc.h ssh.h sshkey.h sshbuf.h hostfile.h auth.h auth-pam.h audit.h loginrec.h cipher.h cipher-chachapoly.h
-monitor.o: chacha.h poly1305.h cipher-aesctr.h rijndael.h kex.h mac.h dh.h packet.h dispatch.h opacket.h auth-options.h sshpty.h channels.h session.h sshlogin.h canohost.h log.h misc.h servconf.h monitor.h monitor_wrap.h monitor_fdpass.h compat.h ssh2.h authfd.h match.h ssherr.h
-monitor_fdpass.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/rmd160.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/getopt.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h log.h monitor_fdpass.h
-monitor_wrap.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/rmd160.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/getopt.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h openbsd-compat/sys-queue.h xmalloc.h ssh.h sshbuf.h sshkey.h cipher.h cipher-chachapoly.h chacha.h poly1305.h cipher-aesctr.h rijndael.h kex.h mac.h hostfile.h auth.h auth-pam.h audit.h loginrec.h
-monitor_wrap.o: auth-options.h packet.h dispatch.h opacket.h log.h monitor.h monitor_wrap.h atomicio.h monitor_fdpass.h misc.h channels.h session.h servconf.h ssherr.h
-msg.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/rmd160.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/getopt.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h sshbuf.h ssherr.h log.h atomicio.h msg.h misc.h
-mux.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/rmd160.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/getopt.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h openbsd-compat/sys-queue.h xmalloc.h log.h ssh.h ssh2.h pathnames.h misc.h match.h sshbuf.h channels.h msg.h packet.h dispatch.h opacket.h monitor_fdpass.h sshpty.h sshkey.h readconf.h clientloop.h ssherr.h
-nchan.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/rmd160.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/getopt.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h openbsd-compat/sys-queue.h ssh2.h sshbuf.h ssherr.h packet.h dispatch.h opacket.h channels.h compat.h log.h
-opacket.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/rmd160.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/getopt.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h ssherr.h packet.h openbsd-compat/sys-queue.h dispatch.h opacket.h log.h
-packet.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/rmd160.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/getopt.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h openbsd-compat/sys-queue.h xmalloc.h crc32.h compat.h ssh2.h cipher.h cipher-chachapoly.h chacha.h poly1305.h cipher-aesctr.h rijndael.h sshkey.h kex.h mac.h digest.h log.h canohost.h misc.h channels.h ssh.h
-packet.o: packet.h dispatch.h opacket.h ssherr.h sshbuf.h
-platform-misc.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/rmd160.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/getopt.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h
-platform-pledge.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/rmd160.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/getopt.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h
-platform-tracing.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/rmd160.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/getopt.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h log.h
-platform.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/rmd160.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/getopt.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h log.h misc.h servconf.h sshkey.h hostfile.h auth.h auth-pam.h audit.h loginrec.h
-poly1305.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/rmd160.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/getopt.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h poly1305.h
-progressmeter.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/rmd160.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/getopt.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h progressmeter.h atomicio.h misc.h
-readconf.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/rmd160.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/getopt.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h openbsd-compat/glob.h xmalloc.h ssh.h ssherr.h compat.h cipher.h cipher-chachapoly.h chacha.h poly1305.h cipher-aesctr.h rijndael.h pathnames.h log.h sshkey.h misc.h readconf.h match.h kex.h mac.h uidswap.h
-readconf.o: myproposal.h digest.h
-readpass.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/rmd160.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/getopt.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h xmalloc.h misc.h pathnames.h log.h ssh.h uidswap.h
-rijndael.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/rmd160.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/getopt.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h rijndael.h
-sandbox-capsicum.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/rmd160.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/getopt.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h
-sandbox-darwin.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/rmd160.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/getopt.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h
-sandbox-null.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/rmd160.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/getopt.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h
-sandbox-pledge.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/rmd160.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/getopt.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h
-sandbox-rlimit.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/rmd160.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/getopt.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h
-sandbox-seccomp-filter.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/rmd160.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/getopt.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h
-sandbox-solaris.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/rmd160.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/getopt.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h
-sandbox-systrace.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/rmd160.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/getopt.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h
-sc25519.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/rmd160.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/getopt.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h sc25519.h crypto_api.h
-scp.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/rmd160.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/getopt.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h xmalloc.h ssh.h atomicio.h pathnames.h log.h misc.h progressmeter.h utf8.h
-servconf.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/rmd160.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/getopt.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h openbsd-compat/sys-queue.h xmalloc.h ssh.h log.h sshbuf.h misc.h servconf.h compat.h pathnames.h cipher.h cipher-chachapoly.h chacha.h poly1305.h cipher-aesctr.h rijndael.h sshkey.h kex.h mac.h match.h channels.h
-servconf.o: groupaccess.h canohost.h packet.h dispatch.h opacket.h ssherr.h hostfile.h auth.h auth-pam.h audit.h loginrec.h myproposal.h digest.h
-serverloop.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/rmd160.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/getopt.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h openbsd-compat/sys-queue.h xmalloc.h packet.h dispatch.h opacket.h sshbuf.h log.h misc.h servconf.h canohost.h sshpty.h channels.h compat.h ssh2.h sshkey.h cipher.h cipher-chachapoly.h chacha.h poly1305.h
-serverloop.o: cipher-aesctr.h rijndael.h kex.h mac.h hostfile.h auth.h auth-pam.h audit.h loginrec.h session.h auth-options.h serverloop.h ssherr.h
-session.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/rmd160.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/getopt.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h openbsd-compat/sys-queue.h xmalloc.h ssh.h ssh2.h sshpty.h packet.h dispatch.h opacket.h sshbuf.h ssherr.h match.h uidswap.h compat.h channels.h sshkey.h cipher.h cipher-chachapoly.h chacha.h poly1305.h
-session.o: cipher-aesctr.h rijndael.h hostfile.h auth.h auth-pam.h audit.h loginrec.h auth-options.h authfd.h pathnames.h log.h misc.h servconf.h sshlogin.h serverloop.h canohost.h session.h kex.h mac.h monitor_wrap.h sftp.h atomicio.h
-sftp-client.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/rmd160.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/getopt.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h openbsd-compat/sys-queue.h xmalloc.h ssherr.h sshbuf.h log.h atomicio.h progressmeter.h misc.h utf8.h sftp.h sftp-common.h sftp-client.h openbsd-compat/glob.h
-sftp-common.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/rmd160.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/getopt.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h xmalloc.h ssherr.h sshbuf.h log.h misc.h sftp.h sftp-common.h
-sftp-glob.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/rmd160.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/getopt.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h xmalloc.h sftp.h sftp-common.h sftp-client.h openbsd-compat/glob.h
-sftp-server-main.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/rmd160.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/getopt.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h log.h sftp.h misc.h xmalloc.h
-sftp-server.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/rmd160.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/getopt.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h xmalloc.h sshbuf.h ssherr.h log.h misc.h match.h uidswap.h sftp.h sftp-common.h
-sftp.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/rmd160.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/getopt.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h xmalloc.h log.h pathnames.h misc.h utf8.h sftp.h ssherr.h sshbuf.h sftp-common.h sftp-client.h openbsd-compat/glob.h
-ssh-add.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/rmd160.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/getopt.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h openbsd-compat/openssl-compat.h xmalloc.h ssh.h log.h sshkey.h sshbuf.h authfd.h authfile.h pathnames.h misc.h ssherr.h digest.h
-ssh-agent.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/rmd160.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/getopt.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h openbsd-compat/sys-queue.h xmalloc.h ssh.h sshbuf.h sshkey.h authfd.h compat.h log.h misc.h digest.h ssherr.h match.h
-ssh-dss.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/rmd160.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/getopt.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h
-ssh-ecdsa.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/rmd160.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/getopt.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h
-ssh-ed25519.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/rmd160.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/getopt.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h crypto_api.h log.h sshbuf.h sshkey.h ssherr.h ssh.h
-ssh-keygen.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/rmd160.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/getopt.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h xmalloc.h sshkey.h authfile.h uuencode.h sshbuf.h pathnames.h log.h misc.h match.h hostfile.h dns.h ssh.h ssh2.h ssherr.h ssh-pkcs11.h atomicio.h krl.h digest.h utf8.h authfd.h
-ssh-keyscan.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/rmd160.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/getopt.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h openbsd-compat/sys-queue.h xmalloc.h ssh.h sshbuf.h sshkey.h cipher.h cipher-chachapoly.h chacha.h poly1305.h cipher-aesctr.h rijndael.h kex.h mac.h compat.h myproposal.h packet.h dispatch.h opacket.h log.h
-ssh-keyscan.o: atomicio.h misc.h hostfile.h ssherr.h ssh_api.h ssh2.h dns.h
-ssh-keysign.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/rmd160.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/getopt.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h xmalloc.h log.h sshkey.h ssh.h ssh2.h misc.h sshbuf.h authfile.h msg.h canohost.h pathnames.h readconf.h uidswap.h ssherr.h
-ssh-pkcs11-client.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/rmd160.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/getopt.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h
-ssh-pkcs11-helper.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/rmd160.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/getopt.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h openbsd-compat/sys-queue.h xmalloc.h sshbuf.h log.h misc.h sshkey.h authfd.h ssh-pkcs11.h ssherr.h
-ssh-pkcs11.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/rmd160.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/getopt.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h
-ssh-rsa.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/rmd160.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/getopt.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h
-ssh-xmss.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/rmd160.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/getopt.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h
-ssh.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/rmd160.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/getopt.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h openbsd-compat/openssl-compat.h openbsd-compat/sys-queue.h xmalloc.h ssh.h ssh2.h canohost.h compat.h cipher.h cipher-chachapoly.h chacha.h poly1305.h cipher-aesctr.h rijndael.h digest.h packet.h dispatch.h opacket.h
-ssh.o: sshbuf.h channels.h sshkey.h authfd.h authfile.h pathnames.h clientloop.h log.h misc.h readconf.h sshconnect.h kex.h mac.h sshpty.h match.h msg.h version.h ssherr.h myproposal.h utf8.h
-ssh_api.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/rmd160.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/getopt.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h ssh_api.h openbsd-compat/sys-queue.h cipher.h cipher-chachapoly.h chacha.h poly1305.h cipher-aesctr.h rijndael.h sshkey.h kex.h mac.h ssh.h ssh2.h packet.h dispatch.h opacket.h compat.h log.h authfile.h misc.h
-ssh_api.o: version.h myproposal.h ssherr.h sshbuf.h
-sshbuf-getput-basic.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/rmd160.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/getopt.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h ssherr.h sshbuf.h
-sshbuf-getput-crypto.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/rmd160.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/getopt.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h ssherr.h sshbuf.h
-sshbuf-misc.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/rmd160.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/getopt.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h ssherr.h sshbuf.h
-sshbuf.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/rmd160.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/getopt.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h ssherr.h sshbuf.h misc.h
-sshconnect.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/rmd160.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/getopt.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h xmalloc.h hostfile.h ssh.h sshbuf.h packet.h openbsd-compat/sys-queue.h dispatch.h opacket.h compat.h sshkey.h sshconnect.h log.h misc.h readconf.h atomicio.h dns.h monitor_fdpass.h ssh2.h version.h authfile.h
-sshconnect.o: ssherr.h authfd.h
-sshconnect2.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/rmd160.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/getopt.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h openbsd-compat/sys-queue.h xmalloc.h ssh.h ssh2.h sshbuf.h packet.h dispatch.h opacket.h compat.h cipher.h cipher-chachapoly.h chacha.h poly1305.h cipher-aesctr.h rijndael.h sshkey.h kex.h mac.h myproposal.h
-sshconnect2.o: sshconnect.h authfile.h dh.h authfd.h log.h misc.h readconf.h match.h canohost.h msg.h pathnames.h uidswap.h hostfile.h ssherr.h utf8.h
-sshd.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/rmd160.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/getopt.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h ./openbsd-compat/sys-tree.h openbsd-compat/sys-queue.h xmalloc.h ssh.h ssh2.h sshpty.h packet.h dispatch.h opacket.h log.h sshbuf.h misc.h match.h servconf.h uidswap.h compat.h cipher.h cipher-chachapoly.h chacha.h
-sshd.o: poly1305.h cipher-aesctr.h rijndael.h digest.h sshkey.h kex.h mac.h myproposal.h authfile.h pathnames.h atomicio.h canohost.h hostfile.h auth.h auth-pam.h audit.h loginrec.h authfd.h msg.h channels.h session.h monitor.h monitor_wrap.h ssh-sandbox.h auth-options.h version.h ssherr.h
+# DO NOT DELETE
+addr.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h addr.h
+addrmatch.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h addr.h match.h log.h ssherr.h
+atomicio.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h atomicio.h
+audit-bsm.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h
+audit-linux.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h
+audit.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h
+auth-bsdauth.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h
+auth-krb5.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h xmalloc.h ssh.h packet.h openbsd-compat/sys-queue.h dispatch.h log.h ssherr.h sshbuf.h sshkey.h misc.h servconf.h uidswap.h hostfile.h auth.h auth-pam.h audit.h loginrec.h
+auth-options.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h openbsd-compat/sys-queue.h xmalloc.h ssherr.h log.h sshbuf.h misc.h sshkey.h match.h ssh2.h auth-options.h
+auth-pam.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h
+auth-passwd.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h packet.h openbsd-compat/sys-queue.h dispatch.h sshbuf.h ssherr.h log.h misc.h servconf.h sshkey.h hostfile.h auth.h auth-pam.h audit.h loginrec.h auth-options.h
+auth-rhosts.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h packet.h openbsd-compat/sys-queue.h dispatch.h uidswap.h pathnames.h log.h ssherr.h misc.h sshbuf.h sshkey.h servconf.h canohost.h hostfile.h auth.h auth-pam.h audit.h loginrec.h
+auth-shadow.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h
+auth-sia.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h
+auth.o: authfile.h monitor_wrap.h compat.h channels.h
+auth.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h xmalloc.h match.h groupaccess.h log.h ssherr.h sshbuf.h misc.h servconf.h openbsd-compat/sys-queue.h sshkey.h hostfile.h auth.h auth-pam.h audit.h loginrec.h auth-options.h canohost.h uidswap.h packet.h dispatch.h
+auth2-chall.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h xmalloc.h ssh2.h sshkey.h hostfile.h auth.h auth-pam.h audit.h loginrec.h sshbuf.h packet.h openbsd-compat/sys-queue.h dispatch.h ssherr.h log.h misc.h servconf.h
+auth2-gss.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h
+auth2-hostbased.o: canohost.h monitor_wrap.h pathnames.h match.h
+auth2-hostbased.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h xmalloc.h ssh2.h packet.h openbsd-compat/sys-queue.h dispatch.h kex.h mac.h crypto_api.h sshbuf.h log.h ssherr.h misc.h servconf.h compat.h sshkey.h hostfile.h auth.h auth-pam.h audit.h loginrec.h
+auth2-kbdint.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h xmalloc.h packet.h openbsd-compat/sys-queue.h dispatch.h hostfile.h auth.h auth-pam.h audit.h loginrec.h log.h ssherr.h misc.h servconf.h
+auth2-none.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h atomicio.h xmalloc.h sshkey.h hostfile.h auth.h auth-pam.h audit.h loginrec.h packet.h openbsd-compat/sys-queue.h dispatch.h log.h ssherr.h misc.h servconf.h compat.h ssh2.h monitor_wrap.h
+auth2-passwd.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h packet.h openbsd-compat/sys-queue.h dispatch.h ssherr.h log.h sshkey.h hostfile.h auth.h auth-pam.h audit.h loginrec.h monitor_wrap.h misc.h servconf.h
+auth2-pubkey.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h xmalloc.h ssh.h ssh2.h packet.h openbsd-compat/sys-queue.h dispatch.h kex.h mac.h crypto_api.h sshbuf.h log.h ssherr.h misc.h servconf.h compat.h sshkey.h hostfile.h auth.h auth-pam.h audit.h loginrec.h
+auth2-pubkey.o: pathnames.h uidswap.h auth-options.h canohost.h monitor_wrap.h authfile.h match.h channels.h session.h sk-api.h
+auth2.o: digest.h
+auth2.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h atomicio.h xmalloc.h ssh2.h packet.h openbsd-compat/sys-queue.h dispatch.h log.h ssherr.h sshbuf.h misc.h servconf.h compat.h sshkey.h hostfile.h auth.h auth-pam.h audit.h loginrec.h pathnames.h monitor_wrap.h
+authfd.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h xmalloc.h ssh.h sshbuf.h sshkey.h authfd.h cipher.h cipher-chachapoly.h chacha.h poly1305.h cipher-aesctr.h rijndael.h compat.h log.h ssherr.h atomicio.h misc.h
+authfile.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h cipher.h cipher-chachapoly.h chacha.h poly1305.h cipher-aesctr.h rijndael.h ssh.h log.h ssherr.h authfile.h misc.h atomicio.h sshkey.h sshbuf.h krl.h
+bitmap.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h bitmap.h
+canohost.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h xmalloc.h packet.h openbsd-compat/sys-queue.h dispatch.h log.h ssherr.h canohost.h misc.h
+chacha.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h chacha.h
+channels.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h openbsd-compat/sys-queue.h xmalloc.h ssh.h ssh2.h ssherr.h sshbuf.h packet.h dispatch.h log.h misc.h channels.h compat.h canohost.h sshkey.h authfd.h pathnames.h match.h
+cipher-aes.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h openbsd-compat/openssl-compat.h
+cipher-aesctr.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h cipher-aesctr.h rijndael.h
+cipher-chachapoly-libcrypto.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h
+cipher-chachapoly.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h log.h ssherr.h sshbuf.h cipher-chachapoly.h chacha.h poly1305.h
+cipher-ctr.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h
+cipher.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h cipher.h cipher-chachapoly.h chacha.h poly1305.h cipher-aesctr.h rijndael.h misc.h sshbuf.h ssherr.h digest.h openbsd-compat/openssl-compat.h
+cleanup.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h log.h ssherr.h
+clientloop.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h openbsd-compat/sys-queue.h xmalloc.h ssh.h ssh2.h packet.h dispatch.h sshbuf.h compat.h channels.h sshkey.h cipher.h cipher-chachapoly.h chacha.h poly1305.h cipher-aesctr.h rijndael.h kex.h mac.h crypto_api.h
+clientloop.o: myproposal.h log.h ssherr.h misc.h readconf.h clientloop.h sshconnect.h authfd.h atomicio.h sshpty.h match.h msg.h hostfile.h
+compat.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h xmalloc.h packet.h openbsd-compat/sys-queue.h dispatch.h compat.h log.h ssherr.h match.h kex.h mac.h crypto_api.h
+dh.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h
+digest-libc.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h ssherr.h sshbuf.h digest.h
+digest-openssl.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h
+dispatch.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h ssh2.h log.h ssherr.h dispatch.h packet.h openbsd-compat/sys-queue.h compat.h
+dns.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h xmalloc.h sshkey.h ssherr.h dns.h log.h digest.h
+ed25519.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h crypto_api.h ge25519.h fe25519.h sc25519.h
+entropy.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h
+fatal.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h log.h ssherr.h
+fe25519.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h fe25519.h crypto_api.h
+ge25519.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h fe25519.h crypto_api.h sc25519.h ge25519.h ge25519_base.data
+groupaccess.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h xmalloc.h groupaccess.h match.h log.h ssherr.h
+gss-genr.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h
+gss-serv-krb5.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h
+gss-serv.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h
+hash.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h crypto_api.h
+hmac.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h sshbuf.h digest.h hmac.h
+hostfile.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h xmalloc.h match.h sshkey.h hostfile.h log.h ssherr.h misc.h pathnames.h digest.h hmac.h sshbuf.h
+kex.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h ssh.h ssh2.h atomicio.h version.h packet.h openbsd-compat/sys-queue.h dispatch.h compat.h cipher.h cipher-chachapoly.h chacha.h poly1305.h cipher-aesctr.h rijndael.h sshkey.h kex.h mac.h crypto_api.h log.h ssherr.h
+kex.o: match.h misc.h monitor.h sshbuf.h digest.h
+kexc25519.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h sshkey.h kex.h mac.h crypto_api.h sshbuf.h digest.h ssherr.h ssh2.h
+kexdh.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h
+kexecdh.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h ssherr.h
+kexgen.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h sshkey.h kex.h mac.h crypto_api.h log.h ssherr.h packet.h openbsd-compat/sys-queue.h dispatch.h ssh2.h sshbuf.h digest.h
+kexgex.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h
+kexgexc.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h
+kexgexs.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h
+kexsntrup761x25519.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h ssherr.h
+krl.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h ./openbsd-compat/sys-tree.h openbsd-compat/sys-queue.h sshbuf.h ssherr.h sshkey.h authfile.h misc.h log.h digest.h bitmap.h utf8.h krl.h
+log.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h log.h ssherr.h match.h
+loginrec.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h xmalloc.h sshkey.h hostfile.h ssh.h loginrec.h log.h ssherr.h atomicio.h packet.h openbsd-compat/sys-queue.h dispatch.h canohost.h auth.h auth-pam.h audit.h sshbuf.h
+logintest.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h loginrec.h
+mac.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h digest.h hmac.h umac.h mac.h misc.h ssherr.h sshbuf.h openbsd-compat/openssl-compat.h
+match.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h xmalloc.h match.h misc.h
+md5crypt.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h
+misc.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h xmalloc.h misc.h log.h ssherr.h ssh.h sshbuf.h
+moduli.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h
+monitor.o: chacha.h poly1305.h cipher-aesctr.h rijndael.h kex.h mac.h crypto_api.h dh.h packet.h dispatch.h auth-options.h sshpty.h channels.h session.h sshlogin.h canohost.h log.h ssherr.h misc.h servconf.h monitor.h monitor_wrap.h monitor_fdpass.h compat.h ssh2.h authfd.h match.h sk-api.h
+monitor.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h ./openbsd-compat/sys-tree.h openbsd-compat/sys-queue.h openbsd-compat/openssl-compat.h atomicio.h xmalloc.h ssh.h sshkey.h sshbuf.h hostfile.h auth.h auth-pam.h audit.h loginrec.h cipher.h cipher-chachapoly.h
+monitor_fdpass.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h log.h ssherr.h monitor_fdpass.h
+monitor_wrap.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h openbsd-compat/sys-queue.h xmalloc.h ssh.h sshbuf.h sshkey.h cipher.h cipher-chachapoly.h chacha.h poly1305.h cipher-aesctr.h rijndael.h kex.h mac.h crypto_api.h hostfile.h auth.h auth-pam.h audit.h
+monitor_wrap.o: loginrec.h auth-options.h packet.h dispatch.h log.h ssherr.h monitor.h monitor_wrap.h atomicio.h monitor_fdpass.h misc.h channels.h session.h servconf.h
+msg.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h sshbuf.h ssherr.h log.h atomicio.h msg.h misc.h
+mux.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h openbsd-compat/sys-queue.h xmalloc.h log.h ssherr.h ssh.h ssh2.h pathnames.h misc.h match.h sshbuf.h channels.h msg.h packet.h dispatch.h monitor_fdpass.h sshpty.h sshkey.h readconf.h clientloop.h
+nchan.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h openbsd-compat/sys-queue.h ssh2.h sshbuf.h ssherr.h packet.h dispatch.h channels.h compat.h log.h
+packet.o: channels.h ssh.h packet.h dispatch.h sshbuf.h
+packet.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h openbsd-compat/sys-queue.h xmalloc.h compat.h ssh2.h cipher.h cipher-chachapoly.h chacha.h poly1305.h cipher-aesctr.h rijndael.h sshkey.h kex.h mac.h crypto_api.h digest.h log.h ssherr.h canohost.h misc.h
+platform-misc.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h
+platform-pledge.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h
+platform-tracing.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h log.h ssherr.h
+platform.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h log.h ssherr.h misc.h servconf.h openbsd-compat/sys-queue.h sshkey.h hostfile.h auth.h auth-pam.h audit.h loginrec.h
+poly1305.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h poly1305.h
+progressmeter.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h progressmeter.h atomicio.h misc.h utf8.h
+readconf.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h openbsd-compat/glob.h xmalloc.h ssh.h ssherr.h compat.h cipher.h cipher-chachapoly.h chacha.h poly1305.h cipher-aesctr.h rijndael.h pathnames.h log.h sshkey.h misc.h readconf.h match.h kex.h mac.h crypto_api.h
+readconf.o: uidswap.h myproposal.h digest.h
+readpass.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h xmalloc.h misc.h pathnames.h log.h ssherr.h ssh.h uidswap.h
+rijndael.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h rijndael.h
+sandbox-capsicum.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h
+sandbox-darwin.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h
+sandbox-null.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h
+sandbox-pledge.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h
+sandbox-rlimit.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h
+sandbox-seccomp-filter.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h
+sandbox-solaris.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h
+sandbox-systrace.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h
+sc25519.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h sc25519.h crypto_api.h
+scp.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h openbsd-compat/glob.h xmalloc.h ssh.h atomicio.h pathnames.h log.h ssherr.h misc.h progressmeter.h utf8.h sftp-common.h sftp-client.h
+servconf.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h openbsd-compat/glob.h openbsd-compat/sys-queue.h xmalloc.h ssh.h log.h ssherr.h sshbuf.h misc.h servconf.h compat.h pathnames.h cipher.h cipher-chachapoly.h chacha.h poly1305.h cipher-aesctr.h rijndael.h sshkey.h
+servconf.o: kex.h mac.h crypto_api.h match.h channels.h groupaccess.h canohost.h packet.h dispatch.h hostfile.h auth.h auth-pam.h audit.h loginrec.h myproposal.h digest.h
+serverloop.o: cipher-aesctr.h rijndael.h kex.h mac.h crypto_api.h hostfile.h auth.h auth-pam.h audit.h loginrec.h session.h auth-options.h serverloop.h
+serverloop.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h openbsd-compat/sys-queue.h xmalloc.h packet.h dispatch.h sshbuf.h log.h ssherr.h misc.h servconf.h canohost.h sshpty.h channels.h compat.h ssh2.h sshkey.h cipher.h cipher-chachapoly.h chacha.h poly1305.h
+session.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h openbsd-compat/sys-queue.h xmalloc.h ssh.h ssh2.h sshpty.h packet.h dispatch.h sshbuf.h ssherr.h match.h uidswap.h compat.h channels.h sshkey.h cipher.h cipher-chachapoly.h chacha.h poly1305.h cipher-aesctr.h
+session.o: rijndael.h hostfile.h auth.h auth-pam.h audit.h loginrec.h auth-options.h authfd.h pathnames.h log.h misc.h servconf.h sshlogin.h serverloop.h canohost.h session.h kex.h mac.h crypto_api.h monitor_wrap.h sftp.h atomicio.h
+sftp-client.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h openbsd-compat/sys-queue.h xmalloc.h ssherr.h sshbuf.h log.h atomicio.h progressmeter.h misc.h utf8.h sftp.h sftp-common.h sftp-client.h openbsd-compat/glob.h
+sftp-common.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h xmalloc.h ssherr.h sshbuf.h log.h misc.h sftp.h sftp-common.h
+sftp-glob.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h xmalloc.h sftp.h sftp-common.h sftp-client.h openbsd-compat/glob.h
+sftp-realpath.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h
+sftp-server-main.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h log.h ssherr.h sftp.h misc.h xmalloc.h
+sftp-server.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h xmalloc.h sshbuf.h ssherr.h log.h misc.h match.h uidswap.h sftp.h sftp-common.h
+sftp.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h xmalloc.h log.h ssherr.h pathnames.h misc.h utf8.h sftp.h sshbuf.h sftp-common.h sftp-client.h openbsd-compat/glob.h
+sk-usbhid.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h
+sntrup761.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h
+srclimit.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h addr.h canohost.h log.h ssherr.h misc.h srclimit.h xmalloc.h
+ssh-add.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h xmalloc.h ssh.h log.h ssherr.h sshkey.h sshbuf.h authfd.h authfile.h pathnames.h misc.h digest.h ssh-sk.h sk-api.h
+ssh-agent.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h openbsd-compat/sys-queue.h xmalloc.h ssh.h ssh2.h sshbuf.h sshkey.h authfd.h compat.h log.h ssherr.h misc.h digest.h match.h msg.h pathnames.h ssh-pkcs11.h sk-api.h
+ssh-dss.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h
+ssh-ecdsa-sk.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h openbsd-compat/openssl-compat.h sshbuf.h ssherr.h digest.h sshkey.h
+ssh-ecdsa.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h
+ssh-ed25519-sk.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h crypto_api.h log.h ssherr.h sshbuf.h sshkey.h ssh.h digest.h
+ssh-ed25519.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h crypto_api.h log.h ssherr.h sshbuf.h sshkey.h ssh.h
+ssh-keygen.o: cipher-chachapoly.h chacha.h poly1305.h cipher-aesctr.h rijndael.h
+ssh-keygen.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h xmalloc.h sshkey.h authfile.h sshbuf.h pathnames.h log.h ssherr.h misc.h match.h hostfile.h dns.h ssh.h ssh2.h ssh-pkcs11.h atomicio.h krl.h digest.h utf8.h authfd.h sshsig.h ssh-sk.h sk-api.h cipher.h
+ssh-keyscan.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h openbsd-compat/sys-queue.h xmalloc.h ssh.h sshbuf.h sshkey.h cipher.h cipher-chachapoly.h chacha.h poly1305.h cipher-aesctr.h rijndael.h kex.h mac.h crypto_api.h compat.h myproposal.h packet.h dispatch.h log.h
+ssh-keyscan.o: ssherr.h atomicio.h misc.h hostfile.h ssh_api.h ssh2.h dns.h
+ssh-keysign.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h xmalloc.h log.h ssherr.h sshkey.h ssh.h ssh2.h misc.h sshbuf.h authfile.h msg.h canohost.h pathnames.h readconf.h uidswap.h
+ssh-pkcs11-client.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h
+ssh-pkcs11-helper.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h openbsd-compat/sys-queue.h xmalloc.h sshbuf.h log.h ssherr.h misc.h sshkey.h authfd.h ssh-pkcs11.h
+ssh-pkcs11.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h log.h ssherr.h sshkey.h
+ssh-rsa.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h
+ssh-sk-client.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h log.h ssherr.h sshbuf.h sshkey.h msg.h digest.h pathnames.h ssh-sk.h misc.h
+ssh-sk-helper.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h xmalloc.h log.h ssherr.h sshkey.h authfd.h misc.h sshbuf.h msg.h uidswap.h ssh-sk.h
+ssh-sk.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h
+ssh-xmss.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h
+ssh.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h openbsd-compat/openssl-compat.h openbsd-compat/sys-queue.h xmalloc.h ssh.h ssh2.h canohost.h compat.h cipher.h cipher-chachapoly.h chacha.h poly1305.h cipher-aesctr.h rijndael.h packet.h dispatch.h sshbuf.h channels.h
+ssh.o: sshkey.h authfd.h authfile.h pathnames.h clientloop.h log.h ssherr.h misc.h readconf.h sshconnect.h kex.h mac.h crypto_api.h sshpty.h match.h msg.h version.h myproposal.h utf8.h
+ssh_api.o: authfile.h misc.h version.h myproposal.h sshbuf.h openbsd-compat/openssl-compat.h
+ssh_api.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h ssh_api.h openbsd-compat/sys-queue.h cipher.h cipher-chachapoly.h chacha.h poly1305.h cipher-aesctr.h rijndael.h sshkey.h kex.h mac.h crypto_api.h ssh.h ssh2.h packet.h dispatch.h compat.h log.h ssherr.h
+sshbuf-getput-basic.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h ssherr.h sshbuf.h
+sshbuf-getput-crypto.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h
+sshbuf-io.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h ssherr.h sshbuf.h atomicio.h
+sshbuf-misc.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h ssherr.h sshbuf.h
+sshbuf.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h ssherr.h sshbuf.h misc.h
+sshconnect.o: authfd.h kex.h mac.h crypto_api.h
+sshconnect.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h xmalloc.h hostfile.h ssh.h sshbuf.h packet.h openbsd-compat/sys-queue.h dispatch.h compat.h sshkey.h sshconnect.h log.h ssherr.h misc.h readconf.h atomicio.h dns.h monitor_fdpass.h ssh2.h version.h authfile.h
+sshconnect2.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h openbsd-compat/sys-queue.h xmalloc.h ssh.h ssh2.h sshbuf.h packet.h dispatch.h compat.h cipher.h cipher-chachapoly.h chacha.h poly1305.h cipher-aesctr.h rijndael.h sshkey.h kex.h mac.h crypto_api.h
+sshconnect2.o: myproposal.h sshconnect.h authfile.h dh.h authfd.h log.h ssherr.h misc.h readconf.h match.h canohost.h msg.h pathnames.h uidswap.h hostfile.h utf8.h ssh-sk.h sk-api.h
+sshd.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h ./openbsd-compat/sys-tree.h openbsd-compat/sys-queue.h xmalloc.h ssh.h ssh2.h sshpty.h packet.h dispatch.h log.h ssherr.h sshbuf.h misc.h match.h servconf.h uidswap.h compat.h cipher.h cipher-chachapoly.h chacha.h
+sshd.o: poly1305.h cipher-aesctr.h rijndael.h digest.h sshkey.h kex.h mac.h crypto_api.h myproposal.h authfile.h pathnames.h atomicio.h canohost.h hostfile.h auth.h auth-pam.h audit.h loginrec.h authfd.h msg.h channels.h session.h monitor.h monitor_wrap.h ssh-sandbox.h auth-options.h version.h sk-api.h srclimit.h dh.h
ssherr.o: ssherr.h
-sshkey-xmss.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/rmd160.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/getopt.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h
-sshkey.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/rmd160.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/getopt.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h crypto_api.h ssh2.h ssherr.h misc.h sshbuf.h cipher.h cipher-chachapoly.h chacha.h poly1305.h cipher-aesctr.h rijndael.h digest.h sshkey.h sshkey-xmss.h match.h xmss_fast.h openbsd-compat/openssl-compat.h
-sshlogin.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/rmd160.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/getopt.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h sshlogin.h ssherr.h loginrec.h log.h sshbuf.h misc.h servconf.h
-sshpty.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/rmd160.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/getopt.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h sshpty.h log.h misc.h
-sshtty.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/rmd160.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/getopt.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h sshpty.h
-ttymodes.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/rmd160.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/getopt.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h packet.h openbsd-compat/sys-queue.h dispatch.h opacket.h log.h compat.h sshbuf.h ssherr.h ttymodes.h
-uidswap.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/rmd160.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/getopt.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h log.h uidswap.h xmalloc.h
-umac.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/rmd160.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/getopt.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h xmalloc.h umac.h misc.h rijndael.h
-umac128.o: umac.c includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/rmd160.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/getopt.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h xmalloc.h umac.h misc.h rijndael.h
-utf8.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/rmd160.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/getopt.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h utf8.h
-uuencode.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/rmd160.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/getopt.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h xmalloc.h uuencode.h
-verify.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/rmd160.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/getopt.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h crypto_api.h
-xmalloc.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/rmd160.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/getopt.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h xmalloc.h log.h
-xmss_commons.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/rmd160.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/getopt.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h
-xmss_fast.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/rmd160.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/getopt.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h
-xmss_hash.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/rmd160.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/getopt.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h
-xmss_hash_address.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/rmd160.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/getopt.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h
-xmss_wots.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/rmd160.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/getopt.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h
+sshkey-xmss.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h
+sshkey.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h crypto_api.h ssh2.h ssherr.h misc.h sshbuf.h cipher.h cipher-chachapoly.h chacha.h poly1305.h cipher-aesctr.h rijndael.h digest.h sshkey.h match.h ssh-sk.h openbsd-compat/openssl-compat.h
+sshlogin.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h sshlogin.h ssherr.h loginrec.h log.h sshbuf.h misc.h servconf.h openbsd-compat/sys-queue.h
+sshpty.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h sshpty.h log.h ssherr.h misc.h
+sshsig.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h authfd.h authfile.h log.h ssherr.h misc.h sshbuf.h sshsig.h sshkey.h match.h digest.h
+sshtty.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h sshpty.h
+ttymodes.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h packet.h openbsd-compat/sys-queue.h dispatch.h log.h ssherr.h compat.h sshbuf.h ttymodes.h
+uidswap.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h log.h ssherr.h uidswap.h xmalloc.h
+umac.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h xmalloc.h umac.h misc.h rijndael.h
+umac128.o: umac.c includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h xmalloc.h umac.h misc.h rijndael.h
+utf8.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h utf8.h
+verify.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h crypto_api.h
+xmalloc.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h xmalloc.h log.h ssherr.h
+xmss_commons.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h
+xmss_fast.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h
+xmss_hash.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h
+xmss_hash_address.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h
+xmss_wots.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h
diff --git a/crypto/openssh/.github/ci-status.md b/crypto/openssh/.github/ci-status.md
new file mode 100644
index 000000000000..0ad8bf5aaf44
--- /dev/null
+++ b/crypto/openssh/.github/ci-status.md
@@ -0,0 +1,4 @@
+[![C/C++ CI](https://github.com/openssh/openssh-portable/actions/workflows/c-cpp.yml/badge.svg)](https://github.com/openssh/openssh-portable/actions/workflows/c-cpp.yml)
+[![C/C++ CI self-hosted](https://github.com/openssh/openssh-portable-selfhosted/actions/workflows/selfhosted.yml/badge.svg)](https://github.com/openssh/openssh-portable-selfhosted/actions/workflows/selfhosted.yml)
+[![Upstream self-hosted](https://github.com/openssh/openssh-portable-selfhosted/actions/workflows/upstream.yml/badge.svg)](https://github.com/openssh/openssh-portable-selfhosted/actions/workflows/upstream.yml)
+[![Fuzzing Status](https://oss-fuzz-build-logs.storage.googleapis.com/badges/openssh.svg)](https://bugs.chromium.org/p/oss-fuzz/issues/list?sort=-opened&can=1&q=proj:openssh)
diff --git a/crypto/openssh/.github/configs b/crypto/openssh/.github/configs
new file mode 100755
index 000000000000..12578c067348
--- /dev/null
+++ b/crypto/openssh/.github/configs
@@ -0,0 +1,170 @@
+#!/bin/sh
+#
+# usage: configs vmname test_config (or '' for default)
+#
+# Sets the following variables:
+# CONFIGFLAGS options to ./configure
+# SSHD_CONFOPTS sshd_config options
+# TEST_TARGET make target used when testing. defaults to "tests".
+# LTESTS
+
+config=$1
+
+TEST_TARGET="tests"
+LTESTS=""
+SKIP_LTESTS=""
+SUDO=sudo # run with sudo by default
+TEST_SSH_UNSAFE_PERMISSIONS=1
+
+CONFIGFLAGS=""
+LIBCRYPTOFLAGS=""
+
+case "$config" in
+ default|sol64)
+ ;;
+ c89)
+ CC="gcc"
+ CFLAGS="-Wall -std=c89 -pedantic -Werror=vla"
+ CONFIGFLAGS="--without-openssl --without-zlib"
+ TEST_TARGET=t-exec
+ ;;
+ kitchensink)
+ CONFIGFLAGS="--with-kerberos5 --with-libedit --with-pam"
+ CONFIGFLAGS="${CONFIGFLAGS} --with-security-key-builtin --with-selinux"
+ CONFIGFLAGS="${CONFIGFLAGS} --with-cflags=-DSK_DEBUG"
+ ;;
+ hardenedmalloc)
+ CONFIGFLAGS="--with-ldflags=-lhardened_malloc"
+ ;;
+ kerberos5)
+ CONFIGFLAGS="--with-kerberos5"
+ ;;
+ libedit)
+ CONFIGFLAGS="--with-libedit"
+ ;;
+ pam-krb5)
+ CONFIGFLAGS="--with-pam --with-kerberos5"
+ SSHD_CONFOPTS="UsePam yes"
+ ;;
+ *pam)
+ CONFIGFLAGS="--with-pam"
+ SSHD_CONFOPTS="UsePam yes"
+ ;;
+ libressl-*)
+ LIBCRYPTOFLAGS="--with-ssl-dir=/opt/libressl --with-rpath=-Wl,-rpath,"
+ ;;
+ openssl-*)
+ LIBCRYPTOFLAGS="--with-ssl-dir=/opt/openssl --with-rpath=-Wl,-rpath,"
+ ;;
+ selinux)
+ CONFIGFLAGS="--with-selinux"
+ ;;
+ sk)
+ CONFIGFLAGS="--with-security-key-builtin"
+ ;;
+ without-openssl)
+ LIBCRYPTOFLAGS="--without-openssl"
+ TEST_TARGET=t-exec
+ ;;
+ valgrind-[1-4]|valgrind-unit)
+ # rlimit sandbox and FORTIFY_SOURCE confuse Valgrind.
+ CONFIGFLAGS="--without-sandbox --without-hardening"
+ CONFIGFLAGS="$CONFIGFLAGS --with-cppflags=-D_FORTIFY_SOURCE=0"
+ TEST_TARGET="t-exec USE_VALGRIND=1"
+ TEST_SSH_ELAPSED_TIMES=1
+ export TEST_SSH_ELAPSED_TIMES
+ # Valgrind slows things down enough that the agent timeout test
+ # won't reliably pass, and the unit tests run longer than allowed
+ # by github so split into three separate tests.
+ tests2="rekey integrity"
+ tests3="krl forward-control sshsig"
+ tests4="cert-userkey cert-hostkey kextype sftp-perm keygen-comment"
+ case "$config" in
+ valgrind-1)
+ # All tests except agent-timeout (which is flaky under valgrind)
+ #) and slow ones that run separately to increase parallelism.
+ SKIP_LTESTS="agent-timeout ${tests2} ${tests3} ${tests4}"
+ ;;
+ valgrind-2)
+ LTESTS="${tests2}"
+ ;;
+ valgrind-3)
+ LTESTS="${tests3}"
+ ;;
+ valgrind-4)
+ LTESTS="${tests4}"
+ ;;
+ valgrind-unit)
+ TEST_TARGET="unit USE_VALGRIND=1"
+ ;;
+ esac
+ ;;
+ *)
+ echo "Unknown configuration $config"
+ exit 1
+ ;;
+esac
+
+# The Solaris 64bit targets are special since they need a non-flag arg.
+case "$config" in
+ sol64*)
+ CONFIGFLAGS="x86_64 --with-cflags=-m64 --with-ldflags=-m64 ${CONFIGFLAGS}"
+ LIBCRYPTOFLAGS="--with-ssl-dir=/usr/local/ssl64"
+ ;;
+esac
+
+case "${TARGET_HOST}" in
+ dfly58*|dfly60*)
+ # scp 3-way connection hangs on these so skip until sorted.
+ SKIP_LTESTS=scp3
+ ;;
+ hurd)
+ SKIP_LTESTS="forwarding multiplex proxy-connect hostkey-agent agent-ptrace"
+ ;;
+ minix3)
+ CC="clang"
+ LIBCRYPTOFLAGS="--without-openssl"
+ # Minix does not have a loopback interface so we have to skip any
+ # test that relies on it.
+ TEST_TARGET=t-exec
+ SKIP_LTESTS="addrmatch cfgparse key-options reexec agent connect"
+ SKIP_LTESTS="$SKIP_LTESTS keyscan rekey allow-deny-users connect-uri"
+ SKIP_LTESTS="$SKIP_LTESTS knownhosts-command sftp-uri brokenkeys"
+ SKIP_LTESTS="$SKIP_LTESTS exit-status login-timeout stderr-data"
+ SKIP_LTESTS="$SKIP_LTESTS cfgmatch forward-control multiplex transfer"
+ SKIP_LTESTS="$SKIP_LTESTS cfgmatchlisten forwarding reconfigure"
+ SUDO=""
+ ;;
+ nbsd4)
+ # System compiler will ICE on some files with fstack-protector
+ CONFIGFLAGS="${CONFIGFLAGS} --without-hardening"
+ ;;
+ sol10|sol11)
+ # sol10 VM is 32bit and the unit tests are slow.
+ # sol11 has 4 test configs so skip unit tests to speed up.
+ TEST_TARGET="tests SKIP_UNIT=1"
+ ;;
+ win10)
+ # No sudo on Windows.
+ SUDO=""
+ ;;
+esac
+
+# If we have a local openssl/libressl, use that.
+if [ -z "${LIBCRYPTOFLAGS}" ]; then
+ # last-match
+ for i in /usr/local /usr/local/ssl /usr/local/opt/openssl; do
+ if [ -x ${i}/bin/openssl ]; then
+ LIBCRYPTOFLAGS="--with-ssl-dir=${i}"
+ fi
+ done
+fi
+
+CONFIGFLAGS="${CONFIGFLAGS} ${LIBCRYPTOFLAGS}"
+
+if [ -x "$(which plink 2>/dev/null)" ]; then
+ REGRESS_INTEROP_PUTTY=yes
+ export REGRESS_INTEROP_PUTTY
+fi
+
+export CC CFLAGS LTESTS SUDO TEST_TARGET TEST_SSH_UNSAFE_PERMISSIONS
diff --git a/crypto/openssh/.github/configure.sh b/crypto/openssh/.github/configure.sh
new file mode 100755
index 000000000000..e098730f02d6
--- /dev/null
+++ b/crypto/openssh/.github/configure.sh
@@ -0,0 +1,6 @@
+#!/bin/sh
+
+. .github/configs $1
+
+set -x
+./configure ${CONFIGFLAGS}
diff --git a/crypto/openssh/.github/run_test.sh b/crypto/openssh/.github/run_test.sh
new file mode 100755
index 000000000000..adf2568ad1e2
--- /dev/null
+++ b/crypto/openssh/.github/run_test.sh
@@ -0,0 +1,34 @@
+#!/bin/sh
+
+. .github/configs $1
+
+[ -z "${SUDO}" ] || ${SUDO} mkdir -p /var/empty
+
+set -ex
+
+output_failed_logs() {
+ for i in regress/failed*; do
+ if [ -f "$i" ]; then
+ echo -------------------------------------------------------------------------
+ echo LOGFILE $i
+ cat $i
+ echo -------------------------------------------------------------------------
+ fi
+ done
+}
+trap output_failed_logs 0
+
+if [ -z "${LTESTS}" ]; then
+ make ${TEST_TARGET} SKIP_LTESTS="${SKIP_LTESTS}"
+else
+ make ${TEST_TARGET} SKIP_LTESTS="${SKIP_LTESTS}" LTESTS="${LTESTS}"
+fi
+
+if [ ! -z "${SSHD_CONFOPTS}" ]; then
+ echo "rerunning t-exec with TEST_SSH_SSHD_CONFOPTS='${SSHD_CONFOPTS}'"
+ if [ -z "${LTESTS}" ]; then
+ make t-exec SKIP_LTESTS="${SKIP_LTESTS}" TEST_SSH_SSHD_CONFOPTS="${SSHD_CONFOPTS}"
+ else
+ make t-exec SKIP_LTESTS="${SKIP_LTESTS}" LTESTS="${LTESTS}" TEST_SSH_SSHD_CONFOPTS="${SSHD_CONFOPTS}"
+ fi
+fi
diff --git a/crypto/openssh/.github/setup_ci.sh b/crypto/openssh/.github/setup_ci.sh
new file mode 100755
index 000000000000..70a444e4eff4
--- /dev/null
+++ b/crypto/openssh/.github/setup_ci.sh
@@ -0,0 +1,115 @@
+#!/bin/sh
+
+case $(./config.guess) in
+*-darwin*)
+ brew install automake
+ exit 0
+ ;;
+esac
+
+TARGETS=$@
+
+PACKAGES=""
+INSTALL_FIDO_PPA="no"
+
+#echo "Setting up for '$TARGETS'"
+
+set -ex
+
+lsb_release -a
+
+if [ "${TARGETS}" = "kitchensink" ]; then
+ TARGETS="kerberos5 libedit pam sk selinux"
+fi
+
+for TARGET in $TARGETS; do
+ case $TARGET in
+ default|without-openssl|without-zlib|c89)
+ # nothing to do
+ ;;
+ kerberos5)
+ PACKAGES="$PACKAGES heimdal-dev"
+ #PACKAGES="$PACKAGES libkrb5-dev"
+ ;;
+ libedit)
+ PACKAGES="$PACKAGES libedit-dev"
+ ;;
+ *pam)
+ PACKAGES="$PACKAGES libpam0g-dev"
+ ;;
+ sk)
+ INSTALL_FIDO_PPA="yes"
+ PACKAGES="$PACKAGES libfido2-dev libu2f-host-dev libcbor-dev"
+ ;;
+ selinux)
+ PACKAGES="$PACKAGES libselinux1-dev selinux-policy-dev"
+ ;;
+ hardenedmalloc)
+ INSTALL_HARDENED_MALLOC=yes
+ ;;
+ openssl-noec)
+ INSTALL_OPENSSL=OpenSSL_1_1_1k
+ SSLCONFOPTS="no-ec"
+ ;;
+ openssl-*)
+ INSTALL_OPENSSL=$(echo ${TARGET} | cut -f2 -d-)
+ case ${INSTALL_OPENSSL} in
+ 1.*) INSTALL_OPENSSL="OpenSSL_$(echo ${INSTALL_OPENSSL} | tr . _)" ;;
+ 3.*) INSTALL_OPENSSL="openssl-${INSTALL_OPENSSL}" ;;
+ esac
+ PACKAGES="${PACKAGES} putty-tools"
+ ;;
+ libressl-*)
+ INSTALL_LIBRESSL=$(echo ${TARGET} | cut -f2 -d-)
+ case ${INSTALL_LIBRESSL} in
+ master) ;;
+ *) INSTALL_LIBRESSL="v$(echo ${TARGET} | cut -f2 -d-)" ;;
+ esac
+ PACKAGES="${PACKAGES} putty-tools"
+ ;;
+ valgrind*)
+ PACKAGES="$PACKAGES valgrind"
+ ;;
+ *) echo "Invalid option '${TARGET}'"
+ exit 1
+ ;;
+ esac
+done
+
+if [ "yes" = "$INSTALL_FIDO_PPA" ]; then
+ sudo apt update -qq
+ sudo apt install software-properties-common
+ sudo apt-add-repository ppa:yubico/stable
+fi
+
+if [ "x" != "x$PACKAGES" ]; then
+ sudo apt update -qq
+ sudo apt install -qy $PACKAGES
+fi
+
+if [ "${INSTALL_HARDENED_MALLOC}" = "yes" ]; then
+ (cd ${HOME} &&
+ git clone https://github.com/GrapheneOS/hardened_malloc.git &&
+ cd ${HOME}/hardened_malloc &&
+ make -j2 && sudo cp libhardened_malloc.so /usr/lib/)
+fi
+
+if [ ! -z "${INSTALL_OPENSSL}" ]; then
+ (cd ${HOME} &&
+ git clone https://github.com/openssl/openssl.git &&
+ cd ${HOME}/openssl &&
+ git checkout ${INSTALL_OPENSSL} &&
+ ./config no-threads shared ${SSLCONFOPTS} \
+ --prefix=/opt/openssl &&
+ make && sudo make install_sw)
+fi
+
+if [ ! -z "${INSTALL_LIBRESSL}" ]; then
+ (mkdir -p ${HOME}/libressl && cd ${HOME}/libressl &&
+ git clone https://github.com/libressl-portable/portable.git &&
+ cd ${HOME}/libressl/portable &&
+ git checkout ${INSTALL_LIBRESSL} &&
+ sh update.sh && sh autogen.sh &&
+ ./configure --prefix=/opt/libressl &&
+ make -j2 && sudo make install)
+fi
diff --git a/crypto/openssh/.github/workflows/c-cpp.yml b/crypto/openssh/.github/workflows/c-cpp.yml
new file mode 100644
index 000000000000..289b18b7f621
--- /dev/null
+++ b/crypto/openssh/.github/workflows/c-cpp.yml
@@ -0,0 +1,76 @@
+name: C/C++ CI
+
+on:
+ push:
+ branches: [ master, ci ]
+ pull_request:
+ branches: [ master ]
+
+jobs:
+ ci:
+ if: github.repository != 'openssh/openssh-portable-selfhosted'
+ strategy:
+ fail-fast: false
+ matrix:
+ # First we test all OSes in the default configuration.
+ os: [ubuntu-20.04, ubuntu-18.04, macos-10.15, macos-11.0]
+ configs: [default]
+ # Then we include any extra configs we want to test for specific VMs.
+ # Valgrind slows things down quite a bit, so start them first.
+ include:
+ - { os: ubuntu-20.04, configs: valgrind-1 }
+ - { os: ubuntu-20.04, configs: valgrind-2 }
+ - { os: ubuntu-20.04, configs: valgrind-3 }
+ - { os: ubuntu-20.04, configs: valgrind-4 }
+ - { os: ubuntu-20.04, configs: valgrind-unit }
+ - { os: ubuntu-20.04, configs: c89 }
+ - { os: ubuntu-20.04, configs: pam }
+ - { os: ubuntu-20.04, configs: kitchensink }
+ - { os: ubuntu-20.04, configs: hardenedmalloc }
+ - { os: ubuntu-latest, configs: libressl-master }
+ - { os: ubuntu-latest, configs: libressl-2.2.9 }
+ - { os: ubuntu-latest, configs: libressl-2.8.3 }
+ - { os: ubuntu-latest, configs: libressl-3.0.2 }
+ - { os: ubuntu-latest, configs: libressl-3.2.5 }
+ - { os: ubuntu-latest, configs: openssl-master }
+ - { os: ubuntu-latest, configs: openssl-noec }
+ - { os: ubuntu-latest, configs: openssl-1.0.1 }
+ - { os: ubuntu-latest, configs: openssl-1.0.1u }
+ - { os: ubuntu-latest, configs: openssl-1.0.2u }
+ - { os: ubuntu-latest, configs: openssl-1.1.0h }
+ - { os: ubuntu-latest, configs: openssl-1.1.1 }
+ - { os: ubuntu-latest, configs: openssl-1.1.1k }
+ - { os: ubuntu-18.04, configs: pam }
+ - { os: ubuntu-18.04, configs: kerberos5 }
+ - { os: ubuntu-18.04, configs: libedit }
+ - { os: ubuntu-18.04, configs: sk }
+ - { os: ubuntu-18.04, configs: selinux }
+ - { os: ubuntu-18.04, configs: kitchensink }
+ - { os: ubuntu-18.04, configs: without-openssl }
+ - { os: macos-10.15, configs: pam }
+ - { os: macos-11.0, configs: pam }
+ runs-on: ${{ matrix.os }}
+ steps:
+ - uses: actions/checkout@v2
+ - name: setup CI system
+ run: ./.github/setup_ci.sh ${{ matrix.configs }}
+ - name: autoreconf
+ run: autoreconf
+ - name: configure
+ run: ./.github/configure.sh ${{ matrix.configs }}
+ - name: make
+ run: make -j2
+ - name: make tests
+ run: ./.github/run_test.sh ${{ matrix.configs }}
+ env:
+ TEST_SSH_UNSAFE_PERMISSIONS: 1
+ - name: save logs
+ if: failure()
+ uses: actions/upload-artifact@v2
+ with:
+ name: ${{ matrix.os }}-${{ matrix.configs }}-logs
+ path: |
+ config.h
+ config.log
+ regress/*.log
+ regress/valgrind-out/
diff --git a/crypto/openssh/.github/workflows/selfhosted.yml b/crypto/openssh/.github/workflows/selfhosted.yml
new file mode 100644
index 000000000000..df6eca714fb5
--- /dev/null
+++ b/crypto/openssh/.github/workflows/selfhosted.yml
@@ -0,0 +1,93 @@
+name: C/C++ CI self-hosted
+
+on:
+ push:
+ branches: [ master, ci ]
+
+jobs:
+ selfhosted:
+ if: github.repository == 'openssh/openssh-portable-selfhosted'
+ runs-on: ${{ matrix.os }}
+ env:
+ TARGET_HOST: ${{ matrix.os }}
+ strategy:
+ fail-fast: false
+ # We use a matrix in two parts: firstly all of the VMs are tested with the
+ # default config. "os" corresponds to a label associated with the worker.
+ matrix:
+ os:
+ - ARM64
+ - bbone
+ - dfly30
+ - dfly48
+ - dfly58
+ - dfly60
+ - fbsd6
+ - fbsd10
+ - fbsd12
+ - fbsd13
+ - hurd
+ - minix3
+ # - nbsd2
+ - nbsd3
+ - nbsd4
+ - nbsd8
+ - nbsd9
+ - obsd51
+ - obsd67
+ - obsd68
+ - obsd69
+ - obsdsnap
+ - openindiana
+ # - rocky84
+ - sol10
+ - sol11
+ - win10
+ configs:
+ - default
+ # Then we include any extra configs we want to test for specific VMs.
+ include:
+ - { os: ARM64, configs: pam }
+ - { os: dfly30, configs: without-openssl}
+ - { os: dfly48, configs: pam }
+ - { os: dfly58, configs: pam }
+ - { os: dfly60, configs: pam }
+ - { os: fbsd6, configs: pam }
+ - { os: fbsd10, configs: pam }
+ - { os: fbsd12, configs: pam }
+ - { os: fbsd13, configs: pam }
+ - { os: nbsd8, configs: pam }
+ - { os: nbsd9, configs: pam }
+ - { os: openindiana, configs: pam }
+ # - { os: rocky84, configs: pam }
+ - { os: sol10, configs: pam }
+ - { os: sol11, configs: pam-krb5 }
+ - { os: sol11, configs: sol64 }
+ # - { os: sol11, configs: sol64-pam }
+ steps:
+ - uses: actions/checkout@v2
+ - name: autoreconf
+ run: autoreconf
+ - name: shutdown VM if running
+ run: vmshutdown
+ - name: startup VM
+ run: vmstartup
+ - name: configure
+ run: vmrun ./.github/configure.sh ${{ matrix.configs }}
+ - name: make
+ run: vmrun make
+ - name: make tests
+ run: vmrun ./.github/run_test.sh ${{ matrix.configs }}
+ - name: save logs
+ if: failure()
+ uses: actions/upload-artifact@v2
+ with:
+ name: ${{ matrix.os }}-${{ matrix.configs }}-logs
+ path: |
+ config.h
+ config.log
+ regress/*.log
+ regress/valgrind-out/
+ - name: shutdown VM
+ if: always()
+ run: vmshutdown
diff --git a/crypto/openssh/.github/workflows/upstream.yml b/crypto/openssh/.github/workflows/upstream.yml
new file mode 100644
index 000000000000..f0493c12d7d5
--- /dev/null
+++ b/crypto/openssh/.github/workflows/upstream.yml
@@ -0,0 +1,43 @@
+name: Upstream self-hosted
+
+on:
+ push:
+ branches: [ master, ci ]
+
+jobs:
+ selfhosted:
+ if: github.repository == 'openssh/openssh-portable-selfhosted'
+ runs-on: ${{ matrix.os }}
+ env:
+ TARGET_HOST: ${{ matrix.os }}
+ strategy:
+ fail-fast: false
+ matrix:
+ os: [ obsdsnap, obsdsnap-i386, obsd69, obsd68 ]
+ configs: [ default, without-openssl ]
+ steps:
+ - uses: actions/checkout@v2
+ - name: shutdown VM if running
+ run: vmshutdown
+ - name: startup VM
+ run: vmstartup
+ - name: update source
+ run: vmrun "cd /usr/src && cvs up -dPA usr.bin/ssh regress/usr.bin/ssh"
+ - name: make clean
+ run: vmrun "cd /usr/src/usr.bin/ssh && make obj && make clean"
+ - name: make
+ run: vmrun "cd /usr/src/usr.bin/ssh && if test '${{ matrix.configs }}' = 'without-openssl'; then make OPENSSL=no; else make; fi"
+ - name: make install
+ run: vmrun "cd /usr/src/usr.bin/ssh && sudo make install"
+ - name: make tests
+ run: vmrun "cd /usr/src/regress/usr.bin/ssh && make obj && make clean && if test '${{ matrix.configs }}' = 'without-openssl'; then make SUDO=sudo OPENSSL=no; else make SUDO=sudo; fi"
+ - name: save logs
+ if: failure()
+ uses: actions/upload-artifact@v2
+ with:
+ name: ${{ matrix.os }}-${{ matrix.configs }}-logs
+ path: |
+ /usr/obj/regress/usr.bin/ssh/*.log
+ - name: shutdown VM
+ if: always()
+ run: vmshutdown
diff --git a/crypto/openssh/.gitignore b/crypto/openssh/.gitignore
index 650eb3c3c90c..5e4ae5a60d06 100644
--- a/crypto/openssh/.gitignore
+++ b/crypto/openssh/.gitignore
@@ -2,8 +2,11 @@ Makefile
buildpkg.sh
config.h
config.h.in
+config.h.in~
+config.log
config.status
configure
+aclocal.m4
openbsd-compat/Makefile
openbsd-compat/regress/Makefile
openssh.xml
@@ -11,6 +14,8 @@ opensshd.init
survey.sh
**/*.0
**/*.o
+**/*.lo
+**/*.so
**/*.out
**/*.a
autom4te.cache/
@@ -24,5 +29,8 @@ ssh-keygen
ssh-keyscan
ssh-keysign
ssh-pkcs11-helper
+ssh-sk-helper
sshd
!regress/misc/fuzz-harness/Makefile
+!regress/unittests/sshsig/Makefile
+tags
diff --git a/crypto/openssh/.skipped-commit-ids b/crypto/openssh/.skipped-commit-ids
index f1b3b7640a3f..1de78172232a 100644
--- a/crypto/openssh/.skipped-commit-ids
+++ b/crypto/openssh/.skipped-commit-ids
@@ -5,6 +5,24 @@ fa728823ba21c4b45212750e1d3a4b2086fd1a62 more Makefile refactoring
1de0e85522051eb2ffa00437e1885e9d7b3e0c2e moduli update
814b2f670df75759e1581ecef530980b2b3d7e0f remove redundant make defs
04431e8e7872f49a2129bf080a6b73c19d576d40 moduli update
+c07772f58028fda683ee6abd41c73da3ff70d403 moduli update
+db6375fc302e3bdf07d96430c63c991b2c2bd3ff moduli update
+5ea3d63ab972691f43e9087ab5fd8376d48e898f uuencode.c Makefile accident
+99dd10e72c04e93849981d43d64c946619efa474 include sshbuf-misc.c
+9e1c23476bb845f3cf3d15d9032da3ed0cb2fcf5 sshbuf-misc.c in regress
+569f08445c27124ec7c7f6c0268d844ec56ac061 Makefile tweaks for !openssl
+58ec755be4e51978ecfee73539090eb68652a987 moduli update
+4bd5551b306df55379afe17d841207990eb773bf Makefile.inc
+14806a59353152f843eb349e618abbf6f4dd3ada Makefile.inc
+8ea4455a2d9364a0a04f9e4a2cbfa4c9fcefe77e Makefile.inc
+d9b910e412d139141b072a905e66714870c38ac0 Makefile.inc
+7b7b619c1452a459310b0cf4391c5757c6bdbc0f moduli update
+5010ff08f7ad92082e87dde098b20f5c24921a8f moduli regen script update
+3bcae7a754db3fc5ad3cab63dd46774edb35b8ae moduli regen script update
+52ff0e3205036147b2499889353ac082e505ea54 moduli update
+07b5031e9f49f2b69ac5e85b8da4fc9e393992a0 Makefile.inc
+cc12a9029833d222043aecd252d654965c351a69 moduli-gen Makefile
+7ac6c252d2a5be8fbad4c66d9d35db507c9dac5b moduli update
Old upstream tree:
diff --git a/crypto/openssh/CREDITS b/crypto/openssh/CREDITS
index 43be5e5f26d5..6cc3512515eb 100644
--- a/crypto/openssh/CREDITS
+++ b/crypto/openssh/CREDITS
@@ -33,7 +33,7 @@ David Agraz <dagraz@jahoopa.com> - Build fixes
David Del Piero <David.DelPiero@qed.qld.gov.au> - bug fixes
David Hesprich <darkgrue@gue-tech.org> - Configure fixes
David Rankin <drankin@bohemians.lexington.ky.us> - libwrap, AIX, NetBSD fixes
-Dag-Erling Smørgrav <des at freebsd.org> - Challenge-Response PAM code.
+Dag-Erling Smørgrav <des at freebsd.org> - Challenge-Response PAM code.
Dhiraj Gulati <dgulati@sco.com> - UnixWare long passwords
Ed Eden <ede370@stl.rural.usda.gov> - configure fixes
Garrick James <garrick@james.net> - configure fixes
diff --git a/crypto/openssh/ChangeLog b/crypto/openssh/ChangeLog
index 0307f62e0557..288e90bbfe51 100644
--- a/crypto/openssh/ChangeLog
+++ b/crypto/openssh/ChangeLog
@@ -1,9706 +1,13703 @@
-commit aede1c34243a6f7feae2fb2cb686ade5f9be6f3d
+commit e1a596186c81e65a34ce13076449712d3bf97eb4
Author: Damien Miller <djm@mindrot.org>
-Date: Wed Oct 17 11:01:20 2018 +1100
+Date: Fri Aug 20 14:03:49 2021 +1000
- Require OpenSSL 1.1.x series 1.1.0g or greater
+ depend
+
+commit 5450606c8f7f7a0d70211cea78bc2dab74ab35d1
+Author: Damien Miller <djm@mindrot.org>
+Date: Fri Aug 20 13:59:43 2021 +1000
+
+ update version numbers
+
+commit feee2384ab8d694c770b7750cfa76a512bdf8246
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Fri Aug 20 03:22:55 2021 +0000
+
+ upstream: openssh-8.7
- Previous versions have a bug with EVP_CipherInit() when passed a
- NULL EVP_CIPHER, per https://github.com/openssl/openssl/pull/4613
+ OpenBSD-Commit-ID: 8769dff0fd76ae3193d77bf83b439adee0f300cd
+
+commit 9a2ed62173cc551b2b5f479460bb015b19499de8
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Fri Aug 20 10:48:13 2021 +1000
+
+ Also check pid in pselect_notify_setup.
- ok dtucker@
+ Spotted by djm@.
-commit 08300c211409c212e010fe2e2f2883e573a04ce2
-Author: Damien Miller <djm@mindrot.org>
-Date: Wed Oct 17 08:12:02 2018 +1100
+commit deaadcb93ca15d4f38aa38fb340156077792ce87
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Fri Aug 20 08:39:33 2021 +1000
+
+ Prefix pselect functions to clarify debug messages
+
+commit 10e45654cff221ca60fd35ee069df67208fcf415
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Fri Aug 20 08:30:42 2021 +1000
- unbreak compilation with --with-ssl-engine
+ Fix race in pselect replacement code.
+
+ On the second and subsequent calls to pselect the notify_pipe was not
+ added to the select readset, opening up a race that om G. Christensen
+ discovered on multiprocessor Solaris <=9 systems.
- Missing last argument to OPENSSL_init_crypto()
+ Also reinitialize notify_pipe if the pid changes. This will prevent a
+ parent and child from using the same FD, although this is not an issue
+ in the current structure it might be in future.
-commit 1673274aee67ce0eb6f00578b6f3d2bcbd58f937
+commit 464ba22f1e38d25402e5ec79a9b8d34a32df5a3f
Author: Darren Tucker <dtucker@dtucker.net>
-Date: Tue Oct 16 14:45:57 2018 +1100
+Date: Wed Aug 18 12:51:30 2021 +1000
- Remove gcc spectre mitigation flags.
+ Check compiler for c99 declarations after code.
- Current impementions of the gcc spectre mitigation flags cause
- miscompilations when combined with other flags and do not provide much
- protection. Found by fweimer at redhat.com, ok djm@
+ The sntrup761 reference code contains c99-style declarations after code
+ so don't try to build that if the compiler doesn't support it.
-commit 4e23deefd7959ef83c73ed9cce574423438f6133
-Author: Damien Miller <djm@mindrot.org>
-Date: Tue Oct 16 10:51:52 2018 +1100
+commit 7d878679a4b155a359d32104ff473f789501748d
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Tue Aug 17 15:12:04 2021 +1000
- Avoid deprecated OPENSSL_config when using 1.1.x
+ Remove trailing backslash on regress-unit-binaries
+
+commit b71b2508f17c68c5d9dbbe537686d81cedb9a781
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Tue Aug 17 07:59:27 2021 +1000
+
+ Put stdint.h inside HAVE_STDINT_H.
- OpenSSL 1.1.x soft-deprecated OPENSSL_config in favour of
- OPENSSL_init_crypto; pointed out by Jakub Jelen
+ From Tom G. Christensen.
-commit 797cdd9c8468ed1125ce60d590ae3f1397866af4
+commit 6a24567a29bd7b4ab64e1afad859ea845cbc6b8c
Author: Darren Tucker <dtucker@dtucker.net>
-Date: Fri Oct 12 16:58:47 2018 +1100
+Date: Mon Aug 16 14:13:02 2021 +1000
- Don't avoid our *sprintf replacements.
+ Improve github test driver script.
- Don't let systems with broken printf(3) avoid our replacements
- via asprintf(3)/vasprintf(3) calling libc internally. From djm@
+ - use a trap to always output any failed regress logs (since the script
+ sets -e, the existing log output is never invoked).
+ - pass LTESTS and SKIP_LTESTS when re-running with sshd options (eg.
+ UsePAM).
-commit e526127cbd2f8ad88fb41229df0c9b850c722830
+commit b467cf13705f59ed348b620722ac098fe31879b7
Author: Darren Tucker <dtucker@dtucker.net>
-Date: Fri Oct 12 16:43:35 2018 +1100
+Date: Mon Aug 16 11:32:23 2021 +1000
- Check if snprintf understands %zu.
+ Remove deprecated ubuntu-16.04 test targets.
- If the platforms snprintf and friends don't understand %zu, use the
- compat replacement. Prevents segfaults on those platforms.
+ Github has deprecated ubuntu-16.04 and it will be removed on 20
+ September.
-commit cf39f875191708c5f2f1a3c1c9019f106e74aea3
-Author: Damien Miller <djm@mindrot.org>
-Date: Fri Oct 12 09:48:05 2018 +1100
+commit 20e6eefcdf78394f05e453d456c1212ffaa6b6a4
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Sun Aug 15 23:25:26 2021 +1000
- remove stale link, tweak
+ Skip agent ptrace test on hurd.
-commit a7205e68decf7de2005810853b4ce6b222b65e2a
-Author: Damien Miller <djm@mindrot.org>
-Date: Fri Oct 12 09:47:20 2018 +1100
+commit 7c9115bbbf958fbf85259a061c1122e2d046aabf
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Sun Aug 15 19:37:22 2021 +1000
+
+ Add hurd test target.
+
+commit 7909a566f6c6a78fcd30708dc49f4e4f9bb80ce3
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Sun Aug 15 12:45:10 2021 +1000
+
+ Skip scp3 tests on all dfly58 and 60 configs.
- update version numbers ahead of release
+commit e65198e52cb03534e8c846d1bca74c310b1526de
+Author: Tim Rice <tim@multitalents.net>
+Date: Sat Aug 14 13:08:07 2021 -0700
+
+ openbsd-compat/openbsd-compat.h: put bsd-signal.h before bsd-misc.h
+ to get sigset_t from signal.h needed for the pselect replacement.
+
+commit e50635640f79920d9375e0155cb3f4adb870eee5
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Fri Aug 13 13:21:00 2021 +1000
-commit 1a4a9cf80f5b92b9d1dadd0bfa8867c04d195391
+ Test OpenSSH from OpenBSD head on 6.8 and 6.9.
+
+commit e0ba38861c490c680117b7fe0a1d61a181cd00e7
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Fri Aug 13 13:00:14 2021 +1000
+
+ Skip scp3 test on dragonfly 58 and 60.
+
+ The tests hang, so skip until we figure them out.
+
+commit dcce2a2bcf007bf817a2fb0dce3db83fa9201e92
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Thu Oct 11 03:48:04 2018 +0000
+Date: Thu Aug 12 23:59:25 2021 +0000
- upstream: don't send new-style rsa-sha2-*-cert-v01@openssh.com names to
+ upstream: mention that CASignatureAlgorithms accepts +/- similarly to
- older OpenSSH that can't handle them. spotted by Adam Eijdenberg; ok dtucker
+ the other algorithm list directives; ok jmc bz#3335
- OpenBSD-Commit-ID: 662bbc402e3d7c9b6c322806269698106a6ae631
+ OpenBSD-Commit-ID: 0d46b53995817052c78e2dce9dbd133963b073d9
-commit dc8ddcdf1a95e011c263486c25869bb5bf4e30ec
-Author: Damien Miller <djm@mindrot.org>
-Date: Thu Oct 11 13:08:59 2018 +1100
+commit 090a82486e5d7a8f7f16613d67e66a673a40367f
+Author: schwarze@openbsd.org <schwarze@openbsd.org>
+Date: Thu Aug 12 09:59:00 2021 +0000
+
+ upstream: In the editline(3) branch of the sftp(1) event loop,
+
+ handle SIGINT rather than ignoring it, such that the user can use Ctrl-C to
+ discard the currently edited command line and get a fresh prompt, just like
+ in ftp(1), bc(1), and in shells.
+
+ It is critical to not use ssl_signal() for this particular case
+ because that function unconditionally sets SA_RESTART, but here we
+ need the signal to interrupt the read(2) in the el_gets(3) event loop.
+
+ OK dtucker@ deraadt@
+
+ OpenBSD-Commit-ID: 8025115a773f52e9bb562eaab37ea2e021cc7299
- update depends
+commit e1371e4f58404d6411d9f95eb774b444cea06a26
+Author: naddy@openbsd.org <naddy@openbsd.org>
+Date: Wed Aug 11 14:07:54 2021 +0000
-commit 26841ac265603fd2253e6832e03602823dbb4022
-Author: Damien Miller <djm@mindrot.org>
-Date: Thu Oct 11 13:02:11 2018 +1100
+ upstream: scp: tweak man page and error message for -3 by default
+
+ Now that the -3 option is enabled by default, flip the documentation
+ and error message logic from "requires -3" to "blocked by -R".
+
+ ok djm@
+
+ OpenBSD-Commit-ID: a872592118444fb3acda5267b2a8c3d4c4252020
- some more duplicated key algorithm lines
+commit 49f46f6d77328a3d10a758522b670a3e8c2235e7
+Author: naddy@openbsd.org <naddy@openbsd.org>
+Date: Wed Aug 11 14:05:19 2021 +0000
+
+ upstream: scp: do not spawn ssh with two -s flags for
+
+ remote-to-remote copies
- From Adam Eijdenberg
+ Do not add another "-s" to the argument vector every time an SFTP
+ connection is initiated. Instead, introduce a subsystem flag to
+ do_cmd() and add "-s" when the flag is set.
+
+ ok djm@
+
+ OpenBSD-Commit-ID: 25df69759f323661d31b2e1e790faa22e27966c1
-commit 5d9d17603bfbb620195a4581025052832b4c4adc
-Author: Damien Miller <djm@mindrot.org>
-Date: Thu Oct 11 11:56:36 2018 +1100
+commit 2a2cd00783e1da45ee730b7f453408af1358ef5b
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Wed Aug 11 08:55:04 2021 +0000
- fix duplicated algorithm specification lines
+ upstream: test -Oprint-pubkey
- Spotted by Adam Eijdenberg
+ OpenBSD-Regress-ID: 3d51afb6d1f287975fb6fddd7a2c00a3bc5094e0
-commit ebfafd9c7a5b2a7fb515ee95dbe0e44e11d0a663
+commit b9f4635ea5bc33ed5ebbacf332d79bae463b0f54
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Thu Oct 11 00:52:46 2018 +0000
+Date: Wed Aug 11 08:54:17 2021 +0000
- upstream: typo in plain RSA algorithm counterpart names for
+ upstream: when verifying sshsig signatures, support an option
- certificates; spotted by Adam Eijdenberg; ok dtucker@
+ (-Oprint-pubkey) to dump the full public key to stdout; based on patch from
+ Fabian Stelzer; ok markus@
- OpenBSD-Commit-ID: bfcdeb6f4fc9e7607f5096574c8f118f2e709e00
+ OpenBSD-Commit-ID: 0598000e5b9adfb45d42afa76ff80daaa12fc3e2
-commit c29b111e7d87c2324ff71c80653dd8da168c13b9
-Author: Damien Miller <djm@mindrot.org>
-Date: Thu Oct 11 11:29:35 2018 +1100
+commit 750c1a45ba4e8ad63793d49418a0780e77947b9b
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Wed Aug 11 05:21:32 2021 +0000
+
+ upstream: oops, missed one more %p
+
+ OpenBSD-Commit-ID: e7e62818d1564cc5cd9086eaf7a51cbd1a9701eb
- check pw_passwd != NULL here too
+commit b5aa27b69ab2e1c13ac2b5ad3f8f7d389bad7489
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Wed Aug 11 05:20:17 2021 +0000
+
+ upstream: remove a bunch of %p in format strings; leftovers of
- Again, for systems with broken NIS implementations.
+ debuggings past. prompted by Michael Forney, ok dtucker@
- Prompted by coolbugcheckers AT gmail.com
+ OpenBSD-Commit-ID: 4853a0d6c9cecaba9ecfcc19066e52d3a8dcb2ac
-commit fe8e8f349a553ef4c567acd418aac769a82b7729
-Author: Damien Miller <djm@mindrot.org>
-Date: Thu Oct 11 11:03:15 2018 +1100
+commit 419aa01123db5ff5dbc68b2376ef23b222862338
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Wed Aug 11 09:21:09 2021 +1000
- check for NULL return from shadow_pw()
+ Add includes.h to compat tests.
- probably unreachable on this platform; pointed out by
- coolbugcheckers AT gmail.com
+ On platforms where closefrom returns void (eg glibc>=2.34) the prototype
+ for closefrom in its compat tests would cause compile errors. Remove
+ this and have the tests pull in the compat headers in the same way as
+ the main code. bz#3336.
-commit acc59cbe7a1fb169e1c3caba65a39bd74d6e030d
-Author: deraadt@openbsd.org <deraadt@openbsd.org>
-Date: Wed Oct 10 16:43:49 2018 +0000
+commit 931f592f26239154eea3eb35a086585897b1a185
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Tue Aug 10 03:35:45 2021 +0000
- upstream: introducing openssh 7.9
+ upstream: adapt to scp -M flag change; make scp3.sh test SFTP mode too
- OpenBSD-Commit-ID: 42d526a9fe01a40dd299ac58014d3349adf40e25
+ OpenBSD-Regress-ID: 43fea26704a0f0b962b53c1fabcb68179638f9c0
-commit 12731158c75c8760a8bea06350eeb3e763fe1a07
-Author: Damien Miller <djm@mindrot.org>
-Date: Thu Oct 11 10:29:29 2018 +1100
+commit 391ca67fb978252c48d20c910553f803f988bd37
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Tue Aug 10 03:33:34 2021 +0000
- supply callback to PEM_read_bio_PrivateKey
+ upstream: Prepare for a future where scp(1) uses the SFTP protocol by
- OpenSSL 1.1.0i has changed the behaviour of their PEM APIs,
- so that empty passphrases are interpreted differently. This
- probabalistically breaks loading some keys, because the PEM format
- is terrible and doesn't include a proper MAC.
+ default. Replace recently added -M option to select the protocol with -O
+ (olde) and -s (SFTP) flags, and label the -s flag with a clear warning that
+ it will be removed in the near future (so no, don't use it in scripts!).
- Avoid this by providing a basic callback to avoid passing empty
- passphrases to OpenSSL in cases where one is required.
+ prompted by/feedback from deraadt@
- Based on patch from Jakub Jelen in bz#2913; ok dtucker@
+ OpenBSD-Commit-ID: 92ad72cc6f0023c9be9e316d8b30eb6d8d749cfc
-commit d1d301a1dd5d6cc3a9ed93ab7ab09dda4cb456e0
-Author: Damien Miller <djm@mindrot.org>
-Date: Wed Oct 10 14:57:00 2018 +1100
+commit bfdd4b722f124a4fa9173d20dd64dd0fc69856be
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Mon Aug 9 23:56:36 2021 +0000
- in pick_salt() avoid dereference of NULL passwords
+ upstream: make scp -3 the default for remote-to-remote copies. It
+
+ provides a much better and more intuitive user experience and doesn't require
+ exposing credentials to the source host.
- Apparently some NIS implementations can leave pw->pw_passwd (or the
- shadow equivalent) NULL.
+ thanks naddy@ for catching the missing argument in usage()
- bz#2909; based on patch from Todd Eigenschink
+ "Yes please!" - markus@
+ "makes a lot of sense" - deraadt@
+ "the right thing to do" - dtucker@
+
+ OpenBSD-Commit-ID: d0d2af5f0965c5192ba5b2fa461c9f9b130e5dd9
-commit edbb6febccee084d212fdc0cb05b40cb1c646ab1
+commit 2f7a3b51cef689ad9e93d0c6c17db5a194eb5555
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Tue Oct 9 05:42:23 2018 +0000
+Date: Mon Aug 9 23:49:31 2021 +0000
- upstream: Treat all PEM_read_bio_PrivateKey() errors when a passphrase
+ upstream: make scp in SFTP mode try to use relative paths as much
+
+ as possible. Previosuly, it would try to make relative and ~/-rooted paths
+ absolute before requesting transfers.
- is specified as "incorrect passphrase" instead of trying to choose between
- that and "invalid format".
+ prompted by and much discussion deraadt@
+ ok markus@
- libcrypto can return ASN1 parsing errors rather than the expected
- decrypt error in certain infrequent cases when trying to decrypt/parse
- PEM private keys when supplied with an invalid passphrase.
+ OpenBSD-Commit-ID: 46639d382ea99546a4914b545fa7b00fa1be5566
+
+commit 2ab864010e0a93c5dd95116fb5ceaf430e2fc23c
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Mon Aug 9 23:47:44 2021 +0000
+
+ upstream: SFTP protocol extension to allow the server to expand
- Report and repro recipe from Thomas Deutschmann in bz#2901
+ ~-prefixed paths, in particular ~user ones. Allows scp in sftp mode to accept
+ these paths, like scp in rcp mode does.
+ prompted by and much discussion deraadt@
ok markus@
- OpenBSD-Commit-ID: b1d4cd92395f9743f81c0d23aab2524109580870
+ OpenBSD-Commit-ID: 7d794def9e4de348e1e777f6030fc9bafdfff392
-commit 2581333d564d8697837729b3d07d45738eaf5a54
-Author: naddy@openbsd.org <naddy@openbsd.org>
-Date: Fri Oct 5 14:26:09 2018 +0000
+commit 41b019ac067f1d1f7d99914d0ffee4d2a547c3d8
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Mon Aug 9 23:44:32 2021 +0000
- upstream: Support using service names for port numbers.
+ upstream: when scp is in SFTP mode, try to deal better with ~
- * Try to resolve a port specification with getservbyname(3) if a
- numeric conversion fails.
- * Make the "Port" option in ssh_config handle its argument as a
- port rather than a plain integer.
+ prefixed paths. ~user paths aren't supported, but ~/ paths will be accepted
+ and prefixed with the SFTP server starting directory (more to come)
- ok dtucker@ deraadt@
+ prompted by and discussed with deraadt@
+ ok markus@
- OpenBSD-Commit-ID: e7f03633133205ab3dfbc67f9df7475fabae660d
+ OpenBSD-Commit-ID: 263a071f14555c045fd03132a8fb6cbd983df00d
-commit e0d6501e86734c48c8c503f81e1c0926e98c5c4c
+commit b4b3f3da6cdceb3fd168b5fab69d11fba73bd0ae
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Thu Oct 4 07:47:35 2018 +0000
+Date: Mon Aug 9 07:21:01 2021 +0000
- upstream: when the peer sends a channel-close message, make sure we
-
- close the local extended read fd (stderr) along with the regular read fd
- (stdout). Avoids weird stuck processed in multiplexing mode.
+ upstream: on fatal errors, make scp wait for ssh connection before
- Report and analysis by Nelson Elhage and Geoffrey Thomas in bz#2863
+ exiting avoids LogLevel=verbose (or greater) messages from ssh appearing
+ after scp has returned exited and control has returned to the shell; ok
+ markus@
- ok dtucker@ markus@
+ (this was originally committed as r1.223 along with unrelated stuff that
+ I rolled back in r1.224)
- OpenBSD-Commit-ID: a48a2467fe938de4de69d2e7193d5fa701f12ae9
+ OpenBSD-Commit-ID: 1261fd667ad918484889ed3d7aec074f3956a74b
-commit 6f1aabb128246f445e33b8844fad3de9cb1d18cb
+commit 2ae7771749e0b4cecb107f9d4860bec16c3f4245
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Thu Oct 4 01:04:52 2018 +0000
+Date: Mon Aug 9 07:19:12 2021 +0000
- upstream: factor out channel status formatting from
-
- channel_open_message() so we can use it in other debug messages
+ upstream: rever r1.223 - I accidentally committed unrelated changes
- OpenBSD-Commit-ID: 9c3903ca28fcabad57f566c9d0045b41ab7d52ba
+ OpenBSD-Commit-ID: fb73f3865b2647a27dd94db73d6589506a9625f9
-commit f1dd179e122bdfdb7ca3072d9603607740efda05
+commit 986abe94d481a1e82a01747360bd767b96b41eda
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Thu Oct 4 00:10:11 2018 +0000
+Date: Mon Aug 9 07:16:09 2021 +0000
- upstream: include a little more information about the status and
+ upstream: show only the final path component in the progress meter;
- disposition of channel's extended (stderr) fd; makes debugging some things a
- bit easier. No behaviour change.
+ more useful with long paths (that may truncate) and better matches
+ traditional scp behaviour; spotted by naddy@ ok deraadt@
- OpenBSD-Commit-ID: 483eb6467dc7d5dbca8eb109c453e7a43075f7ce
+ OpenBSD-Commit-ID: 26b544d0074f03ebb8a3ebce42317d8d7ee291a3
-commit 2d1428b11c8b6f616f070f2ecedce12328526944
+commit 2b67932bb3176dee4fd447af4368789e04a82b93
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Thu Oct 4 00:04:41 2018 +0000
+Date: Mon Aug 9 07:13:54 2021 +0000
- upstream: explicit_bzero here to be consistent with other kex*.c;
+ upstream: on fatal errors, make scp wait for ssh connection before
- report from coolbugcheckers AT gmail.com
+ exiting avoids LogLevel=verbose (or greater) messages from ssh appearing
+ after scp has returned exited and control has returned to the shell; ok
+ markus@
- OpenBSD-Commit-ID: a90f146c5b5f5b1408700395e394f70b440856cb
+ OpenBSD-Commit-ID: ef9dab5ef5ae54a6a4c3b15d380568e94263456c
-commit 5eff5b858e717e901e6af6596306a114de9f79f2
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Wed Oct 3 06:38:35 2018 +0000
+commit 724eb900ace30661d45db2ba01d0f924d95ecccb
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Sun Aug 8 08:49:09 2021 +0000
- upstream: Allow ssh_config IdentityAgent directive to accept
+ upstream: xstrdup environment variable used by ForwardAgent. bz#3328
- environment variable names as well as explicit paths. ok dtucker@
+ from goetze at dovetail.com, ok djm@ deraadt@
- OpenBSD-Commit-ID: 2f0996e103876c53d8c9dd51dcce9889d700767b
+ OpenBSD-Commit-ID: 760320dac1c3b26904284ba417a7d63fccc5e742
-commit a46ac4d86b25414d78b632e8173578b37e5f8a83
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Tue Oct 2 12:51:58 2018 +0000
+commit 86b4cb3a884846b358305aad17a6ef53045fa41f
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Sun Aug 8 08:27:28 2021 +0000
- upstream: mention INFO@openssh.com for sending SIGINFO
+ upstream: Although it's POSIX, not all shells used in Portable support
- OpenBSD-Commit-ID: 132471eeb0df658210afd27852fe65131b26e900
+ the implicit 'in "$@"' after 'for i'.
+
+ OpenBSD-Regress-ID: 3c9aec6bca4868f85d2742b6ba5223fce110bdbc
-commit ff3a411cae0b484274b7900ef52ff4dad3e12876
-Author: Damien Miller <djm@mindrot.org>
-Date: Tue Oct 2 22:49:40 2018 +1000
+commit f2ccf6c9f395923695f22345e626dfd691227aaf
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Sun Aug 8 17:39:56 2021 +1000
- only support SIGINFO on systems with SIGINFO
+ Move portable specific settings down.
+
+ This brings the top hunk of the file back in sync with OpenBSD
+ so patches to the CVS Id should apply instead of always being
+ rejected.
-commit cd98925c6405e972dc9f211afc7e75e838abe81c
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Tue Oct 2 12:40:07 2018 +0000
+commit 71b0eb997e220b0fc9331635af409ad84979f2af
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Sun Aug 8 07:27:52 2021 +0000
- upstream: Add server support for signalling sessions via the SSH
+ upstream: Move setting of USER further down the startup In portable
- channel/ session protocol. Signalling is only supported to sesssions that are
- not subsystems and were not started with a forced command.
+ we have to change this and having it in the same hunk as the CVS Id string
+ means applying changes fails every. single. time.
- Long requested in bz#1424
+ OpenBSD-Regress-ID: 87cd603eb6db58c9b430bf90adacb7f90864429b
+
+commit f0aca2706c710a0da1a4be705f825a807cd15400
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Sun Aug 8 06:38:33 2021 +0000
+
+ upstream: Drop -q in ssh-log-wrapper.sh to preserve logs.
+
+ scp and sftp like to add -q to the command line passed to ssh which
+ overrides the LogLevel we set in the config files and suppresses output
+ to the debug logs so drop any "-q" from the invoked ssh. In the one
+ case where we actually want to use -q in the banner test, call the ssh
+ binary directly bypassing the logging wrapper.
- Based on a patch from markus@ and reworked by dtucker@;
- ok markus@ dtucker@
+ OpenBSD-Regress-ID: e2c97d3c964bda33a751374c56f65cdb29755b75
+
+commit cf27810a649c5cfae60f8ce66eeb25caa53b13bc
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Sat Aug 7 01:57:08 2021 +0000
+
+ upstream: Fix prototype mismatch for do_cmd. ok djm@
- OpenBSD-Commit-ID: 4bea826f575862eaac569c4bedd1056a268be1c3
+ OpenBSD-Commit-ID: 1c1598bb5237a7ae0be99152f185e0071163714d
-commit dba50258333f2604a87848762af07ba2cc40407a
+commit 85de69f64665245786e28c81ab01fe18b0e2a149
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Wed Sep 26 07:32:44 2018 +0000
+Date: Sat Aug 7 01:55:01 2021 +0000
- upstream: remove big ugly TODO comment from start of file. Some of
+ upstream: sftp-client.c needs poll.h
- the mentioned tasks are obsolete and, of the remainder, most are already
- captured in PROTOCOL.mux where they better belong
+ remove unused variable
- OpenBSD-Commit-ID: 16d9d76dee42a5bb651c9d6740f7f0ef68aeb407
+ OpenBSD-Commit-ID: 233ac6c012cd23af62f237167a661db391055a16
+
+commit 397c4d72e50023af5fe3aee5cc2ad407a6eb1073
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Sat Aug 7 11:30:57 2021 +1000
+
+ Include poll.h and friends for struct pollfd.
-commit 92b61a38ee9b765f5049f03cd1143e13f3878905
+commit a9e2c533195f28627f205682482d9da384c4c52e
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Wed Sep 26 07:30:05 2018 +0000
+Date: Sat Aug 7 00:14:17 2021 +0000
- upstream: Document mux proxy mode; added by Markus in openssh-7.4
+ upstream: do_upload() used a near-identical structure for
- Also add a little bit of information about the overall packet format
+ tracking expected status replies from the server to what do_download() was
+ using.
- OpenBSD-Commit-ID: bdb6f6ea8580ef96792e270cae7857786ad84a95
+ Refactor it to use the same structure and factor out some common
+ code into helper functions.
+
+ OpenBSD-Commit-ID: 0c167df8ab6df4a5292c32421922b0cf379e9054
-commit 9d883a1ce4f89b175fd77405ff32674620703fb2
+commit 7b1cbcb7599d9f6a3bbad79d412604aa1203b5ee
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Wed Sep 26 01:48:57 2018 +0000
+Date: Sat Aug 7 00:12:09 2021 +0000
- upstream: s/process_mux_master/mux_master_process/ in mux master
+ upstream: make scp(1) in SFTP mode follow symlinks like
- function names,
+ traditional scp(1) ok markus@
- Gives better symmetry with the existing mux_client_*() names and makes
- it more obvious when a message comes from the master vs client (they
- are interleved in ControlMaster=auto mode).
+ OpenBSD-Commit-ID: 97255e55be37e8e26605e4ba1e69f9781765d231
+
+commit 133b44e500422df68c9c25c3b6de35c0263132f1
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Sat Aug 7 00:10:49 2021 +0000
+
+ upstream: fix incorrect directory permissions on scp -3
- no functional change beyond prefixing a could of log messages with
- __func__ where they were previously lacking.
+ transfers; ok markus@
- OpenBSD-Commit-ID: b01f7c3fdf92692e1713a822a89dc499333daf75
+ OpenBSD-Commit-ID: 64b2abaa5635a2be65ee2e77688ad9bcebf576c2
-commit c2fa53cd6462da82d3a851dc3a4a3f6b920337c8
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Sat Sep 22 14:41:24 2018 +1000
+commit 98b59244ca10e62ff67a420856770cb700164f59
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Sat Aug 7 00:09:57 2021 +0000
- Remove unused variable in _ssh_compat_fflush.
+ upstream: a bit more debugging of file attributes being
+
+ sent/received over the wire
+
+ OpenBSD-Commit-ID: f68c4e207b08ef95200a8b2de499d422808e089b
-commit d1b3540c21212624af907488960d703c7d987b42
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Thu Sep 20 18:08:43 2018 +1000
+commit c677e65365d6f460c084e41e0c4807bb8a9cf601
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Sat Aug 7 00:08:52 2021 +0000
- Import updated moduli.
+ upstream: make scp(1) in SFTP mode output better match original
+
+ scp(1) by suppressing "Retrieving [path]" lines that were emitted to support
+ the interactive sftp(1) client. ok markus@
+
+ OpenBSD-Commit-ID: 06be293df5f156a18f366079be2f33fa68001acc
-commit b5e412a8993ad17b9e1141c78408df15d3d987e1
+commit 48cd39b7a4e5e7c25101c6d1179f98fe544835cd
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Sep 21 12:46:22 2018 +0000
+Date: Sat Aug 7 00:07:18 2021 +0000
- upstream: Allow ssh_config ForwardX11Timeout=0 to disable the
+ upstream: factor out a structure duplicated between downloading
- timeout and allow X11 connections in untrusted mode indefinitely. ok dtucker@
+ and crossloading; ok markus@
- OpenBSD-Commit-ID: ea1ceed3f540b48e5803f933e59a03b20db10c69
+ OpenBSD-Commit-ID: 96eede24d520569232086a129febe342e4765d39
-commit cb24d9fcc901429d77211f274031653476864ec6
+commit 318c06bb04ee21a0cfa6b6022a201eacaa53f388
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Sep 21 12:23:17 2018 +0000
+Date: Sat Aug 7 00:06:30 2021 +0000
- upstream: when compiled with GSSAPI support, cache supported method
+ upstream: use sftp_client crossloading to implement scp -3
- OIDs by calling ssh_gssapi_prepare_supported_oids() regardless of whether
- GSSAPI authentication is enabled in the main config.
+ feedback/ok markus@
- This avoids sandbox violations for configurations that enable GSSAPI
- auth later, e.g.
+ OpenBSD-Commit-ID: 7db4c0086cfc12afc9cfb71d4c2fd3c7e9416ee9
+
+commit de7115b373ba0be3861c65de9b606a3e0e9d29a3
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Sat Aug 7 00:02:41 2021 +0000
+
+ upstream: support for "cross"-loading files/directories, i.e.
- Match user djm
- GSSAPIAuthentication yes
+ downloading from one SFTP server while simultaneously uploading to another.
- bz#2107; ok dtucker@
+ feedback & ok markus@
- OpenBSD-Commit-ID: a5dd42d87c74e27cfb712b15b0f97ab20e0afd1d
+ OpenBSD-Commit-ID: 3982878e29d8df0fa4ddc502f5ff6126ac714235
-commit bbc8af72ba68da014d4de6e21a85eb5123384226
+commit a50bd0367ff2063bbc70a387740a2aa6914de094
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Sep 21 12:20:12 2018 +0000
+Date: Sat Aug 7 00:01:29 2021 +0000
- upstream: In sshkey_in_file(), ignore keys that are considered for
-
- being too short (i.e. SSH_ERR_KEY_LENGTH). These keys will not be considered
- to be "in the file". This allows key revocation lists to contain short keys
- without the entire revocation list being considered invalid.
+ upstream: factor our SSH2_FXP_OPEN calls into their own function;
- bz#2897; ok dtucker
+ "looks fine" markus@
- OpenBSD-Commit-ID: d9f3d857d07194a42ad7e62889a74dc3f9d9924b
+ OpenBSD-Commit-ID: d3dea2153f08855c6d9dacc01973248944adeffb
-commit 383a33d160cefbfd1b40fef81f72eadbf9303a66
+commit e3c0ba05873cf3d3f7d19d595667a251026b2d84
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Sep 21 03:11:36 2018 +0000
+Date: Sat Aug 7 00:00:33 2021 +0000
- upstream: Treat connections with ProxyJump specified the same as ones
+ upstream: prepare for scp -3 implemented via sftp
- with a ProxyCommand set with regards to hostname canonicalisation (i.e. don't
- try to canonicalise the hostname unless CanonicalizeHostname is set to
- 'always').
+ OpenBSD-Commit-ID: 194aac0dd87cb175334b71c2a30623a5ad55bb44
+
+commit 395d8fbdb094497211e1461cf0e2f80af5617e0a
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Fri Aug 6 09:00:18 2021 +0000
+
+ upstream: Make diff invocation more portable.
- Patch from Sven Wegener via bz#2896
+ POSIX does not require diff to have -N, so compare in both directions
+ with just -r, which should catch missing files in either directory.
- OpenBSD-Commit-ID: 527ff501cf98bf65fb4b29ed0cb847dda10f4d37
+ OpenBSD-Regress-ID: 0e2ec8594556a6f369ed5a0a90c6806419b845f7
-commit 0cbed248ed81584129b67c348dbb801660f25a6a
+commit d247a73ce27b460138599648d9c637c6f2b77605
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Thu Sep 20 23:40:16 2018 +0000
+Date: Wed Aug 4 21:28:00 2021 +0000
- upstream: actually make CASignatureAlgorithms available as a config
+ upstream: regression test for scp -3
- option
-
- OpenBSD-Commit-ID: 93fa7ff58314ed7b1ab7744090a6a91232e6ae52
+ OpenBSD-Regress-ID: b44375d125c827754a1f722ec6b6b75b634de05d
-commit 62528870c0ec48cd86a37dd7320fb85886c3e6ee
+commit 35c8e41a6f6d8ad76f8d1cd81ac2ea23d0d993b2
Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Thu Sep 20 08:07:03 2018 +0000
+Date: Fri Aug 6 05:04:42 2021 +0000
- upstream: Import updated moduli.
+ upstream: Document "ProxyJump none". bz#3334.
- OpenBSD-Commit-ID: 04431e8e7872f49a2129bf080a6b73c19d576d40
+ OpenBSD-Commit-ID: f78cc6f55731f2cd35c3a41d5352ac1ee419eba7
-commit e6933a2ffa0659d57f3c7b7c457b2c62b2a84613
-Author: jmc@openbsd.org <jmc@openbsd.org>
-Date: Thu Sep 20 06:58:48 2018 +0000
+commit 911ec6411821bda535d09778df7503b92f0eafab
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Wed Aug 4 01:34:55 2021 +0000
- upstream: reorder CASignatureAlgorithms, and add them to the
+ upstream: Allow for different (but POSIX compliant) behaviour of
+
+ basename(3) and prevent a use-after-free in that case in the new sftp-compat
+ code.
+
+ POSIX allows basename(3) to either return a pointer to static storage
+ or modify the passed string and return a pointer to that. OpenBSD does
+ the former and works as is, but on other platforms "filename" points
+ into "tmp" which was just freed. This makes the freeing of tmp
+ consistent with the other variable in the loop.
- various -o lists; ok djm
+ Pinpointed by the -portable Valgrind regress test. ok djm@ deraadt@
- OpenBSD-Commit-ID: ecb88baecc3c54988b4d1654446ea033da359288
+ OpenBSD-Commit-ID: 750f3c19bd4440e4210e30dd5d7367386e833374
-commit aa083aa9624ea7b764d5a81c4c676719a1a3e42b
+commit 6df1fecb5d3e51f3a8027a74885c3a44f6cbfcbd
+Author: Damien Miller <djm@mindrot.org>
+Date: Wed Aug 4 11:05:11 2021 +1000
+
+ use openbsd-compat glob.h is required
+
+commit 9ebd1828881dfc9014a344587934a5ce7db6fa1b
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Tue Aug 3 21:03:23 2021 +1000
+
+ Missing space between macro arg and punctuation.
+
+ From jmc@
+
+commit 0fd3f62eddc7cf54dcc9053be6f58998f3eb926a
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Tue Aug 3 21:02:33 2021 +1000
+
+ Avoid lines >80 chars. From jmc@
+
+commit af5d8094d8b755e1daaf2e20ff1dc252800b4c9b
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Thu Sep 20 03:31:49 2018 +0000
+Date: Tue Aug 3 01:05:24 2021 +0000
- upstream: fix "ssh -Q sig" to show correct signature algorithm list
+ upstream: regression tests for scp SFTP protocol support; mostly by
- (it was erroneously showing certificate algorithms); prompted by markus@
+ Jakub Jelen in GHPR#194 ok markus
- OpenBSD-Commit-ID: 1cdee002f2f0c21456979deeb887fc889afb154d
+ OpenBSD-Regress-ID: 36f1458525bcb111741ec8547eaf58b13cddc715
-commit ecac7e1f7add6b28874959a11f2238d149dc2c07
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Thu Sep 20 03:30:44 2018 +0000
+commit e4673b7f67ae7740131a4ecea29a846593049a91
+Author: anton@openbsd.org <anton@openbsd.org>
+Date: Thu Jul 29 15:34:09 2021 +0000
- upstream: add CASignatureAlgorithms option for the client, allowing
+ upstream: Treat doas with arguments as a valid SUDO variable.
- it to specify which signature algorithms may be used by CAs when signing
- certificates. Useful if you want to ban RSA/SHA1; ok markus@
+ Allows one to specify SUDO="doas -n" which I do while running make regress.
- OpenBSD-Commit-ID: 9159e5e9f67504829bf53ff222057307a6e3230f
+ ok dtucker@
+
+ OpenBSD-Regress-ID: 4fe5814b5010dbf0885500d703bea06048d11005
-commit 86e5737c39153af134158f24d0cab5827cbd5852
+commit 197e29f1cca190d767c4b2b63a662f9a9e5da0b3
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Thu Sep 20 03:28:06 2018 +0000
+Date: Mon Aug 2 23:38:27 2021 +0000
- upstream: Add sshd_config CASignatureAlgorithms option to allow
+ upstream: support for using the SFTP protocol for file transfers in
- control over which signature algorithms a CA may use when signing
- certificates. In particular, this allows a sshd to ban certificates signed
- with RSA/SHA1.
+ scp, via a new "-M sftp" option. Marked as experimental for now.
- ok markus@
+ Some corner-cases exist, in particular there is no attempt to
+ provide bug-compatibility with scp's weird "double shell" quoting
+ rules.
+
+ Mostly by Jakub Jelen in GHPR#194 with some tweaks by me. ok markus@
+ Thanks jmc@ for improving the scp.1 bits.
- OpenBSD-Commit-ID: b05c86ef8b52b913ed48d54a9b9c1a7714d96bac
+ OpenBSD-Commit-ID: 6ce4c9157ff17b650ace571c9f7793d92874051c
-commit f80e68ea7d62e2dfafc12f1a60ab544ae4033a0f
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Wed Sep 19 02:03:02 2018 +0000
+commit dd533c7ab79d61a7796b77b64bd81b098e0d7f9f
+Author: jmc@openbsd.org <jmc@openbsd.org>
+Date: Fri Jul 30 14:28:13 2021 +0000
- upstream: Make "ssh-add -q" do what it says on the tin: silence
+ upstream: fix a formatting error and add some Xr; from debian at
- output from successful operations.
+ helgefjell de
- Based on patch from Thijs van Dijk; ok dtucker@ deraadt@
+ removed references to rlogin etc. as no longer relevant;
+ suggested by djm
- OpenBSD-Commit-ID: c4f754ecc055c10af166116ce7515104aa8522e1
+ ok djm dtucker
+
+ OpenBSD-Commit-ID: 3c431c303068d3aec5bb18573a0bd5e0cd77c5ae
-commit 5e532320e9e51de720d5f3cc2596e95d29f6e98f
-Author: millert@openbsd.org <millert@openbsd.org>
-Date: Mon Sep 17 15:40:14 2018 +0000
+commit c7cd347a8823819411222c1e10a0d26747d0fd5c
+Author: jmc@openbsd.org <jmc@openbsd.org>
+Date: Fri Jul 30 14:25:01 2021 +0000
- upstream: When choosing a prime from the moduli file, avoid
+ upstream: fix a formatting error and mark up known_hosts
+
+ consistently; issues reported by debian at helgefjell de
- re-using the linenum variable for something that is not a line number to
- avoid the confusion that resulted in the bug in rev. 1.64. This also lets us
- pass the actual linenum to parse_prime() so the error messages include the
- correct line number. OK markus@ some time ago.
+ ok djm dtucker
- OpenBSD-Commit-ID: 4d8e5d3e924d6e8eb70053e3defa23c151a00084
+ OpenBSD-Commit-ID: a1fd8d21dc77f507685443832df0c9700481b0ce
-commit cce8cbe0ed7d1ba3a575310e0b63c193326ae616
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Sat Sep 15 19:44:06 2018 +1000
+commit 4455aec2e4fc90f64ae4fc47e78ebc9c18721738
+Author: jmc@openbsd.org <jmc@openbsd.org>
+Date: Wed Jul 28 05:57:42 2021 +0000
- Fix openssl-1.1 fallout for --without-openssl.
+ upstream: no need to talk about version 2 with the -Q option, so
- ok djm@
+ rewrite the text to read better;
+
+ issue reported by debian at helgefjell de
+ ok djm dtucker
+
+ OpenBSD-Commit-ID: 59fe2e8219c37906740ad062e0fdaea487dbe9cf
-commit 149519b9f201dac755f3cba4789f4d76fecf0ee1
-Author: Damien Miller <djm@mindrot.org>
-Date: Sat Sep 15 19:37:48 2018 +1000
+commit bec429338e9b30d2c7668060e82608286a8a4777
+Author: jmc@openbsd.org <jmc@openbsd.org>
+Date: Tue Jul 27 14:28:46 2021 +0000
- add futex(2) syscall to seccomp sandbox
+ upstream: word fix; reported by debian at helgefjell de
- Apparently needed for some glibc/openssl combinations.
+ OpenBSD-Commit-ID: 0c6fd22142422a25343c5bd1a618f31618f41ece
+
+commit efad4deb5a1f1cf79ebefd63c6625059060bfbe1
+Author: jmc@openbsd.org <jmc@openbsd.org>
+Date: Tue Jul 27 14:14:25 2021 +0000
+
+ upstream: standardise the grammar in the options list; issue
+
+ reported by debian at helgefjell de
- Patch from Arkadiusz Miśkiewicz
+ ok dtucker djm
+
+ OpenBSD-Commit-ID: 7ac15575045d82f4b205a42cc7d5207fe4c3f8e6
-commit 4488ae1a6940af704c4dbf70f55bf2f756a16536
-Author: Damien Miller <djm@mindrot.org>
-Date: Sat Sep 15 19:36:55 2018 +1000
+commit 1e11fb24066f3fc259ee30db3dbb2a3127e05956
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Mon Aug 2 18:56:29 2021 +1000
- really add source for authopt_fuzz this time
+ Check for RLIMIT_NOFILE before trying to use it.
-commit 9201784b4a257c8345fbd740bcbdd70054885707
-Author: Damien Miller <djm@mindrot.org>
-Date: Sat Sep 15 19:35:40 2018 +1000
+commit 0f494236b49fb48c1ef33669f14822ca4f3ce2f4
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Tue Jul 27 17:45:34 2021 +1000
- remove accidentally checked-in authopt_fuzz binary
+ lastenv is only used in setenv.
+
+ Prevents an unused variable warning on platforms that have setenv but
+ not unsetenv.
-commit beb9e522dc7717df08179f9e59f36b361bfa14ab
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Sep 14 05:26:27 2018 +0000
+commit a1f78e08bdb3eaa88603ba3c6e01de7c8671e28a
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Mon Jul 26 12:45:30 2021 +1000
+
+ Move SUDO to "make test" command line.
+
+ Environment variables don't get passed by vmrun, so move to command
+ line.
+
+commit 02e624273b9c78a49a01239159b8c09b8409b1a0
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Sun Jul 25 23:26:36 2021 +1000
- upstream: second try, deals properly with missing and private-only
+ Set SUDO for tests and cleanup.
+
+commit 460ae5d93051bab70239ad823dd784822d58baad
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Sun Jul 25 22:37:55 2021 +1000
+
+ Pass OPENSSL=no to make tests too.
+
+commit b398f499c68d74ebe3298b73757cf3f36e14e0cb
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Sun Jul 25 12:27:37 2021 +0000
+
+ upstream: Skip unit and makefile-based key conversion tests when
- Use consistent format in debug log for keys readied, offered and
- received during public key authentication.
+ we're building with OPENSSL=no.
- This makes it a little easier to see what is going on, as each message
- now contains (where available) the key filename, its type and fingerprint,
- and whether the key is hosted in an agent or a token.
+ OpenBSD-Regress-ID: 20455ed9a977c93f846059d1fcb48e29e2c8d732
+
+commit 727ce36c8c5941bde99216d27109405907caae4f
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Sun Jul 25 12:13:03 2021 +0000
+
+ upstream: Replace OPENSSL as the variable that points to the
+
+ openssl binary with OPENSSL_BIN. This will allow us to use the OPENSSL
+ variable from mk.conf or the make(1) command line indicating if we're
+ building with our without OpenSSL, and ultimately get the regress tests
+ working in the OPENSSL=no configuration.
- OpenBSD-Commit-ID: f1c6a8e9cfc4e108c359db77f24f9a40e1e25ea7
+ OpenBSD-Regress-ID: 2d788fade3264d7803e5b54cae8875963f688c4e
-commit 6bc5a24ac867bfdc3ed615589d69ac640f51674b
-Author: Damien Miller <djm@mindrot.org>
-Date: Fri Sep 14 15:16:34 2018 +1000
+commit 55e17101a9075f6a63af724261c5744809dcb95c
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Sat Jul 24 02:57:28 2021 +0000
- fuzzer harness for authorized_keys option parsing
+ upstream: Skip RFC4716 format import and export tests when built
+
+ without OpenSSL.
+
+ OpenBSD-Regress-ID: d2c2d5d38c1acc2b88cc99cfe00a2eb8bb39dfa4
-commit 6c8b82fc6929b6a9a3f645151b6ec26c5507d9ef
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Sep 14 04:44:04 2018 +0000
+commit f5ccb5895d39cd627ad9e7b2c671d2587616100d
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Sat Jul 24 02:51:14 2021 +0000
- upstream: revert following; deals badly with agent keys
+ upstream: Don't omit ssh-keygen -y from usage when built without
+
+ OpenSSL. It is actually available, albeit only for ed25519 keys.
- revision 1.285
- date: 2018/09/14 04:17:12; author: djm; state: Exp; lines: +47 -26; commitid: lflGFcNb2X2HebaK;
- Use consistent format in debug log for keys readied, offered and
- received during public key authentication.
+ OpenBSD-Commit-ID: 7a254c33d0e6a55c30c6b016a8d298d3cb7a7674
+
+commit 819d57ac23469f1f03baa8feb38ddefbada90fdc
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Sat Jul 24 02:08:13 2021 +0000
+
+ upstream: Exclude key conversion options from usage when built
- This makes it a little easier to see what is going on, as each message
- now contains the key filename, its type and fingerprint, and whether
- the key is hosted in an agent or a token.
+ without OpenSSL since those are not available, similar to what we currently
+ do with the moduli screening options. We can also use this to skip the
+ conversion regression tests in this case.
- OpenBSD-Commit-ID: e496bd004e452d4b051f33ed9ae6a54ab918f56d
+ OpenBSD-Commit-ID: 3c82caa398cf99cd4518c23bba5a2fc66b16bafe
+
+commit b6673b1d2ee90b4690ee84f634efe40225423c38
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Sat Jul 24 13:02:51 2021 +1000
+
+ Test OpenBSD upstream with and without OpenSSL.
-commit 6da046f9c3374ce7e269ded15d8ff8bc45017301
+commit 9d38074b5453c1abbdf888e80828c278d3b886ac
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Sep 14 04:17:44 2018 +0000
+Date: Sat Jul 24 01:54:23 2021 +0000
- upstream: garbage-collect moribund ssh_new_private() API.
+ upstream: test for first-match-wins in authorized_keys environment=
- OpenBSD-Commit-ID: 7c05bf13b094093dfa01848a9306c82eb6e95f6c
+ options
+
+ OpenBSD-Regress-ID: 1517c90276fe84b5dc5821c59f88877fcc34c0e8
+
+commit 2b76f1dd19787e784711ea297ad8fc938b4484fd
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Fri Jul 23 05:53:02 2021 +0000
-commit 1f24ac5fc05252ceb1c1d0e8cab6a283b883c780
+ upstream: Simplify keygen-convert by using $SSH_KEYTYPES directly.
+
+ OpenBSD-Regress-ID: cdbe408ec3671ea9ee9b55651ee551370d2a4108
+
+commit 7d64a9fb587ba9592f027f7a2264226c713d6579
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Sep 14 04:17:12 2018 +0000
+Date: Sat Jul 24 01:55:19 2021 +0000
- upstream: Use consistent format in debug log for keys readied,
+ upstream: don't leak environment= variable when it is not the first
- offered and received during public key authentication.
+ match
- This makes it a little easier to see what is going on, as each message
- now contains the key filename, its type and fingerprint, and whether
- the key is hosted in an agent or a token.
+ OpenBSD-Commit-ID: 7fbdc3dfe0032deaf003fd937eeb4d434ee4efe0
+
+commit db2130e2340bf923e41c791aa9cd27b9e926042c
+Author: jmc@openbsd.org <jmc@openbsd.org>
+Date: Fri Jul 23 06:01:17 2021 +0000
+
+ upstream: punctuation;
- OpenBSD-Commit-ID: 2a01d59285a8a7e01185bb0a43316084b4f06a1f
+ OpenBSD-Commit-ID: 64be152e378c45975073ab1c07e0db7eddd15806
-commit 488c9325bb7233e975dbfbf89fa055edc3d3eddc
-Author: millert@openbsd.org <millert@openbsd.org>
-Date: Thu Sep 13 15:23:32 2018 +0000
+commit 03190d10980c6fc9124e988cb2df13101f266507
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Fri Jul 23 05:56:47 2021 +0000
- upstream: Fix warnings caused by user_from_uid() and group_from_gid()
+ upstream: mention in comment that read_passphrase(..., RP_ALLOW_STDIN)
+
+ will try to use askpass first. bz3314
- now returning const char *.
+ convert a couple of debug() -> debug_f() while here
- OpenBSD-Commit-ID: b5fe571ea77cfa7b9035062829ab05eb87d7cc6f
+ OpenBSD-Commit-ID: c7e812aebc28fcc5db06d4710e0f73613dee545c
-commit 0aa1f230846ebce698e52051a107f3127024a05a
-Author: Damien Miller <djm@mindrot.org>
-Date: Fri Sep 14 10:31:47 2018 +1000
+commit 1653ece6832b2b304d46866b262d5f69880a9ec7
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Fri Jul 23 05:07:16 2021 +0000
- allow SIGUSR1 as synonym for SIGINFO
+ upstream: Test conversion of ed25519 and ecdsa keys too.
- Lets users on those unfortunate operating systems that lack SIGINFO
- still be able to obtain progress information from unit tests :)
+ OpenBSD-Regress-ID: 3676d2d00e58e0d6d37f2878f108cc2b83bbe4bb
-commit d64e78526596f098096113fcf148216798c327ff
-Author: Damien Miller <djm@mindrot.org>
-Date: Thu Sep 13 19:05:48 2018 +1000
+commit 8b7af02dcf9d2b738787efd27da7ffda9859bed2
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Fri Jul 23 04:56:21 2021 +0000
- add compat header
+ upstream: Add test for exporting pubkey from a passphrase-protected
+
+ private key.
+
+ OpenBSD-Regress-ID: da99d93e7b235fbd5b5aaa01efc411225e6ba8ac
-commit a3fd8074e2e2f06602e25618721f9556c731312c
+commit 441095d4a3e5048fe3c87a6c5db5bc3383d767fb
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Thu Sep 13 09:03:20 2018 +0000
+Date: Fri Jul 23 03:54:55 2021 +0000
- upstream: missed a bit of openssl-1.0.x API in this unittest
+ upstream: regression test for time-limited signature keys
- OpenBSD-Regress-ID: a73a54d7f7381856a3f3a2d25947bee7a9a5dbc9
+ OpenBSD-Regress-ID: 2a6f3bd900dbee0a3c96f1ff23e032c93ab392bc
-commit 86e0a9f3d249d5580390daf58e015e68b01cef10
+commit 9e1882ef6489a7dd16b6d7794af96629cae61a53
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Thu Sep 13 05:06:51 2018 +0000
+Date: Fri Jul 23 05:24:02 2021 +0000
- upstream: use only openssl-1.1.x API here too
+ upstream: note successful authentication method in final "Authenticated
+
+ to ..." message and partial auth success messages (all at LogLevel=verbose)
+ ok dtucker@
- OpenBSD-Regress-ID: ae877064597c349954b1b443769723563cecbc8f
+ OpenBSD-Commit-ID: 06834b89ceb89f8f16c5321d368a66c08f441984
-commit 48f54b9d12c1c79fba333bc86d455d8f4cda8cfc
-Author: Damien Miller <djm@mindrot.org>
-Date: Thu Sep 13 12:13:50 2018 +1000
+commit a917e973a1b90b40ff1e950df083364b48fc6c78
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Fri Jul 23 04:04:52 2021 +0000
- adapt -portable to OpenSSL 1.1x API
+ upstream: Add a ForkAfterAuthentication ssh_config(5) counterpart
- Polyfill missing API with replacement functions extracted from LibreSSL
+ to the ssh(1) -f flag. Last part of GHPR231 from Volker Diels-Grabsch. ok
+ dtucker
+
+ OpenBSD-Commit-ID: b18aeda12efdebe2093d55263c90fe4ea0bce0d3
-commit 86112951d63d48839f035b5795be62635a463f99
-Author: Damien Miller <djm@mindrot.org>
-Date: Thu Sep 13 12:12:42 2018 +1000
+commit e0c5088f1c96a145eb6ea1dee438010da78f9ef5
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Fri Jul 23 04:00:59 2021 +0000
- forgot to stage these test files in commit d70d061
+ upstream: Add a StdinNull directive to ssh_config(5) that allows
+
+ the config file to do the same thing as -n does on the ssh(1) commandline.
+ Patch from Volker Diels-Grabsch via GHPR231; ok dtucker
+
+ OpenBSD-Commit-ID: 66ddf3f15c76796d4dcd22ff464aed1edd62468e
-commit 482d23bcacdd3664f21cc82a5135f66fc598275f
+commit e3957e21ffdc119d6d04c0b1686f8e2fe052f5ea
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Thu Sep 13 02:08:33 2018 +0000
+Date: Fri Jul 23 03:57:20 2021 +0000
- upstream: hold our collective noses and use the openssl-1.1.x API in
+ upstream: make authorized_keys environment="..." directives
+
+ first-match-wins and more strictly limit their maximum number; prompted by
+ OOM reported by OSS-fuzz (35470).
- OpenSSH; feedback and ok tb@ jsing@ markus@
+ feedback and ok dtucker@
- OpenBSD-Commit-ID: cacbcac87ce5da0d3ca7ef1b38a6f7fb349e4417
+ OpenBSD-Commit-ID: 01f63fc10dcd995e7aed9c378ad879161af83121
-commit d70d061828730a56636ab6f1f24fe4a8ccefcfc1
+commit d0bb1ce731762c55acb95817df4d5fab526c7ecd
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Wed Sep 12 01:36:45 2018 +0000
+Date: Fri Jul 23 03:37:52 2021 +0000
- upstream: Include certs with multiple RSA signature variants in
+ upstream: Let allowed signers files used by ssh-keygen(1)
- test data Ensure that cert->signature_key is populated correctly
+ signatures support key lifetimes, and allow the verification mode to specify
+ a signature time to check at. This is intended for use by git to support
+ signing objects using ssh keys. ok dtucker@
- OpenBSD-Regress-ID: 56e68f70fe46cb3a193ca207385bdb301fd6603a
+ OpenBSD-Commit-ID: 3e2c67b7dcd94f0610194d1e8e4907829a40cf31
-commit f803b2682992cfededd40c91818b653b5d923ef5
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Wed Sep 12 01:23:48 2018 +0000
+commit 44142068dc7ef783d135e91ff954e754d2ed432e
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Mon Jul 19 08:48:33 2021 +0000
- upstream: test revocation by explicit hash and by fingerprint
+ upstream: Use SUDO when setting up hostkey.
- OpenBSD-Regress-ID: 079c18a9ab9663f4af419327c759fc1e2bc78fd8
+ OpenBSD-Regress-ID: 990cf4481cab8dad62e90818a9b4b36c533851a7
-commit 2de78bc7da70e1338b32feeefcc6045cf49efcd4
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Wed Sep 12 01:22:43 2018 +0000
+commit 6b67f3f1d1d187597e54a139cc7785c0acebd9a2
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Mon Jul 19 05:08:54 2021 +0000
- upstream: s/sshkey_demote/sshkey_from_private/g
+ upstream: Increase time margin for rekey tests. Should help
- OpenBSD-Regress-ID: 782bde7407d94a87aa8d1db7c23750e09d4443c4
+ reliability on very heavily loaded hosts.
+
+ OpenBSD-Regress-ID: 4c28a0fce3ea89ebde441d7091464176e9730533
-commit 41c115a5ea1cb79a6a3182773c58a23f760e8076
-Author: Damien Miller <djm@mindrot.org>
-Date: Wed Sep 12 16:50:01 2018 +1000
+commit 7953e1bfce9e76bec41c1331a29bc6cff9d416b8
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Mon Jul 19 13:47:51 2021 +1000
- delete the correct thing; kexfuzz binary
+ Add sshfp-connect.sh file missed in previous.
-commit f0fcd7e65087db8c2496f13ed39d772f8e38b088
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Wed Sep 12 06:18:59 2018 +0000
+commit b75a80fa8369864916d4c93a50576155cad4df03
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Mon Jul 19 03:13:28 2021 +0000
- upstream: fix edit mistake; spotted by jmc@
+ upstream: Ensure that all returned SSHFP records for the specified host
- OpenBSD-Commit-ID: dd724e1c52c9d6084f4cd260ec7e1b2b138261c6
+ name and hostkey type match instead of only one. While there, simplify the
+ code somewhat and add some debugging. Based on discussion in bz#3322, ok
+ djm@.
+
+ OpenBSD-Commit-ID: 0a6a0a476eb7f9dfe8fe2c05a1a395e3e9b22ee4
-commit 4cc259bac699f4d2a5c52b92230f9e488c88a223
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Wed Sep 12 01:34:02 2018 +0000
+commit 1cc1fd095393663cd72ddac927d82c6384c622ba
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Mon Jul 19 02:21:50 2021 +0000
- upstream: add SSH_ALLOWED_CA_SIGALGS - the default list of
+ upstream: Id sync only, -portable already has this.
- signature algorithms that are allowed for CA signatures. Notably excludes
- ssh-dsa.
+ Put dh_set_moduli_file call inside ifdef WITH_OPENSSL. Fixes
+ build with OPENSSL=no.
- ok markus@
+ OpenBSD-Commit-ID: af54abbebfb12bcde6219a44d544e18204defb15
+
+commit 33abbe2f4153f5ca5c874582f6a7cc91ae167485
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Mon Jul 19 02:46:34 2021 +0000
+
+ upstream: Add test for host key verification via SSHFP records. This
+
+ requires some external setup to operate so is disabled by default (see
+ comments in sshfp-connect.sh).
- OpenBSD-Commit-ID: 1628e4181dc8ab71909378eafe5d06159a22deb4
+ OpenBSD-Regress-ID: c52c461bd1df3a803d17498917d156ef64512fd9
-commit ba9e788315b1f6a350f910cb2a9e95b2ce584e89
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Wed Sep 12 01:32:54 2018 +0000
+commit f0cd000d8e3afeb0416dce1c711c3d7c28d89bdd
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Mon Jul 19 02:29:28 2021 +0000
+
+ upstream: Add ed25519 key and test SSHFP export of it. Only test
+
+ RSA SSHFP export if we have RSA functionality compiled in.
+
+ OpenBSD-Regress-ID: b4ff5181b8c9a5862e7f0ecdd96108622333a9af
- upstream: add sshkey_check_cert_sigtype() that checks a
+commit 0075511e27e5394faa28edca02bfbf13b9a6693e
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Mon Jul 19 00:16:26 2021 +0000
+
+ upstream: Group keygen tests together.
- cert->signature_type against a supplied whitelist; ok markus
+ OpenBSD-Regress-ID: 07e2d25c527bb44f03b7c329d893a1f2d6c5c40c
+
+commit 034828820c7e62652e7c48f9ee6b67fb7ba6fa26
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Sun Jul 18 23:10:10 2021 +0000
+
+ upstream: Add test for ssh-keygen printing of SSHFP records.
- OpenBSD-Commit-ID: caadb8073292ed7a9535e5adc067d11d356d9302
+ OpenBSD-Regress-ID: fde9566b56eeb980e149bbe157a884838507c46b
-commit a70fd4ad7bd9f2ed223ff635a3d41e483057f23b
+commit 52c3b6985ef1d5dadb4c4fe212f8b3a78ca96812
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Wed Sep 12 01:31:30 2018 +0000
+Date: Sat Jul 17 00:38:11 2021 +0000
- upstream: add cert->signature_type field and keep it in sync with
+ upstream: wrap some long lines
- certificate signature wrt loading and certification operations; ok markus@
+ OpenBSD-Commit-ID: 4f5186b1466656762dae37d3e569438d900c350d
+
+commit 43ec991a782791d0b3f42898cd789f99a07bfaa4
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Sat Jul 17 00:36:53 2021 +0000
+
+ upstream: fix sftp on ControlPersist connections, broken by recent
- OpenBSD-Commit-ID: e8b8b9f76b66707a0cd926109c4383db8f664df3
+ SessionType change; spotted by sthen@
+
+ OpenBSD-Commit-ID: 4c5ddc5698790ae6ff50d2a4f8f832f0eeeaa234
-commit 357128ac48630a9970e3af0e6ff820300a28da47
+commit 073f45c236550f158c9a94003e4611c07dea5279
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Wed Sep 12 01:30:10 2018 +0000
+Date: Fri Jul 16 09:00:23 2021 +0000
- upstream: Add "ssh -Q sig" to allow listing supported signature
+ upstream: Explicitly check for and start time-based rekeying in the
+
+ client and server mainloops.
- algorithms ok markus@
+ Previously the rekey timeout could expire but rekeying would not start
+ until a packet was sent or received. This could cause us to spin in
+ select() on the rekey timeout if the connection was quiet.
+
+ ok markus@
- OpenBSD-Commit-ID: 7a8c6eb6c249dc37823ba5081fce64876d10fe2b
+ OpenBSD-Commit-ID: 4356cf50d7900f3df0a8f2117d9e07c91b9ff987
-commit 9405c6214f667be604a820c6823b27d0ea77937d
+commit ef7c4e52d5d840607f9ca3a302a4cbb81053eccf
+Author: jmc@openbsd.org <jmc@openbsd.org>
+Date: Wed Jul 14 06:46:38 2021 +0000
+
+ upstream: reorder SessionType; ok djm
+
+ OpenBSD-Commit-ID: c7dd0b39e942b1caf4976a0b1cf0fed33d05418c
+
+commit 8aa2f9aeb56506dca996d68ab90ab9c0bebd7ec3
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Wed Jul 14 11:26:50 2021 +1000
+
+ Make whitespace consistent.
+
+commit 4f4297ee9b8a39f4dfd243a74c5f51f9e7a05723
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Wed Jul 14 11:26:12 2021 +1000
+
+ Add ARM64 Linux self-hosted runner.
+
+commit eda8909d1b0a85b9c3804a04d03ec6738fd9dc7f
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Wed Sep 12 01:21:34 2018 +0000
+Date: Tue Jul 13 23:48:36 2021 +0000
- upstream: allow key revocation by SHA256 hash and allow ssh-keygen
+ upstream: add a SessionType directive to ssh_config, allowing the
- to create KRLs using SHA256/base64 key fingerprints; ok markus@
+ configuration file to offer equivalent control to the -N (no session) and -s
+ (subsystem) command-line flags.
- OpenBSD-Commit-ID: a0590fd34e7f1141f2873ab3acc57442560e6a94
+ Part of GHPR#231 by Volker Diels-Grabsch with some minor tweaks;
+ feedback and ok dtucker@
+
+ OpenBSD-Commit-ID: 726ee931dd4c5cc7f1d7a187b26f41257f9a2d12
-commit 50e2687ee0941c0ea216d6ffea370ffd2c1f14b9
+commit 7ae69f2628e338ba6e0eae7ee8a63bcf8fea7538
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Wed Sep 12 01:19:12 2018 +0000
+Date: Mon Jul 12 02:12:22 2021 +0000
- upstream: log certificate fingerprint in authentication
+ upstream: fix some broken tests; clean up output
- success/failure message (previously we logged only key ID and CA key
- fingerprint).
+ OpenBSD-Regress-ID: 1d5038edb511dc4ce1622344c1e724626a253566
+
+commit f5fc6a4c3404bbf65c21ca6361853b33d78aa87e
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Mon Jul 12 18:00:05 2021 +1000
+
+ Add configure-time detection for SSH_TIME_T_MAX.
- ok markus@
+ Should fix printing cert times exceeding INT_MAX (bz#3329) on platforms
+ were time_t is a long long. The limit used is for the signed type, so if
+ some system has a 32bit unsigned time_t then the lower limit will still
+ be imposed and we would need to add some way to detect this. Anyone using
+ an unsigned 64bit can let us know when it starts being a problem.
+
+commit fd2d06ae4442820429d634c0a8bae11c8e40c174
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Mon Jul 12 06:22:57 2021 +0000
+
+ upstream: Make limit for time_t test unconditional in the
+
+ format_absolute_time fix for bz#3329 that allows printing of timestamps past
+ INT_MAX. This was incorrectly included with the previous commit. Based on
+ discussion with djm@.
- OpenBSD-Commit-ID: a8ef2d172b7f1ddbcce26d6434b2de6d94f6c05d
+ OpenBSD-Commit-ID: 835936f6837c86504b07cabb596b613600cf0f6e
-commit de37ca909487d23e5844aca289b3f5e75d3f1e1f
+commit 6c29b387cd64a57b0ec8ae7d2c8d02789d88fcc3
Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Fri Sep 7 04:26:56 2018 +0000
+Date: Mon Jul 12 06:08:57 2021 +0000
- upstream: Add FALLTHROUGH comments where appropriate. Patch from
+ upstream: Use existing format_absolute_time() function when
- jjelen at redhat via bz#2687.
+ printing cert validity instead of doing it inline. Part of bz#3329.
- OpenBSD-Commit-ID: c48eb457be697a19d6d2950c6d0879f3ccc851d3
+ OpenBSD-Commit-ID: a13d4e3c4f59644c23745eb02a09b2a4e717c00c
-commit 247766cd3111d5d8c6ea39833a3257ca8fb820f2
+commit 99981d5f8bfa383791afea03f6bce8454e96e323
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Sep 7 01:42:54 2018 +0000
+Date: Fri Jul 9 09:55:56 2021 +0000
+
+ upstream: silence redundant error message; reported by Fabian Stelzer
+
+ OpenBSD-Commit-ID: 9349a703016579a60557dafd03af2fe1d44e6aa2
+
+commit e86097813419b49d5bff5c4b51d1c3a5d4d2d804
+Author: John Ericson <John.Ericson@Obsidian.Systems>
+Date: Sat Dec 26 11:40:49 2020 -0500
+
+ Re-indent krb5 section after pkg-config addition.
+
+commit 32dd2daa56c294e40ff7efea482c9eac536d8cbb
+Author: John Ericson <John.Ericson@Obsidian.Systems>
+Date: Sat Dec 26 11:40:49 2020 -0500
+
+ Support finding Kerberos via pkg-config
+
+ This makes cross compilation easier.
+
+commit def7a72234d7e4f684d72d33a0f7229f9eee0aa4
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Fri Jul 9 14:34:06 2021 +1000
+
+ Update comments about EGD to include prngd.
+
+commit b5d23150b4e3368f4983fd169d432c07afeee45a
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Mon Jul 5 01:21:07 2021 +0000
- upstream: ssh -MM requires confirmation for all operations that
+ upstream: Fix a couple of whitespace things. Portable already has
- change the multiplexing state, not just new sessions.
+ these so this removes two diffs between the two.
- mention that confirmation is checked via ssh-askpass
+ OpenBSD-Commit-ID: 769f017ebafd8e741e337b3e9e89eb5ac73c9c56
+
+commit 8f57be9f279b8e905f9883066aa633c7e67b31cf
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Mon Jul 5 01:16:46 2021 +0000
+
+ upstream: Order includes as per style(9). Portable already has
+
+ these so this removes a handful of diffs between the two.
- OpenBSD-Commit-ID: 0f1b45551ebb9cc5c9a4fe54ad3b23ce90f1f5c2
+ OpenBSD-Commit-ID: 8bd7452d809b199c19bfc49511a798f414eb4a77
-commit db8bb80e3ac1bcb3e1305d846cd98c6b869bf03f
-Author: mestre@openbsd.org <mestre@openbsd.org>
-Date: Tue Aug 28 12:25:53 2018 +0000
+commit b75624f8733b3ed9e240f86cac5d4a39dae11848
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Mon Jul 5 00:50:25 2021 +0000
- upstream: fix misplaced parenthesis inside if-clause. it's harmless
+ upstream: Remove comment referencing now-removed
- and the only issue is showing an unknown error (since it's not defined)
- during fatal(), if it ever an error occurs inside that condition.
+ RhostsRSAAuthentication. ok djm@
- OK deraadt@ markus@ djm@
+ OpenBSD-Commit-ID: 3d864bfbd99a1d4429a58e301688f3be464827a9
+
+commit b67eb12f013c5441bb4f0893a97533582ad4eb13
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Mon Jul 5 00:25:42 2021 +0000
+
+ upstream: allow spaces to appear in usernames for local to remote,
- OpenBSD-Commit-ID: acb0a8e6936bfbe590504752d01d1d251a7101d8
+ and scp -3 remote to remote copies. with & ok dtucker bz#1164
+
+ OpenBSD-Commit-ID: e9b550f3a85ffbb079b6720833da31317901d6dd
-commit 086cc614f550b7d4f100c95e472a6b6b823938ab
-Author: mestre@openbsd.org <mestre@openbsd.org>
-Date: Tue Aug 28 12:17:45 2018 +0000
+commit 8c4ef0943e574f614fc7c6c7e427fd81ee64ab87
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Fri Jul 2 07:20:44 2021 +0000
- upstream: fix build with DEBUG_PK enabled
+ upstream: Remove obsolete comments about SSHv1 auth methods. ok
- OK dtucker@
+ djm@
- OpenBSD-Commit-ID: ec1568cf27726e9638a0415481c20c406e7b441c
+ OpenBSD-Commit-ID: 6060f70966f362d8eb4bec3da2f6c4712fbfb98f
-commit 2678833013e97f8b18f09779b7f70bcbf5eb2ab2
+commit 88908c9b61bcb99f16e8d398fc41e2b3b4be2003
Author: Darren Tucker <dtucker@dtucker.net>
-Date: Fri Sep 7 14:41:53 2018 +1000
+Date: Sat Jul 3 23:00:19 2021 +1000
- Handle ngroups>_SC_NGROUPS_MAX.
+ Remove reference to ChallengeResponse.
- Based on github pull request #99 from Darren Maffat at Oracle: Solaris'
- getgrouplist considers _SC_NGROUPS_MAX more of a guideline and can return
- a larger number of groups. In this case, retry getgrouplist with a
- larger array and defer allocating groups_byname. ok djm@
+ challenge_response_authentication was removed from the struct, keeping
+ kbd_interactive_authentication.
-commit 039bf2a81797b8f3af6058d34005a4896a363221
+commit 321874416d610ad2158ce6112f094a4862c2e37f
Author: Darren Tucker <dtucker@dtucker.net>
-Date: Fri Sep 7 14:06:57 2018 +1000
+Date: Sat Jul 3 20:38:09 2021 +1000
- Initial len for the fmt=NULL case.
-
- Patch from jjelen at redhat via bz#2687. (OpenSSH never calls
- setproctitle with a null format so len is always initialized).
+ Move signal.h up include order to match upstream.
-commit ea9c06e11d2e8fb2f4d5e02f8a41e23d2bd31ca9
+commit 4fa83e2d0e32c2dd758653e0359984bbf1334f32
Author: Darren Tucker <dtucker@dtucker.net>
-Date: Fri Sep 7 14:01:39 2018 +1000
+Date: Sat Jul 3 20:36:06 2021 +1000
- Include stdlib.h.
+ Remove old OpenBSD version marker.
- Patch from jjelen at redhat via bz#2687.
+ Looks like an accidental leftover from a sync.
-commit 9617816dbe73ec4d65075f4d897443f63a97c87f
-Author: Damien Miller <djm@mindrot.org>
-Date: Mon Aug 27 13:08:01 2018 +1000
+commit 9d5e31f55d5f3899b72645bac41a932d298ad73b
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Sat Jul 3 20:34:19 2021 +1000
- document some more regress control env variables
-
- Specifically SKIP_UNIT, USE_VALGRING and LTESTS. Sort the list of
- environment variables.
+ Remove duplicate error on error path.
- Based on patch from Jakub Jelen
+ There's an extra error() call on the listen error path, it looks like
+ its removal was missed during an upstream sync.
-commit 71508e06fab14bc415a79a08f5535ad7bffa93d9
-Author: Damien Miller <djm@mindrot.org>
-Date: Thu Aug 23 15:41:42 2018 +1000
+commit 888c459925c7478ce22ff206c9ac1fb812a40caf
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Sat Jul 3 20:32:46 2021 +1000
- shorten temporary SSH_REGRESS_TMP path
+ Remove some whitespace not in upstream.
- Previous path was exceeding max socket length on at least one platform (OSX)
+ Reduces diff vs OpenBSD by a small amount.
-commit 26739cf5bdc9030a583b41ae5261dedd862060f0
-Author: Damien Miller <djm@mindrot.org>
-Date: Thu Aug 23 13:06:02 2018 +1000
+commit 4d2d4d47a18d93f3e0a91a241a6fdb545bbf7dc2
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Sat Jul 3 19:27:43 2021 +1000
- rebuild dependencies
+ Replace remaining references to ChallengeResponse.
+
+ Portable had a few additional references to ChallengeResponse related to
+ UsePAM, replaces these with equivalent keyboard-interactive ones.
-commit ff729025c7463cf5d0a8d1ca1823306e48c6d4cf
-Author: Damien Miller <djm@mindrot.org>
-Date: Thu Aug 23 13:03:32 2018 +1000
+commit 53237ac789183946dac6dcb8838bc3b6b9b43be1
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Sat Jul 3 19:23:28 2021 +1000
- fix path in distclean target
+ Sync remaining ChallengeResponse removal.
- Patch from Jakub Jelen
+ These were omitted from commit 88868fd131.
-commit 7fef173c28f7462dcd8ee017fdf12b5073f54c02
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Thu Aug 23 03:01:08 2018 +0000
+commit 2c9e4b319f7e98744b188b0f58859d431def343b
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Sat Jul 3 19:17:31 2021 +1000
+
+ Disable rocky84 to figure out why agent test fails
+
+commit bfe19197a92b7916f64a121fbd3c179abf15e218
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Fri Jul 2 15:43:28 2021 +1000
- upstream: memleak introduced in r1.83; from Colin Watson
+ Remove now-unused SSHv1 enums.
- OpenBSD-Commit-ID: 5c019104c280cbd549a264a7217b67665e5732dc
+ sRhostsRSAAuthentication and sRSAAuthentication are protocol 1 options
+ and are no longer used.
-commit b8ae02a2896778b8984c7f51566c7f0f56fa8b56
-Author: schwarze@openbsd.org <schwarze@openbsd.org>
-Date: Tue Aug 21 13:56:27 2018 +0000
+commit c73b02d92d72458a5312bd098f32ce88868fd131
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Fri Jul 2 05:11:20 2021 +0000
- upstream: AIX reports the CODESET as "ISO8859-1" in the POSIX locale.
+ upstream: Remove references to ChallengeResponseAuthentication in
- Treating that as a safe encoding is OK because even when other systems return
- that string for real ISO8859-1, it is still safe in the sense that it is
- ASCII-compatible and stateless.
+ favour of KbdInteractiveAuthentication. The former is what was in SSHv1, the
+ latter is what is in SSHv2 (RFC4256) and they were treated as somewhat but
+ not entirely equivalent. We retain the old name as deprecated alias so
+ config files continue to work and a reference in the man page for people
+ looking for it.
- Issue reported by Val dot Baranov at duke dot edu. Additional
- information provided by Michael dot Felt at felt dot demon dot nl.
- Tested by Michael Felt on AIX 6.1 and by Val Baranov on AIX 7.1.
- Tweak and OK djm@.
+ Prompted by bz#3303 which pointed out the discrepancy between the two
+ when used with Match. Man page help & ok jmc@, with & ok djm@
- OpenBSD-Commit-ID: 36f1210e0b229817d10eb490d6038f507b8256a7
+ OpenBSD-Commit-ID: 2c1bff8e5c9852cfcdab1f3ea94dfef5a22f3b7e
-commit bc44ee088ad269d232e514f037c87ada4c2fd3f0
-Author: Tim Rice <tim@multitalents.net>
-Date: Tue Aug 21 08:57:24 2018 -0700
+commit f841fc9c8c7568a3b5d84a4cc0cefacb7dbc16b9
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Fri Jul 2 15:20:32 2021 +1000
- modified: openbsd-compat/port-uw.c
- remove obsolete and un-needed include
+ Fix ifdefs around get_random_bytes_prngd.
+
+ get_random_bytes_prngd() is used if either of PRNGD_PORT or PRNGD_SOCKET
+ are defined, so adjust ifdef accordingly.
-commit 829fc28a9c54e3f812ee7248c7a3e31eeb4f0b3a
+commit 0767627cf66574484b9c0834500b42ea04fe528a
Author: Damien Miller <djm@mindrot.org>
-Date: Mon Aug 20 15:57:29 2018 +1000
+Date: Fri Jul 2 14:30:23 2021 +1000
- Missing unistd.h for regress/mkdtemp.c
+ wrap get_random_bytes_prngd() in ifdef
+
+ avoid unused static function warning
-commit c8313e492355a368a91799131520d92743d8d16c
-Author: Damien Miller <djm@mindrot.org>
-Date: Fri Aug 17 05:45:20 2018 +1000
+commit f93fdc4de158386efe1116bd44c5b3f4a7a82c25
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Mon Jun 28 13:06:37 2021 +1000
- update version numbers in anticipation of release
+ Add rocky84 test target.
-commit 477b49a34b89f506f4794b35e3c70b3e2e83cd38
-Author: Corinna Vinschen <vinschen@redhat.com>
-Date: Mon Aug 13 17:08:51 2018 +0200
+commit d443006c0ddfa7f6a5bd9c0ae92036f3d5f2fa3b
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Fri Jun 25 06:30:22 2021 +0000
- configure: work around GCC shortcoming on Cygwin
+ upstream: fix decoding of X.509 subject name; from Leif Thuresson
- Cygwin's latest 7.x GCC allows to specify -mfunction-return=thunk
- as well as -mindirect-branch=thunk on the command line, albeit
- producing invalid code, leading to an error at link stage.
+ via bz3327 ok markus@
- The check in configure.ac only checks if the option is present,
- but not if it produces valid code.
+ OpenBSD-Commit-ID: 0ea2e28f39750dd388b7e317bc43dd997a217ae8
+
+commit 2a5704ec142202d387fda2d6872fd4715ab81347
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Fri Jun 25 06:20:39 2021 +0000
+
+ upstream: Use better language to refer to the user. From l1ving
- This patch fixes it by special-casing Cygwin. Another solution
- may be to change these to linker checks.
+ via github PR#250, ok jmc@
- Signed-off-by: Corinna Vinschen <vinschen@redhat.com>
+ OpenBSD-Commit-ID: 07ca3526626996613e128aeddf7748c93c4d6bbf
-commit b0917945efa374be7648d67dbbaaff323ab39edc
-Author: Corinna Vinschen <vinschen@redhat.com>
-Date: Mon Aug 13 17:05:05 2018 +0200
+commit 4bdf7a04797a0ea1c431a9d54588417c29177d19
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Fri Jun 25 03:38:17 2021 +0000
- cygwin: add missing stdarg.h include
+ upstream: Replace SIGCHLD/notify_pipe kludge with pselect.
+
+ Previously sshd's SIGCHLD handler would wake up select() by writing a
+ byte to notify_pipe. We can remove this by blocking SIGCHLD, checking
+ for child terminations then passing the original signal mask through
+ to pselect. This ensures that the pselect will immediately wake up if
+ a child terminates between wait()ing on them and the pselect.
+
+ In -portable, for platforms that do not have pselect the kludge is still
+ there but is hidden behind a pselect interface.
- Further header file standarization in Cygwin uncovered a lazy
- indirect include in bsd-cygwin_util.c
+ Based on other changes for bz#2158, ok djm@
- Signed-off-by: Corinna Vinschen <vinschen@redhat.com>
+ OpenBSD-Commit-ID: 202c85de0b3bdf1744fe53529a05404c5480d813
-commit c3903c38b0fd168ab3d925c2b129d1a599593426
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Mon Aug 13 02:41:05 2018 +0000
+commit c9f7bba2e6f70b7ac1f5ea190d890cb5162ce127
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Fri Jun 25 15:08:18 2021 +1000
- upstream: revert compat.[ch] section of the following change. It
-
- causes double-free under some circumstances.
+ Move closefrom() to before first malloc.
- --
+ When built against tcmalloc, tcmalloc allocates a descriptor for its
+ internal use, so calling closefrom() afterward causes the descriptor
+ number to be reused resulting in a corrupted connection. Moving the
+ closefrom a little earlier should resolve this. From kircherlike at
+ outlook.com via bz#3321, ok djm@
+
+commit 7ebfe4e439853b88997c9cfc2ff703408a1cca92
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Fri Jun 18 20:41:45 2021 +1000
+
+ Put second -lssh in link line for sftp-server.
- date: 2018/07/31 03:07:24; author: djm; state: Exp; lines: +33 -18; commitid: f7g4UI8eeOXReTPh;
- fix some memory leaks spotted by Coverity via Jakub Jelen in bz#2366
- feedback and ok dtucker@
+ When building --without-openssl the recent port-prngd.c change adds
+ a dependency on atomicio, but since nothing else in sftp-server uses
+ it, the linker may not find it. Add a second -lssh similar to other
+ binaries.
+
+commit e409d7966785cfd9f5970e66a820685c42169717
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Fri Jun 18 18:34:08 2021 +1000
+
+ Try EGD/PRNGD if random device fails.
- OpenBSD-Commit-ID: 1e77547f60fdb5e2ffe23e2e4733c54d8d2d1137
+ When built --without-openssl, try EGD/PRGGD (if configured) as a last
+ resort before failing.
-commit 1b9dd4aa15208100fbc3650f33ea052255578282
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sun Aug 12 20:19:13 2018 +0000
+commit e43a898043faa3a965dbaa1193cc60e0b479033d
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Fri Jun 18 18:32:51 2021 +1000
- upstream: better diagnosics on alg list assembly errors; ok
+ Split EGD/PRNGD interface into its own file.
- deraadt@ markus@
+ This will allow us to use it when building --without-openssl.
+
+commit acb2887a769a1b1912cfd7067f3ce04fad240260
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Thu Jun 17 21:03:19 2021 +1000
+
+ Handle GIDs > 2^31 in getgrouplist.
- OpenBSD-Commit-ID: 5a557e74b839daf13cc105924d2af06a1560faee
+ When compiled in 32bit mode, the getgrouplist implementation may fail
+ for GIDs greater than LONG_MAX. Analysis and change from ralf.winkel
+ at tui.com.
-commit e36a5f61b0f5bebf6d49c215d228cd99dfe86e28
-Author: Damien Miller <djm@mindrot.org>
-Date: Sat Aug 11 18:08:45 2018 -0700
+commit 31fac20c941126281b527605b73bff30a8f02edd
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Thu Jun 10 09:46:28 2021 +0000
- Some AIX fixes; report from Michael Felt
+ upstream: Use $SUDO when reading sshd's pidfile here too.
+
+ OpenBSD-Regress-ID: 6bfb0d455d493f24839034a629c5306f84dbd409
-commit 2f4766ceefe6657c5ad5fe92d13c411872acae0e
+commit a3a58acffc8cc527f8fc6729486d34e4c3d27643
Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Fri Aug 10 01:35:49 2018 +0000
+Date: Thu Jun 10 09:43:51 2021 +0000
- upstream: The script that cooks up PuTTY format host keys does not
+ upstream: Use $SUDO when reading sshd's pidfile in case it was
- understand the new key format so convert back to old format to create the
- PuTTY key and remove it once done.
+ created with a very restrictive umask. This resyncs with -portable.
- OpenBSD-Regress-ID: 2a449a18846c3a144bc645135b551ba6177e38d3
+ OpenBSD-Regress-ID: 07fd2af06df759d4f64b82c59094accca1076a5d
-commit e1b26ce504662a5d5b991091228984ccfd25f280
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Aug 10 00:44:01 2018 +0000
+commit 249ad4ae51cd3bc235e75a4846eccdf8b1416611
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Thu Jun 10 09:37:59 2021 +0000
- upstream: improve
+ upstream: Set umask when creating hostkeys to prevent excessive
+
+ permissions warning.
- OpenBSD-Commit-ID: 40d839db0977b4e7ac8b647b16d5411d4faf2f60
+ OpenBSD-Regress-ID: 382841db0ee28dfef7f7bffbd511803e1b8ab0ef
-commit 7c712966a3139622f7fb55045368d05de4e6782c
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Aug 10 00:42:29 2018 +0000
+commit 9d0892153c005cc65897e9372b01fa66fcbe2842
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Thu Jun 10 03:45:31 2021 +0000
- upstream: Describe pubkey format, prompted by bz#2853
+ upstream: Add regress test for SIGHUP restart
- While I'm here, describe and link to the remaining local PROTOCOL.*
- docs that weren't already mentioned (PROTOCOL.key, PROTOCOL.krl and
- PROTOCOL.mux)
+ while handling active and unauthenticated clients. Should catch anything
+ similar to the pselect bug just fixed in sshd.c.
- OpenBSD-Commit-ID: 2a900f9b994ba4d53e7aeb467d44d75829fd1231
+ OpenBSD-Regress-ID: 3b3c19b5e75e43af1ebcb9586875b3ae3a4cac73
-commit ef100a2c5a8ed83afac0b8f36520815803da227a
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Aug 10 00:27:15 2018 +0000
+commit 73f6f191f44440ca3049b9d3c8e5401d10b55097
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Thu Jun 10 03:14:14 2021 +0000
- upstream: fix numbering
+ upstream: Continue accept loop when pselect
- OpenBSD-Commit-ID: bc7a1764dff23fa4c5ff0e3379c9c4d5b63c9596
+ returns -1, eg if it was interrupted by a signal. This should prevent
+ the hang discovered by sthen@ wherein sshd receives a SIGHUP while it has
+ an unauthenticated child and goes on to a blocking read on a notify_pipe.
+ feedback deraadt@, ok djm@
+
+ OpenBSD-Commit-ID: 0243c1c5544fca0974dae92cd4079543a3fceaa0
-commit ed7bd5d93fe14c7bd90febd29b858ea985d14d45
+commit c785c0ae134a8e8b5c82b2193f64c632a98159e4
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Wed Aug 8 01:16:01 2018 +0000
+Date: Tue Jun 8 22:30:27 2021 +0000
- upstream: Use new private key format by default. This format is
+ upstream: test that UserKnownHostsFile correctly accepts multiple
- suported by OpenSSH >= 6.5 (released January 2014), so it should be supported
- by most OpenSSH versions in active use.
+ arguments; would have caught readconf.c r1.356 regression
- It is possible to convert new-format private keys to the older
- format using "ssh-keygen -f /path/key -pm PEM".
+ OpenBSD-Regress-ID: 71ca54e66c2a0211b04999263e56390b1f323a6a
+
+commit 1a6f6b08e62c78906a3032e8d9a83e721c84574e
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Tue Jun 8 22:06:12 2021 +0000
+
+ upstream: fix regression in r1.356: for ssh_config options that
- ok deraadt dtucker
+ accepted multiple string arguments, ssh was only recording the first.
+ Reported by Lucas via bugs@
- OpenBSD-Commit-ID: e3bd4f2509a2103bfa2f710733426af3ad6d8ab8
+ OpenBSD-Commit-ID: 7cbf182f7449bf1cb7c5b4452667dc2b41170d6d
-commit 967226a1bdde59ea137e8f0df871854ff7b91366
+commit 78e30af3e2b2dd540a341cc827c6b98dd8b0a6de
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sat Aug 4 00:55:06 2018 +0000
+Date: Tue Jun 8 07:40:12 2021 +0000
+
+ upstream: test argv_split() optional termination on comments
+
+ OpenBSD-Regress-ID: 9fd1c4a27a409897437c010cfd79c54b639a059c
+
+commit a023138957ea2becf1c7f93fcc42b0aaac6f2b03
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Tue Jun 8 07:05:27 2021 +0000
- upstream: invalidate dh->priv_key after freeing it in error path;
+ upstream: Add testcases from bz#3319 for IPQoS and TunnelDevice
- avoids unlikely double-free later. Reported by Viktor Dukhovni via
- https://github.com/openssh/openssh-portable/pull/96 feedback jsing@ tb@
+ being overridden on the command line.
- OpenBSD-Commit-ID: e317eb17c3e05500ae851f279ef6486f0457c805
+ OpenBSD-Regress-ID: 801674d5d2d02abd58274a78cab2711f11de14a8
-commit 74287f5df9966a0648b4a68417451dd18f079ab8
+commit 660cea10b2cdc11f13ba99c89b1bbb368a4d9ff2
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Tue Jul 31 03:10:27 2018 +0000
+Date: Tue Jun 8 06:52:43 2021 +0000
- upstream: delay bailout for invalid authentic
+ upstream: sprinkle some "# comment" at end of configuration lines
- =?UTF-8?q?ating=20user=20until=20after=20the=20packet=20containing=20the?=
- =?UTF-8?q?=20request=20has=20been=20fully=20parsed.=20Reported=20by=20Dar?=
- =?UTF-8?q?iusz=20Tytko=20and=20Micha=C5=82=20Sajdak;=20ok=20deraadt?=
- MIME-Version: 1.0
- Content-Type: text/plain; charset=UTF-8
- Content-Transfer-Encoding: 8bit
+ to test comment handling
- OpenBSD-Commit-ID: b4891882fbe413f230fe8ac8a37349b03bd0b70d
+ OpenBSD-Regress-ID: cb82fbf40bda5c257a9f742c63b1798e5a8fdda7
-commit 1a66079c0669813306cc69e5776a4acd9fb49015
+commit acc9c32dcb6def6c7d3688bceb4c0e59bd26b411
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Tue Jul 31 03:07:24 2018 +0000
+Date: Tue Jun 8 06:51:47 2021 +0000
- upstream: fix some memory leaks spotted by Coverity via Jakub Jelen
+ upstream: more descriptive failure message
- in bz#2366 feedback and ok dtucker@
-
- OpenBSD-Commit-ID: 8402bbae67d578bedbadb0ce68ff7c5a136ef563
+ OpenBSD-Regress-ID: 5300f6faf1d9e99c0cd10827b51756c5510e3509
-commit 87f08be054b7eeadbb9cdeb3fb4872be79ccf218
-Author: Damien Miller <djm@mindrot.org>
-Date: Fri Jul 20 13:18:28 2018 +1000
+commit ce04dd4eae23d1c9cf7c424a702f48ee78573bc1
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Mon Jun 7 01:16:34 2021 +0000
- Remove support for S/Key
+ upstream: test AuthenticationMethods inside a Match block as well
+
+ as in the main config section
- Most people will 1) be using modern multi-factor authentication methods
- like TOTP/OATH etc and 2) be getting support for multi-factor
- authentication via PAM or BSD Auth.
+ OpenBSD-Regress-ID: ebe0a686621b7cb8bb003ac520975279c28747f7
-commit 5d14019ba2ff54acbfd20a6b9b96bb860a8c7c31
-Author: markus@openbsd.org <markus@openbsd.org>
-Date: Fri Jul 27 12:03:17 2018 +0000
+commit 9018bd821fca17e26e92f7a7e51d9b24cd62f2db
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Mon Jun 7 00:00:50 2021 +0000
- upstream: avoid expensive channel_open_message() calls; ok djm@
+ upstream: prepare for stricter sshd_config parsing that will refuse
- OpenBSD-Commit-ID: aea3b5512ad681cd8710367d743e8a753d4425d9
+ a config that has {Allow,Deny}{Users,Groups} on a line with no subsequent
+ arguments. Such lines are permitted but are nonsensical noops ATM
+
+ OpenBSD-Regress-ID: ef65463fcbc0bd044e27f3fe400ea56eb4b8f650
-commit e655ee04a3cb7999dbf9641b25192353e2b69418
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Fri Jul 27 05:34:42 2018 +0000
+commit a10f929d1ce80640129fc5b6bc1acd9bf689169e
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Tue Jun 8 07:09:42 2021 +0000
- upstream: Now that ssh can't be setuid, remove the
+ upstream: switch sshd_config parsing to argv_split()
+
+ similar to the previous commit, this switches sshd_config parsing to
+ the newer tokeniser. Config parsing will be a little stricter wrt
+ quote correctness and directives appearing without arguments.
- original_real_uid and original_effective_uid globals and replace with calls
- to plain getuid(). ok djm@
+ feedback and ok markus@
- OpenBSD-Commit-ID: 92561c0cd418d34e6841e20ba09160583e27b68c
+ tested in snaps for the last five or so days - thanks Theo and those who
+ caught bugs
+
+ OpenBSD-Commit-ID: 9c4305631d20c2d194661504ce11e1f68b20d93e
-commit 73ddb25bae4c33a0db361ac13f2e3a60d7c6c4a5
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Fri Jul 27 05:13:02 2018 +0000
+commit ea9e45c89a4822d74a9d97fef8480707d584da4d
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Tue Jun 8 07:07:15 2021 +0000
- upstream: Remove uid checks from low port binds. Now that ssh
+ upstream: Switch ssh_config parsing to use argv_split()
- cannot be setuid and sshd always has privsep on, we can remove the uid checks
- for low port binds and just let the system do the check. We leave a sanity
- check for the !privsep case so long as the code is stil there. with & ok
- djm@
+ This fixes a couple of problems with the previous tokeniser,
+ strdelim()
+
+ 1. strdelim() is permissive wrt accepting '=' characters. This is
+ intended to allow it to tokenise "Option=value" but because it
+ cannot keep state, it will incorrectly split "Opt=val=val2".
+ 2. strdelim() has rudimentry handling of quoted strings, but it
+ is incomplete and inconsistent. E.g. it doesn't handle escaped
+ quotes inside a quoted string.
+ 3. It has no support for stopping on a (unquoted) comment. Because
+ of this readconf.c r1.343 added chopping of lines at '#', but
+ this caused a regression because these characters may legitimately
+ appear inside quoted strings.
+
+ The new tokeniser is stricter is a number of cases, including #1 above
+ but previously it was also possible for some directives to appear
+ without arguments. AFAIK these were nonsensical in all cases, and the
+ new tokeniser refuses to accept them.
+
+ The new code handles quotes much better, permitting quoted space as
+ well as escaped closing quotes. Finally, comment handling should be
+ fixed - the tokeniser will terminate only on unquoted # characters.
+
+ feedback & ok markus@
- OpenBSD-Commit-ID: 9535cfdbd1cd54486fdbedfaee44ce4367ec7ca0
+ tested in snaps for the last five or so days - thanks Theo and those who
+ caught bugs
+
+ OpenBSD-Commit-ID: dc72fd12af9d5398f4d9e159d671f9269c5b14d5
-commit c12033e102760d043bc5c98e6c8180e4d331b0df
+commit d786424986c04d1d375f231fda177c8408e05c3e
Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Fri Jul 27 03:55:22 2018 +0000
+Date: Tue Jun 8 07:02:46 2021 +0000
- upstream: ssh(1) no longer supports being setuid root. Remove reference
+ upstream: Check if IPQoS or TunnelDevice are already set before
- to crc32 which went with protocol 1. Pointed out by deraadt@.
+ overriding. Prevents values in config files from overriding values supplied
+ on the command line. bz#3319, ok markus.
- OpenBSD-Commit-ID: f8763c25fd96ed91dd1abdab5667fd2e27e377b6
+ OpenBSD-Commit-ID: f3b08b898c324debb9195e6865d8999406938f74
-commit 4492e2ec4e1956a277ef507f51d66e5c2aafaaf8
-Author: Damien Miller <djm@mindrot.org>
-Date: Fri Jul 27 14:15:28 2018 +1000
+commit aae4b4d3585b9f944d7dbd3c9e5ba0006c55e457
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Tue Jun 8 06:54:40 2021 +0000
- correct snprintf truncation check in closefrom()
+ upstream: Allow argv_split() to optionally terminate tokenisation
+
+ when it encounters an unquoted comment.
- Truncation cannot happen unless the system has set PATH_MAX to some
- nonsensically low value.
+ Add some additional utility function for working with argument
+ vectors, since we'll be switching to using them to parse
+ ssh/sshd_config shortly.
- bz#2862, patch from Daniel Le
+ ok markus@ as part of a larger diff; tested in snaps
+
+ OpenBSD-Commit-ID: fd9c108cef2f713f24e3bc5848861d221bb3a1ac
-commit 149cab325a8599a003364ed833f878449c15f259
+commit da9f9acaac5bab95dca642b48e0c8182b246ab69
Author: Darren Tucker <dtucker@dtucker.net>
-Date: Fri Jul 27 13:46:06 2018 +1000
+Date: Mon Jun 7 19:19:23 2021 +1000
- Include stdarg.h in mkdtemp for va_list.
+ Save logs on failure for upstream test
-commit 6728f31bdfdc864d192773c32465b1860e23f556
-Author: deraadt@openbsd.org <deraadt@openbsd.org>
-Date: Wed Jul 25 17:12:35 2018 +0000
+commit 76883c60161e5f3808787085a27a8c37f8cc4e08
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Mon Jun 7 14:36:32 2021 +1000
- upstream: Don't redefine Makefile choices which come correct from
+ Add obsdsnap-i386 upstream test target.
+
+commit d45b9c63f947ec5ec314696e70281f6afddc0ac3
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Mon Jun 7 03:38:38 2021 +0000
+
+ upstream: fix debug message when finding a private key to match a
- bsd.*.mk ok markus
+ certificate being attempted for user authentication. Previously it would
+ print the certificate's path, whereas it was supposed to be showing the
+ private key's path. Patch from Alex Sherwin via GHPR247
- OpenBSD-Commit-ID: 814b2f670df75759e1581ecef530980b2b3d7e0f
+ OpenBSD-Commit-ID: d5af3be66d0f22c371dc1fe6195e774a18b2327b
-commit 21fd477a855753c1a8e450963669e28e39c3b5d2
-Author: deraadt@openbsd.org <deraadt@openbsd.org>
-Date: Wed Jul 25 13:56:23 2018 +0000
+commit 530739d42f6102668aecd699be0ce59815c1eceb
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Sun Jun 6 11:34:16 2021 +0000
- upstream: fix indent; Clemens Goessnitzer
+ upstream: Match host certificates against host public keys, not private
+
+ keys. Allows use of certificates with private keys held in a ssh-agent.
+ Reported by Miles Zhou in bz3524; ok dtucker@
- OpenBSD-Commit-ID: b5149a6d92b264d35f879d24608087b254857a83
+ OpenBSD-Commit-ID: 25f5bf70003126d19162862d9eb380bf34bac22a
-commit 8e433c2083db8664c41499ee146448ea7ebe7dbf
-Author: beck@openbsd.org <beck@openbsd.org>
-Date: Wed Jul 25 13:10:56 2018 +0000
+commit 4265215d7300901fd7097061c7517688ade82f8e
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Sun Jun 6 03:40:39 2021 +0000
- upstream: Use the caller provided (copied) pwent struct in
+ upstream: Client-side workaround for a bug in OpenSSH 7.4: this release
+
+ allows RSA/SHA2 signatures for public key authentication but fails to
+ advertise this correctly via SSH2_MSG_EXT_INFO. This causes clients of these
+ server to incorrectly match PubkeyAcceptedAlgorithms and potentially refuse
+ to offer valid keys.
- load_public_identity_files instead of calling getpwuid() again and discarding
- the argument. This prevents a client crash where tilde_expand_filename calls
- getpwuid() again before the pwent pointer is used. Issue noticed and reported
- by Pierre-Olivier Martel <pom@apple.com> ok djm@ deraadt@
+ Reported by and based on patch from Gordon Messmer via bz3213, thanks
+ also for additional analysis by Jakub Jelen. ok dtucker
- OpenBSD-Commit-ID: a067d74b5b098763736c94cc1368de8ea3f0b157
+ OpenBSD-Commit-ID: d6d0b7351d5d44c45f3daaa26efac65847a564f7
-commit e2127abb105ae72b6fda64fff150e6b24b3f1317
-Author: jmc@openbsd.org <jmc@openbsd.org>
-Date: Mon Jul 23 19:53:55 2018 +0000
+commit bda270d7fb8522d43c21a79a4b02a052d7c64de8
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Sun Jun 6 03:17:02 2021 +0000
- upstream: oops, failed to notice that SEE ALSO got messed up;
+ upstream: degrade gracefully if a sftp-server offers the
- OpenBSD-Commit-ID: 61c1306542cefdc6e59ac331751afe961557427d
+ limits@openssh.com extension but fails when the client tries to invoke it.
+ Reported by Hector Martin via bz3318
+
+ OpenBSD-Commit-ID: bd9d1839c41811616ede4da467e25746fcd9b967
-commit ddf1b797c2d26bbbc9d410aa4f484cbe94673587
-Author: kn@openbsd.org <kn@openbsd.org>
-Date: Mon Jul 23 19:02:49 2018 +0000
+commit d345d5811afdc2d6923019b653cdd93c4cc95f76
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Sun Jun 6 03:15:39 2021 +0000
- upstream: Point to glob in section 7 for the actual list of special
+ upstream: the limits@openssh.com extension was incorrectly marked
- characters instead the C API in section 3.
+ as an operation that writes to the filesystem, which made it unavailable in
+ sftp-server read-only mode. Spotted by Hector Martin via bz3318
- OK millert jmc nicm, "the right idea" deraadt
+ OpenBSD-Commit-ID: f054465230787e37516c4b57098fc7975e00f067
+
+commit 2b71010d9b43d7b8c9ec1bf010beb00d98fa765a
+Author: naddy@openbsd.org <naddy@openbsd.org>
+Date: Sat Jun 5 13:47:00 2021 +0000
+
+ upstream: PROTOCOL.certkeys: update reference from IETF draft to
+
+ RFC
- OpenBSD-Commit-ID: a74fd215488c382809e4d041613aeba4a4b1ffc6
+ Also fix some typos.
+ ok djm@
+
+ OpenBSD-Commit-ID: 5e855b6c5a22b5b13f8ffa3897a868e40d349b44
-commit 01c98d9661d0ed6156e8602b650f72eed9fc4d12
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Sun Jul 22 12:16:59 2018 +0000
+commit aa99b2d9a3e45b943196914e8d8bf086646fdb54
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Fri Jun 4 23:41:29 2021 +1000
+
+ Clear notify_pipe from readset if present.
+
+ Prevents leaking an implementation detail to the caller.
+
+commit 6de8dadf6b4d0627d35bca0667ca44b1d61c2c6b
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Fri Jun 4 23:24:25 2021 +1000
+
+ space->tabs.
+
+commit c8677065070ee34c05c7582a9c2f58d8642e552d
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Fri Jun 4 18:39:48 2021 +1000
- upstream: Switch authorized_keys example from ssh-dss to ssh-rsa
+ Add pselect implementation for platforms without.
- since the former is no longer enabled by default. Pointed out by Daniel A.
- Maierhofer, ok jmc
+ This is basically the existing notify_pipe kludge from serverloop.c
+ moved behind a pselect interface. It works by installing a signal
+ handler that writes to a pipe that the select is watching, then calls
+ the original handler.
- OpenBSD-Commit-ID: 6a196cef53d7524e0c9b58cdbc1b5609debaf8c7
+ The select call in serverloop will become pselect soon, at which point the
+ kludge will be removed from thereand will only exist in the compat layer.
+ Original code by markus, help from djm.
-commit 472269f8fe19343971c2d08f504ab5cbb8234b33
+commit 7cd7f302d3a072748299f362f9e241d81fcecd26
+Author: Vincent Brillault <vincent.brillault@cern.ch>
+Date: Sun May 24 09:15:06 2020 +0200
+
+ auth_log: dont log partial successes as failures
+
+ By design, 'partial' logins are successful logins, so initially with
+ authenticated set to 1, for which another authentication is required. As
+ a result, authenticated is always reset to 0 when partial is set to 1.
+ However, even if authenticated is 0, those are not failed login
+ attempts, similarly to attempts with authctxt->postponed set to 1.
+
+commit e7606919180661edc7f698e6a1b4ef2cfb363ebf
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Jul 20 05:01:10 2018 +0000
+Date: Fri Jun 4 06:19:07 2021 +0000
- upstream: slightly-clearer description for AuthenticationMethods - the
+ upstream: The RB_GENERATE_STATIC(3) macro expands to a series of
- lists have comma-separated elements; bz#2663 from Hans Meier
+ function definitions and not a statement, so there should be no semicolon
+ following them. Patch from Michael Forney
- OpenBSD-Commit-ID: 931c983d0fde4764d0942fb2c2b5017635993b5a
+ OpenBSD-Commit-ID: c975dd180580f0bdc0a4d5b7d41ab1f5e9b7bedd
-commit c59aca8adbdf7f5597084ad360a19bedb3f80970
-Author: Damien Miller <djm@mindrot.org>
-Date: Fri Jul 20 14:53:42 2018 +1000
+commit c298c4da574ab92df2f051561aeb3e106b0ec954
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Fri Jun 4 05:59:18 2021 +0000
- Create control sockets in clean temp directories
+ upstream: rework authorized_keys example section, removing irrelevant
- Adds a regress/mkdtemp tool and uses it to create empty temp
- directories for tests needing control sockets.
+ stuff, de-wrapping the example lines and better aligning the examples with
+ common usage and FAQs; ok jmc
- Patch from Colin Watson via bz#2660; ok dtucker
+ OpenBSD-Commit-ID: d59f1c9281f828148e2a2e49eb9629266803b75c
-commit 6ad8648e83e4f4ace37b742a05c2a6b6b872514e
+commit d9cb35bbec5f623589d7c58fc094817b33030f35
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Jul 20 03:46:34 2018 +0000
+Date: Fri Jun 4 05:10:03 2021 +0000
- upstream: remove unused zlib.h
+ upstream: adjust SetEnv description to clarify $TERM handling
- OpenBSD-Commit-ID: 8d274a9b467c7958df12668b49144056819f79f1
+ OpenBSD-Commit-ID: 8b8cc0124856bc1094949d55615e5c44390bcb22
-commit 3ba6e6883527fe517b6e4a824876e2fe62af22fc
+commit 771f57a8626709f2ad207058efd68fbf30d31553
Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Thu Jul 19 23:03:16 2018 +0000
+Date: Fri Jun 4 05:09:08 2021 +0000
- upstream: Fix typo in comment. From Alexandru Iacob via github.
+ upstream: Switch the listening select loop from select() to
+
+ pselect() and mask signals while checking signal flags, umasking for pselect
+ and restoring afterwards. Also restore signals before sighup_restart so they
+ don't remain blocked after restart.
- OpenBSD-Commit-ID: eff4ec07c6c8c5483533da43a4dda37d72ef7f1d
+ This prevents a race where a SIGTERM or SIGHUP can arrive between
+ checking the flag and calling select (eg if sshd is processing a
+ new connection) resulting in sshd not shutting down until the next
+ time it receives a new connection. bz#2158, with & ok djm@
+
+ OpenBSD-Commit-ID: bf85bf880fd78e00d7478657644fcda97b9a936f
-commit c77bc73c91bc656e343a1961756e09dd1b170820
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Fri Jul 20 13:48:51 2018 +1000
+commit f64f8c00d158acc1359b8a096835849b23aa2e86
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Fri Jun 4 05:02:40 2021 +0000
- Explicitly include openssl before zlib.
+ upstream: allow ssh_config SetEnv to override $TERM, which is otherwise
+
+ handled specially by the protocol. Useful in ~/.ssh/config to set TERM to
+ something generic (e.g. "xterm" instead of "xterm-256color") for destinations
+ that lack terminfo entries. feedback and ok dtucker@
- Some versions of OpenSSL have "free_func" in their headers, which zlib
- typedefs. Including openssl after zlib (eg via sshkey.h) results in
- "syntax error before `free_func'", which this fixes.
+ OpenBSD-Commit-ID: 38b1ef4d5bc159c7d9d589d05e3017433e2d5758
-commit 95d41e90eafcd1286a901e8e361e4a37b98aeb52
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Thu Jul 19 10:28:47 2018 +0000
+commit 60107677dc0ce1e93c61f23c433ad54687fcd9f5
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Fri Jun 4 04:02:21 2021 +0000
- upstream: Deprecate UsePrivilegedPort now that support for running
+ upstream: correct extension name "no-presence-required" =>
- ssh(1) setuid has been removed, remove supporting code and clean up
- references to it in the man pages
+ "no-touch-required"
- We have not shipped ssh(1) the setuid bit since 2002. If ayone
- really needs to make connections from a low port number this can
- be implemented via a small setuid ProxyCommand.
+ document "verify-required" option
- ok markus@ jmc@ djm@
+ OpenBSD-Commit-ID: 1879ff4062cf61d79b515e433aff0bf49a6c55c5
+
+commit ecc186e46e3e30f27539b4311366dfda502f0a08
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Wed Jun 2 13:54:11 2021 +1000
+
+ Retire fbsd7 test target.
- OpenBSD-Commit-ID: d03364610b7123ae4c6792f5274bd147b6de717e
+ It's the slowest of the selfhosted targets (since it's 32bit but has
+ most of the crypto algos). We still have coverage for 32bit i386.
-commit 258dc8bb07dfb35a46e52b0822a2c5b7027df60a
+commit 5de0867b822ec48b5eec9abde0f5f95d1d646546
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Wed Jun 2 11:21:40 2021 +1000
+
+ Check for $OPENSSL in md5 fallback too.
+
+commit 1db69d1b6542f8419c04cee7fd523a4a11004be2
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Wed Jun 2 11:17:54 2021 +1000
+
+ Add dfly60 target.
+
+commit a3f2dd955f1c19cad387a139f0e719af346ca6ef
Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Wed Jul 18 11:34:04 2018 +0000
+Date: Wed Jun 2 00:17:45 2021 +0000
- upstream: Remove support for running ssh(1) setuid and fatal if
+ upstream: Merge back shell portability changes
- attempted. Do not link uidwap.c into ssh any more. Neuters
- UsePrivilegedPort, which will be marked as deprecated shortly. ok markus@
- djm@
+ bringing it back in sync with -portable.
- OpenBSD-Commit-ID: c4ba5bf9c096f57a6ed15b713a1d7e9e2e373c42
+ OpenBSD-Regress-ID: c07905ba931e66ad7d849b87b7d19648007175d1
-commit ac590760b251506b0a152551abbf8e8d6dc2f527
+commit 9d482295c9f073e84d75af46b720a1c0f7ec2867
Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Mon Jul 16 22:25:01 2018 +0000
+Date: Tue Jun 1 23:56:20 2021 +0000
- upstream: Slot 0 in the hostbased key array was previously RSA1,
+ upstream: Use a default value for $OPENSSL,
- but that is now gone and the slot is unused so remove it. Remove two
- now-unused macros, and add an array bounds check to the two remaining ones
- (array is statically sized, so mostly a safety check on future changes). ok
- markus@
+ allowing it to be overridden. Do the same in the PuTTY tests since it's
+ needed there and not exported by test-exec.sh.
- OpenBSD-Commit-ID: 2e4c0ca6cc1d8daeccead2aa56192a3f9d5e1e7a
+ OpenBSD-Regress-ID: c49dcd6aa7602a8606b7afa192196ca1fa65de16
-commit 26efc2f5df0e3bcf6a6bbdd0506fd682d60c2145
+commit 07660b3c99f8ea74ddf4a440e55c16c9f7fb3dd1
Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Mon Jul 16 11:05:41 2018 +0000
+Date: Mon May 24 10:25:18 2021 +0000
- upstream: Remove support for loading HostBasedAuthentication keys
+ upstream: Find openssl binary via environment variable. This
- directly in ssh(1) and always use ssh-keysign. This removes one of the few
- remaining reasons why ssh(1) might be setuid. ok markus@
+ allows overriding if necessary (eg in -portable where we're testing against a
+ specific version of OpenSSL).
- OpenBSD-Commit-ID: 97f01e1448707129a20d75f86bad5d27c3cf0b7d
+ OpenBSD-Regress-ID: 491f39cae9e762c71aa4bf045803d077139815c5
-commit 3eb7f1038d17af7aea3c2c62d1e30cd545607640
+commit 1a4d1da9188d7c88f646b61f0d6a3b34f47c5439
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Mon Jul 16 07:06:50 2018 +0000
+Date: Fri May 21 04:03:47 2021 +0000
- upstream: keep options.identity_file_userprovided array in sync when we
+ upstream: fix memleak in test
- load keys, fixing some spurious error messages; ok markus
+ OpenBSD-Regress-ID: 5e529d0982aa04666604936df43242e97a7a6f81
+
+commit 60455a5d98065a73ec9a1f303345856bbd49aecc
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Fri May 21 03:59:01 2021 +0000
+
+ upstream: also check contents of remaining string
- OpenBSD-Commit-ID: c63e3d5200ee2cf9e35bda98de847302566c6a00
+ OpenBSD-Regress-ID: d526fa07253f4eebbc7d6205a0ab3d491ec71a28
-commit 2f131e1b34502aa19f345e89cabf6fa3fc097f09
+commit 39f6cd207851d7b67ca46903bfce4a9f615b5b1c
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Mon Jul 16 03:09:59 2018 +0000
+Date: Fri May 21 03:48:07 2021 +0000
- upstream: memleak in unittest; found by valgrind
+ upstream: unit test for misc.c:strdelim() that mostly servces to
+
+ highlight its inconsistencies
- OpenBSD-Regress-ID: 168c23b0fb09fc3d0b438628990d3fd9260a8a5e
+ OpenBSD-Regress-ID: 8d2bf970fcc01ccc6e36a5065f89b9c7fa934195
+
+commit 7a3a1dd2c7d4461962acbcc0ebee9445ba892be0
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Thu May 27 21:23:15 2021 +1000
+
+ Put minix3 config in the host-specific block.
-commit de2997a4cf22ca0a524f0e5b451693c583e2fd89
+commit 59a194825f12fff8a7f75d91bf751ea17645711b
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Mon Jul 16 03:09:13 2018 +0000
+Date: Mon May 31 06:48:42 2021 +0000
- upstream: memleaks; found by valgrind
+ upstream: Hash challenge supplied by client during FIDO key enrollment
- OpenBSD-Commit-ID: 6c3ba22be53e753c899545f771e8399fc93cd844
+ prior to passing it to libfido2, which does expect a hash.
+
+ There is no effect for users who are simply generating FIDO keys using
+ ssh-keygen - by default we generate a random 256 bit challenge, but
+ people building attestation workflows around our tools should now have
+ a more consistent experience (esp. fewer failures when they fail to
+ guess the magic 32-byte challenge length requirement).
+
+ ok markus@
+
+ OpenBSD-Commit-ID: b8d5363a6a7ca3b23dc28f3ca69470472959f2b5
-commit 61cc0003eb37fa07603c969c12b7c795caa498f3
+commit eb68e669bc8ab968d4cca5bf1357baca7136a826
Author: Darren Tucker <dtucker@dtucker.net>
-Date: Sat Jul 14 16:49:01 2018 +1000
+Date: Thu May 27 21:14:15 2021 +1000
- Undef a few new macros in sys-queue.h.
+ Include login_cap.h for login_getpwclass override.
- Prevents macro redefinition warnings on OSX.
+ On minix3, login_getpwclass is __RENAME'ed to __login_getpwclass50 so
+ without this the include overriding login_getpwclass causes a compile
+ error.
-commit 30a2c213877a54a44dfdffb6ca8db70be5b457e0
+commit 2063af71422501b65c7a92a5e14c0e6a3799ed89
Author: Darren Tucker <dtucker@dtucker.net>
-Date: Fri Jul 13 13:40:20 2018 +1000
+Date: Thu May 27 21:13:38 2021 +1000
+
+ Add minix3 test target.
+
+commit 2e1efcfd9f94352ca5f4b6958af8a454f8cf48cd
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Wed May 26 01:47:24 2021 +0000
- Include unistd.h for geteuid declaration.
+ upstream: fix SEGV in UpdateHostkeys debug() message, triggered
+
+ when the update removed more host keys than remain present. Fix tested by
+ reporter James Cook, via bugs@
+
+ OpenBSD-Commit-ID: 44f641f6ee02bb957f0c1d150495b60cf7b869d3
+
+commit 9acd76e6e4d2b519773e7119c33cf77f09534909
+Author: naddy@openbsd.org <naddy@openbsd.org>
+Date: Sun May 23 18:22:57 2021 +0000
+
+ upstream: ssh: The client configuration keyword is
+
+ "hostbasedacceptedalgorithms"
+
+ This fixes a mistake that slipped in when "HostbasedKeyTypes" was
+ renamed to "HostbasedAcceptedAlgorithms".
+
+ Bug report by zack@philomathiclife.com
+
+ OpenBSD-Commit-ID: d745a7e8e50b2589fc56877f322ea204bc784f38
-commit 1dd32c23f2a85714dfafe2a9cc516971d187caa4
+commit 078a0e60c92700da4c536c93c007257828ccd05b
Author: Darren Tucker <dtucker@dtucker.net>
-Date: Fri Jul 13 13:38:10 2018 +1000
+Date: Tue May 25 11:40:47 2021 +1000
- Fallout from buffer conversion in AUDIT_EVENTS.
+ Rename README.md to ci-status.md.
- Supply missing "int r" and fix error path for sshbuf_new().
+ The original intent was to provide a status page for the CIs configured
+ in that directory, but it had the side effect of replacing the top-level
+ README.md.
-commit 7449c178e943e5c4f6c8416a4e41d93b70c11c9e
+commit 7be4ac813662f68e89f23c50de058a49aa32f7e4
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Jul 13 02:13:50 2018 +0000
+Date: Wed May 19 01:24:05 2021 +0000
- upstream: make this use ssh_proxy rather than starting/stopping a
+ upstream: restore blocking status on stdio fds before close
+
+ ssh(1) needs to set file descriptors to non-blocking mode to operate
+ but it was not restoring the original state on exit. This could cause
+ problems with fds shared with other programs via the shell, e.g.
+
+ > $ cat > test.sh << _EOF
+ > #!/bin/sh
+ > {
+ > ssh -Fnone -oLogLevel=verbose ::1 hostname
+ > cat /usr/share/dict/words
+ > } | sleep 10
+ > _EOF
+ > $ ./test.sh
+ > Authenticated to ::1 ([::1]:22).
+ > Transferred: sent 2352, received 2928 bytes, in 0.1 seconds
+ > Bytes per second: sent 44338.9, received 55197.4
+ > cat: stdout: Resource temporarily unavailable
- daemon for each testcase
+ This restores the blocking status for fds 0,1,2 (stdio) before ssh(1)
+ abandons/closes them.
- OpenBSD-Regress-ID: 608b7655ea65b1ba8fff5a13ce9caa60ef0c8166
+ This was reported as bz3280 and GHPR246; ok dtucker@
+
+ OpenBSD-Commit-ID: 8cc67346f05aa85a598bddf2383fcfcc3aae61ce
-commit dbab02f9208d9baa134cec1d007054ec82b96ca9
+commit c4902e1a653c67fea850ec99c7537f358904c0af
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Jul 13 02:13:19 2018 +0000
+Date: Mon May 17 11:43:16 2021 +0000
- upstream: fix leaks in unit test; with this, all unit tests are
+ upstream: fix breakage of -W forwaring introduced in 1.554; reported by
- leak free (as far as valgrind can spot anyway)
+ naddy@ and sthen@, ok sthen@
- OpenBSD-Regress-ID: b824d8b27998365379963440e5d18b95ca03aa17
+ OpenBSD-Commit-ID: f72558e643a26dc4150cff6e5097b5502f6c85fd
-commit 2f6accff5085eb79b0dbe262d8b85ed017d1a51c
-Author: Damien Miller <djm@mindrot.org>
-Date: Fri Jul 13 11:39:25 2018 +1000
+commit afea01381ad1fcea1543b133040f75f7542257e6
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Mon May 17 07:22:45 2021 +0000
- Enable leak checks for unit tests with valgrind
+ upstream: Regenerate moduli.
- Leave the leak checking on unconditionally when running with valgrind.
- The unit tests are leak-free and I want them to stay that way.
+ OpenBSD-Commit-ID: 83c93a2a07c584c347ac6114d6329b18ce515557
-commit e46cfbd9db5e907b821bf4fd0184d4dab99815ee
+commit be2866d6207b090615ff083c9ef212b603816a56
Author: Damien Miller <djm@mindrot.org>
-Date: Fri Jul 13 11:38:59 2018 +1000
+Date: Mon May 17 09:40:23 2021 +1000
- increase timeout to match cfgmatch.sh
+ Handle Android libc returning NULL pw->pw_passwd
- lets test pass under valgrind (on my workstation at least)
+ Reported by Luke Dashjr
-commit 6aa1bf475cf3e7a2149acc5a1e80e904749f064c
-Author: Damien Miller <djm@mindrot.org>
-Date: Thu Jul 12 14:54:18 2018 +1000
+commit 5953c143008259d87342fb5155bd0b8835ba88e5
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Fri May 14 05:20:32 2021 +0000
- rm regress/misc/kexfuzz/*.o in distclean target
+ upstream: fix previous: test saved no_shell_flag, not the one that just
+
+ got clobbered
+
+ OpenBSD-Commit-ID: b8deace085d9d941b2d02f810243b9c302e5355d
-commit eef1447ddb559c03725a23d4aa6d03f40e8b0049
-Author: Damien Miller <djm@mindrot.org>
-Date: Thu Jul 12 14:49:26 2018 +1000
+commit 1e9fa55f4dc4b334651d569d3448aaa3841f736f
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Fri May 14 03:09:48 2021 +0000
- repair !WITH_OPENSSL build
+ upstream: Fix ssh started with ControlPersist incorrectly executing a
+
+ shell when the -N (no shell) option was specified. bz3290 reported by Richard
+ Schwab; patch from markus@ ok me
+
+ OpenBSD-Commit-ID: ea1ea4af16a95687302f7690bdbe36a6aabf87e1
-commit 4d3b2f36fd831941d1627ac587faae37b6d3570f
-Author: Damien Miller <djm@mindrot.org>
-Date: Thu Jul 12 14:49:14 2018 +1000
+commit d1320c492f655d8f5baef8c93899d79dded217a5
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Wed May 12 11:34:30 2021 +0000
- missing headers
+ upstream: Clarify language about moduli. While both ends of the
+
+ connection do need to use the same parameters (ie groups), the DH-GEX
+ protocol takes care of that and both ends do not need the same contents in
+ the moduli file, which is what the previous text suggested. ok djm@ jmc@
+
+ OpenBSD-Commit-ID: f0c18cc8e79c2fbf537a432a9070ed94e96a622a
-commit 3f420a692b293921216549c1099c2e46ff284eae
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Thu Jul 12 14:57:46 2018 +1000
+commit d3cc4d650ce3e59f3e370b101778b0e8f1c02c4d
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Fri May 7 04:11:51 2021 +0000
- Remove key.h from portable files too.
+ upstream: include pid in LogVerbose spam
- Commit 5467fbcb removed key.h so stop including it in portable files
- too. Fixes builds on lots of platforms.
+ OpenBSD-Commit-ID: aacb86f96ee90c7cb84ec27452374285f89a7f00
-commit e2c4af311543093f16005c10044f7e06af0426f0
+commit e3c032333be5fdbbaf2751f6f478e044922b4ec4
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Thu Jul 12 04:35:25 2018 +0000
+Date: Fri May 7 03:09:38 2021 +0000
- upstream: remove prototype to long-gone function
+ upstream: don't sigdie() in signal handler in privsep child process;
- OpenBSD-Commit-ID: 0414642ac7ce01d176b9f359091a66a8bbb640bd
+ this can end up causing sandbox violations per bz3286; ok dtucker@
+
+ OpenBSD-Commit-ID: a7f40b2141dca4287920da68ede812bff7ccfdda
-commit 394a842e60674bf8ee5130b9f15b01452a0b0285
-Author: markus@openbsd.org <markus@openbsd.org>
-Date: Wed Jul 11 18:55:11 2018 +0000
+commit a4039724a3f2abac810735fc95cf9114a3856049
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Fri May 7 09:23:40 2021 +0000
- upstream: treat ssh_packet_write_wait() errors as fatal; ok djm@
+ upstream: Increase ConnectionAttempts from 4 to 10 as the tests
+
+ occasionally time out on heavily loaded hosts.
- OpenBSD-Commit-ID: f88ba43c9d54ed2d911218aa8d3f6285430629c3
+ OpenBSD-Regress-ID: 29a8cdef354fc9da471a301f7f65184770434f3a
-commit 5467fbcb09528ecdcb914f4f2452216c24796790
-Author: markus@openbsd.org <markus@openbsd.org>
-Date: Wed Jul 11 18:53:29 2018 +0000
+commit c0d7e36e979fa3cdb60f5dcb6ac9ad3fd018543b
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Fri May 7 02:26:55 2021 +0000
+
+ upstream: dump out a usable private key string too; inspired by Tyson
+
+ Whitehead
+
+ OpenBSD-Regress-ID: 65572d5333801cb2f650ebc778cbdc955e372058
- upstream: remove legacy key emulation layer; ok djm@
+commit 24fee8973abdf1c521cd2c0047d89e86d9c3fc38
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Fri May 7 02:29:40 2021 +0000
+
+ upstream: correct mistake in spec - the private key blobs are encoded
- OpenBSD-Commit-ID: 2b1f9619259e222bbd4fe9a8d3a0973eafb9dd8d
+ verbatim and not as strings (i.e. no 4-byte length header)
+
+ OpenBSD-Commit-ID: 3606b5d443d72118c5b76c4af6dd87a5d5a4f837
-commit 5dc4c59d5441a19c99e7945779f7ec9051126c25
-Author: martijn@openbsd.org <martijn@openbsd.org>
-Date: Wed Jul 11 08:19:35 2018 +0000
+commit f43859159cc62396ad5d080f0b1f2635a67dac02
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Tue May 4 22:53:52 2021 +0000
- upstream: s/wuth/with/ in comment
+ upstream: Don't pass NULL as a string in debugging as it does not work
- OpenBSD-Commit-ID: 9de41468afd75f54a7f47809d2ad664aa577902c
+ on some platforms in -portable. ok djm@
+
+ OpenBSD-Commit-ID: 937c892c99aa3c9c272a8ed78fa7c2aba3a44fc9
+
+commit ac31aa3c6341905935e75f0539cf4a61bbe99779
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Mon May 3 00:16:45 2021 +0000
-commit 1c688801e9dd7f9889fb2a29bc2b6fbfbc35a11f
+ upstream: more debugging for UpdateHostKeys signature failures
+
+ OpenBSD-Commit-ID: 1ee95f03875e1725df15d5e4bea3e73493d57d36
+
+commit 8e32e97e788e0676ce83018a742203614df6a2b3
Author: Darren Tucker <dtucker@dtucker.net>
-Date: Wed Jul 11 12:12:38 2018 +1000
+Date: Sat May 1 20:07:47 2021 +1000
+
+ Add obsd69 test target.
+
+commit f06893063597c5bb9d9e93f851c4070e77d2fba9
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Fri Apr 30 04:29:53 2021 +0000
- Include stdlib.h for declaration of free.
+ upstream: a little debugging in the main mux process for status
- Fixes build with -Werror on at least Fedora and probably others.
+ confirmation failures in multiplexed sessions
+
+ OpenBSD-Commit-ID: 6e27b87c95176107597035424e1439c3232bcb49
-commit fccfa239def497615f92ed28acc57cfe63da3666
-Author: Damien Miller <djm@mindrot.org>
-Date: Wed Jul 11 10:19:56 2018 +1000
+commit e65cf00da6bc31e5f54603b7feb7252dc018c033
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Fri Apr 30 04:02:52 2021 +0000
- VALGRIND_CHECK_LEAKS logic was backwards :(
+ upstream: Remove now-unused skey function prototypes leftover from
+
+ skey removal.
+
+ OpenBSD-Commit-ID: 2fc36d519fd37c6f10ce74854c628561555a94c3
-commit 416287d45fcde0a8e66eee8b99aa73bd58607588
+commit ae5f9b0d5c8126214244ee6b35aae29c21028133
Author: Darren Tucker <dtucker@dtucker.net>
-Date: Wed Jul 11 10:10:26 2018 +1000
+Date: Thu Apr 29 13:01:50 2021 +1000
- Fix sshbuf_new error path in skey.
+ Wrap sntrup761x25519 inside ifdef.
+
+ From balu.gajjala at gmail.com via bz#3306.
-commit 7aab109b8b90a353c1af780524f1ac0d3af47bab
+commit 70a8dc138a6480f85065cdb239915ad4b7f928cf
Author: Darren Tucker <dtucker@dtucker.net>
-Date: Wed Jul 11 10:06:18 2018 +1000
+Date: Wed Apr 28 14:44:07 2021 +1000
- Supply missing third arg in skey.
-
- During the change to the new buffer api the third arg to
- sshbuf_get_cstring was ommitted. Fixes build when configured with skey.
+ Add status badges for Actions-based tests.
-commit 380320bb72cc353a901790ab04b6287fd335dc4a
+commit 40b59024cc3365815381474cdf4fe423102e391b
Author: Darren Tucker <dtucker@dtucker.net>
-Date: Wed Jul 11 10:03:34 2018 +1000
+Date: Wed Apr 28 12:22:11 2021 +1000
- Supply some more missing "int r" in skey
+ Add obsdsnap (OpenBSD snapshot) test target.
-commit d20720d373d8563ee737d1a45dc5e0804d622dbc
-Author: Damien Miller <djm@mindrot.org>
-Date: Wed Jul 11 09:56:36 2018 +1000
+commit e627067ec8ef9ae8e7a638f4dbac91d52dee3e6d
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Wed Apr 28 11:35:28 2021 +1000
- disable valgrind memleak checking by default
+ Add test building upstream OpenBSD source.
+
+commit 1b8108ebd12fc4ed0fb39ef94c5ba122558ac373
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Tue Apr 27 14:22:20 2021 +1000
+
+ Test against OpenSSL 1.1.0h instead of 1.1.0g.
- Add VALGRIND_CHECK_LEAKS knob to turn it back on.
+ 1.1.0g requires a perl glob module that's not installed by default.
-commit 79c9d35018f3a5e30ae437880b669aa8636cd3cd
+commit 9bc20efd39ce8525be33df3ee009f5a4564224f1
Author: Darren Tucker <dtucker@dtucker.net>
-Date: Wed Jul 11 09:54:00 2018 +1000
+Date: Tue Apr 27 12:37:59 2021 +1000
- Supply missing "int r" in skey code.
+ Use the default VM type for libcrypto ver tests.
-commit 984bacfaacbbe31c35191b828fb5b5b2f0362c36
-Author: sf@openbsd.org <sf@openbsd.org>
-Date: Tue Jul 10 09:36:58 2018 +0000
+commit 9f79e80dc40965c2e73164531250b83b176c1eea
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Tue Apr 27 12:24:10 2021 +1000
- upstream: re-remove some pre-auth compression bits
+ Always build OpenSSL shared.
- This time, make sure to not remove things that are necessary for
- pre-auth compression on the client. Add a comment that pre-auth
- compression is still supported in the client.
+ This is the default for current versions but we need it to test against
+ earlier versions.
+
+commit b3cc9fbdff2782eca79e33e02ac22450dc63bce9
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Tue Apr 27 09:18:02 2021 +1000
+
+ Fix custom OpenSSL tests.
- ok markus@
+ Check out specified OpenSSL version. Install custom libcrypto where
+ configure expects to find it. Remove unneeded OpenSSL config time
+ options. Older OpenSSL versions were not make -j safe so remove it.
+
+commit 77532609874a99a19e3e2eb2d1b7fa93aef963bb
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Mon Apr 26 17:18:25 2021 +1000
+
+ Export CC and CFLAGS for c89 test.
+
+commit 33f62dfbe865f4de77980ab88774bf1eb5e4e040
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Mon Apr 26 17:13:44 2021 +1000
+
+ Add c89 here too.
+
+commit da9d59f526fce58e11cba49cd8eb011dc0bf5677
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Mon Apr 26 15:34:23 2021 +1000
+
+ Add test against OpenSSL w/out ECC.
+
+commit 29e194a752359ebf85bf7fce100f23a0477fc4de
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Mon Apr 26 14:49:59 2021 +1000
+
+ Ensure we can still build with C89.
+
+commit a38016d369d21df5d35f761f2b67e175e132ba22
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Mon Apr 26 14:29:03 2021 +1000
+
+ Interop test agains PuTTY.
+
+commit 095b0307a77be8803768857cc6c0963fa52ed85b
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Mon Apr 26 14:02:03 2021 +1000
+
+ Support testing against arbitary libcrytpo vers.
- OpenBSD-Commit-ID: 282c6fec7201f18a5c333bbb68d9339734d2f784
+ Add tests against various LibreSSL and OpenSSL versions.
-commit 120a1ec74e8d9d29f4eb9a27972ddd22351ddef9
-Author: Damien Miller <djm@mindrot.org>
-Date: Tue Jul 10 19:39:52 2018 +1000
+commit b16082aa110fa7128ece2a9037ff420c4a285317
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Mon Apr 26 13:35:44 2021 +1000
- Adapt portable to legacy buffer API removal
+ Add fbsd10 test target.
-commit 0f3958c1e6ffb8ea4ba27e2a97a00326fce23246
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Tue Jul 10 09:13:30 2018 +0000
+commit 2c805f16b24ea37cc051c6018fcb05defab6e57a
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Sun Apr 25 14:15:02 2021 +1000
- upstream: kerberos/gssapi fixes for buffer removal
+ Disable compiler hardening on nbsd4.
- OpenBSD-Commit-ID: 1cdf56fec95801e4563c47f21696f04cd8b60c4c
+ The system compiler supports -fstack-protector-all, but using it will
+ result in an internal compiler error on some files.
-commit c74ae8e7c45f325f3387abd48fa7dfef07a08069
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Tue Jul 10 06:45:29 2018 +0000
+commit 6a5d39305649da5dff1934ee54292ee0cebd579d
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Sun Apr 25 13:01:34 2021 +1000
+
+ Add nbsd3, nbsd4 and nbsd9 test targets.
+
+commit d1aed05bd2e4ae70f359a394dc60a2d96b88f78c
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Sat Apr 24 22:03:46 2021 +1000
+
+ Comment out nbsd2 test target for now.
+
+commit a6b4ec94e5bd5a8a18cd2c9942d829d2e5698837
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Sat Apr 24 17:52:24 2021 +1000
+
+ Add OPENBSD ORIGINAL marker.
- upstream: buffer.[ch] and bufaux.c are no more
+commit 3737c9f66ee590255546c4b637b6d2be669a11eb
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Fri Apr 23 19:49:46 2021 +1000
+
+ Replace "==" (a bashism) with "=".
+
+commit a116b6f5be17a1dd345b7d54bf8aa3779a28a0df
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Fri Apr 23 16:34:48 2021 +1000
+
+ Add nbsd2 test target.
+
+commit 196bf2a9bb771f45d9b0429cee7d325962233c44
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Fri Apr 23 14:54:10 2021 +1000
+
+ Add obsd68 test target.
+
+commit e3ba6574ed69e8b7af725cf5e8a9edaac04ff077
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Fri Apr 23 14:53:32 2021 +1000
+
+ Remove dependency on bash.
+
+commit db1f9ab8feb838aee9f5b99c6fd3f211355dfdcf
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Fri Apr 23 14:41:13 2021 +1000
+
+ Add obsd67 test target.
+
+commit c039a6bf79192fe1daa9ddcc7c87dd98e258ae7c
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Fri Apr 23 11:08:23 2021 +1000
+
+ Re-add macos-11.0 test target.
+
+commit a6db3a47b56adb76870d59225ffb90a65bc4daf2
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Fri Apr 23 10:28:28 2021 +1000
+
+ Add openindiana test target.
+
+commit 3fe7e73b025c07eda46d78049f1da8ed7dfc0c69
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Fri Apr 23 10:26:35 2021 +1000
+
+ Test krb5 on Solaris 11 too.
+
+commit f57fbfe5eb02df1a91f1a237c4d27165afd87c13
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Thu Apr 22 22:27:26 2021 +1000
+
+ Don't always set SUDO.
- OpenBSD-Commit-ID: d1a1852284e554f39525eb4d4891b207cfb3d3a0
+ Rely on sourcing configs to set as appropriate.
+
+commit e428f29402fb6ac140b52f8f12e06ece7bb104a0
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Thu Apr 22 22:26:08 2021 +1000
+
+ Remove now-unused 2nd arg to configs.
-commit a881e5a133d661eca923fb0633a03152ab2b70b2
+commit cb4ff640d79b3c736879582139778f016bbb2cd7
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Wed Apr 21 01:08:04 2021 +1000
+
+ Add win10 test target.
+
+commit 4457837238072836b2fa3107d603aac809624983
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Tue Apr 20 23:31:29 2021 +1000
+
+ Add nbsd8 test target.
+
+commit bd4fba22e14da2fa196009010aabec5a8ba9dd42
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Sat Apr 17 09:55:47 2021 +1000
+
+ Add obsd51 target.
+
+commit 9403d0e805c77a5741ea8c3281bbe92558c2f125
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Fri Apr 16 18:14:25 2021 +1000
+
+ Add fbsd13 target.
+
+commit e86968280e358e62649d268d41f698d64d0dc9fa
+Author: Damien Miller <djm@mindrot.org>
+Date: Fri Apr 16 13:55:25 2021 +1000
+
+ depend
+
+commit 2fb25ca11e8b281363a2a2a4dec4c497a1475d9a
+Author: Damien Miller <djm@mindrot.org>
+Date: Fri Apr 16 13:53:02 2021 +1000
+
+ crank version in README and RPM spec files
+
+commit b2b60ebab0cb77b5bc02d364d72e13db882f33ae
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Tue Jul 10 06:43:52 2018 +0000
+Date: Fri Apr 16 03:42:00 2021 +0000
- upstream: one mention of Buffer that almost got away :)
+ upstream: openssh-8.6
- OpenBSD-Commit-ID: 30d7c27a90b4544ad5dfacf654595710cd499f02
+ OpenBSD-Commit-ID: b5f3e133c846127ec114812248bc17eff07c3e19
-commit 49f47e656b60bcd1d1db98d88105295f4b4e600d
+commit faf2b86a46c9281d237bcdec18c99e94a4eb820a
Author: markus@openbsd.org <markus@openbsd.org>
-Date: Mon Jul 9 21:59:10 2018 +0000
+Date: Thu Apr 15 16:24:31 2021 +0000
- upstream: replace cast with call to sshbuf_mutable_ptr(); ok djm@
+ upstream: do not pass file/func to monitor; noted by Ilja van Sprundel;
- OpenBSD-Commit-ID: 4dfe9d29fa93d9231645c89084f7217304f7ba29
+ ok djm@
+
+ OpenBSD-Commit-ID: 85ae5c063845c410283cbdce685515dcd19479fa
-commit cb30cd47041edb03476be1c8ef7bc1f4b69d1555
-Author: markus@openbsd.org <markus@openbsd.org>
-Date: Mon Jul 9 21:56:06 2018 +0000
+commit 2dc328023f60212cd29504fc05d849133ae47355
+Author: Damien Miller <djm@mindrot.org>
+Date: Wed Apr 14 11:42:55 2021 +1000
- upstream: remove legacy buffer API emulation layer; ok djm@
+ sshd don't exit on transient read errors
- OpenBSD-Commit-ID: 2dd5dc17cbc23195be4299fa93be2707a0e08ad9
+ openssh-8.5 introduced a regression that would cause sshd to exit
+ because of transient read errors on the network socket (e.g. EINTR,
+ EAGAIN). Reported by balu.gajjala AT gmail.com via bz3297
-commit 235c7c4e3bf046982c2d8242f30aacffa01073d1
-Author: markus@openbsd.org <markus@openbsd.org>
-Date: Mon Jul 9 21:53:45 2018 +0000
+commit d5d6b7d76d171a2e6861609dcd92e714ee62ad88
+Author: Damien Miller <djm@mindrot.org>
+Date: Sat Apr 10 18:45:00 2021 +1000
- upstream: sshd: switch monitor to sshbuf API; lots of help & ok
+ perform report_failed_grab() inline
+
+commit ea996ce2d023aa3c6d31125e2c3ebda1cb42db8c
+Author: Damien Miller <djm@mindrot.org>
+Date: Sat Apr 10 18:22:57 2021 +1000
+
+ dedicated gnome-ssk-askpass3 source
- djm@
+ Compatibility with Wayland requires that we use the gdk_seat_grab()
+ API for grabbing mouse/keyboard, however these API don't exist in
+ Gtk+2.
+
+ This branches gnome-ssk-askpass2.c => gnome-ssk-askpass3.c and
+ makes the changes to use the gdk_seat_grab() instead of grabbing
+ mouse/focus separately via GDK.
- OpenBSD-Commit-ID: d89bd02d33974fd35ca0b8940d88572227b34a48
+ In the future, we can also use the branched file to avoid some
+ API that has been soft-deprecated in GTK+3, e.g. gtk_widget_modify_fg
-commit b8d9214d969775e409e1408ecdf0d58fad99b344
-Author: markus@openbsd.org <markus@openbsd.org>
-Date: Mon Jul 9 21:37:55 2018 +0000
+commit bfa5405da05d906ffd58216eb77c4375b62d64c2
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Thu Apr 8 15:18:15 2021 +1000
- upstream: sshd: switch GSSAPI to sshbuf API; ok djm@
+ Ensure valgrind-out exists.
- OpenBSD-Commit-ID: e48449ab4be3f006f7ba33c66241b7d652973e30
+ Normally the regress tests would create it, but running the unit tests
+ on their own would fail because the directory did not exist.
-commit c7d39ac8dc3587c5f05bdd5bcd098eb5c201c0c8
-Author: markus@openbsd.org <markus@openbsd.org>
-Date: Mon Jul 9 21:35:50 2018 +0000
+commit 1f189181f3ea09a9b08aa866f78843fec800874f
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Thu Apr 8 15:17:19 2021 +1000
- upstream: sshd: switch authentication to sshbuf API; ok djm@
+ Pass OBJ to unit test make invocation.
- OpenBSD-Commit-ID: 880aa06bce4b140781e836bb56bec34873290641
+ At least the Valgrind unit tests uses $OBJ.
-commit c3cb7790e9efb14ba74b2d9f543ad593b3d55b31
-Author: markus@openbsd.org <markus@openbsd.org>
-Date: Mon Jul 9 21:29:36 2018 +0000
+commit f42b550c281d28bd19e9dd6ce65069164f3482b0
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Thu Apr 8 14:20:12 2021 +1000
- upstream: sshd: switch config to sshbuf API; ok djm@
-
- OpenBSD-Commit-ID: 72b02017bac7feac48c9dceff8355056bea300bd
+ Add pattern for valgrind-unit.
-commit 2808d18ca47ad3d251836c555f0e22aaca03d15c
-Author: markus@openbsd.org <markus@openbsd.org>
-Date: Mon Jul 9 21:26:02 2018 +0000
+commit 19e534462710e98737478fd9c44768b50c27c4c6
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Thu Apr 8 13:31:08 2021 +1000
- upstream: sshd: switch loginmsg to sshbuf API; ok djm@
+ Run unit tests under valgrind.
- OpenBSD-Commit-ID: f3cb4e54bff15c593602d95cc43e32ee1a4bac42
+ Run a separate build for the unit tests under Valgrind. They take long
+ enough that running in parallel with the other Valgrind tests helps.
-commit 89dd615b8b531979be63f05f9d5624367c9b28e6
-Author: markus@openbsd.org <markus@openbsd.org>
-Date: Mon Jul 9 21:20:26 2018 +0000
+commit 80032102d05e866dc2a48a5caf760cf42c2e090e
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Thu Apr 8 13:25:57 2021 +1000
- upstream: ttymodes: switch to sshbuf API; ok djm@
+ ifdef out MIN and MAX.
- OpenBSD-Commit-ID: 5df340c5965e822c9da21e19579d08dea3cbe429
+ In -portable, defines.h ensures that these are defined, so redefining
+ potentially causes a warning. We don't just delete it to make any
+ future code syncs a little but easier. bz#3293.
-commit f4608a7065480516ab46214f554e5f853fb7870f
-Author: markus@openbsd.org <markus@openbsd.org>
-Date: Mon Jul 9 21:18:10 2018 +0000
+commit d1bd184046bc310c405f45da3614a1dc5b3e521a
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Wed Apr 7 10:23:51 2021 +1000
- upstream: client: switch mux to sshbuf API; with & ok djm@
+ Remove only use of warn().
- OpenBSD-Commit-ID: 5948fb98d704f9c4e075b92edda64e0290b5feb2
+ The warn() function is only used in one place in portable and does not
+ exist upstream. Upgrade the only instance it's used to fail()
+ (the privsep/sandbox+proxyconnect, from back when that was new) and
+ remove the now-unused function.
-commit cecee2d607099a7bba0a84803e2325d15be4277b
-Author: markus@openbsd.org <markus@openbsd.org>
-Date: Mon Jul 9 21:03:30 2018 +0000
+commit fea8f4b1aa85026ad5aee5ad8e1599a8d5141fe0
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Wed Apr 7 10:18:32 2021 +1000
- upstream: client: switch to sshbuf API; ok djm@
+ Move make_tmpdir() into portable-specific area.
- OpenBSD-Commit-ID: 60cb0356114acc7625ab85105f6f6a7cd44a8d05
+ Reduces diff vs OpenBSD and makes it more likely diffs will apply
+ cleanly.
-commit ff55f4ad898137d4703e7a2bcc81167dfe8e9324
-Author: markus@openbsd.org <markus@openbsd.org>
-Date: Mon Jul 9 20:39:28 2018 +0000
+commit 13e5fa2acffd26e754c6ee1d070d0afd035d4cb7
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Tue Apr 6 23:57:56 2021 +0000
- upstream: pkcs11: switch to sshbuf API; ok djm@
+ upstream: Add TEST_SSH_ELAPSED_TIMES environment variable to print the
- OpenBSD-Commit-ID: 98cc4e800f1617c51caf59a6cb3006f14492db79
+ elapsed time in seconds of each test. This depends on "date +%s" which is
+ not specified by POSIX but is commonly implemented.
+
+ OpenBSD-Regress-ID: ec3c8c19ff49b2192116a0a646ee7c9b944e8a9c
-commit 168b46f405d6736960ba7930389eecb9b6710b7e
-Author: sf@openbsd.org <sf@openbsd.org>
-Date: Mon Jul 9 13:37:10 2018 +0000
+commit ef4f46ab4387bb863b471bad124d46e8d911a79a
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Wed Apr 7 09:59:15 2021 +1000
- upstream: Revert previous two commits
+ Move the TEST_SSH_PORT section down a bit.
- It turns out we still support pre-auth compression on the client.
- Therefore revert the previous two commits:
+ This groups the portable-specific changes together and makes it a
+ little more likely that patches will apply cleanly.
+
+commit 3674e33fa70dfa1fe69b345bf576113af7b7be11
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Wed Apr 7 10:05:10 2021 +1000
+
+ Further split Valgrind tests.
- date: 2018/07/06 09:06:14; author: sf; commitid: yZVYKIRtUZWD9CmE;
- Rename COMP_DELAYED to COMP_ZLIB
+ Even split in two, the Valgrind tests take by far the longest to run,
+ so split them four ways to further increase parallelism.
+
+commit 961af266b861e30fce1e26170ee0dbb5bf591f29
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Tue Apr 6 23:24:30 2021 +0000
+
+ upstream: include "ssherr.h" not <ssherr.h>; from Balu Gajjala via
- Only delayed compression is supported nowadays.
+ bz#3292
- ok markus@
+ OpenBSD-Commit-ID: e9535cd9966eb2e69e73d1ede1f44905c30310bd
+
+commit e7d0a285dbdd65d8df16123ad90f15e91862f959
+Author: Damien Miller <djm@mindrot.org>
+Date: Wed Apr 7 08:50:38 2021 +1000
+
+ wrap struct rlimit in HAVE_GETRLIMIT too
+
+commit f283a6c2e0a9bd9369e18462acd00be56fbe5b0d
+Author: Damien Miller <djm@mindrot.org>
+Date: Wed Apr 7 08:20:35 2021 +1000
+
+ wrap getrlimit call in HAVE_GETRLIMIT; bz3291
+
+commit 679bdc4a5c9244f427a7aee9c14b0a0ed086da1f
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Tue Apr 6 09:07:33 2021 +0000
+
+ upstream: Don't check return value of unsetenv(). It's part of the
- date: 2018/07/06 09:05:01; author: sf; commitid: rEGuT5UgI9f6kddP;
- Remove leftovers from pre-authentication compression
+ environment setup and not part of the actual test, and some platforms
+ -portable runs on declare it as returning void, which prevents the test from
+ compiling.
- Support for this has been removed in 2016.
- COMP_DELAYED will be renamed in a later commit.
+ OpenBSD-Regress-ID: 24f08543ee3cdebc404f2951f3e388cc82b844a1
+
+commit 320af2f3de6333aa123f1b088eca146a245e968a
+Author: jmc@openbsd.org <jmc@openbsd.org>
+Date: Sun Apr 4 11:36:56 2021 +0000
+
+ upstream: remove stray inserts; from matthias schmidt
- ok markus@
+ OpenBSD-Commit-ID: 2c36ebdc54e14bbf1daad70c6a05479a073d5c63
+
+commit 801f710953b24dd2f21939171c622eac77c7484d
+Author: jmc@openbsd.org <jmc@openbsd.org>
+Date: Sun Apr 4 06:11:24 2021 +0000
+
+ upstream: missing comma; from kawashima james
- OpenBSD-Commit-ID: cdfef526357e4e1483c86cf599491b2dafb77772
+ OpenBSD-Commit-ID: 31cec6bf26c6db4ffefc8a070715ebef274e68ea
-commit ab39267fa1243d02b6c330615539fc4b21e17dc4
-Author: sf@openbsd.org <sf@openbsd.org>
-Date: Fri Jul 6 09:06:14 2018 +0000
+commit b3ca08cb174266884d44ec710a84cd64c12414ea
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Mon Apr 5 23:46:42 2021 +1000
+
+ Install libcbor with libfido2.
+
+commit f3ca8af87a4c32ada660da12ae95cf03d190c083
+Author: Damien Miller <djm@mindrot.org>
+Date: Sat Apr 3 18:21:08 2021 +1100
- upstream: Rename COMP_DELAYED to COMP_ZLIB
+ enable authopt and misc unit tests
- Only delayed compression is supported nowadays.
+ Neither were wired into the build, both required some build
+ adaptations for -portable
+
+commit dc1b45841fb97e3d7f655ddbcfef3839735cae5f
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Sat Apr 3 06:58:30 2021 +0000
+
+ upstream: typos in comments; GHPR#180 from Vill
- ok markus@
+ =?UTF-8?q?e=20Skytt=C3=A4?=
+ MIME-Version: 1.0
+ Content-Type: text/plain; charset=UTF-8
+ Content-Transfer-Encoding: 8bit
- OpenBSD-Commit-ID: 5b1dbaf3d9a4085aaa10fec0b7a4364396561821
+ OpenBSD-Commit-ID: 93c732381ae0e2b680c79e67c40c1814b7ceed2c
-commit 95db395d2e56a6f868193aead6cadb2493f036c6
-Author: sf@openbsd.org <sf@openbsd.org>
-Date: Fri Jul 6 09:05:01 2018 +0000
+commit 53ea05e09b04fd7b6dea66b42b34d65fe61b9636
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Sat Apr 3 06:55:52 2021 +0000
- upstream: Remove leftovers from pre-authentication compression
+ upstream: sync CASignatureAlgorithms lists with reality. GHPR#174 from
- Support for this has been removed in 2016.
- COMP_DELAYED will be renamed in a later commit.
+ Matt Hazinski
- ok markus@
-
- OpenBSD-Commit-ID: 6a99616c832627157113fcb0cf5a752daf2e6b58
+ OpenBSD-Commit-ID: f05e4ca54d7e67b90fe58fe1bdb1d2a37e0e2696
+
+commit 57ed647ee07bb883a2f2264231bcd1df6a5b9392
+Author: Damien Miller <djm@mindrot.org>
+Date: Sat Apr 3 17:47:37 2021 +1100
-commit f28a4d5cd24c4aa177e96b4f96957991e552cb70
-Author: sf@openbsd.org <sf@openbsd.org>
-Date: Fri Jul 6 09:03:02 2018 +0000
+ polish whitespace for portable files
- upstream: Remove unused ssh_packet_start_compression()
+commit 31d8d231eb9377df474746a822d380c5d68d7ad6
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Sat Apr 3 06:18:40 2021 +0000
+
+ upstream: highly polished whitespace, mostly fixing spaces-for-tab
- ok markus@
+ and bad indentation on continuation lines. Prompted by GHPR#185
- OpenBSD-Commit-ID: 9d34cf2f59aca5422021ae2857190578187dc2b4
+ OpenBSD-Commit-ID: e5c81f0cbdcc6144df1ce468ec1bac366d8ad6e9
-commit 872517ddbb72deaff31d4760f28f2b0a1c16358f
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Fri Jul 6 13:32:02 2018 +1000
+commit 34afde5c73b5570d6f8cce9b49993b23b77bfb86
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Sat Apr 3 05:54:14 2021 +0000
- Defer setting bufsiz in getdelim.
+ upstream: whitespace (tab after space)
- Do not write to bufsiz until we are sure the malloc has succeeded,
- in case any callers rely on it (which they shouldn't). ok djm@
+ OpenBSD-Commit-ID: 0e2b3f7674e985d3f7c27ff5028e690ba1c2efd4
-commit 3deb56f7190a414dc264e21e087a934fa1847283
+commit 7cd262c1c5a08cc7f4f30e3cab108ef089d0a57b
Author: Darren Tucker <dtucker@dtucker.net>
-Date: Thu Jul 5 13:32:01 2018 +1000
+Date: Sat Apr 3 16:59:10 2021 +1100
+
+ Save config.h and config.log on failure too.
+
+commit 460aee9298f365357e9fd26851c22e0dca51fd6a
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Sat Apr 3 05:46:41 2021 +0000
- Fix other callers of read_environment_file.
+ upstream: fix incorrect plural; from Ville Skyt
- read_environment_file recently gained an extra argument Some platform
- specific code also calls it so add the argument to those too. Fixes
- build on Solaris and AIX.
+ =?UTF-8?q?t=C3=A4=20via=20GHPR#181?=
+ MIME-Version: 1.0
+ Content-Type: text/plain; charset=UTF-8
+ Content-Transfer-Encoding: 8bit
+
+ OpenBSD-Commit-ID: 92f31754c6296d8f403d7c293e09dc27292d22c9
-commit 314908f451e6b2d4ccf6212ad246fa4619c721d3
+commit 082804c14e548cada75c81003a3c68ee098138ee
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Wed Jul 4 13:51:45 2018 +0000
+Date: Sat Apr 3 05:40:39 2021 +0000
- upstream: deal with API rename: match_filter_list() =>
+ upstream: ensure that pkcs11_del_provider() is called before exit -
+
+ some PKCS#11 providers get upset if C_Initialize is not matched with
+ C_Finalize.
- match_filter_blacklist()
+ From Adithya Baglody via GHPR#234; ok markus
- OpenBSD-Regress-ID: 2da342be913efeb51806351af906fab01ba4367f
+ OpenBSD-Commit-ID: f8e770e03b416ee9a58f9762e162add900f832b6
-commit 89f54cdf6b9cf1cf5528fd33897f1443913ddfb4
+commit 464ebc82aa926dd132ec75a0b064574ef375675e
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Wed Jul 4 13:51:12 2018 +0000
+Date: Sat Apr 3 05:28:43 2021 +0000
- upstream: exercise new expansion behaviour of
+ upstream: unused variable
- PubkeyAcceptedKeyTypes and, by proxy, test kex_assemble_names()
+ OpenBSD-Commit-ID: 85f6a394c8e0f60d15ecddda75176f112007b205
+
+commit dc3c0be8208c488e64a8bcb7d9efad98514e0ffb
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Sat Apr 3 05:21:46 2021 +0000
+
+ upstream: Fix two problems in string->argv conversion: 1) multiple
- ok markus@
+ backslashes were not being dequoted correctly and 2) quoted space in the
+ middle of a string was being incorrectly split.
+ MIME-Version: 1.0
+ Content-Type: text/plain; charset=UTF-8
+ Content-Transfer-Encoding: 8bit
+
+ A unit test for these cases has already been committed
+
+ prompted by and based on GHPR#223 by Eero Häkkinen; ok markus@
- OpenBSD-Regress-ID: 292978902e14d5729aa87e492dd166c842f72736
+ OpenBSD-Commit-ID: d7ef27abb4eeeaf6e167e9312e4abe9e89faf1e4
+
+commit f75bcbba58a08c670727ece5e3f8812125969799
+Author: Damien Miller <djm@mindrot.org>
+Date: Sat Apr 3 16:22:48 2021 +1100
+
+ missing bits from 259d648e
-commit 187633f24c71564e970681c8906df5a6017dcccf
+commit 4cbc4a722873d9b68cb5496304dc050d7168df78
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Tue Jul 3 13:53:26 2018 +0000
+Date: Wed Mar 31 21:59:26 2021 +0000
- upstream: add a comment that could have saved me 45 minutes of wild
+ upstream: cannot effectively test posix-rename extension after
- goose chasing
+ changes in feature advertisment.
- OpenBSD-Regress-ID: d469b29ffadd3402c090e21b792d627d46fa5297
+ OpenBSD-Regress-ID: 5e390bf88d379162aaa81b60ed86b34cb0c54d29
-commit 312d2f2861a2598ed08587cb6c45c0e98a85408f
+commit 259d648e63e82ade4fe2c2c73c8b67fe57d9d049
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Wed Jul 4 13:49:31 2018 +0000
+Date: Fri Mar 19 04:23:50 2021 +0000
- upstream: repair PubkeyAcceptedKeyTypes (and friends) after RSA
+ upstream: add a test for misc.c:argv_split(), currently fails
- signature work - returns ability to add/remove/specify algorithms by
- wildcard.
+ OpenBSD-Regress-ID: ad6b96d6ebeb9643b698b3575bdd6f78bb144200
+
+commit 473ddfc2d6b602cb2d1d897e0e5c204de145cd9a
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Fri Mar 19 03:25:01 2021 +0000
+
+ upstream: split
+
+ OpenBSD-Regress-ID: f6c03c0e4c58b3b9e04b161757b8c10dc8378c34
+
+commit 1339800fef8d0dfbfeabff71b34670105bcfddd2
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Wed Mar 31 22:16:34 2021 +0000
+
+ upstream: Use new limits@openssh.com protocol extension to let the
- Algorithm lists are now fully expanded when the server/client configs
- are finalised, so errors are reported early and the config dumps
- (e.g. "ssh -G ...") now list the actual algorithms selected.
+ client select good limits based on what the server supports. Split the
+ download and upload buffer sizes to allow them to be chosen independently.
- Clarify that, while wildcards are accepted in algorithm lists, they
- aren't full pattern-lists that support negation.
+ In practice (and assuming upgraded sftp/sftp-server at each end), this
+ increases the download buffer 32->64KiB and the upload buffer
+ 32->255KiB.
- (lots of) feedback, ok markus@
+ Patches from Mike Frysinger; ok dtucker@
- OpenBSD-Commit-ID: a8894c5c81f399a002f02ff4fe6b4fa46b1f3207
+ OpenBSD-Commit-ID: ebd61c80d85b951b794164acc4b2f2fd8e88606c
-commit 303af5803bd74bf05d375c04e1a83b40c30b2be5
+commit 6653c61202d104e59c8e741329fcc567f7bc36b8
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Tue Jul 3 11:43:49 2018 +0000
+Date: Wed Mar 31 21:58:07 2021 +0000
- upstream: some magic for RSA-SHA2 checks
+ upstream: do not advertise protocol extensions that have been
- OpenBSD-Regress-ID: e5a9b11368ff6d86e7b25ad10ebe43359b471cd4
+ disallowed by the command-line options (e.g. -p/-P/-R); ok dtucker@
+
+ OpenBSD-Commit-ID: 3a8a76b3f5131741aca4b41bfab8d101c9926205
-commit 7d68e262944c1fff1574600fe0e5e92ec8b398f5
+commit 71241fc05db4bbb11bb29340b44b92e2575373d8
Author: Damien Miller <djm@mindrot.org>
-Date: Tue Jul 3 23:27:11 2018 +1000
+Date: Mon Mar 29 15:14:25 2021 +1100
- depend
+ gnome-ssh-askpass3 is a valid target here
-commit b4d4eda633af433d20232cbf7e855ceac8b83fe5
+commit 8a9520836e71830f4fccca066dba73fea3d16bda
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Tue Jul 3 13:20:25 2018 +0000
+Date: Fri Mar 19 02:22:34 2021 +0000
- upstream: some finesse to fix RSA-SHA2 certificate authentication
+ upstream: return non-zero exit status when killed by signal; bz#3281 ok
- for certs hosted in ssh-agent
+ dtucker@
- OpenBSD-Commit-ID: e5fd5edd726137dda2d020e1cdebc464110a010f
+ OpenBSD-Commit-ID: 117b31cf3c807993077b596bd730c24da9e9b816
-commit d78b75df4a57e0f92295f24298e5f2930e71c172
+commit 1269b8a686bf1254b03cd38af78167a04aa6ec88
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Tue Jul 3 13:07:58 2018 +0000
+Date: Fri Mar 19 02:18:28 2021 +0000
- upstream: check correct variable; unbreak agent keys
+ upstream: increase maximum SSH2_FXP_READ to match the maximum
+
+ packet size. Also handle zero-length reads that are borderline nonsensical
+ but not explicitly banned by the spec. Based on patch from Mike Frysinger,
+ feedback deraadt@ ok dtucker@
- OpenBSD-Commit-ID: c36981fdf1f3ce04966d3310826a3e1e6233d93e
+ OpenBSD-Commit-ID: 4e67d60d81bde7b84a742b4ee5a34001bdf80d9c
-commit 2f30300c5e15929d0e34013f38d73e857f445e12
+commit 860b67604416640e8db14f365adc3f840aebcb1f
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Tue Jul 3 11:42:12 2018 +0000
+Date: Tue Mar 16 06:15:43 2021 +0000
- upstream: crank version number to 7.8; needed for new compat flag
+ upstream: don't let logging clobber errno before use
- for prior version; part of RSA-SHA2 strictification, ok markus@
-
- OpenBSD-Commit-ID: 84a11fc0efd2674c050712336b5093f5d408e32b
+ OpenBSD-Commit-ID: ce6cca370005c270c277c51c111bb6911e1680ec
-commit 4ba0d54794814ec0de1ec87987d0c3b89379b436
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Tue Jul 3 11:39:54 2018 +0000
+commit 5ca8a9216559349c56e09039c4335636fd85c241
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Sat Mar 13 14:40:43 2021 +1100
- upstream: Improve strictness and control over RSA-SHA2 signature
+ Only call dh_set_moduli_file if using OpenSSL.
- In ssh, when an agent fails to return a RSA-SHA2 signature when
- requested and falls back to RSA-SHA1 instead, retry the signature to
- ensure that the public key algorithm sent in the SSH_MSG_USERAUTH
- matches the one in the signature itself.
+ Fixes link failure when configuring --without-openssl since dh.c is not
+ linked in.
+
+commit 867a7dcf003c51d5a83f83565771a35f0d9530ac
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Sat Mar 13 13:52:53 2021 +1100
+
+ Don't install moduli during tests.
- In sshd, strictly enforce that the public key algorithm sent in the
- SSH_MSG_USERAUTH message matches what appears in the signature.
+ Now that we have TEST_SSH_MODULI_FILE pointing to the moduli in the
+ soure directory we don't need to install the file to prevent warnings
+ about it being missing.
+
+commit 0c054538fccf92b4a028008321d3711107bee6d5
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Sat Mar 13 13:51:26 2021 +1100
+
+ Point TEST_SSH_MODULI_FILE at our own moduli.
- Make the sshd_config PubkeyAcceptedKeyTypes and
- HostbasedAcceptedKeyTypes options control accepted signature algorithms
- (previously they selected supported key types). This allows these
- options to ban RSA-SHA1 in favour of RSA-SHA2.
+ This will allow the test to run without requiring a moduli file
+ installed at the configured default path.
+
+commit 4d48219c72ab0c71238806f057f0e9630b7dd25c
+Author: jsg@openbsd.org <jsg@openbsd.org>
+Date: Fri Mar 12 05:18:01 2021 +0000
+
+ upstream: spelling
- Add new signature algorithms "rsa-sha2-256-cert-v01@openssh.com" and
- "rsa-sha2-512-cert-v01@openssh.com" to force use of RSA-SHA2 signatures
- with certificate keys.
+ OpenBSD-Commit-ID: 478bc3db04f62f1048ed6e1765400f3ab325e60f
+
+commit 88057eb6df912abf2678ea5c846d9d9cbc92752c
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Fri Mar 12 04:08:19 2021 +0000
+
+ upstream: Add ModuliFile keyword to sshd_config to specify the
- feedback and ok markus@
+ location of the "moduli" file containing the groups for DH-GEX. This will
+ allow us to run tests against arbitrary moduli files without having to
+ install them. ok djm@
- OpenBSD-Commit-ID: c6e9f6d45eed8962ad502d315d7eaef32c419dde
+ OpenBSD-Commit-ID: 8df99d60b14ecaaa28f3469d01fc7f56bff49f66
-commit 95344c257412b51199ead18d54eaed5bafb75617
+commit f07519a2af96109325b5a48b1af18b57601074ca
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Tue Jul 3 10:59:35 2018 +0000
+Date: Fri Mar 12 03:43:40 2021 +0000
- upstream: allow sshd_config PermitUserEnvironment to accept a
+ upstream: pwcopy() struct passwd that we're going to reuse across a
- pattern-list of whitelisted environment variable names in addition to yes|no.
+ bunch of library calls; bz3273 ok dtucker@
- bz#1800, feedback and ok markus@
+ OpenBSD-Commit-ID: b6eafa977b2e44607b1b121f5de855107809b762
+
+commit 69d6d4b0c8a88d3d1288415605f36e2df61a2f12
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Wed Mar 10 06:32:27 2021 +0000
+
+ upstream: Import regenerated moduli file.
- OpenBSD-Commit-ID: 77dc2b468e0bf04b53f333434ba257008a1fdf24
+ OpenBSD-Commit-ID: 7ac6c252d2a5be8fbad4c66d9d35db507c9dac5b
-commit 6f56fe4b9578b0627667f8bce69d4d938a88324c
-Author: millert@openbsd.org <millert@openbsd.org>
-Date: Tue Jun 26 11:23:59 2018 +0000
+commit e5895e8ecfac65086ea6b34d0d168409a66a15e1
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Wed Mar 10 04:58:45 2021 +0000
- upstream: Fix "WARNING: line 6 disappeared in /etc/moduli, giving up"
+ upstream: no need to reset buffer after send_msg() as that is done
- when choosing a prime. An extra increment of linenum snuck in as part of the
- conversion to getline(). OK djm@ markus@
+ for us; patch from Mike Frysinger
- OpenBSD-Commit-ID: 0019225cb52ed621b71cd9f19ee2e78e57e3dd38
+ OpenBSD-Commit-ID: 565516495ff8362a38231e0f1a087b8ae66da59c
-commit 1eee79a11c1b3594f055b01e387c49c9a6e80005
+commit 721948e67488767df0fa0db71ff2578ee2bb9210
Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Mon Jul 2 14:13:30 2018 +0000
+Date: Sat Mar 13 01:52:16 2021 +0000
- upstream: One ampersand is enough to backgroud an process. OpenBSD
+ upstream: Add TEST_SSH_MODULI_FILE variable to allow overriding of the
- doesn't seem to mind, but some platforms in -portable object to the second.
+ moduli file used during the test run.
- OpenBSD-Regress-ID: d6c3e404871764343761dc25c3bbe29c2621ff74
+ OpenBSD-Regress-ID: be10f785263120edb64fc87db0e0d6570a10220a
-commit 6301e6c787d4e26bfae1119ab4f747bbcaa94e44
+commit 82fef71e20ffef425b932bec26f5bc46aa1ed41c
Author: Darren Tucker <dtucker@dtucker.net>
-Date: Mon Jul 2 21:16:58 2018 +1000
+Date: Fri Mar 12 15:58:57 2021 +1100
- Add implementation of getline.
+ Allow (but return EACCES) fstatat64 in sandbox.
- Add getline for the benefit of platforms that don't have it. Sourced
- from NetBSD (OpenBSD's implementation is a little too chummy with the
- internals of FILE).
+ This is apparently used in some configurations of OpenSSL when glibc
+ has getrandom(). bz#3276, patch from Kris Karas, ok djm@
-commit 84623e0037628f9992839063151f7a9f5f13099a
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Tue Jun 26 02:02:36 2018 +0000
+commit 1cd67ee15ce3d192ab51be22bc4872a6a7a4b6d9
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Fri Mar 12 13:16:10 2021 +1100
- upstream: whitespace
+ Move generic includes outside of ifdef.
- OpenBSD-Commit-ID: 9276951caf4daf555f6d262e95720e7f79244572
+ This ensures that the macros in log.h are defined in the case where
+ either of --with-solaris-projects or --with-solaris-privs are used
+ without --with-solaris-contracts. bz#3278.
-commit 90e51d672711c19a36573be1785caf35019ae7a8
+commit 2421a567a8862fe5102a4e7d60003ebffd1313dd
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Wed Mar 10 17:41:21 2021 +1100
+
+ Import regenerated moduli file.
+
+commit e99080c05d9d48dbbdb022538533d53ae1bd567d
+Author: millert@openbsd.org <millert@openbsd.org>
+Date: Sat Mar 6 20:36:31 2021 +0000
+
+ upstream: Fix PRINT macro, the suffix param to sshlog() was missing.
+
+ Also remove redundant __func__ prefix from PRINT calls as the macro already
+ adds __FILE__, __func__ and __LINE__. From Christos Zoulas. OK dtucker@
+
+ OpenBSD-Commit-ID: 01fdfa9c5541151b5461d9d7d6ca186a3413d949
+
+commit 160db17fc678ceb5e3fd4a7e006cc73866f484aa
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Mon Jun 25 22:28:33 2018 +0000
+Date: Wed Mar 3 22:41:49 2021 +0000
- upstream: fix NULL dereference in open_listen_match_tcpip()
+ upstream: don't sshbuf_get_u32() into an enum; reported by goetze
- OpenBSD-Commit-ID: c968c1d29e392352383c0f9681fcc1e93620c4a9
+ AT dovetail.com via bz3269
+
+ OpenBSD-Commit-ID: 99a30a8f1df9bd72be54e21eee5c56a0f050921a
-commit f535ff922a67d9fcc5ee69d060d1b21c8bb01d14
-Author: jmc@openbsd.org <jmc@openbsd.org>
-Date: Tue Jun 19 05:36:57 2018 +0000
+commit cffd033817a5aa388764b6661855dcdaabab0588
+Author: sthen@openbsd.org <sthen@openbsd.org>
+Date: Wed Mar 3 21:40:16 2021 +0000
- upstream: spelling;
+ upstream: typo in other_hostkeys_message() display output, ok djm
- OpenBSD-Commit-ID: db542918185243bea17202383a581851736553cc
+ OpenBSD-Commit-ID: 276f58afc97b6f5826e0be58380b737603dbf5f5
-commit 80e199d6175904152aafc5c297096c3e18297691
+commit 7fe141b96b13bd7dc67ca985e14d55b9bd8a03fd
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Tue Jun 19 03:02:17 2018 +0000
+Date: Wed Mar 3 08:42:52 2021 +0000
- upstream: test PermitListen with bare port numbers
+ upstream: needs FILE*; from Mike Frysinger
- OpenBSD-Regress-ID: 4b50a02dfb0ccaca08247f3877c444126ba901b3
+ OpenBSD-Commit-ID: dddb3aa9cb5792eeeaa37a1af67b5a3f25ded41d
+
+commit d2afd717e62d76bb41ab5f3ab4ce6f885c8edc98
+Author: Damien Miller <djm@mindrot.org>
+Date: Tue Mar 2 21:31:47 2021 +1100
+
+ update depend
+
+commit f0c4eddf7cf224ebcac1f07ac8afdb30c6e9fe0a
+Author: Damien Miller <djm@mindrot.org>
+Date: Tue Mar 2 21:30:14 2021 +1100
-commit 87ddd676da0f3abd08b778b12b53b91b670dc93c
+ update relnotes URL
+
+commit 67a8bb7fe62a381634db4c261720092e7d514a3d
+Author: Damien Miller <djm@mindrot.org>
+Date: Tue Mar 2 21:29:54 2021 +1100
+
+ update RPM spec version numbers
+
+commit 0a4b23b11b9a4e6eec332dd5c6ab2ac6f62aa164
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Tue Jun 19 02:59:41 2018 +0000
+Date: Tue Mar 2 01:48:18 2021 +0000
- upstream: allow bare port numbers to appear in PermitListen directives,
+ upstream: openssh-8.5
- e.g.
+ OpenBSD-Commit-ID: 185e85d60fe042b8f8fa1ef29d4ef637bdf397d6
+
+commit de3866383b6720ad4cad83be76fe4c8aa111a249
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Mon Mar 1 21:13:24 2021 +1100
+
+ Only upload config logs if configure fails.
+
+commit 85ff2a564ce838f8690050081176c1de1fb33116
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Sun Feb 28 22:56:30 2021 +0000
+
+ upstream: Add %k to list of keywords. From
- PermitListen 2222 8080
+ =?UTF-8?q?=20Eero=20H=C3=A4kkinenvia=20bz#3267?=
+ MIME-Version: 1.0
+ Content-Type: text/plain; charset=UTF-8
+ Content-Transfer-Encoding: 8bit
- is equivalent to:
+ OpenBSD-Commit-ID: 9c87f39a048cee2a7d1c8bab951b2f716256865e
+
+commit e774bac35933e71f924f4301786e7fb5bbe1422f
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Sun Feb 28 01:50:47 2021 +0000
+
+ upstream: Do not try to reset signal handler for signal 0 in
- PermitListen *:2222 *:8080
+ subprocess. Prevents spurious debug message. ok djm@
- Some bonus manpage improvements, mostly from markus@
+ OpenBSD-Commit-ID: 7f9785e292dcf304457566ad4637effd27ad1d46
+
+commit 351c5dbbd74ce300c4f058112f9731c867c6e225
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Sat Feb 27 23:42:37 2021 +0000
+
+ upstream: fix alphabetic ordering of options; spotted by Iain Morgan
- "looks fine" markus@
+ OpenBSD-Commit-ID: f955fec617d74af0feb5b275831a9fee813d7ad5
+
+commit 0d1c9dbe578597f8d45d3ac7690df10d32d743e5
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Sat Feb 27 12:25:25 2021 +1100
+
+ zlib is now optional.
+
+commit b7c6ee7b437d9adfd19ef49d6c0f19f13f26f9b3
+Author: Jeffrey H. Johnson <61629094+johnsonjh@users.noreply.github.com>
+Date: Sat Feb 27 01:04:58 2021 +0000
+
+ Fix punctuatio and typo in README.md.
- OpenBSD-Commit-ID: 6546b0cc5aab7f53d65ad0a348ca0ae591d6dd24
+ Some very minor fixes, missing 's' and punctuation.
-commit 26f96ca10ad0ec5da9b05b99de1e1ccea15a11be
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Jun 15 07:01:11 2018 +0000
+commit 6248b86074804983e8f7a2058856a516dbfe2924
+Author: Damien Miller <djm@mindrot.org>
+Date: Fri Feb 26 16:45:50 2021 +1100
- upstream: invalidate supplemental group cache used by
+ Revert "ssh: optional bind interface if bind address specified."
- temporarily_use_uid() when the target uid differs; could cause failure to
- read authorized_keys under some configurations. patch by Jakub Jelen via
- bz2873; ok dtucker, markus
+ This reverts commit 5a878a71a3528c2626aa1d331934fd964782d41c.
- OpenBSD-Commit-ID: 48a345f0ee90f6c465a078eb5e89566b23abd8a1
+ Apologies - I accidentally pushed this.
-commit 89a85d724765b6b82e0135ee5a1181fdcccea9c6
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sun Jun 10 23:45:41 2018 +0000
+commit 493339a940b13be6071629c3c2dd5a3b6fc17023
+Author: Damien Miller <djm@mindrot.org>
+Date: Fri Feb 26 15:45:38 2021 +1100
- upstream: unbreak SendEnv; patch from tb@
+ detech BSD libc hash functions in libbsd / libmd
- OpenBSD-Commit-ID: fc808daced813242563b80976e1478de95940056
+ Some Linux distributions are shipping the BSD-style hashing functions
+ (e.g. SHA256Update) in libbsd and/or libmd. Detect this situation to
+ avoid header/replacement clashes later. ok dtucker@
-commit acf4260f0951f89c64e1ebbc4c92f451768871ad
-Author: jmc@openbsd.org <jmc@openbsd.org>
-Date: Sat Jun 9 06:36:31 2018 +0000
+commit 5a878a71a3528c2626aa1d331934fd964782d41c
+Author: Dmitrii Turlupov <dturlupov@factor-ts.ru>
+Date: Thu Feb 4 16:27:31 2021 +0300
- upstream: sort previous;
+ ssh: optional bind interface if bind address specified.
- OpenBSD-Commit-ID: 27d80d8b8ca99bc33971dee905e8ffd0053ec411
+ Allows the -b and -B options to be used together.
+ For example, when the interface is in the VRF.
-commit 1678d4236451060b735cb242d2e26e1ac99f0947
+commit 1fe4d70df94d3bcc2b35fd57cad6b5fc4b2d7b16
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sat Jun 9 03:18:11 2018 +0000
+Date: Fri Feb 26 04:18:42 2021 +0000
- upstream: slightly better wording re handing of $TERM, from Jakub
+ upstream: remove this KEX fuzzer; it's awkward to use and doesn't play
+
+ nice with popular fuzzing drivers like libfuzzer. AFAIK nobody has used it
+ but me.
- Jelen via bz2386
+ OpenBSD-Regress-ID: cad919522b3ce90c147c95abaf81b0492ac296c9
+
+commit 24a3a67bd7421740d08803b84bd784e764107928
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Fri Feb 26 11:49:19 2021 +1100
+
+ Remove macos-11.00 PAM test target too.
- OpenBSD-Commit-ID: 14bea3f069a93c8be66a7b97794255a91fece964
+ These are failing apparently due to some kind of infrastructure problem,
+ making it look like every commit is busted.
-commit 28013759f09ed3ebf7e8335e83a62936bd7a7f47
+commit 473201783f732ca8b0ec528b56aa55fa0d8cf717
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sat Jun 9 03:03:10 2018 +0000
+Date: Fri Feb 26 00:16:58 2021 +0000
- upstream: add a SetEnv directive for sshd_config to allow an
+ upstream: a bit more debugging behind #ifdef DEBUG_SK
- administrator to explicitly specify environment variables set in sessions
- started by sshd. These override the default environment and any variables set
- by user configuration (PermitUserEnvironment, etc), but not the SSH_*
- variables set by sshd itself.
+ OpenBSD-Commit-ID: d9fbce14945721061cb322f0084c2165d33d1993
+
+commit fd9fa76a344118fe1ef10b9a6c9e85d39599e9a8
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Fri Feb 26 01:15:10 2021 +1100
+
+ Remove macos-11.0 from the test target list.
- ok markus@
+ It has been consistently failing for the past few days with a github
+ actions internal error.
+
+commit 476ac8e9d33dbf96ef97aab812b8d7089d0cdc24
+Author: Philip Hands <phil@hands.com>
+Date: Wed Feb 24 23:43:16 2021 +0100
+
+ tidy the $INSTALLKEY_SH code layout a little
- OpenBSD-Commit-ID: b6a96c0001ccd7dd211df6cae9e961c20fd718c0
+ SSH-Copy-ID-Upstream: 78178aa5017222773e4c23d9001391eeaeca8983
-commit 7082bb58a2eb878d23ec674587c742e5e9673c36
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sat Jun 9 03:01:12 2018 +0000
+commit 983e05ef3b81329d76d6a802b39ad0d1f637c06c
+Author: Jakub Jelen <jjelen@redhat.com>
+Date: Tue Sep 29 10:02:45 2020 +0000
- upstream: add a SetEnv directive to ssh_config that allows setting
+ if unable to add a missing newline, fail
- environment variables for the remote session (subject to the server accepting
- them)
+ SSH-Copy-ID-Upstream: 76b25e18f55499ea9edb4c4d6dc4a80bebc36d95
+
+commit 3594b3b015f6014591da88ba71bf6ff010be7411
+Author: Philip Hands <phil@hands.com>
+Date: Tue Oct 13 14:12:58 2020 +0200
+
+ use $AUTH_KEY_DIR, now that we have it
- refactor SendEnv to remove the arbitrary limit of variable names.
+ since that was a change made since jjelen's commit was written
- ok markus@
+ also, quote the variables
- OpenBSD-Commit-ID: cfbb00d9b0e10c1ffff1d83424351fd961d1f2be
+ SSH-Copy-ID-Upstream: 588cd8e5cbf95f3443d92b9ab27c5d73ceaf6616
-commit 3b9798bda15bd3f598f5ef07595d64e23504da91
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sat Jun 9 02:58:02 2018 +0000
+commit 333e25f7bc43cee6e36f766e39dad6f9918b318c
+Author: Jakub Jelen <jjelen@redhat.com>
+Date: Tue Sep 29 10:00:01 2020 +0000
- upstream: reorder child environment preparation so that variables
+ restorecon the correct directory
- read from ~/.ssh/environment (if enabled) do not override SSH_* variables set
- by the server.
+ if using different path for authorized_keys file
- OpenBSD-Commit-ID: 59f9d4c213cdcef2ef21f4b4ae006594dcf2aa7a
+ SSH-Copy-ID-Upstream: 791a3df47b48412c726bff6f7b1d190721e65d51
-commit 0368889f82f63c82ff8db9f8c944d89e7c657db4
+commit 9beeab8a37a49a9e3ffb1972fff6621ee5bd7a71
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Jun 8 03:35:36 2018 +0000
+Date: Thu Feb 25 03:27:34 2021 +0000
+
+ upstream: s/PubkeyAcceptedKeyTypes/PubkeyAcceptedAlgorithms/
+
+ OpenBSD-Regress-ID: 3dbc005fa29f69dc23d97e433b6dffed6fe7cb69
+
+commit 2dd9870c16ddbd83740adeead5030d6840288c8f
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Wed Feb 24 23:12:35 2021 +0000
- upstream: fix incorrect expansion of %i in
+ upstream: Rename pubkeyacceptedkeytypes to pubkeyacceptedalgorithms in
- load_public_identity_files(); reported by Roumen Petrov
+ test to match change to config-dump output.
- OpenBSD-Commit-ID: a827289e77149b5e0850d72a350c8b0300e7ef25
+ OpenBSD-Regress-ID: 74c9a4ad50306be873d032819d5e55c24eb74d5d
+
+commit b9225c3a1c3f5827e31d5d64a71b8e0504a25619
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Wed Feb 24 01:18:08 2021 +0000
-commit 027607fc2db6a0475a3380f8d95c635482714cb0
+ upstream: Put obsolete aliases for hostbasedalgorithms and
+
+ pubkeyacceptedalgorithms after their current names so that the config-dump
+ mode finds and uses the current names. Spotted by Phil Pennock.
+
+ OpenBSD-Commit-ID: 5dd10e93cccfaff3aaaa09060c917adff04a9b15
+
+commit 8b8b60542d6652b2c91e0ef9e9cc81bcb65e6b42
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Jun 8 01:55:40 2018 +0000
+Date: Tue Feb 23 21:55:08 2021 +0000
- upstream: fix some over-long lines and __func__ up some debug
+ upstream: lots more s/key types/signature algorithms/ mostly in
- messages
+ HostbasedAcceptedAlgorithms and HostKeyAlgorithms; prompted by Jakub Jelen
- OpenBSD-Commit-ID: c70a60b4c8207d9f242fc2351941ba50916bb267
+ OpenBSD-Commit-ID: 3f719de4385b1a89e4323b2549c66aae050129cb
-commit 6ff6fda705bc204456a5fa12518dde6e8790bb02
-Author: jmc@openbsd.org <jmc@openbsd.org>
-Date: Thu Jun 7 11:26:14 2018 +0000
+commit 0aeb508aaabc4818970c90831e3d21843c3c6d09
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Tue Feb 23 21:50:18 2021 +0000
- upstream: tweak previous;
+ upstream: Correct reference to signature algorithms as keys; from
- OpenBSD-Commit-ID: f98f16af10b28e24bcecb806cb71ea994b648fd6
+ Jakub Jelen
+
+ OpenBSD-Commit-ID: 36f7ecee86fc811aa0f8e21e7a872eee044b4be5
-commit f2c06ab8dd90582030991f631a2715216bf45e5a
+commit f186a020f2ba5f9c462a23293750e29ba0a746b1
Author: Darren Tucker <dtucker@dtucker.net>
-Date: Fri Jun 8 17:43:36 2018 +1000
+Date: Tue Feb 23 16:05:22 2021 +1100
- Remove ability to override $LD.
-
- Since autoconf always uses $CC to link C programs, allowing users to
- override LD caused mismatches between what LD_LINK_IFELSE thought worked
- and what ld thought worked. If you do need to do this kind of thing you
- need to set a compiler flag such as gcc's -fuse-ld in LDFLAGS.
+ Add a couple more test VMs.
-commit e1542a80797b4ea40a91d2896efdcc76a57056d2
+commit ffcdd3d90e74176b3bb22937ad1f65a6c1cd3f9d
Author: Darren Tucker <dtucker@dtucker.net>
-Date: Fri Jun 8 13:55:59 2018 +1000
+Date: Mon Feb 22 08:09:27 2021 +1100
- Better detection of unsupported compiler options.
+ Valgrind test: split and move up list.
- Should prevent "unsupported -Wl,-z,retpoline" warnings during linking.
- ok djm@
+ Since the valgrind test takes so long it approaches the limit allowed by
+ github, move it to the head of the list so it's the first one started and
+ split the longest tests out into a second instance that runs concurrently
+ with the first.
-commit 57379dbd013ad32ee3f9989bf5f5741065428360
+commit c3b1636770785cc2830dedd0f22ef7d3d3491d6d
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Thu Jun 7 14:29:43 2018 +0000
+Date: Tue Feb 23 00:05:31 2021 +0000
- upstream: test the correct configuration option name
+ upstream: warn when the user specifies a ForwardAgent path that does
+
+ not exist and exit if ExitOnForwardFailure is set; bz3264
- OpenBSD-Regress-ID: 492279ea9f65657f97a970e0e7c7fd0b339fee23
+ OpenBSD-Commit-ID: 72f7875865e723e464c71bf8692e83110699bf26
-commit 6d41815e202fbd6182c79780b6cc90e1ec1c9981
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Thu Jun 7 09:26:42 2018 +0000
+commit 5fcb0514949d61aadaf4a89cf16eb78fb47491ec
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Sat Feb 20 13:34:02 2021 +1100
- upstream: some permitlisten fixes from markus@ that I missed in my
+ Disable rlimit sandbox, doesn't work with valgrind
- insomnia-fueled commits last night
+ Only run regress tests, runing unit tests as well makes it run longer
+ than allowed y github.
+
+commit bb0b9bf45396c19486080d3eb0a159f94de7e6ba
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Sat Feb 20 13:06:25 2021 +1100
+
+ Upload valgrind logs on failure.
+
+commit ebb3b75e974cb241c6b9b9f5881b09c7bd32b651
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Fri Feb 19 22:18:50 2021 +1100
+
+ Rename "vm" to "os" in selfhosted to match c-cpp.
- OpenBSD-Commit-ID: 26f23622e928996086e85b1419cc1c0f136e359c
+ Should make it easier to share code or maybe merge at some point.
-commit 4319f7a868d86d435fa07112fcb6153895d03a7f
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Thu Jun 7 04:46:34 2018 +0000
+commit 76c0be0fe0465cb2b975dbd409f8d38b55e55bcb
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Fri Feb 19 22:15:22 2021 +1100
- upstream: permitlisten/PermitListen unit test from Markus
+ Upload regress failure logs in c-cpp too.
+
+commit 8751b6c3136f5225c40f41bbf29aa29e15795f6e
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Fri Feb 19 22:13:36 2021 +1100
+
+ Comment out Solaris 64bit PAM build...
- OpenBSD-Regress-ID: ab12eb42f0e14926980441cf7c058a6d1d832ea5
+ until I can figure out why it's failing.
+
+commit e9f6d563c06886b277c6b9abafa99fa80726dc48
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Fri Feb 19 10:20:17 2021 +1100
+
+ Actually run Valgrind tests.
+
+commit 41d232e226624f1a81c17091c36b44c9010aae62
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Fri Feb 19 10:16:56 2021 +1100
+
+ Add test against Valgrind.
+
+commit e6528d91f12fba05f0ea64224091c9d0f38bdf1d
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Thu Feb 18 16:30:01 2021 +1100
+
+ Add fbsd12 test target.
+
+commit 6506cb2798d98ff03a7cc06567c392a81f540680
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Thu Feb 18 15:21:13 2021 +1100
+
+ Remove unused arg.
-commit fa09076410ffc2d34d454145af23c790d728921e
+commit 93c31a623973b0fad508214593aab6ca94b11dcb
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Thu Feb 18 14:54:07 2021 +1100
+
+ Add DEBUG_SK to kitchensink builds.
+
+commit 65085740d3574eeb3289d592f042df62c2689bb0
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Thu Feb 18 14:53:14 2021 +1100
+
+ Add bbone test target (arm32).
+
+commit 63238f5aed66148b8d6ca7bd5fb347d624200155
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Thu Jun 7 04:31:51 2018 +0000
+Date: Thu Feb 18 02:49:35 2021 +0000
- upstream: fix regression caused by recent permitlisten option commit:
+ upstream: Fix the hostkeys rotation extension documentation
- authorized_keys lines that contained permitopen/permitlisten were being
- treated as invalid.
+ The documentation was lacking the needed want-reply field in the initial
+ global request.
- OpenBSD-Commit-ID: 7ef41d63a5a477b405d142dc925b67d9e7aaa31b
+ https://github.com/openssh/openssh-portable/pull/218 by dbussink
+
+ OpenBSD-Commit-ID: 051824fd78edf6d647a0b9ac011bf88e28775054
-commit 7f90635216851f6cb4bf3999e98b825f85d604f8
-Author: markus@openbsd.org <markus@openbsd.org>
-Date: Wed Jun 6 18:29:18 2018 +0000
+commit 34c5ef6e2d06d9f0e20cb04a9aebf67a6f96609a
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Thu Feb 18 02:15:07 2021 +0000
- upstream: switch config file parsing to getline(3) as this avoids
+ upstream: make names in function prototypes match those in
- static limits noted by gerhard@; ok dtucker@, djm@
+ definition from https://github.com/openssh/openssh-portable/pull/225 by
+ ZenithalHourlyRate
- OpenBSD-Commit-ID: 6d702eabef0fa12e5a1d75c334a8c8b325298b5c
+ OpenBSD-Commit-ID: 7c736307bf3f2c7cb24d6f82f244eee959485acd
-commit 392db2bc83215986a91c0b65feb0e40e7619ce7e
+commit 88e3d4de31ab4f14cac658e9e0c512043b15b146
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Wed Jun 6 18:25:33 2018 +0000
+Date: Thu Feb 18 02:13:58 2021 +0000
- upstream: regress test for PermitOpen
+ upstream: unbreak SK_DEBUG builds
+
+ from https://github.com/openssh/openssh-portable/pull/225 by
+ ZenithalHourlyRate
- OpenBSD-Regress-ID: ce8b5f28fc039f09bb297fc4a92319e65982ddaf
+ OpenBSD-Commit-ID: 28d7259ce1b04d025411464decfa2f1a097b43eb
-commit 803d896ef30758135e2f438bdd1a0be27989e018
+commit 788cbc5b74a53956ba9fff11e1ca506271a3597f
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Wed Jun 6 18:24:15 2018 +0000
+Date: Thu Feb 18 00:30:17 2021 +0000
- upstream: man bits for permitlisten authorized_keys option
+ upstream: sftp-server: implement limits@openssh.com extension
+
+ This is a simple extension that allows the server to clearly
+ communicate transfer limits it is imposing so the client doesn't
+ have to guess, or force the user to manually tune. This is
+ particularly useful when an attempt to use too large of a value
+ causes the server to abort the connection.
+
+ Patch from Mike Frysinger; ok dtucker@
- OpenBSD-Commit-ID: 86910af8f781a4ac5980fea125442eb25466dd78
+ OpenBSD-Commit-ID: f96293221e5aa24102d9bf30e4f4ef04d5f4fb51
-commit 04df43208b5b460d7360e1598f876b92a32f5922
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Wed Jun 6 18:24:00 2018 +0000
+commit 324449a68d510720d0e4dfcc8e9e5a702fe6a48f
+Author: Damien Miller <djm@mindrot.org>
+Date: Thu Feb 18 12:06:25 2021 +1100
- upstream: man bits for PermitListen
+ support OpenSSL 3.x cipher IV API change
+
+ OpenSSL renamed the "get current CIPHER_CTX" IV operation in 3.x.
+ This uses the new name if available.
- OpenBSD-Commit-ID: 35b200cba4e46a16a4db6a80ef11838ab0fad67c
+ https://github.com/openssl/openssl/issues/13411
+
+ bz#3238 ok dtucker@
-commit 93c06ab6b77514e0447fe4f1d822afcbb2a9be08
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Wed Jun 6 18:23:32 2018 +0000
+commit 845fe9811c047063d935eca89188ed55c993626b
+Author: Damien Miller <djm@mindrot.org>
+Date: Thu Feb 18 11:25:38 2021 +1100
- upstream: permitlisten option for authorized_keys; ok markus@
+ prefer login_getpwclass() to login_getclass()
+
+ FreeBSD has login_getpwclass() that does some special magic for
+ UID=0. Prefer this to login_getclass() as its easier to emulate
+ the former with the latter.
- OpenBSD-Commit-ID: 8650883018d7aa893173d703379e4456a222c672
+ Based on FreeBSD PR 37416 via Ed Maste; ok dtucker@
-commit 115063a6647007286cc8ca70abfd2a7585f26ccc
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Wed Jun 6 18:22:41 2018 +0000
+commit d0763c8d566119cce84d9806e419badf20444b02
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Thu Feb 18 10:45:27 2021 +1100
- upstream: Add a PermitListen directive to control which server-side
+ Fixing quoting for installing moduli on target guest.
+
+commit b3afc243bc820f323a09e3218e9ec8a30a3c1933
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Thu Feb 18 10:27:16 2021 +1100
+
+ Install moduli on target not host.
+
+commit f060c2bc85d59d111fa18a12eb3872ee4b9f7e97
+Author: Damien Miller <djm@mindrot.org>
+Date: Thu Feb 18 10:33:58 2021 +1100
+
+ don't free string returned by login_getcapstr(3)
- addresses may be listened on when the client requests remote forwarding (ssh
- -R).
+ OpenBSD and NetBSD require the caller to free strings returned
+ bu the login_* functions, but FreeBSD requires that callers don't.
- This is the converse of the existing PermitOpen directive and this
- includes some refactoring to share much of its implementation.
+ Fortunately in this case, we can harmlessly leak as the process is
+ about to exec the shell/command.
- feedback and ok markus@
+ From https://reviews.freebsd.org/D28617 via Ed Maste; ok dtucker@
+
+commit bc9b0c25703215501da28aa7a6539f96c0fa656f
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Thu Feb 18 10:10:00 2021 +1100
+
+ Skip unit tests on sol11 to speed things up.
+
+commit 161873035c12cc22211fc73d07170ade47746bc5
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Thu Feb 18 10:09:27 2021 +1100
+
+ Remove SKIP_UNIT as it needs to be a make arg.
+
+commit 1c293868e4b4e8e74e3ea15b8dff90f6b089967a
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Thu Feb 18 10:05:03 2021 +1100
+
+ Always intall moduli.
- OpenBSD-Commit-ID: 15a931238c61a3f2ac74ea18a98c933e358e277f
+ Allows us to run tests without falling back to a fixed modulus. Ensure that
+ the directory exists.
+
+commit 5c8f41ad100601ec2fdcbccdfe92890c31f81bbe
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Thu Feb 18 09:59:09 2021 +1100
+
+ Quote SSHD_CONFOPTS in case it contains spaces.
+
+commit 4653116c1f5384ea7006e6396d9b53c33d218975
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Thu Feb 18 09:51:18 2021 +1100
+
+ Fix labels on targets (dots vs underscores).
+
+commit 4512047f57ca3c6e8cd68f0cc69be59e98b25287
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Wed Feb 17 21:47:48 2021 +1100
+
+ More compact representation of config matrix.
+
+commit 0406cd09f05c2e419b113dd4c0eac8bc34ec915b
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Wed Feb 17 21:19:18 2021 +1100
+
+ Skip unit tests on hosted VMs to speed things up.
+
+commit 4582612e6147d766c336198c498740242fb8f1ec
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Wed Feb 17 20:21:29 2021 +1100
+
+ Merge macos and ubuntu tests.
-commit 7703ae5f5d42eb302ded51705166ff6e19c92892
+commit 09f4b84654b71099559492e9aed5e1a38bf24815
Author: Darren Tucker <dtucker@dtucker.net>
-Date: Wed Jun 6 16:04:29 2018 +1000
+Date: Wed Feb 17 18:41:30 2021 +1100
- Use ssh-keygen -A to generate missing host keys.
+ Convert most github hosted tests to new config structure.
+
+commit 65380ff7e054be1454e5ab4fd7bb9c66f8fcbaa9
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Wed Feb 17 18:27:36 2021 +1100
+
+ Only run selfhosted tests from selfhosted repo.
+
+commit f031366535650b88248ed7dbf23033afdf466240
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Fri Jan 15 14:11:43 2021 +1100
+
+ Add self-hosted runners for VMs of other platforms.
+
+ Github only hosts a limited number of platforms, and the runner code
+ is only supported on slightly wider range of platforms. To increase
+ our test coverage beyond that, we run the runner natively on a VM host,
+ where it runs a jobs that boot VMs of other platforms, waits for them
+ to come up then runs the build and test by ssh'ing into the guest.
+ This means that the minimum dependencies for the guests are quite low
+ (basically just sshd, a compiler and make).
- Instead of testing for each specific key type, use ssh-keygen -A to
- generate any missing host key types.
+ The interface to the VM host is fairly simple (basically 3 scripts:
+ vmstartup, vmrun and vmshutdown), but those are specific to the VM host
+ so are not in the public repo. We also mount the working directory on the
+ host via sshfs, so things like artifact upload by the runner also work.
+
+ As part of this we are moving the per-test-target configs into a single
+ place (.github/configs) where there will be referenced by a single short
+ "config" key. I plan to make the github-hosted runners use this too.
+
+ The self-hosted runners are run off a private repo on github since that
+ prevents third parties from accessing them[0], and since runner quota is
+ limited on private repos, we avoid running the tests we run on the public
+ repo.
+
+ [0] https://docs.github.com/en/actions/hosting-your-own-runners/about-self-hosted-runners#self-hosted-runner-security-with-public-repositories
-commit e8d59fef1098e24f408248dc64e5c8efa5d01f3c
-Author: jmc@openbsd.org <jmc@openbsd.org>
-Date: Fri Jun 1 06:23:10 2018 +0000
+commit 64bbd7444d658ef7ee14a7ea5ccc7f5810279ee7
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Wed Feb 17 03:59:00 2021 +0000
- upstream: add missing punctuation after %i in ssh_config.5, and
+ upstream: Make sure puttygen is new enough to successfully run the
- make the grammatical format in sshd_config.5 match that in ssh_config.5;
+ PuTTY interop tests, otherwise skip them.
- OpenBSD-Commit-ID: e325663b9342f3d556e223e5306e0d5fa1a74fa0
+ OpenBSD-Regress-ID: 34565bb50b8aec58331ed02a5e9e0a9a929bef51
-commit a1f737d6a99314e291a87856122cb4dbaf64c641
-Author: jmc@openbsd.org <jmc@openbsd.org>
-Date: Fri Jun 1 05:52:26 2018 +0000
+commit da0a9afcc446a30ca49dd216612c41ac3cb1f2d4
+Author: markus@openbsd.org <markus@openbsd.org>
+Date: Mon Feb 15 20:43:15 2021 +0000
- upstream: oops - further adjustment to text neccessary;
+ upstream: ssh: add PermitRemoteOpen for remote dynamic forwarding
+
+ with SOCKS ok djm@, dtucker@
- OpenBSD-Commit-ID: 23585576c807743112ab956be0fb3c786bdef025
+ OpenBSD-Commit-ID: 64fe7b6360acc4ea56aa61b66498b5ecc0a96a7c
-commit 294028493471e0bd0c7ffe55dc0c0a67cba6ec41
-Author: jmc@openbsd.org <jmc@openbsd.org>
-Date: Fri Jun 1 05:50:18 2018 +0000
+commit b696858a7f9db72a83d02cb6edaca4b30a91b386
+Author: markus@openbsd.org <markus@openbsd.org>
+Date: Mon Feb 15 20:36:35 2021 +0000
- upstream: %U needs to be escaped; tweak text;
+ upstream: factor out opt_array_append; ok djm@
- OpenBSD-Commit-ID: 30887b73ece257273fb619ab6f4e86dc92ddc15e
+ OpenBSD-Commit-ID: 571bc5dd35f99c5cf9de6aaeac428b168218e74a
-commit e5019da3c5a31e6e729a565f2b886a80c4be96cc
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Fri Jun 1 04:31:48 2018 +0000
+commit ad74fc127cc45567e170e8c6dfa2cfd9767324ec
+Author: dlg@openbsd.org <dlg@openbsd.org>
+Date: Mon Feb 15 11:09:22 2021 +0000
- upstream: Apply umask to all incoming files and directories not
+ upstream: ProxyJump takes "none" to disable processing like
- just files. This makes sure it gets applied to directories too, and prevents
- a race where files get chmodded after creation. bz#2839, ok djm@
+ ProxyCommand does
- OpenBSD-Commit-ID: 3168ee6c7c39093adac4fd71039600cfa296203b
+ ok djm@ jmc@
+
+ OpenBSD-Commit-ID: 941a2399da2193356bdc30b879d6e1692f18b6d3
-commit a1dcafc41c376332493b9385ee39f9754dc145ec
+commit 16eacdb016ccf38dd9959c78edd3a6282513aa53
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Jun 1 03:52:37 2018 +0000
+Date: Fri Feb 12 03:49:09 2021 +0000
- upstream: Adapt to extra default verboisity from ssh-keygen when
+ upstream: sftp: add missing lsetstat@openssh.com documentation
- searching for and hashing known_hosts entries in a single operation
- (ssh-keygen -HF ...) Patch from Anton Kremenetsky
+ patch from Mike Frysinger
- OpenBSD-Regress-ID: 519585a4de35c4611285bd6a7272766c229b19dd
+ OpenBSD-Commit-ID: 9c114db88d505864075bfe7888b7c8745549715b
-commit 76f314c75dffd4a55839d50ee23622edad52c168
+commit e04fd6dde16de1cdc5a4d9946397ff60d96568db
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Tue May 22 00:22:49 2018 +0000
+Date: Fri Feb 12 03:14:18 2021 +0000
- upstream: Add TEST_SSH_FAIL_FATAL variable, to force all failures
+ upstream: factor SSH_AGENT_CONSTRAIN_EXTENSION parsing into its own
- to instantly abort the test. Useful in capturing clean logs for individual
- failure cases.
+ function and remove an unused variable; ok dtucker@
- OpenBSD-Regress-ID: feba18cf338c2328b9601bd4093cabdd9baa3af1
+ OpenBSD-Commit-ID: e1a938657fbf7ef0ba5e73b30365734a0cc96559
-commit 065c8c055df8d83ae7c92e5e524a579d87668aab
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Fri May 11 03:51:06 2018 +0000
+commit 1bb130ed34721d46452529d094d9bbf045607d79
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Thu Feb 11 10:18:05 2021 +1100
- upstream: Clean up comment.
+ Add __NR_futex_time64 to seccomp sandbox.
- OpenBSD-Regress-ID: 6adb35f384d447e7dcb9f170d4f0d546d3973e10
+ This is apparently needed for (some) 32 bit platforms with glibc 2.33.
+ Patch from nix at esperi.org.uk and jjelen at redhat.com via bz#3260.
-commit 01b048c8eba3b021701bd0ab26257fc82903cba8
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Jun 1 04:21:29 2018 +0000
+commit f88a7a431212a16e572ecabd559e632f369c363e
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Sat Feb 6 09:37:01 2021 +1100
- upstream: whitespace
+ Add a hostname function for systems that don't have it.
- OpenBSD-Commit-ID: e5edb5e843ddc9b73a8e46518899be41d5709add
+ Some systems don't have a hostname command (it's not required by POSIX).
+ The do have uname -n (which is), but as found by tim@ some others (eg
+ UnixWare) do not report the FQDN from uname -n.
-commit 854ae209f992465a276de0b5f10ef770510c2418
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Jun 1 04:05:29 2018 +0000
+commit 5e385a71ef2317856f37c91a98658eb12eb5a89c
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Fri Feb 5 22:03:40 2021 +0000
- upstream: make ssh_remote_ipaddr() capable of being called after
+ upstream: Roll back the hostname->uname change in rev 1.10. It turns
- the ssh->state has been torn down; bz#2773
+ out uname -n doesn't do what we need for some platforms in portable, so we'll
+ fix the original problem (that some other platforms don't have hostname at
+ all) by providing wrapper function to implement it.
- OpenBSD-Commit-ID: 167f12523613ca3d16d7716a690e7afa307dc7eb
+ OpenBSD-Regress-ID: 827a707d6201d5a8e196a8c28aec1d2c76c52341
-commit 3e088aaf236ef35beeef3c9be93fd53700df5861
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Jun 1 03:51:34 2018 +0000
+commit b446c214279de50ed8388e54897eb1be5281c894
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Fri Feb 5 06:01:58 2021 +0000
- upstream: return correct exit code when searching for and hashing
+ upstream: hostname is not specified by POSIX but uname -n is, so use
- known_hosts entries in a single operation (ssh-keygen -HF hostname); bz2772
- Report and fix from Anton Kremenetsky
+ the latter for portability. Patch from Geert Hendrickx via github PR#208.
- OpenBSD-Commit-ID: ac10ca13eb9bb0bc50fcd42ad11c56c317437b58
+ OpenBSD-Regress-ID: d6a79c7c4d141a0d05ade4a042eb57dddbce89f3
-commit 9c935dd9bf05628826ad2495d3e8bdf3d3271c21
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Jun 1 03:33:53 2018 +0000
+commit 1cb6ce98d658e5fbdae025a3bd65793980e3b5d9
+Author: David Carlier <devnexen@gmail.com>
+Date: Sat Nov 21 12:22:23 2020 +0000
- upstream: make UID available as a %-expansion everywhere that the
+ Using explicit_memset for the explicit_bzero compatibility layer.
- username is available currently. In the client this is via %i, in the server
- %U (since %i was already used in the client in some places for this, but used
- for something different in the server); bz#2870, ok dtucker@
+ Favoriting the native implementation in this case.
+
+commit 2e0beff67def2120f4b051b1016d7fbf84823e78
+Author: Luca Weiss <luca@z3ntu.xyz>
+Date: Sun Nov 8 14:19:23 2020 +0100
+
+ Deny (non-fatal) statx in preauth privsep child.
+
+commit a35d3e911e193a652bd09eed40907e3e165b0a7b
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Fri Feb 5 02:20:23 2021 +0000
+
+ upstream: Remove debug message from sigchld handler. While this
+
+ works on OpenBSD it can cause problems on other platforms. From kircherlike
+ at outlook.com via bz#3259, ok djm@
- OpenBSD-Commit-ID: c7e912b0213713316cb55db194b3a6415b3d4b95
+ OpenBSD-Commit-ID: 3e241d7ac1ee77e3de3651780b5dc47b283a7668
-commit d8748b91d1d6c108c0c260ed41fa55f37b9ef34b
+commit 69338ab46afe9e3dfb7762ad65351d854077c998
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Jun 1 03:11:49 2018 +0000
+Date: Tue Feb 2 22:36:59 2021 +0000
- upstream: prefer argv0 to "ssh" when re-executing ssh for ProxyJump
-
- directive; bz2831, feedback and ok dtucker@
+ upstream: whitespace
- OpenBSD-Commit-ID: 3cec709a131499fbb0c1ea8a0a9e0b0915ce769e
+ OpenBSD-Commit-ID: 544bb092e03fcbecb420196cd0f70af13ea868ad
-commit fbb4b5fd4f8e0bb89732670a01954e18b69e15ba
+commit f71219a01d8f71c4b3ed7e456337a84ddba1653e
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri May 25 07:11:01 2018 +0000
+Date: Tue Feb 2 22:36:46 2021 +0000
- upstream: Do not ban PTY allocation when a sshd session is restricted
+ upstream: fix memleaks in private key deserialisation; enforce more
- because the user password is expired as it breaks password change dialog.
+ consistency between redundant fields in private key certificate and private
+ key body; ok markus@
- regression in openssh-7.7 reported by Daniel Wagner
+ OpenBSD-Commit-ID: dec344e414d47f0a7adc13aecf3760fe58101240
+
+commit 3287790e78bf5b53c4a3cafb67bb5aa03e3910f0
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Tue Feb 2 22:35:14 2021 +0000
+
+ upstream: memleak on error path; ok markus@
- OpenBSD-Commit-ID: 9fc09c584c6f1964b00595e3abe7f83db4d90d73
+ OpenBSD-Commit-ID: 2091a36d6ca3980c81891a6c4bdc544e63cb13a8
-commit f6a59a22b0c157c4c4e5fd7232f868138223be64
+commit 3dd0c64e08f1bba21d71996d635c7256c8c139d1
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri May 25 04:25:46 2018 +0000
+Date: Sun Jan 31 22:55:29 2021 +0000
- upstream: Fix return value confusion in several functions (readdir,
+ upstream: more strictly enforce KEX state-machine by banning packet
- download and fsync). These should return -1 on error, not a sftp status code.
+ types once they are received. Fixes memleak caused by duplicate
+ SSH2_MSG_KEX_DH_GEX_REQUEST (spotted by portable OpenSSH kex_fuzz via
+ oss-fuzz #30078).
- patch from Petr Cerny in bz#2871
+ ok markus@
- OpenBSD-Commit-ID: 651aa0220ad23c9167d9297a436162d741f97a09
+ OpenBSD-Commit-ID: 87331c715c095b587d5c88724694cdeb701c9def
-commit 1da5934b860ac0378d52d3035b22b6670f6a967e
+commit 7a92a324a2e351fabd0ba8ef9b434d3b12d54ee3
Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Fri May 25 03:20:59 2018 +0000
+Date: Sun Jan 31 10:50:10 2021 +0000
- upstream: If select() fails in ssh_packet_read_seqnr go directly to
+ upstream: Set linesize returned by getline to zero when freeing and
- the error path instead of trying to read from the socket on the way out,
- which resets errno and causes the true error to be misreported. ok djm@
+ NULLing the returned string. OpenBSD's getline handles this just fine, but
+ some implementations used by -portable do not. ok djm@
- OpenBSD-Commit-ID: 2614edaadbd05a957aa977728aa7a030af7c6f0a
+ OpenBSD-Commit-ID: 4d7bd5169d3397654247db9655cc69a9908d165c
-commit 4ef75926ef517d539f2c7aac3188b09f315c86a7
+commit a5dfc5bae8c16e2a7caf564758d812c7672480b5
Author: Damien Miller <djm@mindrot.org>
-Date: Fri May 25 13:36:58 2018 +1000
+Date: Sat Jan 30 16:32:29 2021 +1100
- Permit getuid()/geteuid() syscalls.
+ allow a fuzz case to contain more than one request
- Requested for Linux/s390; patch from Eduardo Barretto via bz#2752;
- ok dtucker
+ loop until input buffer empty, no message consumed or 256 messages
+ processed
-commit 4b22fd8ecefd059a66140be67f352eb6145a9d88
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Tue May 22 00:13:26 2018 +0000
+commit 0ef24ad60204022f7e33b6e9d171172c50514132
+Author: Damien Miller <djm@mindrot.org>
+Date: Sat Jan 30 16:28:23 2021 +1100
- upstream: support ProxyJump=none to disable ProxyJump
+ expect fuzz cases to have length prefix
- functionality; bz#2869 ok dtucker@
+ might make life a little easier for the fuzzer, e.g. it can now
+ produce valid (multi-request) messages by smashing two cases together.
+
+commit de613f2713d2dfcd3b03c00e5558a40997f52712
+Author: Damien Miller <djm@mindrot.org>
+Date: Sat Jan 30 12:03:30 2021 +1100
+
+ ssh-agent fuzzer
+
+commit 7e96c877bcb2fb645355a687b8cb7347987c1c58
+Author: Damien Miller <djm@mindrot.org>
+Date: Sat Jan 30 12:02:46 2021 +1100
+
+ move keys out of kex_fuzz.cc into separate header
- OpenBSD-Commit-ID: 1c06ee08eb78451b5837fcfd8cbebc5ff3a67a01
+ add certificates and missing key types
-commit f41bcd70f55b4f0fc4d8e1039cb361ac922b23fb
-Author: jmc@openbsd.org <jmc@openbsd.org>
-Date: Tue May 15 05:40:11 2018 +0000
+commit 76f46d75664fdaa1112739ca523ff85ee4eb52b4
+Author: Damien Miller <djm@mindrot.org>
+Date: Sat Jan 30 12:02:10 2021 +1100
+
+ some fixed test data (mostly keys) for fuzzing
+
+commit 7c2e3d6de1f2edb0c8b4725b4c2b56360e032b19
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Sat Jan 30 00:56:38 2021 +0000
- upstream: correct keyowrd name (permitemptypasswords); from brendan
+ upstream: add a SK_DUMMY_INTEGRATE define that allows the dummy
- macdonell
+ security key middleware to be directly linked; useful for writing fuzzers,
+ etc.
- OpenBSD-Commit-ID: ef1bdbc936b2ea693ee37a4c20a94d4d43f5fda3
+ OpenBSD-Regress-ID: 0ebd00159b58ebd85e61d8270fc02f1e45df1544
-commit f18bc97151340127859634d20d79fd39ec8a7f39
+commit 1a4b92758690faa12f49079dd3b72567f909466d
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri May 11 04:01:11 2018 +0000
+Date: Fri Jan 29 06:29:46 2021 +0000
- upstream: Emphasise that -w implicitly sets Tunnel=point-to-point
+ upstream: fix the values of enum sock_type
- and that users should specify an explicit Tunnel directive if they don't want
- this. bz#2365.
+ OpenBSD-Commit-ID: 18d048f4dbfbb159ff500cfc2700b8fb1407facd
+
+commit 8afaa7d7918419d3da6c0477b83db2159879cb33
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Fri Jan 29 06:28:10 2021 +0000
+
+ upstream: give typedef'd struct a struct name; makes the fuzzer I'm
- OpenBSD-Commit-ID: 1a8d9c67ae213ead180481900dbbb3e04864560d
+ writing a bit easier
+
+ OpenBSD-Commit-ID: 1052ab521505a4d8384d67acb3974ef81b8896cb
+
+commit 1e660115f0c7c4a750cd31e468ff889f33dd8088
+Author: Damien Miller <djm@mindrot.org>
+Date: Fri Jan 29 11:09:14 2021 +1100
+
+ fuzz diffie-hellman-group-exchange-sha1 kex too
-commit 32e4e94e1511fe0020fbfbb62399d31b2d22a801
+commit be5f0048ea2aaeddd27be7dcca23aaad345fa16c
Author: Damien Miller <djm@mindrot.org>
-Date: Mon May 14 14:40:08 2018 +1000
+Date: Fri Jan 29 11:03:35 2021 +1100
+
+ support for running kex fuzzer with null cipher
+
+commit 3d59e88c0e42182c3749b446ccd9027933c84be4
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Thu Jan 28 20:55:16 2021 +1100
- sync fmt_scaled.c
+ make with -j2 to use available CPUs.
+
+commit 66dd9ddb5d2ea8c407908c8e8468c9d6e71db05b
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Thu Jan 28 14:31:01 2021 +1100
+
+ Add test against openssl head and libressl head.
+
+commit 237dbb34e24b6b7ea888d54bda4d17da0a0fd0fa
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Thu Jan 28 14:30:50 2021 +1100
+
+ Remove whitespace.
+
+commit d983e1732b8135d7ee8d92290d6dce35f736ab88
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Wed Jan 27 23:49:46 2021 +0000
+
+ upstream: fix leak: was double allocating kex->session_id buffer
- revision 1.17
- date: 2018/05/14 04:39:04; author: djm; state: Exp; lines: +5 -2;
- commitid: 53zY8GjViUBnWo8Z;
- constrain fractional part to [0-9] (less confusing to static analysis); ok ian@
+ OpenBSD-Commit-ID: 3765f4cc3ae1df874dba9102a3588ba7b48b8183
-commit 54268d589e85ecc43d3eba8d83f327bdada9d696
+commit 1134a48cdcef8e7363b9f6c73ebdd24405066738
Author: Damien Miller <djm@mindrot.org>
-Date: Fri May 11 14:04:40 2018 +1000
+Date: Thu Jan 28 08:57:31 2021 +1100
+
+ correct kex name in disabled code
+
+commit 67f47f1965abafc1830a287761125c2f4790857e
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Wed Jan 27 10:15:08 2021 +0000
+
+ upstream: this needs kex.h now
+
+ OpenBSD-Commit-ID: c5a42166c5aa002197217421a971e48be7cb5d41
+
+commit 39be3dc209f28f9c1ebfeba42adde8963b01e1cd
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Wed Jan 27 10:05:28 2021 +0000
- fix key-options.sh on platforms without openpty(3)
+ upstream: make ssh->kex->session_id a sshbuf instead of u_char*/size_t
- Skip the pty tests if the platform lacks openpty(3) and has to chown(2)
- the pty device explicitly. This typically requires root permissions that
- this test lacks.
+ and use that instead of global variables containing copies of it. feedback/ok
+ markus@
- bz#2856 ok dtucker@
+ OpenBSD-Commit-ID: a4b1b1ca4afd2e37cb9f64f737b30a6a7f96af68
-commit b2140a739be4c3b43cc1dc08322dca39a1e39d20
+commit 4ca6a1fac328477c642329676d6469dba59019a3
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri May 11 03:38:51 2018 +0000
+Date: Wed Jan 27 09:26:53 2021 +0000
- upstream: implement EMFILE mitigation for ssh-agent: remember the
+ upstream: remove global variable used to stash compat flags and use the
- fd rlimit and stop accepting new connections when it is exceeded (with some
- grace). Accept is resumed when enough connections are closed.
+ purpose-built ssh->compat variable instead; feedback/ok markus@
- bz#2576. feedback deraadt; ok dtucker@
+ OpenBSD-Commit-ID: 7c4f200e112dae6bcf99f5bae1a5629288378a06
+
+commit bba229b6f3328171f5e3ae85de443002523c0452
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Wed Jan 27 12:34:07 2021 +1100
+
+ Install moduli file before tests.
- OpenBSD-Commit-ID: 6a85d9cec7b85741961e7116a49f8dae777911ea
+ Reduces warnings during test runs.
+
+commit 1b83185593a90a73860a503d753a95ca6d726c00
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Wed Jan 27 11:58:26 2021 +1100
+
+ Run one test with -Werror to catch warnings.
-commit fdba503fdfc647ee8a244002f1581e869c1f3d90
+commit d1532d90074b212054d5fd965f833231b09982f5
Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Fri May 11 03:22:55 2018 +0000
+Date: Wed Jan 27 00:37:26 2021 +0000
- upstream: Explicit cast when snprintf'ing an uint64. Prevents
+ upstream: Logical not bitwise or. ok djm@
- warnings on platforms where int64 is long not long long. ok djm@
+ OpenBSD-Commit-ID: d4dc855cf04951b93c45caa383e1ac9af0a3b0e5
+
+commit 507b448a2465a53ab03a88acbc71cc51b48ca6ac
+Author: naddy@openbsd.org <naddy@openbsd.org>
+Date: Tue Jan 26 15:40:17 2021 +0000
+
+ upstream: move HostbasedAcceptedAlgorithms to the right place in
+
+ alphabetical order
- OpenBSD-Commit-ID: 9c5359e2fbfce11dea2d93f7bc257e84419bd001
+ OpenBSD-Commit-ID: d766820d33dd874d944c14b0638239adb522c7ec
-commit e7751aa4094d51a9bc00778aa8d07e22934c55ee
-Author: bluhm@openbsd.org <bluhm@openbsd.org>
-Date: Thu Apr 26 14:47:03 2018 +0000
+commit e26c980778b228bdd42b8353cc70101cf49b731b
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Tue Jan 26 11:25:01 2021 +0000
- upstream: Since the previous commit, ssh regress test sftp-chroot was
+ upstream: Remove unused variables leftover from refactoring. ok
- failing. The sftp program terminated with the wrong exit code as sftp called
- fatal() instad of exit(0). So when the sigchld handler waits for the child,
- remember that it was found. Then don't expect that main() can wait again. OK
- dtucker@
+ djm@
- OpenBSD-Commit-ID: bfafd940c0de5297940c71ddf362053db0232266
+ OpenBSD-Commit-ID: 8b3ad58bff828fcf874e54b2fc27a4cf1d9505e8
-commit 7c15301841e2e9d37cae732400de63ae9c0961d6
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Sun Apr 29 17:54:12 2018 +1000
+commit e9f78d6b06fc323bba1890b2dc3b8423138fb35c
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Tue Jan 26 05:32:21 2021 +0000
- Use includes.h instead of config.h.
+ upstream: Rename HostbasedKeyTypes (ssh) and
+
+ HostbasedAcceptedKeyTypes (sshd) to HostbasedAcceptedAlgorithms, which more
+ accurately reflects its effect. This matches a previous change to
+ PubkeyAcceptedAlgorithms. The previous names are retained as aliases. ok
+ djm@
- This ensures it picks up the definition of DEF_WEAK, the lack of which
- can cause compile errors in some cases (eg modern AIX). From
- michael at felt.demon.nl.
+ OpenBSD-Commit-ID: 49451c382adc6e69d3fa0e0663eeef2daa4b199e
-commit cec338967a666b7c8ad8b88175f2faeddf268116
+commit 48d0d7a4dd31154c4208ec39029d60646192f978
Author: Darren Tucker <dtucker@dtucker.net>
-Date: Thu Apr 19 09:53:14 2018 +1000
+Date: Tue Jan 26 14:48:07 2021 +1100
- Omit 3des-cbc if OpenSSL built without DES.
+ Disable sntrup761 if compiler doesn't support VLAs.
+
+ The sntrup761 code sourced from supercop uses variable length
+ arrays. Although widely supported, they are not part of the ANSI
+ C89 spec so if the compiler does not support VLAs, disable the
+ sntrup761x25519-sha512@openssh.com KEX method by replacing the kex
+ functions with no-op ones similar to what we do in kexecdh.c.
- Patch from hongxu.jia at windriver.com, ok djm@
+ This should allow OpenSSH to build with a plain C89 compiler again.
+ Spotted by tim@, ok djm@.
-commit a575ddd58835759393d2dddd16ebe5abdb56485e
+commit 37c70ea8d4f3664a88141bcdf0bf7a16bd5fd1ac
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Mon Apr 16 22:50:44 2018 +0000
+Date: Tue Jan 26 00:54:49 2021 +0000
- upstream: Disable SSH2_MSG_DEBUG messages for Twisted Conch clients
+ upstream: refactor key constraint parsing in ssh-agent
- without version numbers since they choke on them under some circumstances.
- https://twistedmatrix.com/trac/ticket/9422 via Colin Watson
+ Key constraints parsing code previously existed in both the "add regular
+ key" and "add smartcard key" path. This unifies them but also introduces
+ more consistency checking: duplicated constraints and constraints that
+ are nonsensical for a particular situation (e.g. FIDO provider for a
+ smartcard key) are now banned.
- Newer Conch versions have a version number in their ident string and
- handle debug messages okay. https://twistedmatrix.com/trac/ticket/9424
+ ok markus@
- OpenBSD-Commit-ID: 6cf7be262af0419c58ddae11324d9c0dc1577539
+ OpenBSD-Commit-ID: 511cb1b1c021ee1d51a4c2d649b937445de7983c
-commit 390c7000a8946db565b66eab9e52fb11948711fa
+commit e0e8bee8024fa9e31974244d14f03d799e5c0775
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sat Apr 14 21:50:41 2018 +0000
+Date: Tue Jan 26 00:53:31 2021 +0000
- upstream: don't free the %C expansion, it's used later for
+ upstream: more ssh-agent refactoring
+
+ Allow confirm_key() to accept an additional reason suffix
- LocalCommand
+ Factor publickey userauth parsing out into its own function and allow
+ it to optionally return things it parsed out of the message to its
+ caller.
- OpenBSD-Commit-ID: 857b5cb37b2d856bfdfce61289a415257a487fb1
+ feedback/ok markus@
+
+ OpenBSD-Commit-ID: 29006515617d1aa2d8b85cd2bf667e849146477e
-commit 3455f1e7c48e2e549192998d330214975b9b1dc7
+commit dfe18a295542c169ffde8533b3d7fe42088e2de7
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Apr 13 05:04:12 2018 +0000
+Date: Tue Jan 26 00:51:30 2021 +0000
- upstream: notify user immediately when underlying ssh process dies;
+ upstream: make struct hostkeys public; I have no idea why I made it
+
+ opaque originally.
- patch from Thomas Kuthan in bz2719; ok dtucker@
+ ok markus@
- OpenBSD-Commit-ID: 78fac88c2f08054d1fc5162c43c24162b131cf78
+ OpenBSD-Commit-ID: e50780b34d4bbe628d69b2405b024dd749d982f3
-commit 1c5b4bc827f4abc3e65888cda061ad5edf1b8c7c
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Fri Apr 13 16:23:57 2018 +1000
+commit 3b44f2513cae89c920e8fe927b9bc910a1c8c65a
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Tue Jan 26 00:49:30 2021 +0000
- Allow nanosleep in preauth privsep child.
+ upstream: move check_host_cert() from sshconnect,c to sshkey.c and
+
+ refactor it to make it more generally usable and testable.
- The new timing attack mitigation code uses nanosleep in the preauth
- codepath, allow in systrace andbox too.
+ ok markus@
+
+ OpenBSD-Commit-ID: 536f489f5ff38808c1fa711ba58d4579b636f9e4
-commit 0e73428038d5ecfa5d2a28cff26661502a7aff4e
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Fri Apr 13 16:06:29 2018 +1000
+commit 1fe16fd61bb53944ec510882acc0491abd66ff76
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Tue Jan 26 00:47:47 2021 +0000
- Allow nanosleep in preauth privsep child.
+ upstream: use recallocarray to allocate the agent sockets table;
+
+ also clear socket entries that are being marked as unused.
- The new timing attack mitigation code uses nanosleep in the preauth
- codepath, allow in sandbox.
+ spinkle in some debug2() spam to make it easier to watch an agent
+ do its thing.
+
+ ok markus
+
+ OpenBSD-Commit-ID: 74582c8e82e96afea46f6c7b6813a429cbc75922
-commit e9d910b0289c820852f7afa67f584cef1c05fe95
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Fri Apr 13 03:57:26 2018 +0000
+commit cb7b22ea20a01332c81c0ddcb3555ad50de9cce2
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Tue Jan 26 00:46:17 2021 +0000
+
+ upstream: factor out common code in the agent client
+
+ Add a ssh_request_reply_decode() function that sends a message to
+ the agent, reads and parses a success/failure reply.
+ Use it for all requests that only expect success/failure
+
+ ok markus@
+
+ OpenBSD-Commit-ID: e0c1f4d5e6cfa525d62581e2b8de93be0cb85adb
+
+commit d1e578afe7cd48140ad6e92a453f9b035363fd7f
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Mon Jan 25 06:00:17 2021 +0000
- upstream: Defend against user enumeration timing attacks. This
+ upstream: make ssh hostbased authentication send the signature
+
+ algorithm in its SSH2_MSG_USERAUTH_REQUEST packets instead of the key type.
+ This make HostbasedAcceptedAlgorithms do what it is supposed to - filter on
+ signature algorithm and not key type.
- establishes a minimum time for each failed authentication attempt (5ms) and
- adds a per-user constant derived from a host secret (0-4ms). Based on work
- by joona.kannisto at tut.fi, ok markus@ djm@.
+ spotted with dtucker@ ok markus@
- OpenBSD-Commit-ID: b7845b355bb7381703339c8fb0e57e81a20ae5ca
+ OpenBSD-Commit-ID: 25bffe19f0326972f5728170f7da81d5f45c78c6
-commit d97874cbd909eb706886cd0cdd418f812c119ef9
+commit 95eca1e195a3b41baa1a725c2c5af8a09d885e4b
Author: Darren Tucker <dtucker@dtucker.net>
-Date: Fri Apr 13 13:43:55 2018 +1000
+Date: Sat Jan 23 18:26:05 2021 +1100
- Using "==" in shell tests is not portable.
+ ifdef new instance of sin6_scope_id
- Patch from rsbecker at nexbridge.com.
+ Put inside HAVE_STRUCT_SOCKADDR_IN6_SIN6_SCOPE_ID similar to
+ existing instance. Should fix error on UnixWare 7.
-commit cfb1d9bc76734681e3dea532a1504fcd466fbe91
-Author: Damien Miller <djm@mindrot.org>
-Date: Fri Apr 13 13:38:06 2018 +1000
+commit 6ffdcdda128045226dda7fbb3956407978028a1e
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Mon Jan 18 11:43:34 2021 +0000
- Fix tunnel forwarding broken in 7.7p1
+ upstream: Fix long->int for convtime tests here too. Spotted by
- bz2855, ok dtucker@
+ tobhe@.
+
+ OpenBSD-Regress-ID: a87094f5863312d00938afba771d25f788c849d0
-commit afa6e79b76fb52a0c09a29688b5c0d125eb08302
-Author: Damien Miller <djm@mindrot.org>
-Date: Fri Apr 13 13:31:42 2018 +1000
+commit b55b7565f15327d82ad7acbddafa90b658c5f0af
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Fri Jan 22 02:46:40 2021 +0000
- prefer to use getrandom() for PRNG seeding
+ upstream: PubkeyAcceptedKeyTypes->PubkeyAcceptedAlgorithms
+
+ here too.
- Only applies when built --without-openssl. Thanks Jann Horn for
- reminder.
+ OpenBSD-Commit-ID: 3b64a640f8ce8c21d9314da9df7ce2420eefde3a
-commit 575fac34a97f69bc217b235f81de9f8f433eceed
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Fri Apr 13 13:13:33 2018 +1000
+commit ee9c0da8035b3168e8e57c1dedc2d1b0daf00eec
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Fri Jan 22 02:44:58 2021 +0000
- Revert $REGRESSTMP changes.
+ upstream: Rename PubkeyAcceptedKeyTypes keyword to
- Revert 3fd2d229 and subsequent changes as they turned out to be a
- portability hassle.
+ PubkeyAcceptedAlgorithms. While the two were originally equivalent, this
+ actually specifies the signature algorithms that are accepted. Some key
+ types (eg RSA) can be used by multiple algorithms (eg ssh-rsa, rsa-sha2-512)
+ so the old name is becoming increasingly misleading. The old name is
+ retained as an alias. Prompted by bz#3253, help & ok djm@, man page help jmc@
+
+ OpenBSD-Commit-ID: 0346b2f73f54c43d4e001089759d149bfe402ca5
-commit 10479cc2a4acd6faaf643eb305233b49d70c31c1
-Author: Damien Miller <djm@mindrot.org>
-Date: Tue Apr 10 10:19:02 2018 +1000
+commit a8e798feabe36d02de292bcfd274712cae1d8d17
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Fri Jan 15 02:58:11 2021 +0000
- Many typo fixes from Karsten Weiss
+ upstream: Change types in convtime() unit test to int to match change
+
+ its new type. Add tests for boundary conditions and fix convtime to work up
+ to INT_MAX. ok djm@
- Spotted using https://github.com/lucasdemarchi/codespell
+ OpenBSD-Regress-ID: ba2b81e9a3257fff204b020affe85b604a44f97e
-commit 907da2f88519b34189fd03fac96de0c52d448233
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Tue Apr 10 00:14:10 2018 +0000
+commit 9bde1a420626da5007bf7ab499fa2159b9eddf72
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Fri Jan 15 04:31:25 2021 +0000
- upstream: more typos spotted by Karsten Weiss using codespell
+ upstream: Make output buffer larger to prevent potential truncation
+
+ warnings from compilers not smart enough to know the strftime calls won't
+ ever fully fill "to" and "from". ok djm@
- OpenBSD-Regress-ID: d906a2aea0663810a658b7d0bc61a1d2907d4d69
+ OpenBSD-Commit-ID: 83733f1b01b82da88b9dd1769475952aff10bdd7
-commit 37e5f4a7ab9a8026e5fc2f47dafb0f1b123d39e9
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Tue Apr 10 00:13:27 2018 +0000
+commit 02da325f10b214219eae2bb1bc2d3bf0c2f13f9f
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Fri Jan 15 02:58:11 2021 +0000
- upstream: make this a bit more portable-friendly
+ upstream: Change types in convtime() unit test to int to match
- OpenBSD-Regress-ID: 62f7b9e055e8dfaab92b3825f158beeb4ca3f963
+ change its new type. Add tests for boundary conditions and fix convtime to
+ work up to INT_MAX. ok djm@
+
+ OpenBSD-Commit-ID: 01dc0475f1484ac2f47facdfcf9221f9472145de
-commit 001aa55484852370488786bd40e9fdad4b465811
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Tue Apr 10 00:10:49 2018 +0000
+commit 5339ab369c225b40bc64d5ec3374f5c91b3ad609
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Fri Jan 15 02:32:41 2021 +0000
- upstream: lots of typos in comments/docs. Patch from Karsten Weiss
+ upstream: In waitfd(), when poll returns early we are subtracting
- after checking with codespell tool
- (https://github.com/lucasdemarchi/codespell)
+ the elapsed time from the timeout each loop, so we only want to measure the
+ elapsed time the poll() in that loop, not since the start of the function.
+ Spotted by chris.xj.zhu at gmail.com, ok djm@
- OpenBSD-Commit-ID: 373222f12d7ab606598a2d36840c60be93568528
+ OpenBSD-Commit-ID: 199df060978ee9aa89b8041a3dfaf1bf7ae8dd7a
-commit 260ede2787fe80b18b8d5920455b4fb268519c7d
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Mon Apr 9 23:54:49 2018 +0000
+commit a164862dfa863b54b7897f66e1dd75437f086c11
+Author: rob@openbsd.org <rob@openbsd.org>
+Date: Thu Jan 14 19:45:06 2021 +0000
- upstream: don't kill ssh-agent's listening socket entriely if we
+ upstream: Minor grammatical correction.
- fail to accept a connection; bz#2837, patch from Lukas Kuster
+ OK jmc@
- OpenBSD-Commit-ID: 52413f5069179bebf30d38f524afe1a2133c738f
+ OpenBSD-Commit-ID: de0fad0581e212b2750751e479b79c18ff8cac02
+
+commit 8635e7df7e3a3fbb4a4f6cd5a7202883b2506087
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Wed Jan 13 18:00:57 2021 +1100
+
+ Merge Mac OS X targets into a single config.
+
+commit ac112ade990585c511048ed4edaf2d9fc92b61f0
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Tue Jan 12 19:22:47 2021 +1100
+
+ Add Mac OS X test targets.
+
+commit 1050109b4b2884bf50fd1b3aa084c7fd0a42ae90
+Author: anatasluo <luolongjuna@gmail.com>
+Date: Mon Jan 11 13:51:39 2021 +0000
-commit ebc8b4656f9b0f834a642a9fb3c9fbca86a61838
-Author: tj@openbsd.org <tj@openbsd.org>
-Date: Mon Apr 9 20:41:22 2018 +0000
+ Remove duplicated declaration in fatal.c .
- upstream: the UseLogin option was removed, so remove it here too.
+commit 7d0f8a3369579dfe398536eb4e3da7bc15da9599
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Mon Jan 11 04:48:22 2021 +0000
+
+ upstream: Correct spelling of persourcenetblocksize in config-dump
- ok dtucker
+ mode.
- OpenBSD-Commit-ID: 7080be73a64d68e21f22f5408a67a0ba8b1b6b06
+ OpenBSD-Commit-ID: ecdc49e2b6bde6b6b0e52163d621831f6ac7b13d
-commit 3e36f281851fc8e9c996b33f108b2ae167314fbe
-Author: jmc@openbsd.org <jmc@openbsd.org>
-Date: Sun Apr 8 07:36:02 2018 +0000
+commit ba328bd7a6774f30daaf90b83f1933cc4afc866c
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Sat Jan 9 12:31:46 2021 +0000
- upstream: tweak previous;
+ upstream: Adjust kexfuzz to addr.c/addrmatch.c split.
- OpenBSD-Commit-ID: 2b9c23022ea7b9dddb62864de4e906000f9d7474
+ OpenBSD-Regress-ID: 1d8d23bb548078020be2fb52c4c643efb190f0eb
-commit 8368571efd6693c5c57f850e23a2372acf3f865f
-Author: jmc@openbsd.org <jmc@openbsd.org>
-Date: Sat Apr 7 13:50:10 2018 +0000
+commit b08ef25552443e94c0857d5e3806dd019ccc55d7
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Sat Jan 9 12:24:30 2021 +0000
- upstream: tweak previous;
+ upstream: Update unittests for addr.c/addrmatch.c split.
- OpenBSD-Commit-ID: 38e347b6f8e888f5e0700d01abb1eba7caa154f9
+ OpenBSD-Regress-ID: de2b415fb7af084a91c6ef147a90482d8f771eef
-commit 555294a7279914ae6795b71bedf4e6011b7636df
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Apr 6 13:02:39 2018 +0000
+commit 6d30673fedec2d251f4962c526fd0451f70c4d97
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Mon Jan 11 02:12:57 2021 +0000
- upstream: Allow "SendEnv -PATTERN" to clear environment variables
+ upstream: Change convtime() from returning long to returning int.
- previously labeled for sendind. bz#1285 ok dtucker@
+ On platforms where sizeof(int) != sizeof(long), convtime could accept values
+ >MAX_INT which subsequently truncate when stored in an int during config
+ parsing. bz#3250, ok djm@
- OpenBSD-Commit-ID: f6fec9e3d0f366f15903094fbe1754cb359a0df9
+ OpenBSD-Commit-ID: 8fc932683d6b4660d52f50911d62bd6639c5db31
-commit 40f5f03544a07ebd2003b443d42e85cb51d94d59
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Apr 6 04:15:45 2018 +0000
+commit 7a57adb8b07b2ad0aead4b2e09ee18edc04d0481
+Author: jmc@openbsd.org <jmc@openbsd.org>
+Date: Sat Jan 9 12:51:12 2021 +0000
- upstream: relax checking of authorized_keys environment="..."
+ upstream: add a comma to previous;
- options to allow underscores in variable names (regression introduced in
- 7.7). bz2851, ok deraadt@
+ OpenBSD-Commit-ID: 9139433701c0aa86a0d3a6c7afe10d1c9c2e0869
+
+commit 3a923129534b007c2e24176a8655dec74eca9c46
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Sat Jan 9 12:10:02 2021 +0000
+
+ upstream: Add PerSourceMaxStartups and PerSourceNetBlockSize
- OpenBSD-Commit-ID: 69690ffe0c97ff393f2c76d25b4b3d2ed4e4ac9c
+ options which provide more fine grained MaxStartups limits. Man page help
+ jmc@, feedback & ok djm@
+
+ OpenBSD-Commit-ID: e2f68664e3d02c0895b35aa751c48a2af622047b
-commit 30fd7f9af0f553aaa2eeda5a1f53f26cfc222b5e
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Apr 6 03:51:27 2018 +0000
+commit d9a2bc71693ea27461a78110005d5a2d8b0c6a50
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Sat Jan 9 11:58:50 2021 +0000
- upstream: add a couple of missed options to the config dump; patch
+ upstream: Move address handling functions out into their own file
- from Jakub Jelen via bz2835
+ in order to reuse them for per-source maxstartups limiting. Supplement with
+ some additional functions from djm's flowtools that we'll also need. ok djm@
+ (as part of a larger diff).
- OpenBSD-Commit-ID: 5970adadf6ef206bee0dddfc75d24c2019861446
+ OpenBSD-Commit-ID: e3e7d9ccc6c9b82e25cfef0ec83598e8e2327cbf
+
+commit b744914fcb76d70761f1b667de95841b3fc80a56
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Sat Jan 9 00:36:05 2021 +1100
+
+ Add test against Graphene hardened malloc.
-commit 8d6829be324452d2acd282d5f8ceb0adaa89a4de
+commit 6cb52d5bf771f6769b630fce35a8e9b8e433044f
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Apr 6 03:34:27 2018 +0000
+Date: Fri Jan 8 04:49:13 2021 +0000
- upstream: ssh does not accept -oInclude=... on the commandline, the
+ upstream: make CheckHostIP default to 'no'. It doesn't provide any
- Include keyword is for configuration files only. bz#2840, patch from Jakub
- Jelen
+ perceptible value and makes it much harder for hosts to change host keys,
+ particularly ones that use IP-based load-balancing.
+
+ ok dtucker@
- OpenBSD-Commit-ID: 32d052b4a7a7f22df35fe3f71c368c02b02cacb0
+ OpenBSD-Commit-ID: 0db98413e82074f78c7d46784b1286d08aee78f0
+
+commit 309b642e1442961b5e57701f095bcd4acd2bfb5f
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Fri Jan 8 15:50:41 2021 +1100
+
+ Run tests with sudo for better coverage.
+
+commit c336644351fa3c715a08b7a292e309e72792e71e
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Fri Jan 8 14:26:32 2021 +1100
+
+ Add Ubuntu 16.04 and 20.04 test targets.
-commit 00c5222ddc0c8edcaa4ea45ac03befdc8013d137
+commit 4c7af01f9dcc1606dec033e7665a042cb0d8ec52
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Thu Apr 5 22:54:28 2018 +0000
+Date: Fri Jan 8 02:57:24 2021 +0000
- upstream: We don't offer CBC cipher by default any more. Spotted by
+ upstream: If a signature operation on a FIDO key fails with a
+
+ "incorrect PIN" reason and no PIN was initially requested from the user, then
+ request a PIN and retry the operation.
+
+ This smoothes over a few corner cases including FIDO devices that
+ require PINs for all hosted credentials, biometric FIDO devices that
+ fall back to requiring PIN when reading the biometric failed, devices
+ that don't implement reading credProtect status for downloaded keys
+ and probably a few more cases that I haven't though of yet.
- Renaud Allard (via otto@)
+ ok dtucker@
- OpenBSD-Commit-ID: a559b1eef741557dd959ae378b665a2977d92dca
+ OpenBSD-Commit-ID: 176db8518933d6a5bbf81a2e3cf62447158dc878
-commit 5ee8448ad7c306f05a9f56769f95336a8269f379
-Author: job@openbsd.org <job@openbsd.org>
-Date: Wed Apr 4 15:12:17 2018 +0000
+commit 64ddd0fe68c4a7acf99b78624f8af45e919cd317
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Fri Jan 8 02:44:14 2021 +0000
- upstream: Update default IPQoS in ssh(1), sshd(8) to DSCP AF21 for
+ upstream: don't try to use timespeccmp(3) directly as a qsort(3)
- interactive and CS1 for bulk
+ comparison function - it returns 0/1 and not the -1/0/1 that qsort expectes.
- AF21 was selected as this is the highest priority within the low-latency
- service class (and it is higher than what we have today). SSH is elastic
- and time-sensitive data, where a user is waiting for a response via the
- network in order to continue with a task at hand. As such, these flows
- should be considered foreground traffic, with delays or drops to such
- traffic directly impacting user-productivity.
+ fixes sftp "ls -ltr" under some circumstances.
- For bulk SSH traffic, the CS1 "Lower Effort" marker was chosen to enable
- networks implementing a scavanger/lower-than-best effort class to
- discriminate scp(1) below normal activities, such as web surfing. In
- general this type of bulk SSH traffic is a background activity.
+ Based on patch by Masahiro Matsuya via bz3248.
- An advantage of using "AF21" for interactive SSH and "CS1" for bulk SSH
- is that they are recognisable values on all common platforms (IANA
- https://www.iana.org/assignments/dscp-registry/dscp-registry.xml), and
- for AF21 specifically a definition of the intended behavior exists
- https://tools.ietf.org/html/rfc4594#section-4.7 in addition to the definition
- of the Assured Forwarding PHB group https://tools.ietf.org/html/rfc2597, and
- for CS1 (Lower Effort) there is https://tools.ietf.org/html/rfc3662
+ OpenBSD-Commit-ID: 65b5e9f18bb0d10573868c3516de6e5170adb163
+
+commit 599df78f3008cf78af21f8977be3e1dd085f8e2e
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Fri Jan 8 02:33:13 2021 +0000
+
+ upstream: Update the sntrup761 creation script and generated code:
- The first three bits of "AF21" map to the equivalent IEEEE 802.1D PCP, IEEE
- 802.11e, MPLS EXP/CoS and IP Precedence value of 2 (also known as "Immediate",
- or "AC_BE"), and CS1's first 3 bits map to IEEEE 802.1D PCP, IEEE 802.11e,
- MPLS/CoS and IP Precedence value 1 ("Background" or "AC_BK").
+ - remove unneeded header files and typedefs and rely on crypto_api.h - add
+ defines to map types used to the crypto_api ones instead of typedefs. This
+ prevents typedef name collisions in -portable. - remove CRYPTO_NAMESPACE
+ entirely instead of making it a no-op - delete unused functions and make the
+ remaining ones that aren't exported static.
- OK deraadt@, "no objection" djm@
+ ok djm@
- OpenBSD-Commit-ID: d11d2a4484f461524ef0c20870523dfcdeb52181
+ OpenBSD-Commit-ID: 7b9d0cf3acd5a3c1091da8afe00c904d38cf5783
-commit 424b544fbda963f973da80f884717c3e0a513288
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Tue Apr 3 02:14:08 2018 +0000
+commit 16448ff529affda7e2a15ee7c3200793abde0759
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Fri Jan 8 02:19:24 2021 +0000
- upstream: Import regenerated moduli file.
+ upstream: mention that DisableForwarding is valid in a sshd_config
+
+ Match block reported by Fredrik Eriksson in bz3239
- OpenBSD-Commit-ID: 1de0e85522051eb2ffa00437e1885e9d7b3e0c2e
+ OpenBSD-Commit-ID: 3a71c3d84b597f5e43e4b40d5232797daf0993f6
-commit 323f66ce934df2da551f256f37d69822428e1ca1
+commit 91bac5e95b1b0debf9b2b4f05c20dcfa96b368b9
Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Fri Apr 6 04:18:35 2018 +0000
+Date: Mon Jan 4 21:58:58 2021 +0000
- upstream: Add test for username options parsing order, prompted by
+ upstream: estructure sntrup761.sh to process all files in a single
- bz#2849.
+ list, which will make it easier to reorder. Re-inline int32_MINMAX. ok
+ tobhe@
- OpenBSD-Regress-ID: 6985cd32f38596882a3ac172ff8c510693b65283
+ OpenBSD-Commit-ID: d145c6c19b08bb93c9e14bfaa7af589d90f144c0
-commit e8f474554e3bda102a797a2fbab0594ccc66f097
-Author: Damien Miller <djm@mindrot.org>
-Date: Fri Apr 6 14:11:44 2018 +1000
+commit 4d96a3ebab2224f17e639a15078e03be1ad3736d
+Author: tobhe@openbsd.org <tobhe@openbsd.org>
+Date: Sun Jan 3 18:05:21 2021 +0000
- Expose SSH_AUTH_INFO_0 to PAM auth modules
+ upstream: Prevent redefinition of `crypto_int32' error with gcc3.
- bz#2408, patch from Radoslaw Ejsmont; ok dtucker@
+ Fixes compilation on luna88k.
+
+ Feedback millert@
+ Found by and ok aoyama@
+
+ OpenBSD-Commit-ID: f305ddfe575a26cc53431af3fde3f4aeebed9ba6
-commit 014ba209cf4c6a159baa30ecebbaddfa97da7100
+commit a23954eeb930ccc8a66a2710153730769dba31b6
Author: Darren Tucker <dtucker@dtucker.net>
-Date: Tue Apr 3 12:18:00 2018 +1000
+Date: Fri Jan 1 22:00:49 2021 +1100
- Import regenerated moduli file.
+ Undef int32 after sort routines.
+
+ This prevents typedef'ing crypto_int32 twice, in sntrup761.c and
+ crypto_api.h, which some compilers (at least some GCCs) don't accept.
-commit a0349a1cc4a18967ad1dbff5389bcdf9da098814
+commit 148b8a661c3f93e4b6d049ee902de3d521261fbc
Author: Damien Miller <djm@mindrot.org>
-Date: Mon Apr 2 15:38:28 2018 +1000
+Date: Thu Dec 31 12:47:22 2020 +1100
- update versions in .spec files
+ fix: missing pieces of previous commit
-commit 816ad38f79792f5617e3913be306ddb27e91091c
+commit 3d999be7b987c848feda718cfcfcdc005ddf670d
+Author: tobhe@openbsd.org <tobhe@openbsd.org>
+Date: Wed Dec 30 14:13:28 2020 +0000
+
+ upstream: Use int64_t for intermediate values in int32_MINMAX to
+
+ prevent signed 32-bit integer overflow.
+
+ Found by and ok djm@
+ ok markus@
+
+ OpenBSD-Commit-ID: 4f0704768e34cf45fdd792bac4011c6971881bb3
+
+commit 5c1953bf98732da5a76c706714ac066dbfa015ac
Author: Damien Miller <djm@mindrot.org>
-Date: Mon Apr 2 15:38:20 2018 +1000
+Date: Tue Dec 29 12:40:54 2020 +1100
- update version number
+ adapt KEX fuzzer to PQ kex change
-commit 2c71ca1dd1efe458cb7dee3f8a1a566f913182c2
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Fri Mar 30 18:23:07 2018 +1100
+commit 659864fe81dbc57eeed3769c462679d83e026640
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Tue Dec 29 01:02:15 2020 +0000
- Disable native strndup and strnlen on AIX.
+ upstream: Adapt to replacement of
- On at least some revisions of AIX, strndup returns unterminated strings
- under some conditions, apparently because strnlen returns incorrect
- values in those cases. Disable both on AIX and use the replacements
- from openbsd-compat. Fixes problem with ECDSA keys there, ok djm.
+ sntrup4591761x25519-sha512@tinyssh.org with
+ sntrup761x25519-sha512@openssh.com.
+
+ Also test sntrup761x25519-sha512@openssh.com in unittests/kex
+
+ OpenBSD-Regress-ID: cfa3506b2b077a9cac1877fb521efd2641b6030c
-commit 6b5a17bc14e896e3904dc58d889b58934cfacd24
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Mon Mar 26 13:12:44 2018 +1100
+commit 2c71cec020219d69df84055c59eba5799a1233ec
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Tue Dec 29 00:59:15 2020 +0000
- Include ssh_api.h for struct ssh.
+ upstream: Update/replace the experimental post-quantim hybrid key
+
+ exchange method based on Streamlined NTRU Prime (coupled with X25519).
+
+ The previous sntrup4591761x25519-sha512@tinyssh.org method is
+ replaced with sntrup761x25519-sha512@openssh.com. Per the authors,
+ sntrup4591761 was replaced almost two years ago by sntrup761.
+
+ The sntrup761 implementaion, like sntrup4591761 before it, is public
+ domain code extracted from the SUPERCOP cryptography benchmark
+ suite (https://bench.cr.yp.to/supercop.html).
- struct ssh is needed by implementations of sys_auth_passwd() that were
- converted in commit bba02a50. Needed to fix build on AIX, I assume for
- the other platforms too (although it should be harmless if not needed).
+ Thanks for Daniel J Bernstein for guidance on algorithm selection.
+ Patch from Tobias Heider; feedback & ok markus@ and myself
+
+ (note this both the updated method and the one that it replaced are
+ disabled by default)
+
+ OpenBSD-Commit-ID: 2bf582b772d81ee24e911bb6f4b2aecfd39338ae
-commit bc3f80e4d191b8e48650045dfa8a682cd3aabd4d
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Mon Mar 26 12:58:09 2018 +1100
+commit 09d070ccc3574ae0d7947d212ed53c7268ef7e1f
+Author: jmc@openbsd.org <jmc@openbsd.org>
+Date: Tue Dec 22 07:40:26 2020 +0000
- Remove UNICOS code missed during removal.
+ upstream: tweak the description of KnownHostsCommand in ssh_conf.5,
+
+ and add entries for it to the -O list in scp.1 and sftp.1;
+
+ ok djm
- Fixes compile error on AIX.
+ OpenBSD-Commit-ID: aba31ebea03f38f8d218857f7ce16a500c3e4aff
-commit 9d57762c24882e2f000a21a0ffc8c5908a1fa738
-Author: markus@openbsd.org <markus@openbsd.org>
-Date: Sat Mar 24 19:29:03 2018 +0000
+commit 931c93389a80e32272712459b1102d303844453d
+Author: Damien Miller <djm@mindrot.org>
+Date: Tue Dec 22 19:43:55 2020 +1100
- upstream: openssh-7.7
-
- OpenBSD-Commit-ID: 274e614352460b9802c905f38fb5ea7ed5db3d41
+ whitespace at EOL
-commit 4b7d8acdbbceef247dc035e611e577174ed8a87e
+commit 397b1c4d393f97427283a4717e9015a2bd31b8a5
Author: Damien Miller <djm@mindrot.org>
-Date: Mon Mar 26 09:37:02 2018 +1100
+Date: Tue Dec 22 19:42:37 2020 +1100
+
+ whitespace at EOL
+
+commit 33fa3ac547e5349ca34681cce6727b2f933dff0a
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Tue Dec 22 19:21:26 2020 +1100
+
+ Improve AIX text.
+
+commit 0f2e21c9dca89598b694932b5b05848380a23ec0
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Tue Dec 22 18:56:54 2020 +1100
- Remove authinfo.sh test dependency on printenv
+ Include stdio.h for FILE in misc.h.
- Some platforms lack printenv in the default $PATH.
- Reported by Tom G. Christensen
+ Fixes build on at least OpenBSD.
-commit 4afeaf3dcb7dc70efd98fcfcb0ed28a6b40b820e
-Author: Tim Rice <tim@multitalents.net>
-Date: Sun Mar 25 10:00:21 2018 -0700
+commit 3e9811e57b57ee66b0f70d99d7258da3153b0e8a
+Author: Damien Miller <djm@mindrot.org>
+Date: Tue Dec 22 18:31:50 2020 +1100
- Use libiaf on all sysv5 systems
+ ensure $LOGNAME is set in tests
-commit bba02a5094b3db228ceac41cb4bfca165d0735f3
-Author: Tim Rice <tim@multitalents.net>
-Date: Sun Mar 25 09:17:33 2018 -0700
+commit 3eb647cbb34d87a063aa7714256c6e56103fffda
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Tue Dec 22 06:47:24 2020 +0000
- modified: auth-sia.c
- modified: openbsd-compat/port-aix.c
- modified: openbsd-compat/port-uw.c
+ upstream: more detail for failing tests
- propogate changes to auth-passwd.c in commit
- 7c856857607112a3dfe6414696bf4c7ab7fb0cb3 to other providers
- of sys_auth_passwd()
+ OpenBSD-Regress-ID: c68c0e5a521cad7e7f68e54c54ebf86d6c10ee1d
-commit d7a7a39168bdfe273587bf85d779d60569100a3f
-Author: markus@openbsd.org <markus@openbsd.org>
-Date: Sat Mar 24 19:29:03 2018 +0000
+commit 2873f19570d4d8758be24dbf78332be9a779009b
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Tue Dec 22 06:03:36 2020 +0000
- upstream: openssh-7.7
+ upstream: regress test for KnownHostsCommand
- OpenBSD-Commit-ID: 274e614352460b9802c905f38fb5ea7ed5db3d41
+ OpenBSD-Regress-ID: ffc77464320b6dabdcfa0a72e0df02659233a38a
-commit 9efcaaac314c611c6c0326e8bac5b486c424bbd2
-Author: markus@openbsd.org <markus@openbsd.org>
-Date: Sat Mar 24 19:28:43 2018 +0000
+commit 0121aa87bab9ad2365de2d07f2832b56d5ff9871
+Author: tb@openbsd.org <tb@openbsd.org>
+Date: Tue Dec 22 03:05:31 2020 +0000
- upstream: fix bogus warning when signing cert keys using agent;
+ upstream: Remove lines accidentally left behind in the ProxyJump
+
+ parsing fix r1.345.
- from djm; ok deraadt dtucker
+ ok djm
- OpenBSD-Commit-ID: 12e50836ba2040042383a8b71e12d7ea06e9633d
+ OpenBSD-Commit-ID: fe767c108c8117bea33767b080ff62eef2c55f5c
-commit 393436024d2e4b4c7a01f9cfa5854e7437896d11
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Sun Mar 25 09:40:46 2018 +1100
+commit da4bf0db942b5f0278f33238b86235e5813d7a5a
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Tue Dec 22 00:15:22 2020 +0000
- Replace /dev/stdin with "-".
+ upstream: add a ssh_config KnownHostsCommand that allows the client
+
+ to obtain known_hosts data from a command in addition to the usual files.
- For some reason sftp -b doesn't work with /dev/stdin on Cygwin, as noted
- and suggested by vinschen at redhat.com.
+ The command accepts bunch of %-expansions, including details of the
+ connection and the offered server host key. Note that the command may
+ be invoked up to three times per connection (see the manpage for
+ details).
+
+ ok markus@
+
+ OpenBSD-Commit-ID: 2433cff4fb323918ae968da6ff38feb99b4d33d0
-commit b5974de1a1d419e316ffb6524b1b277dda2f3b49
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Fri Mar 23 13:21:14 2018 +1100
+commit a34e14a5a0071de2036826a00197ce38c8b4ba8b
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Tue Dec 22 00:12:22 2020 +0000
- Provide $OBJ to paths in PuTTY interop tests.
+ upstream: move subprocess() from auth.c to misc.c
+
+ make privilege dropping optional but allow it via callbacks (to avoid
+ need to link uidswap.c everywhere)
+
+ add some other flags (keep environment, disable strict path safety check)
+ that make this more useful for client-side use.
+
+ feedback & ok markus@
+
+ OpenBSD-Commit-ID: a80ea9fdcc156f1a18e9c166122c759fae1637bf
-commit dc31e79454e9b9140b33ad380565fdb59b9c4f33
+commit 649205fe388b56acb3481a1b2461f6b5b7c6efa6
Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Fri Mar 16 09:06:31 2018 +0000
+Date: Mon Dec 21 22:48:41 2020 +0000
- upstream: Tell puttygen to use /dev/urandom instead of /dev/random. On
+ upstream: Remove explicit rijndael-cbc@lysator.liu.se test since the
- OpenBSD they are both non-blocking, but on many other -portable platforms it
- blocks, stalling tests.
+ cipher was removed.
- OpenBSD-Regress-ID: 397d0d4c719c353f24d79f5b14775e0cfdf0e1cc
+ OpenBSD-Regress-ID: aa93cddb4ecd9bc21446a79008a1a53050e64f17
-commit cb1f94431ef319cd48618b8b771b58739a8210cf
-Author: markus@openbsd.org <markus@openbsd.org>
-Date: Thu Mar 22 07:06:11 2018 +0000
+commit 03e93c753d7c223063ad8acaf9a30aa511e5f931
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Mon Dec 21 11:09:32 2020 +0000
- upstream: ssh/xmss: fix build; ok djm@
+ upstream: Remove the pre-standardization cipher
+
+ rijndael-cbc@lysator.liu.se. It is an alias for aes256-cbc which was
+ standardized in RFC4253 (2006), has been deprecated and disabled by default
+ since OpenSSH 7.2 (2016) and was only briefly documented in ssh.1 in 2001.
+
+ This will reduce the amount of work the cipher/kex regression tests need
+ to do by a little bit. ok markus@ djm@
- OpenBSD-Commit-ID: c9374ca41d4497f1c673ab681cc33f6e7c5dd186
+ OpenBSD-Commit-ID: fb460acc18290a998fd70910b19c29b4e4f199ad
-commit 27979da9e4074322611355598f69175b9ff10d39
-Author: markus@openbsd.org <markus@openbsd.org>
-Date: Thu Mar 22 07:05:48 2018 +0000
+commit a11ca015879eab941add8c6bdaaec7d41107c6f5
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Mon Dec 21 09:19:53 2020 +0000
- upstream: ssh/xmss: fix deserialize for certs; ok djm@
+ upstream: properly fix ProxyJump parsing; Thanks to tb@ for
+
+ pointing out my error (parse_ssh_uri() can return -1/0/1, that I missed).
+ Reported by Raf Czlonka via bugs@
+
+ ok tb@
- OpenBSD-Commit-ID: f44c41636c16ec83502039828beaf521c057dddc
+ OpenBSD-Commit-ID: a2991a3794bcaf1ca2b025212cce11cdb5f6b7d6
-commit c6cb2565c9285eb54fa9dfbb3890f5464aff410f
+commit d97fb879724f1670bf55d9adfea7278a93c33ae2
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Mon Dec 21 01:31:06 2020 +0000
+
+ upstream: adapt to API change in hostkeys_foreach()/load_hostkeys()
+
+ OpenBSD-Regress-ID: dcb468514f32da49a446372453497dc6eeafdbf3
+
+commit bf7eb3c266b7fd4ddda108fcf72b860af2af6406
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Fri Oct 16 14:02:24 2020 +0000
+
+ upstream: few more things needs match.c and addrmatch.c now that
+
+ log.c calls match_pattern_list()
+
+ OpenBSD-Regress-ID: f7c95c76b150d0aeb00a67858b9579b7d1b2db74
+
+commit 2c64f24e27a5e72a7f59e515fc4f4985355237ae
Author: Darren Tucker <dtucker@dtucker.net>
-Date: Thu Mar 22 17:00:28 2018 +1100
+Date: Mon Dec 21 14:02:56 2020 +1100
+
+ Pull in missing rev 1.2.
+
+commit 0f504f592d15d8047e466eb7453067a6880992a8
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Sun Dec 20 23:40:19 2020 +0000
+
+ upstream: plumb ssh_conn_info through to sshconnect.c; feedback/ok
+
+ markus@
+
+ OpenBSD-Commit-ID: e8d14a09cda3f1dc55df08f8a4889beff74e68b0
+
+commit 729b05f59ded35483acef90a6f88aa03eae33b29
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Sun Dec 20 23:38:00 2020 +0000
- Save $? before case statement.
+ upstream: allow UserKnownHostsFile=none; feedback and ok markus@
- In some shells (FreeBSD 9, ash) the case statement resets $?, so save
- for later testing.
+ OpenBSD-Commit-ID: c46d515eac94a35a1d50d5fd71c4b1ca53334b48
-commit 4c4e7f783b43b264c247233acb887ee10ed4ce4d
+commit b4c7cd1185c5dc0593d47eafcc1a34fda569dd1d
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Wed Mar 14 05:35:40 2018 +0000
+Date: Sun Dec 20 23:36:51 2020 +0000
- upstream: rename recently-added "valid-before" key restriction to
+ upstream: load_hostkeys()/hostkeys_foreach() variants for FILE*
- "expiry-time" as the former is confusing wrt similar terminology in X.509;
- pointed out by jsing@
+ Add load_hostkeys_file() and hostkeys_foreach_file() that accept a
+ FILE* argument instead of opening the file directly.
- OpenBSD-Regress-ID: ac8b41dbfd90cffd525d58350c327195b0937793
+ Original load_hostkeys() and hostkeys_foreach() are implemented using
+ these new interfaces.
+
+ Add a u_int note field to the hostkey_entry and hostkey_foreach_line
+ structs that is passed directly from the load_hostkeys() and
+ hostkeys_foreach() call. This is a lightweight way to annotate results
+ between different invocations of load_hostkeys().
+
+ ok markus@
+
+ OpenBSD-Commit-ID: 6ff6db13ec9ee4edfa658b2c38baad0f505d8c20
+
+commit 06fbb386bed666581095cb9cbc7a900e02bfe1b7
+Author: tobhe@openbsd.org <tobhe@openbsd.org>
+Date: Sat Dec 19 22:09:21 2020 +0000
+
+ upstream: Print client kem key with correct length.
+
+ ok markus@
+
+ OpenBSD-Commit-ID: 91689e14a4fc6c270e265a32d1c8faba63a45755
-commit 500396b204c58e78ad9d081516a365a9f28dc3fd
+commit 0ebead6593e2441e4af2735bbe2cd097607cd0d3
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Mon Mar 12 00:56:03 2018 +0000
+Date: Thu Dec 17 23:28:50 2020 +0000
- upstream: check valid-before option in authorized_keys
+ upstream: fix possible error("%s", NULL) on error paths
- OpenBSD-Regress-ID: 7e1e4a84f7f099a290e5a4cbf4196f90ff2d7e11
+ OpenBSD-Commit-ID: 0b3833c2cb985453ecca1d76803ebb8f3b736a11
-commit a76b5d26c2a51d7dd7a5164e683ab3f4419be215
+commit d060bc7f6e6244f001e658208f53e3e2ecbbd382
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Mon Mar 12 00:54:04 2018 +0000
+Date: Thu Dec 17 23:26:11 2020 +0000
- upstream: explicitly specify RSA/SHA-2 keytype here too
+ upstream: refactor client percent_expand() argument passing;
- OpenBSD-Regress-ID: 74d7b24e8c72c27af6b481198344eb077e993a62
+ consolidate the common arguments into a single struct and pass that around
+ instead of using a bunch of globals. ok markus@
+
+ OpenBSD-Commit-ID: 035e6d7ca9145ad504f6af5a021943f1958cd19b
-commit 3a43297ce29d37c64e37c7e21282cb219e28d3d1
+commit 43026da035cd266db37df1f723d5575056150744
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Mon Mar 12 00:52:57 2018 +0000
+Date: Thu Dec 17 23:10:27 2020 +0000
- upstream: exlicitly include RSA/SHA-2 keytypes in
+ upstream: prepare readconf.c for fuzzing; remove fatal calls and
- PubkeyAcceptedKeyTypes here
+ fix some (one-off) memory leaks; ok markus@
- OpenBSD-Regress-ID: 954d19e0032a74e31697fb1dc7e7d3d1b2d65fe9
+ OpenBSD-Commit-ID: 91c6aec57b0e7aae9190de188e9fe8933aad5ec5
-commit 037fdc1dc2d68e1d43f9c9e2586c02cabc8f7cc8
-Author: jmc@openbsd.org <jmc@openbsd.org>
-Date: Wed Mar 14 06:56:20 2018 +0000
+commit bef92346c4a808f33216e54d6f4948f9df2ad7c1
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Mon Dec 14 03:13:12 2020 +0000
- upstream: sort expiry-time;
+ upstream: use _PATH_SSH_USER_DIR instead of hardcoded .ssh in path
- OpenBSD-Commit-ID: 8c7d82ee1e63e26ceb2b3d3a16514019f984f6bf
+ OpenBSD-Commit-ID: 5c1048468813107baa872f5ee33ba51623630e01
+
+commit a5ab499bd2644b4026596fc2cb24a744fa310666
+Author: Damien Miller <djm@mindrot.org>
+Date: Fri Dec 4 14:01:27 2020 +1100
+
+ basic KEX fuzzer; adapted from Markus' unittest
+
+commit 021ff33e383c77b11badd60cec5b141a3e3fa532
+Author: Damien Miller <djm@mindrot.org>
+Date: Fri Dec 4 13:57:43 2020 +1100
+
+ use options that work with recent clang
-commit abc0fa38c9bc136871f28e452c3465c3051fc785
+commit e4d1a0b40add800b6e9352b40c2223e44acc3a45
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Wed Mar 14 05:35:40 2018 +0000
+Date: Fri Dec 4 02:41:10 2020 +0000
- upstream: rename recently-added "valid-before" key restriction to
+ upstream: shuffle a few utility functions into sftp-client.c; from
- "expiry-time" as the former is confusing wrt similar terminology in X.509;
- pointed out by jsing@
+ Jakub Jelen
- OpenBSD-Commit-ID: 376939466a1f562f3950a22314bc6505733aaae6
+ OpenBSD-Commit-ID: fdeb1aae1f6149b193f12cd2af158f948c514a2a
-commit bf0fbf2b11a44f06a64b620af7d01ff171c28e13
+commit ace12dc64f8e3a2496ca48d36b53cb3c0a090755
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Mon Mar 12 00:52:01 2018 +0000
+Date: Fri Dec 4 02:29:56 2020 +0000
- upstream: add valid-before="[time]" authorized_keys option. A
+ upstream: make ssh_free(NULL) a no-op
- simple way of giving a key an expiry date. ok markus@
+ OpenBSD-Commit-ID: 42cb285d94789cefe6608db89c63040ab0a80fa0
+
+commit 3b98b6e27f8a122dbfda9966b1afeb3e371cce91
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Fri Dec 4 02:29:25 2020 +0000
+
+ upstream: memleak of DH public bignum; found with libfuzzer
- OpenBSD-Commit-ID: 1793b4dd5184fa87f42ed33c7b0f4f02bc877947
+ OpenBSD-Commit-ID: 0e913b542c3764b100b1571fdb0d0e5cc086fe97
-commit fbd733ab7adc907118a6cf56c08ed90c7000043f
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Mon Mar 12 19:17:26 2018 +1100
+commit 553b90feedd7da5b90901d73005f86705456d686
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Fri Dec 4 02:27:57 2020 +0000
- Add AC_LANG_PROGRAM to AC_COMPILE_IFELSE.
+ upstream: fix minor memleak of kex->hostkey_alg on rekex
- The recently added MIPS ABI tests need AC_LANG_PROGRAM to prevent
- warnings from autoconf. Pointed out by klausz at haus-gisela.de.
+ OpenBSD-Commit-ID: 2c3969c74966d4ccdfeff5e5f0df0791919aef50
-commit c7c458e8261b04d161763cd333d74e7a5842e917
+commit ac0364b85e66eb53da2f9618f699ba6bd195ceea
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Wed Mar 7 23:53:08 2018 +0000
+Date: Fri Dec 4 02:27:08 2020 +0000
- upstream: revert recent strdelim() change, it causes problems with
+ upstream: typos: s/hex/kex/ in error messages
- some configs.
+ OpenBSD-Commit-ID: 43a026c9571dd779ec148de1829cf5a6b6651905
+
+commit ee22db7c5885a1d90219202c0695bc621aa0409b
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Fri Dec 4 02:25:13 2020 +0000
+
+ upstream: make program name be const
- revision 1.124
- date: 2018/03/02 03:02:11; author: djm; state: Exp; lines: +19 -8; commitid: nNRsCijZiGG6SUTT;
- Allow escaped quotes \" and \' in ssh_config and sshd_config quotes
- option strings. bz#1596 ok markus@
+ OpenBSD-Commit-ID: ece25680ec637fdf20502721ccb0276691df5384
+
+commit 2bcbf679de838bb77a8bd7fa18e100df471a679c
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Mon Nov 30 05:36:39 2020 +0000
+
+ upstream: Ignore comments at the end of config lines in ssh_config,
- OpenBSD-Commit-ID: 59c40b1b81206d713c06b49d8477402c86babda5
+ similar to what we already do for sshd_config. bz#2320, with & ok djm@
+
+ OpenBSD-Commit-ID: bdbf9fc5bc72b1a14266f5f61723ed57307a6db4
-commit 0bcd871ccdf3baf2b642509ba4773d5be067cfa2
-Author: jmc@openbsd.org <jmc@openbsd.org>
-Date: Mon Mar 5 07:03:18 2018 +0000
+commit b755264e7d3cdf1de34e18df1af4efaa76a3c015
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Sat Nov 28 12:52:32 2020 +0000
- upstream: move the input format details to -f; remove the output
+ upstream: Include cipher.h for declaration of cipher_by_name.
- format details and point to sshd(8), where it is documented;
+ OpenBSD-Commit-ID: ddfebbca03ca0e14e00bbad9d35f94b99655d032
+
+commit 022def7bd16c3426a95e25f57cb259d54468341c
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Sat Nov 28 03:27:59 2020 +0000
+
+ upstream: check result of strchr() against NULL rather than
- ok dtucker
+ searched-for characters; from zhongjubin@huawei.com
- OpenBSD-Commit-ID: 95f17e47dae02a6ac7329708c8c893d4cad0004a
+ OpenBSD-Commit-ID: e6f57de1d4a4d25f8db2d44e8d58d847e247a4fe
-commit 45011511a09e03493568506ce32f4891a174a3bd
-Author: Vicente Olivert Riera <Vincent.Riera@imgtec.com>
-Date: Tue Jun 20 16:42:28 2017 +0100
+commit 57bf03f0217554afb8980f6697a7a0b88658d0a9
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Fri Nov 27 10:12:30 2020 +0000
- configure.ac: properly set seccomp_audit_arch for MIPS64
+ upstream: Document ssh-keygen -Z, sanity check its argument earlier and
- Currently seccomp_audit_arch is set to AUDIT_ARCH_MIPS64 or
- AUDIT_ARCH_MIPSEL64 (depending on the endinness) when openssh is built
- for MIPS64. However, that's only valid for n64 ABI. The right macros for
- n32 ABI defined in seccomp.h are AUDIT_ARCH_MIPS64N32 and
- AUDIT_ARCH_MIPSEL64N32, for big and little endian respectively.
+ provide a better error message if it's not correct. Prompted by bz#2879, ok
+ djm@ jmc@
- Because of that an sshd built for MIPS64 n32 rejects connection attempts
- and the output of strace reveals that the problem is related to seccomp
- audit:
+ OpenBSD-Commit-ID: 484178a173e92230fb1803fb4f206d61f7b58005
+
+commit 33313ebc1c7135085676db62189e3520341d6b73
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Fri Nov 27 00:49:58 2020 +0000
+
+ upstream: Set the specified TOS/DSCP for interactive use prior to
- [pid 194] prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, {len=57,
- filter=0x555d5da0}) = 0
- [pid 194] write(7, "\0\0\0]\0\0\0\5\0\0\0Ulist_hostkey_types: "..., 97) = ?
- [pid 193] <... poll resumed> ) = 2 ([{fd=5, revents=POLLIN|POLLHUP},
- {fd=6, revents=POLLHUP}])
- [pid 194] +++ killed by SIGSYS +++
+ TCP connect. The connection phase of the SSH session is time-sensitive (due
+ to server side login grace periods) and is frequently interactive (e.g.
+ entering passwords). The ultimate interactive/bulk TOS/DSCP will be set after
+ authentication completes.
- This patch fixes that problem by setting the right value to
- seccomp_audit_arch taking into account the MIPS64 ABI.
+ ok dtucker@
- Signed-off-by: Vicente Olivert Riera <Vincent.Riera@imgtec.com>
+ OpenBSD-Commit-ID: f31ab10d9233363a6d2c9996007083ba43a093f1
-commit 580086704c31de91dc7ba040a28e416bf1fefbca
-Author: Vicente Olivert Riera <Vincent.Riera@imgtec.com>
-Date: Tue Jun 20 16:42:11 2017 +0100
+commit b2bcec13f17ce9174238a704e91d52203e916432
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Fri Nov 27 00:37:10 2020 +0000
- configure.ac: detect MIPS ABI
+ upstream: clean up passing of struct passwd from monitor to preauth
+
+ privsep process. No longer copy entire struct w/ pointer addresses, but pass
+ remaining scalar fields explicitly,
+
+ Prompted by Yuichiro NAITO, feedback Thorsten Glaser; ok dtucker@
- Signed-off-by: Vicente Olivert Riera <Vincent.Riera@imgtec.com>
+ OpenBSD-Commit-ID: 9925df75a56732c43f3663e70dd15ff413ab3e53
-commit cd4e937aa701f70366cd5b5969af525dff6fdf15
-Author: Alan Yee <alyee@ucsd.edu>
-Date: Wed Mar 7 15:12:14 2018 -0800
+commit 19af04e2231155d513e24fdc81fbec2217ae36a6
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Sun Nov 22 22:38:26 2020 +0000
- Use https URLs for links that support it.
+ upstream: when loading PKCS#11 keys, include the key fingerprints
+
+ and provider/slot information in debug output.
+
+ OpenBSD-Commit-ID: 969a089575d0166a9a364a9901bb6a8d9b8a1431
-commit c0a0c3fc4a76b682db22146b28ddc46566db1ce9
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Mon Mar 5 20:03:07 2018 +1100
+commit 9b9465ea856e15b9e9890b4ecb4110d7106e7766
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Sun Nov 22 22:37:11 2020 +0000
- Disable UTMPX on SunOS4.
+ upstream: when mentioning that the host key has changed, don't
+
+ report the type because it is ambiguous as to whether it referred to the
+ known or new host key. bz3216; ok dtucker@
+
+ OpenBSD-Commit-ID: 2d5ce4a83dbcf44e340a572e361decad8aab7bad
-commit 58fd4c5c0140f6636227ca7acbb149ab0c2509b9
+commit 637017a7dd3281d3f2df804993cc27c30dbfda47
Author: Darren Tucker <dtucker@dtucker.net>
-Date: Mon Mar 5 19:28:08 2018 +1100
+Date: Wed Nov 25 17:38:46 2020 +1100
- Check for and work around buggy fflush(NULL).
+ Use "=" not "==" in string test.
- Some really old platforms (eg SunOS4) segfault on fflush(NULL) so check
- for and work around. With klausz at haus-gisela.de.
+ POSIX says "=" is string comparison and some shells (eg HP-UX) will
+ complain about "==".
-commit 71e48bc7945f867029e50e06c665c66aed6d3c64
+commit 9880f3480f9768897f3b8e714d5317fb993bc5b3
Author: Darren Tucker <dtucker@dtucker.net>
-Date: Mon Mar 5 10:22:32 2018 +1100
+Date: Fri Nov 20 17:16:51 2020 +1100
- Remove extra XMSS #endif
+ Restore correct flags during localtime_r check.
- Extra #endif breaks compile with -DWITH_XMSS. Pointed out by Jack
- Schmidt via github.
+ We were restoring the wrong thing CPPFLAGS (we used CFLAGS) for any
+ platform that doesn't have localtime_r.
-commit 055e09e2212ff52067786bf6d794ca9512ff7f0c
+commit 41935882f4e82de60dbd6e033eabe79e1b963518
Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Sat Mar 3 06:37:53 2018 +0000
+Date: Fri Nov 20 03:16:56 2020 +0000
- upstream: Update RSA minimum modulus size to 1024. sshkey.h rev 1.18
+ upstream: When doing an sftp recursive upload or download of a
- bumped the minimum from 768 to 1024, update man page accordingly.
+ read-only directory, ensure that the directory is created with write and
+ execute permissions in the interim so that we can actually complete the
+ transfer, then set the directory permission as the final step. (The execute
+ bit is only likely to be an issue with a non-POSIX server). bz#3222, ok djm@
- OpenBSD-Commit-ID: 27563ab4e866cd2aac40a5247876f6787c08a338
+ OpenBSD-Commit-ID: a82606212f2796e31f0e1af94a63355a7ad5d903
-commit 7e4fadd3248d6bb7d39d6688c76a613d35d2efc1
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sun Mar 4 01:46:48 2018 +0000
+commit 0f90440ca70abab947acbd77795e9f130967956c
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Fri Nov 20 13:37:54 2020 +1100
- upstream: for the pty control tests, just check that the PTY path
-
- points to something in /dev (rather than checking the device node itself);
- makes life easier for portable, where systems with dynamic ptys can delete
- nodes before we get around to testing their existence.
+ Add new pselect6_time64 syscall on ARM.
- OpenBSD-Regress-ID: b1e455b821e62572bccd98102f8dd9d09bb94994
+ This is apparently needed on armhfp/armv7hl. bz#3232, patch from
+ jjelen at redhat.com.
-commit 13ef4cf53f24753fe920832b990b25c9c9cd0530
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Sat Mar 3 16:21:20 2018 +1100
+commit 3a7c46c72b6a1f643b1fc3589cd20d8320c3d9e1
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Fri Nov 20 02:14:16 2020 +0000
- Update PAM password change to new opts API.
+ upstream: Explicitly initialize all members of the
+
+ find_by_key_ctx struct. Initializing a single member should be enough
+ (the spec says the remainder should be initialized as per the static
+ rules) but some GCCs warn on this which prevents us testing with -Werror
+ on those. ok deraadt@ djm@
+
+ OpenBSD-Commit-ID: 687126e60a27d30f02614760ef3c3ae4e8d6af28
-commit 33561e68e0b27366cb769295a077aabc6a49d2a1
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Sat Mar 3 14:56:09 2018 +1100
+commit 076cb616b87d1ea1d292973fcd0ba38c08ea6832
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Thu Nov 19 23:05:05 2020 +0000
- Add strndup for platforms that need it.
+ upstream: draft-ietf-secsh-architecture is now RFC4251.
- Some platforms don't have strndup, which includes Solaris 10, NetBSD 3
- and FreeBSD 6.
+ OpenBSD-Commit-ID: cb0bb58c2711fb5ed519507659be1dcf179ed403
-commit e8a17feba95eef424303fb94441008f6c5347aaf
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Sat Mar 3 14:49:07 2018 +1100
+commit 85cceda21f1471548e04111aefe2c4943131c1c8
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Tue Nov 17 11:23:58 2020 +0000
- Flatten and alphabetize object file lists.
+ upstream: Specify that the KDF function is bcrypt. Based on github
+
+ PR#214 from rafork, ok markus@, mdoc correction jmc@
- This will make maintenance and changes easier. "no objection" tim@
+ OpenBSD-Commit-ID: d8f2853e7edbcd483f31b50da77ab80ffa18b4ef
-commit de1920d743d295f50e6905e5957c4172c038e8eb
+commit 5b9720f9adbd70ba5a994f407fe07a7d016d8d65
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sat Mar 3 03:16:17 2018 +0000
+Date: Sun Nov 15 22:34:58 2020 +0000
- upstream: unit tests for new authorized_keys options API
+ upstream: revert r1.341; it breaks ProxyJump; reported by sthen@
- OpenBSD-Regress-ID: 820f9ec9c6301f6ca330ad4052d85f0e67d0bdc1
+ OpenBSD-Commit-ID: 6ac2f945b26cb86d936eed338f77861d6da8356a
-commit dc3e92df17556dc5b0ab19cee8dcb2a6ba348717
+commit 04088725ec9c44880c01799b588cd4ba47b3e8bc
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Mar 2 02:53:27 2018 +0000
+Date: Fri Nov 13 07:30:44 2020 +0000
- upstream: fix testing of pty option, include positive test and
+ upstream: scrub keyboard-interactive authentication prompts coming
- testing of restrict keyword
+ from the server through asmprintf() prior to display; suggested by and ok
+ dtucker@
- OpenBSD-Regress-ID: 4268f27c2706a0a95e725d9518c5bcbec9814c6d
+ OpenBSD-Commit-ID: 31fe93367645c37fbfe4691596bf6cf1e3972a58
-commit 3d1edd1ebbc0aabea8bbe61903060f37137f7c61
+commit 5442b491d0ee4bb82f6341ad0ee620ef3947f8c5
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Mar 2 02:51:55 2018 +0000
+Date: Fri Nov 13 04:53:12 2020 +0000
- upstream: better testing for port-forwarding and restrict flags in
+ upstream: prefix keyboard interactive prompts with (user@host) to
- authorized_keys
+ make it easier to determine which connection they are associated with in
+ cases like scp -3, ProxyJump, etc. bz#3224 ok dtucker
- OpenBSD-Regress-ID: ee771df8955f2735df54746872c6228aff381daa
+ OpenBSD-Commit-ID: 67e6189b04b46c867662f8a6759cf3ecb5f59170
-commit 7c856857607112a3dfe6414696bf4c7ab7fb0cb3
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sat Mar 3 03:15:51 2018 +0000
+commit 2992e4e7014ac1047062acfdbbf6feb156fef616
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Fri Nov 13 17:56:11 2020 +1100
- upstream: switch over to the new authorized_keys options API and
+ Remove use of TIME_WITH_SYS_TIME.
- remove the legacy one.
+ It was only set by the recently removed AC_HEADER_TIME macro, replace
+ with simple inclusions of both sys/time.h and time.h. Should prevent
+ mis-detection of struct timespec.
+
+commit e3f27006f15abacb7e89fda3f5e9a0bd420b7e38
+Author: Damien Miller <djm@mindrot.org>
+Date: Fri Nov 13 14:20:43 2020 +1100
+
+ Revert "detect Linux/X32 systems"
- Includes a fairly big refactor of auth2-pubkey.c to retain less state
- between key file lines.
+ This reverts commit 5b56bd0affea7b02b540bdbc4d1d271b0e4fc885.
- feedback and ok markus@
+ The approach used was incorrect; discussion in bz#3085
+
+commit e51dc7fab61df36e43f3bc64b673f88d388cab91
+Author: Damien Miller <djm@mindrot.org>
+Date: Fri Nov 13 13:22:15 2020 +1100
+
+ SELinux has deprecated security_context_t
+
+ (it was only ever a char* anyway)
+
+commit b79add37d118276d67f3899987b9f0629c9449c3
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Fri Nov 13 13:43:30 2020 +1100
+
+ Remove obsolete AC_HEADER_TIME macro.
- OpenBSD-Commit-ID: dece6cae0f47751b9892080eb13d6625599573df
+ AC_HEADER_TIME is marked as obsolete in autoconf-2.70 and as far as I
+ can tell everything we have that might be old enough to need it doesn't.
-commit 90c4bec8b5f9ec4c003ae4abdf13fc7766f00c8b
+commit d5d05cdb3d4efd4a618aa52caab5bec73097c163
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sat Mar 3 03:06:02 2018 +0000
+Date: Thu Nov 12 22:56:00 2020 +0000
- upstream: Introduce a new API for handling authorized_keys options.
+ upstream: when prompting the user to accept a new hostkey, display
+
+ any other host names/addresses already associated with the key. E.g.
- This API parses options to a dedicated structure rather than the old API's
- approach of setting global state. It also includes support for merging
- options, e.g. from authorized_keys, authorized_principals and/or
- certificates.
+ > The authenticity of host 'test (10.0.0.1)' can't be established.
+ > ECDSA key fingerprint is SHA256:milU4MODXm8iJQI18wlsbPG7Yup+34fuNNmV08qDnax.
+ > This host key is known by the following other names/addresses:
+ > ~/.ssh/known_hosts:1: host.example.org,10.0.0.1
+ > ~/.ssh/known_hosts:2: [hashed name]
+ > ~/.ssh/known_hosts:3: [hashed name]
+ > ~/.ssh/known_hosts:4: host
+ > ~/.ssh/known_hosts:5: [host]:2222
+ > Are you sure you want to continue connecting (yes/no/[fingerprint])?
feedback and ok markus@
- OpenBSD-Commit-ID: 98badda102cd575210d7802943e93a34232c80a2
+ OpenBSD-Commit-ID: f6f58a77b49f1368b5883b3a1f776447cfcc7ef4
+
+commit 819b44e8b9af6ce18d3ec7505b9f461bf7991a1f
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Thu Nov 12 22:38:57 2020 +0000
+
+ upstream: Prevent integer overflow when ridiculously large
+
+ ConnectTimeout is specified, capping the effective value (for most platforms)
+ at 24 days. bz#3229, ok djm@
+
+ OpenBSD-Commit-ID: 62d4c4b7b87d111045f8e9f28b5b532d17ac5bc0
-commit 26074380767e639ef89321610e146ae11016b385
+commit add926dd1bbe3c4db06e27cab8ab0f9a3d00a0c2
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sat Mar 3 03:01:50 2018 +0000
+Date: Wed Nov 11 05:22:32 2020 +0000
- upstream: warn when the agent returns a signature type that was
+ upstream: fix logic error that broke URI parsing in ProxyJump
- different to what was requested. This might happen when an old/non-OpenSSH
- agent is asked to make a rsa-sha2-256/512 signature but only supports
- ssh-rsa. bz#2799 feedback and ok markus@
+ directives; ok dtucker@
- OpenBSD-Commit-ID: 760c0f9438c5c58abc16b5f98008ff2d95cb13ce
+ OpenBSD-Commit-ID: 96d48839b1704882a0e9a77898f5e14b2d222705
-commit f493d2b0b66fb003ed29f31dd66ff1aeb64be1fc
-Author: jmc@openbsd.org <jmc@openbsd.org>
-Date: Fri Mar 2 21:40:15 2018 +0000
+commit 4340dd43928dfe746cb7e75fe920b63c0d909a9a
+Author: claudio@openbsd.org <claudio@openbsd.org>
+Date: Tue Nov 10 07:46:20 2020 +0000
- upstream: apply a lick of paint; tweaks/ok dtucker
+ upstream: Free the previously allocated msg buffer after writing it
- OpenBSD-Commit-ID: 518a6736338045e0037f503c21027d958d05e703
+ out. OK djm@
+
+ OpenBSD-Commit-ID: 18c055870fc75e4cb9f926c86c7543e2e21d7fa4
-commit 713d9cb510e0e7759398716cbe6dcf43e574be71
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Mar 2 03:02:11 2018 +0000
+commit fcf429a4c69d30d8725612a55b37181594da8ddf
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Wed Nov 11 12:30:46 2020 +1100
- upstream: Allow escaped quotes \" and \' in ssh_config and
+ Prevent excessively long username going to PAM.
- sshd_config quotes option strings. bz#1596 ok markus@
+ This is a mitigation for a buffer overflow in Solaris' PAM username
+ handling (CVE-2020-14871), and is only enabled for Sun-derived PAM
+ implementations. This is not a problem in sshd itself, it only
+ prevents sshd from being used as a vector to attack Solaris' PAM.
+ It does not prevent the bug in PAM from being exploited via some other
+ PAM application.
- OpenBSD-Commit-ID: dd3a29fc2dc905e8780198e5a6a30b096de1a1cb
+ Based on github PR#212 from Mike Scott but implemented slightly
+ differently. ok tim@ djm@
-commit 94b4e2d29afaaaef89a95289b16c18bf5627f7cd
+commit 10dce8ff68ef615362cfcab0c0cc33ce524e7682
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Mar 2 02:08:03 2018 +0000
+Date: Sun Nov 8 23:19:03 2020 +0000
- upstream: refactor sshkey_read() to make it a little more, err,
-
- readable. ok markus
+ upstream: unbreak; missing NULL check
- OpenBSD-Commit-ID: 2e9247b5762fdac3b6335dc606d3822121714c28
+ OpenBSD-Commit-ID: 6613dfab488123f454d348ef496824476b8c11c0
-commit 5886b92968b360623491699247caddfb77a74d80
-Author: markus@openbsd.org <markus@openbsd.org>
-Date: Thu Mar 1 20:32:16 2018 +0000
+commit d5a0cd4fc430c8eda213a4010a612d4778867cd9
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Sun Nov 8 22:37:24 2020 +0000
- upstream: missing #ifdef for _PATH_HOST_XMSS_KEY_FILE; report by
+ upstream: when requesting a security key touch on stderr, inform the
- jmc@
+ user once the touch has been recorded; requested by claudio@ ok markus@
- OpenBSD-Commit-ID: 9039cb69a3f9886bfef096891a9e7fcbd620280b
+ OpenBSD-Commit-ID: 3b76ee444490e546b9ea7f879e4092ee0d256233
-commit 3b36bed3d26f17f6a2b7e036e01777770fe1bcd4
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Mon Feb 26 12:14:53 2018 +0000
+commit 292bcb2479deb27204e3ff796539c003975a5f7a
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Mon Nov 9 00:33:35 2020 +1100
- upstream: Remove unneeded (local) include. ok markus@
+ Remove preprocessor directive from log macro calls.
- OpenBSD-Commit-ID: 132812dd2296b1caa8cb07d2408afc28e4e60f93
+ Preprocessor directives inside macro calls, such as the new log macros,
+ are undefined behaviour and do not work with, eg old GCCs. Put the
+ entire log call inside the ifdef for OPENSSL_HAS_NISTP521.
-commit 27b9f3950e0289e225b57b7b880a8f1859dcd70b
+commit 71693251b7cbb7dd89aaac18815147124732d0d3
Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Mon Feb 26 03:56:44 2018 +0000
+Date: Sun Nov 8 12:10:20 2020 +0000
- upstream: Add $OpenBSD$ markers to xmss files to help keep synced
+ upstream: Add a comment documenting the source of the moduli group
- with portable. ok djm@.
+ sizes.
- OpenBSD-Commit-ID: 5233a27aafd1dfadad4b957225f95ae51eb365c1
+ OpenBSD-Commit-ID: aec0725ce607630caaa62682624c6763b350391c
-commit afd830847a82ebbd5aeab05bad6d2c8ce74df1cd
+commit 4d94b031ff88b015f0db57e140f481bff7ae1a91
Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Mon Feb 26 03:03:05 2018 +0000
+Date: Sun Nov 8 11:46:12 2020 +0000
- upstream: Add newline at end of file to prevent compiler warnings.
+ upstream: Replace WITH_OPENSSL ifdefs in log calls with a macro.
- OpenBSD-Commit-ID: 52f247d4eafe840c7c14c8befa71a760a8eeb063
+ The log calls are themselves now macros, and preprocessor directives inside
+ macro arguments are undefined behaviour which some compilers (eg old GCCs)
+ choke on. It also makes the code tidier. ok deraadt@
+
+ OpenBSD-Commit-ID: cc12a9029833d222043aecd252d654965c351a69
-commit 941e0d3e9bb8d5e4eb70cc694441445faf037c84
+commit 6d2564b94e51184eb0b73b97d13a36ad50b4f810
Author: Darren Tucker <dtucker@dtucker.net>
-Date: Wed Feb 28 19:59:35 2018 +1100
+Date: Fri Nov 6 17:11:16 2020 +1100
- Add WITH_XMSS, move to prevent conflicts.
+ Fix function body for variadic macro test.
- Add #ifdef WITH_XMSS to ssh-xmss.c, move it in the other files to after
- includes.h so it's less likely to conflict and will pick up WITH_XMSS if
- added to config.h.
+ AC_LANG_PROGRAM puts its second argument inside main() so we don't need
+ to do it ourselves.
-commit a10d8552d0d2438da4ed539275abcbf557d1e7a8
+commit 586f9bd2f5980e12f8cf0d3c2a761fa63175da52
Author: Darren Tucker <dtucker@dtucker.net>
-Date: Tue Feb 27 14:45:17 2018 +1100
+Date: Fri Nov 6 16:53:24 2020 +1100
- Conditionally compile XMSS code.
+ Remove AC_PROC_CC_C99 obsoleted in autoconf 2.70.
- The XMSS code is currently experimental and, unlike the rest of OpenSSH
- cannot currently be compiled with a c89 compiler.
+ Since we only use it to make sure we can handle variadic macros,
+ explicitly check only for that. with & ok djm@
-commit 146c3bd28c8dbee9c4b06465d9c9facab96b1e9b
+commit a019e353df04de1b2ca78d91b39c393256044ad7
Author: Darren Tucker <dtucker@dtucker.net>
-Date: Mon Feb 26 12:51:29 2018 +1100
+Date: Fri Nov 6 13:56:41 2020 +1100
- Check dlopen has RTLD_NOW before enabling pkcs11.
+ Replace AC_TRY_COMPILE obsoleted in autoconf 2.70.
+
+ Replace with the equivalent AC_COMPILE_IFELSE.
-commit 1323f120d06a26074c4d154fcbe7f49bcad3d741
+commit 771b7795c0ef6a2fb43b4c6c66b615c2085cb9cd
Author: Darren Tucker <dtucker@dtucker.net>
-Date: Tue Feb 27 08:41:25 2018 +1100
+Date: Fri Nov 6 13:55:33 2020 +1100
- Check for attributes on prototype args.
+ Move AC_PROG_CC_C99 to immediately afer AC_PROG_CC.
- Some compilers (gcc 2.9.53, 3.0 and probably others, see gcc bug #3481)
- do not accept __attribute__ on function pointer prototype args. Check for
- this and hide them if they're not accepted.
+ This puts the related C version selection output in the same place.
-commit f0b245b0439e600fab782d19e97980e9f2c2533c
+commit e5591161f21ab493c6284a85ac3c0710ad94998f
Author: Darren Tucker <dtucker@dtucker.net>
-Date: Mon Feb 26 11:43:48 2018 +1100
+Date: Fri Nov 6 13:54:17 2020 +1100
- Check if HAVE_DECL_BZERO correctly.
+ AC_CHECK_HEADER() is obsoleted in autoconf 2.70.
+
+ Replace with the non-obsoleted AC_CHECK_HEADERS().
-commit c7ef4a399155e1621a532cc5e08e6fa773658dd4
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Mon Feb 26 17:42:56 2018 +1100
+commit 05bcd0cadf160fd4826a2284afa7cba6ec432633
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Tue Nov 3 22:53:12 2020 +0000
- Wrap <stdint.h> in #ifdef HAVE_STDINT_H.
+ upstream: fold consecutive '*' wildcards to mitigate combinatorial
+
+ explosion of recursive searches; ok dtucker
+
+ OpenBSD-Commit-ID: d18bcb39c40fb8a1ab61153db987e7d11dd3792b
-commit ac53ce46cf8165cbda7f57ee045f9f32e1e92b31
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Mon Feb 26 16:24:23 2018 +1100
+commit 7d680448db5858dc76307663f78d0b8d3c2b4a3d
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Fri Oct 30 01:50:07 2020 +0000
- Replace $(CURDIR) with $(PWD).
+ upstream: print reason in fatal error message when
+
+ kex_assemble_namelist() fails
- The former doesn't work on Solaris or BSDs.
+ OpenBSD-Commit-ID: a9975ee8db6c98d6f32233d88051b2077ca63dab
-commit 534b2680a15d14e7e60274d5b29b812d44cc5a44
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Mon Feb 26 14:51:59 2018 +1100
+commit 95d1109fec7e89ad21f2a97e92bde1305d32a353
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Thu Oct 29 03:13:06 2020 +0000
- Comment out hexdump().
+ upstream: fix sshd_config SetEnv directive inside Match blocks; part of
+
+ github PR#201 from github user manuelm
- Nothing currently uses them but they cause conflicts on at least
- FreeBSD, possibly others. ok djm@
+ OpenBSD-Commit-ID: 9772e3748abff3ad65ae8fc43d026ed569b1d2bc
-commit 5aea4aa522f61bb2f34c3055a7de203909dfae77
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Mon Feb 26 14:39:14 2018 +1100
+commit b12b835dc022ba161afe68348e05a83dfbcb1515
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Thu Oct 29 03:01:18 2020 +0000
- typo: missing ;
+ upstream: fix type of nid in type_bits_valid(); github PR#202 from
+
+ github user thingsconnected
+
+ OpenBSD-Commit-ID: 769d2b040dec7ab32d323daf54b854dd5dcb5485
-commit cd3ab57f9b388f8b1abf601dc4d78ff82d83b75e
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Mon Feb 26 14:37:06 2018 +1100
+commit 1a14c13147618144d1798c36a588397ba9008fcc
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Thu Oct 29 02:52:43 2020 +0000
- Hook up flock() compat code.
+ upstream: whitespace; no code change
- Also a couple of minor changes: fail if we can't lock instead of
- silently succeeding, and apply a couple of minor style fixes.
+ OpenBSD-Commit-ID: efefc1c47e880887bdee8cd2127ca93177eaad79
-commit b087998d1ba90dd1ddb6bfdb17873dc3e7392798
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Mon Feb 26 14:27:02 2018 +1100
+commit 815209abfdd2991fb92ad7d2e33374916cdcbcf4
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Thu Oct 29 02:47:23 2020 +0000
+
+ upstream: UpdateHostkeys: fixed/better detection of host keys that
+
+ exist under other names and addresses; spotted by and debugged with lots of
+ help from jca@
+
+ OpenBSD-Commit-ID: 5113d7f550bbd48243db1705afbf16b63792d4b7
+
+commit a575cf44e59a65506c67bddb62a712208a7a279c
+Author: Duncan Eastoe <duncan.eastoe@att.com>
+Date: Wed Oct 21 10:11:10 2020 +0100
+
+ session.c: use "denylist" terminology
+
+ Follow upstream (6d755706a0059eb9e2d63517f288b75cbc3b4701) language
+ improvements in this portable-specific code.
- Import flock() compat from NetBSD.
+commit 33267feaffd5d98aa56d2f0b3a99ec352effe938
+Author: Damien Miller <djm@mindrot.org>
+Date: Tue Oct 27 16:46:31 2020 +1100
+
+ Remove checks for strict POSIX mkdtemp()
+
+ We needed a mkdtemp() that accepted template paths that did not
+ end in XXXXXX a long time ago for KRB4, but that code is long
+ deprecated. We no longer need to replace mkdtemp() for strictly
+ following POSIX. ok dtucker@
+
+commit 492d70e18bad5a8c97d05f5eddac817171e88d2c
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Mon Oct 26 00:39:04 2020 +0000
+
+ upstream: Minor man page fixes (capitalization, commas) identified by
+
+ the manpage-l10n project via bz#3223. feedback deraadt@, ok jmc@
+
+ OpenBSD-Commit-ID: ab83af0daf18369244a72daaec6c4a58a9eb7e2c
+
+commit eab2888cfc6cc4e2ef24bd017da9835a0f365f3f
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Mon Oct 19 22:49:23 2020 +0000
+
+ upstream: Adapt XMSS to new logging infrastructure. With markus@, ok
+
+ djm@.
+
+ OpenBSD-Commit-ID: 9c35ec3aa0f710e4e3325187ceff4fa3791686de
+
+commit f7bd11e4941620991f3e727cd0131b01f0311a58
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Mon Oct 19 08:07:08 2020 +0000
+
+ upstream: fix SEGV on fatal() errors spotted by dtucker@
- From NetBSD's src/trunk/tools/compat/flock.c, no OpenSSH changes yet.
+ OpenBSD-Commit-ID: 75f155a1ac61e364ed00dc379e2c42df81067ce2
-commit 89212533dde6798324e835b1499084658df4579e
+commit 7715a3b171049afa1feffb1d5a1245dfac36ce99
Author: Darren Tucker <dtucker@dtucker.net>
-Date: Mon Feb 26 12:32:14 2018 +1100
+Date: Mon Oct 19 10:54:41 2020 +1100
+
+ Use fatal_fr not fatal_r when passing r.
+
+ Caught by the PAM -Werror tinderbox build.
+
+commit 816036f142ecd284c12bb3685ae316a68d2ef190
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Sun Oct 18 11:32:01 2020 +0000
+
+ upstream: use the new variant log macros instead of prepending
+
+ __func__ and appending ssh_err(r) manually; ok markus@
+
+ OpenBSD-Commit-ID: 1f14b80bcfa85414b2a1a6ff714fb5362687ace8
+
+commit 9e2c4f64224f68fb84c49b5182e449f94b0dc985
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Sun Oct 18 11:21:59 2020 +0000
+
+ upstream: variants of the log methods that append a ssherr.h string
+
+ from a supplied error code; ok markus@
+
+ OpenBSD-Commit-ID: aed98c4435d48d036ae6740300f6a8357b7cc0bf
+
+commit 28cb0a4b03940d1ee576eb767a81a4113bdc917e
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Sun Oct 18 11:14:27 2020 +0000
- Fix breakage when REGRESSTMP not set.
+ upstream: remove a level of macro indirection; ok markus@
- BUILDDIR is not set where used for REGRESSTMP, use make's CURDIR
- instead. Pointed out by djm@.
+ OpenBSD-Commit-ID: 0c529d06e902c5d1a6b231e1bec6157f76dc67c9
-commit f885474137df4b89498c0b8834c2ac72c47aa4bd
+commit 9cac1db52e6c4961c447910fe02cd68a3b2f9460
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Sun Oct 18 11:13:45 2020 +0000
+
+ upstream: add some variant log.h calls that prepend the calling
+
+ function name; ok markus@
+
+ OpenBSD-Commit-ID: 4be1b2e2455b271ddb7457bc195c5367644f4e48
+
+commit d55dfed34ef6ef1f028d552a90d5f3dba8dd6f7b
Author: Damien Miller <djm@mindrot.org>
-Date: Mon Feb 26 12:18:14 2018 +1100
+Date: Sat Oct 17 22:55:24 2020 +1100
- XMSS-related files get includes.h
+ missing header
-commit 612faa34c72e421cdc9e63f624526bae62d557cc
+commit 999d7cb79a3a73d92a6dfbf174c33da0d984c7a2
Author: Damien Miller <djm@mindrot.org>
-Date: Mon Feb 26 12:17:55 2018 +1100
+Date: Sat Oct 17 22:47:52 2020 +1100
+
+ sync regress/misc/sk-dummy/fatal.c
- object files end with .o - not .c
+commit 3554b4afa38b3483a3302f1be18eaa6f843bb260
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Sat Oct 17 01:28:20 2020 +0000
-commit bda709b8e13d3eef19e69c2d1684139e3af728f5
+ upstream: make the log functions that exit (sshlogdie(),
+
+ sshfatal(), etc) have identical signatures. Makes things a bit more
+ consistent...
+
+ OpenBSD-Commit-ID: bd0ae124733389d7c0042e135c71ee9091362eb9
+
+commit 616029a85ad7529b24bb8c4631d9607c0d6e7afe
+Author: jmc@openbsd.org <jmc@openbsd.org>
+Date: Fri Oct 16 14:34:33 2020 +0000
+
+ upstream: add space between macro arg and punctuation;
+
+ OpenBSD-Commit-ID: bb81e2ed5a77832fe62ab30a915ae67cda57633e
+
+commit f812a36cee5727147bc897d34ab9af068dd4561e
Author: Damien Miller <djm@mindrot.org>
-Date: Mon Feb 26 12:17:22 2018 +1100
+Date: Sat Oct 17 12:03:34 2020 +1100
- avoid inclusion of deprecated selinux/flask.h
+ check for and require a C99 capable compiler
- Use string_to_security_class() instead.
+ recent logging changes use __VA_ARGS__.
-commit 2e396439365c4ca352cac222717d09b14f8a0dfd
+commit f9ea6515202b59a1e2d5b885cafc1b12eff33016
Author: Damien Miller <djm@mindrot.org>
-Date: Mon Feb 26 11:48:27 2018 +1100
+Date: Sat Oct 17 11:51:20 2020 +1100
- updatedepend
+ logging is now macros, remove function pointers
-commit 1b11ea7c58cd5c59838b5fa574cd456d6047b2d4
-Author: markus@openbsd.org <markus@openbsd.org>
-Date: Fri Feb 23 15:58:37 2018 +0000
+commit 0f938f998626e8359324f803157cd7c9f8f403e2
+Author: Damien Miller <djm@mindrot.org>
+Date: Sat Oct 17 11:42:26 2020 +1100
+
+ adapt sk-dummy's fatal implementation to changes
+
+commit afbd9ec9e2dbad04834ce7ce53e58740434f32a5
+Author: Damien Miller <djm@mindrot.org>
+Date: Sat Oct 17 11:33:13 2020 +1100
+
+ fix netcat build problem
+
+commit 793b583d097381730adaf6f68bed3c343139a013
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Fri Oct 16 13:26:13 2020 +0000
- upstream: Add experimental support for PQC XMSS keys (Extended
+ upstream: LogVerbose keyword for ssh and sshd
- Hash-Based Signatures) The code is not compiled in by default (see WITH_XMSS
- in Makefile.inc) Joint work with stefan-lukas_gazdag at genua.eu See
- https://tools.ietf.org/html/draft-irtf-cfrg-xmss-hash-based-signatures-12 ok
- djm@
+ Allows forcing maximum debug logging by file/function/line pattern-
+ lists.
+
+ ok markus@
- OpenBSD-Commit-ID: ef3eccb96762a5d6f135d7daeef608df7776a7ac
+ OpenBSD-Commit-ID: c294c25732d1b4fe7e345cb3e044df00531a6356
-commit 7d330a1ac02076de98cfc8fda05353d57b603755
-Author: jmc@openbsd.org <jmc@openbsd.org>
-Date: Fri Feb 23 07:38:09 2018 +0000
+commit 752250caabda3dd24635503c4cd689b32a650794
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Fri Oct 16 13:24:45 2020 +0000
+
+ upstream: revised log infrastructure for OpenSSH
+
+ log functions receive function, filename and line number of caller.
+ We can use this to selectively enable logging via pattern-lists.
+
+ ok markus@
+
+ OpenBSD-Commit-ID: 51a472610cbe37834ce6ce4a3f0e0b1ccc95a349
+
+commit acadbb3402b70f72f14d9a6930ad41be97c2f9dc
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Fri Oct 16 02:37:12 2020 +0000
- upstream: some cleanup for BindInterface and ssh-keyscan;
+ upstream: use do_log2 instead of function pointers to different log
+
+ functions
- OpenBSD-Commit-ID: 1a719ebeae22a166adf05bea5009add7075acc8c
+ OpenBSD-Commit-ID: 88077b826d348c58352a6b394755520f4e484480
-commit c7b5a47e3b9db9a0f0198f9c90c705f6307afc2b
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Sun Feb 25 23:55:41 2018 +1100
+commit 95b0bcfd1531d59e056ae8af27bb741391f26ab0
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Wed Oct 14 00:55:17 2020 +0000
- Invert sense of getpgrp test.
+ upstream: make UpdateHostkeys still more conservative: refuse to
- AC_FUNC_GETPGRP tests if getpgrp(0) works, which it does if it's not
- declared. Instead, test if the zero-arg version we want to use works.
+ proceed if one of the keys offered by the server is already in known_hosts
+ under another name. This avoid collisions between address entries for
+ different host aliases when CheckHostIP=yes
+
+ Also, do not attempt to fix known_hosts with incomplete host/ip matches
+ when there are no new or deprecated hostkeys.
+
+ OpenBSD-Commit-ID: 95c19842f7c41f9bd9c92aa6441a278c0fd0c4a3
-commit b39593a6de5290650a01adf8699c6460570403c2
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Sun Feb 25 13:25:15 2018 +1100
+commit a336ce8c2c55547cc00e0070a18c55f30bb53fb6
+Author: kn@openbsd.org <kn@openbsd.org>
+Date: Mon Oct 12 08:36:36 2020 +0000
- Add no-op getsid implmentation.
+ upstream: Zap unused family parameter from ssh_connect_direct()
+
+ sshconnect.c r1.241 from 2013 made it unused; found while reading code.
+
+ OK djm
+
+ OpenBSD-Commit-ID: 219ba6d7f9925d0b7992918612680399d86712b5
-commit 11057564eb6ab8fd987de50c3d7f394c6f6632b7
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Sun Feb 25 11:22:57 2018 +1100
+commit e545d94b713effab8e6c7dfabbfb76c1d84d7498
+Author: Philip Hands <phil@hands.com>
+Date: Sun Oct 4 00:15:46 2020 +0200
- bsd-statvfs: include sys/vfs.h, check for f_flags.
+ shift contents of long $() into filter_ids()
+
+ This was prompted by the fact that posh does not deal with $()
+ that contains comments where the comment includes an odd number
+ of single-quotes. It seems to get befuddled into trying to find
+ the matching quote.
+ Regardless, making a function for filtering the unneeded ids
+ seems much neater than avoiding apostrophes,
+ so that's what I've done.
+
+ SSH-Copy-ID-Upstream: 3dab3366a584427045c8a690a93282f02c09cf24
-commit e9dede06e5bc582a4aeb5b1cd5a7a640d7de3609
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Sun Feb 25 10:20:31 2018 +1100
+commit fd360174596047b52aa1cddda74d85012a03ca4b
+Author: Philip Hands <phil@hands.com>
+Date: Sat Oct 3 23:15:16 2020 +0200
- Handle calloc(0,x) where different from malloc.
+ combine if/elif to avoid duplication of the action
- Configure assumes that if malloc(0) returns null then calloc(0,n)
- also does. On some old platforms (SunOS4) malloc behaves as expected
- (as determined by AC_FUNC_MALLOC) but calloc doesn't. Test for this
- at configure time and activate the replacement function if found, plus
- handle this case in rpl_calloc.
+ SSH-Copy-ID-Upstream: 42aeb1cc53d3f7f6e78edc210fb121fda0834914
-commit 2eb4041493fd2635ffdc64a852d02b38c4955e0b
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Sat Feb 24 21:06:48 2018 +1100
+commit f7c3a39b016dd77709ecbf18da8282f967b86cd7
+Author: Philip Hands <phil@hands.com>
+Date: Sat Oct 3 21:45:16 2020 +0200
- Add prototype for readv if needed.
+ shellcheck tidyage
+
+ SSH-Copy-ID-Upstream: 5b08f840e78ac544288b3983010a1b0585e966fd
-commit 6c8c9a615b6d31db8a87bc25033f053d5b0a831e
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Sat Feb 24 20:46:37 2018 +1100
+commit 108676c3f26be6c873db0dd8754063699908727b
+Author: Philip Hands <phil@hands.com>
+Date: Sat Oct 3 21:10:03 2020 +0200
- Check for raise and supply if needed.
+ tidy up test of $SCRATCH_DIR creation
+
+ SSH-Copy-ID-Upstream: 2d8b22d96c105d87743ffe8874887b06f8989b93
-commit a9004425a032d7a7141a5437cfabfd02431e2a74
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Sat Feb 24 20:25:22 2018 +1100
+commit a9c9e91a82bc1a2cf801b4e3ef27a941dbd27717
+Author: Philip Hands <phil@hands.com>
+Date: Wed Sep 16 16:13:30 2020 +0200
- Check for bzero and supply if needed.
+ add -s flag: to install keys via SFTP
+
+ This is prompted by:
+
+ https://bugzilla.mindrot.org/show_bug.cgi?id=3201
+
+ Thanks go to Matthias Blümel for the idea, and the helpful patch, from
+ which this patch grew.
- Since explicit_bzero uses it via an indirect it needs to be a function
- not just a macro.
+ SSH-Copy-ID-Upstream: f7c76dc64427cd20287a6868f672423b62057614
-commit 1a348359e4d2876203b5255941bae348557f4f54
+commit f92424970c02b78852ff149378c7f2616ada4ccf
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Feb 23 05:14:05 2018 +0000
+Date: Sun Oct 11 22:14:38 2020 +0000
- upstream: Add ssh-keyscan -D option to make it print its results in
+ upstream: UpdateHostkeys: check for keys under other names
- SSHFP format bz#2821, ok dtucker@
+ Stop UpdateHostkeys from automatically removing deprecated keys from
+ known_hosts files if the same keys exist under a different name or
+ address to the host that is being connected to.
+
+ This avoids UpdateHostkeys from making known_hosts inconsistent in
+ some cases. For example, multiple host aliases sharing address-based
+ known_hosts on different lines, or hosts that resolves to multiple
+ addresses.
+
+ ok markus@
- OpenBSD-Commit-ID: 831446b582e0f298ca15c9d99c415c899e392221
+ OpenBSD-Commit-ID: 6444a705ba504c3c8ccddccd8d1b94aa33bd11c1
-commit 3e19fb976a47b44b3d7c4f8355269f7f2c5dd82c
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Fri Feb 23 04:18:46 2018 +0000
+commit d98f14b5328922ae3085e07007d820c4f655b57a
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Sun Oct 11 22:13:37 2020 +0000
- upstream: Add missing braces.
+ upstream: UpdateHostkeys: better CheckHostIP handling
+
+ When preparing to update the known_hosts file, fully check both
+ entries for both the host and the address (if CheckHostIP enabled)
+ and ensure that, at the end of the operation, entries for both are
+ recorded.
+
+ Make sure this works with HashKnownHosts too, which requires maintaining
+ a list of entry-types seen across the whole file for each key.
- Caught by the tinderbox's -Werror=misleading-indentation, ok djm@
+ ok markus@
- OpenBSD-Commit-ID: d44656af594c3b2366eb87d6abcef83e1c88a6ca
+ OpenBSD-Commit-ID: 374dc263103f6b343d9671f87dbf81ffd0d6abdd
-commit b59162da99399d89bd57f71c170c0003c55b1583
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Fri Feb 23 15:20:42 2018 +1100
+commit af5941ae9b013aac12585e84c4cf494f3728982f
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Sun Oct 11 22:12:44 2020 +0000
- Check for ifaddrs.h for BindInterface.
+ upstream: UpdateHostkeys: better detect manual host entries
+
+ Disable UpdateHostkeys if the known_hosts line has more than two
+ entries in the pattern-list. ssh(1) only writes "host" or "host,ip"
+ lines so anything else was added by a different tool or by a human.
- BindInterface required getifaddr and friends so disable if not available
- (eg Solaris 10). We should be able to add support for some systems with
- a bit more work but this gets the building again.
+ ok markus@
+
+ OpenBSD-Commit-ID: e434828191fb5f3877d4887c218682825aa59820
-commit a8dd6fe0aa10b6866830b4688a73ef966f0aed88
-Author: Damien Miller <djm@mindrot.org>
-Date: Fri Feb 23 14:19:11 2018 +1100
+commit 6247812c76f70b2245f3c23f5074665b3d436cae
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Thu Oct 8 01:15:16 2020 +0000
- space before tab in previous
+ upstream: don't misdetect comma-separated hostkey names as wildcards;
+
+ spotted by naddy@
+
+ OpenBSD-Commit-ID: 4b874edfec7fc324a21b130bdb42f912177739ce
-commit b5e9263c7704247f9624c8f5c458e9181fcdbc09
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Fri Feb 9 03:40:22 2018 +0000
+commit 67146c7d022a170be3cdad2f5f40259a663fb266
+Author: wangxp006 <wangxiaopeng7@huawei.com>
+Date: Thu Oct 8 17:49:59 2020 +0800
- upstream: Replace fatal with exit in the case that we do not have
+ fix TEST_MALLOC_OPTIONS var
+
+commit 3205eaa3f8883a34fa4559ddef6c90d1067c5cce
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Thu Oct 8 00:31:05 2020 +0000
+
+ upstream: clarify conditions for UpdateHostkeys
+
+ OpenBSD-Commit-ID: 9cba714cf6aeed769f998ccbe8c483077a618e27
+
+commit e8dfca9bfeff05de87160407fb3e6a5717fa3dcb
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Wed Oct 7 06:38:16 2020 +0000
+
+ upstream: remove GlobalKnownHostsFile for this test after
- $SUDO set. Prevents test failures when neither sudo nor doas are configured.
+ UpdateHostkeys change
- OpenBSD-Regress-ID: 6a0464decc4f8ac7d6eded556a032b0fc521bc7b
+ OpenBSD-Regress-ID: a940ad79d59343319613ba8fc46b6ef24aa3f8e1
-commit 3e9d3192ad43758ef761c5b0aa3ac5ccf8121ef2
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Fri Feb 23 14:10:53 2018 +1100
+commit 4aa2717d7517cff4bc423a6cfba3a2defb055aea
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Wed Oct 7 02:26:28 2020 +0000
+
+ upstream: Disable UpdateHostkeys when hostkey checking fails
+
+ If host key checking fails (i.e. a wrong host key is recorded for the
+ server) and the user elects to continue (via StrictHostKeyChecking=no),
+ then disable UpdateHostkeys for the session.
+
+ reminded by Mark D. Baushke; ok markus@
+
+ OpenBSD-Commit-ID: 98b524f121f4252309dd21becd8c4cacb0c6042a
+
+commit 04c06d04475f1f673e9d9743710d194453fe3888
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Wed Oct 7 02:25:43 2020 +0000
+
+ upstream: Fix UpdateHostkeys/HashKnownHosts/CheckHostIP bug
+
+ When all of UpdateHostkeys, HashKnownHosts and ChechHostIP
+ were enabled and new host keys were learned, known_hosts IP
+ entries were not being recorded for new host keys.
+
+ reported by matthieu@ ok markus@
+
+ OpenBSD-Commit-ID: a654a8290bd1c930aac509e8158cf85e42e49cb7
+
+commit b70e33711291f3081702133175a41cccafc0212a
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Wed Oct 7 02:24:51 2020 +0000
+
+ upstream: don't UpdateHostkeys when the hostkey is verified by the
+
+ GlobalKnownHostsFile file, support only UserKnownHostsFile matches
+
+ suggested by Mark D. Baushke; feedback and ok markus@
+
+ OpenBSD-Commit-ID: eabb771a6add676c398d38a143a1aff5f04abbb9
+
+commit aa623142e426ca1ab9db77b06dcc9b1b70bd102b
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Wed Oct 7 02:22:23 2020 +0000
+
+ upstream: revert kex->flags cert hostkey downgrade back to a plain
+
+ key (commitid VtF8vozGOF8DMKVg). We now do this a simpler way that needs less
+ plumbing.
+
+ ok markus@
+
+ OpenBSD-Commit-ID: fb92d25b216bff8c136da818ac2221efaadf18ed
- Use portable syntax for REGRESSTMP.
+commit f4f14e023cafee1cd9ebe4bb0db4029e6e1fafac
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Wed Oct 7 02:20:35 2020 +0000
-commit 73282b61187883a2b2bb48e087fdda1d751d6059
+ upstream: simply disable UpdateHostkeys when a certificate
+
+ successfully authenticated the host; simpler than the complicated plumbing
+ via kex->flags we have now.
+
+ ok markus@
+
+ OpenBSD-Commit-ID: 80e39644eed75717d563a7f177e8117a0e14f42c
+
+commit e79957e877db42c4c68fabcf6ecff2268e53acb5
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Feb 23 03:03:00 2018 +0000
+Date: Wed Oct 7 02:18:45 2020 +0000
- upstream: unbreak interop test after SSHv1 purge; patch from Colin
+ upstream: disable UpdateHostkeys by default if VerifyHostKeyDNS is
- Watson via bz#2823
+ enabled; suggested by Mark D. Baushke
- OpenBSD-Regress-ID: 807d30a597756ed6612bdf46dfebca74f49cb31a
+ OpenBSD-Commit-ID: 85a1b88592c81bc85df7ee7787dbbe721a0542bf
-commit f8985dde5f46aedade0373365cbf86ed3f1aead2
+commit 3d4c2016bae1a6f14b48c1150a4c79ca4c9968bd
Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Fri Feb 9 03:42:57 2018 +0000
+Date: Tue Oct 6 07:12:04 2020 +0000
- upstream: Skip sftp-chroot test when SUDO not set instead of
+ upstream: Agent protocol draft is now at rev 4. ok djm@
- fatal().
+ OpenBSD-Commit-ID: 8c01ea3aae48aab45e01b7421b0fca2dad5e7837
+
+commit af889a40ffc113af9105c03d7b32131eb4372d50
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Sun Oct 4 09:45:01 2020 +0000
+
+ upstream: when ordering host key algorithms in the client, consider
- OpenBSD-Regress-ID: cd4b5f1109b0dc09af4e5ea7d4968c43fbcbde88
+ the ECDSA key subtype; ok markus@
+
+ OpenBSD-Commit-ID: 3097686f853c61ff61772ea35f8b699931392ece
-commit df88551c02d4e3445c44ff67ba8757cff718609a
+commit 2d39fc9f7e039351daa3d6aead1538ac29258add
Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Fri Feb 9 03:40:22 2018 +0000
+Date: Sun Oct 4 03:04:02 2020 +0000
+
+ upstream: Allow full range of UIDs and GIDs for sftp chown and
+
+ chgrp on 32bit platforms instead of being limited by LONG_MAX. bz#3206,
+ found by booking00 at sina.cn, ok markus@
+
+ OpenBSD-Commit-ID: 373b7bbf1f15ae482d39567ce30d18b51c9229b5
+
+commit 396d32f3a1a16e54df2a76b2a9b237868580dcbe
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Sat Oct 3 09:22:26 2020 +0000
- upstream: Replace fatal with exit in the case that we do not have
+ upstream: There are lots of place where we want to redirect stdin,
- $SUDO set. Prevents test failures when neither sudo nor doas are configured.
+ stdout and/or stderr to /dev/null. Factor all these out to a single
+ stdfd_devnull() function that allows selection of which of these to redirect.
+ ok markus@
- OpenBSD-Regress-ID: 6a0464decc4f8ac7d6eded556a032b0fc521bc7b
+ OpenBSD-Commit-ID: 3033ba5a4c47cacfd5def020d42cabc52fad3099
-commit 3b252c20b19f093e87363de197f1100b79705dd3
+commit 1286981d08b8429a64613215ce8bff3f6b32488a
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Thu Feb 8 08:46:20 2018 +0000
+Date: Sat Oct 3 08:30:47 2020 +0000
- upstream: some helpers to check verbose/quiet mode
+ upstream: enable UpdateHostkeys by default when the configuration
- OpenBSD-Regress-ID: e736aac39e563f5360a0935080a71d5fdcb976de
+ has not overridden UserKnownHostsFile; ok markus@ "The timing is perfect"
+ deraadt@
+
+ OpenBSD-Commit-ID: 62df71c9c5242da5763cb473c2a2deefbd0cef60
-commit ac2e3026bbee1367e4cda34765d1106099be3287
+commit 332f21537293d66508f7342dc643bc7fe45f0f69
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Feb 23 02:34:33 2018 +0000
+Date: Sat Oct 3 08:12:59 2020 +0000
- upstream: Add BindInterface ssh_config directive and -B
+ upstream: disable UpdateHostkeys when a wildcard hostname pattern
- command-line argument to ssh(1) that directs it to bind its outgoing
- connection to the address of the specified network interface.
+ is encountered or when a certificate host key is in use. feedback/ok markus@
- BindInterface prefers to use addresses that aren't loopback or link-
- local, but will fall back to those if no other addresses of the
- required family are available on that interface.
+ OpenBSD-Commit-ID: b6e5575af7e6732322be82ec299e09051a5413bd
+
+commit 13cee44ef907824083d89cb9395adbbd552e46c1
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Sat Oct 3 08:11:28 2020 +0000
+
+ upstream: record when the host key checking code downgrades a
- Based on patch by Mike Manning in bz#2820, ok dtucker@
+ certificate host key to a plain key. This occurs when the user connects to a
+ host with a certificate host key but no corresponding CA key configured in
+ known_hosts; feedback and ok markus@
- OpenBSD-Commit-ID: c5064d285c2851f773dd736a2c342aa384fbf713
+ OpenBSD-Commit-ID: 2ada81853ff9ee7824c62f440bcf4ad62030c901
-commit fcdb9d777839a3fa034b3bc3067ba8c1f6886679
+commit 12ae8f95e2e0c273e9e7ef930b01a028ef796a3f
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Mon Feb 19 00:55:02 2018 +0000
+Date: Sat Oct 3 04:15:06 2020 +0000
- upstream: emphasise that the hostkey rotation may send key types
+ upstream: prefer ed25519 signature algorithm variants to ECDSA; ok
- that the client may not support, and that the client should simply disregard
- such keys (this is what ssh does already).
+ markus@
- OpenBSD-Commit-ID: 65f8ffbc32ac8d12be8f913d7c0ea55bef8622bf
+ OpenBSD-Commit-ID: 82187926fca96d35a5b5afbc091afa84e0966e5b
-commit ce066f688dc166506c082dac41ca686066e3de5f
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Thu Feb 22 20:45:09 2018 +1100
+commit e5ed753add7aa8eed6b167e44db6240a76404db2
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Sat Oct 3 03:40:38 2020 +0000
- Add headers for sys/audit.h.
+ upstream: want time.h here too
- On some older platforms (at least sunos4, probably others) sys/audit.h
- requires some other headers. Patch from klausz at haus-gisela.de.
+ OpenBSD-Commit-ID: fafee8f1108c64ad8b282f9a1ed5ea830d8c58a7
-commit 3fd2d2291a695c96a54269deae079bacce6e3fb9
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Mon Feb 19 18:37:40 2018 +1100
+commit 66bd9fdf8b7762eb6a85cabbb1ae4ed955679f60
+Author: deraadt@openbsd.org <deraadt@openbsd.org>
+Date: Sat Oct 3 02:18:33 2020 +0000
- Add REGRESSTMP make var override.
+ upstream: split introductory paragraph, and insert ominous words about
+
+ the glob issue, which cannot be fully fixed and really requires completely
+ replacing scp with a completely different subsystem. team effort to find the
+ right words..
- Defaults to original location ($srcdir/regress) but allows overriding
- if desired, eg a directory in /tmp.
+ OpenBSD-Commit-ID: 58e1f72d292687f63eb357183036ee242513691c
-commit f8338428588f3ecb5243c86336eccaa28809f97e
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Sun Feb 18 15:53:15 2018 +1100
+commit 86cc8ce002ea10e88a4c5d622a8fdfab8a7d261f
+Author: Damien Miller <djm@mindrot.org>
+Date: Sat Oct 3 13:38:55 2020 +1000
+
+ use relative rather than system include here
+
+commit 922cfac5ed5ead9f796f7d39f012dd653dc5c173
+Author: Damien Miller <djm@mindrot.org>
+Date: Sat Oct 3 13:38:41 2020 +1000
+
+ add some openbsd-compat licenses we missed
+
+commit ce941c75ea9cd6c358508a5b206809846c8d9240
+Author: Philip Hands <phil@hands.com>
+Date: Sat Oct 3 00:20:07 2020 +0200
+
+ un-nest $() to make ksh cheerful
- Remove now-unused check for getrusage.
+commit 18ea5f4b88e303677d2003b95e5cb864b439e442
+Author: Philip Hands <phil@hands.com>
+Date: Fri Oct 2 21:30:10 2020 +0200
+
+ ksh doesn't grok 'local'
- getrusage was used in ssh-rand-helper but that's now long gone.
- Patch from klauszh at haus-gisela.de.
+ and AFAICT it's not actually doing anything useful in the code, so let's
+ see how things go without it.
+
+commit d9e727dcc04a52caaac87543ea1d230e9e6b5604
+Author: Oleg <Fallmay@users.noreply.github.com>
+Date: Thu Oct 1 12:09:08 2020 +0300
-commit 8570177195f6a4b3173c0a25484a83641ee3faa6
+ Fix `EOF: command not found` error in ssh-copy-id
+
+commit a1a856d50c89be3206f320baa4bfb32fff4e826f
Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Fri Feb 16 04:43:11 2018 +0000
+Date: Wed Sep 30 09:11:39 2020 +0000
- upstream: Don't send IUTF8 to servers that don't like them.
+ upstream: Regen moduli.
- Some SSH servers eg "ConfD" drop the connection if the client sends the
- new IUTF8 (RFC8160) terminal mode even if it's not set. Add a bug bit
- for such servers and avoid sending IUTF8 to them. ok djm@
+ OpenBSD-Commit-ID: 04967f8c43e9854ac34b917bcd6f5ac96c53a693
+
+commit fa1fe3ead7069d90d3c67d62137ad66acfcc9f48
+Author: HARUYAMA Seigo <haruyama@unixuser.org>
+Date: Sun Sep 27 20:06:20 2020 +0900
+
+ Restore first section title of INSTALL
+
+commit 279261e1ea8150c7c64ab5fe7cb4a4ea17acbb29
+Author: Damien Miller <djm@mindrot.org>
+Date: Sun Sep 27 17:25:01 2020 +1000
+
+ update version numbers
+
+commit 58ca6ab6ff035ed12b5078e3e9c7199fe72c8587
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Sun Sep 27 07:22:05 2020 +0000
+
+ upstream: openssh 8.4
- OpenBSD-Commit-ID: 26425855402d870c3c0a90491e72e2a8a342ceda
+ OpenBSD-Commit-ID: a29e5b372d2c00e297da8a35a3b87c9beb3b4a58
-commit f6dc2ba3c9d12be53057b9371f5109ec553a399f
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Fri Feb 16 17:32:28 2018 +1100
+commit 9bb8a303ce05ff13fb421de991b495930be103c3
+Author: Damien Miller <djm@mindrot.org>
+Date: Tue Sep 22 10:07:43 2020 +1000
- freezero should check for NULL.
+ sync with upstream ssh-copy-id rev f0da1a1b7
-commit 680321f3eb46773883111e234b3c262142ff7c5b
+commit 0a4a5571ada76b1b012bec9cf6ad1203fc19ec8d
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Feb 16 02:40:45 2018 +0000
+Date: Mon Sep 21 07:29:09 2020 +0000
- upstream: Mention recent DH KEX methods:
+ upstream: close stdin when forking after authentication too; ok markus
- diffie-hellman-group14-sha256
- diffie-hellman-group16-sha512
- diffie-hellman-group18-sha512
+ OpenBSD-Commit-ID: 43db17e4abc3e6b4a7b033aa8cdab326a7cb6c24
+
+commit d14fe25e6c3b89f8af17e2894046164ac3b45688
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Sun Sep 20 23:31:46 2020 +0000
+
+ upstream: close stdout/stderr after "ssh -f ..." forking
- From Jakub Jelen via bz#2826
+ bz#3137, ok markus
- OpenBSD-Commit-ID: 51bf769f06e55447f4bfa7306949e62d2401907a
+ OpenBSD-Commit-ID: e2d83cc4dea1665651a7aa924ad1ed6bcaaab3e2
+
+commit 53a33a0d745179c02108589e1722457ca8ae4372
+Author: Damien Miller <djm@mindrot.org>
+Date: Sun Sep 20 15:57:09 2020 +1000
+
+ .depend
-commit 88c50a5ae20902715f0fca306bb9c38514f71679
+commit 107eb3eeafcd390e1fa7cc7672a05e994d14013e
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Feb 16 02:32:40 2018 +0000
+Date: Sun Sep 20 05:47:25 2020 +0000
- upstream: stop loading DSA keys by default, remove sshd_config
+ upstream: cap channel input buffer size at 16MB; avoids high memory use
- stanza and manpage bits; from Colin Watson via bz#2662, ok dtucker@
+ when peer advertises a large window but is slow to consume the data we send
+ (e.g. because of a slow network)
- OpenBSD-Commit-ID: d33a849f481684ff655c140f5eb1b4acda8c5c09
+ reported by Pierre-Yves David
+
+ fix with & ok markus@
+
+ OpenBSD-Commit-ID: 1452771f5e5e768876d3bfe2544e3866d6ade216
+
+commit acfe2ac5fe033e227ad3a56624fbbe4af8b5da04
+Author: Damien Miller <djm@mindrot.org>
+Date: Fri Sep 18 22:02:53 2020 +1000
+
+ libfido2 1.5.0 is recommended
-commit d2b3db2860c962927def39a52f67f1c23f7b201a
-Author: jsing@openbsd.org <jsing@openbsd.org>
-Date: Wed Feb 14 16:27:24 2018 +0000
+commit 52a03e9fca2d74eef953ddd4709250f365ca3975
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Fri Sep 18 08:16:38 2020 +0000
- upstream: Ensure that D mod (P-1) and D mod (Q-1) are calculated in
+ upstream: handle multiple messages in a single read()
- constant time.
+ PR#183 by Dennis Kaarsemaker; feedback and ok markus@
- This avoids a potential side channel timing leak.
+ OpenBSD-Commit-ID: 8570bb4d02d00cf70b98590716ea6a7d1cce68d1
+
+commit dc098405b2939146e17567a25b08fc6122893cdf
+Author: pedro martelletto <pedro@ambientworks.net>
+Date: Fri Sep 18 08:57:29 2020 +0200
+
+ configure.ac: add missing includes
- ok djm@ markus@
+ when testing, make sure to include the relevant header files that
+ declare the types of the functions used by the test:
- OpenBSD-Commit-ID: 71ff3c16be03290e63d8edab8fac053d8a82968c
+ - stdio.h for printf();
+ - stdlib.h for exit();
+ - string.h for strcmp();
+ - unistd.h for unlink(), _exit(), fork(), getppid(), sleep().
-commit 4270efad7048535b4f250f493d70f9acfb201593
-Author: jsing@openbsd.org <jsing@openbsd.org>
-Date: Wed Feb 14 16:03:32 2018 +0000
+commit b3855ff053f5078ec3d3c653cdaedefaa5fc362d
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Fri Sep 18 05:23:03 2020 +0000
- upstream: Some obvious freezero() conversions.
+ upstream: tweak the client hostkey preference ordering algorithm to
- This also zeros an ed25519_pk when it was not being zeroed previously.
+ prefer the default ordering if the user has a key that matches the
+ best-preference default algorithm.
- ok djm@ dtucker@
+ feedback and ok markus@
- OpenBSD-Commit-ID: 5c196a3c85c23ac0bd9b11bcadaedd90b7a2ce82
+ OpenBSD-Commit-ID: a92dd7d7520ddd95c0a16786a7519e6d0167d35f
-commit affa6ba67ffccc30b85d6e98f36eb5afd9386882
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Thu Feb 15 22:32:04 2018 +1100
+commit f93b187ab900c7d12875952cc63350fe4de8a0a8
+Author: Damien Miller <djm@mindrot.org>
+Date: Fri Sep 18 14:55:48 2020 +1000
- Remove execute bit from modpipe.c.
+ control over the colours in gnome-ssh-askpass[23]
+
+ Optionally set the textarea colours via $GNOME_SSH_ASKPASS_FG_COLOR and
+ $GNOME_SSH_ASKPASS_BG_COLOR. These accept the usual three or six digit
+ hex colours.
-commit 9879dca438526ae6dfd656fecb26b0558c29c731
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Thu Feb 15 22:26:16 2018 +1100
+commit 9d3d36bdb10b66abd1af42e8655502487b6ba1fa
+Author: Damien Miller <djm@mindrot.org>
+Date: Fri Sep 18 14:50:38 2020 +1000
- Update prngd link to point to sourceforge.
+ focus improvement for gnome-ssh-askpass[23]
+
+ When serving a SSH_ASKPASS_PROMPT=none information dialog, ensure
+ then <enter> doesn't immediately close the dialog. Instead, require an
+ explicit <tab> to reach the close button, or <esc>.
-commit b6973fa5152b1a0bafd2417b7c3ad96f6e87d014
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Thu Feb 15 22:22:38 2018 +1100
+commit d6f507f37e6c75a899db0ef8224e72797c5563b6
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Wed Sep 16 03:07:31 2020 +0000
- Remove references to UNICOS.
+ upstream: Remove unused buf, last user was removed when switching
+
+ to the sshbuf API. Patch from Sebastian Andrzej Siewior.
+
+ OpenBSD-Commit-ID: 250fa17f0cec01039cc4abd95917d9746e24c889
-commit f1ca487940449f0b64f38f1da575078257609966
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Thu Feb 15 22:18:37 2018 +1100
+commit c3c786c3a0973331ee0922b2c51832a3b8d7f20f
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Wed Sep 9 21:57:27 2020 +0000
- Remove extra newline.
+ upstream: For the hostkey confirmation message:
+
+ > Are you sure you want to continue connecting (yes/no/[fingerprint])?
+
+ compare the fingerprint case sensitively; spotted Patrik Lundin
+ ok dtucker
+
+ OpenBSD-Commit-ID: 73097afee1b3a5929324e345ba4a4a42347409f2
-commit 6d4e980f3cf27f409489cf89cd46c21501b13731
+commit f2950baf0bafe6aa20dfe2e8d1ca4b23528df617
Author: Darren Tucker <dtucker@dtucker.net>
-Date: Thu Feb 15 22:16:54 2018 +1100
+Date: Fri Sep 11 14:45:23 2020 +1000
- OpenSSH's builtin entropy gathering is long gone.
+ New config-build-time dependency on automake.
-commit 389125b25d1a1d7f22e907463b7e8eca74af79ea
+commit 600c1c27abd496372bd0cf83d21a1c119dfdf9a5
Author: Darren Tucker <dtucker@dtucker.net>
-Date: Thu Feb 15 21:43:01 2018 +1100
+Date: Sun Sep 6 21:56:36 2020 +1000
- Replace remaining mysignal() with signal().
+ Add aclocal.m4 and config.h.in~ to .gitignore.
- These seem to have been missed during the replacement of mysignal
- with #define signal in commit 5ade9ab. Both include the requisite
- headers to pick up the #define.
+ aclocal.m4 is now generated by autoreconf.
-commit 265d88d4e61e352de6791733c8b29fa3d7d0c26d
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Thu Feb 15 20:06:19 2018 +1100
+commit 4bf7e1d00b1dcd3a6b3239f77465c019e61c6715
+Author: Sebastian Andrzej Siewior <sebastian@breakpoint.cc>
+Date: Sat Sep 5 17:50:03 2020 +0200
- Remove remaining now-obsolete cvs $Ids.
+ Quote the definition of OSSH_CHECK_HEADER_FOR_FIELD
+
+ autoreconf complains about underquoted definition of
+ OSSH_CHECK_HEADER_FOR_FIELD after aclocal.m4 has been and now is beeing
+ recreated.
+
+ Quote OSSH_CHECK_HEADER_FOR_FIELD as suggested.
+
+ Signed-off-by: Sebastian Andrzej Siewior <sebastian@breakpoint.cc>
-commit 015749e9b1d2f6e14733466d19ba72f014d0845c
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Thu Feb 15 17:01:54 2018 +1100
+commit a2f3ae386b5f7938ed3c565ad71f30c4f7f010f1
+Author: Sebastian Andrzej Siewior <sebastian@breakpoint.cc>
+Date: Sat Sep 5 17:50:02 2020 +0200
- Regenerate dependencies after UNICOS removal.
+ Move the local m4 macros
+
+ The `aclocal' step is skipped during `autoreconf' because aclocal.m4 is
+ present.
+ Move the current aclocal.m4 which contains local macros into the m4/
+ folder. With this change the aclocal.m4 will be re-created during
+ changes to the m4/ macro.
+ This is needed so the `aclocal' can fetch m4 macros from the system if
+ they are references in the configure script. This is a prerequisite to
+ use PKG_CHECK_MODULES.
+
+ Signed-off-by: Sebastian Andrzej Siewior <sebastian@breakpoint.cc>
-commit ddc0f3814881ea279a6b6d4d98e03afc60ae1ed7
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Tue Feb 13 09:10:46 2018 +1100
+commit 8372bff3a895b84fd78a81dc39da10928b662f5a
+Author: Sebastian Andrzej Siewior <sebastian@breakpoint.cc>
+Date: Sat Sep 5 17:50:01 2020 +0200
- Remove UNICOS support.
+ Remove HAVE_MMAP and BROKEN_MMAP
+
+ BROKEN_MMAP is no longer defined since commit
+ 1cfd5c06efb12 ("Remove portability support for mmap")
+
+ this commit also removed other HAVE_MMAP user. I didn't find anything
+ that defines HAVE_MMAP. The check does not trigger because compression
+ on server side is by default COMP_DELAYED (2) so it never triggers.
- The code required to support it is quite invasive to the mainline
- code that is synced with upstream and is an ongoing maintenance burden.
- Both the hardware and software are literal museum pieces these days and
- we could not find anyone still running OpenSSH on one.
+ Remove remaining HAVE_MMAP and BROKEN_MMAP bits.
+
+ Signed-off-by: Sebastian Andrzej Siewior <sebastian@breakpoint.cc>
-commit 174bed686968494723e6db881208cc4dac0d020f
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Tue Feb 13 18:12:47 2018 +1100
+commit bbf20ac8065905f9cb9aeb8f1df57fcab52ee2fb
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Wed Sep 9 03:10:21 2020 +0000
- Retpoline linker flag only needed for linking.
+ upstream: adapt to SSH_SK_VERSION_MAJOR crank
+
+ OpenBSD-Regress-ID: 0f3e76bdc8f9dbd9d22707c7bdd86051d5112ab8
-commit 075e258c2cc41e1d7f3ea2d292c5342091728d40
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Tue Feb 13 17:36:43 2018 +1100
+commit 9afe2a150893b20bdf9eab764978d817b9a7b783
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Fri Aug 28 03:17:13 2020 +0000
- Default PidFile is sshd.pid not ssh.pid.
+ upstream: Ensure that address/mask mismatches are flagged at
+
+ config-check time. ok djm@
+
+ OpenBSD-Regress-ID: 8f5f4c2c0bf00e6ceae7a1755a444666de0ea5c2
-commit 49f3c0ec47730ea264e2bd1e6ece11167d6384df
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Tue Feb 13 16:27:09 2018 +1100
+commit c76773524179cb654ff838dd43ba1ddb155bafaa
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Wed Sep 9 03:08:01 2020 +0000
- Remove assigned-to-but-never-used variable.
+ upstream: when writing an attestation blob for a FIDO key, record all
- 'p' was removed in previous change but I neglected to remove the
- otherwise-unused assignment to it.
+ the data needed to verify the attestation. Previously we were missing the
+ "authenticator data" that is included in the signature.
+
+ spotted by Ian Haken
+ feedback Pedro Martelletto and Ian Haken; ok markus@
+
+ OpenBSD-Commit-ID: 8439896e63792b2db99c6065dd9a45eabbdb7e0a
+
+commit c1c44eeecddf093a7983bd91e70b446de789b363
+Author: pedro martelletto <pedro@ambientworks.net>
+Date: Tue Sep 1 17:01:55 2020 +0200
+
+ configure.ac: fix libfido2 back-compat
+
+ - HAVE_FIDO_CRED_PROD -> HAVE_FIDO_CRED_PROT;
+ - check for fido_dev_get_touch_begin(), so that
+ HAVE_FIDO_DEV_GET_TOUCH_BEGIN gets defined.
-commit b8bbff3b3fc823bf80c5ab226c94f13cb887d5b1
+commit 785f0f315bf7ac5909e988bb1ac3e019fb5e1594
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Tue Feb 13 03:36:56 2018 +0000
+Date: Mon Aug 31 04:33:17 2020 +0000
- upstream: remove space before tab
+ upstream: refuse to add verify-required (PINful) FIDO keys to
+
+ ssh-agent until the agent supports them properly
- OpenBSD-Commit-ID: 674edd214d0a7332dd4623c9cf8117301b012890
+ OpenBSD-Commit-ID: 125bd55a8df32c87c3ec33c6ebe437673a3d037e
+
+commit 39e88aeff9c7cb6862b37ad1a87a03ebbb38c233
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Mon Aug 31 00:17:41 2020 +0000
-commit 05046d907c211cb9b4cd21b8eff9e7a46cd6c5ab
+ upstream: Add RCS IDs to the few files that are missing them; from
+
+ Pedro Martelletto
+
+ OpenBSD-Commit-ID: 39aa37a43d0c75ec87f1659f573d3b5867e4a3b3
+
+commit 72730249b38a676da94a1366b54a6e96e6928bcb
Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Sun Feb 11 21:16:56 2018 +0000
+Date: Fri Aug 28 03:15:52 2020 +0000
- upstream Don't reset signal handlers inside handlers.
+ upstream: Check that the addresses supplied to Match Address and
- The signal handlers from the original ssh1 code on which OpenSSH
- is based assume unreliable signals and reinstall their handlers.
- Since OpenBSD (and pretty much every current system) has reliable
- signals this is not needed. In the unlikely even that -portable
- is still being used on such systems we will deal with it in the
- compat layer. ok deraadt@
+ Match LocalAddress are valid when parsing in config-test mode. This will
+ catch address/mask mismatches before they cause problems at runtime. Found by
+ Daniel Stocker, ok djm@
- OpenBSD-Commit-ID: f53a1015cb6908431b92116130d285d71589612c
+ OpenBSD-Commit-ID: 2d0b10c69fad5d8fda4c703e7c6804935289378b
-commit 3c51143c639ac686687c7acf9b373b8c08195ffb
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Tue Feb 13 09:07:29 2018 +1100
+commit 2a3a9822311a565a9df48ed3b6a3c972f462bd7d
+Author: jmc@openbsd.org <jmc@openbsd.org>
+Date: Thu Aug 27 12:34:00 2020 +0000
- Whitespace sync with upstream.
+ upstream: sentence fix; from pedro martelletto
+
+ OpenBSD-Commit-ID: f95b84a1e94e9913173229f3787448eea2f8a575
-commit 19edfd4af746bedf0df17f01953ba8c6d3186eb7
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Tue Feb 13 08:25:46 2018 +1100
+commit ce178be0d954b210c958bc2b9e998cd6a7aa73a9
+Author: Damien Miller <djm@mindrot.org>
+Date: Thu Aug 27 20:01:52 2020 +1000
- Whitespace sync with upstream.
+ tweak back-compat for older libfido2
-commit fbfa6f980d7460b3e12b0ce88ed3b6018edf4711
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Sun Feb 11 21:25:11 2018 +1300
+commit d6f45cdde031acdf434bbb27235a1055621915f4
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Thu Aug 27 09:46:04 2020 +0000
- Move signal compat code into bsd-signal.{c,h}
+ upstream: debug()-print a little info about FIDO-specific key
+
+ fields via "ssh-keygen -vyf /path/key"
+
+ OpenBSD-Commit-ID: cf315c4fe77db43947d111b00155165cb6b577cf
-commit 24d2a33bd3bf5170700bfdd8675498aa09a79eab
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Sun Feb 11 21:20:39 2018 +1300
+commit b969072cc3d62d05cb41bc6d6f3c22c764ed932f
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Thu Aug 27 09:43:28 2020 +0000
- Include headers for linux/if.h.
+ upstream: skip a bit more FIDO token selection logic when only a
+
+ single token is attached.
- Prevents configure-time "present but cannot be compiled" warning.
+ with Pedro Martelletto
+
+ OpenBSD-Commit-ID: e4a324bd9814227ec1faa8cb619580e661cca9ac
-commit bc02181c24fc551aab85eb2cff0f90380928ef43
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Sun Feb 11 19:45:47 2018 +1300
+commit 744df42a129d7d7db26947b7561be32edac89f88
+Author: jmc@openbsd.org <jmc@openbsd.org>
+Date: Thu Aug 27 06:15:22 2020 +0000
- Fix test for -z,retpolineplt linker flag.
+ upstream: tweak previous;
+
+ OpenBSD-Commit-ID: 92714b6531e244e4da401b2defaa376374e24be7
-commit 3377df00ea3fece5293db85fe63baef33bf5152e
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Sun Feb 11 09:32:37 2018 +1100
+commit e32479645ce649b444ba5c6e7151304306a09654
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Thu Aug 27 03:55:22 2020 +0000
- Add checks for Spectre v2 mitigation (retpoline)
+ upstream: adapt to API changes
- This adds checks for gcc and clang flags for mitigations for Spectre
- variant 2, ie "retpoline". It'll automatically enabled if the compiler
- supports it as part of toolchain hardening flag. ok djm@
+ OpenBSD-Regress-ID: 5f147990cb67094fe554333782ab268a572bb2dd
-commit d9e5cf078ea5380da6df767bb1773802ec557ef0
+commit bbcc858ded3fbc46abfa7760e40389e3ca93884c
+Author: Damien Miller <djm@mindrot.org>
+Date: Thu Aug 27 12:37:12 2020 +1000
+
+ degrade semi-gracefully when libfido2 is too old
+
+commit 9cbbdc12cb6a2ab1e9ffe9974cca91d213c185c2
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sat Feb 10 09:25:34 2018 +0000
+Date: Thu Aug 27 01:15:36 2020 +0000
- upstream commit
+ upstream: dummy firmware needs to match API version numner crank (for
- constify some private key-related functions; based on
- https://github.com/openssh/openssh-portable/pull/56 by Vincent Brillault
+ verify-required resident keys) even though it doesn't implement this feature
- OpenBSD-Commit-ID: dcb94a41834a15f4d00275cb5051616fdc4c988c
+ OpenBSD-Regress-ID: 86579ea2891e18e822e204413d011b2ae0e59657
-commit a7c38215d564bf98e8e9eb40c1079e3adf686f15
+commit c1e76c64956b424ba260fd4eec9970e5b5859039
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sat Feb 10 09:03:54 2018 +0000
+Date: Thu Aug 27 02:11:09 2020 +0000
- upstream commit
-
- Mention ServerAliveTimeout in context of TCPKeepAlives;
- prompted by Christoph Anton Mitterer via github
+ upstream: remove unreachable code I forgot to delete in r1.334
- OpenBSD-Commit-ID: f0cf1b5bd3f1fbf41d71c88d75d93afc1c880ca2
+ OpenBSD-Commit-ID: 9ed6078251a0959ee8deda443b9ae42484fd8b18
-commit 62562ceae61e4f7cf896566592bb840216e71061
+commit 0caff05350bd5fc635674c9e051a0322faba5ae3
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sat Feb 10 06:54:38 2018 +0000
+Date: Thu Aug 27 01:08:45 2020 +0000
- upstream commit
+ upstream: Request PIN ahead of time for certain FIDO actions
+
+ When we know that a particular action will require a PIN, such as
+ downloading resident keys or generating a verify-required key, request
+ the PIN before attempting it.
- clarify IgnoreUserKnownHosts; based on github PR from
- Christoph Anton Mitterer.
+ joint work with Pedro Martelletto; ok markus@
- OpenBSD-Commit-ID: 4fff2c17620c342fb2f1f9c2d2e679aab3e589c3
+ OpenBSD-Commit-ID: 863182d38ef075bad1f7d20ca485752a05edb727
-commit 4f011daa4cada6450fa810f7563b8968639bb562
+commit b649b3daa6d4b8ebe1bd6de69b3db5d2c03c9af0
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sat Feb 10 06:40:28 2018 +0000
+Date: Thu Aug 27 01:08:19 2020 +0000
- upstream commit
+ upstream: preserve verify-required for resident FIDO keys
+
+ When downloading a resident, verify-required key from a FIDO token,
+ preserve the verify-required in the private key that is written to
+ disk. Previously we weren't doing that because of lack of support
+ in the middleware API.
- Shorter, more accurate explanation of
- NoHostAuthenticationForLocalhost without the confusing example. Prompted by
- Christoph Anton Mitterer via github and bz#2293.
+ from Pedro Martelletto; ok markus@ and myself
- OpenBSD-Commit-ID: 19dc96bea25b80d78d416b581fb8506f1e7b76df
+ OpenBSD-Commit-ID: 201c46ccdd227cddba3d64e1bdbd082afa956517
-commit 77e05394af21d3f5faa0c09ed3855e4505a5cf9f
+commit 642e06d0df983fa2af85126cf4b23440bb2985bf
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sat Feb 10 06:15:12 2018 +0000
+Date: Thu Aug 27 01:07:51 2020 +0000
- upstream commit
+ upstream: major rework of FIDO token selection logic
- Disable RemoteCommand and RequestTTY in the ssh session
- started by scp. sftp is already doing this. From Camden Narzt via github; ok
- dtucker
+ When PINs are in use and multiple FIDO tokens are attached to a host, we
+ cannot just blast requests at all attached tokens with the PIN specified
+ as this will cause the per-token PIN failure counter to increment. If
+ this retry counter hits the token's limit (usually 3 attempts), then the
+ token will lock itself and render all (web and SSH) of its keys invalid.
+ We don't want this.
+
+ So this reworks the key selection logic for the specific case of
+ multiple keys being attached. When multiple keys are attached and the
+ operation requires a PIN, then the user must touch the key that they
+ wish to use first in order to identify it.
+
+ This may require multiple touches, but only if there are multiple keys
+ attached AND (usually) the operation requires a PIN. The usual case of a
+ single key attached should be unaffected.
+
+ Work by Pedro Martelletto; ok myself and markus@
- OpenBSD-Commit-ID: 59e2611141c0b2ee579c6866e8eb9d7d8217bc6b
+ OpenBSD-Commit-ID: 637d3049ced61b7a9ee796914bbc4843d999a864
-commit ca613249a00b64b2eea9f52d3834b55c28cf2862
+commit 801c9f095e6d8b7b91aefd98f5001c652ea13488
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sat Feb 10 05:48:46 2018 +0000
+Date: Thu Aug 27 01:07:09 2020 +0000
- upstream commit
+ upstream: support for requiring user verified FIDO keys in sshd
+
+ This adds a "verify-required" authorized_keys flag and a corresponding
+ sshd_config option that tells sshd to require that FIDO keys verify the
+ user identity before completing the signing/authentication attempt.
+ Whether or not user verification was performed is already baked into the
+ signature made on the FIDO token, so this is just plumbing that flag
+ through and adding ways to require it.
- Refuse to create a certificate with an unusable number of
- principals; Prompted by gdestuynder via github
+ feedback and ok markus@
- OpenBSD-Commit-ID: 8cfae2451e8f07810e3e2546dfdcce66984cbd29
+ OpenBSD-Commit-ID: 3a2313aae153e043d57763d766bb6d55c4e276e6
-commit b56ac069d46b6f800de34e1e935f98d050731d14
+commit 9b8ad93824c682ce841f53f3b5762cef4e7cc4dc
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sat Feb 10 05:43:26 2018 +0000
+Date: Thu Aug 27 01:06:18 2020 +0000
- upstream commit
+ upstream: support for user-verified FIDO keys
- fatal if we're unable to write all the public key; previously
- we would silently ignore errors writing the comment and terminating newline.
- Prompted by github PR from WillerZ; ok dtucker
+ FIDO2 supports a notion of "user verification" where the user is
+ required to demonstrate their identity to the token before particular
+ operations (e.g. signing). Typically this is done by authenticating
+ themselves using a PIN that has been set on the token.
- OpenBSD-Commit-ID: 18fbfcfd4e8c6adbc84820039b64d70906e49831
+ This adds support for generating and using user verified keys where
+ the verification happens via PIN (other options might be added in the
+ future, but none are in common use now). Practically, this adds
+ another key generation option "verify-required" that yields a key that
+ requires a PIN before each authentication.
+
+ feedback markus@ and Pedro Martelletto; ok markus@
+
+ OpenBSD-Commit-ID: 57fd461e4366f87c47502c5614ec08573e6d6a15
-commit cdb10bd431f9f6833475c27e9a82ebb36fdb12db
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Sat Feb 10 11:18:38 2018 +1100
+commit 1196d7f49d4fbc90f37e550de3056561613b0960
+Author: cheloha@openbsd.org <cheloha@openbsd.org>
+Date: Wed Aug 12 01:23:45 2020 +0000
- Add changelog entry for binary strip change.
+ upstream: ssh-keyscan(1): simplify conloop() with timercmp(3),
+
+ timersub(3); ok djm@
+
+ OpenBSD-Commit-ID: a102acb544f840d33ad73d40088adab4a687fa27
-commit fbddd91897cfaf456bfc2081f39fb4a2208a0ebf
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Sat Feb 10 11:14:54 2018 +1100
+commit d0a195c89e26766d3eb8f3e4e2a00ebc98b57795
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Tue Aug 11 09:49:57 2020 +0000
- Remove unused variables.
+ upstream: let ssh_config(5)'s AddKeysToAgent keyword accept a time
+
+ limit for keys in addition to its current flag options. Time-limited keys
+ will automatically be removed from ssh-agent after their expiry time has
+ passed; ok markus@
+
+ OpenBSD-Commit-ID: 792e71cacbbc25faab5424cf80bee4a006119f94
-commit 937d96587df99c16c611d828cded292fa474a32b
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Sat Feb 10 11:12:45 2018 +1100
+commit e9c2002891a7b8e66f4140557a982978f372e5a3
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Tue Aug 11 09:45:54 2020 +0000
- Don't strip binaries so debuginfo gets built.
+ upstream: let the "Confirm user presence for key ..." ssh-askpass
+
+ notification respect $SSH_ASKPASS_REQUIRE; ok markus@
- Tell install not to strip binaries during package creation so that the
- debuginfo package can be built.
+ OpenBSD-Commit-ID: 7c1a616b348779bda3b9ad46bf592741f8e206c1
-commit eb0865f330f59c889ec92696b97bd397090e720c
+commit eaf8672b1b52db2815a229745f4e4b08681bed6d
Author: Darren Tucker <dtucker@dtucker.net>
-Date: Sat Feb 10 10:33:11 2018 +1100
+Date: Fri Aug 21 00:04:13 2020 +1000
- Fix bogus dates in changelog.
+ Remove check for 'ent' command.
+
+ It was added in 8d1fd57a9 for measuring entropy of ssh_prng_cmds which
+ has long since been removed and there are no other references to it.
-commit 7fbde1b34c1f6c9ca9e9d10805ba1e5e4538e165
+commit 05c215de8d224e094a872d97d45f37f60c06206b
Author: Darren Tucker <dtucker@dtucker.net>
-Date: Sat Feb 10 10:25:15 2018 +1100
+Date: Mon Aug 17 21:34:32 2020 +1000
- Remove SSH1 from description.
+ Wrap stdint.h include in ifdef HAVE_STDINT_H.
-commit 9c34a76f099c4e0634bf6ecc2f40ce93925402c4
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Sat Feb 10 10:19:16 2018 +1100
+commit eaf2765efe8bc74feba85c34295d067637fc6635
+Author: Damien Miller <djm@mindrot.org>
+Date: Mon Aug 10 13:24:09 2020 +1000
- Add support for compat-openssl10 build dep.
+ sync memmem.c with OpenBSD
-commit 04f4e8193cb5a5a751fcc356bd6656291fec539e
+commit ed6bef77f5bb5b8f9ca2914478949e29f2f0a780
Author: Darren Tucker <dtucker@dtucker.net>
-Date: Sat Feb 10 09:57:04 2018 +1100
+Date: Fri Aug 7 17:12:16 2020 +1000
- Add leading zero so it'll work when rhel not set.
+ Always send any PAM account messages.
- When rhel is not set it will error out with "bad if". Add leading zero
- as per https://fedoraproject.org/wiki/Packaging:DistTag so it'll work
- on non-RHEL.
+ If the PAM account stack reaturns any messages, send them to the user
+ not just if the check succeeds. bz#2049, ok djm@
-commit 12abd67a6af28476550807a443b38def2076bb92
+commit a09e98dcae1e26f026029b7142b0e0d10130056f
Author: Darren Tucker <dtucker@dtucker.net>
-Date: Sat Feb 10 09:56:34 2018 +1100
+Date: Fri Aug 7 15:37:37 2020 +1000
- Update openssl-devel dependency.
+ Output test debug logs on failure.
-commit b33e7645f8813719d7f9173fef24463c8833ebb3
-Author: nkadel <nkadel@gmail.com>
-Date: Sun Nov 16 18:19:58 2014 -0500
+commit eb122b1eebe58b29a83a507ee814cbcf8aeded1b
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Fri Aug 7 15:11:42 2020 +1000
- Add mandir with-mandir' for RHEL 5 compatibility.
-
- Activate '--mandir' and '--with-mandir' settings in setup for RHEL
- 5 compatibility.
+ Add ability to specify exact test target.
-commit 94f8bf360eb0162e39ddf39d69925c2e93511e40
-Author: nkadel <nkadel@gmail.com>
-Date: Sun Nov 16 18:18:51 2014 -0500
+commit c2ec7a07f8caabb4d8e00c66e7cd46bf2cd1e922
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Fri Aug 7 14:21:15 2020 +1000
- Discard 'K5DIR' reporting.
-
- It does not work inside 'mock' build environment.
+ Document --without-openssl and --without-zlib.
-commit bb7e54dbaf34b70b3e57acf7982f3a2136c94ee5
-Author: nkadel <nkadel@gmail.com>
-Date: Sun Nov 16 18:17:15 2014 -0500
+commit 651bb3a31949bbdc3a78b2ede95a77bce0c72984
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Fri Aug 7 14:15:11 2020 +1000
- Add 'dist' to 'rel' for OS specific RPM names.
+ Add without-openssl without-zlib test target.
-commit 87346f1f57f71150a9b8c7029d8c210e27027716
-Author: nkadel <nkadel@gmail.com>
-Date: Sun Nov 16 14:17:38 2014 -0500
+commit 9499f2bb01dc1032ae155999b2d7764b9491341f
+Author: Stefan Schindler <dns2utf8@estada.ch>
+Date: Wed Aug 5 19:00:52 2020 +0200
- Add openssh-devel >= 0.9.8f for redhat spec file.
+ Add CI with prepare script
+
+ * Only use heimdal kerberos implementation
+ * Fetch yubico/libfido2 (see: https://github.com/Yubico/libfido2)
+ * Add one target for
+ * all features
+ * each feature alone
+ * no features
-commit bec1478d710866d3c1b119343a35567a8fc71ec3
-Author: nkadel <nkadel@gmail.com>
-Date: Sun Nov 16 13:10:24 2014 -0500
+commit ea1f649046546a860f68b97ddc3015b7e44346ca
+Author: Damien Miller <djm@mindrot.org>
+Date: Wed Aug 5 08:58:57 2020 +1000
- Enhance BuildRequires for openssh-x11-askpass.
+ support NetBSD's utmpx.ut_ss address field
+
+ bz#960, ok dtucker
-commit 3104fcbdd3c70aefcb0cdc3ee24948907db8dc8f
-Author: nkadel <nkadel@gmail.com>
-Date: Sun Nov 16 13:04:14 2014 -0500
+commit 32c63e75a70a0ed9d6887a55fcb0e4531a6ad617
+Author: Damien Miller <djm@mindrot.org>
+Date: Tue Aug 4 14:59:21 2020 +1000
- Always include x11-ssh-askpass SRPM.
+ wrap a declaration in the same ifdefs as its use
- Always include x11-ssh-askpass tarball in redhat SRPM, even if unused.
+ avoids warnings on NetBSD
-commit c61d0d038d58eebc365f31830be6e04ce373ad1b
+commit c9e3be9f4b41fda32a2a0138d54c7a6b563bc94d
Author: Damien Miller <djm@mindrot.org>
-Date: Sat Feb 10 09:43:12 2018 +1100
+Date: Tue Aug 4 14:58:46 2020 +1000
+
+ undef TAILQ_CONCAT and friends
+
+ Needed for NetBSD. etc that supply these macros
- this is long unused; prompted by dtucker@
+commit 2d8a3b7e8b0408dfeb933ac5cfd3a58f5bac49af
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Mon Aug 3 02:53:51 2020 +0000
-commit 745771fb788e41bb7cdad34e5555bf82da3af7ed
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Fri Feb 9 02:37:36 2018 +0000
+ upstream: ensure that certificate extensions are lexically sorted.
+
+ Previously if the user specified a custom extension then the everything would
+ be in order except the custom ones. bz3198 ok dtucker markus
+
+ OpenBSD-Commit-ID: d97deb90587b06cb227c66ffebb2d9667bf886f0
- upstream commit
+commit a8732d74cb8e72f0c6366015687f1e649f60be87
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Mon Aug 3 02:43:41 2020 +0000
+
+ upstream: allow -A to explicitly enable agent forwarding in scp and
- Remove unused sKerberosTgtPassing from enum. From
- calestyo via github pull req #11, ok djm@
+ sftp. The default remains to not forward an agent, even when ssh_config
+ enables it. ok jmc dtucker markus
- OpenBSD-Commit-ID: 1008f8870865a7c4968b7aed402a0a9e3e5b9540
+ OpenBSD-Commit-ID: 36cc526aa3b0f94e4704b8d7b969dd63e8576822
-commit 1f385f55332db830b0ae22a7663b98279ca2d657
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Thu Feb 8 04:12:32 2018 +0000
+commit ab9105470a83ed5d8197959a1b1f367399958ba1
+Author: deraadt@openbsd.org <deraadt@openbsd.org>
+Date: Mon Aug 3 02:42:49 2020 +0000
- upstream commit
+ upstream: clang -Wimplicit-fallthrough does not recognise /*
- Rename struct umac_ctx to umac128_ctx too. In portable
- some linkers complain about two symbols with the same name having differing
- sizes. ok djm@
+ FALLTHROUGH */ comments, which is the style we currently use, and gives too
+ many boring warnings. ok djm
- OpenBSD-Commit-ID: cbebf8bdd3310a9795b4939a1e112cfe24061ca3
+ OpenBSD-Commit-ID: 07b5031e9f49f2b69ac5e85b8da4fc9e393992a0
-commit f1f047fb031c0081dbc8738f05bf5d4cc47acadf
+commit ced327b9fb78c94d143879ef4b2a02cbc5d38690
Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Wed Feb 7 22:52:45 2018 +0000
+Date: Fri Jul 31 04:19:37 2020 +0000
- upstream commit
+ upstream: Also compare username when checking for JumpHost loops.
- ssh_free checks for and handles NULL args, remove NULL
- checks from remaining callers. ok djm@
+ bz#3057, ok djm@
- OpenBSD-Commit-ID: bb926825c53724c069df68a93a2597f9192f7e7b
+ OpenBSD-Commit-ID: 9bbc1d138adb34c54f3c03a15a91f75dbf418782
-commit aee49b2a89b6b323c80dd3b431bd486e51f94c8c
+commit ae7527010c44b3376b85d036a498f136597b2099
Author: Darren Tucker <dtucker@dtucker.net>
-Date: Thu Feb 8 12:36:22 2018 +1100
+Date: Fri Jul 31 15:19:04 2020 +1000
- Set SO_REUSEADDR in regression test netcat.
+ Remove AC_REVISION.
- Sometimes multiplex tests fail on Solaris with "netcat: local_listen:
- Address already in use" which is likely due to previous invocations
- leaving the port in TIME_WAIT. Set SO_REUSEADDR (in addition to
- SO_REUSEPORT which is alread set on platforms that support it). ok djm@
+ It hasn't been useful since we switched to git in 2014. ok djm@
-commit 1749991c55bab716877b7c687cbfbf19189ac6f1
-Author: jsing@openbsd.org <jsing@openbsd.org>
-Date: Wed Feb 7 05:17:56 2018 +0000
+commit 89fc3f414be0ce4e8008332a9739a7d721269e50
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Tue Jul 28 19:40:30 2020 +1000
- upstream commit
-
- Convert some explicit_bzero()/free() calls to freezero().
+ Use argv in OSSH_CHECK_CFLAG_COMPILE test.
- ok deraadt@ dtucker@
-
- OpenBSD-Commit-ID: f566ab99149650ebe58b1d4b946ea726c3829609
+ configure.ac is not detecting -Wextra in compilers that implement the
+ option. The problem is that -Wextra implies -Wunused-parameter, and the
+ C excerpt used by aclocal.m4 does not use argv. Patch from pedro at
+ ambientworks.net, ok djm@
-commit 94ec2b69d403f4318b7a0d9b17f8bc3efbf4d0d2
-Author: jsing@openbsd.org <jsing@openbsd.org>
-Date: Wed Feb 7 05:15:49 2018 +0000
+commit 62c81ef531b0cc7ff655455dd34f5f0c94f48e82
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Mon Jul 20 22:12:07 2020 +1000
- upstream commit
-
- Remove some #ifdef notyet code from OpenSSL 0.9.8 days.
+ Skip ECDSA-SK webauthn test when built w/out ECC
+
+commit 3ec9a6d7317236a9994887d8bd5d246af403a00d
+Author: Damien Miller <djm@mindrot.org>
+Date: Mon Jul 20 13:09:25 2020 +1000
+
+ Add ssh-sk-helper and manpage to RPM spec file
- These functions have never appeared in OpenSSL and are likely never to do
- so.
+ Based on patch from Fabio Pedretti
+
+commit a2855c048b3f4b17d8787bd3f24232ec0cd79abe
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Fri Jul 17 07:09:24 2020 +0000
+
+ upstream: Add %k to the TOKENs for Match Exec for consistency with
- "kill it with fire" djm@
+ the other keywords that recently got %k.
- OpenBSD-Commit-ID: fee9560e283fd836efc2631ef381658cc673d23e
+ OpenBSD-Commit-ID: 1857d1c40f270cbc254fca91e66110641dddcfdb
-commit 7cd31632e3a6607170ed0c9ed413a7ded5b9b377
-Author: jsing@openbsd.org <jsing@openbsd.org>
-Date: Wed Feb 7 02:06:50 2018 +0000
+commit 69860769fa9f4529d8612ec055ae11912f7344cf
+Author: jmc@openbsd.org <jmc@openbsd.org>
+Date: Fri Jul 17 05:59:05 2020 +0000
- upstream commit
+ upstream: fix macro slip in previous;
- Remove all guards for calls to OpenSSL free functions -
- all of these functions handle NULL, from at least OpenSSL 1.0.1g onwards.
+ OpenBSD-Commit-ID: 624e47ab209450ad9ad5c69f54fa69244de5ed9a
+
+commit 40649bd0822883b684183854b16d0b8461d5697b
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Fri Jul 17 07:10:24 2020 +0000
+
+ upstream: Add test for '%k' (HostKeyAlias) TOKEN.
- Prompted by dtucker@ asking about guards for RSA_free(), when looking at
- openssh-portable pr#84 on github.
+ OpenBSD-Regress-ID: 8ed1ba1a811790031aad3fcea860a34ad7910456
+
+commit 6736fe680704a3518cb4f3f8f6723b00433bd3dd
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Fri Jul 17 03:26:58 2020 +0000
+
+ upstream: Add tests for expansions on UserKnownHostsFile.
- ok deraadt@ dtucker@
+ OpenBSD-Regress-ID: bccf8060306c841bbcceb1392644f906a4d6ca51
+
+commit 287dc6396e0f9cb2393f901816dbd7f2a7dfbb5f
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Fri Jul 17 03:51:32 2020 +0000
+
+ upstream: log error message for process_write() write failures
- OpenBSD-Commit-ID: 954f1c51b94297d0ae1f749271e184141e0cadae
+ OpenBSD-Commit-ID: f733d7b3b05e3c68967dc18dfe39b9e8fad29851
-commit 3c000d57d46882eb736c6563edfc4995915c24a2
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Wed Feb 7 09:19:38 2018 +1100
+commit 8df5774a42d2eaffe057bd7f293fc6a4b1aa411c
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Fri Jul 17 03:43:42 2020 +0000
- Remove obsolete "Smartcard support" message
+ upstream: Add a '%k' TOKEN that expands to the effective HostKey of
+
+ the destination. This allows, eg, keeping host keys in individual files
+ using "UserKnownHostsFile ~/.ssh/known_hosts.d/%k". bz#1654, ok djm@, jmc@
+ (man page bits)
- The configure checks that populated $SCARD_MSG were removed in commits
- 7ea845e4 and d8f60022 when the smartcard support was replaced with
- PKCS#11.
+ OpenBSD-Commit-ID: 7084d723c9cc987a5c47194219efd099af5beadc
-commit 3e615090de0ce36a833d811e01c28aec531247c4
+commit c4f239944a4351810fd317edf408bdcd5c0102d9
Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Tue Feb 6 06:01:54 2018 +0000
+Date: Fri Jul 17 03:23:10 2020 +0000
- upstream commit
+ upstream: Add %-TOKEN, environment variable and tilde expansion to
- Replace "trojan horse" with the correct term (MITM).
- From maikel at predikkta.com via bz#2822, ok markus@
+ UserKnownHostsFile, allowing the file to be automagically split up in the
+ configuration (eg bz#1654). ok djm@, man page parts jmc@
- OpenBSD-Commit-ID: e86ac64c512057c89edfadb43302ac0aa81a6c53
+ OpenBSD-Commit-ID: 7e1b406caf147638bb51558836a72d6cc0bd1b18
-commit 3484380110d437c50e17f87d18544286328c75cb
-Author: tb@openbsd.org <tb@openbsd.org>
-Date: Mon Feb 5 05:37:46 2018 +0000
+commit dbaaa01daedb423c38124a72c471982fb08a16fb
+Author: solene@openbsd.org <solene@openbsd.org>
+Date: Wed Jul 15 07:50:46 2020 +0000
- upstream commit
+ upstream: - Add [-a rounds] in ssh-keygen man page and usage() -
- Add a couple of non-negativity checks to avoid close(-1).
+ Reorder parameters list in the first usage() case - Sentence rewording
- ok djm
+ ok dtucker@
+ jmc@ noticed usage() missed -a flag too
- OpenBSD-Commit-ID: 4701ce0b37161c891c838d0931305f1d37a50880
+ OpenBSD-Commit-ID: f06b9afe91cc96f260b929a56e9930caecbde246
-commit 5069320be93c8b2a6584b9f944c86f60c2b04e48
-Author: tb@openbsd.org <tb@openbsd.org>
-Date: Mon Feb 5 05:36:49 2018 +0000
+commit 69924a92c3af7b99a7541aa544a2334ec0fb092c
+Author: jmc@openbsd.org <jmc@openbsd.org>
+Date: Wed Jul 15 05:40:05 2020 +0000
- upstream commit
+ upstream: start sentence with capital letter;
- The file descriptors for socket, stdin, stdout and stderr
- aren't necessarily distinct, so check if they are the same to avoid closing
- the same fd several times.
+ OpenBSD-Commit-ID: ab06581d51b2b4cc1b4aab781f7f3cfa56cad973
+
+commit 5b56bd0affea7b02b540bdbc4d1d271b0e4fc885
+Author: Damien Miller <djm@mindrot.org>
+Date: Fri Jul 17 13:15:50 2020 +1000
+
+ detect Linux/X32 systems
- ok djm
+ This is a frankenstein monster of AMD64 instructions/calling conventions
+ but with a 4GB address space. Allegedly deprecated but people still run
+ into it causing weird sandbox failures, e.g. bz#3085
+
+commit 9c9ddc1391d6af8d09580a2424ab467d0a5df3c7
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Wed Jul 15 06:43:16 2020 +0000
+
+ upstream: Fix previous by calling the correct function.
- OpenBSD-Commit-ID: 60d71fd22e9a32f5639d4ba6e25a2f417fc36ac1
+ OpenBSD-Regress-ID: 821cdd1dff9c502cceff4518b6afcb81767cad5a
-commit 2b428f90ea1b21d7a7c68ec1ee334253b3f9324d
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Mon Feb 5 04:02:53 2018 +0000
+commit f1a4798941b4372bfe5e46f1c0f8672fe692d9e4
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Wed Jul 15 05:36:50 2020 +0000
- upstream commit
+ upstream: Update test to match recent change in match.c
- I accidentially a word
+ OpenBSD-Regress-ID: 965bda1f95f09a765050707340c73ad755f41167
+
+commit d7e71be4fd57b7c7e620d733cdf2333b27bfa924
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Wed Jul 15 15:30:43 2020 +1000
+
+ Adjust portable code to match changes in 939d787d,
+
+commit fec89f32a84fd0aa1afc81deec80a460cbaf451a
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Wed Jul 15 04:27:34 2020 +0000
+
+ upstream: Add default for number of rounds (-a). ok djm@
- OpenBSD-Commit-ID: 4547ee713fa941da861e83ae7a3e6432f915e14a
+ OpenBSD-Commit-ID: cb7e9aa04ace01a98e63e4bd77f34a42ab169b15
-commit 130283d5c2545ff017c2162dc1258c5354e29399
+commit aaa8b609a7b332be836cd9a3b782422254972777
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Thu Jan 25 03:34:43 2018 +0000
+Date: Tue Jul 14 23:57:01 2020 +0000
- upstream commit
+ upstream: allow some additional control over the use of ssh-askpass
- certificate options are case-sensitive; fix case on one
- that had it wrong.
+ via $SSH_ASKPASS_REQUIRE, including force-enable/disable. bz#69 ok markus@
- move a badly-place sentence to a less bad place
+ OpenBSD-Commit-ID: 3a1e6cbbf6241ddc4405c4246caa2c249f149eb2
+
+commit 6368022cd4dd508671c4999a59ec5826df098530
+Author: deraadt@openbsd.org <deraadt@openbsd.org>
+Date: Tue Jul 7 02:47:21 2020 +0000
+
+ upstream: correct recently broken comments
- OpenBSD-Commit-ID: 231e516bba860699a1eece6d48532d825f5f747b
+ OpenBSD-Commit-ID: 964d9a88f7de1d0eedd3f8070b43fb6e426351f1
-commit 89f09ee68730337015bf0c3f138504494a34e9a6
-Author: Damien Miller <djm@mindrot.org>
-Date: Wed Jan 24 12:20:44 2018 +1100
+commit 6d755706a0059eb9e2d63517f288b75cbc3b4701
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Sun Jul 5 23:59:45 2020 +0000
- crypto_api.h needs includes.h
+ upstream: some language improvements; ok markus
+
+ OpenBSD-Commit-ID: 939d787d571b4d5da50b3b721fd0b2ac236acaa8
-commit c9c1bba06ad1c7cad8548549a68c071bd807af60
-Author: stsp@openbsd.org <stsp@openbsd.org>
-Date: Tue Jan 23 20:00:58 2018 +0000
+commit b0c1e8384d5e136ebdf895d1434aea7dd8661a1c
+Author: markus@openbsd.org <markus@openbsd.org>
+Date: Fri Jul 3 10:12:26 2020 +0000
- upstream commit
+ upstream: update setproctitle after re-exec; ok djm
- Fix a logic bug in sshd_exchange_identification which
- prevented clients using major protocol version 2 from connecting to the
- server. ok millert@
+ OpenBSD-Commit-ID: bc92d122f9184ec2a9471ade754b80edd034ce8b
+
+commit cd119a5ec2bf0ed5df4daff3bd14f8f7566dafd3
+Author: markus@openbsd.org <markus@openbsd.org>
+Date: Fri Jul 3 10:11:33 2020 +0000
+
+ upstream: keep ignoring HUP after fork+exec; ok djm
- OpenBSD-Commit-ID: 8668dec04586e27f1c0eb039ef1feb93d80a5ee9
+ OpenBSD-Commit-ID: 7679985a84ee5ceb09839905bb6f3ddd568749a2
-commit a60c5dcfa2538ffc94dc5b5adb3db5b6ed905bdb
-Author: stsp@openbsd.org <stsp@openbsd.org>
-Date: Tue Jan 23 18:33:49 2018 +0000
+commit 8af4a743693ccbea3e15fc9e93edbeb610fa94f4
+Author: markus@openbsd.org <markus@openbsd.org>
+Date: Fri Jul 3 10:10:17 2020 +0000
- upstream commit
+ upstream: don't exit the listener on send_rexec_state errors; ok
- Add missing braces; fixes 'write: Socket is not
- connected' error in ssh. ok deraadt@
+ djm
- OpenBSD-Commit-ID: db73a3a9e147722d410866cac34d43ed52e1ad24
+ OpenBSD-Commit-ID: 57cbd757d130d3f45b7d41310b3a15eeec137d5c
-commit 20d53ac283e1c60245ea464bdedd015ed9b38f4a
-Author: Damien Miller <djm@mindrot.org>
-Date: Tue Jan 23 16:49:43 2018 +1100
+commit 03da4c2b70468f04ed1c08518ea0a70e67232739
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Wed Jul 15 04:55:47 2020 +0000
- rebuild depends
+ upstream: Use $OBJ to find key files. Fixes test when run on an obj
+
+ directory (on OpenBSD) or out of tree (in Portable).
+
+ OpenBSD-Regress-ID: 938fa8ac86adaa527d64a305bd2135cfbb1c0a17
-commit 552ea155be44f9c439c1f9f0c38f9e593428f838
-Author: Damien Miller <djm@mindrot.org>
-Date: Tue Jan 23 16:49:22 2018 +1100
+commit 73f20f195ad18f1cf633eb7d8be95dc1b6111eea
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Sat Jul 4 23:11:23 2020 +1000
- one SSH_BUG_BANNER instance that got away
+ Wrap stdint.h in ifdef HAVE_STDINT_H.
-commit 14b5c635d1190633b23ac3372379517fb645b0c2
+commit aa6fa4bf3023fa0e5761cd8f4b2cd015d2de74dd
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Tue Jan 23 05:27:21 2018 +0000
+Date: Fri Jul 3 07:25:18 2020 +0000
- upstream commit
-
- Drop compatibility hacks for some ancient SSH
- implementations, including ssh.com <=2.* and OpenSSH <= 3.*.
+ upstream: put back the mux_ctx memleak fix, but only for channels of
- These versions were all released in or before 2001 and predate the
- final SSH RFCs. The hacks in question aren't necessary for RFC-
- compliant SSH implementations.
+ type SSH_CHANNEL_MUX_LISTENER; Specifically SSH_CHANNEL_MUX_PROXY channels
+ should not have this structure freed.
- ok markus@
-
- OpenBSD-Commit-ID: 4be81c67db57647f907f4e881fb9341448606138
+ OpenBSD-Commit-ID: f3b213ae60405f77439e2b06262f054760c9d325
-commit 7c77991f5de5d8475cbeb7cbb06d0c7d1611d7bb
+commit d8195914eb43b20b13381f4e5a74f9f8a14f0ded
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Tue Jan 23 05:17:04 2018 +0000
+Date: Fri Jul 3 07:17:35 2020 +0000
- upstream commit
+ upstream: revert r1.399 - the lifetime of c->mux_ctx is more complex;
- try harder to preserve errno during
- ssh_connect_direct() to make the final error message possibly accurate;
- bz#2814, ok dtucker@
+ simply freeing it here causes other problems
- OpenBSD-Commit-ID: 57de882cb47381c319b04499fef845dd0c2b46ca
+ OpenBSD-Commit-ID: c6fee8ca94e2485faa783839541962be2834c5ed
-commit 9e9c4a7e57b96ab29fe6d7545ed09d2e5bddbdec
+commit 20b5fab9f773b3d3c7f06cb15b8f69a2c081ee80
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Tue Jan 23 05:12:12 2018 +0000
+Date: Fri Jul 3 07:02:37 2020 +0000
- upstream commit
+ upstream: avoid tilde_expand_filename() in expanding ~/.ssh/rc - if
- unbreak support for clients that advertise a protocol
- version of "1.99" (indicating both v2 and v1 support). Busted by me during
- SSHv1 purge in r1.358; bz2810, ok dtucker
+ sshd is in chroot mode, the likely absence of a password database will cause
+ tilde_expand_filename() to fatal; ok dtucker@
- OpenBSD-Commit-ID: e8f9c2bee11afc16c872bb79d6abe9c555bd0e4b
+ OpenBSD-Commit-ID: e20aee6159e8b79190d18dba1513fc1b7c8b7ee1
-commit fc21ea97968264ad9bb86b13fedaaec8fd3bf97d
+commit c8935081db35d73ee6355999142fa0776a2af912
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Tue Jan 23 05:06:25 2018 +0000
+Date: Fri Jul 3 06:46:41 2020 +0000
- upstream commit
+ upstream: when redirecting sshd's log output to a file, undo this
- don't attempt to force hostnames that are addresses to
- lowercase, but instead canonicalise them through getnameinfo/getaddrinfo to
- remove ambiguities (e.g. ::0001 => ::1) before they are matched against
- known_hosts; bz#2763, ok dtucker@
+ redirection after the session child process is forked(); ok dtucker@
- OpenBSD-Commit-ID: ba0863ff087e61e5c65efdbe53be3cb92c9aefa0
+ OpenBSD-Commit-ID: 6df86dd653c91f5bc8ac1916e7680d9d24690865
-commit d6364f6fb1a3d753d7ca9bf15b2adce961324513
+commit 183c4aaef944af3a1a909ffa01058c65bac55748
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Tue Jan 23 05:01:15 2018 +0000
+Date: Fri Jul 3 06:29:57 2020 +0000
- upstream commit
+ upstream: start ClientAliveInterval bookkeeping before first pass
- avoid modifying pw->pw_passwd; let endpwent() clean up
- for us, but keep a scrubbed copy; bz2777, ok dtucker@
+ through select() loop; fixed theoretical case where busy sshd may ignore
+ timeouts from client; inspired by and ok dtucker
- OpenBSD-Commit-ID: 715afc0f59c6b82c4929a73279199ed241ce0752
+ OpenBSD-Commit-ID: 96bfc4b1f86c7da313882a84755b2b47eb31957f
-commit a69bbb07cd6fb4dfb9bdcacd370ab26d0a2b4215
-Author: naddy@openbsd.org <naddy@openbsd.org>
-Date: Sat Jan 13 00:24:09 2018 +0000
+commit 6fcfd303d67f16695198cf23d109a988e40eefb6
+Author: Damien Miller <djm@mindrot.org>
+Date: Fri Jul 3 15:28:27 2020 +1000
- upstream commit
-
- clarify authorship; prodded by and ok markus@
-
- OpenBSD-Commit-ID: e1938eee58c89b064befdabe232835fa83bb378c
+ add check for fido_cred_set_prot() to configure
-commit 04214b30be3d3e73a01584db4e040d5ccbaaddd4
-Author: markus@openbsd.org <markus@openbsd.org>
-Date: Mon Jan 8 15:37:21 2018 +0000
+commit f11b23346309e4d5138e733a49321aedd6eeaa2f
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Fri Jul 3 05:09:06 2020 +0000
- upstream commit
+ upstream: Only reset the serveralive check when we receive traffic from
- group shared source files (e.g. SRCS_KEX) and allow
- compilation w/o OPENSSL ok djm@
+ the server and ignore traffic from a port forwarding client, preventing a
+ client from keeping a connection alive when it should be terminated. Based
+ on a patch from jxraynor at gmail.com via openssh-unix-dev and bz#2265, ok
+ djm@
- OpenBSD-Commit-ID: fa728823ba21c4b45212750e1d3a4b2086fd1a62
+ OpenBSD-Commit-ID: a941a575a5cbc244c0ef5d7abd0422bbf02c2dcd
-commit 25cf9105b849932fc3b141590c009e704f2eeba6
-Author: markus@openbsd.org <markus@openbsd.org>
-Date: Mon Jan 8 15:21:49 2018 +0000
+commit adfdbf1211914b631c038f0867a447db7b519937
+Author: Damien Miller <djm@mindrot.org>
+Date: Fri Jul 3 15:15:15 2020 +1000
- upstream commit
-
- move subprocess() so scp/sftp do not need uidswap.o; ok
- djm@
+ sync sys-queue.h with OpenBSD upstream
- OpenBSD-Commit-ID: 6601b8360388542c2e5fef0f4085f8e54750bea8
+ needed for TAILQ_CONCAT
-commit b0d34132b3ca26fe94013f01d7b92101e70b68bb
-Author: markus@openbsd.org <markus@openbsd.org>
-Date: Mon Jan 8 15:18:46 2018 +0000
+commit 1b90ddde49e2ff377204082b6eb130a096411dc1
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Fri Jul 3 05:08:41 2020 +0000
- upstream commit
+ upstream: fix memory leak of mux_ctx; patch from Sergiy Lozovsky
- switch ssh-pkcs11-helper to new API; ok djm@
+ via bz3189 ok dtucker
- OpenBSD-Commit-ID: e0c0ed2a568e25b1d2024f3e630f3fea837c2a42
+ OpenBSD-Commit-ID: db249bd4526fd42d0f4f43f72f7b8b7705253bde
-commit ec4a9831184c0c6ed5f7f0cfff01ede5455465a3
+commit 55ef3e9cbd5b336bd0f89205716924886fcf86de
Author: markus@openbsd.org <markus@openbsd.org>
-Date: Mon Jan 8 15:15:36 2018 +0000
+Date: Wed Jul 1 16:28:31 2020 +0000
- upstream commit
-
- split client/server kex; only ssh-keygen needs
- uuencode.o; only scp/sftp use progressmeter.o; ok djm@
+ upstream: free kex in ssh_packet_close; ok djm semarie
- OpenBSD-Commit-ID: f2c9feb26963615c4fece921906cf72e248b61ee
+ OpenBSD-Commit-ID: dbc181e90d3d32fd97b10d75e68e374270e070a2
-commit ec77efeea06ac62ee1d76fe0b3225f3000775a9e
-Author: markus@openbsd.org <markus@openbsd.org>
-Date: Mon Jan 8 15:15:17 2018 +0000
+commit e1c401109b61f7dbc199b5099933d579e7fc5dc9
+Author: bket@openbsd.org <bket@openbsd.org>
+Date: Sat Jun 27 13:39:09 2020 +0000
- upstream commit
+ upstream: Replace TAILQ concatenation loops with TAILQ_CONCAT
- only ssh-keygen needs uuencode.o; only scp/sftp use
- progressmeter.o
+ OK djm@
- OpenBSD-Commit-ID: a337e886a49f96701ccbc4832bed086a68abfa85
+ OpenBSD-Commit-ID: 454b40e09a117ddb833794358970a65b14c431ef
-commit 25aae35d3d6ee86a8c4c0b1896acafc1eab30172
-Author: markus@openbsd.org <markus@openbsd.org>
-Date: Mon Jan 8 15:14:44 2018 +0000
+commit 14beca57ac92d62830c42444c26ba861812dc837
+Author: semarie@openbsd.org <semarie@openbsd.org>
+Date: Fri Jun 26 11:26:01 2020 +0000
- upstream commit
+ upstream: backout 1.293 fix kex mem-leak in ssh_packet_close at markus
- uuencode.h is not used
+ request
- OpenBSD-Commit-ID: 238eb4659f3c119904326b9e94a5e507a912796c
+ the change introduced a NULL deref in sshpkt_vfatal() (uses of ssh->kex after
+ calling ssh_packet_clear_keys())
+
+ OpenBSD-Commit-ID: 9c9a6721411461b0b1c28dc00930d7251a798484
-commit 4f29309c4cb19bcb1774931db84cacc414f17d29
+commit 598c3a5e3885080ced0d7c40fde00f1d5cdbb32b
Author: Damien Miller <djm@mindrot.org>
-Date: Wed Jan 3 19:50:43 2018 +1100
+Date: Fri Jun 26 16:07:12 2020 +1000
- unbreak fuzz harness
+ document a PAM spec problem in a frustrated comment
-commit f6b50bf84dc0b61f22c887c00423e0ea7644e844
+commit 976c4f86286d52a0cb2aadf4a095d379c0da752e
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Thu Dec 21 05:46:35 2017 +0000
+Date: Fri Jun 26 05:42:16 2020 +0000
- upstream commit
+ upstream: avoid spurious error message when ssh-keygen creates files
- another libssh casualty
+ outside ~/.ssh; with dtucker@
- OpenBSD-Regress-ID: 839b970560246de23e7c50215095fb527a5a83ec
+ OpenBSD-Commit-ID: ac0c662d44607e00ec78c266ee60752beb1c7e08
+
+commit 32b2502a9dfdfded1ccdc1fd6dc2b3fe41bfc205
+Author: Damien Miller <djm@mindrot.org>
+Date: Fri Jun 26 15:30:06 2020 +1000
+
+ missing ifdef SELINUX; spotted by dtucker
-commit 5fb4fb5a0158318fb8ed7dbb32f3869bbf221f13
+commit e073106f370cdd2679e41f6f55a37b491f0e82fe
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Thu Dec 21 03:01:49 2017 +0000
+Date: Fri Jun 26 05:12:21 2020 +0000
- upstream commit
+ upstream: regress test for ssh-add -d; ok dtucker@
- missed one (unbreak after ssh/lib removal)
+ OpenBSD-Regress-ID: 3a2e044be616afc7dd4f56c100179e83b33d8abf
+
+commit c809daaa1bad6b1c305b0e0b5440360f32546c84
+Author: markus@openbsd.org <markus@openbsd.org>
+Date: Wed Jun 24 15:16:23 2020 +0000
+
+ upstream: add test for mux w/-Oproxy; ok djm
- OpenBSD-Regress-ID: cfdd132143131769e2d2455e7892b5d55854c322
+ OpenBSD-Regress-ID: 764d5c696e2a259f1316a056e225e50023abb027
-commit e6c4134165d05447009437a96e7201276688807f
+commit 3d06ff4bbd3dca8054c238d2a94c0da563ef7eee
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Thu Dec 21 00:41:22 2017 +0000
+Date: Fri Jun 26 05:16:38 2020 +0000
- upstream commit
+ upstream: handle EINTR in waitfd() and timeout_connect() helpers;
- unbreak unit tests after removal of src/usr.bin/ssh/lib
+ bz#3071; ok dtucker@
- OpenBSD-Regress-ID: 3a79760494147b20761cbd2bd5c20e86c63dc8f9
+ OpenBSD-Commit-ID: 08fa87be50070bd8b754d9b1ebb1138d7bc9d8ee
-commit d45d69f2a937cea215c7f0424e5a4677b6d8c7fe
+commit fe2ec0b9c19adeab0cd9f04b8152dc17f31c31e5
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Thu Dec 21 00:00:28 2017 +0000
+Date: Fri Jun 26 05:04:07 2020 +0000
- upstream commit
+ upstream: allow "ssh-add -d -" to read keys to be deleted from
- revert stricter key type / signature type checking in
- userauth path; too much software generates inconsistent messages, so we need
- a better plan.
+ stdin bz#3180; ok dtucker@
- OpenBSD-Commit-ID: 4a44ddc991c803c4ecc8f1ad40e0ab4d22e1c519
+ OpenBSD-Commit-ID: 15c7f10289511eb19fce7905c9cae8954e3857ff
-commit c5a6cbdb79752f7e761074abdb487953ea6db671
+commit a3e0c376ffc11862fa3568b28188bd12965973e1
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Tue Dec 19 00:49:30 2017 +0000
+Date: Fri Jun 26 05:03:36 2020 +0000
- upstream commit
+ upstream: constify a few things; ok dtucker (as part of another
- explicitly test all key types and their certificate
- counterparts
+ diff)
- refactor a little
+ OpenBSD-Commit-ID: 7c17fc987085994d752304bd20b1ae267a9bcdf6
+
+commit 74344c3ca42c3f53b00b025daf09ae7f6aa38076
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Fri Jun 26 05:02:03 2020 +0000
+
+ upstream: Defer creation of ~/.ssh by ssh(1) until we attempt to
- OpenBSD-Regress-ID: e9ecd5580821b9ef8b7106919c6980d8e45ca8c4
+ write to it so we don't leave an empty .ssh directory when it's not needed.
+ Use the same function to replace the code in ssh-keygen that does the same
+ thing. bz#3156, ok djm@
+
+ OpenBSD-Commit-ID: 59c073b569be1a60f4de36f491a4339bc4ae870f
-commit f689adb7a370b5572612d88be9837ca9aea75447
+commit c9e24daac6324fcbdba171392c325bf9ccc3c768
Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Mon Dec 11 11:41:56 2017 +0000
+Date: Fri Jun 26 04:45:11 2020 +0000
- upstream commit
+ upstream: Expand path to ~/.ssh/rc rather than relying on it
- use cmp in a loop instead of diff -N to compare
- directories. The former works on more platforms for Portable.
+ being relative to the current directory, so that it'll still be found if the
+ shell startup changes its directory. Since the path is potentially longer,
+ make the cmd buffer that uses it dynamically sized. bz#3185, with & ok djm@
- OpenBSD-Regress-ID: c3aa72807f9c488e8829a26ae50fe5bcc5b57099
+ OpenBSD-Commit-ID: 36e33ff01497af3dc8226d0c4c1526fc3a1e46bf
-commit 748dd8e5de332b24c40f4b3bbedb902acb048c98
-Author: Damien Miller <djm@mindrot.org>
-Date: Tue Dec 19 16:17:59 2017 +1100
+commit 07f5f369a25e228a7357ef6c57205f191f073d99
+Author: markus@openbsd.org <markus@openbsd.org>
+Date: Wed Jun 24 15:12:09 2020 +0000
- remove blocks.c from Makefile
+ upstream: fix kex mem-leak in ssh_packet_close; ok djm
+
+ OpenBSD-Commit-ID: e2e9533f393620383afd0b68ef435de8d5e8abe4
-commit 278856320520e851063b06cef6ef1c60d4c5d652
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Tue Dec 19 00:24:34 2017 +0000
+commit e35995088cd6691a712bfd586bae8084a3a922ba
+Author: markus@openbsd.org <markus@openbsd.org>
+Date: Wed Jun 24 15:10:38 2020 +0000
- upstream commit
+ upstream: fix ssh -O proxy w/mux which got broken by no longer
- include signature type and CA key (if applicable) in some
- debug messages
+ making ssh->kex optional in packet.c revision 1.278 ok djm@
- OpenBSD-Commit-ID: b71615cc20e78cec7105bb6e940c03ce9ae414a5
+ OpenBSD-Commit-ID: 2b65df04a064c2c6277359921d2320c90ab7d917
-commit 7860731ef190b52119fa480f8064ab03c44a120a
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Mon Dec 18 23:16:23 2017 +0000
+commit 250246fef22b87a54a63211c60a2def9be431fbd
+Author: markus@openbsd.org <markus@openbsd.org>
+Date: Wed Jun 24 15:09:53 2020 +0000
- upstream commit
+ upstream: support loading big sshd_config files w/o realloc; ok
- unbreak hostkey rotation; attempting to sign with a
- desired signature algorithm of kex->hostkey_alg is incorrect when the key
- type isn't capable of making those signatures. ok markus@
+ djm
- OpenBSD-Commit-ID: 35ae46864e1f5859831ec0d115ee5ea50953a906
+ OpenBSD-Commit-ID: ba9238e810074ac907f0cf8cee1737ac04983171
-commit 966ef478339ad5e631fb684d2a8effe846ce3fd4
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Mon Dec 18 23:14:34 2017 +0000
+commit 89b54900ac61986760452f132bbe3fb7249cfdac
+Author: markus@openbsd.org <markus@openbsd.org>
+Date: Wed Jun 24 15:08:53 2020 +0000
- upstream commit
+ upstream: allow sshd_config longer than 256k; ok djm
- log mismatched RSA signature types; ok markus@
+ OpenBSD-Commit-ID: 83f40dd5457a64c1d3928eb4364461b22766beb3
+
+commit e3fa6249e6d9ceb57c14b04dd4c0cfab12fa7cd5
+Author: markus@openbsd.org <markus@openbsd.org>
+Date: Wed Jun 24 15:07:33 2020 +0000
+
+ upstream: only call sshkey_xmss_init() once for KEY_XMSS_CERT; ok
- OpenBSD-Commit-ID: 381bddfcc1e297a42292222f3bcb5ac2b7ea2418
+ djm
+
+ OpenBSD-Commit-ID: d0002ffb7f20f538b014d1d0735facd5a81ff096
-commit 349ecd4da3a985359694a74635748009be6baca6
+commit 37f2da069c0619f2947fb92785051d82882876d7
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Mon Dec 18 23:13:42 2017 +0000
+Date: Mon Jun 22 23:44:27 2020 +0000
- upstream commit
+ upstream: some clarifying comments
+
+ OpenBSD-Commit-ID: 5268479000fd97bfa30ab819f3517139daa054a2
+
+commit b659319a5bc9e8adf3c4facc51f37b670d2a7426
+Author: jmc@openbsd.org <jmc@openbsd.org>
+Date: Mon Jun 22 06:37:38 2020 +0000
+
+ upstream: updated argument name for -P in first synopsis was
- pass kex->hostkey_alg and kex->hostkey_nid from pre-auth
- to post-auth unpriviledged child processes; ok markus@
+ missed in previous;
- OpenBSD-Commit-ID: 4a35bc7af0a5f8a232d1361f79f4ebc376137302
+ OpenBSD-Commit-ID: 8d84dc3050469884ea91e29ee06a371713f2d0b7
-commit c9e37a8725c083441dd34a8a53768aa45c3c53fe
-Author: millert@openbsd.org <millert@openbsd.org>
-Date: Mon Dec 18 17:28:54 2017 +0000
+commit 02a9222cbce7131d639984c2f6c71d1551fc3333
+Author: jmc@openbsd.org <jmc@openbsd.org>
+Date: Mon Jun 22 06:36:40 2020 +0000
- upstream commit
+ upstream: supply word missing in previous;
+
+ OpenBSD-Commit-ID: 16a38b049f216108f66c8b699aa046063381bd23
+
+commit 5098b3b6230852a80ac6cef5d53a785c789a5a56
+Author: Damien Miller <djm@mindrot.org>
+Date: Mon Jun 22 16:54:02 2020 +1000
+
+ missing files for webauthn/sshsig unit test
+
+commit 354535ff79380237924ac8fdc98f8cdf83e67da6
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Mon Jun 22 06:00:06 2020 +0000
+
+ upstream: add support for verification of webauthn sshsig signature,
- Add helper function for uri handing in scp where a
- missing path simply means ".". Also fix exit code and add warnings when an
- invalid uri is encountered. OK otto@
+ and example HTML/JS to generate webauthn signatures in SSH formats (also used
+ to generate the testdata/* for the test).
- OpenBSD-Commit-ID: 47dcf872380586dabf7fcc6e7baf5f8ad508ae1a
+ OpenBSD-Regress-ID: dc575be5bb1796fdf4b8aaee0ef52a6671a0f6fb
-commit 04c7e28f83062dc42f2380d1bb3a6bf0190852c0
+commit bb52e70fa5330070ec9a23069c311d9e277bbd6f
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Mon Dec 18 02:25:15 2017 +0000
+Date: Mon Jun 22 05:58:35 2020 +0000
- upstream commit
+ upstream: Add support for FIDO webauthn (verification only).
- pass negotiated signing algorithm though to
- sshkey_verify() and check that the negotiated algorithm matches the type in
- the signature (only matters for RSA SHA1/SHA2 sigs). ok markus@
+ webauthn is a standard for using FIDO keys in web browsers. webauthn
+ signatures are a slightly different format to plain FIDO signatures - this
+ support allows verification of these. Feedback and ok markus@
- OpenBSD-Commit-ID: 735fb15bf4adc060d3bee9d047a4bcaaa81b1af9
+ OpenBSD-Commit-ID: ab7e3a9fb5782d99d574f408614d833379e564ad
-commit 931c78dfd7fe30669681a59e536bbe66535f3ee9
+commit 64bc121097f377142f1387ffb2df7592c49935af
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Mon Dec 18 02:22:29 2017 +0000
+Date: Mon Jun 22 05:56:23 2020 +0000
- upstream commit
+ upstream: refactor ECDSA-SK verification a little ahead of adding
- sshkey_sigtype() function to return the type of a
- signature; ok markus@
+ support for FIDO webauthn signature verification support; ok markus@
- OpenBSD-Commit-ID: d3772b065ad6eed97285589bfb544befed9032e8
+ OpenBSD-Commit-ID: c9f478fd8e0c1bd17e511ce8694f010d8e32043e
-commit 4cdc5956f2fcc9e9078938db833142dc07d8f523
-Author: naddy@openbsd.org <naddy@openbsd.org>
-Date: Thu Dec 14 21:07:39 2017 +0000
+commit 12848191f8fe725af4485d3600e0842d92f8637f
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Mon Jun 22 05:54:10 2020 +0000
- upstream commit
+ upstream: support for RFC4648 base64url encoding; ok markus
- Replace ED25519's private SHA-512 implementation with a
- call to the regular digest code. This speeds up compilation considerably. ok
- markus@
+ OpenBSD-Commit-ID: 0ef22c55e772dda05c112c88412c0797fec66eb4
+
+commit 473b4af43db12127137c7fc1a10928313f5a16d2
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Mon Jun 22 05:53:26 2020 +0000
+
+ upstream: better terminology for permissions; feedback & ok markus@
- OpenBSD-Commit-ID: fcce8c3bcfe7389462a28228f63c823e80ade41c
+ OpenBSD-Commit-ID: ff2a71803b5ea57b83cc3fa9b3be42b70e462fb9
-commit 012e5cb839faf76549e3b6101b192fe1a74d367e
-Author: naddy@openbsd.org <naddy@openbsd.org>
-Date: Tue Dec 12 15:06:12 2017 +0000
+commit fc270baf264248c3ee3050b13a6c8c0919e6559f
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Mon Jun 22 05:52:05 2020 +0000
- upstream commit
+ upstream: better terminology for permissions; feedback & ok markus@
- Create a persistent umac128.c source file: #define the
- output size and the name of the entry points for UMAC-128 before including
- umac.c. Idea from FreeBSD. ok dtucker@
+ OpenBSD-Commit-ID: ffb220b435610741dcb4de0e7fc68cbbdc876d2c
+
+commit 00531bb42f1af17ddabea59c3d9c4b0629000d27
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Fri Jun 19 07:21:42 2020 +0000
+
+ upstream: Correct synopsis and usage for the options accepted when
+
+ passing a command to ssh-agent. ok jmc@
- OpenBSD-Commit-ID: 463cfacfa07cb8060a4d4961e63dca307bf3f4b1
+ OpenBSD-Commit-ID: b36f0679cb0cac0e33b361051b3406ade82ea846
-commit b35addfb4cd3b5cdb56a2a489d38e940ada926c7
-Author: Darren Tucker <dtucker@zip.com.au>
-Date: Mon Dec 11 16:23:28 2017 +1100
+commit b4556c8ad7177e379f0b60305a0cd70f12180e7c
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Fri Jun 19 19:22:00 2020 +1000
- Update .depend with empty config.h
+ Add OPENBSD ORIGINAL marker to bcrypt_pbkdf.
-commit 2d96f28246938e0ca474a939d8ac82ecd0de27e3
-Author: Darren Tucker <dtucker@zip.com.au>
-Date: Mon Dec 11 16:21:55 2017 +1100
+commit 1babb8bb14c423011ca34c2f563bb1c51c8fbf1d
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Fri Jun 19 19:10:47 2020 +1000
- Ensure config.h is always in dependencies.
+ Extra brackets around sizeof() in bcrypt.
- Put an empty config.h into the dependency list to ensure that it's
- always listed and consistent.
+ Prevents following warning from clang 10:
+ bcrypt_pbkdf.c:94:40: error: expression does not compute the number of
+ elements in this array; element type is ´uint32_tÂ[...]
+ place parentheses around the ´sizeof(uint64_t)´ expression to
+ silence this warning
-commit ac4987a55ee5d4dcc8e87f7ae7c1f87be7257d71
-Author: deraadt@openbsd.org <deraadt@openbsd.org>
-Date: Sun Dec 10 19:37:57 2017 +0000
+commit 9e065729592633290e5ddb6852792913b2286545
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Fri Jun 19 18:47:56 2020 +1000
- upstream commit
+ Add includes.h to new test.
- ssh/lib hasn't worked towards our code-sharing goals for
- a quit while, perhaps it is too verbose? Change each */Makefile to
- specifying exactly what sources that program requires, compiling it seperate.
- Maybe we'll iterate by sorting those into seperatable chunks, splitting up
- files which contain common code + server/client specific code, or whatnot.
- But this isn't one step, or we'd have done it a long time ago.. ok dtucker
- markus djm
+ Fixes warnings eg "´bounded´ attribute directive ignor" from gcc.
+
+commit e684b1ea365e070433f282a3c1dabc3e2311ce49
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Fri Jun 19 18:38:39 2020 +1000
+
+ Skip OpenSSL specific tests w/out OpenSSL.
- OpenBSD-Commit-ID: 5317f294d63a876bfc861e19773b1575f96f027d
+ Allows unit tests to pass when configure'ed --without-openssl.
+
+commit 80610e97a76407ca982e62fd051c9be03622fe7b
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Fri Jun 19 17:15:27 2020 +1000
+
+ Hook sshsig tests up to Portable Makefiles.
-commit 48c23a39a8f1069a57264dd826f6c90aa12778d5
+commit 5dba1fcabacaab46693338ec829b42a1293d1f52
Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Sun Dec 10 05:55:29 2017 +0000
+Date: Fri Jun 19 05:07:09 2020 +0000
- upstream commit
+ upstream: Test that ssh-agent exits when running as as subprocess
- Put remote client info back into the ClientAlive
- connection termination message. Based in part on diff from lars.nooden at
- gmail, ok djm
+ of a specified command (ie "ssh-agent command"). Would have caught bz#3181.
- OpenBSD-Commit-ID: 80a0f619a29bbf2f32eb5297a69978a0e05d0ee0
+ OpenBSD-Regress-ID: 895b4765ba5153eefaea3160a7fe08ac0b6db8b3
-commit aabd75ec76575c1b17232e6526a644097cd798e5
-Author: deraadt@openbsd.org <deraadt@openbsd.org>
-Date: Fri Dec 8 03:45:52 2017 +0000
+commit 68e8294f6b04f9590ea227e63d3e129398a49e27
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Fri Jun 19 04:34:21 2020 +0000
- upstream commit
+ upstream: run sshsig unit tests
- time_t printing needs %lld and (long long) casts ok djm
-
- OpenBSD-Commit-ID: 4a93bc2b0d42a39b8f8de8bb74d07ad2e5e83ef7
+ OpenBSD-Regress-ID: 706ef17e2b545b64873626e0e35553da7c06052a
-commit fd4eeeec16537870bd40d04836c7906ec141c17d
+commit 5edfa1690e9a75048971fd8775f7c16d153779db
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Dec 8 02:14:33 2017 +0000
+Date: Fri Jun 19 04:32:09 2020 +0000
- upstream commit
+ upstream: basic unit test for sshsig.[ch], including FIDO keys
- fix ordering in previous to ensure errno isn't clobbered
- before logging.
+ verification only so far
- OpenBSD-Commit-ID: e260bc1e145a9690dcb0d5aa9460c7b96a0c8ab2
+ OpenBSD-Regress-ID: fb1f946c8fc59206bc6a6666e577b5d5d7e45896
-commit 155072fdb0d938015df828836beb2f18a294ab8a
+commit e95c0a0e964827722d29b4bc00d5c0ff4afe0ed2
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Dec 8 02:13:02 2017 +0000
+Date: Fri Jun 19 03:48:49 2020 +0000
- upstream commit
+ upstream: basic unit test for FIDO kep parsing
- for some reason unix_listener() logged most errors twice
- with each message containing only some of the useful information; merge these
+ OpenBSD-Regress-ID: 8089b88393dd916d7c95422b442a6fd4cfe00c82
+
+commit 7775819c6de3e9547ac57b87c7dd2bfd28cefcc5
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Thu Jun 18 23:34:19 2020 +0000
+
+ upstream: check public host key matches private; ok markus@ (as
- OpenBSD-Commit-ID: 1978a7594a9470c0dddcd719586066311b7c9a4a
+ part of previous diff)
+
+ OpenBSD-Commit-ID: 65a4f66436028748b59fb88b264cb8c94ce2ba63
-commit 79c0e1d29959304e5a49af1dbc58b144628c09f3
-Author: Darren Tucker <dtucker@zip.com.au>
-Date: Mon Dec 11 14:38:33 2017 +1100
+commit c514f3c0522855b4d548286eaa113e209051a6d2
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Thu Jun 18 23:33:38 2020 +0000
- Add autogenerated dependency info to Makefile.
+ upstream: avoid spurious "Unable to load host key" message when
- Adds a .depend file containing dependency information generated by
- makedepend, which is appended to the generated Makefile by configure.
+ sshd can load a private key but no public counterpart; with & ok markus@
- You can regen the file with "make -f Makefile.in depend" if necessary,
- but we'll be looking at some way to automatically keep this up to date.
+ OpenBSD-Commit-ID: 0713cbdf9aa1ff8ac7b1f78b09ac911af510f81b
+
+commit 7fafaeb5da365f4a408fec355dac04a774f27193
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Fri Jun 12 05:26:37 2020 +0000
+
+ upstream: correct RFC number; from HARUYAMA Seigo via GH PR191
- "no objection" djm@
+ OpenBSD-Commit-ID: 8d03b6c96ca98bfbc23d3754c3c33e1fe0852e10
-commit f001de8fbf7f3faddddd8efd03df18e57601f7eb
-Author: Darren Tucker <dtucker@zip.com.au>
-Date: Mon Dec 11 13:42:51 2017 +1100
+commit 3a7f654d5bcb20df24a134b6581b0d235da4564a
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Fri Jun 5 06:18:07 2020 +0000
- Fix pasto in ldns handling.
+ upstream: unbreak "sshd -ddd" - close of config passing fd happened too
- When ldns-config is not found, configure would check the wrong variable.
- ok djm@
+ early. ok markus@
+
+ OpenBSD-Commit-ID: 49346e945c6447aca3e904e65fc400128d2f8ed0
-commit c5bfe83f67cb64e71cf2fe0d1500f6904b0099ee
-Author: Darren Tucker <dtucker@zip.com.au>
-Date: Sat Dec 9 10:12:23 2017 +1100
+commit 3de02be39e5c0c2208d9682a3844991651620fcc
+Author: Andreas Schwab <schwab@suse.de>
+Date: Mon May 25 11:10:44 2020 +0200
- Portable switched to git so s/CVS/git/.
+ Add support for AUDIT_ARCH_RISCV64
-commit bb82e61a40a4ee52e4eb904caaee2c27b763ab5b
-Author: Darren Tucker <dtucker@zip.com.au>
-Date: Sat Dec 9 08:06:00 2017 +1100
+commit ea547eb0329c2f8da77a4ac05f6c330bd49bdaab
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Fri Jun 5 03:25:35 2020 +0000
- Remove now-used check for perl.
+ upstream: make sshbuf_putb(b, NULL) a no-op
+
+ OpenBSD-Commit-ID: 976fdc99b500e347023d430df372f31c1dd128f7
-commit e0ce54c0b9ca3a9388f9c50f4fa6cc25c28a3240
+commit 69796297c812640415c6cea074ea61afc899cbaa
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Wed Dec 6 05:06:21 2017 +0000
+Date: Fri Jun 5 03:24:36 2020 +0000
- upstream commit
+ upstream: make sshbuf_dump() args const
- don't accept junk after "yes" or "no" responses to
- hostkey prompts. bz#2803 reported by Maksim Derbasov; ok dtucker@
+ OpenBSD-Commit-ID: b4a5accae750875d665b862504169769bcf663bd
+
+commit 670428895739d1f79894bdb2457891c3afa60a59
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Fri Jun 5 03:24:16 2020 +0000
+
+ upstream: wrap long line
- OpenBSD-Commit-ID: e1b159fb2253be973ce25eb7a7be26e6f967717c
+ OpenBSD-Commit-ID: ed405a12bd27bdc9c52e169bc5ff3529b4ebbbb2
-commit 609d96b3d58475a15b2eb6b3d463f2c5d8e510c0
+commit 2f648cf222882719040906722b3593b01df4ad1a
Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Tue Dec 5 23:59:47 2017 +0000
+Date: Fri Jun 5 03:15:26 2020 +0000
- upstream commit
+ upstream: Correct historical comment: provos@ modified OpenSSH to
- Replace atoi and strtol conversions for integer arguments
- to config keywords with a checking wrapper around strtonum. This will
- prevent and flag invalid and negative arguments to these keywords. ok djm@
+ work with SSLeay (very quickly replaced by OpenSSL) not SSL in general. ok
+ deraadt, historical context markus@
- OpenBSD-Commit-ID: 99ae3981f3d608a219ccb8d2fff635ae52c17998
+ OpenBSD-Commit-ID: 7209e07a2984b50411ed8ca5a4932da5030d2b90
-commit 168ecec13f9d7cb80c07df3bf7d414f4e4165e84
+commit 56548e4efcc3e3e8093c2eba30c75b23e561b172
Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Tue Dec 5 23:56:07 2017 +0000
+Date: Wed Jun 3 08:23:18 2020 +0000
- upstream commit
-
- Add missing break for rdomain. Prevents spurious
- "Deprecated option" warnings. ok djm@
+ upstream: Import regenerated moduli file.
- OpenBSD-Commit-ID: ba28a675d39bb04a974586241c3cba71a9c6099a
+ OpenBSD-Commit-ID: 52ff0e3205036147b2499889353ac082e505ea54
-commit 927f8514ceffb1af380a5f63ab4d3f7709b1b198
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Tue Dec 5 01:30:19 2017 +0000
+commit 8da801f585dd9c534c0cbe487a3b1648036bf2fb
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Fri Jun 5 13:20:10 2020 +1000
- upstream commit
+ Test fallthrough in OSSH_CHECK_CFLAG_COMPILE.
- include the addr:port in bind/listen failure messages
+ clang 10's -Wimplicit-fallthrough does not understand /* FALLTHROUGH */
+ comments and we don't use the __attribute__((fallthrough)) that it's
+ looking for. This has the effect of turning off -Wimplicit-fallthrough
+ where it does not currently help (particularly with -Werror). ok djm@
+
+commit 049297de975b92adcc2db77e3fb7046c0e3c695d
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Wed Jun 3 08:23:18 2020 +0000
+
+ upstream: Import regenerated moduli file.
- OpenBSD-Commit-ID: fdadb69fe1b38692608809cf0376b71c2c28e58e
+ OpenBSD-Commit-ID: 52ff0e3205036147b2499889353ac082e505ea54
-commit a8c89499543e2d889629c4e5e8dcf47a655cf889
+commit b458423a38a3140ac022ffcffcb332609faccfe3
Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Wed Nov 29 05:49:54 2017 +0000
+Date: Mon Jun 1 07:11:38 2020 +0000
- upstream commit
+ upstream: Remove now-unused proto_spec and associated definitions.
- Import updated moduli.
+ ok djm@
- OpenBSD-Commit-ID: 524d210f982af6007aa936ca7f4c977f4d32f38a
+ OpenBSD-Commit-ID: 2e2b18e3aa6ee22a7b69c39f2d3bd679ec35c362
-commit 3dde09ab38c8e1cfc28252be473541a81bc57097
+commit 5ad3c3a33ef038b55a14ebd31faeeec46073db2c
+Author: millert@openbsd.org <millert@openbsd.org>
+Date: Fri May 29 21:22:02 2020 +0000
+
+ upstream: Fix error message on close(2) and add printf format
+
+ attributes. From Christos Zoulas, OK markus@
+
+ OpenBSD-Commit-ID: 41523c999a9e3561fcc7082fd38ea2e0629ee07e
+
+commit 712ac1efb687a945a89db6aa3e998c1a17b38653
Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Tue Nov 28 21:10:22 2017 +0000
+Date: Fri May 29 11:17:56 2020 +0000
- upstream commit
+ upstream: Make dollar_expand variadic and pass a real va_list to
- Have sftp print a warning about shell cleanliness when
- decoding the first packet fails, which is usually caused by shells polluting
- stdout of non-interactive starups. bz#2800, ok markus@ deraadt@.
+ vdollar_percent_expand. Fixes build error on arm64 spotted by otto@.
- OpenBSD-Commit-ID: 88d6a9bf3470f9324b76ba1cbd53e50120f685b5
+ OpenBSD-Commit-ID: 181910d7ae489f40ad609b4cf4a20f3d068a7279
-commit 6c8a246437f612ada8541076be2414846d767319
-Author: Darren Tucker <dtucker@zip.com.au>
-Date: Fri Dec 1 17:11:47 2017 +1100
+commit 837ffa9699a9cba47ae7921d2876afaccc027133
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Fri May 29 20:39:00 2020 +1000
- Replace mkinstalldirs with mkdir -p.
+ Omit ToS setting if we don't have IPV6_TCLASS too.
- Check for MIKDIR_P and use it instead of mkinstalldirs. Should fix "mkdir:
- cannot create directory:... File exists" during "make install".
- Patch from eb at emlix.com.
+ Fixes tests on old BSDs.
-commit 3058dd78d2e43ed0f82ad8eab8bb04b043a72023
-Author: Darren Tucker <dtucker@zip.com.au>
-Date: Fri Dec 1 17:07:08 2017 +1100
+commit f85b118d2150847cc333895296bc230e367be6b5
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Fri May 29 09:02:44 2020 +0000
- Pull in newer install-sh from autoconf-2.69.
+ upstream: Pass a NULL instead of zeroed out va_list from
+
+ dollar_expand. The original intent was in case there's some platform where
+ va_list is not a pointer equivalent, but on i386 this chokes on the memset.
+ This unbreaks that build, but will require further consideration.
- Suggested by eb at emlix.com
+ OpenBSD-Commit-ID: 7b90afcd8e1137a1d863204060052aef415baaf7
-commit 79226e5413c5b0fda3511351a8511ff457e306d8
-Author: Darren Tucker <dtucker@zip.com.au>
-Date: Fri Dec 1 16:55:35 2017 +1100
+commit ec1d50b01c84ff667240ed525f669454c4ebc8e9
+Author: jmc@openbsd.org <jmc@openbsd.org>
+Date: Fri May 29 05:48:39 2020 +0000
- Remove RSA1 host key generation.
+ upstream: remove a stray .El;
- SSH1 support is now gone, remove SSH1 key generation.
- Patch from eb at emlix.com.
+ OpenBSD-Commit-ID: 58ddfe6f8a15fe10209db6664ecbe7896f1d167c
-commit 2937dd02c572a12f33d5c334d518f6cbe0b645eb
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Tue Nov 28 06:09:38 2017 +0000
+commit 058674a62ffe33f01d871d46e624bc2a2c22d91f
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Fri May 29 04:32:26 2020 +0000
- upstream commit
+ upstream: Add regression and unit tests for ${ENV} style
- more whitespace errors
+ environment variable expansion in various keywords (bz#3140). ok djm@
- OpenBSD-Commit-ID: 5e11c125378327b648940b90145e0d98beb05abb
+ OpenBSD-Regress-ID: 4d9ceb95d89365b7b674bc26cf064c15a5bbb197
-commit 7f257bf3fd3a759f31098960cbbd1453fafc4164
-Author: djm@openbsd.org@openbsd.org <djm@openbsd.org@openbsd.org>
-Date: Tue Nov 28 06:04:51 2017 +0000
+commit 0b15892fc47d6840eba1291a6be9be1a70bc8972
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Fri May 29 01:21:35 2020 +0000
- upstream commit
+ upstream: Unit test for convtime. ok djm@
- whitespace at EOL
-
- OpenBSD-Commit-ID: 76d3965202b22d59c2784a8df3a8bfa5ee67b96a
+ OpenBSD-Regress-ID: cec4239efa2fc4c7062064f07a847e1cbdbcd5dd
-commit 5db6fbf1438b108e5df3e79a1b4de544373bc2d4
-Author: dtucker@openbsd.org@openbsd.org <dtucker@openbsd.org@openbsd.org>
-Date: Sat Nov 25 06:46:22 2017 +0000
+commit 188e332d1c8f9f24e5b6659e9680bf083f837df9
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Fri May 29 05:37:03 2020 +0000
- upstream commit
+ upstream: mention that wildcards are processed in lexical order;
- Add monotime_ts and monotime_tv that return monotonic
- timespec and timeval respectively. Replace calls to gettimeofday() in packet
- timing with monotime_tv so that the callers will work over a clock step.
- Should prevent integer overflow during clock steps reported by wangle6 at
- huawei.com. "I like" markus@
+ bz#3165
- OpenBSD-Commit-ID: 74d684264814ff806f197948b87aa732cb1b0b8a
+ OpenBSD-Commit-ID: 8856f3d1612bd42e9ee606d89386cae456dd165c
-commit 2d638e986085bdf1a40310ed6e2307463db96ea0
-Author: dtucker@openbsd.org@openbsd.org <dtucker@openbsd.org@openbsd.org>
-Date: Sat Nov 25 05:58:47 2017 +0000
+commit 4a1b46e6d032608b7ec00ae51c4e25b82f460b05
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Fri May 29 04:25:40 2020 +0000
- upstream commit
+ upstream: Allow some keywords to expand shell-style ${ENV}
- Remove get_current_time() and replace with calls to
- monotime_double() which uses CLOCK_MONOTONIC and works over clock steps. "I
- like" markus@
+ environment variables on the client side. The supported keywords are
+ CertificateFile, ControlPath, IdentityAgent and IdentityFile, plus
+ LocalForward and RemoteForward when used for Unix domain socket paths. This
+ would for example allow forwarding of Unix domain socket paths that change at
+ runtime. bz#3140, ok djm@
- OpenBSD-Commit-ID: 3ad2f7d2414e2cfcaef99877a7a5b0baf2242952
+ OpenBSD-Commit-ID: a4a2e801fc2d4df2fe0e58f50d9c81b03822dffa
-commit ba460acae48a36ef749cb23068f968f4d5d90a24
-Author: Darren Tucker <dtucker@zip.com.au>
-Date: Fri Nov 24 16:24:31 2017 +1100
+commit c9bab1d3a9e183cef3a3412f57880a0374cc8cb2
+Author: Damien Miller <djm@mindrot.org>
+Date: Fri May 29 14:49:16 2020 +1000
- Include string.h for explicit_bzero.
+ depend
-commit a65655fb1a12b77fb22f9e71559b9d73030ec8ff
-Author: Damien Miller <djm@mindrot.org>
-Date: Fri Nov 24 10:23:47 2017 +1100
+commit 0b0d219313bf9239ca043f20b1a095db0245588f
+Author: sobrado <sobrado@openbsd.org>
+Date: Thu Sep 3 23:06:28 2015 +0000
- fix incorrect range of OpenSSL versions supported
+ partial sync of regress/netcat.c with upstream
- Pointed out by Solar Designer
+ synchronize synopsis and usage.
-commit 83a1e5dbec52d05775174f368e0c44b08619a308
-Author: djm@openbsd.org@openbsd.org <djm@openbsd.org@openbsd.org>
-Date: Wed Nov 15 02:10:16 2017 +0000
+commit 0f04c8467f589f85a523e19fd684c4f6c4ed9482
+Author: chl <chl@openbsd.org>
+Date: Sun Jul 26 19:12:28 2015 +0000
- upstream commit
+ partial sync of regress/netcat.c with upstream
- downgrade a couple more request parsing errors from
- process-fatal to just returning failure, making them consistent with the
- others that were already like that.
+ remove unused variable
- OpenBSD-Commit-ID: c111461f7a626690a2d53018ef26557b34652918
+ ok tedu@
-commit 93c68a8f3da8e5e6acdc3396f54d73919165e242
-Author: djm@openbsd.org@openbsd.org <djm@openbsd.org@openbsd.org>
-Date: Wed Nov 15 00:13:40 2017 +0000
+commit d6a81050ace2630b06c3c6dd39bb4eef5d1043f8
+Author: tobias <tobias@openbsd.org>
+Date: Thu Mar 26 21:22:50 2015 +0000
- upstream commit
+ partial sync of regress/netcat.c with upstream
- fix regression in 7.6: failure to parse a signature request
- message shouldn't be fatal to the process, just the request. Reported by Ron
- Frederick
+ The code in socks.c writes multiple times in a row to a socket. If the socket becomes invalid between these calls (e.g. connection closed), write will throw SIGPIPE. With this patch, SIGPIPE is ignored so we can handle write's -1 return value (errno will be EPIPE). Ultimately, it leads to program exit, too -- but with nicer error message. :)
- OpenBSD-Commit-ID: e5d01b3819caa1a2ad51fc57d6ded43f48bbcc05
+ with input by and ok djm
-commit 548d3a66feb64c405733932a6b1abeaf7198fa71
-Author: djm@openbsd.org@openbsd.org <djm@openbsd.org@openbsd.org>
-Date: Tue Nov 14 00:45:29 2017 +0000
+commit bf3893dddd35e16def04bf48ed2ee1ad695b8f82
+Author: tobias <tobias@openbsd.org>
+Date: Thu Mar 26 10:36:03 2015 +0000
- upstream commit
-
- fix problem in configuration parsing when in config dump mode
- (sshd -T) without providing a full connection specification (sshd -T -C ...)
+ partial sync of regress/netcat.c with upstream
- spotted by bluhm@
+ Check for short writes in fdpass(). Clean up while at it.
- OpenBSD-Commit-ID: 7125faf5740eaa9d3a2f25400a0bc85e94e28b8f
+ ok djm
-commit 33edb6ebdc2f81ebed1bceadacdfb8910b64fb88
-Author: djm@openbsd.org@openbsd.org <djm@openbsd.org@openbsd.org>
-Date: Fri Nov 3 05:18:44 2017 +0000
+commit e18435fec124b4c08eb6bbbbee9693dc04f4befb
+Author: jca <jca@openbsd.org>
+Date: Sat Feb 14 22:40:22 2015 +0000
- upstream commit
+ partial sync of regress/netcat.c with upstream
- reuse parse_multistate for parse_flag (yes/no arguments).
- Saves a few lines of code and makes the parser more consistent wrt case-
- sensitivity. bz#2664 ok dtucker@
+ Support for nc -T on IPv6 addresses.
- OpenBSD-Commit-ID: b2ad1b6086858d5db71c7b11e5a74dba6d60efef
+ ok sthen@
-commit d52131a98316e76c0caa348f09bf6f7b9b01a1b9
-Author: djm@openbsd.org@openbsd.org <djm@openbsd.org@openbsd.org>
-Date: Fri Nov 3 05:14:04 2017 +0000
+commit 4c607244054a036ad3b2449a6cb4c15feb846a76
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Fri May 29 03:14:02 2020 +0000
- upstream commit
+ upstream: fix compilation on !HAVE_DLOPEN platforms; stub function
- allow certificate validity intervals that specify only a
- start or stop time (we already support specifying both or neither)
+ was not updated to match API change. From Dale Rahn via beck@ ok markus@
- OpenBSD-Commit-ID: 9be486545603c003030bdb5c467d1318b46b4e42
+ OpenBSD-Commit-ID: 2b8d054afe34c9ac85e417dae702ef981917b836
-commit fbe8e7ac94c2fa380421a9205a8bc966549c2f91
-Author: djm@openbsd.org@openbsd.org <djm@openbsd.org@openbsd.org>
-Date: Fri Nov 3 03:46:52 2017 +0000
+commit 224418cf55611869a4ace1b8b07bba0dff77a9c3
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Fri May 29 03:11:54 2020 +0000
- upstream commit
+ upstream: fix exit status for downloading of FIDO resident keys;
- allow "cd" and "lcd" commands with no explicit path
- argument. lcd will change to the local user's home directory as usual. cd
- will change to the starting directory for session (because the protocol
- offers no way to obtain the remote user's home directory). bz#2760 ok
- dtucker@
+ from Pedro Martelletto, ok markus@
- OpenBSD-Commit-ID: 15333f5087cee8c1ed1330cac1bd0a3e6a767393
+ OpenBSD-Commit-ID: 0da77dc24a1084798eedd83c39a002a9d231faef
-commit 0208a48517b5e8e8b091f32fa4addcd67c31ca9e
-Author: dtucker@openbsd.org@openbsd.org <dtucker@openbsd.org@openbsd.org>
-Date: Fri Nov 3 03:18:53 2017 +0000
+commit 1001dd148ed7c57bccf56afb40cb77482ea343a6
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Fri May 29 01:20:46 2020 +0000
- upstream commit
+ upstream: Fix multiplier in convtime when handling seconds after
- When doing a config test with sshd -T, only require the
- attributes that are actually used in Match criteria rather than (an
- incomplete list of) all criteria. ok djm@, man page help jmc@
+ other units. bz#3171, spotted by ronf at timeheart.net, ok djm@.
- OpenBSD-Commit-ID: b4e773c4212d3dea486d0259ae977551aab2c1fc
+ OpenBSD-Commit-ID: 95b7a848e1083974a65fbb6ccb381d438e1dd5be
-commit c357eed5a52cd2f4ff358b17e30e3f9a800644da
-Author: djm@openbsd.org@openbsd.org <djm@openbsd.org@openbsd.org>
-Date: Fri Nov 3 02:32:19 2017 +0000
+commit 7af1e92cd289b7eaa9a683e9a6f2fddd98f37a01
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Wed May 27 22:37:53 2020 +0000
- upstream commit
+ upstream: fix Include before Match in sshd_config; bz#3122 patch
- typos in ECDSA certificate names; bz#2787 reported by
- Mike Gerow
+ from Jakub Jelen
- OpenBSD-Commit-ID: 824938b6aba1b31321324ba1f56c05f84834b163
+ OpenBSD-Commit-ID: 1b0aaf135fe6732b5d326946042665dd3beba5f4
-commit ecbf005b8fd80b81d0c61dfc1e96fe3da6099395
-Author: djm@openbsd.org@openbsd.org <djm@openbsd.org@openbsd.org>
-Date: Fri Nov 3 02:29:17 2017 +0000
+commit 0a9a611619b0a1fecd0195ec86a9885f5d681c84
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Wed May 27 21:59:11 2020 +0000
- upstream commit
+ upstream: Do not call process_queued_listen_addrs() for every
- Private keys in PEM format have been encrypted by AES-128 for
- a while (not 3DES). bz#2788 reported by Calum Mackay
+ included file from sshd_config; patch from Jakub Jelen
- OpenBSD-Commit-ID: bd33da7acbbb3c882f0a0ee56007a35ce0d8a11a
+ OpenBSD-Commit-ID: 0ff603d6f06a7fab4881f12503b53024799d0a49
-commit 81c9ccdbf6ddbf9bfbd6f1f775a5a7c13e47e185
-Author: Darren Tucker <dtucker@zip.com.au>
-Date: Fri Nov 3 14:52:51 2017 +1100
+commit 16ea1fdbe736648f79a827219134331f8d9844fb
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Wed May 27 21:25:18 2020 +0000
- Check for linux/if.h when enabling rdomain.
+ upstream: fix crash in recallocarray when deleting SendEnv
- musl libc doesn't seem to have linux/if.h, so check for its presence
- before enabling rdomain support on Linux.
-
-commit fa1b834cce41a1ce3e6a8d57fb67ef18c9dd803f
-Author: Darren Tucker <dtucker@zip.com.au>
-Date: Fri Nov 3 14:09:45 2017 +1100
-
- Add headers for sys/sysctl.h and net/route.h
+ variables; spotted by & ok sthen@
- On at least older OpenBSDs, sys/sysctl.h and net/route.h require
- sys/types and, in the case of sys/sysctl.h, sys/param.h for MAXLOGNAME.
+ OpenBSD-Commit-ID: b881e8e849edeec5082b5c0a87d8d7cff091a8fd
-commit 41bff4da21fcd8a7c6a83a7e0f92b018f904f6fb
-Author: djm@openbsd.org@openbsd.org <djm@openbsd.org@openbsd.org>
-Date: Fri Nov 3 02:22:41 2017 +0000
+commit 47adfdc07f4f8ea0064a1495500244de08d311ed
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Wed May 27 22:35:19 2020 +0000
- upstream commit
+ upstream: two new tests for Include in sshd_config, checking whether
- avoid unused variable warnings for !WITH_OPENSSL; patch from
- Marcus Folkesson
+ Port directives are processed correctly and handling of Include directives
+ that appear before Match. Both tests currently fail. bz#3122 and bz#3169 -
+ patch from Jakub Jelen
- OpenBSD-Commit-ID: c01d27a3f907acdc3dd4ea48170fac3ba236d229
+ OpenBSD-Regress-ID: 8ad5a4a385a63f0a1c59c59c763ff029b45715df
-commit 6b373e4635a7470baa94253dd1dc8953663da9e8
-Author: Marcus Folkesson <marcus.folkesson@gmail.com>
-Date: Sat Oct 28 19:48:39 2017 +0200
+commit 47faad8f794516c33864d866aa1b55d88416f94c
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Wed May 27 23:26:23 2020 +1000
- only enable functions in dh.c when openssl is used
-
- Signed-off-by: Marcus Folkesson <marcus.folkesson@gmail.com>
+ Document that libfido2 >= 1.4.0 is needed.
-commit 939b30ba23848b572e15bf92f0f1a3d9cf3acc2b
-Author: djm@openbsd.org@openbsd.org <djm@openbsd.org@openbsd.org>
-Date: Wed Nov 1 00:04:15 2017 +0000
+commit 4be563994c0cbe9856e7dd3078909f41beae4a9c
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Tue May 26 01:59:46 2020 +0000
- upstream commit
-
- fix broken stdout in ControlPersist mode, introduced by me in
- r1.467 and reported by Alf Schlichting
+ upstream: fix memleak of signature; from Pedro Martelletto
- OpenBSD-Commit-ID: 3750a16e02108fc25f747e4ebcedb7123c1ef509
+ OpenBSD-Commit-ID: d0a6eb07e77c001427d738b220dd024ddc64b2bb
-commit f21455a084f9cc3942cf1bde64055a4916849fed
-Author: Darren Tucker <dtucker@zip.com.au>
-Date: Tue Oct 31 10:09:33 2017 +1100
+commit 0c111eb84efba7c2a38b2cc3278901a0123161b9
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Tue May 26 01:26:58 2020 +0000
- Include includes.h for HAVE_GETPAGESIZE.
+ upstream: Restrict ssh-agent from signing web challenges for FIDO
- The configure script checks for getpagesize() and sets HAVE_GETPAGESIZE in
- config.h, but bsd-getpagesize.c forgot to include includes.h (which
- indirectly includes config.h) so the checks always fails, causing linker
- issues when linking statically on systems with getpagesize().
+ keys.
- Patch from Peter Korsgaard <peter at korsgaard.com>
-
-commit f2ad63c0718b93ac1d1e85f53fee33b06eef86b5
-Author: djm@openbsd.org@openbsd.org <djm@openbsd.org@openbsd.org>
-Date: Mon Oct 30 22:01:52 2017 +0000
-
- upstream commit
+ When signing messages in ssh-agent using a FIDO key that has an
+ application string that does not start with "ssh:", ensure that the
+ message being signed is one of the forms expected for the SSH protocol
+ (currently pubkey authentication and sshsig signatures).
- whitespace at EOL
+ This prevents ssh-agent forwarding on a host that has FIDO keys
+ attached granting the ability for the remote side to sign challenges
+ for web authentication using those keys too.
- OpenBSD-Regress-ID: f4b5df99b28c6f63478deb916c6ed0e794685f07
-
-commit c6415b1f8f1d0c2735564371647fd6a177fb9a3e
-Author: djm@openbsd.org@openbsd.org <djm@openbsd.org@openbsd.org>
-Date: Mon Oct 30 21:59:43 2017 +0000
-
- upstream commit
+ Note that the converse case of web browsers signing SSH challenges is
+ already precluded because no web RP can have the "ssh:" prefix in the
+ application string that we require.
- whitespace at EOL
+ ok markus@
- OpenBSD-Regress-ID: 19b1394393deee4c8a2114a3b7d18189f27a15cd
+ OpenBSD-Commit-ID: 9ab6012574ed0352d2f097d307f4a988222d1b19
-commit e4d4ddbbba0e585ca3ec3a455430750b4622a6d3
-Author: millert@openbsd.org@openbsd.org <millert@openbsd.org@openbsd.org>
-Date: Wed Oct 25 20:08:36 2017 +0000
+commit 9c5f64b6cb3a68b99915202d318b842c6c76cf14
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Tue May 26 01:09:05 2020 +0000
- upstream commit
+ upstream: improve logging for MaxStartups connection throttling:
- Use printenv to test whether an SSH_USER_AUTH is set
- instead of using $SSH_USER_AUTH. The latter won't work with csh which treats
- unknown variables as an error when expanding them. OK markus@
+ have sshd log when it starts and stops throttling and periodically while in
+ this state. bz#3055 ok markus@
- OpenBSD-Regress-ID: f601e878dd8b71aa40381573dde3a8f567e6f2d1
+ OpenBSD-Commit-ID: 2e07a09a62ab45d790d3d2d714f8cc09a9ac7ab9
-commit 116b1b439413a724ebb3320633a64dd0f3ee1fe7
-Author: millert@openbsd.org@openbsd.org <millert@openbsd.org@openbsd.org>
-Date: Tue Oct 24 19:33:32 2017 +0000
+commit 756c6f66aee83a5862a6f936a316f761532f3320
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Tue May 26 01:06:52 2020 +0000
- upstream commit
+ upstream: add fmt_timeframe() (from bgpd) to format a time
- Add tests for URI parsing. OK markus@
+ interval in a human- friendly format. Switch copyright for this file from BSD
+ to MIT to make it easier to add Henning's copyright for this function. ok
+ markus@
- OpenBSD-Regress-ID: 5d1df19874f3b916d1a2256a905526e17a98bd3b
+ OpenBSD-Commit-ID: 414a831c662df7e68893e5233e86f2cac081ccf9
-commit dbe0662e9cd482593a4a8bf58c6481bfe8a747a4
-Author: djm@openbsd.org@openbsd.org <djm@openbsd.org@openbsd.org>
-Date: Fri Oct 27 01:57:06 2017 +0000
+commit 2a63ce5cd6d0e782783bf721462239b03757dd49
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Mon May 18 04:29:35 2020 +0000
- upstream commit
+ upstream: avoid possible NULL deref; from Pedro Martelletto
- whitespace at EOL
-
- OpenBSD-Commit-ID: c95549cf5a07d56ea11aaff818415118720214f6
+ OpenBSD-Commit-ID: e6099c3fbb70aa67eb106e84d8b43f1fa919b721
-commit d2135474344335a7c6ee643b6ade6db400fa76ee
-Author: djm@openbsd.org@openbsd.org <djm@openbsd.org@openbsd.org>
-Date: Fri Oct 27 01:01:17 2017 +0000
+commit 4b307faf2fb0e63e51a550b37652f7f972df9676
+Author: markus@openbsd.org <markus@openbsd.org>
+Date: Fri May 15 08:34:03 2020 +0000
- upstream commit
+ upstream: sshd listener must not block if reexecd sshd exits
- whitespace at EOL (lots)
+ in write(2) on config_s[0] if the forked child exits early before finishing
+ recv_rexec_state (e.g. with fatal()) because config_s[1] stays open in the
+ parent. this prevents the parent from accepting new connections. ok djm,
+ deraadt
- OpenBSD-Commit-ID: 757257dd44116794ee1b5a45c6724973de181747
+ OpenBSD-Commit-ID: 92ccfeb939ccd55bda914dc3fe84582158c4a9ef
-commit b77c29a07f5a02c7c1998701c73d92bde7ae1608
-Author: djm@openbsd.org@openbsd.org <djm@openbsd.org@openbsd.org>
-Date: Fri Oct 27 00:18:41 2017 +0000
+commit af8b16fb2cce880341c0ee570ceb0d84104bdcc0
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Fri May 15 03:57:33 2020 +0000
- upstream commit
+ upstream: fix off-by-one error that caused sftp downloads to make
- improve printing of rdomain on accept() a little
+ one more concurrent request that desired. This prevented using sftp(1) in
+ unpipelined request/response mode, which is useful when debugging. Patch from
+ Stephen Goetze in bz#3054
- OpenBSD-Commit-ID: 5da58db2243606899cedaa646c70201b2d12247a
+ OpenBSD-Commit-ID: 41b394ebe57037dbc43bdd0eef21ff0511191f28
-commit 68d3bbb2e6dfbf117c46e942142795b2cdd0274b
-Author: jmc@openbsd.org@openbsd.org <jmc@openbsd.org@openbsd.org>
-Date: Thu Oct 26 06:44:01 2017 +0000
+commit d7d753e2979f2d3c904b03a08d30856cd2a6e892
+Author: deraadt@openbsd.org <deraadt@openbsd.org>
+Date: Wed May 13 22:38:41 2020 +0000
- upstream commit
+ upstream: we are still aiming for pre-C99 ...
- mark up the rdomain keyword;
-
- OpenBSD-Commit-ID: 1b597d0ad0ad20e94dbd61ca066057e6f6313b8a
+ OpenBSD-Commit-ID: a240fc9cbe60bc4e6c3d24d022eb4ab01fe1cb38
-commit 0b2e2896b9d0d6cfb59e9ec8271085296bd4e99b
-Author: jmc@openbsd.org@openbsd.org <jmc@openbsd.org@openbsd.org>
-Date: Wed Oct 25 06:19:46 2017 +0000
+commit 2ad7b7e46408dbebf2a4efc4efd75a9544197d57
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Wed May 13 10:08:02 2020 +0000
- upstream commit
+ upstream: Enable credProtect extension when generating a resident
- tweak the uri text, specifically removing some markup to
- make it a bit more readable;
+ key.
- issue reported by - and diff ok - millert
+ The FIDO 2.1 Client to Authenticator Protocol introduced a "credProtect"
+ feature to better protect resident keys. This option allows (amone other
+ possibilities) requiring a PIN prior to all operations that may retrieve
+ the key handle.
- OpenBSD-Commit-ID: 8b56a20208040b2d0633536fd926e992de37ef3f
+ Patch by Pedro Martelletto; ok djm and markus
+
+ OpenBSD-Commit-ID: 013bc06a577dcaa66be3913b7f183eb8cad87e73
-commit 7530e77bdc9415386d2a8ea3d086e8b611b2ba40
-Author: jmc@openbsd.org@openbsd.org <jmc@openbsd.org@openbsd.org>
-Date: Wed Oct 25 06:18:06 2017 +0000
+commit 1e70dc3285fc9b4f6454975acb81e8702c23dd89
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Wed May 13 09:57:17 2020 +0000
- upstream commit
+ upstream: always call fido_init(); previous behaviour only called
- simplify macros in previous, and some minor tweaks;
+ fido_init() when SK_DEBUG was defined. Harmless with current libfido2, but
+ this isn't guaranteed in the future.
- OpenBSD-Commit-ID: 6efeca3d8b095b76e21b484607d9cc67ac9a11ca
+ OpenBSD-Commit-ID: c7ea20ff2bcd98dd12015d748d3672d4f01f0864
-commit eb9c582b710dc48976b48eb2204218f6863bae9a
-Author: Damien Miller <djm@mindrot.org>
-Date: Tue Oct 31 00:46:29 2017 +1100
+commit f2d84f1b3fa68d77c99238d4c645d0266fae2a74
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Wed May 13 09:55:57 2020 +0000
- Switch upstream git repository.
+ upstream: preserve group/world read permission on known_hosts
- Previously portable OpenSSH has synced against a conversion of OpenBSD's
- CVS repository made using the git cvsimport tool, but this has become
- increasingly unreliable.
+ file across runs of "ssh-keygen -Rf /path". The old behaviour was to remove
+ all rights for group/other. bz#3146 ok dtucker@
- As of this commit, portable OpenSSH now tracks a conversion of the
- OpenBSD CVS upstream made using the excellent cvs2gitdump tool from
- YASUOKA Masahiko: https://github.com/yasuoka/cvs2gitdump
+ OpenBSD-Commit-ID: dc369d0e0b5dd826430c63fd5f4b269953448a8a
+
+commit 05a651400da6fbe12296c34e3d3bcf09f034fbbf
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Wed May 13 09:52:41 2020 +0000
+
+ upstream: when ordering the hostkey algorithms to request from a
- cvs2gitdump is considerably more reliable than gitcvsimport and the old
- version of cvsps that it uses under the hood, and is the same tool used
- to export the entire OpenBSD repository to git (so we know it can cope
- with future growth).
+ server, prefer certificate types if the known_hosts files contain a key
+ marked as a @cert-authority; bz#3157 ok markus@
- These new conversions are mirrored at github, so interested parties can
- match portable OpenSSH commits to their upstream counterparts.
+ OpenBSD-Commit-ID: 8f194573e5bb7c01b69bbfaabc68f27c9fa5e0db
+
+commit 829451815ec207e14bd54ff5cf7e22046816f042
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Tue May 12 01:41:32 2020 +0000
+
+ upstream: fix non-ASCII quote that snuck in; spotted by Gabriel
- https://github.com/djmdjm/openbsd-openssh-src
- https://github.com/djmdjm/openbsd-openssh-regress
+ Kihlman
- An unfortunate side effect of switching upstreams is that we must have
- a flag day, across which the upstream commit IDs will be inconsistent.
- The old commit IDs are recorded with the tags "Upstream-ID" for main
- directory commits and "Upstream-Regress-ID" for regress commits.
+ OpenBSD-Commit-ID: 04bcde311de2325d9e45730c744c8de079b49800
+
+commit 5a442cec92c0efd6fffb4af84bf99c70af248ef3
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Mon May 11 02:11:29 2020 +0000
+
+ upstream: clarify role of FIDO tokens in multi-factor
- To make it clear that the commit IDs do not refer to the same
- things, the new repository will instead use "OpenBSD-ID" and
- "OpenBSD-Regress-ID" tags instead.
+ authentictation; mostly from Pedro Martelletto
- Apart from being a longwinded explanation of what is going on, this
- commit message also serves to synchronise our tools with the state of
- the tree, which happens to be:
+ OpenBSD-Commit-ID: fbe05685a1f99c74b1baca7130c5a03c2df7c0ac
+
+commit ecb2c02d994b3e21994f31a70ff911667c262f1f
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Fri May 8 05:13:14 2020 +0000
+
+ upstream: fix compilation with DEBUG_KEXDH; bz#3160 ok dtucker@
- OpenBSD-ID: 9c43a9968c7929613284ea18e9fb92e4e2a8e4c1
- OpenBSD-Regress-ID: b33b385719420bf3bc57d664feda6f699c147fef
+ OpenBSD-Commit-ID: 832e771948fb45f2270e8b8895aac36d176ba17a
-commit 2de5c6b53bf063ac698596ef4e23d8e3099656ea
+commit 3ab6fccc3935e9b778ff52f9c8d40f215d58e01d
Author: Damien Miller <djm@mindrot.org>
-Date: Fri Oct 27 08:42:33 2017 +1100
+Date: Thu May 14 12:22:09 2020 +1000
+
+ prefer ln to cp for temporary copy of sshd
+
+ I saw failures on the reexec fallback test on Darwin 19.4 where
+ fork()ed children of a process that had it's executable removed
+ would instantly fail. Using ln to preserve the inode avoids this.
- fix rdomain compilation errors
+commit f700d316c6b15a9cfbe87230d2dca81a5d916279
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Wed May 13 15:24:51 2020 +1000
+
+ Actually skip pty tests when needed.
+
+commit 08ce6b2210f46f795e7db747809f8e587429dfd2
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Wed May 13 13:56:45 2020 +1000
-commit 6bd5b569fd6dfd5e8c8af20bbc41e45c2d6462ab
+ Skip building sk-dummy library if no SK support.
+
+commit 102d106bc2e50347d0e545fad6ff5ce408d67247
Author: Damien Miller <djm@mindrot.org>
-Date: Wed Oct 25 14:15:42 2017 +1100
+Date: Wed May 13 12:08:34 2020 +1000
- autoconf glue to enable Linux VRF
+ explicitly manage .depend and .depend.bak
+
+ Bring back removal of .depend to give the file a known state before
+ running makedepend, but manually move aside the current .depend file
+ and restore it as .depend.bak afterwards so the stale .depend check
+ works as expected.
-commit 97c5aaf925d61641d599071abb56012cde265978
+commit 83a6dc6ba1e03b3fa39d12a8522b8b0e68dd6390
Author: Damien Miller <djm@mindrot.org>
-Date: Wed Oct 25 14:09:56 2017 +1100
+Date: Wed May 13 12:03:42 2020 +1000
- basic valid_rdomain() implementation for Linux
+ make depend
-commit ce1cca39d7935dd394080ce2df62f5ce5b51f485
+commit 7c0bbed967abed6301a63e0267cc64144357a99a
Author: Damien Miller <djm@mindrot.org>
-Date: Wed Oct 25 13:47:59 2017 +1100
+Date: Wed May 13 12:01:10 2020 +1000
- implement get/set_rdomain() for Linux
+ revert removal of .depend before makedepend
- Not enabled, pending implementation of valid_rdomain() and autoconf glue
+ Commit 83657eac4 started removing .depend before running makedepend
+ to reset the contents of .depend to a known state. Unfortunately
+ this broke the depend-check step as now .depend.bak would only ever
+ be created as an empty file.
+
+ ok dtucker
-commit 6eee79f9b8d4a3b113b698383948a119acb82415
+commit 58ad004acdcabf3b9f40bc3aaa206b25d998db8c
Author: Damien Miller <djm@mindrot.org>
-Date: Wed Oct 25 13:22:29 2017 +1100
+Date: Tue May 12 12:58:46 2020 +1000
- stubs for rdomain replacement functions
+ prepare for 8.3 release
-commit f5594f939f844bbb688313697d6676238da355b3
+commit 4fa9e048c2af26beb7dc2ee9479ff3323e92a7b5
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Fri May 8 21:50:43 2020 +1000
+
+ Ensure SA_SIGNAL test only signals itself.
+
+ When the test's child signals its parent and it exits the result of
+ getppid changes. On Ubuntu 20.04 this results in the ppid being that
+ of the GDM session, causing it to exit. Analysis and testing from pedro
+ at ambientworks.net
+
+commit dc2da29aae76e170d22f38bb36f1f5d1edd5ec2b
Author: Damien Miller <djm@mindrot.org>
-Date: Wed Oct 25 13:13:57 2017 +1100
+Date: Fri May 8 13:31:53 2020 +1000
- rename port-tun.[ch] => port-net.[ch]
+ sync config.guess/config.sub with latest versions
- Ahead of adding rdomain support
+ ok dtucker@
-commit d685e5a31feea35fb99e1a31a70b3c60a7f2a0eb
+commit a8265bd64c14881fc7f4fa592f46dfc66b911f17
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Wed Oct 25 02:10:39 2017 +0000
+Date: Wed May 6 20:58:01 2020 +0000
- upstream commit
+ upstream: openssh-8.3; ok deraadt@
+
+ OpenBSD-Commit-ID: c8831ec88b9c750f5816aed9051031fb535d22c1
+
+commit 955854cafca88e0cdcd3d09ca1ad4ada465364a1
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Wed May 6 20:57:38 2020 +0000
+
+ upstream: another case where a utimes() failure could make scp send
- uninitialised variable in PermitTunnel printing code
+ a desynchronising error; reminded by Aymeric Vincent ok deraadt markus
- Upstream-ID: f04dc33e42855704e116b8da61095ecc71bc9e9a
+ OpenBSD-Commit-ID: 2ea611d34d8ff6d703a7a8bf858aa5dbfbfa7381
-commit 43c29bb7cfd46bbbc61e0ffa61a11e74d49a712f
-Author: Damien Miller <djm@mindrot.org>
-Date: Wed Oct 25 13:10:59 2017 +1100
+commit 59d531553fd90196946743da391f3a27cf472f4e
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Thu May 7 15:34:12 2020 +1000
- provide hooks and fallbacks for rdomain support
+ Check if -D_REENTRANT is needed for localtime_r.
+
+ On at least HP-UX 11.11, the localtime_r declararation is behind
+ ifdef _REENTRANT. Check for and add if needed.
-commit 3235473bc8e075fad7216b7cd62fcd2b0320ea04
-Author: Damien Miller <djm@mindrot.org>
-Date: Wed Oct 25 11:25:43 2017 +1100
+commit c13403e55de8cdbb9da628ed95017b1d4c0f205f
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Tue May 5 11:32:43 2020 +1000
- check for net/route.h and sys/sysctl.h
+ Skip security key tests if ENABLE_SK not set.
-commit 4d5456c7de108e17603a0920c4d15bca87244921
+commit 4da393f87cd52d788c84112ee3f2191c9bcaaf30
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Wed Oct 25 00:21:37 2017 +0000
+Date: Fri May 1 04:03:14 2020 +0000
- upstream commit
+ upstream: sure enough, some of the test data that we though were in
- transfer ownership of stdout to the session channel by
- dup2'ing /dev/null to fd 1. This allows propagation of remote stdout close to
- the local side; reported by David Newall, ok markus@
+ new format were actually in the old format; fix from Michael Forney
- Upstream-ID: 8d9ac18a11d89e6b0415f0cbf67b928ac67f0e79
+ OpenBSD-Regress-ID: a41a5c43a61b0f0b1691994dbf16dfb88e8af933
-commit 68af80e6fdeaeb79432209db614386ff0f37e75f
+commit 15bfafc1db4c8792265ada9623a96f387990f732
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Wed Oct 25 00:19:47 2017 +0000
+Date: Fri May 1 04:00:29 2020 +0000
- upstream commit
+ upstream: make mktestdata.sh generate old/new format keys that we
- add a "rdomain" criteria for the sshd_config Match
- keyword to allow conditional configuration that depends on which rdomain(4) a
- connection was recevied on. ok markus@
+ expect. This script was written before OpenSSH switched to new-format private
+ keys by default and was never updated to the change (until now) From Michael
+ Forney
- Upstream-ID: 27d8fd5a3f1bae18c9c6e533afdf99bff887a4fb
+ OpenBSD-Regress-ID: 38cf354715c96852e5b71c2393fb6e7ad28b7ca7
-commit 35eb33fb957979e3fcbe6ea0eaee8bf4a217421a
+commit 7882d2eda6ad3eb82220a85294de545d20ef82db
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Wed Oct 25 00:17:08 2017 +0000
+Date: Fri May 1 03:58:02 2020 +0000
- upstream commit
+ upstream: portability fix for sed that always emil a newline even
- add sshd_config RDomain keyword to place sshd and the
- subsequent user session (including the shell and any TCP/IP forwardings) into
- the specified rdomain(4)
+ if the input does not contain one; from Michael Forney
- ok markus@
-
- Upstream-ID: be2358e86346b5cacf20d90f59f980b87d1af0f5
+ OpenBSD-Regress-ID: 9190c3ddf0d2562ccc02c4a95fce0e392196bfc7
-commit acf559e1cffbd1d6167cc1742729fc381069f06b
+commit 8074f9499e454df0acdacea33598858a1453a357
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Wed Oct 25 00:15:35 2017 +0000
+Date: Fri May 1 03:36:25 2020 +0000
- upstream commit
-
- Add optional rdomain qualifier to sshd_config's
- ListenAddress option to allow listening on a different rdomain(4), e.g.
+ upstream: remove obsolete RSA1 test keys; spotted by Michael Forney
- ListenAddress 0.0.0.0 rdomain 4
+ OpenBSD-Regress-ID: 6384ba889594e217d166908ed8253718ab0866da
+
+commit c697e46c314aa94574af0d393d80f23e0ebc9748
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Sat May 2 18:34:47 2020 +1000
+
+ Update .depend.
+
+commit 83657eac42941f270c4b02b2c46d9a21f616ef99
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Sat May 2 18:29:40 2020 +1000
+
+ Remove use of tail for 'make depend'.
- Upstream-ID: 24b6622c376feeed9e9be8b9605e593695ac9091
+ Not every tail supports +N and we can do with out it so just remove it.
+ Prompted by mforney at mforney.org.
-commit b9903ee8ee8671b447fc260c2bee3761e26c7227
-Author: millert@openbsd.org <millert@openbsd.org>
-Date: Tue Oct 24 19:41:45 2017 +0000
+commit d25d630d24c5a1c64d4e646510e79dc22d6d7b88
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Sat May 2 07:19:43 2020 +0000
- upstream commit
+ upstream: we have a sshkey_save_public() function to save public keys;
+
+ use it and save a bunch of redundant code.
- Kill dead store and some spaces vs. tabs indent in
- parse_user_host_path(). Noticed by markus@
+ Patch from loic AT venez.fr; ok markus@ djm@
- Upstream-ID: 114fec91dadf9af46c7c94fd40fc630ea2de8200
+ OpenBSD-Commit-ID: f93e030a0ebcd0fd9054ab30db501ec63454ea5f
-commit 0869627e00f4ee2a038cb62d7bd9ffad405e1800
-Author: jmc@openbsd.org <jmc@openbsd.org>
-Date: Tue Oct 24 06:27:42 2017 +0000
+commit e9dc9863723e111ae05e353d69df857f0169544a
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Fri May 1 18:32:25 2020 +1000
- upstream commit
+ Use LONG_LONG_MAX and friends if available.
- tweak previous; ok djm
+ If we don't have LLONG_{MIN,MAX} but do have LONG_LONG_{MIN,MAX}
+ then use those instead. We do calculate these values in configure,
+ but it turns out that at least one compiler (old HP ANSI C) can't
+ parse "-9223372036854775808LL" without mangling it. (It can parse
+ "-9223372036854775807LL" which is presumably why its limits.h defines
+ LONG_LONG_MIN as the latter minus 1.)
- Upstream-ID: 7d913981ab315296be1f759c67b6e17aea38fca9
+ Fixes rekey test when compiled with the aforementioned compiler.
-commit e3fa20e2e58fdc88a0e842358778f2de448b771b
-Author: Damien Miller <djm@mindrot.org>
-Date: Mon Oct 23 16:25:24 2017 +1100
+commit aad87b88fc2536b1ea023213729aaf4eaabe1894
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Fri May 1 06:31:42 2020 +0000
- avoid -Wsign-compare warning in argv copying
+ upstream: when receving a file in sink(), be careful to send at
+
+ most a single error response after the file has been opened. Otherwise the
+ source() and sink() can become desyncronised. Reported by Daniel Goujot,
+ Georges-Axel Jaloyan, Ryan Lahfa, and David Naccache.
+
+ ok deraadt@ markus@
+
+ OpenBSD-Commit-ID: 6c14d233c97349cb811a8f7921ded3ae7d9e0035
-commit b7548b12a6b2b4abf4d057192c353147e0abba08
+commit 31909696c4620c431dd55f6cd15db65c4e9b98da
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Mon Oct 23 05:08:00 2017 +0000
+Date: Fri May 1 06:28:52 2020 +0000
- upstream commit
+ upstream: expose vasnmprintf(); ok (as part of other commit) markus
- Expose devices allocated for tun/tap forwarding.
+ deraadt
- At the client, the device may be obtained from a new %T expansion
- for LocalCommand.
+ OpenBSD-Commit-ID: 2e80cea441c599631a870fd40307d2ade5a7f9b5
+
+commit 99ce9cefbe532ae979744c6d956b49f4b02aff82
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Fri May 1 04:23:11 2020 +0000
+
+ upstream: avoid NULL dereference when attempting to convert invalid
- At the server, the allocated devices will be listed in a
- SSH_TUNNEL variable exposed to the environment of any user sessions
- started after the tunnel forwarding was established.
+ ssh.com private keys using "ssh-keygen -i"; spotted by Michael Forney
- ok markus
-
- Upstream-ID: e61e53f8ae80566e9ddc0d67a5df5bdf2f3c9f9e
+ OpenBSD-Commit-ID: 2e56e6d26973967d11d13f56ea67145f435bf298
-commit 887669ef032d63cf07f53cada216fa8a0c9a7d72
-Author: millert@openbsd.org <millert@openbsd.org>
-Date: Sat Oct 21 23:06:24 2017 +0000
+commit 6c6072ba8b079e6f5caa38b011a6f4570c14ed38
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Fri May 1 15:09:26 2020 +1000
- upstream commit
+ See if SA_RESTART signals will interrupt select().
- Add URI support to ssh, sftp and scp. For example
- ssh://user@host or sftp://user@host/path. The connection parameters
- described in draft-ietf-secsh-scp-sftp-ssh-uri-04 are not implemented since
- the ssh fingerprint format in the draft uses md5 with no way to specify the
- hash function type. OK djm@
+ On some platforms (at least older HP-UXes such as 11.11, possibly others)
+ setting SA_RESTART on signal handers will cause it to not interrupt
+ select(), at least for calls that do not specify a timeout. Try to
+ detect this and if found, don't use SA_RESTART.
- Upstream-ID: 4ba3768b662d6722de59e6ecb00abf2d4bf9cacc
+ POSIX says "If SA_RESTART has been set for the interrupting signal, it
+ is implementation-dependent whether select() restarts or returns with
+ [EINTR]" so this behaviour is within spec.
+
+commit 90a0b434ed41f9c505662dba8782591818599cb3
+Author: Damien Miller <djm@mindrot.org>
+Date: Fri May 1 13:55:03 2020 +1000
+
+ fix reversed test
-commit d27bff293cfeb2252f4c7a58babe5ad3262c6c98
+commit c0dfd18dd1c2107c73d18f70cd164f7ebd434b08
Author: Damien Miller <djm@mindrot.org>
-Date: Fri Oct 20 13:22:00 2017 +1100
+Date: Fri May 1 13:29:16 2020 +1000
- Fix missed RCSID merges
+ wrap sha2.h inclusion in #ifdef HAVE_SHA2_H
-commit d3b6aeb546242c9e61721225ac4387d416dd3d5e
+commit a01817a9f63dbcbbc6293aacc4019993a4cdc7e3
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Oct 20 02:13:41 2017 +0000
+Date: Tue Apr 28 04:59:29 2020 +0000
- upstream commit
+ upstream: adapt dummy FIDO middleware to API change; ok markus@
- more RCSIDs
+ OpenBSD-Regress-ID: 8bb84ee500c2eaa5616044314dd0247709a1790f
+
+commit 261571ddf02ea38fdb5e4a97c69ee53f847ca5b7
+Author: jmc@openbsd.org <jmc@openbsd.org>
+Date: Thu Apr 30 18:28:37 2020 +0000
+
+ upstream: tweak previous; ok markus
- Upstream-Regress-ID: 1aecbe3f8224793f0ec56741a86d619830eb33be
+ OpenBSD-Commit-ID: 41895450ce2294ec44a5713134491cc31f0c09fd
-commit b011edbb32e41aaab01386ce4c0efcc9ff681c4a
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Oct 20 01:56:39 2017 +0000
+commit 5de21c82e1d806d3e401b5338371e354b2e0a66f
+Author: markus@openbsd.org <markus@openbsd.org>
+Date: Thu Apr 30 17:12:20 2020 +0000
- upstream commit
+ upstream: bring back debug() removed in rev 1.74; noted by pradeep
- add RCSIDs to these; they make syncing portable a bit
- easier
+ kumar
- Upstream-ID: 56cb7021faea599736dd7e7f09c2e714425b1e68
+ OpenBSD-Commit-ID: 8d134d22ab25979078a3b48d058557d49c402e65
-commit 6eb27597781dccaf0ec2b80107a9f0592a0cb464
-Author: Damien Miller <djm@mindrot.org>
-Date: Fri Oct 20 12:54:15 2017 +1100
+commit ea14103ce9a5e13492e805f7e9277516ff5a4273
+Author: markus@openbsd.org <markus@openbsd.org>
+Date: Thu Apr 30 17:07:10 2020 +0000
- upstream commit
+ upstream: run the 2nd ssh with BatchMode for scp -3
- Apply missing commit 1.11 to kexc25519s.c
-
- Upstream-ID: 5f020e23a1ee6c3597af1f91511e68552cdf15e8
+ OpenBSD-Commit-ID: 77994fc8c7ca02d88e6d0d06d0f0fe842a935748
-commit 6f72280553cb6918859ebcacc717f2d2fafc1a27
-Author: Damien Miller <djm@mindrot.org>
-Date: Fri Oct 20 12:52:50 2017 +1100
+commit 59d2de956ed29aa5565ed5e5947a7abdb27ac013
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Tue Apr 28 04:02:29 2020 +0000
- upstream commit
+ upstream: when signing a challenge using a FIDO toke, perform the
- Apply missing commit 1.127 to servconf.h
+ hashing in the middleware layer rather than in ssh code. This allows
+ middlewares that call APIs that perform the hashing implicitly (including
+ Microsoft's AFAIK). ok markus@
- Upstream-ID: f14c4bac74a2b7cf1e3cff6bea5c447f192a7d15
+ OpenBSD-Commit-ID: c9fc8630aba26c75d5016884932f08a5a237f37d
-commit bb3e16ab25cb911238c2eb7455f9cf490cb143cc
-Author: jmc@openbsd.org <jmc@openbsd.org>
-Date: Wed Oct 18 05:36:59 2017 +0000
+commit c9d10dbc0ccfb1c7568bbb784f7aeb7a0b5ded12
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Sun Apr 26 09:38:14 2020 +0000
- upstream commit
-
- remove unused Pp;
+ upstream: Fix comment typo. Patch from mforney at mforney.org.
- Upstream-ID: 8ad26467f1f6a40be887234085a8e01a61a00550
+ OpenBSD-Commit-ID: 3565f056003707a5e678e60e03f7a3efd0464a2b
-commit 05b69e99570553c8e1eafb895b1fbf1d098d2e14
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Wed Oct 18 02:49:44 2017 +0000
+commit 4d2c87b4d1bde019cdd0f00552fcf97dd8b39940
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Sat Apr 25 06:59:36 2020 +0000
- upstream commit
+ upstream: We've standardized on memset over bzero, replace a couple
- In the description of pattern-lists, clarify negated
- matches by explicitly stating that a negated match will never yield a
- positive result, and that at least one positive term in the pattern-list must
- match. bz#1918
+ that had slipped in. ok deraadt markus djm.
- Upstream-ID: 652d2f9d993f158fc5f83cef4a95cd9d95ae6a14
+ OpenBSD-Commit-ID: f5be055554ee93e6cc66b0053b590bef3728dbd6
-commit eb80e26a15c10bc65fed8b8cdb476819a713c0fd
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Oct 13 21:13:54 2017 +0000
+commit 7f23f42123d64272a7b00754afa6b0841d676691
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Fri May 1 12:21:58 2020 +1000
- upstream commit
+ Include sys/byteorder.h for htons and friends.
- log debug messages sent to peer; ok deraadt markus
+ These are usually in netinet/in.h but on HP-UX they are not defined if
+ _XOPEN_SOURCE_EXTENDED is set. Only needed for netcat in the regression
+ tests.
+
+commit d27cba58c972d101a5de976777e518f34ac779cb
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Fri May 1 09:21:52 2020 +1000
+
+ Fix conditional for openssl-based chacha20.
- Upstream-ID: 3b4fdc0a06ea5083f61d96e20043000f477103d9
+ Fixes warnings or link errors when building against older OpenSSLs.
+ ok djm
-commit 071325f458d615d7740da5c1c1d5a8b68a0b4605
-Author: jmc@openbsd.org <jmc@openbsd.org>
-Date: Fri Oct 13 16:50:45 2017 +0000
+commit 20819b962dc1467cd6fad5486a7020c850efdbee
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Fri Apr 24 15:07:55 2020 +1000
- upstream commit
+ Error out if given RDomain if unsupported.
- trim permitrootlogin description somewhat, to avoid
- ambiguity; original diff from walter alejandro iglesias, tweaked by sthen and
- myself
+ If the config contained 'RDomain %D' on a platform that did not support
+ it, the error would not be detected until runtime resulting in a broken
+ sshd. Detect this earlier and error out if found. bz#3126, based on a
+ patch from jjelen at redhat.com, tweaks and ok djm@
+
+commit 2c1690115a585c624eed2435075a93a463a894e2
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Fri Apr 24 03:33:21 2020 +0000
+
+ upstream: Fix incorrect error message for "too many known hosts files."
- ok sthen schwarze deraadt
+ bz#3149, patch from jjelen at redhat.com.
- Upstream-ID: 1749418b2bc073f3fdd25fe21f8263c3637fe5d2
+ OpenBSD-Commit-ID: e0fcb07ed5cf7fd54ce340471a747c24454235e5
-commit 10727487becb897a15f658e0cb2d05466236e622
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Oct 13 06:45:18 2017 +0000
+commit 3beb7276e7a8aedd3d4a49f9c03b97f643448c92
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Fri Apr 24 02:19:40 2020 +0000
- upstream commit
+ upstream: Remove leave_non_blocking() which is now dead code
- mention SSH_USER_AUTH in the list of environment
- variables
+ because nothing sets in_non_blocking_mode any more. Patch from
+ michaael.meeks at collabora.com, ok djm@
- Upstream-ID: 1083397c3ee54b4933121ab058c70a0fc6383691
+ OpenBSD-Commit-ID: c403cefe97a5a99eca816e19cc849cdf926bd09c
-commit 224f193d6a4b57e7a0cb2b9ecd3b6c54d721d8c2
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Oct 13 06:24:51 2017 +0000
+commit 8654e3561772f0656e7663a0bd6a1a8cb6d43300
+Author: jmc@openbsd.org <jmc@openbsd.org>
+Date: Thu Apr 23 21:28:09 2020 +0000
- upstream commit
+ upstream: ce examples of "Ar arg Ar arg" with "Ar arg arg" and
- BIO_get_mem_data() is supposed to take a char* as pointer
- argument, so don't pass it a const char*
+ stop the spread;
- Upstream-ID: 1ccd91eb7f4dd4f0fa812d4f956987cd00b5f6ec
+ OpenBSD-Commit-ID: af0e952ea0f5e2019c2ce953ed1796eca47f0705
-commit cfa46825b5ef7097373ed8e31b01a4538a8db565
-Author: benno@openbsd.org <benno@openbsd.org>
-Date: Mon Oct 9 20:12:51 2017 +0000
+commit 67697e4a8246dd8423e44b8785f3ee31fee72d07
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Fri Apr 24 11:10:18 2020 +1000
- upstream commit
-
- clarify the order in which config statements are used. ok
- jmc@ djm@
+ Update .depend.
+
+commit d6cc76176216fe3fac16cd20d148d75cb9c50876
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Wed Apr 22 14:07:00 2020 +1000
+
+ Mailing list is now closed to non-subscribers.
- Upstream-ID: e37e27bb6bbac71315e22cb9690fd8a556a501ed
+ While there, add a reference to the bugzilla. ok djm@
-commit dceabc7ad7ebc7769c8214a1647af64c9a1d92e5
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Thu Oct 5 15:52:03 2017 +0000
+commit cecde6a41689d0ae585ec903b190755613a6de79
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Wed Apr 22 12:09:40 2020 +1000
- upstream commit
+ Put the values from env vars back.
- replace statically-sized arrays in ServerOptions with
- dynamic ones managed by xrecallocarray, removing some arbitrary (though
- large) limits and saving a bit of memory; "much nicer" markus@
+ This merges the values from the recently removed environment into make's
+ command line arguments since we actually need those.
+
+commit 300c4322b92e98d3346efa0aec1c094c94d0f964
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Wed Apr 22 11:33:15 2020 +1000
+
+ Pass configure's egrep through to test-exec.sh.
- Upstream-ID: 1732720b2f478fe929d6687ac7b0a97ff2efe9d2
+ Use it to create a wrapper function to call it from tests. Fixes the
+ keygen-comment test on platforms with impoverished default egrep (eg
+ Solaris).
-commit 2b4f3ab050c2aaf6977604dd037041372615178d
-Author: jmc@openbsd.org <jmc@openbsd.org>
-Date: Thu Oct 5 12:56:50 2017 +0000
+commit c8d9796cfe046f00eb8b2096d2b7028d6a523a84
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Wed Apr 22 10:56:44 2020 +1000
- upstream commit
+ Remove unneeded env vars from t-exec invocation.
+
+commit 01d4cdcd4514e99a4b6eb9523cd832bbf008d1d7
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Tue Apr 21 23:14:58 2020 +0000
+
+ upstream: Backslash '$' at then end of string. Prevents warning on
+
+ some shells.
- %C is hashed; from klemens nanni ok markus
+ OpenBSD-Regress-ID: 5dc27ab624c09d34078fd326b10e38c1ce9c741f
+
+commit 8854724ccefc1fa16f10b37eda2e759c98148caa
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Tue Apr 21 18:27:23 2020 +1000
+
+ Sync rev 1.49.
- Upstream-ID: 6ebed7b2e1b6ee5402a67875d74f5e2859d8f998
+ Prevent infinite for loop since i went from ssize_t to size_t. Patch from
+ eagleoflqj via OpenSSH github PR#178, ok djm@, feedback & ok millert@
-commit a66714508b86d6814e9055fefe362d9fe4d49ab3
+commit d00d07b6744d3b4bb7aca46c734ecd670148da23
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Wed Oct 4 18:50:23 2017 +0000
+Date: Mon Apr 20 04:44:47 2020 +0000
- upstream commit
+ upstream: regression test for printing of private key fingerprints and
- exercise PermitOpen a little more thoroughly
+ key comments, mostly by loic AT venez.fr (slightly tweaked for portability)
+ ok dtucker@
- Upstream-Regress-ID: f41592334e227a4c1f9a983044522de4502d5eac
+ OpenBSD-Regress-ID: 8dc6c4feaf4fe58b6d634cd89afac9a13fd19004
-commit 609ecc8e57eb88e2eac976bd3cae7f7889aaeff6
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Tue Sep 26 22:39:25 2017 +0000
+commit a98d5ba31e5e7e01317352f85fa63b846a960f8c
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Mon Apr 20 04:43:57 2020 +0000
- upstream commit
+ upstream: fix a bug I introduced in r1.406: when printing private key
- UsePrivilegeSeparation is gone, stop trying to test it.
+ fingerprint of old-format key, key comments were not being displayed. Spotted
+ by loic AT venez.fr, ok dtucker
- Upstream-Regress-ID: 796a5057cfd79456a20ea935cc53f6eb80ace191
+ OpenBSD-Commit-ID: 2d98e4f9eb168eea733d17e141e1ead9fe26e533
-commit 69bda0228861f3dacd4fb3d28b60ce9d103d254b
+commit 32f2d0aad42c15e19bd3b07496076ca891573a58
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Wed Oct 4 18:49:30 2017 +0000
+Date: Fri Apr 17 07:16:07 2020 +0000
- upstream commit
+ upstream: repair private key fingerprint printing to also print
- fix (another) problem in PermitOpen introduced during the
- channels.c refactor: the third and subsequent arguments to PermitOpen were
- being silently ignored; ok markus@
+ comment after regression caused by my recent pubkey loading refactor.
+ Reported by loic AT venez.fr, ok dtucker@
- Upstream-ID: 067c89f1f53cbc381628012ba776d6861e6782fd
+ OpenBSD-Commit-ID: f8db49acbee6a6ccb2a4259135693b3cceedb89e
-commit 66bf74a92131b7effe49fb0eefe5225151869dc5
+commit 094dd513f4b42e6a3cebefd18d1837eb709b4d99
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Mon Oct 2 19:33:20 2017 +0000
+Date: Fri Apr 17 07:15:11 2020 +0000
- upstream commit
+ upstream: refactor out some duplicate private key loading code;
- Fix PermitOpen crash; spotted by benno@, ok dtucker@ deraadt@
+ based on patch from loic AT venez.fr, ok dtucker@
- Upstream-ID: c2cc84ffac070d2e1ff76182c70ca230a387983c
+ OpenBSD-Commit-ID: 5eff2476b0d8d0614924c55e350fb7bb9c84f45e
-commit d63b38160a59039708fd952adc75a0b3da141560
-Author: Damien Miller <djm@mindrot.org>
-Date: Sun Oct 1 10:32:25 2017 +1100
+commit 4e04f46f248f1708e39b900b76c9693c820eff68
+Author: jmc@openbsd.org <jmc@openbsd.org>
+Date: Fri Apr 17 06:12:41 2020 +0000
- update URL again
+ upstream: add space beteen macro arg and punctuation;
- I spotted a typo in the draft so uploaded a new version...
+ OpenBSD-Commit-ID: c93a6cbb4bf9468fc4c13e64bc1fd4efee201a44
-commit 6f64f596430cd3576c529f07acaaf2800aa17d58
-Author: Damien Miller <djm@mindrot.org>
-Date: Sun Oct 1 10:01:56 2017 +1100
+commit 44ae009a0112081d0d541aeaa90088bedb6f21ce
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Fri Apr 17 04:27:03 2020 +0000
- sync release notes URL
+ upstream: auth2-pubkey r1.89 changed the order of operations to
+
+ checking AuthorizedKeysFile first and falling back to AuthorizedKeysCommand
+ if no key was found in a file. Document this order here; bz3134
+
+ OpenBSD-Commit-ID: afce0872cbfcfc1d4910ad7722e50f792a1dce12
-commit 35ff70a04dd71663a5ac1e73b90d16d270a06e0d
+commit f96f17f920f38ceea6f3c5cb0b075c46b8929fdc
Author: Damien Miller <djm@mindrot.org>
-Date: Sun Oct 1 10:01:25 2017 +1100
+Date: Fri Apr 17 14:07:15 2020 +1000
- sync contrib/ssh-copy-id with upstream
+ sys/sysctl.h is only used on OpenBSD
+
+ so change the preprocessor test used to include it to check
+ __OpenBSD__, matching the code that uses the symbols it declares.
-commit 290843b8ede85f8b30bf29cd7dceb805c3ea5b66
-Author: Damien Miller <djm@mindrot.org>
-Date: Sun Oct 1 09:59:19 2017 +1100
+commit 54688e937a69c7aebef8a3d50cbd4c6345bab2ca
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Fri Apr 17 03:38:47 2020 +0000
- update version in RPM spec files
+ upstream: fix reversed test that caused IdentitiesOnly=yes to not
+
+ apply to keys loaded from a PKCS11Provider; bz3141, ok dtucker@
+
+ OpenBSD-Commit-ID: e3dd6424b94685671fe84c9b9dbe352fb659f677
-commit 4e4e0bb223c5be88d87d5798c75cc6b0d4fef31d
-Author: Damien Miller <djm@mindrot.org>
-Date: Sun Oct 1 09:58:24 2017 +1100
+commit 267cbc87b5b6e78973ac4d3c7a6f807ed226928c
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Fri Apr 17 03:34:42 2020 +0000
- update agent draft URL
+ upstream: mention that /etc/hosts.equiv and /etc/shosts.equiv are
+
+ not considered for HostbasedAuthentication when the target user is root;
+ bz3148
+
+ OpenBSD-Commit-ID: fe4c1256929e53f23af17068fbef47852f4bd752
-commit e4a798f001d2ecd8bf025c1d07658079f27cc604
+commit c90f72d29e84b4a2709078bf5546a72c29a65177
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sat Sep 30 22:26:33 2017 +0000
+Date: Fri Apr 17 03:30:05 2020 +0000
- upstream commit
+ upstream: make IgnoreRhosts a tri-state option: "yes" ignore
- openssh-7.6; ok deraadt@
+ rhosts/shosts, "no" allow rhosts/shosts or (new) "shosts-only" to allow
+ .shosts files but not .rhosts. ok dtucker@
- Upstream-ID: a39c3a5b63a1baae109ae1ae4c7c34c2a59acde0
+ OpenBSD-Commit-ID: d08d6930ed06377a80cf53923c1955e9589342e9
-commit 5fa1407e16e7e5fda9769d53b626ce39d5588d4d
-Author: jmc@openbsd.org <jmc@openbsd.org>
-Date: Wed Sep 27 06:45:53 2017 +0000
+commit 321c7147079270f3a154f91b59e66219aac3d514
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Fri Apr 17 03:23:13 2020 +0000
- upstream commit
+ upstream: allow the IgnoreRhosts directive to appear anywhere in a
- tweak EposeAuthinfo; diff from lars nooden
+ sshd_config, not just before any Match blocks; bz3148, ok dtucker@
- tweaked by sthen; ok djm dtucker
-
- Upstream-ID: 8f2ea5d2065184363e8be7a0ba24d98a3b259748
+ OpenBSD-Commit-ID: e042467d703bce640b1f42c5d1a62bf3825736e8
-commit bba69c246f0331f657fd6ec97724df99fc1ad174
-Author: Damien Miller <djm@mindrot.org>
-Date: Thu Sep 28 16:06:21 2017 -0700
+commit ca5403b085a735055ec7b7cdcd5b91f2662df94c
+Author: jmc@openbsd.org <jmc@openbsd.org>
+Date: Sat Apr 11 20:20:09 2020 +0000
- don't fatal ./configure for LibreSSL
+ upstream: add space between macro arg and punctuation;
+
+ OpenBSD-Commit-ID: e579e4d95eef13059c30931ea1f09ed8296b819c
-commit 04dc070e8b4507d9d829f910b29be7e3b2414913
-Author: Damien Miller <djm@mindrot.org>
-Date: Thu Sep 28 14:54:34 2017 -0700
+commit 8af0244d7b4a65eed2e62f9c89141c7c8e63f09d
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Wed Apr 15 10:58:02 2020 +1000
- abort in configure when only openssl-1.1.x found
+ Add sys/syscall.h for syscall numbers.
- We don't support openssl-1.1.x yet (see multiple threads on the
- openssh-unix-dev@ mailing list for the reason), but previously
- ./configure would accept it and the compilation would subsequently
- fail. This makes ./configure display an explicit error message and
- abort.
-
- ok dtucker@
+ In some architecture/libc configurations we need to explicitly include
+ sys/syscall.h for the syscall number (__NR_xxx) definitions. bz#3085,
+ patch from blowfist at xroutine.net.
-commit 74c1c3660acf996d9dc329e819179418dc115f2c
-Author: Darren Tucker <dtucker@zip.com.au>
-Date: Wed Sep 27 07:44:41 2017 +1000
+commit 3779b50ee952078018a5d9e1df20977f4355df17
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Sat Apr 11 10:16:11 2020 +0000
- Check for and handle calloc(p, 0) = NULL.
+ upstream: Refactor private key parsing. Eliminates a fair bit of
+
+ duplicated code and fixes oss-fuzz#20074 (NULL deref) caused by a missing key
+ type check in the ECDSA_CERT parsing path.
- On some platforms (AIX, maybe others) allocating zero bytes of memory
- via the various *alloc functions returns NULL, which is permitted
- by the standards. Autoconf has some macros for detecting this (with
- the exception of calloc for some reason) so use these and if necessary
- activate shims for them. ok djm@
+ feedback and ok markus@
+
+ OpenBSD-Commit-ID: 4711981d88afb7196d228f7baad9be1d3b20f9c9
-commit 6a9481258a77b0b54b2a313d1761c87360c5f1f5
-Author: markus@openbsd.org <markus@openbsd.org>
-Date: Thu Sep 21 19:18:12 2017 +0000
+commit b6a4013647db67ec622c144a9e05dd768f1966b3
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Fri Apr 10 00:54:03 2020 +0000
- upstream commit
+ upstream: Add tests for TOKEN expansion of LocalForward and
- test reverse dynamic forwarding with SOCKS
+ RemoteForward.
- Upstream-Regress-ID: 95cf290470f7e5e2f691e4bc6ba19b91eced2f79
+ OpenBSD-Regress-ID: 90fcbc60d510eb114a2b6eaf4a06ff87ecd80a89
-commit 1b9f321605733754df60fac8c1d3283c89b74455
-Author: Damien Miller <djm@mindrot.org>
-Date: Tue Sep 26 16:55:55 2017 +1000
+commit abc3e0a5179c13c0469a1b11fe17d832abc39999
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Mon Apr 6 09:43:55 2020 +0000
- sync missing changes in dynamic-forward.sh
+ upstream: Add utf8.c for asmprintf used by krl.c
+
+ OpenBSD-Regress-ID: 433708d11165afdb189fe635151d21659dd37a37
-commit 44fc334c7a9ebdd08addb6d5fa005369897fddeb
-Author: Darren Tucker <dtucker@zip.com.au>
-Date: Mon Sep 25 09:48:10 2017 +1000
+commit 990687a0336098566c3a854d23cce74a31ec6fe2
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Fri Apr 10 00:52:07 2020 +0000
- Add minimal strsignal for platforms without it.
+ upstream: Add TOKEN percent expansion to LocalFoward and RemoteForward
+
+ when used for Unix domain socket forwarding. Factor out the code for the
+ config keywords that use the most common subset of TOKENS into its own
+ function. bz#3014, ok jmc@ (man page bits) djm@
+
+ OpenBSD-Commit-ID: bffc9f7e7b5cf420309a057408bef55171fd0b97
-commit 218e6f98df566fb9bd363f6aa47018cb65ede196
+commit 2b13d3934d5803703c04803ca3a93078ecb5b715
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sun Sep 24 13:45:34 2017 +0000
+Date: Wed Apr 8 00:10:37 2020 +0000
- upstream commit
+ upstream: let sshkey_try_load_public() load public keys from the
- fix inverted test on channel open failure path that
- "upgraded" a transient failure into a fatal error; reported by sthen and also
- seen by benno@; ok sthen@
+ unencrypted envelope of private key files if not sidecar public key file is
+ present.
- Upstream-ID: b58b3fbb79ba224599c6cd6b60c934fc46c68472
+ ok markus@
+
+ OpenBSD-Commit-ID: 252a0a580e10b9a6311632530d63b5ac76592040
-commit c704f641f7b8777497dc82e81f2ac89afec7e401
+commit d01f39304eaab0352793b490a25e1ab5f59a5366
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sun Sep 24 09:50:01 2017 +0000
+Date: Wed Apr 8 00:09:24 2020 +0000
- upstream commit
+ upstream: simplify sshkey_try_load_public()
- write the correct buffer when tunnel forwarding; doesn't
- matter on OpenBSD (they are the same) but does matter on portable where we
- use an output filter to translate os-specific tun/tap headers
+ ok markus@
- Upstream-ID: f1ca94eff48404827b12e1d12f6139ee99a72284
+ OpenBSD-Commit-ID: 05a5d46562aafcd70736c792208b1856064f40ad
-commit 55486f5cef117354f0c64f991895835077b7c7f7
+commit f290ab0833e44355fc006e4e67b92446c14673ef
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sat Sep 23 22:04:07 2017 +0000
+Date: Wed Apr 8 00:08:46 2020 +0000
- upstream commit
+ upstream: add sshkey_parse_pubkey_from_private_fileblob_type()
+
+ Extracts a public key from the unencrypted envelope of a new-style
+ OpenSSH private key.
- fix tunnel forwarding problem introduced in refactor;
- reported by stsp@ ok markus@
+ ok markus@
- Upstream-ID: 81a731cdae1122c8522134095d1a8b60fa9dcd04
+ OpenBSD-Commit-ID: 44d7ab446e5e8c686aee96d5897b26b3939939aa
-commit 609d7a66ce578abf259da2d5f6f68795c2bda731
-Author: markus@openbsd.org <markus@openbsd.org>
-Date: Thu Sep 21 19:16:53 2017 +0000
+commit 8d514eea4ae089626a55e11c7bc1745c8d9683e4
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Wed Apr 8 00:07:19 2020 +0000
- upstream commit
-
- Add 'reverse' dynamic forwarding which combines dynamic
- forwarding (-D) with remote forwarding (-R) where the remote-forwarded port
- expects SOCKS-requests.
+ upstream: simplify sshkey_parse_private_fileblob_type()
- The SSH server code is unchanged and the parsing happens at the SSH
- clients side. Thus the full SOCKS-request is sent over the forwarded
- channel and the client parses c->output. Parsing happens in
- channel_before_prepare_select(), _before_ the select bitmask is
- computed in the pre[] handlers, but after network input processing
- in the post[] handlers.
+ Try new format parser for all key types first, fall back to PEM
+ parser only for invalid format errors.
- help and ok djm@
+ ok markus@
- Upstream-ID: aa25a6a3851064f34fe719e0bf15656ad5a64b89
+ OpenBSD-Commit-ID: 0173bbb3a5cface77b0679d4dca0e15eb5600b77
-commit 36945fa103176c00b39731e1fc1919a0d0808b81
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Wed Sep 20 05:19:00 2017 +0000
+commit 421169d0e758351b105eabfcebf42378ebf17217
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Wed Apr 8 00:05:59 2020 +0000
- upstream commit
+ upstream: check private key type against requested key type in
- Use strsignal in debug message instead of casting for the
- benefit of portable where sig_atomic_t might not be int. "much nicer"
- deraadt@
+ new-style private decoding; ok markus@
- Upstream-ID: 2dac6c1e40511c700bd90664cd263ed2299dcf79
+ OpenBSD-Commit-ID: 04d44b3a34ce12ce5187fb6f6e441a88c8c51662
-commit 3e8d185af326bf183b6f78597d5e3d2eeb2dc40e
-Author: millert@openbsd.org <millert@openbsd.org>
-Date: Tue Sep 19 12:10:30 2017 +0000
+commit 6aabfb6d22b36d07f584cba97f4cdc4363a829da
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Wed Apr 8 00:04:32 2020 +0000
- upstream commit
+ upstream: check that pubkey in private key envelope matches actual
+
+ private key
- Use explicit_bzero() instead of bzero() before free() to
- prevent the compiler from optimizing away the bzero() call. OK djm@
+ (this public key is currently unusued)
+
+ ok markus@
- Upstream-ID: cdc6197e64c9684c7250e23d60863ee1b53cef1d
+ OpenBSD-Commit-ID: 634a60b5e135d75f48249ccdf042f3555112049c
-commit 5b8da1f53854c0923ec6e927e86709e4d72737b6
+commit c0f5b2294796451001fd328c44f0d00f1114eddf
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Tue Sep 19 04:24:22 2017 +0000
+Date: Wed Apr 8 00:01:52 2020 +0000
- upstream commit
+ upstream: refactor private key parsing a little
+
+ Split out the base64 decoding and private section decryption steps in
+ to separate functions. This will make the decryption step easier to fuzz
+ as well as making it easier to write a "load public key from new-format
+ private key" function.
- fix use-after-free in ~^Z escape handler path, introduced
- in channels.c refactor; spotted by millert@ "makes sense" deraadt@
+ ok markus@
- Upstream-ID: 8fa2cdc65c23ad6420c1e59444b0c955b0589b22
+ OpenBSD-Commit-ID: 7de31d80fb9062aa01901ddf040c286b64ff904e
-commit a3839d8d2b89ff1a80cadd4dd654336710de2c9e
+commit 8461a5b3db34ed0b5a4a18d82f64fd5ac8693ea8
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Mon Apr 6 20:54:34 2020 +1000
+
+ Include openssl-compat.h before checking ifdefs.
+
+ Fixes problem where unsuitable chacha20 code in libressl would be used
+ unintentionally.
+
+commit 931c50c5883a9910ea1ae9a371e4e815ec56b035
+Author: Damien Miller <djm@mindrot.org>
+Date: Mon Apr 6 10:04:56 2020 +1000
+
+ fix inverted test for LibreSSL version
+
+commit d1d5f728511e2338b7c994968d301d8723012264
Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Mon Sep 18 12:03:24 2017 +0000
+Date: Sat Apr 4 23:04:41 2020 +0000
- upstream commit
+ upstream: Indicate if we're using a cached key in trace output.
- Prevent type mismatch warning in debug on platforms where
- sig_atomic_t != int. ok djm@
+ OpenBSD-Regress-ID: 409a7b0e59d1272890fda507651c0c3d2d3c0d89
+
+commit a398251a4627367c78bc483c70c2ec973223f82c
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Sun Apr 5 08:43:57 2020 +1000
+
+ Use /usr/bin/xp4g/id if necessary.
- Upstream-ID: 306e2375eb0364a4c68e48f091739bea4f4892ed
+ Solaris' native "id" doesn't support the options we use but the one
+ in /usr/bin/xp4g does, so use that instead.
-commit 30484e5e5f0b63d2c6ba32c6b85f06b6c6fa55fc
+commit db0fdd48335b5b01114f78c1a73a195235910f81
Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Mon Sep 18 09:41:52 2017 +0000
+Date: Sat Apr 4 22:14:26 2020 +0000
- upstream commit
+ upstream: Some platforms don't have "hostname -s", so use cut to trim
- Add braces missing after channels refactor. ok markus@
+ short hostname instead.
- Upstream-ID: 72ab325c84e010680dbc88f226e2aa96b11a3980
+ OpenBSD-Regress-ID: ebcf36a6fdf287c9336b0d4f6fc9f793c05307a7
-commit b79569190b9b76dfacc6d996faa482f16e8fc026
-Author: Damien Miller <djm@mindrot.org>
-Date: Tue Sep 19 12:29:23 2017 +1000
+commit e7e59a9cc8eb7fd5944ded28f4d7e3ae0a5fdecd
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Fri Apr 3 07:53:10 2020 +0000
- add freezero(3) replacement
+ upstream: Compute hash locally and re-enable %C tests.
- ok dtucker@
+ OpenBSD-Regress-ID: 94d1366e8105274858b88a1f9ad2e62801e49770
-commit 161af8f5ec0961b10cc032efb5cc1b44ced5a92e
+commit abe2b245b3ac6c4801e99bc0f13289cd28211e22
Author: Damien Miller <djm@mindrot.org>
-Date: Tue Sep 19 10:18:56 2017 +1000
+Date: Fri Apr 3 17:25:46 2020 +1100
- move FORTIFY_SOURCE into hardening options group
-
- It's still on by default, but now it's possible to turn it off using
- --without-hardening. This is useful since it's known to cause problems
- with some -fsanitize options. ok dtucker@
+ prefer libcrypto chacha20-poly1305 where possible
-commit 09eacf856e0fe1a6e3fe597ec8032b7046292914
-Author: bluhm@openbsd.org <bluhm@openbsd.org>
-Date: Wed Sep 13 14:58:26 2017 +0000
+commit bc5c5d01ad668981f9e554e62195383bc12e8528
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Fri Apr 3 05:43:11 2020 +0000
- upstream commit
+ upstream: Temporarily remove tests for '%C' since the hash contains the
- Print SKIPPED if sudo and doas configuration is missing.
- Prevents that running the regression test with wrong environment is reported
- as failure. Keep the fatal there to avoid interfering with other setups for
- portable ssh. OK dtucker@
+ local hostname and it doesn't work on any machine except mine... spotted by
+ djm@
- Upstream-Regress-ID: f0dc60023caef496ded341ac5aade2a606fa234e
+ OpenBSD-Regress-ID: 2d4c3585b9fcbbff14f4a5a5fde51dbd0d690401
-commit cdede10899892f25f1ccdccd7a3fe5e5ef0aa49a
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Mon Aug 7 03:52:55 2017 +0000
+commit 81624026989654955a657ebf2a1fe8b9994f3c87
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Fri Apr 3 06:07:57 2020 +0000
- upstream commit
+ upstream: r1.522 deleted one too many lines; repair
- Remove obsolete privsep=no fallback test.
+ OpenBSD-Commit-ID: 1af8851fd7a99e4a887b19aa8f4c41a6b3d25477
+
+commit 668cb3585ce829bd6e34d4a962c489bda1d16370
+Author: jmc@openbsd.org <jmc@openbsd.org>
+Date: Fri Apr 3 05:53:52 2020 +0000
+
+ upstream: sort -N and add it to usage();
- Upstream-Regress-ID: 7d6e1baa1678ac6be50c2a1555662eb1047638df
+ OpenBSD-Commit-ID: 5b00e8db37c2b0a54c7831fed9e5f4db53ada332
-commit ec218c105daa9f5b192f7aa890fdb2d4fdc4e9d8
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Mon Aug 7 00:53:51 2017 +0000
+commit 338ccee1e7fefa47f3d128c2541e94c5270abe0c
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Fri Apr 3 05:48:57 2020 +0000
- upstream commit
+ upstream: avoid another compiler warning spotted in -portable
- Remove non-privsep test since disabling privsep is now
- deprecated.
+ OpenBSD-Commit-ID: 1d29c51ac844b287c4c8bcaf04c63c7d9ba3b8c7
+
+commit 9f8a42340bd9af86a99cf554dc39ecdf89287544
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Fri Apr 3 04:07:48 2020 +0000
+
+ upstream: this needs utf8.c too
- Upstream-Regress-ID: 77ad3f3d8d52e87f514a80f285c6c1229b108ce8
+ OpenBSD-Regress-ID: 445040036cec714d28069a20da25553a04a28451
-commit 239c57d5bc2253e27e3e6ad7ac52ec8c377ee24e
+commit 92115ea7c3a834374720c350841fc729e7d5c8b2
Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Fri Jul 28 10:32:08 2017 +0000
+Date: Fri Apr 3 03:14:03 2020 +0000
- upstream commit
+ upstream: Add percent_expand test for 'Match Exec'.
- Don't call fatal from stop_sshd since it calls cleanup
- which calls stop_sshd which will probably fail in the same way. Instead,
- just bail. Differentiate between sshd dying without cleanup and not shutting
- down.
-
- Upstream-Regress-ID: f97315f538618b349e2b0bea02d6b0c9196c6bc4
+ OpenBSD-Regress-ID: a41c14fd6a0b54d66aa1e9eebfb9ec962b41232f
-commit aea59a0d9f120f2a87c7f494a0d9c51eaa79b8ba
+commit de34a440276ae855c38deb20f926d46752c62c9d
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Thu Sep 14 04:32:21 2017 +0000
+Date: Fri Apr 3 04:43:24 2020 +0000
- upstream commit
+ upstream: fix format string (use %llu for uint64, not %lld). spotted by
- Revert commitid: gJtIN6rRTS3CHy9b.
+ Darren and his tinderbox tests
- -------------
- identify the case where SSHFP records are missing but other DNS RR
- types are present and display a more useful error message for this
- case; patch by Thordur Bjornsson; bz#2501; ok dtucker@
- -------------
-
- This caused unexpected failures when VerifyHostKeyDNS=yes, SSHFP results
- are missing but the user already has the key in known_hosts
+ OpenBSD-Commit-ID: 3b4587c3d9d46a7be9bdf028704201943fba96c2
+
+commit 9cd40b829a5295cc81fbea8c7d632b2478db6274
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Fri Apr 3 04:34:15 2020 +0000
+
+ upstream: Add a flag to re-enable verbose output when in batch
- Spotted by dtucker@
+ mode; requested in bz3135; ok dtucker
- Upstream-ID: 97e31742fddaf72046f6ffef091ec0d823299920
+ OpenBSD-Commit-ID: 5ad2ed0e6440562ba9c84b666a5bbddc1afe2e2b
-commit 871f1e4374420b07550041b329627c474abc3010
-Author: Damien Miller <djm@mindrot.org>
-Date: Tue Sep 12 18:01:35 2017 +1000
+commit 6ce51a5da5d333a44e7c74c027f3571f70c39b24
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Fri Apr 3 04:32:21 2020 +0000
- adapt portable to channels API changes
+ upstream: chacha20-poly1305 AEAD using libcrypto EVP_chacha20
+
+ Based on patch from Yuriy M. Kaminskiy. ok + lots of assistance along the
+ way at a2k20 tb@
+
+ OpenBSD-Commit-ID: 5e08754c13d31258bae6c5e318cc96219d6b10f0
-commit 4ec0bb9f9ad7b4eb0af110fa8eddf8fa199e46bb
+commit eba523f0a130f1cce829e6aecdcefa841f526a1a
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Tue Sep 12 07:55:48 2017 +0000
+Date: Fri Apr 3 04:27:03 2020 +0000
- upstream commit
+ upstream: make Chacha20-POLY1305 context struct opaque; ok tb@ as
- unused variable
+ part of a larger diff at a2k20
- Upstream-ID: 2f9ba09f2708993d35eac5aa71df910dcc52bac1
+ OpenBSD-Commit-ID: a4609b7263284f95c9417ef60ed7cdbb7bf52cfd
-commit 9145a73ce2ba30c82bbf91d7205bfd112529449f
+commit ebd29e90129cf18fedfcfe1de86e324228669295
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Tue Sep 12 07:32:04 2017 +0000
+Date: Fri Apr 3 04:06:26 2020 +0000
- upstream commit
+ upstream: fix debug statement
- fix tun/tap forwarding case in previous
-
- Upstream-ID: 43ebe37a930320e24bca6900dccc39857840bc53
+ OpenBSD-Commit-ID: 42c6edeeda5ce88b51a20d88c93be3729ce6b916
-commit 9f53229c2ac97dbc6f5a03657de08a1150a9ac7e
+commit 7b4d8999f2e1a0cb7b065e3efa83e6edccfc7d82
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Tue Sep 12 06:35:31 2017 +0000
+Date: Fri Apr 3 04:03:51 2020 +0000
- upstream commit
+ upstream: the tunnel-forwarding vs ExitOnForwardFailure fix that I
- Make remote channel ID a u_int
+ committed earlier had an off-by-one. Fix this and add some debugging that
+ would have made it apparent sooner.
- Previously we tracked the remote channel IDs in an int, but this is
- strictly incorrect: the wire protocol uses uint32 and there is nothing
- in-principle stopping a SSH implementation from sending, say, 0xffff0000.
+ OpenBSD-Commit-ID: 082f8f72b1423bd81bbdad750925b906e5ac6910
+
+commit eece243666d44ceb710d004624c5c7bdc05454bc
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Fri Apr 3 03:12:11 2020 +0000
+
+ upstream: %C expansion just added to Match Exec should include
- In practice everyone numbers their channels sequentially, so this has
- never been a problem.
+ remote user not local user.
- ok markus@
+ OpenBSD-Commit-ID: 80f1d976938f2a55ee350c11d8b796836c8397e2
+
+commit d5318a784d016478fc8da90a38d9062c51c10432
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Fri Apr 3 02:33:31 2020 +0000
+
+ upstream: Add regression test for percent expansions where possible.
- Upstream-ID: b9f4cd3dc53155b4a5c995c0adba7da760d03e73
+ OpenBSD-Regress-ID: 7283be8b2733ac1cbefea3048a23d02594485288
-commit dbee4119b502e3f8b6cd3282c69c537fd01d8e16
+commit 663e84bb53de2a60e56a44d538d25b8152b5c1cc
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Tue Sep 12 06:32:07 2017 +0000
+Date: Fri Apr 3 02:40:32 2020 +0000
- upstream commit
+ upstream: make failures when establishing "Tunnel" forwarding terminate
- refactor channels.c
+ the connection when ExitOnForwardFailure is enabled; bz3116; ok dtucker
- Move static state to a "struct ssh_channels" that is allocated at
- runtime and tracked as a member of struct ssh.
+ OpenBSD-Commit-ID: ef4b4808de0a419c17579b1081da768625c1d735
+
+commit ed833da176611a39d3376d62154eb88eb440d31c
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Fri Apr 3 02:27:12 2020 +0000
+
+ upstream: Make with config keywords support which
- Explicitly pass "struct ssh" to all channels functions.
+ percent_expansions more consistent. - %C is moved into its own function and
+ added to Match Exec. - move the common (global) options into a macro. This
+ is ugly but it's the least-ugly way I could come up with. - move
+ IdentityAgent and ForwardAgent percent expansion to before the config dump
+ to make it regression-testable. - document all of the above
- Replace use of the legacy packet APIs in channels.c.
+ ok jmc@ for man page bits, "makes things less terrible" djm@ for the rest.
- Rework sshd_config PermitOpen handling: previously the configuration
- parser would call directly into the channels layer. After the refactor
- this is not possible, as the channels structures are allocated at
- connection time and aren't available when the configuration is parsed.
- The server config parser now tracks PermitOpen itself and explicitly
- configures the channels code later.
+ OpenBSD-Commit-ID: 4b65664bd6d8ae2a9afaf1a2438ddd1b614b1d75
+
+commit 6ec7457171468da2bbd908b8cd63d298b0e049ea
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Fri Apr 3 02:26:56 2020 +0000
+
+ upstream: give ssh-keygen the ability to dump the contents of a
- ok markus@
+ binary key revocation list: ssh-keygen -lQf /path bz#3132; ok dtucker
- Upstream-ID: 11828f161656b965cc306576422613614bea2d8f
+ OpenBSD-Commit-ID: b76afc4e3b74ab735dbde4e5f0cfa1f02356033b
-commit abd59663df37a42152e37980113ccaa405b9a282
+commit af628b8a6c3ef403644d83d205c80ff188c97f0c
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Thu Sep 7 23:48:09 2017 +0000
+Date: Fri Apr 3 02:25:21 2020 +0000
- upstream commit
+ upstream: add allocating variant of the safe utf8 printer; ok
- typo in comment
+ dtucker as part of a larger diff
- Upstream-ID: a93b1e6f30f1f9b854b5b964b9fd092d0c422c47
+ OpenBSD-Commit-ID: 037e2965bd50eacc2ffb49889ecae41552744fa0
-commit 149a8cd24ce9dd47c36f571738681df5f31a326c
-Author: jmc@openbsd.org <jmc@openbsd.org>
-Date: Mon Sep 4 06:34:43 2017 +0000
+commit d8ac9af645f5519ac5211e9e1e4dc1ed00e9cced
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Mon Mar 16 02:17:02 2020 +0000
- upstream commit
+ upstream: Cast lifetime to u_long for comparison to prevent unsigned
- tweak previous;
+ comparison warning on 32bit arches. Spotted by deraadt, ok djm.
- Upstream-ID: bb8cc40b61b15f6a13d81da465ac5bfc65cbfc4b
+ OpenBSD-Commit-ID: 7a75b2540bff5ab4fa00b4d595db1df13bb0515a
-commit ec9d22cc251cc5acfe7b2bcef9cc7a1fe0e949d8
-Author: Damien Miller <djm@mindrot.org>
-Date: Fri Sep 8 12:44:13 2017 +1000
+commit 0eaca933ae08b0a515edfccd5cc4a6b667034813
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Sat Mar 14 20:58:46 2020 +1100
- Fuzzer harnesses for sig verify and pubkey parsing
+ Include fido.h when checking for fido/credman.h.
- These are some basic clang libfuzzer harnesses for signature
- verification and public key parsing. Some assembly (metaphorical)
- required.
+ It's required for fido_dev_t, otherwise configure fails with
+ when given --with-security-key-builtin.
-commit de35c382894964a896a63ecd5607d3a3b93af75d
-Author: Damien Miller <djm@mindrot.org>
-Date: Fri Sep 8 12:38:31 2017 +1000
+commit c7c099060f82ffe6a36d8785ecf6052e12fd92f0
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Fri Mar 13 03:18:45 2020 +0000
- Give configure ability to set CFLAGS/LDFLAGS later
+ upstream: some more speeling mistakes from
- Some CFLAGS/LDFLAGS may disrupt the configure script's operation,
- in particular santization and fuzzer options that break assumptions
- about memory and file descriptor dispositions.
+ OpenBSD-Regress-ID: 02471c079805471c546b7a69d9ab1d34e9a57443
+
+commit 1d89232a4aa97fe935cd60b8d24d75c2f70d56c5
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Fri Mar 13 04:16:27 2020 +0000
+
+ upstream: improve error messages for some common PKCS#11 C_Login
- This adds two flags to configure --with-cflags-after and
- --with-ldflags-after that allow specifying additional compiler and
- linker options that are added to the resultant Makefiles but not
- used in the configure run itself.
+ failure cases; based on patch from Jacob Hoffman-Andrews in bz3130; ok
+ dtucker
- E.g.
+ OpenBSD-Commit-ID: b8b849621b4a98e468942efd0a1c519c12ce089e
+
+commit 5becbec023f2037394987f85ed7f74b9a28699e0
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Fri Mar 13 04:01:56 2020 +0000
+
+ upstream: use sshpkt_fatal() for kex_exchange_identification()
- env CC=clang-3.9 ./configure \
- --with-cflags-after=-fsantize=address \
- --with-ldflags-after="-g -fsanitize=address"
+ errors. This ensures that the logged errors are consistent with other
+ transport- layer errors and that the relevant IP addresses are logged. bz3129
+ ok dtucker@
+
+ OpenBSD-Commit-ID: 2c22891f0b9e1a6cd46771cedbb26ac96ec2e6ab
+
+commit eef88418f9e5e51910af3c5b23b5606ebc17af55
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Fri Mar 13 03:24:49 2020 +0000
-commit 22376d27a349f62c502fec3396dfe0fdcb2a40b7
+ upstream: Don't clear alarm timers in listening sshd. Previously
+
+ these timers were used for regenerating the SSH1 ephemeral host keys but
+ those are now gone so there's no need to clear the timers either. ok
+ deraadt@
+
+ OpenBSD-Commit-ID: 280d2b885e4a1ce404632e8cc38fcb17be7dafc0
+
+commit d081f017c20a3564255873ed99fd7d024cac540f
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sun Sep 3 23:33:13 2017 +0000
+Date: Fri Mar 13 03:17:07 2020 +0000
- upstream commit
+ upstream: spelling errors in comments; no code change from
- Expand ssh_config's StrictModes option with two new
- settings:
+ OpenBSD-Commit-ID: 166ea64f6d84f7bac5636dbd38968592cb5eb924
+
+commit c084a2d040f160bc2b83f13297e3e3ca3f5dbac6
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Fri Mar 13 03:12:17 2020 +0000
+
+ upstream: when downloading FIDO2 resident keys from a token, don't
- StrictModes=accept-new will automatically accept hitherto-unseen keys
- but will refuse connections for changed or invalid hostkeys.
+ prompt for a PIN until the token has told us that it needs one. Avoids
+ double-prompting on devices that implement on-device authentication (e.g. a
+ touchscreen PIN pad on the Trezor Model T). ok dtucker@
- StrictModes=off is the same as StrictModes=no
+ OpenBSD-Commit-ID: 38b78903dd4422d7d3204095a31692fb69130817
+
+commit 955c4cf4c6a1417c28d4e1040702c4d9bf63645b
+Author: Damien Miller <djm@mindrot.org>
+Date: Fri Mar 13 14:30:16 2020 +1100
+
+ sync fnmatch.c with upstream to fix another typo
+
+commit 397f217e8640e75bb719a8e87111b4bd848fb3df
+Author: Damien Miller <djm@mindrot.org>
+Date: Fri Mar 13 14:24:23 2020 +1100
+
+ another spelling error in comment
+
+commit def31bc5427579ec3f7f2ce99f2da1338fdc0c9f
+Author: Damien Miller <djm@mindrot.org>
+Date: Fri Mar 13 14:23:07 2020 +1100
+
+ spelling mistakes
- Motivation:
+ from https://fossies.org/linux/misc/openssh-8.2p1.tar.gz/codespell.html
+
+commit 8bdc3bb7cf4c82c3344cfcb82495a43406e87e83
+Author: markus@openbsd.org <markus@openbsd.org>
+Date: Fri Mar 6 18:29:54 2020 +0000
+
+ upstream: fix relative includes in sshd_config; ok djm
+
+ OpenBSD-Commit-ID: fa29b0da3c93cbc3a1d4c6bcd58af43c00ffeb5b
+
+commit e32ef97a56ae03febfe307688858badae3a70e5a
+Author: markus@openbsd.org <markus@openbsd.org>
+Date: Fri Mar 6 18:29:14 2020 +0000
+
+ upstream: fix use-after-free in do_download_sk; ok djm
- StrictModes=no combines two behaviours for host key processing:
- automatically learning new hostkeys and continuing to connect to hosts
- with invalid/changed hostkeys. The latter behaviour is quite dangerous
- since it removes most of the protections the SSH protocol is supposed to
- provide.
+ OpenBSD-Commit-ID: 96b49623d297797d4fc069f1f09e13c8811f8863
+
+commit 5732d58020309364bf31fa125354e399361006db
+Author: markus@openbsd.org <markus@openbsd.org>
+Date: Fri Mar 6 18:28:50 2020 +0000
+
+ upstream: do not leak oprincipals; ok djm
- Quite a few users want to automatically learn hostkeys however, so
- this makes that feature available with less danger.
+ OpenBSD-Commit-ID: 4691d9387eab36f8fda48f5d8009756ed13a7c4c
+
+commit 8fae395f34c2c52cdaf9919aa261d1848b4bb00b
+Author: markus@openbsd.org <markus@openbsd.org>
+Date: Fri Mar 6 18:28:27 2020 +0000
+
+ upstream: initialize seconds for debug message; ok djm
- At some point in the future, StrictModes=no will change to be a synonym
- for accept-new, with its current behaviour remaining available via
- StrictModes=off.
+ OpenBSD-Commit-ID: 293fbefe6d00b4812a180ba02e26170e4c855b81
+
+commit 46e5c4c8ffcd1569bcd5d04803abaa2ecf3e4cff
+Author: markus@openbsd.org <markus@openbsd.org>
+Date: Fri Mar 6 18:27:50 2020 +0000
+
+ upstream: correct return code; ok djm
- bz#2400, suggested by Michael Samuel; ok markus
+ OpenBSD-Commit-ID: 319d09e3b7f4b2bc920c67244d9ff6426b744810
+
+commit 31c39e7840893f1bfdcbe4f813b20d1d7e69ec3e
+Author: markus@openbsd.org <markus@openbsd.org>
+Date: Fri Mar 6 18:27:15 2020 +0000
+
+ upstream: principalsp is optional, pubkey required; ok djm
- Upstream-ID: 0f55502bf75fc93a74fb9853264a8276b9680b64
+ OpenBSD-Commit-ID: 2cc3ea5018c28ed97edaccd7f17d2cc796f01024
-commit ff3c42384033514e248ba5d7376aa033f4a2b99a
-Author: jmc@openbsd.org <jmc@openbsd.org>
-Date: Fri Sep 1 15:41:26 2017 +0000
+commit e26a31757c5df2f58687cb9a4853d1418f39728e
+Author: markus@openbsd.org <markus@openbsd.org>
+Date: Fri Mar 6 18:26:21 2020 +0000
- upstream commit
+ upstream: remove unused variables in ssh-pkcs11-helper; ok djm
- remove blank line;
+ OpenBSD-Commit-ID: 13e572846d0d1b28f1251ddd2165e9cf18135ae1
+
+commit 1b378c0d982d6ab522eda634b0e88cf1fca5e352
+Author: markus@openbsd.org <markus@openbsd.org>
+Date: Fri Mar 6 18:25:48 2020 +0000
+
+ upstream: return correct error in sshsk_ed25519_sig; ok djm
- Upstream-ID: 2f46b51a0ddb3730020791719e94d3e418e9f423
+ OpenBSD-Commit-ID: 52bf733df220303c260fee4f165ec64b4a977625
-commit b828605d51f57851316d7ba402b4ae06cf37c55d
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Sep 1 05:53:56 2017 +0000
+commit fbff605e637b068061ab6784ff03e3874890c092
+Author: markus@openbsd.org <markus@openbsd.org>
+Date: Fri Mar 6 18:25:12 2020 +0000
- upstream commit
+ upstream: fix possible null-deref in check_key_not_revoked; ok
- identify the case where SSHFP records are missing but
- other DNS RR types are present and display a more useful error message for
- this case; patch by Thordur Bjornsson; bz#2501; ok dtucker@
+ djm
- Upstream-ID: 8f7a5a8344f684823d8317a9708b63e75be2c244
+ OpenBSD-Commit-ID: 80855e9d7af42bb6fcc16c074ba69876bfe5e3bf
-commit 8042bad97e2789a50e8f742c3bcd665ebf0add32
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Sep 1 05:50:48 2017 +0000
+commit bc30b446841fc16e50ed6e75c56ccfbd37b9f281
+Author: markus@openbsd.org <markus@openbsd.org>
+Date: Fri Mar 6 18:24:39 2020 +0000
- upstream commit
+ upstream: ssh_fetch_identitylist() returns the return value from
- document available AuthenticationMethods; bz#2453 ok
- dtucker@
+ ssh_request_reply() so we should also check against != 0 ok djm
- Upstream-ID: 2c70576f237bb699aff59889dbf2acba4276d3d0
+ OpenBSD-Commit-ID: 28d0028769d03e665688c61bb5fd943e18614952
-commit 71e5a536ec815d542b199f2ae6d646c0db9f1b58
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Wed Aug 30 03:59:08 2017 +0000
+commit 7b4f70ddeb59f35283d77d8d9c834ca58f8cf436
+Author: markus@openbsd.org <markus@openbsd.org>
+Date: Fri Mar 6 18:23:17 2020 +0000
- upstream commit
+ upstream: sshkey_cert_check_authority requires reason to be set;
- pass packet state down to some of the channels function
- (more to come...); ok markus@
+ ok djm
- Upstream-ID: d8ce7a94f4059d7ac1e01fb0eb01de0c4b36c81b
+ OpenBSD-Commit-ID: 6f7a6f19540ed5749763c2f9530c0897c94aa552
-commit 6227fe5b362239c872b91bbdee4bf63cf85aebc5
-Author: jmc@openbsd.org <jmc@openbsd.org>
-Date: Tue Aug 29 13:05:58 2017 +0000
+commit 05efe270df1e925db0af56a806d18b5063db4b6d
+Author: markus@openbsd.org <markus@openbsd.org>
+Date: Fri Mar 6 18:21:28 2020 +0000
- upstream commit
+ upstream: passphrase depends on kdfname, not ciphername (possible
- sort options;
+ null-deref); ok djm
- Upstream-ID: cf21d68cf54e81968bca629aaeddc87f0c684f3c
+ OpenBSD-Commit-ID: 0d39668edf5e790b5837df4926ee1141cec5471c
-commit 530591a5795a02d01c78877d58604723918aac87
-Author: dlg@openbsd.org <dlg@openbsd.org>
-Date: Tue Aug 29 09:42:29 2017 +0000
+commit 1ddf5682f3992bdacd29164891abb71a19c2cf61
+Author: markus@openbsd.org <markus@openbsd.org>
+Date: Fri Mar 6 18:20:44 2020 +0000
- upstream commit
+ upstream: consistently check packet_timeout_ms against 0; ok djm
- add a -q option to ssh-add to make it quiet on success.
+ OpenBSD-Commit-ID: e8fb8cb2c96c980f075069302534eaf830929928
+
+commit 31f1ee54968ad84eb32375e4412e0318766b586b
+Author: markus@openbsd.org <markus@openbsd.org>
+Date: Fri Mar 6 18:20:02 2020 +0000
+
+ upstream: initialize cname in case ai_canonname is NULL or too
- if you want to silence ssh-add without this you generally redirect
- the output to /dev/null, but that can hide error output which you
- should see.
+ long; ok djm
- ok djm@
+ OpenBSD-Commit-ID: c27984636fdb1035d1642283664193e91aab6e37
+
+commit a6134b02b5264b2611c8beae98bb392329452bba
+Author: markus@openbsd.org <markus@openbsd.org>
+Date: Fri Mar 6 18:19:21 2020 +0000
+
+ upstream: fix uninitialized pointers for forward_cancel; ok djm
- Upstream-ID: 2f31b9b13f99dcf587e9a8ba443458e6c0d8997c
+ OpenBSD-Commit-ID: 612778e6d87ee865d0ba97d0a335f141cee1aa37
-commit a54eb27dd64b5eca3ba94e15cec3535124bd5029
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Sun Aug 27 00:38:41 2017 +0000
+commit 16d4f9961c75680aab374dee762a5baa0ad507af
+Author: markus@openbsd.org <markus@openbsd.org>
+Date: Fri Mar 6 18:16:21 2020 +0000
- upstream commit
+ upstream: exit on parse failures in input_service_request; ok djm
- Increase the buffer sizes for user prompts to ensure that
- they won't be truncated by snprintf. Based on patch from cjwatson at
- debian.org via bz#2768, ok djm@
+ OpenBSD-Commit-ID: 6a7e1bfded26051d5aa893c030229b1ee6a0d5d2
+
+commit 5f25afe5216ba7f8921e04f79aa4ca0624eca820
+Author: markus@openbsd.org <markus@openbsd.org>
+Date: Fri Mar 6 18:15:38 2020 +0000
+
+ upstream: fix null-deref on calloc failure; ok djm
- Upstream-ID: 6ffacf1abec8f40b469de5b94bfb29997d96af3e
+ OpenBSD-Commit-ID: a313519579b392076b7831ec022dfdefbec8724a
-commit dd9d9b3381a4597b840d480b043823112039327e
-Author: Darren Tucker <dtucker@zip.com.au>
-Date: Mon Aug 28 16:48:27 2017 +1000
+commit ff2acca039aef16a15fce409163df404858f7aa5
+Author: markus@openbsd.org <markus@openbsd.org>
+Date: Fri Mar 6 18:15:04 2020 +0000
- Switch Capsicum header to sys/capsicum.h.
+ upstream: exit if ssh_krl_revoke_key_sha256 fails; ok djm
- FreeBSD's <sys/capability.h> was renamed to <sys/capsicum.h> in 2014 to
- avoid future conflicts with POSIX capabilities (the last release that
- didn't have it was 9.3) so switch to that. Patch from des at des.no.
+ OpenBSD-Commit-ID: 0864ad4fe8bf28ab21fd1df766e0365c11bbc0dc
-commit f5e917ab105af5dd6429348d9bc463e52b263f92
-Author: Darren Tucker <dtucker@zip.com.au>
-Date: Sun Aug 27 08:55:40 2017 +1000
+commit 31c860a0212af2d5b6a129e3e8fcead51392ee1d
+Author: markus@openbsd.org <markus@openbsd.org>
+Date: Fri Mar 6 18:14:13 2020 +0000
- Add missing includes for bsd-err.c.
+ upstream: pkcs11_register_provider: return < 0 on error; ok djm
- Patch from cjwatson at debian.org via bz#2767.
+ OpenBSD-Commit-ID: cfc8321315b787e4d40da4bdb2cbabd4154b0d97
-commit 878e029797cfc9754771d6f6ea17f8c89e11d225
-Author: Damien Miller <djm@mindrot.org>
-Date: Fri Aug 25 13:25:01 2017 +1000
+commit 15be29e1e3318737b0768ca37d5b4a3fbe868ef0
+Author: markus@openbsd.org <markus@openbsd.org>
+Date: Fri Mar 6 18:13:29 2020 +0000
- Split platform_sys_dir_uid into its own file
+ upstream: sshsig: return correct error, fix null-deref; ok djm
- platform.o is too heavy for libssh.a use; it calls into the server on
- many platforms. Move just the function needed by misc.c into its own
- file.
+ OpenBSD-Commit-ID: 1d1af7cd538b8b23e621cf7ab84f11e7a923edcd
-commit 07949bfe9133234eddd01715592aa0dde67745f0
-Author: Damien Miller <djm@mindrot.org>
-Date: Wed Aug 23 20:13:18 2017 +1000
+commit 6fb6f186cb62a6370fba476b6a03478a1e95c30d
+Author: markus@openbsd.org <markus@openbsd.org>
+Date: Fri Mar 6 18:12:55 2020 +0000
+
+ upstream: vasnmprintf allocates str and returns -1; ok djm
+
+ OpenBSD-Commit-ID: dae4c9e83d88471bf3b3f89e3da7a107b44df11c
- misc.c needs functions from platform.c now
+commit 714e1cbca17daa13f4f98978cf9e0695d4b2e0a4
+Author: markus@openbsd.org <markus@openbsd.org>
+Date: Fri Mar 6 18:11:10 2020 +0000
+
+ upstream: sshpkt_fatal() does not return; ok djm
+
+ OpenBSD-Commit-ID: 7dfe847e28bd78208eb227b37f29f4a2a0929929
-commit b074c3c3f820000a21953441cea7699c4b17d72f
+commit 9b47bd7b09d191991ad9e0506bb66b74bbc93d34
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Aug 18 05:48:04 2017 +0000
+Date: Fri Feb 28 01:07:28 2020 +0000
- upstream commit
+ upstream: no-touch-required certificate option should be an
- add a "quiet" flag to exited_cleanly() that supresses
- errors about exit status (failure due to signal is still reported)
+ extension, not a critical option.
- Upstream-ID: db85c39c3aa08e6ff67fc1fb4ffa89f807a9d2f0
+ OpenBSD-Commit-ID: 626b22c5feb7be8a645e4b9a9bef89893b88600d
-commit de4ae07f12dabf8815ecede54235fce5d22e3f63
+commit dd992520bed35387fc010239abe1bdc0c2665e38
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Aug 18 05:36:45 2017 +0000
+Date: Fri Feb 28 01:06:05 2020 +0000
- upstream commit
+ upstream: better error message when trying to use a FIDO key
+
+ function and SecurityKeyProvider is empty
- Move several subprocess-related functions from various
- locations to misc.c. Extend subprocess() to offer a little more control over
- stdio disposition.
+ OpenBSD-Commit-ID: e56602c2ee8c82f835d30e4dc8ee2e4a7896be24
+
+commit b81e66dbe0345aef4717911abcb4f589fff33a0a
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Thu Feb 27 02:32:37 2020 +0000
+
+ upstream: Drop leading space from line count that was confusing
- feedback & ok dtucker@
+ ssh-keygen's screen mode.
- Upstream-ID: 3573dd7109d13ef9bd3bed93a3deb170fbfce049
+ OpenBSD-Commit-ID: 3bcae7a754db3fc5ad3cab63dd46774edb35b8ae
-commit 643c2ad82910691b2240551ea8b14472f60b5078
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sat Aug 12 06:46:01 2017 +0000
+commit d5ba1c03278eb079438bb038266d80d7477d49cb
+Author: jsg@openbsd.org <jsg@openbsd.org>
+Date: Wed Feb 26 13:40:09 2020 +0000
- upstream commit
+ upstream: change explicit_bzero();free() to freezero()
- make "--" before the hostname terminate command-line
- option processing completely; previous behaviour would not prevent further
- options appearing after the hostname (ssh has a supported options after the
- hostname for >20 years, so that's too late to change).
+ While freezero() returns early if the pointer is NULL the tests for
+ NULL in callers are left to avoid warnings about passing an
+ uninitialised size argument across a function boundry.
- ok deraadt@
+ ok deraadt@ djm@
- Upstream-ID: ef5ee50571b98ad94dcdf8282204e877ec88ad89
+ OpenBSD-Commit-ID: 2660fa334fcc7cd05ec74dd99cb036f9ade6384a
-commit 0f3455356bc284d7c6f4d3c1614d31161bd5dcc2
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sat Aug 12 06:42:52 2017 +0000
+commit 9e3220b585c5be19a7431ea4ff8884c137b3a81c
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Wed Feb 26 11:46:51 2020 +0000
- upstream commit
+ upstream: Have sftp reject "-1" in the same way as ssh(1) and
- Switch from aes256-cbc to aes256-ctr for encrypting
- new-style private keys. The latter having the advantage of being supported
- for no-OpenSSL builds; bz#2754 ok markus@
+ scp(1) do instead of accepting and silently ignoring it since protocol 1
+ support has been removed. Spotted by shivakumar2696 at gmail.com, ok
+ deraadt@
- Upstream-ID: 54179a2afd28f93470471030567ac40431e56909
+ OpenBSD-Commit-ID: b79f95559a1c993214f4ec9ae3c34caa87e9d5de
-commit c4972d0a9bd6f898462906b4827e09b7caea2d9b
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Aug 11 04:47:12 2017 +0000
+commit ade8e67bb0f07b12e5e47e7baeafbdc898de639f
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Wed Feb 26 01:31:47 2020 +0000
- upstream commit
+ upstream: Remove obsolete XXX comment. ok deraadt@
- refuse to a private keys when its corresponding .pub key
- does not match. bz#2737 ok dtucker@
+ OpenBSD-Commit-ID: bc462cc843947feea26a2e21c750b3a7469ff01b
+
+commit 7eb903f51eba051d7f65790bab92a28970ac1ccc
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Mon Feb 24 04:27:58 2020 +0000
+
+ upstream: Fix typo. Patch from itoama at live.jp via github PR#173.
- Upstream-ID: 54ff5e2db00037f9db8d61690f26ef8f16e0d913
+ OpenBSD-Commit-ID: 5cdaafab38bbdea0d07e24777d00bfe6f972568a
-commit 4b3ecbb663c919132dddb3758e17a23089413519
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Aug 11 04:41:08 2017 +0000
+commit b2491c289dd1b557a18a2aca04eeff5c157fc5ef
+Author: Nico Kadel-Garcia <nkadel@gmail.com>
+Date: Sat Oct 12 17:51:01 2019 -0400
- upstream commit
+ Switch %define to %global for redhat/openssh.spec
+
+commit b18dcf6cca7c7aba1cc22e668e04492090ef0255
+Author: mkontani <itoama@live.jp>
+Date: Fri Feb 21 00:54:49 2020 +0900
+
+ fix some typos and sentence
+
+commit 0001576a096f788d40c2c0a39121cff51bf961ad
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Fri Feb 21 00:04:43 2020 +0000
+
+ upstream: Fix some typos and an incorrect word in docs. Patch from
- don't print verbose error message when ssh disconnects
- under sftp; bz#2750; ok dtucker@
+ itoama at live.jp via github PR#172.
- Upstream-ID: 6d83708aed77b933c47cf155a87dc753ec01f370
+ OpenBSD-Commit-ID: 166ee8f93a7201fef431b9001725ab8b269d5874
-commit 42a8f8bc288ef8cac504c5c73f09ed610bc74a34
+commit 99ff8fefe4b2763a53778d06b5f74443c8701615
Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Fri Aug 11 04:16:35 2017 +0000
+Date: Thu Feb 20 05:58:08 2020 +0000
- upstream commit
+ upstream: Update moduli generation script to new ssh-keygen
- Tweak previous keepalive commit: if last_time + keepalive
- <= now instead of just "<" so client_alive_check will fire if the select
- happens to return on exact second of the timeout. ok djm@
+ generation and screening command line flags.
- Upstream-ID: e02756bd6038d11bb8522bfd75a4761c3a684fcc
+ OpenBSD-Commit-ID: 5010ff08f7ad92082e87dde098b20f5c24921a8f
-commit b60ff20051ef96dfb207b6bfa45c0ad6c34a542a
+commit 700d16f5e534d6de5a3b7105a74a7a6f4487b681
Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Fri Aug 11 03:58:36 2017 +0000
+Date: Thu Feb 20 05:41:51 2020 +0000
- upstream commit
+ upstream: Import regenerated moduli.
- Keep track of the last time we actually heard from the
- client and use this to also schedule a client_alive_check(). Prevents
- activity on a forwarded port from indefinitely preventing the select timeout
- so that client_alive_check() will eventually (although not optimally) be
- called.
+ OpenBSD-Commit-ID: 7b7b619c1452a459310b0cf4391c5757c6bdbc0f
+
+commit 4753b74ba0f09e4aacdaab5e184cd540352004d5
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Thu Feb 20 16:42:50 2020 +1100
+
+ Import regenerated moduli.
+
+commit 11d427162778c18fa42917893a75d178679a2389
+Author: HARUYAMA Seigo <haruyama@unixuser.org>
+Date: Fri Feb 14 16:14:23 2020 +0900
+
+ Fix typos in INSTALL: s/avilable/available/ s/suppports/supports/
+
+commit 264a966216137c9f4f8220fd9142242d784ba059
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Tue Feb 18 08:58:33 2020 +0000
+
+ upstream: Ensure that the key lifetime provided fits within the
- Analysis by willchan at google com via bz#2756, feedback & ok djm@
+ values allowed by the wire format (u32). Prevents integer wraparound of the
+ timeout values. bz#3119, ok markus@ djm@
- Upstream-ID: c08721e0bbda55c6d18e2760f3fe1b17fb71169e
+ OpenBSD-Commit-ID: 8afe6038b5cdfcf63360788f012a7ad81acc46a2
-commit 94bc1e7ffba3cbdea8c7dcdab8376bf29283128f
-Author: Damien Miller <djm@mindrot.org>
-Date: Fri Jul 28 14:50:59 2017 +1000
+commit de1f3564cd85915b3002859873a37cb8d31ac9ce
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Tue Feb 18 08:49:49 2020 +0000
- Expose list of completed auth methods to PAM
+ upstream: Detect and prevent simple configuration loops when using
- bz#2408; ok dtucker@
+ ProxyJump. bz#3057, ok djm@
+
+ OpenBSD-Commit-ID: 077d21c564c886c98309d871ed6f8ef267b9f037
-commit c78e6eec78c88acf8d51db90ae05a3e39458603d
-Author: Damien Miller <djm@mindrot.org>
-Date: Fri Jul 21 14:38:16 2017 +1000
+commit 30144865bfa06b12239cfabc37c45e5ddc369d97
+Author: naddy@openbsd.org <naddy@openbsd.org>
+Date: Sun Feb 16 21:15:43 2020 +0000
- fix problems in tunnel forwarding portability code
+ upstream: document -F none; with jmc@
- This fixes a few problems in the tun forwarding code, mostly to do
- with host/network byte order confusion.
+ OpenBSD-Commit-ID: 0eb93b75473d2267aae9200e02588e57778c84f2
+
+commit 011052de73f3dbc53f50927ccf677266a9ade4f6
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Mon Feb 17 22:55:51 2020 +1100
+
+ Remove unused variable warning.
+
+commit 31c9348c5e4e94e9913ec64b3ca6e15f68ba19e5
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Mon Feb 17 22:53:24 2020 +1100
+
+ Constify aix_krb5_get_principal_name.
- Based on a report and patch by stepe AT centaurus.uberspace.de;
- bz#2735; ok dtucker@
+ Prevents warning about discarding type qualifiers on AIX.
-commit 2985d4062ebf4204bbd373456a810d558698f9f5
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Tue Jul 25 09:22:25 2017 +0000
+commit 290c994336a2cfe03c5496bebb6580863f94b232
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Mon Feb 17 22:51:36 2020 +1100
- upstream commit
+ Check if TILDE is already defined and undef.
- Make WinSCP patterns for SSH_OLD_DHGEX more specific to
- exclude WinSCP 5.10.x and up. bz#2748, from martin at winscp.net, ok djm@
+ Prevents redefinition warning on AIX.
+
+commit 41a2e64ae480eda73ee0e809bbe743d203890938
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Mon Feb 17 22:51:00 2020 +1100
+
+ Prevent unused variable warning.
+
+commit d4860ec4efd25ba194337082736797fce0bda016
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Mon Feb 17 22:48:50 2020 +1100
+
+ Check if getpeereid is actually declared.
- Upstream-ID: 6fd7c32e99af3952db007aa180e73142ddbc741a
+ Check in sys/socket.h (AIX) and unistd.h (FreeBSD, DragonFLy and OS X).
+ Prevents undeclared function warning on at least some versions of AIX.
-commit 9f0e44e1a0439ff4646495d5735baa61138930a9
+commit 8aa3455b16fddea4c0144a7c4a1edb10ec67dcc8
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Mon Jul 24 04:34:28 2017 +0000
+Date: Fri Feb 14 00:39:20 2020 +0000
- upstream commit
+ upstream: openssh-8.2
- g/c unused variable; make a little more portable
+ OpenBSD-Commit-ID: 0a1340ff65fad0d84b997ac58dd1b393dec7c19b
+
+commit 72f0ce33f0d5a37f31bad5800d1eb2fbdb732de6
+Author: Damien Miller <djm@mindrot.org>
+Date: Wed Feb 12 09:28:35 2020 +1100
+
+ crank version numbers
+
+commit b763ed05bd1f1f15ae1727c86a4498546bc36ca8
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Tue Feb 11 12:51:24 2020 +1100
+
+ Minor documentation update:
- Upstream-ID: 3f5980481551cb823c6fb2858900f93fa9217dea
+ - remove duplication of dependency information (it's all in INSTALL).
+ - SSHFP is now an RFC.
+
+commit 14ccfdb7248e33b1dc8bbac1425ace4598e094cb
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Sun Feb 9 11:23:35 2020 +1100
+
+ Check if UINT32_MAX is defined before redefining.
+
+commit be075110c735a451fd9d79a864e01e2e0d9f19d2
+Author: Damien Miller <djm@mindrot.org>
+Date: Fri Feb 7 15:07:27 2020 +1100
-commit 51676ec61491ec6d7cbd06082034e29b377b3bf6
+ typo; reported by Phil Pennock
+
+commit 963d71851e727ffdd2a97fe0898fad61d4a70ba1
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sun Jul 23 23:37:02 2017 +0000
+Date: Fri Feb 7 03:57:31 2020 +0000
- upstream commit
+ upstream: sync the description of the $SSH_SK_PROVIDER environment
- Allow IPQoS=none in ssh/sshd to not set an explicit
- ToS/DSCP value and just use the operating system default; ok dtucker@
+ variable with that of the SecurityKeyProvider ssh/sshd_config(5) directive,
+ as the latter was more descriptive.
- Upstream-ID: 77906ff8c7b660b02ba7cb1e47b17d66f54f1f7e
+ OpenBSD-Commit-ID: 0488f09530524a7e53afca6b6e1780598022552f
-commit 6c1fbd5a50d8d2415f06c920dd3b1279b741072d
-Author: Damien Miller <djm@mindrot.org>
-Date: Fri Jul 21 14:24:26 2017 +1000
+commit d4d9e1d40514e2746f9e05335d646512ea1020c6
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Fri Feb 7 03:54:44 2020 +0000
- mention libedit
+ upstream: Add ssh -Q key-sig for all key and signature types.
+
+ Teach ssh -Q to accept ssh_config(5) and sshd_config(5) algorithm keywords as
+ an alias for the corresponding query. Man page help jmc@, ok djm@.
+
+ OpenBSD-Commit-ID: 1e110aee3db2fc4bc5bee2d893b7128fd622e0f8
-commit dc2bd308768386b02c7337120203ca477e67ba62
-Author: markus@openbsd.org <markus@openbsd.org>
-Date: Wed Jul 19 08:30:41 2017 +0000
+commit fd68dc27864b099b552a6d9d507ca4b83afd6a76
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Fri Feb 7 03:27:54 2020 +0000
- upstream commit
+ upstream: fix two PIN entry bugs on FIDO keygen: 1) it would allow more
- fix support for unknown key types; ok djm@
+ than the intended number of prompts (3) and 2) it would SEGV too many
+ incorrect PINs were entered; based on patch by Gabriel Kihlman
- Upstream-ID: 53fb29394ed04d616d65b3748dee5aa06b07ab48
+ OpenBSD-Commit-ID: 9c0011f28ba8bd8adf2014424b64960333da1718
-commit fd0e8fa5f89d21290b1fb5f9d110ca4f113d81d9
+commit 96bd895a0a0b3a36f81c14db8c91513578fc5563
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Wed Jul 19 01:15:02 2017 +0000
+Date: Thu Feb 6 22:48:23 2020 +0000
- upstream commit
+ upstream: When using HostkeyAlgorithms to merely append or remove
- switch from select() to poll() for the ssh-agent
- mainloop; ok markus
+ algorithms from the default set (i.e. HostkeyAlgorithms=+/-...), retain the
+ default behaviour of preferring those algorithms that have existing keys in
+ known_hosts; ok markus
- Upstream-ID: 4a94888ee67b3fd948fd10693973beb12f802448
+ OpenBSD-Commit-ID: 040e7fcc38ea00146b5d224ce31ce7a1795ee6ed
-commit b1e72df2b813ecc15bd0152167bf4af5f91c36d3
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Fri Jul 14 03:18:21 2017 +0000
+commit c7288486731734a864b58d024b1395029b55bbc5
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Thu Feb 6 22:46:31 2020 +0000
- upstream commit
+ upstream: expand HostkeyAlgorithms prior to config dump, matching
- Make ""Killed by signal 1" LogLevel verbose so it's not
- shown at the default level. Prevents it from appearing during ssh -J and
- equivalent ProxyCommand configs. bz#1906, bz#2744, feedback&ok markus@
+ other algorithm lists; ok markus@
- Upstream-ID: debfaa7e859b272246c2f2633335d288d2e2ae28
+ OpenBSD-Commit-ID: a66f0fca8cc5ce30405a2867bc115fff600671d0
-commit 1f3d202770a08ee6752ed2a234b7ca6f180eb498
-Author: jmc@openbsd.org <jmc@openbsd.org>
-Date: Thu Jul 13 19:16:33 2017 +0000
+commit a6ac5d36efc072b15690c65039754f8e44247bdf
+Author: naddy@openbsd.org <naddy@openbsd.org>
+Date: Thu Feb 6 22:34:58 2020 +0000
- upstream commit
-
- man pages with pseudo synopses which list filenames end
- up creating very ugly output in man -k; after some discussion with ingo, we
- feel the simplest fix is to remove such SYNOPSIS sections: the info is hardly
- helpful at page top, is contained already in FILES, and there are
- sufficiently few that just zapping them is simple;
+ upstream: Add Include to the list of permitted keywords after a
- ok schwarze, who also helpfully ran things through a build to check
- output;
+ Match keyword. ok markus@
- Upstream-ID: 3e211b99457e2f4c925c5927d608e6f97431336c
+ OpenBSD-Commit-ID: 342e940538b13dd41e0fa167dc9ab192b9f6e2eb
-commit 7f13a4827fb28957161de4249bd6d71954f1f2ed
-Author: espie@openbsd.org <espie@openbsd.org>
-Date: Mon Jul 10 14:09:59 2017 +0000
+commit a47f6a6c0e06628eed0c2a08dc31a8923bcc37ba
+Author: naddy@openbsd.org <naddy@openbsd.org>
+Date: Thu Feb 6 22:30:54 2020 +0000
- upstream commit
+ upstream: Replace "security key" with "authenticator" in program
- zap redundant Makefile variables. okay djm@
+ messages.
+
+ This replaces "security key" in error/usage/verbose messages and
+ distinguishes between "authenticator" and "authenticator-hosted key".
+
+ ok djm@
- Upstream-ID: e39b3902fe1d6c4a7ba6a3c58e072219f3c1e604
+ OpenBSD-Commit-ID: 7c63800e9c340c59440a054cde9790a78f18592e
-commit dc44dd3a9e2c9795394e6a7e1e71c929cbc70ce0
-Author: jmc@openbsd.org <jmc@openbsd.org>
-Date: Sat Jul 8 18:32:54 2017 +0000
+commit 849a9b87144f8a5b1771de6c85e44bfeb86be9a9
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Thu Feb 6 11:28:14 2020 +1100
- upstream commit
+ Don't look for UINT32_MAX in inttypes.h
- slightly rework previous, to avoid an article issue;
+ ... unless we are actually going to use it. Fixes build on HP-UX
+ without the potential impact to other platforms of a header change
+ shortly before release.
+
+commit a2437f8ed0c3be54ddd21630a93c68ebd168286f
+Author: Damien Miller <djm@mindrot.org>
+Date: Thu Feb 6 12:02:22 2020 +1100
+
+ depend
+
+commit 9716e8c4956acdd7b223d1642bfa376e07e7503d
+Author: Michael Forney <mforney@mforney.org>
+Date: Wed Nov 27 19:17:26 2019 -0800
+
+ Fix sha2 MAKE_CLONE no-op definition
- Upstream-ID: 15a315f0460ddd3d4e2ade1f16d6c640a8c41b30
+ The point of the dummy declaration is so that MAKE_CLONE(...) can have
+ a trailing semicolon without introducing an empty declaration. So,
+ the macro replacement text should *not* have a trailing semicolon,
+ just like DEF_WEAK.
-commit 853edbe057a84ebd0024c8003e4da21bf2b469f7
+commit d596b1d30dc158915a3979fa409d21ff2465b6ee
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Jul 7 03:53:12 2017 +0000
+Date: Tue Feb 4 09:58:04 2020 +0000
- upstream commit
+ upstream: require FIDO application strings to start with "ssh:"; ok
- When generating all hostkeys (ssh-keygen -A), clobber
- existing keys if they exist but are zero length. zero-length keys could
- previously be made if ssh-keygen failed part way through generating them, so
- avoid that case too. bz#2561 reported by Krzysztof Cieplucha; ok dtucker@
+ markus@
- Upstream-ID: f662201c28ab8e1f086b5d43c59cddab5ade4044
+ OpenBSD-Commit-ID: 94e9c1c066d42b76f035a3d58250a32b14000afb
-commit 43616876ba68a2ffaece6a6c792def4b039f2d6e
+commit 501f3582438cb2cb1cb92be0f17be490ae96fb23
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sat Jul 1 22:55:44 2017 +0000
+Date: Mon Feb 3 23:47:57 2020 +0000
- upstream commit
+ upstream: revert enabling UpdateHostKeys by default - there are still
- actually remove these files
+ corner cases we need to address; ok markus
- Upstream-ID: 1bd41cba06a7752de4df304305a8153ebfb6b0ac
+ OpenBSD-Commit-ID: ff7ad941bfdc49fb1d8baa95fd0717a61adcad57
-commit 83fa3a044891887369ce8b487ce88d713a04df48
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sat Jul 1 13:50:45 2017 +0000
+commit 072f3b832d2a4db8d9880effcb6c4d0dad676504
+Author: jmc@openbsd.org <jmc@openbsd.org>
+Date: Mon Feb 3 08:15:37 2020 +0000
- upstream commit
+ upstream: use better markup for challenge and write-attestation, and
- remove post-SSHv1 removal dead code from rsa.c and merge
- the remaining bit that it still used into ssh-rsa.c; ok markus
+ rejig the challenge text a little;
- Upstream-ID: ac8a048d24dcd89594b0052ea5e3404b473bfa2f
+ ok djm
+
+ OpenBSD-Commit-ID: 9f351e6da9edfdc907d5c3fdaf2e9ff3ab0a7a6f
-commit 738c73dca2c99ee78c531b4cbeefc2008fe438f0
+commit 262eb05a22cb1fabc3bc1746c220566490b80229
Author: Damien Miller <djm@mindrot.org>
-Date: Fri Jul 14 14:26:36 2017 +1000
-
- make explicit_bzero/memset safe for sz=0
-
-commit 8433d51e067e0829f5521c0c646b6fd3fe17e732
-Author: Tim Rice <tim@multitalents.net>
-Date: Tue Jul 11 18:47:56 2017 -0700
+Date: Mon Feb 3 21:22:15 2020 +1100
- modified: configure.ac
- UnixWare needs BROKEN_TCGETATTR_ICANON like Solaris
- Analysis by Robbie Zhang
+ mention libfido2 in dependencies section
-commit ff3507aea9c7d30cd098e7801e156c68faff7cc7
+commit ccd3b247d59d3bde16c3bef0ea888213fbd6da86
Author: Damien Miller <djm@mindrot.org>
-Date: Fri Jul 7 11:21:27 2017 +1000
+Date: Mon Feb 3 19:40:12 2020 +1100
- typo
+ add clock_gettime64(2) to sandbox allowed syscalls
+
+ bz3093
-commit d79bceb9311a9c137d268f5bc481705db4151810
+commit adffbe1c645ad2887ba0b6d24c194aa7a40c5735
Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Fri Jun 30 04:17:23 2017 +0000
+Date: Sun Feb 2 09:45:34 2020 +0000
- upstream commit
+ upstream: Output (none) in debug in the case in the CheckHostIP=no case
- Only call close once in confree(). ssh_packet_close will
- close the FD so only explicitly close non-SSH channels. bz#2734, from
- bagajjal at microsoft.com, ok djm@
+ as suggested by markus@
- Upstream-ID: a81ce0c8b023527167739fccf1732b154718ab02
+ OpenBSD-Commit-ID: 4ab9117ee5261cbbd1868717fcc3142eea6385cf
-commit 197dc9728f062e23ce374f44c95a2b5f9ffa4075
-Author: Darren Tucker <dtucker@zip.com.au>
-Date: Thu Jun 29 15:40:25 2017 +1000
+commit 58c819096a2167983e55ae686486ce317b69b2d1
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Sun Feb 2 09:22:22 2020 +0000
- Update link for my patches.
+ upstream: Prevent possible null pointer deref of ip_str in debug.
+
+ OpenBSD-Commit-ID: 37b252e2e6f690efed6682437ef75734dbc8addf
-commit a98339edbc1fc21342a390f345179a9c3031bef7
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Wed Jun 28 01:09:22 2017 +0000
+commit 0facae7bc8d3f8f9d02d0f6bed3d163ff7f39806
+Author: jmc@openbsd.org <jmc@openbsd.org>
+Date: Sun Feb 2 07:36:50 2020 +0000
- upstream commit
+ upstream: shuffle the challenge keyword to keep the -O list sorted;
- Allow ssh-keygen to use a key held in ssh-agent as a CA when
- signing certificates. bz#2377 ok markus
-
- Upstream-ID: fb42e920b592edcbb5b50465739a867c09329c8f
+ OpenBSD-Commit-ID: 08efad608b790949a9a048d65578fae9ed5845fe
-commit c9cdef35524bd59007e17d5bd2502dade69e2dfb
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sat Jun 24 06:35:24 2017 +0000
+commit 6fb3dd0ccda1c26b06223b87bcd1cab9ec8ec3cc
+Author: jmc@openbsd.org <jmc@openbsd.org>
+Date: Sat Feb 1 06:53:12 2020 +0000
- upstream commit
+ upstream: tweak previous;
- regress test for ExposeAuthInfo
+ OpenBSD-Commit-ID: 0c42851cdc88583402b4ab2b110a6348563626d3
+
+commit 92725d4d3fde675acc0ca040b48f3d0c7be73b7f
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Sat Feb 1 17:25:09 2020 +1100
+
+ Use sys-queue.h from compat library.
- Upstream-Regress-ID: 190e5b6866376f4061c411ab157ca4d4e7ae86fd
+ Fixes build on platforms that don't have sys/queue.h (eg MUSL).
-commit f17ee61cad25d210edab69d04ed447ad55fe80c1
+commit 677d0ece67634262b3b96c3cd6410b19f3a603b7
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sat Jun 24 07:08:57 2017 +0000
+Date: Fri Jan 31 23:25:08 2020 +0000
- upstream commit
+ upstream: regress test for sshd_config Include directive; from Jakub
- correct env var name
+ Jelen
- Upstream-ID: 721e761c2b1d6a4dcf700179f16fd53a1dadb313
+ OpenBSD-Regress-ID: 0d9224de3297c7a5f51ba68d6e3725a2a9345fa4
-commit 40962198e3b132cecdb32e9350acd4294e6a1082
-Author: jmc@openbsd.org <jmc@openbsd.org>
-Date: Sat Jun 24 06:57:04 2017 +0000
+commit d4f4cdd681ab6408a98419f398b75a55497ed324
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Fri Jan 31 23:13:04 2020 +0000
- upstream commit
-
- spelling;
+ upstream: whitespace
- Upstream-ID: 606f933c8e2d0be902ea663946bc15e3eee40b25
+ OpenBSD-Commit-ID: 564cf7a5407ecf5da2d94ec15474e07427986772
-commit 33f86265d7e8a0e88d3a81745d746efbdd397370
+commit 245399dfb3ecebc6abfc2ef4ee2e650fa9f6942b
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sat Jun 24 06:38:11 2017 +0000
+Date: Fri Jan 31 23:11:25 2020 +0000
- upstream commit
+ upstream: force early logging to stderr if debug_flag (-d) is set;
- don't pass pointer to struct sshcipher between privsep
- processes, just redo the lookup in each using the already-passed cipher name.
- bz#2704 based on patch from Brooks Davis; ok markus dtucker
+ avoids missing messages from re-exec config passing
- Upstream-ID: 2eab434c09bdf549dafd7da3e32a0d2d540adbe0
+ OpenBSD-Commit-ID: 02484b8241c1f49010e7a543a7098e6910a8c9ff
-commit 8f574959272ac7fe9239c4f5d10fd913f8920ab0
+commit 7365f28a66d1c443723fbe6f4a2612ea6002901e
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sat Jun 24 06:34:38 2017 +0000
+Date: Fri Jan 31 23:08:08 2020 +0000
- upstream commit
-
- refactor authentication logging
+ upstream: mistake in previous: filling the incorrect buffer
- optionally record successful auth methods and public credentials
- used in a file accessible to user sessions
+ OpenBSD-Commit-ID: 862ee84bd4b97b529f64aec5d800c3dcde952e3a
+
+commit c2bd7f74b0e0f3a3ee9d19ac549e6ba89013abaf
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Fri Jan 31 22:42:45 2020 +0000
+
+ upstream: Add a sshd_config "Include" directive to allow inclusion
- feedback and ok markus@
+ of files. This has sensible semantics wrt Match blocks and accepts glob(3)
+ patterns to specify the included files. Based on patch by Jakub Jelen in
+ bz2468; feedback and ok markus@
- Upstream-ID: 090b93036967015717b9a54fd0467875ae9d32fb
+ OpenBSD-Commit-ID: 36ed0e845b872e33f03355b936a4fff02d5794ff
-commit e2004d4bb7eb01c663dd3a3e7eb224f1ccdc9bba
+commit ba261a1dd33266168ead4f8f40446dcece4d1600
Author: jmc@openbsd.org <jmc@openbsd.org>
-Date: Sat Jun 24 06:28:50 2017 +0000
+Date: Fri Jan 31 22:25:59 2020 +0000
- upstream commit
-
- word fix;
+ upstream: spelling fix;
- Upstream-ID: 8539bdaf2366603a34a9b2f034527ca13bb795c5
+ OpenBSD-Commit-ID: 3c079523c4b161725a4b15dd06348186da912402
-commit 4540428cd0adf039bcf5a8a27f2d5cdf09191513
+commit 771891a044f763be0711493eca14b6b0082e030f
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sat Jun 24 05:37:44 2017 +0000
+Date: Thu Jan 30 22:25:34 2020 +0000
- upstream commit
-
- switch sshconnect.c from (slightly abused) select() to
- poll(); ok deraadt@ a while back
+ upstream: document changed default for UpdateHostKeys
- Upstream-ID: efc1937fc591bbe70ac9e9542bb984f354c8c175
+ OpenBSD-Commit-ID: 25c390b21d142f78ac0106241d13441c4265fd2c
-commit 6f8ca3b92540fa1a9b91670edc98d15448e3d765
+commit d53a518536c552672c00e8892e2aea28f664148c
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sat Jun 24 05:35:05 2017 +0000
+Date: Thu Jan 30 22:19:32 2020 +0000
- upstream commit
+ upstream: enable UpdateKnownHosts=yes if the configuration
- use HostKeyAlias if specified instead of hostname for
- matching host certificate principal names; bz#2728; ok dtucker@
+ specifies only the default known_hosts files, otherwise select
+ UpdateKnownHosts=ask; ok markus@
- Upstream-ID: dc2e11c83ae9201bbe74872a0c895ae9725536dd
+ OpenBSD-Commit-ID: ab401a5ec4a33d2e1a9449eae6202e4b6d427df7
+
+commit bb63ff844e818d188da4fed3c016e0a4eecbbf25
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Thu Jan 30 18:54:42 2020 +1100
-commit 8904ffce057b80a7472955f1ec00d7d5c250076c
+ Look in inttypes.h for UINT32_MAX.
+
+ Should prevent warnings on at least some AIX versions.
+
+commit afeb6a960da23f0a5cbc4b80cca107c7504e932a
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sat Jun 24 05:24:11 2017 +0000
+Date: Thu Jan 30 07:21:38 2020 +0000
- upstream commit
+ upstream: use sshpkt_fatal() instead of plain fatal() for
- no need to call log_init to reinitialise logged PID in
- child sessions, since we haven't called openlog() in log_init() since 1999;
- ok markus@
+ ssh_packet_write_poll() failures here too as the former yields better error
+ messages; ok dtucker@
- Upstream-ID: 0906e4002af5d83d3d544df75e1187c932a3cf2e
+ OpenBSD-Commit-ID: 1f7a6ca95bc2b716c2e948fc1370753be772d8e3
-commit e238645d789cd7eb47541b66aea2a887ea122c9b
-Author: mestre@openbsd.org <mestre@openbsd.org>
-Date: Fri Jun 23 07:24:48 2017 +0000
+commit 65d6fd0a8a6f31c3ddf0c1192429a176575cf701
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Thu Jan 30 07:20:57 2020 +0000
- upstream commit
+ upstream: check the return value of ssh_packet_write_poll() and
- When using the escape sequence &~ the code path is
- client_loop() -> client_simple_escape_filter() -> process_escapes() -> fork()
- and the pledge for this path lacks the proc promise and therefore aborts the
- process. The solution is to just add proc the promise to this specific
- pledge.
+ call sshpkt_fatal() if it fails; avoid potential busy-loop under some
+ circumstances. Based on patch by Mike Frysinger; ok dtucker@
- Reported by Gregoire Jadi gjadi ! omecha.info
- Insight with tb@, OK jca@
-
- Upstream-ID: 63c05e30c28209519f476023b65b0b1b0387a05b
+ OpenBSD-Commit-ID: c79fe5cf4f0cd8074cb6db257c1394d5139408ec
-commit 5abbb31c4e7a6caa922cc1cbb14e87a77f9d19d3
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Fri Jun 23 03:30:42 2017 +0000
+commit dce74eab0c0f9010dc84c62500a17771d0131ff3
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Thu Jan 30 07:20:05 2020 +0000
- upstream commit
+ upstream: have sshpkt_fatal() save/restore errno before we
- Import regenerated moduli.
+ potentially call strerror() (via ssh_err()); ok dtucker
- Upstream-ID: b25bf747544265b39af74fe0716dc8d9f5b63b95
+ OpenBSD-Commit-ID: 5590df31d21405498c848245b85c24acb84ad787
-commit 849c5468b6d9b4365784c5dd88e3f1fb568ba38f
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Fri Jun 23 03:25:53 2017 +0000
+commit 14ef4efe2bf4180e085ea6738fdbebc199458b0c
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Wed Jan 29 08:17:49 2020 +0000
- upstream commit
+ upstream: markus suggests a simplification to previous
- Run the screen twice so we end up with more candidate
- groups. ok djm@
-
- Upstream-ID: b92c93266d8234d493857bb822260dacf4366157
+ OpenBSD-Commit-ID: 10bbfb6607ebbb9a018dcd163f0964941adf58de
-commit 4626e39c7053c6486c1c8b708ec757e464623f5f
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Wed Jun 14 00:31:38 2017 +0000
+commit 101ebc3a8cfa78d2e615afffbef9861bbbabf1ff
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Wed Jan 29 07:51:30 2020 +0000
- upstream commit
+ upstream: give more context to UpdateHostKeys messages, mentioning
- Add user@host prefix to client's "Permisison denied"
- messages, useful in particular when using "stacked" connections where it's
- not clear which host is denying. bz#2720, ok djm@ markus@
+ that the changes are validated by the existing trusted host key. Prompted by
+ espie@ feedback and ok markus@
- Upstream-ID: de88e1e9dcb050c98e85377482d1287a9fe0d2be
+ OpenBSD-Commit-ID: b3d95f4a45f2692f4143b9e77bb241184dbb8dc5
-commit c948030d54911b2d3cddb96a7a8e9269e15d11cd
+commit 24c0f752adf9021277a7b0a84931bb5fe48ea379
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Tue Jun 13 12:13:59 2017 +0000
+Date: Tue Jan 28 08:01:34 2020 +0000
- upstream commit
+ upstream: changes to support FIDO attestation
- Do not require that unknown EXT_INFO extension values not
- contain \0 characters. This would cause fatal connection errors if an
- implementation sent e.g. string-encoded sub-values inside a value.
+ Allow writing to disk the attestation certificate that is generated by
+ the FIDO token at key enrollment time. These certificates may be used
+ by an out-of-band workflow to prove that a particular key is held in
+ trustworthy hardware.
- Reported by Denis Bider; ok markus@
+ Allow passing in a challenge that will be sent to the card during
+ key enrollment. These are needed to build an attestation workflow
+ that resists replay attacks.
- Upstream-ID: 030e10fdc605563c040244c4b4f1d8ae75811a5c
+ ok markus@
+
+ OpenBSD-Commit-ID: 457dc3c3d689ba39eed328f0817ed9b91a5f78f6
-commit 6026f48dfca78b713e4a7f681ffa42a0afe0929e
+commit 156bef36f93a48212383235bb8e3d71eaf2b2777
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Tue Jun 13 11:22:15 2017 +0000
+Date: Tue Jan 28 07:24:15 2020 +0000
- upstream commit
+ upstream: disable UpdateHostKeys=ask when in quiet mode; "work for
- missing prototype.
+ me" matthieu@
- Upstream-ID: f443d2be9910fd2165a0667956d03343c46f66c9
+ OpenBSD-Commit-ID: 60d7b5eb91accf935ed9852650a826d86db2ddc7
-commit bcd1485075aa72ba9418003f5cc27af2b049c51b
+commit ec8a759b4045e54d6b38e690ffee4cbffc53c7b7
Author: Damien Miller <djm@mindrot.org>
-Date: Sat Jun 10 23:41:25 2017 +1000
+Date: Tue Jan 28 12:57:25 2020 +1100
- portability for sftp globbed ls sort by mtime
-
- Include replacement timespeccmp() for systems that lack it.
- Support time_t struct stat->st_mtime in addition to
- timespec stat->st_mtim, as well as unsorted fallback.
+ compat for missing IPTOS_DSCP_LE in system headers
-commit 072e172f1d302d2a2c6043ecbfb4004406717b96
+commit 4594c7627680c4f41c2ad5fe412e55b7cc79b10c
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sat Jun 10 06:36:46 2017 +0000
+Date: Tue Jan 28 01:49:36 2020 +0000
- upstream commit
+ upstream: make IPTOS_DSCP_LE available via IPQoS directive; bz2986,
- print '?' instead of incorrect link count (that the
- protocol doesn't provide) for remote listings. bz#2710 ok dtucker@
+ based on patch by veegish AT cyberstorm.mu
- Upstream-ID: c611f98a66302cea452ef10f13fff8cf0385242e
+ OpenBSD-Commit-ID: 9902bf4fbb4ea51de2193ac2b1d965bc5d99c425
-commit 72be5b2f8e7dc37235e8c4b8d0bc7b5ee1301505
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sat Jun 10 06:33:34 2017 +0000
+commit da22216b5db3613325aa7b639f40dc017e4c6f69
+Author: markus@openbsd.org <markus@openbsd.org>
+Date: Mon Jan 27 20:51:32 2020 +0000
- upstream commit
+ upstream: disable UpdateHostKeys=ask if command is specified; ok
- implement sorting for globbed ls; bz#2649 ok dtucker@
+ djm@ sthen@
- Upstream-ID: ed3110f351cc9703411bf847ba864041fb7216a8
+ OpenBSD-Commit-ID: e5bcc45eadb78896637d4143d289f1e42c2ef5d7
-commit 5b2f34a74aa6a524cd57e856b23e1b7b25007721
+commit 1e1db0544fdd788e2e3fc21d972a7ccb7de6b4ae
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Jun 9 06:47:13 2017 +0000
+Date: Sun Jan 26 00:09:50 2020 +0000
- upstream commit
+ upstream: unbreak unittests for recent API / source file changes
- return failure rather than fatal() for more cases during
- mux negotiations. Causes the session to fall back to a non-mux connection if
- they occur. bz#2707 ok dtucker@
+ OpenBSD-Regress-ID: 075a899a01bbf7781d38bf0b33d8366faaf6d3c0
+
+commit 0d1144769151edf65f74aee9a4c8545c37861695
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Sun Jan 26 15:09:15 2020 +1100
+
+ Move definition of UINT32_MAX.
- Upstream-ID: d2a7892f464d434e1f615334a1c9d0cdb83b29ab
+ This allows us to always define it if needed not just if we also
+ define the type ourself.
-commit 7f5637c4a67a49ef256cb4eedf14e8590ac30976
+commit f73ab8a811bc874c2fb403012aa8e4bfdcaf5ec7
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Jun 9 06:43:01 2017 +0000
+Date: Sun Jan 26 00:09:50 2020 +0000
- upstream commit
+ upstream: unbreak unittests for recent API / source file changes
- in description of public key authentication, mention that
- the server will send debug messages to the client for some error conditions
- after authentication has completed. bz#2709 ok dtucker
+ OpenBSD-Regress-ID: 075a899a01bbf7781d38bf0b33d8366faaf6d3c0
+
+commit 0373f9eba2b63455dceedbd3ac3d5dca306789ff
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Sun Jan 26 14:09:17 2020 +1100
+
+ Include signal.h to prevent redefintion of _NSIG.
+
+commit 638a45b5c1e20a8539100ca44166caad8abf26f8
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Sun Jan 26 13:40:51 2020 +1100
+
+ Wrap stdint.h in tests inside HAVE_STDINT_H.
+
+commit 74dfc2c859c906eaab1f88a27fd883115ffb928f
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Sun Jan 26 00:14:45 2020 +0000
+
+ upstream: for UpdateHostKeys, don't report errors for unsupported
- Upstream-ID: 750127dbd58c5a2672c2d28bc35fe221fcc8d1dd
+ key types - just ignore them. spotted by and ok dtucker@
+
+ OpenBSD-Commit-ID: 91769e443f6197c983932fc8ae9d39948727d473
-commit 2076e4adb986512ce8c415dd194fd4e52136c4b4
+commit b59618246c332e251160be0f1e0e88a7d4e2b0ae
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Jun 9 06:40:24 2017 +0000
+Date: Sun Jan 26 00:13:20 2020 +0000
- upstream commit
+ upstream: downgrade error() for missing subsequent known_hosts
- better translate libcrypto errors by looking deeper in
- the accursed error stack for codes that indicate the wrong passphrase was
- supplied for a PEM key. bz#2699 ok dtucker@
+ files to debug() as it was intended to be; spotted by dtucker@
- Upstream-ID: 4da4286326d570f4f0489459bb71f6297e54b681
+ OpenBSD-Commit-ID: 18cfea382cb52f2da761be524e309cc3d5354ef9
-commit ad0531614cbe8ec424af3c0fa90c34a8e1ebee4c
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Fri Jun 9 04:40:04 2017 +0000
+commit 469df611f778eec5950d556aabfe1d4efc227915
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Sat Jan 25 23:33:27 2020 +0000
- upstream commit
+ upstream: clarify that BatchMode applies to all interactive prompts
- Add comments referring to the relevant RFC sections for
- rekeying behaviour.
+ (e.g. host key confirmation) and not just password prompts.
- Upstream-ID: 6fc8e82485757a27633f9175ad00468f49a07d40
+ OpenBSD-Commit-ID: 97b001883d89d3fb1620d2e6b747c14a26aa9818
-commit ce9134260b9b1247e2385a1afed00c26112ba479
-Author: Damien Miller <djm@mindrot.org>
-Date: Fri Jun 9 14:43:47 2017 +1000
+commit de40876c4a5d7c519d3d7253557572fdfc13db76
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Sat Jan 25 23:28:06 2020 +0000
- drop two more privileges in the Solaris sandbox
+ upstream: tidy headers; some junk snuck into sshbuf-misc.c and
- Drop PRIV_DAX_ACCESS and PRIV_SYS_IB_INFO.
- Patch from huieying.lee AT oracle.com via bz#2723
+ sshbuf-io.c doesn't need SSHBUF_INTERNAL set
+
+ OpenBSD-Commit-ID: 27a724d2e0b2619c1a1490f44093bbd73580d9e6
-commit e0f609c8a2ab940374689ab8c854199c3c285a76
-Author: Darren Tucker <dtucker@zip.com.au>
-Date: Fri Jun 9 13:36:29 2017 +1000
+commit 6a107606355fa9547884cad6740e6144a7a7955b
+Author: Damien Miller <djm@mindrot.org>
+Date: Sun Jan 26 10:28:21 2020 +1100
- Wrap stdint.h include in #ifdef.
+ depend
-commit 1de5e47a85850526a4fdaf77185134046c050f75
+commit 59d01f1d720ebede4da42882f592d1093dac7adc
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Wed Jun 7 01:48:15 2017 +0000
+Date: Sat Jan 25 23:13:09 2020 +0000
- upstream commit
+ upstream: improve the error message for u2f enrollment errors by
- unbreak after sshv1 purge
+ making ssh-keygen be solely responsible for printing the error message and
+ convertint some more common error responses from the middleware to a useful
+ ssherr.h status code. more detail remains visible via -v of course.
- Upstream-Regress-ID: 8ea01a92d5f571b9fba88c1463a4254a7552d51b
-
-commit 550c053168123fcc0791f9952abad684704b5760
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Tue Jun 6 09:12:17 2017 +0000
-
- upstream commit
+ also remove indepedent copy of sk-api.h declarations in sk-usbhid.c
+ and just include it.
- Fix compression output stats broken in rev 1.201. Patch
- originally by Russell Coker via Debian bug #797964 and Christoph Biedl. ok
- djm@
+ feedback & ok markus@
- Upstream-ID: 83a1903b95ec2e4ed100703debb4b4a313b01016
+ OpenBSD-Commit-ID: a4a8ffa870d9a3e0cfd76544bcdeef5c9fb1f1bb
-commit 55d06c6e72a9abf1c06a7ac2749ba733134a1f39
+commit 99aa8035554ddb976348d2a9253ab3653019728d
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Jun 2 06:06:10 2017 +0000
+Date: Sat Jan 25 23:02:13 2020 +0000
- upstream commit
+ upstream: factor out reading/writing sshbufs to dedicated
- rationalise the long list of manual CDIAGFLAGS that we
- add; most of these were redundant to -Wall -Wextra
+ functions; feedback and ok markus@
- Upstream-ID: ea80f445e819719ccdcb237022cacfac990fdc5c
+ OpenBSD-Commit-ID: dc09e5f1950b7acc91b8fdf8015347782d2ecd3d
-commit 1527d9f61e6d50f6c2b4a3fa5b45829034b1b0b1
+commit 065064fcf455778b0918f783033b374d4ba37a92
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Thu Jun 1 06:59:21 2017 +0000
+Date: Sat Jan 25 22:49:38 2020 +0000
- upstream commit
+ upstream: add a comment describing the ranges of channel IDs that
- no need to bzero allocated space now that we use use
- recallocarray; ok deraadt@
+ we use; requested by markus@
- Upstream-ID: 53333c62ccf97de60b8cb570608c1ba5ca5803c8
+ OpenBSD-Commit-ID: 83a1f09810ffa3a96a55fbe32675b34ba739e56b
-commit cc812baf39b93d5355565da98648d8c31f955990
+commit 69334996ae203c51c70bf01d414c918a44618f8e
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Thu Jun 1 06:58:25 2017 +0000
+Date: Sat Jan 25 22:41:01 2020 +0000
- upstream commit
+ upstream: make sshd_config:ClientAliveCountMax=0 disable the
- unconditionally zero init size of buffer; ok markus@
- deraadt@
+ connection killing behaviour, rather than killing the connection after
+ sending the first liveness test probe (regardless of whether the client was
+ responsive) bz2627; ok markus
- Upstream-ID: 218963e846d8f26763ba25afe79294547b99da29
+ OpenBSD-Commit-ID: 5af79c35f4c9fa280643b6852f524bfcd9bccdaf
-commit 65eb8fae0d7ba45ef4483a3cf0ae7fd0dbc7c226
-Author: Damien Miller <djm@mindrot.org>
-Date: Thu Jun 1 16:25:09 2017 +1000
+commit bf986a9e2792555e0879a3145fa18d2b49436c74
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Sat Jan 25 22:36:22 2020 +0000
- avoid compiler warning
+ upstream: clarify order of AllowUsers/DenyUsers vs
+
+ AllowGroups/DenyGroups; bz1690, ok markus@
+
+ OpenBSD-Commit-ID: 5637584ec30db9cf64822460f41b3e42c8f9facd
-commit 2d75d74272dc2a0521fce13cfe6388800c9a2406
+commit 022ce92fa0daa9d78830baeb2bd2dc3f83c724ba
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Thu Jun 1 06:16:43 2017 +0000
+Date: Sat Jan 25 07:17:18 2020 +0000
- upstream commit
+ upstream: when AddKeysToAgent=yes is set and the key contains no
- some warnings spotted by clang; ok markus@
+ comment, add the key to the agent with the key's path as the comment. bz2564
- Upstream-ID: 24381d68ca249c5cee4388ceb0f383fa5b43991b
+ OpenBSD-Commit-ID: 8dd8ca9340d7017631a27f4ed5358a4cfddec16f
-commit 151c6e433a5f5af761c78de87d7b5d30a453cf5e
-Author: Damien Miller <djm@mindrot.org>
-Date: Thu Jun 1 15:25:13 2017 +1000
+commit 0b813436bbf6546638b10c1fa71f54691bcf5e63
+Author: tedu@openbsd.org <tedu@openbsd.org>
+Date: Sat Jan 25 07:09:14 2020 +0000
- add recallocarray replacement and dependency
+ upstream: group14-sha1 is no longer a default algorithm
- recallocarray() needs getpagesize() so add a tiny replacement for that.
+ OpenBSD-Commit-ID: a96f04d5e9c2ff760c6799579dc44f69b4ff431d
-commit 01e6f78924da308447e71e9a32c8a6104ef4e888
-Author: Damien Miller <djm@mindrot.org>
-Date: Thu Jun 1 15:16:24 2017 +1000
+commit 3432b6e05d5c583c91c566c5708fed487cec79ac
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Sat Jan 25 07:02:51 2020 +0000
- add *.0 manpage droppings
+ upstream: reword HashKnownHosts description a little more; some
+
+ people found the wording confusing (bz#2560)
+
+ OpenBSD-Commit-ID: ac30896598694f07d498828690aecd424c496988
-commit 4b2e2d3fd9dccff357e1e26ce9a5f2e103837a36
+commit f80d7d6aa98d6eddc5df02412efee6db75673d4c
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Thu Jun 1 04:51:58 2017 +0000
+Date: Sat Jan 25 07:01:00 2020 +0000
- upstream commit
+ upstream: weaken the language for what HashKnownHosts provides with
- fix casts re constness
+ regards to known_hosts name privacy, it's not practical for this option to
+ offer any guarantee that hostnames cannot be recovered from a disclosed
+ known_hosts file (e.g. by brute force).
- Upstream-ID: e38f2bac162b37dbaf784d349c8327a6626fa266
+ OpenBSD-Commit-ID: 13f1e3285f8acf7244e9770074296bcf446c6972
-commit 75b8af8de805c0694b37fcf80ce82783b2acc86f
-Author: markus@openbsd.org <markus@openbsd.org>
-Date: Wed May 31 10:54:00 2017 +0000
+commit 846446bf3e7421e6671a4afd074bdf15eecd7832
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Sat Jan 25 06:40:20 2020 +0000
- upstream commit
+ upstream: the GatewayPorts vs -R listen address selection logic is
- make sure we don't pass a NULL string to vfprintf
- (triggered by the principals-command regress test); ok bluhm
+ still confusing people, so add another comment explaining the special
+ handling of "localhost"; bz#3258
- Upstream-ID: eb49854f274ab37a0b57056a6af379a0b7111990
+ OpenBSD-Commit-ID: e6bf0f0fbf1c7092bf0dbd9c6eab105970b5b53a
-commit 84008608c9ee944d9f72f5100f31ccff743b10f2
-Author: markus@openbsd.org <markus@openbsd.org>
-Date: Wed May 31 10:04:29 2017 +0000
+commit 734f2f83f5ff86f2967a99d67be9ce22dd0394dd
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Sat Jan 25 06:03:10 2020 +0000
- upstream commit
+ upstream: mention that permitopen=/PermitOpen do no name to address
- use SO_ZEROIZE for privsep communication (if available)
+ translation; prompted by bz3099
- Upstream-ID: abcbb6d2f8039fc4367a6a78096e5d5c39de4a62
+ OpenBSD-Commit-ID: 0dda8e54d566b29855e76bebf9cfecce573f5c23
-commit 9e509d4ec97cb3d71696f1a2f1fdad254cbbce11
-Author: deraadt@openbsd.org <deraadt@openbsd.org>
-Date: Wed May 31 09:15:42 2017 +0000
+commit e1e97cae19ff07b7a7f7e82556bc048c3c54af63
+Author: Damien Miller <djm@mindrot.org>
+Date: Sat Jan 25 16:30:22 2020 +1100
- upstream commit
+ include tunnel device path in error message
+
+commit 0ecd20bc9f0b9c7c697c9eb014613516c8f65834
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Sat Jan 25 04:48:26 2020 +0000
+
+ upstream: unrevert this:
+
+ > revision 1.217
+ > date: 2019/11/27 03:34:04; author: dtucker; state: Exp; lines: +5 -7; commitid: wkiMn49XJyjzoJIs;
+ > Make channel_id u_int32_t and remove unnecessary check and cast that were
+ > left over from the type conversion. Noted by t-hashida@amiya.co.jp in
+ > bz#3098, ok markus@ djm@
- Switch to recallocarray() for a few operations. Both
- growth and shrinkage are handled safely, and there also is no need for
- preallocation dances. Future changes in this area will be less error prone.
- Review and one bug found by markus
+ Darren was right the first time; ok dtucker@ "agreed" markus@
- Upstream-ID: 822d664d6a5a1d10eccb23acdd53578a679d5065
+ OpenBSD-Commit-ID: 641dd1b99a6bbd85b7160da462ae1be83432c7c8
-commit dc5dc45662773c0f7745c29cf77ae2d52723e55e
-Author: deraadt@openbsd.org <deraadt@openbsd.org>
-Date: Wed May 31 08:58:52 2017 +0000
+commit a0c81d2402eedc514b9c9f25ef9604eb0576b86a
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Sat Jan 25 02:57:53 2020 +0000
- upstream commit
+ upstream: Move setting $NC into test-exec since it's now used by
- These shutdown() SHUT_RDWR are not needed before close()
- ok djm markus claudio
+ multiple tests, and in -portable we use our own local copy to avoid
+ portability problems.
- Upstream-ID: 36f13ae4ba10f5618cb9347933101eb4a98dbcb5
+ OpenBSD-Regress-ID: ceb78445fcaac317bec2fc51b3f0d9589048c114
-commit 1e0cdf8efb745d0d1116e1aa22bdc99ee731695e
-Author: markus@openbsd.org <markus@openbsd.org>
-Date: Wed May 31 08:09:45 2017 +0000
+commit e16dfa94f86358033531c4a97dcb51508ef84d49
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Sat Jan 25 13:05:42 2020 +1100
- upstream commit
-
- clear session keys from memory; ok djm@
+ Put EC key export inside OPENSSL_HAS_ECC.
- Upstream-ID: ecd178819868975affd5fd6637458b7c712b6a0f
+ Fixes link error when building against an OpenSSL that does not have
+ ECC.
-commit 92e9fe633130376a95dd533df6e5e6a578c1e6b8
-Author: markus@openbsd.org <markus@openbsd.org>
-Date: Wed May 31 07:00:13 2017 +0000
+commit 94a2e5951b374e1a89761ceaff72e66eb1946807
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Sat Jan 25 00:27:56 2020 +0000
- upstream commit
+ upstream: Wait a bit longer for the multiplex master to become ready
- remove now obsolete ctx from ssh_dispatch_run; ok djm@
+ since on very slow hosts the current delay is not sufficient and the test
+ will fail.
- Upstream-ID: 9870aabf7f4d71660c31fda91b942b19a8e68d29
+ OpenBSD-Regress-ID: 6d90c7475d67ac3a95610b64af700629ece51a48
-commit 17ad5b346043c5bbc5befa864d0dbeb76be39390
-Author: markus@openbsd.org <markus@openbsd.org>
-Date: Wed May 31 05:34:14 2017 +0000
+commit b2df804f571d77b07059f087b90955ffbc2f67d4
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Fri Jan 24 10:08:17 2020 +0000
- upstream commit
+ upstream: Add a connection test for proxycommand. This would have
- use the ssh_dispatch_run_fatal variant
+ caught the problem caused by ssh.c rev 1.507 wherein Host and Hostname were
+ swapped. Prompted by beck@
- Upstream-ID: 28c5b364e37c755d1b22652b8cd6735a05c625d8
+ OpenBSD-Regress-ID: d218500ae6aca4c479c27318fb5b09ebc00f7aae
-commit 39896b777320a6574dd06707aebac5fb98e666da
+commit c6f06fd38a257b9fcc7d6760f8fb6d505dccb628
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Wed May 31 05:08:46 2017 +0000
+Date: Sat Jan 25 00:22:31 2020 +0000
- upstream commit
+ upstream: set UpdateKnownHosts=ask by default; bz#2894; ok
- another ctx => ssh conversion (in GSSAPI code)
+ markus@
- Upstream-ID: 4d6574c3948075c60608d8e045af42fe5b5d8ae0
+ OpenBSD-Commit-ID: f09cb3177f3a14c96428e14f347e976a8a531fee
-commit 6116bd4ed354a71a733c8fd0f0467ce612f12911
-Author: Damien Miller <djm@mindrot.org>
-Date: Wed May 31 14:56:07 2017 +1000
+commit 7955633a554397bc24913cec9fd7285002935f7e
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Sat Jan 25 00:21:08 2020 +0000
- fix conversion of kexc25519s.c to struct ssh too
+ upstream: allow UpdateKnownHosts=yes to function when multiple
- git cvsimport missed this commit for some reason
+ known_hosts files are in use. When updating host keys, ssh will now search
+ subsequent known_hosts files, but will add new/changed host keys to the first
+ specified file only. bz#2738
+
+ ok markus@
+
+ OpenBSD-Commit-ID: 6ded6d878a03e57d5aa20bab9c31f92e929dbc6c
-commit d40dbdc85b6fb2fd78485ba02225511b8cbf20d7
+commit e5a278a62ab49dffe96929fa8d8506c6928dba90
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Wed May 31 04:29:44 2017 +0000
+Date: Sat Jan 25 00:06:48 2020 +0000
- upstream commit
+ upstream: process security key provider via realpath() in agent,
+
+ avoids malicious client from being able to cause agent to load arbitrary
+ libraries into ssh-sk-helper.
- spell out that custom options/extensions should follow the
- usual SSH naming rules, e.g. "extension@example.com"
+ reported by puck AT puckipedia.com; ok markus
- Upstream-ID: ab326666d2fad40769ec96b5a6de4015ffd97b8d
+ OpenBSD-Commit-ID: 1086643df1b7eee4870825c687cf0c26a6145d1c
-commit 2a108277f976e8d0955c8b29d1dfde04dcbb3d5b
+commit 89a8d4525e8edd9958ed3df60cf683551142eae0
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Wed May 31 04:17:12 2017 +0000
+Date: Sat Jan 25 00:03:36 2020 +0000
- upstream commit
+ upstream: expose PKCS#11 key labels/X.509 subjects as comments
+
+ Extract the key label or X.509 subject string when PKCS#11 keys
+ are retrieved from the token and plumb this through to places where
+ it may be used as a comment.
- one more void *ctx => struct ssh *ssh conversion
+ based on https://github.com/openssh/openssh-portable/pull/138
+ by Danielle Church
+
+ feedback and ok markus@
- Upstream-ID: d299d043471c10214cf52c03daa10f1c232759e2
+ OpenBSD-Commit-ID: cae1fda10d9e10971dea29520916e27cfec7ca35
-commit c04e979503e97f52b750d3b98caa6fe004ab2ab9
+commit a8c05c640873621681ab64d2e47a314592d5efa2
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Wed May 31 00:43:04 2017 +0000
+Date: Fri Jan 24 23:56:01 2020 +0000
- upstream commit
+ upstream: tweak proctitle to include sshd arguments, as these are
- fix possible OOB strlen() in SOCKS4A hostname parsing;
- ok markus@
+ frequently used to distinguish between multiple independent instances of the
+ server. New proctitle looks like this:
- Upstream-ID: c67297cbeb0e5a19d81752aa18ec44d31270cd11
-
-commit a3bb250c93bfe556838c46ed965066afce61cffa
-Author: jmc@openbsd.org <jmc@openbsd.org>
-Date: Tue May 30 19:38:17 2017 +0000
-
- upstream commit
+ $ pgrep -lf sshd
+ 12844 sshd: /usr/sbin/sshd -f /etc/ssh/sshd_config [listener] 0 of 10-100 startups
- tweak previous;
+ requested by sthen@ and aja@; ok aja@
- Upstream-ID: 66987651046c42d142f7318c9695fb81a6d14031
+ OpenBSD-Commit-ID: cf235a561c655a3524a82003cf7244ecb48ccc1e
-commit 1112b534a6a7a07190e497e6bf86b0d5c5fb02dc
-Author: bluhm@openbsd.org <bluhm@openbsd.org>
-Date: Tue May 30 18:58:37 2017 +0000
+commit 8075fccbd4f70a4371acabcfb47562471ff0de6f
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Fri Jan 24 23:54:40 2020 +0000
- upstream commit
+ upstream: add xextendf() to extend a string with a format
- Add RemoteCommand option to specify a command in the
- ssh config file instead of giving it on the client's command line. This
- command will be executed on the remote host. The feature allows to automate
- tasks using ssh config. OK markus@
+ (reallocating as necessary). ok aja@ as part of a larger diff
- Upstream-ID: 5d982fc17adea373a9c68cae1021ce0a0904a5ee
+ OpenBSD-Commit-ID: 30796b50d330b3e0e201747fe40cdf9aa70a77f9
-commit eb272ea4099fd6157846f15c129ac5727933aa69
-Author: markus@openbsd.org <markus@openbsd.org>
-Date: Tue May 30 14:29:59 2017 +0000
+commit d15c8adf2c6f1a6b4845131074383eb9c3d05c3d
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Fri Jan 24 05:33:01 2020 +0000
- upstream commit
+ upstream: minor tweaks to ssh-keygen -Y find-principals:
+
+ emit matched principals one per line to stdout rather than as comma-
+ separated and with a free-text preamble (easy confusion opportunity)
- switch auth2 to ssh_dispatch API; ok djm@
+ emit "not found" error to stderr
- Upstream-ID: a752ca19e2782900dd83060b5c6344008106215f
+ fix up argument testing for -Y operations and improve error message for
+ unsupported operations
+
+ OpenBSD-Commit-ID: 3d9c9a671ab07fc04a48f543edfa85eae77da69c
-commit 5a146bbd4fdf5c571f9fb438e5210d28cead76d9
-Author: markus@openbsd.org <markus@openbsd.org>
-Date: Tue May 30 14:27:22 2017 +0000
+commit c3368a5d5ec368ef6bdf9971d6330ca0e3bdca06
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Fri Jan 24 00:28:57 2020 +0000
- upstream commit
+ upstream: remove ssh-rsa (SHA1) from the list of allowed CA
- switch auth2-none.c to modern APIs; ok djm@
+ signature algorithms ok markus
- Upstream-ID: 07252b58e064d332214bcabbeae8e08c44b2001b
+ OpenBSD-Commit-ID: da3481fca8c81e6951f319a86b7be67502237f57
-commit 60306b2d2f029f91927c6aa7c8e08068519a0fa2
-Author: markus@openbsd.org <markus@openbsd.org>
-Date: Tue May 30 14:26:49 2017 +0000
+commit 4a41d245d6b13bd3882c8dc058dbd2e2b39a9f67
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Fri Jan 24 00:27:04 2020 +0000
- upstream commit
+ upstream: when signing a certificate with an RSA key, default to
- switch auth2-passwd.c to modern APIs; ok djm@
+ a safe signature algorithm (rsa-sha-512) if not is explicitly specified by
+ the user; ok markus@
- Upstream-ID: cba0a8b72b4f97adfb7e3b3fd2f8ba3159981fc7
+ OpenBSD-Commit-ID: e05f638f0be6c0266e1d3d799716b461011e83a9
-commit eb76698b91338bd798c978d4db2d6af624d185e4
-Author: markus@openbsd.org <markus@openbsd.org>
-Date: Tue May 30 14:25:42 2017 +0000
+commit 8dfb6a202c96cdf037c8ce05e53e32e0e0b7b454
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Fri Jan 24 00:00:31 2020 +0000
- upstream commit
+ upstream: allow PEM export of DSA and ECDSA keys; bz3091, patch
- switch auth2-hostbased.c to modern APIs; ok djm@
+ from Jakub Jelen ok markus@
- Upstream-ID: 146af25c36daeeb83d5dbbb8ca52b5d25de88f4e
+ OpenBSD-Commit-ID: a58edec8b9f07acab4b962a71a5125830d321b51
-commit 2ae666a8fc20b3b871b2f1b90ad65cc027336ccd
-Author: markus@openbsd.org <markus@openbsd.org>
-Date: Tue May 30 14:23:52 2017 +0000
+commit 72a8bea2d748c8bd7f076a8b39a52082c79ae95f
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Thu Jan 23 23:31:52 2020 +0000
- upstream commit
+ upstream: ssh-keygen -Y find-principals fixes based on feedback
- protocol handlers all get struct ssh passed; ok djm@
+ from Markus:
- Upstream-ID: 0ca9ea2a5d01a6d2ded94c5024456a930c5bfb5d
+ use "principals" instead of principal, as allowed_signers lines may list
+ multiple.
+
+ When the signing key is a certificate, emit only principals that match
+ the certificate principal list.
+
+ NB. the command -Y name changes: "find-principal" => "find-principals"
+
+ ok markus@
+
+ OpenBSD-Commit-ID: ab575946ff9a55624cd4e811bfd338bf3b1d0faf
-commit 94583beb24a6c5fd19cedb9104ab2d2d5cd052b6
-Author: markus@openbsd.org <markus@openbsd.org>
-Date: Tue May 30 14:19:15 2017 +0000
+commit 0585b5697201f5d8b32e6f1b0fee7e188268d30d
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Fri Jan 24 01:29:23 2020 +0000
- upstream commit
-
- ssh: pass struct ssh to auth functions, too; ok djm@
+ upstream: Do not warn about permissions on symlinks.
- Upstream-ID: d13c509cc782f8f19728fbea47ac7cf36f6e85dd
+ OpenBSD-Regress-ID: 339d4cbae224bd8743ffad9c3afb0cf3cb66c357
-commit 5f4082d886c6173b9e90b9768c9a38a3bfd92c2b
-Author: markus@openbsd.org <markus@openbsd.org>
-Date: Tue May 30 14:18:15 2017 +0000
+commit 415192348a5737a960f6d1b292a17b64d55b542c
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Thu Jan 23 11:19:12 2020 +0000
- upstream commit
+ upstream: Handle zlib compression being disabled now that it's
- sshd: pass struct ssh to auth functions; ok djm@
+ optional.
- Upstream-ID: b00a80c3460884ebcdd14ef550154c761aebe488
+ OpenBSD-Regress-ID: 0af4fbc5168e62f89d0350de524bff1cb00e707a
-commit 7da5df11ac788bc1133d8d598d298e33500524cc
-Author: markus@openbsd.org <markus@openbsd.org>
-Date: Tue May 30 14:16:41 2017 +0000
+commit fbce7c1a898ae75286349822950682cf46346121
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Thu Jan 23 10:53:04 2020 +0000
- upstream commit
-
- remove unused wrapper functions from key.[ch]; ok djm@
+ upstream: Fix typo in comment.
- Upstream-ID: ea0f4016666a6817fc11f439dd4be06bab69707e
+ OpenBSD-Commit-ID: d1d7a6553208bf439378fd1cf686a828aceb353a
-commit ff7371afd08ac0bbd957d90451d4dcd0da087ef5
-Author: markus@openbsd.org <markus@openbsd.org>
-Date: Tue May 30 14:15:17 2017 +0000
+commit ba247af8e9e302910e22881ef9d307a8afeef036
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Thu Jan 23 10:19:59 2020 +0000
- upstream commit
+ upstream: When checking for unsafe directories, ignore non-directories
- sshkey_new() might return NULL (pkcs#11 code only); ok
- djm@
+ (ie symlinks, where permissions are not relevant).
- Upstream-ID: de9f2ad4a42c0b430caaa7d08dea7bac943075dd
+ OpenBSD-Regress-ID: fb6cfc8b022becb62b2dcb99ed3f072b3326e501
-commit beb965bbc5a984fa69fb1e2b45ebe766ae09d1ef
-Author: markus@openbsd.org <markus@openbsd.org>
-Date: Tue May 30 14:13:40 2017 +0000
+commit 74deb7029be4c00810443114aac9308875a81dae
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Thu Jan 23 22:17:24 2020 +1100
- upstream commit
-
- switch sshconnect.c to modern APIs; ok djm@
+ zlib is now optional.
+
+commit 633a2af47ee90291aaf93969aeee1e5046074c7c
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Thu Jan 23 22:16:51 2020 +1100
+
+ Plumb WITH_ZLIB into configure.
- Upstream-ID: 27be17f84b950d5e139b7a9b281aa487187945ad
+ This allows zlib support to be disabled by ./configure --without-zlib.
-commit 00ed75c92d1f95fe50032835106c368fa22f0f02
-Author: markus@openbsd.org <markus@openbsd.org>
-Date: Tue May 30 14:10:53 2017 +0000
+commit 7f8e66fea8c4e2a910df9067cb7638999b7764d5
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Thu Jan 23 10:24:29 2020 +0000
- upstream commit
+ upstream: Make zlib optional. This adds a "ZLIB" build time option
- switch auth2-pubkey.c to modern APIs; with & ok djm@
+ that allows building without zlib compression and associated options. With
+ feedback from markus@, ok djm@
- Upstream-ID: 8f08d4316eb1b0c4ffe4a206c05cdd45ed1daf07
+ OpenBSD-Commit-ID: 44c6e1133a90fd15a3aa865bdedc53bab28b7910
-commit 54d90ace1d3535b44d92a8611952dc109a74a031
-Author: markus@openbsd.org <markus@openbsd.org>
-Date: Tue May 30 08:52:19 2017 +0000
+commit 69ac4e33023b379e9a8e9b4b6aeeffa6d1fcf6fa
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Thu Jan 23 07:54:04 2020 +0000
- upstream commit
+ upstream: remove trailing period characters from pub/priv key
- switch from Key typedef with struct sshkey; ok djm@
+ pathnames - they make them needlessly more difficult to cut and paste without
+ error; ok markus@ & dtucker@
- Upstream-ID: 3067d33e04efbe5131ce8f70668c47a58e5b7a1f
+ OpenBSD-Commit-ID: abdcfd1a5723fcac0711feee7665edc66ae2335a
-commit c221219b1fbee47028dcaf66613f4f8d6b7640e9
-Author: markus@openbsd.org <markus@openbsd.org>
-Date: Tue May 30 08:49:58 2017 +0000
+commit 945bf52c3c815d95b1e842ebf6c910c3524bd5bb
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Thu Jan 23 21:06:45 2020 +1100
- upstream commit
+ Fix a couple of mysig_t leftovers.
+
+commit 84226b447d45fe4542613de68c2ca59a890d7c01
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Thu Jan 23 18:55:24 2020 +1100
+
+ Remove mysignal wrapper.
- remove ssh1 references; ok djm@
+ We switched the main code to use sigaction(), so the wrapper is no
+ longer used.
+
+commit 5533c2fb7ef21172fa3708d66b03faa2c6b3d93f
+Author: jmc@openbsd.org <jmc@openbsd.org>
+Date: Thu Jan 23 07:16:38 2020 +0000
+
+ upstream: new sentence, new line;
- Upstream-ID: fc23b7578e7b0a8daaec72946d7f5e58ffff5a3d
+ OpenBSD-Commit-ID: b6c3f2f36ec77e99198619b38a9f146655281925
-commit afbfa68fa18081ef05a9cd294958509a5d3cda8b
-Author: markus@openbsd.org <markus@openbsd.org>
-Date: Tue May 30 08:49:32 2017 +0000
+commit 3bf2a6ac791d64046a537335a0f1d5e43579c5ad
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Thu Jan 23 07:10:22 2020 +0000
- upstream commit
+ upstream: Replace all calls to signal(2) with a wrapper around
- revise sshkey_load_public(): remove ssh1 related
- comments, remove extra open()/close() on keyfile, prevent leak of 'pub' if
- 'keyp' is NULL, replace strlcpy+cat with asprintf; ok djm@
+ sigaction(2). This wrapper blocks all other signals during the handler
+ preventing races between handlers, and sets SA_RESTART which should reduce
+ the potential for short read/write operations.
- Upstream-ID: 6175e47cab5b4794dcd99c1175549a483ec673ca
+ OpenBSD-Commit-ID: 5e047663fd77a40d7b07bdabe68529df51fd2519
-commit 813f55336a24fdfc45e7ed655fccc7d792e8f859
-Author: markus@openbsd.org <markus@openbsd.org>
-Date: Fri May 26 20:34:49 2017 +0000
+commit e027c044c796f3a01081a91bee55741204283f28
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Thu Jan 23 04:54:34 2020 +0000
- upstream commit
+ upstream: missing header change from previous; spotted by dtucker@
- sshbuf_consume: reset empty buffer; ok djm@
+ OpenBSD-Commit-ID: 321ce74c0a5bbd0f02fa3f20cb5cf2a952c6b96f
+
+commit 7e1323102b1b04eef391b01e180710a2d408a7ab
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Thu Jan 23 03:42:41 2020 +0000
+
+ upstream: Check for and warn about StrictModes permission problems. ok tb@
- Upstream-ID: 0d4583ba57f69e369d38bbd7843d85cac37fa821
+ OpenBSD-Regress-ID: 4841704ccdee50ee7efc6035bc686695c6ac2991
-commit 6cf711752cc2a7ffaad1fb4de18cae65715ed8bb
-Author: markus@openbsd.org <markus@openbsd.org>
-Date: Fri May 26 19:35:50 2017 +0000
+commit 84de1c27f845d15c859db44e7070a46f45504b66
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Thu Jan 23 03:35:07 2020 +0000
- upstream commit
+ upstream: Also test PuTTY chacha20.
- remove SSH_CHANNEL_XXX_DRAINING (ssh1 only); ok djm@
+ OpenBSD-Regress-ID: 7af6a0e8763b05f1f8eee6bca5f31fcb16151040
+
+commit c7ed15a39695ecd5f1f21842d8d9cd22246d4ee2
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Thu Jan 23 03:24:38 2020 +0000
+
+ upstream: Also test PuTTY ecdh kex methods.
- Upstream-ID: e2e225b6ac67b84dd024f38819afff2554fafe42
+ OpenBSD-Regress-ID: ec4017dce612131842398a03e93007a869c2c133
-commit 364f0d5edea27767fb0f915ea7fc61aded88d3e8
-Author: markus@openbsd.org <markus@openbsd.org>
-Date: Fri May 26 19:34:12 2017 +0000
+commit c4b3a128954ee1b7fbcbda167baf8aca1a3d1c84
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Thu Jan 23 02:46:49 2020 +0000
- upstream commit
+ upstream: Remove unsupported algorithms from list of defaults at run
- remove channel_input_close_confirmation (ssh1 only); ok
- djm@
+ time and remove ifdef and distinct settings for OPENSSL=no case.
- Upstream-ID: 8e7c8c38f322d255bb0294a5c0ebef53fdf576f1
+ This will make things much simpler for -portable where the exact set
+ of algos depends on the configuration of both OpenSSH and the libcrypto
+ it's linked against (if any). ok djm@
+
+ OpenBSD-Commit-ID: e0116d0183dcafc7a9c40ba5fe9127805c5dfdd2
-commit 8ba0fd40082751dbbc23a830433488bbfb1abdca
+commit 56cffcc09f8a2e661d2ba02e61364ae6f998b2b1
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri May 26 01:40:07 2017 +0000
+Date: Thu Jan 23 02:43:48 2020 +0000
- upstream commit
+ upstream: add a new signature operations "find-principal" to look
- fix references to obsolete v00 cert format; spotted by
- Jakub Jelen
+ up the principal associated with a signature from an allowed-signers file.
+ Work by Sebastian Kinne; ok dtucker@
- Upstream-ID: 7600ce193ab8fd19451acfe24fc2eb39d46b2c4f
+ OpenBSD-Commit-ID: 6f782cc7e18e38fcfafa62af53246a1dcfe74e5d
-commit dcc714c65cfb81eb6903095b4590719e8690f3da
-Author: Mike Frysinger <vapier@chromium.org>
-Date: Wed May 24 23:21:19 2017 -0400
+commit 65cf8730de6876a56595eef296e07a86c52534a6
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Wed Jan 22 07:38:30 2020 +0000
- configure: actually set cache vars when cross-compiling
+ upstream: Ignore whitespace when checking explict fingerprint.
+
+ When confirming a host key using the fingerprint itself, ignore leading and
+ trailing whitespace. ok deraadt@ djm@
- The cross-compiling fallback message says it's assuming the test
- passed, but it didn't actually set the cache var which causes
- later tests to fail.
+ OpenBSD-Commit-ID: cafd7f803bbdcd40c3a8f8f1a77747e6b6d8c011
-commit 947a3e829a5b8832a4768fd764283709a4ca7955
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sat May 20 02:35:47 2017 +0000
+commit 8d3af6ebdf524b34087a0a3ae415b5141ba10572
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Wed Jan 22 07:31:27 2020 +0000
- upstream commit
+ upstream: Increase keyscan timeout from default. On slow hosts 3
- there's no reason to artificially limit the key path
- here, just check that it fits PATH_MAX; spotted by Matthew Patton
+ concurrent keyscans can hit the default 5 second timeout, so increase to 15
+ seconds.
- Upstream-ID: 858addaf2009c9cf04d80164a41b2088edb30b58
+ OpenBSD-Regress-ID: 16383dec166af369b7fb9948572856f5d544c93f
-commit 773224802d7cb250bb8b461546fcce10567b4b2e
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri May 19 21:07:17 2017 +0000
+commit 6c30c9adbeeed09a8a9e7a69974cfa1f1ddd1e9e
+Author: tedu@openbsd.org <tedu@openbsd.org>
+Date: Wed Jan 22 04:58:23 2020 +0000
- upstream commit
+ upstream: remove diffie-hellman-group14-sha1 from default kex to
- Now that we no longer support SSHv1, replace the contents
- of this file with a pointer to
- https://tools.ietf.org/html/draft-miller-ssh-agent-00 It's better edited,
- doesn't need to document stuff we no longer implement and does document stuff
- that we do implement (RSA SHA256/512 signature flags)
+ see what happens. general mostly ok
- Upstream-ID: da8cdc46bbcc266efabd565ddddd0d8e556f846e
+ OpenBSD-Commit-ID: 216b7b8462d2ef5f4531f26cb2cb839b2153dad9
-commit 54cd41a4663fad66406dd3c8fe0e4760ccd8a899
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Wed May 17 01:24:17 2017 +0000
+commit 4a32c0ca44a2dc2a358f69b5d43c08e528b44b39
+Author: claudio@openbsd.org <claudio@openbsd.org>
+Date: Wed Jan 22 04:51:51 2020 +0000
- upstream commit
+ upstream: For ssh-keygen -lF only add a space after key fingerprint
- allow LogLevel in sshd_config Match blocks; ok dtucker
- bz#2717
+ when there is a comment. This makes copy-paste of fingerprints into ssh
+ easier. OK djm@
- Upstream-ID: 662e303be63148f47db1aa78ab81c5c2e732baa8
+ OpenBSD-Commit-ID: fa01d95624f65c1eb4dc7c575d20d77c78010dfd
-commit 277abcda3f1b08d2376686f0ef20320160d4c8ab
+commit 37d3b736506760e4ebc7fe56255f7b8ea823a00c
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Tue May 16 16:56:15 2017 +0000
+Date: Wed Jan 22 04:49:16 2020 +0000
- upstream commit
+ upstream: some __func__ and strerror(errno) here; no functional
- remove duplicate check; spotted by Jakub Jelen
+ change
- Upstream-ID: 30c2996c1767616a8fdc49d4cee088efac69c3b0
+ OpenBSD-Commit-ID: 6c3ddd5f848b99ea560b31d3fba99ceed66cef37
-commit adb47ce839c977fa197e770c1be8f852508d65aa
+commit e2031b05c74c98b141179ceab13a323cf17d01e5
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Tue May 16 16:54:05 2017 +0000
+Date: Wed Jan 22 02:25:21 2020 +0000
- upstream commit
+ upstream: factor out parsing of allowed-signers lines
- mention that Ed25519 keys are valid as CA keys; spotted
- by Jakub Jelen
-
- Upstream-ID: d3f6db58b30418cb1c3058211b893a1ffed3dfd4
+ OpenBSD-Commit-ID: 85ee6aeff608371826019ea85e55bfa87f79d06e
-commit 6bdf70f01e700348bb4d8c064c31a0ab90896df6
+commit 47160e1de8c2f638f0ef41cef42c976417b61778
Author: Damien Miller <djm@mindrot.org>
-Date: Tue May 9 14:35:03 2017 +1000
+Date: Wed Jan 22 10:30:13 2020 +1100
- clean up regress files and add a .gitignore
+ unbreak fuzzer support for recent ssh-sk.h changes
-commit 7bdb2eeb1d3c26acdc409bd94532eefa252e440b
+commit 70d38c3cfd4550e8ee66cc3bf1b91aa339c91df5
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Mon May 8 22:57:38 2017 +0000
+Date: Tue Jan 21 22:39:57 2020 +0000
- upstream commit
+ upstream: expose the number of currently-authenticating connections
- remove hmac-ripemd160; ok dtucker
+ along with the MaxStartups limit in the proctitle; suggestion from Philipp
+ Marek, w/ feedback from Craig Miskell ok dtucker@
- Upstream-ID: 896e737ea0bad6e23327d1c127e02d5e9e9c654d
+ OpenBSD-Commit-ID: a4a6db2dc1641a5df8eddf7d6652176e359dffb3
-commit 5f02bb1f99f70bb422be8a5c2b77ef853f1db554
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Mon May 8 06:11:06 2017 +0000
+commit a78c66d5d2144bd49779bc80a647346bd3d7233d
+Author: naddy@openbsd.org <naddy@openbsd.org>
+Date: Tue Jan 21 12:40:04 2020 +0000
- upstream commit
+ upstream: document the default value of the ControlPersist option;
- make requesting bad ECDSA bits yield the same error
- (SSH_ERR_KEY_LENGTH) as the same mistake for RSA/DSA
+ ok dtucker@ djm@
- Upstream-ID: bf40d3fee567c271e33f05ef8e4e0fa0b6f0ece6
+ OpenBSD-Commit-ID: 0788e7f2b5a9d4e36d3d2ab378f73329320fef66
-commit d757a4b633e8874629a1442c7c2e7b1b55d28c19
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Mon May 8 06:08:42 2017 +0000
+commit b46a6325849e40aa2e4b0d962a6f00f708f6576a
+Author: Damien Miller <djm@mindrot.org>
+Date: Wed Jan 22 09:28:32 2020 +1100
- upstream commit
-
- fix for new SSH_ERR_KEY_LENGTH error value
-
- Upstream-Regress-ID: c38a6e6174d4c3feca3518df150d4fbae0dca8dc
+ remove accidental change in f8c11461
-commit 2e58a69508ac49c02d1bb6057300fa6a76db1045
+commit 80d3bebcab96fe1d177e45906e10db16895da01d
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Mon May 8 06:03:39 2017 +0000
+Date: Tue Jan 21 11:06:09 2020 +0000
- upstream commit
+ upstream: don't #ifdef out the KRL code when compiling without
- helps if I commit the correct version of the file. fix
- missing return statement.
+ libcrypto support; it works just fine and disabling it breaks a few tests. ok
+ dtucker@
- Upstream-ID: c86394a3beeb1ec6611e659bfa830254f325546c
+ OpenBSD-Commit-ID: 65f6272c4241eb4b04de78b012fe98b2b555ad44
-commit effaf526bfa57c0ac9056ca236becf52385ce8af
+commit f8c11461aa6db168fc5e7eeae448b4cbbf59642a
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Mon May 8 01:52:49 2017 +0000
+Date: Tue Jan 21 08:06:27 2020 +0000
- upstream commit
+ upstream: pass SSH_SK_HELPER explicitly past $SUDO to avoid it getting
- remove arcfour, blowfish and CAST here too
+ cleared; with dtucker@
- Upstream-Regress-ID: c613b3bcbef75df1fe84ca4dc2d3ef253dc5e920
+ OpenBSD-Regress-ID: 03178a0580324bf0dff28f7eac6c3edbc5407f8e
-commit 7461a5bc571696273252df28a1f1578968cae506
+commit b5fcb0ac1cc0ef01aeec1c089146298654ab3ae0
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Mon May 8 00:21:36 2017 +0000
+Date: Tue Jan 21 07:07:31 2020 +0000
- upstream commit
+ upstream: check access(ssh-sk-helper, X_OK) to provide friendly
- I was too aggressive with the scalpel in the last commit;
- unbreak sshd, spotted quickly by naddy@
+ error message for misconfigured helper paths
- Upstream-ID: fb7e75d2b2c7e6ca57dee00ca645e322dd49adbf
+ OpenBSD-Commit-ID: 061bcc262155d12e726305c91394ac0aaf1f8341
-commit bd636f40911094a39c2920bf87d2ec340533c152
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sun May 7 23:15:59 2017 +0000
+commit 56bced43c14dc6fa2bfa1816007e441644105609
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Tue Jan 21 06:09:56 2020 +0000
- upstream commit
+ upstream: Document sntrup4591761x25519-sha512@tinyssh.org. Patch
- Refuse RSA keys <1024 bits in length. Improve reporting
- for keys that do not meet this requirement. ok markus@
+ from jtesta@positronsecurity.com via github PR#151.
- Upstream-ID: b385e2a7b13b1484792ee681daaf79e1e203df6c
+ OpenBSD-Commit-ID: f3d48168623045c258245c340a5a2af7dbb74edc
-commit 70c1218fc45757a030285051eb4d209403f54785
+commit 4a05d789b86314fef7303824f69defbc6b96ed60
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sun May 7 23:13:42 2017 +0000
+Date: Tue Jan 21 05:56:56 2020 +0000
- upstream commit
+ upstream: fix ssh-keygen not displaying authenticator touch
- Don't offer CBC ciphers by default in the client. ok
- markus@
+ prompt; reported by jmc@
- Upstream-ID: 94c9ce8d0d1a085052e11c7f3307950fdc0901ef
+ OpenBSD-Commit-ID: 04d4f582fc194eb3897ebcbfe286c49958ba2859
-commit acaf34fd823235d549c633c0146ee03ac5956e82
+commit 881aded0389d999375f926051491a944c6d8752b
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sun May 7 23:12:57 2017 +0000
+Date: Tue Jan 21 05:56:27 2020 +0000
- upstream commit
+ upstream: a little more verbosity in sign_and_send_pubkey() debug
- As promised in last release announcement: remove
- support for Blowfish, RC4 and CAST ciphers. ok markus@ deraadt@
+ messages
- Upstream-ID: 21f8facdba3fd8da248df6417000867cec6ba222
+ OpenBSD-Commit-ID: 6da47a0e6373f6683006f49bc2a516d197655508
-commit 3e371bd2124427403971db853fb2e36ce789b6fd
+commit b715fdc71bbd009d0caff691ab3fc04903c4aee8
Author: naddy@openbsd.org <naddy@openbsd.org>
-Date: Fri May 5 10:42:49 2017 +0000
+Date: Sat Jan 18 21:16:43 2020 +0000
- upstream commit
+ upstream: one more replacement "(security) key" -> "(FIDO)
- more simplification and removal of SSHv1-related code;
- ok djm@
+ authenticator"
- Upstream-ID: d2f041aa0b79c0ebd98c68a01e5a0bfab2cf3b55
+ OpenBSD-Commit-ID: 031bca03c1d1f878ab929facd561911f1bc68dfd
-commit 2e9c324b3a7f15c092d118c2ac9490939f6228fd
+commit 84911da1beeb6ed258a43468efb316cd39fb6855
Author: naddy@openbsd.org <naddy@openbsd.org>
-Date: Fri May 5 10:41:58 2017 +0000
+Date: Sat Jan 18 15:45:41 2020 +0000
- upstream commit
+ upstream: undo merge error and replace the term "security key"
- remove superfluous protocol 2 mentions; ok jmc@
+ again
- Upstream-ID: 0aaf7567c9f2e50fac5906b6a500a39c33c4664d
+ OpenBSD-Commit-ID: 341749062c089cc360a7877e9ee3a887aecde395
-commit 744bde79c3361e2153cb395a2ecdcee6c713585d
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Thu May 4 06:10:57 2017 +0000
+commit e8c06c4ee708720efec12cd1a6f78a3c6d76b7f0
+Author: naddy@openbsd.org <naddy@openbsd.org>
+Date: Fri Jan 17 20:13:47 2020 +0000
- upstream commit
+ upstream: Document loading of resident keys from a FIDO
- since a couple of people have asked, leave a comment
- explaining why we retain SSH v.1 support in the "delete all keys from agent"
- path.
+ authenticator.
- Upstream-ID: 4b42dcfa339813c15fe9248a2c1b7ed41c21bbb4
-
-commit 0c378ff6d98d80bc465a4a6a787670fb9cc701ee
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Thu May 4 01:33:21 2017 +0000
-
- upstream commit
+ * Rename -O to -K to keep "-O option" available.
+ * Document -K.
+ * Trim usage() message down to synopsis, like all other commands.
- another tentacle: cipher_set_key_string() was only ever
- used for SSHv1
+ ok markus@
- Upstream-ID: 7fd31eb6c48946f7e7cc12af0699fe8eb637e94a
+ OpenBSD-Commit-ID: 015c2c4b28f8e19107adc80351b44b23bca4c78a
-commit 9a82e24b986e3e0dc70849dbb2c19aa6c707b37f
+commit 0d005d6372a067b59123dec8fc6dc905f2c09e1e
Author: naddy@openbsd.org <naddy@openbsd.org>
-Date: Wed May 3 21:49:18 2017 +0000
+Date: Tue Jan 14 15:07:30 2020 +0000
- upstream commit
+ upstream: sync ssh-keygen.1 and ssh-keygen's usage() with each
- restore mistakenly deleted description of the
- ConnectionAttempts option ok markus@
+ other and reality ok markus@
- Upstream-ID: 943002b1b7c470caea3253ba7b7348c359de0348
+ OpenBSD-Commit-ID: cdf64454f2c3604c25977c944e5b6262a3bcce92
-commit 768405fddf64ff83aa6ef701ebb3c1f82d98a2f3
+commit b8a4ca2ebfddab862f7eb1ea2a07fb9f70330429
Author: naddy@openbsd.org <naddy@openbsd.org>
-Date: Wed May 3 21:08:09 2017 +0000
+Date: Sat Jan 11 16:23:10 2020 +0000
- upstream commit
+ upstream: revise the fix for reversed arguments on
- remove miscellaneous SSH1 leftovers; ok markus@
+ expand_proxy_command()
- Upstream-ID: af23696022ae4d45a1abc2fb8b490d8d9dd63b7c
+ Always put 'host' before 'host_arg' for consistency. ok markus@ djm@
+
+ OpenBSD-Commit-ID: 1ba5b25472779f1b1957295fcc6907bb961472a3
-commit 1a1b24f8229bf7a21f89df21987433283265527a
-Author: jmc@openbsd.org <jmc@openbsd.org>
-Date: Wed May 3 10:01:44 2017 +0000
+commit 57b181eaf2d34fd0a1b51ab30cb6983df784de5a
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Fri Jan 10 23:43:26 2020 +0000
- upstream commit
+ upstream: pass the log-on-stderr flag and log level through to
- more protocol 1 bits removed; ok djm
+ ssh-sk-helper, making debugging a bit easier. ok markus@
- Upstream-ID: b5b977eaf756915acb56aef3604a650e27f7c2b9
+ OpenBSD-Commit-ID: 2e7aea6bf5770d3f38b7c7bba891069256c5a49a
-commit 2b6f799e9b230cf13a7eefc05ecead7d8569d6b5
-Author: jmc@openbsd.org <jmc@openbsd.org>
-Date: Wed May 3 06:32:02 2017 +0000
+commit a8bd5fdbdb7581afc7123a042a7cd6ca25357388
+Author: Damien Miller <djm@mindrot.org>
+Date: Tue Jan 21 12:32:16 2020 +1100
- upstream commit
-
- more protocol 1 stuff to go; ok djm
+ Wrap copy_environment_blacklist() in #ifdef
- Upstream-ID: 307a30441d2edda480fd1661d998d36665671e47
+ It's only needed for USE_PAM or HAVE_CYGWIN cases and will cause compiler
+ warnings otherwise.
-commit f10c0d32cde2084d2a0b19bc47d80cb93e85a093
-Author: jmc@openbsd.org <jmc@openbsd.org>
-Date: Tue May 2 17:04:09 2017 +0000
+commit 10ecc647fc1db8d2dde9f6b9b826b201dfc48b62
+Author: Damien Miller <djm@mindrot.org>
+Date: Tue Jan 21 12:20:05 2020 +1100
- upstream commit
+ depend
+
+commit b3f7009c9ffa5891283ed96e043001e09934a8d4
+Author: Ruben Kerkhof <ruben@rubenkerkhof.com>
+Date: Mon Jan 20 11:56:48 2020 +0100
+
+ Fix missing prototype warning for copy_environment
- rsa1 is no longer valid;
+ This function is only used in this file, and only on Cygwin, so make
+ it static and hide it behind HAVE_CYGWIN. Prevents missing prototype
+ warning.
+
+commit 0c428c0e991e2c4fabc48cf5d9b8f84c9412e0c3
+Author: Ruben Kerkhof <ruben@rubenkerkhof.com>
+Date: Mon Jan 20 13:58:11 2020 +0100
+
+ configure.ac: fix ldns test
- Upstream-ID: 9953d09ed9841c44b7dcf7019fa874783a709d89
+ When running ./configure --with-ldns, if ldns-config cannot be found, we
+ add -Iyes/include to CPPFLAGS and -Lyes/lib to LDFLAGS. Fix that.
-commit 42b690b4fd0faef78c4d68225948b6e5c46c5163
-Author: jmc@openbsd.org <jmc@openbsd.org>
-Date: Tue May 2 14:06:37 2017 +0000
+commit 6089abf715e2784751c9f62697e09bb103295b93
+Author: Ruben Kerkhof <ruben@rubenkerkhof.com>
+Date: Mon Jan 20 12:13:26 2020 +0100
- upstream commit
+ Make sshpam_password_change_required static.
- add PubKeyAcceptedKeyTypes to the -o list: scp(1) has
- it, so i guess this should too;
+ sshpam_password_change_required is only used in auth-pam.c, so make it
+ static to prevent a mising prototype warning.
+
+commit 5a9b9c82851b7bc219dc3a65962a80803c76c102
+Author: Ruben Kerkhof <ruben@rubenkerkhof.com>
+Date: Mon Jan 20 12:24:51 2020 +0100
+
+ sandbox-darwin.c: fix missing prototypes.
- Upstream-ID: 7fab32e869ca5831d09ab0c40d210b461d527a2c
+ Include the right header just like the other sandbox files.
+ Fixes missing prototype warnings for ssh_sandbox_* functions.
-commit d852603214defd93e054de2877b20cc79c19d0c6
-Author: jmc@openbsd.org <jmc@openbsd.org>
-Date: Tue May 2 13:44:51 2017 +0000
+commit 335dc93526942a650f6c69666b3f6ca44d0a2910
+Author: Ruben Kerkhof <ruben@rubenkerkhof.com>
+Date: Mon Jan 20 11:09:27 2020 +0100
- upstream commit
+ Fix a few warnings when on Mac OS X.
- remove now obsolete protocol1 options from the -o
- lists;
+ Include stdlib.h for calloc, malloc, free and setenv.
+
+commit 0488dc2d3050ea1a99ef5cf44afc50ffbf3f1315
+Author: Ruben Kerkhof <ruben@rubenkerkhof.com>
+Date: Mon Jan 20 10:32:23 2020 +0100
+
+ Fix building without openssl.
- Upstream-ID: 828e478a440bc5f9947672c392420510a362b3dd
+ This fixes the following when there are no openssl headers on the system:
+ ssh-ecdsa-sk.c:34:10: fatal error: 'openssl/bn.h' file not found
-commit 8b60ce8d8111e604c711c4cdd9579ffe0edced74
-Author: jmc@openbsd.org <jmc@openbsd.org>
-Date: Tue May 2 09:05:58 2017 +0000
+commit e6b7157b4ef29c83ec3a2d1d7c927e4b8898f9bb
+Author: Ruben Kerkhof <ruben@rubenkerkhof.com>
+Date: Wed Jan 15 16:08:55 2020 +0100
- upstream commit
+ Add config.log to .gitignore
+
+commit 515e10ddf9644010b88cfd7ecf601f4306d42232
+Author: Ruben Kerkhof <ruben@rubenkerkhof.com>
+Date: Wed Jan 15 16:16:31 2020 +0100
+
+ Fix typo in README.md, s/crytpo/crypto/
+
+commit 1af3354aea3c4bfa5b5ecfb5d1ff3ad231c2073c
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Wed Jan 15 16:22:36 2020 +1100
+
+ Wrap stdint.h in ifdef HAVE_STDINT_H.
+
+commit 429170f273ce1b0140f8111a45ba69390d98de3a
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Tue Jan 14 14:41:47 2020 +1100
+
+ Wrap stdint.h inside HAVE_STDINT_H.
+
+commit a0989b60211b6f1c2313e1397c526d883a23a075
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Tue Jan 14 14:26:41 2020 +1100
+
+ Include compat header for definitions.
+
+commit e0cedcad51fe02683943bf4f1ad2961aa3f35313
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Tue Jan 14 09:42:52 2020 +1100
+
+ Improve search for 'struct timespec'.
- more -O shuffle; ok djm
+ Make struct timespec test consistent with existing timeval test.
+ Include time.h for timespec in compat header where required.
+
+commit acaf9e058594310001ce64468ed2923dc6323e81
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Tue Jan 14 12:43:03 2020 +1100
+
+ Update depend to remove rmd160.h.
+
+commit 26b2675b0c3e3efea11a52609073aec01736ec84
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Tue Jan 14 07:24:46 2020 +1100
+
+ Remove configure test & compat code for ripemd160.
- Upstream-ID: c239991a3a025cdbb030b73e990188dd9bfbeceb
+ RIPEMD160 support was removed upstream in 2017, however we still had
+ a configure test and compat code for it, so clean those up now.
-commit 3575f0b12afe6b561681582fd3c34067d1196231
+commit ed3ad71b17adcd1fb4431d145f53cee1c6a1135e
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Tue May 2 08:54:19 2017 +0000
+Date: Thu Jan 9 03:28:38 2020 +0000
- upstream commit
+ upstream: fix reversed arguments on expand_proxy_command(); spotted
- remove -1 / -2 options; pointed out by jmc@
+ by anton@
- Upstream-ID: 65d2a816000741a95df1c7cfdb5fa8469fcc7daa
+ OpenBSD-Commit-ID: db1c32478a01dfbc9c4db171de0f25907bea5775
-commit 4f1ca823bad12e4f9614895eefe0d0073b84a28f
+commit cd53476383f0cf475f40ba8ac8deb6b76dd5ce4e
Author: jmc@openbsd.org <jmc@openbsd.org>
-Date: Tue May 2 08:06:33 2017 +0000
+Date: Mon Jan 6 07:43:28 2020 +0000
- upstream commit
+ upstream: put the fido options in a list, and tidy up the text a
- remove options -12 from usage();
+ little; ok djm
- Upstream-ID: db7ceef25132e63b50ed05289bf447fece1d1270
+ OpenBSD-Commit-ID: 491ce15ae52a88b7a6a2b3b6708a14b4aacdeebb
-commit 6b84897f7fd39956b849eac7810319d8a9958568
-Author: jmc@openbsd.org <jmc@openbsd.org>
-Date: Tue May 2 07:13:31 2017 +0000
+commit 30f704ebc0e9e32b3d12f5d9e8c1b705fdde2c89
+Author: Jeremy Drake <github@jdrake.com>
+Date: Fri Oct 11 18:31:05 2019 -0700
- upstream commit
+ Deny (non-fatal) ipc in preauth privsep child.
- tidy up -O somewhat; ok djm
+ As noted in openssh/openssh-portable#149, i386 does not have have
+ _NR_shmget etc. Instead, it has a single ipc syscall (see man 2 ipc,
+ https://linux.die.net/man/2/ipc). Add this syscall, if present, to the
+ list of syscalls that seccomp will deny non-fatally.
+
+commit b110cefdfbf5a20f49b774a55062d6ded2fb6e22
+Author: Khem Raj <raj.khem@gmail.com>
+Date: Tue Jan 7 16:26:45 2020 -0800
+
+ seccomp: Allow clock_gettime64() in sandbox.
- Upstream-ID: 804405f716bf7ef15c1f36ab48581ca16aeb4d52
+ This helps sshd accept connections on mips platforms with
+ upcoming glibc ( 2.31 )
-commit d1c6b7fdbdfe4a7a37ecd48a97f0796b061c2868
+commit 3cc60c899a92a469e5118310ba6b74cb57215618
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Mon May 1 22:09:48 2017 +0000
+Date: Mon Jan 6 02:39:30 2020 +0000
- upstream commit
+ upstream: missing else in check_enroll_options()
- when freeing a bitmap, zero all it bytes; spotted by Ilya
- Kaliman
+ OpenBSD-Commit-ID: e058fb918fda56ddbbf0bee910101004cec421d4
+
+commit ff5784e2698d6c41e9f39ce4df24968c1beeb2bb
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Mon Jan 6 02:24:28 2020 +0000
+
+ upstream: fix error message
- Upstream-ID: 834ac024f2c82389d6ea6b1c7d6701b3836e28e4
+ OpenBSD-Commit-ID: 1eb52025658eb78ea6223181e552862198d3d505
-commit 0f163983016c2988a92e039d18a7569f9ea8e071
+commit dd2acc8b862c09751621995fba2d5fa6f4e24cc9
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Mon May 1 14:08:26 2017 +0000
+Date: Mon Jan 6 02:07:50 2020 +0000
- upstream commit
+ upstream: adapt sk-dummy to SK API changes
- this one I did forget to "cvs rm"
+ also, make it pull prototypes directly from sk-api.c and #error
+ if the expected version changes. This will make any future regress
+ test breakage because of SK API changes much more apparent
- Upstream-ID: 5781670c0578fe89663c9085ed3ba477cf7e7913
+ OpenBSD-Regress-ID: 79b07055de4feb988e31da71a89051ad5969829d
-commit 21ed00a8e26fe8a772bcca782175fafc2b0890ed
+commit c312ca077cd2a6c15545cd6b4d34ee2f69289174
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Mon May 1 09:27:45 2017 +0000
+Date: Mon Jan 6 02:00:46 2020 +0000
- upstream commit
+ upstream: Extends the SK API to accept a set of key/value options
+
+ for all operations. These are intended to future-proof the API a little by
+ making it easier to specify additional fields for without having to change
+ the API version for each.
+
+ At present, only two options are defined: one to explicitly specify
+ the device for an operation (rather than accepting the middleware's
+ autoselection) and another to specify the FIDO2 username that may
+ be used when generating a resident key. These new options may be
+ invoked at key generation time via ssh-keygen -O
- don't know why cvs didn't exterminate these the first
- time around, I use rm -f and everuthing...
+ This also implements a suggestion from Markus to avoid "int" in favour
+ of uint32_t for the algorithm argument in the API, to make implementation
+ of ssh-sk-client/helper a little easier.
- pointed out by sobrado@
+ feedback, fixes and ok markus@
- Upstream-ID: a6c44a0c2885330d322ee01fcfd7f6f209b1e15d
+ OpenBSD-Commit-ID: 973ce11704609022ab36abbdeb6bc23c8001eabc
-commit d29ba6f45086703fdcb894532848ada3427dfde6
-Author: Darren Tucker <dtucker@zip.com.au>
-Date: Mon May 1 13:53:07 2017 +1000
+commit 2ab335712d084d9ccaf3f53afc3fa9535329da87
+Author: beck@openbsd.org <beck@openbsd.org>
+Date: Sun Jan 5 16:28:22 2020 +0000
- Define INT32_MAX and INT64_MAX if needed.
+ upstream: fix CanonicalizeHostname, broken by rev 1.507
+
+ Issue noticed and reported by Pierre-Olivier Martel <pom@apple.com>
+ ok dtucker@ markus@ djm@
+
+ OpenBSD-Commit-ID: 749f3168ec520609c35b0c4e1984e5fa47f16094
-commit 329037e389f02ec95c8e16bf93ffede94d3d44ce
-Author: Darren Tucker <dtucker@zip.com.au>
-Date: Mon May 1 13:19:41 2017 +1000
+commit 69e44ba701b90b0f530d64c3fe4363ea86e50cd3
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Mon Jan 6 09:02:53 2020 +1100
- Wrap stdint.h in HAVE_STDINT_H
+ Fix typo: 'you' -> 'your'.
+
+ bz#3108 from jmckitrick@gmail.com.
-commit f382362e8dfb6b277f16779ab1936399d7f2af78
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Mon May 1 02:27:11 2017 +0000
+commit 7652a57662969bd5c61448b3843ec6d407ad12be
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Mon Jan 6 08:56:46 2020 +1100
- upstream commit
-
- remove unused variable
+ Remove auth-skey.c.
- Upstream-ID: 66011f00819d0e71b14700449a98414033284516
+ S/Key support was removed in OpenSSH 7.8 but this file was missed.
-commit dd369320d2435b630a5974ab270d686dcd92d024
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sun Apr 30 23:34:55 2017 +0000
+commit c593cc5e826c9f4ec506e22b629d37cabfaacff9
+Author: jmc@openbsd.org <jmc@openbsd.org>
+Date: Fri Jan 3 07:33:33 2020 +0000
- upstream commit
+ upstream: the download resident keys option is -K (upper) not -k
- eliminate explicit specification of protocol in tests and
- loops over protocol. We only support SSHv2 now.
+ (lower); ok djm
- Upstream-Regress-ID: 0082838a9b8a382b7ee9cbf0c1b9db727784fadd
+ OpenBSD-Commit-ID: 71dc28a3e1fa7c553844abc508845bcf5766e091
-commit 557f921aad004be15805e09fd9572969eb3d9321
+commit ff31f15773ee173502eec4d7861ec56f26bba381
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sun Apr 30 23:33:48 2017 +0000
+Date: Fri Jan 3 03:02:26 2020 +0000
- upstream commit
+ upstream: what bozo decided to use 2020 as a future date in a regress
- remove SSHv1 support from unit tests
+ test?
- Upstream-Regress-ID: 395ca2aa48f1f7d23eefff6cb849ea733ca8bbfe
+ OpenBSD-Regress-ID: 3b953df5a7e14081ff6cf495d4e8d40e153cbc3a
-commit e77e1562716fb3da413e4c2397811017b762f5e3
+commit 680eb7749a39d0e4d046e66cac4e51e8e3640b75
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Mon May 1 00:03:18 2017 +0000
+Date: Fri Jan 3 02:46:19 2020 +0000
- upstream commit
+ upstream: implement recent SK API change to support resident keys
- fixup setting ciphercontext->plaintext (lost in SSHv1 purge),
- though it isn't really used for much anymore.
+ and PIN prompting in the dummy middleware that we use for the tests. Should
+ fix breakage spotted by dtucker@
- Upstream-ID: 859b8bce84ff4865b32097db5430349d04b9b747
+ OpenBSD-Regress-ID: 379cf9eabfea57aaf7f3f59dafde59889566c484
-commit f7849e6c83a4e0f602dea6c834a24091c622d68e
-Author: Damien Miller <djm@mindrot.org>
-Date: Mon May 1 09:55:56 2017 +1000
+commit 86834fe6b54ac57b8528c30cf0b27e5cac5b7af7
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Thu Jan 2 13:25:38 2020 +0000
- remove configure --with-ssh1
+ upstream: Update keygen moduli screen test to match recent command
+
+ line option change to ssh-keygen(1).
+
+ OpenBSD-Regress-ID: 744a72755004377e9669b662c13c6aa9ead8a0c3
-commit f4a6a88ddb6dba6d2f7bfb9e2c9879fcc9633043
+commit 9039971887cccd95b209c479296f772a3a93e8e7
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sun Apr 30 23:29:10 2017 +0000
+Date: Thu Jan 2 22:40:09 2020 +0000
- upstream commit
+ upstream: ability to download FIDO2 resident keys from a token via
- flense SSHv1 support from ssh-agent, considerably
- simplifying it
+ "ssh-keygen -K". This will save public/private keys into the current
+ directory.
- ok markus
+ This is handy if you move a token between hosts.
- Upstream-ID: 71d772cdcefcb29f76e01252e8361e6fc2dfc365
+ feedback & ok markus@
+
+ OpenBSD-Commit-ID: d57c1f9802f7850f00a117a1d36682a6c6d10da6
-commit 930e8d2827853bc2e196c20c3e000263cc87fb75
+commit 878ba4350d57e905d6bb1865d8ff31bdfe5deab4
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sun Apr 30 23:28:41 2017 +0000
+Date: Thu Jan 2 22:38:33 2020 +0000
- upstream commit
+ upstream: add sshkey_save_public(), to save a public key; ok
- obliterate ssh1.h and some dead code that used it
+ markus@
- ok markus@
+ OpenBSD-Commit-ID: 5d6f96a966d10d7fa689ff9aa9e1d6767ad5a076
+
+commit 3b1382ffd5e71eff78db8cef0f3cada22ff29409
+Author: jmc@openbsd.org <jmc@openbsd.org>
+Date: Mon Dec 30 16:10:00 2019 +0000
+
+ upstream: simplify the list for moduli options - no need for
+
+ -compact;
- Upstream-ID: 1ca9159a9fb95618f9d51e069ac8e1131a087343
+ OpenBSD-Commit-ID: 6492c72280482c6d072be46236b365cb359fc280
+
+commit 0248ec7c763dee9ff730a589e3d166eac5c74d7c
+Author: Damien Miller <djm@mindrot.org>
+Date: Thu Jan 2 13:41:31 2020 +1100
+
+ ssh-sk-null.cc needs extern "C" {}
+
+commit 5ca4b414effe4b56f0cfe3058c92391aa8a43871
+Author: Damien Miller <djm@mindrot.org>
+Date: Thu Jan 2 10:56:29 2020 +1100
+
+ add dummy ssh-sk API for linking with fuzzers
+
+commit c4b2664be7ba25e4c233315b25212dec29b727ab
+Author: Damien Miller <djm@mindrot.org>
+Date: Mon Dec 30 21:04:09 2019 +1100
+
+ refresh depend
-commit a3710d5d529a34b8f56aa62db798c70e85d576a0
+commit 3093d12ff80927cf45da08d9f262a26680fb14ee
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sun Apr 30 23:28:12 2017 +0000
+Date: Mon Dec 30 09:49:52 2019 +0000
- upstream commit
+ upstream: Remove the -x option currently used for
- exterminate the -1 flag from scp
+ FIDO/U2F-specific key flags. Instead these flags may be specified via -O.
ok markus@
- Upstream-ID: 26d247f7065da15056b209cef5f594ff591b89db
+ OpenBSD-Commit-ID: f23ebde2a8a7e1bf860a51055a711cffb8c328c1
-commit aebd0abfaa8a41e75d50f9f7934267b0a2d9acb4
+commit ef65e7dbaa8fac3245aa2bfc9f7e09be7cba0d9d
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sun Apr 30 23:26:54 2017 +0000
+Date: Mon Dec 30 09:25:29 2019 +0000
- upstream commit
+ upstream: document SK API changes in PROTOCOL.u2f
- purge the last traces of SSHv1 from the TTY modes
- handling code
-
- ok markus
+ ok markus@
- Upstream-ID: 963a19f1e06577377c38a3b7ce468f121b966195
+ OpenBSD-Commit-ID: 52622363c103a3c4d3d546050480ffe978a32186
-commit dfa641f758d4b8b2608ab1b00abaf88df0a8e36a
+commit 43ce96427b76c4918e39af654e2fc9ee18d5d478
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sun Apr 30 23:26:16 2017 +0000
+Date: Mon Dec 30 09:24:45 2019 +0000
- upstream commit
+ upstream: translate and return error codes; retry on bad PIN
- remove the (in)famous SSHv1 CRC compensation attack
- detector.
+ Define some well-known error codes in the SK API and pass
+ them back via ssh-sk-helper.
- Despite your cameo in The Matrix movies, you will not be missed.
+ Use the new "wrong PIN" error code to retry PIN prompting during
+ ssh-keygen of resident keys.
- ok markus
+ feedback and ok markus@
- Upstream-ID: 44261fce51a56d93cdb2af7b6e184be629f667e0
+ OpenBSD-Commit-ID: 9663c6a2bb7a0bc8deaccc6c30d9a2983b481620
-commit e5d3bd36ef67d82092861f39b5bf422cb12b31a6
+commit d433596736a2cd4818f538be11fc94783f5c5236
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sun Apr 30 23:25:03 2017 +0000
+Date: Mon Dec 30 09:24:03 2019 +0000
- upstream commit
-
- undo some local debugging stuff that I committed by
- accident
+ upstream: improve some error messages; ok markus@
- Upstream-ID: fe5b31f69a60d47171836911f144acff77810217
+ OpenBSD-Commit-ID: 4ccd8ddabb8df4f995107dd3b7ea58220e93cb81
-commit 3d6d09f2e90f4ad650ebda6520bf2da446f37f14
+commit c54cd1892c3e7f268b21e1f07ada9f0d9816ffc0
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sun Apr 30 23:23:54 2017 +0000
+Date: Mon Dec 30 09:23:28 2019 +0000
- upstream commit
+ upstream: SK API and sk-helper error/PIN passing
- remove SSHv1 support from packet and buffer APIs
+ Allow passing a PIN via the SK API (API major crank) and let the
+ ssh-sk-helper API follow.
- ok markus@
+ Also enhance the ssh-sk-helper API to support passing back an error
+ code instead of a complete reply. Will be used to signal "wrong PIN",
+ etc.
- Upstream-ID: bfc290053d40b806ecac46317d300677d80e1dc9
+ feedback and ok markus@
+
+ OpenBSD-Commit-ID: a1bd6b0a2421646919a0c139b8183ad76d28fb71
-commit 05164358577c82de18ed7373196bc7dbd8a3f79c
+commit 79fe22d9bc2868c5118f032ec1200ac9c2e3aaef
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sun Apr 30 23:21:54 2017 +0000
+Date: Mon Dec 30 09:22:49 2019 +0000
- upstream commit
+ upstream: implement loading resident keys in ssh-add
- remove SSHv1-related buffers from client code
+ "ssh-add -O" will load resident keys from a FIDO2 token and add them
+ to a ssh-agent.
+
+ feedback and ok markus@
- Upstream-ID: dca5d01108f891861ceaf7ba1c0f2eb274e0c7dd
+ OpenBSD-Commit-ID: 608104ae957a7d65cb84e0a3a26c8f60e0df3290
-commit 873d3e7d9a4707d0934fb4c4299354418f91b541
+commit 27753a8e21887d47fe6b5c78a4aed0efe558a850
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sun Apr 30 23:18:44 2017 +0000
+Date: Mon Dec 30 09:21:59 2019 +0000
- upstream commit
-
- remove KEY_RSA1
+ upstream: implement loading of resident keys in ssh-sk-helper
- ok markus@
+ feedback and ok markus@
- Upstream-ID: 7408517b077c892a86b581e19f82a163069bf133
+ OpenBSD-Commit-ID: b273c23769ea182c55c4a7b8f9cbd9181722011a
-commit 788ac799a6efa40517f2ac0d895a610394298ffc
+commit 14cea36df397677b8f8568204300ef654114fd76
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sun Apr 30 23:18:22 2017 +0000
+Date: Mon Dec 30 09:21:16 2019 +0000
- upstream commit
+ upstream: resident keys support in SK API
- remove SSHv1 configuration options and man pages bits
+ Adds a sk_load_resident_keys() function to the security key
+ API that accepts a security key provider and a PIN and returns
+ a list of keys.
- ok markus@
+ Implement support for this in the usbhid middleware.
+
+ feedback and ok markus@
- Upstream-ID: 84638c23546c056727b7a7d653c72574e0f19424
+ OpenBSD-Commit-ID: 67e984e4e87f4999ce447a6178c4249a9174eff0
-commit e6882463a8ae0594aacb6d6575a6318a41973d84
+commit 2fe05fcb4a2695f190b4fcf27770b655586ab349
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sun Apr 30 23:17:37 2017 +0000
+Date: Mon Dec 30 09:20:36 2019 +0000
- upstream commit
+ upstream: Factor out parsing of struct sk_enroll_response
+
+ We'll reuse this for extracting resident keys from a device.
- remove SSH1 make flag and associated files ok markus@
+ feedback and ok markus@
- Upstream-ID: ba9feacc5787337c413db7cf26ea3d53f854cfef
+ OpenBSD-Commit-ID: 9bc1efd9c6897eac4df0983746cf6578c1542273
-commit cdccebdf85204bf7542b7fcc1aa2ea3f36661833
+commit 4532bd01d57ee13c3ca881eceac1bf9da96a4d7e
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sun Apr 30 23:15:04 2017 +0000
+Date: Mon Dec 30 09:19:52 2019 +0000
- upstream commit
+ upstream: basic support for generating FIDO2 resident keys
+
+ "ssh-keygen -t ecdsa-sk|ed25519-sk -x resident" will generate a
+ device-resident key.
- remove SSHv1 ciphers; ok markus@
+ feedback and ok markus@
- Upstream-ID: e5ebc5e540d7f23a8c1266db1839794d4d177890
+ OpenBSD-Commit-ID: 8e1b3c56a4b11d85047bd6c6c705b7eef4d58431
-commit 97f4d3083b036ce3e68d6346a6140a22123d5864
+commit 3e60d18fba1b502c21d64fc7e81d80bcd08a2092
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sun Apr 30 23:13:25 2017 +0000
+Date: Mon Dec 30 03:30:09 2019 +0000
- upstream commit
+ upstream: remove single-letter flags for moduli options
- remove compat20/compat13/compat15 variables
+ Move all moduli generation options to live under the -O flag.
- ok markus@
+ Frees up seven single-letter flags.
+
+ NB. this change break existing ssh-keygen commandline syntax for moduli-
+ related operations. Very few people use these fortunately.
+
+ feedback and ok markus@
- Upstream-ID: 43802c035ceb3fef6c50c400e4ecabf12354691c
+ OpenBSD-Commit-ID: d498f3eaf28128484826a4fcb343612764927935
-commit 99f95ba82673d33215dce17bfa1512b57f54ec09
+commit 1e645fe767f27725dc7fd7864526de34683f7daf
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sun Apr 30 23:11:45 2017 +0000
+Date: Mon Dec 30 03:28:41 2019 +0000
- upstream commit
+ upstream: prepare for use of ssh-keygen -O flag beyond certs
- remove options.protocol and client Protocol
- configuration knob
+ Move list of available certificate options in ssh-keygen.1 to the
+ CERTIFICATES section.
+
+ Collect options specified by -O but delay parsing/validation of
+ certificate options until we're sure that we're acting as a CA.
ok markus@
- Upstream-ID: 5a967f5d06e2d004b0235457b6de3a9a314e9366
+ OpenBSD-Commit-ID: 33e6bcc29cfca43606f6fa09bd84b955ee3a4106
-commit 56912dea6ef63dae4eb1194e5d88973a7c6c5740
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sun Apr 30 23:10:43 2017 +0000
+commit 20ccd854245c598e2b47cc9f8d4955d645195055
+Author: jmc@openbsd.org <jmc@openbsd.org>
+Date: Fri Dec 27 08:28:44 2019 +0000
- upstream commit
+ upstream: sort -Y internally in the options list, as is already
- unifdef WITH_SSH1 ok markus@
+ done in synopsis;
- Upstream-ID: 9716e62a883ef8826c57f4d33b4a81a9cc7755c7
+ OpenBSD-Commit-ID: 86d033c5764404057616690d7be992e445b42274
-commit d4084cd230f7319056559b00db8b99296dad49d5
+commit 5b6c954751dd3677466cda7adb92e4f05446c96c
Author: jmc@openbsd.org <jmc@openbsd.org>
-Date: Sat Apr 29 06:06:01 2017 +0000
+Date: Fri Dec 27 08:25:07 2019 +0000
- upstream commit
+ upstream: in the options list, sort -Y and -y;
- tweak previous;
-
- Upstream-ID: a3abc6857455299aa42a046d232b7984568bceb9
+ OpenBSD-Commit-ID: 24c2e6a3aeab6e050a0271ffc73fdff91c10dcaa
-commit 249516e428e8461b46340a5df5d5ed1fbad2ccce
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sat Apr 29 04:12:25 2017 +0000
+commit 141df487ba699cfd1ec3dcd98186e7c956e99024
+Author: naddy@openbsd.org <naddy@openbsd.org>
+Date: Sat Dec 21 20:22:34 2019 +0000
- upstream commit
+ upstream: Replace the term "security key" with "(FIDO)
- allow ssh-keygen to include arbitrary string or flag
- certificate extensions and critical options. ok markus@ dtucker@
+ authenticator".
- Upstream-ID: 2cf28dd6c5489eb9fc136e0b667ac3ea10241646
+ The polysemous use of "key" was too confusing. Input from markus@.
+ ok jmc@
+
+ OpenBSD-Commit-ID: 12eea973a44c8232af89f86e4269d71ae900ca8f
-commit 47a287bb6ac936c26b4f3ae63279c02902ded3b9
-Author: jmc@openbsd.org <jmc@openbsd.org>
-Date: Fri Apr 28 06:15:03 2017 +0000
+commit fbd9729d4eadf2f7097b6017156387ac64302453
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Sat Dec 21 02:33:07 2019 +0000
- upstream commit
+ upstream: unit tests for ForwardAgent=/path; from Eric Chiang
- sort;
-
- Upstream-ID: 7e6b56e52b039cf44d0418e9de9aca20a2d2d15a
+ OpenBSD-Regress-ID: 24f693f78290b2c17725dab2c614dffe4a88c8da
-commit 36465a76a79ad5040800711b41cf5f32249d5120
-Author: Darren Tucker <dtucker@zip.com.au>
-Date: Fri Apr 28 14:44:28 2017 +1000
+commit e5b7cf8edca7e843adc125621e1dab14507f430a
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Mon Dec 16 02:39:05 2019 +0000
- Typo.
+ upstream: test security key host keys in addition to user keys
- Upstream-Regress-ID: 1e6b51ddf767cbad0a4e63eb08026c127e654308
+ OpenBSD-Regress-ID: 9fb45326106669a27e4bf150575c321806e275b1
-commit 9d18cb7bdeb00b20205fd13d412aae8c0e0457ed
-Author: Darren Tucker <dtucker@zip.com.au>
-Date: Fri Apr 28 14:41:17 2017 +1000
+commit 40be78f503277bd91c958fa25ea9ef918a2ffd3d
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Sat Dec 21 02:19:13 2019 +0000
- Add 2 regress commits I applied by hand.
+ upstream: Allow forwarding a different agent socket to the path
+
+ specified by $SSH_AUTH_SOCK, by extending the existing ForwardAgent option to
+ accepting an explicit path or the name of an environment variable in addition
+ to yes/no.
- Upstream-Regress-ID: 30c20180c87cbc99fa1020489fe7fd8245b6420c
- Upstream-Regress-ID: 1e6b51ddf767cbad0a4e63eb08026c127e654308
+ Patch by Eric Chiang, manpage by me; ok markus@
+
+ OpenBSD-Commit-ID: 98f2ed80bf34ea54d8b2ddd19ac14ebbf40e9265
-commit 9504ea6b27f9f0ece64e88582ebb9235e664a100
-Author: Darren Tucker <dtucker@zip.com.au>
-Date: Fri Apr 28 14:33:43 2017 +1000
+commit 416f15372bfb5be1709a0ad1d00ef5d8ebfb9e0e
+Author: naddy@openbsd.org <naddy@openbsd.org>
+Date: Fri Dec 20 20:28:55 2019 +0000
- Merge integrity.sh rev 1.22.
+ upstream: SSH U2F keys can now be used as host keys. Fix a garden
+
+ path sentence. ok markus@
- Merge missing bits from Colin Watson's patch in bz#2658 which make integrity
- tests more robust against timeouts. ok djm@
+ OpenBSD-Commit-ID: 67d7971ca1a020acd6c151426c54bd29d784bd6b
-commit 06ec837a34542627e2183a412d6a9d2236f22140
-Author: Darren Tucker <dtucker@zip.com.au>
-Date: Fri Apr 28 14:30:03 2017 +1000
+commit 68010acbcfe36167b3eece3115f3a502535f80df
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Fri Dec 20 02:42:42 2019 +0000
- Id sync for integrity.sh rev 1.21 which pulls in some shell portability fixes
+ upstream: Move always unsupported keywords to be grouped with the other
+
+ ones. Move oSecurityProvider to match the order in the OpCodes enum. Patch
+ from openbsd@academicsolutions.ch, ok djm@
+
+ OpenBSD-Commit-ID: 061e4505861ec1e02ba3a63e3d1b3be3cad458ec
-commit e0194b471efe7d3daedc9cc66686cb1ab69d3be8
-Author: jsg@openbsd.org <jsg@openbsd.org>
-Date: Mon Apr 17 11:02:31 2017 +0000
+commit 8784b02dc49e1c98df4e7aca466be2f652ed4ad1
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Fri Dec 20 02:29:21 2019 +0000
- upstream commit
+ upstream: Remove obsolete opcodes from the configuation enum.
- Change COMPILER_VERSION tests which limited additional
- warnings to gcc4 to instead skip them on gcc3 as clang can handle
- -Wpointer-sign and -Wold-style-definition.
+ Patch from openbsd@academicsolutions.ch, ok djm@
- Upstream-Regress-ID: e48d7dc13e48d9334b8195ef884dfbc51316012f
+ OpenBSD-Commit-ID: 395c202228872ce8d9044cc08552ac969f51e01b
-commit 6830be90e71f46bcd182a9202b151eaf2b299434
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Apr 28 03:24:53 2017 +0000
+commit 345be6091bdc9be09c90a937d1320f97c01fab2a
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Fri Dec 20 02:11:38 2019 +0000
- upstream commit
+ upstream: Remove now-obsolete config options from example in
- include key fingerprint in "Offering public key" debug
- message
+ comment. Patch from openbsd@academicsolutions.ch, ok djm@
- Upstream-ID: 964749f820c2ed4cf6a866268b1a05e907315c52
+ OpenBSD-Commit-ID: 35862beb0927b1cb0af476ec23cc07f6e3006101
-commit 066437187e16dcafcbc19f9402ef0e6575899b1d
-Author: millert@openbsd.org <millert@openbsd.org>
-Date: Fri Apr 28 03:21:12 2017 +0000
+commit ae024b22c4fd68e7f39681d605585889f9511108
+Author: naddy@openbsd.org <naddy@openbsd.org>
+Date: Thu Dec 19 15:09:30 2019 +0000
- upstream commit
+ upstream: Document that security key-hosted keys can act as host
- Avoid relying on implementation-specific behavior when
- detecting whether the timestamp or file size overflowed. If time_t and off_t
- are not either 32-bit or 64-bit scp will exit with an error. OK djm@
+ keys.
- Upstream-ID: f31caae73ddab6df496b7bbbf7da431e267ad135
+ Update the list of default host key algorithms in ssh_config.5 and
+ sshd_config.5. Copy the description of the SecurityKeyProvider
+ option to sshd_config.5.
+
+ ok jmc@
+
+ OpenBSD-Commit-ID: edadf3566ab5e94582df4377fee3b8b702c7eca0
-commit 68d3a2a059183ebd83b15e54984ffaced04d2742
+commit bc2dc091e0ac4ff6245c43a61ebe12c7e9ea0b7f
Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Fri Apr 28 03:20:27 2017 +0000
+Date: Thu Dec 19 03:50:01 2019 +0000
- upstream commit
+ upstream: "Forward security" -> "Forward secrecy" since that's the
- Add SyslogFacility option to ssh(1) matching the
- equivalent option in sshd(8). bz#2705, patch from erahn at arista.com, ok
- djm@
+ correct term. Add "MAC" since we use that acronym in other man pages. ok
+ naddy@
- Upstream-ID: d5115c2c0193ceb056ed857813b2a7222abda9ed
+ OpenBSD-Commit-ID: c35529e511788586725fb63bda3459e10738c5f5
-commit e13aad66e73a14b062d13aee4e98f1e21a3f6a14
-Author: jsg@openbsd.org <jsg@openbsd.org>
-Date: Thu Apr 27 13:40:05 2017 +0000
+commit e905f7260d72bc0e33ef5f10a0db737ff6e77ba7
+Author: naddy@openbsd.org <naddy@openbsd.org>
+Date: Tue Dec 17 16:21:07 2019 +0000
- upstream commit
+ upstream: cut obsolete lists of crypto algorithms from outline of
- remove a static array unused since rev 1.306 spotted by
- clang ok djm@
+ how SSH works ok markus@ jmc@
- Upstream-ID: 249b3eed2446f6074ba2219ccc46919dd235a7b8
+ OpenBSD-Commit-ID: 8e34973f232ab48c4d4f5d07df48d501708b9160
-commit 91bd2181866659f00714903e78e1c3edd4c45f3d
-Author: millert@openbsd.org <millert@openbsd.org>
-Date: Thu Apr 27 11:53:12 2017 +0000
+commit f65cf1163ff01531ae02f3f9210391d0d692f699
+Author: tobhe@openbsd.org <tobhe@openbsd.org>
+Date: Mon Dec 16 13:58:53 2019 +0000
- upstream commit
+ upstream: strdup may return NULL if memory allocation fails. Use
- Avoid potential signed int overflow when parsing the file
- size. Use strtoul() instead of parsing manually. OK djm@
+ the safer xstrdup which fatals on allocation failures.
- Upstream-ID: 1f82640861c7d905bbb05e7d935d46b0419ced02
-
-commit 17a54a03f5a1d35e33cc24e22cd7a9d0f6865dc4
-Author: Darren Tucker <dtucker@zip.com.au>
-Date: Tue Apr 25 08:32:27 2017 +1000
-
- Fix typo in "socketcall".
+ ok markus@
- Pointed out by jjelen at redhat.com.
+ OpenBSD-Commit-ID: 8b608d387120630753cbcb8110e0b019c0c9a0d0
-commit 8b0eee148f7cf8b248c30d1bae57300f2cc5aafd
-Author: Darren Tucker <dtucker@zip.com.au>
-Date: Mon Apr 24 19:40:31 2017 +1000
+commit 57634bfc5708477826c0be265ddc59b9d83e4886
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Mon Dec 16 03:16:58 2019 +0000
- Deny socketcall in seccomp filter on ppc64le.
+ upstream: sort sk-* methods behind their plain key methods cousins
- OpenSSL is using socket() calls (in FIPS mode) when handling ECDSA keys
- in privsep child. The socket() syscall is already denied in the seccomp
- filter, but in ppc64le kernel, it is implemented using socketcall()
- syscall, which is not denied yet (only SYS_SHUTDOWN is allowed) and
- therefore fails hard.
+ for now
- Patch from jjelen at redhat.com.
+ OpenBSD-Commit-ID: c97e22c2b28c0d12ee389b8b4ef5f2ada7908828
-commit f8500b2be599053daa05248a86a743232ec6a536
-Author: schwarze@openbsd.org <schwarze@openbsd.org>
-Date: Mon Apr 17 14:31:23 2017 +0000
+commit b8df8fe920e697edcc69c520390b78c3b7ad9d84
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Tue Dec 17 19:46:15 2019 +1100
- upstream commit
-
- Recognize nl_langinfo(CODESET) return values "646" and ""
- as aliases for "US-ASCII", useful for different versions of NetBSD and
- Solaris. Found by dtucker@ and by Tom G. Christensen <tgc at jupiterrise dot
- com>. OK dtucker@ deraadt@
+ Mac OS X has PAM too.
+
+commit bf8de8b8251af69b5ce96a8faa69145af156af4d
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Tue Dec 17 19:37:06 2019 +1100
+
+ Show portable tarball pattern in example.
+
+commit a19ef613e98141cc37c8acdeebe285b9dbe2531e
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Tue Dec 17 19:35:59 2019 +1100
+
+ OpenSSL is now optional.
+
+commit 1a7217ac063e48cf0082895aeee81ed2b8a57191
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Sun Dec 15 18:58:33 2019 +0000
+
+ upstream: adapt to ssh-sk-client change
- Upstream-ID: 38c2133817cbcae75c88c63599ac54228f0fa384
+ OpenBSD-Regress-ID: 40481999a5928d635ab2e5b029e8239c112005ea
-commit 7480dfedf8c5c93baaabef444b3def9331e86ad5
-Author: jsg@openbsd.org <jsg@openbsd.org>
-Date: Mon Apr 17 11:02:31 2017 +0000
+commit a7fc1df246e80bfdabd09b069b91c72f9c578ca8
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Wed Dec 11 18:47:14 2019 +0000
- upstream commit
+ upstream: it's no longer possible to disable privilege separation
- Change COMPILER_VERSION tests which limited additional
- warnings to gcc4 to instead skip them on gcc3 as clang can handle
- -Wpointer-sign and -Wold-style-definition.
+ in sshd, so don't double the tests' work by trying both off/on
- Upstream-ID: 5cbe348aa76dc1adf55be6c0e388fafaa945439a
+ OpenBSD-Regress-ID: d366665466dbd09e9b707305da884be3e7619c68
-commit 4d827f0d75a53d3952288ab882efbddea7ffadfe
+commit 3145d38ea06820a66c0f5e068f49af14fd2b7ac1
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Tue Apr 4 00:24:56 2017 +0000
+Date: Sun Dec 15 20:59:23 2019 +0000
- upstream commit
+ upstream: don't treat HostKeyAgent=none as a path either; avoids
- disallow creation (of empty files) in read-only mode;
- reported by Michal Zalewski, feedback & ok deraadt@
+ spurious warnings from the cfgparse regress test
- Upstream-ID: 5d9c8f2fa8511d4ecf95322994ffe73e9283899b
+ OpenBSD-Commit-ID: ba49ea7a5c92b8a16cb9c2e975dbb163853afc54
-commit ef47843af0a904a21c920e619c5aec97b65dd9ac
-Author: deraadt@openbsd.org <deraadt@openbsd.org>
-Date: Sun Mar 26 00:18:52 2017 +0000
+commit 747e25192f436e71dd39e15d65aa32bca967533a
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Sun Dec 15 20:57:15 2019 +0000
- upstream commit
+ upstream: do not attempt to find an absolute path for sshd_config
- incorrect renditions of this quote bother me
+ SecurityKeyProvider=internal - unbreaks cfgparse regress test
- Upstream-ID: 1662be3ebb7a71d543da088119c31d4d463a9e49
+ OpenBSD-Commit-ID: d2ddcf525c0dc3c8339522360c10b3c70f1fd641
-commit d9048861bea842c4eba9c2dbbf97064cc2a5ef02
-Author: Darren Tucker <dtucker@zip.com.au>
-Date: Fri Mar 31 11:04:43 2017 +1100
+commit 9b6e30b96b094ad787511a5b989253e3b8fe1789
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Sun Dec 15 19:47:10 2019 +0000
- Check for and use gcc's -pipe.
+ upstream: allow ssh-keyscan to find security key hostkeys
- Speeds up configure and build by a couple of percent. ok djm@
+ OpenBSD-Commit-ID: 1fe822a7f714df19a7e7184e3a3bbfbf546811d3
-commit 282cad2240c4fbc104c2f2df86d688192cbbe4bb
-Author: Darren Tucker <dtucker@zip.com.au>
-Date: Wed Mar 29 16:34:44 2017 +1100
+commit 56584cce75f3d20aaa30befc7cbd331d922927f3
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Sun Dec 15 18:57:30 2019 +0000
- Import fmt_scaled.c rev 1.16 from OpenBSD.
+ upstream: allow security keys to act as host keys as well as user
+
+ keys.
+
+ Previously we didn't do this because we didn't want to expose
+ the attack surface presented by USB and FIDO protocol handling,
+ but now that this is insulated behind ssh-sk-helper there is
+ less risk.
- Fix overly-conservative overflow checks on mulitplications and add checks
- on additions. This allows scan_scaled to work up to +/-LLONG_MAX (LLONG_MIN
- will still be flagged as a range error). ok millert@
+ ok markus@
+
+ OpenBSD-Commit-ID: 77b068dd133b8d87e0f010987bd5131e640ee64c
-commit c73a229e4edf98920f395e19fd310684fc6bb951
-Author: Darren Tucker <dtucker@zip.com.au>
-Date: Wed Mar 29 16:34:02 2017 +1100
+commit 5af6fd5461bb709304e6979c8b7856c7af921c9e
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Mon Dec 16 13:55:56 2019 +1100
- Import fmt_scaled.c rev 1.15 from OpenBSD.
+ Allow clock_nanosleep_time64 in seccomp sandbox.
- Collapse underflow and overflow checks into a single block.
- ok djm@ millert@
+ Needed on Linux ARM. bz#3100, patch from jjelen@redhat.com.
-commit d427b73bf5a564f663d16546dbcbd84ba8b9d4af
-Author: Darren Tucker <dtucker@zip.com.au>
-Date: Wed Mar 29 16:32:57 2017 +1100
+commit fff8ff6dd580e1a72ba09a6775d185175cdc8d13
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Sun Dec 15 18:27:02 2019 +1100
- Import fmt_scaled.c rev 1.14 from OpenBSD.
+ Put SK ECDSA bits inside ifdef OPENSSL_HAS_ECC.
- Catch integer underflow in scan_scaled reported by Nicolas Iooss.
- ok deraadt@ djm@
+ Fixes build when linking against OpenSSLs built with no-ec.
-commit d13281f2964abc5f2e535e1613c77fc61b0c53e7
-Author: Darren Tucker <dtucker@zip.com.au>
-Date: Wed Mar 29 12:39:39 2017 +1100
+commit 9244990ecdcfa36bb9371058111685b05f201c1e
+Author: Damien Miller <djm@mindrot.org>
+Date: Sat Dec 14 09:21:46 2019 +1100
- Don't check privsep user or path when unprivileged
+ remove a bunch of ENABLE_SK #ifdefs
- If running with privsep (mandatory now) as a non-privileged user, we
- don't chroot or change to an unprivileged user however we still checked
- the existence of the user and directory. Don't do those checks if we're
- not going to use them. Based in part on a patch from Lionel Fourquaux
- via Corinna Vinschen, ok djm@
+ The ssh-sk-helper client API gives us a nice place to disable
+ security key support when it is wasn't enabled at compile time,
+ so we don't need to check everywere.
+
+ Also, verification of security key signatures can remain enabled
+ all the time - it has no additional dependencies. So sshd can
+ accept security key pubkeys in authorized_keys, etc regardless of
+ the host's support for dlopen, etc.
-commit f2742a481fe151e493765a3fbdef200df2ea7037
-Author: Darren Tucker <dtucker@zip.com.au>
-Date: Wed Mar 29 10:50:31 2017 +1100
+commit a33ab1688b5c460a7e2a301418241ce1b13b2638
+Author: Damien Miller <djm@mindrot.org>
+Date: Sat Dec 14 09:15:06 2019 +1100
- Remove SHA256 EVP wrapper implementation.
-
- All supported versions of OpenSSL should now have SHA256 so remove our
- EVP wrapper implementaion. ok djm@
+ ssh-sk-client.c needs includes.h
+
+commit 633778d567ad50b63d2a3bca5e1b97d279d236d9
+Author: Damien Miller <djm@mindrot.org>
+Date: Sat Dec 14 08:40:33 2019 +1100
-commit 5346f271fc76549caf4a8e65b5fba319be422fe9
-Author: Darren Tucker <dtucker@zip.com.au>
-Date: Wed Mar 29 10:23:58 2017 +1100
+ only link ssh-sk-helper against libfido2
- Remove check for OpenSSL < 0.9.8g.
+commit 7b47b40b170db4d6f41da0479575f6d99dd7228a
+Author: Damien Miller <djm@mindrot.org>
+Date: Sat Dec 14 08:20:52 2019 +1100
+
+ adapt Makefile to ssh-sk-client everywhere
+
+commit f45f3a8a12e2bee601046b916e6c5cd6eae08048
+Author: Damien Miller <djm@mindrot.org>
+Date: Sat Dec 14 07:53:11 2019 +1100
+
+ fixup
+
+commit d21434766764d5babf99fc3937c19b625c0f6334
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Fri Dec 13 20:16:56 2019 +0000
+
+ upstream: actually commit the ssh-sk-helper client code; ok markus
- We no longer support OpenSSL < 1.0.1 so remove check for unreliable ECC
- in OpenSSL < 0.9.8g.
+ OpenBSD-Commit-ID: fd2ea776a5bbbf4d452989d3c3054cf25a5e0589
-commit 8fed0a5fe7b4e78a6810b133d8e91be9742ee0a1
-Author: Darren Tucker <dtucker@zip.com.au>
-Date: Wed Mar 29 10:16:15 2017 +1100
+commit 611073fb40ecaf4ac65094e403edea3a08deb700
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Fri Dec 13 19:11:14 2019 +0000
- Remove compat code for OpenSSL < 0.9.7.
+ upstream: perform security key enrollment via ssh-sk-helper too.
+
+ This means that ssh-keygen no longer needs to link against ssh-sk-helper, and
+ only ssh-sk-helper needs libfido2 and /dev/uhid* access;
- Resyncs that code with OpenBSD upstream.
+ feedback & ok markus@
+
+ OpenBSD-Commit-ID: 9464233fab95708d2ff059f8bee29c0d1f270800
-commit 608ec1f62ff22fdccc3952e51463d79c43cbd0d3
-Author: Darren Tucker <dtucker@zip.com.au>
-Date: Wed Mar 29 09:50:54 2017 +1100
+commit 612b1dd1ec91ffb1e01f58cca0c6eb1d47bf4423
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Fri Dec 13 19:09:37 2019 +0000
- Remove SSHv1 code path.
+ upstream: allow sshbuf_put_stringb(buf, NULL); ok markus@
- Server-side support for Protocol 1 has been removed so remove !compat20
- PAM code path.
+ OpenBSD-Commit-ID: 91482c1ada9adb283165d48dafbb88ae91c657bd
-commit 7af27bf538cbc493d609753f9a6d43168d438f1b
-Author: Darren Tucker <dtucker@zip.com.au>
-Date: Fri Mar 24 09:44:56 2017 +1100
+commit b52ec0ba3983859514aa7b57d6100fa9759fe696
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Fri Dec 13 19:09:10 2019 +0000
- Enable ldns when using ldns-config.
+ upstream: use ssh-sk-helper for all security key signing operations
+
+ This extracts and refactors the client interface for ssh-sk-helper
+ from ssh-agent and generalises it for use by the other programs.
+ This means that most OpenSSH tools no longer need to link against
+ libfido2 or directly interact with /dev/uhid*
+
+ requested by, feedback and ok markus@
- Actually enable ldns when attempting to use ldns-config. bz#2697, patch
- from fredrik at fornwall.net.
+ OpenBSD-Commit-ID: 1abcd3aea9a7460eccfbf8ca154cdfa62f1dc93f
-commit 58b8cfa2a062b72139d7229ae8de567f55776f24
-Author: Damien Miller <djm@mindrot.org>
-Date: Wed Mar 22 12:43:02 2017 +1100
+commit c33d46868c3d88e04a92610cdb429094aeeb5847
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Wed Dec 11 22:19:47 2019 +0000
- Missing header on Linux/s390
+ upstream: add a note about the 'extensions' field in the signed
- Patch from Jakub Jelen
+ object
+
+ OpenBSD-Commit-ID: 67c01e0565b258e0818c1ccfe1f1aeaf9a0d4c7b
-commit 096fb65084593f9f3c1fc91b6d9052759a272a00
+commit a62f4e1960691f3aeb1f972e009788b29e2ae464
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Mon Mar 20 22:08:06 2017 +0000
+Date: Tue Dec 10 23:37:31 2019 +0000
- upstream commit
+ upstream: some more corrections for documentation problems spotted
- remove /usr/bin/time calls around tests, makes diffing test
- runs harder. Based on patch from Mike Frysinger
+ by Ron Frederick
- Upstream-Regress-ID: 81c1083b14dcf473b23d2817882f40b346ebc95c
+ document certifiate private key format
+ correct flags type for sk-ssh-ed25519@openssh.com keys
+
+ OpenBSD-Commit-ID: fc4e9a1ed7f9f7f9dd83e2e2c59327912e933e74
-commit 6b853c6f8ba5eecc50f3b57af8e63f8184eb0fa6
-Author: Damien Miller <djm@mindrot.org>
-Date: Tue Mar 21 08:47:55 2017 +1100
+commit 22d4beb79622fc82d7111ac941269861fc7aef8d
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Tue Dec 10 23:21:56 2019 +0000
- Fix syntax error on Linux/X32
+ upstream: loading security keys into ssh-agent used the extension
- Patch from Mike Frysinger
+ constraint "sk-provider@openssh.com", not "sk@openssh.com"; spotted by Ron
+ Frederick
+
+ OpenBSD-Commit-ID: dbfba09edbe023abadd5f59c1492df9073b0e51d
-commit d38f05dbdd291212bc95ea80648b72b7177e9f4e
-Author: Darren Tucker <dtucker@zip.com.au>
-Date: Mon Mar 20 13:38:27 2017 +1100
+commit 75f7f22a43799f6d25dffd9d6683de1601da05a3
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Tue Dec 10 22:43:19 2019 +0000
- Add llabs() implementation.
+ upstream: add security key types to list of keys allowed to act as
+
+ CAs; spotted by Ron Frederick
+
+ OpenBSD-Commit-ID: 9bb0dfff927b4f7aa70679f983f84c69d45656c3
-commit 72536316a219b7394996a74691a5d4ec197480f7
-Author: Damien Miller <djm@mindrot.org>
-Date: Mon Mar 20 12:23:04 2017 +1100
+commit 516605f2d596884cedc2beed6b262716ec76f63d
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Tue Dec 10 22:37:20 2019 +0000
- crank version numbers
+ upstream: when acting as a CA and using a security key as the CA
+
+ key, remind the user to touch they key to authorise the signature.
+
+ OpenBSD-Commit-ID: fe58733edd367362f9766b526a8b56827cc439c1
-commit 3be52bc36bdfd24ded7e0f46999e7db520fb4e3f
+commit c4036fe75ea5a4d03a2a40be1f3660dcbbfa01b2
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Mon Mar 20 01:18:59 2017 +0000
+Date: Tue Dec 10 22:36:08 2019 +0000
- upstream commit
+ upstream: chop some unnecessary and confusing verbiage from the
- openssh-7.5
+ security key protocol description; feedback from Ron Frederick
- Upstream-ID: b8b9a4a949427c393cd868215e1724ceb3467ee5
+ OpenBSD-Commit-ID: 048c9483027fbf9c995e5a51b3ac502989085a42
-commit db84e52fe9cfad57f22e7e23c5fbf00092385129
-Author: Damien Miller <djm@mindrot.org>
-Date: Mon Mar 20 12:07:20 2017 +1100
+commit 59175a350fe1091af7528b2971e3273aa7ca7295
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Fri Dec 6 03:06:08 2019 +0000
- I'm a doofus.
+ upstream: fix setting of $SSH_ASKPASS_PROMPT - it shouldn't be set
+
+ when asking passphrases, only when confirming the use of a key (i.e. for
+ ssh-agent keys added with "ssh-add -c keyfile")
- Unbreak obvious syntax error.
+ OpenBSD-Commit-ID: 6643c82960d9427d5972eb702c917b3b838ecf89
-commit 89f04852db27643717c9c3a2b0dde97ae50099ee
-Author: Damien Miller <djm@mindrot.org>
-Date: Mon Mar 20 11:53:34 2017 +1100
+commit 36eaa356d391a23a2d4e3a8aaa0223abc70b9822
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Fri Dec 6 02:55:21 2019 +0000
- on Cygwin, check paths from server for backslashes
+ upstream: bring the __func__
- Pointed out by Jann Horn of Google Project Zero
+ OpenBSD-Commit-ID: 71a3a45b0fe1b8f680ff95cf264aa81f7abbff67
-commit 7ef1f9bafc2cc8d97ff2fbd4f280002b6e8ea5d9
-Author: Damien Miller <djm@mindrot.org>
-Date: Mon Mar 20 11:48:34 2017 +1100
+commit 483cc723d1ff3b7fdafc6239348040a608ebc78d
+Author: jmc@openbsd.org <jmc@openbsd.org>
+Date: Sat Nov 30 07:07:59 2019 +0000
- Yet another synonym for ASCII: "646"
+ upstream: tweak the Nd lines for a bit of consistency; ok markus
- Used by NetBSD; this unbreaks mprintf() and friends there for the C
- locale (caught by dtucker@ and his menagerie of test systems).
+ OpenBSD-Commit-ID: 876651bdde06bc1e72dd4bd7ad599f42a6ce5a16
-commit 9165abfea3f68a0c684a6ed2e575e59bc31a3a6b
-Author: Damien Miller <djm@mindrot.org>
-Date: Mon Mar 20 09:58:34 2017 +1100
+commit afffd310360b155df2133d1f5f1ab2f4e939b570
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Wed Dec 11 13:22:06 2019 +1100
- create test mux socket in /tmp
+ Check if memmem is declared in system headers.
- Creating the socket in $OBJ could blow past the (quite limited)
- path limit for Unix domain sockets. As a bandaid for bz#2660,
- reported by Colin Watson; ok dtucker@
+ If the system (or one of the dependencies) implements memmem but does
+ not define the header, we would not declare it either resulting in
+ compiler warnings. Check for declaration explicitly. bz#3102.
-commit 2adbe1e63bc313d03e8e84e652cc623af8ebb163
-Author: markus@openbsd.org <markus@openbsd.org>
-Date: Wed Mar 15 07:07:39 2017 +0000
+commit ad8cd420797695f3b580aea1034b9de60bede9b9
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Wed Dec 11 13:12:01 2019 +1100
- upstream commit
+ Sort depends.
+
+commit 5e3abff39e01817f6866494416f2ada25c316018
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Wed Dec 11 13:09:34 2019 +1100
+
+ Sort .depend when rebuilding.
- disallow KEXINIT before NEWKEYS; ok djm; report by
- vegard.nossum at oracle.com
+ This makes diffs more stable between makedepend implementations.
+
+commit 5df9d1f5c0943367d9b68435f4c82224ce11a73f
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Wed Dec 11 13:06:43 2019 +1100
+
+ Update depend to include sk files.
+
+commit 9a967c5bbfca35835165f7d8a6165009f5b21872
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Mon Dec 9 20:25:26 2019 +1100
+
+ Describe how to build libcrypto as PIC.
- Upstream-ID: 3668852d1f145050e62f1da08917de34cb0c5234
+ While there, move the OpenSSL 1.1.0g caveat closer to the other version
+ information.
+
+commit b66fa5da25c4b5b67cf9f0ce7af513f5a6a6a686
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Mon Dec 9 17:23:22 2019 +1100
-commit 2fbf91684d76d38b9cf06550b69c9e41bca5a71c
-Author: Darren Tucker <dtucker@zip.com.au>
-Date: Thu Mar 16 14:05:46 2017 +1100
+ Recommend running LibreSSL or OpenSSL self-tests.
- Include includes.h for compat bits.
+commit fa7924008e838cded7e8a561356ffe5e06e0ed64
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Fri Dec 6 14:17:26 2019 +1100
+
+ Wrap ECC specific bits in ifdef.
+
+ Fixes tests when built against an OpenSSL configured with no-ec.
-commit b55f634e96b9c5b0cd991e23a9ca181bec4bdbad
-Author: Darren Tucker <dtucker@zip.com.au>
-Date: Thu Mar 16 13:45:17 2017 +1100
+commit 2ff822eabd7d4461743f22d3b9ba35ab76069df5
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Fri Nov 29 20:21:36 2019 +1100
- Wrap stdint.h in #ifdef HAVE_STDINT_H
+ Wrap sha2.h include in ifdef.
+
+ Fixes build --without-openssl on at least Fedora.
-commit 55a1117d7342a0bf8b793250cf314bab6b482b99
+commit 443848155ffcda65a6077aac118c861b503a093f
Author: Damien Miller <djm@mindrot.org>
-Date: Thu Mar 16 11:22:42 2017 +1100
+Date: Fri Nov 29 15:10:21 2019 +1100
- Adapt Cygwin config script to privsep knob removal
+ compile sk-dummy.so with no-PIE version of LDFLAGS
- Patch from Corinna Vinschen.
+ This lets it pick up the -L path to libcrypto for example.
-commit 1a321bfdb91defe3c4d9cca5651724ae167e5436
-Author: deraadt@openbsd.org <deraadt@openbsd.org>
-Date: Wed Mar 15 03:52:30 2017 +0000
+commit 37f5b5346e4cc6a894245aa89d2930649bb7045b
+Author: Damien Miller <djm@mindrot.org>
+Date: Fri Nov 29 14:48:46 2019 +1100
- upstream commit
+ includes.h for sk-dummy.c, dummy
+
+commit b218055e59a7c1a1816f7a55ca18e3f3c05d63a4
+Author: Damien Miller <djm@mindrot.org>
+Date: Fri Nov 29 12:32:23 2019 +1100
+
+ (yet) another x-platform fix for sk-dummy.so
- accidents happen to the best of us; ok djm
+ Check for -fPIC support from compiler
- Upstream-ID: b7a9dbd71011ffde95e06f6945fe7197dedd1604
+ Compile libopenbsd-compat -fPIC
+
+ Don't mix -fPIE and -fPIC when compiling
-commit 25f837646be8c2017c914d34be71ca435dfc0e07
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Wed Mar 15 02:25:09 2017 +0000
+commit 0dedb703adcd98d0dbc4479f5f312a2bd3df2850
+Author: Damien Miller <djm@mindrot.org>
+Date: Fri Nov 29 11:53:57 2019 +1100
- upstream commit
+ needs includes.h for WITH_OPENSSL
+
+commit ef3853bb94c2c72e7eda0de6cec0bcb1da62058f
+Author: Damien Miller <djm@mindrot.org>
+Date: Fri Nov 29 11:52:23 2019 +1100
+
+ another attempt at sk-dummy.so working x-platform
- fix regression in 7.4: deletion of PKCS#11-hosted keys
- would fail unless they were specified by full physical pathname. Report and
- fix from Jakub Jelen via bz#2682; ok dtucker@
+ include a fatal() implementation to satisfy libopenbsd-compat
- Upstream-ID: 5b5bc20ca11cacb5d5eb29c3f93fd18425552268
+ clean up .lo and .so files
+
+ .gitignore .lo and .so files
-commit a8c5eeacf032a7d3408957e45dd7603cc1baf55f
+commit d46ac56f1cbd5a855a2d5e7309f90d383dcf6431
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Wed Mar 15 02:19:09 2017 +0000
+Date: Fri Nov 29 00:13:29 2019 +0000
- upstream commit
+ upstream: lots of dependencies go away here with ed25519 no longer
- Fix segfault when sshd attempts to load RSA1 keys (can
- only happen when protocol v.1 support is enabled for the client). Reported by
- Jakub Jelen in bz#2686; ok dtucker
+ needing the ssh_digest API.
- Upstream-ID: 8fdaec2ba4b5f65db1d094f6714ce64b25d871d7
+ OpenBSD-Regress-ID: 785847ec78cb580d141e29abce351a436d6b5d49
-commit 66705948c0639a7061a0d0753266da7685badfec
+commit 7404b81f25a4a7847380c0f0cf7f1bea5f0a5cd3
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Tue Mar 14 07:19:07 2017 +0000
+Date: Fri Nov 29 00:11:21 2019 +0000
- upstream commit
+ upstream: perform hashing directly in crypto_hash_sha512() using
+
+ libcrypto or libc SHA512 functions rather than calling ssh_digest_memory();
+ avoids many dependencies on ssh code that complicate standalone use of
+ ed25519, as we want to do in sk-dummy.so
- Mark the sshd_config UsePrivilegeSeparation option as
- deprecated, effectively making privsep mandatory in sandboxing mode. ok
- markus@ deraadt@
+ OpenBSD-Commit-ID: 5a3c37593d3ba7add037b587cec44aaea088496d
+
+commit d39a865b7af93a7a9b5a64cf7cf0ef4396c80ba3
+Author: jmc@openbsd.org <jmc@openbsd.org>
+Date: Thu Nov 28 12:24:31 2019 +0000
+
+ upstream: improve the text for -A a little; input from naddy and
- (note: this doesn't remove the !privsep code paths, though that will
- happen eventually).
+ djm
- Upstream-ID: b4c52666256c4dd865f8ce9431af5d6ce2d74a0a
+ OpenBSD-Commit-ID: f9cdfb1d6dbb9887c4bf3bb25f9c7a94294c988d
-commit f86586b03fe6cd8f595289bde200a94bc2c191af
-Author: Damien Miller <djm@mindrot.org>
-Date: Tue Mar 14 18:26:29 2017 +1100
+commit 9a0e01bd0c61f553ead96b5af84abd73865847b8
+Author: jmc@openbsd.org <jmc@openbsd.org>
+Date: Thu Nov 28 12:23:25 2019 +0000
- Make seccomp-bpf sandbox work on Linux/X32
+ upstream: reshuffle the text to read better; input from naddy,
- Allow clock_gettime syscall with X32 bit masked off. Apparently
- this is required for at least some kernel versions. bz#2142
- Patch mostly by Colin Watson. ok dtucker@
+ djmc, and dtucker
+
+ OpenBSD-Commit-ID: a0b2aca2b67614dda3d6618ea097bf0610c35013
-commit 2429cf78dd2a9741ce27ba25ac41c535274a0af6
+commit 5ca52c0f2e5e7f7d01d8d557b994b5c2087bed00
Author: Damien Miller <djm@mindrot.org>
-Date: Tue Mar 14 18:01:52 2017 +1100
+Date: Thu Nov 28 18:09:07 2019 +1100
- require OpenSSL >=1.0.1
+ $< doesn't work as` I thought; explicily list objs
-commit e3ea335abeab731c68f2b2141bee85a4b0bf680f
-Author: Damien Miller <djm@mindrot.org>
-Date: Tue Mar 14 17:48:43 2017 +1100
+commit 18e84bfdc5906a73405c3b42d7f840013bbffe34
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Thu Nov 28 05:20:54 2019 +0000
- Remove macro trickery; no binary change
-
- This stops the SC_ALLOW(), SC_ALLOW_ARG() and SC_DENY() macros
- prepending __NR_ to the syscall number parameter and just makes
- them explicit in the macro invocations.
+ upstream: tweak wording
- No binary change in stripped object file before/after.
+ OpenBSD-Commit-ID: bd002ca1599b71331faca735ff5f6de29e32222e
-commit 5f1596e11d55539678c41f68aed358628d33d86f
+commit 8ef5bf9d03aa0f047711cff47f5ffbe3b33ff8c9
Author: Damien Miller <djm@mindrot.org>
-Date: Tue Mar 14 13:15:18 2017 +1100
+Date: Thu Nov 28 13:12:30 2019 +1100
- support ioctls for ICA crypto card on Linux/s390
-
- Based on patch from Eduardo Barretto; ok dtucker@
+ missing .SUFFIXES line makes make sad
-commit b1b22dd0df2668b322dda174e501dccba2cf5c44
-Author: Darren Tucker <dtucker@zip.com.au>
-Date: Tue Mar 14 14:19:36 2017 +1100
+commit 323da82b8ea993b7f2c5793fd53b4f5ca105d19d
+Author: Damien Miller <djm@mindrot.org>
+Date: Thu Nov 28 09:53:42 2019 +1100
- Plumb conversion test into makefile.
+ (hopefully) fix out of tree builds of sk-dummy.so
-commit f57783f1ddfb4cdfbd612c6beb5ec01cb5b9a6b9
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Tue Mar 14 01:20:29 2017 +0000
+commit d8b2838c5d19bf409d44ede4d32df8ee47aeb4cd
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Wed Nov 27 22:32:11 2019 +0000
- upstream commit
+ upstream: remove stray semicolon after closing brace of function;
- Add unit test for convtime().
+ from Michael Forney
- Upstream-Regress-ID: 8717bc0ca4c21120f6dd3a1d3b7a363f707c31e1
+ OpenBSD-Commit-ID: fda95acb799bb160d15e205ee126117cf33da3a7
-commit 8884b7247d094cd11ff9e39c325ba928c5bdbc6c
+commit 6e1d1bbf5a3eca875005e0c87f341a0a03799809
Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Tue Mar 14 01:10:07 2017 +0000
+Date: Wed Nov 27 05:38:43 2019 +0000
- upstream commit
+ upstream: Revert previous commit. The channels code still uses int
- Add ASSERT_LONG_* helpers.
+ in many places for channel ids so the INT_MAX check still makes sense.
- Upstream-Regress-ID: fe15beaea8f5063c7f21b0660c722648e3d76431
+ OpenBSD-Commit-ID: 532e4b644791b826956c3c61d6ac6da39bac84bf
-commit c6774d21185220c0ba11e8fd204bf0ad1a432071
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Tue Mar 14 00:55:37 2017 +0000
+commit 48989244658b9748b6801034ff4ffbdfc6b1520f
+Author: Damien Miller <djm@mindrot.org>
+Date: Wed Nov 27 16:03:12 2019 +1100
- upstream commit
+ wire sk-dummy.so into test suite
+
+commit f79364bacaebde4f1c260318ab460fceacace02f
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Wed Nov 27 05:00:17 2019 +0000
+
+ upstream: use error()+_exit() instead of fatal() to avoid running
- Fix convtime() overflow test on boundary condition,
- spotted by & ok djm.
+ cleanup handlers in child process; spotted via weird regress failures in
+ portable
- Upstream-ID: 51f14c507ea87a3022e63f574100613ab2ba5708
+ OpenBSD-Commit-ID: 6902a9bb3987c7d347774444f7979b8a9ba7f412
-commit f5746b40cfe6d767c8e128fe50c43274b31cd594
+commit 70ec5e5e2681bcd409a9df94a2fec6f57a750945
Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Tue Mar 14 00:25:03 2017 +0000
+Date: Wed Nov 27 03:34:04 2019 +0000
- upstream commit
+ upstream: Make channel_id u_int32_t and remove unnecessary check
- Check for integer overflow when parsing times in
- convtime(). Reported by nicolas.iooss at m4x.org, ok djm@
+ and cast that were left over from the type conversion. Noted by
+ t-hashida@amiya.co.jp in bz#3098, ok markus@ djm@
- Upstream-ID: 35e6a4e98f6fa24df50bfb8ba1307cf70e966f13
+ OpenBSD-Commit-ID: 3ad105b6a905284e780b1fd7ff118e1c346e90b5
-commit f5907982f42a8d88a430b8a46752cbb7859ba979
-Author: Darren Tucker <dtucker@zip.com.au>
-Date: Tue Mar 14 13:38:15 2017 +1100
+commit ad44ca81bea83657d558aaef5a1d789a9032bac3
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Tue Nov 26 23:43:10 2019 +0000
- Add a "unit" target to run only unit tests.
+ upstream: test FIDO2/U2F key types; ok markus@
+
+ OpenBSD-Regress-ID: 367e06d5a260407619b4b113ea0bd7004a435474
-commit 9e96b41682aed793fadbea5ccd472f862179fb02
-Author: Damien Miller <djm@mindrot.org>
-Date: Tue Mar 14 12:24:47 2017 +1100
+commit c6efa8a91af1d4fdb43909a23a0a4ffa012155ad
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Tue Nov 26 23:41:23 2019 +0000
- Fix weakness in seccomp-bpf sandbox arg inspection
+ upstream: add dummy security key middleware based on work by
- Syscall arguments are passed via an array of 64-bit values in struct
- seccomp_data, but we were only inspecting the bottom 32 bits and not
- even those correctly for BE systems.
+ markus@
- Fortunately, the only case argument inspection was used was in the
- socketcall filtering so using this for sandbox escape seems
- impossible.
+ This will allow us to test U2F/FIDO2 support in OpenSSH without
+ requiring real hardware.
- ok dtucker
+ ok markus@
+
+ OpenBSD-Regress-ID: 88b309464b8850c320cf7513f26d97ee1fdf9aae
+
+commit 8635afa1cdc21366d61730d943f3cf61861899c8
+Author: jmc@openbsd.org <jmc@openbsd.org>
+Date: Tue Nov 26 22:42:26 2019 +0000
-commit 8ff3fc3f2f7c13e8968717bc2b895ee32c441275
+ upstream: tweak previous;
+
+ OpenBSD-Commit-ID: a4c097364c75da320f1b291568db830fb1ee4883
+
+commit e0d38ae9bc8c0de421605b9021d8144e4d8ff22b
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sat Mar 11 23:44:16 2017 +0000
+Date: Tue Nov 26 03:04:27 2019 +0000
- upstream commit
+ upstream: more debugging; behind DEBUG_SK
- regress tests for loading certificates without public keys;
- bz#2617 based on patch from Adam Eijdenberg; ok markus@ dtucker@
+ OpenBSD-Commit-ID: a978896227118557505999ddefc1f4c839818b60
+
+commit 9281d4311b8abc63b88259f354944c53f9b0b3c7
+Author: Damien Miller <djm@mindrot.org>
+Date: Mon Nov 25 21:47:49 2019 +1100
+
+ unbreak fuzzers for recent security key changes
+
+commit c5f1cc993597fed0a9013743556b1567f476c677
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Mon Nov 25 10:32:35 2019 +0000
+
+ upstream: unbreak tests for recent security key changes
- Upstream-Regress-ID: 0145d19328ed995b73fe2d9da33596b17429d0d0
+ OpenBSD-Regress-ID: 2cdf2fcae9962ca4d711338f3ceec3c1391bdf95
-commit 1e24552716194db8f2f620587b876158a9ef56ad
+commit 64988266820cc90a45a21672be9d762cbde8d34d
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sat Mar 11 23:40:26 2017 +0000
+Date: Mon Nov 25 06:53:04 2019 +0000
- upstream commit
+ upstream: unbreak after security key support landed
+
+ OpenBSD-Regress-ID: 3ab578b0dbeb2aa6d9969b54a9c1bad329c0dcba
+
+commit e65e25c81e22ea622e89a142a303726a3882384f
+Author: tb@openbsd.org <tb@openbsd.org>
+Date: Thu Nov 21 05:18:47 2019 +0000
+
+ upstream: Remove workaround for broken 'openssl rsa -text' output
- allow ssh to use certificates accompanied by a private
- key file but no corresponding plain *.pub public key. bz#2617 based on patch
- from Adam Eijdenberg; ok dtucker@ markus@
+ that was fixed in libcrypto/rsa/rsa_ameth.c r1.24.
- Upstream-ID: 295668dca2c39505281577217583ddd2bd4b00b9
+ ok dtucker inoguchi
+
+ OpenBSD-Regress-ID: c260edfac177daa8fcce90141587cf04a95c4f5f
-commit 0fb1a617a07b8df5de188dd5a0c8bf293d4bfc0e
-Author: markus@openbsd.org <markus@openbsd.org>
-Date: Sat Mar 11 13:07:35 2017 +0000
+commit 21377ec2a9378579ba4b44a681af7bbca77581f4
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Mon Nov 25 10:23:36 2019 +0000
- upstream commit
+ upstream: redundant test
- Don't count the initial block twice when computing how
- many bytes to discard for the work around for the attacks against CBC-mode.
- ok djm@; report from Jean Paul, Kenny, Martin and Torben @ RHUL
+ OpenBSD-Commit-ID: 38fa7806c528a590d91ae560e67bd8b246c2d7a3
+
+commit 664deef95a2e770812533439b8bdd3f3c291ae59
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Mon Nov 25 00:57:51 2019 +0000
+
+ upstream: document the "no-touch-required" certificate extension;
- Upstream-ID: f445f509a4e0a7ba3b9c0dae7311cb42458dc1e2
+ ok markus, feedback deraadt
+
+ OpenBSD-Commit-ID: 47640122b13f825e9c404ea99803b2372246579d
-commit ef653dd5bd5777132d9f9ee356225f9ee3379504
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Fri Mar 10 07:18:32 2017 +0000
+commit 26cb128b31efdd5395153f4943f5be3eddc07033
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Mon Nov 25 00:57:27 2019 +0000
- upstream commit
+ upstream: Print a key touch reminder when generating a security
- krl.c
+ key. Most keys require a touch to authorize the operation.
- Upstream-ID: fc5e695d5d107d730182e2da7b23f00b489e0ee1
+ OpenBSD-Commit-ID: 7fe8b23edbf33e1bb81741b9f25e9a63be5f6b68
-commit d94c1dfef2ea30ca67b1204ada7c3b537c54f4d0
-Author: Damien Miller <djm@mindrot.org>
-Date: Sun Mar 12 10:48:14 2017 +1100
+commit daeaf4136927c2a82af1399022103d67ff03f74a
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Mon Nov 25 00:55:58 2019 +0000
- sync fmt_scaled.c with OpenBSD
+ upstream: allow "ssh-keygen -x no-touch-required" when generating a
- revision 1.13
- date: 2017/03/11 23:37:23; author: djm; state: Exp; lines: +14 -1; commitid: jnFKyHkB3CEiEZ2R;
- fix signed integer overflow in scan_scaled. Found by Nicolas Iooss
- using AFL against ssh_config. ok deraadt@ millert@
- ----------------------------
- revision 1.12
- date: 2013/11/29 19:00:51; author: deraadt; state: Exp; lines: +6 -5;
- fairly simple unsigned char casts for ctype
- ok krw
- ----------------------------
- revision 1.11
- date: 2012/11/12 14:07:20; author: halex; state: Exp; lines: +4 -2;
- make scan_scaled set errno to EINVAL rather than ERANGE if it encounters
- an invalid multiplier, like the man page says it should
+ security key keypair to request one that does not require a touch for each
+ authentication attempt. The default remains to require touch.
- "looks sensible" deraadt@, ok ian@
- ----------------------------
- revision 1.10
- date: 2009/06/20 15:00:04; author: martynas; state: Exp; lines: +4 -4;
- use llabs instead of the home-grown version; and some comment changes
- ok ian@, millert@
- ----------------------------
+ feedback deraadt; ok markus@
+
+ OpenBSD-Commit-ID: 887e7084b2e89c0c62d1598ac378aad8e434bcbd
-commit 894221a63fa061e52e414ca58d47edc5fe645968
+commit 2e71263b80fec7ad977e098004fef7d122169d40
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Mar 10 05:01:13 2017 +0000
+Date: Mon Nov 25 00:54:23 2019 +0000
- upstream commit
+ upstream: add a "no-touch-required" option for authorized_keys and
- When updating hostkeys, accept RSA keys if
- HostkeyAlgorithms contains any RSA keytype. Previously, ssh could ignore RSA
- keys when any of the ssh-rsa-sha2-* methods was enabled in HostkeyAlgorithms
- nit ssh-rsa (SHA1 signatures) was not. bz#2650 reported by Luis Ressel; ok
- dtucker@
+ a similar extension for certificates. This option disables the default
+ requirement that security key signatures attest that the user touched their
+ key to authorize them.
+
+ feedback deraadt, ok markus
- Upstream-ID: c5e8cfee15c42f4a05d126158a0766ea06da79d2
+ OpenBSD-Commit-ID: f1fb56151ba68d55d554d0f6d3d4dba0cf1a452e
-commit dd3e2298663f4cc1a06bc69582d00dcfee27d73c
+commit 0fddf2967ac51d518e300408a0d7e6adf4cd2634
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Mar 10 04:24:55 2017 +0000
+Date: Mon Nov 25 00:52:46 2019 +0000
- upstream commit
+ upstream: Add a sshd_config PubkeyAuthOptions directive
- make hostname matching really insensitive to case;
- bz#2685, reported by Petr Cerny; ok dtucker@
+ This directive has a single valid option "no-touch-required" that
+ causes sshd to skip checking whether user presence was tested before
+ a security key signature was made (usually by the user touching the
+ key).
- Upstream-ID: e467622ff154269e36ba8b6c9e3d105e1c4a9253
+ ok markus@
+
+ OpenBSD-Commit-ID: 46e434a49802d4ed82bc0aa38cb985c198c407de
-commit 77a9be9446697fe8b5499fe651f4a82a71a4b51f
+commit b7e74ea072919b31391bc0f5ff653f80b9f5e84f
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Mar 10 03:52:48 2017 +0000
+Date: Mon Nov 25 00:51:37 2019 +0000
- upstream commit
+ upstream: Add new structure for signature options
+
+ This is populated during signature verification with additional fields
+ that are present in and covered by the signature. At the moment, it is
+ only used to record security key-specific options, especially the flags
+ field.
- reword a comment to make it fit 80 columns
+ with and ok markus@
- Upstream-ID: 4ef509a66b96c7314bbcc87027c2af71fa9d0ba4
+ OpenBSD-Commit-ID: 338a1f0e04904008836130bedb9ece4faafd4e49
-commit 61b8ef6a66efaec07e023342cb94a10bdc2254dc
+commit d2b0f88178ec9e3f11b606bf1004ac2fe541a2c3
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Mar 10 04:27:32 2017 +0000
+Date: Mon Nov 25 00:38:17 2019 +0000
- upstream commit
+ upstream: memleak in error path
- better match sshd config parser behaviour: fatal() if
- line is overlong, increase line buffer to match sshd's; bz#2651 reported by
- Don Fong; ok dtucker@
+ OpenBSD-Commit-ID: 93488431bf02dde85a854429362695d2d43d9112
+
+commit e2c0a21ade5e0bd7f0aab08d7eb9457f086681e9
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Fri Nov 22 06:50:30 2019 +0000
+
+ upstream: Wait for FD to be readable or writeable during a nonblocking
+
+ connect, not just readable. Prevents a timeout when the server doesn't
+ immediately send a banner (eg multiplexers like sslh) but is also slightly
+ quicker for other connections since, unlike ssh1, ssh2 doesn't specify
+ that the client should parse the server banner before sending its own.
+ Patch from mnissler@chromium.org, ok djm@
+
+ OpenBSD-Commit-ID: aba9cd8480d1d9dd31d0ca0422ea155c26c5df1d
+
+commit 2f95d43dc222ce194622b706682e8de07c9cfb42
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Wed Nov 20 16:34:11 2019 +1100
+
+ Include openssl compat header.
- Upstream-ID: b175ae7e0ba403833f1ee566edf10f67443ccd18
+ Fixes warning for ECDSA_SIG_set0 on OpenSSL versions prior to 1.1.
-commit db2597207e69912f2592cd86a1de8e948a9d7ffb
+commit a70d92f236576c032a45c39e68ca0d71e958d19d
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Mar 10 04:26:06 2017 +0000
+Date: Tue Nov 19 22:23:19 2019 +0000
- upstream commit
+ upstream: adjust on-wire signature encoding for ecdsa-sk keys to
+
+ better match ec25519-sk keys. Discussed with markus@ and Sebastian Kinne
- ensure hostname is lower-case before hashing it;
- bz#2591 reported by Griff Miller II; ok dtucker@
+ NB. if you are depending on security keys (already?) then make sure you
+ update both your clients and servers.
- Upstream-ID: c3b8b93804f376bd00d859b8bcd9fc0d86b4db17
+ OpenBSD-Commit-ID: 53d88d8211f0dd02a7954d3af72017b1a79c0679
-commit df9936936c695f85c1038bd706d62edf752aca4b
+commit 26369a5f7d9c4e4ef44a3e04910126e1bcea43d8
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Mar 10 04:24:55 2017 +0000
+Date: Tue Nov 19 22:21:15 2019 +0000
- upstream commit
+ upstream: a little more information from the monitor when signature
- make hostname matching really insensitive to case;
- bz#2685, reported by Petr Cerny; ok dtucker@
+ verification fails.
- Upstream-ID: e632b7a9bf0d0558d5ff56dab98b7cca6c3db549
+ OpenBSD-Commit-ID: e6a30071e0518cac512f9e10be3dc3500e2003f3
-commit 67eed24bfa7645d88fa0b883745fccb22a0e527e
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Fri Mar 10 04:11:00 2017 +0000
+commit 4402d6c9b5bf128dcfae2429f1d41cdaa8849b6b
+Author: jmc@openbsd.org <jmc@openbsd.org>
+Date: Tue Nov 19 16:02:32 2019 +0000
- upstream commit
+ upstream: revert previous: naddy pointed out what's meant to
- Remove old null check from config dumper. Patch from
- jjelen at redhat.com vi bz#2687, ok djm@
+ happen. rethink needed...
- Upstream-ID: 824ab71467b78c4bab0dd1b3a38e8bc5f63dd528
+ OpenBSD-Commit-ID: fb0fede8123ea7f725fd65e00d49241c40bd3421
-commit 183ba55aaaecca0206184b854ad6155df237adbe
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Mar 10 04:07:20 2017 +0000
+commit 88056f881315233e990e4e04a815f8f96b4674e1
+Author: jmc@openbsd.org <jmc@openbsd.org>
+Date: Tue Nov 19 14:54:47 2019 +0000
- upstream commit
+ upstream: -c and -s do not make sense with -k; reshuffle -k into
- fix regression in 7.4 server-sig-algs, where we were
- accidentally excluding SHA2 RSA signature methods. bz#2680, patch from Nuno
- Goncalves; ok dtucker@
+ the main synopsis/usage; ok djm
- Upstream-ID: 81ac8bfb30960447740b9b8f6a214dcf322f12e8
+ OpenBSD-Commit-ID: f881ba253da015398ae8758d973e3390754869bc
-commit 66be4fe8c4435af5bbc82998501a142a831f1181
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Fri Mar 10 03:53:11 2017 +0000
+commit 2cf262c21f35296c2ff718cfdb52e0473a1c3983
+Author: naddy@openbsd.org <naddy@openbsd.org>
+Date: Mon Nov 18 23:17:48 2019 +0000
- upstream commit
+ upstream: document '$' environment variable expansion for
- Check for NULL return value from key_new. Patch from
- jjelen at redhat.com via bz#2687, ok djm@
+ SecurityKeyProvider; ok djm@
- Upstream-ID: 059e33cd43cba88dc8caf0b1936fd4dd88fd5b8e
+ OpenBSD-Commit-ID: 76db507ebd336a573e1cd4146cc40019332c5799
-commit ec2892b5c7fea199914cb3a6afb3af38f84990bf
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Mar 10 03:52:48 2017 +0000
+commit f0edda81c5ebccffcce52b182c3033531a1aab71
+Author: naddy@openbsd.org <naddy@openbsd.org>
+Date: Mon Nov 18 23:16:49 2019 +0000
- upstream commit
+ upstream: more missing mentions of ed25519-sk; ok djm@
- reword a comment to make it fit 80 columns
+ OpenBSD-Commit-ID: f242e53366f61697dffd53af881bc5daf78230ff
+
+commit 189550f5bc85148e85f4caa1f6b2fc623149a4ee
+Author: naddy@openbsd.org <naddy@openbsd.org>
+Date: Mon Nov 18 16:10:05 2019 +0000
+
+ upstream: additional missing stdarg.h includes when built without
+
+ WITH_OPENSSL; ok djm@
- Upstream-ID: b4b48b4487c0821d16e812c40c9b09f03b28e349
+ OpenBSD-Commit-ID: 881f9a2c4e2239849cee8bbf4faec9bab128f55b
-commit 7fadbb6da3f4122de689165651eb39985e1cba85
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Fri Mar 10 03:48:57 2017 +0000
+commit 723a5369864b338c48d22854bc2bb4ee5c083deb
+Author: naddy@openbsd.org <naddy@openbsd.org>
+Date: Mon Nov 18 16:08:57 2019 +0000
- upstream commit
+ upstream: add the missing WITH_OPENSSL ifdefs after the ED25519-SK
- Check for NULL argument to sshkey_read. Patch from
- jjelen at redhat.com via bz#2687, ok djm@
+ addition; ok djm@
- Upstream-ID: c2d00c2ea50c4861d271d0a586f925cc64a87e0e
+ OpenBSD-Commit-ID: a9545e1c273e506cf70e328cbb9d0129b6d62474
-commit 5a06b9e019e2b0b0f65a223422935b66f3749de3
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Fri Mar 10 03:45:40 2017 +0000
+commit 478f4f98e4e93ae4ed1a8911dec4e5b75ea10f30
+Author: Damien Miller <djm@mindrot.org>
+Date: Tue Nov 19 08:52:24 2019 +1100
- upstream commit
+ remove all EC algs from proposals, no just sk ones
- Plug some mem leaks mostly on error paths. From jjelen
- at redhat.com via bz#2687, ok djm@
+ ok dtucker@
+
+commit 6a7ef310da100f876a257b7367e3b0766dac3994
+Author: Damien Miller <djm@mindrot.org>
+Date: Mon Nov 18 22:22:04 2019 +1100
+
+ filter PUBKEY_DEFAULT_PK_ALG for ECC algorithms
- Upstream-ID: 3fb030149598957a51b7c8beb32bf92cf30c96f2
+ Remove ECC algorithms from the PUBKEY_DEFAULT_PK_ALG list when
+ compiling without ECC support in libcrypto.
-commit f6edbe9febff8121f26835996b1229b5064d31b7
+commit 64f56f1d1af3947a71a4c391f2c08747d19ee591
Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Fri Mar 10 03:24:48 2017 +0000
+Date: Mon Nov 18 09:15:17 2019 +0000
- upstream commit
+ upstream: LibreSSL change the format for openssl rsa -text output from
- Plug mem leak on GLOB_NOMATCH case. From jjelen at
- redhat.com via bz#2687, ok djm@
+ "publicExponent" to "Exponent" so accept either. with djm.
- Upstream-ID: 8016a7ae97719d3aa55fb723fc2ad3200058340d
+ OpenBSD-Regress-ID: b7e6c4bf700029a31c98be14600d4472fe0467e6
-commit 566b3a46e89a2fda2db46f04f2639e92da64a120
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Fri Mar 10 03:22:40 2017 +0000
+commit 4bfc0503ad94a2a7190686a89649567c20b8534f
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Mon Nov 18 06:58:00 2019 +0000
- upstream commit
+ upstream: fix a bug that prevented serialisation of ed25519-sk keys
- Plug descriptor leaks of auth_sock. From jjelen at
- redhat.com via bz#2687, ok djm@
+ OpenBSD-Commit-ID: 066682b79333159cac04fcbe03ebd9c8dcc152a9
+
+commit d88205417084f523107fbe1bc92061635cd57fd2
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Mon Nov 18 06:39:36 2019 +0000
+
+ upstream: Fix incorrect error message when key certification fails
- Upstream-ID: 248acb99a5ed2fdca37d1aa33c0fcee7be286d88
+ OpenBSD-Commit-ID: 7771bd77ee73f7116df37c734c41192943a73cee
-commit 8a2834454c73dfc1eb96453c0e97690595f3f4c2
+commit 740c4bc9875cbb4b9fc03fd5eac19df080f20df5
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Mar 10 03:18:24 2017 +0000
+Date: Mon Nov 18 06:39:02 2019 +0000
- upstream commit
+ upstream: fix bug that prevented certification of ed25519-sk keys
- correctly hash hosts with a port number. Reported by Josh
- Powers in bz#2692; ok dtucker@
+ OpenBSD-Commit-ID: 64c8cc6f5de2cdd0ee3a81c3a9dee8d862645996
+
+commit 85409cbb505d8c463ab6e2284b4039764c7243de
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Mon Nov 18 06:24:17 2019 +0000
+
+ upstream: allow *-sk key types to be turned into certificates
- Upstream-ID: 468e357ff143e00acc05bdd2803a696b3d4b6442
+ OpenBSD-Commit-ID: cd365ee343934862286d0b011aa77fa739d2a945
-commit 9747b9c742de409633d4753bf1a752cbd211e2d3
+commit e2e1283404e06a22ac6135d057199e70dcadb8dd
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Mar 10 03:15:58 2017 +0000
+Date: Mon Nov 18 04:55:02 2019 +0000
- upstream commit
+ upstream: mention ed25519-sk key/cert types here too; prompted by
- don't truncate off \r\n from long stderr lines; bz#2688,
- reported by Brian Dyson; ok dtucker@
+ jmc@
- Upstream-ID: cdfdc4ba90639af807397ce996153c88af046ca4
+ OpenBSD-Commit-ID: e281977e4a4f121f3470517cbd5e483eee37b818
-commit 4a4b75adac862029a1064577eb5af299b1580cdd
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Fri Mar 10 02:59:51 2017 +0000
+commit 97dc5d1d82865a7d20f1eb193b5c62ce684024e5
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Mon Nov 18 04:50:45 2019 +0000
- upstream commit
+ upstream: mention ed25519-sk in places where it is accepted;
- Validate digest arg in ssh_digest_final; from jjelen at
- redhat.com via bz#2687, ok djm@
+ prompted by jmc@
- Upstream-ID: dbe5494dfddfe523fab341a3dab5a79e7338f878
+ OpenBSD-Commit-ID: 076d386739ebe7336c2137e583bc7a5c9538a442
-commit bee0167be2340d8de4bdc1ab1064ec957c85a447
-Author: Darren Tucker <dtucker@zip.com.au>
-Date: Fri Mar 10 13:40:18 2017 +1100
+commit 130664344862a8c7afd3e24d8d36ce40af41a99f
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Mon Nov 18 04:34:47 2019 +0000
- Check for NULL from malloc.
+ upstream: document ed25519-sk pubkey, private key and certificate
+
+ formats
- Part of bz#2687, from jjelen at redhat.com.
+ OpenBSD-Commit-ID: 795a7c1c80315412e701bef90e31e376ea2f3c88
-commit da39b09d43b137a5a3d071b51589e3efb3701238
-Author: Darren Tucker <dtucker@zip.com.au>
-Date: Fri Mar 10 13:22:32 2017 +1100
+commit 71856e1142fc01628ce53098f8cfc74765464b35
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Mon Nov 18 04:29:50 2019 +0000
- If OSX is using launchd, remove screen no.
+ upstream: correct order or ecdsa-sk private key fields
- Check for socket with and without screen number. From Apple and Jakob
- Schlyter via bz#2341, with contributions from Ron Frederick, ok djm@
+ OpenBSD-Commit-ID: 4d4a0c13226a79f0080ce6cbe74f73b03ed8092e
-commit 8fb15311a011517eb2394bb95a467c209b8b336c
+commit 93fa2a6649ae3e0626cbff25c985a4573d63e3f2
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Wed Mar 8 12:07:47 2017 +0000
+Date: Mon Nov 18 04:16:53 2019 +0000
- upstream commit
+ upstream: correct description of fields in pub/private keys (was
- quote [host]:port in generated ProxyJump commandline; the
- [ / ] characters can confuse some shells (e.g. zsh). Reported by Lauri
- Tirkkonen via bugs@
+ missing curve name); spotted by Sebastian Kinne
- Upstream-ID: 65cdd161460e1351c3d778e974c1c2a4fa4bc182
+ OpenBSD-Commit-ID: 2a11340dc7ed16200342d384fb45ecd4fcce26e7
-commit 18501151cf272a15b5f2c5e777f2e0933633c513
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Mon Mar 6 02:03:20 2017 +0000
+commit b497e920b409250309c4abe64229237b8f2730ba
+Author: Damien Miller <djm@mindrot.org>
+Date: Mon Nov 18 15:05:04 2019 +1100
- upstream commit
+ Teach the GTK2/3 ssh-askpass the new prompt hints
- Check l->hosts before dereferencing; fixes potential null
- pointer deref. ok djm@
+ ssh/ssh-agent now sets a hint environment variable $SSH_ASKPASS_PROMPT
+ when running the askpass program. This is intended to allow the
+ askpass to vary its UI across the three cases it supports: asking for
+ a passphrase, confirming the use of a key and (recently) reminding
+ a user to touch their security key.
- Upstream-ID: 81c0327c6ec361da794b5c680601195cc23d1301
+ This adapts the gnome-ssh-askpass[23] to use these hints. Specifically,
+ for SSH_ASKPASS_PROMPT=confirm it will skip the text input box and show
+ only "yes"/"no" buttons. For SSH_ASKPASS_PROMPT=none (used to remind
+ users to tap their security key), it shows only a "close" button.
+
+ Help wanted: adapt the other askpass programs in active use, including
+ x11-ssh-askpass, lxqt-openssh-askpass, etc.
-commit d072370793f1a20f01ad827ba8fcd3b8f2c46165
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Mon Mar 6 00:44:51 2017 +0000
+commit 857f49e91eeae6feb781ef5f5e26c38ca3d953ec
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Mon Nov 18 14:15:26 2019 +1100
- upstream commit
+ Move ifdef OPENSSL_HAS_ECC.
- linenum is unsigned long so use %lu in log formats. ok
- deraadt@
+ Found by -Wimplicit-fallthrough: one ECC case was not inside the ifdef.
+ ok djm@
+
+commit 6cf1c40096a79e5eedcf897c7cdb46bb32d4a3ee
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Mon Nov 18 14:14:18 2019 +1100
+
+ Enable -Wimplicit-fallthrough if supported
- Upstream-ID: 9dc582d9bb887ebe0164e030d619fc20b1a4ea08
+ Suggested by djm.
-commit 12d3767ba4c84c32150cbe6ff6494498780f12c9
+commit 103c51fd5f5ddc01cd6b5c1132e711765b921bf5
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Mar 3 06:13:11 2017 +0000
+Date: Mon Nov 18 01:59:48 2019 +0000
- upstream commit
+ upstream: missing break in getopt switch; spotted by Sebastian Kinne
+
+ OpenBSD-Commit-ID: f002dbf14dba5586e8407e90f0141148ade8e8fc
+
+commit 9a1225e8ca2ce1fe809910874935302234399a6d
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Sat Nov 16 23:17:20 2019 +0000
+
+ upstream: tweak debug message
- fix ssh-keygen -H accidentally corrupting known_hosts that
- contained already-hashed entries. HKF_MATCH_HOST_HASHED is only set by
- hostkeys_foreach() when hostname matching is in use, so we need to look for
- the hash marker explicitly.
+ OpenBSD-Commit-ID: 2bf336d3be0b7e3dd97920d7e7471146a281d2b9
+
+commit 4103a3ec7c68493dbc4f0994a229507e943a86d3
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Sat Nov 16 22:42:30 2019 +0000
+
+ upstream: a little debug() in the security key interface
- Upstream-ID: da82ad653b93e8a753580d3cf5cd448bc2520528
+ OpenBSD-Commit-ID: 4c70300609a5c8b19707207bb7ad4109e963b0e8
-commit d7abb771bd5a941b26144ba400a34563a1afa589
+commit 05daa211de926f66f50b7380d637f84dc6341574
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Tue Feb 28 06:10:08 2017 +0000
+Date: Sat Nov 16 22:36:48 2019 +0000
- upstream commit
+ upstream: always use ssh-sk-helper, even for the internal USB HID
- small memleak: free fd_set on connection timeout (though
- we are heading to exit anyway). From Tom Rix in bz#2683
+ support. This avoid the need for a wpath pledge in ssh-agent.
- Upstream-ID: 10e3dadbb8199845b66581473711642d9e6741c4
+ reported by jmc@
+
+ OpenBSD-Commit-ID: 19f799c4d020b870741d221335dbfa5e76691c23
-commit 78142e3ab3887e53a968d6e199bcb18daaf2436e
-Author: jmc@openbsd.org <jmc@openbsd.org>
-Date: Mon Feb 27 14:30:33 2017 +0000
+commit d431778a561d90131814f986b646299f9af33c8c
+Author: markus@openbsd.org <markus@openbsd.org>
+Date: Fri Nov 15 15:41:01 2019 +0000
- upstream commit
+ upstream: fix typos in sk_enroll
- errant dot; from klemens nanni
+ OpenBSD-Commit-ID: faa9bf779e008b3e64e2eb1344d9b7d83b3c4487
+
+commit af90aec0443ec51e6b2d804cb91771d3905f8a6f
+Author: jmc@openbsd.org <jmc@openbsd.org>
+Date: Fri Nov 15 11:16:28 2019 +0000
+
+ upstream: double word;
- Upstream-ID: 83d93366a5acf47047298c5d3ebc5e7426f37921
+ OpenBSD-Commit-ID: 43d09bafa4ea9002078cb30ca9adc3dcc0b9c2b9
-commit 8071a6924c12bb51406a9a64a4b2892675112c87
+commit fd1a96490cef7f945a1b3b5df4e90c8a1070f425
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Feb 24 03:16:34 2017 +0000
+Date: Fri Nov 15 06:00:20 2019 +0000
- upstream commit
+ upstream: remove most uses of BN_CTX
+
+ We weren't following the rules re BN_CTX_start/BN_CTX_end and the places
+ we were using it didn't benefit from its use anyway. ok dtucker@
- might as well set the listener socket CLOEXEC
+ OpenBSD-Commit-ID: ea9ba6c0d2e6f6adfe00b309a8f41842fe12fc7a
+
+commit 39b87104cdd47baf79ef77dc81de62cea07d119f
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Fri Nov 15 18:56:54 2019 +1100
+
+ Add wrappers for other ultrix headers.
- Upstream-ID: 9c538433d6a0ca79f5f21decc5620e46fb68ab57
+ Wrappers protect against multiple inclusions for headers that don't do
+ it themselves.
+
+commit 134a74f4e0cf750931f1125beb2a3f40c54c8809
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Fri Nov 15 18:55:13 2019 +1100
+
+ Add SSIZE_MAX when we define ssize_t.
+
+commit 9c6d0a3a1ed77989d8c5436d8c3cc6c7045c0197
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Fri Nov 15 17:13:19 2019 +1100
-commit d5499190559ebe374bcdfa8805408646ceffad64
+ Remove ultrix realpath hack.
+
+commit c63fba5e3472307167850bbd84187186af7fa9f0
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sun Feb 19 00:11:29 2017 +0000
+Date: Fri Nov 15 05:37:27 2019 +0000
- upstream commit
+ upstream: unshield security key privkey before attempting signature
- add test cases for C locale; ok schwarze@
+ in agent. spotted by dtucker@
- Upstream-Regress-ID: 783d75de35fbc923d46e2a5e6cee30f8f381ba87
+ OpenBSD-Commit-ID: fb67d451665385b8a0a55371231c50aac67b91d2
-commit 011c8ffbb0275281a0cf330054cf21be10c43e37
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sun Feb 19 00:10:57 2017 +0000
+commit d165bb5396e3f718480e6039ca2cf77f5a2c2885
+Author: deraadt@openbsd.org <deraadt@openbsd.org>
+Date: Fri Nov 15 05:26:56 2019 +0000
+
+ upstream: rewrite c99-ism
+
+ OpenBSD-Commit-ID: d0c70cca29cfa7e6d9f7ec1d6d5dabea112499b3
+
+commit 03e06dd0e6e1c0a9f4b4b9de7def8a44dcbf93a7
+Author: deraadt@openbsd.org <deraadt@openbsd.org>
+Date: Fri Nov 15 05:25:52 2019 +0000
+
+ upstream: only clang understands those new -W options
+
+ OpenBSD-Commit-ID: d9b910e412d139141b072a905e66714870c38ac0
+
+commit 5c0bc273cba53f822b7d777bbb6c35d160d3b505
+Author: Damien Miller <djm@mindrot.org>
+Date: Fri Nov 15 16:08:00 2019 +1100
+
+ configure flag to built-in security key support
+
+ Require --with-security-key-builtin before enabling the built-in
+ security key support (and consequent dependency on libfido2).
+
+commit fbcb9a7fa55300b8bd4c18bee024c6104c5a25d7
+Author: Damien Miller <djm@mindrot.org>
+Date: Fri Nov 15 16:06:30 2019 +1100
upstream commit
- Add a common nl_langinfo(CODESET) alias for US-ASCII
- "ANSI_X3.4-1968" that is used by Linux. Fixes mprintf output truncation for
- non-UTF-8 locales on Linux spotted by dtucker@; ok deraadt@ schwarze@
+ revision 1.48
+ date: 2019/02/04 16:45:40; author: millert; state: Exp; lines: +16 -17; commitid: cpNtVC7erojNyctw;
+ Make gl_pathc, gl_matchc and gl_offs size_t in glob_t to match POSIX.
+ This requires a libc major version bump. OK deraadt@
+
+commit 2cfb11abac85885de0cb888bbeb9a3e4303105ea
+Author: Damien Miller <djm@mindrot.org>
+Date: Fri Nov 15 16:05:07 2019 +1100
+
+ upstream commit
- Upstream-ID: c6808956ebffd64066f9075d839f74ff0dd60719
+ revision 1.47
+ date: 2017/05/08 14:53:27; author: millert; state: Exp; lines: +34 -21; commitid: sYfxfyUHAfarP8sE;
+ Fix exponential CPU use with repeated '*' operators by changing '*'
+ handling to be interative instead of recursive.
+ Fix by Yves Orton, ported to OpenBSD glob.c by Ray Lai. OK tb@
-commit 0c4430a19b73058a569573492f55e4c9eeaae67b
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Tue Feb 7 23:03:11 2017 +0000
+commit 228dd595c7882bb9b161dbb7d4dca15c8a5f03f5
+Author: Damien Miller <djm@mindrot.org>
+Date: Fri Nov 15 16:04:28 2019 +1100
upstream commit
- Remove deprecated SSH1 options RSAAuthentication and
- RhostsRSAAuthentication from regression test sshd_config.
+ revision 1.46
+ date: 2015/12/28 22:08:18; author: mmcc; state: Exp; lines: +5 -9; commitid: 0uXuF2O13NH9q2e1;
+ Remove NULL-checks before free() and a few related dead assignments.
- Upstream-Regress-ID: 8066b753d9dce7cf02ff87af5c727ff680d99491
+ ok and valuable input from millert@
-commit 3baa4cdd197c95d972ec3d07f1c0d08f2d7d9199
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Fri Feb 17 02:32:05 2017 +0000
+commit a16f748690139b9f452485d97511ad5e578f59b2
+Author: Damien Miller <djm@mindrot.org>
+Date: Fri Nov 15 16:02:43 2019 +1100
upstream commit
- Do not show rsa1 key type in usage when compiled without
- SSH1 support.
+ revision 1.44
+ date: 2015/09/14 16:09:13; author: tedu; state: Exp; lines: +3 -5; commitid: iWfSX2BIn0sLw62l;
+ remove null check before free. from Michael McConville
+ ok semarie
+
+commit fd37cdeafe25adfcdc752280f535d28de7997ff1
+Author: Damien Miller <djm@mindrot.org>
+Date: Fri Nov 15 16:02:27 2019 +1100
+
+ upstream commit
- Upstream-ID: 068b5c41357a02f319957746fa4e84ea73960f57
+ revision 1.43
+ date: 2015/06/13 16:57:04; author: deraadt; state: Exp; lines: +4 -4; commitid: zOUKuqWBdOPOz1SZ;
+ in glob() initialize the glob_t before the first failure check.
+ from j@pureftpd.org
+ ok millert stsp
-commit ecc35893715f969e98fee118481f404772de4132
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Fri Feb 17 02:31:14 2017 +0000
+commit fd62769c3882adea118dccaff80a06009874a2d1
+Author: Damien Miller <djm@mindrot.org>
+Date: Fri Nov 15 16:01:20 2019 +1100
upstream commit
- ifdef out "rsa1" from the list of supported keytypes when
- compiled without SSH1 support. Found by kdunlop at guralp.com, ok djm@
+ revision 1.42
+ date: 2015/02/05 12:59:57; author: millert; state: Exp; lines: +2 -1; commitid: DTQbfd4poqBW8iSJ;
+ Include stdint.h, not limits.h to get SIZE_MAX. OK guenther@
+
+commit 2b6cba7ee2b8b36f393be739c860a9d2e5d8eb48
+Author: Damien Miller <djm@mindrot.org>
+Date: Fri Nov 15 16:00:07 2019 +1100
+
+ upstream commit
- Upstream-ID: cea93a26433d235bb1d64b1d990f19a9c160a70f
+ revision 1.41
+ date: 2014/10/08 05:35:27; author: deraadt; state: Exp; lines: +3 -3; commitid: JwTGarRLHQKDgPh2;
+ obvious realloc -> reallocarray conversion
-commit 10577c6d96a55b877a960b2d0b75edef1b9945af
+commit ab3600665387ae34785498558c4409e27f495b0b
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Feb 17 02:04:15 2017 +0000
+Date: Fri Nov 15 04:12:32 2019 +0000
- upstream commit
+ upstream: don't consult dlopen whitelist for internal security key
- For ProxyJump/-J, surround host name with brackets to
- allow literal IPv6 addresses. From Dick Visser; ok dtucker@
+ provider; spotted by dtucker@
- Upstream-ID: 3a5d3b0171250daf6a5235e91bce09c1d5746bf1
+ OpenBSD-Commit-ID: bfe5fbd17e4ff95dd85b9212181652b54444192e
-commit b2afdaf1b52231aa23d2153f4a8c5a60a694dda4
-Author: jsg@openbsd.org <jsg@openbsd.org>
-Date: Wed Feb 15 23:38:31 2017 +0000
+commit 19f8ec428db835f68c1cfd63587e9880ccd6486c
+Author: Damien Miller <djm@mindrot.org>
+Date: Fri Nov 15 15:08:28 2019 +1100
+
+ upstream commit
+
+ revision 1.40
+ date: 2013/09/30 12:02:34; author: millert; state: Exp; lines: +14 -15;
+ Use PATH_MAX, NAME_MAX and LOGIN_NAME_MAX not MAXPATHNAMELEN,
+ MAXNAMLEN or MAXLOGNAME where possible. OK deraadt@
+
+commit bb7413db98e418d4af791244660abf6c829783f5
+Author: Damien Miller <djm@mindrot.org>
+Date: Fri Nov 15 15:07:30 2019 +1100
upstream commit
- Fix memory leaks in match_filter_list() error paths.
+ revision 1.39
+ date: 2012/01/20 07:09:42; author: tedu; state: Exp; lines: +4 -4;
+ the glob stat limit is way too low. bump to 2048.
+ while here, failed stats should count against the limit too.
+ ok deraadt sthen stsp
+
+commit 01362cf7cb979525c014714e2bccf799a46e772e
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Fri Nov 15 03:41:57 2019 +0000
+
+ upstream: U2F tokens may return FIDO_ERR_USER_PRESENCE_REQUIRED when
+
+ probed to see if they own a key handle. Handle this case so the find_device()
+ look can work for them. Reported by Michael Forney
+
+ OpenBSD-Commit-ID: 2ccd5b30a6ddfe4dba228b7159bf168601bd9166
+
+commit cf62307bc9758105913dcb91b418e4968ac2244d
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Fri Nov 15 14:01:00 2019 +1100
+
+ Add libfido2 to INSTALL.
+
+commit 69fbda1894349d1f420c842dfcbcc883239d1aa7
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Fri Nov 15 13:42:15 2019 +1100
+
+ libcrypto is now optional.
+
+commit 45ffa369886e37930776d7c15dd8b973242d6ecc
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Fri Nov 15 02:38:07 2019 +0000
+
+ upstream: show the "please touch your security key" notifier when
- ok dtucker@ markus@
+ using the (default) build-in security key support.
- Upstream-ID: c7f96ac0877f6dc9188bbc908100a8d246cc7f0e
+ OpenBSD-Commit-ID: 4707643aaa7124501d14e92d1364b20f312a6428
-commit 6d5a41b38b55258213ecfaae9df7a758caa752a1
+commit 49dc9fa928d77807c53bdc2898db7fb515fe5eb3
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Wed Feb 15 01:46:47 2017 +0000
+Date: Fri Nov 15 02:37:24 2019 +0000
- upstream commit
+ upstream: close the "touch your security key" notifier on the error
- fix division by zero crash in "df" output when server
- returns zero total filesystem blocks/inodes. Spotted by Guido Vranken; ok
- dtucker@
+ path too
- Upstream-ID: 6fb6c2ae6b289aa07b6232dbc0be54682ef5419f
+ OpenBSD-Commit-ID: c7628bf80505c1aefbb1de7abc8bb5ee51826829
-commit bd5d7d239525d595ecea92765334af33a45d9d63
-Author: Darren Tucker <dtucker@zip.com.au>
-Date: Sun Feb 12 15:45:15 2017 +1100
+commit 22a82712e89bf17c27427aeba15795fb4011a0c2
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Fri Nov 15 02:20:06 2019 +0000
- ifdef out EVP_R_PRIVATE_KEY_DECODE_ERROR
+ upstream: correct function name in debug message
- EVP_R_PRIVATE_KEY_DECODE_ERROR was added in OpenSSL 1.0.0 so ifdef out
- for the benefit of OpenSSL versions prior to that.
+ OpenBSD-Commit-ID: 2482c99d2ce448f39282493050f8a01e3ffc39ab
-commit 155d540d00ff55f063421ec182ec8ff2b7ab6cbe
+commit 018e2902a65c22faded215a7c588492c948f108c
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Feb 10 04:34:50 2017 +0000
+Date: Fri Nov 15 00:32:40 2019 +0000
- upstream commit
+ upstream: follow existing askpass logic for security key notifier:
- bring back r1.34 that was backed out for problems loading
- public keys:
+ fall back to _PATH_SSH_ASKPASS_DEFAULT if no $SSH_ASKPASS environment
+ variable is set.
- translate OpenSSL error codes to something more
- meaninful; bz#2522 reported by Jakub Jelen, ok dtucker@
+ OpenBSD-Commit-ID: cda753726b13fb797bf7a9f7a0b3022d9ade4520
+
+commit 575d0042a94997c1eeb86a6dcfb30b3c7bdbcba3
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Thu Nov 14 21:56:52 2019 +0000
+
+ upstream: remove debugging goop that snuck in to last commit
- with additional fix from Jakub Jelen to solve the backout.
- bz#2525 bz#2523 re-ok dtucker@
+ OpenBSD-Commit-ID: 8ea4455a2d9364a0a04f9e4a2cbfa4c9fcefe77e
+
+commit 63a5b24f2dbdc9a4bf2182ac3db26731ddc617e8
+Author: Damien Miller <djm@mindrot.org>
+Date: Fri Nov 15 11:21:26 2019 +1100
+
+ don't fatal if libfido2 not found
- Upstream-ID: a9d5bc0306f4473d9b4f4484f880e95f3c1cc031
+ spotted by dtucker@
-commit a287c5ad1e0bf9811c7b9221979b969255076019
+commit 129952a81c00c332721b4ba3ede868c720ad7f4e
+Author: Damien Miller <djm@mindrot.org>
+Date: Fri Nov 15 11:17:12 2019 +1100
+
+ correct object dependency
+
+commit 6bff9521ab9a9f7396d635755c342b72373bb4f9
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Feb 10 03:36:40 2017 +0000
+Date: Thu Nov 14 21:27:29 2019 +0000
- upstream commit
+ upstream: directly support U2F/FIDO2 security keys in OpenSSH by
- Sanitise escape sequences in key comments sent to printf
- but preserve valid UTF-8 when the locale supports it; bz#2520 ok dtucker@
+ linking against the (previously external) USB HID middleware. The dlopen()
+ capability still exists for alternate middlewares, e.g. for Bluetooth, NFC
+ and test/debugging.
- Upstream-ID: e8eed28712ba7b22d49be534237eed019875bd1e
+ OpenBSD-Commit-ID: 14446cf170ac0351f0d4792ba0bca53024930069
-commit e40269be388972848aafcca7060111c70aab5b87
-Author: millert@openbsd.org <millert@openbsd.org>
-Date: Wed Feb 8 20:32:43 2017 +0000
+commit 4f5e331cb8e11face3025aa6578662dde489c3ad
+Author: markus@openbsd.org <markus@openbsd.org>
+Date: Wed Nov 13 22:00:21 2019 +0000
- upstream commit
+ upstream: in order to be able to figure out the number of
- Avoid printf %s NULL. From semarie@, OK djm@
+ signatures left on a shielded key, we need to transfer the number of
+ signatures left from the private to the public key. ok djm@
- Upstream-ID: 06beef7344da0208efa9275d504d60d2a5b9266c
+ OpenBSD-Commit-ID: 8a5d0d260aeace47d372695fdae383ce9b962574
-commit 5b90709ab8704dafdb31e5651073b259d98352bc
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Mon Feb 6 09:22:51 2017 +0000
+commit dffd02e297e6c2a4e86775f293eb1b0ff01fb3df
+Author: markus@openbsd.org <markus@openbsd.org>
+Date: Wed Nov 13 20:25:45 2019 +0000
- upstream commit
+ upstream: fix check for sig_s; noted by qsa at qualys.com
- Restore \r\n newline sequence for server ident string. The CR
- got lost in the flensing of SSHv1. Pointed out by Stef Bon
+ OpenBSD-Commit-ID: 34198084e4afb424a859f52c04bb2c9668a52867
+
+commit fc173aeb1526d4268db89ec5dfebaf8750dd26cd
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Wed Nov 13 11:25:11 2019 +0000
+
+ upstream: When clients get denied by MaxStartups, send a
+
+ noification prior to the SSH2 protocol banner according to RFC4253 section
+ 4.2. ok djm@ deraadt@ markus@
- Upstream-ID: 5333fd43ce5396bf5999496096fac5536e678fac
+ OpenBSD-Commit-ID: e5dabcb722d54dea18eafb336d50b733af4f9c63
-commit 97c31c46ee2e6b46dfffdfc4f90bbbf188064cbc
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Feb 3 23:01:42 2017 +0000
+commit bf219920b70cafbf29ebc9890ef67d0efa54e738
+Author: markus@openbsd.org <markus@openbsd.org>
+Date: Wed Nov 13 07:53:10 2019 +0000
- upstream commit
+ upstream: fix shield/unshield for xmss keys: - in ssh-agent we need
- unit test for match_filter_list() function; still want a
- better name for this...
+ to delay the call to shield until we have received key specific options. -
+ when serializing xmss keys for shield we need to deal with all optional
+ components (e.g. state might not be loaded). ok djm@
- Upstream-Regress-ID: 840ad6118552c35111f0a897af9c8d93ab8de92a
+ OpenBSD-Commit-ID: cc2db82524b209468eb176d6b4d6b9486422f41f
-commit f1a193464a7b77646f0d0cedc929068e4a413ab4
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Feb 3 23:05:57 2017 +0000
+commit 40598b85d72a509566b7b2a6d57676c7231fed34
+Author: deraadt@openbsd.org <deraadt@openbsd.org>
+Date: Wed Nov 13 05:42:26 2019 +0000
- upstream commit
+ upstream: remove size_t gl_pathc < 0 test, it is invalid. the
- use ssh_packet_set_log_preamble() to include connection
- username in packet log messages, e.g.
+ return value from glob() is sufficient. discussed with djm
- Connection closed by invalid user foo 10.1.1.1 port 44056 [preauth]
+ OpenBSD-Commit-ID: c91203322db9caaf7efaf5ae90c794a91070be3c
+
+commit 72687c8e7c38736e3e64e833ee7aa8f9cd9efed1
+Author: deraadt@openbsd.org <deraadt@openbsd.org>
+Date: Wed Nov 13 04:47:52 2019 +0000
+
+ upstream: stdarg.h required more broadly; ok djm
- ok markus@ bz#113
+ OpenBSD-Commit-ID: b5b15674cde1b54d6dbbae8faf30d47e6e5d6513
+
+commit 1e0b248d47c96be944868a735553af8482300a07
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Thu Nov 14 16:08:17 2019 +1100
+
+ Put sshsk_sign call inside ifdef ENABLE_SK.
- Upstream-ID: 3591b88bdb5416d6066fb3d49d8fff2375bf1a15
+ Fixes build against OpenSSL configured without ECC.
-commit 07edd7e9537ab32aa52abb5fb2a915c350fcf441
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Feb 3 23:03:33 2017 +0000
+commit 546274a6f89489d2e6be8a8b62f2bb63c87a61fd
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Wed Nov 13 23:27:31 2019 +1100
- upstream commit
+ Remove duplicate __NR_clock_nanosleep
+
+commit b1c82f4b8adf3f42476d8a1f292df33fb7aa1a56
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Wed Nov 13 23:19:35 2019 +1100
+
+ seccomp: Allow clock_nanosleep() in sandbox.
- add ssh_packet_set_log_preamble() to allow inclusion of a
- preamble string in disconnect messages; ok markus@
+ seccomp: Allow clock_nanosleep() to make OpenSSH working with latest
+ glibc. Patch from Jakub Jelen <jjelen@redhat.com> via bz #3093.
+
+commit 2b523d23804c13cb68db135b919fcf312c42b580
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Wed Nov 13 11:56:56 2019 +1100
+
+ Include stdarg.h for va_list in xmalloc.h.
+
+commit 245dcbdca5374296bdb9c48be6e24bdf6b1c0af7
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Wed Nov 13 11:19:26 2019 +1100
+
+ Put headers inside ifdef _AIX.
- Upstream-ID: 34cb41182cd76d414c214ccb01c01707849afead
+ Prevents compile errors due to missing definitions (eg va_list) on
+ non-AIX platforms.
+
+commit a4cc579c6ad2b2e54bdd6cc0d5e12c2288113a56
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Wed Nov 13 10:41:41 2019 +1100
-commit 68bc8cfa7642d3ccbf2cd64281c16b8b9205be59
+ Fix comment in match_usergroup_pattern_list.
+
+ Spotted by balu.gajjala@gmail.com via bz#3092.
+
+commit fccff339cab5aa66f2554e0188b83f980683490b
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Feb 3 23:01:19 2017 +0000
+Date: Tue Nov 12 22:38:19 2019 +0000
- upstream commit
+ upstream: allow an empty attestation certificate returned by a
+
+ security key enrollment - these are possible for tokens that only offer self-
+ attestation. This also needs support from the middleware.
- support =- for removing methods from algorithms lists,
- e.g. Ciphers=-*cbc; suggested by Cristian Ionescu-Idbohrn in bz#2671 "I like
- it" markus@
+ ok markus@
- Upstream-ID: c78c38f9f81a963b33d0eade559f6048add24a6d
+ OpenBSD-Commit-ID: 135eeeb937088ef6830a25ca0bbe678dfd2c57cc
-commit c924b2ef941028a1f31e6e94f54dfeeeef462a4e
+commit e44bb61824e36d0d181a08489c16c378c486a974
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Feb 3 05:05:56 2017 +0000
+Date: Tue Nov 12 22:36:44 2019 +0000
- upstream commit
+ upstream: security keys typically need to be tapped/touched in
- allow form-feed characters at EOL; bz#2431 ok dtucker@
+ order to perform a signature operation. Notify the user when this is expected
+ via the TTY (if available) or $SSH_ASKPASS if we can.
+
+ ok markus@
- Upstream-ID: 1f453afaba6da2ae69d6afdf1ae79a917552f1a2
+ OpenBSD-Commit-ID: 0ef90a99a85d4a2a07217a58efb4df8444818609
-commit 523db8540b720c4d21ab0ff6f928476c70c38aab
-Author: Damien Miller <djm@mindrot.org>
-Date: Fri Feb 3 16:01:22 2017 +1100
+commit 4671211068441519011ac0e38c588317f4157ba1
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Tue Nov 12 22:35:02 2019 +0000
- prefer to use ldns-config to find libldns
+ upstream: pass SSH_ASKPASS_PROMPT hint to y/n key confirm too
- Should fix bz#2603 - "Build with ldns and without kerberos support
- fails if ldns compiled with kerberos support" by including correct
- cflags/libs
+ OpenBSD-Commit-ID: 08d46712e5e5f1bad0aea68e7717b7bec1ab8959
+
+commit 5d1c1590d736694f41b03e686045f08fcae20d62
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Tue Nov 12 22:34:20 2019 +0000
+
+ upstream: dd API for performing one-shot notifications via tty or
- ok dtucker@
+ SSH_ASKPASS
+
+ OpenBSD-Commit-ID: 9484aea33aff5b62ce3642bf259546c7639f23f3
-commit c998bf0afa1a01257a53793eba57941182e9e0b7
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Fri Feb 3 02:56:00 2017 +0000
+commit 166927fd410823eec8a7b2472463db51e0e6fef5
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Tue Nov 12 22:32:48 2019 +0000
- upstream commit
+ upstream: add xvasprintf()
- Make ssh_packet_set_rekey_limits take u32 for the number of
- seconds until rekeying (negative values are rejected at config parse time).
- This allows the removal of some casts and a signed vs unsigned comparison
- warning.
+ OpenBSD-Commit-ID: e5e3671c05c121993b034db935bce1a7aa372247
+
+commit 782093ec6cf64cc6c4078410093359869ea9329f
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Wed Nov 13 09:08:55 2019 +1100
+
+ Remove leftover if statement from sync.
+
+commit b556cc3cbf0c43f073bb41bba4e92ca709a1ec13
+Author: markus@openbsd.org <markus@openbsd.org>
+Date: Tue Nov 12 19:34:40 2019 +0000
+
+ upstream: remove extra layer for ed25519 signature; ok djm@
- rekey_time is cast to int64 for the comparison which is a no-op
- on OpenBSD, but should also do the right thing in -portable on
- anything still using 32bit time_t (until the system time actually
- wraps, anyway).
+ OpenBSD-Commit-ID: 7672d9d0278b4bf656a12d3aab0c0bfe92a8ae47
+
+commit 3fcf69ace19e75cf9dcd7206f396adfcb29611a8
+Author: markus@openbsd.org <markus@openbsd.org>
+Date: Tue Nov 12 19:34:00 2019 +0000
+
+ upstream: check sig_r and sig_s for ssh-sk keys; ok djm
- some early guidance deraadt@, ok djm@
+ OpenBSD-Commit-ID: 1a1e6a85b5f465d447a3800f739e35c5b74e0abc
+
+commit 2c55744a56de0ffc81fe445a1e7fc5cd308712b3
+Author: markus@openbsd.org <markus@openbsd.org>
+Date: Tue Nov 12 19:33:08 2019 +0000
+
+ upstream: enable ed25519 support; ok djm
- Upstream-ID: c9f18613afb994a07e7622eb326f49de3d123b6c
+ OpenBSD-Commit-ID: 1a399c5b3ef15bd8efb916110cf5a9e0b554ab7e
-commit 3ec5fa4ba97d4c4853620daea26a33b9f1fe3422
-Author: jsg@openbsd.org <jsg@openbsd.org>
-Date: Thu Feb 2 10:54:25 2017 +0000
+commit fd1a3b5e38721b1d69aae2d9de1a1d9155dfa5c7
+Author: markus@openbsd.org <markus@openbsd.org>
+Date: Tue Nov 12 19:32:30 2019 +0000
- upstream commit
+ upstream: update sk-api to version 2 for ed25519 support; ok djm
- In vasnmprintf() return an error if malloc fails and
- don't set a function argument to the address of free'd memory.
+ OpenBSD-Commit-ID: 77aa4d5b6ab17987d8a600907b49573940a0044a
+
+commit 7c32b51edbed5bd57870249c0a45dffd06be0002
+Author: markus@openbsd.org <markus@openbsd.org>
+Date: Tue Nov 12 19:31:45 2019 +0000
+
+ upstream: implement sshsk_ed25519_assemble(); ok djm
- ok djm@
+ OpenBSD-Commit-ID: af9ec838b9bc643786310b5caefc4ca4754e68c6
+
+commit fe05a36dc0ea884c8c2395d53d804fe4f4202b26
+Author: markus@openbsd.org <markus@openbsd.org>
+Date: Tue Nov 12 19:31:18 2019 +0000
+
+ upstream: implement sshsk_ed25519_inner_sig(); ok djm
- Upstream-ID: 1efffffff2f51d53c9141f245b90ac23d33b9779
+ OpenBSD-Commit-ID: f422d0052c6d948fe0e4b04bc961f37fdffa0910
-commit 858252fb1d451ebb0969cf9749116c8f0ee42753
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Wed Feb 1 02:59:09 2017 +0000
+commit e03a29e6554cd0c9cdbac0dae53dd79e6eb4ea47
+Author: markus@openbsd.org <markus@openbsd.org>
+Date: Tue Nov 12 19:30:50 2019 +0000
- upstream commit
+ upstream: rename sshsk_ecdsa_sign() to sshsk_sign(); ok djm
- Return true reason for port forwarding failures where
- feasible rather than always "administratively prohibited". bz#2674, ok djm@
+ OpenBSD-Commit-ID: 1524042e09d81e54c4470d7bfcc0194c5b46fe19
+
+commit bc7b5d6187de625c086b5f639b25bbad17bbabfc
+Author: markus@openbsd.org <markus@openbsd.org>
+Date: Tue Nov 12 19:30:21 2019 +0000
+
+ upstream: factor out sshsk_ecdsa_inner_sig(); ok djm@
- Upstream-ID: d901d9887951774e604ca970e1827afaaef9e419
+ OpenBSD-Commit-ID: 07e41997b542f670a15d7e2807143fe01efef584
-commit 6ba9f893838489add6ec4213c7a997b425e4a9e0
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Mon Jan 30 23:27:39 2017 +0000
+commit cef84a062db8cfeece26f067235dc440f6992c17
+Author: markus@openbsd.org <markus@openbsd.org>
+Date: Tue Nov 12 19:29:54 2019 +0000
- upstream commit
+ upstream: factor out sshsk_ecdsa_assemble(); ok djm@
- Small correction to the known_hosts section on when it is
- updated. Patch from lkppo at free.fr some time ago, pointed out by smallm at
- sdf.org
+ OpenBSD-Commit-ID: 2313761a3a84ccfe032874d638d3c363e0f14026
+
+commit 7c096c456f33f3d2682736d4735cc10e790276e9
+Author: markus@openbsd.org <markus@openbsd.org>
+Date: Tue Nov 12 19:29:24 2019 +0000
+
+ upstream: implement ssh-ed25519-sk verification; ok djm@
- Upstream-ID: 1834d7af179dea1a12ad2137f84566664af225d5
+ OpenBSD-Commit-ID: 37906d93948a1e3d237c20e713d6ca8fbf7d13f6
+
+commit ba5fb02bed1e556d0ce7b1740ae8a5f87b737491
+Author: Damien Miller <djm@mindrot.org>
+Date: Wed Nov 13 08:48:30 2019 +1100
-commit c61d5ec3c11e7ff9779b6127421d9f166cf10915
-Author: Darren Tucker <dtucker@zip.com.au>
-Date: Fri Feb 3 14:10:34 2017 +1100
+ ignore ssh-sk-helper
- Remove _XOPEN_SOURCE from wide char detection.
+commit 78c96498947f711141f493a40d202c482cc59438
+Author: deraadt@openbsd.org <deraadt@openbsd.org>
+Date: Mon Nov 11 19:53:37 2019 +0000
+
+ upstream: skip demanding -fstack-protector-all on hppa. we never
- Having _XOPEN_SOURCE unconditionally causes problems on some platforms
- and configurations, notably Solaris 64-bit binaries. It was there for
- the benefit of Linux put the required bits in the *-*linux* section.
+ wrote a stack protector for reverse-stack architectures, and i don't think
+ anyone else did either. a warning per compiled file is just annoying.
- Patch from yvoinov at gmail.com.
+ OpenBSD-Commit-ID: 14806a59353152f843eb349e618abbf6f4dd3ada
-commit f25ee13b3e81fd80efeb871dc150fe49d7fc8afd
+commit aa1c9e37789f999979fe59df74ce5c8424861ac8
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Mon Jan 30 05:22:14 2017 +0000
+Date: Fri Nov 8 03:54:02 2019 +0000
- upstream commit
+ upstream: duplicate 'x' character in getopt(3) optstring
+
+ OpenBSD-Commit-ID: 64c81caa0cb5798de3621eca16b7dd22e5d0d8a7
+
+commit aa4c640dc362816d63584a16e786d5e314e24390
+Author: naddy@openbsd.org <naddy@openbsd.org>
+Date: Thu Nov 7 08:38:38 2019 +0000
+
+ upstream: Fill in missing man page bits for U2F security key support:
+
+ Mention the new key types, the ~/.ssh/id_ecdsa_sk file, ssh's
+ SecurityKeyProvider keyword, the SSH_SK_PROVIDER environment variable,
+ and ssh-keygen's new -w and -x options.
- fully unbreak: some $SSH invocations did not have -F
- specified and could pick up the ~/.ssh/config of the user running the tests
+ Copy the ssh-sk-helper man page from ssh-pkcs11-helper with minimal
+ substitutions.
- Upstream-Regress-ID: f362d1892c0d3e66212d5d3fc02d915c58ef6b89
+ ok djm@
+
+ OpenBSD-Commit-ID: ef2e8f83d0c0ce11ad9b8c28945747e5ca337ac4
-commit 6956e21fb26652887475fe77ea40d2efcf25908b
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Mon Jan 30 04:54:07 2017 +0000
+commit b236b27d6dada7f0542214003632b4e9b7aa1380
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Sun Nov 3 00:10:43 2019 +1100
- upstream commit
+ Put sftp-realpath in libssh.a
- partially unbreak: was not specifying hostname on some
- $SSH invocations
+ and remove it from the specific binary targets.
+
+commit 382c18c20cdcec45b5d21ff25b4a5e0df91a68c4
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Sun Nov 3 00:09:21 2019 +1100
+
+ statfs might be defined in sys/mount.h.
- Upstream-Regress-ID: bc8a5e98e57bad0a92ef4f34ed91c1d18294e2cc
+ eg on old NetBSDs.
-commit 52763dd3fe0a4678dafdf7aeb32286e514130afc
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Mon Jan 30 01:03:00 2017 +0000
+commit 03ffc0951c305c8e3b5fdc260d65312a57f8f7ea
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Sat Nov 2 23:25:01 2019 +1100
- upstream commit
+ Put stdint.h inside ifdef HAVE_STDINT_H.
+
+commit 19cb64c4b42d4312ce12091fd9436dbd6898998c
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Sat Nov 2 22:45:44 2019 +1100
+
+ Rebuild .depend.
+
+commit 3611bfe89b92ada5914526d8ff0919aeb967cfa7
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Sat Nov 2 22:42:05 2019 +1100
+
+ Define __BSD_VISIBLE in fnmatch.h.
- revise keys/principals command hang fix (bz#2655) to
- consume entire output, avoiding sending SIGPIPE to subprocesses early; ok
- dtucker@
+ .. since we use symbols defined only when it is when using the compat
+ fnmatch.
+
+commit f5cc5816aaddb8eca3cba193f53e99d6a0b37d05
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Sat Nov 2 16:39:38 2019 +1100
+
+ Only enable U2F if OpenSSL supports ECC.
- Upstream-ID: 7cb04b31a61f8c78c4e48ceededcd2fd5c4ee1bc
+ This requires moving the U2F bits to below the OpenSSL parts so we have
+ the required information. ok djm@
-commit 381a2615a154a82c4c53b787f4a564ef894fe9ac
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Mon Jan 30 00:38:50 2017 +0000
+commit ad38406fc95fa223b0ef2edf8ff50508f8ab1cb6
+Author: naddy@openbsd.org <naddy@openbsd.org>
+Date: Fri Nov 1 12:10:43 2019 +0000
- upstream commit
+ upstream: fix miscellaneous text problems; ok djm@
- small cleanup post SSHv1 removal:
+ OpenBSD-Commit-ID: 0cbf411a14d8fa0b269b69cbb1b4fc0ca699fe9f
+
+commit 9cac151c2dc76b8e5b727b2fa216f572e372170f
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Fri Nov 1 18:26:07 2019 +1100
+
+ Add flags needed to build and work on Ultrix.
+
+commit 0e3c5bc50907d2058407641b5a3581b7eda91b7e
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Fri Nov 1 18:24:29 2019 +1100
+
+ Hook up fnmatch for platforms that don't have it.
+
+commit b56dbfd9d967e5b6ce7be9f81f206112e19e1030
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Fri Nov 1 18:17:42 2019 +1100
+
+ Add missing bracket in realpath macro.
+
+commit 59ccb56f15e5e530e7c1b5a0b361749d8c6217d5
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Fri Nov 1 17:32:47 2019 +1100
+
+ Import fnmatch.c from OpenBSD.
+
+commit 79d46de9fbea0f3c0e8ae7cf84effaba089071b0
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Fri Nov 1 15:22:32 2019 +1100
+
+ Use sftp_realpath if no native realpath.
+
+commit bb4f003ed8c5f61ec74a66bcedc8ab19bf5b35c4
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Fri Nov 1 15:06:16 2019 +1100
+
+ Configure flags for haiku from haikuports.
- remove SSHv1-isms in commented examples
+ Should build with the default flags with ./configure
+
+commit 4332b4fe49360679647a8705bc08f4e81323f6b4
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Fri Nov 1 03:54:33 2019 +0000
+
+ upstream: fix a race condition in the SIGCHILD handler that could turn
- reorder token table to group deprecated and compile-time conditional tokens
- better
+ in to a kill(-1); bz3084, reported by Gao Rui, ok dtucker@
- fix config dumping code for some compile-time conditional options that
- weren't being correctly skipped (SSHv1 and PKCS#11)
+ OpenBSD-Commit-ID: ac2742e04a69d4c34223505b6a32f6d686e18896
+
+commit 03f9205f0fb49ea2507eacc143737a8511ae5a4e
+Author: Damien Miller <djm@mindrot.org>
+Date: Fri Nov 1 14:49:25 2019 +1100
+
+ conditionalise SK sign/verify on ENABLE_SK
- Upstream-ID: f2e96b3cb3158d857c5a91ad2e15925df3060105
+ Spotted by Darren and his faux-Vax
+
+commit 5eb7b9563ff818e17de24231bf2d347d9db302c5
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Fri Nov 1 14:41:07 2019 +1100
+
+ Add prototype for localtime_r if needed.
+
+commit d500b59a825f6a58f2abf7b04eb1992d81e45d58
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Fri Nov 1 13:42:12 2019 +1100
-commit 4833d01591b7eb049489d9558b65f5553387ed43
+ Check if IP_TOS is defined before using.
+
+commit 764d51e04460ec0da12e05e4777bc90c116accb9
+Author: Damien Miller <djm@mindrot.org>
+Date: Fri Nov 1 13:34:49 2019 +1100
+
+ autoconf pieces for U2F support
+
+ Mostly following existing logic for PKCS#11 - turning off support
+ when either libcrypto or dlopen(3) are unavailable.
+
+commit 45f17a159acfc5a8e450bfbcc2cffe72950ed7a3
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Mon Jan 30 00:34:01 2017 +0000
+Date: Fri Nov 1 02:32:05 2019 +0000
- upstream commit
+ upstream: remove duplicate PUBKEY_DEFAULT_PK_ALG on !WITH_OPENSSL path
- some explicit NULL tests when dumping configured
- forwardings; from Karsten Weiss
+ OpenBSD-Commit-ID: 95a7cafad2a4665d57cabacc28031fabc0bea9fc
+
+commit db8d13f7925da7337df87248995c533e111637ec
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Fri Nov 1 02:06:52 2019 +0000
+
+ upstream: more additional source files
- Upstream-ID: 40957b8dea69672b0e50df6b4a91a94e3e37f72d
+ OpenBSD-Regress-ID: 8eaa25fb901594aee23b76eda99dca5b8db94c6f
-commit 326e2fae9f2e3e067b5651365eba86b35ee5a6b2
+commit f89c5df65dd307739ff22319c2cf847d3b0c5ab4
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Mon Jan 30 00:32:28 2017 +0000
+Date: Fri Nov 1 02:04:25 2019 +0000
- upstream commit
+ upstream: additional source files here too
- misplaced braces in test; from Karsten Weiss
+ OpenBSD-Regress-ID: 8809f8e1c8f7459e7096ab6b58d8e56cb2f483fd
+
+commit 02275afa1ecbfbd39f27d34c97090e76bec232ec
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Fri Nov 1 02:03:27 2019 +0000
+
+ upstream: additional source files here too
- Upstream-ID: f7b794074d3aae8e35b69a91d211c599c94afaae
+ OpenBSD-Regress-ID: 09297e484327f911fd353489518cceaa0c1b95ce
-commit 3e032a95e46bfaea9f9e857678ac8fa5f63997fb
+commit dfc8f01b9886c7999e6e20acf3f7492cb8c80796
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Mon Jan 30 00:32:03 2017 +0000
+Date: Fri Nov 1 01:57:59 2019 +0000
- upstream commit
+ upstream: adapt to extra sshkey_sign() argument and additional
- don't dereference authctxt before testing != NULL, it
- causes compilers to make assumptions; from Karsten Weiss
+ dependencies
- Upstream-ID: 794243aad1e976ebc717885b7a97a25e00c031b2
+ OpenBSD-Regress-ID: 7a25604968486c4d6f81d06e8fbc7d17519de50e
-commit 01cfaa2b1cfb84f3cdd32d1bf82b120a8d30e057
+commit afa59e26eeb44a93f36f043f60b936eaddae77c4
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Jan 6 02:51:16 2017 +0000
+Date: Fri Nov 1 01:55:41 2019 +0000
- upstream commit
+ upstream: skip security-key key types for tests until we have a
- use correct ssh-add program; bz#2654, from Colin Watson
+ dummy U2F middleware to use.
- Upstream-Regress-ID: 7042a36e1bdaec6562f6e57e9d047efe9c7a6030
+ OpenBSD-Regress-ID: 37200462b44334a4ad45e6a1f7ad1bd717521a95
-commit e5c7ec67cdc42ae2584085e0fc5cc5ee91133cf5
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Fri Jan 6 02:26:10 2017 +0000
+commit de871e4daf346a712c78fa4ab8f18b231a47cb85
+Author: jmc@openbsd.org <jmc@openbsd.org>
+Date: Fri Nov 1 00:52:35 2019 +0000
- upstream commit
+ upstream: sort;
- Account for timeouts in the integrity tests as failures.
+ OpenBSD-Commit-ID: 8264b0be01ec5a60602bd50fd49cc3c81162ea16
+
+commit 2aae149a34b1b5dfbef423d3b7999a96818969bb
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Thu Oct 31 21:37:33 2019 +0000
+
+ upstream: undo debugging bits that shouldn't have been committed
- If the first test in a series for a given MAC happens to modify the low
- bytes of a packet length, then ssh will time out and this will be
- interpreted as a test failure. Patch from cjwatson at debian.org via
- bz#2658.
+ OpenBSD-Commit-ID: 4bd5551b306df55379afe17d841207990eb773bf
+
+commit 3420e0464bd0e8fedcfa5fd20ad37bdc740ad5b4
+Author: Damien Miller <djm@mindrot.org>
+Date: Fri Nov 1 09:24:58 2019 +1100
+
+ depend
+
+commit b923a90abc7bccb11a513dc8b5c0f13a0ea9682c
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Thu Oct 31 21:28:27 2019 +0000
+
+ upstream: fix -Wshadow warning
- Upstream-Regress-ID: e7467613b0badedaa300bc6fc7495ec2f44e2fb9
+ OpenBSD-Commit-ID: 3441eb04f872a00c2483c11a5f1570dfe775103c
-commit dbaf599b61bd6e0f8469363a8c8e7f633b334018
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Fri Jan 6 02:09:25 2017 +0000
+commit 9a14c64c38fc14d0029f1c7bc70cf62cc7f0fdf9
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Thu Oct 31 21:23:19 2019 +0000
- upstream commit
+ upstream: Refactor signing - use sshkey_sign for everything,
+
+ including the new U2F signatures.
- Make forwarding test less racy by using unix domain
- sockets instead of TCP ports where possible. Patch from cjwatson at
- debian.org via bz#2659.
+ Don't use sshsk_ecdsa_sign() directly, instead make it reachable via
+ sshkey_sign() like all other signature operations. This means that
+ we need to add a provider argument to sshkey_sign(), so most of this
+ change is mechanically adding that.
- Upstream-Regress-ID: 4756375aac5916ef9d25452a1c1d5fa9e90299a9
+ Suggested by / ok markus@
+
+ OpenBSD-Commit-ID: d5193a03fcfa895085d91b2b83d984a9fde76c8c
-commit 9390b0031ebd6eb5488d3bc4d4333c528dffc0a6
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Sun Jan 29 21:35:23 2017 +0000
+commit 07da39f71d36fb547749a5b16aa8892e621a7e4a
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Thu Oct 31 21:22:01 2019 +0000
- upstream commit
+ upstream: ssh-agent support for U2F/FIDO keys
- Fix typo in ~C error message for bad port forward
- cancellation. bz#2672, from Brad Marshall via Colin Watson and Ubuntu's
- bugtracker.
+ feedback & ok markus@
- Upstream-ID: 0d4a7e5ead6cc59c9a44b4c1e5435ab3aada09af
+ OpenBSD-Commit-ID: bb544a44bc32e45d2ec8bf652db2046f38360acb
-commit 4ba15462ca38883b8a61a1eccc093c79462d5414
-Author: guenther@openbsd.org <guenther@openbsd.org>
-Date: Sat Jan 21 11:32:04 2017 +0000
+commit eebec620c9519c4839d781c4d5b6082152998f82
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Thu Oct 31 21:20:38 2019 +0000
- upstream commit
+ upstream: ssh AddKeysToAgent support for U2F/FIDO keys
- The POSIX APIs that that sockaddrs all ignore the s*_len
- field in the incoming socket, so userspace doesn't need to set it unless it
- has its own reasons for tracking the size along with the sockaddr.
+ feedback & ok markus@
- ok phessler@ deraadt@ florian@
+ OpenBSD-Commit-ID: ac08e45c7f995fa71f8d661b3f582e38cc0a2f91
+
+commit 486164d060314a7f8bca2a00f53be9e900c5e74d
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Thu Oct 31 21:19:56 2019 +0000
+
+ upstream: ssh-add support for U2F/FIDO keys
- Upstream-ID: ca6e49e2f22f2b9e81d6d924b90ecd7e422e7437
+ OpenBSD-Commit-ID: 7f88a5181c982687afedf3130c6ab2bba60f7644
-commit a1187bd3ef3e4940af849ca953a1b849dae78445
-Author: jmc@openbsd.org <jmc@openbsd.org>
-Date: Fri Jan 6 16:28:12 2017 +0000
+commit b9dd14d3091e31fb836f69873d3aa622eb7b4a1c
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Thu Oct 31 21:19:14 2019 +0000
- upstream commit
+ upstream: add new agent key constraint for U2F/FIDO provider
- keep the tokens list sorted;
+ feedback & ok markus@
- Upstream-ID: b96239dae4fb3aa94146bb381afabcc7740a1638
+ OpenBSD-Commit-ID: d880c380170704280b4003860a1744d286c7a172
-commit b64077f9767634715402014f509e58decf1e140d
+commit 884416bdb10468f1252e4d7c13d51b43dccba7f6
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Jan 6 09:27:52 2017 +0000
+Date: Thu Oct 31 21:18:28 2019 +0000
- upstream commit
-
- fix previous
+ upstream: ssh client support for U2F/FIDO keys
- Upstream-ID: c107d6a69bc22325d79fbf78a2a62e04bcac6895
+ OpenBSD-Commit-ID: eb2cfa6cf7419a1895e06e398ea6d41516c5b0bc
-commit 5e820e9ea2e949aeb93071fe31c80b0c42f2b2de
+commit 01a0670f69c5b86e471e033b92145d6c7cc77c58
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Jan 6 03:53:58 2017 +0000
+Date: Thu Oct 31 21:17:49 2019 +0000
- upstream commit
+ upstream: Separate myproposal.h userauth pubkey types
+
+ U2F/FIDO keys are not supported for host authentication, so we need
+ a separate list for user keys.
- show a useful error message when included config files
- can't be opened; bz#2653, ok dtucker@
+ feedback & ok markus@
- Upstream-ID: f598b73b5dfe497344cec9efc9386b4e5a3cb95b
+ OpenBSD-Commit-ID: 7fe2e6ab85f9f2338866e5af8ca2d312abbf0429
-commit 13bd2e2d622d01dc85d22b94520a5b243d006049
+commit 23f38c2d8cda3fad24e214e1f0133c42435b54ee
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Jan 6 03:45:41 2017 +0000
+Date: Thu Oct 31 21:17:09 2019 +0000
- upstream commit
-
- sshd_config is documented to set
- GSSAPIStrictAcceptorCheck=yes by default, so actually make it do this.
- bz#2637 ok dtucker
+ upstream: ssh-keygen support for generating U2F/FIDO keys
- Upstream-ID: 99ef8ac51f17f0f7aec166cb2e34228d4d72a665
+ OpenBSD-Commit-ID: 6ce04f2b497ac9dd8c327f76f1e6c724fb1d1b37
-commit f89b928534c9e77f608806a217d39a2960cc7fd0
+commit ed3467c1e16b7396ff7fcf12d2769261512935ec
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Jan 6 03:41:58 2017 +0000
+Date: Thu Oct 31 21:16:20 2019 +0000
- upstream commit
+ upstream: U2F/FIDO middleware interface
- Avoid confusing error message when attempting to use
- ssh-keyscan built without SSH protocol v.1 to scan for v.1 keys; bz#2583
+ Supports enrolling (generating) keys and signatures.
- Upstream-ID: 5d214abd3a21337d67c6dcc5aa6f313298d0d165
+ feedback & ok markus@
+
+ OpenBSD-Commit-ID: 73d1dd5939454f9c7bd840f48236cba41e8ad592
-commit 0999533014784579aa6f01c2d3a06e3e8804b680
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Fri Jan 6 02:34:54 2017 +0000
+commit 02bb0768a937e50bbb236efc2bbdddb1991b1c85
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Thu Oct 31 21:15:14 2019 +0000
- upstream commit
+ upstream: Initial infrastructure for U2F/FIDO support
- Re-add '%k' token for AuthorizedKeysCommand which was
- lost during the re-org in rev 1.235. bz#2656, from jboning at gmail.com.
+ Key library support: including allocation, marshalling public/private
+ keys and certificates, signature validation.
- Upstream-ID: 2884e203c02764d7b3fe7472710d9c24bdc73e38
+ feedback & ok markus@
+
+ OpenBSD-Commit-ID: a17615ba15e0f7932ac4360cb18fc9a9544e68c7
-commit 51045869fa084cdd016fdd721ea760417c0a3bf3
+commit 57ecc10628b04c384cbba2fbc87d38b74cd1199d
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Wed Jan 4 05:37:40 2017 +0000
+Date: Thu Oct 31 21:14:17 2019 +0000
- upstream commit
+ upstream: Protocol documentation for U2F/FIDO keys in OpenSSH
+
+ OpenBSD-Commit-ID: 8f3247317c2909870593aeb306dff848bc427915
+
+commit f4fdcd2b7a2bbf5d8770d44565173ca5158d4dcb
+Author: Damien Miller <djm@mindrot.org>
+Date: Fri Nov 1 08:36:16 2019 +1100
+
+ Missing unit test files
+
+commit 1bcd1169c5221688418fa38606e9c69055b72451
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Tue Oct 29 19:45:03 2019 +1100
+
+ Add implementation of localtime_r.
+
+commit 2046ed16c1202431b0307674c33a123a113e8297
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Tue Oct 29 07:47:27 2019 +0000
+
+ upstream: Signal handler cleanup: remove leftover support for
- unbreak Unix domain socket forwarding for root; ok
+ unreliable signals and now-unneeded save and restore of errno. ok deraadt@
markus@
- Upstream-ID: 6649c76eb7a3fa15409373295ca71badf56920a2
+ OpenBSD-Commit-ID: 01dd8a1ebdd991c8629ba1f5237283341a93cd88
-commit 58fca12ba967ea5c768653535604e1522d177e44
-Author: Darren Tucker <dtucker@zip.com.au>
-Date: Mon Jan 16 09:08:32 2017 +1100
+commit 70fc9a6ca4dd33cb2dd400a4dad5db9683a3d284
+Author: jmc@openbsd.org <jmc@openbsd.org>
+Date: Tue Oct 22 08:50:35 2019 +0000
- Remove LOGIN_PROGRAM.
+ upstream: fixes from lucas;
- UseLogin is gone, remove leftover. bz#2665, from cjwatson at debian.org
+ OpenBSD-Commit-ID: 4c4bfd2806c5bbc753788ffe19c5ee13aaf418b2
-commit b108ce92aae0ca0376dce9513d953be60e449ae1
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Wed Jan 4 02:21:43 2017 +0000
+commit 702368aa4381c3b482368257ac574a87b5a80938
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Tue Oct 22 07:06:35 2019 +0000
- upstream commit
-
- relax PKCS#11 whitelist a bit to allow libexec as well as
- lib directories.
+ upstream: Import regenerated moduli file.
- Upstream-ID: cf5617958e2e2d39f8285fd3bc63b557da484702
+ OpenBSD-Commit-ID: 58ec755be4e51978ecfee73539090eb68652a987
-commit c7995f296b9222df2846f56ecf61e5ae13d7a53d
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Tue Jan 3 05:46:51 2017 +0000
+commit 5fe81da22652f8caa63e9e3a1af519a85d36337e
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Mon Oct 28 21:19:47 2019 +1100
- upstream commit
+ Fix ifdefs to not mask needed bits.
+
+commit 7694e9d2fb5785bbdd0920dce7a160bd79feaf00
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Mon Oct 28 17:05:36 2019 +1100
+
+ Only use RLIMIT_NOFILE if it's defined.
+
+commit d561b0b2fa2531b4cc3bc70a7d657c6485c9fd0b
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Mon Oct 28 16:09:04 2019 +1100
+
+ Make sure we have struct statfs before using.
+
+commit 2912596aecfcf48e5115c7a906d1e664f7717a4b
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Mon Oct 28 16:06:59 2019 +1100
+
+ Define UINT32_MAX if needed.
+
+commit 7169e31121e8c8cc729b55154deb722ae495b316
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Mon Oct 28 16:00:45 2019 +1100
+
+ Move utimensat definition into timespec section.
- check number of entries in SSH2_FXP_NAME response; avoids
- unreachable overflow later. Reported by Jann Horn
+ Since utimensat uses struct timespec, move it to the section where we
+ define struct timespec when needed.
+
+commit 850ec1773d656cbff44d78a79e369dc262ce5853
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Mon Oct 28 15:57:22 2019 +1100
+
+ Wrap OpenSSL bits in WITH_OPENSSL.
+
+commit 6fc7e1c6fec3ba589869ae98e968c0e5e2e4695b
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Mon Oct 28 15:53:25 2019 +1100
+
+ Wrap poll.h includes in HAVE_POLL_H.
+
+commit 9239a18f96905cc1a353e861e33af093652f24e7
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Thu Oct 24 14:39:49 2019 +1100
+
+ Add a function call stackprotector tests.
- Upstream-ID: b6b2b434a6d6035b1644ca44f24cd8104057420f
+ Including a function call in the test programs for the gcc stack
+ protector flag tests exercises more of the compiler and makes it more
+ likely it'll detect problems.
+
+commit b9705393be4612fd5e29d0cd8e7cf2b66ed19eb7
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Tue Oct 22 18:09:22 2019 +1100
-commit ddd3d34e5c7979ca6f4a3a98a7d219a4ed3d98c2
+ Import regenerated moduli file.
+
+commit 76ed2199491397e0f9902ade80d5271e4a9b2630
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Dec 30 22:08:02 2016 +0000
+Date: Wed Oct 16 06:05:39 2019 +0000
- upstream commit
+ upstream: potential NULL dereference for revoked hostkeys; reported
- fix deadlock when keys/principals command produces a lot of
- output and a key is matched early; bz#2655, patch from jboning AT gmail.com
+ by krishnaiah bommu
- Upstream-ID: e19456429bf99087ea994432c16d00a642060afe
+ OpenBSD-Commit-ID: 35ff685e7cc9dd2e3fe2e3dfcdcb9bc5c79f6506
-commit 30eee7d1b2fec33c14870cc11910610be5d2aa6f
-Author: Darren Tucker <dtucker@zip.com.au>
-Date: Tue Dec 20 12:16:11 2016 +1100
+commit 6500c3bc71bf4fe14972c1177e6b93f1164d07a4
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Wed Oct 16 06:03:30 2019 +0000
- Re-add missing "Prerequisites" header and fix typo
+ upstream: free buf before return; reported by krishnaiah bommu
- Patch from HARUYAMA Seigo <haruyama at unixuser org>.
+ OpenBSD-Commit-ID: 091bb23a6e913af5d4f72c50030b53ce1cef4de1
-commit c8c60f3663165edd6a52632c6ddbfabfce1ca865
+commit d7d116b6d9e6cb79cc235e9801caa683d3db3181
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Mon Dec 19 22:35:23 2016 +0000
+Date: Mon Oct 14 06:00:02 2019 +0000
- upstream commit
+ upstream: memleak in error path; spotted by oss-fuzz, ok markus@
- use standard /bin/sh equality test; from Mike Frysinger
+ OpenBSD-Commit-ID: d6ed260cbbc297ab157ad63931802fb1ef7a4266
+
+commit 9b9e3ca6945351eefb821ff783a4a8e6d9b98b9a
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Fri Oct 11 14:12:16 2019 +1100
+
+ Re-add SA_RESTART to mysignal.
+
+ This makes mysignal implement reliable BSD semantics according to
+ Stevens' APUE. This was first attempted in 2001 but was reverted
+ due to problems with HP-UX 10.20 and select() and possibly grantpt().
+ Modern systems should be fine with it, but if any current platforms have
+ a problem with it now we can disable it just for those. ok djm@
+
+commit 0bd312a362168c1eae3cd6b3889395a78e6fd0f8
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Thu Oct 10 09:42:03 2019 +1100
+
+ Fix ifdef typo for declaration of memmem.
- Upstream-Regress-ID: 7b6f0b63525f399844c8ac211003acb8e4b0bec2
+ Fixes build on IRIX. bz#3081.
+
+commit 01ce1cd402d5eecde2bba35b67e08f5b266b37fd
+Author: Abhishek Arya <inferno@chromium.org>
+Date: Tue Oct 8 20:19:18 2019 -0700
+
+ Update README.md
+
+commit 1ba130ac8fb2884307f658126f04578f8aef409e
+Author: Damien Miller <djm@mindrot.org>
+Date: Wed Oct 9 13:49:35 2019 +1100
+
+ add a fuzzer for private key parsing
-commit 4a354fc231174901f2629437c2a6e924a2dd6772
+commit cdf1d0a9f5d18535e0a18ff34860e81a6d83aa5c
Author: Damien Miller <djm@mindrot.org>
-Date: Mon Dec 19 15:59:26 2016 +1100
+Date: Wed Oct 9 11:31:03 2019 +1100
- crank version numbers for release
+ prepare for 8.1 release
-commit 5f8d0bb8413d4d909cc7aa3c616fb0538224c3c9
+commit 3b4e56d740b74324e2d7542957cad5a11518f455
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Mon Dec 19 04:55:51 2016 +0000
+Date: Wed Oct 9 00:04:57 2019 +0000
- upstream commit
+ upstream: openssh-8.1
- openssh-7.4
+ OpenBSD-Commit-ID: 3356bb34e2aa287f0e6d6773c9ae659dc680147d
+
+commit 29e0ecd9b4eb3b9f305e2240351f0c59cad9ef81
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Wed Oct 9 00:04:42 2019 +0000
+
+ upstream: fix an unreachable integer overflow similar to the XMSS
+
+ case, and some other NULL dereferences found by fuzzing.
+
+ fix with and ok markus@
- Upstream-ID: 1ee404adba6bbe10ae9277cbae3a94abe2867b79
+ OpenBSD-Commit-ID: 0f81adbb95ef887ce586953e1cb225fa45c7a47b
-commit 3a8213ea0ed843523e34e55ab9c852332bab4c7b
+commit a546b17bbaeb12beac4c9aeed56f74a42b18a93a
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Mon Dec 19 04:55:18 2016 +0000
+Date: Wed Oct 9 00:02:57 2019 +0000
- upstream commit
+ upstream: fix integer overflow in XMSS private key parsing.
+
+ Reported by Adam Zabrocki via SecuriTeam's SSH program.
+
+ Note that this code is experimental and not compiled by default.
- remove testcase that depends on exact output and
- behaviour of snprintf(..., "%s", NULL)
+ ok markus@
- Upstream-Regress-ID: cab4288531766bd9593cb556613b91a2eeefb56f
+ OpenBSD-Commit-ID: cd0361896d15e8a1bac495ac583ff065ffca2be1
-commit eae735a82d759054f6ec7b4e887fb7a5692c66d7
+commit c2cc25480ba36ab48c1a577bebb12493865aad87
Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Mon Dec 19 03:32:57 2016 +0000
+Date: Tue Oct 8 22:40:39 2019 +0000
- upstream commit
+ upstream: Correct type for end-of-list sentinel; fixes initializer
- Use LOGNAME to get current user and fall back to whoami if
- not set. Mainly to benefit -portable since some platforms don't have whoami.
+ warnings on some platforms. ok deraadt.
- Upstream-Regress-ID: e3a16b7836a3ae24dc8f8a4e43fdf8127a60bdfa
+ OpenBSD-Commit-ID: a990dbc2dac25bdfa07e79321349c73fd991efa2
-commit 0d2f88428487518eea60602bd593989013831dcf
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Fri Dec 16 03:51:19 2016 +0000
+commit e827aedf8818e75c0016b47ed8fc231427457c43
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Mon Oct 7 23:10:38 2019 +0000
- upstream commit
+ upstream: reversed test yielded incorrect debug message
- Add regression test for AllowUsers and DenyUsers. Patch from
- Zev Weiss <zev at bewilderbeest.net>
+ OpenBSD-Commit-ID: 78bb512d04cfc238adb2c5b7504ac93eecf523b3
+
+commit 8ca491d29fbe26e5909ce22b344c0a848dc28d55
+Author: Damien Miller <djm@mindrot.org>
+Date: Tue Oct 8 17:05:57 2019 +1100
+
+ depend
+
+commit 86a0323374cbd404629e75bb320b3fa1c16aaa6b
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Wed Oct 9 09:36:06 2019 +1100
+
+ Make MAKE_CLONE no-op macro more correct.
- Upstream-Regress-ID: 8f1aac24d52728398871dac14ad26ea38b533fb9
+ Similar to the previous change to DEF_WEAK, some compilers don't like
+ the empty statement, so convert into a no-op function prototype.
-commit 3bc8180a008929f6fe98af4a56fb37d04444b417
-Author: Darren Tucker <dtucker@zip.com.au>
-Date: Fri Dec 16 15:02:24 2016 +1100
+commit cfc1897a2002ec6c4dc879b24e8b3153c87ea2cf
+Author: Damien Miller <djm@mindrot.org>
+Date: Wed Oct 9 09:06:35 2019 +1100
- Add missing monitor.h include.
+ wrap stdint.h include in HAVE_STDINT_H
+
+ make the indenting a little more consistent too..
- Fixes warning pointed out by Zev Weiss <zev at bewilderbeest.net>
+ Fixes Solaris 2.6; reported by Tom G. Christensen
-commit 410681f9015d76cc7b137dd90dac897f673244a0
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Dec 16 02:48:55 2016 +0000
+commit 13b3369830a43b89a503915216a23816d1b25744
+Author: Damien Miller <djm@mindrot.org>
+Date: Tue Oct 8 15:32:02 2019 +1100
- upstream commit
+ avoid "return (value)" in void-declared function
- revert to rev1.2; the new bits in this test depend on changes
- to ssh that aren't yet committed
+ spotted by Tim Rice; ok dtucker
+
+commit 0c7f8d2326d812b371f7afd63aff846973ec80a4
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Tue Oct 8 14:44:50 2019 +1100
+
+ Make DEF_WEAK more likely to be correct.
- Upstream-Regress-ID: 828ffc2c7afcf65d50ff2cf3dfc47a073ad39123
+ Completely nop-ing out DEF_WEAK leaves an empty statemment which some
+ compilers don't like. Replace with a no-op function template. ok djm@
-commit 2f2ffa4fbe4b671bbffa0611f15ba44cff64d58e
+commit b1e79ea8fae9c252399677a28707661d85c7d00c
Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Fri Dec 16 01:06:27 2016 +0000
+Date: Sun Oct 6 11:49:50 2019 +0000
- upstream commit
+ upstream: Instead of running sed over the whole log to remove CRs,
- Move the "stop sshd" code into its own helper function.
- Patch from Zev Weiss <zev at bewilderbeest.net>, ok djm@
+ remove them only where it's needed (and confuses test(1) on at least OS X in
+ portable).
- Upstream-Regress-ID: a113dea77df5bd97fb4633ea31f3d72dbe356329
+ OpenBSD-Regress-ID: a6ab9b4bd1d33770feaf01b2dfb96f9e4189d2d0
-commit e15e7152331e3976b35475fd4e9c72897ad0f074
+commit 8dc7d6b75a7f746fdd056acd41dffc0a13557a4c
+Author: Eduardo Barretto <ebarretto@linux.vnet.ibm.com>
+Date: Tue May 9 13:33:30 2017 -0300
+
+ Enable specific ioctl call for EP11 crypto card (s390)
+
+ The EP11 crypto card needs to make an ioctl call, which receives an
+ specific argument. This crypto card is for s390 only.
+
+ Signed-off-by: Eduardo Barretto <ebarretto@linux.vnet.ibm.com>
+
+commit 07f2c7f34951c04d2cd796ac6c80e47c56c4969e
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Dec 16 01:01:07 2016 +0000
+Date: Fri Oct 4 04:31:59 2019 +0000
- upstream commit
+ upstream: fix memory leak in error path; bz#3074 patch from
- regression test for certificates along with private key
- with no public half. bz#2617, mostly from Adam Eijdenberg
+ krishnaiah.bommu@intel.com, ok dtucker
- Upstream-Regress-ID: 2e74dc2c726f4dc839609b3ce045466b69f01115
+ OpenBSD-Commit-ID: d031853f3ecf47b35a0669588f4d9d8e3b307b3c
-commit 9a70ec085faf6e55db311cd1a329f1a35ad2a500
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Thu Dec 15 23:50:37 2016 +0000
+commit b7fbc75e119170f4d15c94a7fda4a1050e0871d6
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Fri Oct 4 04:13:39 2019 +0000
- upstream commit
+ upstream: space
- Use $SUDO to read pidfile in case root's umask is
- restricted. From portable.
+ OpenBSD-Commit-ID: 350648bcf00a2454e7ef998b7d88e42552b348ac
+
+commit 643ab68c79ac1644f4a31e36928c2bfc8a51db3c
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Fri Oct 4 03:39:19 2019 +0000
+
+ upstream: more sshsig regress tests: check key revocation, the
+
+ check-novalidate signature test mode and signing keys in ssh-agent.
+
+ From Sebastian Kinne (slightly tweaked)
- Upstream-Regress-ID: f6b1c7ffbc5a0dfb7d430adb2883344899174a98
+ OpenBSD-Regress-ID: b39566f5cec70140674658cdcedf38752a52e2e2
-commit fe06b68f824f8f55670442fb31f2c03526dd326c
+commit 714031a10bbe378a395a93cf1040f4ee1451f45f
Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Thu Dec 15 21:29:05 2016 +0000
+Date: Fri Oct 4 03:26:58 2019 +0000
- upstream commit
+ upstream: Check for gmtime failure in moduli generation. Based on
- Add missing braces in DenyUsers code. Patch from zev at
- bewilderbeest.net, ok deraadt@
+ patch from krishnaiah.bommu@intel.com, ok djm@
- Upstream-ID: d747ace338dcf943b077925f90f85f789714b54e
+ OpenBSD-Commit-ID: 4c6a4cde0022188ac83737de08da0e875704eeaa
-commit dcc7d74242a574fd5c4afbb4224795b1644321e7
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Thu Dec 15 21:20:41 2016 +0000
+commit 6918974405cc28ed977f802fd97a9c9a9b2e141b
+Author: jmc@openbsd.org <jmc@openbsd.org>
+Date: Thu Oct 3 17:07:50 2019 +0000
- upstream commit
+ upstream: use a more common options order in SYNOPSIS and sync
+
+ usage(); while here, no need for Bk/Ek;
- Fix text in error message. Patch from zev at
- bewilderbeest.net.
+ ok dtucker
- Upstream-ID: deb0486e175e7282f98f9a15035d76c55c84f7f6
+ OpenBSD-Commit-ID: 38715c3f10b166f599a2283eb7bc14860211bb90
-commit b737e4d7433577403a31cff6614f6a1b0b5e22f4
+commit feff96b7d4c0b99307f0459cbff128aede4a8984
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Wed Dec 14 00:36:34 2016 +0000
+Date: Wed Oct 2 09:50:50 2019 +0000
- upstream commit
+ upstream: thinko in previous; spotted by Mantas
- disable Unix-domain socket forwarding when privsep is
- disabled
+ =?UTF-8?q?=20Mikul=C4=97nas?=
+ MIME-Version: 1.0
+ Content-Type: text/plain; charset=UTF-8
+ Content-Transfer-Encoding: 8bit
- Upstream-ID: ab61516ae0faadad407857808517efa900a0d6d0
+ OpenBSD-Commit-ID: ffa3f5a45e09752fc47d9041e2203ee2ec15b24d
-commit 08a1e7014d65c5b59416a0e138c1f73f417496eb
+commit b5a89eec410967d6b712665f8cf0cb632928d74b
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Dec 9 03:04:29 2016 +0000
+Date: Wed Oct 2 08:07:13 2019 +0000
- upstream commit
+ upstream: make signature format match PROTOCO
- log connections dropped in excess of MaxStartups at
- verbose LogLevel; bz#2613 based on diff from Tomas Kuthan; ok dtucker@
+ =?UTF-8?q?=20as=20a=20string,=20not=20raw=20bytes.=20Spotted=20by=20Manta?=
+ =?UTF-8?q?s=20Mikul=C4=97nas?=
+ MIME-Version: 1.0
+ Content-Type: text/plain; charset=UTF-8
+ Content-Transfer-Encoding: 8bit
- Upstream-ID: 703ae690dbf9b56620a6018f8a3b2389ce76d92b
+ OpenBSD-Commit-ID: 80fcc6d52893f80c6de2bedd65353cebfebcfa8f
-commit 10e290ec00964b2bf70faab15a10a5574bb80527
-Author: Darren Tucker <dtucker@zip.com.au>
-Date: Tue Dec 13 13:51:32 2016 +1100
+commit dc6f81ee94995deb11bbf7e19801022c5f6fd90a
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Wed Oct 2 08:05:50 2019 +0000
- Get default of TEST_SSH_UTF8 from environment.
+ upstream: ban empty namespace strings for s
+
+ =?UTF-8?q?shsig;=20spotted=20by=20Mantas=20Mikul=C4=97nas?=
+ MIME-Version: 1.0
+ Content-Type: text/plain; charset=UTF-8
+ Content-Transfer-Encoding: 8bit
+
+ OpenBSD-Commit-ID: 7c5bcf40bed8f4e826230176f4aa353c52aeb698
-commit b9b8ba3f9ed92c6220b58d70d1e6d8aa3eea1104
-Author: Darren Tucker <dtucker@zip.com.au>
-Date: Tue Dec 13 12:56:40 2016 +1100
+commit fa5bd8107e0e2b3e1e184f55d0f9320c119f65f0
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Wed Oct 2 14:30:55 2019 +1000
- Remove commented-out includes.
-
- These commented-out includes have "Still needed?" comments. Since
- they've been commented out for ~13 years I assert that they're not.
+ Put ssherr.h back as it's actually needed.
-commit 25275f1c9d5f01a0877d39444e8f90521a598ea0
-Author: Darren Tucker <dtucker@zip.com.au>
-Date: Tue Dec 13 12:54:23 2016 +1100
+commit 3ef92a657444f172b61f92d5da66d94fa8265602
+Author: Lonnie Abelbeck <lonnie@abelbeck.com>
+Date: Tue Oct 1 09:05:09 2019 -0500
- Add prototype for strcasestr in compat library.
+ Deny (non-fatal) shmget/shmat/shmdt in preauth privsep child.
+
+ New wait_random_seeded() function on OpenSSL 1.1.1d uses shmget, shmat, and shmdt
+ in the preauth codepath, deny (non-fatal) in seccomp_filter sandbox.
-commit afec07732aa2985142f3e0b9a01eb6391f523dec
-Author: Darren Tucker <dtucker@zip.com.au>
-Date: Tue Dec 13 10:23:03 2016 +1100
+commit edd1d3a6261aecbf9a55944fd7be1db83571b46e
+Author: Damien Miller <djm@mindrot.org>
+Date: Wed Oct 2 10:54:28 2019 +1000
- Add strcasestr to compat library.
+ remove duplicate #includes
- Fixes build on (at least) Solaris 10.
+ Prompted by Jakub Jelen
-commit dda78a03af32e7994f132d923c2046e98b7c56c8
+commit 13c508dfed9f25e6e54c984ad00a74ef08539e70
Author: Damien Miller <djm@mindrot.org>
-Date: Mon Dec 12 13:57:10 2016 +1100
+Date: Wed Oct 2 10:51:15 2019 +1000
+
+ typo in comment
+
+commit d0c3ac427f6c52b872d6617421421dd791664445
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Wed Oct 2 00:42:30 2019 +0000
+
+ upstream: remove some duplicate #includes
+
+ OpenBSD-Commit-ID: ed6827ab921eff8027669848ef4f70dc1da4098c
+
+commit 084682786d9275552ee93857cb36e43c446ce92c
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Tue Oct 1 10:22:53 2019 +0000
- Force Turkish locales back to C/POSIX; bz#2643
+ upstream: revert unconditional forced login implemented in r1.41 of
- Turkish locales are unique in their handling of the letters 'i' and
- 'I' (yes, they are different letters) and OpenSSH isn't remotely
- prepared to deal with that. For now, the best we can do is to force
- OpenSSH to use the C/POSIX locale and try to preserve the UTF-8
- encoding if possible.
+ ssh-pkcs11.c; r1.45 added a forced login as a fallback for cases where the
+ token returns no objects and this is less disruptive for users of tokens
+ directly in ssh (rather than via ssh-agent) and in ssh-keygen
- ok dtucker@
+ bz3006, patch from Jakub Jelen; ok markus
+
+ OpenBSD-Commit-ID: 33d6df589b072094384631ff93b1030103b3d02e
-commit c35995048f41239fc8895aadc3374c5f75180554
-Author: Darren Tucker <dtucker@zip.com.au>
-Date: Fri Dec 9 12:52:02 2016 +1100
+commit 6c91d42cce3f055917dc3fd2c305dfc5b3b584b3
+Author: jmc@openbsd.org <jmc@openbsd.org>
+Date: Sun Sep 29 16:31:57 2019 +0000
- exit is in stdlib.h not unistd.h (that's _exit).
+ upstream: group and sort single letter options; ok deraadt
+
+ OpenBSD-Commit-ID: e1480e760a2b582f79696cdcff70098e23fc603f
-commit d399a8b914aace62418c0cfa20341aa37a192f98
-Author: Darren Tucker <dtucker@zip.com.au>
-Date: Fri Dec 9 12:33:25 2016 +1100
+commit 3b44bf39ff4d7ef5d50861e2e9dda62d2926d2fe
+Author: jmc@openbsd.org <jmc@openbsd.org>
+Date: Fri Sep 27 20:03:24 2019 +0000
- Include <unistd.h> for exit in utf8 locale test.
+ upstream: fix the DH-GEX text in -a; because this required a comma,
+
+ i added a comma to the first part, for balance...
+
+ OpenBSD-Commit-ID: 2c3464e9e82a41e8cdfe8f0a16d94266e43dbb58
-commit 47b8c99ab3221188ad3926108dd9d36da3b528ec
-Author: Darren Tucker <dtucker@zip.com.au>
-Date: Thu Dec 8 15:48:34 2016 +1100
+commit 3e53ef28fab53094e3b19622ba0e9c3d5fe71273
+Author: deraadt@openbsd.org <deraadt@openbsd.org>
+Date: Tue Sep 24 12:50:46 2019 +0000
- Check for utf8 local support before testing it.
+ upstream: identity_file[] should be PATH_MAX, not the arbitrary
- Check for utf8 local support and if not found, do not attempt to run the
- utf8 tests. Suggested by djm@
+ number 1024
+
+ OpenBSD-Commit-ID: e775f94ad47ce9ab37bd1410d7cf3b7ea98b11b7
-commit 4089fc1885b3a2822204effbb02b74e3da58240d
-Author: Darren Tucker <dtucker@zip.com.au>
-Date: Thu Dec 8 12:57:24 2016 +1100
+commit 90d4b2541e8c907793233d9cbd4963f7624f4174
+Author: jmc@openbsd.org <jmc@openbsd.org>
+Date: Fri Sep 20 18:50:58 2019 +0000
- Use AC_PATH_TOOL for krb5-config.
+ upstream: new sentence, new line;
- This will use the host-prefixed version when cross compiling; patch from
- david.michael at coreos.com.
+ OpenBSD-Commit-ID: c35ca5ec07be460e95e7406af12eee04a77b6698
-commit b4867e0712c89b93be905220c82f0a15e6865d1e
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Tue Dec 6 07:48:01 2016 +0000
+commit fbec7dba01b70b49ac47f56031310865dff86200
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Mon Sep 30 18:01:12 2019 +1000
- upstream commit
+ Include stdio.h for snprintf.
- make IdentityFile successfully load and use certificates that
- have no corresponding bare public key. E.g. just a private id_rsa and
- certificate id_rsa-cert.pub (and no id_rsa.pub).
+ Patch from vapier@gentoo.org.
+
+commit 0a403bfde71c4b82147473298d3a60b4171468bd
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Mon Sep 30 14:11:42 2019 +1000
+
+ Add SKIP_LTESTS for skipping specific tests.
+
+commit 4d59f7a5169c451ebf559aedec031ac9da2bf80c
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Fri Sep 27 05:25:12 2019 +0000
+
+ upstream: Test for empty result in expected bits. Remove CRs from log
- bz#2617 ok dtucker@
+ as they confuse tools on some platforms. Re-enable the 3des-cbc test.
- Upstream-ID: c1e9699b8c0e3b63cc4189e6972e3522b6292604
+ OpenBSD-Regress-ID: edf536d4f29fc1ba412889b37247a47f1b49d250
-commit c9792783a98881eb7ed295680013ca97a958f8ac
-Author: Damien Miller <djm@mindrot.org>
-Date: Fri Nov 25 14:04:21 2016 +1100
+commit 7c817d129e2d48fc8a6f7965339313023ec45765
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Fri Sep 27 15:26:22 2019 +1000
- Add a gnome-ssh-askpass3 target for GTK+3 version
+ Re-enable dhgex test.
- Based on patch from Colin Watson via bz#2640
+ Since we've added larger fallback groups to dh.c this test will pass
+ even if there is no moduli file installed on the system.
-commit 7be85ae02b9de0993ce0a1d1e978e11329f6e763
-Author: Damien Miller <djm@mindrot.org>
-Date: Fri Nov 25 14:03:53 2016 +1100
+commit c1e0a32fa852de6d1c82ece4f76add0ab0ca0eae
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Tue Sep 24 21:17:20 2019 +1000
- Make gnome-ssh-askpass2.c GTK+3-friendly
-
- Patch from Colin Watson via bz#2640
+ Add more ToS bits, currently only used by netcat.
+
+commit 5a273a33ca1410351cb484af7db7c13e8b4e8e4e
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Thu Sep 19 15:41:23 2019 +1000
+
+ Privsep is now required.
-commit b9844a45c7f0162fd1b5465683879793d4cc4aaa
+commit 8aa2aa3cd4d27d14e74b247c773696349472ef20
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sun Dec 4 23:54:02 2016 +0000
+Date: Mon Sep 16 03:23:02 2019 +0000
- upstream commit
+ upstream: Allow testing signature syntax and validity without verifying
+
+ that a signature came from a trusted signer. To discourage accidental or
+ unintentional use, this is invoked by the deliberately ugly option name
+ "check-novalidate"
+
+ from Sebastian Kinne
- Fix public key authentication when multiple
- authentication is in use. Instead of deleting and re-preparing the entire
- keys list, just reset the 'used' flags; the keys list is already in a good
- order (with already- tried keys at the back)
+ OpenBSD-Commit-ID: cea42c36ab7d6b70890e2d8635c1b5b943adcc0b
+
+commit 7047d5afe3103f0f07966c05b810682d92add359
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Fri Sep 13 04:52:34 2019 +0000
+
+ upstream: clarify that IdentitiesOnly also applies to the default
- Analysis and patch from Vincent Brillault on bz#2642; ok dtucker@
+ ~/.ssh/id_* keys; bz#3062
- Upstream-ID: 7123f12dc2f3bcaae715853035a97923d7300176
+ OpenBSD-Commit-ID: 604be570e04646f0f4a17026f8b2aada6a585dfa
-commit f2398eb774075c687b13af5bc22009eb08889abe
+commit b36ee3fcb2f1601693b1b7fd60dd6bd96006ea75
Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Sun Dec 4 22:27:25 2016 +0000
+Date: Fri Sep 13 04:36:43 2019 +0000
- upstream commit
+ upstream: Plug mem leaks on error paths, based in part on github
- Unlink PidFile on SIGHUP and always recreate it when the
- new sshd starts. Regression tests (and possibly other things) depend on the
- pidfile being recreated after SIGHUP, and unlinking it means it won't contain
- a stale pid if sshd fails to restart. ok djm@ markus@
+ pr#120 from David Carlier. ok djm@.
- Upstream-ID: 132dd6dda0c77dd49d2f15b2573b5794f6160870
+ OpenBSD-Commit-ID: c57adeb1022a8148fc86e5a88837b3b156dbdb7e
-commit 85aa2efeba51a96bf6834f9accf2935d96150296
+commit 2aefdf1aef906cf7548a2e5927d35aacb55948d4
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Wed Nov 30 03:01:33 2016 +0000
+Date: Fri Sep 13 04:31:19 2019 +0000
- upstream commit
+ upstream: whitespace
+
+ OpenBSD-Commit-ID: 57a71dd5f4cae8d61e0ac631a862589fb2bfd700
+
+commit fbe24b142915331ceb2a3a76be3dc5b6d204fddf
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Fri Sep 13 04:27:35 2019 +0000
+
+ upstream: allow %n to be expanded in ProxyCommand strings
- test new behaviour of cert force-command restriction vs.
- authorized_key/ principals
+ From Zachary Harmany via github.com/openssh/openssh-portable/pull/118
+ ok dtucker@
- Upstream-Regress-ID: 399efa7469d40c404c0b0a295064ce75d495387c
+ OpenBSD-Commit-ID: 7eebf1b7695f50c66d42053d352a4db9e8fb84b6
-commit 5d333131cd8519d022389cfd3236280818dae1bc
-Author: jmc@openbsd.org <jmc@openbsd.org>
-Date: Wed Nov 30 06:54:26 2016 +0000
+commit 2ce1d11600e13bee0667d6b717ffcc18a057b821
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Fri Sep 13 04:07:42 2019 +0000
- upstream commit
+ upstream: clarify that ConnectTimeout applies both to the TCP
+
+ connection and to the protocol handshake/KEX. From Jean-Charles Longuet via
+ Github PR140
+
+ OpenBSD-Commit-ID: ce1766abc6da080f0d88c09c2c5585a32b2256bf
+
+commit df780114278f406ef7cb2278802a2660092fff09
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Mon Sep 9 02:31:19 2019 +0000
+
+ upstream: Fix potential truncation warning. ok deraadt.
+
+ OpenBSD-Commit-ID: d87b7e3a94ec935e8194e7fce41815e22804c3ff
+
+commit ec0e6243660bf2df30c620a6a0d83eded376c9c6
+Author: Damien Miller <djm@mindrot.org>
+Date: Fri Sep 13 13:14:39 2019 +1000
+
+ memleak of buffer in sshpam_query
- tweak previous; while here fix up FILES and AUTHORS;
+ coverity report via Ed Maste; ok dtucker@
+
+commit c17e4638e5592688264fc0349f61bfc7b4425aa5
+Author: Damien Miller <djm@mindrot.org>
+Date: Fri Sep 13 13:12:42 2019 +1000
+
+ explicitly test set[ug]id() return values
- Upstream-ID: 93f6e54086145a75df8d8ec7d8689bdadbbac8fa
+ Legacy !_POSIX_SAVED_IDS path only; coverity report via Ed Maste
+ ok dtucker@
+
+commit 91a2135f32acdd6378476c5bae475a6e7811a6a2
+Author: naddy@openbsd.org <naddy@openbsd.org>
+Date: Fri Sep 6 14:45:34 2019 +0000
-commit 786d5994da79151180cb14a6cf157ebbba61c0cc
+ upstream: Allow prepending a list of algorithms to the default set
+
+ by starting the list with the '^' character, e.g.
+
+ HostKeyAlgorithms ^ssh-ed25519
+ Ciphers ^aes128-gcm@openssh.com,aes256-gcm@openssh.com
+
+ ok djm@ dtucker@
+
+ OpenBSD-Commit-ID: 1e1996fac0dc8a4b0d0ff58395135848287f6f97
+
+commit c8bdd2db77ac2369d5cdee237656f266c8f41552
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Wed Nov 30 03:07:37 2016 +0000
+Date: Fri Sep 6 07:53:40 2019 +0000
- upstream commit
+ upstream: key conversion should fail for !openssl builds, not fall
- add a whitelist of paths from which ssh-agent will load
- (via ssh-pkcs11-helper) a PKCS#11 module; ok markus@
+ through to the key generation code
- Upstream-ID: fe79769469d9cd6d26fe0dc15751b83ef2a06e8f
+ OpenBSD-Commit-ID: b957436adc43c4941e61d61958a193a708bc83c9
-commit 7844f357cdd90530eec81340847783f1f1da010b
+commit 823f6c37eb2d8191d45539f7b6fa877a4cb4ed3d
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Wed Nov 30 03:00:05 2016 +0000
+Date: Fri Sep 6 06:08:11 2019 +0000
- upstream commit
+ upstream: typo in previous
- Add a sshd_config DisableForwaring option that disables
- X11, agent, TCP, tunnel and Unix domain socket forwarding, as well as
- anything else we might implement in the future.
+ OpenBSD-Commit-ID: 7c3b94110864771a6b80a0d8acaca34037c3c96e
+
+commit 6a710d3e06fd375e2c2ae02546b9541c488a2cdb
+Author: Damien Miller <djm@mindrot.org>
+Date: Sun Sep 8 14:48:11 2019 +1000
+
+ needs time.h for --without-openssl
+
+commit f61f29afda6c71eda26effa54d3c2e5306fd0833
+Author: Damien Miller <djm@mindrot.org>
+Date: Sat Sep 7 19:25:00 2019 +1000
+
+ make unittests pass for no-openssl case
+
+commit 105e1c9218940eb53473f55a9177652d889ddbad
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Fri Sep 6 05:59:41 2019 +0000
+
+ upstream: avoid compiling certain files that deeply depend on
- This, like the 'restrict' authorized_keys flag, is intended to be a
- simple and future-proof way of restricting an account. Suggested as
- a complement to 'restrict' by Jann Horn; ok markus@
+ libcrypto when WITH_OPENSSL isn't set
- Upstream-ID: 203803f66e533a474086b38a59ceb4cf2410fcf7
+ OpenBSD-Commit-ID: 569f08445c27124ec7c7f6c0268d844ec56ac061
-commit fd6dcef2030d23c43f986d26979f84619c10589d
+commit 670104b923dd97b1c06c0659aef7c3e52af571b2
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Wed Nov 30 02:57:40 2016 +0000
+Date: Fri Sep 6 05:23:55 2019 +0000
- upstream commit
+ upstream: fixes for !WITH_OPENSSL compilation; ok dtucker@
- When a forced-command appears in both a certificate and
- an authorized keys/principals command= restriction, refuse to accept the
- certificate unless they are identical.
+ OpenBSD-Commit-ID: 7fd68eaa9e0f7482b5d4c7e8d740aed4770a839f
+
+commit be02d7cbde3d211ec2ed2320a1f7d86b2339d758
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Fri Sep 6 04:53:27 2019 +0000
+
+ upstream: lots of things were relying on libcrypto headers to
- The previous (documented) behaviour of having the certificate forced-
- command override the other could be a bit confused and more error-prone.
+ transitively include various system headers (mostly stdlib.h); include them
+ explicitly
- Pointed out by Jann Horn of Project Zero; ok dtucker@
+ OpenBSD-Commit-ID: 5b522f4f2d844f78bf1cc4f3f4cc392e177b2080
+
+commit d05aaaaadcad592abfaa44540928e0c61ef72ebb
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Fri Sep 6 03:30:42 2019 +0000
+
+ upstream: remove leakmalloc reference; we used this early when
+
+ refactoring but not since
- Upstream-ID: 79d811b6eb6bbe1221bf146dde6928f92d2cd05f
+ OpenBSD-Commit-ID: bb28ebda8f7c490b87b37954044a6cdd43a7eb2c
-commit 7fc4766ac78abae81ee75b22b7550720bfa28a33
+commit 1268f0bcd8fc844ac6c27167888443c8350005eb
Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Wed Nov 30 00:28:31 2016 +0000
+Date: Fri Sep 6 04:24:06 2019 +0000
- upstream commit
+ upstream: Check for RSA support before using it for the user key,
+
+ otherwise use ed25519 which is supported when built without OpenSSL.
+
+ OpenBSD-Regress-ID: 3d23ddfe83c5062f00ac845d463f19a2ec78c0f7
+
+commit fd7a2dec652b9efc8e97f03f118f935dce732c60
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Fri Sep 6 14:07:10 2019 +1000
+
+ Provide explicit path to configure-check.
- On startup, check to see if sshd is already daemonized
- and if so, skip the call to daemon() and do not rewrite the PidFile. This
- means that when sshd re-execs itself on SIGHUP the process ID will no longer
- change. Should address bz#2641. ok djm@ markus@.
+ On some platforms (at least OpenBSD) make won't search VPATH for target
+ files, so building out-of-tree will fail at configure-check. Provide
+ explicit path. ok djm@
+
+commit 00865c29690003b4523cc09a0e104724b9f911a4
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Fri Sep 6 01:58:50 2019 +0000
+
+ upstream: better error code for bad arguments; inspired by
- Upstream-ID: 5ea0355580056fb3b25c1fd6364307d9638a37b9
+ OpenBSD-Commit-ID: dfc263b6041de7f0ed921a1de0b81ddebfab1e0a
-commit c9f880c195c65f1dddcbc4ce9d6bfea7747debcc
+commit afdf27f5aceb4973b9f5308f4310c6e3fd8db1fb
Author: Damien Miller <djm@mindrot.org>
-Date: Wed Nov 30 13:51:49 2016 +1100
+Date: Thu Sep 5 21:38:40 2019 +1000
- factor out common PRNG reseed before privdrop
+ revert config.h/config.h.in freshness checks
- Add a call to RAND_poll() to ensure than more than pid+time gets
- stirred into child processes states. Prompted by analysis from Jann
- Horn at Project Zero. ok dtucker@
+ turns out autoreconf and configure don't touch some files if their content
+ doesn't change, so the mtime can't be relied upon in a makefile rule
-commit 79e4829ec81dead1b30999e1626eca589319a47f
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Fri Nov 25 03:02:01 2016 +0000
+commit a97609e850c57bd2cc2fe7e175fc35cb865bc834
+Author: Damien Miller <djm@mindrot.org>
+Date: Thu Sep 5 20:54:39 2019 +1000
- upstream commit
+ extend autoconf freshness test
- Allow PuTTY interop tests to run unattended. bz#2639,
- patch from cjwatson at debian.org.
+ make it cover config.h.in and config.h separately
+
+commit 182297c10edb21c4856c6a38326fd04d81de41a5
+Author: Damien Miller <djm@mindrot.org>
+Date: Thu Sep 5 20:34:54 2019 +1000
+
+ check that configure/config.h is up to date
- Upstream-Regress-ID: 4345253558ac23b2082aebabccd48377433b6fe0
+ Ensure they are newer than the configure.ac / aclocal.m4 source
-commit 504c3a9a1bf090f6b27260fc3e8ea7d984d163dc
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Fri Nov 25 02:56:49 2016 +0000
+commit 7d6034bd020248e9fc0f8c39c71c858debd0d0c1
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Thu Sep 5 10:05:51 2019 +0000
- upstream commit
+ upstream: if a PKCS#11 token returns no keys then try to login and
- Reverse args to sshd-log-wrapper. Matches change in
- portable, where it allows sshd do be optionally run under Valgrind.
+ refetch them. Based on patch from Jakub Jelen; bz#2430 ok markus@
- Upstream-Regress-ID: b438d1c6726dc5caa2a45153e6103a0393faa906
+ OpenBSD-Commit-ID: ab53bd6ddd54dd09e54a8bfbed1a984496f08b43
-commit bd13017736ec2f8f9ca498fe109fb0035f322733
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Fri Nov 25 02:49:18 2016 +0000
+commit 76f09bd95917862101b740afb19f4db5ccc752bf
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Thu Sep 5 09:35:19 2019 +0000
- upstream commit
+ upstream: sprinkle in some explicit errors here, otherwise the
+
+ percolate all the way up to dispatch_run_fatal() and lose all meaninful
+ context
- Fix typo in trace message; from portable.
+ to help with bz#3063; ok dtucker@
- Upstream-Regress-ID: 4c4a2ba0d37faf5fd230a91b4c7edb5699fbd73a
+ OpenBSD-Commit-ID: 5b2da83bb1c4a3471444b7910b2120ae36438a0a
-commit 7da751d8b007c7f3e814fd5737c2351440d78b4c
-Author: tb@openbsd.org <tb@openbsd.org>
-Date: Tue Nov 1 13:43:27 2016 +0000
+commit 0ea332497b2b2fc3995f72f6bafe9d664c0195b3
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Thu Sep 5 09:25:13 2019 +0000
- upstream commit
+ upstream: only send ext_info for KEX_INITIAL; bz#2929 ok dtucker
- Clean up MALLOC_OPTIONS. For the unittests, move
- MALLOC_OPTIONS and TEST_ENV to unittets/Makefile.inc.
+ OpenBSD-Commit-ID: 00f5c6062f6863769f5447c6346f78c05d2e4a63
+
+commit f23d91f9fa7f6f42e70404e000fac88aebfe3076
+Author: jmc@openbsd.org <jmc@openbsd.org>
+Date: Thu Sep 5 05:47:23 2019 +0000
+
+ upstream: macro fix; ok djm
- ok otto
+ OpenBSD-Commit-ID: e891dd6c7996114cb32f0924cb7898ab55efde6e
+
+commit 8b57337c1c1506df2bb9f039d0628a6de618566b
+Author: Damien Miller <djm@mindrot.org>
+Date: Thu Sep 5 15:46:39 2019 +1000
+
+ update fuzzing makefile to more recent clang
+
+commit ae631ad77daf8fd39723d15a687cd4b1482cbae8
+Author: Damien Miller <djm@mindrot.org>
+Date: Thu Sep 5 15:45:32 2019 +1000
+
+ fuzzer for sshsig allowed_signers option parsing
+
+commit 69159afe24120c97e5ebaf81016c85968afb903e
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Thu Sep 5 05:42:59 2019 +0000
+
+ upstream: memleak on error path; found by libfuzzer
- Upstream-Regress-ID: 890d497e0a38eeddfebb11cc429098d76cf29f12
+ OpenBSD-Commit-ID: 34d44cb0fb5bdb5fcbc6b02b804e71b20a7a5fc7
-commit 36f58e68221bced35e06d1cca8d97c48807a8b71
-Author: tb@openbsd.org <tb@openbsd.org>
-Date: Mon Oct 31 23:45:08 2016 +0000
+commit bab6feb01f9924758ca7129dba708298a53dde5f
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Thu Sep 5 04:55:32 2019 +0000
- upstream commit
+ upstream: expose allowed_signers options parsing code in header for
- Remove the obsolete A and P flags from MALLOC_OPTIONS.
+ fuzzing
- ok dtucker
+ rename to make more consistent with philosophically-similar auth
+ options parsing API.
- Upstream-Regress-ID: 6cc25024c8174a87e5734a0dc830194be216dd59
+ OpenBSD-Commit-ID: 0c67600ef04187f98e2912ca57b60c22a8025b7c
-commit b0899ee26a6630883c0f2350098b6a35e647f512
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Tue Nov 29 03:54:50 2016 +0000
+commit 4f9d75fbafde83d428e291516f8ce98e6b3a7c4b
+Author: naddy@openbsd.org <naddy@openbsd.org>
+Date: Wed Sep 4 20:31:15 2019 +0000
- upstream commit
+ upstream: Call comma-separated lists as such to clarify semantics.
+
+ Options such as Ciphers take values that may be a list of ciphers; the
+ complete list, not indiviual elements, may be prefixed with a dash or plus
+ character to remove from or append to the default list, respectively.
+
+ Users might read the current text as if each elment took an optional prefix,
+ so tweak the wording from "values" to "list" to prevent such ambiguity for
+ all options supporting these semantics.
- Factor out code to disconnect from controlling terminal
- into its own function. ok djm@
+ Fix instances missed in first commit. ok jmc@ kn@
- Upstream-ID: 39fd9e8ebd7222615a837312face5cc7ae962885
+ OpenBSD-Commit-ID: 7112522430a54fb9f15a7a26d26190ed84d5e417
+
+commit db1e6f60f03641b2d17e0ab062242609f4ed4598
+Author: jmc@openbsd.org <jmc@openbsd.org>
+Date: Wed Sep 4 05:56:54 2019 +0000
+
+ upstream: tweak previous;
+
+ OpenBSD-Commit-ID: 0abd728aef6b5b35f6db43176aa83b7e3bf3ce27
+
+commit 0f44e5956c7c816f6600f2a47be4d7bb5a8d711d
+Author: naddy@openbsd.org <naddy@openbsd.org>
+Date: Tue Sep 3 20:51:49 2019 +0000
+
+ upstream: repair typo and editing mishap
+
+ OpenBSD-Commit-ID: d125ab720ca71ccf9baf83e08ddc8c12a328597e
+
+commit f4846dfc6a79f84bbc6356ae3184f142bacedc24
+Author: Damien Miller <djm@mindrot.org>
+Date: Thu Sep 5 11:09:28 2019 +1000
-commit 54d022026aae4f53fa74cc636e4a032d9689b64d
+ Fuzzer harness for sshsig
+
+commit b08a6bc1cc7750c6f8a425d1cdbd86552fffc637
+Author: Damien Miller <djm@mindrot.org>
+Date: Tue Sep 3 18:45:42 2019 +1000
+
+ oops; missed including the actual file
+
+commit 1a72c0dd89f09754df443c9576dde624a17d7dd0
+Author: Damien Miller <djm@mindrot.org>
+Date: Tue Sep 3 18:44:10 2019 +1000
+
+ portability fixes for sshsig
+
+commit 6d6427d01304d967e58544cf1c71d2b4394c0522
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Nov 25 23:24:45 2016 +0000
+Date: Tue Sep 3 08:37:45 2019 +0000
- upstream commit
+ upstream: regress test for sshsig; feedback and ok markus@
- use sshbuf_allocate() to pre-allocate the buffer used for
- loading keys. This avoids implicit realloc inside the buffer code, which
- might theoretically leave fragments of the key on the heap. This doesn't
- appear to happen in practice for normal sized keys, but was observed for
- novelty oversize ones.
+ OpenBSD-Regress-ID: 74c0974f2cdae8d9599b9d76a09680bae55d8a8b
+
+commit 59650f0eaf65115afe04c39abfb93a4fc994ec55
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Tue Sep 3 08:37:06 2019 +0000
+
+ upstream: only add plain keys to prevent any certs laying around
- Pointed out by Jann Horn of Project Zero; ok markus@
+ from confusing the test.
- Upstream-ID: d620e1d46a29fdea56aeadeda120879eddc60ab1
+ OpenBSD-Regress-ID: b8f1508f822bc560b98dea910e61ecd76f34100f
-commit a9c746088787549bb5b1ae3add7d06a1b6d93d5e
+commit d637c4aee6f9b5280c13c020d7653444ac1fcaa5
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Nov 25 23:22:04 2016 +0000
+Date: Tue Sep 3 08:35:27 2019 +0000
- upstream commit
+ upstream: sshsig tweaks and improvements from and suggested by
+
+ Markus
- split allocation out of sshbuf_reserve() into a separate
- sshbuf_allocate() function; ok markus@
+ ok markus/me
- Upstream-ID: 11b8a2795afeeb1418d508a2c8095b3355577ec2
+ OpenBSD-Commit-ID: ea4f46ad5a16b27af96e08c4877423918c4253e9
-commit f0ddedee460486fa0e32fefb2950548009e5026e
-Author: markus@openbsd.org <markus@openbsd.org>
-Date: Wed Nov 23 23:14:15 2016 +0000
+commit 2a9c9f7272c1e8665155118fe6536bebdafb6166
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Tue Sep 3 08:34:19 2019 +0000
- upstream commit
+ upstream: sshsig: lightweight signature and verification ability
- allow ClientAlive{Interval,CountMax} in Match; ok dtucker,
- djm
+ for OpenSSH
+
+ This adds a simple manual signature scheme to OpenSSH.
+ Signatures can be made and verified using ssh-keygen -Y sign|verify
+
+ Signatures embed the key used to make them. At verification time, this
+ is matched via principal name against an authorized_keys-like list
+ of allowed signers.
+
+ Mostly by Sebastian Kinne w/ some tweaks by me
+
+ ok markus@
- Upstream-ID: 8beb4c1eadd588f1080b58932281983864979f55
+ OpenBSD-Commit-ID: 2ab568e7114c933346616392579d72be65a4b8fb
-commit 1a6f9d2e2493d445cd9ee496e6e3c2a2f283f66a
+commit 5485f8d50a5bc46aeed829075ebf5d9c617027ea
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Tue Nov 8 22:04:34 2016 +0000
+Date: Tue Sep 3 08:32:11 2019 +0000
- upstream commit
+ upstream: move authorized_keys option parsing helpsers to misc.c
- unbreak DenyUsers; reported by henning@
+ and make them public; ok markus@
- Upstream-ID: 1c67d4148f5e953c35acdb62e7c08ae8e33f7cb2
+ OpenBSD-Commit-ID: c18bcb2a687227b3478377c981c2d56af2638ea2
-commit 010359b32659f455fddd2bd85fd7cc4d7a3b994a
+commit f8df0413f0a057b6a3d3dd7bd8bc7c5d80911d3a
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sun Nov 6 05:46:37 2016 +0000
+Date: Tue Sep 3 08:31:20 2019 +0000
- upstream commit
+ upstream: make get_sigtype public as sshkey_get_sigtype(); ok
+
+ markus@
- Validate address ranges for AllowUser/DenyUsers at
- configuration load time and refuse to accept bad ones. It was previously
- possible to specify invalid CIDR address ranges (e.g. djm@127.1.2.3/55) and
- these would always match.
+ OpenBSD-Commit-ID: 01f8cdbec63350490d2249f41112c5780d1cfbb8
+
+commit dd8002fbe63d903ffea5be7b7f5fc2714acab4a0
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Tue Sep 3 08:30:47 2019 +0000
+
+ upstream: move advance_past_options to authfile.c and make it
- Thanks to Laurence Parry for a detailed bug report. ok markus (for
- a previous diff version)
+ public; ok markus@
- Upstream-ID: 9dfcdd9672b06e65233ea4434c38226680d40bfb
+ OpenBSD-Commit-ID: edda2fbba2c5b1f48e60f857a2010479e80c5f3c
-commit efb494e81d1317209256b38b49f4280897c61e69
+commit c72d78ccbe642e08591a626e5de18381489716e0
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Oct 28 03:33:52 2016 +0000
+Date: Tue Sep 3 08:29:58 2019 +0000
- upstream commit
+ upstream: move skip_space() to misc.c and make it public; ok
- Improve pkcs11_add_provider() logging: demote some
- excessively verbose error()s to debug()s, include PKCS#11 provider name and
- slot in log messages where possible. bz#2610, based on patch from Jakub Jelen
+ markus@
- Upstream-ID: 3223ef693cfcbff9079edfc7e89f55bf63e1973d
+ OpenBSD-Commit-ID: caa77e8a3b210948e29ad3e28c5db00852961eae
-commit 5ee3fb5affd7646f141749483205ade5fc54adaf
-Author: Darren Tucker <dtucker@zip.com.au>
-Date: Tue Nov 1 08:12:33 2016 +1100
+commit 06af3583f46e2c327fdd44d8a95b8b4e8dfd8db5
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Tue Sep 3 08:29:15 2019 +0000
- Use ptrace(PT_DENY_ATTACH, ..) on OS X.
+ upstream: authfd: add function to check if key is in agent
+
+ This commit adds a helper function which allows the caller to
+ check if a given public key is present in ssh-agent.
+
+ work by Sebastian Kinne; ok markus@
+
+ OpenBSD-Commit-ID: d43c5826353e1fdc1af71eb42961b30782c7bd13
-commit 315d2a4e674d0b7115574645cb51f968420ebb34
-Author: Damien Miller <djm@mindrot.org>
-Date: Fri Oct 28 14:34:07 2016 +1100
+commit 2ab5a8464870cc4b29ddbe849bbbc255729437bf
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Tue Sep 3 08:28:30 2019 +0000
- Unbreak AES-CTR ciphers on old (~0.9.8) OpenSSL
+ upstream: fix memleak in ssh_free_identitylist(); ok markus@
- ok dtucker@
+ OpenBSD-Commit-ID: aa51f77ae2c5330a1f61b2d22933f24a443f9abf
-commit a9ff3950b8e80ff971b4d44bbce96df27aed28af
-Author: Darren Tucker <dtucker@zip.com.au>
-Date: Fri Oct 28 14:26:58 2016 +1100
+commit 85443f165b4169b2a448b3e24bc1d4dc5b3156a4
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Tue Sep 3 08:27:52 2019 +0000
- Move OPENSSL_NO_RIPEMD160 to compat.
+ upstream: factor out confirm_overwrite(); ok markus@
- Move OPENSSL_NO_RIPEMD160 to compat and add ifdefs to mac.c around the
- ripemd160 MACs.
+ OpenBSD-Commit-ID: 304e95381b39c774c8fced7e5328b106a3ff0400
-commit bce58885160e5db2adda3054c3b81fe770f7285a
-Author: Darren Tucker <dtucker@zip.com.au>
-Date: Fri Oct 28 13:52:31 2016 +1100
+commit 9a396e33685633581c67d5ad9664570ef95281f2
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Mon Sep 2 23:46:46 2019 +0000
- Check if RIPEMD160 is disabled in OpenSSL.
+ upstream: constify an argument
+
+ OpenBSD-Commit-ID: 724bafc9f993746ad4303e95bede2c030de6233b
-commit d924640d4c355d1b5eca1f4cc60146a9975dbbff
-Author: Darren Tucker <dtucker@zip.com.au>
-Date: Fri Oct 28 13:38:19 2016 +1100
+commit b52c0c2e64988277a35a955a474d944967059aeb
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Mon Sep 2 00:19:25 2019 +0000
- Skip ssh1 specfic ciphers.
+ upstream: downgrade PKCS#11 "provider returned no slots" warning
+
+ from log level error to debug. This is common when attempting to enumerate
+ keys on smartcard readers with no cards plugged in. bz#3058 ok dtucker@
- cipher-3des1.c and cipher-bf1.c are specific to sshv1 so don't even try
- to compile them when Protocol 1 is not enabled.
+ OpenBSD-Commit-ID: bb8839ddeb77c271390488af1b771041d43e49c6
-commit 79d078e7a49caef746516d9710ec369ba45feab6
-Author: jsg@openbsd.org <jsg@openbsd.org>
-Date: Tue Oct 25 04:08:13 2016 +0000
+commit 0713322e18162463c5ab5ddfb9f935055ca775d8
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Sun Sep 1 23:47:32 2019 +0000
- upstream commit
+ upstream: print comment when printing pubkey from private
- Fix logic in add_local_forward() that inverted a test
- when code was refactored out into bind_permitted(). This broke ssh port
- forwarding for non-priv ports as a non root user.
+ bz#3052; ok dtucker
- ok dtucker@ 'looks good' deraadt@
+ OpenBSD-Commit-ID: a91b2a8d5f1053d34d7fce44523c53fb534ba914
+
+commit 368f1cc2fbd6ad10c66bc1b67c2c04aebf8a04a8
+Author: Damien Miller <djm@mindrot.org>
+Date: Mon Sep 2 10:28:42 2019 +1000
+
+ fixed test in OSX closefrom() replacement
- Upstream-ID: ddb8156ca03cc99997de284ce7777536ff9570c9
+ from likan_999.student AT sina.com
-commit a903e315dee483e555c8a3a02c2946937f9b4e5d
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Mon Oct 24 01:09:17 2016 +0000
+commit 6b7c53498def19a14dd9587bf521ab6dbee8988f
+Author: Damien Miller <djm@mindrot.org>
+Date: Mon Sep 2 10:22:02 2019 +1000
- upstream commit
+ retain Solaris PRIV_FILE_LINK_ANY in sftp-server
- Remove dead breaks, found via opencoverage.net. ok
- deraadt@
+ Dropping this privilege removes the ability to create hard links to
+ files owned by other users. This is required for the legacy sftp rename
+ operation.
- Upstream-ID: ad9cc655829d67fad219762810770787ba913069
+ bz#3036; approach ok Alex Wilson (the original author of the Solaris
+ sandbox/pledge replacement code)
-commit b4e96b4c9bea4182846e4942ba2048e6d708ee54
-Author: Darren Tucker <dtucker@zip.com.au>
-Date: Wed Oct 26 08:43:25 2016 +1100
+commit e50f808712393e86d69e42e9847cdf8d473412d7
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Fri Aug 30 05:08:28 2019 +0000
- Use !=NULL instead of >0 for getdefaultproj.
+ upstream: Use ed25519 for most hostkey rotation tests since it's
- getdefaultproj() returns a pointer so test it for NULL inequality
- instead of >0. Fixes compiler warning and is more correct. Patch from
- David Binderman.
+ supported even when built without OpenSSL. Use RSA for the secondary type
+ test if supported, otherwise skip it. Fixes this test for !OpenSSL builds.
+
+ OpenBSD-Regress-ID: 101cb34a84fd974c623bdb2e496f25a6e91be109
-commit 1c4ef0b808d3d38232aeeb1cebb7e9a43def42c5
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Sun Oct 23 22:04:05 2016 +0000
+commit 5e4796c47dd8d6c38fb2ff0b3e817525fed6040d
+Author: bluhm@openbsd.org <bluhm@openbsd.org>
+Date: Thu Aug 22 21:47:27 2019 +0000
- upstream commit
+ upstream: Test did not compile due to missing symbols. Add source
- Factor out "can bind to low ports" check into its own function. This will
- make it easier for Portable to support platforms with permissions models
- other than uid==0 (eg bz#2625). ok djm@, "doesn't offend me too much"
- deraadt@.
+ sshbuf-misc.c to regress as it was done in ssh make file. from Moritz Buhl
- Upstream-ID: 86213df4183e92b8f189a6d2dac858c994bfface
+ OpenBSD-Regress-ID: 9e1c23476bb845f3cf3d15d9032da3ed0cb2fcf5
-commit 0b9ee623d57e5de7e83e66fd61a7ba9a5be98894
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Wed Oct 19 23:21:56 2016 +0000
+commit e0e7e3d0e26f2c30697e6d0cfc293414908963c7
+Author: Damien Miller <djm@mindrot.org>
+Date: Fri Aug 30 14:26:19 2019 +1000
- upstream commit
+ tweak warning flags
- When tearing down ControlMaster connecctions, don't
- pollute stderr when LogLevel=quiet. Patch from Tim Kuijsten via tech@.
+ Enable -Wextra if compiler supports it
- Upstream-ID: d9b3a68b2a7c2f2fc7f74678e29a4618d55ceced
+ Set -Wno-error=format-truncation if available to prevent expected
+ string truncations in openbsd-compat from breaking -Werror builds
-commit 09e6a7d8354224933febc08ddcbc2010f542284e
-Author: Darren Tucker <dtucker@zip.com.au>
-Date: Mon Oct 24 09:06:18 2016 +1100
+commit 28744182cf90e0073b76a9e98de58a47e688b2c4
+Author: Damien Miller <djm@mindrot.org>
+Date: Fri Aug 30 13:21:38 2019 +1000
- Wrap stdint.h include in ifdef.
+ proc_pidinfo()-based closefrom() for OS X
+
+ Refactor closefrom() to use a single brute-force close() loop fallback.
+
+ Based on patch from likan_999.student@sina.com in bz#3049. ok dtucker@
-commit 08d9e9516e587b25127545c029e5464b2e7f2919
-Author: Darren Tucker <dtucker@zip.com.au>
-Date: Fri Oct 21 09:46:46 2016 +1100
+commit dc2ca588144f088a54febebfde3414568dc73d5f
+Author: kn@openbsd.org <kn@openbsd.org>
+Date: Fri Aug 16 11:16:32 2019 +0000
- Fix formatting.
+ upstream: Call comma-separated lists as such to clarify semantics
+
+ Options such as Ciphers take values that may be a list of ciphers; the
+ complete list, not indiviual elements, may be prefixed with a dash or plus
+ character to remove from or append to the default list respectively.
+
+ Users might read the current text as if each elment took an optional prefix,
+ so tweak the wording from "values" to "list" to prevent such ambiguity for
+ all options supporting this semantics (those that provide a list of
+ available elements via "ssh -Q ...").
+
+ Input and OK jmc
+
+ OpenBSD-Commit-ID: 4fdd175b0e5f5cb10ab3f26ccc38a93bb6515d57
-commit 461f50e7ab8751d3a55e9158c44c13031db7ba1d
-Author: Darren Tucker <dtucker@zip.com.au>
-Date: Fri Oct 21 06:55:58 2016 +1100
+commit c4736f39e66729ce2bf5b06ee6b391e092b48f47
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Fri Aug 16 06:35:27 2019 +0000
- Update links to https.
+ upstream: include sshbuf-misc.c in SRCS_BASE
- www.openssh.com now supports https and ftp.openbsd.org no longer
- supports ftp. Make all links to these https.
+ OpenBSD-Commit-ID: 99dd10e72c04e93849981d43d64c946619efa474
-commit dd4e7212a6141f37742de97795e79db51e4427ad
-Author: Darren Tucker <dtucker@zip.com.au>
-Date: Fri Oct 21 06:48:46 2016 +1100
+commit d0e51810f332fe44ebdba41113aacf319d35f5a5
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Sat Aug 24 15:12:11 2019 +1000
- Update host key generation examples.
+ Fix pasto in fallback code.
- Remove ssh1 host key generation, add ssh-keygen -A
+ There is no parameter called "pathname", it should simply be "path".
+ bz#3059, patch from samuel at cendio.se.
-commit 6d49ae82634c67e9a4d4af882bee20b40bb8c639
-Author: Darren Tucker <dtucker@zip.com.au>
-Date: Fri Oct 21 05:22:55 2016 +1100
+commit e83c989bfd9fc9838b7dfb711d1dc6da81814045
+Author: Damien Miller <djm@mindrot.org>
+Date: Fri Aug 23 10:19:30 2019 +1000
- Update links.
+ use SC_ALLOW_ARG_MASK to limit mmap protections
- Make links to openssh.com HTTPS now that it's supported, point release
- notes link to the HTML release notes page, and update a couple of other
- links and bits of text.
+ Restrict to PROT_(READ|WRITE|NONE), i.e. exclude PROT_EXEC
-commit fe0d1ca6ace06376625084b004ee533f2c2ea9d6
-Author: Darren Tucker <dtucker@zip.com.au>
-Date: Thu Oct 20 03:42:09 2016 +1100
+commit f6906f9bf12c968debec3671bbf19926ff8a235b
+Author: Damien Miller <djm@mindrot.org>
+Date: Fri Aug 23 10:08:48 2019 +1000
- Remote channels .orig and .rej files.
+ allow mprotect(2) with PROT_(READ|WRITE|NONE) only
- These files were incorrectly added during an OpenBSD sync.
+ Used by some hardened heap allocators. Requested by Yegor
+ Timoshenko in https://github.com/openssh/openssh-portable/pull/142
diff --git a/crypto/openssh/FREEBSD-vendor b/crypto/openssh/FREEBSD-vendor
index f48cbb6c3079..c7f6462985a2 100644
--- a/crypto/openssh/FREEBSD-vendor
+++ b/crypto/openssh/FREEBSD-vendor
@@ -1,6 +1,6 @@
# $FreeBSD$
Project: Portable OpenSSH
ProjectURL: http://www.openssh.com/portable.html
-Version: 7.9p1
+Version: 8.7p1
License: BSD
-Maintainer: des
+Maintainer: emaste
diff --git a/crypto/openssh/INSTALL b/crypto/openssh/INSTALL
index 775eb6c05342..8ab8a403a4e2 100644
--- a/crypto/openssh/INSTALL
+++ b/crypto/openssh/INSTALL
@@ -7,39 +7,52 @@ options. Some notes about specific compilers:
- clang: -ftrapv and -sanitize=integer require the compiler-rt runtime
(CC=clang LDFLAGS=--rtlib=compiler-rt ./configure)
-You will need working installations of Zlib and libcrypto (LibreSSL /
-OpenSSL)
+To support Privilege Separation (which is now required) you will need
+to create the user, group and directory used by sshd for privilege
+separation. See README.privsep for details.
+
+The remaining items are optional.
+
+A working installation of zlib:
Zlib 1.1.4 or 1.2.1.2 or greater (earlier 1.2.x versions have problems):
http://www.gzip.org/zlib/
-libcrypto (LibreSSL or OpenSSL >= 1.0.1 < 1.1.0)
-LibreSSL http://www.libressl.org/ ; or
-OpenSSL http://www.openssl.org/
+libcrypto from either of LibreSSL or OpenSSL. Building without libcrypto
+is supported but severely restricts the available ciphers and algorithms.
+ - LibreSSL (https://www.libressl.org/)
+ - OpenSSL (https://www.openssl.org) with any of the following versions:
+ - 1.0.x >= 1.0.1 or 1.1.0 >= 1.1.0g or any 1.1.1
+
+Note that due to a bug in EVP_CipherInit OpenSSL 1.1 versions prior to
+1.1.0g can't be used.
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. Note that because of API changes,
-OpenSSL 1.1.x is not currently supported.
+(i.e. -fPIC, eg by configuring OpenSSL as "./config [options] -fPIC"
+or LibreSSL as "CFLAGS=-fPIC ./configure") 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.
+If you build either from source, running the OpenSSL self-test ("make
+tests") or the LibreSSL equivalent ("make check") and ensuring that all
+tests pass is strongly recommended.
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
+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.
+Jaenicke's PRNGd is recommended. It requires that libcrypto be configured
+to support it.
http://prngd.sourceforge.net/
EGD:
-If the kernel lacks /dev/random the Entropy Gathering Daemon (EGD) is
-supported only if libcrypto supports it.
+The Entropy Gathering Daemon (EGD) supports the same interface as prngd.
+It also supported only if libcrypto is configured to support it.
http://egd.sourceforge.net/
@@ -47,7 +60,7 @@ 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.
+HP-UX 11, AIX >= 5.2, FreeBSD, NetBSD and Mac OS X.
Information about the various PAM implementations are available:
@@ -93,11 +106,12 @@ http://nlnetlabs.nl/projects/ldns/
Autoconf:
If you modify configure.ac or configure doesn't exist (eg if you checked
-the code out of git yourself) then you will need autoconf-2.69 to rebuild
-the automatically generated files by running "autoreconf". Earlier
-versions may also work but this is not guaranteed.
+the code out of git yourself) then you will need autoconf-2.69 and
+automake-1.16.1 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/
+http://www.gnu.org/software/automake/
Basic Security Module (BSM):
@@ -113,6 +127,16 @@ If you are making significant changes to the code you may need to rebuild
the dependency (.depend) file using "make depend", which requires the
"makedepend" tool from the X11 distribution.
+libfido2:
+
+libfido2 allows the use of hardware security keys over USB. libfido2
+in turn depends on libcbor. libfido2 >= 1.5.0 is strongly recommended.
+Limited functionality is possible with earlier libfido2 versions.
+
+https://github.com/Yubico/libfido2
+https://github.com/pjk/libcbor
+
+
2. Building / Installation
--------------------------
@@ -140,10 +164,6 @@ 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,
@@ -215,6 +235,11 @@ libraries are installed.
--with-ssl-engine enables Libre/OpenSSL's (hardware) ENGINE support
+--without-openssl builds without using OpenSSL. Only a subset of ciphers
+and algorithms are supported in this configuration.
+
+--without-zlib builds without zlib. This disables the Compression option.
+
--with-4in6 Check for IPv4 in IPv6 mapped addresses and convert them to
real (AF_INET) IPv4 addresses. Works around some quirks on Linux.
@@ -246,10 +271,10 @@ to generate keys for all supported types.
Replacing /etc/ssh with the correct path to the configuration directory.
(${prefix}/etc or whatever you specified with --sysconfdir during
-configuration)
+configuration).
-If you have configured OpenSSH with EGD support, ensure that EGD is
-running and has collected some Entropy.
+If you have configured OpenSSH with EGD/prngd support, ensure that EGD or
+prngd is running and has collected some entropy first.
For more information on configuration, please refer to the manual pages
for sshd, ssh and ssh-agent.
@@ -271,6 +296,6 @@ 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
+If you experience problems compiling, installing or running OpenSSH,
+please refer to the "reporting bugs" section of the webpage at
https://www.openssh.com/
diff --git a/crypto/openssh/LICENCE b/crypto/openssh/LICENCE
index 15248212a80d..5999c5e9d50d 100644
--- a/crypto/openssh/LICENCE
+++ b/crypto/openssh/LICENCE
@@ -174,7 +174,7 @@ OpenSSH contains no GPL code.
Gert Doering
Jakob Schlyter
Jason Downs
- Juha Yrjölä
+ Juha Yrjölä
Michael Stone
Networks Associates Technology, Inc.
Solar Designer
@@ -314,6 +314,68 @@ OpenSSH contains no GPL code.
* authorization. *
****************************************************************************/
+ The Blowfish cipher implementation is licensed by Niels Provis under
+ a 4-clause BSD license:
+
+ * Blowfish - a fast block cipher designed by Bruce Schneier
+ *
+ * Copyright 1997 Niels Provos <provos@physnet.uni-hamburg.de>
+ * 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.
+
+ Some replacement code is licensed by the NetBSD foundation under a
+ 2-clause BSD license:
+
+ * Copyright (c) 2001 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Todd Vierling.
+ *
+ * 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: LICENCE,v 1.20 2017/04/30 23:26:16 djm Exp $
diff --git a/crypto/openssh/Makefile.in b/crypto/openssh/Makefile.in
index 126b2c742bd3..b0293841a4f2 100644
--- a/crypto/openssh/Makefile.in
+++ b/crypto/openssh/Makefile.in
@@ -16,6 +16,7 @@ sysconfdir=@sysconfdir@
piddir=@piddir@
srcdir=@srcdir@
top_srcdir=@top_srcdir@
+abs_top_srcdir=@abs_top_srcdir@
DESTDIR=
VPATH=@srcdir@
@@ -24,6 +25,7 @@ ASKPASS_PROGRAM=$(libexecdir)/ssh-askpass
SFTP_SERVER=$(libexecdir)/sftp-server
SSH_KEYSIGN=$(libexecdir)/ssh-keysign
SSH_PKCS11_HELPER=$(libexecdir)/ssh-pkcs11-helper
+SSH_SK_HELPER=$(libexecdir)/ssh-sk-helper
PRIVSEP_PATH=@PRIVSEP_PATH@
SSH_PRIVSEP_USER=@SSH_PRIVSEP_USER@
STRIP_OPT=@STRIP_OPT@
@@ -35,32 +37,37 @@ PATHS= -DSSHDIR=\"$(sysconfdir)\" \
-D_PATH_SFTP_SERVER=\"$(SFTP_SERVER)\" \
-D_PATH_SSH_KEY_SIGN=\"$(SSH_KEYSIGN)\" \
-D_PATH_SSH_PKCS11_HELPER=\"$(SSH_PKCS11_HELPER)\" \
+ -D_PATH_SSH_SK_HELPER=\"$(SSH_SK_HELPER)\" \
-D_PATH_SSH_PIDDIR=\"$(piddir)\" \
-D_PATH_PRIVSEP_CHROOT_DIR=\"$(PRIVSEP_PATH)\"
CC=@CC@
LD=@LD@
CFLAGS=@CFLAGS@
+CFLAGS_NOPIE=@CFLAGS_NOPIE@
CPPFLAGS=-I. -I$(srcdir) @CPPFLAGS@ $(PATHS) @DEFS@
+PICFLAG=@PICFLAG@
LIBS=@LIBS@
K5LIBS=@K5LIBS@
GSSLIBS=@GSSLIBS@
-SSHLIBS=@SSHLIBS@
SSHDLIBS=@SSHDLIBS@
LIBEDIT=@LIBEDIT@
+LIBFIDO2=@LIBFIDO2@
AR=@AR@
AWK=@AWK@
RANLIB=@RANLIB@
INSTALL=@INSTALL@
SED=@SED@
-ENT=@ENT@
XAUTH_PATH=@XAUTH_PATH@
LDFLAGS=-L. -Lopenbsd-compat/ @LDFLAGS@
+LDFLAGS_NOPIE=-L. -Lopenbsd-compat/ @LDFLAGS_NOPIE@
EXEEXT=@EXEEXT@
MANFMT=@MANFMT@
MKDIR_P=@MKDIR_P@
-TARGETS=ssh$(EXEEXT) sshd$(EXEEXT) ssh-add$(EXEEXT) ssh-keygen$(EXEEXT) ssh-keyscan${EXEEXT} ssh-keysign${EXEEXT} ssh-pkcs11-helper$(EXEEXT) ssh-agent$(EXEEXT) scp$(EXEEXT) sftp-server$(EXEEXT) sftp$(EXEEXT)
+.SUFFIXES: .lo
+
+TARGETS=ssh$(EXEEXT) sshd$(EXEEXT) ssh-add$(EXEEXT) ssh-keygen$(EXEEXT) ssh-keyscan${EXEEXT} ssh-keysign${EXEEXT} ssh-pkcs11-helper$(EXEEXT) ssh-agent$(EXEEXT) scp$(EXEEXT) sftp-server$(EXEEXT) sftp$(EXEEXT) ssh-sk-helper$(EXEEXT)
XMSS_OBJS=\
ssh-xmss.o \
@@ -87,23 +94,27 @@ LIBSSH_OBJS=${LIBOPENSSH_OBJS} \
authfd.o authfile.o \
canohost.o channels.o cipher.o cipher-aes.o cipher-aesctr.o \
cipher-ctr.o cleanup.o \
- compat.o crc32.o fatal.o hostfile.o \
- log.o match.o moduli.o nchan.o packet.o opacket.o \
- readpass.o ttymodes.o xmalloc.o addrmatch.o \
- atomicio.o dispatch.o mac.o uuencode.o misc.o utf8.o \
- monitor_fdpass.o rijndael.o ssh-dss.o ssh-ecdsa.o ssh-rsa.o dh.o \
+ compat.o fatal.o hostfile.o \
+ log.o match.o moduli.o nchan.o packet.o \
+ readpass.o ttymodes.o xmalloc.o addr.o addrmatch.o \
+ atomicio.o dispatch.o mac.o misc.o utf8.o \
+ monitor_fdpass.o rijndael.o ssh-dss.o ssh-ecdsa.o ssh-ecdsa-sk.o \
+ ssh-ed25519-sk.o ssh-rsa.o dh.o \
msg.o progressmeter.o dns.o entropy.o gss-genr.o umac.o umac128.o \
ssh-pkcs11.o smult_curve25519_ref.o \
- poly1305.o chacha.o cipher-chachapoly.o \
- ssh-ed25519.o digest-openssl.o digest-libc.o hmac.o \
- sc25519.o ge25519.o fe25519.o ed25519.o verify.o hash.o \
+ poly1305.o chacha.o cipher-chachapoly.o cipher-chachapoly-libcrypto.o \
+ ssh-ed25519.o digest-openssl.o digest-libc.o \
+ hmac.o sc25519.o ge25519.o fe25519.o ed25519.o verify.o hash.o \
kex.o kexdh.o kexgex.o kexecdh.o kexc25519.o \
- kexdhc.o kexgexc.o kexecdhc.o kexc25519c.o \
- kexdhs.o kexgexs.o kexecdhs.o kexc25519s.o \
- platform-pledge.o platform-tracing.o platform-misc.o
+ kexgexc.o kexgexs.o \
+ kexsntrup761x25519.o sntrup761.o kexgen.o \
+ sftp-realpath.o platform-pledge.o platform-tracing.o platform-misc.o \
+ sshbuf-io.o
+
+SKOBJS= ssh-sk-client.o
SSHOBJS= ssh.o readconf.o clientloop.o sshtty.o \
- sshconnect.o sshconnect2.o mux.o
+ sshconnect.o sshconnect2.o mux.o $(SKOBJS)
SSHDOBJS=sshd.o auth-rhosts.o auth-passwd.o \
audit.o audit-bsm.o audit-linux.o platform.o \
@@ -115,13 +126,35 @@ SSHDOBJS=sshd.o auth-rhosts.o auth-passwd.o \
monitor.o monitor_wrap.o auth-krb5.o \
auth2-gss.o gss-serv.o gss-serv-krb5.o \
loginrec.o auth-pam.o auth-shadow.o auth-sia.o md5crypt.o \
- sftp-server.o sftp-common.o \
+ srclimit.o sftp-server.o sftp-common.o \
sandbox-null.o sandbox-rlimit.o sandbox-systrace.o sandbox-darwin.o \
sandbox-seccomp-filter.o sandbox-capsicum.o sandbox-pledge.o \
- sandbox-solaris.o uidswap.o
+ sandbox-solaris.o uidswap.o $(SKOBJS)
+
+SFTP_CLIENT_OBJS=sftp-common.o sftp-client.o sftp-glob.o
+
+SCP_OBJS= scp.o progressmeter.o $(SFTP_CLIENT_OBJS)
+
+SSHADD_OBJS= ssh-add.o $(SKOBJS)
+
+SSHAGENT_OBJS= ssh-agent.o ssh-pkcs11-client.o $(SKOBJS)
+
+SSHKEYGEN_OBJS= ssh-keygen.o sshsig.o $(SKOBJS)
+
+SSHKEYSIGN_OBJS=ssh-keysign.o readconf.o uidswap.o $(SKOBJS)
+
+P11HELPER_OBJS= ssh-pkcs11-helper.o ssh-pkcs11.o $(SKOBJS)
-MANPAGES = moduli.5.out scp.1.out ssh-add.1.out ssh-agent.1.out ssh-keygen.1.out ssh-keyscan.1.out ssh.1.out sshd.8.out sftp-server.8.out sftp.1.out ssh-keysign.8.out ssh-pkcs11-helper.8.out sshd_config.5.out ssh_config.5.out
-MANPAGES_IN = moduli.5 scp.1 ssh-add.1 ssh-agent.1 ssh-keygen.1 ssh-keyscan.1 ssh.1 sshd.8 sftp-server.8 sftp.1 ssh-keysign.8 ssh-pkcs11-helper.8 sshd_config.5 ssh_config.5
+SKHELPER_OBJS= ssh-sk-helper.o ssh-sk.o sk-usbhid.o
+
+SSHKEYSCAN_OBJS=ssh-keyscan.o $(SKOBJS)
+
+SFTPSERVER_OBJS=sftp-common.o sftp-server.o sftp-server-main.o
+
+SFTP_OBJS= sftp.o progressmeter.o $(SFTP_CLIENT_OBJS)
+
+MANPAGES = moduli.5.out scp.1.out ssh-add.1.out ssh-agent.1.out ssh-keygen.1.out ssh-keyscan.1.out ssh.1.out sshd.8.out sftp-server.8.out sftp.1.out ssh-keysign.8.out ssh-pkcs11-helper.8.out ssh-sk-helper.8.out sshd_config.5.out ssh_config.5.out
+MANPAGES_IN = moduli.5 scp.1 ssh-add.1 ssh-agent.1 ssh-keygen.1 ssh-keyscan.1 ssh.1 sshd.8 sftp-server.8 sftp.1 ssh-keysign.8 ssh-pkcs11-helper.8 ssh-sk-helper.8 sshd_config.5 ssh_config.5
MANTYPE = @MANTYPE@
CONFIGFILES=sshd_config.out ssh_config.out moduli.out
@@ -150,11 +183,16 @@ FIXPATHSCMD = $(SED) $(PATHSUBS)
FIXALGORITHMSCMD= $(SHELL) $(srcdir)/fixalgorithms $(SED) \
@UNSUPPORTED_ALGORITHMS@
-all: $(CONFIGFILES) $(MANPAGES) $(TARGETS)
+all: configure-check $(CONFIGFILES) $(MANPAGES) $(TARGETS)
$(LIBSSH_OBJS): Makefile.in config.h
$(SSHOBJS): Makefile.in config.h
$(SSHDOBJS): Makefile.in config.h
+configure-check: $(srcdir)/configure
+
+$(srcdir)/configure: configure.ac $(srcdir)/m4/*.m4
+ @echo "ERROR: configure is out of date; please run ${AUTORECONF} (and configure)" 1>&2
+ @exit 1
.c.o:
$(CC) $(CFLAGS) $(CPPFLAGS) -c $< -o $@
@@ -169,37 +207,40 @@ libssh.a: $(LIBSSH_OBJS)
$(RANLIB) $@
ssh$(EXEEXT): $(LIBCOMPAT) libssh.a $(SSHOBJS)
- $(LD) -o $@ $(SSHOBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(SSHLIBS) $(LIBS) $(GSSLIBS)
+ $(LD) -o $@ $(SSHOBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) $(GSSLIBS)
sshd$(EXEEXT): libssh.a $(LIBCOMPAT) $(SSHDOBJS)
$(LD) -o $@ $(SSHDOBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(SSHDLIBS) $(LIBS) $(GSSLIBS) $(K5LIBS)
-scp$(EXEEXT): $(LIBCOMPAT) libssh.a scp.o progressmeter.o
- $(LD) -o $@ scp.o progressmeter.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS)
+scp$(EXEEXT): $(LIBCOMPAT) libssh.a $(SCP_OBJS)
+ $(LD) -o $@ $(SCP_OBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS)
+
+ssh-add$(EXEEXT): $(LIBCOMPAT) libssh.a $(SSHADD_OBJS)
+ $(LD) -o $@ $(SSHADD_OBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS)
-ssh-add$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-add.o
- $(LD) -o $@ ssh-add.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS)
+ssh-agent$(EXEEXT): $(LIBCOMPAT) libssh.a $(SSHAGENT_OBJS)
+ $(LD) -o $@ $(SSHAGENT_OBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS)
-ssh-agent$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-agent.o ssh-pkcs11-client.o
- $(LD) -o $@ ssh-agent.o ssh-pkcs11-client.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS)
+ssh-keygen$(EXEEXT): $(LIBCOMPAT) libssh.a $(SSHKEYGEN_OBJS)
+ $(LD) -o $@ $(SSHKEYGEN_OBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS)
-ssh-keygen$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-keygen.o
- $(LD) -o $@ ssh-keygen.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS)
+ssh-keysign$(EXEEXT): $(LIBCOMPAT) libssh.a $(SSHKEYSIGN_OBJS)
+ $(LD) -o $@ $(SSHKEYSIGN_OBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS)
-ssh-keysign$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-keysign.o readconf.o uidswap.o
- $(LD) -o $@ ssh-keysign.o readconf.o uidswap.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS)
+ssh-pkcs11-helper$(EXEEXT): $(LIBCOMPAT) libssh.a $(P11HELPER_OBJS)
+ $(LD) -o $@ $(P11HELPER_OBJS) $(LDFLAGS) -lssh -lopenbsd-compat -lssh -lopenbsd-compat $(LIBS)
-ssh-pkcs11-helper$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-pkcs11-helper.o ssh-pkcs11.o
- $(LD) -o $@ ssh-pkcs11-helper.o ssh-pkcs11.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh -lopenbsd-compat $(LIBS)
+ssh-sk-helper$(EXEEXT): $(LIBCOMPAT) libssh.a $(SKHELPER_OBJS)
+ $(LD) -o $@ $(SKHELPER_OBJS) $(LDFLAGS) -lssh -lopenbsd-compat -lssh -lopenbsd-compat $(LIBS) $(LIBFIDO2)
-ssh-keyscan$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-keyscan.o
- $(LD) -o $@ ssh-keyscan.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh $(LIBS)
+ssh-keyscan$(EXEEXT): $(LIBCOMPAT) libssh.a $(SSHKEYSCAN_OBJS)
+ $(LD) -o $@ $(SSHKEYSCAN_OBJS) $(LDFLAGS) -lssh -lopenbsd-compat -lssh $(LIBS)
-sftp-server$(EXEEXT): $(LIBCOMPAT) libssh.a sftp.o sftp-common.o sftp-server.o sftp-server-main.o
- $(LD) -o $@ sftp-server.o sftp-common.o sftp-server-main.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS)
+sftp-server$(EXEEXT): $(LIBCOMPAT) libssh.a $(SFTPSERVER_OBJS)
+ $(LD) -o $@ $(SFTPSERVER_OBJS) $(LDFLAGS) -lssh -lopenbsd-compat -lssh $(LIBS)
-sftp$(EXEEXT): $(LIBCOMPAT) libssh.a sftp.o sftp-client.o sftp-common.o sftp-glob.o progressmeter.o
- $(LD) -o $@ progressmeter.o sftp.o sftp-client.o sftp-common.o sftp-glob.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) $(LIBEDIT)
+sftp$(EXEEXT): $(LIBCOMPAT) libssh.a $(SFTP_OBJS)
+ $(LD) -o $@ $(SFTP_OBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) $(LIBEDIT)
# test driver for the loginrec code - not built by default
logintest: logintest.o $(LIBCOMPAT) libssh.a loginrec.o
@@ -227,16 +268,14 @@ moduli:
echo
clean: regressclean
- rm -f *.o *.a $(TARGETS) logintest config.cache config.log
+ rm -f *.o *.lo *.a $(TARGETS) logintest config.cache config.log
rm -f *.out core survey
rm -f regress/check-perm$(EXEEXT)
rm -f regress/mkdtemp$(EXEEXT)
rm -f regress/unittests/test_helper/*.a
rm -f regress/unittests/test_helper/*.o
- rm -f regress/unittests/sshbuf/*.o
- rm -f regress/unittests/sshbuf/test_sshbuf$(EXEEXT)
- rm -f regress/unittests/sshkey/*.o
- rm -f regress/unittests/sshkey/test_sshkey$(EXEEXT)
+ rm -f regress/unittests/authopt/*.o
+ rm -f regress/unittests/authopt/test_authopt$(EXEEXT)
rm -f regress/unittests/bitmap/*.o
rm -f regress/unittests/bitmap/test_bitmap$(EXEEXT)
rm -f regress/unittests/conversion/*.o
@@ -247,10 +286,19 @@ clean: regressclean
rm -f regress/unittests/kex/test_kex$(EXEEXT)
rm -f regress/unittests/match/*.o
rm -f regress/unittests/match/test_match$(EXEEXT)
+ rm -f regress/unittests/misc/*.o
+ rm -f regress/unittests/misc/test_misc$(EXEEXT)
+ rm -f regress/unittests/sshbuf/*.o
+ rm -f regress/unittests/sshbuf/test_sshbuf$(EXEEXT)
+ rm -f regress/unittests/sshkey/*.o
+ rm -f regress/unittests/sshkey/test_sshkey$(EXEEXT)
+ rm -f regress/unittests/sshsig/*.o
+ rm -f regress/unittests/sshsig/test_sshsig$(EXEEXT)
rm -f regress/unittests/utf8/*.o
rm -f regress/unittests/utf8/test_utf8$(EXEEXT)
- rm -f regress/misc/kexfuzz/*.o
- rm -f regress/misc/kexfuzz/kexfuzz$(EXEEXT)
+ rm -f regress/misc/sk-dummy/*.o
+ rm -f regress/misc/sk-dummy/*.lo
+ rm -f regress/misc/sk-dummy/sk-dummy.so
(cd openbsd-compat && $(MAKE) clean)
distclean: regressclean
@@ -263,10 +311,8 @@ distclean: regressclean
rm -f regress/mkdtemp
rm -f regress/unittests/test_helper/*.a
rm -f regress/unittests/test_helper/*.o
- rm -f regress/unittests/sshbuf/*.o
- rm -f regress/unittests/sshbuf/test_sshbuf
- rm -f regress/unittests/sshkey/*.o
- rm -f regress/unittests/sshkey/test_sshkey
+ rm -f regress/unittests/authopt/*.o
+ rm -f regress/unittests/authopt/test_authopt
rm -f regress/unittests/bitmap/*.o
rm -f regress/unittests/bitmap/test_bitmap
rm -f regress/unittests/conversion/*.o
@@ -277,10 +323,16 @@ distclean: regressclean
rm -f regress/unittests/kex/test_kex
rm -f regress/unittests/match/*.o
rm -f regress/unittests/match/test_match
+ rm -f regress/unittests/misc/*.o
+ rm -f regress/unittests/misc/test_misc
+ rm -f regress/unittests/sshbuf/*.o
+ rm -f regress/unittests/sshbuf/test_sshbuf
+ rm -f regress/unittests/sshkey/*.o
+ rm -f regress/unittests/sshkey/test_sshkey
+ rm -f regress/unittests/sshsig/*.o
+ rm -f regress/unittests/sshsig/test_sshsig
rm -f regress/unittests/utf8/*.o
rm -f regress/unittests/utf8/test_utf8
- rm -f regress/misc/kexfuzz/*.o
- rm -f regress/misc/kexfuzz/kexfuzz$(EXEEXT)
(cd openbsd-compat && $(MAKE) distclean)
if test -d pkg ; then \
rm -fr pkg ; \
@@ -307,9 +359,15 @@ depend: depend-rebuild
rm -f .depend.bak
depend-rebuild:
- rm -f config.h
- touch config.h
+ mv .depend .depend.old
+ rm -f config.h .depend
+ touch config.h .depend
makedepend -w1000 -Y. -f .depend *.c 2>/dev/null
+ (echo '# Automatically generated by makedepend.'; \
+ echo '# Run "make depend" to rebuild.'; sort .depend ) >.depend.tmp
+ mv .depend.tmp .depend
+ rm -f .depend.bak
+ mv .depend.old .depend.bak
rm -f config.h
depend-check: depend-rebuild
@@ -343,6 +401,7 @@ install-files:
$(INSTALL) -m 0755 $(STRIP_OPT) sshd$(EXEEXT) $(DESTDIR)$(sbindir)/sshd$(EXEEXT)
$(INSTALL) -m 4711 $(STRIP_OPT) ssh-keysign$(EXEEXT) $(DESTDIR)$(SSH_KEYSIGN)$(EXEEXT)
$(INSTALL) -m 0755 $(STRIP_OPT) ssh-pkcs11-helper$(EXEEXT) $(DESTDIR)$(SSH_PKCS11_HELPER)$(EXEEXT)
+ $(INSTALL) -m 0755 $(STRIP_OPT) ssh-sk-helper$(EXEEXT) $(DESTDIR)$(SSH_SK_HELPER)$(EXEEXT)
$(INSTALL) -m 0755 $(STRIP_OPT) sftp$(EXEEXT) $(DESTDIR)$(bindir)/sftp$(EXEEXT)
$(INSTALL) -m 0755 $(STRIP_OPT) sftp-server$(EXEEXT) $(DESTDIR)$(SFTP_SERVER)$(EXEEXT)
$(INSTALL) -m 644 ssh.1.out $(DESTDIR)$(mandir)/$(mansubdir)1/ssh.1
@@ -359,6 +418,7 @@ install-files:
$(INSTALL) -m 644 sftp-server.8.out $(DESTDIR)$(mandir)/$(mansubdir)8/sftp-server.8
$(INSTALL) -m 644 ssh-keysign.8.out $(DESTDIR)$(mandir)/$(mansubdir)8/ssh-keysign.8
$(INSTALL) -m 644 ssh-pkcs11-helper.8.out $(DESTDIR)$(mandir)/$(mansubdir)8/ssh-pkcs11-helper.8
+ $(INSTALL) -m 644 ssh-sk-helper.8.out $(DESTDIR)$(mandir)/$(mansubdir)8/ssh-sk-helper.8
install-sysconf:
$(MKDIR_P) $(DESTDIR)$(sysconfdir)
@@ -419,6 +479,7 @@ uninstall:
-rm -r $(DESTDIR)$(SFTP_SERVER)$(EXEEXT)
-rm -f $(DESTDIR)$(SSH_KEYSIGN)$(EXEEXT)
-rm -f $(DESTDIR)$(SSH_PKCS11_HELPER)$(EXEEXT)
+ -rm -f $(DESTDIR)$(SSH_SK_HELPER)$(EXEEXT)
-rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/ssh.1
-rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/scp.1
-rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/ssh-add.1
@@ -430,18 +491,22 @@ uninstall:
-rm -f $(DESTDIR)$(mandir)/$(mansubdir)8/sftp-server.8
-rm -f $(DESTDIR)$(mandir)/$(mansubdir)8/ssh-keysign.8
-rm -f $(DESTDIR)$(mandir)/$(mansubdir)8/ssh-pkcs11-helper.8
+ -rm -f $(DESTDIR)$(mandir)/$(mansubdir)8/ssh-sk-helper.8
regress-prep:
$(MKDIR_P) `pwd`/regress/unittests/test_helper
- $(MKDIR_P) `pwd`/regress/unittests/sshbuf
- $(MKDIR_P) `pwd`/regress/unittests/sshkey
+ $(MKDIR_P) `pwd`/regress/unittests/authopt
$(MKDIR_P) `pwd`/regress/unittests/bitmap
$(MKDIR_P) `pwd`/regress/unittests/conversion
$(MKDIR_P) `pwd`/regress/unittests/hostkeys
$(MKDIR_P) `pwd`/regress/unittests/kex
$(MKDIR_P) `pwd`/regress/unittests/match
+ $(MKDIR_P) `pwd`/regress/unittests/misc
+ $(MKDIR_P) `pwd`/regress/unittests/sshbuf
+ $(MKDIR_P) `pwd`/regress/unittests/sshkey
+ $(MKDIR_P) `pwd`/regress/unittests/sshsig
$(MKDIR_P) `pwd`/regress/unittests/utf8
- $(MKDIR_P) `pwd`/regress/misc/kexfuzz
+ $(MKDIR_P) `pwd`/regress/misc/sk-dummy
[ -f `pwd`/regress/Makefile ] || \
ln -s `cd $(srcdir) && pwd`/regress/Makefile `pwd`/regress/Makefile
@@ -496,7 +561,8 @@ UNITTESTS_TEST_SSHKEY_OBJS=\
regress/unittests/sshkey/tests.o \
regress/unittests/sshkey/common.o \
regress/unittests/sshkey/test_file.o \
- regress/unittests/sshkey/test_sshkey.o
+ regress/unittests/sshkey/test_sshkey.o \
+ $(SKOBJS)
regress/unittests/sshkey/test_sshkey$(EXEEXT): ${UNITTESTS_TEST_SSHKEY_OBJS} \
regress/unittests/test_helper/libtest_helper.a libssh.a
@@ -504,6 +570,17 @@ regress/unittests/sshkey/test_sshkey$(EXEEXT): ${UNITTESTS_TEST_SSHKEY_OBJS} \
regress/unittests/test_helper/libtest_helper.a \
-lssh -lopenbsd-compat -lssh -lopenbsd-compat $(LIBS)
+UNITTESTS_TEST_SSHSIG_OBJS=\
+ sshsig.o \
+ regress/unittests/sshsig/tests.o \
+ $(SKOBJS)
+
+regress/unittests/sshsig/test_sshsig$(EXEEXT): ${UNITTESTS_TEST_SSHSIG_OBJS} \
+ regress/unittests/test_helper/libtest_helper.a libssh.a
+ $(LD) -o $@ $(LDFLAGS) $(UNITTESTS_TEST_SSHSIG_OBJS) \
+ regress/unittests/test_helper/libtest_helper.a \
+ -lssh -lopenbsd-compat -lssh -lopenbsd-compat $(LIBS)
+
UNITTESTS_TEST_BITMAP_OBJS=\
regress/unittests/bitmap/tests.o
@@ -513,6 +590,18 @@ regress/unittests/bitmap/test_bitmap$(EXEEXT): ${UNITTESTS_TEST_BITMAP_OBJS} \
regress/unittests/test_helper/libtest_helper.a \
-lssh -lopenbsd-compat -lssh -lopenbsd-compat $(LIBS)
+UNITTESTS_TEST_AUTHOPT_OBJS=\
+ regress/unittests/authopt/tests.o \
+ auth-options.o \
+ $(SKOBJS)
+
+regress/unittests/authopt/test_authopt$(EXEEXT): \
+ ${UNITTESTS_TEST_AUTHOPT_OBJS} \
+ regress/unittests/test_helper/libtest_helper.a libssh.a
+ $(LD) -o $@ $(LDFLAGS) $(UNITTESTS_TEST_AUTHOPT_OBJS) \
+ regress/unittests/test_helper/libtest_helper.a \
+ -lssh -lopenbsd-compat -lssh -lopenbsd-compat $(LIBS)
+
UNITTESTS_TEST_CONVERSION_OBJS=\
regress/unittests/conversion/tests.o
@@ -525,7 +614,8 @@ regress/unittests/conversion/test_conversion$(EXEEXT): \
UNITTESTS_TEST_KEX_OBJS=\
regress/unittests/kex/tests.o \
- regress/unittests/kex/test_kex.o
+ regress/unittests/kex/test_kex.o \
+ $(SKOBJS)
regress/unittests/kex/test_kex$(EXEEXT): ${UNITTESTS_TEST_KEX_OBJS} \
regress/unittests/test_helper/libtest_helper.a libssh.a
@@ -535,7 +625,8 @@ regress/unittests/kex/test_kex$(EXEEXT): ${UNITTESTS_TEST_KEX_OBJS} \
UNITTESTS_TEST_HOSTKEYS_OBJS=\
regress/unittests/hostkeys/tests.o \
- regress/unittests/hostkeys/test_iterate.o
+ regress/unittests/hostkeys/test_iterate.o \
+ $(SKOBJS)
regress/unittests/hostkeys/test_hostkeys$(EXEEXT): \
${UNITTESTS_TEST_HOSTKEYS_OBJS} \
@@ -554,6 +645,21 @@ regress/unittests/match/test_match$(EXEEXT): \
regress/unittests/test_helper/libtest_helper.a \
-lssh -lopenbsd-compat -lssh -lopenbsd-compat $(LIBS)
+UNITTESTS_TEST_MISC_OBJS=\
+ regress/unittests/misc/tests.o \
+ regress/unittests/misc/test_parse.o \
+ regress/unittests/misc/test_expand.o \
+ regress/unittests/misc/test_convtime.o \
+ regress/unittests/misc/test_argv.o \
+ regress/unittests/misc/test_strdelim.o
+
+regress/unittests/misc/test_misc$(EXEEXT): \
+ ${UNITTESTS_TEST_MISC_OBJS} \
+ regress/unittests/test_helper/libtest_helper.a libssh.a
+ $(LD) -o $@ $(LDFLAGS) $(UNITTESTS_TEST_MISC_OBJS) \
+ regress/unittests/test_helper/libtest_helper.a \
+ -lssh -lopenbsd-compat -lssh -lopenbsd-compat $(LIBS)
+
UNITTESTS_TEST_UTF8_OBJS=\
regress/unittests/utf8/tests.o
@@ -564,47 +670,58 @@ regress/unittests/utf8/test_utf8$(EXEEXT): \
regress/unittests/test_helper/libtest_helper.a \
-lssh -lopenbsd-compat -lssh -lopenbsd-compat $(LIBS)
-MISC_KEX_FUZZ_OBJS=\
- regress/misc/kexfuzz/kexfuzz.o
+# These all need to be compiled -fPIC, so they are treated differently.
+SK_DUMMY_OBJS=\
+ regress/misc/sk-dummy/sk-dummy.lo \
+ regress/misc/sk-dummy/fatal.lo \
+ ed25519.lo hash.lo ge25519.lo fe25519.lo sc25519.lo verify.lo
-regress/misc/kexfuzz/kexfuzz$(EXEEXT): ${MISC_KEX_FUZZ_OBJS} libssh.a
- $(LD) -o $@ $(LDFLAGS) $(MISC_KEX_FUZZ_OBJS) \
- -lssh -lopenbsd-compat -lssh -lopenbsd-compat $(LIBS)
+SK_DUMMY_LIBRARY=@SK_DUMMY_LIBRARY@
+
+.c.lo: Makefile.in config.h
+ $(CC) $(CFLAGS_NOPIE) $(PICFLAG) $(CPPFLAGS) -c $< -o $@
+
+regress/misc/sk-dummy/sk-dummy.so: $(SK_DUMMY_OBJS)
+ $(CC) $(CFLAGS) $(CPPFLAGS) -fPIC -shared -o $@ $(SK_DUMMY_OBJS) \
+ -L. -Lopenbsd-compat -lopenbsd-compat $(LDFLAGS_NOPIE) $(LIBS)
-regress-binaries: regress/modpipe$(EXEEXT) \
+regress-binaries: regress-prep $(LIBCOMPAT) \
+ regress/modpipe$(EXEEXT) \
regress/setuid-allowed$(EXEEXT) \
regress/netcat$(EXEEXT) \
regress/check-perm$(EXEEXT) \
regress/mkdtemp$(EXEEXT) \
- regress/unittests/sshbuf/test_sshbuf$(EXEEXT) \
- regress/unittests/sshkey/test_sshkey$(EXEEXT) \
+ $(SK_DUMMY_LIBRARY)
+
+regress-unit-binaries: regress-prep $(REGRESSLIBS) \
+ regress/unittests/authopt/test_authopt$(EXEEXT) \
regress/unittests/bitmap/test_bitmap$(EXEEXT) \
regress/unittests/conversion/test_conversion$(EXEEXT) \
regress/unittests/hostkeys/test_hostkeys$(EXEEXT) \
regress/unittests/kex/test_kex$(EXEEXT) \
regress/unittests/match/test_match$(EXEEXT) \
- regress/unittests/utf8/test_utf8$(EXEEXT) \
- regress/misc/kexfuzz/kexfuzz$(EXEEXT)
+ regress/unittests/misc/test_misc$(EXEEXT) \
+ regress/unittests/sshbuf/test_sshbuf$(EXEEXT) \
+ regress/unittests/sshkey/test_sshkey$(EXEEXT) \
+ regress/unittests/sshsig/test_sshsig$(EXEEXT) \
+ regress/unittests/utf8/test_utf8$(EXEEXT)
+
+tests: file-tests t-exec interop-tests unit
+ echo all tests passed
+
+unit: regress-unit-binaries
+ BUILDDIR=`pwd`; \
+ cd $(srcdir)/regress || exit $$?; \
+ $(MAKE) \
+ .OBJDIR="$${BUILDDIR}/regress" \
+ .CURDIR="`pwd`" \
+ OBJ="$${BUILDDIR}/regress" \
+ $@ && echo $@ tests passed
-tests interop-tests t-exec unit: regress-prep regress-binaries $(TARGETS)
+interop-tests t-exec file-tests: regress-prep regress-binaries $(TARGETS)
BUILDDIR=`pwd`; \
- TEST_SSH_SCP="$${BUILDDIR}/scp"; \
- TEST_SSH_SSH="$${BUILDDIR}/ssh"; \
- TEST_SSH_SSHD="$${BUILDDIR}/sshd"; \
- TEST_SSH_SSHAGENT="$${BUILDDIR}/ssh-agent"; \
- TEST_SSH_SSHADD="$${BUILDDIR}/ssh-add"; \
- TEST_SSH_SSHKEYGEN="$${BUILDDIR}/ssh-keygen"; \
- TEST_SSH_SSHPKCS11HELPER="$${BUILDDIR}/ssh-pkcs11-helper"; \
- TEST_SSH_SSHKEYSCAN="$${BUILDDIR}/ssh-keyscan"; \
- TEST_SSH_SFTP="$${BUILDDIR}/sftp"; \
- TEST_SSH_SFTPSERVER="$${BUILDDIR}/sftp-server"; \
- TEST_SSH_PLINK="plink"; \
- TEST_SSH_PUTTYGEN="puttygen"; \
- TEST_SSH_CONCH="conch"; \
- TEST_SSH_IPV6="@TEST_SSH_IPV6@" ; \
- TEST_SSH_UTF8="@TEST_SSH_UTF8@" ; \
- TEST_SSH_ECC="@TEST_SSH_ECC@" ; \
cd $(srcdir)/regress || exit $$?; \
+ EGREP='@EGREP@' \
$(MAKE) \
.OBJDIR="$${BUILDDIR}/regress" \
.CURDIR="`pwd`" \
@@ -613,25 +730,28 @@ tests interop-tests t-exec unit: regress-prep regress-binaries $(TARGETS)
PATH="$${BUILDDIR}:$${PATH}" \
TEST_ENV=MALLOC_OPTIONS="@TEST_MALLOC_OPTIONS@" \
TEST_MALLOC_OPTIONS="@TEST_MALLOC_OPTIONS@" \
- TEST_SSH_SCP="$${TEST_SSH_SCP}" \
- TEST_SSH_SSH="$${TEST_SSH_SSH}" \
- TEST_SSH_SSHD="$${TEST_SSH_SSHD}" \
- TEST_SSH_SSHAGENT="$${TEST_SSH_SSHAGENT}" \
- TEST_SSH_SSHADD="$${TEST_SSH_SSHADD}" \
- TEST_SSH_SSHKEYGEN="$${TEST_SSH_SSHKEYGEN}" \
- TEST_SSH_SSHPKCS11HELPER="$${TEST_SSH_SSHPKCS11HELPER}" \
- TEST_SSH_SSHKEYSCAN="$${TEST_SSH_SSHKEYSCAN}" \
- TEST_SSH_SFTP="$${TEST_SSH_SFTP}" \
- TEST_SSH_SFTPSERVER="$${TEST_SSH_SFTPSERVER}" \
- TEST_SSH_PLINK="$${TEST_SSH_PLINK}" \
- TEST_SSH_PUTTYGEN="$${TEST_SSH_PUTTYGEN}" \
- TEST_SSH_CONCH="$${TEST_SSH_CONCH}" \
- TEST_SSH_IPV6="$${TEST_SSH_IPV6}" \
- TEST_SSH_UTF8="$${TEST_SSH_UTF8}" \
- TEST_SSH_ECC="$${TEST_SSH_ECC}" \
+ TEST_SSH_SCP="$${BUILDDIR}/scp" \
+ TEST_SSH_SSH="$${BUILDDIR}/ssh" \
+ TEST_SSH_SSHD="$${BUILDDIR}/sshd" \
+ TEST_SSH_SSHAGENT="$${BUILDDIR}/ssh-agent" \
+ TEST_SSH_SSHADD="$${BUILDDIR}/ssh-add" \
+ TEST_SSH_SSHKEYGEN="$${BUILDDIR}/ssh-keygen" \
+ TEST_SSH_SSHPKCS11HELPER="$${BUILDDIR}/ssh-pkcs11-helper" \
+ TEST_SSH_SSHKEYSCAN="$${BUILDDIR}/ssh-keyscan" \
+ TEST_SSH_SFTP="$${BUILDDIR}/sftp" \
+ TEST_SSH_PKCS11_HELPER="$${BUILDDIR}/ssh-pkcs11-helper" \
+ TEST_SSH_SK_HELPER="$${BUILDDIR}/ssh-sk-helper" \
+ TEST_SSH_SFTPSERVER="$${BUILDDIR}/sftp-server" \
+ TEST_SSH_MODULI_FILE="$(abs_top_srcdir)/moduli" \
+ TEST_SSH_PLINK="plink" \
+ TEST_SSH_PUTTYGEN="puttygen" \
+ TEST_SSH_CONCH="conch" \
+ TEST_SSH_IPV6="@TEST_SSH_IPV6@" \
+ TEST_SSH_UTF8="@TEST_SSH_UTF8@" \
+ TEST_SSH_ECC="@TEST_SSH_ECC@" \
TEST_SHELL="${TEST_SHELL}" \
EXEEXT="$(EXEEXT)" \
- $@ && echo all tests passed
+ $@ && echo all $@ passed
compat-tests: $(LIBCOMPAT)
(cd openbsd-compat/regress && $(MAKE))
diff --git a/crypto/openssh/OVERVIEW b/crypto/openssh/OVERVIEW
index 515567f45b0c..cec7cd75b51c 100644
--- a/crypto/openssh/OVERVIEW
+++ b/crypto/openssh/OVERVIEW
@@ -34,11 +34,12 @@ these programs.
- Ssh contains several encryption algorithms. These are all
accessed through the cipher.h interface. The interface code is
- in cipher.c, and the implementations are in libc.
+ in cipher.c, and the implementations are either in libc or
+ LibreSSL.
Multiple Precision Integer Library
- - Uses the SSLeay BIGNUM sublibrary.
+ - Uses the LibreSSL BIGNUM sublibrary.
Random Numbers
@@ -158,4 +159,4 @@ these programs.
uidswap.c uid-swapping
xmalloc.c "safe" malloc routines
-$OpenBSD: OVERVIEW,v 1.14 2018/07/27 03:55:22 dtucker Exp $
+$OpenBSD: OVERVIEW,v 1.15 2018/10/23 05:56:35 djm Exp $
diff --git a/crypto/openssh/PROTOCOL b/crypto/openssh/PROTOCOL
index f75c1c0ae5b0..3141cda6fa37 100644
--- a/crypto/openssh/PROTOCOL
+++ b/crypto/openssh/PROTOCOL
@@ -140,7 +140,7 @@ window space and may be sent even if no window space is available.
NB. due to certain broken SSH implementations aborting upon receipt
of this message (in contravention of RFC4254 section 5.4), this
message is only sent to OpenSSH peers (identified by banner).
-Other SSH implementations may be whitelisted to receive this message
+Other SSH implementations may be listed to receive this message
upon request.
2.2. connection: disallow additional sessions extension
@@ -169,7 +169,7 @@ Note that this is not a general defence against compromised clients
NB. due to certain broken SSH implementations aborting upon receipt
of this message, the no-more-sessions request is only sent to OpenSSH
servers (identified by banner). Other SSH implementations may be
-whitelisted to receive this message upon request.
+listed to receive this message upon request.
2.3. connection: Tunnel forward extension "tun@openssh.com"
@@ -194,7 +194,7 @@ layer 2 frames or layer 3 packets. It may take one of the following values:
SSH_TUNMODE_ETHERNET 2 /* layer 2 frames */
The "tunnel unit number" specifies the remote interface number, or may
-be 0x7fffffff to allow the server to automatically chose an interface. A
+be 0x7fffffff to allow the server to automatically choose an interface. A
server that is not willing to open a client-specified unit should refuse
the request with a SSH_MSG_CHANNEL_OPEN_FAILURE error. On successful
open, the server should reply with SSH_MSG_CHANNEL_OPEN_SUCCESS.
@@ -292,13 +292,14 @@ has completed.
byte SSH_MSG_GLOBAL_REQUEST
string "hostkeys-00@openssh.com"
+ char 0 /* want-reply */
string[] hostkeys
Upon receiving this message, a client should check which of the
supplied host keys are present in known_hosts.
Note that the server may send key types that the client does not
-support. The client should disgregard such keys if they are received.
+support. The client should disregard such keys if they are received.
If the client identifies any keys that are not present for the host,
it should send a "hostkeys-prove@openssh.com" message to request the
@@ -465,6 +466,84 @@ respond with a SSH_FXP_STATUS message.
This extension is advertised in the SSH_FXP_VERSION hello with version
"1".
+3.7. sftp: Extension request "lsetstat@openssh.com"
+
+This request is like the "setstat" command, but sets file attributes on
+symlinks. It is implemented as a SSH_FXP_EXTENDED request with the
+following format:
+
+ uint32 id
+ string "lsetstat@openssh.com"
+ string path
+ ATTRS attrs
+
+See the "setstat" command for more details.
+
+This extension is advertised in the SSH_FXP_VERSION hello with version
+"1".
+
+3.8. sftp: Extension request "limits@openssh.com"
+
+This request is used to determine various limits the server might impose.
+Clients should not attempt to exceed these limits as the server might sever
+the connection immediately.
+
+ uint32 id
+ string "limits@openssh.com"
+
+The server will respond with a SSH_FXP_EXTENDED_REPLY reply:
+
+ uint32 id
+ uint64 max-packet-length
+ uint64 max-read-length
+ uint64 max-write-length
+ uint64 max-open-handles
+
+The 'max-packet-length' applies to the total number of bytes in a
+single SFTP packet. Servers SHOULD set this at least to 34000.
+
+The 'max-read-length' is the largest length in a SSH_FXP_READ packet.
+Even if the client requests a larger size, servers will usually respond
+with a shorter SSH_FXP_DATA packet. Servers SHOULD set this at least to
+32768.
+
+The 'max-write-length' is the largest length in a SSH_FXP_WRITE packet
+the server will accept. Servers SHOULD set this at least to 32768.
+
+The 'max-open-handles' is the maximum number of active handles that the
+server allows (e.g. handles created by SSH_FXP_OPEN and SSH_FXP_OPENDIR
+packets). Servers MAY count internal file handles against this limit
+(e.g. system logging or stdout/stderr), so clients SHOULD NOT expect to
+open this many handles in practice.
+
+If the server doesn't enforce a specific limit, then the field may be
+set to 0. This implies the server relies on the OS to enforce limits
+(e.g. available memory or file handles), and such limits might be
+dynamic. The client SHOULD take care to not try to exceed reasonable
+limits.
+
+This extension is advertised in the SSH_FXP_VERSION hello with version
+"1".
+
+3.9. sftp: Extension request "expand-path@openssh.com"
+
+This request supports canonicalisation of relative paths and
+those that need tilde-expansion, i.e. "~", "~/..." and "~user/..."
+These paths are expanded using shell-like rules and the resultant
+path is canonicalised similarly to SSH2_FXP_REALPATH.
+
+It is implemented as a SSH_FXP_EXTENDED request with the following
+format:
+
+ uint32 id
+ string "expand-path@openssh.com"
+ string path
+
+Its reply is the same format as that of SSH2_FXP_REALPATH.
+
+This extension is advertised in the SSH_FXP_VERSION hello with version
+"1".
+
4. Miscellaneous changes
4.1 Public key format
@@ -496,4 +575,4 @@ OpenSSH's connection multiplexing uses messages as described in
PROTOCOL.mux over a Unix domain socket for communications between a
master instance and later clients.
-$OpenBSD: PROTOCOL,v 1.36 2018/10/02 12:51:58 djm Exp $
+$OpenBSD: PROTOCOL,v 1.42 2021/08/09 23:47:44 djm Exp $
diff --git a/crypto/openssh/PROTOCOL.agent b/crypto/openssh/PROTOCOL.agent
index da3381942e08..ed47146a30ee 100644
--- a/crypto/openssh/PROTOCOL.agent
+++ b/crypto/openssh/PROTOCOL.agent
@@ -1,5 +1,5 @@
This file used to contain a description of the SSH agent protocol
-implemented by OpenSSH. It has since been superseded by an Internet-
-draft that is available from:
+implemented by OpenSSH. It has since been superseded by
+https://tools.ietf.org/html/draft-miller-ssh-agent-04
-https://tools.ietf.org/html/draft-miller-ssh-agent-02
+$OpenBSD: PROTOCOL.agent,v 1.14 2020/10/06 07:12:04 dtucker Exp $
diff --git a/crypto/openssh/PROTOCOL.certkeys b/crypto/openssh/PROTOCOL.certkeys
index 11363fdc370e..68622e60743c 100644
--- a/crypto/openssh/PROTOCOL.certkeys
+++ b/crypto/openssh/PROTOCOL.certkeys
@@ -36,6 +36,7 @@ Certified keys are represented using new key types:
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
Two additional types exist for RSA certificates to force use of
SHA-2 signatures (SHA-256 and SHA-512 respectively):
@@ -44,7 +45,7 @@ SHA-2 signatures (SHA-256 and SHA-512 respectively):
rsa-sha2-512-cert-v01@openssh.com
These RSA/SHA-2 types should not appear in keys at rest or transmitted
-on their wire, but do appear in a SSH_MSG_KEXINIT's host-key algorithms
+on the wire, but do appear in a SSH_MSG_KEXINIT's host-key algorithms
field or in the "public key algorithm name" field of a "publickey"
SSH_USERAUTH_REQUEST to indicate that the signature will use the
specified algorithm.
@@ -158,12 +159,11 @@ p, q, g, y are the DSA parameters as described in FIPS-186-2.
curve and public key are respectively the ECDSA "[identifier]" and "Q"
defined in section 3.1 of RFC5656.
-pk is the encoded Ed25519 public key as defined by
-draft-josefsson-eddsa-ed25519-03.
+pk is the encoded Ed25519 public key as defined by RFC8032.
serial is an optional certificate serial number set by the CA to
provide an abbreviated way to refer to certificates from that CA.
-If a CA does not wish to number its certificates it must set this
+If a CA does not wish to number its certificates, it must set this
field to zero.
type specifies whether this certificate is for identification of a user
@@ -216,13 +216,13 @@ signature is computed over all preceding fields from the initial string
up to, and including the signature key. Signatures are computed and
encoded according to the rules defined for the CA's public key algorithm
(RFC4253 section 6.6 for ssh-rsa and ssh-dss, RFC5656 for the ECDSA
-types), and draft-josefsson-eddsa-ed25519-03 for Ed25519.
+types, and RFC8032 for Ed25519).
Critical options
----------------
The critical options section of the certificate specifies zero or more
-options on the certificates validity. The format of this field
+options on the certificate's validity. The format of this field
is a sequence of zero or more tuples:
string name
@@ -233,7 +233,7 @@ sequence. Each named option may only appear once in a certificate.
The name field identifies the option and the data field encodes
option-specific information (see below). All options are
-"critical", if an implementation does not recognise a option
+"critical"; if an implementation does not recognise a option,
then the validating party should refuse to accept the certificate.
Custom options should append the originating author or organisation's
@@ -255,10 +255,18 @@ source-address string Comma-separated list of source addresses
for authentication. Addresses are
specified in CIDR format (nn.nn.nn.nn/nn
or hhhh::hhhh/nn).
- If this option is not present then
+ If this option is not present, then
certificates may be presented from any
source address.
+verify-required empty Flag indicating that signatures made
+ with this certificate must assert FIDO
+ user verification (e.g. PIN or
+ biometric). This option only makes sense
+ for the U2F/FIDO security key types that
+ support this feature in their signature
+ formats.
+
Extensions
----------
@@ -279,6 +287,13 @@ their data fields are:
Name Format Description
-----------------------------------------------------------------------------
+no-touch-required empty Flag indicating that signatures made
+ with this certificate need not assert
+ FIDO user presence. This option only
+ makes sense for the U2F/FIDO security
+ key types that support this feature in
+ their signature formats.
+
permit-X11-forwarding empty Flag indicating that X11 forwarding
should be permitted. X11 forwarding will
be refused if this option is absent.
@@ -290,7 +305,7 @@ permit-agent-forwarding empty Flag indicating that agent forwarding
permit-port-forwarding empty Flag indicating that port-forwarding
should be allowed. If this option is
- not present then no port forwarding will
+ not present, then no port forwarding will
be allowed.
permit-pty empty Flag indicating that PTY allocation
@@ -303,4 +318,4 @@ permit-user-rc empty Flag indicating that execution of
of this script will not be permitted if
this option is not present.
-$OpenBSD: PROTOCOL.certkeys,v 1.15 2018/07/03 11:39:54 djm Exp $
+$OpenBSD: PROTOCOL.certkeys,v 1.19 2021/06/05 13:47:00 naddy Exp $
diff --git a/crypto/openssh/PROTOCOL.chacha20poly1305 b/crypto/openssh/PROTOCOL.chacha20poly1305
index 9ce2a1e3a146..0bfff28d70ef 100644
--- a/crypto/openssh/PROTOCOL.chacha20poly1305
+++ b/crypto/openssh/PROTOCOL.chacha20poly1305
@@ -34,7 +34,7 @@ Detailed Construction
The chacha20-poly1305@openssh.com cipher requires 512 bits of key
material as output from the SSH key exchange. This forms two 256 bit
keys (K_1 and K_2), used by two separate instances of chacha20.
-The first 256 bits consitute K_2 and the second 256 bits become
+The first 256 bits constitute K_2 and the second 256 bits become
K_1.
The instance keyed by K_1 is a stream cipher that is used only
@@ -103,5 +103,5 @@ References
[3] "ChaCha20 and Poly1305 based Cipher Suites for TLS", Adam Langley
http://tools.ietf.org/html/draft-agl-tls-chacha20poly1305-03
-$OpenBSD: PROTOCOL.chacha20poly1305,v 1.4 2018/04/10 00:10:49 djm Exp $
+$OpenBSD: PROTOCOL.chacha20poly1305,v 1.5 2020/02/21 00:04:43 dtucker Exp $
diff --git a/crypto/openssh/PROTOCOL.key b/crypto/openssh/PROTOCOL.key
index 959bd7aeec22..38df268b6536 100644
--- a/crypto/openssh/PROTOCOL.key
+++ b/crypto/openssh/PROTOCOL.key
@@ -35,9 +35,9 @@ of the cipher block size.
uint32 checkint
uint32 checkint
- string privatekey1
+ byte[] privatekey1
string comment1
- string privatekey2
+ byte[] privatekey2
string comment2
...
string privatekeyN
@@ -48,6 +48,9 @@ of the cipher block size.
...
char padlen % 255
+where each private key is encoded using the same rules as used for
+SSH agent.
+
Before the key is encrypted, a random integer is assigned
to both checkint fields so successful decryption can be
quickly checked by verifying that both checkint fields
@@ -65,4 +68,4 @@ For unencrypted keys the cipher "none" and the KDF "none"
are used with empty passphrases. The options if the KDF "none"
are the empty string.
-$OpenBSD: PROTOCOL.key,v 1.1 2013/12/06 13:34:54 markus Exp $
+$OpenBSD: PROTOCOL.key,v 1.2 2021/05/07 02:29:40 djm Exp $
diff --git a/crypto/openssh/PROTOCOL.mux b/crypto/openssh/PROTOCOL.mux
index 77a0780a5234..5fc4c06b9660 100644
--- a/crypto/openssh/PROTOCOL.mux
+++ b/crypto/openssh/PROTOCOL.mux
@@ -39,7 +39,7 @@ messages between the client and server. The client therefore must
speak a significant subset of the SSH protocol, but in return is able
to access basically the full suite of connection protocol features.
Moreover, as no file descriptor passing is required, the connection
-supporting a proxy client may iteself be forwarded or relayed to another
+supporting a proxy client may itself be forwarded or relayed to another
host if necessary.
1. Connection setup
@@ -295,4 +295,4 @@ XXX session inspection via master
XXX signals via mux request
XXX list active connections via mux
-$OpenBSD: PROTOCOL.mux,v 1.11 2018/09/26 07:30:05 djm Exp $
+$OpenBSD: PROTOCOL.mux,v 1.12 2020/03/13 03:17:07 djm Exp $
diff --git a/crypto/openssh/PROTOCOL.sshsig b/crypto/openssh/PROTOCOL.sshsig
new file mode 100644
index 000000000000..78457ddfc653
--- /dev/null
+++ b/crypto/openssh/PROTOCOL.sshsig
@@ -0,0 +1,100 @@
+This document describes a lightweight SSH Signature format
+that is compatible with SSH keys and wire formats.
+
+At present, only detached and armored signatures are supported.
+
+1. Armored format
+
+The Armored SSH signatures consist of a header, a base64
+encoded blob, and a footer.
+
+The header is the string "-----BEGIN SSH SIGNATURE-----"
+followed by a newline. The footer is the string
+"-----END SSH SIGNATURE-----" immediately after a newline.
+
+The header MUST be present at the start of every signature.
+Files containing the signature MUST start with the header.
+Likewise, the footer MUST be present at the end of every
+signature.
+
+The base64 encoded blob SHOULD be broken up by newlines
+every 76 characters.
+
+Example:
+
+-----BEGIN SSH SIGNATURE-----
+U1NIU0lHAAAAAQAAADMAAAALc3NoLWVkMjU1MTkAAAAgJKxoLBJBivUPNTUJUSslQTt2hD
+jozKvHarKeN8uYFqgAAAADZm9vAAAAAAAAAFMAAAALc3NoLWVkMjU1MTkAAABAKNC4IEbt
+Tq0Fb56xhtuE1/lK9H9RZJfON4o6hE9R4ZGFX98gy0+fFJ/1d2/RxnZky0Y7GojwrZkrHT
+FgCqVWAQ==
+-----END SSH SIGNATURE-----
+
+2. Blob format
+
+#define MAGIC_PREAMBLE "SSHSIG"
+#define SIG_VERSION 0x01
+
+ byte[6] MAGIC_PREAMBLE
+ uint32 SIG_VERSION
+ string publickey
+ string namespace
+ string reserved
+ string hash_algorithm
+ string signature
+
+The publickey field MUST contain the serialisation of the
+public key used to make the signature using the usual SSH
+encoding rules, i.e RFC4253, RFC5656,
+draft-ietf-curdle-ssh-ed25519-ed448, etc.
+
+Verifiers MUST reject signatures with versions greater than those
+they support.
+
+The purpose of the namespace value is to specify a unambiguous
+interpretation domain for the signature, e.g. file signing.
+This prevents cross-protocol attacks caused by signatures
+intended for one intended domain being accepted in another.
+The namespace value MUST NOT be the empty string.
+
+The reserved value is present to encode future information
+(e.g. tags) into the signature. Implementations should ignore
+the reserved field if it is not empty.
+
+Data to be signed is first hashed with the specified hash_algorithm.
+This is done to limit the amount of data presented to the signature
+operation, which may be of concern if the signing key is held in limited
+or slow hardware or on a remote ssh-agent. The supported hash algorithms
+are "sha256" and "sha512".
+
+The signature itself is made using the SSH signature algorithm and
+encoding rules for the chosen key type. For RSA signatures, the
+signature algorithm must be "rsa-sha2-512" or "rsa-sha2-256" (i.e.
+not the legacy RSA-SHA1 "ssh-rsa").
+
+This blob is encoded as a string using the RFC4253 encoding
+rules and base64 encoded to form the middle part of the
+armored signature.
+
+
+3. Signed Data, of which the signature goes into the blob above
+
+#define MAGIC_PREAMBLE "SSHSIG"
+
+ byte[6] MAGIC_PREAMBLE
+ string namespace
+ string reserved
+ string hash_algorithm
+ string H(message)
+
+The preamble is the six-byte sequence "SSHSIG". It is included to
+ensure that manual signatures can never be confused with any message
+signed during SSH user or host authentication.
+
+The reserved value is present to encode future information
+(e.g. tags) into the signature. Implementations should ignore
+the reserved field if it is not empty.
+
+The data is concatenated and passed to the SSH signing
+function.
+
+$OpenBSD: PROTOCOL.sshsig,v 1.4 2020/08/31 00:17:41 djm Exp $
diff --git a/crypto/openssh/PROTOCOL.u2f b/crypto/openssh/PROTOCOL.u2f
new file mode 100644
index 000000000000..f8ca56b11c8c
--- /dev/null
+++ b/crypto/openssh/PROTOCOL.u2f
@@ -0,0 +1,309 @@
+This document describes OpenSSH's support for U2F/FIDO security keys.
+
+Background
+----------
+
+U2F is an open standard for two-factor authentication hardware, widely
+used for user authentication to websites. U2F tokens are ubiquitous,
+available from a number of manufacturers and are currently by far the
+cheapest way for users to achieve hardware-backed credential storage.
+
+The U2F protocol however cannot be trivially used as an SSH protocol key
+type as both the inputs to the signature operation and the resultant
+signature differ from those specified for SSH. For similar reasons,
+integration of U2F devices cannot be achieved via the PKCS#11 API.
+
+U2F also offers a number of features that are attractive in the context
+of SSH authentication. They can be configured to require indication
+of "user presence" for each signature operation (typically achieved
+by requiring the user touch the key). They also offer an attestation
+mechanism at key enrollment time that can be used to prove that a
+given key is backed by hardware. Finally the signature format includes
+a monotonic signature counter that can be used (at scale) to detect
+concurrent use of a private key, should it be extracted from hardware.
+
+U2F private keys are generated through an enrollment operation,
+which takes an application ID - a URL-like string, typically "ssh:"
+in this case, but a HTTP origin for the case of web authentication,
+and a challenge string (typically randomly generated). The enrollment
+operation returns a public key, a key handle that must be used to invoke
+the hardware-backed private key, some flags and signed attestation
+information that may be used to verify that a private key is hosted on a
+particular hardware instance.
+
+It is common for U2F hardware to derive private keys from the key handle
+in conjunction with a small per-device secret that is unique to the
+hardware, thus requiring little on-device storage for an effectively
+unlimited number of supported keys. This drives the requirement that
+the key handle be supplied for each signature operation. U2F tokens
+primarily use ECDSA signatures in the NIST-P256 field, though the FIDO2
+standard specifies additional key types, including one based on Ed25519.
+
+Use of U2F security keys does not automatically imply multi-factor
+authentication. From sshd's perspective, a security key constitutes a
+single factor of authentication, even if protected by a PIN or biometric
+authentication. To enable multi-factor authentication in ssh, please
+refer to the AuthenticationMethods option in sshd_config(5).
+
+
+SSH U2F Key formats
+-------------------
+
+OpenSSH integrates U2F as new key and corresponding certificate types:
+
+ sk-ecdsa-sha2-nistp256@openssh.com
+ sk-ecdsa-sha2-nistp256-cert-v01@openssh.com
+ sk-ssh-ed25519@openssh.com
+ sk-ssh-ed25519-cert-v01@openssh.com
+
+While each uses ecdsa-sha256-nistp256 as the underlying signature primitive,
+keys require extra information in the public and private keys, and in
+the signature object itself. As such they cannot be made compatible with
+the existing ecdsa-sha2-nistp* key types.
+
+The format of a sk-ecdsa-sha2-nistp256@openssh.com public key is:
+
+ string "sk-ecdsa-sha2-nistp256@openssh.com"
+ string curve name
+ ec_point Q
+ string application (user-specified, but typically "ssh:")
+
+The corresponding private key contains:
+
+ string "sk-ecdsa-sha2-nistp256@openssh.com"
+ string curve name
+ ec_point Q
+ string application (user-specified, but typically "ssh:")
+ uint8 flags
+ string key_handle
+ string reserved
+
+The format of a sk-ssh-ed25519@openssh.com public key is:
+
+ string "sk-ssh-ed25519@openssh.com"
+ string public key
+ string application (user-specified, but typically "ssh:")
+
+With a private half consisting of:
+
+ string "sk-ssh-ed25519@openssh.com"
+ string public key
+ string application (user-specified, but typically "ssh:")
+ uint8 flags
+ string key_handle
+ string reserved
+
+The certificate form for SSH U2F keys appends the usual certificate
+information to the public key:
+
+ string "sk-ecdsa-sha2-nistp256-cert-v01@openssh.com"
+ string nonce
+ string curve name
+ ec_point Q
+ string application
+ uint64 serial
+ uint32 type
+ string key id
+ string valid principals
+ uint64 valid after
+ uint64 valid before
+ string critical options
+ string extensions
+ string reserved
+ string signature key
+ string signature
+
+and for security key ed25519 certificates:
+
+ string "sk-ssh-ed25519-cert-v01@openssh.com"
+ string nonce
+ string public key
+ string application
+ uint64 serial
+ uint32 type
+ string key id
+ string valid principals
+ uint64 valid after
+ uint64 valid before
+ string critical options
+ string extensions
+ string reserved
+ string signature key
+ string signature
+
+Both security key certificates use the following encoding for private keys:
+
+ string type (e.g. "sk-ssh-ed25519-cert-v01@openssh.com")
+ string pubkey (the above key/cert structure)
+ string application
+ uint8 flags
+ string key_handle
+ string reserved
+
+During key generation, the hardware also returns attestation information
+that may be used to cryptographically prove that a given key is
+hardware-backed. Unfortunately, the protocol required for this proof is
+not privacy-preserving and may be used to identify U2F tokens with at
+least manufacturer and batch number granularity. For this reason, we
+choose not to include this information in the public key or save it by
+default.
+
+Attestation information is useful for out-of-band key and certificate
+registration workflows, e.g. proving to a CA that a key is backed
+by trusted hardware before it will issue a certificate. To support this
+case, OpenSSH optionally allows retaining the attestation information
+at the time of key generation. It will take the following format:
+
+ string "ssh-sk-attest-v01"
+ string attestation certificate
+ string enrollment signature
+ string authenticator data (CBOR encoded)
+ uint32 reserved flags
+ string reserved string
+
+A previous version of this format, emitted prior to OpenSSH 8.4 omitted
+the authenticator data.
+
+ string "ssh-sk-attest-v00"
+ string attestation certificate
+ string enrollment signature
+ uint32 reserved flags
+ string reserved string
+
+OpenSSH treats the attestation certificate and enrollment signatures as
+opaque objects and does no interpretation of them itself.
+
+SSH U2F signatures
+------------------
+
+In addition to the message to be signed, the U2F signature operation
+requires the key handle and a few additional parameters. The signature
+is signed over a blob that consists of:
+
+ byte[32] SHA256(application)
+ byte flags (including "user present", extensions present)
+ uint32 counter
+ byte[] extensions
+ byte[32] SHA256(message)
+
+No extensions are yet defined for SSH use. If any are defined in the future,
+it will be possible to infer their presence from the contents of the "flags"
+value.
+
+The signature returned from U2F hardware takes the following format:
+
+ byte flags (including "user present")
+ uint32 counter
+ byte[] ecdsa_signature (in X9.62 format).
+
+For use in the SSH protocol, we wish to avoid server-side parsing of ASN.1
+format data in the pre-authentication attack surface. Therefore, the
+signature format used on the wire in SSH2_USERAUTH_REQUEST packets will
+be reformatted to better match the existing signature encoding:
+
+ string "sk-ecdsa-sha2-nistp256@openssh.com"
+ string ecdsa_signature
+ byte flags
+ uint32 counter
+
+Where the "ecdsa_signature" field follows the RFC5656 ECDSA signature
+encoding:
+
+ mpint r
+ mpint s
+
+For Ed25519 keys the signature is encoded as:
+
+ string "sk-ssh-ed25519@openssh.com"
+ string signature
+ byte flags
+ uint32 counter
+
+webauthn signatures
+-------------------
+
+The W3C/FIDO webauthn[1] standard defines a mechanism for a web browser to
+interact with FIDO authentication tokens. This standard builds upon the
+FIDO standards, but requires different signature contents to raw FIDO
+messages. OpenSSH supports ECDSA/p256 webauthn signatures through the
+"webauthn-sk-ecdsa-sha2-nistp256@openssh.com" signature algorithm.
+
+The wire encoding for a webauthn-sk-ecdsa-sha2-nistp256@openssh.com
+signature is similar to the sk-ecdsa-sha2-nistp256@openssh.com format:
+
+ string "webauthn-sk-ecdsa-sha2-nistp256@openssh.com"
+ string ecdsa_signature
+ byte flags
+ uint32 counter
+ string origin
+ string clientData
+ string extensions
+
+Where "origin" is the HTTP origin making the signature, "clientData" is
+the JSON-like structure signed by the browser and "extensions" are any
+extensions used in making the signature.
+
+[1] https://www.w3.org/TR/webauthn-2/
+
+ssh-agent protocol extensions
+-----------------------------
+
+ssh-agent requires a protocol extension to support U2F keys. At
+present the closest analogue to Security Keys in ssh-agent are PKCS#11
+tokens, insofar as they require a middleware library to communicate with
+the device that holds the keys. Unfortunately, the protocol message used
+to add PKCS#11 keys to ssh-agent does not include any way to send the
+key handle to the agent as U2F keys require.
+
+To avoid this, without having to add wholly new messages to the agent
+protocol, we will use the existing SSH2_AGENTC_ADD_ID_CONSTRAINED message
+with a new key constraint extension to encode a path to the middleware
+library for the key. The format of this constraint extension would be:
+
+ byte SSH_AGENT_CONSTRAIN_EXTENSION
+ string sk-provider@openssh.com
+ string middleware path
+
+This constraint-based approach does not present any compatibility
+problems.
+
+OpenSSH integration
+-------------------
+
+U2F tokens may be attached via a number of means, including USB and NFC.
+The USB interface is standardised around a HID protocol, but we want to
+be able to support other transports as well as dummy implementations for
+regress testing. For this reason, OpenSSH shall support a dynamically-
+loaded middleware libraries to communicate with security keys, but offer
+support for the common case of USB HID security keys internally.
+
+The middleware library need only expose a handful of functions and
+numbers listed in sk-api.h. Included in the defined numbers is a
+SSH_SK_VERSION_MAJOR that should be incremented for each incompatible
+API change.
+
+miscellaneous options may be passed to the middleware as a NULL-
+terminated array of pointers to struct sk_option. The middleware may
+ignore unsupported or unknown options unless the "required" flag is set,
+in which case it should return failure if an unsupported option is
+requested.
+
+At present the following options names are supported:
+
+ "device"
+
+ Specifies a specific FIDO device on which to perform the
+ operation. The value in this field is interpreted by the
+ middleware but it would be typical to specify a path to
+ a /dev node for the device in question.
+
+ "user"
+
+ Specifies the FIDO2 username used when enrolling a key,
+ overriding OpenSSH's default of using an all-zero username.
+
+In OpenSSH, the middleware will be invoked by using a similar mechanism to
+ssh-pkcs11-helper to provide address-space containment of the
+middleware from ssh-agent.
+
+$OpenBSD: PROTOCOL.u2f,v 1.26 2020/09/09 03:08:01 djm Exp $
diff --git a/crypto/openssh/README b/crypto/openssh/README
index 05916459c08b..5c7f8647dc8e 100644
--- a/crypto/openssh/README
+++ b/crypto/openssh/README
@@ -1,4 +1,4 @@
-See https://www.openssh.com/releasenotes.html#7.9p1 for the release notes.
+See https://www.openssh.com/releasenotes.html#8.7p1 for the release notes.
Please read https://www.openssh.com/report.html for bug reporting
instructions and note that we do not use Github for bug reporting or
@@ -15,7 +15,7 @@ Aaron Campbell, Bob Beck, Markus Friedl, Niels Provos, Theo de Raadt,
and Dug Song. It has a homepage at https://www.openssh.com/
This port consists of the re-introduction of autoconf support, PAM
-support, EGD[1]/PRNGD[2] support and replacements for OpenBSD library
+support, EGD/PRNGD support and replacements for OpenBSD library
functions that are (regrettably) absent from other unices. This port
has been best tested on AIX, Cygwin, HP-UX, Linux, MacOS/X,
FreeBSD, NetBSD, OpenBSD, OpenServer, Solaris and UnixWare.
@@ -26,37 +26,27 @@ The PAM support is now more functional than the popular packages of
commercial ssh-1.2.x. It checks "account" and "session" modules for
all logins, not just when using password authentication.
-OpenSSH depends on Zlib[3], OpenSSL[4], and optionally PAM[5] and
-libedit[6]
-
There is now several mailing lists for this port of OpenSSH. Please
refer to https://www.openssh.com/list.html for details on how to join.
-Please send bug reports and patches to the mailing list
-openssh-unix-dev@mindrot.org. The list is open to posting by unsubscribed
-users. Code contribution are welcomed, but please follow the OpenBSD
-style guidelines[7].
+Please send bug reports and patches to https://bugzilla.mindrot.org or
+the mailing list openssh-unix-dev@mindrot.org. To mitigate spam, the
+list only allows posting from subscribed addresses. Code contribution
+are welcomed, but please follow the OpenBSD style guidelines[1].
-Please refer to the INSTALL document for information on how to install
-OpenSSH on your system.
+Please refer to the INSTALL document for information on dependencies and
+how to install OpenSSH on your system.
Damien Miller <djm@mindrot.org>
Miscellania -
-This version of OpenSSH is based upon code retrieved from the OpenBSD
-CVS repository which in turn was based on the last free sample
-implementation released by Tatu Ylonen.
+This version of OpenSSH is based upon code retrieved from the OpenBSD CVS
+repository which in turn was based on the last free sample implementation
+released by Tatu Ylonen.
References -
[0] https://www.openssh.com/
-[1] http://www.lothar.com/tech/crypto/
-[2] http://prngd.sourceforge.net/
-[3] https://www.zlib.net/
-[4] https://www.openssl.org/
-[5] https://www.openpam.org
- https://www.kernel.org/pub/linux/libs/pam/
- (PAM also is standard on Solaris and HP-UX 11)
-[6] https://thrysoee.dk/editline/ (portable version)
-[7] https://man.openbsd.org/style.9
+[1] https://man.openbsd.org/style.9
+
diff --git a/crypto/openssh/README.dns b/crypto/openssh/README.dns
index 97879183e396..29ecaee8da39 100644
--- a/crypto/openssh/README.dns
+++ b/crypto/openssh/README.dns
@@ -1,10 +1,10 @@
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.
+OpenSSH contains support for verifying host keys using DNS as described
+in https://tools.ietf.org/html/rfc4255. 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
diff --git a/crypto/openssh/README.md b/crypto/openssh/README.md
new file mode 100644
index 000000000000..de4717737eac
--- /dev/null
+++ b/crypto/openssh/README.md
@@ -0,0 +1,84 @@
+# Portable OpenSSH
+
+[![C/C++ CI](https://github.com/openssh/openssh-portable/actions/workflows/c-cpp.yml/badge.svg)](https://github.com/openssh/openssh-portable/actions/workflows/c-cpp.yml)
+[![Fuzzing Status](https://oss-fuzz-build-logs.storage.googleapis.com/badges/openssh.svg)](https://bugs.chromium.org/p/oss-fuzz/issues/list?sort=-opened&can=1&q=proj:openssh)
+
+OpenSSH is a complete implementation of the SSH protocol (version 2) for secure remote login, command execution and file transfer. It includes a client ``ssh`` and server ``sshd``, file transfer utilities ``scp`` and ``sftp`` as well as tools for key generation (``ssh-keygen``), run-time key storage (``ssh-agent``) and a number of supporting programs.
+
+This is a port of OpenBSD's [OpenSSH](https://openssh.com) to most Unix-like operating systems, including Linux, OS X and Cygwin. Portable OpenSSH polyfills OpenBSD APIs that are not available elsewhere, adds sshd sandboxing for more operating systems and includes support for OS-native authentication and auditing (e.g. using PAM).
+
+## Documentation
+
+The official documentation for OpenSSH are the man pages for each tool:
+
+* [ssh(1)](https://man.openbsd.org/ssh.1)
+* [sshd(8)](https://man.openbsd.org/sshd.8)
+* [ssh-keygen(1)](https://man.openbsd.org/ssh-keygen.1)
+* [ssh-agent(1)](https://man.openbsd.org/ssh-agent.1)
+* [scp(1)](https://man.openbsd.org/scp.1)
+* [sftp(1)](https://man.openbsd.org/sftp.1)
+* [ssh-keyscan(8)](https://man.openbsd.org/ssh-keyscan.8)
+* [sftp-server(8)](https://man.openbsd.org/sftp-server.8)
+
+## Stable Releases
+
+Stable release tarballs are available from a number of [download mirrors](https://www.openssh.com/portable.html#downloads). We recommend the use of a stable release for most users. Please read the [release notes](https://www.openssh.com/releasenotes.html) for details of recent changes and potential incompatibilities.
+
+## Building Portable OpenSSH
+
+### Dependencies
+
+Portable OpenSSH is built using autoconf and make. It requires a working C compiler, standard library and headers.
+
+``libcrypto`` from either [LibreSSL](https://www.libressl.org/) or [OpenSSL](https://www.openssl.org) may also be used, but OpenSSH may be built without it supporting a subset of crypto algorithms.
+
+[zlib](https://www.zlib.net/) is optional; without it transport compression is not supported.
+
+FIDO security token support needs [libfido2](https://github.com/Yubico/libfido2) and its dependencies. Also, certain platforms and build-time options may require additional dependencies; see README.platform for details.
+
+### Building a release
+
+Releases include a pre-built copy of the ``configure`` script and may be built using:
+
+```
+tar zxvf openssh-X.YpZ.tar.gz
+cd openssh
+./configure # [options]
+make && make tests
+```
+
+See the [Build-time Customisation](#build-time-customisation) section below for configure options. If you plan on installing OpenSSH to your system, then you will usually want to specify destination paths.
+
+### Building from git
+
+If building from git, you'll need [autoconf](https://www.gnu.org/software/autoconf/) installed to build the ``configure`` script. The following commands will check out and build portable OpenSSH from git:
+
+```
+git clone https://github.com/openssh/openssh-portable # or https://anongit.mindrot.org/openssh.git
+cd openssh-portable
+autoreconf
+./configure
+make && make tests
+```
+
+### Build-time Customisation
+
+There are many build-time customisation options available. All Autoconf destination path flags (e.g. ``--prefix``) are supported (and are usually required if you want to install OpenSSH).
+
+For a full list of available flags, run ``configure --help`` but a few of the more frequently-used ones are described below. Some of these flags will require additional libraries and/or headers be installed.
+
+Flag | Meaning
+--- | ---
+``--with-pam`` | Enable [PAM](https://en.wikipedia.org/wiki/Pluggable_authentication_module) support. [OpenPAM](https://www.openpam.org/), [Linux PAM](http://www.linux-pam.org/) and Solaris PAM are supported.
+``--with-libedit`` | Enable [libedit](https://www.thrysoee.dk/editline/) support for sftp.
+``--with-kerberos5`` | Enable Kerberos/GSSAPI support. Both [Heimdal](https://www.h5l.org/) and [MIT](https://web.mit.edu/kerberos/) Kerberos implementations are supported.
+``--with-selinux`` | Enable [SELinux](https://en.wikipedia.org/wiki/Security-Enhanced_Linux) support.
+``--with-security-key-builtin`` | Include built-in support for U2F/FIDO2 security keys. This requires [libfido2](https://github.com/Yubico/libfido2) be installed.
+
+## Development
+
+Portable OpenSSH development is discussed on the [openssh-unix-dev mailing list](https://lists.mindrot.org/mailman/listinfo/openssh-unix-dev) ([archive mirror](https://marc.info/?l=openssh-unix-dev)). Bugs and feature requests are tracked on our [Bugzilla](https://bugzilla.mindrot.org/).
+
+## Reporting bugs
+
+_Non-security_ bugs may be reported to the developers via [Bugzilla](https://bugzilla.mindrot.org/) or via the mailing list above. Security bugs should be reported to [openssh@openssh.com](mailto:openssh.openssh.com).
diff --git a/crypto/openssh/README.platform b/crypto/openssh/README.platform
index 9210e07c8c6e..7b754ba42a10 100644
--- a/crypto/openssh/README.platform
+++ b/crypto/openssh/README.platform
@@ -1,19 +1,19 @@
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).
+
+Beginning with OpenSSH 3.8p1, sshd will honour an account's password
+expiry settings, where prior to that 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
+As of OpenSSH 4.0p1, 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
diff --git a/crypto/openssh/README.privsep b/crypto/openssh/README.privsep
index 460e90565202..d658c46db11e 100644
--- a/crypto/openssh/README.privsep
+++ b/crypto/openssh/README.privsep
@@ -5,13 +5,10 @@ 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).
-
-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
+Privilege separation is now mandatory. 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
diff --git a/crypto/openssh/aclocal.m4 b/crypto/openssh/aclocal.m4
index 25ecc49a2203..9d85d34d4772 100644
--- a/crypto/openssh/aclocal.m4
+++ b/crypto/openssh/aclocal.m4
@@ -1,186 +1,15 @@
-dnl OpenSSH-specific autoconf macros
-dnl
+# generated automatically by aclocal 1.16.3 -*- Autoconf -*-
-dnl OSSH_CHECK_CFLAG_COMPILE(check_flag[, define_flag])
-dnl Check that $CC accepts a flag 'check_flag'. If it is supported append
-dnl 'define_flag' to $CFLAGS. If 'define_flag' is not specified, then append
-dnl 'check_flag'.
-AC_DEFUN([OSSH_CHECK_CFLAG_COMPILE], [{
- AC_MSG_CHECKING([if $CC supports compile flag $1])
- saved_CFLAGS="$CFLAGS"
- CFLAGS="$CFLAGS $WERROR $1"
- _define_flag="$2"
- test "x$_define_flag" = "x" && _define_flag="$1"
- AC_COMPILE_IFELSE([AC_LANG_SOURCE([[
-#include <stdlib.h>
-#include <stdio.h>
-int main(int argc, char **argv) {
- /* Some math to catch -ftrapv problems in the toolchain */
- int i = 123 * argc, j = 456 + argc, k = 789 - argc;
- float l = i * 2.1;
- double m = l / 0.5;
- long long int n = argc * 12345LL, o = 12345LL * (long long int)argc;
- printf("%d %d %d %f %f %lld %lld\n", i, j, k, l, m, n, o);
- exit(0);
-}
- ]])],
- [
-if $ac_cv_path_EGREP -i "unrecognized option|warning.*ignored" conftest.err >/dev/null
-then
- AC_MSG_RESULT([no])
- CFLAGS="$saved_CFLAGS"
-else
- AC_MSG_RESULT([yes])
- CFLAGS="$saved_CFLAGS $_define_flag"
-fi],
- [ AC_MSG_RESULT([no])
- CFLAGS="$saved_CFLAGS" ]
- )
-}])
+# Copyright (C) 1996-2020 Free Software Foundation, Inc.
-dnl OSSH_CHECK_CFLAG_LINK(check_flag[, define_flag])
-dnl Check that $CC accepts a flag 'check_flag'. If it is supported append
-dnl 'define_flag' to $CFLAGS. If 'define_flag' is not specified, then append
-dnl 'check_flag'.
-AC_DEFUN([OSSH_CHECK_CFLAG_LINK], [{
- AC_MSG_CHECKING([if $CC supports compile flag $1 and linking succeeds])
- saved_CFLAGS="$CFLAGS"
- CFLAGS="$CFLAGS $WERROR $1"
- _define_flag="$2"
- test "x$_define_flag" = "x" && _define_flag="$1"
- AC_LINK_IFELSE([AC_LANG_SOURCE([[
-#include <stdlib.h>
-#include <stdio.h>
-int main(int argc, char **argv) {
- /* Some math to catch -ftrapv problems in the toolchain */
- int i = 123 * argc, j = 456 + argc, k = 789 - argc;
- float l = i * 2.1;
- double m = l / 0.5;
- long long int n = argc * 12345LL, o = 12345LL * (long long int)argc;
- long long int p = n * o;
- printf("%d %d %d %f %f %lld %lld %lld\n", i, j, k, l, m, n, o, p);
- exit(0);
-}
- ]])],
- [
-if $ac_cv_path_EGREP -i "unrecognized option|warning.*ignored" conftest.err >/dev/null
-then
- AC_MSG_RESULT([no])
- CFLAGS="$saved_CFLAGS"
-else
- AC_MSG_RESULT([yes])
- CFLAGS="$saved_CFLAGS $_define_flag"
-fi],
- [ AC_MSG_RESULT([no])
- CFLAGS="$saved_CFLAGS" ]
- )
-}])
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
-dnl OSSH_CHECK_LDFLAG_LINK(check_flag[, define_flag])
-dnl Check that $LD accepts a flag 'check_flag'. If it is supported append
-dnl 'define_flag' to $LDFLAGS. If 'define_flag' is not specified, then append
-dnl 'check_flag'.
-AC_DEFUN([OSSH_CHECK_LDFLAG_LINK], [{
- AC_MSG_CHECKING([if $LD supports link flag $1])
- saved_LDFLAGS="$LDFLAGS"
- LDFLAGS="$LDFLAGS $WERROR $1"
- _define_flag="$2"
- test "x$_define_flag" = "x" && _define_flag="$1"
- AC_LINK_IFELSE([AC_LANG_SOURCE([[
-#include <stdlib.h>
-#include <stdio.h>
-int main(int argc, char **argv) {
- /* Some math to catch -ftrapv problems in the toolchain */
- int i = 123 * argc, j = 456 + argc, k = 789 - argc;
- float l = i * 2.1;
- double m = l / 0.5;
- long long int n = argc * 12345LL, o = 12345LL * (long long int)argc;
- long long p = n * o;
- printf("%d %d %d %f %f %lld %lld %lld\n", i, j, k, l, m, n, o, p);
- exit(0);
-}
- ]])],
- [
-if $ac_cv_path_EGREP -i "unrecognized option|warning.*ignored" conftest.err >/dev/null
-then
- AC_MSG_RESULT([no])
- LDFLAGS="$saved_LDFLAGS"
-else
- AC_MSG_RESULT([yes])
- LDFLAGS="$saved_LDFLAGS $_define_flag"
-fi ],
- [ AC_MSG_RESULT([no])
- LDFLAGS="$saved_LDFLAGS" ]
- )
-}])
-
-dnl OSSH_CHECK_HEADER_FOR_FIELD(field, header, symbol)
-dnl Does AC_EGREP_HEADER on 'header' for the string 'field'
-dnl If found, set 'symbol' to be defined. Cache the result.
-dnl TODO: This is not foolproof, better to compile and read from there
-AC_DEFUN(OSSH_CHECK_HEADER_FOR_FIELD, [
-# look for field '$1' in header '$2'
- dnl This strips characters illegal to m4 from the header filename
- ossh_safe=`echo "$2" | sed 'y%./+-%__p_%'`
- dnl
- ossh_varname="ossh_cv_$ossh_safe""_has_"$1
- AC_MSG_CHECKING(for $1 field in $2)
- AC_CACHE_VAL($ossh_varname, [
- AC_EGREP_HEADER($1, $2, [ dnl
- eval "$ossh_varname=yes" dnl
- ], [ dnl
- eval "$ossh_varname=no" dnl
- ]) dnl
- ])
- ossh_result=`eval 'echo $'"$ossh_varname"`
- if test -n "`echo $ossh_varname`"; then
- AC_MSG_RESULT($ossh_result)
- if test "x$ossh_result" = "xyes"; then
- AC_DEFINE($3, 1, [Define if you have $1 in $2])
- fi
- else
- AC_MSG_RESULT(no)
- fi
-])
-
-dnl Check for socklen_t: historically on BSD it is an int, and in
-dnl POSIX 1g it is a type of its own, but some platforms use different
-dnl types for the argument to getsockopt, getpeername, etc. So we
-dnl have to test to find something that will work.
-AC_DEFUN([TYPE_SOCKLEN_T],
-[
- AC_CHECK_TYPE([socklen_t], ,[
- AC_MSG_CHECKING([for socklen_t equivalent])
- AC_CACHE_VAL([curl_cv_socklen_t_equiv],
- [
- # Systems have either "struct sockaddr *" or
- # "void *" as the second argument to getpeername
- curl_cv_socklen_t_equiv=
- for arg2 in "struct sockaddr" void; do
- for t in int size_t unsigned long "unsigned long"; do
- AC_TRY_COMPILE([
- #include <sys/types.h>
- #include <sys/socket.h>
-
- int getpeername (int, $arg2 *, $t *);
- ],[
- $t len;
- getpeername(0,0,&len);
- ],[
- curl_cv_socklen_t_equiv="$t"
- break
- ])
- done
- done
-
- if test "x$curl_cv_socklen_t_equiv" = x; then
- AC_MSG_ERROR([Cannot find a type to use in place of socklen_t])
- fi
- ])
- AC_MSG_RESULT($curl_cv_socklen_t_equiv)
- AC_DEFINE_UNQUOTED(socklen_t, $curl_cv_socklen_t_equiv,
- [type to use in place of socklen_t if not defined])],
- [#include <sys/types.h>
-#include <sys/socket.h>])
-])
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+m4_ifndef([AC_CONFIG_MACRO_DIRS], [m4_defun([_AM_CONFIG_MACRO_DIRS], [])m4_defun([AC_CONFIG_MACRO_DIRS], [_AM_CONFIG_MACRO_DIRS($@)])])
+m4_include([m4/openssh.m4])
diff --git a/crypto/openssh/addr.c b/crypto/openssh/addr.c
new file mode 100644
index 000000000000..ba0fad4e9eb0
--- /dev/null
+++ b/crypto/openssh/addr.c
@@ -0,0 +1,423 @@
+/* $OpenBSD: addr.c,v 1.1 2021/01/09 11:58:50 dtucker Exp $ */
+
+/*
+ * Copyright (c) 2004-2008 Damien Miller <djm@mindrot.org>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "includes.h"
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+#include <netdb.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "addr.h"
+
+#define _SA(x) ((struct sockaddr *)(x))
+
+int
+addr_unicast_masklen(int af)
+{
+ switch (af) {
+ case AF_INET:
+ return 32;
+ case AF_INET6:
+ return 128;
+ default:
+ return -1;
+ }
+}
+
+static inline int
+masklen_valid(int af, u_int masklen)
+{
+ switch (af) {
+ case AF_INET:
+ return masklen <= 32 ? 0 : -1;
+ case AF_INET6:
+ return masklen <= 128 ? 0 : -1;
+ default:
+ return -1;
+ }
+}
+
+int
+addr_xaddr_to_sa(const struct xaddr *xa, struct sockaddr *sa, socklen_t *len,
+ u_int16_t port)
+{
+ struct sockaddr_in *in4 = (struct sockaddr_in *)sa;
+ struct sockaddr_in6 *in6 = (struct sockaddr_in6 *)sa;
+
+ if (xa == NULL || sa == NULL || len == NULL)
+ return -1;
+
+ switch (xa->af) {
+ case AF_INET:
+ if (*len < sizeof(*in4))
+ return -1;
+ memset(sa, '\0', sizeof(*in4));
+ *len = sizeof(*in4);
+#ifdef SOCK_HAS_LEN
+ in4->sin_len = sizeof(*in4);
+#endif
+ in4->sin_family = AF_INET;
+ in4->sin_port = htons(port);
+ memcpy(&in4->sin_addr, &xa->v4, sizeof(in4->sin_addr));
+ break;
+ case AF_INET6:
+ if (*len < sizeof(*in6))
+ return -1;
+ memset(sa, '\0', sizeof(*in6));
+ *len = sizeof(*in6);
+#ifdef SOCK_HAS_LEN
+ in6->sin6_len = sizeof(*in6);
+#endif
+ in6->sin6_family = AF_INET6;
+ in6->sin6_port = htons(port);
+ memcpy(&in6->sin6_addr, &xa->v6, sizeof(in6->sin6_addr));
+#ifdef HAVE_STRUCT_SOCKADDR_IN6_SIN6_SCOPE_ID
+ in6->sin6_scope_id = xa->scope_id;
+#endif
+ break;
+ default:
+ return -1;
+ }
+ return 0;
+}
+
+/*
+ * Convert struct sockaddr to struct xaddr
+ * Returns 0 on success, -1 on failure.
+ */
+int
+addr_sa_to_xaddr(struct sockaddr *sa, socklen_t slen, struct xaddr *xa)
+{
+ struct sockaddr_in *in4 = (struct sockaddr_in *)sa;
+ struct sockaddr_in6 *in6 = (struct sockaddr_in6 *)sa;
+
+ memset(xa, '\0', sizeof(*xa));
+
+ switch (sa->sa_family) {
+ case AF_INET:
+ if (slen < (socklen_t)sizeof(*in4))
+ return -1;
+ xa->af = AF_INET;
+ memcpy(&xa->v4, &in4->sin_addr, sizeof(xa->v4));
+ break;
+ case AF_INET6:
+ if (slen < (socklen_t)sizeof(*in6))
+ return -1;
+ xa->af = AF_INET6;
+ memcpy(&xa->v6, &in6->sin6_addr, sizeof(xa->v6));
+#ifdef HAVE_STRUCT_SOCKADDR_IN6_SIN6_SCOPE_ID
+ xa->scope_id = in6->sin6_scope_id;
+#endif
+ break;
+ default:
+ return -1;
+ }
+
+ return 0;
+}
+
+int
+addr_invert(struct xaddr *n)
+{
+ int i;
+
+ if (n == NULL)
+ return -1;
+
+ switch (n->af) {
+ case AF_INET:
+ n->v4.s_addr = ~n->v4.s_addr;
+ return 0;
+ case AF_INET6:
+ for (i = 0; i < 4; i++)
+ n->addr32[i] = ~n->addr32[i];
+ return 0;
+ default:
+ return -1;
+ }
+}
+
+/*
+ * Calculate a netmask of length 'l' for address family 'af' and
+ * store it in 'n'.
+ * Returns 0 on success, -1 on failure.
+ */
+int
+addr_netmask(int af, u_int l, struct xaddr *n)
+{
+ int i;
+
+ if (masklen_valid(af, l) != 0 || n == NULL)
+ return -1;
+
+ memset(n, '\0', sizeof(*n));
+ switch (af) {
+ case AF_INET:
+ n->af = AF_INET;
+ if (l == 0)
+ return 0;
+ n->v4.s_addr = htonl((0xffffffff << (32 - l)) & 0xffffffff);
+ return 0;
+ case AF_INET6:
+ n->af = AF_INET6;
+ for (i = 0; i < 4 && l >= 32; i++, l -= 32)
+ n->addr32[i] = 0xffffffffU;
+ if (i < 4 && l != 0)
+ n->addr32[i] = htonl((0xffffffff << (32 - l)) &
+ 0xffffffff);
+ return 0;
+ default:
+ return -1;
+ }
+}
+
+int
+addr_hostmask(int af, u_int l, struct xaddr *n)
+{
+ if (addr_netmask(af, l, n) == -1 || addr_invert(n) == -1)
+ return -1;
+ return 0;
+}
+
+/*
+ * Perform logical AND of addresses 'a' and 'b', storing result in 'dst'.
+ * Returns 0 on success, -1 on failure.
+ */
+int
+addr_and(struct xaddr *dst, const struct xaddr *a, const struct xaddr *b)
+{
+ int i;
+
+ if (dst == NULL || a == NULL || b == NULL || a->af != b->af)
+ return -1;
+
+ memcpy(dst, a, sizeof(*dst));
+ switch (a->af) {
+ case AF_INET:
+ dst->v4.s_addr &= b->v4.s_addr;
+ return 0;
+ case AF_INET6:
+ dst->scope_id = a->scope_id;
+ for (i = 0; i < 4; i++)
+ dst->addr32[i] &= b->addr32[i];
+ return 0;
+ default:
+ return -1;
+ }
+}
+
+int
+addr_cmp(const struct xaddr *a, const struct xaddr *b)
+{
+ int i;
+
+ if (a->af != b->af)
+ return (a->af == AF_INET6 ? 1 : -1);
+
+ switch (a->af) {
+ case AF_INET:
+ /*
+ * Can't just subtract here as 255.255.255.255 - 0.0.0.0 is
+ * too big to fit into a signed int
+ */
+ if (a->v4.s_addr == b->v4.s_addr)
+ return 0;
+ return (ntohl(a->v4.s_addr) > ntohl(b->v4.s_addr) ? 1 : -1);
+ case AF_INET6:;
+ /*
+ * Do this a byte at a time to avoid the above issue and
+ * any endian problems
+ */
+ for (i = 0; i < 16; i++)
+ if (a->addr8[i] - b->addr8[i] != 0)
+ return (a->addr8[i] - b->addr8[i]);
+ if (a->scope_id == b->scope_id)
+ return (0);
+ return (a->scope_id > b->scope_id ? 1 : -1);
+ default:
+ return (-1);
+ }
+}
+
+int
+addr_is_all0s(const struct xaddr *a)
+{
+ int i;
+
+ switch (a->af) {
+ case AF_INET:
+ return (a->v4.s_addr == 0 ? 0 : -1);
+ case AF_INET6:;
+ for (i = 0; i < 4; i++)
+ if (a->addr32[i] != 0)
+ return -1;
+ return 0;
+ default:
+ return -1;
+ }
+}
+
+/*
+ * Test whether host portion of address 'a', as determined by 'masklen'
+ * is all zeros.
+ * Returns 0 on if host portion of address is all-zeros,
+ * -1 if not all zeros or on failure.
+ */
+int
+addr_host_is_all0s(const struct xaddr *a, u_int masklen)
+{
+ struct xaddr tmp_addr, tmp_mask, tmp_result;
+
+ memcpy(&tmp_addr, a, sizeof(tmp_addr));
+ if (addr_hostmask(a->af, masklen, &tmp_mask) == -1)
+ return -1;
+ if (addr_and(&tmp_result, &tmp_addr, &tmp_mask) == -1)
+ return -1;
+ return addr_is_all0s(&tmp_result);
+}
+
+/*
+ * Parse string address 'p' into 'n'
+ * Returns 0 on success, -1 on failure.
+ */
+int
+addr_pton(const char *p, struct xaddr *n)
+{
+ struct addrinfo hints, *ai;
+
+ memset(&hints, '\0', sizeof(hints));
+ hints.ai_flags = AI_NUMERICHOST;
+
+ if (p == NULL || getaddrinfo(p, NULL, &hints, &ai) != 0)
+ return -1;
+
+ if (ai == NULL || ai->ai_addr == NULL)
+ return -1;
+
+ if (n != NULL && addr_sa_to_xaddr(ai->ai_addr, ai->ai_addrlen,
+ n) == -1) {
+ freeaddrinfo(ai);
+ return -1;
+ }
+
+ freeaddrinfo(ai);
+ return 0;
+}
+
+int
+addr_sa_pton(const char *h, const char *s, struct sockaddr *sa, socklen_t slen)
+{
+ struct addrinfo hints, *ai;
+
+ memset(&hints, '\0', sizeof(hints));
+ hints.ai_flags = AI_NUMERICHOST;
+
+ if (h == NULL || getaddrinfo(h, s, &hints, &ai) != 0)
+ return -1;
+
+ if (ai == NULL || ai->ai_addr == NULL)
+ return -1;
+
+ if (sa != NULL) {
+ if (slen < ai->ai_addrlen)
+ return -1;
+ memcpy(sa, &ai->ai_addr, ai->ai_addrlen);
+ }
+
+ freeaddrinfo(ai);
+ return 0;
+}
+
+int
+addr_ntop(const struct xaddr *n, char *p, size_t len)
+{
+ struct sockaddr_storage ss;
+ socklen_t slen = sizeof(ss);
+
+ if (addr_xaddr_to_sa(n, _SA(&ss), &slen, 0) == -1)
+ return -1;
+ if (n == NULL || p == NULL || len == 0)
+ return -1;
+ if (getnameinfo(_SA(&ss), slen, p, len, NULL, 0,
+ NI_NUMERICHOST) == -1)
+ return -1;
+
+ return 0;
+}
+
+/*
+ * Parse a CIDR address (x.x.x.x/y or xxxx:yyyy::/z).
+ * Return -1 on parse error, -2 on inconsistency or 0 on success.
+ */
+int
+addr_pton_cidr(const char *p, struct xaddr *n, u_int *l)
+{
+ struct xaddr tmp;
+ long unsigned int masklen = 999;
+ char addrbuf[64], *mp, *cp;
+
+ /* Don't modify argument */
+ if (p == NULL || strlcpy(addrbuf, p, sizeof(addrbuf)) >= sizeof(addrbuf))
+ return -1;
+
+ if ((mp = strchr(addrbuf, '/')) != NULL) {
+ *mp = '\0';
+ mp++;
+ masklen = strtoul(mp, &cp, 10);
+ if (*mp == '\0' || *cp != '\0' || masklen > 128)
+ return -1;
+ }
+
+ if (addr_pton(addrbuf, &tmp) == -1)
+ return -1;
+
+ if (mp == NULL)
+ masklen = addr_unicast_masklen(tmp.af);
+ if (masklen_valid(tmp.af, masklen) == -1)
+ return -2;
+ if (addr_host_is_all0s(&tmp, masklen) != 0)
+ return -2;
+
+ if (n != NULL)
+ memcpy(n, &tmp, sizeof(*n));
+ if (l != NULL)
+ *l = masklen;
+
+ return 0;
+}
+
+int
+addr_netmatch(const struct xaddr *host, const struct xaddr *net, u_int masklen)
+{
+ struct xaddr tmp_mask, tmp_result;
+
+ if (host->af != net->af)
+ return -1;
+
+ if (addr_netmask(host->af, masklen, &tmp_mask) == -1)
+ return -1;
+ if (addr_and(&tmp_result, host, &tmp_mask) == -1)
+ return -1;
+ return addr_cmp(&tmp_result, net);
+}
diff --git a/crypto/openssh/addr.h b/crypto/openssh/addr.h
new file mode 100644
index 000000000000..5eff02628592
--- /dev/null
+++ b/crypto/openssh/addr.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2004,2005 Damien Miller <djm@mindrot.org>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* Address handling routines */
+
+#ifndef _ADDR_H
+#define _ADDR_H
+
+#include <sys/socket.h>
+#include <netinet/in.h>
+
+struct xaddr {
+ sa_family_t af;
+ union {
+ struct in_addr v4;
+ struct in6_addr v6;
+ u_int8_t addr8[16];
+ u_int16_t addr16[8];
+ u_int32_t addr32[4];
+ } xa; /* 128-bit address */
+ u_int32_t scope_id; /* iface scope id for v6 */
+#define v4 xa.v4
+#define v6 xa.v6
+#define addr8 xa.addr8
+#define addr16 xa.addr16
+#define addr32 xa.addr32
+};
+
+int addr_unicast_masklen(int af);
+int addr_xaddr_to_sa(const struct xaddr *xa, struct sockaddr *sa,
+ socklen_t *len, u_int16_t port);
+int addr_sa_to_xaddr(struct sockaddr *sa, socklen_t slen, struct xaddr *xa);
+int addr_netmask(int af, u_int l, struct xaddr *n);
+int addr_hostmask(int af, u_int l, struct xaddr *n);
+int addr_invert(struct xaddr *n);
+int addr_pton(const char *p, struct xaddr *n);
+int addr_sa_pton(const char *h, const char *s, struct sockaddr *sa,
+ socklen_t slen);
+int addr_pton_cidr(const char *p, struct xaddr *n, u_int *l);
+int addr_ntop(const struct xaddr *n, char *p, size_t len);
+int addr_and(struct xaddr *dst, const struct xaddr *a, const struct xaddr *b);
+int addr_cmp(const struct xaddr *a, const struct xaddr *b);
+int addr_is_all0s(const struct xaddr *n);
+int addr_host_is_all0s(const struct xaddr *n, u_int masklen);
+int addr_netmatch(const struct xaddr *host, const struct xaddr *net,
+ u_int masklen);
+#endif /* _ADDR_H */
diff --git a/crypto/openssh/addrmatch.c b/crypto/openssh/addrmatch.c
index 5a402d065612..b0dc096804db 100644
--- a/crypto/openssh/addrmatch.c
+++ b/crypto/openssh/addrmatch.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: addrmatch.c,v 1.14 2018/07/31 03:07:24 djm Exp $ */
+/* $OpenBSD: addrmatch.c,v 1.17 2021/04/03 06:18:40 djm Exp $ */
/*
* Copyright (c) 2004-2008 Damien Miller <djm@mindrot.org>
@@ -29,337 +29,10 @@
#include <stdio.h>
#include <stdarg.h>
+#include "addr.h"
#include "match.h"
#include "log.h"
-struct xaddr {
- sa_family_t af;
- union {
- struct in_addr v4;
- struct in6_addr v6;
- u_int8_t addr8[16];
- u_int32_t addr32[4];
- } xa; /* 128-bit address */
- u_int32_t scope_id; /* iface scope id for v6 */
-#define v4 xa.v4
-#define v6 xa.v6
-#define addr8 xa.addr8
-#define addr32 xa.addr32
-};
-
-static int
-addr_unicast_masklen(int af)
-{
- switch (af) {
- case AF_INET:
- return 32;
- case AF_INET6:
- return 128;
- default:
- return -1;
- }
-}
-
-static inline int
-masklen_valid(int af, u_int masklen)
-{
- switch (af) {
- case AF_INET:
- return masklen <= 32 ? 0 : -1;
- case AF_INET6:
- return masklen <= 128 ? 0 : -1;
- default:
- return -1;
- }
-}
-
-/*
- * Convert struct sockaddr to struct xaddr
- * Returns 0 on success, -1 on failure.
- */
-static int
-addr_sa_to_xaddr(struct sockaddr *sa, socklen_t slen, struct xaddr *xa)
-{
- struct sockaddr_in *in4 = (struct sockaddr_in *)sa;
- struct sockaddr_in6 *in6 = (struct sockaddr_in6 *)sa;
-
- memset(xa, '\0', sizeof(*xa));
-
- switch (sa->sa_family) {
- case AF_INET:
- if (slen < (socklen_t)sizeof(*in4))
- return -1;
- xa->af = AF_INET;
- memcpy(&xa->v4, &in4->sin_addr, sizeof(xa->v4));
- break;
- case AF_INET6:
- if (slen < (socklen_t)sizeof(*in6))
- return -1;
- xa->af = AF_INET6;
- memcpy(&xa->v6, &in6->sin6_addr, sizeof(xa->v6));
-#ifdef HAVE_STRUCT_SOCKADDR_IN6_SIN6_SCOPE_ID
- xa->scope_id = in6->sin6_scope_id;
-#endif
- break;
- default:
- return -1;
- }
-
- return 0;
-}
-
-/*
- * Calculate a netmask of length 'l' for address family 'af' and
- * store it in 'n'.
- * Returns 0 on success, -1 on failure.
- */
-static int
-addr_netmask(int af, u_int l, struct xaddr *n)
-{
- int i;
-
- if (masklen_valid(af, l) != 0 || n == NULL)
- return -1;
-
- memset(n, '\0', sizeof(*n));
- switch (af) {
- case AF_INET:
- n->af = AF_INET;
- if (l == 0)
- return 0;
- n->v4.s_addr = htonl((0xffffffff << (32 - l)) & 0xffffffff);
- return 0;
- case AF_INET6:
- n->af = AF_INET6;
- for (i = 0; i < 4 && l >= 32; i++, l -= 32)
- n->addr32[i] = 0xffffffffU;
- if (i < 4 && l != 0)
- n->addr32[i] = htonl((0xffffffff << (32 - l)) &
- 0xffffffff);
- return 0;
- default:
- return -1;
- }
-}
-
-/*
- * Perform logical AND of addresses 'a' and 'b', storing result in 'dst'.
- * Returns 0 on success, -1 on failure.
- */
-static int
-addr_and(struct xaddr *dst, const struct xaddr *a, const struct xaddr *b)
-{
- int i;
-
- if (dst == NULL || a == NULL || b == NULL || a->af != b->af)
- return -1;
-
- memcpy(dst, a, sizeof(*dst));
- switch (a->af) {
- case AF_INET:
- dst->v4.s_addr &= b->v4.s_addr;
- return 0;
- case AF_INET6:
- dst->scope_id = a->scope_id;
- for (i = 0; i < 4; i++)
- dst->addr32[i] &= b->addr32[i];
- return 0;
- default:
- return -1;
- }
-}
-
-/*
- * Compare addresses 'a' and 'b'
- * Return 0 if addresses are identical, -1 if (a < b) or 1 if (a > b)
- */
-static int
-addr_cmp(const struct xaddr *a, const struct xaddr *b)
-{
- int i;
-
- if (a->af != b->af)
- return a->af == AF_INET6 ? 1 : -1;
-
- switch (a->af) {
- case AF_INET:
- if (a->v4.s_addr == b->v4.s_addr)
- return 0;
- return ntohl(a->v4.s_addr) > ntohl(b->v4.s_addr) ? 1 : -1;
- case AF_INET6:
- for (i = 0; i < 16; i++)
- if (a->addr8[i] - b->addr8[i] != 0)
- return a->addr8[i] > b->addr8[i] ? 1 : -1;
- if (a->scope_id == b->scope_id)
- return 0;
- return a->scope_id > b->scope_id ? 1 : -1;
- default:
- return -1;
- }
-}
-
-/*
- * Parse string address 'p' into 'n'
- * Returns 0 on success, -1 on failure.
- */
-static int
-addr_pton(const char *p, struct xaddr *n)
-{
- struct addrinfo hints, *ai = NULL;
- int ret = -1;
-
- memset(&hints, '\0', sizeof(hints));
- hints.ai_flags = AI_NUMERICHOST;
-
- if (p == NULL || getaddrinfo(p, NULL, &hints, &ai) != 0)
- goto out;
- if (ai == NULL || ai->ai_addr == NULL)
- goto out;
- if (n != NULL && addr_sa_to_xaddr(ai->ai_addr, ai->ai_addrlen, n) == -1)
- goto out;
- /* success */
- ret = 0;
- out:
- if (ai != NULL)
- freeaddrinfo(ai);
- return ret;
-}
-
-/*
- * Perform bitwise negation of address
- * Returns 0 on success, -1 on failure.
- */
-static int
-addr_invert(struct xaddr *n)
-{
- int i;
-
- if (n == NULL)
- return (-1);
-
- switch (n->af) {
- case AF_INET:
- n->v4.s_addr = ~n->v4.s_addr;
- return (0);
- case AF_INET6:
- for (i = 0; i < 4; i++)
- n->addr32[i] = ~n->addr32[i];
- return (0);
- default:
- return (-1);
- }
-}
-
-/*
- * Calculate a netmask of length 'l' for address family 'af' and
- * store it in 'n'.
- * Returns 0 on success, -1 on failure.
- */
-static int
-addr_hostmask(int af, u_int l, struct xaddr *n)
-{
- if (addr_netmask(af, l, n) == -1 || addr_invert(n) == -1)
- return (-1);
- return (0);
-}
-
-/*
- * Test whether address 'a' is all zeros (i.e. 0.0.0.0 or ::)
- * Returns 0 on if address is all-zeros, -1 if not all zeros or on failure.
- */
-static int
-addr_is_all0s(const struct xaddr *a)
-{
- int i;
-
- switch (a->af) {
- case AF_INET:
- return (a->v4.s_addr == 0 ? 0 : -1);
- case AF_INET6:;
- for (i = 0; i < 4; i++)
- if (a->addr32[i] != 0)
- return (-1);
- return (0);
- default:
- return (-1);
- }
-}
-
-/*
- * Test whether host portion of address 'a', as determined by 'masklen'
- * is all zeros.
- * Returns 0 on if host portion of address is all-zeros,
- * -1 if not all zeros or on failure.
- */
-static int
-addr_host_is_all0s(const struct xaddr *a, u_int masklen)
-{
- struct xaddr tmp_addr, tmp_mask, tmp_result;
-
- memcpy(&tmp_addr, a, sizeof(tmp_addr));
- if (addr_hostmask(a->af, masklen, &tmp_mask) == -1)
- return (-1);
- if (addr_and(&tmp_result, &tmp_addr, &tmp_mask) == -1)
- return (-1);
- return (addr_is_all0s(&tmp_result));
-}
-
-/*
- * Parse a CIDR address (x.x.x.x/y or xxxx:yyyy::/z).
- * Return -1 on parse error, -2 on inconsistency or 0 on success.
- */
-static int
-addr_pton_cidr(const char *p, struct xaddr *n, u_int *l)
-{
- struct xaddr tmp;
- long unsigned int masklen = 999;
- char addrbuf[64], *mp, *cp;
-
- /* Don't modify argument */
- if (p == NULL || strlcpy(addrbuf, p, sizeof(addrbuf)) >= sizeof(addrbuf))
- return -1;
-
- if ((mp = strchr(addrbuf, '/')) != NULL) {
- *mp = '\0';
- mp++;
- masklen = strtoul(mp, &cp, 10);
- if (*mp == '\0' || *cp != '\0' || masklen > 128)
- return -1;
- }
-
- if (addr_pton(addrbuf, &tmp) == -1)
- return -1;
-
- if (mp == NULL)
- masklen = addr_unicast_masklen(tmp.af);
- if (masklen_valid(tmp.af, masklen) == -1)
- return -2;
- if (addr_host_is_all0s(&tmp, masklen) != 0)
- return -2;
-
- if (n != NULL)
- memcpy(n, &tmp, sizeof(*n));
- if (l != NULL)
- *l = masklen;
-
- return 0;
-}
-
-static int
-addr_netmatch(const struct xaddr *host, const struct xaddr *net, u_int masklen)
-{
- struct xaddr tmp_mask, tmp_result;
-
- if (host->af != net->af)
- return -1;
-
- if (addr_netmask(host->af, masklen, &tmp_mask) == -1)
- return -1;
- if (addr_and(&tmp_result, host, &tmp_mask) == -1)
- return -1;
- return addr_cmp(&tmp_result, net);
-}
-
/*
* Match "addr" against list pattern list "_list", which may contain a
* mix of CIDR addresses and old-school wildcards.
@@ -381,7 +54,7 @@ addr_match_list(const char *addr, const char *_list)
int ret = 0, r;
if (addr != NULL && addr_pton(addr, &try_addr) != 0) {
- debug2("%s: couldn't parse address %.100s", __func__, addr);
+ debug2_f("couldn't parse address %.100s", addr);
return 0;
}
if ((o = list = strdup(_list)) == NULL)
@@ -397,13 +70,13 @@ addr_match_list(const char *addr, const char *_list)
/* Prefer CIDR address matching */
r = addr_pton_cidr(cp, &match_addr, &masklen);
if (r == -2) {
- debug2("%s: inconsistent mask length for "
- "match network \"%.100s\"", __func__, cp);
+ debug2_f("inconsistent mask length for "
+ "match network \"%.100s\"", cp);
ret = -2;
break;
} else if (r == 0) {
if (addr != NULL && addr_netmatch(&try_addr,
- &match_addr, masklen) == 0) {
+ &match_addr, masklen) == 0) {
foundit:
if (neg) {
ret = -1;
@@ -441,15 +114,14 @@ addr_match_cidr_list(const char *addr, const char *_list)
int ret = 0, r;
if (addr != NULL && addr_pton(addr, &try_addr) != 0) {
- debug2("%s: couldn't parse address %.100s", __func__, addr);
+ debug2_f("couldn't parse address %.100s", addr);
return 0;
}
if ((o = list = strdup(_list)) == NULL)
return -1;
while ((cp = strsep(&list, ",")) != NULL) {
if (*cp == '\0') {
- error("%s: empty entry in list \"%.100s\"",
- __func__, o);
+ error_f("empty entry in list \"%.100s\"", o);
ret = -1;
break;
}
@@ -462,15 +134,14 @@ addr_match_cidr_list(const char *addr, const char *_list)
/* Stop junk from reaching getaddrinfo. +3 is for masklen */
if (strlen(cp) > INET6_ADDRSTRLEN + 3) {
- error("%s: list entry \"%.100s\" too long",
- __func__, cp);
+ error_f("list entry \"%.100s\" too long", cp);
ret = -1;
break;
}
#define VALID_CIDR_CHARS "0123456789abcdefABCDEF.:/"
if (strspn(cp, VALID_CIDR_CHARS) != strlen(cp)) {
- error("%s: list entry \"%.100s\" contains invalid "
- "characters", __func__, cp);
+ error_f("list entry \"%.100s\" contains invalid "
+ "characters", cp);
ret = -1;
}
diff --git a/crypto/openssh/atomicio.c b/crypto/openssh/atomicio.c
index f854a06f5f50..e00c9f0d4e22 100644
--- a/crypto/openssh/atomicio.c
+++ b/crypto/openssh/atomicio.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: atomicio.c,v 1.28 2016/07/27 23:18:12 djm Exp $ */
+/* $OpenBSD: atomicio.c,v 1.30 2019/01/24 02:42:23 dtucker Exp $ */
/*
* Copyright (c) 2006 Damien Miller. All rights reserved.
* Copyright (c) 2005 Anil Madhavapeddy. All rights reserved.
@@ -57,20 +57,25 @@ atomicio6(ssize_t (*f) (int, void *, size_t), int fd, void *_s, size_t n,
ssize_t res;
struct pollfd pfd;
-#ifndef BROKEN_READ_COMPARISON
pfd.fd = fd;
+#ifndef BROKEN_READ_COMPARISON
pfd.events = f == read ? POLLIN : POLLOUT;
+#else
+ pfd.events = POLLIN|POLLOUT;
#endif
while (n > pos) {
res = (f) (fd, s + pos, n - pos);
switch (res) {
case -1:
- if (errno == EINTR)
+ if (errno == EINTR) {
+ /* possible SIGALARM, update callback */
+ if (cb != NULL && cb(cb_arg, 0) == -1) {
+ errno = EINTR;
+ return pos;
+ }
continue;
- if (errno == EAGAIN || errno == EWOULDBLOCK) {
-#ifndef BROKEN_READ_COMPARISON
+ } else if (errno == EAGAIN || errno == EWOULDBLOCK) {
(void)poll(&pfd, 1, -1);
-#endif
continue;
}
return 0;
@@ -114,20 +119,25 @@ atomiciov6(ssize_t (*f) (int, const struct iovec *, int), int fd,
/* Make a copy of the iov array because we may modify it below */
memcpy(iov, _iov, (size_t)iovcnt * sizeof(*_iov));
-#ifndef BROKEN_READV_COMPARISON
pfd.fd = fd;
+#ifndef BROKEN_READV_COMPARISON
pfd.events = f == readv ? POLLIN : POLLOUT;
+#else
+ pfd.events = POLLIN|POLLOUT;
#endif
for (; iovcnt > 0 && iov[0].iov_len > 0;) {
res = (f) (fd, iov, iovcnt);
switch (res) {
case -1:
- if (errno == EINTR)
+ if (errno == EINTR) {
+ /* possible SIGALARM, update callback */
+ if (cb != NULL && cb(cb_arg, 0) == -1) {
+ errno = EINTR;
+ return pos;
+ }
continue;
- if (errno == EAGAIN || errno == EWOULDBLOCK) {
-#ifndef BROKEN_READV_COMPARISON
+ } else if (errno == EAGAIN || errno == EWOULDBLOCK) {
(void)poll(&pfd, 1, -1);
-#endif
continue;
}
return 0;
diff --git a/crypto/openssh/atomicio.h b/crypto/openssh/atomicio.h
index 0d728ac86ea9..8b3cc6e211bd 100644
--- a/crypto/openssh/atomicio.h
+++ b/crypto/openssh/atomicio.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: atomicio.h,v 1.11 2010/09/22 22:58:51 djm Exp $ */
+/* $OpenBSD: atomicio.h,v 1.12 2018/12/27 03:25:25 djm Exp $ */
/*
* Copyright (c) 2006 Damien Miller. All rights reserved.
@@ -29,6 +29,8 @@
#ifndef _ATOMICIO_H
#define _ATOMICIO_H
+struct iovec;
+
/*
* Ensure all of data on socket comes through. f==read || f==vwrite
*/
diff --git a/crypto/openssh/audit-bsm.c b/crypto/openssh/audit-bsm.c
index 1409f69aeb90..ccfcf6f7fc68 100644
--- a/crypto/openssh/audit-bsm.c
+++ b/crypto/openssh/audit-bsm.c
@@ -129,7 +129,7 @@ static AuditInfoTermID ssh_bsm_tid;
* 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 *);
+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)
@@ -183,41 +183,41 @@ getacna(char *auditstring, int len)
scf_value_t *value = NULL;
int ret = 0;
+ /*
+ * 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.
+ */
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.
- */
+ return -2;
ret = scf_handle_bind(handle);
if (ret == -1)
- return -2;
+ return -2;
property = scf_property_create(handle);
if (property == NULL)
- return -2;
+ return -2;
ret = scf_handle_decode_fmri(handle,
- "svc:/system/auditd:default/:properties/preselection/naflags",
- NULL, NULL, NULL, NULL, property, 0);
+ "svc:/system/auditd:default/:properties/preselection/naflags",
+ NULL, NULL, NULL, NULL, property, 0);
if (ret == -1)
- return -2;
+ return -2;
value = scf_value_create(handle);
if (value == NULL)
- return -2;
+ return -2;
ret = scf_property_get_value(property, value);
if (ret == -1)
- return -2;
+ return -2;
ret = scf_value_get_astring(value, auditstring, len);
if (ret == -1)
- return -2;
+ return -2;
scf_value_destroy(value);
scf_property_destroy(property);
@@ -280,9 +280,10 @@ bsm_audit_record(int typ, char *string, au_event_t event_no)
(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. */
+ /*
+ * 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);
@@ -391,7 +392,7 @@ audit_session_close(struct logininfo *li)
}
void
-audit_event(ssh_audit_event_t event)
+audit_event(struct ssh *ssh, ssh_audit_event_t event)
{
char textbuf[BSM_TEXTBUFSZ];
static int logged_in = 0;
diff --git a/crypto/openssh/audit-linux.c b/crypto/openssh/audit-linux.c
index 136ed76bbe4b..3fcbe5c53ef9 100644
--- a/crypto/openssh/audit-linux.c
+++ b/crypto/openssh/audit-linux.c
@@ -97,10 +97,8 @@ audit_session_close(struct logininfo *li)
}
void
-audit_event(ssh_audit_event_t event)
+audit_event(struct ssh *ssh, ssh_audit_event_t event)
{
- struct ssh *ssh = active_state; /* XXX */
-
switch(event) {
case SSH_AUTH_SUCCESS:
case SSH_CONNECTION_CLOSE:
diff --git a/crypto/openssh/audit.c b/crypto/openssh/audit.c
index 33a04376dd6e..dd2f03558fe9 100644
--- a/crypto/openssh/audit.c
+++ b/crypto/openssh/audit.c
@@ -131,7 +131,7 @@ audit_connection_from(const char *host, int port)
* events and what they mean).
*/
void
-audit_event(ssh_audit_event_t event)
+audit_event(struct ssh *ssh, ssh_audit_event_t event)
{
debug("audit event euid %d user %s event %d (%s)", geteuid(),
audit_username(), event, audit_event_lookup(event));
diff --git a/crypto/openssh/audit.h b/crypto/openssh/audit.h
index 0b593666d9e1..38cb5ad31d4a 100644
--- a/crypto/openssh/audit.h
+++ b/crypto/openssh/audit.h
@@ -27,6 +27,8 @@
#include "loginrec.h"
+struct ssh;
+
enum ssh_audit_event_type {
SSH_LOGIN_EXCEED_MAXTRIES,
SSH_LOGIN_ROOT_DENIED,
@@ -46,7 +48,7 @@ enum ssh_audit_event_type {
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_event(struct ssh *, ssh_audit_event_t);
void audit_session_open(struct logininfo *);
void audit_session_close(struct logininfo *);
void audit_run_command(const char *);
diff --git a/crypto/openssh/auth-bsdauth.c b/crypto/openssh/auth-bsdauth.c
index 4dc5045c2619..d124e994e776 100644
--- a/crypto/openssh/auth-bsdauth.c
+++ b/crypto/openssh/auth-bsdauth.c
@@ -29,8 +29,6 @@
#include <stdarg.h>
#include <stdio.h>
-#include <stdarg.h>
-
#ifdef BSD_AUTH
#include "xmalloc.h"
#include "sshkey.h"
diff --git a/crypto/openssh/auth-krb5.c b/crypto/openssh/auth-krb5.c
index 3096f1c8ea4d..c99e4e430e73 100644
--- a/crypto/openssh/auth-krb5.c
+++ b/crypto/openssh/auth-krb5.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: auth-krb5.c,v 1.23 2018/07/09 21:35:50 markus Exp $ */
+/* $OpenBSD: auth-krb5.c,v 1.24 2021/04/03 06:18:40 djm Exp $ */
/*
* Kerberos v5 authentication and ticket-passing routines.
*
@@ -99,7 +99,7 @@ auth_krb5_password(Authctxt *authctxt, const char *password)
#ifdef HEIMDAL
# ifdef HAVE_KRB5_CC_NEW_UNIQUE
problem = krb5_cc_new_unique(authctxt->krb5_ctx,
- krb5_mcc_ops.prefix, NULL, &ccache);
+ krb5_mcc_ops.prefix, NULL, &ccache);
# else
problem = krb5_cc_gen_new(authctxt->krb5_ctx, &krb5_mcc_ops, &ccache);
# endif
@@ -123,7 +123,7 @@ auth_krb5_password(Authctxt *authctxt, const char *password)
# ifdef HAVE_KRB5_CC_NEW_UNIQUE
problem = krb5_cc_new_unique(authctxt->krb5_ctx,
- krb5_fcc_ops.prefix, NULL, &authctxt->krb5_fwd_ccache);
+ krb5_fcc_ops.prefix, NULL, &authctxt->krb5_fwd_ccache);
# else
problem = krb5_cc_gen_new(authctxt->krb5_ctx, &krb5_fcc_ops,
&authctxt->krb5_fwd_ccache);
@@ -163,17 +163,18 @@ auth_krb5_password(Authctxt *authctxt, const char *password)
goto out;
}
- problem = ssh_krb5_cc_gen(authctxt->krb5_ctx, &authctxt->krb5_fwd_ccache);
+ problem = ssh_krb5_cc_gen(authctxt->krb5_ctx,
+ &authctxt->krb5_fwd_ccache);
if (problem)
goto out;
- problem = krb5_cc_initialize(authctxt->krb5_ctx, authctxt->krb5_fwd_ccache,
- authctxt->krb5_user);
+ problem = krb5_cc_initialize(authctxt->krb5_ctx,
+ authctxt->krb5_fwd_ccache, authctxt->krb5_user);
if (problem)
goto out;
- problem= krb5_cc_store_cred(authctxt->krb5_ctx, authctxt->krb5_fwd_ccache,
- &creds);
+ problem = krb5_cc_store_cred(authctxt->krb5_ctx,
+ authctxt->krb5_fwd_ccache, &creds);
if (problem)
goto out;
#endif
@@ -202,7 +203,7 @@ auth_krb5_password(Authctxt *authctxt, const char *password)
if (authctxt->krb5_ctx != NULL && problem!=-1) {
errmsg = krb5_get_error_message(authctxt->krb5_ctx,
problem);
- debug("Kerberos password authentication failed: %s",
+ debug("Kerberos password authentication failed: %s",
errmsg);
krb5_free_error_message(authctxt->krb5_ctx, errmsg);
} else
diff --git a/crypto/openssh/auth-options.c b/crypto/openssh/auth-options.c
index b05d6d6f3c8a..335f03238f28 100644
--- a/crypto/openssh/auth-options.c
+++ b/crypto/openssh/auth-options.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: auth-options.c,v 1.84 2018/10/03 06:38:35 djm Exp $ */
+/* $OpenBSD: auth-options.c,v 1.97 2021/07/24 01:55:19 djm Exp $ */
/*
* Copyright (c) 2018 Damien Miller <djm@mindrot.org>
*
@@ -19,6 +19,7 @@
#include <sys/types.h>
+#include <stdlib.h>
#include <netdb.h>
#include <pwd.h>
#include <string.h>
@@ -39,75 +40,6 @@
#include "ssh2.h"
#include "auth-options.h"
-/*
- * Match flag 'opt' in *optsp, and if allow_negate is set then also match
- * 'no-opt'. Returns -1 if option not matched, 1 if option matches or 0
- * if negated option matches.
- * If the option or negated option matches, then *optsp is updated to
- * point to the first character after the option.
- */
-static int
-opt_flag(const char *opt, int allow_negate, const char **optsp)
-{
- size_t opt_len = strlen(opt);
- const char *opts = *optsp;
- int negate = 0;
-
- if (allow_negate && strncasecmp(opts, "no-", 3) == 0) {
- opts += 3;
- negate = 1;
- }
- if (strncasecmp(opts, opt, opt_len) == 0) {
- *optsp = opts + opt_len;
- return negate ? 0 : 1;
- }
- return -1;
-}
-
-static char *
-opt_dequote(const char **sp, const char **errstrp)
-{
- const char *s = *sp;
- char *ret;
- size_t i;
-
- *errstrp = NULL;
- if (*s != '"') {
- *errstrp = "missing start quote";
- return NULL;
- }
- s++;
- if ((ret = malloc(strlen((s)) + 1)) == NULL) {
- *errstrp = "memory allocation failed";
- return NULL;
- }
- for (i = 0; *s != '\0' && *s != '"';) {
- if (s[0] == '\\' && s[1] == '"')
- s++;
- ret[i++] = *s++;
- }
- if (*s == '\0') {
- *errstrp = "missing end quote";
- free(ret);
- return NULL;
- }
- ret[i] = '\0';
- s++;
- *sp = s;
- return ret;
-}
-
-static int
-opt_match(const char **opts, const char *term)
-{
- if (strncasecmp((*opts), term, strlen(term)) == 0 &&
- (*opts)[strlen(term)] == '=') {
- *opts += strlen(term) + 1;
- return 1;
- }
- return 0;
-}
-
static int
dup_strings(char ***dstp, size_t *ndstp, char **src, size_t nsrc)
{
@@ -147,7 +79,7 @@ cert_option_list(struct sshauthopt *opts, struct sshbuf *oblob,
int r, ret = -1, found;
if ((c = sshbuf_fromb(oblob)) == NULL) {
- error("%s: sshbuf_fromb failed", __func__);
+ error_f("sshbuf_fromb failed");
goto out;
}
@@ -156,15 +88,17 @@ cert_option_list(struct sshauthopt *opts, struct sshbuf *oblob,
data = NULL;
if ((r = sshbuf_get_cstring(c, &name, NULL)) != 0 ||
(r = sshbuf_froms(c, &data)) != 0) {
- error("Unable to parse certificate options: %s",
- ssh_err(r));
+ error_r(r, "Unable to parse certificate options");
goto out;
}
debug3("found certificate option \"%.100s\" len %zu",
name, sshbuf_len(data));
found = 0;
if ((which & OPTIONS_EXTENSIONS) != 0) {
- if (strcmp(name, "permit-X11-forwarding") == 0) {
+ if (strcmp(name, "no-touch-required") == 0) {
+ opts->no_require_user_presence = 1;
+ found = 1;
+ } else if (strcmp(name, "permit-X11-forwarding") == 0) {
opts->permit_x11_forwarding_flag = 1;
found = 1;
} else if (strcmp(name,
@@ -184,11 +118,14 @@ cert_option_list(struct sshauthopt *opts, struct sshbuf *oblob,
}
}
if (!found && (which & OPTIONS_CRITICAL) != 0) {
- if (strcmp(name, "force-command") == 0) {
+ if (strcmp(name, "verify-required") == 0) {
+ opts->require_verify = 1;
+ found = 1;
+ } else if (strcmp(name, "force-command") == 0) {
if ((r = sshbuf_get_cstring(data, &command,
NULL)) != 0) {
- error("Unable to parse \"%s\" "
- "section: %s", name, ssh_err(r));
+ error_r(r, "Unable to parse \"%s\" "
+ "section", name);
goto out;
}
if (opts->force_command != NULL) {
@@ -199,12 +136,11 @@ cert_option_list(struct sshauthopt *opts, struct sshbuf *oblob,
}
opts->force_command = command;
found = 1;
- }
- if (strcmp(name, "source-address") == 0) {
+ } else if (strcmp(name, "source-address") == 0) {
if ((r = sshbuf_get_cstring(data, &allowed,
NULL)) != 0) {
- error("Unable to parse \"%s\" "
- "section: %s", name, ssh_err(r));
+ error_r(r, "Unable to parse \"%s\" "
+ "section", name);
goto out;
}
if (opts->required_from_host_cert != NULL) {
@@ -287,8 +223,7 @@ sshauthopt_free(struct sshauthopt *opts)
free(opts->permitlisten[i]);
free(opts->permitlisten);
- explicit_bzero(opts, sizeof(*opts));
- free(opts);
+ freezero(opts, sizeof(*opts));
}
struct sshauthopt *
@@ -320,7 +255,7 @@ handle_permit(const char **optsp, int allow_bare_port,
size_t npermits = *npermitsp;
const char *errstr = "unknown error";
- if (npermits > INT_MAX) {
+ if (npermits > SSH_AUTHOPT_PERMIT_MAX) {
*errstrp = "too many permission directives";
return -1;
}
@@ -332,7 +267,8 @@ handle_permit(const char **optsp, int allow_bare_port,
* Allow a bare port number in permitlisten to indicate a
* listen_host wildcard.
*/
- if (asprintf(&tmp, "*:%s", opt) < 0) {
+ if (asprintf(&tmp, "*:%s", opt) == -1) {
+ free(opt);
*errstrp = "memory allocation failed";
return -1;
}
@@ -388,6 +324,7 @@ sshauthopt_parse(const char *opts, const char **errstrp)
struct sshauthopt *ret = NULL;
const char *errstr = "unknown error";
uint64_t valid_before;
+ size_t i, l;
if (errstrp != NULL)
*errstrp = NULL;
@@ -414,6 +351,10 @@ sshauthopt_parse(const char *opts, const char **errstrp)
ret->permit_agent_forwarding_flag = r == 1;
} else if ((r = opt_flag("x11-forwarding", 1, &opts)) != -1) {
ret->permit_x11_forwarding_flag = r == 1;
+ } else if ((r = opt_flag("touch-required", 1, &opts)) != -1) {
+ ret->no_require_user_presence = r != 1; /* NB. flip */
+ } else if ((r = opt_flag("verify-required", 1, &opts)) != -1) {
+ ret->require_verify = r == 1;
} else if ((r = opt_flag("pty", 1, &opts)) != -1) {
ret->permit_pty_flag = r == 1;
} else if ((r = opt_flag("user-rc", 1, &opts)) != -1) {
@@ -457,7 +398,7 @@ sshauthopt_parse(const char *opts, const char **errstrp)
valid_before < ret->valid_before)
ret->valid_before = valid_before;
} else if (opt_match(&opts, "environment")) {
- if (ret->nenv > INT_MAX) {
+ if (ret->nenv > SSH_AUTHOPT_ENV_MAX) {
errstr = "too many environment strings";
goto fail;
}
@@ -469,25 +410,41 @@ sshauthopt_parse(const char *opts, const char **errstrp)
errstr = "invalid environment string";
goto fail;
}
- if ((cp = strdup(opt)) == NULL)
+ if ((cp = strdup(opt)) == NULL) {
+ free(opt);
goto alloc_fail;
- cp[tmp - opt] = '\0'; /* truncate at '=' */
+ }
+ l = (size_t)(tmp - opt);
+ cp[l] = '\0'; /* truncate at '=' */
if (!valid_env_name(cp)) {
free(cp);
free(opt);
errstr = "invalid environment string";
goto fail;
}
+ /* Check for duplicates; XXX O(n*log(n)) */
+ for (i = 0; i < ret->nenv; i++) {
+ if (strncmp(ret->env[i], cp, l) == 0 &&
+ ret->env[i][l] == '=')
+ break;
+ }
free(cp);
- /* Append it. */
- oarray = ret->env;
- if ((ret->env = recallocarray(ret->env, ret->nenv,
- ret->nenv + 1, sizeof(*ret->env))) == NULL) {
- free(opt);
- ret->env = oarray; /* put it back for cleanup */
- goto alloc_fail;
+ /* First match wins */
+ if (i >= ret->nenv) {
+ /* Append it. */
+ oarray = ret->env;
+ if ((ret->env = recallocarray(ret->env,
+ ret->nenv, ret->nenv + 1,
+ sizeof(*ret->env))) == NULL) {
+ free(opt);
+ /* put it back for cleanup */
+ ret->env = oarray;
+ goto alloc_fail;
+ }
+ ret->env[ret->nenv++] = opt;
+ opt = NULL; /* transferred */
}
- ret->env[ret->nenv++] = opt;
+ free(opt);
} else if (opt_match(&opts, "permitopen")) {
if (handle_permit(&opts, 0, &ret->permitopen,
&ret->npermitopen, &errstr) != 0)
@@ -634,14 +591,18 @@ sshauthopt_merge(const struct sshauthopt *primary,
goto alloc_fail;
}
- /* Flags are logical-AND (i.e. must be set in both for permission) */
-#define OPTFLAG(x) ret->x = (primary->x == 1) && (additional->x == 1)
- OPTFLAG(permit_port_forwarding_flag);
- OPTFLAG(permit_agent_forwarding_flag);
- OPTFLAG(permit_x11_forwarding_flag);
- OPTFLAG(permit_pty_flag);
- OPTFLAG(permit_user_rc);
-#undef OPTFLAG
+#define OPTFLAG_AND(x) ret->x = (primary->x == 1) && (additional->x == 1)
+#define OPTFLAG_OR(x) ret->x = (primary->x == 1) || (additional->x == 1)
+ /* Permissive flags are logical-AND (i.e. must be set in both) */
+ OPTFLAG_AND(permit_port_forwarding_flag);
+ OPTFLAG_AND(permit_agent_forwarding_flag);
+ OPTFLAG_AND(permit_x11_forwarding_flag);
+ OPTFLAG_AND(permit_pty_flag);
+ OPTFLAG_AND(permit_user_rc);
+ OPTFLAG_AND(no_require_user_presence);
+ /* Restrictive flags are logical-OR (i.e. must be set in either) */
+ OPTFLAG_OR(require_verify);
+#undef OPTFLAG_AND
/* Earliest expiry time should win */
if (primary->valid_before != 0)
@@ -710,6 +671,8 @@ sshauthopt_copy(const struct sshauthopt *orig)
OPTSCALAR(cert_authority);
OPTSCALAR(force_tun_device);
OPTSCALAR(valid_before);
+ OPTSCALAR(no_require_user_presence);
+ OPTSCALAR(require_verify);
#undef OPTSCALAR
#define OPTSTRING(x) \
do { \
@@ -795,9 +758,11 @@ deserialise_array(struct sshbuf *m, char ***ap, size_t *np)
*np = n;
n = 0;
out:
- for (i = 0; i < n; i++)
- free(a[i]);
- free(a);
+ if (a != NULL) {
+ for (i = 0; i < n; i++)
+ free(a[i]);
+ free(a);
+ }
sshbuf_free(b);
return r;
}
@@ -832,7 +797,7 @@ sshauthopt_serialise(const struct sshauthopt *opts, struct sshbuf *m,
{
int r = SSH_ERR_INTERNAL_ERROR;
- /* Flag and simple integer options */
+ /* Flag options */
if ((r = sshbuf_put_u8(m, opts->permit_port_forwarding_flag)) != 0 ||
(r = sshbuf_put_u8(m, opts->permit_agent_forwarding_flag)) != 0 ||
(r = sshbuf_put_u8(m, opts->permit_x11_forwarding_flag)) != 0 ||
@@ -840,7 +805,12 @@ sshauthopt_serialise(const struct sshauthopt *opts, struct sshbuf *m,
(r = sshbuf_put_u8(m, opts->permit_user_rc)) != 0 ||
(r = sshbuf_put_u8(m, opts->restricted)) != 0 ||
(r = sshbuf_put_u8(m, opts->cert_authority)) != 0 ||
- (r = sshbuf_put_u64(m, opts->valid_before)) != 0)
+ (r = sshbuf_put_u8(m, opts->no_require_user_presence)) != 0 ||
+ (r = sshbuf_put_u8(m, opts->require_verify)) != 0)
+ return r;
+
+ /* Simple integer options */
+ if ((r = sshbuf_put_u64(m, opts->valid_before)) != 0)
return r;
/* tunnel number can be negative to indicate "unset" */
@@ -857,7 +827,7 @@ sshauthopt_serialise(const struct sshauthopt *opts, struct sshbuf *m,
(r = serialise_nullable_string(m,
untrusted ? NULL : opts->required_from_host_cert)) != 0 ||
(r = serialise_nullable_string(m,
- untrusted ? NULL : opts->required_from_host_keys)) != 0)
+ untrusted ? NULL : opts->required_from_host_keys)) != 0)
return r;
/* Array options */
@@ -884,6 +854,7 @@ sshauthopt_deserialise(struct sshbuf *m, struct sshauthopt **optsp)
if ((opts = calloc(1, sizeof(*opts))) == NULL)
return SSH_ERR_ALLOC_FAIL;
+ /* Flag options */
#define OPT_FLAG(x) \
do { \
if ((r = sshbuf_get_u8(m, &f)) != 0) \
@@ -897,8 +868,11 @@ sshauthopt_deserialise(struct sshbuf *m, struct sshauthopt **optsp)
OPT_FLAG(permit_user_rc);
OPT_FLAG(restricted);
OPT_FLAG(cert_authority);
+ OPT_FLAG(no_require_user_presence);
+ OPT_FLAG(require_verify);
#undef OPT_FLAG
+ /* Simple integer options */
if ((r = sshbuf_get_u64(m, &opts->valid_before)) != 0)
goto out;
diff --git a/crypto/openssh/auth-options.h b/crypto/openssh/auth-options.h
index 0462983b5d89..6e29b727c3d2 100644
--- a/crypto/openssh/auth-options.h
+++ b/crypto/openssh/auth-options.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: auth-options.h,v 1.27 2018/06/06 18:23:32 djm Exp $ */
+/* $OpenBSD: auth-options.h,v 1.31 2021/07/23 03:57:20 djm Exp $ */
/*
* Copyright (c) 2018 Damien Miller <djm@mindrot.org>
@@ -22,6 +22,12 @@
struct passwd;
struct sshkey;
+/* Maximum number of permitopen/permitlisten directives to accept */
+#define SSH_AUTHOPT_PERMIT_MAX 4096
+
+/* Maximum number of environment directives to accept */
+#define SSH_AUTHOPT_ENV_MAX 1024
+
/*
* sshauthopt represents key options parsed from authorized_keys or
* from certificate extensions/options.
@@ -65,6 +71,11 @@ struct sshauthopt {
*/
char *required_from_host_cert;
char *required_from_host_keys;
+
+ /* Key requires user presence asserted */
+ int no_require_user_presence;
+ /* Key requires user verification (e.g. PIN) */
+ int require_verify;
};
struct sshauthopt *sshauthopt_new(void);
diff --git a/crypto/openssh/auth-pam.c b/crypto/openssh/auth-pam.c
index 51b4aafe0aca..f077b70595e6 100644
--- a/crypto/openssh/auth-pam.c
+++ b/crypto/openssh/auth-pam.c
@@ -56,6 +56,7 @@
#include <errno.h>
#include <signal.h>
#include <stdarg.h>
+#include <stdlib.h>
#include <string.h>
#include <unistd.h>
@@ -99,6 +100,7 @@ extern char *__progname;
#include "servconf.h"
#include "ssh2.h"
#include "auth-options.h"
+#include "misc.h"
#ifdef GSSAPI
#include "ssh-gss.h"
#endif
@@ -151,12 +153,12 @@ static struct pam_ctxt *cleanup_ctxt;
*/
static int sshpam_thread_status = -1;
-static mysig_t sshpam_oldsig;
+static sshsig_t sshpam_oldsig;
static void
sshpam_sigchld_handler(int sig)
{
- signal(SIGCHLD, SIG_DFL);
+ ssh_signal(SIGCHLD, SIG_DFL);
if (cleanup_ctxt == NULL)
return; /* handler called after PAM cleanup, shouldn't happen */
if (waitpid(cleanup_ctxt->pam_thread, &sshpam_thread_status, WNOHANG)
@@ -198,7 +200,7 @@ pthread_create(sp_pthread_t *thread, const void *attr,
switch ((pid = fork())) {
case -1:
error("fork(): %s", strerror(errno));
- return (-1);
+ return errno;
case 0:
close(ctx->pam_psock);
ctx->pam_psock = -1;
@@ -208,7 +210,7 @@ pthread_create(sp_pthread_t *thread, const void *attr,
*thread = pid;
close(ctx->pam_csock);
ctx->pam_csock = -1;
- sshpam_oldsig = signal(SIGCHLD, sshpam_sigchld_handler);
+ sshpam_oldsig = ssh_signal(SIGCHLD, sshpam_sigchld_handler);
return (0);
}
}
@@ -216,7 +218,7 @@ pthread_create(sp_pthread_t *thread, const void *attr,
static int
pthread_cancel(sp_pthread_t thread)
{
- signal(SIGCHLD, sshpam_oldsig);
+ ssh_signal(SIGCHLD, sshpam_oldsig);
return (kill(thread, SIGTERM));
}
@@ -228,7 +230,7 @@ pthread_join(sp_pthread_t thread, void **value)
if (sshpam_thread_status != -1)
return (sshpam_thread_status);
- signal(SIGCHLD, sshpam_oldsig);
+ ssh_signal(SIGCHLD, sshpam_oldsig);
while (waitpid(thread, &status, 0) == -1) {
if (errno == EINTR)
continue;
@@ -249,6 +251,9 @@ static int sshpam_maxtries_reached = 0;
static char **sshpam_env = NULL;
static Authctxt *sshpam_authctxt = NULL;
static const char *sshpam_password = NULL;
+static char *sshpam_rhost = NULL;
+static char *sshpam_laddr = NULL;
+static char *sshpam_conninfo = NULL;
/* Some PAM implementations don't implement this */
#ifndef HAVE_PAM_GETENVLIST
@@ -256,7 +261,7 @@ static char **
pam_getenvlist(pam_handle_t *pamh)
{
/*
- * XXX - If necessary, we can still support envrionment passing
+ * XXX - If necessary, we can still support environment passing
* for platforms without pam_getenvlist by searching for known
* env vars (e.g. KRB5CCNAME) from the PAM environment.
*/
@@ -264,6 +269,14 @@ pam_getenvlist(pam_handle_t *pamh)
}
#endif
+#ifndef HAVE_PAM_PUTENV
+static int
+pam_putenv(pam_handle_t *pamh, const char *name_value)
+{
+ return PAM_SUCCESS;
+}
+#endif /* HAVE_PAM_PUTENV */
+
/*
* Some platforms, notably Solaris, do not enforce password complexity
* rules during pam_chauthtok() if the real uid of the calling process
@@ -289,7 +302,7 @@ sshpam_chauthtok_ruid(pam_handle_t *pamh, int flags)
# define pam_chauthtok(a,b) (sshpam_chauthtok_ruid((a), (b)))
#endif
-void
+static void
sshpam_password_change_required(int reqd)
{
extern struct sshauthopt *auth_opts;
@@ -358,14 +371,16 @@ import_environments(struct sshbuf *b)
for (i = 0; i < num_env; i++) {
if ((r = sshbuf_get_cstring(b, &env, NULL)) != 0)
fatal("%s: buffer error: %s", __func__, ssh_err(r));
-#ifdef HAVE_PAM_PUTENV
/* Errors are not fatal here */
if ((r = pam_putenv(sshpam_handle, env)) != PAM_SUCCESS) {
error("PAM: pam_putenv: %s",
pam_strerror(sshpam_handle, r));
}
-#endif
- /* XXX leak env? */
+ /*
+ * XXX this possibly leaks env because it is not documented
+ * what pam_putenv() does with it. Does it copy it? Does it
+ * take ownweship? We don't know, so it's safest just to leak.
+ */
}
#endif
}
@@ -533,7 +548,7 @@ sshpam_thread(void *ctxtp)
for (i = 0; environ[i] != NULL; i++) {
/* Count */
if (i > INT_MAX)
- fatal("%s: too many enviornment strings", __func__);
+ fatal("%s: too many environment strings", __func__);
}
if ((r = sshbuf_put_u32(buffer, i)) != 0)
fatal("%s: buffer error: %s", __func__, ssh_err(r));
@@ -546,7 +561,7 @@ sshpam_thread(void *ctxtp)
for (i = 0; env_from_pam != NULL && env_from_pam[i] != NULL; i++) {
/* Count */
if (i > INT_MAX)
- fatal("%s: too many PAM enviornment strings", __func__);
+ fatal("%s: too many PAM environment strings", __func__);
}
if ((r = sshbuf_put_u32(buffer, i)) != 0)
fatal("%s: buffer error: %s", __func__, ssh_err(r));
@@ -670,13 +685,23 @@ sshpam_cleanup(void)
}
static int
-sshpam_init(Authctxt *authctxt)
+sshpam_init(struct ssh *ssh, Authctxt *authctxt)
{
- const char *pam_rhost, *pam_user, *user = authctxt->user;
+ const char *pam_user, *user = authctxt->user;
const char **ptr_pam_user = &pam_user;
- struct ssh *ssh = active_state; /* XXX */
- if (sshpam_handle != NULL) {
+#if defined(PAM_SUN_CODEBASE) && defined(PAM_MAX_RESP_SIZE)
+ /* Protect buggy PAM implementations from excessively long usernames */
+ if (strlen(user) >= PAM_MAX_RESP_SIZE)
+ fatal("Username too long from %s port %d",
+ ssh_remote_ipaddr(ssh), ssh_remote_port(ssh));
+#endif
+ if (sshpam_handle == NULL) {
+ if (ssh == NULL) {
+ fatal("%s: called initially with no "
+ "packet context", __func__);
+ }
+ } if (sshpam_handle != NULL) {
/* We already have a PAM context; check if the user matches */
sshpam_err = pam_get_item(sshpam_handle,
PAM_USER, (sshpam_const void **)ptr_pam_user);
@@ -695,14 +720,33 @@ sshpam_init(Authctxt *authctxt)
sshpam_handle = NULL;
return (-1);
}
- pam_rhost = auth_get_canonical_hostname(ssh, options.use_dns);
- debug("PAM: setting PAM_RHOST to \"%s\"", pam_rhost);
- sshpam_err = pam_set_item(sshpam_handle, PAM_RHOST, pam_rhost);
- if (sshpam_err != PAM_SUCCESS) {
- pam_end(sshpam_handle, sshpam_err);
- sshpam_handle = NULL;
- return (-1);
+
+ if (ssh != NULL && sshpam_rhost == NULL) {
+ /*
+ * We need to cache these as we don't have packet context
+ * during the kbdint flow.
+ */
+ sshpam_rhost = xstrdup(auth_get_canonical_hostname(ssh,
+ options.use_dns));
+ sshpam_laddr = get_local_ipaddr(
+ ssh_packet_get_connection_in(ssh));
+ xasprintf(&sshpam_conninfo, "SSH_CONNECTION=%.50s %d %.50s %d",
+ ssh_remote_ipaddr(ssh), ssh_remote_port(ssh),
+ sshpam_laddr, ssh_local_port(ssh));
}
+ if (sshpam_rhost != NULL) {
+ debug("PAM: setting PAM_RHOST to \"%s\"", sshpam_rhost);
+ sshpam_err = pam_set_item(sshpam_handle, PAM_RHOST,
+ sshpam_rhost);
+ if (sshpam_err != PAM_SUCCESS) {
+ pam_end(sshpam_handle, sshpam_err);
+ sshpam_handle = NULL;
+ return (-1);
+ }
+ /* Put SSH_CONNECTION in the PAM environment too */
+ pam_putenv(sshpam_handle, sshpam_conninfo);
+ }
+
#ifdef PAM_TTY_KLUDGE
/*
* Some silly PAM modules (e.g. pam_time) require a TTY to operate.
@@ -745,7 +789,7 @@ static void *
sshpam_init_ctx(Authctxt *authctxt)
{
struct pam_ctxt *ctxt;
- int socks[2];
+ int result, socks[2];
debug3("PAM: %s entering", __func__);
/*
@@ -756,7 +800,7 @@ sshpam_init_ctx(Authctxt *authctxt)
return NULL;
/* Initialize PAM */
- if (sshpam_init(authctxt) == -1) {
+ if (sshpam_init(NULL, authctxt) == -1) {
error("PAM: initialization failed");
return (NULL);
}
@@ -772,9 +816,10 @@ sshpam_init_ctx(Authctxt *authctxt)
}
ctxt->pam_psock = socks[0];
ctxt->pam_csock = socks[1];
- if (pthread_create(&ctxt->pam_thread, NULL, sshpam_thread, ctxt) == -1) {
+ result = pthread_create(&ctxt->pam_thread, NULL, sshpam_thread, ctxt);
+ if (result != 0) {
error("PAM: failed to start authentication thread: %s",
- strerror(errno));
+ strerror(result));
close(socks[0]);
close(socks[1]);
free(ctxt);
@@ -788,7 +833,6 @@ static int
sshpam_query(void *ctx, char **name, char **info,
u_int *num, char ***prompts, u_int **echo_on)
{
- struct ssh *ssh = active_state; /* XXX */
struct sshbuf *buffer;
struct pam_ctxt *ctxt = ctx;
size_t plen;
@@ -820,6 +864,7 @@ sshpam_query(void *ctx, char **name, char **info,
plen += mlen;
**echo_on = (type == PAM_PROMPT_ECHO_ON);
free(msg);
+ sshbuf_free(buffer);
return (0);
case PAM_ERROR_MSG:
case PAM_TEXT_INFO:
@@ -848,6 +893,7 @@ sshpam_query(void *ctx, char **name, char **info,
**echo_on = 0;
ctxt->pam_done = -1;
free(msg);
+ sshbuf_free(buffer);
return 0;
}
/* FALLTHROUGH */
@@ -874,23 +920,25 @@ sshpam_query(void *ctx, char **name, char **info,
**echo_on = 0;
ctxt->pam_done = 1;
free(msg);
+ sshbuf_free(buffer);
return (0);
}
BLACKLIST_NOTIFY(BLACKLIST_BAD_USER,
sshpam_authctxt->user);
error("PAM: %s for %s%.100s from %.100s", msg,
sshpam_authctxt->valid ? "" : "illegal user ",
- sshpam_authctxt->user,
- auth_get_canonical_hostname(ssh, options.use_dns));
+ sshpam_authctxt->user, sshpam_rhost);
/* FALLTHROUGH */
default:
*num = 0;
**echo_on = 0;
free(msg);
ctxt->pam_done = -1;
+ sshbuf_free(buffer);
return (-1);
}
}
+ sshbuf_free(buffer);
return (-1);
}
@@ -998,12 +1046,14 @@ KbdintDevice mm_sshpam_device = {
* This replaces auth-pam.c
*/
void
-start_pam(Authctxt *authctxt)
+start_pam(struct ssh *ssh)
{
+ Authctxt *authctxt = (Authctxt *)ssh->authctxt;
+
if (!options.use_pam)
fatal("PAM: initialisation requested when UsePAM=no");
- if (sshpam_init(authctxt) == -1)
+ if (sshpam_init(ssh, authctxt) == -1)
fatal("PAM: initialisation failed");
}
@@ -1182,7 +1232,6 @@ int
do_pam_putenv(char *name, char *value)
{
int ret = 1;
-#ifdef HAVE_PAM_PUTENV
char *compound;
size_t len;
@@ -1192,7 +1241,6 @@ do_pam_putenv(char *name, char *value)
snprintf(compound, len, "%s=%s", name, value);
ret = pam_putenv(sshpam_handle, compound);
free(compound);
-#endif
return (ret);
}
@@ -1347,6 +1395,5 @@ sshpam_set_maxtries_reached(int reached)
sshpam_maxtries_reached = 1;
options.password_authentication = 0;
options.kbd_interactive_authentication = 0;
- options.challenge_response_authentication = 0;
}
#endif /* USE_PAM */
diff --git a/crypto/openssh/auth-pam.h b/crypto/openssh/auth-pam.h
index 4198607454fb..9fcea270faec 100644
--- a/crypto/openssh/auth-pam.h
+++ b/crypto/openssh/auth-pam.h
@@ -27,7 +27,7 @@
struct ssh;
-void start_pam(Authctxt *);
+void start_pam(struct ssh *);
void finish_pam(void);
u_int do_pam_account(void);
void do_pam_session(struct ssh *);
diff --git a/crypto/openssh/auth-passwd.c b/crypto/openssh/auth-passwd.c
index 24fcb67b2383..347d91e25192 100644
--- a/crypto/openssh/auth-passwd.c
+++ b/crypto/openssh/auth-passwd.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: auth-passwd.c,v 1.47 2018/07/09 21:26:02 markus Exp $ */
+/* $OpenBSD: auth-passwd.c,v 1.48 2020/10/18 11:32:01 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -152,14 +152,14 @@ warn_expiry(Authctxt *authctxt, auth_session_t *as)
if ((r = sshbuf_putf(loginmsg,
"Your password will expire in %lld day%s.\n",
daysleft, daysleft == 1 ? "" : "s")) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "buffer error");
}
if (actimeleft != 0 && actimeleft < acwarntime) {
daysleft = actimeleft / DAY + 1;
if ((r = sshbuf_putf(loginmsg,
"Your account will expire in %lld day%s.\n",
daysleft, daysleft == 1 ? "" : "s")) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "buffer error");
}
}
diff --git a/crypto/openssh/auth-rhosts.c b/crypto/openssh/auth-rhosts.c
index 57296e1f6f06..0bc4d424c781 100644
--- a/crypto/openssh/auth-rhosts.c
+++ b/crypto/openssh/auth-rhosts.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: auth-rhosts.c,v 1.49 2018/07/09 21:35:50 markus Exp $ */
+/* $OpenBSD: auth-rhosts.c,v 1.53 2020/10/18 11:32:01 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -38,7 +38,6 @@
#include "sshkey.h"
#include "servconf.h"
#include "canohost.h"
-#include "sshkey.h"
#include "hostfile.h"
#include "auth.h"
@@ -222,9 +221,9 @@ auth_rhosts2(struct passwd *pw, const char *client_user, const char *hostname,
* are no system-wide files.
*/
if (!rhosts_files[rhosts_file_index] &&
- stat(_PATH_RHOSTS_EQUIV, &st) < 0 &&
- stat(_PATH_SSH_HOSTS_EQUIV, &st) < 0) {
- debug3("%s: no hosts access files exist", __func__);
+ stat(_PATH_RHOSTS_EQUIV, &st) == -1 &&
+ stat(_PATH_SSH_HOSTS_EQUIV, &st) == -1) {
+ debug3_f("no hosts access files exist");
return 0;
}
@@ -233,7 +232,7 @@ auth_rhosts2(struct passwd *pw, const char *client_user, const char *hostname,
* shosts.equiv.
*/
if (pw->pw_uid == 0)
- debug3("%s: root user, ignoring system hosts files", __func__);
+ debug3_f("root user, ignoring system hosts files");
else {
if (check_rhosts_file(_PATH_RHOSTS_EQUIV, hostname, ipaddr,
client_user, pw->pw_name)) {
@@ -253,7 +252,7 @@ auth_rhosts2(struct passwd *pw, const char *client_user, const char *hostname,
* Check that the home directory is owned by root or the user, and is
* not group or world writable.
*/
- if (stat(pw->pw_dir, &st) < 0) {
+ if (stat(pw->pw_dir, &st) == -1) {
logit("Rhosts authentication refused for %.100s: "
"no home directory %.200s", pw->pw_name, pw->pw_dir);
auth_debug_add("Rhosts authentication refused for %.100s: "
@@ -278,7 +277,7 @@ auth_rhosts2(struct passwd *pw, const char *client_user, const char *hostname,
/* Check users .rhosts or .shosts. */
snprintf(buf, sizeof buf, "%.500s/%.100s",
pw->pw_dir, rhosts_files[rhosts_file_index]);
- if (stat(buf, &st) < 0)
+ if (stat(buf, &st) == -1)
continue;
/*
@@ -299,7 +298,9 @@ auth_rhosts2(struct passwd *pw, const char *client_user, const char *hostname,
* Check if we have been configured to ignore .rhosts
* and .shosts files.
*/
- if (options.ignore_rhosts) {
+ if (options.ignore_rhosts == IGNORE_RHOSTS_YES ||
+ (options.ignore_rhosts == IGNORE_RHOSTS_SHOSTS &&
+ strcmp(rhosts_files[rhosts_file_index], ".shosts") != 0)) {
auth_debug_add("Server has been configured to "
"ignore %.100s.", rhosts_files[rhosts_file_index]);
continue;
diff --git a/crypto/openssh/auth-skey.c b/crypto/openssh/auth-skey.c
deleted file mode 100644
index b347527f6390..000000000000
--- a/crypto/openssh/auth-skey.c
+++ /dev/null
@@ -1,107 +0,0 @@
-/* $OpenBSD: auth-skey.c,v 1.27 2007/01/21 01:41:54 stevesk 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.
- */
-
-#include "includes.h"
-
-#ifdef SKEY
-
-#include <sys/types.h>
-
-#include <pwd.h>
-#include <stdio.h>
-
-#include <skey.h>
-
-#include "xmalloc.h"
-#include "hostfile.h"
-#include "auth.h"
-#include "ssh-gss.h"
-#include "log.h"
-#include "monitor_wrap.h"
-
-static void *
-skey_init_ctx(Authctxt *authctxt)
-{
- return authctxt;
-}
-
-int
-skey_query(void *ctx, char **name, char **infotxt,
- u_int* numprompts, char ***prompts, u_int **echo_on)
-{
- Authctxt *authctxt = ctx;
- char challenge[1024];
- struct skey skey;
-
- if (_compat_skeychallenge(&skey, authctxt->user, challenge,
- sizeof(challenge)) == -1)
- return -1;
-
- *name = xstrdup("");
- *infotxt = xstrdup("");
- *numprompts = 1;
- *prompts = xcalloc(*numprompts, sizeof(char *));
- *echo_on = xcalloc(*numprompts, sizeof(u_int));
-
- xasprintf(*prompts, "%s%s", challenge, SKEY_PROMPT);
-
- return 0;
-}
-
-int
-skey_respond(void *ctx, u_int numresponses, char **responses)
-{
- Authctxt *authctxt = ctx;
-
- if (authctxt->valid &&
- numresponses == 1 &&
- skey_haskey(authctxt->pw->pw_name) == 0 &&
- skey_passcheck(authctxt->pw->pw_name, responses[0]) != -1)
- return 0;
- return -1;
-}
-
-static void
-skey_free_ctx(void *ctx)
-{
- /* we don't have a special context */
-}
-
-KbdintDevice skey_device = {
- "skey",
- skey_init_ctx,
- skey_query,
- skey_respond,
- skey_free_ctx
-};
-
-KbdintDevice mm_skey_device = {
- "skey",
- skey_init_ctx,
- mm_skey_query,
- mm_skey_respond,
- skey_free_ctx
-};
-#endif /* SKEY */
diff --git a/crypto/openssh/auth.c b/crypto/openssh/auth.c
index a2e1fa10ce45..6b53585e2567 100644
--- a/crypto/openssh/auth.c
+++ b/crypto/openssh/auth.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: auth.c,v 1.133 2018/09/12 01:19:12 djm Exp $ */
+/* $OpenBSD: auth.c,v 1.153 2021/07/05 00:50:25 dtucker Exp $ */
/*
* Copyright (c) 2000 Markus Friedl. All rights reserved.
*
@@ -33,6 +33,7 @@ __RCSID("$FreeBSD$");
#include <netinet/in.h>
+#include <stdlib.h>
#include <errno.h>
#include <fcntl.h>
#ifdef HAVE_PATHS_H
@@ -51,6 +52,7 @@ __RCSID("$FreeBSD$");
#include <unistd.h>
#include <limits.h>
#include <netdb.h>
+#include <time.h>
#include "xmalloc.h"
#include "match.h"
@@ -72,7 +74,6 @@ __RCSID("$FreeBSD$");
#endif
#include "authfile.h"
#include "monitor_wrap.h"
-#include "authfile.h"
#include "ssherr.h"
#include "compat.h"
#include "channels.h"
@@ -80,6 +81,7 @@ __RCSID("$FreeBSD$");
/* import */
extern ServerOptions options;
+extern struct include_list includes;
extern int use_privsep;
extern struct sshbuf *loginmsg;
extern struct passwd *privsep_pw;
@@ -98,9 +100,8 @@ static struct sshbuf *auth_debug;
* Otherwise true is returned.
*/
int
-allowed_user(struct passwd * pw)
+allowed_user(struct ssh *ssh, struct passwd * pw)
{
- struct ssh *ssh = active_state; /* XXX */
struct stat st;
const char *hostname = NULL, *ipaddr = NULL, *passwd = NULL;
u_int i;
@@ -169,7 +170,7 @@ allowed_user(struct passwd * pw)
char *shell = xstrdup((pw->pw_shell[0] == '\0') ?
_PATH_BSHELL : pw->pw_shell); /* empty = /bin/sh */
- if (stat(shell, &st) != 0) {
+ if (stat(shell, &st) == -1) {
logit("User %.100s not allowed because shell %.100s "
"does not exist", pw->pw_name, shell);
free(shell);
@@ -260,7 +261,7 @@ allowed_user(struct passwd * pw)
}
#ifdef CUSTOM_SYS_AUTH_ALLOWED_USER
- if (!sys_auth_allowed_user(pw, &loginmsg))
+ if (!sys_auth_allowed_user(pw, loginmsg))
return 0;
#endif
@@ -310,10 +311,10 @@ format_method_key(Authctxt *authctxt)
}
void
-auth_log(Authctxt *authctxt, int authenticated, int partial,
+auth_log(struct ssh *ssh, int authenticated, int partial,
const char *method, const char *submethod)
{
- struct ssh *ssh = active_state; /* XXX */
+ Authctxt *authctxt = (Authctxt *)ssh->authctxt;
int level = SYSLOG_LEVEL_VERBOSE;
const char *authmsg;
char *extra = NULL;
@@ -356,31 +357,33 @@ auth_log(Authctxt *authctxt, int authenticated, int partial,
free(extra);
-#ifdef CUSTOM_FAILED_LOGIN
- if (authenticated == 0 && !authctxt->postponed &&
- (strcmp(method, "password") == 0 ||
- strncmp(method, "keyboard-interactive", 20) == 0 ||
- strcmp(method, "challenge-response") == 0))
- record_failed_login(authctxt->user,
- auth_get_canonical_hostname(ssh, options.use_dns), "ssh");
-# ifdef WITH_AIXAUTHENTICATE
+#if defined(CUSTOM_FAILED_LOGIN) || defined(SSH_AUDIT_EVENTS)
+ if (authenticated == 0 && !(authctxt->postponed || partial)) {
+ /* Log failed login attempt */
+# ifdef CUSTOM_FAILED_LOGIN
+ if (strcmp(method, "password") == 0 ||
+ strncmp(method, "keyboard-interactive", 20) == 0 ||
+ strcmp(method, "challenge-response") == 0)
+ record_failed_login(ssh, authctxt->user,
+ auth_get_canonical_hostname(ssh, options.use_dns), "ssh");
+# endif
+# ifdef SSH_AUDIT_EVENTS
+ audit_event(ssh, audit_classify_auth(method));
+# endif
+ }
+#endif
+#if defined(CUSTOM_FAILED_LOGIN) && defined(WITH_AIXAUTHENTICATE)
if (authenticated)
sys_auth_record_login(authctxt->user,
auth_get_canonical_hostname(ssh, options.use_dns), "ssh",
- &loginmsg);
-# endif
-#endif
-#ifdef SSH_AUDIT_EVENTS
- if (authenticated == 0 && !authctxt->postponed)
- audit_event(audit_classify_auth(method));
+ loginmsg);
#endif
}
-
void
-auth_maxtries_exceeded(Authctxt *authctxt)
+auth_maxtries_exceeded(struct ssh *ssh)
{
- struct ssh *ssh = active_state; /* XXX */
+ Authctxt *authctxt = (Authctxt *)ssh->authctxt;
error("maximum authentication attempts exceeded for "
"%s%.100s from %.200s port %d ssh2",
@@ -388,7 +391,7 @@ auth_maxtries_exceeded(Authctxt *authctxt)
authctxt->user,
ssh_remote_ipaddr(ssh),
ssh_remote_port(ssh));
- packet_disconnect("Too many authentication failures");
+ ssh_packet_disconnect(ssh, "Too many authentication failures");
/* NOTREACHED */
}
@@ -442,7 +445,7 @@ expand_authorized_keys(const char *filename, struct passwd *pw)
* Ensure that filename starts anchored. If not, be backward
* compatible and prepend the '%h/'
*/
- if (*file == '/')
+ if (path_absolute(file))
return (file);
i = snprintf(ret, sizeof(ret), "%s/%s", pw->pw_dir, file);
@@ -472,7 +475,7 @@ check_key_in_hostfiles(struct passwd *pw, struct sshkey *key, const char *host,
const struct hostkey_entry *found;
hostkeys = init_hostkeys();
- load_hostkeys(hostkeys, host, sysfile);
+ load_hostkeys(hostkeys, host, sysfile, 0);
if (userfile != NULL) {
user_hostfile = tilde_expand_filename(userfile, pw->pw_uid);
if (options.strict_modes &&
@@ -486,7 +489,7 @@ check_key_in_hostfiles(struct passwd *pw, struct sshkey *key, const char *host,
user_hostfile);
} else {
temporarily_use_uid(pw);
- load_hostkeys(hostkeys, host, user_hostfile);
+ load_hostkeys(hostkeys, host, user_hostfile, 0);
restore_uid();
}
free(user_hostfile);
@@ -494,12 +497,12 @@ check_key_in_hostfiles(struct passwd *pw, struct sshkey *key, const char *host,
host_status = check_key_in_hostkeys(hostkeys, key, &found);
if (host_status == HOST_REVOKED)
error("WARNING: revoked key for %s attempted authentication",
- found->host);
+ host);
else if (host_status == HOST_OK)
- debug("%s: key for %s found at %s:%ld", __func__,
+ debug_f("key for %s found at %s:%ld",
found->host, found->file, found->line);
else
- debug("%s: key for host %s not found", __func__, host);
+ debug_f("key for host %s not found", host);
free_hostkeys(hostkeys);
@@ -518,11 +521,11 @@ auth_openfile(const char *file, struct passwd *pw, int strict_modes,
if ((fd = open(file, O_RDONLY|O_NONBLOCK)) == -1) {
if (log_missing || errno != ENOENT)
debug("Could not open %s '%s': %s", file_type, file,
- strerror(errno));
+ strerror(errno));
return NULL;
}
- if (fstat(fd, &st) < 0) {
+ if (fstat(fd, &st) == -1) {
close(fd);
return NULL;
}
@@ -563,9 +566,8 @@ auth_openprincipals(const char *file, struct passwd *pw, int strict_modes)
}
struct passwd *
-getpwnamallow(const char *user)
+getpwnamallow(struct ssh *ssh, const char *user)
{
- struct ssh *ssh = active_state; /* XXX */
#ifdef HAVE_LOGIN_CAP
extern login_cap_t *lc;
#ifdef HAVE_AUTH_HOSTOK
@@ -576,11 +578,16 @@ getpwnamallow(const char *user)
#endif
#endif
struct passwd *pw;
- struct connection_info *ci = get_connection_info(1, options.use_dns);
+ struct connection_info *ci;
+ u_int i;
+ ci = get_connection_info(ssh, 1, options.use_dns);
ci->user = user;
- parse_server_match_config(&options, ci);
+ parse_server_match_config(&options, &includes, ci);
log_change_level(options.log_level);
+ log_verbose_reset();
+ for (i = 0; i < options.num_log_verbose; i++)
+ log_verbose_add(options.log_verbose[i]);
process_permitopen(ssh, &options);
#if defined(_AIX) && defined(HAVE_SETAUTHDB)
@@ -592,33 +599,20 @@ getpwnamallow(const char *user)
#if defined(_AIX) && defined(HAVE_SETAUTHDB)
aix_restoreauthdb();
#endif
-#ifdef HAVE_CYGWIN
- /*
- * Windows usernames are case-insensitive. To avoid later problems
- * when trying to match the username, the user is only allowed to
- * login if the username is given in the same case as stored in the
- * user database.
- */
- if (pw != NULL && strcmp(user, pw->pw_name) != 0) {
- logit("Login name %.100s does not match stored username %.100s",
- user, pw->pw_name);
- pw = NULL;
- }
-#endif
if (pw == NULL) {
BLACKLIST_NOTIFY(BLACKLIST_BAD_USER, user);
logit("Invalid user %.100s from %.100s port %d",
user, ssh_remote_ipaddr(ssh), ssh_remote_port(ssh));
#ifdef CUSTOM_FAILED_LOGIN
- record_failed_login(user,
+ record_failed_login(ssh, user,
auth_get_canonical_hostname(ssh, options.use_dns), "ssh");
#endif
#ifdef SSH_AUDIT_EVENTS
- audit_event(SSH_INVALID_USER);
+ audit_event(ssh, SSH_INVALID_USER);
#endif /* SSH_AUDIT_EVENTS */
return (NULL);
}
- if (!allowed_user(pw))
+ if (!allowed_user(ssh, pw))
return (NULL);
#ifdef HAVE_LOGIN_CAP
if ((lc = login_getpwclass(pw)) == NULL) {
@@ -667,7 +661,7 @@ auth_key_is_revoked(struct sshkey *key)
if ((fp = sshkey_fingerprint(key, options.fingerprint_hash,
SSH_FP_DEFAULT)) == NULL) {
r = SSH_ERR_ALLOC_FAIL;
- error("%s: fingerprint key: %s", __func__, ssh_err(r));
+ error_fr(r, "fingerprint key");
goto out;
}
@@ -680,9 +674,9 @@ auth_key_is_revoked(struct sshkey *key)
sshkey_type(key), fp, options.revoked_keys_file);
goto out;
default:
- error("Error checking authentication key %s %s in "
- "revoked keys file %s: %s", sshkey_type(key), fp,
- options.revoked_keys_file, ssh_err(r));
+ error_r(r, "Error checking authentication key %s %s in "
+ "revoked keys file %s", sshkey_type(key), fp,
+ options.revoked_keys_file);
goto out;
}
@@ -708,13 +702,12 @@ auth_debug_add(const char *fmt,...)
vsnprintf(buf, sizeof(buf), fmt, args);
va_end(args);
if ((r = sshbuf_put_cstring(auth_debug, buf)) != 0)
- fatal("%s: sshbuf_put_cstring: %s", __func__, ssh_err(r));
+ fatal_fr(r, "sshbuf_put_cstring");
}
void
-auth_debug_send(void)
+auth_debug_send(struct ssh *ssh)
{
- struct ssh *ssh = active_state; /* XXX */
char *msg;
int r;
@@ -722,8 +715,7 @@ auth_debug_send(void)
return;
while (sshbuf_len(auth_debug) != 0) {
if ((r = sshbuf_get_cstring(auth_debug, &msg, NULL)) != 0)
- fatal("%s: sshbuf_get_cstring: %s",
- __func__, ssh_err(r));
+ fatal_fr(r, "sshbuf_get_cstring");
ssh_packet_send_debug(ssh, "%s", msg);
free(msg);
}
@@ -735,7 +727,7 @@ auth_debug_reset(void)
if (auth_debug != NULL)
sshbuf_reset(auth_debug);
else if ((auth_debug = sshbuf_new()) == NULL)
- fatal("%s: sshbuf_new failed", __func__);
+ fatal_f("sshbuf_new failed");
}
struct passwd *
@@ -766,9 +758,7 @@ fakepw(void)
* be freed. NB. this will usually trigger a DNS query the first time it is
* called.
* This function does additional checks on the hostname to mitigate some
- * attacks on legacy rhosts-style authentication.
- * XXX is RhostsRSAAuthentication vulnerable to these?
- * XXX Can we remove these checks? (or if not, remove RhostsRSAAuthentication?)
+ * attacks on based on conflation of hostnames and IP addresses.
*/
static char *
@@ -784,9 +774,9 @@ remote_hostname(struct ssh *ssh)
fromlen = sizeof(from);
memset(&from, 0, sizeof(from));
if (getpeername(ssh_packet_get_connection_in(ssh),
- (struct sockaddr *)&from, &fromlen) < 0) {
+ (struct sockaddr *)&from, &fromlen) == -1) {
debug("getpeername failed: %.100s", strerror(errno));
- return strdup(ntop);
+ return xstrdup(ntop);
}
ipv64_normalise_mapped(&from, &fromlen);
@@ -798,7 +788,7 @@ remote_hostname(struct ssh *ssh)
if (getnameinfo((struct sockaddr *)&from, fromlen, name, sizeof(name),
NULL, 0, NI_NAMEREQD) != 0) {
/* Host name not found. Use ip address. */
- return strdup(ntop);
+ return xstrdup(ntop);
}
/*
@@ -813,7 +803,7 @@ remote_hostname(struct ssh *ssh)
logit("Nasty PTR record \"%s\" is set up for %s, ignoring",
name, ntop);
freeaddrinfo(ai);
- return strdup(ntop);
+ return xstrdup(ntop);
}
/* Names are stored in lowercase. */
@@ -834,7 +824,7 @@ remote_hostname(struct ssh *ssh)
if (getaddrinfo(name, NULL, &hints, &aitop) != 0) {
logit("reverse mapping checking getaddrinfo for %.700s "
"[%s] failed.", name, ntop);
- return strdup(ntop);
+ return xstrdup(ntop);
}
/* Look for the address from the list of addresses. */
for (ai = aitop; ai; ai = ai->ai_next) {
@@ -849,9 +839,9 @@ remote_hostname(struct ssh *ssh)
/* Address not found for the host name. */
logit("Address %.100s maps to %.600s, but this does not "
"map back to the address.", ntop, name);
- return strdup(ntop);
+ return xstrdup(ntop);
}
- return strdup(name);
+ return xstrdup(name);
}
/*
@@ -875,158 +865,6 @@ auth_get_canonical_hostname(struct ssh *ssh, int use_dns)
}
}
-/*
- * Runs command in a subprocess with a minimal environment.
- * Returns pid on success, 0 on failure.
- * The child stdout and stderr maybe captured, left attached or sent to
- * /dev/null depending on the contents of flags.
- * "tag" is prepended to log messages.
- * NB. "command" is only used for logging; the actual command executed is
- * av[0].
- */
-pid_t
-subprocess(const char *tag, struct passwd *pw, const char *command,
- int ac, char **av, FILE **child, u_int flags)
-{
- FILE *f = NULL;
- struct stat st;
- int fd, devnull, p[2], i;
- pid_t pid;
- char *cp, errmsg[512];
- u_int envsize;
- char **child_env;
-
- if (child != NULL)
- *child = NULL;
-
- debug3("%s: %s command \"%s\" running as %s (flags 0x%x)", __func__,
- tag, command, pw->pw_name, flags);
-
- /* Check consistency */
- if ((flags & SSH_SUBPROCESS_STDOUT_DISCARD) != 0 &&
- (flags & SSH_SUBPROCESS_STDOUT_CAPTURE) != 0) {
- error("%s: inconsistent flags", __func__);
- return 0;
- }
- if (((flags & SSH_SUBPROCESS_STDOUT_CAPTURE) == 0) != (child == NULL)) {
- error("%s: inconsistent flags/output", __func__);
- return 0;
- }
-
- /*
- * If executing an explicit binary, then verify the it exists
- * and appears safe-ish to execute
- */
- if (*av[0] != '/') {
- error("%s path is not absolute", tag);
- return 0;
- }
- temporarily_use_uid(pw);
- if (stat(av[0], &st) < 0) {
- error("Could not stat %s \"%s\": %s", tag,
- av[0], strerror(errno));
- restore_uid();
- return 0;
- }
- if (safe_path(av[0], &st, NULL, 0, errmsg, sizeof(errmsg)) != 0) {
- error("Unsafe %s \"%s\": %s", tag, av[0], errmsg);
- restore_uid();
- return 0;
- }
- /* Prepare to keep the child's stdout if requested */
- if (pipe(p) != 0) {
- error("%s: pipe: %s", tag, strerror(errno));
- restore_uid();
- return 0;
- }
- restore_uid();
-
- switch ((pid = fork())) {
- case -1: /* error */
- error("%s: fork: %s", tag, strerror(errno));
- close(p[0]);
- close(p[1]);
- return 0;
- case 0: /* child */
- /* Prepare a minimal environment for the child. */
- envsize = 5;
- child_env = xcalloc(sizeof(*child_env), envsize);
- child_set_env(&child_env, &envsize, "PATH", _PATH_STDPATH);
- child_set_env(&child_env, &envsize, "USER", pw->pw_name);
- child_set_env(&child_env, &envsize, "LOGNAME", pw->pw_name);
- child_set_env(&child_env, &envsize, "HOME", pw->pw_dir);
- if ((cp = getenv("LANG")) != NULL)
- child_set_env(&child_env, &envsize, "LANG", cp);
-
- for (i = 0; i < NSIG; i++)
- signal(i, SIG_DFL);
-
- if ((devnull = open(_PATH_DEVNULL, O_RDWR)) == -1) {
- error("%s: open %s: %s", tag, _PATH_DEVNULL,
- strerror(errno));
- _exit(1);
- }
- if (dup2(devnull, STDIN_FILENO) == -1) {
- error("%s: dup2: %s", tag, strerror(errno));
- _exit(1);
- }
-
- /* Set up stdout as requested; leave stderr in place for now. */
- fd = -1;
- if ((flags & SSH_SUBPROCESS_STDOUT_CAPTURE) != 0)
- fd = p[1];
- else if ((flags & SSH_SUBPROCESS_STDOUT_DISCARD) != 0)
- fd = devnull;
- if (fd != -1 && dup2(fd, STDOUT_FILENO) == -1) {
- error("%s: dup2: %s", tag, strerror(errno));
- _exit(1);
- }
- closefrom(STDERR_FILENO + 1);
-
- /* Don't use permanently_set_uid() here to avoid fatal() */
- if (setresgid(pw->pw_gid, pw->pw_gid, pw->pw_gid) != 0) {
- error("%s: setresgid %u: %s", tag, (u_int)pw->pw_gid,
- strerror(errno));
- _exit(1);
- }
- if (setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid) != 0) {
- error("%s: setresuid %u: %s", tag, (u_int)pw->pw_uid,
- strerror(errno));
- _exit(1);
- }
- /* stdin is pointed to /dev/null at this point */
- if ((flags & SSH_SUBPROCESS_STDOUT_DISCARD) != 0 &&
- dup2(STDIN_FILENO, STDERR_FILENO) == -1) {
- error("%s: dup2: %s", tag, strerror(errno));
- _exit(1);
- }
-
- execve(av[0], av, child_env);
- error("%s exec \"%s\": %s", tag, command, strerror(errno));
- _exit(127);
- default: /* parent */
- break;
- }
-
- close(p[1]);
- if ((flags & SSH_SUBPROCESS_STDOUT_CAPTURE) == 0)
- close(p[0]);
- else if ((f = fdopen(p[0], "r")) == NULL) {
- error("%s: fdopen: %s", tag, strerror(errno));
- close(p[0]);
- /* Don't leave zombie child */
- kill(pid, SIGTERM);
- while (waitpid(pid, NULL, 0) == -1 && errno == EINTR)
- ;
- return 0;
- }
- /* Success */
- debug3("%s: %s pid %ld", __func__, tag, (long)pid);
- if (child != NULL)
- *child = f;
- return pid;
-}
-
/* These functions link key/cert options to the auth framework */
/* Log sshauthopt options locally and (optionally) for remote transmission */
@@ -1043,16 +881,18 @@ auth_log_authopts(const char *loc, const struct sshauthopt *opts, int do_remote)
snprintf(buf, sizeof(buf), "%d", opts->force_tun_device);
/* Try to keep this alphabetically sorted */
- snprintf(msg, sizeof(msg), "key options:%s%s%s%s%s%s%s%s%s%s%s%s%s",
+ snprintf(msg, sizeof(msg), "key options:%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s",
opts->permit_agent_forwarding_flag ? " agent-forwarding" : "",
opts->force_command == NULL ? "" : " command",
do_env ? " environment" : "",
opts->valid_before == 0 ? "" : "expires",
+ opts->no_require_user_presence ? " no-touch-required" : "",
do_permitopen ? " permitopen" : "",
do_permitlisten ? " permitlisten" : "",
opts->permit_port_forwarding_flag ? " port-forwarding" : "",
opts->cert_principals == NULL ? "" : " principals",
opts->permit_pty_flag ? " pty" : "",
+ opts->require_verify ? " uv" : "",
opts->force_tun_device == -1 ? "" : " tun=",
opts->force_tun_device == -1 ? "" : buf,
opts->permit_user_rc ? " user-rc" : "",
@@ -1104,7 +944,7 @@ auth_activate_options(struct ssh *ssh, struct sshauthopt *opts)
struct sshauthopt *old = auth_opts;
const char *emsg = NULL;
- debug("%s: setting new authentication options", __func__);
+ debug_f("setting new authentication options");
if ((auth_opts = sshauthopt_merge(old, opts, &emsg)) == NULL) {
error("Inconsistent authentication options: %s", emsg);
return -1;
@@ -1118,7 +958,7 @@ auth_restrict_session(struct ssh *ssh)
{
struct sshauthopt *restricted;
- debug("%s: restricting session", __func__);
+ debug_f("restricting session");
/* A blank sshauthopt defaults to permitting nothing */
restricted = sshauthopt_new();
@@ -1126,7 +966,7 @@ auth_restrict_session(struct ssh *ssh)
restricted->restricted = 1;
if (auth_activate_options(ssh, restricted) != 0)
- fatal("%s: failed to restrict session", __func__);
+ fatal_f("failed to restrict session");
sshauthopt_free(restricted);
}
@@ -1201,8 +1041,7 @@ auth_authorise_keyopts(struct ssh *ssh, struct passwd *pw,
case -1:
default:
/* invalid */
- error("%s: Certificate source-address invalid",
- loc);
+ error("%s: Certificate source-address invalid", loc);
/* FALLTHROUGH */
case 0:
logit("%s: Authentication tried for %.100s with valid "
diff --git a/crypto/openssh/auth.h b/crypto/openssh/auth.h
index 977562f0a6f3..43c7d3d4041d 100644
--- a/crypto/openssh/auth.h
+++ b/crypto/openssh/auth.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: auth.h,v 1.96 2018/04/10 00:10:49 djm Exp $ */
+/* $OpenBSD: auth.h,v 1.101 2020/12/22 00:12:22 djm Exp $ */
/*
* Copyright (c) 2000 Markus Friedl. All rights reserved.
@@ -30,8 +30,6 @@
#include <signal.h>
-#include <openssl/rsa.h>
-
#ifdef HAVE_LOGIN_CAP
#include <login_cap.h>
#endif
@@ -132,8 +130,8 @@ auth_rhosts2(struct passwd *, const char *, const char *, const char *);
int auth_password(struct ssh *, const char *);
-int hostbased_key_allowed(struct passwd *, const char *, char *,
- struct sshkey *);
+int hostbased_key_allowed(struct ssh *, struct passwd *,
+ const char *, char *, struct sshkey *);
int user_key_allowed(struct ssh *, struct passwd *, struct sshkey *, int,
struct sshauthopt **);
int auth2_key_already_used(Authctxt *, const struct sshkey *);
@@ -166,15 +164,13 @@ int auth_shadow_pwexpired(Authctxt *);
#include "audit.h"
void remove_kbdint_device(const char *);
-void do_authentication2(Authctxt *);
+void do_authentication2(struct ssh *);
-void auth_log(Authctxt *, int, int, const char *, const char *);
-void auth_maxtries_exceeded(Authctxt *) __attribute__((noreturn));
+void auth_log(struct ssh *, int, int, const char *, const char *);
+void auth_maxtries_exceeded(struct ssh *) __attribute__((noreturn));
void userauth_finish(struct ssh *, int, const char *, const char *);
int auth_root_allowed(struct ssh *, const char *);
-void userauth_send_banner(const char *);
-
char *auth2_read_banner(void);
int auth2_methods_valid(const char *, int);
int auth2_update_methods_lists(Authctxt *, const char *, const char *);
@@ -188,8 +184,8 @@ void auth2_challenge_stop(struct ssh *);
int bsdauth_query(void *, char **, char **, u_int *, char ***, u_int **);
int bsdauth_respond(void *, u_int, char **);
-int allowed_user(struct passwd *);
-struct passwd * getpwnamallow(const char *user);
+int allowed_user(struct ssh *, struct passwd *);
+struct passwd * getpwnamallow(struct ssh *, const char *user);
char *expand_authorized_keys(const char *, struct passwd *pw);
char *authorized_principals_file(struct passwd *);
@@ -210,8 +206,8 @@ struct sshkey *get_hostkey_public_by_index(int, struct ssh *);
struct sshkey *get_hostkey_public_by_type(int, int, struct ssh *);
struct sshkey *get_hostkey_private_by_type(int, int, struct ssh *);
int get_hostkey_index(struct sshkey *, int, struct ssh *);
-int sshd_hostkey_sign(struct sshkey *, struct sshkey *, u_char **,
- size_t *, const u_char *, size_t, const char *, u_int);
+int sshd_hostkey_sign(struct ssh *, struct sshkey *, struct sshkey *,
+ u_char **, size_t *, const u_char *, size_t, const char *);
/* Key / cert options linkage to auth layer */
const struct sshauthopt *auth_options(struct ssh *);
@@ -224,21 +220,15 @@ void auth_log_authopts(const char *, const struct sshauthopt *, int);
/* debug messages during authentication */
void auth_debug_add(const char *fmt,...)
__attribute__((format(printf, 1, 2)));
-void auth_debug_send(void);
+void auth_debug_send(struct ssh *);
void auth_debug_reset(void);
struct passwd *fakepw(void);
-#define SSH_SUBPROCESS_STDOUT_DISCARD (1) /* Discard stdout */
-#define SSH_SUBPROCESS_STDOUT_CAPTURE (1<<1) /* Redirect stdout */
-#define SSH_SUBPROCESS_STDERR_DISCARD (1<<2) /* Discard stderr */
-pid_t subprocess(const char *, struct passwd *,
- const char *, int, char **, FILE **, u_int flags);
-
int sys_auth_passwd(struct ssh *, const char *);
#if defined(KRB5) && !defined(HEIMDAL)
-#include <krb5.h>
krb5_error_code ssh_krb5_cc_gen(krb5_context, krb5_ccache *);
#endif
-#endif
+
+#endif /* AUTH_H */
diff --git a/crypto/openssh/auth2-chall.c b/crypto/openssh/auth2-chall.c
index 2d5cff448abc..021df8291736 100644
--- a/crypto/openssh/auth2-chall.c
+++ b/crypto/openssh/auth2-chall.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: auth2-chall.c,v 1.50 2018/07/11 18:55:11 markus Exp $ */
+/* $OpenBSD: auth2-chall.c,v 1.54 2020/10/18 11:32:01 djm Exp $ */
/*
* Copyright (c) 2001 Markus Friedl. All rights reserved.
* Copyright (c) 2001 Per Allansson. All rights reserved.
@@ -28,9 +28,10 @@
#include <sys/types.h>
-#include <stdarg.h>
+#include <stdlib.h>
#include <stdio.h>
#include <string.h>
+#include <stdarg.h>
#include "xmalloc.h"
#include "ssh2.h"
@@ -111,15 +112,14 @@ kbdint_alloc(const char *devs)
kbdintctxt = xcalloc(1, sizeof(KbdintAuthctxt));
if (strcmp(devs, "") == 0) {
if ((b = sshbuf_new()) == NULL)
- fatal("%s: sshbuf_new failed", __func__);
+ fatal_f("sshbuf_new failed");
for (i = 0; devices[i]; i++) {
if ((r = sshbuf_putf(b, "%s%s",
sshbuf_len(b) ? "," : "", devices[i]->name)) != 0)
- fatal("%s: buffer error: %s",
- __func__, ssh_err(r));
+ fatal_fr(r, "buffer error");
}
if ((kbdintctxt->devices = sshbuf_dup_string(b)) == NULL)
- fatal("%s: sshbuf_dup_string failed", __func__);
+ fatal_f("sshbuf_dup_string failed");
sshbuf_free(b);
} else {
kbdintctxt->devices = xstrdup(devs);
@@ -146,8 +146,7 @@ kbdint_free(KbdintAuthctxt *kbdintctxt)
if (kbdintctxt->device)
kbdint_reset_device(kbdintctxt);
free(kbdintctxt->devices);
- explicit_bzero(kbdintctxt, sizeof(*kbdintctxt));
- free(kbdintctxt);
+ freezero(kbdintctxt, sizeof(*kbdintctxt));
}
/* get next device */
static int
@@ -268,15 +267,15 @@ send_userauth_info_request(struct ssh *ssh)
(r = sshpkt_put_cstring(ssh, instr)) != 0 ||
(r = sshpkt_put_cstring(ssh, "")) != 0 || /* language not used */
(r = sshpkt_put_u32(ssh, kbdintctxt->nreq)) != 0)
- fatal("%s: %s", __func__, ssh_err(r));
+ fatal_fr(r, "start packet");
for (i = 0; i < kbdintctxt->nreq; i++) {
if ((r = sshpkt_put_cstring(ssh, prompts[i])) != 0 ||
(r = sshpkt_put_u8(ssh, echo_on[i])) != 0)
- fatal("%s: %s", __func__, ssh_err(r));
+ fatal_fr(r, "assemble packet");
}
if ((r = sshpkt_send(ssh)) != 0 ||
(r = ssh_packet_write_wait(ssh)) != 0)
- fatal("%s: %s", __func__, ssh_err(r));
+ fatal_fr(r, "send packet");
for (i = 0; i < kbdintctxt->nreq; i++)
free(prompts[i]);
@@ -299,29 +298,29 @@ input_userauth_info_response(int type, u_int32_t seq, struct ssh *ssh)
char **response = NULL;
if (authctxt == NULL)
- fatal("input_userauth_info_response: no authctxt");
+ fatal_f("no authctxt");
kbdintctxt = authctxt->kbdintctxt;
if (kbdintctxt == NULL || kbdintctxt->ctxt == NULL)
- fatal("input_userauth_info_response: no kbdintctxt");
+ fatal_f("no kbdintctxt");
if (kbdintctxt->device == NULL)
- fatal("input_userauth_info_response: no device");
+ fatal_f("no device");
authctxt->postponed = 0; /* reset */
if ((r = sshpkt_get_u32(ssh, &nresp)) != 0)
- fatal("%s: %s", __func__, ssh_err(r));
+ fatal_fr(r, "parse packet");
if (nresp != kbdintctxt->nreq)
- fatal("input_userauth_info_response: wrong number of replies");
+ fatal_f("wrong number of replies");
if (nresp > 100)
- fatal("input_userauth_info_response: too many replies");
+ fatal_f("too many replies");
if (nresp > 0) {
response = xcalloc(nresp, sizeof(char *));
- for (i = 0; i < nresp; i++)
- if ((r = sshpkt_get_cstring(ssh, &response[i],
- NULL)) != 0)
- fatal("%s: %s", __func__, ssh_err(r));
+ for (i = 0; i < nresp; i++) {
+ if ((r = sshpkt_get_cstring(ssh, &response[i], NULL)) != 0)
+ fatal_fr(r, "parse response");
+ }
}
if ((r = sshpkt_get_end(ssh)) != 0)
- fatal("%s: %s", __func__, ssh_err(r));
+ fatal_fr(r, "parse packet");
res = kbdintctxt->device->respond(kbdintctxt->ctxt, nresp, response);
diff --git a/crypto/openssh/auth2-gss.c b/crypto/openssh/auth2-gss.c
index 9351e042819f..60e36961ce0a 100644
--- a/crypto/openssh/auth2-gss.c
+++ b/crypto/openssh/auth2-gss.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: auth2-gss.c,v 1.29 2018/07/31 03:10:27 djm Exp $ */
+/* $OpenBSD: auth2-gss.c,v 1.32 2021/01/27 10:15:08 djm Exp $ */
/*
* Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved.
@@ -44,6 +44,7 @@
#include "misc.h"
#include "servconf.h"
#include "packet.h"
+#include "kex.h"
#include "ssh-gss.h"
#include "monitor_wrap.h"
@@ -71,7 +72,7 @@ userauth_gssapi(struct ssh *ssh)
u_char *doid = NULL;
if ((r = sshpkt_get_u32(ssh, &mechs)) != 0)
- fatal("%s: %s", __func__, ssh_err(r));
+ fatal_fr(r, "parse packet");
if (mechs == 0) {
debug("Mechanism negotiation is not supported");
@@ -85,7 +86,7 @@ userauth_gssapi(struct ssh *ssh)
present = 0;
if ((r = sshpkt_get_string(ssh, &doid, &len)) != 0)
- fatal("%s: %s", __func__, ssh_err(r));
+ fatal_fr(r, "parse oid");
if (len > 2 && doid[0] == SSH_GSS_OIDTYPE &&
doid[1] == len - 2) {
@@ -104,7 +105,7 @@ userauth_gssapi(struct ssh *ssh)
}
if (!authctxt->valid || authctxt->user == NULL) {
- debug2("%s: disabled because of invalid user", __func__);
+ debug2_f("disabled because of invalid user");
free(doid);
return (0);
}
@@ -123,7 +124,7 @@ userauth_gssapi(struct ssh *ssh)
if ((r = sshpkt_start(ssh, SSH2_MSG_USERAUTH_GSSAPI_RESPONSE)) != 0 ||
(r = sshpkt_put_string(ssh, doid, len)) != 0 ||
(r = sshpkt_send(ssh)) != 0)
- fatal("%s: %s", __func__, ssh_err(r));
+ fatal_fr(r, "send packet");
free(doid);
@@ -152,7 +153,7 @@ input_gssapi_token(int type, u_int32_t plen, struct ssh *ssh)
gssctxt = authctxt->methoddata;
if ((r = sshpkt_get_string(ssh, &p, &len)) != 0 ||
(r = sshpkt_get_end(ssh)) != 0)
- fatal("%s: %s", __func__, ssh_err(r));
+ fatal_fr(r, "parse packet");
recv_tok.value = p;
recv_tok.length = len;
@@ -168,7 +169,7 @@ input_gssapi_token(int type, u_int32_t plen, struct ssh *ssh)
(r = sshpkt_put_string(ssh, send_tok.value,
send_tok.length)) != 0 ||
(r = sshpkt_send(ssh)) != 0)
- fatal("%s: %s", __func__, ssh_err(r));
+ fatal_fr(r, "send ERRTOK packet");
}
authctxt->postponed = 0;
ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_GSSAPI_TOKEN, NULL);
@@ -180,7 +181,7 @@ input_gssapi_token(int type, u_int32_t plen, struct ssh *ssh)
(r = sshpkt_put_string(ssh, send_tok.value,
send_tok.length)) != 0 ||
(r = sshpkt_send(ssh)) != 0)
- fatal("%s: %s", __func__, ssh_err(r));
+ fatal_fr(r, "send TOKEN packet");
}
if (maj_status == GSS_S_COMPLETE) {
ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_GSSAPI_TOKEN, NULL);
@@ -216,7 +217,7 @@ input_gssapi_errtok(int type, u_int32_t plen, struct ssh *ssh)
gssctxt = authctxt->methoddata;
if ((r = sshpkt_get_string(ssh, &p, &len)) != 0 ||
(r = sshpkt_get_end(ssh)) != 0)
- fatal("%s: %s", __func__, ssh_err(r));
+ fatal_fr(r, "parse packet");
recv_tok.value = p;
recv_tok.length = len;
@@ -258,7 +259,7 @@ input_gssapi_exchange_complete(int type, u_int32_t plen, struct ssh *ssh)
*/
if ((r = sshpkt_get_end(ssh)) != 0)
- fatal("%s: %s", __func__, ssh_err(r));
+ fatal_fr(r, "parse packet");
authenticated = PRIVSEP(ssh_gssapi_userok(authctxt->user));
@@ -293,16 +294,16 @@ input_gssapi_mic(int type, u_int32_t plen, struct ssh *ssh)
gssctxt = authctxt->methoddata;
if ((r = sshpkt_get_string(ssh, &p, &len)) != 0)
- fatal("%s: %s", __func__, ssh_err(r));
+ fatal_fr(r, "parse packet");
if ((b = sshbuf_new()) == NULL)
- fatal("%s: sshbuf_new failed", __func__);
+ fatal_f("sshbuf_new failed");
mic.value = p;
mic.length = len;
ssh_gssapi_buildmic(b, authctxt->user, authctxt->service,
- "gssapi-with-mic");
+ "gssapi-with-mic", ssh->kex->session_id);
if ((gssbuf.value = sshbuf_mutable_ptr(b)) == NULL)
- fatal("%s: sshbuf_mutable_ptr failed", __func__);
+ fatal_f("sshbuf_mutable_ptr failed");
gssbuf.length = sshbuf_len(b);
if (!GSS_ERROR(PRIVSEP(ssh_gssapi_checkmic(gssctxt, &gssbuf, &mic))))
diff --git a/crypto/openssh/auth2-hostbased.c b/crypto/openssh/auth2-hostbased.c
index 764ceff74ee6..3a29126c37a6 100644
--- a/crypto/openssh/auth2-hostbased.c
+++ b/crypto/openssh/auth2-hostbased.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: auth2-hostbased.c,v 1.38 2018/09/20 03:28:06 djm Exp $ */
+/* $OpenBSD: auth2-hostbased.c,v 1.47 2021/07/23 03:37:52 djm Exp $ */
/*
* Copyright (c) 2000 Markus Friedl. All rights reserved.
*
@@ -27,6 +27,7 @@
#include <sys/types.h>
+#include <stdlib.h>
#include <pwd.h>
#include <string.h>
#include <stdarg.h>
@@ -34,6 +35,7 @@
#include "xmalloc.h"
#include "ssh2.h"
#include "packet.h"
+#include "kex.h"
#include "sshbuf.h"
#include "log.h"
#include "misc.h"
@@ -53,8 +55,6 @@
/* import */
extern ServerOptions options;
-extern u_char *session_id2;
-extern u_int session_id2_len;
static int
userauth_hostbased(struct ssh *ssh)
@@ -73,9 +73,9 @@ userauth_hostbased(struct ssh *ssh)
(r = sshpkt_get_cstring(ssh, &chost, NULL)) != 0 ||
(r = sshpkt_get_cstring(ssh, &cuser, NULL)) != 0 ||
(r = sshpkt_get_string(ssh, &sig, &slen)) != 0)
- fatal("%s: packet parsing: %s", __func__, ssh_err(r));
+ fatal_fr(r, "parse packet");
- debug("%s: cuser %s chost %s pkalg %s slen %zu", __func__,
+ debug_f("cuser %s chost %s pkalg %s slen %zu",
cuser, chost, pkalg, slen);
#ifdef DEBUG_PK
debug("signature:");
@@ -84,21 +84,21 @@ userauth_hostbased(struct ssh *ssh)
pktype = sshkey_type_from_name(pkalg);
if (pktype == KEY_UNSPEC) {
/* this is perfectly legal */
- logit("%s: unsupported public key algorithm: %s",
- __func__, pkalg);
+ logit_f("unsupported public key algorithm: %s",
+ pkalg);
goto done;
}
if ((r = sshkey_from_blob(pkblob, blen, &key)) != 0) {
- error("%s: key_from_blob: %s", __func__, ssh_err(r));
+ error_fr(r, "key_from_blob");
goto done;
}
if (key == NULL) {
- error("%s: cannot decode key: %s", __func__, pkalg);
+ error_f("cannot decode key: %s", pkalg);
goto done;
}
if (key->type != pktype) {
- error("%s: type mismatch for decoded key "
- "(received %d, expected %d)", __func__, key->type, pktype);
+ error_f("type mismatch for decoded key "
+ "(received %d, expected %d)", key->type, pktype);
goto done;
}
if (sshkey_type_plain(key->type) == KEY_RSA &&
@@ -107,28 +107,28 @@ userauth_hostbased(struct ssh *ssh)
"signature format");
goto done;
}
- if (match_pattern_list(pkalg, options.hostbased_key_types, 0) != 1) {
- logit("%s: key type %s not in HostbasedAcceptedKeyTypes",
- __func__, sshkey_type(key));
+ if (match_pattern_list(pkalg, options.hostbased_accepted_algos, 0) != 1) {
+ logit_f("key type %s not in HostbasedAcceptedAlgorithms",
+ sshkey_type(key));
goto done;
}
if ((r = sshkey_check_cert_sigtype(key,
options.ca_sign_algorithms)) != 0) {
- logit("%s: certificate signature algorithm %s: %s", __func__,
+ logit_fr(r, "certificate signature algorithm %s",
(key->cert == NULL || key->cert->signature_type == NULL) ?
- "(null)" : key->cert->signature_type, ssh_err(r));
+ "(null)" : key->cert->signature_type);
goto done;
}
if (!authctxt->valid || authctxt->user == NULL) {
- debug2("%s: disabled because of invalid user", __func__);
+ debug2_f("disabled because of invalid user");
goto done;
}
if ((b = sshbuf_new()) == NULL)
- fatal("%s: sshbuf_new failed", __func__);
+ fatal_f("sshbuf_new failed");
/* reconstruct packet */
- if ((r = sshbuf_put_string(b, session_id2, session_id2_len)) != 0 ||
+ if ((r = sshbuf_put_stringb(b, ssh->kex->session_id)) != 0 ||
(r = sshbuf_put_u8(b, SSH2_MSG_USERAUTH_REQUEST)) != 0 ||
(r = sshbuf_put_cstring(b, authctxt->user)) != 0 ||
(r = sshbuf_put_cstring(b, authctxt->service)) != 0 ||
@@ -137,7 +137,7 @@ userauth_hostbased(struct ssh *ssh)
(r = sshbuf_put_string(b, pkblob, blen)) != 0 ||
(r = sshbuf_put_cstring(b, chost)) != 0 ||
(r = sshbuf_put_cstring(b, cuser)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "reconstruct packet");
#ifdef DEBUG_PK
sshbuf_dump(b, stderr);
#endif
@@ -147,15 +147,16 @@ userauth_hostbased(struct ssh *ssh)
/* test for allowed key and correct signature */
authenticated = 0;
- if (PRIVSEP(hostbased_key_allowed(authctxt->pw, cuser, chost, key)) &&
+ if (PRIVSEP(hostbased_key_allowed(ssh, authctxt->pw, cuser,
+ chost, key)) &&
PRIVSEP(sshkey_verify(key, sig, slen,
- sshbuf_ptr(b), sshbuf_len(b), pkalg, ssh->compat)) == 0)
+ sshbuf_ptr(b), sshbuf_len(b), pkalg, ssh->compat, NULL)) == 0)
authenticated = 1;
auth2_record_key(authctxt, authenticated, key);
sshbuf_free(b);
done:
- debug2("%s: authenticated %d", __func__, authenticated);
+ debug2_f("authenticated %d", authenticated);
sshkey_free(key);
free(pkalg);
free(pkblob);
@@ -167,10 +168,9 @@ done:
/* return 1 if given hostkey is allowed */
int
-hostbased_key_allowed(struct passwd *pw, const char *cuser, char *chost,
- struct sshkey *key)
+hostbased_key_allowed(struct ssh *ssh, struct passwd *pw,
+ const char *cuser, char *chost, struct sshkey *key)
{
- struct ssh *ssh = active_state; /* XXX */
const char *resolvedname, *ipaddr, *lookup, *reason;
HostStatus host_status;
int len;
@@ -182,7 +182,7 @@ hostbased_key_allowed(struct passwd *pw, const char *cuser, char *chost,
resolvedname = auth_get_canonical_hostname(ssh, options.use_dns);
ipaddr = ssh_remote_ipaddr(ssh);
- debug2("%s: chost %s resolvedname %s ipaddr %s", __func__,
+ debug2_f("chost %s resolvedname %s ipaddr %s",
chost, resolvedname, ipaddr);
if (((len = strlen(chost)) > 0) && chost[len - 1] == '.') {
@@ -192,9 +192,8 @@ hostbased_key_allowed(struct passwd *pw, const char *cuser, char *chost,
if (options.hostbased_uses_name_from_packet_only) {
if (auth_rhosts2(pw, cuser, chost, chost) == 0) {
- debug2("%s: auth_rhosts2 refused "
- "user \"%.100s\" host \"%.100s\" (from packet)",
- __func__, cuser, chost);
+ debug2_f("auth_rhosts2 refused user \"%.100s\" "
+ "host \"%.100s\" (from packet)", cuser, chost);
return 0;
}
lookup = chost;
@@ -204,17 +203,17 @@ hostbased_key_allowed(struct passwd *pw, const char *cuser, char *chost,
"client sends %s, but we resolve %s to %s",
chost, ipaddr, resolvedname);
if (auth_rhosts2(pw, cuser, resolvedname, ipaddr) == 0) {
- debug2("%s: auth_rhosts2 refused "
+ debug2_f("auth_rhosts2 refused "
"user \"%.100s\" host \"%.100s\" addr \"%.100s\"",
- __func__, cuser, resolvedname, ipaddr);
+ cuser, resolvedname, ipaddr);
return 0;
}
lookup = resolvedname;
}
- debug2("%s: access allowed by auth_rhosts2", __func__);
+ debug2_f("access allowed by auth_rhosts2");
if (sshkey_is_cert(key) &&
- sshkey_cert_check_authority(key, 1, 0, lookup, &reason)) {
+ sshkey_cert_check_authority_now(key, 1, 0, 0, lookup, &reason)) {
error("%s", reason);
auth_debug_add("%s", reason);
return 0;
@@ -236,7 +235,7 @@ hostbased_key_allowed(struct passwd *pw, const char *cuser, char *chost,
if (sshkey_is_cert(key)) {
if ((fp = sshkey_fingerprint(key->cert->signature_key,
options.fingerprint_hash, SSH_FP_DEFAULT)) == NULL)
- fatal("%s: sshkey_fingerprint fail", __func__);
+ fatal_f("sshkey_fingerprint fail");
verbose("Accepted certificate ID \"%s\" signed by "
"%s CA %s from %s@%s", key->cert->key_id,
sshkey_type(key->cert->signature_key), fp,
@@ -244,7 +243,7 @@ hostbased_key_allowed(struct passwd *pw, const char *cuser, char *chost,
} else {
if ((fp = sshkey_fingerprint(key,
options.fingerprint_hash, SSH_FP_DEFAULT)) == NULL)
- fatal("%s: sshkey_fingerprint fail", __func__);
+ fatal_f("sshkey_fingerprint fail");
verbose("Accepted %s public key %s from %s@%s",
sshkey_type(key), fp, cuser, lookup);
}
diff --git a/crypto/openssh/auth2-kbdint.c b/crypto/openssh/auth2-kbdint.c
index a813b8f56710..037139d44949 100644
--- a/crypto/openssh/auth2-kbdint.c
+++ b/crypto/openssh/auth2-kbdint.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: auth2-kbdint.c,v 1.9 2018/07/09 21:35:50 markus Exp $ */
+/* $OpenBSD: auth2-kbdint.c,v 1.13 2021/07/02 05:11:20 dtucker Exp $ */
/*
* Copyright (c) 2000 Markus Friedl. All rights reserved.
*
@@ -27,6 +27,8 @@
#include <sys/types.h>
+#include <stdlib.h>
+#include <stdio.h>
#include <stdarg.h>
#include "xmalloc.h"
@@ -50,11 +52,11 @@ userauth_kbdint(struct ssh *ssh)
if ((r = sshpkt_get_cstring(ssh, &lang, NULL)) != 0 ||
(r = sshpkt_get_cstring(ssh, &devs, NULL)) != 0 ||
(r = sshpkt_get_end(ssh)) != 0)
- fatal("%s: %s", __func__, ssh_err(r));
+ fatal_fr(r, "parse packet");
debug("keyboard-interactive devs %s", devs);
- if (options.challenge_response_authentication)
+ if (options.kbd_interactive_authentication)
authenticated = auth2_challenge(ssh, devs);
free(devs);
diff --git a/crypto/openssh/auth2-none.c b/crypto/openssh/auth2-none.c
index dacb5fb839e2..02d6e341ca4c 100644
--- a/crypto/openssh/auth2-none.c
+++ b/crypto/openssh/auth2-none.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: auth2-none.c,v 1.22 2018/07/09 21:35:50 markus Exp $ */
+/* $OpenBSD: auth2-none.c,v 1.23 2020/10/18 11:32:01 djm Exp $ */
/*
* Copyright (c) 2000 Markus Friedl. All rights reserved.
*
@@ -65,7 +65,7 @@ userauth_none(struct ssh *ssh)
none_enabled = 0;
if ((r = sshpkt_get_end(ssh)) != 0)
- fatal("%s: %s", __func__, ssh_err(r));
+ fatal_fr(r, "parse packet");
if (options.permit_empty_passwd && options.password_authentication)
return (PRIVSEP(auth_password(ssh, "")));
return (0);
diff --git a/crypto/openssh/auth2-passwd.c b/crypto/openssh/auth2-passwd.c
index 0395a69f4094..be4b8606a6c7 100644
--- a/crypto/openssh/auth2-passwd.c
+++ b/crypto/openssh/auth2-passwd.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: auth2-passwd.c,v 1.16 2018/07/09 21:35:50 markus Exp $ */
+/* $OpenBSD: auth2-passwd.c,v 1.19 2020/10/18 11:32:01 djm Exp $ */
/*
* Copyright (c) 2000 Markus Friedl. All rights reserved.
*
@@ -27,8 +27,10 @@
#include <sys/types.h>
+#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
+#include <stdio.h>
#include "packet.h"
#include "ssherr.h"
@@ -58,14 +60,13 @@ userauth_passwd(struct ssh *ssh)
(r = sshpkt_get_cstring(ssh, &password, &len)) != 0 ||
(change && (r = sshpkt_get_cstring(ssh, NULL, NULL)) != 0) ||
(r = sshpkt_get_end(ssh)) != 0)
- fatal("%s: %s", __func__, ssh_err(r));
+ fatal_fr(r, "parse packet");
if (change)
logit("password change not supported");
else if (PRIVSEP(auth_password(ssh, password)) == 1)
authenticated = 1;
- explicit_bzero(password, len);
- free(password);
+ freezero(password, len);
return authenticated;
}
diff --git a/crypto/openssh/auth2-pubkey.c b/crypto/openssh/auth2-pubkey.c
index 2fb5950ea608..9e32259a5ca3 100644
--- a/crypto/openssh/auth2-pubkey.c
+++ b/crypto/openssh/auth2-pubkey.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: auth2-pubkey.c,v 1.86 2018/09/20 03:28:06 djm Exp $ */
+/* $OpenBSD: auth2-pubkey.c,v 1.109 2021/07/23 03:37:52 djm Exp $ */
/*
* Copyright (c) 2000 Markus Friedl. All rights reserved.
*
@@ -28,6 +28,7 @@
#include <sys/types.h>
#include <sys/stat.h>
+#include <stdlib.h>
#include <errno.h>
#include <fcntl.h>
#ifdef HAVE_PATHS_H
@@ -46,6 +47,7 @@
#include "ssh.h"
#include "ssh2.h"
#include "packet.h"
+#include "kex.h"
#include "sshbuf.h"
#include "log.h"
#include "misc.h"
@@ -67,11 +69,10 @@
#include "ssherr.h"
#include "channels.h" /* XXX for session.h */
#include "session.h" /* XXX for child_set_env(); refactor? */
+#include "sk-api.h"
/* import */
extern ServerOptions options;
-extern u_char *session_id2;
-extern u_int session_id2_len;
static char *
format_key(const struct sshkey *key)
@@ -95,31 +96,47 @@ userauth_pubkey(struct ssh *ssh)
u_char *pkblob = NULL, *sig = NULL, have_sig;
size_t blen, slen;
int r, pktype;
- int authenticated = 0;
+ int req_presence = 0, req_verify = 0, authenticated = 0;
struct sshauthopt *authopts = NULL;
+ struct sshkey_sig_details *sig_details = NULL;
if ((r = sshpkt_get_u8(ssh, &have_sig)) != 0 ||
(r = sshpkt_get_cstring(ssh, &pkalg, NULL)) != 0 ||
(r = sshpkt_get_string(ssh, &pkblob, &blen)) != 0)
- fatal("%s: parse request failed: %s", __func__, ssh_err(r));
+ fatal_fr(r, "parse packet");
+
+ if (log_level_get() >= SYSLOG_LEVEL_DEBUG2) {
+ char *keystring;
+ struct sshbuf *pkbuf;
+
+ if ((pkbuf = sshbuf_from(pkblob, blen)) == NULL)
+ fatal_f("sshbuf_from failed");
+ if ((keystring = sshbuf_dtob64_string(pkbuf, 0)) == NULL)
+ fatal_f("sshbuf_dtob64 failed");
+ debug2_f("%s user %s %s public key %s %s",
+ authctxt->valid ? "valid" : "invalid", authctxt->user,
+ have_sig ? "attempting" : "querying", pkalg, keystring);
+ sshbuf_free(pkbuf);
+ free(keystring);
+ }
+
pktype = sshkey_type_from_name(pkalg);
if (pktype == KEY_UNSPEC) {
/* this is perfectly legal */
- verbose("%s: unsupported public key algorithm: %s",
- __func__, pkalg);
+ verbose_f("unsupported public key algorithm: %s", pkalg);
goto done;
}
if ((r = sshkey_from_blob(pkblob, blen, &key)) != 0) {
- error("%s: could not parse key: %s", __func__, ssh_err(r));
+ error_fr(r, "parse key");
goto done;
}
if (key == NULL) {
- error("%s: cannot decode key: %s", __func__, pkalg);
+ error_f("cannot decode key: %s", pkalg);
goto done;
}
if (key->type != pktype) {
- error("%s: type mismatch for decoded key "
- "(received %d, expected %d)", __func__, key->type, pktype);
+ error_f("type mismatch for decoded key "
+ "(received %d, expected %d)", key->type, pktype);
goto done;
}
if (sshkey_type_plain(key->type) == KEY_RSA &&
@@ -132,16 +149,16 @@ userauth_pubkey(struct ssh *ssh)
logit("refusing previously-used %s key", sshkey_type(key));
goto done;
}
- if (match_pattern_list(pkalg, options.pubkey_key_types, 0) != 1) {
- logit("%s: key type %s not in PubkeyAcceptedKeyTypes",
- __func__, sshkey_ssh_name(key));
+ if (match_pattern_list(pkalg, options.pubkey_accepted_algos, 0) != 1) {
+ logit_f("key type %s not in PubkeyAcceptedAlgorithms",
+ sshkey_ssh_name(key));
goto done;
}
if ((r = sshkey_check_cert_sigtype(key,
options.ca_sign_algorithms)) != 0) {
- logit("%s: certificate signature algorithm %s: %s", __func__,
+ logit_fr(r, "certificate signature algorithm %s",
(key->cert == NULL || key->cert->signature_type == NULL) ?
- "(null)" : key->cert->signature_type, ssh_err(r));
+ "(null)" : key->cert->signature_type);
goto done;
}
key_s = format_key(key);
@@ -149,29 +166,23 @@ userauth_pubkey(struct ssh *ssh)
ca_s = format_key(key->cert->signature_key);
if (have_sig) {
- debug3("%s: have %s signature for %s%s%s",
- __func__, pkalg, key_s,
- ca_s == NULL ? "" : " CA ",
- ca_s == NULL ? "" : ca_s);
+ debug3_f("have %s signature for %s%s%s", pkalg, key_s,
+ ca_s == NULL ? "" : " CA ", ca_s == NULL ? "" : ca_s);
if ((r = sshpkt_get_string(ssh, &sig, &slen)) != 0 ||
(r = sshpkt_get_end(ssh)) != 0)
- fatal("%s: %s", __func__, ssh_err(r));
+ fatal_fr(r, "parse signature packet");
if ((b = sshbuf_new()) == NULL)
- fatal("%s: sshbuf_new failed", __func__);
+ fatal_f("sshbuf_new failed");
if (ssh->compat & SSH_OLD_SESSIONID) {
- if ((r = sshbuf_put(b, session_id2,
- session_id2_len)) != 0)
- fatal("%s: sshbuf_put session id: %s",
- __func__, ssh_err(r));
+ if ((r = sshbuf_putb(b, ssh->kex->session_id)) != 0)
+ fatal_fr(r, "put old session id");
} else {
- if ((r = sshbuf_put_string(b, session_id2,
- session_id2_len)) != 0)
- fatal("%s: sshbuf_put_string session id: %s",
- __func__, ssh_err(r));
+ if ((r = sshbuf_put_stringb(b,
+ ssh->kex->session_id)) != 0)
+ fatal_fr(r, "put session id");
}
if (!authctxt->valid || authctxt->user == NULL) {
- debug2("%s: disabled because of invalid user",
- __func__);
+ debug2_f("disabled because of invalid user");
goto done;
}
/* reconstruct packet */
@@ -185,8 +196,7 @@ userauth_pubkey(struct ssh *ssh)
(r = sshbuf_put_u8(b, have_sig)) != 0 ||
(r = sshbuf_put_cstring(b, pkalg)) != 0 ||
(r = sshbuf_put_string(b, pkblob, blen)) != 0)
- fatal("%s: build packet failed: %s",
- __func__, ssh_err(r));
+ fatal_fr(r, "reconstruct packet");
#ifdef DEBUG_PK
sshbuf_dump(b, stderr);
#endif
@@ -196,22 +206,54 @@ userauth_pubkey(struct ssh *ssh)
PRIVSEP(sshkey_verify(key, sig, slen,
sshbuf_ptr(b), sshbuf_len(b),
(ssh->compat & SSH_BUG_SIGTYPE) == 0 ? pkalg : NULL,
- ssh->compat)) == 0) {
+ ssh->compat, &sig_details)) == 0) {
authenticated = 1;
}
+ if (authenticated == 1 && sig_details != NULL) {
+ auth2_record_info(authctxt, "signature count = %u",
+ sig_details->sk_counter);
+ debug_f("sk_counter = %u, sk_flags = 0x%02x",
+ sig_details->sk_counter, sig_details->sk_flags);
+ req_presence = (options.pubkey_auth_options &
+ PUBKEYAUTH_TOUCH_REQUIRED) ||
+ !authopts->no_require_user_presence;
+ if (req_presence && (sig_details->sk_flags &
+ SSH_SK_USER_PRESENCE_REQD) == 0) {
+ error("public key %s signature for %s%s from "
+ "%.128s port %d rejected: user presence "
+ "(authenticator touch) requirement "
+ "not met ", key_s,
+ authctxt->valid ? "" : "invalid user ",
+ authctxt->user, ssh_remote_ipaddr(ssh),
+ ssh_remote_port(ssh));
+ authenticated = 0;
+ goto done;
+ }
+ req_verify = (options.pubkey_auth_options &
+ PUBKEYAUTH_VERIFY_REQUIRED) ||
+ authopts->require_verify;
+ if (req_verify && (sig_details->sk_flags &
+ SSH_SK_USER_VERIFICATION_REQD) == 0) {
+ error("public key %s signature for %s%s from "
+ "%.128s port %d rejected: user "
+ "verification requirement not met ", key_s,
+ authctxt->valid ? "" : "invalid user ",
+ authctxt->user, ssh_remote_ipaddr(ssh),
+ ssh_remote_port(ssh));
+ authenticated = 0;
+ goto done;
+ }
+ }
auth2_record_key(authctxt, authenticated, key);
} else {
- debug("%s: test pkalg %s pkblob %s%s%s",
- __func__, pkalg, key_s,
- ca_s == NULL ? "" : " CA ",
- ca_s == NULL ? "" : ca_s);
+ debug_f("test pkalg %s pkblob %s%s%s", pkalg, key_s,
+ ca_s == NULL ? "" : " CA ", ca_s == NULL ? "" : ca_s);
if ((r = sshpkt_get_end(ssh)) != 0)
- fatal("%s: %s", __func__, ssh_err(r));
+ fatal_fr(r, "parse packet");
if (!authctxt->valid || authctxt->user == NULL) {
- debug2("%s: disabled because of invalid user",
- __func__);
+ debug2_f("disabled because of invalid user");
goto done;
}
/* XXX fake reply and always send PK_OK ? */
@@ -229,16 +271,16 @@ userauth_pubkey(struct ssh *ssh)
(r = sshpkt_put_string(ssh, pkblob, blen)) != 0 ||
(r = sshpkt_send(ssh)) != 0 ||
(r = ssh_packet_write_wait(ssh)) != 0)
- fatal("%s: %s", __func__, ssh_err(r));
+ fatal_fr(r, "send packet");
authctxt->postponed = 1;
}
}
done:
if (authenticated == 1 && auth_activate_options(ssh, authopts) != 0) {
- debug("%s: key options inconsistent with existing", __func__);
+ debug_f("key options inconsistent with existing");
authenticated = 0;
}
- debug2("%s: authenticated %d pkalg %s", __func__, authenticated, pkalg);
+ debug2_f("authenticated %d pkalg %s", authenticated, pkalg);
sshbuf_free(b);
sshauthopt_free(authopts);
@@ -249,6 +291,7 @@ done:
free(key_s);
free(ca_s);
free(sig);
+ sshkey_sig_details_free(sig_details);
return authenticated;
}
@@ -402,7 +445,7 @@ match_principals_command(struct ssh *ssh, struct passwd *user_pw,
pid_t pid;
char *tmp, *username = NULL, *command = NULL, **av = NULL;
char *ca_fp = NULL, *key_fp = NULL, *catext = NULL, *keytext = NULL;
- char serial_s[16], uidstr[32];
+ char serial_s[32], uidstr[32];
void (*osigchld)(int);
if (authoptsp != NULL)
@@ -419,7 +462,7 @@ match_principals_command(struct ssh *ssh, struct passwd *user_pw,
* NB. all returns later this function should go via "out" to
* ensure the original SIGCHLD handler is restored properly.
*/
- osigchld = signal(SIGCHLD, SIG_DFL);
+ osigchld = ssh_signal(SIGCHLD, SIG_DFL);
/* Prepare and verify the user for the command */
username = percent_expand(options.authorized_principals_command_user,
@@ -432,32 +475,33 @@ match_principals_command(struct ssh *ssh, struct passwd *user_pw,
}
/* Turn the command into an argument vector */
- if (argv_split(options.authorized_principals_command, &ac, &av) != 0) {
+ if (argv_split(options.authorized_principals_command,
+ &ac, &av, 0) != 0) {
error("AuthorizedPrincipalsCommand \"%s\" contains "
- "invalid quotes", command);
+ "invalid quotes", options.authorized_principals_command);
goto out;
}
if (ac == 0) {
error("AuthorizedPrincipalsCommand \"%s\" yielded no arguments",
- command);
+ options.authorized_principals_command);
goto out;
}
if ((ca_fp = sshkey_fingerprint(cert->signature_key,
options.fingerprint_hash, SSH_FP_DEFAULT)) == NULL) {
- error("%s: sshkey_fingerprint failed", __func__);
+ error_f("sshkey_fingerprint failed");
goto out;
}
if ((key_fp = sshkey_fingerprint(key,
options.fingerprint_hash, SSH_FP_DEFAULT)) == NULL) {
- error("%s: sshkey_fingerprint failed", __func__);
+ error_f("sshkey_fingerprint failed");
goto out;
}
if ((r = sshkey_to_base64(cert->signature_key, &catext)) != 0) {
- error("%s: sshkey_to_base64 failed: %s", __func__, ssh_err(r));
+ error_fr(r, "sshkey_to_base64 failed");
goto out;
}
if ((r = sshkey_to_base64(key, &keytext)) != 0) {
- error("%s: sshkey_to_base64 failed: %s", __func__, ssh_err(r));
+ error_fr(r, "sshkey_to_base64 failed");
goto out;
}
snprintf(serial_s, sizeof(serial_s), "%llu",
@@ -479,16 +523,17 @@ match_principals_command(struct ssh *ssh, struct passwd *user_pw,
"s", serial_s,
(char *)NULL);
if (tmp == NULL)
- fatal("%s: percent_expand failed", __func__);
+ fatal_f("percent_expand failed");
free(av[i]);
av[i] = tmp;
}
/* Prepare a printable command for logs, etc. */
command = argv_assemble(ac, av);
- if ((pid = subprocess("AuthorizedPrincipalsCommand", runas_pw, command,
+ if ((pid = subprocess("AuthorizedPrincipalsCommand", command,
ac, av, &f,
- SSH_SUBPROCESS_STDOUT_CAPTURE|SSH_SUBPROCESS_STDERR_DISCARD)) == 0)
+ SSH_SUBPROCESS_STDOUT_CAPTURE|SSH_SUBPROCESS_STDERR_DISCARD,
+ runas_pw, temporarily_use_uid, restore_uid)) == 0)
goto out;
uid_swapped = 1;
@@ -507,7 +552,7 @@ match_principals_command(struct ssh *ssh, struct passwd *user_pw,
out:
if (f != NULL)
fclose(f);
- signal(SIGCHLD, osigchld);
+ ssh_signal(SIGCHLD, osigchld);
for (i = 0; i < ac; i++)
free(av[i]);
free(av);
@@ -522,38 +567,6 @@ match_principals_command(struct ssh *ssh, struct passwd *user_pw,
return found_principal;
}
-static void
-skip_space(char **cpp)
-{
- char *cp;
-
- for (cp = *cpp; *cp == ' ' || *cp == '\t'; cp++)
- ;
- *cpp = cp;
-}
-
-/*
- * Advanced *cpp past the end of key options, defined as the first unquoted
- * whitespace character. Returns 0 on success or -1 on failure (e.g.
- * unterminated quotes).
- */
-static int
-advance_past_options(char **cpp)
-{
- char *cp = *cpp;
- int quoted = 0;
-
- for (; *cp && (quoted || (*cp != ' ' && *cp != '\t')); cp++) {
- if (*cp == '\\' && cp[1] == '"')
- cp++; /* Skip both */
- else if (*cp == '"')
- quoted = !quoted;
- }
- *cpp = cp;
- /* return failure for unterminated quotes */
- return (*cp == '\0' && quoted) ? -1 : 0;
-}
-
/*
* Check a single line of an authorized_keys-format file. Returns 0 if key
* matches, -1 otherwise. Will return key/cert options via *authoptsp
@@ -574,7 +587,7 @@ check_authkey_line(struct ssh *ssh, struct passwd *pw, struct sshkey *key,
*authoptsp = NULL;
if ((found = sshkey_new(want_keytype)) == NULL) {
- debug3("%s: keytype %d failed", __func__, want_keytype);
+ debug3_f("keytype %d failed", want_keytype);
goto out;
}
@@ -584,7 +597,7 @@ check_authkey_line(struct ssh *ssh, struct passwd *pw, struct sshkey *key,
/* no key? check for options */
debug2("%s: check options: '%s'", loc, cp);
key_options = cp;
- if (advance_past_options(&cp) != 0) {
+ if (sshkey_advance_past_options(&cp) != 0) {
reason = "invalid key option string";
goto fail_reason;
}
@@ -616,7 +629,7 @@ check_authkey_line(struct ssh *ssh, struct passwd *pw, struct sshkey *key,
/* We have a candidate key, perform authorisation checks */
if ((fp = sshkey_fingerprint(found,
options.fingerprint_hash, SSH_FP_DEFAULT)) == NULL)
- fatal("%s: fingerprint failed", __func__);
+ fatal_f("fingerprint failed");
debug("%s: matching %s found: %s %s", loc,
sshkey_is_cert(key) ? "CA" : "key", sshkey_type(found), fp);
@@ -661,8 +674,9 @@ check_authkey_line(struct ssh *ssh, struct passwd *pw, struct sshkey *key,
reason = "Certificate does not contain an authorized principal";
goto fail_reason;
}
- if (sshkey_cert_check_authority(key, 0, 0,
- keyopts->cert_principals == NULL ? pw->pw_name : NULL, &reason) != 0)
+ if (sshkey_cert_check_authority_now(key, 0, 0, 0,
+ keyopts->cert_principals == NULL ? pw->pw_name : NULL,
+ &reason) != 0)
goto fail_reason;
verbose("Accepted certificate ID \"%s\" (serial %llu) "
@@ -673,7 +687,7 @@ check_authkey_line(struct ssh *ssh, struct passwd *pw, struct sshkey *key,
success:
if (finalopts == NULL)
- fatal("%s: internal error: missing options", __func__);
+ fatal_f("internal error: missing options");
if (authoptsp != NULL) {
*authoptsp = finalopts;
finalopts = NULL;
@@ -752,9 +766,9 @@ user_cert_trusted_ca(struct ssh *ssh, struct passwd *pw, struct sshkey *key,
if ((r = sshkey_in_file(key->cert->signature_key,
options.trusted_user_ca_keys, 1, 0)) != 0) {
- debug2("%s: CA %s %s is not listed in %s: %s", __func__,
+ debug2_fr(r, "CA %s %s is not listed in %s",
sshkey_type(key->cert->signature_key), ca_fp,
- options.trusted_user_ca_keys, ssh_err(r));
+ options.trusted_user_ca_keys);
goto out;
}
/*
@@ -773,14 +787,14 @@ user_cert_trusted_ca(struct ssh *ssh, struct passwd *pw, struct sshkey *key,
found_principal = 1;
/* If principals file or command is specified, then require a match */
use_authorized_principals = principals_file != NULL ||
- options.authorized_principals_command != NULL;
+ options.authorized_principals_command != NULL;
if (!found_principal && use_authorized_principals) {
reason = "Certificate does not contain an authorized principal";
goto fail_reason;
}
if (use_authorized_principals && principals_opts == NULL)
- fatal("%s: internal error: missing principals_opts", __func__);
- if (sshkey_cert_check_authority(key, 0, 1,
+ fatal_f("internal error: missing principals_opts");
+ if (sshkey_cert_check_authority_now(key, 0, 1, 0,
use_authorized_principals ? NULL : pw->pw_name, &reason) != 0)
goto fail_reason;
@@ -889,7 +903,7 @@ user_key_command_allowed2(struct ssh *ssh, struct passwd *user_pw,
* NB. all returns later this function should go via "out" to
* ensure the original SIGCHLD handler is restored properly.
*/
- osigchld = signal(SIGCHLD, SIG_DFL);
+ osigchld = ssh_signal(SIGCHLD, SIG_DFL);
/* Prepare and verify the user for the command */
username = percent_expand(options.authorized_keys_command_user,
@@ -904,23 +918,23 @@ user_key_command_allowed2(struct ssh *ssh, struct passwd *user_pw,
/* Prepare AuthorizedKeysCommand */
if ((key_fp = sshkey_fingerprint(key, options.fingerprint_hash,
SSH_FP_DEFAULT)) == NULL) {
- error("%s: sshkey_fingerprint failed", __func__);
+ error_f("sshkey_fingerprint failed");
goto out;
}
if ((r = sshkey_to_base64(key, &keytext)) != 0) {
- error("%s: sshkey_to_base64 failed: %s", __func__, ssh_err(r));
+ error_fr(r, "sshkey_to_base64 failed");
goto out;
}
/* Turn the command into an argument vector */
- if (argv_split(options.authorized_keys_command, &ac, &av) != 0) {
+ if (argv_split(options.authorized_keys_command, &ac, &av, 0) != 0) {
error("AuthorizedKeysCommand \"%s\" contains invalid quotes",
- command);
+ options.authorized_keys_command);
goto out;
}
if (ac == 0) {
error("AuthorizedKeysCommand \"%s\" yielded no arguments",
- command);
+ options.authorized_keys_command);
goto out;
}
snprintf(uidstr, sizeof(uidstr), "%llu",
@@ -935,7 +949,7 @@ user_key_command_allowed2(struct ssh *ssh, struct passwd *user_pw,
"k", keytext,
(char *)NULL);
if (tmp == NULL)
- fatal("%s: percent_expand failed", __func__);
+ fatal_f("percent_expand failed");
free(av[i]);
av[i] = tmp;
}
@@ -956,9 +970,10 @@ user_key_command_allowed2(struct ssh *ssh, struct passwd *user_pw,
xasprintf(&command, "%s %s", av[0], av[1]);
}
- if ((pid = subprocess("AuthorizedKeysCommand", runas_pw, command,
+ if ((pid = subprocess("AuthorizedKeysCommand", command,
ac, av, &f,
- SSH_SUBPROCESS_STDOUT_CAPTURE|SSH_SUBPROCESS_STDERR_DISCARD)) == 0)
+ SSH_SUBPROCESS_STDOUT_CAPTURE|SSH_SUBPROCESS_STDERR_DISCARD,
+ runas_pw, temporarily_use_uid, restore_uid)) == 0)
goto out;
uid_swapped = 1;
@@ -978,7 +993,7 @@ user_key_command_allowed2(struct ssh *ssh, struct passwd *user_pw,
out:
if (f != NULL)
fclose(f);
- signal(SIGCHLD, osigchld);
+ ssh_signal(SIGCHLD, osigchld);
for (i = 0; i < ac; i++)
free(av[i]);
free(av);
@@ -998,9 +1013,10 @@ int
user_key_allowed(struct ssh *ssh, struct passwd *pw, struct sshkey *key,
int auth_attempt, struct sshauthopt **authoptsp)
{
- u_int success, i;
+ u_int success = 0, i;
char *file;
struct sshauthopt *opts = NULL;
+
if (authoptsp != NULL)
*authoptsp = NULL;
@@ -1010,6 +1026,21 @@ user_key_allowed(struct ssh *ssh, struct passwd *pw, struct sshkey *key,
auth_key_is_revoked(key->cert->signature_key))
return 0;
+ for (i = 0; !success && i < options.num_authkeys_files; i++) {
+ if (strcasecmp(options.authorized_keys_files[i], "none") == 0)
+ continue;
+ file = expand_authorized_keys(
+ options.authorized_keys_files[i], pw);
+ success = user_key_allowed2(ssh, pw, key, file, &opts);
+ free(file);
+ if (!success) {
+ sshauthopt_free(opts);
+ opts = NULL;
+ }
+ }
+ if (success)
+ goto out;
+
if ((success = user_cert_trusted_ca(ssh, pw, key, &opts)) != 0)
goto out;
sshauthopt_free(opts);
@@ -1020,15 +1051,6 @@ user_key_allowed(struct ssh *ssh, struct passwd *pw, struct sshkey *key,
sshauthopt_free(opts);
opts = NULL;
- for (i = 0; !success && i < options.num_authkeys_files; i++) {
- if (strcasecmp(options.authorized_keys_files[i], "none") == 0)
- continue;
- file = expand_authorized_keys(
- options.authorized_keys_files[i], pw);
- success = user_key_allowed2(ssh, pw, key, file, &opts);
- free(file);
- }
-
out:
if (success && authoptsp != NULL) {
*authoptsp = opts;
diff --git a/crypto/openssh/auth2.c b/crypto/openssh/auth2.c
index d6eb067245b7..cd5bd9ff501c 100644
--- a/crypto/openssh/auth2.c
+++ b/crypto/openssh/auth2.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: auth2.c,v 1.149 2018/07/11 18:53:29 markus Exp $ */
+/* $OpenBSD: auth2.c,v 1.161 2021/04/03 06:18:40 djm Exp $ */
/*
* Copyright (c) 2000 Markus Friedl. All rights reserved.
*
@@ -36,7 +36,9 @@ __RCSID("$FreeBSD$");
#include <stdarg.h>
#include <string.h>
#include <unistd.h>
+#include <time.h>
+#include "stdlib.h"
#include "atomicio.h"
#include "xmalloc.h"
#include "ssh2.h"
@@ -51,21 +53,16 @@ __RCSID("$FreeBSD$");
#include "auth.h"
#include "dispatch.h"
#include "pathnames.h"
-#include "sshbuf.h"
#include "ssherr.h"
#include "blacklist_client.h"
-
#ifdef GSSAPI
#include "ssh-gss.h"
#endif
#include "monitor_wrap.h"
-#include "ssherr.h"
#include "digest.h"
/* import */
extern ServerOptions options;
-extern u_char *session_id2;
-extern u_int session_id2_len;
extern struct sshbuf *loginmsg;
/* methods */
@@ -139,18 +136,21 @@ auth2_read_banner(void)
return (banner);
}
-void
-userauth_send_banner(const char *msg)
+static void
+userauth_send_banner(struct ssh *ssh, const char *msg)
{
- packet_start(SSH2_MSG_USERAUTH_BANNER);
- packet_put_cstring(msg);
- packet_put_cstring(""); /* language, unused */
- packet_send();
+ int r;
+
+ if ((r = sshpkt_start(ssh, SSH2_MSG_USERAUTH_BANNER)) != 0 ||
+ (r = sshpkt_put_cstring(ssh, msg)) != 0 ||
+ (r = sshpkt_put_cstring(ssh, "")) != 0 || /* language, unused */
+ (r = sshpkt_send(ssh)) != 0)
+ fatal_fr(r, "send packet");
debug("%s: sent", __func__);
}
static void
-userauth_banner(void)
+userauth_banner(struct ssh *ssh)
{
char *banner = NULL;
@@ -159,7 +159,7 @@ userauth_banner(void)
if ((banner = PRIVSEP(auth2_read_banner())) == NULL)
goto done;
- userauth_send_banner(banner);
+ userauth_send_banner(ssh, banner);
done:
free(banner);
@@ -169,10 +169,10 @@ done:
* loop until authctxt->success == TRUE
*/
void
-do_authentication2(Authctxt *authctxt)
+do_authentication2(struct ssh *ssh)
{
- struct ssh *ssh = active_state; /* XXX */
- ssh->authctxt = authctxt; /* XXX move to caller */
+ Authctxt *authctxt = ssh->authctxt;
+
ssh_dispatch_init(ssh, &dispatch_protocol_error);
ssh_dispatch_set(ssh, SSH2_MSG_SERVICE_REQUEST, &input_service_request);
ssh_dispatch_run_fatal(ssh, DISPATCH_BLOCK, &authctxt->success);
@@ -184,10 +184,12 @@ static int
input_service_request(int type, u_int32_t seq, struct ssh *ssh)
{
Authctxt *authctxt = ssh->authctxt;
- u_int len;
- int acceptit = 0;
- char *service = packet_get_cstring(&len);
- packet_check_eom();
+ char *service = NULL;
+ int r, acceptit = 0;
+
+ if ((r = sshpkt_get_cstring(ssh, &service, NULL)) != 0 ||
+ (r = sshpkt_get_end(ssh)) != 0)
+ goto out;
if (authctxt == NULL)
fatal("input_service_request: no authctxt");
@@ -196,22 +198,26 @@ input_service_request(int type, u_int32_t seq, struct ssh *ssh)
if (!authctxt->success) {
acceptit = 1;
/* now we can handle user-auth requests */
- ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_REQUEST, &input_userauth_request);
+ ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_REQUEST,
+ &input_userauth_request);
}
}
/* XXX all other service requests are denied */
if (acceptit) {
- packet_start(SSH2_MSG_SERVICE_ACCEPT);
- packet_put_cstring(service);
- packet_send();
- packet_write_wait();
+ if ((r = sshpkt_start(ssh, SSH2_MSG_SERVICE_ACCEPT)) != 0 ||
+ (r = sshpkt_put_cstring(ssh, service)) != 0 ||
+ (r = sshpkt_send(ssh)) != 0 ||
+ (r = ssh_packet_write_wait(ssh)) != 0)
+ goto out;
} else {
debug("bad service request %s", service);
- packet_disconnect("bad service request %s", service);
+ ssh_packet_disconnect(ssh, "bad service request %s", service);
}
+ r = 0;
+ out:
free(service);
- return 0;
+ return r;
}
#define MIN_FAIL_DELAY_SECONDS 0.005
@@ -224,13 +230,13 @@ user_specific_delay(const char *user)
double delay;
(void)snprintf(b, sizeof b, "%llu%s",
- (unsigned long long)options.timing_secret, user);
+ (unsigned long long)options.timing_secret, user);
if (ssh_digest_memory(SSH_DIGEST_SHA512, b, strlen(b), hash, len) != 0)
- fatal("%s: ssh_digest_memory", __func__);
+ fatal_f("ssh_digest_memory");
/* 0-4.2 ms of delay */
delay = (double)PEEK_U32(hash) / 1000 / 1000 / 1000 / 1000;
freezero(hash, len);
- debug3("%s: user specific delay %0.3lfms", __func__, delay/1000);
+ debug3_f("user specific delay %0.3lfms", delay/1000);
return MIN_FAIL_DELAY_SECONDS + delay;
}
@@ -246,8 +252,8 @@ ensure_minimum_time_since(double start, double seconds)
ts.tv_sec = remain;
ts.tv_nsec = (remain - ts.tv_sec) * 1000000000;
- debug3("%s: elapsed %0.3lfms, delaying %0.3lfms (requested %0.3lfms)",
- __func__, elapsed*1000, remain*1000, req*1000);
+ debug3_f("elapsed %0.3lfms, delaying %0.3lfms (requested %0.3lfms)",
+ elapsed*1000, remain*1000, req*1000);
nanosleep(&ts, NULL);
}
@@ -257,16 +263,17 @@ input_userauth_request(int type, u_int32_t seq, struct ssh *ssh)
{
Authctxt *authctxt = ssh->authctxt;
Authmethod *m = NULL;
- char *user, *service, *method, *style = NULL;
- int authenticated = 0;
+ char *user = NULL, *service = NULL, *method = NULL, *style = NULL;
+ int r, authenticated = 0;
double tstart = monotime_double();
if (authctxt == NULL)
fatal("input_userauth_request: no authctxt");
- user = packet_get_cstring(NULL);
- service = packet_get_cstring(NULL);
- method = packet_get_cstring(NULL);
+ if ((r = sshpkt_get_cstring(ssh, &user, NULL)) != 0 ||
+ (r = sshpkt_get_cstring(ssh, &service, NULL)) != 0 ||
+ (r = sshpkt_get_cstring(ssh, &method, NULL)) != 0)
+ goto out;
debug("userauth-request for user %s service %s method %s", user, service, method);
debug("attempt %d failures %d", authctxt->attempt, authctxt->failures);
@@ -275,22 +282,21 @@ input_userauth_request(int type, u_int32_t seq, struct ssh *ssh)
if (authctxt->attempt++ == 0) {
/* setup auth context */
- authctxt->pw = PRIVSEP(getpwnamallow(user));
+ authctxt->pw = PRIVSEP(getpwnamallow(ssh, user));
authctxt->user = xstrdup(user);
if (authctxt->pw && strcmp(service, "ssh-connection")==0) {
authctxt->valid = 1;
- debug2("%s: setting up authctxt for %s",
- __func__, user);
+ debug2_f("setting up authctxt for %s", user);
} else {
/* Invalid user, fake password information */
authctxt->pw = fakepw();
#ifdef SSH_AUDIT_EVENTS
- PRIVSEP(audit_event(SSH_INVALID_USER));
+ PRIVSEP(audit_event(ssh, SSH_INVALID_USER));
#endif
}
#ifdef USE_PAM
if (options.use_pam)
- PRIVSEP(start_pam(authctxt));
+ PRIVSEP(start_pam(ssh));
#endif
ssh_packet_set_log_preamble(ssh, "%suser %s",
authctxt->valid ? "authenticating " : "invalid ", user);
@@ -300,13 +306,14 @@ input_userauth_request(int type, u_int32_t seq, struct ssh *ssh)
authctxt->style = style ? xstrdup(style) : NULL;
if (use_privsep)
mm_inform_authserv(service, style);
- userauth_banner();
+ userauth_banner(ssh);
if (auth2_setup_methods_lists(authctxt) != 0)
- packet_disconnect("no authentication methods enabled");
+ ssh_packet_disconnect(ssh,
+ "no authentication methods enabled");
} else if (strcmp(user, authctxt->user) != 0 ||
strcmp(service, authctxt->service) != 0) {
- packet_disconnect("Change of username or service not allowed: "
- "(%s,%s) -> (%s,%s)",
+ ssh_packet_disconnect(ssh, "Change of username or service "
+ "not allowed: (%s,%s) -> (%s,%s)",
authctxt->user, authctxt->service, user, service);
}
/* reset state */
@@ -332,11 +339,12 @@ input_userauth_request(int type, u_int32_t seq, struct ssh *ssh)
ensure_minimum_time_since(tstart,
user_specific_delay(authctxt->user));
userauth_finish(ssh, authenticated, method, NULL);
-
+ r = 0;
+ out:
free(service);
free(user);
free(method);
- return 0;
+ return r;
}
void
@@ -345,7 +353,7 @@ userauth_finish(struct ssh *ssh, int authenticated, const char *method,
{
Authctxt *authctxt = ssh->authctxt;
char *methods;
- int partial = 0;
+ int r, partial = 0;
if (!authctxt->valid && authenticated)
fatal("INTERNAL ERROR: authenticated invalid user %s",
@@ -358,7 +366,7 @@ userauth_finish(struct ssh *ssh, int authenticated, const char *method,
!auth_root_allowed(ssh, method)) {
authenticated = 0;
#ifdef SSH_AUDIT_EVENTS
- PRIVSEP(audit_event(SSH_LOGIN_ROOT_DENIED));
+ PRIVSEP(audit_event(ssh, SSH_LOGIN_ROOT_DENIED));
#endif
}
@@ -370,7 +378,7 @@ userauth_finish(struct ssh *ssh, int authenticated, const char *method,
}
/* Log before sending the reply */
- auth_log(authctxt, authenticated, partial, method, submethod);
+ auth_log(ssh, authenticated, partial, method, submethod);
/* Update information exposed to session */
if (authenticated || partial)
@@ -381,17 +389,20 @@ userauth_finish(struct ssh *ssh, int authenticated, const char *method,
#ifdef USE_PAM
if (options.use_pam && authenticated) {
- int r;
-
- if (!PRIVSEP(do_pam_account())) {
- /* if PAM returned a message, send it to the user */
- if (sshbuf_len(loginmsg) > 0) {
- if ((r = sshbuf_put(loginmsg, "\0", 1)) != 0)
- fatal("%s: buffer error: %s",
- __func__, ssh_err(r));
- userauth_send_banner(sshbuf_ptr(loginmsg));
- packet_write_wait();
+ int r, success = PRIVSEP(do_pam_account());
+
+ /* If PAM returned a message, send it to the user. */
+ if (sshbuf_len(loginmsg) > 0) {
+ if ((r = sshbuf_put(loginmsg, "\0", 1)) != 0)
+ fatal("%s: buffer error: %s",
+ __func__, ssh_err(r));
+ userauth_send_banner(ssh, sshbuf_ptr(loginmsg));
+ if ((r = ssh_packet_write_wait(ssh)) != 0) {
+ sshpkt_fatal(ssh, r,
+ "%s: send PAM banner", __func__);
}
+ }
+ if (!success) {
fatal("Access denied for user %s by PAM account "
"configuration", authctxt->user);
}
@@ -400,10 +411,12 @@ userauth_finish(struct ssh *ssh, int authenticated, const char *method,
if (authenticated == 1) {
/* turn off userauth */
- ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_REQUEST, &dispatch_protocol_ignore);
- packet_start(SSH2_MSG_USERAUTH_SUCCESS);
- packet_send();
- packet_write_wait();
+ ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_REQUEST,
+ &dispatch_protocol_ignore);
+ if ((r = sshpkt_start(ssh, SSH2_MSG_USERAUTH_SUCCESS)) != 0 ||
+ (r = sshpkt_send(ssh)) != 0 ||
+ (r = ssh_packet_write_wait(ssh)) != 0)
+ fatal_fr(r, "send success packet");
/* now we can break out */
authctxt->success = 1;
ssh_packet_set_log_preamble(ssh, "user %s", authctxt->user);
@@ -416,18 +429,19 @@ userauth_finish(struct ssh *ssh, int authenticated, const char *method,
}
if (authctxt->failures >= options.max_authtries) {
#ifdef SSH_AUDIT_EVENTS
- PRIVSEP(audit_event(SSH_LOGIN_EXCEED_MAXTRIES));
+ PRIVSEP(audit_event(ssh, SSH_LOGIN_EXCEED_MAXTRIES));
#endif
- auth_maxtries_exceeded(authctxt);
+ auth_maxtries_exceeded(ssh);
}
methods = authmethods_get(authctxt);
- debug3("%s: failure partial=%d next methods=\"%s\"", __func__,
+ debug3_f("failure partial=%d next methods=\"%s\"",
partial, methods);
- packet_start(SSH2_MSG_USERAUTH_FAILURE);
- packet_put_cstring(methods);
- packet_put_char(partial);
- packet_send();
- packet_write_wait();
+ if ((r = sshpkt_start(ssh, SSH2_MSG_USERAUTH_FAILURE)) != 0 ||
+ (r = sshpkt_put_cstring(ssh, methods)) != 0 ||
+ (r = sshpkt_put_u8(ssh, partial)) != 0 ||
+ (r = sshpkt_send(ssh)) != 0 ||
+ (r = ssh_packet_write_wait(ssh)) != 0)
+ fatal_fr(r, "send failure packet");
free(methods);
}
}
@@ -465,7 +479,7 @@ authmethods_get(Authctxt *authctxt)
int i, r;
if ((b = sshbuf_new()) == NULL)
- fatal("%s: sshbuf_new failed", __func__);
+ fatal_f("sshbuf_new failed");
for (i = 0; authmethods[i] != NULL; i++) {
if (strcmp(authmethods[i]->name, "none") == 0)
continue;
@@ -477,10 +491,10 @@ authmethods_get(Authctxt *authctxt)
continue;
if ((r = sshbuf_putf(b, "%s%s", sshbuf_len(b) ? "," : "",
authmethods[i]->name)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "buffer error");
}
if ((list = sshbuf_dup_string(b)) == NULL)
- fatal("%s: sshbuf_dup_string failed", __func__);
+ fatal_f("sshbuf_dup_string failed");
sshbuf_free(b);
return list;
}
@@ -562,9 +576,17 @@ auth2_setup_methods_lists(Authctxt *authctxt)
{
u_int i;
+ /* First, normalise away the "any" pseudo-method */
+ if (options.num_auth_methods == 1 &&
+ strcmp(options.auth_methods[0], "any") == 0) {
+ free(options.auth_methods[0]);
+ options.auth_methods[0] = NULL;
+ options.num_auth_methods = 0;
+ }
+
if (options.num_auth_methods == 0)
return 0;
- debug3("%s: checking methods", __func__);
+ debug3_f("checking methods");
authctxt->auth_methods = xcalloc(options.num_auth_methods,
sizeof(*authctxt->auth_methods));
authctxt->num_auth_methods = 0;
@@ -652,7 +674,7 @@ auth2_update_methods_lists(Authctxt *authctxt, const char *method,
{
u_int i, found = 0;
- debug3("%s: updating methods list after \"%s\"", __func__, method);
+ debug3_f("updating methods list after \"%s\"", method);
for (i = 0; i < authctxt->num_auth_methods; i++) {
if (!remove_method(&(authctxt->auth_methods[i]), method,
submethod))
@@ -667,7 +689,7 @@ auth2_update_methods_lists(Authctxt *authctxt, const char *method,
}
/* This should not happen, but would be bad if it did */
if (!found)
- fatal("%s: method not in AuthenticationMethods", __func__);
+ fatal_f("method not in AuthenticationMethods");
return 0;
}
@@ -685,7 +707,7 @@ void
auth2_record_info(Authctxt *authctxt, const char *fmt, ...)
{
va_list ap;
- int i;
+ int i;
free(authctxt->auth_method_info);
authctxt->auth_method_info = NULL;
@@ -694,8 +716,8 @@ auth2_record_info(Authctxt *authctxt, const char *fmt, ...)
i = vasprintf(&authctxt->auth_method_info, fmt, ap);
va_end(ap);
- if (i < 0 || authctxt->auth_method_info == NULL)
- fatal("%s: vasprintf failed", __func__);
+ if (i == -1)
+ fatal_f("vasprintf failed");
}
/*
@@ -711,7 +733,7 @@ auth2_record_key(Authctxt *authctxt, int authenticated,
int r;
if ((r = sshkey_from_private(key, &dup)) != 0)
- fatal("%s: copy key: %s", __func__, ssh_err(r));
+ fatal_fr(r, "copy key");
sshkey_free(authctxt->auth_method_key);
authctxt->auth_method_key = dup;
@@ -720,11 +742,11 @@ auth2_record_key(Authctxt *authctxt, int authenticated,
/* If authenticated, make sure we don't accept this key again */
if ((r = sshkey_from_private(key, &dup)) != 0)
- fatal("%s: copy key: %s", __func__, ssh_err(r));
+ fatal_fr(r, "copy key");
if (authctxt->nprev_keys >= INT_MAX ||
(tmp = recallocarray(authctxt->prev_keys, authctxt->nprev_keys,
authctxt->nprev_keys + 1, sizeof(*authctxt->prev_keys))) == NULL)
- fatal("%s: reallocarray failed", __func__);
+ fatal_f("reallocarray failed");
authctxt->prev_keys = tmp;
authctxt->prev_keys[authctxt->nprev_keys] = dup;
authctxt->nprev_keys++;
@@ -742,7 +764,7 @@ auth2_key_already_used(Authctxt *authctxt, const struct sshkey *key)
if (sshkey_equal_public(key, authctxt->prev_keys[i])) {
fp = sshkey_fingerprint(authctxt->prev_keys[i],
options.fingerprint_hash, SSH_FP_DEFAULT);
- debug3("%s: key already used: %s %s", __func__,
+ debug3_f("key already used: %s %s",
sshkey_type(authctxt->prev_keys[i]),
fp == NULL ? "UNKNOWN" : fp);
free(fp);
@@ -764,35 +786,34 @@ auth2_update_session_info(Authctxt *authctxt, const char *method,
if (authctxt->session_info == NULL) {
if ((authctxt->session_info = sshbuf_new()) == NULL)
- fatal("%s: sshbuf_new", __func__);
+ fatal_f("sshbuf_new");
}
/* Append method[/submethod] */
if ((r = sshbuf_putf(authctxt->session_info, "%s%s%s",
method, submethod == NULL ? "" : "/",
submethod == NULL ? "" : submethod)) != 0)
- fatal("%s: append method: %s", __func__, ssh_err(r));
+ fatal_fr(r, "append method");
/* Append key if present */
if (authctxt->auth_method_key != NULL) {
if ((r = sshbuf_put_u8(authctxt->session_info, ' ')) != 0 ||
(r = sshkey_format_text(authctxt->auth_method_key,
authctxt->session_info)) != 0)
- fatal("%s: append key: %s", __func__, ssh_err(r));
+ fatal_fr(r, "append key");
}
if (authctxt->auth_method_info != NULL) {
/* Ensure no ambiguity here */
if (strchr(authctxt->auth_method_info, '\n') != NULL)
- fatal("%s: auth_method_info contains \\n", __func__);
+ fatal_f("auth_method_info contains \\n");
if ((r = sshbuf_put_u8(authctxt->session_info, ' ')) != 0 ||
(r = sshbuf_putf(authctxt->session_info, "%s",
authctxt->auth_method_info)) != 0) {
- fatal("%s: append method info: %s",
- __func__, ssh_err(r));
+ fatal_fr(r, "append method info");
}
}
if ((r = sshbuf_put_u8(authctxt->session_info, '\n')) != 0)
- fatal("%s: append: %s", __func__, ssh_err(r));
+ fatal_fr(r, "append");
}
diff --git a/crypto/openssh/authfd.c b/crypto/openssh/authfd.c
index ecdd869abf01..9f092f7cf955 100644
--- a/crypto/openssh/authfd.c
+++ b/crypto/openssh/authfd.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: authfd.c,v 1.111 2018/07/09 21:59:10 markus Exp $ */
+/* $OpenBSD: authfd.c,v 1.127 2021/01/26 00:46:17 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -44,8 +44,8 @@
#include <fcntl.h>
#include <stdlib.h>
#include <signal.h>
-#include <stdarg.h>
#include <string.h>
+#include <stdarg.h>
#include <unistd.h>
#include <errno.h>
@@ -62,7 +62,7 @@
#include "ssherr.h"
#define MAX_AGENT_IDENTITIES 2048 /* Max keys in agent reply */
-#define MAX_AGENT_REPLY_LEN (256 * 1024) /* Max bytes in agent reply */
+#define MAX_AGENT_REPLY_LEN (256 * 1024) /* Max bytes in agent reply */
/* macro to check for "agent failure" message */
#define agent_failed(x) \
@@ -82,31 +82,26 @@ decode_reply(u_char type)
return SSH_ERR_INVALID_FORMAT;
}
-/* Returns the number of the authentication fd, or -1 if there is none. */
+/*
+ * Opens an authentication socket at the provided path and stores the file
+ * descriptor in fdp. Returns 0 on success and an error on failure.
+ */
int
-ssh_get_authentication_socket(int *fdp)
+ssh_get_authentication_socket_path(const char *authsocket, int *fdp)
{
- const char *authsocket;
int sock, oerrno;
struct sockaddr_un sunaddr;
- if (fdp != NULL)
- *fdp = -1;
-
- authsocket = getenv(SSH_AUTHSOCKET_ENV_NAME);
- if (!authsocket)
- return SSH_ERR_AGENT_NOT_PRESENT;
-
memset(&sunaddr, 0, sizeof(sunaddr));
sunaddr.sun_family = AF_UNIX;
strlcpy(sunaddr.sun_path, authsocket, sizeof(sunaddr.sun_path));
- if ((sock = socket(AF_UNIX, SOCK_STREAM, 0)) < 0)
+ if ((sock = socket(AF_UNIX, SOCK_STREAM, 0)) == -1)
return SSH_ERR_SYSTEM_ERROR;
/* close on exec */
if (fcntl(sock, F_SETFD, FD_CLOEXEC) == -1 ||
- connect(sock, (struct sockaddr *)&sunaddr, sizeof(sunaddr)) < 0) {
+ connect(sock, (struct sockaddr *)&sunaddr, sizeof(sunaddr)) == -1) {
oerrno = errno;
close(sock);
errno = oerrno;
@@ -119,6 +114,25 @@ ssh_get_authentication_socket(int *fdp)
return 0;
}
+/*
+ * Opens the default authentication socket and stores the file descriptor in
+ * fdp. Returns 0 on success and an error on failure.
+ */
+int
+ssh_get_authentication_socket(int *fdp)
+{
+ const char *authsocket;
+
+ if (fdp != NULL)
+ *fdp = -1;
+
+ authsocket = getenv(SSH_AUTHSOCKET_ENV_NAME);
+ if (authsocket == NULL || *authsocket == '\0')
+ return SSH_ERR_AGENT_NOT_PRESENT;
+
+ return ssh_get_authentication_socket_path(authsocket, fdp);
+}
+
/* Communicate with agent: send request and read reply */
static int
ssh_request_reply(int sock, struct sshbuf *request, struct sshbuf *reply)
@@ -163,6 +177,27 @@ ssh_request_reply(int sock, struct sshbuf *request, struct sshbuf *reply)
return 0;
}
+/* Communicate with agent: sent request, read and decode status reply */
+static int
+ssh_request_reply_decode(int sock, struct sshbuf *request)
+{
+ struct sshbuf *reply;
+ int r;
+ u_char type;
+
+ if ((reply = sshbuf_new()) == NULL)
+ return SSH_ERR_ALLOC_FAIL;
+ if ((r = ssh_request_reply(sock, request, reply)) != 0 ||
+ (r = sshbuf_get_u8(reply, &type)) != 0 ||
+ (r = decode_reply(type)) != 0)
+ goto out;
+ /* success */
+ r = 0;
+ out:
+ sshbuf_free(reply);
+ return r;
+}
+
/*
* Closes the agent socket if it should be closed (depends on how it was
* obtained). The argument must have been returned by
@@ -186,13 +221,11 @@ ssh_lock_agent(int sock, int lock, const char *password)
if ((msg = sshbuf_new()) == NULL)
return SSH_ERR_ALLOC_FAIL;
if ((r = sshbuf_put_u8(msg, type)) != 0 ||
- (r = sshbuf_put_cstring(msg, password)) != 0)
- goto out;
- if ((r = ssh_request_reply(sock, msg, msg)) != 0)
- goto out;
- if ((r = sshbuf_get_u8(msg, &type)) != 0)
+ (r = sshbuf_put_cstring(msg, password)) != 0 ||
+ (r = ssh_request_reply_decode(sock, msg)) != 0)
goto out;
- r = decode_reply(type);
+ /* success */
+ r = 0;
out:
sshbuf_free(msg);
return r;
@@ -312,10 +345,38 @@ ssh_free_identitylist(struct ssh_identitylist *idl)
if (idl->comments != NULL)
free(idl->comments[i]);
}
+ free(idl->keys);
+ free(idl->comments);
free(idl);
}
/*
+ * Check if the ssh agent has a given key.
+ * Returns 0 if found, or a negative SSH_ERR_* error code on failure.
+ */
+int
+ssh_agent_has_key(int sock, const struct sshkey *key)
+{
+ int r, ret = SSH_ERR_KEY_NOT_FOUND;
+ size_t i;
+ struct ssh_identitylist *idlist = NULL;
+
+ if ((r = ssh_fetch_identitylist(sock, &idlist)) != 0) {
+ return r;
+ }
+
+ for (i = 0; i < idlist->nkeys; i++) {
+ if (sshkey_equal_public(idlist->keys[i], key)) {
+ ret = 0;
+ break;
+ }
+ }
+
+ ssh_free_identitylist(idlist);
+ return ret;
+}
+
+/*
* Sends a challenge (typically from a server via ssh(1)) to the agent,
* and waits for a response from the agent.
* Returns true (non-zero) if the agent gave the correct answer, zero
@@ -327,10 +388,12 @@ ssh_free_identitylist(struct ssh_identitylist *idl)
static u_int
agent_encode_alg(const struct sshkey *key, const char *alg)
{
- if (alg != NULL && key->type == KEY_RSA) {
- if (strcmp(alg, "rsa-sha2-256") == 0)
+ if (alg != NULL && sshkey_type_plain(key->type) == KEY_RSA) {
+ if (strcmp(alg, "rsa-sha2-256") == 0 ||
+ strcmp(alg, "rsa-sha2-256-cert-v01@openssh.com") == 0)
return SSH_AGENT_RSA_SHA2_256;
- else if (strcmp(alg, "rsa-sha2-512") == 0)
+ if (strcmp(alg, "rsa-sha2-512") == 0 ||
+ strcmp(alg, "rsa-sha2-512-cert-v01@openssh.com") == 0)
return SSH_AGENT_RSA_SHA2_512;
}
return 0;
@@ -393,7 +456,8 @@ ssh_agent_sign(int sock, const struct sshkey *key,
static int
-encode_constraints(struct sshbuf *m, u_int life, u_int confirm, u_int maxsign)
+encode_constraints(struct sshbuf *m, u_int life, u_int confirm, u_int maxsign,
+ const char *provider)
{
int r;
@@ -411,6 +475,14 @@ encode_constraints(struct sshbuf *m, u_int life, u_int confirm, u_int maxsign)
(r = sshbuf_put_u32(m, maxsign)) != 0)
goto out;
}
+ if (provider != NULL) {
+ if ((r = sshbuf_put_u8(m,
+ SSH_AGENT_CONSTRAIN_EXTENSION)) != 0 ||
+ (r = sshbuf_put_cstring(m,
+ "sk-provider@openssh.com")) != 0 ||
+ (r = sshbuf_put_cstring(m, provider)) != 0)
+ goto out;
+ }
r = 0;
out:
return r;
@@ -421,11 +493,12 @@ encode_constraints(struct sshbuf *m, u_int life, u_int confirm, u_int maxsign)
* This call is intended only for use by ssh-add(1) and like applications.
*/
int
-ssh_add_identity_constrained(int sock, const struct sshkey *key,
- const char *comment, u_int life, u_int confirm, u_int maxsign)
+ssh_add_identity_constrained(int sock, struct sshkey *key,
+ const char *comment, u_int life, u_int confirm, u_int maxsign,
+ const char *provider)
{
struct sshbuf *msg;
- int r, constrained = (life || confirm || maxsign);
+ int r, constrained = (life || confirm || maxsign || provider);
u_char type;
if ((msg = sshbuf_new()) == NULL)
@@ -439,9 +512,13 @@ ssh_add_identity_constrained(int sock, const struct sshkey *key,
case KEY_DSA_CERT:
case KEY_ECDSA:
case KEY_ECDSA_CERT:
+ case KEY_ECDSA_SK:
+ case KEY_ECDSA_SK_CERT:
#endif
case KEY_ED25519:
case KEY_ED25519_CERT:
+ case KEY_ED25519_SK:
+ case KEY_ED25519_SK_CERT:
case KEY_XMSS:
case KEY_XMSS_CERT:
type = constrained ?
@@ -449,7 +526,7 @@ ssh_add_identity_constrained(int sock, const struct sshkey *key,
SSH2_AGENTC_ADD_IDENTITY;
if ((r = sshbuf_put_u8(msg, type)) != 0 ||
(r = sshkey_private_serialize_maxsign(key, msg, maxsign,
- NULL)) != 0 ||
+ 0)) != 0 ||
(r = sshbuf_put_cstring(msg, comment)) != 0)
goto out;
break;
@@ -458,13 +535,13 @@ ssh_add_identity_constrained(int sock, const struct sshkey *key,
goto out;
}
if (constrained &&
- (r = encode_constraints(msg, life, confirm, maxsign)) != 0)
+ (r = encode_constraints(msg, life, confirm, maxsign,
+ provider)) != 0)
goto out;
- if ((r = ssh_request_reply(sock, msg, msg)) != 0)
+ if ((r = ssh_request_reply_decode(sock, msg)) != 0)
goto out;
- if ((r = sshbuf_get_u8(msg, &type)) != 0)
- goto out;
- r = decode_reply(type);
+ /* success */
+ r = 0;
out:
sshbuf_free(msg);
return r;
@@ -475,11 +552,11 @@ ssh_add_identity_constrained(int sock, const struct sshkey *key,
* This call is intended only for use by ssh-add(1) and like applications.
*/
int
-ssh_remove_identity(int sock, struct sshkey *key)
+ssh_remove_identity(int sock, const struct sshkey *key)
{
struct sshbuf *msg;
int r;
- u_char type, *blob = NULL;
+ u_char *blob = NULL;
size_t blen;
if ((msg = sshbuf_new()) == NULL)
@@ -496,16 +573,13 @@ ssh_remove_identity(int sock, struct sshkey *key)
r = SSH_ERR_INVALID_ARGUMENT;
goto out;
}
- if ((r = ssh_request_reply(sock, msg, msg)) != 0)
+ if ((r = ssh_request_reply_decode(sock, msg)) != 0)
goto out;
- if ((r = sshbuf_get_u8(msg, &type)) != 0)
- goto out;
- r = decode_reply(type);
+ /* success */
+ r = 0;
out:
- if (blob != NULL) {
- explicit_bzero(blob, blen);
- free(blob);
- }
+ if (blob != NULL)
+ freezero(blob, blen);
sshbuf_free(msg);
return r;
}
@@ -536,13 +610,12 @@ ssh_update_card(int sock, int add, const char *reader_id, const char *pin,
(r = sshbuf_put_cstring(msg, pin)) != 0)
goto out;
if (constrained &&
- (r = encode_constraints(msg, life, confirm, 0)) != 0)
+ (r = encode_constraints(msg, life, confirm, 0, NULL)) != 0)
goto out;
- if ((r = ssh_request_reply(sock, msg, msg)) != 0)
- goto out;
- if ((r = sshbuf_get_u8(msg, &type)) != 0)
+ if ((r = ssh_request_reply_decode(sock, msg)) != 0)
goto out;
- r = decode_reply(type);
+ /* success */
+ r = 0;
out:
sshbuf_free(msg);
return r;
@@ -569,11 +642,10 @@ ssh_remove_all_identities(int sock, int version)
return SSH_ERR_ALLOC_FAIL;
if ((r = sshbuf_put_u8(msg, type)) != 0)
goto out;
- if ((r = ssh_request_reply(sock, msg, msg)) != 0)
- goto out;
- if ((r = sshbuf_get_u8(msg, &type)) != 0)
+ if ((r = ssh_request_reply_decode(sock, msg)) != 0)
goto out;
- r = decode_reply(type);
+ /* success */
+ r = 0;
out:
sshbuf_free(msg);
return r;
diff --git a/crypto/openssh/authfd.h b/crypto/openssh/authfd.h
index a032fd5428fb..4fbf82f8c008 100644
--- a/crypto/openssh/authfd.h
+++ b/crypto/openssh/authfd.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: authfd.h,v 1.44 2018/07/12 04:35:25 djm Exp $ */
+/* $OpenBSD: authfd.h,v 1.49 2020/06/26 05:03:36 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -24,14 +24,17 @@ struct ssh_identitylist {
};
int ssh_get_authentication_socket(int *fdp);
+int ssh_get_authentication_socket_path(const char *authsocket, int *fdp);
void ssh_close_authentication_socket(int sock);
int ssh_lock_agent(int sock, int lock, const char *password);
int ssh_fetch_identitylist(int sock, struct ssh_identitylist **idlp);
void ssh_free_identitylist(struct ssh_identitylist *idl);
-int ssh_add_identity_constrained(int sock, const struct sshkey *key,
- const char *comment, u_int life, u_int confirm, u_int maxsign);
-int ssh_remove_identity(int sock, struct sshkey *key);
+int ssh_add_identity_constrained(int sock, struct sshkey *key,
+ const char *comment, u_int life, u_int confirm, u_int maxsign,
+ const char *provider);
+int ssh_agent_has_key(int sock, const struct sshkey *key);
+int ssh_remove_identity(int sock, const struct sshkey *key);
int ssh_update_card(int sock, int add, const char *reader_id,
const char *pin, u_int life, u_int confirm);
int ssh_remove_all_identities(int sock, int version);
@@ -76,6 +79,7 @@ int ssh_agent_sign(int sock, const struct sshkey *key,
#define SSH_AGENT_CONSTRAIN_LIFETIME 1
#define SSH_AGENT_CONSTRAIN_CONFIRM 2
#define SSH_AGENT_CONSTRAIN_MAXSIGN 3
+#define SSH_AGENT_CONSTRAIN_EXTENSION 255
/* extended failure messages */
#define SSH2_AGENT_FAILURE 30
diff --git a/crypto/openssh/authfile.c b/crypto/openssh/authfile.c
index b1c92f4ad621..946f50ca8114 100644
--- a/crypto/openssh/authfile.c
+++ b/crypto/openssh/authfile.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: authfile.c,v 1.131 2018/09/21 12:20:12 djm Exp $ */
+/* $OpenBSD: authfile.c,v 1.141 2020/06/18 23:33:38 djm Exp $ */
/*
* Copyright (c) 2000, 2013 Markus Friedl. All rights reserved.
*
@@ -55,26 +55,19 @@
static int
sshkey_save_private_blob(struct sshbuf *keybuf, const char *filename)
{
- int fd, oerrno;
+ int r;
+ mode_t omask;
- if ((fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0600)) < 0)
- return SSH_ERR_SYSTEM_ERROR;
- if (atomicio(vwrite, fd, sshbuf_mutable_ptr(keybuf),
- sshbuf_len(keybuf)) != sshbuf_len(keybuf)) {
- oerrno = errno;
- close(fd);
- unlink(filename);
- errno = oerrno;
- return SSH_ERR_SYSTEM_ERROR;
- }
- close(fd);
- return 0;
+ omask = umask(077);
+ r = sshbuf_write_file(filename, keybuf);
+ umask(omask);
+ return r;
}
int
sshkey_save_private(struct sshkey *key, const char *filename,
const char *passphrase, const char *comment,
- int force_new_format, const char *new_format_cipher, int new_format_rounds)
+ int format, const char *openssh_format_cipher, int openssh_format_rounds)
{
struct sshbuf *keyblob = NULL;
int r;
@@ -82,7 +75,7 @@ sshkey_save_private(struct sshkey *key, const char *filename,
if ((keyblob = sshbuf_new()) == NULL)
return SSH_ERR_ALLOC_FAIL;
if ((r = sshkey_private_to_fileblob(key, keyblob, passphrase, comment,
- force_new_format, new_format_cipher, new_format_rounds)) != 0)
+ format, openssh_format_cipher, openssh_format_rounds)) != 0)
goto out;
if ((r = sshkey_save_private_blob(keyblob, filename)) != 0)
goto out;
@@ -92,56 +85,13 @@ sshkey_save_private(struct sshkey *key, const char *filename,
return r;
}
-/* Load a key from a fd into a buffer */
-int
-sshkey_load_file(int fd, struct sshbuf *blob)
-{
- u_char buf[1024];
- size_t len;
- struct stat st;
- int r;
-
- if (fstat(fd, &st) < 0)
- return SSH_ERR_SYSTEM_ERROR;
- if ((st.st_mode & (S_IFSOCK|S_IFCHR|S_IFIFO)) == 0 &&
- st.st_size > MAX_KEY_FILE_SIZE)
- return SSH_ERR_INVALID_FORMAT;
- for (;;) {
- if ((len = atomicio(read, fd, buf, sizeof(buf))) == 0) {
- if (errno == EPIPE)
- break;
- r = SSH_ERR_SYSTEM_ERROR;
- goto out;
- }
- if ((r = sshbuf_put(blob, buf, len)) != 0)
- goto out;
- if (sshbuf_len(blob) > MAX_KEY_FILE_SIZE) {
- r = SSH_ERR_INVALID_FORMAT;
- goto out;
- }
- }
- if ((st.st_mode & (S_IFSOCK|S_IFCHR|S_IFIFO)) == 0 &&
- st.st_size != (off_t)sshbuf_len(blob)) {
- r = SSH_ERR_FILE_CHANGED;
- goto out;
- }
- r = 0;
-
- out:
- explicit_bzero(buf, sizeof(buf));
- if (r != 0)
- sshbuf_reset(blob);
- return r;
-}
-
-
/* XXX remove error() calls from here? */
int
sshkey_perm_ok(int fd, const char *filename)
{
struct stat st;
- if (fstat(fd, &st) < 0)
+ if (fstat(fd, &st) == -1)
return SSH_ERR_SYSTEM_ERROR;
/*
* if a key owned by the user is accessed, then we check the
@@ -164,10 +114,9 @@ sshkey_perm_ok(int fd, const char *filename)
return 0;
}
-/* XXX kill perm_ok now that we have SSH_ERR_KEY_BAD_PERMISSIONS? */
int
sshkey_load_private_type(int type, const char *filename, const char *passphrase,
- struct sshkey **keyp, char **commentp, int *perm_ok)
+ struct sshkey **keyp, char **commentp)
{
int fd, r;
@@ -176,19 +125,12 @@ sshkey_load_private_type(int type, const char *filename, const char *passphrase,
if (commentp != NULL)
*commentp = NULL;
- if ((fd = open(filename, O_RDONLY)) < 0) {
- if (perm_ok != NULL)
- *perm_ok = 0;
+ if ((fd = open(filename, O_RDONLY)) == -1)
return SSH_ERR_SYSTEM_ERROR;
- }
- if (sshkey_perm_ok(fd, filename) != 0) {
- if (perm_ok != NULL)
- *perm_ok = 0;
- r = SSH_ERR_KEY_BAD_PERMISSIONS;
+
+ r = sshkey_perm_ok(fd, filename);
+ if (r != 0)
goto out;
- }
- if (perm_ok != NULL)
- *perm_ok = 1;
r = sshkey_load_private_type_fd(fd, type, passphrase, keyp, commentp);
if (r == 0 && keyp && *keyp)
@@ -199,6 +141,14 @@ sshkey_load_private_type(int type, const char *filename, const char *passphrase,
}
int
+sshkey_load_private(const char *filename, const char *passphrase,
+ struct sshkey **keyp, char **commentp)
+{
+ return sshkey_load_private_type(KEY_UNSPEC, filename, passphrase,
+ keyp, commentp);
+}
+
+int
sshkey_load_private_type_fd(int fd, int type, const char *passphrase,
struct sshkey **keyp, char **commentp)
{
@@ -207,11 +157,7 @@ sshkey_load_private_type_fd(int fd, int type, const char *passphrase,
if (keyp != NULL)
*keyp = NULL;
- if ((buffer = sshbuf_new()) == NULL) {
- r = SSH_ERR_ALLOC_FAIL;
- goto out;
- }
- if ((r = sshkey_load_file(fd, buffer)) != 0 ||
+ if ((r = sshbuf_load_fd(fd, &buffer)) != 0 ||
(r = sshkey_parse_private_fileblob_type(buffer, type,
passphrase, keyp, commentp)) != 0)
goto out;
@@ -223,56 +169,57 @@ sshkey_load_private_type_fd(int fd, int type, const char *passphrase,
return r;
}
-/* XXX this is almost identical to sshkey_load_private_type() */
-int
-sshkey_load_private(const char *filename, const char *passphrase,
- struct sshkey **keyp, char **commentp)
+/* Load a pubkey from the unencrypted envelope of a new-format private key */
+static int
+sshkey_load_pubkey_from_private(const char *filename, struct sshkey **pubkeyp)
{
struct sshbuf *buffer = NULL;
+ struct sshkey *pubkey = NULL;
int r, fd;
- if (keyp != NULL)
- *keyp = NULL;
- if (commentp != NULL)
- *commentp = NULL;
+ if (pubkeyp != NULL)
+ *pubkeyp = NULL;
- if ((fd = open(filename, O_RDONLY)) < 0)
+ if ((fd = open(filename, O_RDONLY)) == -1)
return SSH_ERR_SYSTEM_ERROR;
- if (sshkey_perm_ok(fd, filename) != 0) {
- r = SSH_ERR_KEY_BAD_PERMISSIONS;
+ if ((r = sshbuf_load_fd(fd, &buffer)) != 0 ||
+ (r = sshkey_parse_pubkey_from_private_fileblob_type(buffer,
+ KEY_UNSPEC, &pubkey)) != 0)
goto out;
- }
-
- if ((buffer = sshbuf_new()) == NULL) {
- r = SSH_ERR_ALLOC_FAIL;
+ if ((r = sshkey_set_filename(pubkey, filename)) != 0)
goto out;
+ /* success */
+ if (pubkeyp != NULL) {
+ *pubkeyp = pubkey;
+ pubkey = NULL;
}
- if ((r = sshkey_load_file(fd, buffer)) != 0 ||
- (r = sshkey_parse_private_fileblob(buffer, passphrase, keyp,
- commentp)) != 0)
- goto out;
- if (keyp && *keyp &&
- (r = sshkey_set_filename(*keyp, filename)) != 0)
- goto out;
r = 0;
out:
close(fd);
sshbuf_free(buffer);
+ sshkey_free(pubkey);
return r;
}
static int
-sshkey_try_load_public(struct sshkey *k, const char *filename, char **commentp)
+sshkey_try_load_public(struct sshkey **kp, const char *filename,
+ char **commentp)
{
FILE *f;
char *line = NULL, *cp;
size_t linesize = 0;
int r;
+ struct sshkey *k = NULL;
+ *kp = NULL;
if (commentp != NULL)
*commentp = NULL;
if ((f = fopen(filename, "r")) == NULL)
return SSH_ERR_SYSTEM_ERROR;
+ if ((k = sshkey_new(KEY_UNSPEC)) == NULL) {
+ fclose(f);
+ return SSH_ERR_ALLOC_FAIL;
+ }
while (getline(&line, &linesize, f) != -1) {
cp = line;
switch (*cp) {
@@ -297,12 +244,15 @@ sshkey_try_load_public(struct sshkey *k, const char *filename, char **commentp)
if (*commentp == NULL)
r = SSH_ERR_ALLOC_FAIL;
}
+ /* success */
+ *kp = k;
free(line);
fclose(f);
return r;
}
}
}
+ free(k);
free(line);
fclose(f);
return SSH_ERR_INVALID_FORMAT;
@@ -312,44 +262,35 @@ sshkey_try_load_public(struct sshkey *k, const char *filename, char **commentp)
int
sshkey_load_public(const char *filename, struct sshkey **keyp, char **commentp)
{
- struct sshkey *pub = NULL;
- char *file = NULL;
- int r;
+ char *pubfile = NULL;
+ int r, oerrno;
if (keyp != NULL)
*keyp = NULL;
if (commentp != NULL)
*commentp = NULL;
- if ((pub = sshkey_new(KEY_UNSPEC)) == NULL)
- return SSH_ERR_ALLOC_FAIL;
- if ((r = sshkey_try_load_public(pub, filename, commentp)) == 0) {
- if (keyp != NULL) {
- *keyp = pub;
- pub = NULL;
- }
- r = 0;
+ if ((r = sshkey_try_load_public(keyp, filename, commentp)) == 0)
goto out;
- }
- sshkey_free(pub);
/* try .pub suffix */
- if (asprintf(&file, "%s.pub", filename) == -1)
+ if (asprintf(&pubfile, "%s.pub", filename) == -1)
return SSH_ERR_ALLOC_FAIL;
- if ((pub = sshkey_new(KEY_UNSPEC)) == NULL) {
- r = SSH_ERR_ALLOC_FAIL;
+ if ((r = sshkey_try_load_public(keyp, pubfile, commentp)) == 0)
goto out;
- }
- if ((r = sshkey_try_load_public(pub, file, commentp)) == 0) {
- if (keyp != NULL) {
- *keyp = pub;
- pub = NULL;
- }
- r = 0;
- }
+
+ /* finally, try to extract public key from private key file */
+ if ((r = sshkey_load_pubkey_from_private(filename, keyp)) == 0)
+ goto out;
+
+ /* Pretend we couldn't find the key */
+ r = SSH_ERR_SYSTEM_ERROR;
+ errno = ENOENT;
+
out:
- free(file);
- sshkey_free(pub);
+ oerrno = errno;
+ free(pubfile);
+ errno = oerrno;
return r;
}
@@ -367,18 +308,7 @@ sshkey_load_cert(const char *filename, struct sshkey **keyp)
if (asprintf(&file, "%s-cert.pub", filename) == -1)
return SSH_ERR_ALLOC_FAIL;
- if ((pub = sshkey_new(KEY_UNSPEC)) == NULL) {
- goto out;
- }
- if ((r = sshkey_try_load_public(pub, file, NULL)) != 0)
- goto out;
- /* success */
- if (keyp != NULL) {
- *keyp = pub;
- pub = NULL;
- }
- r = 0;
- out:
+ r = sshkey_try_load_public(keyp, file, NULL);
free(file);
sshkey_free(pub);
return r;
@@ -387,7 +317,7 @@ sshkey_load_cert(const char *filename, struct sshkey **keyp)
/* Load private key and certificate */
int
sshkey_load_private_cert(int type, const char *filename, const char *passphrase,
- struct sshkey **keyp, int *perm_ok)
+ struct sshkey **keyp)
{
struct sshkey *key = NULL, *cert = NULL;
int r;
@@ -410,7 +340,7 @@ sshkey_load_private_cert(int type, const char *filename, const char *passphrase,
}
if ((r = sshkey_load_private_type(type, filename,
- passphrase, &key, NULL, perm_ok)) != 0 ||
+ passphrase, &key, NULL)) != 0 ||
(r = sshkey_load_cert(filename, &cert)) != 0)
goto out;
@@ -536,3 +466,56 @@ sshkey_check_revoked(struct sshkey *key, const char *revoked_keys_file)
}
}
+/*
+ * Advanced *cpp past the end of key options, defined as the first unquoted
+ * whitespace character. Returns 0 on success or -1 on failure (e.g.
+ * unterminated quotes).
+ */
+int
+sshkey_advance_past_options(char **cpp)
+{
+ char *cp = *cpp;
+ int quoted = 0;
+
+ for (; *cp && (quoted || (*cp != ' ' && *cp != '\t')); cp++) {
+ if (*cp == '\\' && cp[1] == '"')
+ cp++; /* Skip both */
+ else if (*cp == '"')
+ quoted = !quoted;
+ }
+ *cpp = cp;
+ /* return failure for unterminated quotes */
+ return (*cp == '\0' && quoted) ? -1 : 0;
+}
+
+/* Save a public key */
+int
+sshkey_save_public(const struct sshkey *key, const char *path,
+ const char *comment)
+{
+ int fd, oerrno;
+ FILE *f = NULL;
+ int r = SSH_ERR_INTERNAL_ERROR;
+
+ if ((fd = open(path, O_WRONLY|O_CREAT|O_TRUNC, 0644)) == -1)
+ return SSH_ERR_SYSTEM_ERROR;
+ if ((f = fdopen(fd, "w")) == NULL) {
+ r = SSH_ERR_SYSTEM_ERROR;
+ goto fail;
+ }
+ if ((r = sshkey_write(key, f)) != 0)
+ goto fail;
+ fprintf(f, " %s\n", comment);
+ if (ferror(f) || fclose(f) != 0) {
+ r = SSH_ERR_SYSTEM_ERROR;
+ fail:
+ oerrno = errno;
+ if (f != NULL)
+ fclose(f);
+ else
+ close(fd);
+ errno = oerrno;
+ return r;
+ }
+ return 0;
+}
diff --git a/crypto/openssh/authfile.h b/crypto/openssh/authfile.h
index 624d269f1bdb..1db067a813a1 100644
--- a/crypto/openssh/authfile.h
+++ b/crypto/openssh/authfile.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: authfile.h,v 1.21 2015/01/08 10:14:08 djm Exp $ */
+/* $OpenBSD: authfile.h,v 1.25 2020/01/25 23:02:13 djm Exp $ */
/*
* Copyright (c) 2000, 2013 Markus Friedl. All rights reserved.
@@ -35,18 +35,20 @@ struct sshkey;
int sshkey_save_private(struct sshkey *, const char *,
const char *, const char *, int, const char *, int);
-int sshkey_load_file(int, struct sshbuf *);
int sshkey_load_cert(const char *, struct sshkey **);
int sshkey_load_public(const char *, struct sshkey **, char **);
int sshkey_load_private(const char *, const char *, struct sshkey **, char **);
int sshkey_load_private_cert(int, const char *, const char *,
- struct sshkey **, int *);
+ struct sshkey **);
int sshkey_load_private_type(int, const char *, const char *,
- struct sshkey **, char **, int *);
+ struct sshkey **, char **);
int sshkey_load_private_type_fd(int fd, int type, const char *passphrase,
struct sshkey **keyp, char **commentp);
int sshkey_perm_ok(int, const char *);
int sshkey_in_file(struct sshkey *, const char *, int, int);
int sshkey_check_revoked(struct sshkey *key, const char *revoked_keys_file);
+int sshkey_advance_past_options(char **cpp);
+int sshkey_save_public(const struct sshkey *key, const char *path,
+ const char *comment);
#endif
diff --git a/crypto/openssh/blacklist.c b/crypto/openssh/blacklist.c
index b4f5d3e128c1..78830c525c85 100644
--- a/crypto/openssh/blacklist.c
+++ b/crypto/openssh/blacklist.c
@@ -76,7 +76,7 @@ im_log(int priority, const char *message, va_list args)
default:
imlevel = SYSLOG_LEVEL_DEBUG2;
}
- do_log(imlevel, message, args);
+ do_log2(imlevel, message, args);
}
void
@@ -91,7 +91,7 @@ void
blacklist_notify(int action, const char *msg)
{
- if (blstate != NULL && packet_connection_is_on_socket())
+ if (blstate != NULL && ssh_packet_connection_is_on_socket(NULL))
(void)blacklist_r(blstate, action,
- packet_get_connection_in(), msg);
+ ssh_packet_get_connection_in(NULL), msg);
}
diff --git a/crypto/openssh/buildpkg.sh.in b/crypto/openssh/buildpkg.sh.in
index 4ccc5f8d1419..15555cd7ed7e 100644
--- a/crypto/openssh/buildpkg.sh.in
+++ b/crypto/openssh/buildpkg.sh.in
@@ -268,7 +268,7 @@ then
touch space
else
cat > space << _EOF
-# extra space required by start/stop links added by installf
+# extra space required by start/stop links added by installf
# in postinstall
$TEST_DIR/etc/rc0.d/${SYSVINITSTOPT}${SYSVINIT_NAME} 0 1
$TEST_DIR/etc/rc2.d/${SYSVINITSTART}${SYSVINIT_NAME} 0 1
@@ -293,7 +293,7 @@ cat >> preinstall << _EOF
#
if [ "\${PRE_INS_STOP}" = "yes" ]
then
- if [ $DO_SMF -eq 1 ]
+ if [ $DO_SMF -eq 1 ]
then
svcadm disable $OPENSSH_FMRI
else
@@ -326,7 +326,7 @@ cat > postinstall << _EOF
if [ $DO_SMF -eq 1 ]
then
- # Delete the existing service, if it exists, then import the
+ # Delete the existing service, if it exists, then import the
# new one.
if svcs $OPENSSH_FMRI > /dev/null 2>&1
then
@@ -438,7 +438,7 @@ echo "Building preremove file..."
cat > preremove << _EOF
#! ${SCRIPT_SHELL}
#
-if [ $DO_SMF -eq 1 ]
+if [ $DO_SMF -eq 1 ]
then
svcadm disable $OPENSSH_FMRI
else
diff --git a/crypto/openssh/canohost.c b/crypto/openssh/canohost.c
index f71a08568ed9..a810da0eeb73 100644
--- a/crypto/openssh/canohost.c
+++ b/crypto/openssh/canohost.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: canohost.c,v 1.73 2016/03/07 19:02:43 djm Exp $ */
+/* $OpenBSD: canohost.c,v 1.75 2020/10/18 11:32:01 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -96,7 +96,7 @@ get_socket_address(int sock, int remote, int flags)
/* Get the address in ascii. */
if ((r = getnameinfo((struct sockaddr *)&addr, addrlen, ntop,
sizeof(ntop), NULL, 0, flags)) != 0) {
- error("%s: getnameinfo %d failed: %s", __func__,
+ error_f("getnameinfo %d failed: %s",
flags, ssh_gai_strerror(r));
return NULL;
}
@@ -141,7 +141,7 @@ get_local_name(int fd)
/* Handle the case where we were passed a pipe */
if (gethostname(myname, sizeof(myname)) == -1) {
- verbose("%s: gethostname: %s", __func__, strerror(errno));
+ verbose_f("gethostname: %s", strerror(errno));
host = xstrdup("UNKNOWN");
} else {
host = xstrdup(myname);
@@ -164,12 +164,12 @@ get_sock_port(int sock, int local)
fromlen = sizeof(from);
memset(&from, 0, sizeof(from));
if (local) {
- if (getsockname(sock, (struct sockaddr *)&from, &fromlen) < 0) {
+ if (getsockname(sock, (struct sockaddr *)&from, &fromlen) == -1) {
error("getsockname failed: %.100s", strerror(errno));
return 0;
}
} else {
- if (getpeername(sock, (struct sockaddr *)&from, &fromlen) < 0) {
+ if (getpeername(sock, (struct sockaddr *)&from, &fromlen) == -1) {
debug("getpeername failed: %.100s", strerror(errno));
return -1;
}
@@ -186,7 +186,7 @@ get_sock_port(int sock, int local)
/* Return port number. */
if ((r = getnameinfo((struct sockaddr *)&from, fromlen, NULL, 0,
strport, sizeof(strport), NI_NUMERICSERV)) != 0)
- fatal("%s: getnameinfo NI_NUMERICSERV failed: %s", __func__,
+ fatal_f("getnameinfo NI_NUMERICSERV failed: %s",
ssh_gai_strerror(r));
return atoi(strport);
}
diff --git a/crypto/openssh/chacha.h b/crypto/openssh/chacha.h
index 762052565d5c..19a61e294230 100644
--- a/crypto/openssh/chacha.h
+++ b/crypto/openssh/chacha.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: chacha.h,v 1.4 2016/08/27 04:04:56 guenther Exp $ */
+/* $OpenBSD: chacha.h,v 1.5 2021/04/03 05:54:14 djm Exp $ */
/*
chacha-merged.c version 20080118
@@ -16,7 +16,7 @@ struct chacha_ctx {
u_int input[16];
};
-#define CHACHA_MINKEYLEN 16
+#define CHACHA_MINKEYLEN 16
#define CHACHA_NONCELEN 8
#define CHACHA_CTRLEN 8
#define CHACHA_STATELEN (CHACHA_NONCELEN+CHACHA_CTRLEN)
diff --git a/crypto/openssh/channels.c b/crypto/openssh/channels.c
index c85d46abd762..fd72f371df98 100644
--- a/crypto/openssh/channels.c
+++ b/crypto/openssh/channels.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: channels.c,v 1.386 2018/10/04 01:04:52 djm Exp $ */
+/* $OpenBSD: channels.c,v 1.407 2021/05/19 01:24:05 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -59,7 +59,7 @@
#include <netdb.h>
#include <stdarg.h>
#ifdef HAVE_STDINT_H
- #include <stdint.h>
+# include <stdint.h>
#endif
#include <stdio.h>
#include <stdlib.h>
@@ -227,12 +227,8 @@ channel_init_channels(struct ssh *ssh)
{
struct ssh_channels *sc;
- if ((sc = calloc(1, sizeof(*sc))) == NULL ||
- (sc->channel_pre = calloc(SSH_CHANNEL_MAX_TYPE,
- sizeof(*sc->channel_pre))) == NULL ||
- (sc->channel_post = calloc(SSH_CHANNEL_MAX_TYPE,
- sizeof(*sc->channel_post))) == NULL)
- fatal("%s: allocation failed", __func__);
+ if ((sc = calloc(1, sizeof(*sc))) == NULL)
+ fatal_f("allocation failed");
sc->channels_alloc = 10;
sc->channels = xcalloc(sc->channels_alloc, sizeof(*sc->channels));
sc->IPv4or6 = AF_UNSPEC;
@@ -247,12 +243,12 @@ channel_by_id(struct ssh *ssh, int id)
Channel *c;
if (id < 0 || (u_int)id >= ssh->chanctxt->channels_alloc) {
- logit("%s: %d: bad id", __func__, id);
+ logit_f("%d: bad id", id);
return NULL;
}
c = ssh->chanctxt->channels[id];
if (c == NULL) {
- logit("%s: %d: bad id: channel free", __func__, id);
+ logit_f("%d: bad id: channel free", id);
return NULL;
}
return c;
@@ -337,7 +333,27 @@ channel_register_fds(struct ssh *ssh, Channel *c, int rfd, int wfd, int efd,
#endif
/* enable nonblocking mode */
- if (nonblock) {
+ c->restore_block = 0;
+ if (nonblock == CHANNEL_NONBLOCK_STDIO) {
+ /*
+ * Special handling for stdio file descriptors: do not set
+ * non-blocking mode if they are TTYs. Otherwise prepare to
+ * restore their blocking state on exit to avoid interfering
+ * with other programs that follow.
+ */
+ if (rfd != -1 && !isatty(rfd) && fcntl(rfd, F_GETFL) == 0) {
+ c->restore_block |= CHANNEL_RESTORE_RFD;
+ set_nonblock(rfd);
+ }
+ if (wfd != -1 && !isatty(wfd) && fcntl(wfd, F_GETFL) == 0) {
+ c->restore_block |= CHANNEL_RESTORE_WFD;
+ set_nonblock(wfd);
+ }
+ if (efd != -1 && !isatty(efd) && fcntl(efd, F_GETFL) == 0) {
+ c->restore_block |= CHANNEL_RESTORE_EFD;
+ set_nonblock(efd);
+ }
+ } else if (nonblock) {
if (rfd != -1)
set_nonblock(rfd);
if (wfd != -1)
@@ -358,6 +374,7 @@ channel_new(struct ssh *ssh, char *ctype, int type, int rfd, int wfd, int efd,
struct ssh_channels *sc = ssh->chanctxt;
u_int i, found;
Channel *c;
+ int r;
/* Try to find a free slot where to put the new channel. */
for (i = 0; i < sc->channels_alloc; i++) {
@@ -374,8 +391,8 @@ channel_new(struct ssh *ssh, char *ctype, int type, int rfd, int wfd, int efd,
*/
found = sc->channels_alloc;
if (sc->channels_alloc > CHANNELS_MAX_CHANNELS)
- fatal("%s: internal error: channels_alloc %d too big",
- __func__, sc->channels_alloc);
+ fatal_f("internal error: channels_alloc %d too big",
+ sc->channels_alloc);
sc->channels = xrecallocarray(sc->channels, sc->channels_alloc,
sc->channels_alloc + 10, sizeof(*sc->channels));
sc->channels_alloc += 10;
@@ -386,7 +403,9 @@ channel_new(struct ssh *ssh, char *ctype, int type, int rfd, int wfd, int efd,
if ((c->input = sshbuf_new()) == NULL ||
(c->output = sshbuf_new()) == NULL ||
(c->extended = sshbuf_new()) == NULL)
- fatal("%s: sshbuf_new failed", __func__);
+ fatal_f("sshbuf_new failed");
+ if ((r = sshbuf_set_max_size(c->input, CHAN_INPUT_MAX)) != 0)
+ fatal_fr(r, "sshbuf_set_max_size");
c->ostate = CHAN_OUTPUT_OPEN;
c->istate = CHAN_INPUT_OPEN;
channel_register_fds(ssh, c, rfd, wfd, efd, extusage, nonblock, 0);
@@ -423,17 +442,23 @@ channel_find_maxfd(struct ssh_channels *sc)
}
int
-channel_close_fd(struct ssh *ssh, int *fdp)
+channel_close_fd(struct ssh *ssh, Channel *c, int *fdp)
{
struct ssh_channels *sc = ssh->chanctxt;
- int ret = 0, fd = *fdp;
+ int ret, fd = *fdp;
- if (fd != -1) {
- ret = close(fd);
- *fdp = -1;
- if (fd == sc->channel_max_fd)
- channel_find_maxfd(sc);
- }
+ if (fd == -1)
+ return 0;
+
+ if ((*fdp == c->rfd && (c->restore_block & CHANNEL_RESTORE_RFD) != 0) ||
+ (*fdp == c->wfd && (c->restore_block & CHANNEL_RESTORE_WFD) != 0) ||
+ (*fdp == c->efd && (c->restore_block & CHANNEL_RESTORE_EFD) != 0))
+ (void)fcntl(*fdp, F_SETFL, 0); /* restore blocking */
+
+ ret = close(fd);
+ *fdp = -1;
+ if (fd == sc->channel_max_fd)
+ channel_find_maxfd(sc);
return ret;
}
@@ -443,13 +468,13 @@ channel_close_fds(struct ssh *ssh, Channel *c)
{
int sock = c->sock, rfd = c->rfd, wfd = c->wfd, efd = c->efd;
- channel_close_fd(ssh, &c->sock);
+ channel_close_fd(ssh, c, &c->sock);
if (rfd != sock)
- channel_close_fd(ssh, &c->rfd);
+ channel_close_fd(ssh, c, &c->rfd);
if (wfd != sock && wfd != rfd)
- channel_close_fd(ssh, &c->wfd);
+ channel_close_fd(ssh, c, &c->wfd);
if (efd != sock && efd != rfd && efd != wfd)
- channel_close_fd(ssh, &c->efd);
+ channel_close_fd(ssh, c, &c->efd);
}
static void
@@ -458,7 +483,7 @@ fwd_perm_clear(struct permission *perm)
free(perm->host_to_connect);
free(perm->listen_host);
free(perm->listen_path);
- bzero(perm, sizeof(*perm));
+ memset(perm, 0, sizeof(*perm));
}
/* Returns an printable name for the specified forwarding permission list */
@@ -493,11 +518,11 @@ permission_set_get(struct ssh *ssh, int where)
return &sc->remote_perms;
break;
default:
- fatal("%s: invalid forwarding direction %d", __func__, where);
+ fatal_f("invalid forwarding direction %d", where);
}
}
-/* Reutrns pointers to the specified forwarding list and its element count */
+/* Returns pointers to the specified forwarding list and its element count */
static void
permission_set_get_array(struct ssh *ssh, int who, int where,
struct permission ***permpp, u_int **npermpp)
@@ -514,7 +539,7 @@ permission_set_get_array(struct ssh *ssh, int who, int where,
*npermpp = &pset->num_permitted_admin;
break;
default:
- fatal("%s: invalid forwarding client %d", __func__, who);
+ fatal_f("invalid forwarding client %d", who);
}
}
@@ -531,7 +556,7 @@ permission_set_add(struct ssh *ssh, int who, int where,
permission_set_get_array(ssh, who, where, &permp, &npermp);
if (*npermp >= INT_MAX)
- fatal("%s: %s overflow", __func__, fwd_ident(who, where));
+ fatal_f("%s overflow", fwd_ident(who, where));
*permp = xrecallocarray(*permp, *npermp, *npermp + 1, sizeof(**permp));
n = (*npermp)++;
@@ -571,8 +596,7 @@ mux_remove_remote_forwardings(struct ssh *ssh, Channel *c)
channel_rfwd_bind_host(perm->listen_host))) != 0 ||
(r = sshpkt_put_u32(ssh, perm->listen_port)) != 0 ||
(r = sshpkt_send(ssh)) != 0) {
- fatal("%s: channel %i: %s", __func__,
- c->self, ssh_err(r));
+ fatal_fr(r, "channel %i", c->self);
}
fwd_perm_clear(perm); /* unregister */
}
@@ -607,6 +631,10 @@ channel_free(struct ssh *ssh, Channel *c)
if (c->type == SSH_CHANNEL_MUX_CLIENT)
mux_remove_remote_forwardings(ssh, c);
+ else if (c->type == SSH_CHANNEL_MUX_LISTENER) {
+ free(c->mux_ctx);
+ c->mux_ctx = NULL;
+ }
if (log_level_get() >= SYSLOG_LEVEL_DEBUG3) {
s = channel_open_message(ssh);
@@ -629,24 +657,42 @@ channel_free(struct ssh *ssh, Channel *c)
if (cc->abandon_cb != NULL)
cc->abandon_cb(ssh, c, cc->ctx);
TAILQ_REMOVE(&c->status_confirms, cc, entry);
- explicit_bzero(cc, sizeof(*cc));
- free(cc);
+ freezero(cc, sizeof(*cc));
}
if (c->filter_cleanup != NULL && c->filter_ctx != NULL)
c->filter_cleanup(ssh, c->self, c->filter_ctx);
sc->channels[c->self] = NULL;
- explicit_bzero(c, sizeof(*c));
- free(c);
+ freezero(c, sizeof(*c));
}
void
channel_free_all(struct ssh *ssh)
{
u_int i;
+ struct ssh_channels *sc = ssh->chanctxt;
- for (i = 0; i < ssh->chanctxt->channels_alloc; i++)
- if (ssh->chanctxt->channels[i] != NULL)
- channel_free(ssh, ssh->chanctxt->channels[i]);
+ for (i = 0; i < sc->channels_alloc; i++)
+ if (sc->channels[i] != NULL)
+ channel_free(ssh, sc->channels[i]);
+
+ free(sc->channels);
+ sc->channels = NULL;
+ sc->channels_alloc = 0;
+ sc->channel_max_fd = 0;
+
+ free(sc->x11_saved_display);
+ sc->x11_saved_display = NULL;
+
+ free(sc->x11_saved_proto);
+ sc->x11_saved_proto = NULL;
+
+ free(sc->x11_saved_data);
+ sc->x11_saved_data = NULL;
+ sc->x11_saved_data_len = 0;
+
+ free(sc->x11_fake_data);
+ sc->x11_fake_data = NULL;
+ sc->x11_fake_data_len = 0;
}
/*
@@ -682,7 +728,7 @@ channel_stop_listening(struct ssh *ssh)
case SSH_CHANNEL_X11_LISTENER:
case SSH_CHANNEL_UNIX_LISTENER:
case SSH_CHANNEL_RUNIX_LISTENER:
- channel_close_fd(ssh, &c->sock);
+ channel_close_fd(ssh, c, &c->sock);
channel_free(ssh, c);
break;
}
@@ -750,7 +796,7 @@ channel_still_open(struct ssh *ssh)
case SSH_CHANNEL_MUX_PROXY:
return 1;
default:
- fatal("%s: bad channel type %d", __func__, c->type);
+ fatal_f("bad channel type %d", c->type);
/* NOTREACHED */
}
}
@@ -792,7 +838,7 @@ channel_find_open(struct ssh *ssh)
case SSH_CHANNEL_X11_OPEN:
return i;
default:
- fatal("%s: bad channel type %d", __func__, c->type);
+ fatal_f("bad channel type %d", c->type);
/* NOTREACHED */
}
}
@@ -849,10 +895,10 @@ channel_open_message(struct ssh *ssh)
char *cp, *ret;
if ((buf = sshbuf_new()) == NULL)
- fatal("%s: sshbuf_new", __func__);
+ fatal_f("sshbuf_new");
if ((r = sshbuf_putf(buf,
"The following connections are open:\r\n")) != 0)
- fatal("%s: sshbuf_putf: %s", __func__, ssh_err(r));
+ fatal_fr(r, "sshbuf_putf");
for (i = 0; i < ssh->chanctxt->channels_alloc; i++) {
c = ssh->chanctxt->channels[i];
if (c == NULL)
@@ -883,18 +929,17 @@ channel_open_message(struct ssh *ssh)
if ((r = sshbuf_putf(buf, " #%d %.300s (%s)\r\n",
c->self, c->remote_name, cp)) != 0) {
free(cp);
- fatal("%s: sshbuf_putf: %s",
- __func__, ssh_err(r));
+ fatal_fr(r, "sshbuf_putf");
}
free(cp);
continue;
default:
- fatal("%s: bad channel type %d", __func__, c->type);
+ fatal_f("bad channel type %d", c->type);
/* NOTREACHED */
}
}
if ((ret = sshbuf_dup_string(buf)) == NULL)
- fatal("%s: sshbuf_dup_string", __func__);
+ fatal_f("sshbuf_dup_string");
sshbuf_free(buf);
return ret;
}
@@ -909,7 +954,7 @@ open_preamble(struct ssh *ssh, const char *where, Channel *c, const char *type)
(r = sshpkt_put_u32(ssh, c->self)) != 0 ||
(r = sshpkt_put_u32(ssh, c->local_window)) != 0 ||
(r = sshpkt_put_u32(ssh, c->local_maxpacket)) != 0) {
- fatal("%s: channel %i: open: %s", where, c->self, ssh_err(r));
+ fatal_r(r, "%s: channel %i: open", where, c->self);
}
}
@@ -926,7 +971,7 @@ channel_send_open(struct ssh *ssh, int id)
debug2("channel %d: send open", id);
open_preamble(ssh, __func__, c, c->ctype);
if ((r = sshpkt_send(ssh)) != 0)
- fatal("%s: channel %i: %s", __func__, c->self, ssh_err(r));
+ fatal_fr(r, "channel %i", c->self);
}
void
@@ -936,18 +981,18 @@ channel_request_start(struct ssh *ssh, int id, char *service, int wantconfirm)
int r;
if (c == NULL) {
- logit("%s: %d: unknown channel id", __func__, id);
+ logit_f("%d: unknown channel id", id);
return;
}
if (!c->have_remote_id)
- fatal(":%s: channel %d: no remote id", __func__, c->self);
+ fatal_f("channel %d: no remote id", c->self);
debug2("channel %d: request %s confirm %d", id, service, wantconfirm);
if ((r = sshpkt_start(ssh, SSH2_MSG_CHANNEL_REQUEST)) != 0 ||
(r = sshpkt_put_u32(ssh, c->remote_id)) != 0 ||
(r = sshpkt_put_cstring(ssh, service)) != 0 ||
(r = sshpkt_put_u8(ssh, wantconfirm)) != 0) {
- fatal("%s: channel %i: %s", __func__, c->self, ssh_err(r));
+ fatal_fr(r, "channel %i", c->self);
}
}
@@ -959,7 +1004,7 @@ channel_register_status_confirm(struct ssh *ssh, int id,
Channel *c;
if ((c = channel_lookup(ssh, id)) == NULL)
- fatal("%s: %d: bad id", __func__, id);
+ fatal_f("%d: bad id", id);
cc = xcalloc(1, sizeof(*cc));
cc->cb = cb;
@@ -975,7 +1020,7 @@ channel_register_open_confirm(struct ssh *ssh, int id,
Channel *c = channel_lookup(ssh, id);
if (c == NULL) {
- logit("%s: %d: bad id", __func__, id);
+ logit_f("%d: bad id", id);
return;
}
c->open_confirm = fn;
@@ -989,7 +1034,7 @@ channel_register_cleanup(struct ssh *ssh, int id,
Channel *c = channel_by_id(ssh, id);
if (c == NULL) {
- logit("%s: %d: bad id", __func__, id);
+ logit_f("%d: bad id", id);
return;
}
c->detach_user = fn;
@@ -1002,7 +1047,7 @@ channel_cancel_cleanup(struct ssh *ssh, int id)
Channel *c = channel_by_id(ssh, id);
if (c == NULL) {
- logit("%s: %d: bad id", __func__, id);
+ logit_f("%d: bad id", id);
return;
}
c->detach_user = NULL;
@@ -1016,7 +1061,7 @@ channel_register_filter(struct ssh *ssh, int id, channel_infilter_fn *ifn,
Channel *c = channel_lookup(ssh, id);
if (c == NULL) {
- logit("%s: %d: bad id", __func__, id);
+ logit_f("%d: bad id", id);
return;
}
c->input_filter = ifn;
@@ -1035,7 +1080,7 @@ channel_set_fds(struct ssh *ssh, int id, int rfd, int wfd, int efd,
if (c == NULL || c->type != SSH_CHANNEL_LARVAL)
fatal("channel_activate for non-larval channel %d.", id);
if (!c->have_remote_id)
- fatal(":%s: channel %d: no remote id", __func__, c->self);
+ fatal_f("channel %d: no remote id", c->self);
channel_register_fds(ssh, c, rfd, wfd, efd, extusage, nonblock, is_tty);
c->type = SSH_CHANNEL_OPEN;
@@ -1045,7 +1090,7 @@ channel_set_fds(struct ssh *ssh, int id, int rfd, int wfd, int efd,
(r = sshpkt_put_u32(ssh, c->remote_id)) != 0 ||
(r = sshpkt_put_u32(ssh, c->local_window)) != 0 ||
(r = sshpkt_send(ssh)) != 0)
- fatal("%s: channel %i: %s", __func__, c->self, ssh_err(r));
+ fatal_fr(r, "channel %i", c->self);
}
static void
@@ -1274,24 +1319,21 @@ channel_decode_socks4(Channel *c, struct sshbuf *input, struct sshbuf *output)
(r = sshbuf_get(input, &s4_req.command, 1)) != 0 ||
(r = sshbuf_get(input, &s4_req.dest_port, 2)) != 0 ||
(r = sshbuf_get(input, &s4_req.dest_addr, 4)) != 0) {
- debug("channels %d: decode socks4: %s", c->self, ssh_err(r));
+ debug_r(r, "channels %d: decode socks4", c->self);
return -1;
}
have = sshbuf_len(input);
p = sshbuf_ptr(input);
if (memchr(p, '\0', have) == NULL) {
- error("channel %d: decode socks4: user not nul terminated",
- c->self);
+ error("channel %d: decode socks4: unterminated user", c->self);
return -1;
}
len = strlen(p);
debug2("channel %d: decode socks4: user %s/%d", c->self, p, len);
len++; /* trailing '\0' */
strlcpy(username, p, sizeof(username));
- if ((r = sshbuf_consume(input, len)) != 0) {
- fatal("%s: channel %d: consume: %s", __func__,
- c->self, ssh_err(r));
- }
+ if ((r = sshbuf_consume(input, len)) != 0)
+ fatal_fr(r, "channel %d: consume", c->self);
free(c->path);
c->path = NULL;
if (need == 1) { /* SOCKS4: one string */
@@ -1315,10 +1357,8 @@ channel_decode_socks4(Channel *c, struct sshbuf *input, struct sshbuf *output)
return -1;
}
c->path = xstrdup(p);
- if ((r = sshbuf_consume(input, len)) != 0) {
- fatal("%s: channel %d: consume: %s", __func__,
- c->self, ssh_err(r));
- }
+ if ((r = sshbuf_consume(input, len)) != 0)
+ fatal_fr(r, "channel %d: consume", c->self);
}
c->host_port = ntohs(s4_req.dest_port);
@@ -1334,10 +1374,8 @@ channel_decode_socks4(Channel *c, struct sshbuf *input, struct sshbuf *output)
s4_rsp.command = 90; /* cd: req granted */
s4_rsp.dest_port = 0; /* ignored */
s4_rsp.dest_addr.s_addr = INADDR_ANY; /* ignored */
- if ((r = sshbuf_put(output, &s4_rsp, sizeof(s4_rsp))) != 0) {
- fatal("%s: channel %d: append reply: %s", __func__,
- c->self, ssh_err(r));
- }
+ if ((r = sshbuf_put(output, &s4_rsp, sizeof(s4_rsp))) != 0)
+ fatal_fr(r, "channel %d: append reply", c->self);
return 1;
}
@@ -1390,16 +1428,12 @@ channel_decode_socks5(Channel *c, struct sshbuf *input, struct sshbuf *output)
c->self);
return -1;
}
- if ((r = sshbuf_consume(input, nmethods + 2)) != 0) {
- fatal("%s: channel %d: consume: %s", __func__,
- c->self, ssh_err(r));
- }
+ if ((r = sshbuf_consume(input, nmethods + 2)) != 0)
+ fatal_fr(r, "channel %d: consume", c->self);
/* version, method */
if ((r = sshbuf_put_u8(output, 0x05)) != 0 ||
- (r = sshbuf_put_u8(output, SSH_SOCKS5_NOAUTH)) != 0) {
- fatal("%s: channel %d: append reply: %s", __func__,
- c->self, ssh_err(r));
- }
+ (r = sshbuf_put_u8(output, SSH_SOCKS5_NOAUTH)) != 0)
+ fatal_fr(r, "channel %d: append reply", c->self);
c->flags |= SSH_SOCKS5_AUTHDONE;
debug2("channel %d: socks5 auth done", c->self);
return 0; /* need more */
@@ -1436,20 +1470,16 @@ channel_decode_socks5(Channel *c, struct sshbuf *input, struct sshbuf *output)
need++;
if (have < need)
return 0;
- if ((r = sshbuf_consume(input, sizeof(s5_req))) != 0) {
- fatal("%s: channel %d: consume: %s", __func__,
- c->self, ssh_err(r));
- }
+ if ((r = sshbuf_consume(input, sizeof(s5_req))) != 0)
+ fatal_fr(r, "channel %d: consume", c->self);
if (s5_req.atyp == SSH_SOCKS5_DOMAIN) {
/* host string length */
- if ((r = sshbuf_consume(input, 1)) != 0) {
- fatal("%s: channel %d: consume: %s", __func__,
- c->self, ssh_err(r));
- }
+ if ((r = sshbuf_consume(input, 1)) != 0)
+ fatal_fr(r, "channel %d: consume", c->self);
}
if ((r = sshbuf_get(input, &dest_addr, addrlen)) != 0 ||
(r = sshbuf_get(input, &dest_port, 2)) != 0) {
- debug("channel %d: parse addr/port: %s", c->self, ssh_err(r));
+ debug_r(r, "channel %d: parse addr/port", c->self);
return -1;
}
dest_addr[addrlen] = '\0';
@@ -1481,22 +1511,22 @@ channel_decode_socks5(Channel *c, struct sshbuf *input, struct sshbuf *output)
if ((r = sshbuf_put(output, &s5_rsp, sizeof(s5_rsp))) != 0 ||
(r = sshbuf_put_u32(output, ntohl(INADDR_ANY))) != 0 ||
(r = sshbuf_put(output, &dest_port, sizeof(dest_port))) != 0)
- fatal("%s: channel %d: append reply: %s", __func__,
- c->self, ssh_err(r));
+ fatal_fr(r, "channel %d: append reply", c->self);
return 1;
}
Channel *
channel_connect_stdio_fwd(struct ssh *ssh,
- const char *host_to_connect, u_short port_to_connect, int in, int out)
+ const char *host_to_connect, u_short port_to_connect,
+ int in, int out, int nonblock)
{
Channel *c;
- debug("%s %s:%d", __func__, host_to_connect, port_to_connect);
+ debug_f("%s:%d", host_to_connect, port_to_connect);
c = channel_new(ssh, "stdio-forward", SSH_CHANNEL_OPENING, in, out,
-1, CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT,
- 0, "stdio-forward", /*nonblock*/0);
+ 0, "stdio-forward", nonblock);
c->path = xstrdup(host_to_connect);
c->host_port = port_to_connect;
@@ -1581,10 +1611,8 @@ channel_before_prepare_select_rdynamic(struct ssh *ssh, Channel *c)
/* sshbuf_dump(c->output, stderr); */
/* EOF received */
if (c->flags & CHAN_EOF_RCVD) {
- if ((r = sshbuf_consume(c->output, have)) != 0) {
- fatal("%s: channel %d: consume: %s",
- __func__, c->self, ssh_err(r));
- }
+ if ((r = sshbuf_consume(c->output, have)) != 0)
+ fatal_fr(r, "channel %d: consume", c->self);
rdynamic_close(ssh, c);
return;
}
@@ -1616,13 +1644,10 @@ channel_before_prepare_select_rdynamic(struct ssh *ssh, Channel *c)
(r = sshpkt_put_u32(ssh, c->remote_id)) != 0 ||
(r = sshpkt_put_stringb(ssh, c->input)) != 0 ||
(r = sshpkt_send(ssh)) != 0) {
- fatal("%s: channel %i: rdynamic: %s", __func__,
- c->self, ssh_err(r));
- }
- if ((r = sshbuf_consume(c->input, len)) != 0) {
- fatal("%s: channel %d: consume: %s",
- __func__, c->self, ssh_err(r));
+ fatal_fr(r, "channel %i: rdynamic", c->self);
}
+ if ((r = sshbuf_consume(c->input, len)) != 0)
+ fatal_fr(r, "channel %d: consume", c->self);
c->remote_window -= len;
}
} else if (rdynamic_connect_finish(ssh, c) < 0) {
@@ -1651,11 +1676,11 @@ channel_post_x11_listener(struct ssh *ssh, Channel *c,
if (c->single_connection) {
oerrno = errno;
debug2("single_connection: closing X11 listener.");
- channel_close_fd(ssh, &c->sock);
+ channel_close_fd(ssh, c, &c->sock);
chan_mark_dead(ssh, c);
errno = oerrno;
}
- if (newsock < 0) {
+ if (newsock == -1) {
if (errno != EINTR && errno != EWOULDBLOCK &&
errno != ECONNABORTED)
error("accept: %.100s", strerror(errno));
@@ -1675,11 +1700,10 @@ channel_post_x11_listener(struct ssh *ssh, Channel *c,
open_preamble(ssh, __func__, nc, "x11");
if ((r = sshpkt_put_cstring(ssh, remote_ipaddr)) != 0 ||
(r = sshpkt_put_u32(ssh, remote_port)) != 0) {
- fatal("%s: channel %i: reply %s", __func__,
- c->self, ssh_err(r));
+ fatal_fr(r, "channel %i: reply", c->self);
}
if ((r = sshpkt_send(ssh)) != 0)
- fatal("%s: channel %i: send %s", __func__, c->self, ssh_err(r));
+ fatal_fr(r, "channel %i: send", c->self);
free(remote_ipaddr);
}
@@ -1710,46 +1734,34 @@ port_open_helper(struct ssh *ssh, Channel *c, char *rtype)
if (strcmp(rtype, "direct-tcpip") == 0) {
/* target host, port */
if ((r = sshpkt_put_cstring(ssh, c->path)) != 0 ||
- (r = sshpkt_put_u32(ssh, c->host_port)) != 0) {
- fatal("%s: channel %i: reply %s", __func__,
- c->self, ssh_err(r));
- }
+ (r = sshpkt_put_u32(ssh, c->host_port)) != 0)
+ fatal_fr(r, "channel %i: reply", c->self);
} else if (strcmp(rtype, "direct-streamlocal@openssh.com") == 0) {
/* target path */
- if ((r = sshpkt_put_cstring(ssh, c->path)) != 0) {
- fatal("%s: channel %i: reply %s", __func__,
- c->self, ssh_err(r));
- }
+ if ((r = sshpkt_put_cstring(ssh, c->path)) != 0)
+ fatal_fr(r, "channel %i: reply", c->self);
} else if (strcmp(rtype, "forwarded-streamlocal@openssh.com") == 0) {
/* listen path */
- if ((r = sshpkt_put_cstring(ssh, c->path)) != 0) {
- fatal("%s: channel %i: reply %s", __func__,
- c->self, ssh_err(r));
- }
+ if ((r = sshpkt_put_cstring(ssh, c->path)) != 0)
+ fatal_fr(r, "channel %i: reply", c->self);
} else {
/* listen address, port */
if ((r = sshpkt_put_cstring(ssh, c->path)) != 0 ||
- (r = sshpkt_put_u32(ssh, local_port)) != 0) {
- fatal("%s: channel %i: reply %s", __func__,
- c->self, ssh_err(r));
- }
+ (r = sshpkt_put_u32(ssh, local_port)) != 0)
+ fatal_fr(r, "channel %i: reply", c->self);
}
if (strcmp(rtype, "forwarded-streamlocal@openssh.com") == 0) {
/* reserved for future owner/mode info */
- if ((r = sshpkt_put_cstring(ssh, "")) != 0) {
- fatal("%s: channel %i: reply %s", __func__,
- c->self, ssh_err(r));
- }
+ if ((r = sshpkt_put_cstring(ssh, "")) != 0)
+ fatal_fr(r, "channel %i: reply", c->self);
} else {
/* originator host and port */
if ((r = sshpkt_put_cstring(ssh, remote_ipaddr)) != 0 ||
- (r = sshpkt_put_u32(ssh, (u_int)remote_port)) != 0) {
- fatal("%s: channel %i: reply %s", __func__,
- c->self, ssh_err(r));
- }
+ (r = sshpkt_put_u32(ssh, (u_int)remote_port)) != 0)
+ fatal_fr(r, "channel %i: reply", c->self);
}
if ((r = sshpkt_send(ssh)) != 0)
- fatal("%s: channel %i: send %s", __func__, c->self, ssh_err(r));
+ fatal_fr(r, "channel %i: send", c->self);
free(remote_ipaddr);
free(local_ipaddr);
}
@@ -1798,7 +1810,7 @@ channel_post_port_listener(struct ssh *ssh, Channel *c,
addrlen = sizeof(addr);
newsock = accept(c->sock, (struct sockaddr *)&addr, &addrlen);
- if (newsock < 0) {
+ if (newsock == -1) {
if (errno != EINTR && errno != EWOULDBLOCK &&
errno != ECONNABORTED)
error("accept: %.100s", strerror(errno));
@@ -1837,7 +1849,7 @@ channel_post_auth_listener(struct ssh *ssh, Channel *c,
addrlen = sizeof(addr);
newsock = accept(c->sock, (struct sockaddr *)&addr, &addrlen);
- if (newsock < 0) {
+ if (newsock == -1) {
error("accept from auth socket: %.100s", strerror(errno));
if (errno == EMFILE || errno == ENFILE)
c->notbefore = monotime() + 1;
@@ -1849,7 +1861,7 @@ channel_post_auth_listener(struct ssh *ssh, Channel *c,
0, "accepted auth socket", 1);
open_preamble(ssh, __func__, nc, "auth-agent@openssh.com");
if ((r = sshpkt_send(ssh)) != 0)
- fatal("%s: channel %i: %s", __func__, c->self, ssh_err(r));
+ fatal_fr(r, "channel %i", c->self);
}
static void
@@ -1862,10 +1874,10 @@ channel_post_connecting(struct ssh *ssh, Channel *c,
if (!FD_ISSET(c->sock, writeset))
return;
if (!c->have_remote_id)
- fatal(":%s: channel %d: no remote id", __func__, c->self);
+ fatal_f("channel %d: no remote id", c->self);
/* for rdynamic the OPEN_CONFIRMATION has been sent already */
isopen = (c->type == SSH_CHANNEL_RDYNAMIC_FINISH);
- if (getsockopt(c->sock, SOL_SOCKET, SO_ERROR, &err, &sz) < 0) {
+ if (getsockopt(c->sock, SOL_SOCKET, SO_ERROR, &err, &sz) == -1) {
err = errno;
error("getsockopt SO_ERROR failed");
}
@@ -1882,13 +1894,9 @@ channel_post_connecting(struct ssh *ssh, Channel *c,
(r = sshpkt_put_u32(ssh, c->remote_id)) != 0 ||
(r = sshpkt_put_u32(ssh, c->self)) != 0 ||
(r = sshpkt_put_u32(ssh, c->local_window)) != 0 ||
- (r = sshpkt_put_u32(ssh, c->local_maxpacket))
- != 0)
- fatal("%s: channel %i: confirm: %s", __func__,
- c->self, ssh_err(r));
- if ((r = sshpkt_send(ssh)) != 0)
- fatal("%s: channel %i: %s", __func__, c->self,
- ssh_err(r));
+ (r = sshpkt_put_u32(ssh, c->local_maxpacket)) != 0 ||
+ (r = sshpkt_send(ssh)) != 0)
+ fatal_fr(r, "channel %i open confirm", c->self);
}
} else {
debug("channel %d: connection failed: %s",
@@ -1913,13 +1921,9 @@ channel_post_connecting(struct ssh *ssh, Channel *c,
(r = sshpkt_put_u32(ssh,
SSH2_OPEN_CONNECT_FAILED)) != 0 ||
(r = sshpkt_put_cstring(ssh, strerror(err))) != 0 ||
- (r = sshpkt_put_cstring(ssh, "")) != 0) {
- fatal("%s: channel %i: failure: %s", __func__,
- c->self, ssh_err(r));
- }
- if ((r = sshpkt_send(ssh)) != 0)
- fatal("%s: channel %i: %s", __func__, c->self,
- ssh_err(r));
+ (r = sshpkt_put_cstring(ssh, "")) != 0 ||
+ (r = sshpkt_send(ssh)) != 0)
+ fatal_fr(r, "channel %i: failure", c->self);
chan_mark_dead(ssh, c);
}
}
@@ -1940,11 +1944,11 @@ channel_handle_rfd(struct ssh *ssh, Channel *c,
errno = 0;
len = read(c->rfd, buf, sizeof(buf));
- if (len < 0 && (errno == EINTR ||
+ if (len == -1 && (errno == EINTR ||
((errno == EAGAIN || errno == EWOULDBLOCK) && !force)))
return 1;
#ifndef PTY_ZEROREAD
- if (len <= 0) {
+ if (len <= 0) {
#else
if ((!c->isatty && len <= 0) ||
(c->isatty && (len < 0 || (len == 0 && errno != 0)))) {
@@ -1967,12 +1971,9 @@ channel_handle_rfd(struct ssh *ssh, Channel *c,
}
} else if (c->datagram) {
if ((r = sshbuf_put_string(c->input, buf, len)) != 0)
- fatal("%s: channel %d: put datagram: %s", __func__,
- c->self, ssh_err(r));
- } else if ((r = sshbuf_put(c->input, buf, len)) != 0) {
- fatal("%s: channel %d: put data: %s", __func__,
- c->self, ssh_err(r));
- }
+ fatal_fr(r, "channel %i: put datagram", c->self);
+ } else if ((r = sshbuf_put(c->input, buf, len)) != 0)
+ fatal_fr(r, "channel %i: put data", c->self);
return 1;
}
@@ -2002,8 +2003,7 @@ channel_handle_wfd(struct ssh *ssh, Channel *c,
}
} else if (c->datagram) {
if ((r = sshbuf_get_string(c->output, &data, &dlen)) != 0)
- fatal("%s: channel %d: get datagram: %s", __func__,
- c->self, ssh_err(r));
+ fatal_fr(r, "channel %i: get datagram", c->self);
buf = data;
} else {
buf = data = sshbuf_mutable_ptr(c->output);
@@ -2014,7 +2014,7 @@ channel_handle_wfd(struct ssh *ssh, Channel *c,
/* ignore truncated writes, datagrams might get lost */
len = write(c->wfd, buf, dlen);
free(data);
- if (len < 0 && (errno == EINTR || errno == EAGAIN ||
+ if (len == -1 && (errno == EINTR || errno == EAGAIN ||
errno == EWOULDBLOCK))
return 1;
if (len <= 0)
@@ -2029,7 +2029,7 @@ channel_handle_wfd(struct ssh *ssh, Channel *c,
#endif
len = write(c->wfd, buf, dlen);
- if (len < 0 &&
+ if (len == -1 &&
(errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK))
return 1;
if (len <= 0) {
@@ -2055,15 +2055,12 @@ channel_handle_wfd(struct ssh *ssh, Channel *c,
*/
if ((r = sshpkt_msg_ignore(ssh, 4+len)) != 0 ||
(r = sshpkt_send(ssh)) != 0)
- fatal("%s: channel %d: ignore: %s",
- __func__, c->self, ssh_err(r));
+ fatal_fr(r, "channel %i: ignore", c->self);
}
}
#endif /* BROKEN_TCGETATTR_ICANON */
- if ((r = sshbuf_consume(c->output, len)) != 0) {
- fatal("%s: channel %d: consume: %s",
- __func__, c->self, ssh_err(r));
- }
+ if ((r = sshbuf_consume(c->output, len)) != 0)
+ fatal_fr(r, "channel %i: consume", c->self);
out:
c->local_consumed += olen - sshbuf_len(c->output);
@@ -2083,17 +2080,15 @@ channel_handle_efd_write(struct ssh *ssh, Channel *c,
len = write(c->efd, sshbuf_ptr(c->extended),
sshbuf_len(c->extended));
debug2("channel %d: written %zd to efd %d", c->self, len, c->efd);
- if (len < 0 && (errno == EINTR || errno == EAGAIN ||
+ if (len == -1 && (errno == EINTR || errno == EAGAIN ||
errno == EWOULDBLOCK))
return 1;
if (len <= 0) {
debug2("channel %d: closing write-efd %d", c->self, c->efd);
- channel_close_fd(ssh, &c->efd);
+ channel_close_fd(ssh, c, &c->efd);
} else {
- if ((r = sshbuf_consume(c->extended, len)) != 0) {
- fatal("%s: channel %d: consume: %s",
- __func__, c->self, ssh_err(r));
- }
+ if ((r = sshbuf_consume(c->extended, len)) != 0)
+ fatal_fr(r, "channel %i: consume", c->self);
c->local_consumed += len;
}
return 1;
@@ -2104,30 +2099,26 @@ channel_handle_efd_read(struct ssh *ssh, Channel *c,
fd_set *readset, fd_set *writeset)
{
char buf[CHAN_RBUF];
- int r;
ssize_t len;
+ int r, force;
+
+ force = c->isatty && c->detach_close && c->istate != CHAN_INPUT_CLOSED;
- if (!c->detach_close && !FD_ISSET(c->efd, readset))
+ if (c->efd == -1 || (!force && !FD_ISSET(c->efd, readset)))
return 1;
len = read(c->efd, buf, sizeof(buf));
debug2("channel %d: read %zd from efd %d", c->self, len, c->efd);
- if (len < 0 && (errno == EINTR || ((errno == EAGAIN ||
- errno == EWOULDBLOCK) && !c->detach_close)))
+ if (len == -1 && (errno == EINTR || ((errno == EAGAIN ||
+ errno == EWOULDBLOCK) && !force)))
return 1;
if (len <= 0) {
- debug2("channel %d: closing read-efd %d",
- c->self, c->efd);
- channel_close_fd(ssh, &c->efd);
- } else {
- if (c->extended_usage == CHAN_EXTENDED_IGNORE) {
- debug3("channel %d: discard efd",
- c->self);
- } else if ((r = sshbuf_put(c->extended, buf, len)) != 0) {
- fatal("%s: channel %d: append: %s",
- __func__, c->self, ssh_err(r));
- }
- }
+ debug2("channel %d: closing read-efd %d", c->self, c->efd);
+ channel_close_fd(ssh, c, &c->efd);
+ } else if (c->extended_usage == CHAN_EXTENDED_IGNORE)
+ debug3("channel %d: discard efd", c->self);
+ else if ((r = sshbuf_put(c->extended, buf, len)) != 0)
+ fatal_fr(r, "channel %i: append", c->self);
return 1;
}
@@ -2161,19 +2152,16 @@ channel_check_window(struct ssh *ssh, Channel *c)
c->local_window < c->local_window_max/2) &&
c->local_consumed > 0) {
if (!c->have_remote_id)
- fatal(":%s: channel %d: no remote id",
- __func__, c->self);
+ fatal_f("channel %d: no remote id", c->self);
if ((r = sshpkt_start(ssh,
SSH2_MSG_CHANNEL_WINDOW_ADJUST)) != 0 ||
(r = sshpkt_put_u32(ssh, c->remote_id)) != 0 ||
(r = sshpkt_put_u32(ssh, c->local_consumed)) != 0 ||
(r = sshpkt_send(ssh)) != 0) {
- fatal("%s: channel %i: %s", __func__,
- c->self, ssh_err(r));
+ fatal_fr(r, "channel %i", c->self);
}
- debug2("channel %d: window %d sent adjust %d",
- c->self, c->local_window,
- c->local_consumed);
+ debug2("channel %d: window %d sent adjust %d", c->self,
+ c->local_window, c->local_consumed);
c->local_window += c->local_consumed;
c->local_consumed = 0;
}
@@ -2201,17 +2189,15 @@ read_mux(struct ssh *ssh, Channel *c, u_int need)
if (sshbuf_len(c->input) < need) {
rlen = need - sshbuf_len(c->input);
len = read(c->rfd, buf, MINIMUM(rlen, CHAN_RBUF));
- if (len < 0 && (errno == EINTR || errno == EAGAIN))
+ if (len == -1 && (errno == EINTR || errno == EAGAIN))
return sshbuf_len(c->input);
if (len <= 0) {
debug2("channel %d: ctl read<=0 rfd %d len %zd",
c->self, c->rfd, len);
chan_read_failed(ssh, c);
return 0;
- } else if ((r = sshbuf_put(c->input, buf, len)) != 0) {
- fatal("%s: channel %d: append: %s",
- __func__, c->self, ssh_err(r));
- }
+ } else if ((r = sshbuf_put(c->input, buf, len)) != 0)
+ fatal_fr(r, "channel %i: append", c->self);
}
return sshbuf_len(c->input);
}
@@ -2265,15 +2251,14 @@ channel_post_mux_client_write(struct ssh *ssh, Channel *c,
return;
len = write(c->wfd, sshbuf_ptr(c->output), sshbuf_len(c->output));
- if (len < 0 && (errno == EINTR || errno == EAGAIN))
+ if (len == -1 && (errno == EINTR || errno == EAGAIN))
return;
if (len <= 0) {
chan_mark_dead(ssh, c);
return;
}
if ((r = sshbuf_consume(c->output, len)) != 0)
- fatal("%s: channel %d: consume: %s", __func__,
- c->self, ssh_err(r));
+ fatal_fr(r, "channel %i: consume", c->self);
}
static void
@@ -2307,15 +2292,14 @@ channel_post_mux_listener(struct ssh *ssh, Channel *c,
addrlen = sizeof(addr);
if ((newsock = accept(c->sock, (struct sockaddr*)&addr,
&addrlen)) == -1) {
- error("%s accept: %s", __func__, strerror(errno));
+ error_f("accept: %s", strerror(errno));
if (errno == EMFILE || errno == ENFILE)
c->notbefore = monotime() + 1;
return;
}
- if (getpeereid(newsock, &euid, &egid) < 0) {
- error("%s getpeereid failed: %s", __func__,
- strerror(errno));
+ if (getpeereid(newsock, &euid, &egid) == -1) {
+ error_f("getpeereid failed: %s", strerror(errno));
close(newsock);
return;
}
@@ -2329,7 +2313,7 @@ channel_post_mux_listener(struct ssh *ssh, Channel *c,
newsock, newsock, -1, c->local_window_max,
c->local_maxpacket, 0, "mux-control", 1);
nc->mux_rcb = c->mux_rcb;
- debug3("%s: new mux channel %d fd %d", __func__, nc->self, nc->sock);
+ debug3_f("new mux channel %d fd %d", nc->self, nc->sock);
/* establish state */
nc->mux_rcb(ssh, nc);
/* mux state transitions must not elicit protocol messages */
@@ -2342,8 +2326,8 @@ channel_handler_init(struct ssh_channels *sc)
chan_fn **pre, **post;
if ((pre = calloc(SSH_CHANNEL_MAX_TYPE, sizeof(*pre))) == NULL ||
- (post = calloc(SSH_CHANNEL_MAX_TYPE, sizeof(*post))) == NULL)
- fatal("%s: allocation failed", __func__);
+ (post = calloc(SSH_CHANNEL_MAX_TYPE, sizeof(*post))) == NULL)
+ fatal_f("allocation failed");
pre[SSH_CHANNEL_OPEN] = &channel_pre_open;
pre[SSH_CHANNEL_X11_OPEN] = &channel_pre_x11_open;
@@ -2435,8 +2419,8 @@ channel_handler(struct ssh *ssh, int table,
* Collect the time that the earliest
* channel comes off pause.
*/
- debug3("%s: chan %d: skip for %d more seconds",
- __func__, c->self,
+ debug3_f("chan %d: skip for %d more "
+ "seconds", c->self,
(int)(c->notbefore - now));
if (*unpause_secs == 0 ||
(c->notbefore - now) < *unpause_secs)
@@ -2446,8 +2430,8 @@ channel_handler(struct ssh *ssh, int table,
channel_garbage_collect(ssh, c);
}
if (unpause_secs != NULL && *unpause_secs != 0)
- debug3("%s: first channel unpauses in %d seconds",
- __func__, (int)*unpause_secs);
+ debug3_f("first channel unpauses in %d seconds",
+ (int)*unpause_secs);
}
/*
@@ -2546,13 +2530,12 @@ channel_output_poll_input_open(struct ssh *ssh, Channel *c)
}
if (!c->have_remote_id)
- fatal(":%s: channel %d: no remote id", __func__, c->self);
+ fatal_f("channel %d: no remote id", c->self);
if (c->datagram) {
/* Check datagram will fit; drop if not */
if ((r = sshbuf_get_string_direct(c->input, &pkt, &plen)) != 0)
- fatal("%s: channel %d: get datagram: %s", __func__,
- c->self, ssh_err(r));
+ fatal_fr(r, "channel %i: get datagram", c->self);
/*
* XXX this does tail-drop on the datagram queue which is
* usually suboptimal compared to head-drop. Better to have
@@ -2566,10 +2549,8 @@ channel_output_poll_input_open(struct ssh *ssh, Channel *c)
if ((r = sshpkt_start(ssh, SSH2_MSG_CHANNEL_DATA)) != 0 ||
(r = sshpkt_put_u32(ssh, c->remote_id)) != 0 ||
(r = sshpkt_put_string(ssh, pkt, plen)) != 0 ||
- (r = sshpkt_send(ssh)) != 0) {
- fatal("%s: channel %i: datagram: %s", __func__,
- c->self, ssh_err(r));
- }
+ (r = sshpkt_send(ssh)) != 0)
+ fatal_fr(r, "channel %i: send datagram", c->self);
c->remote_window -= plen;
return;
}
@@ -2584,13 +2565,10 @@ channel_output_poll_input_open(struct ssh *ssh, Channel *c)
if ((r = sshpkt_start(ssh, SSH2_MSG_CHANNEL_DATA)) != 0 ||
(r = sshpkt_put_u32(ssh, c->remote_id)) != 0 ||
(r = sshpkt_put_string(ssh, sshbuf_ptr(c->input), len)) != 0 ||
- (r = sshpkt_send(ssh)) != 0) {
- fatal("%s: channel %i: data: %s", __func__,
- c->self, ssh_err(r));
- }
+ (r = sshpkt_send(ssh)) != 0)
+ fatal_fr(r, "channel %i: send data", c->self);
if ((r = sshbuf_consume(c->input, len)) != 0)
- fatal("%s: channel %i: consume: %s", __func__,
- c->self, ssh_err(r));
+ fatal_fr(r, "channel %i: consume", c->self);
c->remote_window -= len;
}
@@ -2615,18 +2593,15 @@ channel_output_poll_extended_read(struct ssh *ssh, Channel *c)
if (len == 0)
return;
if (!c->have_remote_id)
- fatal(":%s: channel %d: no remote id", __func__, c->self);
+ fatal_f("channel %d: no remote id", c->self);
if ((r = sshpkt_start(ssh, SSH2_MSG_CHANNEL_EXTENDED_DATA)) != 0 ||
(r = sshpkt_put_u32(ssh, c->remote_id)) != 0 ||
(r = sshpkt_put_u32(ssh, SSH2_EXTENDED_DATA_STDERR)) != 0 ||
(r = sshpkt_put_string(ssh, sshbuf_ptr(c->extended), len)) != 0 ||
- (r = sshpkt_send(ssh)) != 0) {
- fatal("%s: channel %i: data: %s", __func__,
- c->self, ssh_err(r));
- }
+ (r = sshpkt_send(ssh)) != 0)
+ fatal_fr(r, "channel %i: data", c->self);
if ((r = sshbuf_consume(c->extended, len)) != 0)
- fatal("%s: channel %i: consume: %s", __func__,
- c->self, ssh_err(r));
+ fatal_fr(r, "channel %i: consume", c->self);
c->remote_window -= len;
debug2("channel %d: sent ext data %zu", c->self, len);
}
@@ -2723,11 +2698,11 @@ channel_proxy_downstream(struct ssh *ssh, Channel *downstream)
/* sshbuf_dump(downstream->input, stderr); */
if ((r = sshbuf_get_string_direct(downstream->input, &cp, &have))
!= 0) {
- error("%s: malformed message: %s", __func__, ssh_err(r));
+ error_fr(r, "parse");
return -1;
}
if (have < 2) {
- error("%s: short message", __func__);
+ error_f("short message");
return -1;
}
type = cp[1];
@@ -2735,29 +2710,29 @@ channel_proxy_downstream(struct ssh *ssh, Channel *downstream)
cp += 2;
have -= 2;
if (ssh_packet_log_type(type))
- debug3("%s: channel %u: down->up: type %u", __func__,
+ debug3_f("channel %u: down->up: type %u",
downstream->self, type);
switch (type) {
case SSH2_MSG_CHANNEL_OPEN:
if ((original = sshbuf_from(cp, have)) == NULL ||
(modified = sshbuf_new()) == NULL) {
- error("%s: alloc", __func__);
+ error_f("alloc");
goto out;
}
if ((r = sshbuf_get_cstring(original, &ctype, NULL)) != 0 ||
(r = sshbuf_get_u32(original, &id)) != 0) {
- error("%s: parse error %s", __func__, ssh_err(r));
+ error_fr(r, "parse");
goto out;
}
c = channel_new(ssh, "mux proxy", SSH_CHANNEL_MUX_PROXY,
- -1, -1, -1, 0, 0, 0, ctype, 1);
+ -1, -1, -1, 0, 0, 0, ctype, 1);
c->mux_ctx = downstream; /* point to mux client */
c->mux_downstream_id = id; /* original downstream id */
if ((r = sshbuf_put_cstring(modified, ctype)) != 0 ||
(r = sshbuf_put_u32(modified, c->self)) != 0 ||
(r = sshbuf_putb(modified, original)) != 0) {
- error("%s: compose error %s", __func__, ssh_err(r));
+ error_fr(r, "compose");
channel_free(ssh, c);
goto out;
}
@@ -2769,16 +2744,16 @@ channel_proxy_downstream(struct ssh *ssh, Channel *downstream)
*/
if ((original = sshbuf_from(cp, have)) == NULL ||
(modified = sshbuf_new()) == NULL) {
- error("%s: alloc", __func__);
+ error_f("alloc");
goto out;
}
if ((r = sshbuf_get_u32(original, &remote_id)) != 0 ||
(r = sshbuf_get_u32(original, &id)) != 0) {
- error("%s: parse error %s", __func__, ssh_err(r));
+ error_fr(r, "parse");
goto out;
}
c = channel_new(ssh, "mux proxy", SSH_CHANNEL_MUX_PROXY,
- -1, -1, -1, 0, 0, 0, "mux-down-connect", 1);
+ -1, -1, -1, 0, 0, 0, "mux-down-connect", 1);
c->mux_ctx = downstream; /* point to mux client */
c->mux_downstream_id = id;
c->remote_id = remote_id;
@@ -2786,33 +2761,33 @@ channel_proxy_downstream(struct ssh *ssh, Channel *downstream)
if ((r = sshbuf_put_u32(modified, remote_id)) != 0 ||
(r = sshbuf_put_u32(modified, c->self)) != 0 ||
(r = sshbuf_putb(modified, original)) != 0) {
- error("%s: compose error %s", __func__, ssh_err(r));
+ error_fr(r, "compose");
channel_free(ssh, c);
goto out;
}
break;
case SSH2_MSG_GLOBAL_REQUEST:
if ((original = sshbuf_from(cp, have)) == NULL) {
- error("%s: alloc", __func__);
+ error_f("alloc");
goto out;
}
if ((r = sshbuf_get_cstring(original, &ctype, NULL)) != 0) {
- error("%s: parse error %s", __func__, ssh_err(r));
+ error_fr(r, "parse");
goto out;
}
if (strcmp(ctype, "tcpip-forward") != 0) {
- error("%s: unsupported request %s", __func__, ctype);
+ error_f("unsupported request %s", ctype);
goto out;
}
if ((r = sshbuf_get_u8(original, NULL)) != 0 ||
(r = sshbuf_get_cstring(original, &listen_host, NULL)) != 0 ||
(r = sshbuf_get_u32(original, &listen_port)) != 0) {
- error("%s: parse error %s", __func__, ssh_err(r));
+ error_fr(r, "parse");
goto out;
}
if (listen_port > 65535) {
- error("%s: tcpip-forward for %s: bad port %u",
- __func__, listen_host, listen_port);
+ error_f("tcpip-forward for %s: bad port %u",
+ listen_host, listen_port);
goto out;
}
/* Record that connection to this host/port is permitted. */
@@ -2836,14 +2811,14 @@ channel_proxy_downstream(struct ssh *ssh, Channel *downstream)
if ((r = sshpkt_start(ssh, type)) != 0 ||
(r = sshpkt_putb(ssh, modified)) != 0 ||
(r = sshpkt_send(ssh)) != 0) {
- error("%s: send %s", __func__, ssh_err(r));
+ error_fr(r, "send");
goto out;
}
} else {
if ((r = sshpkt_start(ssh, type)) != 0 ||
(r = sshpkt_put(ssh, cp, have)) != 0 ||
(r = sshpkt_send(ssh)) != 0) {
- error("%s: send %s", __func__, ssh_err(r));
+ error_fr(r, "send");
goto out;
}
}
@@ -2894,18 +2869,17 @@ channel_proxy_upstream(Channel *c, int type, u_int32_t seq, struct ssh *ssh)
case SSH2_MSG_CHANNEL_REQUEST:
break;
default:
- debug2("%s: channel %u: unsupported type %u", __func__,
- c->self, type);
+ debug2_f("channel %u: unsupported type %u", c->self, type);
return 0;
}
if ((b = sshbuf_new()) == NULL) {
- error("%s: alloc reply", __func__);
+ error_f("alloc reply");
goto out;
}
/* get remaining payload (after id) */
cp = sshpkt_ptr(ssh, &len);
if (cp == NULL) {
- error("%s: no packet", __func__);
+ error_f("no packet");
goto out;
}
/* translate id and send to muxclient */
@@ -2914,13 +2888,12 @@ channel_proxy_upstream(Channel *c, int type, u_int32_t seq, struct ssh *ssh)
(r = sshbuf_put_u32(b, c->mux_downstream_id)) != 0 ||
(r = sshbuf_put(b, cp, len)) != 0 ||
(r = sshbuf_put_stringb(downstream->output, b)) != 0) {
- error("%s: compose for muxclient %s", __func__, ssh_err(r));
+ error_fr(r, "compose muxclient");
goto out;
}
/* sshbuf_dump(b, stderr); */
if (ssh_packet_log_type(type))
- debug3("%s: channel %u: up->down: type %u", __func__, c->self,
- type);
+ debug3_f("channel %u: up->down: type %u", c->self, type);
out:
/* update state */
switch (type) {
@@ -2952,11 +2925,11 @@ channel_parse_id(struct ssh *ssh, const char *where, const char *what)
int r;
if ((r = sshpkt_get_u32(ssh, &id)) != 0) {
- error("%s: parse id: %s", where, ssh_err(r));
+ error_r(r, "%s: parse id", where);
ssh_packet_disconnect(ssh, "Invalid %s message", what);
}
if (id > INT_MAX) {
- error("%s: bad channel id %u: %s", where, id, ssh_err(r));
+ error_r(r, "%s: bad channel id %u", where, id);
ssh_packet_disconnect(ssh, "Invalid %s channel id", what);
}
return (int)id;
@@ -2995,10 +2968,9 @@ channel_input_data(int type, u_int32_t seq, struct ssh *ssh)
return 0;
/* Get the data. */
- if ((r = sshpkt_get_string_direct(ssh, &data, &data_len)) != 0)
- fatal("%s: channel %d: get data: %s", __func__,
- c->self, ssh_err(r));
- ssh_packet_check_eom(ssh);
+ if ((r = sshpkt_get_string_direct(ssh, &data, &data_len)) != 0 ||
+ (r = sshpkt_get_end(ssh)) != 0)
+ fatal_fr(r, "channel %i: get data", c->self);
win_len = data_len;
if (c->datagram)
@@ -3029,11 +3001,9 @@ channel_input_data(int type, u_int32_t seq, struct ssh *ssh)
if (c->datagram) {
if ((r = sshbuf_put_string(c->output, data, data_len)) != 0)
- fatal("%s: channel %d: append datagram: %s",
- __func__, c->self, ssh_err(r));
+ fatal_fr(r, "channel %i: append datagram", c->self);
} else if ((r = sshbuf_put(c->output, data, data_len)) != 0)
- fatal("%s: channel %d: append data: %s",
- __func__, c->self, ssh_err(r));
+ fatal_fr(r, "channel %i: append data", c->self);
return 0;
}
@@ -3054,7 +3024,7 @@ channel_input_extended_data(int type, u_int32_t seq, struct ssh *ssh)
return 0;
}
if (c->flags & CHAN_EOF_RCVD) {
- if (datafellows & SSH_BUG_EXTEOF)
+ if (ssh->compat & SSH_BUG_EXTEOF)
debug("channel %d: accepting ext data after eof",
c->self);
else
@@ -3063,7 +3033,7 @@ channel_input_extended_data(int type, u_int32_t seq, struct ssh *ssh)
}
if ((r = sshpkt_get_u32(ssh, &tcode)) != 0) {
- error("%s: parse tcode: %s", __func__, ssh_err(r));
+ error_fr(r, "parse tcode");
ssh_packet_disconnect(ssh, "Invalid extended_data message");
}
if (c->efd == -1 ||
@@ -3072,11 +3042,11 @@ channel_input_extended_data(int type, u_int32_t seq, struct ssh *ssh)
logit("channel %d: bad ext data", c->self);
return 0;
}
- if ((r = sshpkt_get_string_direct(ssh, &data, &data_len)) != 0) {
- error("%s: parse data: %s", __func__, ssh_err(r));
+ if ((r = sshpkt_get_string_direct(ssh, &data, &data_len)) != 0 ||
+ (r = sshpkt_get_end(ssh)) != 0) {
+ error_fr(r, "parse data");
ssh_packet_disconnect(ssh, "Invalid extended_data message");
}
- ssh_packet_check_eom(ssh);
if (data_len > c->local_window) {
logit("channel %d: rcvd too much extended_data %zu, win %u",
@@ -3086,7 +3056,7 @@ channel_input_extended_data(int type, u_int32_t seq, struct ssh *ssh)
debug2("channel %d: rcvd ext data %zu", c->self, data_len);
/* XXX sshpkt_getb? */
if ((r = sshbuf_put(c->extended, data, data_len)) != 0)
- error("%s: append: %s", __func__, ssh_err(r));
+ error_fr(r, "append");
c->local_window -= data_len;
return 0;
}
@@ -3095,8 +3065,12 @@ int
channel_input_ieof(int type, u_int32_t seq, struct ssh *ssh)
{
Channel *c = channel_from_packet_id(ssh, __func__, "ieof");
+ int r;
- ssh_packet_check_eom(ssh);
+ if ((r = sshpkt_get_end(ssh)) != 0) {
+ error_fr(r, "parse data");
+ ssh_packet_disconnect(ssh, "Invalid ieof message");
+ }
if (channel_proxy_upstream(c, type, seq, ssh))
return 0;
@@ -3116,10 +3090,14 @@ int
channel_input_oclose(int type, u_int32_t seq, struct ssh *ssh)
{
Channel *c = channel_from_packet_id(ssh, __func__, "oclose");
+ int r;
if (channel_proxy_upstream(c, type, seq, ssh))
return 0;
- ssh_packet_check_eom(ssh);
+ if ((r = sshpkt_get_end(ssh)) != 0) {
+ error_fr(r, "parse data");
+ ssh_packet_disconnect(ssh, "Invalid oclose message");
+ }
chan_rcvd_oclose(ssh, c);
return 0;
}
@@ -3134,7 +3112,7 @@ channel_input_open_confirmation(int type, u_int32_t seq, struct ssh *ssh)
if (channel_proxy_upstream(c, type, seq, ssh))
return 0;
if (c->type != SSH_CHANNEL_OPENING)
- packet_disconnect("Received open confirmation for "
+ ssh_packet_disconnect(ssh, "Received open confirmation for "
"non-opening channel %d.", c->self);
/*
* Record the remote channel number and mark that the channel
@@ -3142,20 +3120,20 @@ channel_input_open_confirmation(int type, u_int32_t seq, struct ssh *ssh)
*/
if ((r = sshpkt_get_u32(ssh, &c->remote_id)) != 0 ||
(r = sshpkt_get_u32(ssh, &remote_window)) != 0 ||
- (r = sshpkt_get_u32(ssh, &remote_maxpacket)) != 0) {
- error("%s: window/maxpacket: %s", __func__, ssh_err(r));
- packet_disconnect("Invalid open confirmation message");
+ (r = sshpkt_get_u32(ssh, &remote_maxpacket)) != 0 ||
+ (r = sshpkt_get_end(ssh)) != 0) {
+ error_fr(r, "window/maxpacket");
+ ssh_packet_disconnect(ssh, "Invalid open confirmation message");
}
- ssh_packet_check_eom(ssh);
c->have_remote_id = 1;
c->remote_window = remote_window;
c->remote_maxpacket = remote_maxpacket;
c->type = SSH_CHANNEL_OPEN;
if (c->open_confirm) {
- debug2("%s: channel %d: callback start", __func__, c->self);
+ debug2_f("channel %d: callback start", c->self);
c->open_confirm(ssh, c->self, 1, c->open_confirm_ctx);
- debug2("%s: channel %d: callback done", __func__, c->self);
+ debug2_f("channel %d: callback done", c->self);
}
debug2("channel %d: open confirm rwindow %u rmax %u", c->self,
c->remote_window, c->remote_maxpacket);
@@ -3189,26 +3167,26 @@ channel_input_open_failure(int type, u_int32_t seq, struct ssh *ssh)
if (channel_proxy_upstream(c, type, seq, ssh))
return 0;
if (c->type != SSH_CHANNEL_OPENING)
- packet_disconnect("Received open failure for "
+ ssh_packet_disconnect(ssh, "Received open failure for "
"non-opening channel %d.", c->self);
if ((r = sshpkt_get_u32(ssh, &reason)) != 0) {
- error("%s: reason: %s", __func__, ssh_err(r));
- packet_disconnect("Invalid open failure message");
+ error_fr(r, "parse reason");
+ ssh_packet_disconnect(ssh, "Invalid open failure message");
}
/* skip language */
if ((r = sshpkt_get_cstring(ssh, &msg, NULL)) != 0 ||
- (r = sshpkt_get_string_direct(ssh, NULL, NULL)) != 0) {
- error("%s: message/lang: %s", __func__, ssh_err(r));
- packet_disconnect("Invalid open failure message");
+ (r = sshpkt_get_string_direct(ssh, NULL, NULL)) != 0 ||
+ (r = sshpkt_get_end(ssh)) != 0) {
+ error_fr(r, "parse msg/lang");
+ ssh_packet_disconnect(ssh, "Invalid open failure message");
}
- ssh_packet_check_eom(ssh);
logit("channel %d: open failed: %s%s%s", c->self,
reason2txt(reason), msg ? ": ": "", msg ? msg : "");
free(msg);
if (c->open_confirm) {
- debug2("%s: channel %d: callback start", __func__, c->self);
+ debug2_f("channel %d: callback start", c->self);
c->open_confirm(ssh, c->self, 0, c->open_confirm_ctx);
- debug2("%s: channel %d: callback done", __func__, c->self);
+ debug2_f("channel %d: callback done", c->self);
}
/* Schedule the channel for cleanup/deletion. */
chan_mark_dead(ssh, c);
@@ -3231,11 +3209,11 @@ channel_input_window_adjust(int type, u_int32_t seq, struct ssh *ssh)
if (channel_proxy_upstream(c, type, seq, ssh))
return 0;
- if ((r = sshpkt_get_u32(ssh, &adjust)) != 0) {
- error("%s: adjust: %s", __func__, ssh_err(r));
- packet_disconnect("Invalid window adjust message");
+ if ((r = sshpkt_get_u32(ssh, &adjust)) != 0 ||
+ (r = sshpkt_get_end(ssh)) != 0) {
+ error_fr(r, "parse adjust");
+ ssh_packet_disconnect(ssh, "Invalid window adjust message");
}
- ssh_packet_check_eom(ssh);
debug2("channel %d: rcvd adjust %u", c->self, adjust);
if ((new_rwin = c->remote_window + adjust) < c->remote_window) {
fatal("channel %d: adjust %u overflows remote window %u",
@@ -3253,23 +3231,23 @@ channel_input_status_confirm(int type, u_int32_t seq, struct ssh *ssh)
struct channel_confirm *cc;
/* Reset keepalive timeout */
- packet_set_alive_timeouts(0);
+ ssh_packet_set_alive_timeouts(ssh, 0);
- debug2("%s: type %d id %d", __func__, type, id);
+ debug2_f("type %d id %d", type, id);
if ((c = channel_lookup(ssh, id)) == NULL) {
- logit("%s: %d: unknown", __func__, id);
+ logit_f("%d: unknown", id);
return 0;
}
if (channel_proxy_upstream(c, type, seq, ssh))
return 0;
- ssh_packet_check_eom(ssh);
+ if (sshpkt_get_end(ssh) != 0)
+ ssh_packet_disconnect(ssh, "Invalid status confirm message");
if ((cc = TAILQ_FIRST(&c->status_confirms)) == NULL)
return 0;
cc->cb(ssh, type, c, cc->ctx);
TAILQ_REMOVE(&c->status_confirms, cc, entry);
- explicit_bzero(cc, sizeof(*cc));
- free(cc);
+ freezero(cc, sizeof(*cc));
return 0;
}
@@ -3298,7 +3276,7 @@ channel_set_af(struct ssh *ssh, int af)
* "127.0.0.1" / "::1" -> accepted even if gateway_ports isn't set
*/
static const char *
-channel_fwd_bind_addr(const char *listen_addr, int *wildcardp,
+channel_fwd_bind_addr(struct ssh *ssh, const char *listen_addr, int *wildcardp,
int is_client, struct ForwardOptions *fwd_opts)
{
const char *addr = NULL;
@@ -3309,7 +3287,7 @@ channel_fwd_bind_addr(const char *listen_addr, int *wildcardp,
if (fwd_opts->gateway_ports)
wildcard = 1;
} else if (fwd_opts->gateway_ports || is_client) {
- if (((datafellows & SSH_OLD_FORWARD_ADDR) &&
+ if (((ssh->compat & SSH_OLD_FORWARD_ADDR) &&
strcmp(listen_addr, "0.0.0.0") == 0 && is_client == 0) ||
*listen_addr == '\0' || strcmp(listen_addr, "*") == 0 ||
(!is_client && fwd_opts->gateway_ports == 1)) {
@@ -3321,14 +3299,20 @@ channel_fwd_bind_addr(const char *listen_addr, int *wildcardp,
if (*listen_addr != '\0' &&
strcmp(listen_addr, "0.0.0.0") != 0 &&
strcmp(listen_addr, "*") != 0) {
- packet_send_debug("Forwarding listen address "
+ ssh_packet_send_debug(ssh,
+ "Forwarding listen address "
"\"%s\" overridden by server "
"GatewayPorts", listen_addr);
}
} else if (strcmp(listen_addr, "localhost") != 0 ||
strcmp(listen_addr, "127.0.0.1") == 0 ||
strcmp(listen_addr, "::1") == 0) {
- /* Accept localhost address when GatewayPorts=yes */
+ /*
+ * Accept explicit localhost address when
+ * GatewayPorts=yes. The "localhost" hostname is
+ * deliberately skipped here so it will listen on all
+ * available local address families.
+ */
addr = listen_addr;
}
} else if (strcmp(listen_addr, "127.0.0.1") == 0 ||
@@ -3375,10 +3359,10 @@ channel_setup_fwd_listener_tcpip(struct ssh *ssh, int type,
}
/* Determine the bind address, cf. channel_fwd_bind_addr() comment */
- addr = channel_fwd_bind_addr(fwd->listen_host, &wildcard,
+ addr = channel_fwd_bind_addr(ssh, fwd->listen_host, &wildcard,
is_client, fwd_opts);
- debug3("%s: type %d wildcard %d addr %s", __func__,
- type, wildcard, (addr == NULL) ? "NULL" : addr);
+ debug3_f("type %d wildcard %d addr %s", type, wildcard,
+ (addr == NULL) ? "NULL" : addr);
/*
* getaddrinfo returns a loopback address if the hostname is
@@ -3392,10 +3376,10 @@ channel_setup_fwd_listener_tcpip(struct ssh *ssh, int type,
if ((r = getaddrinfo(addr, strport, &hints, &aitop)) != 0) {
if (addr == NULL) {
/* This really shouldn't happen */
- packet_disconnect("getaddrinfo: fatal error: %s",
+ ssh_packet_disconnect(ssh, "getaddrinfo: fatal error: %s",
ssh_gai_strerror(r));
} else {
- error("%s: getaddrinfo(%.64s): %s", __func__, addr,
+ error_f("getaddrinfo(%.64s): %s", addr,
ssh_gai_strerror(r));
}
return 0;
@@ -3427,12 +3411,12 @@ channel_setup_fwd_listener_tcpip(struct ssh *ssh, int type,
if (getnameinfo(ai->ai_addr, ai->ai_addrlen, ntop, sizeof(ntop),
strport, sizeof(strport),
NI_NUMERICHOST|NI_NUMERICSERV) != 0) {
- error("%s: getnameinfo failed", __func__);
+ error_f("getnameinfo failed");
continue;
}
/* Create a port to listen for the host. */
sock = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
- if (sock < 0) {
+ if (sock == -1) {
/* this is no error since kernel may not support ipv6 */
verbose("socket [%s]:%s: %.100s", ntop, strport,
strerror(errno));
@@ -3447,7 +3431,7 @@ channel_setup_fwd_listener_tcpip(struct ssh *ssh, int type,
ntop, strport);
/* Bind the socket to the address. */
- if (bind(sock, ai->ai_addr, ai->ai_addrlen) < 0) {
+ if (bind(sock, ai->ai_addr, ai->ai_addrlen) == -1) {
/*
* address can be in if use ipv6 address is
* already bound
@@ -3463,8 +3447,7 @@ channel_setup_fwd_listener_tcpip(struct ssh *ssh, int type,
continue;
}
/* Start listening for connections on the socket. */
- if (listen(sock, SSH_LISTEN_BACKLOG) < 0) {
- error("listen: %.100s", strerror(errno));
+ if (listen(sock, SSH_LISTEN_BACKLOG) == -1) {
error("listen [%s]:%s: %.100s", ntop, strport,
strerror(errno));
close(sock);
@@ -3492,15 +3475,14 @@ channel_setup_fwd_listener_tcpip(struct ssh *ssh, int type,
c->host_port = fwd->connect_port;
c->listening_addr = addr == NULL ? NULL : xstrdup(addr);
if (fwd->listen_port == 0 && allocated_listen_port != NULL &&
- !(datafellows & SSH_BUG_DYNAMIC_RPORT))
+ !(ssh->compat & SSH_BUG_DYNAMIC_RPORT))
c->listening_port = *allocated_listen_port;
else
c->listening_port = fwd->listen_port;
success = 1;
}
if (success == 0)
- error("%s: cannot listen to port: %d", __func__,
- fwd->listen_port);
+ error_f("cannot listen to port: %d", fwd->listen_port);
freeaddrinfo(aitop);
return success;
}
@@ -3543,7 +3525,7 @@ channel_setup_fwd_listener_streamlocal(struct ssh *ssh, int type,
port = PORT_STREAMLOCAL;
break;
default:
- error("%s: unexpected channel type %d", __func__, type);
+ error_f("unexpected channel type %d", type);
return 0;
}
@@ -3556,7 +3538,7 @@ channel_setup_fwd_listener_streamlocal(struct ssh *ssh, int type,
return 0;
}
- debug3("%s: type %d path %s", __func__, type, fwd->listen_path);
+ debug3_f("type %d path %s", type, fwd->listen_path);
/* Start a Unix domain listener. */
omask = umask(fwd_opts->streamlocal_bind_mask);
@@ -3591,7 +3573,7 @@ channel_cancel_rport_listener_tcpip(struct ssh *ssh,
if (c == NULL || c->type != SSH_CHANNEL_RPORT_LISTENER)
continue;
if (strcmp(c->path, host) == 0 && c->listening_port == port) {
- debug2("%s: close channel %d", __func__, i);
+ debug2_f("close channel %d", i);
channel_free(ssh, c);
found = 1;
}
@@ -3613,7 +3595,7 @@ channel_cancel_rport_listener_streamlocal(struct ssh *ssh, const char *path)
if (c->path == NULL)
continue;
if (strcmp(c->path, path) == 0) {
- debug2("%s: close channel %d", __func__, i);
+ debug2_f("close channel %d", i);
channel_free(ssh, c);
found = 1;
}
@@ -3641,7 +3623,7 @@ channel_cancel_lport_listener_tcpip(struct ssh *ssh,
{
u_int i;
int found = 0;
- const char *addr = channel_fwd_bind_addr(lhost, NULL, 1, fwd_opts);
+ const char *addr = channel_fwd_bind_addr(ssh, lhost, NULL, 1, fwd_opts);
for (i = 0; i < ssh->chanctxt->channels_alloc; i++) {
Channel *c = ssh->chanctxt->channels[i];
@@ -3661,7 +3643,7 @@ channel_cancel_lport_listener_tcpip(struct ssh *ssh,
(c->listening_addr != NULL && addr == NULL))
continue;
if (addr == NULL || strcmp(c->listening_addr, addr) == 0) {
- debug2("%s: close channel %d", __func__, i);
+ debug2_f("close channel %d", i);
channel_free(ssh, c);
found = 1;
}
@@ -3677,7 +3659,7 @@ channel_cancel_lport_listener_streamlocal(struct ssh *ssh, const char *path)
int found = 0;
if (path == NULL) {
- error("%s: no path specified.", __func__);
+ error_f("no path specified.");
return 0;
}
@@ -3688,7 +3670,7 @@ channel_cancel_lport_listener_streamlocal(struct ssh *ssh, const char *path)
if (c->listening_addr == NULL)
continue;
if (strcmp(c->listening_addr, path) == 0) {
- debug2("%s: close channel %d", __func__, i);
+ debug2_f("close channel %d", i);
channel_free(ssh, c);
found = 1;
}
@@ -3793,7 +3775,24 @@ channel_setup_remote_fwd_listener(struct ssh *ssh, struct Forward *fwd,
int *allocated_listen_port, struct ForwardOptions *fwd_opts)
{
if (!check_rfwd_permission(ssh, fwd)) {
- packet_send_debug("port forwarding refused");
+ ssh_packet_send_debug(ssh, "port forwarding refused");
+ if (fwd->listen_path != NULL)
+ /* XXX always allowed, see remote_open_match() */
+ logit("Received request from %.100s port %d to "
+ "remote forward to path \"%.100s\", "
+ "but the request was denied.",
+ ssh_remote_ipaddr(ssh), ssh_remote_port(ssh),
+ fwd->listen_path);
+ else if(fwd->listen_host != NULL)
+ logit("Received request from %.100s port %d to "
+ "remote forward to host %.100s port %d, "
+ "but the request was denied.",
+ ssh_remote_ipaddr(ssh), ssh_remote_port(ssh),
+ fwd->listen_host, fwd->listen_port );
+ else
+ logit("Received request from %.100s port %d to remote "
+ "forward, but the request was denied.",
+ ssh_remote_ipaddr(ssh), ssh_remote_port(ssh));
return 0;
}
if (fwd->listen_path != NULL) {
@@ -3843,8 +3842,7 @@ channel_request_remote_forwarding(struct ssh *ssh, struct Forward *fwd)
(r = sshpkt_put_cstring(ssh, fwd->listen_path)) != 0 ||
(r = sshpkt_send(ssh)) != 0 ||
(r = ssh_packet_write_wait(ssh)) != 0)
- fatal("%s: request streamlocal: %s",
- __func__, ssh_err(r));
+ fatal_fr(r, "request streamlocal");
} else {
if ((r = sshpkt_start(ssh, SSH2_MSG_GLOBAL_REQUEST)) != 0 ||
(r = sshpkt_put_cstring(ssh, "tcpip-forward")) != 0 ||
@@ -3854,8 +3852,7 @@ channel_request_remote_forwarding(struct ssh *ssh, struct Forward *fwd)
(r = sshpkt_put_u32(ssh, fwd->listen_port)) != 0 ||
(r = sshpkt_send(ssh)) != 0 ||
(r = ssh_packet_write_wait(ssh)) != 0)
- fatal("%s: request tcpip-forward: %s",
- __func__, ssh_err(r));
+ fatal_fr(r, "request tcpip-forward");
}
/* Assume that server accepts the request */
success = 1;
@@ -3954,7 +3951,7 @@ channel_request_rforward_cancel_tcpip(struct ssh *ssh,
struct permission_set *pset = &sc->local_perms;
int r;
u_int i;
- struct permission *perm;
+ struct permission *perm = NULL;
for (i = 0; i < pset->num_permitted_user; i++) {
perm = &pset->permitted_user[i];
@@ -3963,7 +3960,7 @@ channel_request_rforward_cancel_tcpip(struct ssh *ssh,
perm = NULL;
}
if (perm == NULL) {
- debug("%s: requested forward not found", __func__);
+ debug_f("requested forward not found");
return -1;
}
if ((r = sshpkt_start(ssh, SSH2_MSG_GLOBAL_REQUEST)) != 0 ||
@@ -3972,7 +3969,7 @@ channel_request_rforward_cancel_tcpip(struct ssh *ssh,
(r = sshpkt_put_cstring(ssh, channel_rfwd_bind_host(host))) != 0 ||
(r = sshpkt_put_u32(ssh, port)) != 0 ||
(r = sshpkt_send(ssh)) != 0)
- fatal("%s: send cancel: %s", __func__, ssh_err(r));
+ fatal_fr(r, "send cancel");
fwd_perm_clear(perm); /* unregister */
@@ -3990,7 +3987,7 @@ channel_request_rforward_cancel_streamlocal(struct ssh *ssh, const char *path)
struct permission_set *pset = &sc->local_perms;
int r;
u_int i;
- struct permission *perm;
+ struct permission *perm = NULL;
for (i = 0; i < pset->num_permitted_user; i++) {
perm = &pset->permitted_user[i];
@@ -3999,7 +3996,7 @@ channel_request_rforward_cancel_streamlocal(struct ssh *ssh, const char *path)
perm = NULL;
}
if (perm == NULL) {
- debug("%s: requested forward not found", __func__);
+ debug_f("requested forward not found");
return -1;
}
if ((r = sshpkt_start(ssh, SSH2_MSG_GLOBAL_REQUEST)) != 0 ||
@@ -4008,13 +4005,13 @@ channel_request_rforward_cancel_streamlocal(struct ssh *ssh, const char *path)
(r = sshpkt_put_u8(ssh, 0)) != 0 || /* want reply */
(r = sshpkt_put_cstring(ssh, path)) != 0 ||
(r = sshpkt_send(ssh)) != 0)
- fatal("%s: send cancel: %s", __func__, ssh_err(r));
+ fatal_fr(r, "send cancel");
fwd_perm_clear(perm); /* unregister */
return 0;
}
-
+
/*
* Request cancellation of remote forwarding of a connection from local side.
*/
@@ -4103,8 +4100,8 @@ channel_update_permission(struct ssh *ssh, int idx, int newport)
struct permission_set *pset = &ssh->chanctxt->local_perms;
if (idx < 0 || (u_int)idx >= pset->num_permitted_user) {
- debug("%s: index out of range: %d num_permitted_user %d",
- __func__, idx, pset->num_permitted_user);
+ debug_f("index out of range: %d num_permitted_user %d",
+ idx, pset->num_permitted_user);
return;
}
debug("%s allowed port %d for forwarding to host %s port %d",
@@ -4116,7 +4113,7 @@ channel_update_permission(struct ssh *ssh, int idx, int newport)
fwd_perm_clear(&pset->permitted_user[idx]);
else {
pset->permitted_user[idx].listen_port =
- (datafellows & SSH_BUG_DYNAMIC_RPORT) ? 0 : newport;
+ (ssh->compat & SSH_BUG_DYNAMIC_RPORT) ? 0 : newport;
}
}
@@ -4171,7 +4168,7 @@ connect_next(struct channel_connect *cctx)
continue;
}
if (set_nonblock(sock) == -1)
- fatal("%s: set_nonblock(%d)", __func__, sock);
+ fatal_f("set_nonblock(%d)", sock);
if (connect(sock, cctx->ai->ai_addr,
cctx->ai->ai_addrlen) == -1 && errno != EINPROGRESS) {
debug("connect_next: host %.100s ([%.100s]:%s): "
@@ -4389,8 +4386,9 @@ channel_connect_to_port(struct ssh *ssh, const char *host, u_short port,
}
if (!permit || !permit_adm) {
- logit("Received request to connect to host %.100s port %d, "
- "but the request was denied.", host, port);
+ logit("Received request from %.100s port %d to connect to "
+ "host %.100s port %d, but the request was denied.",
+ ssh_remote_ipaddr(ssh), ssh_remote_port(ssh), host, port);
if (reason != NULL)
*reason = SSH2_OPEN_ADMINISTRATIVELY_PROHIBITED;
return NULL;
@@ -4465,7 +4463,7 @@ channel_send_window_changes(struct ssh *ssh)
if (sc->channels[i] == NULL || !sc->channels[i]->client_tty ||
sc->channels[i]->type != SSH_CHANNEL_OPEN)
continue;
- if (ioctl(sc->channels[i]->rfd, TIOCGWINSZ, &ws) < 0)
+ if (ioctl(sc->channels[i]->rfd, TIOCGWINSZ, &ws) == -1)
continue;
channel_request_start(ssh, i, "window-change", 0);
if ((r = sshpkt_put_u32(ssh, (u_int)ws.ws_col)) != 0 ||
@@ -4473,8 +4471,7 @@ channel_send_window_changes(struct ssh *ssh)
(r = sshpkt_put_u32(ssh, (u_int)ws.ws_xpixel)) != 0 ||
(r = sshpkt_put_u32(ssh, (u_int)ws.ws_ypixel)) != 0 ||
(r = sshpkt_send(ssh)) != 0)
- fatal("%s: channel %u: send window-change: %s",
- __func__, i, ssh_err(r));
+ fatal_fr(r, "channel %u; send window-change", i);
}
}
@@ -4498,10 +4495,8 @@ rdynamic_connect_prepare(struct ssh *ssh, char *ctype, char *rname)
(r = sshpkt_put_u32(ssh, c->remote_id)) != 0 ||
(r = sshpkt_put_u32(ssh, c->self)) != 0 ||
(r = sshpkt_put_u32(ssh, c->local_window)) != 0 ||
- (r = sshpkt_put_u32(ssh, c->local_maxpacket)) != 0) {
- fatal("%s: channel %i: confirm: %s", __func__,
- c->self, ssh_err(r));
- }
+ (r = sshpkt_put_u32(ssh, c->local_maxpacket)) != 0)
+ fatal_fr(r, "channel %i; confirm", c->self);
return c;
}
@@ -4509,9 +4504,28 @@ rdynamic_connect_prepare(struct ssh *ssh, char *ctype, char *rname)
static int
rdynamic_connect_finish(struct ssh *ssh, Channel *c)
{
+ struct ssh_channels *sc = ssh->chanctxt;
+ struct permission_set *pset = &sc->local_perms;
+ struct permission *perm;
struct channel_connect cctx;
+ u_int i, permit_adm = 1;
int sock;
+ if (pset->num_permitted_admin > 0) {
+ permit_adm = 0;
+ for (i = 0; i < pset->num_permitted_admin; i++) {
+ perm = &pset->permitted_admin[i];
+ if (open_match(perm, c->path, c->host_port)) {
+ permit_adm = 1;
+ break;
+ }
+ }
+ }
+ if (!permit_adm) {
+ debug_f("requested forward not permitted");
+ return -1;
+ }
+
memset(&cctx, 0, sizeof(cctx));
sock = connect_to_helper(ssh, c->path, c->host_port, SOCK_STREAM, NULL,
NULL, &cctx, NULL, NULL);
@@ -4568,7 +4582,7 @@ x11_create_display_inet(struct ssh *ssh, int x11_display_offset,
continue;
sock = socket(ai->ai_family, ai->ai_socktype,
ai->ai_protocol);
- if (sock < 0) {
+ if (sock == -1) {
if ((errno != EINVAL) && (errno != EAFNOSUPPORT)
#ifdef EPFNOSUPPORT
&& (errno != EPFNOSUPPORT)
@@ -4587,9 +4601,9 @@ x11_create_display_inet(struct ssh *ssh, int x11_display_offset,
sock_set_v6only(sock);
if (x11_use_localhost)
set_reuseaddr(sock);
- if (bind(sock, ai->ai_addr, ai->ai_addrlen) < 0) {
- debug2("%s: bind port %d: %.100s", __func__,
- port, strerror(errno));
+ if (bind(sock, ai->ai_addr, ai->ai_addrlen) == -1) {
+ debug2_f("bind port %d: %.100s", port,
+ strerror(errno));
close(sock);
for (n = 0; n < num_socks; n++)
close(socks[n]);
@@ -4611,7 +4625,7 @@ x11_create_display_inet(struct ssh *ssh, int x11_display_offset,
/* Start listening for connections on the socket. */
for (n = 0; n < num_socks; n++) {
sock = socks[n];
- if (listen(sock, SSH_LISTEN_BACKLOG) < 0) {
+ if (listen(sock, SSH_LISTEN_BACKLOG) == -1) {
error("listen: %.100s", strerror(errno));
close(sock);
return -1;
@@ -4643,7 +4657,7 @@ connect_local_xsocket_path(const char *pathname)
struct sockaddr_un addr;
sock = socket(AF_UNIX, SOCK_STREAM, 0);
- if (sock < 0)
+ if (sock == -1)
error("socket: %.100s", strerror(errno));
memset(&addr, 0, sizeof(addr));
addr.sun_family = AF_UNIX;
@@ -4784,12 +4798,12 @@ x11_connect_display(struct ssh *ssh)
for (ai = aitop; ai; ai = ai->ai_next) {
/* Create a socket. */
sock = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
- if (sock < 0) {
+ if (sock == -1) {
debug2("socket: %.100s", strerror(errno));
continue;
}
/* Connect it to the display. */
- if (connect(sock, ai->ai_addr, ai->ai_addrlen) < 0) {
+ if (connect(sock, ai->ai_addr, ai->ai_addrlen) == -1) {
debug2("connect %.100s port %u: %.100s", buf,
6000 + display_number, strerror(errno));
close(sock);
@@ -4847,9 +4861,10 @@ x11_request_forwarding_with_spoofing(struct ssh *ssh, int client_session_id,
/* Extract real authentication data. */
sc->x11_saved_data = xmalloc(data_len);
for (i = 0; i < data_len; i++) {
- if (sscanf(data + 2 * i, "%2x", &value) != 1)
+ if (sscanf(data + 2 * i, "%2x", &value) != 1) {
fatal("x11_request_forwarding: bad "
"authentication data: %.100s", data);
+ }
sc->x11_saved_data[i] = value;
}
sc->x11_saved_data_len = data_len;
@@ -4871,6 +4886,6 @@ x11_request_forwarding_with_spoofing(struct ssh *ssh, int client_session_id,
(r = sshpkt_put_u32(ssh, screen_number)) != 0 ||
(r = sshpkt_send(ssh)) != 0 ||
(r = ssh_packet_write_wait(ssh)) != 0)
- fatal("%s: send x11-req: %s", __func__, ssh_err(r));
+ fatal_fr(r, "send x11-req");
free(new_data);
}
diff --git a/crypto/openssh/channels.h b/crypto/openssh/channels.h
index aa2a87c10edf..6bf86b003e53 100644
--- a/crypto/openssh/channels.h
+++ b/crypto/openssh/channels.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: channels.h,v 1.132 2018/10/04 00:10:11 djm Exp $ */
+/* $OpenBSD: channels.h,v 1.138 2021/05/19 01:24:05 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -52,17 +52,27 @@
#define SSH_CHANNEL_DYNAMIC 13
#define SSH_CHANNEL_ZOMBIE 14 /* Almost dead. */
#define SSH_CHANNEL_MUX_LISTENER 15 /* Listener for mux conn. */
-#define SSH_CHANNEL_MUX_CLIENT 16 /* Conn. to mux slave */
+#define SSH_CHANNEL_MUX_CLIENT 16 /* Conn. to mux client */
#define SSH_CHANNEL_ABANDONED 17 /* Abandoned session, eg mux */
#define SSH_CHANNEL_UNIX_LISTENER 18 /* Listening on a domain socket. */
#define SSH_CHANNEL_RUNIX_LISTENER 19 /* Listening to a R-style domain socket. */
-#define SSH_CHANNEL_MUX_PROXY 20 /* proxy channel for mux-slave */
+#define SSH_CHANNEL_MUX_PROXY 20 /* proxy channel for mux-client */
#define SSH_CHANNEL_RDYNAMIC_OPEN 21 /* reverse SOCKS, parsing request */
#define SSH_CHANNEL_RDYNAMIC_FINISH 22 /* reverse SOCKS, finishing connect */
#define SSH_CHANNEL_MAX_TYPE 23
#define CHANNEL_CANCEL_PORT_STATIC -1
+/* nonblocking flags for channel_new */
+#define CHANNEL_NONBLOCK_LEAVE 0 /* don't modify non-blocking state */
+#define CHANNEL_NONBLOCK_SET 1 /* set non-blocking state */
+#define CHANNEL_NONBLOCK_STDIO 2 /* set non-blocking and restore on close */
+
+/* c->restore_block mask flags */
+#define CHANNEL_RESTORE_RFD 0x01
+#define CHANNEL_RESTORE_WFD 0x02
+#define CHANNEL_RESTORE_EFD 0x04
+
/* TCP forwarding */
#define FORWARD_DENY 0
#define FORWARD_REMOTE (1)
@@ -105,8 +115,16 @@ struct channel_connect {
/* Callbacks for mux channels back into client-specific code */
typedef int mux_callback_fn(struct ssh *, struct Channel *);
+/*
+ * NB. channel IDs on the wire and in c->remote_id are uint32, but local
+ * channel IDs (e.g. c->self) only ever use the int32 subset of this range,
+ * because we use local channel ID -1 for housekeeping. Remote channels have
+ * a dedicated "have_remote_id" flag to indicate their validity.
+ */
+
struct Channel {
int type; /* channel type/state */
+
int self; /* my own channel identifier */
uint32_t remote_id; /* channel identifier for remote peer */
int have_remote_id; /* non-zero if remote_id is valid */
@@ -131,6 +149,7 @@ struct Channel {
* to a matching pre-select handler.
* this way post-select handlers are not
* accidentally called if a FD gets reused */
+ int restore_block; /* fd mask to restore blocking status */
struct sshbuf *input; /* data read from socket, to be sent over
* encrypted connection */
struct sshbuf *output; /* data received over encrypted connection for
@@ -169,7 +188,7 @@ struct Channel {
channel_filter_cleanup_fn *filter_cleanup;
/* keep boundaries */
- int datagram;
+ int datagram;
/* non-blocking connect */
/* XXX make this a pointer so the structure can be opaque */
@@ -179,7 +198,7 @@ struct Channel {
mux_callback_fn *mux_rcb;
void *mux_ctx;
int mux_pause;
- int mux_downstream_id;
+ int mux_downstream_id;
};
#define CHAN_EXTENDED_IGNORE 0
@@ -215,6 +234,9 @@ struct Channel {
/* Read buffer size */
#define CHAN_RBUF (16*1024)
+/* Maximum channel input buffer size */
+#define CHAN_INPUT_MAX (16*1024*1024)
+
/* Hard limit on number of channels */
#define CHANNELS_MAX_CHANNELS (16*1024)
@@ -255,7 +277,7 @@ void channel_register_filter(struct ssh *, int, channel_infilter_fn *,
void channel_register_status_confirm(struct ssh *, int,
channel_confirm_cb *, channel_confirm_abandon_cb *, void *);
void channel_cancel_cleanup(struct ssh *, int);
-int channel_close_fd(struct ssh *, int *);
+int channel_close_fd(struct ssh *, Channel *, int *);
void channel_send_window_changes(struct ssh *);
/* mux proxy support */
@@ -278,7 +300,7 @@ int channel_input_status_confirm(int, u_int32_t, struct ssh *);
/* file descriptor handling (read/write) */
void channel_prepare_select(struct ssh *, fd_set **, fd_set **, int *,
- u_int*, time_t*);
+ u_int*, time_t*);
void channel_after_select(struct ssh *, fd_set *, fd_set *);
void channel_output_poll(struct ssh *);
@@ -302,7 +324,7 @@ Channel *channel_connect_to_port(struct ssh *, const char *, u_short,
char *, char *, int *, const char **);
Channel *channel_connect_to_path(struct ssh *, const char *, char *, char *);
Channel *channel_connect_stdio_fwd(struct ssh *, const char*,
- u_short, int, int);
+ u_short, int, int, int);
Channel *channel_connect_by_listen_address(struct ssh *, const char *,
u_short, char *, char *);
Channel *channel_connect_by_listen_path(struct ssh *, const char *,
diff --git a/crypto/openssh/cipher-chachapoly-libcrypto.c b/crypto/openssh/cipher-chachapoly-libcrypto.c
new file mode 100644
index 000000000000..719f9c843d63
--- /dev/null
+++ b/crypto/openssh/cipher-chachapoly-libcrypto.c
@@ -0,0 +1,166 @@
+/*
+ * Copyright (c) 2013 Damien Miller <djm@mindrot.org>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $OpenBSD: cipher-chachapoly-libcrypto.c,v 1.1 2020/04/03 04:32:21 djm Exp $ */
+
+#include "includes.h"
+#ifdef WITH_OPENSSL
+#include "openbsd-compat/openssl-compat.h"
+#endif
+
+#if defined(HAVE_EVP_CHACHA20) && !defined(HAVE_BROKEN_CHACHA20)
+
+#include <sys/types.h>
+#include <stdarg.h> /* needed for log.h */
+#include <string.h>
+#include <stdio.h> /* needed for misc.h */
+
+#include <openssl/evp.h>
+
+#include "log.h"
+#include "sshbuf.h"
+#include "ssherr.h"
+#include "cipher-chachapoly.h"
+
+struct chachapoly_ctx {
+ EVP_CIPHER_CTX *main_evp, *header_evp;
+};
+
+struct chachapoly_ctx *
+chachapoly_new(const u_char *key, u_int keylen)
+{
+ struct chachapoly_ctx *ctx;
+
+ if (keylen != (32 + 32)) /* 2 x 256 bit keys */
+ return NULL;
+ if ((ctx = calloc(1, sizeof(*ctx))) == NULL)
+ return NULL;
+ if ((ctx->main_evp = EVP_CIPHER_CTX_new()) == NULL ||
+ (ctx->header_evp = EVP_CIPHER_CTX_new()) == NULL)
+ goto fail;
+ if (!EVP_CipherInit(ctx->main_evp, EVP_chacha20(), key, NULL, 1))
+ goto fail;
+ if (!EVP_CipherInit(ctx->header_evp, EVP_chacha20(), key + 32, NULL, 1))
+ goto fail;
+ if (EVP_CIPHER_CTX_iv_length(ctx->header_evp) != 16)
+ goto fail;
+ return ctx;
+ fail:
+ chachapoly_free(ctx);
+ return NULL;
+}
+
+void
+chachapoly_free(struct chachapoly_ctx *cpctx)
+{
+ if (cpctx == NULL)
+ return;
+ EVP_CIPHER_CTX_free(cpctx->main_evp);
+ EVP_CIPHER_CTX_free(cpctx->header_evp);
+ freezero(cpctx, sizeof(*cpctx));
+}
+
+/*
+ * chachapoly_crypt() operates as following:
+ * En/decrypt with header key 'aadlen' bytes from 'src', storing result
+ * to 'dest'. The ciphertext here is treated as additional authenticated
+ * data for MAC calculation.
+ * En/decrypt 'len' bytes at offset 'aadlen' from 'src' to 'dest'. Use
+ * POLY1305_TAGLEN bytes at offset 'len'+'aadlen' as the authentication
+ * tag. This tag is written on encryption and verified on decryption.
+ */
+int
+chachapoly_crypt(struct chachapoly_ctx *ctx, u_int seqnr, u_char *dest,
+ const u_char *src, u_int len, u_int aadlen, u_int authlen, int do_encrypt)
+{
+ u_char seqbuf[16]; /* layout: u64 counter || u64 seqno */
+ int r = SSH_ERR_INTERNAL_ERROR;
+ u_char expected_tag[POLY1305_TAGLEN], poly_key[POLY1305_KEYLEN];
+
+ /*
+ * Run ChaCha20 once to generate the Poly1305 key. The IV is the
+ * packet sequence number.
+ */
+ memset(seqbuf, 0, sizeof(seqbuf));
+ POKE_U64(seqbuf + 8, seqnr);
+ memset(poly_key, 0, sizeof(poly_key));
+ if (!EVP_CipherInit(ctx->main_evp, NULL, NULL, seqbuf, 1) ||
+ EVP_Cipher(ctx->main_evp, poly_key,
+ poly_key, sizeof(poly_key)) < 0) {
+ r = SSH_ERR_LIBCRYPTO_ERROR;
+ goto out;
+ }
+
+ /* If decrypting, check tag before anything else */
+ if (!do_encrypt) {
+ const u_char *tag = src + aadlen + len;
+
+ poly1305_auth(expected_tag, src, aadlen + len, poly_key);
+ if (timingsafe_bcmp(expected_tag, tag, POLY1305_TAGLEN) != 0) {
+ r = SSH_ERR_MAC_INVALID;
+ goto out;
+ }
+ }
+
+ /* Crypt additional data */
+ if (aadlen) {
+ if (!EVP_CipherInit(ctx->header_evp, NULL, NULL, seqbuf, 1) ||
+ EVP_Cipher(ctx->header_evp, dest, src, aadlen) < 0) {
+ r = SSH_ERR_LIBCRYPTO_ERROR;
+ goto out;
+ }
+ }
+
+ /* Set Chacha's block counter to 1 */
+ seqbuf[0] = 1;
+ if (!EVP_CipherInit(ctx->main_evp, NULL, NULL, seqbuf, 1) ||
+ EVP_Cipher(ctx->main_evp, dest + aadlen, src + aadlen, len) < 0) {
+ r = SSH_ERR_LIBCRYPTO_ERROR;
+ goto out;
+ }
+
+ /* If encrypting, calculate and append tag */
+ if (do_encrypt) {
+ poly1305_auth(dest + aadlen + len, dest, aadlen + len,
+ poly_key);
+ }
+ r = 0;
+ out:
+ explicit_bzero(expected_tag, sizeof(expected_tag));
+ explicit_bzero(seqbuf, sizeof(seqbuf));
+ explicit_bzero(poly_key, sizeof(poly_key));
+ return r;
+}
+
+/* Decrypt and extract the encrypted packet length */
+int
+chachapoly_get_length(struct chachapoly_ctx *ctx,
+ u_int *plenp, u_int seqnr, const u_char *cp, u_int len)
+{
+ u_char buf[4], seqbuf[16];
+
+ if (len < 4)
+ return SSH_ERR_MESSAGE_INCOMPLETE;
+ memset(seqbuf, 0, sizeof(seqbuf));
+ POKE_U64(seqbuf + 8, seqnr);
+ if (!EVP_CipherInit(ctx->header_evp, NULL, NULL, seqbuf, 0))
+ return SSH_ERR_LIBCRYPTO_ERROR;
+ if (EVP_Cipher(ctx->header_evp, buf, (u_char *)cp, sizeof(buf)) < 0)
+ return SSH_ERR_LIBCRYPTO_ERROR;
+ *plenp = PEEK_U32(buf);
+ return 0;
+}
+#endif /* defined(HAVE_EVP_CHACHA20) && !defined(HAVE_BROKEN_CHACHA20) */
diff --git a/crypto/openssh/cipher-chachapoly.c b/crypto/openssh/cipher-chachapoly.c
index 0899c5ad5b79..716f8d426a06 100644
--- a/crypto/openssh/cipher-chachapoly.c
+++ b/crypto/openssh/cipher-chachapoly.c
@@ -14,9 +14,14 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-/* $OpenBSD: cipher-chachapoly.c,v 1.8 2016/08/03 05:41:57 djm Exp $ */
+/* $OpenBSD: cipher-chachapoly.c,v 1.9 2020/04/03 04:27:03 djm Exp $ */
#include "includes.h"
+#ifdef WITH_OPENSSL
+#include "openbsd-compat/openssl-compat.h"
+#endif
+
+#if !defined(HAVE_EVP_CHACHA20) || defined(HAVE_BROKEN_CHACHA20)
#include <sys/types.h>
#include <stdarg.h> /* needed for log.h */
@@ -28,15 +33,28 @@
#include "ssherr.h"
#include "cipher-chachapoly.h"
-int
-chachapoly_init(struct chachapoly_ctx *ctx,
- const u_char *key, u_int keylen)
+struct chachapoly_ctx {
+ struct chacha_ctx main_ctx, header_ctx;
+};
+
+struct chachapoly_ctx *
+chachapoly_new(const u_char *key, u_int keylen)
{
+ struct chachapoly_ctx *ctx;
+
if (keylen != (32 + 32)) /* 2 x 256 bit keys */
- return SSH_ERR_INVALID_ARGUMENT;
+ return NULL;
+ if ((ctx = calloc(1, sizeof(*ctx))) == NULL)
+ return NULL;
chacha_keysetup(&ctx->main_ctx, key, 256);
chacha_keysetup(&ctx->header_ctx, key + 32, 256);
- return 0;
+ return ctx;
+}
+
+void
+chachapoly_free(struct chachapoly_ctx *cpctx)
+{
+ freezero(cpctx, sizeof(*cpctx));
}
/*
@@ -117,3 +135,5 @@ chachapoly_get_length(struct chachapoly_ctx *ctx,
*plenp = PEEK_U32(buf);
return 0;
}
+
+#endif /* !defined(HAVE_EVP_CHACHA20) || defined(HAVE_BROKEN_CHACHA20) */
diff --git a/crypto/openssh/cipher-chachapoly.h b/crypto/openssh/cipher-chachapoly.h
index b7072be7d9d6..026d2de93a3a 100644
--- a/crypto/openssh/cipher-chachapoly.h
+++ b/crypto/openssh/cipher-chachapoly.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: cipher-chachapoly.h,v 1.4 2014/06/24 01:13:21 djm Exp $ */
+/* $OpenBSD: cipher-chachapoly.h,v 1.5 2020/04/03 04:27:03 djm Exp $ */
/*
* Copyright (c) Damien Miller 2013 <djm@mindrot.org>
@@ -24,13 +24,12 @@
#define CHACHA_KEYLEN 32 /* Only 256 bit keys used here */
-struct chachapoly_ctx {
- struct chacha_ctx main_ctx, header_ctx;
-};
+struct chachapoly_ctx;
+
+struct chachapoly_ctx *chachapoly_new(const u_char *key, u_int keylen)
+ __attribute__((__bounded__(__buffer__, 1, 2)));
+void chachapoly_free(struct chachapoly_ctx *cpctx);
-int chachapoly_init(struct chachapoly_ctx *cpctx,
- const u_char *key, u_int keylen)
- __attribute__((__bounded__(__buffer__, 2, 3)));
int chachapoly_crypt(struct chachapoly_ctx *cpctx, u_int seqnr,
u_char *dest, const u_char *src, u_int len, u_int aadlen, u_int authlen,
int do_encrypt);
diff --git a/crypto/openssh/cipher.c b/crypto/openssh/cipher.c
index 12c5988816cf..5b3a86d69219 100644
--- a/crypto/openssh/cipher.c
+++ b/crypto/openssh/cipher.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: cipher.c,v 1.111 2018/02/23 15:58:37 markus Exp $ */
+/* $OpenBSD: cipher.c,v 1.119 2021/04/03 06:18:40 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -51,12 +51,15 @@
#include "openbsd-compat/openssl-compat.h"
+#ifndef WITH_OPENSSL
+#define EVP_CIPHER_CTX void
+#endif
struct sshcipher_ctx {
int plaintext;
int encrypt;
EVP_CIPHER_CTX *evp;
- struct chachapoly_ctx cp_ctx; /* XXX union with evp? */
+ struct chachapoly_ctx *cp_ctx;
struct aesctr_ctx ac_ctx; /* XXX union with evp? */
const struct sshcipher *cipher;
};
@@ -88,8 +91,6 @@ static const struct sshcipher ciphers[] = {
{ "aes128-cbc", 16, 16, 0, 0, CFLAG_CBC, EVP_aes_128_cbc },
{ "aes192-cbc", 16, 24, 0, 0, CFLAG_CBC, EVP_aes_192_cbc },
{ "aes256-cbc", 16, 32, 0, 0, CFLAG_CBC, EVP_aes_256_cbc },
- { "rijndael-cbc@lysator.liu.se",
- 16, 32, 0, 0, CFLAG_CBC, EVP_aes_256_cbc },
{ "aes128-ctr", 16, 16, 0, 0, 0, EVP_aes_128_ctr },
{ "aes192-ctr", 16, 24, 0, 0, 0, EVP_aes_192_ctr },
{ "aes256-ctr", 16, 32, 0, 0, 0, EVP_aes_256_ctr },
@@ -140,6 +141,17 @@ cipher_alg_list(char sep, int auth_only)
return ret;
}
+const char *
+compression_alg_list(int compression)
+{
+#ifdef WITH_ZLIB
+ return compression ? "zlib@openssh.com,zlib,none" :
+ "none,zlib@openssh.com,zlib";
+#else
+ return "none";
+#endif
+}
+
u_int
cipher_blocksize(const struct sshcipher *c)
{
@@ -259,7 +271,8 @@ cipher_init(struct sshcipher_ctx **ccp, const struct sshcipher *cipher,
cc->cipher = cipher;
if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0) {
- ret = chachapoly_init(&cc->cp_ctx, key, keylen);
+ cc->cp_ctx = chachapoly_new(key, keylen);
+ ret = cc->cp_ctx != NULL ? 0 : SSH_ERR_INVALID_ARGUMENT;
goto out;
}
if ((cc->cipher->flags & CFLAG_NONE) != 0) {
@@ -314,8 +327,7 @@ cipher_init(struct sshcipher_ctx **ccp, const struct sshcipher *cipher,
#ifdef WITH_OPENSSL
EVP_CIPHER_CTX_free(cc->evp);
#endif /* WITH_OPENSSL */
- explicit_bzero(cc, sizeof(*cc));
- free(cc);
+ freezero(cc, sizeof(*cc));
}
}
return ret;
@@ -324,7 +336,7 @@ cipher_init(struct sshcipher_ctx **ccp, const struct sshcipher *cipher,
/*
* cipher_crypt() operates as following:
* Copy 'aadlen' bytes (without en/decryption) from 'src' to 'dest'.
- * Theses bytes are treated as additional authenticated data for
+ * These bytes are treated as additional authenticated data for
* authenticated encryption modes.
* En/Decrypt 'len' bytes at offset 'aadlen' from 'src' to 'dest'.
* Use 'authlen' bytes at offset 'len'+'aadlen' as the authentication tag.
@@ -336,7 +348,7 @@ cipher_crypt(struct sshcipher_ctx *cc, u_int seqnr, u_char *dest,
const u_char *src, u_int len, u_int aadlen, u_int authlen)
{
if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0) {
- return chachapoly_crypt(&cc->cp_ctx, seqnr, dest, src,
+ return chachapoly_crypt(cc->cp_ctx, seqnr, dest, src,
len, aadlen, authlen, cc->encrypt);
}
if ((cc->cipher->flags & CFLAG_NONE) != 0) {
@@ -399,7 +411,7 @@ cipher_get_length(struct sshcipher_ctx *cc, u_int *plenp, u_int seqnr,
const u_char *cp, u_int len)
{
if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0)
- return chachapoly_get_length(&cc->cp_ctx, plenp, seqnr,
+ return chachapoly_get_length(cc->cp_ctx, plenp, seqnr,
cp, len);
if (len < 4)
return SSH_ERR_MESSAGE_INCOMPLETE;
@@ -412,16 +424,16 @@ cipher_free(struct sshcipher_ctx *cc)
{
if (cc == NULL)
return;
- if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0)
- explicit_bzero(&cc->cp_ctx, sizeof(cc->cp_ctx));
- else if ((cc->cipher->flags & CFLAG_AESCTR) != 0)
+ if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0) {
+ chachapoly_free(cc->cp_ctx);
+ cc->cp_ctx = NULL;
+ } else if ((cc->cipher->flags & CFLAG_AESCTR) != 0)
explicit_bzero(&cc->ac_ctx, sizeof(cc->ac_ctx));
#ifdef WITH_OPENSSL
EVP_CIPHER_CTX_free(cc->evp);
cc->evp = NULL;
#endif
- explicit_bzero(cc, sizeof(*cc));
- free(cc);
+ freezero(cc, sizeof(*cc));
}
/*
@@ -482,10 +494,10 @@ cipher_get_keyiv(struct sshcipher_ctx *cc, u_char *iv, size_t len)
#endif
if (cipher_authlen(c)) {
if (!EVP_CIPHER_CTX_ctrl(cc->evp, EVP_CTRL_GCM_IV_GEN,
- len, iv))
- return SSH_ERR_LIBCRYPTO_ERROR;
+ len, iv))
+ return SSH_ERR_LIBCRYPTO_ERROR;
} else if (!EVP_CIPHER_CTX_get_iv(cc->evp, iv, len))
- return SSH_ERR_LIBCRYPTO_ERROR;
+ return SSH_ERR_LIBCRYPTO_ERROR;
#endif
return 0;
}
diff --git a/crypto/openssh/cipher.h b/crypto/openssh/cipher.h
index dc1571d2eca9..1a591cd7fd46 100644
--- a/crypto/openssh/cipher.h
+++ b/crypto/openssh/cipher.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: cipher.h,v 1.52 2017/05/07 23:12:57 djm Exp $ */
+/* $OpenBSD: cipher.h,v 1.55 2020/01/23 10:24:29 dtucker Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -38,7 +38,9 @@
#define CIPHER_H
#include <sys/types.h>
+#ifdef WITH_OPENSSL
#include <openssl/evp.h>
+#endif
#include "cipher-chachapoly.h"
#include "cipher-aesctr.h"
@@ -52,6 +54,7 @@ const struct sshcipher *cipher_by_name(const char *);
const char *cipher_warning_message(const struct sshcipher_ctx *);
int ciphers_valid(const char *);
char *cipher_alg_list(char, int);
+const char *compression_alg_list(int);
int cipher_init(struct sshcipher_ctx **, const struct sshcipher *,
const u_char *, u_int, const u_char *, u_int, int);
int cipher_crypt(struct sshcipher_ctx *, u_int, u_char *, const u_char *,
diff --git a/crypto/openssh/clientloop.c b/crypto/openssh/clientloop.c
index 8d312cdaa755..bfcd50c263fd 100644
--- a/crypto/openssh/clientloop.c
+++ b/crypto/openssh/clientloop.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: clientloop.c,v 1.318 2018/09/21 12:46:22 djm Exp $ */
+/* $OpenBSD: clientloop.c,v 1.369 2021/07/23 04:04:52 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -77,10 +77,10 @@
#include <paths.h>
#endif
#include <signal.h>
-#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <stdarg.h>
#include <termios.h>
#include <pwd.h>
#include <unistd.h>
@@ -115,26 +115,23 @@
/* import options */
extern Options options;
-/* Flag indicating that stdin should be redirected from /dev/null. */
-extern int stdin_null_flag;
-
-/* Flag indicating that no shell has been requested */
-extern int no_shell_flag;
-
-/* Flag indicating that ssh should daemonise after authentication is complete */
-extern int fork_after_authentication_flag;
-
/* Control socket */
extern int muxserver_sock; /* XXX use mux_client_cleanup() instead */
/*
* Name of the host we are connecting to. This is the name given on the
- * command line, or the HostName specified for the user-supplied name in a
+ * command line, or the Hostname specified for the user-supplied name in a
* configuration file.
*/
extern char *host;
/*
+ * If this field is not NULL, the ForwardAgent socket is this path and different
+ * instead of SSH_AUTH_SOCK.
+ */
+extern char *forward_agent_sock_path;
+
+/*
* Flag to indicate that we have received a window change signal which has
* not yet been processed. This will cause a message indicating the new
* window size to be sent to the server a little later. This is volatile
@@ -143,9 +140,6 @@ extern char *host;
static volatile sig_atomic_t received_window_change_signal = 0;
static volatile sig_atomic_t received_signal = 0;
-/* Flag indicating whether the user's terminal is in non-blocking mode. */
-static int in_non_blocking_mode = 0;
-
/* Time when backgrounded control master using ControlPersist should exit */
static time_t control_persist_exit_time = 0;
@@ -159,8 +153,9 @@ static int connection_out; /* Connection to server (output). */
static int need_rekeying; /* Set to non-zero if rekeying is requested. */
static int session_closed; /* In SSH2: login session closed. */
static u_int x11_refuse_time; /* If >0, refuse x11 opens after this time. */
+static time_t server_alive_time; /* Time to do server_alive_check */
-static void client_init_dispatch(void);
+static void client_init_dispatch(struct ssh *ssh);
int session_ident = -1;
/* Track escape per proto2 channel */
@@ -190,17 +185,6 @@ static struct global_confirms global_confirms =
void ssh_process_session2_setup(int, int, int, struct sshbuf *);
-/* Restores stdin to blocking mode. */
-
-static void
-leave_non_blocking(void)
-{
- if (in_non_blocking_mode) {
- unset_nonblock(fileno(stdin));
- in_non_blocking_mode = 0;
- }
-}
-
/*
* Signal handler for the window change signal (SIGWINCH). This just sets a
* flag indicating that the window has changed.
@@ -240,13 +224,13 @@ set_control_persist_exit_time(struct ssh *ssh)
} else if (channel_still_open(ssh)) {
/* some client connections are still open */
if (control_persist_exit_time > 0)
- debug2("%s: cancel scheduled exit", __func__);
+ debug2_f("cancel scheduled exit");
control_persist_exit_time = 0;
} else if (control_persist_exit_time <= 0) {
/* a client connection has recently closed */
control_persist_exit_time = monotime() +
(time_t)options.control_persist_timeout;
- debug2("%s: schedule exit in %d seconds", __func__,
+ debug2_f("schedule exit in %d seconds",
options.control_persist_timeout);
}
/* else we are already counting down to the timeout */
@@ -314,7 +298,7 @@ client_x11_get_proto(struct ssh *ssh, const char *display,
if ((r = snprintf(xdisplay, sizeof(xdisplay), "unix:%s",
display + 10)) < 0 ||
(size_t)r >= sizeof(xdisplay)) {
- error("%s: display name too long", __func__);
+ error_f("display name too long");
return -1;
}
display = xdisplay;
@@ -329,16 +313,14 @@ client_x11_get_proto(struct ssh *ssh, const char *display,
*/
mktemp_proto(xauthdir, sizeof(xauthdir));
if (mkdtemp(xauthdir) == NULL) {
- error("%s: mkdtemp: %s",
- __func__, strerror(errno));
+ error_f("mkdtemp: %s", strerror(errno));
return -1;
}
do_unlink = 1;
if ((r = snprintf(xauthfile, sizeof(xauthfile),
"%s/xauthfile", xauthdir)) < 0 ||
(size_t)r >= sizeof(xauthfile)) {
- error("%s: xauthfile path too long", __func__);
- unlink(xauthfile);
+ error_f("xauthfile path too long");
rmdir(xauthdir);
return -1;
}
@@ -364,7 +346,7 @@ client_x11_get_proto(struct ssh *ssh, const char *display,
SSH_X11_PROTO, x11_timeout_real,
_PATH_DEVNULL);
}
- debug2("%s: %s", __func__, cmd);
+ debug2_f("xauth command: %s", cmd);
if (timeout != 0 && x11_refuse_time == 0) {
now = monotime() + 1;
@@ -452,11 +434,8 @@ client_check_window_change(struct ssh *ssh)
{
if (!received_window_change_signal)
return;
- /** XXX race */
received_window_change_signal = 0;
-
- debug2("%s: changed", __func__);
-
+ debug2_f("changed");
channel_send_window_changes(ssh);
}
@@ -471,27 +450,37 @@ client_global_request_reply(int type, u_int32_t seq, struct ssh *ssh)
gc->cb(ssh, type, seq, gc->ctx);
if (--gc->ref_count <= 0) {
TAILQ_REMOVE(&global_confirms, gc, entry);
- explicit_bzero(gc, sizeof(*gc));
- free(gc);
+ freezero(gc, sizeof(*gc));
}
- packet_set_alive_timeouts(0);
+ ssh_packet_set_alive_timeouts(ssh, 0);
return 0;
}
static void
-server_alive_check(void)
+schedule_server_alive_check(void)
{
- if (packet_inc_alive_timeouts() > options.server_alive_count_max) {
+ if (options.server_alive_interval > 0)
+ server_alive_time = monotime() + options.server_alive_interval;
+}
+
+static void
+server_alive_check(struct ssh *ssh)
+{
+ int r;
+
+ if (ssh_packet_inc_alive_timeouts(ssh) > options.server_alive_count_max) {
logit("Timeout, server %s not responding.", host);
cleanup_exit(255);
}
- packet_start(SSH2_MSG_GLOBAL_REQUEST);
- packet_put_cstring("keepalive@openssh.com");
- packet_put_char(1); /* boolean: want reply */
- packet_send();
+ if ((r = sshpkt_start(ssh, SSH2_MSG_GLOBAL_REQUEST)) != 0 ||
+ (r = sshpkt_put_cstring(ssh, "keepalive@openssh.com")) != 0 ||
+ (r = sshpkt_put_u8(ssh, 1)) != 0 || /* boolean: want reply */
+ (r = sshpkt_send(ssh)) != 0)
+ fatal_fr(r, "send packet");
/* Insert an empty placeholder to maintain ordering */
client_register_global_confirm(NULL, NULL);
+ schedule_server_alive_check();
}
/*
@@ -505,16 +494,16 @@ client_wait_until_can_do_something(struct ssh *ssh,
{
struct timeval tv, *tvp;
int timeout_secs;
- time_t minwait_secs = 0, server_alive_time = 0, now = monotime();
+ time_t minwait_secs = 0, now = monotime();
int r, ret;
/* Add any selections by the channel mechanism. */
- channel_prepare_select(active_state, readsetp, writesetp, maxfdp,
+ channel_prepare_select(ssh, readsetp, writesetp, maxfdp,
nallocp, &minwait_secs);
/* channel_prepare_select could have closed the last channel */
if (session_closed && !channel_still_open(ssh) &&
- !packet_have_data_to_write()) {
+ !ssh_packet_have_data_to_write(ssh)) {
/* clear mask since we did not call select() */
memset(*readsetp, 0, *nallocp);
memset(*writesetp, 0, *nallocp);
@@ -524,7 +513,7 @@ client_wait_until_can_do_something(struct ssh *ssh,
FD_SET(connection_in, *readsetp);
/* Select server connection if have data to write to the server. */
- if (packet_have_data_to_write())
+ if (ssh_packet_have_data_to_write(ssh))
FD_SET(connection_out, *writesetp);
/*
@@ -534,12 +523,11 @@ client_wait_until_can_do_something(struct ssh *ssh,
*/
timeout_secs = INT_MAX; /* we use INT_MAX to mean no timeout */
- if (options.server_alive_interval > 0) {
- timeout_secs = options.server_alive_interval;
- server_alive_time = now + options.server_alive_interval;
- }
+ if (options.server_alive_interval > 0)
+ timeout_secs = MAXIMUM(server_alive_time - now, 0);
if (options.rekey_interval > 0 && !rekeying)
- timeout_secs = MINIMUM(timeout_secs, packet_get_rekey_timeout());
+ timeout_secs = MINIMUM(timeout_secs,
+ ssh_packet_get_rekey_timeout(ssh));
set_control_persist_exit_time(ssh);
if (control_persist_exit_time > 0) {
timeout_secs = MINIMUM(timeout_secs,
@@ -558,7 +546,7 @@ client_wait_until_can_do_something(struct ssh *ssh,
}
ret = select((*maxfdp)+1, *readsetp, *writesetp, NULL, tvp);
- if (ret < 0) {
+ if (ret == -1) {
/*
* We have to clear the select masks, because we return.
* We have to return, because the mainloop checks for the flags
@@ -566,23 +554,21 @@ client_wait_until_can_do_something(struct ssh *ssh,
*/
memset(*readsetp, 0, *nallocp);
memset(*writesetp, 0, *nallocp);
-
if (errno == EINTR)
return;
/* Note: we might still have data in the buffers. */
if ((r = sshbuf_putf(stderr_buffer,
"select: %s\r\n", strerror(errno))) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "sshbuf_putf");
quit_pending = 1;
- } else if (ret == 0) {
+ } else if (options.server_alive_interval > 0 && !FD_ISSET(connection_in,
+ *readsetp) && monotime() >= server_alive_time)
/*
- * Timeout. Could have been either keepalive or rekeying.
- * Keepalive we check here, rekeying is checked in clientloop.
+ * ServerAlive check is needed. We can't rely on the select
+ * timing out since traffic on the client side such as port
+ * forwards can keep waking it up.
*/
- if (server_alive_time != 0 && server_alive_time <= monotime())
- server_alive_check();
- }
-
+ server_alive_check(ssh);
}
static void
@@ -612,7 +598,7 @@ client_suspend_self(struct sshbuf *bin, struct sshbuf *bout, struct sshbuf *berr
}
static void
-client_process_net_input(fd_set *readset)
+client_process_net_input(struct ssh *ssh, fd_set *readset)
{
char buf[SSH_IOBUFSZ];
int r, len;
@@ -622,6 +608,7 @@ client_process_net_input(fd_set *readset)
* the packet subsystem.
*/
if (FD_ISSET(connection_in, readset)) {
+ schedule_server_alive_check();
/* Read as much as possible. */
len = read(connection_in, buf, sizeof(buf));
if (len == 0) {
@@ -632,8 +619,7 @@ client_process_net_input(fd_set *readset)
if ((r = sshbuf_putf(stderr_buffer,
"Connection to %.300s closed by remote host.\r\n",
host)) != 0)
- fatal("%s: buffer error: %s",
- __func__, ssh_err(r));
+ fatal_fr(r, "sshbuf_putf");
quit_pending = 1;
return;
}
@@ -641,11 +627,11 @@ client_process_net_input(fd_set *readset)
* There is a kernel bug on Solaris that causes select to
* sometimes wake up even though there is no data available.
*/
- if (len < 0 &&
+ if (len == -1 &&
(errno == EAGAIN || errno == EINTR || errno == EWOULDBLOCK))
len = 0;
- if (len < 0) {
+ if (len == -1) {
/*
* An error has encountered. Perhaps there is a
* network problem.
@@ -653,12 +639,11 @@ client_process_net_input(fd_set *readset)
if ((r = sshbuf_putf(stderr_buffer,
"Read from remote host %.300s: %.100s\r\n",
host, strerror(errno))) != 0)
- fatal("%s: buffer error: %s",
- __func__, ssh_err(r));
+ fatal_fr(r, "sshbuf_putf");
quit_pending = 1;
return;
}
- packet_process_incoming(buf, len);
+ ssh_packet_process_incoming(ssh, buf, len);
}
}
@@ -702,10 +687,11 @@ client_status_confirm(struct ssh *ssh, int type, Channel *c, void *ctx)
* their stderr.
*/
if (tochan) {
+ debug3_f("channel %d: mux request: %s", c->self,
+ cr->request_type);
if ((r = sshbuf_put(c->extended, errmsg,
strlen(errmsg))) != 0)
- fatal("%s: buffer error %s", __func__,
- ssh_err(r));
+ fatal_fr(r, "sshbuf_put");
} else
error("%s", errmsg);
if (cr->action == CONFIRM_TTY) {
@@ -753,8 +739,8 @@ client_register_global_confirm(global_confirm_cb *cb, void *ctx)
last_gc = TAILQ_LAST(&global_confirms, global_confirms);
if (last_gc && last_gc->cb == cb && last_gc->ctx == ctx) {
if (++last_gc->ref_count >= INT_MAX)
- fatal("%s: last_gc->ref_count = %d",
- __func__, last_gc->ref_count);
+ fatal_f("last_gc->ref_count = %d",
+ last_gc->ref_count);
return;
}
@@ -776,7 +762,7 @@ process_cmdline(struct ssh *ssh)
memset(&fwd, 0, sizeof(fwd));
leave_raw_mode(options.request_tty == REQUEST_TTY_FORCE);
- handler = signal(SIGINT, SIG_IGN);
+ handler = ssh_signal(SIGINT, SIG_IGN);
cmd = s = read_passphrase("\r\nssh> ", RP_ECHO);
if (s == NULL)
goto out;
@@ -874,7 +860,7 @@ process_cmdline(struct ssh *ssh)
}
out:
- signal(SIGINT, handler);
+ ssh_signal(SIGINT, handler);
enter_raw_mode(options.request_tty == REQUEST_TTY_FORCE);
free(cmd);
free(fwd.listen_host);
@@ -917,7 +903,7 @@ print_escape_help(struct sshbuf *b, int escape_char, int mux_client,
if ((r = sshbuf_putf(b,
"%c?\r\nSupported escape sequences:\r\n", escape_char)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "sshbuf_putf");
suppress_flags =
(mux_client ? SUPPRESS_MUXCLIENT : 0) |
@@ -929,14 +915,14 @@ print_escape_help(struct sshbuf *b, int escape_char, int mux_client,
continue;
if ((r = sshbuf_putf(b, " %c%-3s - %s\r\n",
escape_char, esc_txt[i].cmd, esc_txt[i].text)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "sshbuf_putf");
}
if ((r = sshbuf_putf(b,
" %c%c - send the escape character by typing it twice\r\n"
"(Note that escapes are only recognized immediately after "
"newline.)\r\n", escape_char, escape_char)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "sshbuf_putf");
}
/*
@@ -976,8 +962,7 @@ process_escapes(struct ssh *ssh, Channel *c,
/* Terminate the connection. */
if ((r = sshbuf_putf(berr, "%c.\r\n",
efc->escape_char)) != 0)
- fatal("%s: buffer error: %s",
- __func__, ssh_err(r));
+ fatal_fr(r, "sshbuf_putf");
if (c && c->ctl_chan != -1) {
chan_read_failed(ssh, c);
chan_write_failed(ssh, c);
@@ -1006,16 +991,14 @@ process_escapes(struct ssh *ssh, Channel *c,
"%c%s escape not available to "
"multiplexed sessions\r\n",
efc->escape_char, b)) != 0)
- fatal("%s: buffer error: %s",
- __func__, ssh_err(r));
+ fatal_fr(r, "sshbuf_putf");
continue;
}
/* Suspend the program. Inform the user */
if ((r = sshbuf_putf(berr,
"%c^Z [suspend ssh]\r\n",
efc->escape_char)) != 0)
- fatal("%s: buffer error: %s",
- __func__, ssh_err(r));
+ fatal_fr(r, "sshbuf_putf");
/* Restore terminal modes and suspend. */
client_suspend_self(bin, bout, berr);
@@ -1026,17 +1009,15 @@ process_escapes(struct ssh *ssh, Channel *c,
case 'B':
if ((r = sshbuf_putf(berr,
"%cB\r\n", efc->escape_char)) != 0)
- fatal("%s: buffer error: %s",
- __func__, ssh_err(r));
+ fatal_fr(r, "sshbuf_putf");
channel_request_start(ssh, c->self, "break", 0);
if ((r = sshpkt_put_u32(ssh, 1000)) != 0 ||
(r = sshpkt_send(ssh)) != 0)
- fatal("%s: %s", __func__,
- ssh_err(r));
+ fatal_fr(r, "send packet");
continue;
case 'R':
- if (datafellows & SSH_BUG_NOREKEY)
+ if (ssh->compat & SSH_BUG_NOREKEY)
logit("Server does not "
"support re-keying");
else
@@ -1052,8 +1033,7 @@ process_escapes(struct ssh *ssh, Channel *c,
if ((r = sshbuf_putf(berr,
"%c%c [Logging to syslog]\r\n",
efc->escape_char, ch)) != 0)
- fatal("%s: buffer error: %s",
- __func__, ssh_err(r));
+ fatal_fr(r, "sshbuf_putf");
continue;
}
if (ch == 'V' && options.log_level >
@@ -1066,8 +1046,7 @@ process_escapes(struct ssh *ssh, Channel *c,
"%c%c [LogLevel %s]\r\n",
efc->escape_char, ch,
log_level_name(options.log_level))) != 0)
- fatal("%s: buffer error: %s",
- __func__, ssh_err(r));
+ fatal_fr(r, "sshbuf_putf");
continue;
case '&':
@@ -1085,15 +1064,13 @@ process_escapes(struct ssh *ssh, Channel *c,
/* Stop listening for new connections. */
channel_stop_listening(ssh);
- if ((r = sshbuf_putf(berr,
- "%c& [backgrounded]\n", efc->escape_char))
- != 0)
- fatal("%s: buffer error: %s",
- __func__, ssh_err(r));
+ if ((r = sshbuf_putf(berr, "%c& "
+ "[backgrounded]\n", efc->escape_char)) != 0)
+ fatal_fr(r, "sshbuf_putf");
/* Fork into background. */
pid = fork();
- if (pid < 0) {
+ if (pid == -1) {
error("fork: %.100s", strerror(errno));
continue;
}
@@ -1104,8 +1081,7 @@ process_escapes(struct ssh *ssh, Channel *c,
/* The child continues serving connections. */
/* fake EOF on stdin */
if ((r = sshbuf_put_u8(bin, 4)) != 0)
- fatal("%s: buffer error: %s",
- __func__, ssh_err(r));
+ fatal_fr(r, "sshbuf_put_u8");
return -1;
case '?':
print_escape_help(berr, efc->escape_char,
@@ -1116,12 +1092,10 @@ process_escapes(struct ssh *ssh, Channel *c,
case '#':
if ((r = sshbuf_putf(berr, "%c#\r\n",
efc->escape_char)) != 0)
- fatal("%s: buffer error: %s",
- __func__, ssh_err(r));
+ fatal_fr(r, "sshbuf_putf");
s = channel_open_message(ssh);
if ((r = sshbuf_put(berr, s, strlen(s))) != 0)
- fatal("%s: buffer error: %s",
- __func__, ssh_err(r));
+ fatal_fr(r, "sshbuf_put");
free(s);
continue;
@@ -1135,8 +1109,7 @@ process_escapes(struct ssh *ssh, Channel *c,
if (ch != efc->escape_char) {
if ((r = sshbuf_put_u8(bin,
efc->escape_char)) != 0)
- fatal("%s: buffer error: %s",
- __func__, ssh_err(r));
+ fatal_fr(r, "sshbuf_put_u8");
bytes++;
}
/* Escaped characters fall through here */
@@ -1163,7 +1136,7 @@ process_escapes(struct ssh *ssh, Channel *c,
*/
last_was_cr = (ch == '\r' || ch == '\n');
if ((r = sshbuf_put_u8(bin, ch)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "sshbuf_put_u8");
bytes++;
}
return bytes;
@@ -1182,9 +1155,9 @@ process_escapes(struct ssh *ssh, Channel *c,
*/
static void
-client_process_buffered_input_packets(void)
+client_process_buffered_input_packets(struct ssh *ssh)
{
- ssh_dispatch_run_fatal(active_state, DISPATCH_NONBLOCK, &quit_pending);
+ ssh_dispatch_run_fatal(ssh, DISPATCH_NONBLOCK, &quit_pending);
}
/* scan buf[] for '~' before sending data to the peer */
@@ -1241,39 +1214,38 @@ client_loop(struct ssh *ssh, int have_pty, int escape_char_arg,
int r, max_fd = 0, max_fd2 = 0, len;
u_int64_t ibytes, obytes;
u_int nalloc = 0;
- char buf[100];
debug("Entering interactive session.");
if (options.control_master &&
!option_clear_or_none(options.control_path)) {
debug("pledge: id");
- if (pledge("stdio rpath wpath cpath unix inet dns recvfd proc exec id tty",
+ if (pledge("stdio rpath wpath cpath unix inet dns recvfd sendfd proc exec id tty",
NULL) == -1)
- fatal("%s pledge(): %s", __func__, strerror(errno));
+ fatal_f("pledge(): %s", strerror(errno));
} else if (options.forward_x11 || options.permit_local_command) {
debug("pledge: exec");
if (pledge("stdio rpath wpath cpath unix inet dns proc exec tty",
NULL) == -1)
- fatal("%s pledge(): %s", __func__, strerror(errno));
+ fatal_f("pledge(): %s", strerror(errno));
} else if (options.update_hostkeys) {
debug("pledge: filesystem full");
if (pledge("stdio rpath wpath cpath unix inet dns proc tty",
NULL) == -1)
- fatal("%s pledge(): %s", __func__, strerror(errno));
+ fatal_f("pledge(): %s", strerror(errno));
} else if (!option_clear_or_none(options.proxy_command) ||
- fork_after_authentication_flag) {
+ options.fork_after_authentication) {
debug("pledge: proc");
if (pledge("stdio cpath unix inet dns proc tty", NULL) == -1)
- fatal("%s pledge(): %s", __func__, strerror(errno));
+ fatal_f("pledge(): %s", strerror(errno));
} else {
debug("pledge: network");
if (pledge("stdio unix inet dns proc tty", NULL) == -1)
- fatal("%s pledge(): %s", __func__, strerror(errno));
+ fatal_f("pledge(): %s", strerror(errno));
}
start_time = monotime_double();
@@ -1281,31 +1253,31 @@ client_loop(struct ssh *ssh, int have_pty, int escape_char_arg,
/* Initialize variables. */
last_was_cr = 1;
exit_status = -1;
- connection_in = packet_get_connection_in();
- connection_out = packet_get_connection_out();
+ connection_in = ssh_packet_get_connection_in(ssh);
+ connection_out = ssh_packet_get_connection_out(ssh);
max_fd = MAXIMUM(connection_in, connection_out);
quit_pending = 0;
/* Initialize buffer. */
if ((stderr_buffer = sshbuf_new()) == NULL)
- fatal("%s: sshbuf_new failed", __func__);
+ fatal_f("sshbuf_new failed");
- client_init_dispatch();
+ client_init_dispatch(ssh);
/*
* Set signal handlers, (e.g. to restore non-blocking mode)
* but don't overwrite SIG_IGN, matches behaviour from rsh(1)
*/
- if (signal(SIGHUP, SIG_IGN) != SIG_IGN)
- signal(SIGHUP, signal_handler);
- if (signal(SIGINT, SIG_IGN) != SIG_IGN)
- signal(SIGINT, signal_handler);
- if (signal(SIGQUIT, SIG_IGN) != SIG_IGN)
- signal(SIGQUIT, signal_handler);
- if (signal(SIGTERM, SIG_IGN) != SIG_IGN)
- signal(SIGTERM, signal_handler);
- signal(SIGWINCH, window_change_handler);
+ if (ssh_signal(SIGHUP, SIG_IGN) != SIG_IGN)
+ ssh_signal(SIGHUP, signal_handler);
+ if (ssh_signal(SIGINT, SIG_IGN) != SIG_IGN)
+ ssh_signal(SIGINT, signal_handler);
+ if (ssh_signal(SIGQUIT, SIG_IGN) != SIG_IGN)
+ ssh_signal(SIGQUIT, signal_handler);
+ if (ssh_signal(SIGTERM, SIG_IGN) != SIG_IGN)
+ ssh_signal(SIGTERM, signal_handler);
+ ssh_signal(SIGWINCH, window_change_handler);
if (have_pty)
enter_raw_mode(options.request_tty == REQUEST_TTY_FORCE);
@@ -1323,11 +1295,13 @@ client_loop(struct ssh *ssh, int have_pty, int escape_char_arg,
client_channel_closed, 0);
}
+ schedule_server_alive_check();
+
/* Main loop of the client for the interactive session mode. */
while (!quit_pending) {
/* Process buffered packets sent by the server. */
- client_process_buffered_input_packets();
+ client_process_buffered_input_packets(ssh);
if (session_closed && !channel_still_open(ssh))
break;
@@ -1338,15 +1312,14 @@ client_loop(struct ssh *ssh, int have_pty, int escape_char_arg,
/* manual rekey request */
debug("need rekeying");
if ((r = kex_start_rekex(ssh)) != 0)
- fatal("%s: kex_start_rekex: %s", __func__,
- ssh_err(r));
+ fatal_fr(r, "kex_start_rekex");
need_rekeying = 0;
} else {
/*
* Make packets from buffered channel data, and
* enqueue them for sending to the server.
*/
- if (packet_not_very_much_data_to_write())
+ if (ssh_packet_not_very_much_data_to_write(ssh))
channel_output_poll(ssh);
/*
@@ -1374,17 +1347,25 @@ client_loop(struct ssh *ssh, int have_pty, int escape_char_arg,
channel_after_select(ssh, readset, writeset);
/* Buffer input from the connection. */
- client_process_net_input(readset);
+ client_process_net_input(ssh, readset);
if (quit_pending)
break;
+ /* A timeout may have triggered rekeying */
+ if ((r = ssh_packet_check_rekey(ssh)) != 0)
+ fatal_fr(r, "cannot start rekeying");
+
/*
* Send as much buffered packet data as possible to the
* sender.
*/
- if (FD_ISSET(connection_out, writeset))
- packet_write_poll();
+ if (FD_ISSET(connection_out, writeset)) {
+ if ((r = ssh_packet_write_poll(ssh)) != 0) {
+ sshpkt_fatal(ssh, r,
+ "%s: ssh_packet_write_poll", __func__);
+ }
+ }
/*
* If we are a backgrounded control master, and the
@@ -1404,41 +1385,34 @@ client_loop(struct ssh *ssh, int have_pty, int escape_char_arg,
/* Terminate the session. */
/* Stop watching for window change. */
- signal(SIGWINCH, SIG_DFL);
+ ssh_signal(SIGWINCH, SIG_DFL);
- packet_start(SSH2_MSG_DISCONNECT);
- packet_put_int(SSH2_DISCONNECT_BY_APPLICATION);
- packet_put_cstring("disconnected by user");
- packet_put_cstring(""); /* language tag */
- packet_send();
- packet_write_wait();
+ if ((r = sshpkt_start(ssh, SSH2_MSG_DISCONNECT)) != 0 ||
+ (r = sshpkt_put_u32(ssh, SSH2_DISCONNECT_BY_APPLICATION)) != 0 ||
+ (r = sshpkt_put_cstring(ssh, "disconnected by user")) != 0 ||
+ (r = sshpkt_put_cstring(ssh, "")) != 0 || /* language tag */
+ (r = sshpkt_send(ssh)) != 0 ||
+ (r = ssh_packet_write_wait(ssh)) != 0)
+ fatal_fr(r, "send disconnect");
channel_free_all(ssh);
if (have_pty)
leave_raw_mode(options.request_tty == REQUEST_TTY_FORCE);
- /* restore blocking io */
- if (!isatty(fileno(stdin)))
- unset_nonblock(fileno(stdin));
- if (!isatty(fileno(stdout)))
- unset_nonblock(fileno(stdout));
- if (!isatty(fileno(stderr)))
- unset_nonblock(fileno(stderr));
-
/*
* If there was no shell or command requested, there will be no remote
* exit status to be returned. In that case, clear error code if the
* connection was deliberately terminated at this end.
*/
- if (no_shell_flag && received_signal == SIGTERM) {
+ if (options.session_type == SESSION_TYPE_NONE && received_signal == SIGTERM) {
received_signal = 0;
exit_status = 0;
}
if (received_signal) {
verbose("Killed by signal %d.", (int) received_signal);
- cleanup_exit(0);
+ cleanup_exit(255);
}
/*
@@ -1448,7 +1422,7 @@ client_loop(struct ssh *ssh, int have_pty, int escape_char_arg,
if (have_pty && options.log_level != SYSLOG_LEVEL_QUIET) {
if ((r = sshbuf_putf(stderr_buffer,
"Connection to %.64s closed.\r\n", host)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "sshbuf_putf");
}
/* Output any buffered data for stderr. */
@@ -1459,16 +1433,15 @@ client_loop(struct ssh *ssh, int have_pty, int escape_char_arg,
if (len < 0 || (u_int)len != sshbuf_len(stderr_buffer))
error("Write failed flushing stderr buffer.");
else if ((r = sshbuf_consume(stderr_buffer, len)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "sshbuf_consume");
}
/* Clear and free any buffers. */
- explicit_bzero(buf, sizeof(buf));
sshbuf_free(stderr_buffer);
/* Report bytes transferred, and transfer rates. */
total_time = monotime_double() - start_time;
- packet_get_bytes(&ibytes, &obytes);
+ ssh_packet_get_bytes(ssh, &ibytes, &obytes);
verbose("Transferred: sent %llu, received %llu bytes, in %.1f seconds",
(unsigned long long)obytes, (unsigned long long)ibytes, total_time);
if (total_time > 0)
@@ -1488,25 +1461,33 @@ client_request_forwarded_tcpip(struct ssh *ssh, const char *request_type,
Channel *c = NULL;
struct sshbuf *b = NULL;
char *listen_address, *originator_address;
- u_short listen_port, originator_port;
+ u_int listen_port, originator_port;
int r;
/* Get rest of the packet */
- listen_address = packet_get_string(NULL);
- listen_port = packet_get_int();
- originator_address = packet_get_string(NULL);
- originator_port = packet_get_int();
- packet_check_eom();
-
- debug("%s: listen %s port %d, originator %s port %d", __func__,
+ if ((r = sshpkt_get_cstring(ssh, &listen_address, NULL)) != 0 ||
+ (r = sshpkt_get_u32(ssh, &listen_port)) != 0 ||
+ (r = sshpkt_get_cstring(ssh, &originator_address, NULL)) != 0 ||
+ (r = sshpkt_get_u32(ssh, &originator_port)) != 0 ||
+ (r = sshpkt_get_end(ssh)) != 0)
+ fatal_fr(r, "parse packet");
+
+ debug_f("listen %s port %d, originator %s port %d",
listen_address, listen_port, originator_address, originator_port);
- c = channel_connect_by_listen_address(ssh, listen_address, listen_port,
- "forwarded-tcpip", originator_address);
+ if (listen_port > 0xffff)
+ error_f("invalid listen port");
+ else if (originator_port > 0xffff)
+ error_f("invalid originator port");
+ else {
+ c = channel_connect_by_listen_address(ssh,
+ listen_address, listen_port, "forwarded-tcpip",
+ originator_address);
+ }
if (c != NULL && c->type == SSH_CHANNEL_MUX_CLIENT) {
if ((b = sshbuf_new()) == NULL) {
- error("%s: alloc reply", __func__);
+ error_f("alloc reply");
goto out;
}
/* reconstruct and send to muxclient */
@@ -1521,8 +1502,7 @@ client_request_forwarded_tcpip(struct ssh *ssh, const char *request_type,
(r = sshbuf_put_cstring(b, originator_address)) != 0 ||
(r = sshbuf_put_u32(b, originator_port)) != 0 ||
(r = sshbuf_put_stringb(c->output, b)) != 0) {
- error("%s: compose for muxclient %s", __func__,
- ssh_err(r));
+ error_fr(r, "compose for muxclient");
goto out;
}
}
@@ -1540,15 +1520,15 @@ client_request_forwarded_streamlocal(struct ssh *ssh,
{
Channel *c = NULL;
char *listen_path;
+ int r;
/* Get the remote path. */
- listen_path = packet_get_string(NULL);
- /* XXX: Skip reserved field for now. */
- if (packet_get_string_ptr(NULL) == NULL)
- fatal("%s: packet_get_string_ptr failed", __func__);
- packet_check_eom();
+ if ((r = sshpkt_get_cstring(ssh, &listen_path, NULL)) != 0 ||
+ (r = sshpkt_get_string(ssh, NULL, NULL)) != 0 || /* reserved */
+ (r = sshpkt_get_end(ssh)) != 0)
+ fatal_fr(r, "parse packet");
- debug("%s: %s", __func__, listen_path);
+ debug_f("request: %s", listen_path);
c = channel_connect_by_listen_path(ssh, listen_path,
"forwarded-streamlocal@openssh.com", "forwarded-streamlocal");
@@ -1561,8 +1541,8 @@ client_request_x11(struct ssh *ssh, const char *request_type, int rchan)
{
Channel *c = NULL;
char *originator;
- u_short originator_port;
- int sock;
+ u_int originator_port;
+ int r, sock;
if (!options.forward_x11) {
error("Warning: ssh server tried X11 forwarding.");
@@ -1575,11 +1555,13 @@ client_request_x11(struct ssh *ssh, const char *request_type, int rchan)
"expired");
return NULL;
}
- originator = packet_get_string(NULL);
- originator_port = packet_get_int();
- packet_check_eom();
+ if ((r = sshpkt_get_cstring(ssh, &originator, NULL)) != 0 ||
+ (r = sshpkt_get_u32(ssh, &originator_port)) != 0 ||
+ (r = sshpkt_get_end(ssh)) != 0)
+ fatal_fr(r, "parse packet");
/* XXX check permission */
- debug("client_request_x11: request from %s %d", originator,
+ /* XXX range check originator port? */
+ debug("client_request_x11: request from %s %u", originator,
originator_port);
free(originator);
sock = x11_connect_display(ssh);
@@ -1604,10 +1586,14 @@ client_request_agent(struct ssh *ssh, const char *request_type, int rchan)
"malicious server.");
return NULL;
}
- if ((r = ssh_get_authentication_socket(&sock)) != 0) {
+ if (forward_agent_sock_path == NULL) {
+ r = ssh_get_authentication_socket(&sock);
+ } else {
+ r = ssh_get_authentication_socket_path(forward_agent_sock_path, &sock);
+ }
+ if (r != 0) {
if (r != SSH_ERR_AGENT_NOT_PRESENT)
- debug("%s: ssh_get_authentication_socket: %s",
- __func__, ssh_err(r));
+ debug_fr(r, "ssh_get_authentication_socket");
return NULL;
}
c = channel_new(ssh, "authentication agent connection",
@@ -1620,10 +1606,10 @@ client_request_agent(struct ssh *ssh, const char *request_type, int rchan)
char *
client_request_tun_fwd(struct ssh *ssh, int tun_mode,
- int local_tun, int remote_tun)
+ int local_tun, int remote_tun, channel_open_fn *cb, void *cbctx)
{
Channel *c;
- int fd;
+ int r, fd;
char *ifname = NULL;
if (tun_mode == SSH_TUNMODE_NO)
@@ -1648,14 +1634,18 @@ client_request_tun_fwd(struct ssh *ssh, int tun_mode,
sys_tun_outfilter, NULL, NULL);
#endif
- packet_start(SSH2_MSG_CHANNEL_OPEN);
- packet_put_cstring("tun@openssh.com");
- packet_put_int(c->self);
- packet_put_int(c->local_window_max);
- packet_put_int(c->local_maxpacket);
- packet_put_int(tun_mode);
- packet_put_int(remote_tun);
- packet_send();
+ if (cb != NULL)
+ channel_register_open_confirm(ssh, c->self, cb, cbctx);
+
+ if ((r = sshpkt_start(ssh, SSH2_MSG_CHANNEL_OPEN)) != 0 ||
+ (r = sshpkt_put_cstring(ssh, "tun@openssh.com")) != 0 ||
+ (r = sshpkt_put_u32(ssh, c->self)) != 0 ||
+ (r = sshpkt_put_u32(ssh, c->local_window_max)) != 0 ||
+ (r = sshpkt_put_u32(ssh, c->local_maxpacket)) != 0 ||
+ (r = sshpkt_put_u32(ssh, tun_mode)) != 0 ||
+ (r = sshpkt_put_u32(ssh, remote_tun)) != 0 ||
+ (r = sshpkt_send(ssh)) != 0)
+ sshpkt_fatal(ssh, r, "%s: send reply", __func__);
return ifname;
}
@@ -1665,14 +1655,17 @@ static int
client_input_channel_open(int type, u_int32_t seq, struct ssh *ssh)
{
Channel *c = NULL;
- char *ctype;
- int rchan;
- u_int rmaxpack, rwindow, len;
-
- ctype = packet_get_string(&len);
- rchan = packet_get_int();
- rwindow = packet_get_int();
- rmaxpack = packet_get_int();
+ char *ctype = NULL;
+ int r;
+ u_int rchan;
+ size_t len;
+ u_int rmaxpack, rwindow;
+
+ if ((r = sshpkt_get_cstring(ssh, &ctype, &len)) != 0 ||
+ (r = sshpkt_get_u32(ssh, &rchan)) != 0 ||
+ (r = sshpkt_get_u32(ssh, &rwindow)) != 0 ||
+ (r = sshpkt_get_u32(ssh, &rmaxpack)) != 0)
+ goto out;
debug("client_input_channel_open: ctype %s rchan %d win %d max %d",
ctype, rchan, rwindow, rmaxpack);
@@ -1696,78 +1689,90 @@ client_input_channel_open(int type, u_int32_t seq, struct ssh *ssh)
c->remote_window = rwindow;
c->remote_maxpacket = rmaxpack;
if (c->type != SSH_CHANNEL_CONNECTING) {
- packet_start(SSH2_MSG_CHANNEL_OPEN_CONFIRMATION);
- packet_put_int(c->remote_id);
- packet_put_int(c->self);
- packet_put_int(c->local_window);
- packet_put_int(c->local_maxpacket);
- packet_send();
+ if ((r = sshpkt_start(ssh, SSH2_MSG_CHANNEL_OPEN_CONFIRMATION)) != 0 ||
+ (r = sshpkt_put_u32(ssh, c->remote_id)) != 0 ||
+ (r = sshpkt_put_u32(ssh, c->self)) != 0 ||
+ (r = sshpkt_put_u32(ssh, c->local_window)) != 0 ||
+ (r = sshpkt_put_u32(ssh, c->local_maxpacket)) != 0 ||
+ (r = sshpkt_send(ssh)) != 0)
+ sshpkt_fatal(ssh, r, "%s: send reply", __func__);
}
} else {
debug("failure %s", ctype);
- packet_start(SSH2_MSG_CHANNEL_OPEN_FAILURE);
- packet_put_int(rchan);
- packet_put_int(SSH2_OPEN_ADMINISTRATIVELY_PROHIBITED);
- packet_put_cstring("open failed");
- packet_put_cstring("");
- packet_send();
+ if ((r = sshpkt_start(ssh, SSH2_MSG_CHANNEL_OPEN_FAILURE)) != 0 ||
+ (r = sshpkt_put_u32(ssh, rchan)) != 0 ||
+ (r = sshpkt_put_u32(ssh, SSH2_OPEN_ADMINISTRATIVELY_PROHIBITED)) != 0 ||
+ (r = sshpkt_put_cstring(ssh, "open failed")) != 0 ||
+ (r = sshpkt_put_cstring(ssh, "")) != 0 ||
+ (r = sshpkt_send(ssh)) != 0)
+ sshpkt_fatal(ssh, r, "%s: send failure", __func__);
}
+ r = 0;
+ out:
free(ctype);
- return 0;
+ return r;
}
static int
client_input_channel_req(int type, u_int32_t seq, struct ssh *ssh)
{
Channel *c = NULL;
- int exitval, id, reply, success = 0;
- char *rtype;
-
- id = packet_get_int();
- c = channel_lookup(ssh, id);
+ char *rtype = NULL;
+ u_char reply;
+ u_int id, exitval;
+ int r, success = 0;
+
+ if ((r = sshpkt_get_u32(ssh, &id)) != 0)
+ return r;
+ if (id <= INT_MAX)
+ c = channel_lookup(ssh, id);
if (channel_proxy_upstream(c, type, seq, ssh))
return 0;
- rtype = packet_get_string(NULL);
- reply = packet_get_char();
+ if ((r = sshpkt_get_cstring(ssh, &rtype, NULL)) != 0 ||
+ (r = sshpkt_get_u8(ssh, &reply)) != 0)
+ goto out;
- debug("client_input_channel_req: channel %d rtype %s reply %d",
+ debug("client_input_channel_req: channel %u rtype %s reply %d",
id, rtype, reply);
- if (id == -1) {
- error("client_input_channel_req: request for channel -1");
- } else if (c == NULL) {
+ if (c == NULL) {
error("client_input_channel_req: channel %d: "
"unknown channel", id);
} else if (strcmp(rtype, "eow@openssh.com") == 0) {
- packet_check_eom();
+ if ((r = sshpkt_get_end(ssh)) != 0)
+ goto out;
chan_rcvd_eow(ssh, c);
} else if (strcmp(rtype, "exit-status") == 0) {
- exitval = packet_get_int();
+ if ((r = sshpkt_get_u32(ssh, &exitval)) != 0)
+ goto out;
if (c->ctl_chan != -1) {
mux_exit_message(ssh, c, exitval);
success = 1;
- } else if (id == session_ident) {
+ } else if ((int)id == session_ident) {
/* Record exit value of local session */
success = 1;
exit_status = exitval;
} else {
/* Probably for a mux channel that has already closed */
- debug("%s: no sink for exit-status on channel %d",
- __func__, id);
+ debug_f("no sink for exit-status on channel %d",
+ id);
}
- packet_check_eom();
+ if ((r = sshpkt_get_end(ssh)) != 0)
+ goto out;
}
if (reply && c != NULL && !(c->flags & CHAN_CLOSE_SENT)) {
if (!c->have_remote_id)
- fatal("%s: channel %d: no remote_id",
- __func__, c->self);
- packet_start(success ?
- SSH2_MSG_CHANNEL_SUCCESS : SSH2_MSG_CHANNEL_FAILURE);
- packet_put_int(c->remote_id);
- packet_send();
+ fatal_f("channel %d: no remote_id", c->self);
+ if ((r = sshpkt_start(ssh, success ?
+ SSH2_MSG_CHANNEL_SUCCESS : SSH2_MSG_CHANNEL_FAILURE)) != 0 ||
+ (r = sshpkt_put_u32(ssh, c->remote_id)) != 0 ||
+ (r = sshpkt_send(ssh)) != 0)
+ sshpkt_fatal(ssh, r, "%s: send failure", __func__);
}
+ r = 0;
+ out:
free(rtype);
- return 0;
+ return r;
}
struct hostkeys_update_ctx {
@@ -1777,12 +1782,13 @@ struct hostkeys_update_ctx {
/*
* Keys received from the server and a flag for each indicating
* whether they already exist in known_hosts.
- * keys_seen is filled in by hostkeys_find() and later (for new
+ * keys_match is filled in by hostkeys_find() and later (for new
* keys) by client_global_hostkeys_private_confirm().
*/
struct sshkey **keys;
- int *keys_seen;
- size_t nkeys, nnew;
+ u_int *keys_match; /* mask of HKF_MATCH_* from hostfile.h */
+ int *keys_verified; /* flag for new keys verified by server */
+ size_t nkeys, nnew, nincomplete; /* total, new keys, incomplete match */
/*
* Keys that are in known_hosts, but were not present in the update
@@ -1791,6 +1797,12 @@ struct hostkeys_update_ctx {
*/
struct sshkey **old_keys;
size_t nold;
+
+ /* Various special cases. */
+ int complex_hostspec; /* wildcard or manual pattern-list host name */
+ int ca_available; /* saw CA key for this host */
+ int old_key_seen; /* saw old key with other name/addr */
+ int other_name_seen; /* saw key with other name/addr */
};
static void
@@ -1803,7 +1815,8 @@ hostkeys_update_ctx_free(struct hostkeys_update_ctx *ctx)
for (i = 0; i < ctx->nkeys; i++)
sshkey_free(ctx->keys[i]);
free(ctx->keys);
- free(ctx->keys_seen);
+ free(ctx->keys_match);
+ free(ctx->keys_verified);
for (i = 0; i < ctx->nold; i++)
sshkey_free(ctx->old_keys[i]);
free(ctx->old_keys);
@@ -1812,6 +1825,30 @@ hostkeys_update_ctx_free(struct hostkeys_update_ctx *ctx)
free(ctx);
}
+/*
+ * Returns non-zero if a known_hosts hostname list is not of a form that
+ * can be handled by UpdateHostkeys. These include wildcard hostnames and
+ * hostnames lists that do not follow the form host[,ip].
+ */
+static int
+hostspec_is_complex(const char *hosts)
+{
+ char *cp;
+
+ /* wildcard */
+ if (strchr(hosts, '*') != NULL || strchr(hosts, '?') != NULL)
+ return 1;
+ /* single host/ip = ok */
+ if ((cp = strchr(hosts, ',')) == NULL)
+ return 0;
+ /* more than two entries on the line */
+ if (strchr(cp + 1, ',') != NULL)
+ return 1;
+ /* XXX maybe parse cp+1 and ensure it is an IP? */
+ return 0;
+}
+
+/* callback to search for ctx->keys in known_hosts */
static int
hostkeys_find(struct hostkey_foreach_line *l, void *_ctx)
{
@@ -1819,25 +1856,73 @@ hostkeys_find(struct hostkey_foreach_line *l, void *_ctx)
size_t i;
struct sshkey **tmp;
- if (l->status != HKF_STATUS_MATCHED || l->key == NULL)
+ if (l->key == NULL)
+ return 0;
+ if (l->status != HKF_STATUS_MATCHED) {
+ /* Record if one of the keys appears on a non-matching line */
+ for (i = 0; i < ctx->nkeys; i++) {
+ if (sshkey_equal(l->key, ctx->keys[i])) {
+ ctx->other_name_seen = 1;
+ debug3_f("found %s key under different "
+ "name/addr at %s:%ld",
+ sshkey_ssh_name(ctx->keys[i]),
+ l->path, l->linenum);
+ return 0;
+ }
+ }
return 0;
+ }
+ /* Don't proceed if revocation or CA markers are present */
+ /* XXX relax this */
+ if (l->marker != MRK_NONE) {
+ debug3_f("hostkeys file %s:%ld has CA/revocation marker",
+ l->path, l->linenum);
+ ctx->complex_hostspec = 1;
+ return 0;
+ }
- /* Mark off keys we've already seen for this host */
- for (i = 0; i < ctx->nkeys; i++) {
- if (sshkey_equal(l->key, ctx->keys[i])) {
- debug3("%s: found %s key at %s:%ld", __func__,
- sshkey_ssh_name(ctx->keys[i]), l->path, l->linenum);
- ctx->keys_seen[i] = 1;
+ /* If CheckHostIP is enabled, then check for mismatched hostname/addr */
+ if (ctx->ip_str != NULL && strchr(l->hosts, ',') != NULL) {
+ if ((l->match & HKF_MATCH_HOST) == 0) {
+ /* Record if address matched a different hostname. */
+ ctx->other_name_seen = 1;
+ debug3_f("found address %s against different hostname "
+ "at %s:%ld", ctx->ip_str, l->path, l->linenum);
return 0;
+ } else if ((l->match & HKF_MATCH_IP) == 0) {
+ /* Record if hostname matched a different address. */
+ ctx->other_name_seen = 1;
+ debug3_f("found hostname %s against different address "
+ "at %s:%ld", ctx->host_str, l->path, l->linenum);
}
}
+
+ /*
+ * UpdateHostkeys is skipped for wildcard host names and hostnames
+ * that contain more than two entries (ssh never writes these).
+ */
+ if (hostspec_is_complex(l->hosts)) {
+ debug3_f("hostkeys file %s:%ld complex host specification",
+ l->path, l->linenum);
+ ctx->complex_hostspec = 1;
+ return 0;
+ }
+
+ /* Mark off keys we've already seen for this host */
+ for (i = 0; i < ctx->nkeys; i++) {
+ if (!sshkey_equal(l->key, ctx->keys[i]))
+ continue;
+ debug3_f("found %s key at %s:%ld",
+ sshkey_ssh_name(ctx->keys[i]), l->path, l->linenum);
+ ctx->keys_match[i] |= l->match;
+ return 0;
+ }
/* This line contained a key that not offered by the server */
- debug3("%s: deprecated %s key at %s:%ld", __func__,
- sshkey_ssh_name(l->key), l->path, l->linenum);
+ debug3_f("deprecated %s key at %s:%ld", sshkey_ssh_name(l->key),
+ l->path, l->linenum);
if ((tmp = recallocarray(ctx->old_keys, ctx->nold, ctx->nold + 1,
sizeof(*ctx->old_keys))) == NULL)
- fatal("%s: recallocarray failed nold = %zu",
- __func__, ctx->nold);
+ fatal_f("recallocarray failed nold = %zu", ctx->nold);
ctx->old_keys = tmp;
ctx->old_keys[ctx->nold++] = l->key;
l->key = NULL;
@@ -1845,31 +1930,103 @@ hostkeys_find(struct hostkey_foreach_line *l, void *_ctx)
return 0;
}
+/* callback to search for ctx->old_keys in known_hosts under other names */
+static int
+hostkeys_check_old(struct hostkey_foreach_line *l, void *_ctx)
+{
+ struct hostkeys_update_ctx *ctx = (struct hostkeys_update_ctx *)_ctx;
+ size_t i;
+ int hashed;
+
+ /* only care about lines that *don't* match the active host spec */
+ if (l->status == HKF_STATUS_MATCHED || l->key == NULL)
+ return 0;
+
+ hashed = l->match & (HKF_MATCH_HOST_HASHED|HKF_MATCH_IP_HASHED);
+ for (i = 0; i < ctx->nold; i++) {
+ if (!sshkey_equal(l->key, ctx->old_keys[i]))
+ continue;
+ debug3_f("found deprecated %s key at %s:%ld as %s",
+ sshkey_ssh_name(ctx->old_keys[i]), l->path, l->linenum,
+ hashed ? "[HASHED]" : l->hosts);
+ ctx->old_key_seen = 1;
+ break;
+ }
+ return 0;
+}
+
+/*
+ * Check known_hosts files for deprecated keys under other names. Returns 0
+ * on success or -1 on failure. Updates ctx->old_key_seen if deprecated keys
+ * exist under names other than the active hostname/IP.
+ */
+static int
+check_old_keys_othernames(struct hostkeys_update_ctx *ctx)
+{
+ size_t i;
+ int r;
+
+ debug2_f("checking for %zu deprecated keys", ctx->nold);
+ for (i = 0; i < options.num_user_hostfiles; i++) {
+ debug3_f("searching %s for %s / %s",
+ options.user_hostfiles[i], ctx->host_str,
+ ctx->ip_str ? ctx->ip_str : "(none)");
+ if ((r = hostkeys_foreach(options.user_hostfiles[i],
+ hostkeys_check_old, ctx, ctx->host_str, ctx->ip_str,
+ HKF_WANT_PARSE_KEY, 0)) != 0) {
+ if (r == SSH_ERR_SYSTEM_ERROR && errno == ENOENT) {
+ debug_f("hostkeys file %s does not exist",
+ options.user_hostfiles[i]);
+ continue;
+ }
+ error_fr(r, "hostkeys_foreach failed for %s",
+ options.user_hostfiles[i]);
+ return -1;
+ }
+ }
+ return 0;
+}
+
+static void
+hostkey_change_preamble(LogLevel loglevel)
+{
+ do_log2(loglevel, "The server has updated its host keys.");
+ do_log2(loglevel, "These changes were verified by the server's "
+ "existing trusted key.");
+}
+
static void
update_known_hosts(struct hostkeys_update_ctx *ctx)
{
- int r, was_raw = 0;
- int loglevel = options.update_hostkeys == SSH_UPDATE_HOSTKEYS_ASK ?
- SYSLOG_LEVEL_INFO : SYSLOG_LEVEL_VERBOSE;
+ int r, was_raw = 0, first = 1;
+ int asking = options.update_hostkeys == SSH_UPDATE_HOSTKEYS_ASK;
+ LogLevel loglevel = asking ? SYSLOG_LEVEL_INFO : SYSLOG_LEVEL_VERBOSE;
char *fp, *response;
size_t i;
+ struct stat sb;
for (i = 0; i < ctx->nkeys; i++) {
- if (ctx->keys_seen[i] != 2)
+ if (!ctx->keys_verified[i])
continue;
if ((fp = sshkey_fingerprint(ctx->keys[i],
options.fingerprint_hash, SSH_FP_DEFAULT)) == NULL)
- fatal("%s: sshkey_fingerprint failed", __func__);
+ fatal_f("sshkey_fingerprint failed");
+ if (first && asking)
+ hostkey_change_preamble(loglevel);
do_log2(loglevel, "Learned new hostkey: %s %s",
sshkey_type(ctx->keys[i]), fp);
+ first = 0;
free(fp);
}
for (i = 0; i < ctx->nold; i++) {
if ((fp = sshkey_fingerprint(ctx->old_keys[i],
options.fingerprint_hash, SSH_FP_DEFAULT)) == NULL)
- fatal("%s: sshkey_fingerprint failed", __func__);
+ fatal_f("sshkey_fingerprint failed");
+ if (first && asking)
+ hostkey_change_preamble(loglevel);
do_log2(loglevel, "Deprecating obsolete hostkey: %s %s",
sshkey_type(ctx->old_keys[i]), fp);
+ first = 0;
free(fp);
}
if (options.update_hostkeys == SSH_UPDATE_HOSTKEYS_ASK) {
@@ -1899,19 +2056,38 @@ update_known_hosts(struct hostkeys_update_ctx *ctx)
if (was_raw)
enter_raw_mode(1);
}
-
+ if (options.update_hostkeys == 0)
+ return;
/*
* Now that all the keys are verified, we can go ahead and replace
* them in known_hosts (assuming SSH_UPDATE_HOSTKEYS_ASK didn't
* cancel the operation).
*/
- if (options.update_hostkeys != 0 &&
- (r = hostfile_replace_entries(options.user_hostfiles[0],
- ctx->host_str, ctx->ip_str, ctx->keys, ctx->nkeys,
- options.hash_known_hosts, 0,
- options.fingerprint_hash)) != 0)
- error("%s: hostfile_replace_entries failed: %s",
- __func__, ssh_err(r));
+ for (i = 0; i < options.num_user_hostfiles; i++) {
+ /*
+ * NB. keys are only added to hostfiles[0], for the rest we
+ * just delete the hostname entries.
+ */
+ if (stat(options.user_hostfiles[i], &sb) != 0) {
+ if (errno == ENOENT) {
+ debug_f("known hosts file %s does not "
+ "exist", options.user_hostfiles[i]);
+ } else {
+ error_f("known hosts file %s "
+ "inaccessible: %s",
+ options.user_hostfiles[i], strerror(errno));
+ }
+ continue;
+ }
+ if ((r = hostfile_replace_entries(options.user_hostfiles[i],
+ ctx->host_str, ctx->ip_str,
+ i == 0 ? ctx->keys : NULL, i == 0 ? ctx->nkeys : 0,
+ options.hash_known_hosts, 0,
+ options.fingerprint_hash)) != 0) {
+ error_fr(r, "hostfile_replace_entries failed for %s",
+ options.user_hostfiles[i]);
+ }
+ }
}
static void
@@ -1926,7 +2102,7 @@ client_global_hostkeys_private_confirm(struct ssh *ssh, int type,
size_t siglen;
if (ctx->nnew == 0)
- fatal("%s: ctx->nnew == 0", __func__); /* sanity */
+ fatal_f("ctx->nnew == 0"); /* sanity */
if (type != SSH2_MSG_REQUEST_SUCCESS) {
error("Server failed to confirm ownership of "
"private host keys");
@@ -1937,31 +2113,26 @@ client_global_hostkeys_private_confirm(struct ssh *ssh, int type,
sshkey_type_from_name(ssh->kex->hostkey_alg));
if ((signdata = sshbuf_new()) == NULL)
- fatal("%s: sshbuf_new failed", __func__);
- /* Don't want to accidentally accept an unbound signature */
- if (ssh->kex->session_id_len == 0)
- fatal("%s: ssh->kex->session_id_len == 0", __func__);
+ fatal_f("sshbuf_new failed");
/*
* Expect a signature for each of the ctx->nnew private keys we
* haven't seen before. They will be in the same order as the
- * ctx->keys where the corresponding ctx->keys_seen[i] == 0.
+ * ctx->keys where the corresponding ctx->keys_match[i] == 0.
*/
for (ndone = i = 0; i < ctx->nkeys; i++) {
- if (ctx->keys_seen[i])
+ if (ctx->keys_match[i])
continue;
/* Prepare data to be signed: session ID, unique string, key */
sshbuf_reset(signdata);
if ( (r = sshbuf_put_cstring(signdata,
"hostkeys-prove-00@openssh.com")) != 0 ||
- (r = sshbuf_put_string(signdata, ssh->kex->session_id,
- ssh->kex->session_id_len)) != 0 ||
+ (r = sshbuf_put_stringb(signdata,
+ ssh->kex->session_id)) != 0 ||
(r = sshkey_puts(ctx->keys[i], signdata)) != 0)
- fatal("%s: failed to prepare signature: %s",
- __func__, ssh_err(r));
+ fatal_fr(r, "compose signdata");
/* Extract and verify signature */
if ((r = sshpkt_get_string_direct(ssh, &sig, &siglen)) != 0) {
- error("%s: couldn't parse message: %s",
- __func__, ssh_err(r));
+ error_fr(r, "parse sig");
goto out;
}
/*
@@ -1970,21 +2141,28 @@ client_global_hostkeys_private_confirm(struct ssh *ssh, int type,
*/
use_kexsigtype = kexsigtype == KEY_RSA &&
sshkey_type_plain(ctx->keys[i]->type) == KEY_RSA;
+ debug3_f("verify %s key %zu using %s sigalg",
+ sshkey_type(ctx->keys[i]), i,
+ use_kexsigtype ? ssh->kex->hostkey_alg : "default");
if ((r = sshkey_verify(ctx->keys[i], sig, siglen,
sshbuf_ptr(signdata), sshbuf_len(signdata),
- use_kexsigtype ? ssh->kex->hostkey_alg : NULL, 0)) != 0) {
- error("%s: server gave bad signature for %s key %zu",
- __func__, sshkey_type(ctx->keys[i]), i);
+ use_kexsigtype ? ssh->kex->hostkey_alg : NULL, 0,
+ NULL)) != 0) {
+ error_fr(r, "server gave bad signature for %s key %zu",
+ sshkey_type(ctx->keys[i]), i);
goto out;
}
/* Key is good. Mark it as 'seen' */
- ctx->keys_seen[i] = 2;
+ ctx->keys_verified[i] = 1;
ndone++;
}
+ /* Shouldn't happen */
if (ndone != ctx->nnew)
- fatal("%s: ndone != ctx->nnew (%zu / %zu)", __func__,
- ndone, ctx->nnew); /* Shouldn't happen */
- ssh_packet_check_eom(ssh);
+ fatal_f("ndone != ctx->nnew (%zu / %zu)", ndone, ctx->nnew);
+ if ((r = sshpkt_get_end(ssh)) != 0) {
+ error_f("protocol error");
+ goto out;
+ }
/* Make the edits to known_hosts */
update_known_hosts(ctx);
@@ -2000,8 +2178,7 @@ static int
key_accepted_by_hostkeyalgs(const struct sshkey *key)
{
const char *ktype = sshkey_ssh_name(key);
- const char *hostkeyalgs = options.hostkeyalgorithms != NULL ?
- options.hostkeyalgorithms : KEX_DEFAULT_PK_ALG;
+ const char *hostkeyalgs = options.hostkeyalgorithms;
if (key == NULL || key->type == KEY_UNSPEC)
return 0;
@@ -2018,9 +2195,8 @@ key_accepted_by_hostkeyalgs(const struct sshkey *key)
* HostkeyAlgorithms preference before they are accepted.
*/
static int
-client_input_hostkeys(void)
+client_input_hostkeys(struct ssh *ssh)
{
- struct ssh *ssh = active_state; /* XXX */
const u_char *blob = NULL;
size_t i, len = 0;
struct sshbuf *buf = NULL;
@@ -2030,9 +2206,10 @@ client_input_hostkeys(void)
static int hostkeys_seen = 0; /* XXX use struct ssh */
extern struct sockaddr_storage hostaddr; /* XXX from ssh.c */
struct hostkeys_update_ctx *ctx = NULL;
+ u_int want;
if (hostkeys_seen)
- fatal("%s: server already sent hostkeys", __func__);
+ fatal_f("server already sent hostkeys");
if (options.update_hostkeys == SSH_UPDATE_HOSTKEYS_ASK &&
options.batch_mode)
return 1; /* won't ask in batchmode, so don't even try */
@@ -2044,57 +2221,59 @@ client_input_hostkeys(void)
sshkey_free(key);
key = NULL;
if ((r = sshpkt_get_string_direct(ssh, &blob, &len)) != 0) {
- error("%s: couldn't parse message: %s",
- __func__, ssh_err(r));
+ error_fr(r, "parse key");
goto out;
}
if ((r = sshkey_from_blob(blob, len, &key)) != 0) {
- error("%s: parse key: %s", __func__, ssh_err(r));
- goto out;
+ do_log2_fr(r, r == SSH_ERR_KEY_TYPE_UNKNOWN ?
+ SYSLOG_LEVEL_DEBUG1 : SYSLOG_LEVEL_ERROR,
+ "convert key");
+ continue;
}
fp = sshkey_fingerprint(key, options.fingerprint_hash,
SSH_FP_DEFAULT);
- debug3("%s: received %s key %s", __func__,
- sshkey_type(key), fp);
+ debug3_f("received %s key %s", sshkey_type(key), fp);
free(fp);
if (!key_accepted_by_hostkeyalgs(key)) {
- debug3("%s: %s key not permitted by HostkeyAlgorithms",
- __func__, sshkey_ssh_name(key));
+ debug3_f("%s key not permitted by "
+ "HostkeyAlgorithms", sshkey_ssh_name(key));
continue;
}
/* Skip certs */
if (sshkey_is_cert(key)) {
- debug3("%s: %s key is a certificate; skipping",
- __func__, sshkey_ssh_name(key));
+ debug3_f("%s key is a certificate; skipping",
+ sshkey_ssh_name(key));
continue;
}
/* Ensure keys are unique */
for (i = 0; i < ctx->nkeys; i++) {
if (sshkey_equal(key, ctx->keys[i])) {
- error("%s: received duplicated %s host key",
- __func__, sshkey_ssh_name(key));
+ error_f("received duplicated %s host key",
+ sshkey_ssh_name(key));
goto out;
}
}
/* Key is good, record it */
if ((tmp = recallocarray(ctx->keys, ctx->nkeys, ctx->nkeys + 1,
sizeof(*ctx->keys))) == NULL)
- fatal("%s: recallocarray failed nkeys = %zu",
- __func__, ctx->nkeys);
+ fatal_f("recallocarray failed nkeys = %zu",
+ ctx->nkeys);
ctx->keys = tmp;
ctx->keys[ctx->nkeys++] = key;
key = NULL;
}
if (ctx->nkeys == 0) {
- debug("%s: server sent no hostkeys", __func__);
+ debug_f("server sent no hostkeys");
goto out;
}
- if ((ctx->keys_seen = calloc(ctx->nkeys,
- sizeof(*ctx->keys_seen))) == NULL)
- fatal("%s: calloc failed", __func__);
+ if ((ctx->keys_match = calloc(ctx->nkeys,
+ sizeof(*ctx->keys_match))) == NULL ||
+ (ctx->keys_verified = calloc(ctx->nkeys,
+ sizeof(*ctx->keys_verified))) == NULL)
+ fatal_f("calloc failed");
get_hostfile_hostname_ipaddr(host,
options.check_host_ip ? (struct sockaddr *)&hostaddr : NULL,
@@ -2102,58 +2281,108 @@ client_input_hostkeys(void)
options.check_host_ip ? &ctx->ip_str : NULL);
/* Find which keys we already know about. */
- if ((r = hostkeys_foreach(options.user_hostfiles[0], hostkeys_find,
- ctx, ctx->host_str, ctx->ip_str,
- HKF_WANT_PARSE_KEY|HKF_WANT_MATCH)) != 0) {
- error("%s: hostkeys_foreach failed: %s", __func__, ssh_err(r));
- goto out;
+ for (i = 0; i < options.num_user_hostfiles; i++) {
+ debug_f("searching %s for %s / %s",
+ options.user_hostfiles[i], ctx->host_str,
+ ctx->ip_str ? ctx->ip_str : "(none)");
+ if ((r = hostkeys_foreach(options.user_hostfiles[i],
+ hostkeys_find, ctx, ctx->host_str, ctx->ip_str,
+ HKF_WANT_PARSE_KEY, 0)) != 0) {
+ if (r == SSH_ERR_SYSTEM_ERROR && errno == ENOENT) {
+ debug_f("hostkeys file %s does not exist",
+ options.user_hostfiles[i]);
+ continue;
+ }
+ error_fr(r, "hostkeys_foreach failed for %s",
+ options.user_hostfiles[i]);
+ goto out;
+ }
}
/* Figure out if we have any new keys to add */
- ctx->nnew = 0;
+ ctx->nnew = ctx->nincomplete = 0;
+ want = HKF_MATCH_HOST | ( options.check_host_ip ? HKF_MATCH_IP : 0);
for (i = 0; i < ctx->nkeys; i++) {
- if (!ctx->keys_seen[i])
+ if (ctx->keys_match[i] == 0)
ctx->nnew++;
+ if ((ctx->keys_match[i] & want) != want)
+ ctx->nincomplete++;
}
- debug3("%s: %zu keys from server: %zu new, %zu retained. %zu to remove",
- __func__, ctx->nkeys, ctx->nnew, ctx->nkeys - ctx->nnew, ctx->nold);
+ debug3_f("%zu server keys: %zu new, %zu retained, "
+ "%zu incomplete match. %zu to remove", ctx->nkeys, ctx->nnew,
+ ctx->nkeys - ctx->nnew - ctx->nincomplete,
+ ctx->nincomplete, ctx->nold);
- if (ctx->nnew == 0 && ctx->nold != 0) {
- /* We have some keys to remove. Just do it. */
- update_known_hosts(ctx);
- } else if (ctx->nnew != 0) {
+ if (ctx->nnew == 0 && ctx->nold == 0) {
+ debug_f("no new or deprecated keys from server");
+ goto out;
+ }
+
+ /* Various reasons why we cannot proceed with the update */
+ if (ctx->complex_hostspec) {
+ debug_f("CA/revocation marker, manual host list or wildcard "
+ "host pattern found, skipping UserKnownHostsFile update");
+ goto out;
+ }
+ if (ctx->other_name_seen) {
+ debug_f("host key found matching a different name/address, "
+ "skipping UserKnownHostsFile update");
+ goto out;
+ }
+ /*
+ * If removing keys, check whether they appear under different
+ * names/addresses and refuse to proceed if they do. This avoids
+ * cases such as hosts with multiple names becoming inconsistent
+ * with regards to CheckHostIP entries.
+ * XXX UpdateHostkeys=force to override this (and other) checks?
+ */
+ if (ctx->nold != 0) {
+ if (check_old_keys_othernames(ctx) != 0)
+ goto out; /* error already logged */
+ if (ctx->old_key_seen) {
+ debug_f("key(s) for %s%s%s exist under other names; "
+ "skipping UserKnownHostsFile update",
+ ctx->host_str, ctx->ip_str == NULL ? "" : ",",
+ ctx->ip_str == NULL ? "" : ctx->ip_str);
+ goto out;
+ }
+ }
+
+ if (ctx->nnew == 0) {
/*
- * We have received hitherto-unseen keys from the server.
- * Ask the server to confirm ownership of the private halves.
+ * We have some keys to remove or fix matching for.
+ * We can proceed to do this without requiring a fresh proof
+ * from the server.
*/
- debug3("%s: asking server to prove ownership for %zu keys",
- __func__, ctx->nnew);
- if ((r = sshpkt_start(ssh, SSH2_MSG_GLOBAL_REQUEST)) != 0 ||
- (r = sshpkt_put_cstring(ssh,
- "hostkeys-prove-00@openssh.com")) != 0 ||
- (r = sshpkt_put_u8(ssh, 1)) != 0) /* bool: want reply */
- fatal("%s: cannot prepare packet: %s",
- __func__, ssh_err(r));
- if ((buf = sshbuf_new()) == NULL)
- fatal("%s: sshbuf_new", __func__);
- for (i = 0; i < ctx->nkeys; i++) {
- if (ctx->keys_seen[i])
- continue;
- sshbuf_reset(buf);
- if ((r = sshkey_putb(ctx->keys[i], buf)) != 0)
- fatal("%s: sshkey_putb: %s",
- __func__, ssh_err(r));
- if ((r = sshpkt_put_stringb(ssh, buf)) != 0)
- fatal("%s: sshpkt_put_string: %s",
- __func__, ssh_err(r));
- }
- if ((r = sshpkt_send(ssh)) != 0)
- fatal("%s: sshpkt_send: %s", __func__, ssh_err(r));
- client_register_global_confirm(
- client_global_hostkeys_private_confirm, ctx);
- ctx = NULL; /* will be freed in callback */
+ update_known_hosts(ctx);
+ goto out;
}
+ /*
+ * We have received previously-unseen keys from the server.
+ * Ask the server to confirm ownership of the private halves.
+ */
+ debug3_f("asking server to prove ownership for %zu keys", ctx->nnew);
+ if ((r = sshpkt_start(ssh, SSH2_MSG_GLOBAL_REQUEST)) != 0 ||
+ (r = sshpkt_put_cstring(ssh,
+ "hostkeys-prove-00@openssh.com")) != 0 ||
+ (r = sshpkt_put_u8(ssh, 1)) != 0) /* bool: want reply */
+ fatal_fr(r, "prepare hostkeys-prove");
+ if ((buf = sshbuf_new()) == NULL)
+ fatal_f("sshbuf_new");
+ for (i = 0; i < ctx->nkeys; i++) {
+ if (ctx->keys_match[i])
+ continue;
+ sshbuf_reset(buf);
+ if ((r = sshkey_putb(ctx->keys[i], buf)) != 0 ||
+ (r = sshpkt_put_stringb(ssh, buf)) != 0)
+ fatal_fr(r, "assemble hostkeys-prove");
+ }
+ if ((r = sshpkt_send(ssh)) != 0)
+ fatal_fr(r, "send hostkeys-prove");
+ client_register_global_confirm(
+ client_global_hostkeys_private_confirm, ctx);
+ ctx = NULL; /* will be freed in callback */
/* Success */
out:
@@ -2171,23 +2400,40 @@ static int
client_input_global_request(int type, u_int32_t seq, struct ssh *ssh)
{
char *rtype;
- int want_reply;
- int success = 0;
+ u_char want_reply;
+ int r, success = 0;
- rtype = packet_get_cstring(NULL);
- want_reply = packet_get_char();
+ if ((r = sshpkt_get_cstring(ssh, &rtype, NULL)) != 0 ||
+ (r = sshpkt_get_u8(ssh, &want_reply)) != 0)
+ goto out;
debug("client_input_global_request: rtype %s want_reply %d",
rtype, want_reply);
if (strcmp(rtype, "hostkeys-00@openssh.com") == 0)
- success = client_input_hostkeys();
+ success = client_input_hostkeys(ssh);
if (want_reply) {
- packet_start(success ?
- SSH2_MSG_REQUEST_SUCCESS : SSH2_MSG_REQUEST_FAILURE);
- packet_send();
- packet_write_wait();
+ if ((r = sshpkt_start(ssh, success ? SSH2_MSG_REQUEST_SUCCESS :
+ SSH2_MSG_REQUEST_FAILURE)) != 0 ||
+ (r = sshpkt_send(ssh)) != 0 ||
+ (r = ssh_packet_write_wait(ssh)) != 0)
+ goto out;
}
+ r = 0;
+ out:
free(rtype);
- return 0;
+ return r;
+}
+
+static void
+client_send_env(struct ssh *ssh, int id, const char *name, const char *val)
+{
+ int r;
+
+ debug("channel %d: setting env %s = \"%s\"", id, name, val);
+ channel_request_start(ssh, id, "env", 0);
+ if ((r = sshpkt_put_cstring(ssh, name)) != 0 ||
+ (r = sshpkt_put_cstring(ssh, val)) != 0 ||
+ (r = sshpkt_send(ssh)) != 0)
+ fatal_fr(r, "send setenv");
}
void
@@ -2195,36 +2441,39 @@ client_session2_setup(struct ssh *ssh, int id, int want_tty, int want_subsystem,
const char *term, struct termios *tiop, int in_fd, struct sshbuf *cmd,
char **env)
{
- int i, j, matched, len;
+ int i, j, matched, len, r;
char *name, *val;
Channel *c = NULL;
- debug2("%s: id %d", __func__, id);
+ debug2_f("id %d", id);
if ((c = channel_lookup(ssh, id)) == NULL)
- fatal("%s: channel %d: unknown channel", __func__, id);
+ fatal_f("channel %d: unknown channel", id);
- packet_set_interactive(want_tty,
+ ssh_packet_set_interactive(ssh, want_tty,
options.ip_qos_interactive, options.ip_qos_bulk);
if (want_tty) {
struct winsize ws;
/* Store window size in the packet. */
- if (ioctl(in_fd, TIOCGWINSZ, &ws) < 0)
+ if (ioctl(in_fd, TIOCGWINSZ, &ws) == -1)
memset(&ws, 0, sizeof(ws));
channel_request_start(ssh, id, "pty-req", 1);
client_expect_confirm(ssh, id, "PTY allocation", CONFIRM_TTY);
- packet_put_cstring(term != NULL ? term : "");
- packet_put_int((u_int)ws.ws_col);
- packet_put_int((u_int)ws.ws_row);
- packet_put_int((u_int)ws.ws_xpixel);
- packet_put_int((u_int)ws.ws_ypixel);
+ if ((r = sshpkt_put_cstring(ssh, term != NULL ? term : ""))
+ != 0 ||
+ (r = sshpkt_put_u32(ssh, (u_int)ws.ws_col)) != 0 ||
+ (r = sshpkt_put_u32(ssh, (u_int)ws.ws_row)) != 0 ||
+ (r = sshpkt_put_u32(ssh, (u_int)ws.ws_xpixel)) != 0 ||
+ (r = sshpkt_put_u32(ssh, (u_int)ws.ws_ypixel)) != 0)
+ fatal_fr(r, "build pty-req");
if (tiop == NULL)
tiop = get_saved_tio();
ssh_tty_make_modes(ssh, -1, tiop);
- packet_send();
+ if ((r = sshpkt_send(ssh)) != 0)
+ fatal_fr(r, "send pty-req");
/* XXX wait for reply */
c->client_tty = 1;
}
@@ -2253,12 +2502,7 @@ client_session2_setup(struct ssh *ssh, int id, int want_tty, int want_subsystem,
free(name);
continue;
}
-
- debug("Sending env %s = %s", name, val);
- channel_request_start(ssh, id, "env", 0);
- packet_put_cstring(name);
- packet_put_cstring(val);
- packet_send();
+ client_send_env(ssh, id, name, val);
free(name);
}
}
@@ -2270,12 +2514,7 @@ client_session2_setup(struct ssh *ssh, int id, int want_tty, int want_subsystem,
continue;
}
*val++ = '\0';
-
- debug("Setting env %s = %s", name, val);
- channel_request_start(ssh, id, "env", 0);
- packet_put_cstring(name);
- packet_put_cstring(val);
- packet_send();
+ client_send_env(ssh, id, name, val);
free(name);
}
@@ -2295,39 +2534,41 @@ client_session2_setup(struct ssh *ssh, int id, int want_tty, int want_subsystem,
channel_request_start(ssh, id, "exec", 1);
client_expect_confirm(ssh, id, "exec", CONFIRM_CLOSE);
}
- packet_put_string(sshbuf_ptr(cmd), sshbuf_len(cmd));
- packet_send();
+ if ((r = sshpkt_put_stringb(ssh, cmd)) != 0 ||
+ (r = sshpkt_send(ssh)) != 0)
+ fatal_fr(r, "send command");
} else {
channel_request_start(ssh, id, "shell", 1);
client_expect_confirm(ssh, id, "shell", CONFIRM_CLOSE);
- packet_send();
+ if ((r = sshpkt_send(ssh)) != 0)
+ fatal_fr(r, "send shell");
}
}
static void
-client_init_dispatch(void)
+client_init_dispatch(struct ssh *ssh)
{
- dispatch_init(&dispatch_protocol_error);
-
- dispatch_set(SSH2_MSG_CHANNEL_CLOSE, &channel_input_oclose);
- dispatch_set(SSH2_MSG_CHANNEL_DATA, &channel_input_data);
- dispatch_set(SSH2_MSG_CHANNEL_EOF, &channel_input_ieof);
- dispatch_set(SSH2_MSG_CHANNEL_EXTENDED_DATA, &channel_input_extended_data);
- dispatch_set(SSH2_MSG_CHANNEL_OPEN, &client_input_channel_open);
- dispatch_set(SSH2_MSG_CHANNEL_OPEN_CONFIRMATION, &channel_input_open_confirmation);
- dispatch_set(SSH2_MSG_CHANNEL_OPEN_FAILURE, &channel_input_open_failure);
- dispatch_set(SSH2_MSG_CHANNEL_REQUEST, &client_input_channel_req);
- dispatch_set(SSH2_MSG_CHANNEL_WINDOW_ADJUST, &channel_input_window_adjust);
- dispatch_set(SSH2_MSG_CHANNEL_SUCCESS, &channel_input_status_confirm);
- dispatch_set(SSH2_MSG_CHANNEL_FAILURE, &channel_input_status_confirm);
- dispatch_set(SSH2_MSG_GLOBAL_REQUEST, &client_input_global_request);
+ ssh_dispatch_init(ssh, &dispatch_protocol_error);
+
+ ssh_dispatch_set(ssh, SSH2_MSG_CHANNEL_CLOSE, &channel_input_oclose);
+ ssh_dispatch_set(ssh, SSH2_MSG_CHANNEL_DATA, &channel_input_data);
+ ssh_dispatch_set(ssh, SSH2_MSG_CHANNEL_EOF, &channel_input_ieof);
+ ssh_dispatch_set(ssh, SSH2_MSG_CHANNEL_EXTENDED_DATA, &channel_input_extended_data);
+ ssh_dispatch_set(ssh, SSH2_MSG_CHANNEL_OPEN, &client_input_channel_open);
+ ssh_dispatch_set(ssh, SSH2_MSG_CHANNEL_OPEN_CONFIRMATION, &channel_input_open_confirmation);
+ ssh_dispatch_set(ssh, SSH2_MSG_CHANNEL_OPEN_FAILURE, &channel_input_open_failure);
+ ssh_dispatch_set(ssh, SSH2_MSG_CHANNEL_REQUEST, &client_input_channel_req);
+ ssh_dispatch_set(ssh, SSH2_MSG_CHANNEL_WINDOW_ADJUST, &channel_input_window_adjust);
+ ssh_dispatch_set(ssh, SSH2_MSG_CHANNEL_SUCCESS, &channel_input_status_confirm);
+ ssh_dispatch_set(ssh, SSH2_MSG_CHANNEL_FAILURE, &channel_input_status_confirm);
+ ssh_dispatch_set(ssh, SSH2_MSG_GLOBAL_REQUEST, &client_input_global_request);
/* rekeying */
- dispatch_set(SSH2_MSG_KEXINIT, &kex_input_kexinit);
+ ssh_dispatch_set(ssh, SSH2_MSG_KEXINIT, &kex_input_kexinit);
/* global request reply messages */
- dispatch_set(SSH2_MSG_REQUEST_FAILURE, &client_global_request_reply);
- dispatch_set(SSH2_MSG_REQUEST_SUCCESS, &client_global_request_reply);
+ ssh_dispatch_set(ssh, SSH2_MSG_REQUEST_FAILURE, &client_global_request_reply);
+ ssh_dispatch_set(ssh, SSH2_MSG_REQUEST_SUCCESS, &client_global_request_reply);
}
void
@@ -2339,7 +2580,7 @@ client_stop_mux(void)
* If we are in persist mode, or don't have a shell, signal that we
* should close when all active channels are closed.
*/
- if (options.control_persist || no_shell_flag) {
+ if (options.control_persist || options.session_type == SESSION_TYPE_NONE) {
session_closed = 1;
setproctitle("[stopped mux]");
}
@@ -2350,7 +2591,6 @@ void
cleanup_exit(int i)
{
leave_raw_mode(options.request_tty == REQUEST_TTY_FORCE);
- leave_non_blocking();
if (options.control_path != NULL && muxserver_sock != -1)
unlink(options.control_path);
ssh_kill_proxy_command();
diff --git a/crypto/openssh/clientloop.h b/crypto/openssh/clientloop.h
index bf79c87bf89d..31630551b23c 100644
--- a/crypto/openssh/clientloop.h
+++ b/crypto/openssh/clientloop.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: clientloop.h,v 1.36 2018/07/09 21:03:30 markus Exp $ */
+/* $OpenBSD: clientloop.h,v 1.37 2020/04/03 02:40:32 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -46,7 +46,8 @@ int client_x11_get_proto(struct ssh *, const char *, const char *,
void client_global_request_reply_fwd(int, u_int32_t, void *);
void client_session2_setup(struct ssh *, int, int, int,
const char *, struct termios *, int, struct sshbuf *, char **);
-char *client_request_tun_fwd(struct ssh *, int, int, int);
+char *client_request_tun_fwd(struct ssh *, int, int, int,
+ channel_open_fn *, void *);
void client_stop_mux(void);
/* Escape filter for protocol 2 sessions */
diff --git a/crypto/openssh/compat.c b/crypto/openssh/compat.c
index 0624dc6de13f..3f153bd424f8 100644
--- a/crypto/openssh/compat.c
+++ b/crypto/openssh/compat.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: compat.c,v 1.113 2018/08/13 02:41:05 djm Exp $ */
+/* $OpenBSD: compat.c,v 1.118 2021/06/06 03:40:39 djm Exp $ */
/*
* Copyright (c) 1999, 2000, 2001, 2002 Markus Friedl. All rights reserved.
*
@@ -38,11 +38,9 @@
#include "match.h"
#include "kex.h"
-int datafellows = 0;
-
-/* datafellows bug compatibility */
-u_int
-compat_datafellows(const char *version)
+/* determine bug flags from SSH protocol banner */
+void
+compat_banner(struct ssh *ssh, const char *version)
{
int i;
static struct {
@@ -65,6 +63,8 @@ compat_datafellows(const char *version)
{ "OpenSSH_6.5*,"
"OpenSSH_6.6*", SSH_NEW_OPENSSH|SSH_BUG_CURVE25519PAD|
SSH_BUG_SIGTYPE},
+ { "OpenSSH_7.4*", SSH_NEW_OPENSSH|SSH_BUG_SIGTYPE|
+ SSH_BUG_SIGTYPE74},
{ "OpenSSH_7.0*,"
"OpenSSH_7.1*,"
"OpenSSH_7.2*,"
@@ -145,89 +145,63 @@ compat_datafellows(const char *version)
};
/* process table, return first match */
+ ssh->compat = 0;
for (i = 0; check[i].pat; i++) {
if (match_pattern_list(version, check[i].pat, 0) == 1) {
- debug("match: %s pat %s compat 0x%08x",
+ debug_f("match: %s pat %s compat 0x%08x",
version, check[i].pat, check[i].bugs);
- datafellows = check[i].bugs; /* XXX for now */
- return check[i].bugs;
- }
- }
- debug("no match: %s", version);
- return 0;
-}
-
-#define SEP ","
-int
-proto_spec(const char *spec)
-{
- char *s, *p, *q;
- int ret = SSH_PROTO_UNKNOWN;
-
- if (spec == NULL)
- return ret;
- q = s = strdup(spec);
- if (s == NULL)
- return ret;
- for ((p = strsep(&q, SEP)); p && *p != '\0'; (p = strsep(&q, SEP))) {
- switch (atoi(p)) {
- case 2:
- ret |= SSH_PROTO_2;
- break;
- default:
- logit("ignoring bad proto spec: '%s'.", p);
- break;
+ ssh->compat = check[i].bugs;
+ return;
}
}
- free(s);
- return ret;
+ debug_f("no match: %s", version);
}
char *
-compat_cipher_proposal(char *cipher_prop)
+compat_cipher_proposal(struct ssh *ssh, char *cipher_prop)
{
- if (!(datafellows & SSH_BUG_BIGENDIANAES))
+ if (!(ssh->compat & SSH_BUG_BIGENDIANAES))
return cipher_prop;
- debug2("%s: original cipher proposal: %s", __func__, cipher_prop);
- if ((cipher_prop = match_filter_blacklist(cipher_prop, "aes*")) == NULL)
- fatal("match_filter_blacklist failed");
- debug2("%s: compat cipher proposal: %s", __func__, cipher_prop);
+ debug2_f("original cipher proposal: %s", cipher_prop);
+ if ((cipher_prop = match_filter_denylist(cipher_prop, "aes*")) == NULL)
+ fatal("match_filter_denylist failed");
+ debug2_f("compat cipher proposal: %s", cipher_prop);
if (*cipher_prop == '\0')
fatal("No supported ciphers found");
return cipher_prop;
}
char *
-compat_pkalg_proposal(char *pkalg_prop)
+compat_pkalg_proposal(struct ssh *ssh, char *pkalg_prop)
{
- if (!(datafellows & SSH_BUG_RSASIGMD5))
+ if (!(ssh->compat & SSH_BUG_RSASIGMD5))
return pkalg_prop;
- debug2("%s: original public key proposal: %s", __func__, pkalg_prop);
- if ((pkalg_prop = match_filter_blacklist(pkalg_prop, "ssh-rsa")) == NULL)
- fatal("match_filter_blacklist failed");
- debug2("%s: compat public key proposal: %s", __func__, pkalg_prop);
+ debug2_f("original public key proposal: %s", pkalg_prop);
+ if ((pkalg_prop = match_filter_denylist(pkalg_prop, "ssh-rsa")) == NULL)
+ fatal("match_filter_denylist failed");
+ debug2_f("compat public key proposal: %s", pkalg_prop);
if (*pkalg_prop == '\0')
fatal("No supported PK algorithms found");
return pkalg_prop;
}
char *
-compat_kex_proposal(char *p)
+compat_kex_proposal(struct ssh *ssh, char *p)
{
- if ((datafellows & (SSH_BUG_CURVE25519PAD|SSH_OLD_DHGEX)) == 0)
+ if ((ssh->compat & (SSH_BUG_CURVE25519PAD|SSH_OLD_DHGEX)) == 0)
return p;
- debug2("%s: original KEX proposal: %s", __func__, p);
- if ((datafellows & SSH_BUG_CURVE25519PAD) != 0)
- if ((p = match_filter_blacklist(p,
+ debug2_f("original KEX proposal: %s", p);
+ if ((ssh->compat & SSH_BUG_CURVE25519PAD) != 0)
+ if ((p = match_filter_denylist(p,
"curve25519-sha256@libssh.org")) == NULL)
- fatal("match_filter_blacklist failed");
- if ((datafellows & SSH_OLD_DHGEX) != 0) {
- if ((p = match_filter_blacklist(p,
+ fatal("match_filter_denylist failed");
+ if ((ssh->compat & SSH_OLD_DHGEX) != 0) {
+ if ((p = match_filter_denylist(p,
"diffie-hellman-group-exchange-sha256,"
"diffie-hellman-group-exchange-sha1")) == NULL)
- fatal("match_filter_blacklist failed");
+ fatal("match_filter_denylist failed");
}
- debug2("%s: compat KEX proposal: %s", __func__, p);
+ debug2_f("compat KEX proposal: %s", p);
if (*p == '\0')
fatal("No supported key exchange algorithms found");
return p;
diff --git a/crypto/openssh/compat.h b/crypto/openssh/compat.h
index d611d33e7363..167409b2bd33 100644
--- a/crypto/openssh/compat.h
+++ b/crypto/openssh/compat.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: compat.h,v 1.54 2018/08/13 02:41:05 djm Exp $ */
+/* $OpenBSD: compat.h,v 1.57 2021/06/06 03:40:39 djm Exp $ */
/*
* Copyright (c) 1999, 2000, 2001 Markus Friedl. All rights reserved.
@@ -27,14 +27,9 @@
#ifndef COMPAT_H
#define COMPAT_H
-#define SSH_PROTO_UNKNOWN 0x00
-#define SSH_PROTO_1 0x01
-#define SSH_PROTO_1_PREFERRED 0x02
-#define SSH_PROTO_2 0x04
-
#define SSH_BUG_UTF8TTYMODE 0x00000001
#define SSH_BUG_SIGTYPE 0x00000002
-/* #define unused 0x00000004 */
+#define SSH_BUG_SIGTYPE74 0x00000004
/* #define unused 0x00000008 */
#define SSH_OLD_SESSIONID 0x00000010
/* #define unused 0x00000020 */
@@ -63,11 +58,10 @@
#define SSH_BUG_HOSTKEYS 0x20000000
#define SSH_BUG_DHGEX_LARGE 0x40000000
-u_int compat_datafellows(const char *);
-int proto_spec(const char *);
-char *compat_cipher_proposal(char *);
-char *compat_pkalg_proposal(char *);
-char *compat_kex_proposal(char *);
+struct ssh;
-extern int datafellows;
+void compat_banner(struct ssh *, const char *);
+char *compat_cipher_proposal(struct ssh *, char *);
+char *compat_pkalg_proposal(struct ssh *, char *);
+char *compat_kex_proposal(struct ssh *, char *);
#endif
diff --git a/crypto/openssh/config.guess b/crypto/openssh/config.guess
index c4bd827a7bed..11fda528bc7b 100755
--- a/crypto/openssh/config.guess
+++ b/crypto/openssh/config.guess
@@ -1,8 +1,8 @@
#! /bin/sh
# Attempt to guess a canonical system name.
-# Copyright 1992-2016 Free Software Foundation, Inc.
+# Copyright 1992-2020 Free Software Foundation, Inc.
-timestamp='2016-05-15'
+timestamp='2020-04-26'
# This file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
@@ -15,7 +15,7 @@ timestamp='2016-05-15'
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
-# along with this program; if not, see <http://www.gnu.org/licenses/>.
+# along with this program; if not, see <https://www.gnu.org/licenses/>.
#
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
@@ -27,7 +27,7 @@ timestamp='2016-05-15'
# Originally written by Per Bothner; maintained since 2000 by Ben Elliston.
#
# You can get the latest version of this script from:
-# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess
+# https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess
#
# Please send patches to <config-patches@gnu.org>.
@@ -39,7 +39,7 @@ Usage: $0 [OPTION]
Output the configuration name of the system \`$me' is run on.
-Operation modes:
+Options:
-h, --help print this help, then exit
-t, --time-stamp print date of last modification, then exit
-v, --version print version number, then exit
@@ -50,7 +50,7 @@ version="\
GNU config.guess ($timestamp)
Originally written by Per Bothner.
-Copyright 1992-2016 Free Software Foundation, Inc.
+Copyright 1992-2020 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
@@ -84,8 +84,6 @@ if test $# != 0; then
exit 1
fi
-trap 'exit 1' 1 2 15
-
# CC_FOR_BUILD -- compiler used by this script. Note that the use of a
# compiler to aid in system detection is discouraged as it requires
# temporary files to be created and, as you can see below, it is a
@@ -96,34 +94,40 @@ trap 'exit 1' 1 2 15
# Portable tmp directory creation inspired by the Autoconf team.
-set_cc_for_build='
-trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ;
-trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ;
-: ${TMPDIR=/tmp} ;
- { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } ||
- { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } ||
- { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } ||
- { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ;
-dummy=$tmp/dummy ;
-tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ;
-case $CC_FOR_BUILD,$HOST_CC,$CC in
- ,,) echo "int x;" > $dummy.c ;
- for c in cc gcc c89 c99 ; do
- if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then
- CC_FOR_BUILD="$c"; break ;
- fi ;
- done ;
- if test x"$CC_FOR_BUILD" = x ; then
- CC_FOR_BUILD=no_compiler_found ;
- fi
- ;;
- ,,*) CC_FOR_BUILD=$CC ;;
- ,*,*) CC_FOR_BUILD=$HOST_CC ;;
-esac ; set_cc_for_build= ;'
+tmp=
+# shellcheck disable=SC2172
+trap 'test -z "$tmp" || rm -fr "$tmp"' 0 1 2 13 15
+
+set_cc_for_build() {
+ # prevent multiple calls if $tmp is already set
+ test "$tmp" && return 0
+ : "${TMPDIR=/tmp}"
+ # shellcheck disable=SC2039
+ { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } ||
+ { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir "$tmp" 2>/dev/null) ; } ||
+ { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir "$tmp" 2>/dev/null) && echo "Warning: creating insecure temp directory" >&2 ; } ||
+ { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; }
+ dummy=$tmp/dummy
+ case ${CC_FOR_BUILD-},${HOST_CC-},${CC-} in
+ ,,) echo "int x;" > "$dummy.c"
+ for driver in cc gcc c89 c99 ; do
+ if ($driver -c -o "$dummy.o" "$dummy.c") >/dev/null 2>&1 ; then
+ CC_FOR_BUILD="$driver"
+ break
+ fi
+ done
+ if test x"$CC_FOR_BUILD" = x ; then
+ CC_FOR_BUILD=no_compiler_found
+ fi
+ ;;
+ ,,*) CC_FOR_BUILD=$CC ;;
+ ,*,*) CC_FOR_BUILD=$HOST_CC ;;
+ esac
+}
# This is needed to find uname on a Pyramid OSx when run in the BSD universe.
# (ghazi@noc.rutgers.edu 1994-08-24)
-if (test -f /.attbin/uname) >/dev/null 2>&1 ; then
+if test -f /.attbin/uname ; then
PATH=$PATH:/.attbin ; export PATH
fi
@@ -132,14 +136,14 @@ UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown
UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown
UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown
-case "${UNAME_SYSTEM}" in
+case "$UNAME_SYSTEM" in
Linux|GNU|GNU/*)
# If the system lacks a compiler, then just pick glibc.
# We could probably try harder.
LIBC=gnu
- eval $set_cc_for_build
- cat <<-EOF > $dummy.c
+ set_cc_for_build
+ cat <<-EOF > "$dummy.c"
#include <features.h>
#if defined(__UCLIBC__)
LIBC=uclibc
@@ -149,13 +153,20 @@ Linux|GNU|GNU/*)
LIBC=gnu
#endif
EOF
- eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC' | sed 's, ,,g'`
+ eval "`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^LIBC' | sed 's, ,,g'`"
+
+ # If ldd exists, use it to detect musl libc.
+ if command -v ldd >/dev/null && \
+ ldd --version 2>&1 | grep -q ^musl
+ then
+ LIBC=musl
+ fi
;;
esac
# Note: order is significant - the case branches are not exclusive.
-case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
+case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in
*:NetBSD:*:*)
# NetBSD (nbsd) targets should (where applicable) match one or
# more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*,
@@ -169,30 +180,30 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
# portion of the name. We always set it to "unknown".
sysctl="sysctl -n hw.machine_arch"
UNAME_MACHINE_ARCH=`(uname -p 2>/dev/null || \
- /sbin/$sysctl 2>/dev/null || \
- /usr/sbin/$sysctl 2>/dev/null || \
+ "/sbin/$sysctl" 2>/dev/null || \
+ "/usr/sbin/$sysctl" 2>/dev/null || \
echo unknown)`
- case "${UNAME_MACHINE_ARCH}" in
+ case "$UNAME_MACHINE_ARCH" in
armeb) machine=armeb-unknown ;;
arm*) machine=arm-unknown ;;
sh3el) machine=shl-unknown ;;
sh3eb) machine=sh-unknown ;;
sh5el) machine=sh5le-unknown ;;
earmv*)
- arch=`echo ${UNAME_MACHINE_ARCH} | sed -e 's,^e\(armv[0-9]\).*$,\1,'`
- endian=`echo ${UNAME_MACHINE_ARCH} | sed -ne 's,^.*\(eb\)$,\1,p'`
- machine=${arch}${endian}-unknown
+ arch=`echo "$UNAME_MACHINE_ARCH" | sed -e 's,^e\(armv[0-9]\).*$,\1,'`
+ endian=`echo "$UNAME_MACHINE_ARCH" | sed -ne 's,^.*\(eb\)$,\1,p'`
+ machine="${arch}${endian}"-unknown
;;
- *) machine=${UNAME_MACHINE_ARCH}-unknown ;;
+ *) machine="$UNAME_MACHINE_ARCH"-unknown ;;
esac
# The Operating System including object format, if it has switched
# to ELF recently (or will in the future) and ABI.
- case "${UNAME_MACHINE_ARCH}" in
+ case "$UNAME_MACHINE_ARCH" in
earm*)
os=netbsdelf
;;
arm*|i386|m68k|ns32k|sh3*|sparc|vax)
- eval $set_cc_for_build
+ set_cc_for_build
if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \
| grep -q __ELF__
then
@@ -208,10 +219,10 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
;;
esac
# Determine ABI tags.
- case "${UNAME_MACHINE_ARCH}" in
+ case "$UNAME_MACHINE_ARCH" in
earm*)
expr='s/^earmv[0-9]/-eabi/;s/eb$//'
- abi=`echo ${UNAME_MACHINE_ARCH} | sed -e "$expr"`
+ abi=`echo "$UNAME_MACHINE_ARCH" | sed -e "$expr"`
;;
esac
# The OS release
@@ -219,45 +230,60 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
# thus, need a distinct triplet. However, they do not need
# kernel version information, so it can be replaced with a
# suitable tag, in the style of linux-gnu.
- case "${UNAME_VERSION}" in
+ case "$UNAME_VERSION" in
Debian*)
release='-gnu'
;;
*)
- release=`echo ${UNAME_RELEASE} | sed -e 's/[-_].*//' | cut -d. -f1,2`
+ release=`echo "$UNAME_RELEASE" | sed -e 's/[-_].*//' | cut -d. -f1,2`
;;
esac
# Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM:
# contains redundant information, the shorter form:
# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used.
- echo "${machine}-${os}${release}${abi}"
+ echo "$machine-${os}${release}${abi-}"
exit ;;
*:Bitrig:*:*)
UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'`
- echo ${UNAME_MACHINE_ARCH}-unknown-bitrig${UNAME_RELEASE}
+ echo "$UNAME_MACHINE_ARCH"-unknown-bitrig"$UNAME_RELEASE"
exit ;;
*:OpenBSD:*:*)
UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'`
- echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE}
+ echo "$UNAME_MACHINE_ARCH"-unknown-openbsd"$UNAME_RELEASE"
exit ;;
*:LibertyBSD:*:*)
UNAME_MACHINE_ARCH=`arch | sed 's/^.*BSD\.//'`
- echo ${UNAME_MACHINE_ARCH}-unknown-libertybsd${UNAME_RELEASE}
+ echo "$UNAME_MACHINE_ARCH"-unknown-libertybsd"$UNAME_RELEASE"
+ exit ;;
+ *:MidnightBSD:*:*)
+ echo "$UNAME_MACHINE"-unknown-midnightbsd"$UNAME_RELEASE"
exit ;;
*:ekkoBSD:*:*)
- echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE}
+ echo "$UNAME_MACHINE"-unknown-ekkobsd"$UNAME_RELEASE"
exit ;;
*:SolidBSD:*:*)
- echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE}
+ echo "$UNAME_MACHINE"-unknown-solidbsd"$UNAME_RELEASE"
+ exit ;;
+ *:OS108:*:*)
+ echo "$UNAME_MACHINE"-unknown-os108_"$UNAME_RELEASE"
exit ;;
macppc:MirBSD:*:*)
- echo powerpc-unknown-mirbsd${UNAME_RELEASE}
+ echo powerpc-unknown-mirbsd"$UNAME_RELEASE"
exit ;;
*:MirBSD:*:*)
- echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE}
+ echo "$UNAME_MACHINE"-unknown-mirbsd"$UNAME_RELEASE"
exit ;;
*:Sortix:*:*)
- echo ${UNAME_MACHINE}-unknown-sortix
+ echo "$UNAME_MACHINE"-unknown-sortix
+ exit ;;
+ *:Twizzler:*:*)
+ echo "$UNAME_MACHINE"-unknown-twizzler
+ exit ;;
+ *:Redox:*:*)
+ echo "$UNAME_MACHINE"-unknown-redox
+ exit ;;
+ mips:OSF1:*.*)
+ echo mips-dec-osf1
exit ;;
alpha:OSF1:*:*)
case $UNAME_RELEASE in
@@ -310,28 +336,19 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
# A Tn.n version is a released field test version.
# A Xn.n version is an unreleased experimental baselevel.
# 1.2 uses "1.2" for uname -r.
- echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz`
+ echo "$UNAME_MACHINE"-dec-osf"`echo "$UNAME_RELEASE" | sed -e 's/^[PVTX]//' | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz`"
# Reset EXIT trap before exiting to avoid spurious non-zero exit code.
exitcode=$?
trap '' 0
exit $exitcode ;;
- Alpha\ *:Windows_NT*:*)
- # How do we know it's Interix rather than the generic POSIX subsystem?
- # Should we change UNAME_MACHINE based on the output of uname instead
- # of the specific Alpha model?
- echo alpha-pc-interix
- exit ;;
- 21064:Windows_NT:50:3)
- echo alpha-dec-winnt3.5
- exit ;;
Amiga*:UNIX_System_V:4.0:*)
echo m68k-unknown-sysv4
exit ;;
*:[Aa]miga[Oo][Ss]:*:*)
- echo ${UNAME_MACHINE}-unknown-amigaos
+ echo "$UNAME_MACHINE"-unknown-amigaos
exit ;;
*:[Mm]orph[Oo][Ss]:*:*)
- echo ${UNAME_MACHINE}-unknown-morphos
+ echo "$UNAME_MACHINE"-unknown-morphos
exit ;;
*:OS/390:*:*)
echo i370-ibm-openedition
@@ -343,7 +360,7 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
echo powerpc-ibm-os400
exit ;;
arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
- echo arm-acorn-riscix${UNAME_RELEASE}
+ echo arm-acorn-riscix"$UNAME_RELEASE"
exit ;;
arm*:riscos:*:*|arm*:RISCOS:*:*)
echo arm-unknown-riscos
@@ -370,19 +387,19 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
sparc) echo sparc-icl-nx7; exit ;;
esac ;;
s390x:SunOS:*:*)
- echo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ echo "$UNAME_MACHINE"-ibm-solaris2"`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'`"
exit ;;
sun4H:SunOS:5.*:*)
- echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ echo sparc-hal-solaris2"`echo "$UNAME_RELEASE"|sed -e 's/[^.]*//'`"
exit ;;
sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
- echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ echo sparc-sun-solaris2"`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'`"
exit ;;
i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*)
- echo i386-pc-auroraux${UNAME_RELEASE}
+ echo i386-pc-auroraux"$UNAME_RELEASE"
exit ;;
i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*)
- eval $set_cc_for_build
+ set_cc_for_build
SUN_ARCH=i386
# If there is a compiler, see if it is configured for 64-bit objects.
# Note that the Sun cc does not turn __LP64__ into 1 like gcc does.
@@ -395,13 +412,13 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
SUN_ARCH=x86_64
fi
fi
- echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ echo "$SUN_ARCH"-pc-solaris2"`echo "$UNAME_RELEASE"|sed -e 's/[^.]*//'`"
exit ;;
sun4*:SunOS:6*:*)
# According to config.sub, this is the proper way to canonicalize
# SunOS6. Hard to guess exactly what SunOS6 will be like, but
# it's likely to be more like Solaris than SunOS4.
- echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ echo sparc-sun-solaris3"`echo "$UNAME_RELEASE"|sed -e 's/[^.]*//'`"
exit ;;
sun4*:SunOS:*:*)
case "`/usr/bin/arch -k`" in
@@ -410,25 +427,25 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
;;
esac
# Japanese Language versions have a version number like `4.1.3-JL'.
- echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'`
+ echo sparc-sun-sunos"`echo "$UNAME_RELEASE"|sed -e 's/-/_/'`"
exit ;;
sun3*:SunOS:*:*)
- echo m68k-sun-sunos${UNAME_RELEASE}
+ echo m68k-sun-sunos"$UNAME_RELEASE"
exit ;;
sun*:*:4.2BSD:*)
UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null`
- test "x${UNAME_RELEASE}" = x && UNAME_RELEASE=3
+ test "x$UNAME_RELEASE" = x && UNAME_RELEASE=3
case "`/bin/arch`" in
sun3)
- echo m68k-sun-sunos${UNAME_RELEASE}
+ echo m68k-sun-sunos"$UNAME_RELEASE"
;;
sun4)
- echo sparc-sun-sunos${UNAME_RELEASE}
+ echo sparc-sun-sunos"$UNAME_RELEASE"
;;
esac
exit ;;
aushp:SunOS:*:*)
- echo sparc-auspex-sunos${UNAME_RELEASE}
+ echo sparc-auspex-sunos"$UNAME_RELEASE"
exit ;;
# The situation for MiNT is a little confusing. The machine name
# can be virtually everything (everything which is not
@@ -439,44 +456,44 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
# MiNT. But MiNT is downward compatible to TOS, so this should
# be no problem.
atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*)
- echo m68k-atari-mint${UNAME_RELEASE}
+ echo m68k-atari-mint"$UNAME_RELEASE"
exit ;;
atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*)
- echo m68k-atari-mint${UNAME_RELEASE}
+ echo m68k-atari-mint"$UNAME_RELEASE"
exit ;;
*falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*)
- echo m68k-atari-mint${UNAME_RELEASE}
+ echo m68k-atari-mint"$UNAME_RELEASE"
exit ;;
milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*)
- echo m68k-milan-mint${UNAME_RELEASE}
+ echo m68k-milan-mint"$UNAME_RELEASE"
exit ;;
hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*)
- echo m68k-hades-mint${UNAME_RELEASE}
+ echo m68k-hades-mint"$UNAME_RELEASE"
exit ;;
*:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*)
- echo m68k-unknown-mint${UNAME_RELEASE}
+ echo m68k-unknown-mint"$UNAME_RELEASE"
exit ;;
m68k:machten:*:*)
- echo m68k-apple-machten${UNAME_RELEASE}
+ echo m68k-apple-machten"$UNAME_RELEASE"
exit ;;
powerpc:machten:*:*)
- echo powerpc-apple-machten${UNAME_RELEASE}
+ echo powerpc-apple-machten"$UNAME_RELEASE"
exit ;;
RISC*:Mach:*:*)
echo mips-dec-mach_bsd4.3
exit ;;
RISC*:ULTRIX:*:*)
- echo mips-dec-ultrix${UNAME_RELEASE}
+ echo mips-dec-ultrix"$UNAME_RELEASE"
exit ;;
VAX*:ULTRIX*:*:*)
- echo vax-dec-ultrix${UNAME_RELEASE}
+ echo vax-dec-ultrix"$UNAME_RELEASE"
exit ;;
2020:CLIX:*:* | 2430:CLIX:*:*)
- echo clipper-intergraph-clix${UNAME_RELEASE}
+ echo clipper-intergraph-clix"$UNAME_RELEASE"
exit ;;
mips:*:*:UMIPS | mips:*:*:RISCos)
- eval $set_cc_for_build
- sed 's/^ //' << EOF >$dummy.c
+ set_cc_for_build
+ sed 's/^ //' << EOF > "$dummy.c"
#ifdef __cplusplus
#include <stdio.h> /* for printf() prototype */
int main (int argc, char *argv[]) {
@@ -485,23 +502,23 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
#endif
#if defined (host_mips) && defined (MIPSEB)
#if defined (SYSTYPE_SYSV)
- printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0);
+ printf ("mips-mips-riscos%ssysv\\n", argv[1]); exit (0);
#endif
#if defined (SYSTYPE_SVR4)
- printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0);
+ printf ("mips-mips-riscos%ssvr4\\n", argv[1]); exit (0);
#endif
#if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD)
- printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0);
+ printf ("mips-mips-riscos%sbsd\\n", argv[1]); exit (0);
#endif
#endif
exit (-1);
}
EOF
- $CC_FOR_BUILD -o $dummy $dummy.c &&
- dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` &&
- SYSTEM_NAME=`$dummy $dummyarg` &&
+ $CC_FOR_BUILD -o "$dummy" "$dummy.c" &&
+ dummyarg=`echo "$UNAME_RELEASE" | sed -n 's/\([0-9]*\).*/\1/p'` &&
+ SYSTEM_NAME=`"$dummy" "$dummyarg"` &&
{ echo "$SYSTEM_NAME"; exit; }
- echo mips-mips-riscos${UNAME_RELEASE}
+ echo mips-mips-riscos"$UNAME_RELEASE"
exit ;;
Motorola:PowerMAX_OS:*:*)
echo powerpc-motorola-powermax
@@ -527,17 +544,17 @@ EOF
AViiON:dgux:*:*)
# DG/UX returns AViiON for all architectures
UNAME_PROCESSOR=`/usr/bin/uname -p`
- if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ]
+ if [ "$UNAME_PROCESSOR" = mc88100 ] || [ "$UNAME_PROCESSOR" = mc88110 ]
then
- if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \
- [ ${TARGET_BINARY_INTERFACE}x = x ]
+ if [ "$TARGET_BINARY_INTERFACE"x = m88kdguxelfx ] || \
+ [ "$TARGET_BINARY_INTERFACE"x = x ]
then
- echo m88k-dg-dgux${UNAME_RELEASE}
+ echo m88k-dg-dgux"$UNAME_RELEASE"
else
- echo m88k-dg-dguxbcs${UNAME_RELEASE}
+ echo m88k-dg-dguxbcs"$UNAME_RELEASE"
fi
else
- echo i586-dg-dgux${UNAME_RELEASE}
+ echo i586-dg-dgux"$UNAME_RELEASE"
fi
exit ;;
M88*:DolphinOS:*:*) # DolphinOS (SVR3)
@@ -554,7 +571,7 @@ EOF
echo m68k-tektronix-bsd
exit ;;
*:IRIX*:*:*)
- echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'`
+ echo mips-sgi-irix"`echo "$UNAME_RELEASE"|sed -e 's/-/_/g'`"
exit ;;
????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX.
echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id
@@ -566,14 +583,14 @@ EOF
if [ -x /usr/bin/oslevel ] ; then
IBM_REV=`/usr/bin/oslevel`
else
- IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
+ IBM_REV="$UNAME_VERSION.$UNAME_RELEASE"
fi
- echo ${UNAME_MACHINE}-ibm-aix${IBM_REV}
+ echo "$UNAME_MACHINE"-ibm-aix"$IBM_REV"
exit ;;
*:AIX:2:3)
if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then
- eval $set_cc_for_build
- sed 's/^ //' << EOF >$dummy.c
+ set_cc_for_build
+ sed 's/^ //' << EOF > "$dummy.c"
#include <sys/systemcfg.h>
main()
@@ -584,7 +601,7 @@ EOF
exit(0);
}
EOF
- if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy`
+ if $CC_FOR_BUILD -o "$dummy" "$dummy.c" && SYSTEM_NAME=`"$dummy"`
then
echo "$SYSTEM_NAME"
else
@@ -598,7 +615,7 @@ EOF
exit ;;
*:AIX:*:[4567])
IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'`
- if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then
+ if /usr/sbin/lsattr -El "$IBM_CPU_ID" | grep ' POWER' >/dev/null 2>&1; then
IBM_ARCH=rs6000
else
IBM_ARCH=powerpc
@@ -607,18 +624,18 @@ EOF
IBM_REV=`/usr/bin/lslpp -Lqc bos.rte.libc |
awk -F: '{ print $3 }' | sed s/[0-9]*$/0/`
else
- IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
+ IBM_REV="$UNAME_VERSION.$UNAME_RELEASE"
fi
- echo ${IBM_ARCH}-ibm-aix${IBM_REV}
+ echo "$IBM_ARCH"-ibm-aix"$IBM_REV"
exit ;;
*:AIX:*:*)
echo rs6000-ibm-aix
exit ;;
- ibmrt:4.4BSD:*|romp-ibm:BSD:*)
+ ibmrt:4.4BSD:*|romp-ibm:4.4BSD:*)
echo romp-ibm-bsd4.4
exit ;;
ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and
- echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to
+ echo romp-ibm-bsd"$UNAME_RELEASE" # 4.3 with uname added to
exit ;; # report: romp-ibm BSD 4.3
*:BOSX:*:*)
echo rs6000-bull-bosx
@@ -633,28 +650,28 @@ EOF
echo m68k-hp-bsd4.4
exit ;;
9000/[34678]??:HP-UX:*:*)
- HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
- case "${UNAME_MACHINE}" in
- 9000/31? ) HP_ARCH=m68000 ;;
- 9000/[34]?? ) HP_ARCH=m68k ;;
+ HPUX_REV=`echo "$UNAME_RELEASE"|sed -e 's/[^.]*.[0B]*//'`
+ case "$UNAME_MACHINE" in
+ 9000/31?) HP_ARCH=m68000 ;;
+ 9000/[34]??) HP_ARCH=m68k ;;
9000/[678][0-9][0-9])
if [ -x /usr/bin/getconf ]; then
sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null`
sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`
- case "${sc_cpu_version}" in
+ case "$sc_cpu_version" in
523) HP_ARCH=hppa1.0 ;; # CPU_PA_RISC1_0
528) HP_ARCH=hppa1.1 ;; # CPU_PA_RISC1_1
532) # CPU_PA_RISC2_0
- case "${sc_kernel_bits}" in
+ case "$sc_kernel_bits" in
32) HP_ARCH=hppa2.0n ;;
64) HP_ARCH=hppa2.0w ;;
'') HP_ARCH=hppa2.0 ;; # HP-UX 10.20
esac ;;
esac
fi
- if [ "${HP_ARCH}" = "" ]; then
- eval $set_cc_for_build
- sed 's/^ //' << EOF >$dummy.c
+ if [ "$HP_ARCH" = "" ]; then
+ set_cc_for_build
+ sed 's/^ //' << EOF > "$dummy.c"
#define _HPUX_SOURCE
#include <stdlib.h>
@@ -687,13 +704,13 @@ EOF
exit (0);
}
EOF
- (CCOPTS="" $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy`
+ (CCOPTS="" $CC_FOR_BUILD -o "$dummy" "$dummy.c" 2>/dev/null) && HP_ARCH=`"$dummy"`
test -z "$HP_ARCH" && HP_ARCH=hppa
fi ;;
esac
- if [ ${HP_ARCH} = hppa2.0w ]
+ if [ "$HP_ARCH" = hppa2.0w ]
then
- eval $set_cc_for_build
+ set_cc_for_build
# hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating
# 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler
@@ -712,15 +729,15 @@ EOF
HP_ARCH=hppa64
fi
fi
- echo ${HP_ARCH}-hp-hpux${HPUX_REV}
+ echo "$HP_ARCH"-hp-hpux"$HPUX_REV"
exit ;;
ia64:HP-UX:*:*)
- HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
- echo ia64-hp-hpux${HPUX_REV}
+ HPUX_REV=`echo "$UNAME_RELEASE"|sed -e 's/[^.]*.[0B]*//'`
+ echo ia64-hp-hpux"$HPUX_REV"
exit ;;
3050*:HI-UX:*:*)
- eval $set_cc_for_build
- sed 's/^ //' << EOF >$dummy.c
+ set_cc_for_build
+ sed 's/^ //' << EOF > "$dummy.c"
#include <unistd.h>
int
main ()
@@ -745,11 +762,11 @@ EOF
exit (0);
}
EOF
- $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` &&
+ $CC_FOR_BUILD -o "$dummy" "$dummy.c" && SYSTEM_NAME=`"$dummy"` &&
{ echo "$SYSTEM_NAME"; exit; }
echo unknown-hitachi-hiuxwe2
exit ;;
- 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* )
+ 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:*)
echo hppa1.1-hp-bsd
exit ;;
9000/8??:4.3bsd:*:*)
@@ -758,7 +775,7 @@ EOF
*9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*)
echo hppa1.0-hp-mpeix
exit ;;
- hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* )
+ hp7??:OSF1:*:* | hp8?[79]:OSF1:*:*)
echo hppa1.1-hp-osf
exit ;;
hp8??:OSF1:*:*)
@@ -766,9 +783,9 @@ EOF
exit ;;
i*86:OSF1:*:*)
if [ -x /usr/sbin/sysversion ] ; then
- echo ${UNAME_MACHINE}-unknown-osf1mk
+ echo "$UNAME_MACHINE"-unknown-osf1mk
else
- echo ${UNAME_MACHINE}-unknown-osf1
+ echo "$UNAME_MACHINE"-unknown-osf1
fi
exit ;;
parisc*:Lites*:*:*)
@@ -793,130 +810,123 @@ EOF
echo c4-convex-bsd
exit ;;
CRAY*Y-MP:*:*:*)
- echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+ echo ymp-cray-unicos"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'
exit ;;
CRAY*[A-Z]90:*:*:*)
- echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \
+ echo "$UNAME_MACHINE"-cray-unicos"$UNAME_RELEASE" \
| sed -e 's/CRAY.*\([A-Z]90\)/\1/' \
-e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \
-e 's/\.[^.]*$/.X/'
exit ;;
CRAY*TS:*:*:*)
- echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+ echo t90-cray-unicos"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'
exit ;;
CRAY*T3E:*:*:*)
- echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+ echo alphaev5-cray-unicosmk"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'
exit ;;
CRAY*SV1:*:*:*)
- echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+ echo sv1-cray-unicos"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'
exit ;;
*:UNICOS/mp:*:*)
- echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+ echo craynv-cray-unicosmp"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'
exit ;;
F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*)
FUJITSU_PROC=`uname -m | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz`
FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'`
- FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
+ FUJITSU_REL=`echo "$UNAME_RELEASE" | sed -e 's/ /_/'`
echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
exit ;;
5000:UNIX_System_V:4.*:*)
FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'`
- FUJITSU_REL=`echo ${UNAME_RELEASE} | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/ /_/'`
+ FUJITSU_REL=`echo "$UNAME_RELEASE" | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/ /_/'`
echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
exit ;;
i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*)
- echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE}
+ echo "$UNAME_MACHINE"-pc-bsdi"$UNAME_RELEASE"
exit ;;
sparc*:BSD/OS:*:*)
- echo sparc-unknown-bsdi${UNAME_RELEASE}
+ echo sparc-unknown-bsdi"$UNAME_RELEASE"
exit ;;
*:BSD/OS:*:*)
- echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE}
+ echo "$UNAME_MACHINE"-unknown-bsdi"$UNAME_RELEASE"
+ exit ;;
+ arm:FreeBSD:*:*)
+ UNAME_PROCESSOR=`uname -p`
+ set_cc_for_build
+ if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \
+ | grep -q __ARM_PCS_VFP
+ then
+ echo "${UNAME_PROCESSOR}"-unknown-freebsd"`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`"-gnueabi
+ else
+ echo "${UNAME_PROCESSOR}"-unknown-freebsd"`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`"-gnueabihf
+ fi
exit ;;
*:FreeBSD:*:*)
UNAME_PROCESSOR=`/usr/bin/uname -p`
- case ${UNAME_PROCESSOR} in
+ case "$UNAME_PROCESSOR" in
amd64)
- echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
- *)
- echo ${UNAME_PROCESSOR}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
+ UNAME_PROCESSOR=x86_64 ;;
+ i386)
+ UNAME_PROCESSOR=i586 ;;
esac
+ echo "$UNAME_PROCESSOR"-unknown-freebsd"`echo "$UNAME_RELEASE"|sed -e 's/[-(].*//'`"
exit ;;
i*:CYGWIN*:*)
- echo ${UNAME_MACHINE}-pc-cygwin
+ echo "$UNAME_MACHINE"-pc-cygwin
exit ;;
*:MINGW64*:*)
- echo ${UNAME_MACHINE}-pc-mingw64
+ echo "$UNAME_MACHINE"-pc-mingw64
exit ;;
*:MINGW*:*)
- echo ${UNAME_MACHINE}-pc-mingw32
+ echo "$UNAME_MACHINE"-pc-mingw32
exit ;;
*:MSYS*:*)
- echo ${UNAME_MACHINE}-pc-msys
- exit ;;
- i*:windows32*:*)
- # uname -m includes "-pc" on this system.
- echo ${UNAME_MACHINE}-mingw32
+ echo "$UNAME_MACHINE"-pc-msys
exit ;;
i*:PW*:*)
- echo ${UNAME_MACHINE}-pc-pw32
+ echo "$UNAME_MACHINE"-pc-pw32
exit ;;
*:Interix*:*)
- case ${UNAME_MACHINE} in
+ case "$UNAME_MACHINE" in
x86)
- echo i586-pc-interix${UNAME_RELEASE}
+ echo i586-pc-interix"$UNAME_RELEASE"
exit ;;
authenticamd | genuineintel | EM64T)
- echo x86_64-unknown-interix${UNAME_RELEASE}
+ echo x86_64-unknown-interix"$UNAME_RELEASE"
exit ;;
IA64)
- echo ia64-unknown-interix${UNAME_RELEASE}
+ echo ia64-unknown-interix"$UNAME_RELEASE"
exit ;;
esac ;;
- [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*)
- echo i${UNAME_MACHINE}-pc-mks
- exit ;;
- 8664:Windows_NT:*)
- echo x86_64-pc-mks
- exit ;;
- i*:Windows_NT*:* | Pentium*:Windows_NT*:*)
- # How do we know it's Interix rather than the generic POSIX subsystem?
- # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we
- # UNAME_MACHINE based on the output of uname instead of i386?
- echo i586-pc-interix
- exit ;;
i*:UWIN*:*)
- echo ${UNAME_MACHINE}-pc-uwin
+ echo "$UNAME_MACHINE"-pc-uwin
exit ;;
amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*)
- echo x86_64-unknown-cygwin
- exit ;;
- p*:CYGWIN*:*)
- echo powerpcle-unknown-cygwin
+ echo x86_64-pc-cygwin
exit ;;
prep*:SunOS:5.*:*)
- echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ echo powerpcle-unknown-solaris2"`echo "$UNAME_RELEASE"|sed -e 's/[^.]*//'`"
exit ;;
*:GNU:*:*)
# the GNU system
- echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-${LIBC}`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
+ echo "`echo "$UNAME_MACHINE"|sed -e 's,[-/].*$,,'`-unknown-$LIBC`echo "$UNAME_RELEASE"|sed -e 's,/.*$,,'`"
exit ;;
*:GNU/*:*:*)
# other systems with GNU libc and userland
- echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr "[:upper:]" "[:lower:]"``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-${LIBC}
+ echo "$UNAME_MACHINE-unknown-`echo "$UNAME_SYSTEM" | sed 's,^[^/]*/,,' | tr "[:upper:]" "[:lower:]"``echo "$UNAME_RELEASE"|sed -e 's/[-(].*//'`-$LIBC"
exit ;;
- i*86:Minix:*:*)
- echo ${UNAME_MACHINE}-pc-minix
+ *:Minix:*:*)
+ echo "$UNAME_MACHINE"-unknown-minix
exit ;;
aarch64:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
exit ;;
aarch64_be:Linux:*:*)
UNAME_MACHINE=aarch64_be
- echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
exit ;;
alpha:Linux:*:*)
- case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in
+ case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' /proc/cpuinfo 2>/dev/null` in
EV5) UNAME_MACHINE=alphaev5 ;;
EV56) UNAME_MACHINE=alphaev56 ;;
PCA56) UNAME_MACHINE=alphapca56 ;;
@@ -927,134 +937,168 @@ EOF
esac
objdump --private-headers /bin/sh | grep -q ld.so.1
if test "$?" = 0 ; then LIBC=gnulibc1 ; fi
- echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
exit ;;
arc:Linux:*:* | arceb:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
exit ;;
arm*:Linux:*:*)
- eval $set_cc_for_build
+ set_cc_for_build
if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \
| grep -q __ARM_EABI__
then
- echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
else
if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \
| grep -q __ARM_PCS_VFP
then
- echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabi
+ echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"eabi
else
- echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabihf
+ echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"eabihf
fi
fi
exit ;;
avr32*:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
exit ;;
cris:Linux:*:*)
- echo ${UNAME_MACHINE}-axis-linux-${LIBC}
+ echo "$UNAME_MACHINE"-axis-linux-"$LIBC"
exit ;;
crisv32:Linux:*:*)
- echo ${UNAME_MACHINE}-axis-linux-${LIBC}
+ echo "$UNAME_MACHINE"-axis-linux-"$LIBC"
exit ;;
e2k:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
exit ;;
frv:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
exit ;;
hexagon:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
exit ;;
i*86:Linux:*:*)
- echo ${UNAME_MACHINE}-pc-linux-${LIBC}
+ echo "$UNAME_MACHINE"-pc-linux-"$LIBC"
exit ;;
ia64:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
exit ;;
k1om:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
exit ;;
m32r*:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
exit ;;
m68*:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
exit ;;
mips:Linux:*:* | mips64:Linux:*:*)
- eval $set_cc_for_build
- sed 's/^ //' << EOF >$dummy.c
+ set_cc_for_build
+ IS_GLIBC=0
+ test x"${LIBC}" = xgnu && IS_GLIBC=1
+ sed 's/^ //' << EOF > "$dummy.c"
#undef CPU
- #undef ${UNAME_MACHINE}
- #undef ${UNAME_MACHINE}el
+ #undef mips
+ #undef mipsel
+ #undef mips64
+ #undef mips64el
+ #if ${IS_GLIBC} && defined(_ABI64)
+ LIBCABI=gnuabi64
+ #else
+ #if ${IS_GLIBC} && defined(_ABIN32)
+ LIBCABI=gnuabin32
+ #else
+ LIBCABI=${LIBC}
+ #endif
+ #endif
+
+ #if ${IS_GLIBC} && defined(__mips64) && defined(__mips_isa_rev) && __mips_isa_rev>=6
+ CPU=mipsisa64r6
+ #else
+ #if ${IS_GLIBC} && !defined(__mips64) && defined(__mips_isa_rev) && __mips_isa_rev>=6
+ CPU=mipsisa32r6
+ #else
+ #if defined(__mips64)
+ CPU=mips64
+ #else
+ CPU=mips
+ #endif
+ #endif
+ #endif
+
#if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
- CPU=${UNAME_MACHINE}el
+ MIPS_ENDIAN=el
#else
#if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
- CPU=${UNAME_MACHINE}
+ MIPS_ENDIAN=
#else
- CPU=
+ MIPS_ENDIAN=
#endif
#endif
EOF
- eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'`
- test x"${CPU}" != x && { echo "${CPU}-unknown-linux-${LIBC}"; exit; }
+ eval "`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^CPU\|^MIPS_ENDIAN\|^LIBCABI'`"
+ test "x$CPU" != x && { echo "$CPU${MIPS_ENDIAN}-unknown-linux-$LIBCABI"; exit; }
;;
+ mips64el:Linux:*:*)
+ echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
+ exit ;;
openrisc*:Linux:*:*)
- echo or1k-unknown-linux-${LIBC}
+ echo or1k-unknown-linux-"$LIBC"
exit ;;
or32:Linux:*:* | or1k*:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
exit ;;
padre:Linux:*:*)
- echo sparc-unknown-linux-${LIBC}
+ echo sparc-unknown-linux-"$LIBC"
exit ;;
parisc64:Linux:*:* | hppa64:Linux:*:*)
- echo hppa64-unknown-linux-${LIBC}
+ echo hppa64-unknown-linux-"$LIBC"
exit ;;
parisc:Linux:*:* | hppa:Linux:*:*)
# Look for CPU level
case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in
- PA7*) echo hppa1.1-unknown-linux-${LIBC} ;;
- PA8*) echo hppa2.0-unknown-linux-${LIBC} ;;
- *) echo hppa-unknown-linux-${LIBC} ;;
+ PA7*) echo hppa1.1-unknown-linux-"$LIBC" ;;
+ PA8*) echo hppa2.0-unknown-linux-"$LIBC" ;;
+ *) echo hppa-unknown-linux-"$LIBC" ;;
esac
exit ;;
ppc64:Linux:*:*)
- echo powerpc64-unknown-linux-${LIBC}
+ echo powerpc64-unknown-linux-"$LIBC"
exit ;;
ppc:Linux:*:*)
- echo powerpc-unknown-linux-${LIBC}
+ echo powerpc-unknown-linux-"$LIBC"
exit ;;
ppc64le:Linux:*:*)
- echo powerpc64le-unknown-linux-${LIBC}
+ echo powerpc64le-unknown-linux-"$LIBC"
exit ;;
ppcle:Linux:*:*)
- echo powerpcle-unknown-linux-${LIBC}
+ echo powerpcle-unknown-linux-"$LIBC"
+ exit ;;
+ riscv32:Linux:*:* | riscv64:Linux:*:*)
+ echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
exit ;;
s390:Linux:*:* | s390x:Linux:*:*)
- echo ${UNAME_MACHINE}-ibm-linux-${LIBC}
+ echo "$UNAME_MACHINE"-ibm-linux-"$LIBC"
exit ;;
sh64*:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
exit ;;
sh*:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
exit ;;
sparc:Linux:*:* | sparc64:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
exit ;;
tile*:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
exit ;;
vax:Linux:*:*)
- echo ${UNAME_MACHINE}-dec-linux-${LIBC}
+ echo "$UNAME_MACHINE"-dec-linux-"$LIBC"
exit ;;
x86_64:Linux:*:*)
- echo ${UNAME_MACHINE}-pc-linux-${LIBC}
+ echo "$UNAME_MACHINE"-pc-linux-"$LIBC"
exit ;;
xtensa*:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
exit ;;
i*86:DYNIX/ptx:4*:*)
# ptx 4.0 does uname -s correctly, with DYNIX/ptx in there.
@@ -1068,34 +1112,34 @@ EOF
# I am not positive that other SVR4 systems won't match this,
# I just have to hope. -- rms.
# Use sysv4.2uw... so that sysv4* matches it.
- echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION}
+ echo "$UNAME_MACHINE"-pc-sysv4.2uw"$UNAME_VERSION"
exit ;;
i*86:OS/2:*:*)
# If we were able to find `uname', then EMX Unix compatibility
# is probably installed.
- echo ${UNAME_MACHINE}-pc-os2-emx
+ echo "$UNAME_MACHINE"-pc-os2-emx
exit ;;
i*86:XTS-300:*:STOP)
- echo ${UNAME_MACHINE}-unknown-stop
+ echo "$UNAME_MACHINE"-unknown-stop
exit ;;
i*86:atheos:*:*)
- echo ${UNAME_MACHINE}-unknown-atheos
+ echo "$UNAME_MACHINE"-unknown-atheos
exit ;;
i*86:syllable:*:*)
- echo ${UNAME_MACHINE}-pc-syllable
+ echo "$UNAME_MACHINE"-pc-syllable
exit ;;
i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*)
- echo i386-unknown-lynxos${UNAME_RELEASE}
+ echo i386-unknown-lynxos"$UNAME_RELEASE"
exit ;;
i*86:*DOS:*:*)
- echo ${UNAME_MACHINE}-pc-msdosdjgpp
+ echo "$UNAME_MACHINE"-pc-msdosdjgpp
exit ;;
- i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*)
- UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'`
+ i*86:*:4.*:*)
+ UNAME_REL=`echo "$UNAME_RELEASE" | sed 's/\/MP$//'`
if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then
- echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL}
+ echo "$UNAME_MACHINE"-univel-sysv"$UNAME_REL"
else
- echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL}
+ echo "$UNAME_MACHINE"-pc-sysv"$UNAME_REL"
fi
exit ;;
i*86:*:5:[678]*)
@@ -1105,12 +1149,12 @@ EOF
*Pentium) UNAME_MACHINE=i586 ;;
*Pent*|*Celeron) UNAME_MACHINE=i686 ;;
esac
- echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION}
+ echo "$UNAME_MACHINE-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION}"
exit ;;
i*86:*:3.2:*)
if test -f /usr/options/cb.name; then
UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name`
- echo ${UNAME_MACHINE}-pc-isc$UNAME_REL
+ echo "$UNAME_MACHINE"-pc-isc"$UNAME_REL"
elif /bin/uname -X 2>/dev/null >/dev/null ; then
UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')`
(/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486
@@ -1120,9 +1164,9 @@ EOF
&& UNAME_MACHINE=i686
(/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \
&& UNAME_MACHINE=i686
- echo ${UNAME_MACHINE}-pc-sco$UNAME_REL
+ echo "$UNAME_MACHINE"-pc-sco"$UNAME_REL"
else
- echo ${UNAME_MACHINE}-pc-sysv32
+ echo "$UNAME_MACHINE"-pc-sysv32
fi
exit ;;
pc:*:*:*)
@@ -1142,9 +1186,9 @@ EOF
exit ;;
i860:*:4.*:*) # i860-SVR4
if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then
- echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4
+ echo i860-stardent-sysv"$UNAME_RELEASE" # Stardent Vistra i860-SVR4
else # Add other i860-SVR4 vendors below as they are discovered.
- echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4
+ echo i860-unknown-sysv"$UNAME_RELEASE" # Unknown i860-SVR4
fi
exit ;;
mini*:CTIX:SYS*5:*)
@@ -1164,9 +1208,9 @@ EOF
test -r /etc/.relid \
&& OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
/bin/uname -p 2>/dev/null | grep 86 >/dev/null \
- && { echo i486-ncr-sysv4.3${OS_REL}; exit; }
+ && { echo i486-ncr-sysv4.3"$OS_REL"; exit; }
/bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
- && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;;
+ && { echo i586-ncr-sysv4.3"$OS_REL"; exit; } ;;
3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)
/bin/uname -p 2>/dev/null | grep 86 >/dev/null \
&& { echo i486-ncr-sysv4; exit; } ;;
@@ -1175,28 +1219,28 @@ EOF
test -r /etc/.relid \
&& OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
/bin/uname -p 2>/dev/null | grep 86 >/dev/null \
- && { echo i486-ncr-sysv4.3${OS_REL}; exit; }
+ && { echo i486-ncr-sysv4.3"$OS_REL"; exit; }
/bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
- && { echo i586-ncr-sysv4.3${OS_REL}; exit; }
+ && { echo i586-ncr-sysv4.3"$OS_REL"; exit; }
/bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \
- && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;;
+ && { echo i586-ncr-sysv4.3"$OS_REL"; exit; } ;;
m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*)
- echo m68k-unknown-lynxos${UNAME_RELEASE}
+ echo m68k-unknown-lynxos"$UNAME_RELEASE"
exit ;;
mc68030:UNIX_System_V:4.*:*)
echo m68k-atari-sysv4
exit ;;
TSUNAMI:LynxOS:2.*:*)
- echo sparc-unknown-lynxos${UNAME_RELEASE}
+ echo sparc-unknown-lynxos"$UNAME_RELEASE"
exit ;;
rs6000:LynxOS:2.*:*)
- echo rs6000-unknown-lynxos${UNAME_RELEASE}
+ echo rs6000-unknown-lynxos"$UNAME_RELEASE"
exit ;;
PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*)
- echo powerpc-unknown-lynxos${UNAME_RELEASE}
+ echo powerpc-unknown-lynxos"$UNAME_RELEASE"
exit ;;
SM[BE]S:UNIX_SV:*:*)
- echo mips-dde-sysv${UNAME_RELEASE}
+ echo mips-dde-sysv"$UNAME_RELEASE"
exit ;;
RM*:ReliantUNIX-*:*:*)
echo mips-sni-sysv4
@@ -1207,7 +1251,7 @@ EOF
*:SINIX-*:*:*)
if uname -p 2>/dev/null >/dev/null ; then
UNAME_MACHINE=`(uname -p) 2>/dev/null`
- echo ${UNAME_MACHINE}-sni-sysv4
+ echo "$UNAME_MACHINE"-sni-sysv4
else
echo ns32k-sni-sysv
fi
@@ -1227,23 +1271,23 @@ EOF
exit ;;
i*86:VOS:*:*)
# From Paul.Green@stratus.com.
- echo ${UNAME_MACHINE}-stratus-vos
+ echo "$UNAME_MACHINE"-stratus-vos
exit ;;
*:VOS:*:*)
# From Paul.Green@stratus.com.
echo hppa1.1-stratus-vos
exit ;;
mc68*:A/UX:*:*)
- echo m68k-apple-aux${UNAME_RELEASE}
+ echo m68k-apple-aux"$UNAME_RELEASE"
exit ;;
news*:NEWS-OS:6*:*)
echo mips-sony-newsos6
exit ;;
R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*)
if [ -d /usr/nec ]; then
- echo mips-nec-sysv${UNAME_RELEASE}
+ echo mips-nec-sysv"$UNAME_RELEASE"
else
- echo mips-unknown-sysv${UNAME_RELEASE}
+ echo mips-unknown-sysv"$UNAME_RELEASE"
fi
exit ;;
BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only.
@@ -1262,60 +1306,68 @@ EOF
echo x86_64-unknown-haiku
exit ;;
SX-4:SUPER-UX:*:*)
- echo sx4-nec-superux${UNAME_RELEASE}
+ echo sx4-nec-superux"$UNAME_RELEASE"
exit ;;
SX-5:SUPER-UX:*:*)
- echo sx5-nec-superux${UNAME_RELEASE}
+ echo sx5-nec-superux"$UNAME_RELEASE"
exit ;;
SX-6:SUPER-UX:*:*)
- echo sx6-nec-superux${UNAME_RELEASE}
+ echo sx6-nec-superux"$UNAME_RELEASE"
exit ;;
SX-7:SUPER-UX:*:*)
- echo sx7-nec-superux${UNAME_RELEASE}
+ echo sx7-nec-superux"$UNAME_RELEASE"
exit ;;
SX-8:SUPER-UX:*:*)
- echo sx8-nec-superux${UNAME_RELEASE}
+ echo sx8-nec-superux"$UNAME_RELEASE"
exit ;;
SX-8R:SUPER-UX:*:*)
- echo sx8r-nec-superux${UNAME_RELEASE}
+ echo sx8r-nec-superux"$UNAME_RELEASE"
exit ;;
SX-ACE:SUPER-UX:*:*)
- echo sxace-nec-superux${UNAME_RELEASE}
+ echo sxace-nec-superux"$UNAME_RELEASE"
exit ;;
Power*:Rhapsody:*:*)
- echo powerpc-apple-rhapsody${UNAME_RELEASE}
+ echo powerpc-apple-rhapsody"$UNAME_RELEASE"
exit ;;
*:Rhapsody:*:*)
- echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE}
+ echo "$UNAME_MACHINE"-apple-rhapsody"$UNAME_RELEASE"
exit ;;
*:Darwin:*:*)
- UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown
- eval $set_cc_for_build
- if test "$UNAME_PROCESSOR" = unknown ; then
- UNAME_PROCESSOR=powerpc
+ UNAME_PROCESSOR=`uname -p`
+ case $UNAME_PROCESSOR in
+ unknown) UNAME_PROCESSOR=powerpc ;;
+ esac
+ if command -v xcode-select > /dev/null 2> /dev/null && \
+ ! xcode-select --print-path > /dev/null 2> /dev/null ; then
+ # Avoid executing cc if there is no toolchain installed as
+ # cc will be a stub that puts up a graphical alert
+ # prompting the user to install developer tools.
+ CC_FOR_BUILD=no_compiler_found
+ else
+ set_cc_for_build
fi
- if test `echo "$UNAME_RELEASE" | sed -e 's/\..*//'` -le 10 ; then
- if [ "$CC_FOR_BUILD" != no_compiler_found ]; then
- if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \
- (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \
- grep IS_64BIT_ARCH >/dev/null
- then
- case $UNAME_PROCESSOR in
- i386) UNAME_PROCESSOR=x86_64 ;;
- powerpc) UNAME_PROCESSOR=powerpc64 ;;
- esac
- fi
+ if [ "$CC_FOR_BUILD" != no_compiler_found ]; then
+ if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \
+ (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \
+ grep IS_64BIT_ARCH >/dev/null
+ then
+ case $UNAME_PROCESSOR in
+ i386) UNAME_PROCESSOR=x86_64 ;;
+ powerpc) UNAME_PROCESSOR=powerpc64 ;;
+ esac
+ fi
+ # On 10.4-10.6 one might compile for PowerPC via gcc -arch ppc
+ if (echo '#ifdef __POWERPC__'; echo IS_PPC; echo '#endif') | \
+ (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \
+ grep IS_PPC >/dev/null
+ then
+ UNAME_PROCESSOR=powerpc
fi
elif test "$UNAME_PROCESSOR" = i386 ; then
- # Avoid executing cc on OS X 10.9, as it ships with a stub
- # that puts up a graphical alert prompting to install
- # developer tools. Any system running Mac OS X 10.7 or
- # later (Darwin 11 and later) is required to have a 64-bit
- # processor. This is not true of the ARM version of Darwin
- # that Apple uses in portable devices.
- UNAME_PROCESSOR=x86_64
+ # uname -m returns i386 or x86_64
+ UNAME_PROCESSOR=$UNAME_MACHINE
fi
- echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE}
+ echo "$UNAME_PROCESSOR"-apple-darwin"$UNAME_RELEASE"
exit ;;
*:procnto*:*:* | *:QNX:[0123456789]*:*)
UNAME_PROCESSOR=`uname -p`
@@ -1323,19 +1375,25 @@ EOF
UNAME_PROCESSOR=i386
UNAME_MACHINE=pc
fi
- echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE}
+ echo "$UNAME_PROCESSOR"-"$UNAME_MACHINE"-nto-qnx"$UNAME_RELEASE"
exit ;;
*:QNX:*:4*)
echo i386-pc-qnx
exit ;;
- NEO-?:NONSTOP_KERNEL:*:*)
- echo neo-tandem-nsk${UNAME_RELEASE}
+ NEO-*:NONSTOP_KERNEL:*:*)
+ echo neo-tandem-nsk"$UNAME_RELEASE"
exit ;;
NSE-*:NONSTOP_KERNEL:*:*)
- echo nse-tandem-nsk${UNAME_RELEASE}
+ echo nse-tandem-nsk"$UNAME_RELEASE"
exit ;;
- NSR-?:NONSTOP_KERNEL:*:*)
- echo nsr-tandem-nsk${UNAME_RELEASE}
+ NSR-*:NONSTOP_KERNEL:*:*)
+ echo nsr-tandem-nsk"$UNAME_RELEASE"
+ exit ;;
+ NSV-*:NONSTOP_KERNEL:*:*)
+ echo nsv-tandem-nsk"$UNAME_RELEASE"
+ exit ;;
+ NSX-*:NONSTOP_KERNEL:*:*)
+ echo nsx-tandem-nsk"$UNAME_RELEASE"
exit ;;
*:NonStop-UX:*:*)
echo mips-compaq-nonstopux
@@ -1344,18 +1402,19 @@ EOF
echo bs2000-siemens-sysv
exit ;;
DS/*:UNIX_System_V:*:*)
- echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE}
+ echo "$UNAME_MACHINE"-"$UNAME_SYSTEM"-"$UNAME_RELEASE"
exit ;;
*:Plan9:*:*)
# "uname -m" is not consistent, so use $cputype instead. 386
# is converted to i386 for consistency with other x86
# operating systems.
+ # shellcheck disable=SC2154
if test "$cputype" = 386; then
UNAME_MACHINE=i386
else
UNAME_MACHINE="$cputype"
fi
- echo ${UNAME_MACHINE}-unknown-plan9
+ echo "$UNAME_MACHINE"-unknown-plan9
exit ;;
*:TOPS-10:*:*)
echo pdp10-unknown-tops10
@@ -1376,14 +1435,14 @@ EOF
echo pdp10-unknown-its
exit ;;
SEI:*:*:SEIUX)
- echo mips-sei-seiux${UNAME_RELEASE}
+ echo mips-sei-seiux"$UNAME_RELEASE"
exit ;;
*:DragonFly:*:*)
- echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
+ echo "$UNAME_MACHINE"-unknown-dragonfly"`echo "$UNAME_RELEASE"|sed -e 's/[-(].*//'`"
exit ;;
*:*VMS:*:*)
UNAME_MACHINE=`(uname -p) 2>/dev/null`
- case "${UNAME_MACHINE}" in
+ case "$UNAME_MACHINE" in
A*) echo alpha-dec-vms ; exit ;;
I*) echo ia64-dec-vms ; exit ;;
V*) echo vax-dec-vms ; exit ;;
@@ -1392,32 +1451,190 @@ EOF
echo i386-pc-xenix
exit ;;
i*86:skyos:*:*)
- echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE} | sed -e 's/ .*$//'`
+ echo "$UNAME_MACHINE"-pc-skyos"`echo "$UNAME_RELEASE" | sed -e 's/ .*$//'`"
exit ;;
i*86:rdos:*:*)
- echo ${UNAME_MACHINE}-pc-rdos
+ echo "$UNAME_MACHINE"-pc-rdos
exit ;;
i*86:AROS:*:*)
- echo ${UNAME_MACHINE}-pc-aros
+ echo "$UNAME_MACHINE"-pc-aros
exit ;;
x86_64:VMkernel:*:*)
- echo ${UNAME_MACHINE}-unknown-esx
+ echo "$UNAME_MACHINE"-unknown-esx
exit ;;
amd64:Isilon\ OneFS:*:*)
echo x86_64-unknown-onefs
exit ;;
+ *:Unleashed:*:*)
+ echo "$UNAME_MACHINE"-unknown-unleashed"$UNAME_RELEASE"
+ exit ;;
+esac
+
+# No uname command or uname output not recognized.
+set_cc_for_build
+cat > "$dummy.c" <<EOF
+#ifdef _SEQUENT_
+#include <sys/types.h>
+#include <sys/utsname.h>
+#endif
+#if defined(ultrix) || defined(_ultrix) || defined(__ultrix) || defined(__ultrix__)
+#if defined (vax) || defined (__vax) || defined (__vax__) || defined(mips) || defined(__mips) || defined(__mips__) || defined(MIPS) || defined(__MIPS__)
+#include <signal.h>
+#if defined(_SIZE_T_) || defined(SIGLOST)
+#include <sys/utsname.h>
+#endif
+#endif
+#endif
+main ()
+{
+#if defined (sony)
+#if defined (MIPSEB)
+ /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed,
+ I don't know.... */
+ printf ("mips-sony-bsd\n"); exit (0);
+#else
+#include <sys/param.h>
+ printf ("m68k-sony-newsos%s\n",
+#ifdef NEWSOS4
+ "4"
+#else
+ ""
+#endif
+ ); exit (0);
+#endif
+#endif
+
+#if defined (NeXT)
+#if !defined (__ARCHITECTURE__)
+#define __ARCHITECTURE__ "m68k"
+#endif
+ int version;
+ version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`;
+ if (version < 4)
+ printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version);
+ else
+ printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version);
+ exit (0);
+#endif
+
+#if defined (MULTIMAX) || defined (n16)
+#if defined (UMAXV)
+ printf ("ns32k-encore-sysv\n"); exit (0);
+#else
+#if defined (CMU)
+ printf ("ns32k-encore-mach\n"); exit (0);
+#else
+ printf ("ns32k-encore-bsd\n"); exit (0);
+#endif
+#endif
+#endif
+
+#if defined (__386BSD__)
+ printf ("i386-pc-bsd\n"); exit (0);
+#endif
+
+#if defined (sequent)
+#if defined (i386)
+ printf ("i386-sequent-dynix\n"); exit (0);
+#endif
+#if defined (ns32000)
+ printf ("ns32k-sequent-dynix\n"); exit (0);
+#endif
+#endif
+
+#if defined (_SEQUENT_)
+ struct utsname un;
+
+ uname(&un);
+ if (strncmp(un.version, "V2", 2) == 0) {
+ printf ("i386-sequent-ptx2\n"); exit (0);
+ }
+ if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */
+ printf ("i386-sequent-ptx1\n"); exit (0);
+ }
+ printf ("i386-sequent-ptx\n"); exit (0);
+#endif
+
+#if defined (vax)
+#if !defined (ultrix)
+#include <sys/param.h>
+#if defined (BSD)
+#if BSD == 43
+ printf ("vax-dec-bsd4.3\n"); exit (0);
+#else
+#if BSD == 199006
+ printf ("vax-dec-bsd4.3reno\n"); exit (0);
+#else
+ printf ("vax-dec-bsd\n"); exit (0);
+#endif
+#endif
+#else
+ printf ("vax-dec-bsd\n"); exit (0);
+#endif
+#else
+#if defined(_SIZE_T_) || defined(SIGLOST)
+ struct utsname un;
+ uname (&un);
+ printf ("vax-dec-ultrix%s\n", un.release); exit (0);
+#else
+ printf ("vax-dec-ultrix\n"); exit (0);
+#endif
+#endif
+#endif
+#if defined(ultrix) || defined(_ultrix) || defined(__ultrix) || defined(__ultrix__)
+#if defined(mips) || defined(__mips) || defined(__mips__) || defined(MIPS) || defined(__MIPS__)
+#if defined(_SIZE_T_) || defined(SIGLOST)
+ struct utsname *un;
+ uname (&un);
+ printf ("mips-dec-ultrix%s\n", un.release); exit (0);
+#else
+ printf ("mips-dec-ultrix\n"); exit (0);
+#endif
+#endif
+#endif
+
+#if defined (alliant) && defined (i860)
+ printf ("i860-alliant-bsd\n"); exit (0);
+#endif
+
+ exit (1);
+}
+EOF
+
+$CC_FOR_BUILD -o "$dummy" "$dummy.c" 2>/dev/null && SYSTEM_NAME=`$dummy` &&
+ { echo "$SYSTEM_NAME"; exit; }
+
+# Apollos put the system type in the environment.
+test -d /usr/apollo && { echo "$ISP-apollo-$SYSTYPE"; exit; }
+
+echo "$0: unable to guess system type" >&2
+
+case "$UNAME_MACHINE:$UNAME_SYSTEM" in
+ mips:Linux | mips64:Linux)
+ # If we got here on MIPS GNU/Linux, output extra information.
+ cat >&2 <<EOF
+
+NOTE: MIPS GNU/Linux systems require a C compiler to fully recognize
+the system type. Please install a C compiler and try again.
+EOF
+ ;;
esac
cat >&2 <<EOF
-$0: unable to guess system type
This script (version $timestamp), has failed to recognize the
-operating system you are using. If your script is old, overwrite
-config.guess and config.sub with the latest versions from:
+operating system you are using. If your script is old, overwrite *all*
+copies of config.guess and config.sub with the latest versions from:
- http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess
+ https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess
and
- http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub
+ https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub
+EOF
+
+year=`echo $timestamp | sed 's,-.*,,'`
+# shellcheck disable=SC2003
+if test "`expr "\`date +%Y\`" - "$year"`" -lt 3 ; then
+ cat >&2 <<EOF
If $0 has already been updated, send the following data and any
information you think might be pertinent to config-patches@gnu.org to
@@ -1440,16 +1657,17 @@ hostinfo = `(hostinfo) 2>/dev/null`
/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null`
/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null`
-UNAME_MACHINE = ${UNAME_MACHINE}
-UNAME_RELEASE = ${UNAME_RELEASE}
-UNAME_SYSTEM = ${UNAME_SYSTEM}
-UNAME_VERSION = ${UNAME_VERSION}
+UNAME_MACHINE = "$UNAME_MACHINE"
+UNAME_RELEASE = "$UNAME_RELEASE"
+UNAME_SYSTEM = "$UNAME_SYSTEM"
+UNAME_VERSION = "$UNAME_VERSION"
EOF
+fi
exit 1
# Local variables:
-# eval: (add-hook 'write-file-hooks 'time-stamp)
+# eval: (add-hook 'before-save-hook 'time-stamp)
# time-stamp-start: "timestamp='"
# time-stamp-format: "%:y-%02m-%02d"
# time-stamp-end: "'"
diff --git a/crypto/openssh/config.h b/crypto/openssh/config.h
index df98cea2b4ba..43ec7ab6b3fe 100644
--- a/crypto/openssh/config.h
+++ b/crypto/openssh/config.h
@@ -46,9 +46,6 @@
against it */
/* #undef BROKEN_READ_COMPARISON */
-/* realpath does not work with nonexistent files */
-#define BROKEN_REALPATH 1
-
/* Needed for NeXT */
/* #undef BROKEN_SAVED_UIDS */
@@ -103,7 +100,7 @@
/* 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 */
+/* Need to call setpgrp as root */
/* #undef DISABLE_FD_PASSING */
/* Define if you don't want to use lastlog */
@@ -136,6 +133,12 @@
/* Enable for PKCS#11 support */
#define ENABLE_PKCS11 /**/
+/* Enable for U2F/FIDO support */
+#define ENABLE_SK /**/
+
+/* Enable for built-in U2F/FIDO support */
+/* #undef ENABLE_SK_INTERNAL */
+
/* define if fflush(NULL) does not work */
/* #undef FFLUSH_NULL_BUG */
@@ -319,6 +322,10 @@
*/
#define HAVE_DECL_BZERO 1
+/* Define to 1 if you have the declaration of `getpeereid', and to 0 if you
+ don't. */
+#define HAVE_DECL_GETPEEREID 1
+
/* Define to 1 if you have the declaration of `GLOB_NOMATCH', and to 0 if you
don't. */
#define HAVE_DECL_GLOB_NOMATCH 1
@@ -351,6 +358,10 @@
don't. */
#define HAVE_DECL_MAXSYMLINKS 1
+/* Define to 1 if you have the declaration of `memmem', and to 0 if you don't.
+ */
+#define HAVE_DECL_MEMMEM 1
+
/* Define to 1 if you have the declaration of `NFDBITS', and to 0 if you
don't. */
#define HAVE_DECL_NFDBITS 1
@@ -379,6 +390,10 @@
don't. */
#define HAVE_DECL_SHUT_RD 1
+/* Define to 1 if you have the declaration of `UINT32_MAX', and to 0 if you
+ don't. */
+#define HAVE_DECL_UINT32_MAX 1
+
/* Define to 1 if you have the declaration of `writev', and to 0 if you don't.
*/
#define HAVE_DECL_WRITEV 1
@@ -400,19 +415,19 @@
/* Define if you have /dev/ptc */
/* #undef HAVE_DEV_PTS_AND_PTC */
-/* Define if libcrypto has DH_get0_key */
+/* Define to 1 if you have the `DH_get0_key' function. */
#define HAVE_DH_GET0_KEY 1
-/* Define if libcrypto has DH_get0_pqg */
+/* Define to 1 if you have the `DH_get0_pqg' function. */
#define HAVE_DH_GET0_PQG 1
-/* Define if libcrypto has DH_set0_key */
+/* Define to 1 if you have the `DH_set0_key' function. */
#define HAVE_DH_SET0_KEY 1
-/* Define if libcrypto has DH_set0_pqg */
+/* Define to 1 if you have the `DH_set0_pqg' function. */
#define HAVE_DH_SET0_PQG 1
-/* Define if libcrypto has DH_set_length */
+/* Define to 1 if you have the `DH_set_length' function. */
#define HAVE_DH_SET_LENGTH 1
/* Define to 1 if you have the <dirent.h> header file. */
@@ -424,33 +439,39 @@
/* Define to 1 if you have the `dirname' function. */
#define HAVE_DIRNAME 1
+/* Define to 1 if you have the `dlopen' function. */
+#define HAVE_DLOPEN 1
+
/* Define to 1 if you have the `DSA_generate_parameters_ex' function. */
#define HAVE_DSA_GENERATE_PARAMETERS_EX 1
-/* Define if libcrypto has DSA_get0_key */
+/* Define to 1 if you have the `DSA_get0_key' function. */
#define HAVE_DSA_GET0_KEY 1
-/* Define if libcrypto has DSA_get0_pqg */
+/* Define to 1 if you have the `DSA_get0_pqg' function. */
#define HAVE_DSA_GET0_PQG 1
-/* Define if libcrypto has DSA_set0_key */
+/* Define to 1 if you have the `DSA_set0_key' function. */
#define HAVE_DSA_SET0_KEY 1
-/* Define if libcrypto has DSA_set0_pqg */
+/* Define to 1 if you have the `DSA_set0_pqg' function. */
#define HAVE_DSA_SET0_PQG 1
-/* Define if libcrypto has DSA_SIG_get0 */
+/* Define to 1 if you have the `DSA_SIG_get0' function. */
#define HAVE_DSA_SIG_GET0 1
-/* Define if libcrypto has DSA_SIG_set0 */
+/* Define to 1 if you have the `DSA_SIG_set0' function. */
#define HAVE_DSA_SIG_SET0 1
-/* Define if libcrypto has ECDSA_SIG_get0 */
+/* Define to 1 if you have the `ECDSA_SIG_get0' function. */
#define HAVE_ECDSA_SIG_GET0 1
-/* Define if libcrypto has ECDSA_SIG_set0 */
+/* Define to 1 if you have the `ECDSA_SIG_set0' function. */
#define HAVE_ECDSA_SIG_SET0 1
+/* Define to 1 if you have the `EC_KEY_METHOD_new' function. */
+#define HAVE_EC_KEY_METHOD_NEW 1
+
/* Define to 1 if you have the <elf.h> header file. */
#define HAVE_ELF_H 1
@@ -478,18 +499,27 @@
/* Define if your system has /etc/default/login */
/* #undef HAVE_ETC_DEFAULT_LOGIN */
-/* Define if libcrypto has EVP_CIPHER_CTX_ctrl */
+/* Define to 1 if you have the `EVP_chacha20' function. */
+#define HAVE_EVP_CHACHA20 1
+
+/* Define to 1 if you have the `EVP_CIPHER_CTX_ctrl' function. */
#define HAVE_EVP_CIPHER_CTX_CTRL 1
-/* Define if libcrypto has EVP_CIPHER_CTX_set_iv */
+/* Define to 1 if you have the `EVP_CIPHER_CTX_get_iv' function. */
/* #undef HAVE_EVP_CIPHER_CTX_GET_IV */
-/* Define if libcrypto has EVP_CIPHER_CTX_iv */
+/* Define to 1 if you have the `EVP_CIPHER_CTX_get_updated_iv' function. */
+/* #undef HAVE_EVP_CIPHER_CTX_GET_UPDATED_IV */
+
+/* Define to 1 if you have the `EVP_CIPHER_CTX_iv' function. */
#define HAVE_EVP_CIPHER_CTX_IV 1
-/* Define if libcrypto has EVP_CIPHER_CTX_iv_noconst */
+/* Define to 1 if you have the `EVP_CIPHER_CTX_iv_noconst' function. */
#define HAVE_EVP_CIPHER_CTX_IV_NOCONST 1
+/* Define to 1 if you have the `EVP_CIPHER_CTX_set_iv' function. */
+/* #undef HAVE_EVP_CIPHER_CTX_SET_IV */
+
/* Define to 1 if you have the `EVP_DigestFinal_ex' function. */
#define HAVE_EVP_DIGESTFINAL_EX 1
@@ -502,36 +532,48 @@
/* Define to 1 if you have the `EVP_MD_CTX_copy_ex' function. */
#define HAVE_EVP_MD_CTX_COPY_EX 1
-/* Define if libcrypto has EVP_MD_CTX_free */
+/* Define to 1 if you have the `EVP_MD_CTX_free' function. */
#define HAVE_EVP_MD_CTX_FREE 1
/* Define to 1 if you have the `EVP_MD_CTX_init' function. */
/* #undef HAVE_EVP_MD_CTX_INIT */
-/* Define if libcrypto has EVP_MD_CTX_new */
+/* Define to 1 if you have the `EVP_MD_CTX_new' function. */
#define HAVE_EVP_MD_CTX_NEW 1
-/* Define if libcrypto has EVP_PKEY_get0_RSA */
+/* Define to 1 if you have the `EVP_PKEY_get0_RSA' function. */
#define HAVE_EVP_PKEY_GET0_RSA 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 to 1 if you have the `EVP_sha384' function. */
+#define HAVE_EVP_SHA384 1
+
+/* Define to 1 if you have the `EVP_sha512' function. */
+#define HAVE_EVP_SHA512 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. */
#define HAVE_EXPLICIT_BZERO 1
+/* Define to 1 if you have the `explicit_memset' function. */
+/* #undef HAVE_EXPLICIT_MEMSET */
+
/* Define to 1 if you have the `fchmod' function. */
#define HAVE_FCHMOD 1
+/* Define to 1 if you have the `fchmodat' function. */
+#define HAVE_FCHMODAT 1
+
/* Define to 1 if you have the `fchown' function. */
#define HAVE_FCHOWN 1
+/* Define to 1 if you have the `fchownat' function. */
+#define HAVE_FCHOWNAT 1
+
/* Use F_CLOSEM fcntl for closefrom */
/* #undef HAVE_FCNTL_CLOSEM */
@@ -544,6 +586,21 @@
/* Define to 1 if you have the <features.h> header file. */
/* #undef HAVE_FEATURES_H */
+/* Define to 1 if you have the `fido_cred_prot' function. */
+/* #undef HAVE_FIDO_CRED_PROT */
+
+/* Define to 1 if you have the `fido_cred_set_prot' function. */
+/* #undef HAVE_FIDO_CRED_SET_PROT */
+
+/* Define to 1 if you have the `fido_dev_get_touch_begin' function. */
+/* #undef HAVE_FIDO_DEV_GET_TOUCH_BEGIN */
+
+/* Define to 1 if you have the `fido_dev_get_touch_status' function. */
+/* #undef HAVE_FIDO_DEV_GET_TOUCH_STATUS */
+
+/* Define to 1 if you have the `fido_dev_supports_cred_prot' function. */
+/* #undef HAVE_FIDO_DEV_SUPPORTS_CRED_PROT */
+
/* Define to 1 if you have the <floatingpoint.h> header file. */
#define HAVE_FLOATINGPOINT_H 1
@@ -553,6 +610,12 @@
/* Define to 1 if you have the `fmt_scaled' function. */
/* #undef HAVE_FMT_SCALED */
+/* Define to 1 if you have the `fnmatch' function. */
+#define HAVE_FNMATCH 1
+
+/* Define to 1 if you have the <fnmatch.h> header file. */
+#define HAVE_FNMATCH_H 1
+
/* Define to 1 if you have the `freeaddrinfo' function. */
#define HAVE_FREEADDRINFO 1
@@ -794,7 +857,7 @@
/* #undef HAVE_LIBCRYPT */
/* Define to 1 if you have the `dl' library (-ldl). */
-#define HAVE_LIBDL 1
+/* #undef HAVE_LIBDL */
/* Define to 1 if you have the <libgen.h> header file. */
#define HAVE_LIBGEN_H 1
@@ -806,7 +869,10 @@
/* #undef HAVE_LIBNETWORK */
/* Define to 1 if you have the `pam' library (-lpam). */
-#define HAVE_LIBPAM 1
+/* #undef HAVE_LIBPAM */
+
+/* Define to 1 if you have the <libproc.h> header file. */
+/* #undef HAVE_LIBPROC_H */
/* Define to 1 if you have the `socket' library (-lsocket). */
/* #undef HAVE_LIBSOCKET */
@@ -841,6 +907,9 @@
/* Define to 1 if you have the <locale.h> header file. */
#define HAVE_LOCALE_H 1
+/* Define to 1 if you have the `localtime_r' function. */
+#define HAVE_LOCALTIME_R 1
+
/* Define to 1 if you have the `login' function. */
/* #undef HAVE_LOGIN */
@@ -850,6 +919,9 @@
/* Define to 1 if you have the `login_getcapbool' function. */
#define HAVE_LOGIN_GETCAPBOOL 1
+/* Define to 1 if you have the `login_getpwclass' function. */
+#define HAVE_LOGIN_GETPWCLASS 1
+
/* Define to 1 if you have the <login.h> header file. */
/* #undef HAVE_LOGIN_H */
@@ -884,6 +956,9 @@
/* Define if you want to allow MD5 passwords */
/* #undef HAVE_MD5_PASSWORDS */
+/* Define to 1 if you have the `memmem' function. */
+#define HAVE_MEMMEM 1
+
/* Define to 1 if you have the `memmove' function. */
#define HAVE_MEMMOVE 1
@@ -942,20 +1017,29 @@
/* Define to 1 if you have the `openpty' function. */
#define HAVE_OPENPTY 1
-/* Define if your ssl headers are included with #include <openssl/header.h> */
-#define HAVE_OPENSSL 1
+/* as a macro */
+#define HAVE_OPENSSL_ADD_ALL_ALGORITHMS 1
+
+/* Define to 1 if you have the `OPENSSL_init_crypto' function. */
+#define HAVE_OPENSSL_INIT_CRYPTO 1
+
+/* Define to 1 if you have the `OpenSSL_version' function. */
+#define HAVE_OPENSSL_VERSION 1
+
+/* Define to 1 if you have the `OpenSSL_version_num' function. */
+#define HAVE_OPENSSL_VERSION_NUM 1
/* Define if you have Digital Unix Security Integration Architecture */
/* #undef HAVE_OSF_SIA */
/* Define to 1 if you have the `pam_getenvlist' function. */
-#define HAVE_PAM_GETENVLIST 1
+/* #undef HAVE_PAM_GETENVLIST */
/* Define to 1 if you have the <pam/pam_appl.h> header file. */
/* #undef HAVE_PAM_PAM_APPL_H */
/* Define to 1 if you have the `pam_putenv' function. */
-#define HAVE_PAM_PUTENV 1
+/* #undef HAVE_PAM_PUTENV */
/* Define to 1 if you have the <paths.h> header file. */
#define HAVE_PATHS_H 1
@@ -987,6 +1071,12 @@
/* Define if you have /proc/$pid/fd */
/* #undef HAVE_PROC_PID */
+/* Define to 1 if you have the `proc_pidinfo' function. */
+/* #undef HAVE_PROC_PIDINFO */
+
+/* Define to 1 if you have the `pselect' function. */
+#define HAVE_PSELECT 1
+
/* Define to 1 if you have the `pstat' function. */
/* #undef HAVE_PSTAT */
@@ -1036,46 +1126,46 @@
/* Define to 1 if you have the `RSA_generate_key_ex' function. */
#define HAVE_RSA_GENERATE_KEY_EX 1
-/* Define if libcrypto has RSA_get0_crt_params */
+/* Define to 1 if you have the `RSA_get0_crt_params' function. */
#define HAVE_RSA_GET0_CRT_PARAMS 1
-/* Define if libcrypto has RSA_get0_factors */
+/* Define to 1 if you have the `RSA_get0_factors' function. */
#define HAVE_RSA_GET0_FACTORS 1
-/* Define if libcrypto has RSA_get0_key */
+/* Define to 1 if you have the `RSA_get0_key' function. */
#define HAVE_RSA_GET0_KEY 1
/* Define to 1 if you have the `RSA_get_default_method' function. */
#define HAVE_RSA_GET_DEFAULT_METHOD 1
-/* Define if libcrypto has RSA_meth_dup */
+/* Define to 1 if you have the `RSA_meth_dup' function. */
#define HAVE_RSA_METH_DUP 1
-/* Define if libcrypto has RSA_meth_free */
+/* Define to 1 if you have the `RSA_meth_free' function. */
#define HAVE_RSA_METH_FREE 1
-/* Define if libcrypto has RSA_meth_get_finish */
+/* Define to 1 if you have the `RSA_meth_get_finish' function. */
#define HAVE_RSA_METH_GET_FINISH 1
-/* Define if libcrypto has RSA_meth_set1_name */
+/* Define to 1 if you have the `RSA_meth_set1_name' function. */
#define HAVE_RSA_METH_SET1_NAME 1
-/* Define if libcrypto has RSA_meth_set_finish */
+/* Define to 1 if you have the `RSA_meth_set_finish' function. */
#define HAVE_RSA_METH_SET_FINISH 1
-/* Define if libcrypto has RSA_meth_set_priv_dec */
+/* Define to 1 if you have the `RSA_meth_set_priv_dec' function. */
#define HAVE_RSA_METH_SET_PRIV_DEC 1
-/* Define if libcrypto has RSA_meth_set_priv_enc */
+/* Define to 1 if you have the `RSA_meth_set_priv_enc' function. */
#define HAVE_RSA_METH_SET_PRIV_ENC 1
-/* Define if libcrypto has RSA_get0_srt_params */
+/* Define to 1 if you have the `RSA_set0_crt_params' function. */
#define HAVE_RSA_SET0_CRT_PARAMS 1
-/* Define if libcrypto has RSA_set0_factors */
+/* Define to 1 if you have the `RSA_set0_factors' function. */
#define HAVE_RSA_SET0_FACTORS 1
-/* Define if libcrypto has RSA_set0_key */
+/* Define to 1 if you have the `RSA_set0_key' function. */
#define HAVE_RSA_SET0_KEY 1
/* Define to 1 if you have the <sandbox.h> header file. */
@@ -1177,18 +1267,27 @@
/* 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 `SHA256Update' function. */
+/* #undef HAVE_SHA256UPDATE */
/* Define to 1 if you have the <sha2.h> header file. */
/* #undef HAVE_SHA2_H */
+/* Define to 1 if you have the `SHA384Update' function. */
+/* #undef HAVE_SHA384UPDATE */
+
+/* Define to 1 if you have the `SHA512Update' function. */
+/* #undef HAVE_SHA512UPDATE */
+
/* Define to 1 if you have the <shadow.h> header file. */
/* #undef HAVE_SHADOW_H */
/* Define to 1 if you have the `sigaction' function. */
#define HAVE_SIGACTION 1
+/* Define to 1 if the system has the type `sighandler_t'. */
+/* #undef HAVE_SIGHANDLER_T */
+
/* Define to 1 if you have the `sigvec' function. */
#define HAVE_SIGVEC 1
@@ -1213,6 +1312,9 @@
/* Fields in struct sockaddr_storage */
#define HAVE_SS_FAMILY_IN_SS 1
+/* Define if you have ut_ss in utmpx.h */
+/* #undef HAVE_SS_IN_UTMPX */
+
/* Define to 1 if you have the `statfs' function. */
#define HAVE_STATFS 1
@@ -1240,9 +1342,6 @@
/* 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 <strings.h> header file. */
#define HAVE_STRINGS_H 1
@@ -1315,8 +1414,11 @@
/* define if you have struct sockaddr_storage data type */
#define HAVE_STRUCT_SOCKADDR_STORAGE 1
+/* Define to 1 if `f_files' is a member of `struct statfs'. */
+#define HAVE_STRUCT_STATFS_F_FILES 1
+
/* Define to 1 if `f_flags' is a member of `struct statfs'. */
-/* #undef HAVE_STRUCT_STATFS_F_FLAGS */
+#define HAVE_STRUCT_STATFS_F_FLAGS 1
/* Define to 1 if `st_blksize' is a member of `struct stat'. */
#define HAVE_STRUCT_STAT_ST_BLKSIZE 1
@@ -1327,7 +1429,7 @@
/* Define to 1 if `st_mtime' is a member of `struct stat'. */
#define HAVE_STRUCT_STAT_ST_MTIME 1
-/* Define to 1 if the system has the type `struct timespec'. */
+/* define if you have struct timespec */
#define HAVE_STRUCT_TIMESPEC 1
/* define if you have struct timeval */
@@ -1351,6 +1453,9 @@
/* Define to 1 if you have the <sys/bsdtty.h> header file. */
/* #undef HAVE_SYS_BSDTTY_H */
+/* Define to 1 if you have the <sys/byteorder.h> header file. */
+/* #undef HAVE_SYS_BYTEORDER_H */
+
/* Define to 1 if you have the <sys/capsicum.h> header file. */
#define HAVE_SYS_CAPSICUM_H 1
@@ -1379,7 +1484,7 @@
/* #undef HAVE_SYS_NDIR_H */
/* Define if your system defines sys_nerr */
-#define HAVE_SYS_NERR 1
+/* #undef HAVE_SYS_NERR */
/* Define to 1 if you have the <sys/poll.h> header file. */
#define HAVE_SYS_POLL_H 1
@@ -1519,6 +1624,9 @@
/* Define to 1 if you have the <util.h> header file. */
/* #undef HAVE_UTIL_H */
+/* Define to 1 if you have the `utimensat' function. */
+#define HAVE_UTIMENSAT 1
+
/* Define to 1 if you have the `utimes' function. */
#define HAVE_UTIMES 1
@@ -1655,7 +1763,7 @@
/* Set this to your mail directory if you do not have _PATH_MAILDIR */
/* #undef MAIL_DIRECTORY */
-/* Need setpgrp to acquire controlling tty */
+/* Need setpgrp to for controlling tty */
/* #undef NEED_SETPGRP */
/* compiler does not accept __attribute__ on prototype args */
@@ -1664,6 +1772,9 @@
/* compiler does not accept __attribute__ on return types */
/* #undef NO_ATTRIBUTE_ON_RETURN_TYPE */
+/* SA_RESTARTed signals do no interrupt select */
+/* #undef NO_SA_RESTART */
+
/* Define to disable UID restoration test */
/* #undef NO_UID_RESTORATION_TEST */
@@ -1785,6 +1896,9 @@
/* The size of `short int', as computed by sizeof. */
#define SIZEOF_SHORT_INT 2
+/* The size of `time_t', as computed by sizeof. */
+#define SIZEOF_TIME_T 8
+
/* Define as const if snprintf() can declare const char *fmt */
#define SNPRINTF_CONST const
@@ -1856,16 +1970,16 @@
/* #undef USE_BTMP */
/* Use libedit for sftp */
-#define USE_LIBEDIT 1
+/* #undef USE_LIBEDIT */
/* Use Linux audit module */
/* #undef USE_LINUX_AUDIT */
/* Enable OpenSSL engine support */
-#define USE_OPENSSL_ENGINE 1
+/* #undef USE_OPENSSL_ENGINE */
/* Define if you want to enable PAM support */
-#define USE_PAM 1
+/* #undef USE_PAM */
/* Use PIPES instead of a socketpair() */
/* #undef USE_PIPES */
@@ -1879,6 +1993,12 @@
/* Define if you have Solaris projects */
/* #undef USE_SOLARIS_PROJECTS */
+/* compiler variable declarations after code */
+#define VARIABLE_DECLARATION_AFTER_CODE 1
+
+/* compiler supports variable length arrays */
+#define VARIABLE_LENGTH_ARRAYS 1
+
/* Define if you shouldn't strip 'tty' from your ttyname in [uw]tmp */
/* #undef WITH_ABBREV_NO_TTY */
@@ -1904,6 +2024,9 @@
/* Define if you want SELinux support. */
/* #undef WITH_SELINUX */
+/* Enable zlib */
+#define WITH_ZLIB 1
+
/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most
significant byte first (like Motorola and SPARC, unlike Intel). */
#if defined AC_APPLE_UNIVERSAL_BUILD
@@ -1917,7 +2040,7 @@
#endif
/* Define if xauth is found in your path */
-/* #undef XAUTH_PATH */
+#define XAUTH_PATH "/usr/local/bin/xauth"
/* Enable large inode numbers on Mac OS X 10.5. */
#ifndef _DARWIN_USE_64_BIT_INODE
diff --git a/crypto/openssh/config.sub b/crypto/openssh/config.sub
index 9feb73bf088f..973a2980ac3a 100755
--- a/crypto/openssh/config.sub
+++ b/crypto/openssh/config.sub
@@ -1,8 +1,8 @@
#! /bin/sh
# Configuration validation subroutine script.
-# Copyright 1992-2016 Free Software Foundation, Inc.
+# Copyright 1992-2020 Free Software Foundation, Inc.
-timestamp='2016-06-20'
+timestamp='2020-05-04'
# This file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
@@ -15,7 +15,7 @@ timestamp='2016-06-20'
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
-# along with this program; if not, see <http://www.gnu.org/licenses/>.
+# along with this program; if not, see <https://www.gnu.org/licenses/>.
#
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
@@ -33,7 +33,7 @@ timestamp='2016-06-20'
# Otherwise, we print the canonical config type on stdout and succeed.
# You can get the latest version of this script from:
-# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub
+# https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub
# This file is supposed to be the same for all GNU packages
# and recognize all the CPU types, system types and aliases
@@ -57,7 +57,7 @@ Usage: $0 [OPTION] CPU-MFR-OPSYS or ALIAS
Canonicalize a configuration name.
-Operation modes:
+Options:
-h, --help print this help, then exit
-t, --time-stamp print date of last modification, then exit
-v, --version print version number, then exit
@@ -67,7 +67,7 @@ Report bugs and patches to <config-patches@gnu.org>."
version="\
GNU config.sub ($timestamp)
-Copyright 1992-2016 Free Software Foundation, Inc.
+Copyright 1992-2020 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
@@ -89,12 +89,12 @@ while test $# -gt 0 ; do
- ) # Use stdin as input.
break ;;
-* )
- echo "$me: invalid option $1$help"
+ echo "$me: invalid option $1$help" >&2
exit 1 ;;
*local*)
# First pass through any local machine types.
- echo $1
+ echo "$1"
exit ;;
* )
@@ -110,1242 +110,1164 @@ case $# in
exit 1;;
esac
-# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any).
-# Here we must recognize all the valid KERNEL-OS combinations.
-maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
-case $maybe_os in
- nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \
- linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \
- knetbsd*-gnu* | netbsd*-gnu* | netbsd*-eabi* | \
- kopensolaris*-gnu* | \
- storm-chaos* | os2-emx* | rtmk-nova*)
- os=-$maybe_os
- basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
- ;;
- android-linux)
- os=-linux-android
- basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`-unknown
- ;;
- *)
- basic_machine=`echo $1 | sed 's/-[^-]*$//'`
- if [ $basic_machine != $1 ]
- then os=`echo $1 | sed 's/.*-/-/'`
- else os=; fi
- ;;
-esac
+# Split fields of configuration type
+# shellcheck disable=SC2162
+IFS="-" read field1 field2 field3 field4 <<EOF
+$1
+EOF
-### Let's recognize common machines as not being operating systems so
-### that things like config.sub decstation-3100 work. We also
-### recognize some manufacturers as not being operating systems, so we
-### can provide default operating systems below.
-case $os in
- -sun*os*)
- # Prevent following clause from handling this invalid input.
- ;;
- -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \
- -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \
- -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \
- -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
- -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
- -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \
- -apple | -axis | -knuth | -cray | -microblaze*)
- os=
- basic_machine=$1
- ;;
- -bluegene*)
- os=-cnk
- ;;
- -sim | -cisco | -oki | -wec | -winbond)
- os=
- basic_machine=$1
- ;;
- -scout)
- ;;
- -wrs)
- os=-vxworks
- basic_machine=$1
- ;;
- -chorusos*)
- os=-chorusos
- basic_machine=$1
- ;;
- -chorusrdb)
- os=-chorusrdb
- basic_machine=$1
- ;;
- -hiux*)
- os=-hiuxwe2
- ;;
- -sco6)
- os=-sco5v6
- basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
- ;;
- -sco5)
- os=-sco3.2v5
- basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
- ;;
- -sco4)
- os=-sco3.2v4
- basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
- ;;
- -sco3.2.[4-9]*)
- os=`echo $os | sed -e 's/sco3.2./sco3.2v/'`
- basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
- ;;
- -sco3.2v[4-9]*)
- # Don't forget version if it is 3.2v4 or newer.
- basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
- ;;
- -sco5v6*)
- # Don't forget version if it is 3.2v4 or newer.
- basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
- ;;
- -sco*)
- os=-sco3.2v2
- basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
- ;;
- -udk*)
- basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
- ;;
- -isc)
- os=-isc2.2
- basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
- ;;
- -clix*)
- basic_machine=clipper-intergraph
- ;;
- -isc*)
- basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
- ;;
- -lynx*178)
- os=-lynxos178
- ;;
- -lynx*5)
- os=-lynxos5
- ;;
- -lynx*)
- os=-lynxos
+# Separate into logical components for further validation
+case $1 in
+ *-*-*-*-*)
+ echo Invalid configuration \`"$1"\': more than four components >&2
+ exit 1
;;
- -ptx*)
- basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'`
+ *-*-*-*)
+ basic_machine=$field1-$field2
+ os=$field3-$field4
;;
- -windowsnt*)
- os=`echo $os | sed -e 's/windowsnt/winnt/'`
+ *-*-*)
+ # Ambiguous whether COMPANY is present, or skipped and KERNEL-OS is two
+ # parts
+ maybe_os=$field2-$field3
+ case $maybe_os in
+ nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc \
+ | linux-newlib* | linux-musl* | linux-uclibc* | uclinux-uclibc* \
+ | uclinux-gnu* | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* \
+ | netbsd*-eabi* | kopensolaris*-gnu* | cloudabi*-eabi* \
+ | storm-chaos* | os2-emx* | rtmk-nova*)
+ basic_machine=$field1
+ os=$maybe_os
+ ;;
+ android-linux)
+ basic_machine=$field1-unknown
+ os=linux-android
+ ;;
+ *)
+ basic_machine=$field1-$field2
+ os=$field3
+ ;;
+ esac
;;
- -psos*)
- os=-psos
+ *-*)
+ # A lone config we happen to match not fitting any pattern
+ case $field1-$field2 in
+ decstation-3100)
+ basic_machine=mips-dec
+ os=
+ ;;
+ *-*)
+ # Second component is usually, but not always the OS
+ case $field2 in
+ # Prevent following clause from handling this valid os
+ sun*os*)
+ basic_machine=$field1
+ os=$field2
+ ;;
+ # Manufacturers
+ dec* | mips* | sequent* | encore* | pc533* | sgi* | sony* \
+ | att* | 7300* | 3300* | delta* | motorola* | sun[234]* \
+ | unicom* | ibm* | next | hp | isi* | apollo | altos* \
+ | convergent* | ncr* | news | 32* | 3600* | 3100* \
+ | hitachi* | c[123]* | convex* | sun | crds | omron* | dg \
+ | ultra | tti* | harris | dolphin | highlevel | gould \
+ | cbm | ns | masscomp | apple | axis | knuth | cray \
+ | microblaze* | sim | cisco \
+ | oki | wec | wrs | winbond)
+ basic_machine=$field1-$field2
+ os=
+ ;;
+ *)
+ basic_machine=$field1
+ os=$field2
+ ;;
+ esac
+ ;;
+ esac
;;
- -mint | -mint[0-9]*)
- basic_machine=m68k-atari
- os=-mint
+ *)
+ # Convert single-component short-hands not valid as part of
+ # multi-component configurations.
+ case $field1 in
+ 386bsd)
+ basic_machine=i386-pc
+ os=bsd
+ ;;
+ a29khif)
+ basic_machine=a29k-amd
+ os=udi
+ ;;
+ adobe68k)
+ basic_machine=m68010-adobe
+ os=scout
+ ;;
+ alliant)
+ basic_machine=fx80-alliant
+ os=
+ ;;
+ altos | altos3068)
+ basic_machine=m68k-altos
+ os=
+ ;;
+ am29k)
+ basic_machine=a29k-none
+ os=bsd
+ ;;
+ amdahl)
+ basic_machine=580-amdahl
+ os=sysv
+ ;;
+ amiga)
+ basic_machine=m68k-unknown
+ os=
+ ;;
+ amigaos | amigados)
+ basic_machine=m68k-unknown
+ os=amigaos
+ ;;
+ amigaunix | amix)
+ basic_machine=m68k-unknown
+ os=sysv4
+ ;;
+ apollo68)
+ basic_machine=m68k-apollo
+ os=sysv
+ ;;
+ apollo68bsd)
+ basic_machine=m68k-apollo
+ os=bsd
+ ;;
+ aros)
+ basic_machine=i386-pc
+ os=aros
+ ;;
+ aux)
+ basic_machine=m68k-apple
+ os=aux
+ ;;
+ balance)
+ basic_machine=ns32k-sequent
+ os=dynix
+ ;;
+ blackfin)
+ basic_machine=bfin-unknown
+ os=linux
+ ;;
+ cegcc)
+ basic_machine=arm-unknown
+ os=cegcc
+ ;;
+ convex-c1)
+ basic_machine=c1-convex
+ os=bsd
+ ;;
+ convex-c2)
+ basic_machine=c2-convex
+ os=bsd
+ ;;
+ convex-c32)
+ basic_machine=c32-convex
+ os=bsd
+ ;;
+ convex-c34)
+ basic_machine=c34-convex
+ os=bsd
+ ;;
+ convex-c38)
+ basic_machine=c38-convex
+ os=bsd
+ ;;
+ cray)
+ basic_machine=j90-cray
+ os=unicos
+ ;;
+ crds | unos)
+ basic_machine=m68k-crds
+ os=
+ ;;
+ da30)
+ basic_machine=m68k-da30
+ os=
+ ;;
+ decstation | pmax | pmin | dec3100 | decstatn)
+ basic_machine=mips-dec
+ os=
+ ;;
+ delta88)
+ basic_machine=m88k-motorola
+ os=sysv3
+ ;;
+ dicos)
+ basic_machine=i686-pc
+ os=dicos
+ ;;
+ djgpp)
+ basic_machine=i586-pc
+ os=msdosdjgpp
+ ;;
+ ebmon29k)
+ basic_machine=a29k-amd
+ os=ebmon
+ ;;
+ es1800 | OSE68k | ose68k | ose | OSE)
+ basic_machine=m68k-ericsson
+ os=ose
+ ;;
+ gmicro)
+ basic_machine=tron-gmicro
+ os=sysv
+ ;;
+ go32)
+ basic_machine=i386-pc
+ os=go32
+ ;;
+ h8300hms)
+ basic_machine=h8300-hitachi
+ os=hms
+ ;;
+ h8300xray)
+ basic_machine=h8300-hitachi
+ os=xray
+ ;;
+ h8500hms)
+ basic_machine=h8500-hitachi
+ os=hms
+ ;;
+ harris)
+ basic_machine=m88k-harris
+ os=sysv3
+ ;;
+ hp300 | hp300hpux)
+ basic_machine=m68k-hp
+ os=hpux
+ ;;
+ hp300bsd)
+ basic_machine=m68k-hp
+ os=bsd
+ ;;
+ hppaosf)
+ basic_machine=hppa1.1-hp
+ os=osf
+ ;;
+ hppro)
+ basic_machine=hppa1.1-hp
+ os=proelf
+ ;;
+ i386mach)
+ basic_machine=i386-mach
+ os=mach
+ ;;
+ isi68 | isi)
+ basic_machine=m68k-isi
+ os=sysv
+ ;;
+ m68knommu)
+ basic_machine=m68k-unknown
+ os=linux
+ ;;
+ magnum | m3230)
+ basic_machine=mips-mips
+ os=sysv
+ ;;
+ merlin)
+ basic_machine=ns32k-utek
+ os=sysv
+ ;;
+ mingw64)
+ basic_machine=x86_64-pc
+ os=mingw64
+ ;;
+ mingw32)
+ basic_machine=i686-pc
+ os=mingw32
+ ;;
+ mingw32ce)
+ basic_machine=arm-unknown
+ os=mingw32ce
+ ;;
+ monitor)
+ basic_machine=m68k-rom68k
+ os=coff
+ ;;
+ morphos)
+ basic_machine=powerpc-unknown
+ os=morphos
+ ;;
+ moxiebox)
+ basic_machine=moxie-unknown
+ os=moxiebox
+ ;;
+ msdos)
+ basic_machine=i386-pc
+ os=msdos
+ ;;
+ msys)
+ basic_machine=i686-pc
+ os=msys
+ ;;
+ mvs)
+ basic_machine=i370-ibm
+ os=mvs
+ ;;
+ nacl)
+ basic_machine=le32-unknown
+ os=nacl
+ ;;
+ ncr3000)
+ basic_machine=i486-ncr
+ os=sysv4
+ ;;
+ netbsd386)
+ basic_machine=i386-pc
+ os=netbsd
+ ;;
+ netwinder)
+ basic_machine=armv4l-rebel
+ os=linux
+ ;;
+ news | news700 | news800 | news900)
+ basic_machine=m68k-sony
+ os=newsos
+ ;;
+ news1000)
+ basic_machine=m68030-sony
+ os=newsos
+ ;;
+ necv70)
+ basic_machine=v70-nec
+ os=sysv
+ ;;
+ nh3000)
+ basic_machine=m68k-harris
+ os=cxux
+ ;;
+ nh[45]000)
+ basic_machine=m88k-harris
+ os=cxux
+ ;;
+ nindy960)
+ basic_machine=i960-intel
+ os=nindy
+ ;;
+ mon960)
+ basic_machine=i960-intel
+ os=mon960
+ ;;
+ nonstopux)
+ basic_machine=mips-compaq
+ os=nonstopux
+ ;;
+ os400)
+ basic_machine=powerpc-ibm
+ os=os400
+ ;;
+ OSE68000 | ose68000)
+ basic_machine=m68000-ericsson
+ os=ose
+ ;;
+ os68k)
+ basic_machine=m68k-none
+ os=os68k
+ ;;
+ paragon)
+ basic_machine=i860-intel
+ os=osf
+ ;;
+ parisc)
+ basic_machine=hppa-unknown
+ os=linux
+ ;;
+ pw32)
+ basic_machine=i586-unknown
+ os=pw32
+ ;;
+ rdos | rdos64)
+ basic_machine=x86_64-pc
+ os=rdos
+ ;;
+ rdos32)
+ basic_machine=i386-pc
+ os=rdos
+ ;;
+ rom68k)
+ basic_machine=m68k-rom68k
+ os=coff
+ ;;
+ sa29200)
+ basic_machine=a29k-amd
+ os=udi
+ ;;
+ sei)
+ basic_machine=mips-sei
+ os=seiux
+ ;;
+ sequent)
+ basic_machine=i386-sequent
+ os=
+ ;;
+ sps7)
+ basic_machine=m68k-bull
+ os=sysv2
+ ;;
+ st2000)
+ basic_machine=m68k-tandem
+ os=
+ ;;
+ stratus)
+ basic_machine=i860-stratus
+ os=sysv4
+ ;;
+ sun2)
+ basic_machine=m68000-sun
+ os=
+ ;;
+ sun2os3)
+ basic_machine=m68000-sun
+ os=sunos3
+ ;;
+ sun2os4)
+ basic_machine=m68000-sun
+ os=sunos4
+ ;;
+ sun3)
+ basic_machine=m68k-sun
+ os=
+ ;;
+ sun3os3)
+ basic_machine=m68k-sun
+ os=sunos3
+ ;;
+ sun3os4)
+ basic_machine=m68k-sun
+ os=sunos4
+ ;;
+ sun4)
+ basic_machine=sparc-sun
+ os=
+ ;;
+ sun4os3)
+ basic_machine=sparc-sun
+ os=sunos3
+ ;;
+ sun4os4)
+ basic_machine=sparc-sun
+ os=sunos4
+ ;;
+ sun4sol2)
+ basic_machine=sparc-sun
+ os=solaris2
+ ;;
+ sun386 | sun386i | roadrunner)
+ basic_machine=i386-sun
+ os=
+ ;;
+ sv1)
+ basic_machine=sv1-cray
+ os=unicos
+ ;;
+ symmetry)
+ basic_machine=i386-sequent
+ os=dynix
+ ;;
+ t3e)
+ basic_machine=alphaev5-cray
+ os=unicos
+ ;;
+ t90)
+ basic_machine=t90-cray
+ os=unicos
+ ;;
+ toad1)
+ basic_machine=pdp10-xkl
+ os=tops20
+ ;;
+ tpf)
+ basic_machine=s390x-ibm
+ os=tpf
+ ;;
+ udi29k)
+ basic_machine=a29k-amd
+ os=udi
+ ;;
+ ultra3)
+ basic_machine=a29k-nyu
+ os=sym1
+ ;;
+ v810 | necv810)
+ basic_machine=v810-nec
+ os=none
+ ;;
+ vaxv)
+ basic_machine=vax-dec
+ os=sysv
+ ;;
+ vms)
+ basic_machine=vax-dec
+ os=vms
+ ;;
+ vsta)
+ basic_machine=i386-pc
+ os=vsta
+ ;;
+ vxworks960)
+ basic_machine=i960-wrs
+ os=vxworks
+ ;;
+ vxworks68)
+ basic_machine=m68k-wrs
+ os=vxworks
+ ;;
+ vxworks29k)
+ basic_machine=a29k-wrs
+ os=vxworks
+ ;;
+ xbox)
+ basic_machine=i686-pc
+ os=mingw32
+ ;;
+ ymp)
+ basic_machine=ymp-cray
+ os=unicos
+ ;;
+ *)
+ basic_machine=$1
+ os=
+ ;;
+ esac
;;
esac
-# Decode aliases for certain CPU-COMPANY combinations.
+# Decode 1-component or ad-hoc basic machines
case $basic_machine in
- # Recognize the basic CPU types without company name.
- # Some are omitted here because they have special meanings below.
- 1750a | 580 \
- | a29k \
- | aarch64 | aarch64_be \
- | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \
- | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \
- | am33_2.0 \
- | arc | arceb \
- | arm | arm[bl]e | arme[lb] | armv[2-8] | armv[3-8][lb] | armv7[arm] \
- | avr | avr32 \
- | ba \
- | be32 | be64 \
- | bfin \
- | c4x | c8051 | clipper \
- | d10v | d30v | dlx | dsp16xx \
- | e2k | epiphany \
- | fido | fr30 | frv | ft32 \
- | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
- | hexagon \
- | i370 | i860 | i960 | ia64 \
- | ip2k | iq2000 \
- | k1om \
- | le32 | le64 \
- | lm32 \
- | m32c | m32r | m32rle | m68000 | m68k | m88k \
- | maxq | mb | microblaze | microblazeel | mcore | mep | metag \
- | mips | mipsbe | mipseb | mipsel | mipsle \
- | mips16 \
- | mips64 | mips64el \
- | mips64octeon | mips64octeonel \
- | mips64orion | mips64orionel \
- | mips64r5900 | mips64r5900el \
- | mips64vr | mips64vrel \
- | mips64vr4100 | mips64vr4100el \
- | mips64vr4300 | mips64vr4300el \
- | mips64vr5000 | mips64vr5000el \
- | mips64vr5900 | mips64vr5900el \
- | mipsisa32 | mipsisa32el \
- | mipsisa32r2 | mipsisa32r2el \
- | mipsisa32r6 | mipsisa32r6el \
- | mipsisa64 | mipsisa64el \
- | mipsisa64r2 | mipsisa64r2el \
- | mipsisa64r6 | mipsisa64r6el \
- | mipsisa64sb1 | mipsisa64sb1el \
- | mipsisa64sr71k | mipsisa64sr71kel \
- | mipsr5900 | mipsr5900el \
- | mipstx39 | mipstx39el \
- | mn10200 | mn10300 \
- | moxie \
- | mt \
- | msp430 \
- | nds32 | nds32le | nds32be \
- | nios | nios2 | nios2eb | nios2el \
- | ns16k | ns32k \
- | open8 | or1k | or1knd | or32 \
- | pdp10 | pdp11 | pj | pjl \
- | powerpc | powerpc64 | powerpc64le | powerpcle \
- | pyramid \
- | riscv32 | riscv64 \
- | rl78 | rx \
- | score \
- | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[234]eb | sheb | shbe | shle | sh[1234]le | sh3ele \
- | sh64 | sh64le \
- | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \
- | sparcv8 | sparcv9 | sparcv9b | sparcv9v \
- | spu \
- | tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \
- | ubicom32 \
- | v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \
- | visium \
- | we32k \
- | x86 | xc16x | xstormy16 | xtensa \
- | z8k | z80)
- basic_machine=$basic_machine-unknown
- ;;
- c54x)
- basic_machine=tic54x-unknown
- ;;
- c55x)
- basic_machine=tic55x-unknown
- ;;
- c6x)
- basic_machine=tic6x-unknown
- ;;
- leon|leon[3-9])
- basic_machine=sparc-$basic_machine
- ;;
- m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | nvptx | picochip)
- basic_machine=$basic_machine-unknown
- os=-none
+ # Here we handle the default manufacturer of certain CPU types. It is in
+ # some cases the only manufacturer, in others, it is the most popular.
+ w89k)
+ cpu=hppa1.1
+ vendor=winbond
;;
- m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k)
+ op50n)
+ cpu=hppa1.1
+ vendor=oki
;;
- ms1)
- basic_machine=mt-unknown
+ op60c)
+ cpu=hppa1.1
+ vendor=oki
;;
-
- strongarm | thumb | xscale)
- basic_machine=arm-unknown
+ ibm*)
+ cpu=i370
+ vendor=ibm
;;
- xgate)
- basic_machine=$basic_machine-unknown
- os=-none
+ orion105)
+ cpu=clipper
+ vendor=highlevel
;;
- xscaleeb)
- basic_machine=armeb-unknown
+ mac | mpw | mac-mpw)
+ cpu=m68k
+ vendor=apple
;;
-
- xscaleel)
- basic_machine=armel-unknown
+ pmac | pmac-mpw)
+ cpu=powerpc
+ vendor=apple
;;
- # We use `pc' rather than `unknown'
- # because (1) that's what they normally are, and
- # (2) the word "unknown" tends to confuse beginning users.
- i*86 | x86_64)
- basic_machine=$basic_machine-pc
- ;;
- # Object if more than one company name word.
- *-*-*)
- echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
- exit 1
- ;;
- # Recognize the basic CPU types with company name.
- 580-* \
- | a29k-* \
- | aarch64-* | aarch64_be-* \
- | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \
- | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \
- | alphapca5[67]-* | alpha64pca5[67]-* | arc-* | arceb-* \
- | arm-* | armbe-* | armle-* | armeb-* | armv*-* \
- | avr-* | avr32-* \
- | ba-* \
- | be32-* | be64-* \
- | bfin-* | bs2000-* \
- | c[123]* | c30-* | [cjt]90-* | c4x-* \
- | c8051-* | clipper-* | craynv-* | cydra-* \
- | d10v-* | d30v-* | dlx-* \
- | e2k-* | elxsi-* \
- | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \
- | h8300-* | h8500-* \
- | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
- | hexagon-* \
- | i*86-* | i860-* | i960-* | ia64-* \
- | ip2k-* | iq2000-* \
- | k1om-* \
- | le32-* | le64-* \
- | lm32-* \
- | m32c-* | m32r-* | m32rle-* \
- | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
- | m88110-* | m88k-* | maxq-* | mcore-* | metag-* \
- | microblaze-* | microblazeel-* \
- | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \
- | mips16-* \
- | mips64-* | mips64el-* \
- | mips64octeon-* | mips64octeonel-* \
- | mips64orion-* | mips64orionel-* \
- | mips64r5900-* | mips64r5900el-* \
- | mips64vr-* | mips64vrel-* \
- | mips64vr4100-* | mips64vr4100el-* \
- | mips64vr4300-* | mips64vr4300el-* \
- | mips64vr5000-* | mips64vr5000el-* \
- | mips64vr5900-* | mips64vr5900el-* \
- | mipsisa32-* | mipsisa32el-* \
- | mipsisa32r2-* | mipsisa32r2el-* \
- | mipsisa32r6-* | mipsisa32r6el-* \
- | mipsisa64-* | mipsisa64el-* \
- | mipsisa64r2-* | mipsisa64r2el-* \
- | mipsisa64r6-* | mipsisa64r6el-* \
- | mipsisa64sb1-* | mipsisa64sb1el-* \
- | mipsisa64sr71k-* | mipsisa64sr71kel-* \
- | mipsr5900-* | mipsr5900el-* \
- | mipstx39-* | mipstx39el-* \
- | mmix-* \
- | mt-* \
- | msp430-* \
- | nds32-* | nds32le-* | nds32be-* \
- | nios-* | nios2-* | nios2eb-* | nios2el-* \
- | none-* | np1-* | ns16k-* | ns32k-* \
- | open8-* \
- | or1k*-* \
- | orion-* \
- | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
- | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \
- | pyramid-* \
- | riscv32-* | riscv64-* \
- | rl78-* | romp-* | rs6000-* | rx-* \
- | sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \
- | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \
- | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \
- | sparclite-* \
- | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx*-* \
- | tahoe-* \
- | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \
- | tile*-* \
- | tron-* \
- | ubicom32-* \
- | v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \
- | vax-* \
- | visium-* \
- | we32k-* \
- | x86-* | x86_64-* | xc16x-* | xps100-* \
- | xstormy16-* | xtensa*-* \
- | ymp-* \
- | z8k-* | z80-*)
- ;;
- # Recognize the basic CPU types without company name, with glob match.
- xtensa*)
- basic_machine=$basic_machine-unknown
- ;;
# Recognize the various machine names and aliases which stand
# for a CPU type and a company and sometimes even an OS.
- 386bsd)
- basic_machine=i386-unknown
- os=-bsd
- ;;
3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc)
- basic_machine=m68000-att
+ cpu=m68000
+ vendor=att
;;
3b*)
- basic_machine=we32k-att
- ;;
- a29khif)
- basic_machine=a29k-amd
- os=-udi
- ;;
- abacus)
- basic_machine=abacus-unknown
- ;;
- adobe68k)
- basic_machine=m68010-adobe
- os=-scout
- ;;
- alliant | fx80)
- basic_machine=fx80-alliant
- ;;
- altos | altos3068)
- basic_machine=m68k-altos
- ;;
- am29k)
- basic_machine=a29k-none
- os=-bsd
- ;;
- amd64)
- basic_machine=x86_64-pc
- ;;
- amd64-*)
- basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'`
- ;;
- amdahl)
- basic_machine=580-amdahl
- os=-sysv
- ;;
- amiga | amiga-*)
- basic_machine=m68k-unknown
- ;;
- amigaos | amigados)
- basic_machine=m68k-unknown
- os=-amigaos
- ;;
- amigaunix | amix)
- basic_machine=m68k-unknown
- os=-sysv4
- ;;
- apollo68)
- basic_machine=m68k-apollo
- os=-sysv
- ;;
- apollo68bsd)
- basic_machine=m68k-apollo
- os=-bsd
- ;;
- aros)
- basic_machine=i386-pc
- os=-aros
- ;;
- asmjs)
- basic_machine=asmjs-unknown
- ;;
- aux)
- basic_machine=m68k-apple
- os=-aux
- ;;
- balance)
- basic_machine=ns32k-sequent
- os=-dynix
- ;;
- blackfin)
- basic_machine=bfin-unknown
- os=-linux
- ;;
- blackfin-*)
- basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'`
- os=-linux
+ cpu=we32k
+ vendor=att
;;
bluegene*)
- basic_machine=powerpc-ibm
- os=-cnk
- ;;
- c54x-*)
- basic_machine=tic54x-`echo $basic_machine | sed 's/^[^-]*-//'`
- ;;
- c55x-*)
- basic_machine=tic55x-`echo $basic_machine | sed 's/^[^-]*-//'`
- ;;
- c6x-*)
- basic_machine=tic6x-`echo $basic_machine | sed 's/^[^-]*-//'`
- ;;
- c90)
- basic_machine=c90-cray
- os=-unicos
- ;;
- cegcc)
- basic_machine=arm-unknown
- os=-cegcc
- ;;
- convex-c1)
- basic_machine=c1-convex
- os=-bsd
- ;;
- convex-c2)
- basic_machine=c2-convex
- os=-bsd
- ;;
- convex-c32)
- basic_machine=c32-convex
- os=-bsd
- ;;
- convex-c34)
- basic_machine=c34-convex
- os=-bsd
- ;;
- convex-c38)
- basic_machine=c38-convex
- os=-bsd
- ;;
- cray | j90)
- basic_machine=j90-cray
- os=-unicos
- ;;
- craynv)
- basic_machine=craynv-cray
- os=-unicosmp
- ;;
- cr16 | cr16-*)
- basic_machine=cr16-unknown
- os=-elf
- ;;
- crds | unos)
- basic_machine=m68k-crds
- ;;
- crisv32 | crisv32-* | etraxfs*)
- basic_machine=crisv32-axis
- ;;
- cris | cris-* | etrax*)
- basic_machine=cris-axis
- ;;
- crx)
- basic_machine=crx-unknown
- os=-elf
- ;;
- da30 | da30-*)
- basic_machine=m68k-da30
- ;;
- decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn)
- basic_machine=mips-dec
+ cpu=powerpc
+ vendor=ibm
+ os=cnk
;;
decsystem10* | dec10*)
- basic_machine=pdp10-dec
- os=-tops10
+ cpu=pdp10
+ vendor=dec
+ os=tops10
;;
decsystem20* | dec20*)
- basic_machine=pdp10-dec
- os=-tops20
+ cpu=pdp10
+ vendor=dec
+ os=tops20
;;
delta | 3300 | motorola-3300 | motorola-delta \
| 3300-motorola | delta-motorola)
- basic_machine=m68k-motorola
- ;;
- delta88)
- basic_machine=m88k-motorola
- os=-sysv3
- ;;
- dicos)
- basic_machine=i686-pc
- os=-dicos
- ;;
- djgpp)
- basic_machine=i586-pc
- os=-msdosdjgpp
- ;;
- dpx20 | dpx20-*)
- basic_machine=rs6000-bull
- os=-bosx
- ;;
- dpx2* | dpx2*-bull)
- basic_machine=m68k-bull
- os=-sysv3
- ;;
- e500v[12])
- basic_machine=powerpc-unknown
- os=$os"spe"
- ;;
- e500v[12]-*)
- basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
- os=$os"spe"
+ cpu=m68k
+ vendor=motorola
;;
- ebmon29k)
- basic_machine=a29k-amd
- os=-ebmon
- ;;
- elxsi)
- basic_machine=elxsi-elxsi
- os=-bsd
+ dpx2*)
+ cpu=m68k
+ vendor=bull
+ os=sysv3
;;
encore | umax | mmax)
- basic_machine=ns32k-encore
+ cpu=ns32k
+ vendor=encore
;;
- es1800 | OSE68k | ose68k | ose | OSE)
- basic_machine=m68k-ericsson
- os=-ose
+ elxsi)
+ cpu=elxsi
+ vendor=elxsi
+ os=${os:-bsd}
;;
fx2800)
- basic_machine=i860-alliant
+ cpu=i860
+ vendor=alliant
;;
genix)
- basic_machine=ns32k-ns
- ;;
- gmicro)
- basic_machine=tron-gmicro
- os=-sysv
- ;;
- go32)
- basic_machine=i386-pc
- os=-go32
+ cpu=ns32k
+ vendor=ns
;;
h3050r* | hiux*)
- basic_machine=hppa1.1-hitachi
- os=-hiuxwe2
- ;;
- h8300hms)
- basic_machine=h8300-hitachi
- os=-hms
- ;;
- h8300xray)
- basic_machine=h8300-hitachi
- os=-xray
- ;;
- h8500hms)
- basic_machine=h8500-hitachi
- os=-hms
- ;;
- harris)
- basic_machine=m88k-harris
- os=-sysv3
- ;;
- hp300-*)
- basic_machine=m68k-hp
- ;;
- hp300bsd)
- basic_machine=m68k-hp
- os=-bsd
- ;;
- hp300hpux)
- basic_machine=m68k-hp
- os=-hpux
+ cpu=hppa1.1
+ vendor=hitachi
+ os=hiuxwe2
;;
hp3k9[0-9][0-9] | hp9[0-9][0-9])
- basic_machine=hppa1.0-hp
+ cpu=hppa1.0
+ vendor=hp
;;
hp9k2[0-9][0-9] | hp9k31[0-9])
- basic_machine=m68000-hp
+ cpu=m68000
+ vendor=hp
;;
hp9k3[2-9][0-9])
- basic_machine=m68k-hp
+ cpu=m68k
+ vendor=hp
;;
hp9k6[0-9][0-9] | hp6[0-9][0-9])
- basic_machine=hppa1.0-hp
+ cpu=hppa1.0
+ vendor=hp
;;
hp9k7[0-79][0-9] | hp7[0-79][0-9])
- basic_machine=hppa1.1-hp
+ cpu=hppa1.1
+ vendor=hp
;;
hp9k78[0-9] | hp78[0-9])
# FIXME: really hppa2.0-hp
- basic_machine=hppa1.1-hp
+ cpu=hppa1.1
+ vendor=hp
;;
hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893)
# FIXME: really hppa2.0-hp
- basic_machine=hppa1.1-hp
+ cpu=hppa1.1
+ vendor=hp
;;
hp9k8[0-9][13679] | hp8[0-9][13679])
- basic_machine=hppa1.1-hp
+ cpu=hppa1.1
+ vendor=hp
;;
hp9k8[0-9][0-9] | hp8[0-9][0-9])
- basic_machine=hppa1.0-hp
- ;;
- hppa-next)
- os=-nextstep3
- ;;
- hppaosf)
- basic_machine=hppa1.1-hp
- os=-osf
- ;;
- hppro)
- basic_machine=hppa1.1-hp
- os=-proelf
- ;;
- i370-ibm* | ibm*)
- basic_machine=i370-ibm
+ cpu=hppa1.0
+ vendor=hp
;;
i*86v32)
- basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
- os=-sysv32
+ cpu=`echo "$1" | sed -e 's/86.*/86/'`
+ vendor=pc
+ os=sysv32
;;
i*86v4*)
- basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
- os=-sysv4
+ cpu=`echo "$1" | sed -e 's/86.*/86/'`
+ vendor=pc
+ os=sysv4
;;
i*86v)
- basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
- os=-sysv
+ cpu=`echo "$1" | sed -e 's/86.*/86/'`
+ vendor=pc
+ os=sysv
;;
i*86sol2)
- basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
- os=-solaris2
+ cpu=`echo "$1" | sed -e 's/86.*/86/'`
+ vendor=pc
+ os=solaris2
;;
- i386mach)
- basic_machine=i386-mach
- os=-mach
- ;;
- i386-vsta | vsta)
- basic_machine=i386-unknown
- os=-vsta
+ j90 | j90-cray)
+ cpu=j90
+ vendor=cray
+ os=${os:-unicos}
;;
iris | iris4d)
- basic_machine=mips-sgi
+ cpu=mips
+ vendor=sgi
case $os in
- -irix*)
+ irix*)
;;
*)
- os=-irix4
+ os=irix4
;;
esac
;;
- isi68 | isi)
- basic_machine=m68k-isi
- os=-sysv
- ;;
- leon-*|leon[3-9]-*)
- basic_machine=sparc-`echo $basic_machine | sed 's/-.*//'`
- ;;
- m68knommu)
- basic_machine=m68k-unknown
- os=-linux
- ;;
- m68knommu-*)
- basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'`
- os=-linux
- ;;
- m88k-omron*)
- basic_machine=m88k-omron
- ;;
- magnum | m3230)
- basic_machine=mips-mips
- os=-sysv
- ;;
- merlin)
- basic_machine=ns32k-utek
- os=-sysv
- ;;
- microblaze*)
- basic_machine=microblaze-xilinx
- ;;
- mingw64)
- basic_machine=x86_64-pc
- os=-mingw64
- ;;
- mingw32)
- basic_machine=i686-pc
- os=-mingw32
- ;;
- mingw32ce)
- basic_machine=arm-unknown
- os=-mingw32ce
- ;;
miniframe)
- basic_machine=m68000-convergent
- ;;
- *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*)
- basic_machine=m68k-atari
- os=-mint
- ;;
- mips3*-*)
- basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`
- ;;
- mips3*)
- basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown
- ;;
- monitor)
- basic_machine=m68k-rom68k
- os=-coff
- ;;
- morphos)
- basic_machine=powerpc-unknown
- os=-morphos
- ;;
- moxiebox)
- basic_machine=moxie-unknown
- os=-moxiebox
- ;;
- msdos)
- basic_machine=i386-pc
- os=-msdos
- ;;
- ms1-*)
- basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'`
- ;;
- msys)
- basic_machine=i686-pc
- os=-msys
- ;;
- mvs)
- basic_machine=i370-ibm
- os=-mvs
+ cpu=m68000
+ vendor=convergent
;;
- nacl)
- basic_machine=le32-unknown
- os=-nacl
- ;;
- ncr3000)
- basic_machine=i486-ncr
- os=-sysv4
- ;;
- netbsd386)
- basic_machine=i386-unknown
- os=-netbsd
- ;;
- netwinder)
- basic_machine=armv4l-rebel
- os=-linux
- ;;
- news | news700 | news800 | news900)
- basic_machine=m68k-sony
- os=-newsos
- ;;
- news1000)
- basic_machine=m68030-sony
- os=-newsos
+ *mint | mint[0-9]* | *MiNT | *MiNT[0-9]*)
+ cpu=m68k
+ vendor=atari
+ os=mint
;;
news-3600 | risc-news)
- basic_machine=mips-sony
- os=-newsos
- ;;
- necv70)
- basic_machine=v70-nec
- os=-sysv
+ cpu=mips
+ vendor=sony
+ os=newsos
;;
- next | m*-next )
- basic_machine=m68k-next
+ next | m*-next)
+ cpu=m68k
+ vendor=next
case $os in
- -nextstep* )
+ openstep*)
+ ;;
+ nextstep*)
;;
- -ns2*)
- os=-nextstep2
+ ns2*)
+ os=nextstep2
;;
*)
- os=-nextstep3
+ os=nextstep3
;;
esac
;;
- nh3000)
- basic_machine=m68k-harris
- os=-cxux
- ;;
- nh[45]000)
- basic_machine=m88k-harris
- os=-cxux
- ;;
- nindy960)
- basic_machine=i960-intel
- os=-nindy
- ;;
- mon960)
- basic_machine=i960-intel
- os=-mon960
- ;;
- nonstopux)
- basic_machine=mips-compaq
- os=-nonstopux
- ;;
np1)
- basic_machine=np1-gould
- ;;
- neo-tandem)
- basic_machine=neo-tandem
- ;;
- nse-tandem)
- basic_machine=nse-tandem
- ;;
- nsr-tandem)
- basic_machine=nsr-tandem
+ cpu=np1
+ vendor=gould
;;
op50n-* | op60c-*)
- basic_machine=hppa1.1-oki
- os=-proelf
- ;;
- openrisc | openrisc-*)
- basic_machine=or32-unknown
- ;;
- os400)
- basic_machine=powerpc-ibm
- os=-os400
- ;;
- OSE68000 | ose68000)
- basic_machine=m68000-ericsson
- os=-ose
- ;;
- os68k)
- basic_machine=m68k-none
- os=-os68k
+ cpu=hppa1.1
+ vendor=oki
+ os=proelf
;;
pa-hitachi)
- basic_machine=hppa1.1-hitachi
- os=-hiuxwe2
- ;;
- paragon)
- basic_machine=i860-intel
- os=-osf
- ;;
- parisc)
- basic_machine=hppa-unknown
- os=-linux
- ;;
- parisc-*)
- basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'`
- os=-linux
+ cpu=hppa1.1
+ vendor=hitachi
+ os=hiuxwe2
;;
pbd)
- basic_machine=sparc-tti
+ cpu=sparc
+ vendor=tti
;;
pbb)
- basic_machine=m68k-tti
- ;;
- pc532 | pc532-*)
- basic_machine=ns32k-pc532
+ cpu=m68k
+ vendor=tti
;;
- pc98)
- basic_machine=i386-pc
- ;;
- pc98-*)
- basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'`
- ;;
- pentium | p5 | k5 | k6 | nexgen | viac3)
- basic_machine=i586-pc
- ;;
- pentiumpro | p6 | 6x86 | athlon | athlon_*)
- basic_machine=i686-pc
- ;;
- pentiumii | pentium2 | pentiumiii | pentium3)
- basic_machine=i686-pc
- ;;
- pentium4)
- basic_machine=i786-pc
- ;;
- pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*)
- basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'`
- ;;
- pentiumpro-* | p6-* | 6x86-* | athlon-*)
- basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
- ;;
- pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*)
- basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
- ;;
- pentium4-*)
- basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'`
+ pc532)
+ cpu=ns32k
+ vendor=pc532
;;
pn)
- basic_machine=pn-gould
+ cpu=pn
+ vendor=gould
;;
- power) basic_machine=power-ibm
- ;;
- ppc | ppcbe) basic_machine=powerpc-unknown
- ;;
- ppc-* | ppcbe-*)
- basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
- ;;
- ppcle | powerpclittle | ppc-le | powerpc-little)
- basic_machine=powerpcle-unknown
- ;;
- ppcle-* | powerpclittle-*)
- basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'`
- ;;
- ppc64) basic_machine=powerpc64-unknown
- ;;
- ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'`
- ;;
- ppc64le | powerpc64little | ppc64-le | powerpc64-little)
- basic_machine=powerpc64le-unknown
- ;;
- ppc64le-* | powerpc64little-*)
- basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'`
+ power)
+ cpu=power
+ vendor=ibm
;;
ps2)
- basic_machine=i386-ibm
- ;;
- pw32)
- basic_machine=i586-unknown
- os=-pw32
- ;;
- rdos | rdos64)
- basic_machine=x86_64-pc
- os=-rdos
- ;;
- rdos32)
- basic_machine=i386-pc
- os=-rdos
- ;;
- rom68k)
- basic_machine=m68k-rom68k
- os=-coff
+ cpu=i386
+ vendor=ibm
;;
rm[46]00)
- basic_machine=mips-siemens
+ cpu=mips
+ vendor=siemens
;;
rtpc | rtpc-*)
- basic_machine=romp-ibm
- ;;
- s390 | s390-*)
- basic_machine=s390-ibm
- ;;
- s390x | s390x-*)
- basic_machine=s390x-ibm
+ cpu=romp
+ vendor=ibm
;;
- sa29200)
- basic_machine=a29k-amd
- os=-udi
- ;;
- sb1)
- basic_machine=mipsisa64sb1-unknown
+ sde)
+ cpu=mipsisa32
+ vendor=sde
+ os=${os:-elf}
;;
- sb1el)
- basic_machine=mipsisa64sb1el-unknown
+ simso-wrs)
+ cpu=sparclite
+ vendor=wrs
+ os=vxworks
;;
- sde)
- basic_machine=mipsisa32-sde
- os=-elf
+ tower | tower-32)
+ cpu=m68k
+ vendor=ncr
;;
- sei)
- basic_machine=mips-sei
- os=-seiux
+ vpp*|vx|vx-*)
+ cpu=f301
+ vendor=fujitsu
;;
- sequent)
- basic_machine=i386-sequent
+ w65)
+ cpu=w65
+ vendor=wdc
;;
- sh)
- basic_machine=sh-hitachi
- os=-hms
+ w89k-*)
+ cpu=hppa1.1
+ vendor=winbond
+ os=proelf
;;
- sh5el)
- basic_machine=sh5le-unknown
+ none)
+ cpu=none
+ vendor=none
;;
- sh64)
- basic_machine=sh64-unknown
+ leon|leon[3-9])
+ cpu=sparc
+ vendor=$basic_machine
;;
- sparclite-wrs | simso-wrs)
- basic_machine=sparclite-wrs
- os=-vxworks
+ leon-*|leon[3-9]-*)
+ cpu=sparc
+ vendor=`echo "$basic_machine" | sed 's/-.*//'`
;;
- sps7)
- basic_machine=m68k-bull
- os=-sysv2
+
+ *-*)
+ # shellcheck disable=SC2162
+ IFS="-" read cpu vendor <<EOF
+$basic_machine
+EOF
;;
- spur)
- basic_machine=spur-unknown
+ # We use `pc' rather than `unknown'
+ # because (1) that's what they normally are, and
+ # (2) the word "unknown" tends to confuse beginning users.
+ i*86 | x86_64)
+ cpu=$basic_machine
+ vendor=pc
;;
- st2000)
- basic_machine=m68k-tandem
+ # These rules are duplicated from below for sake of the special case above;
+ # i.e. things that normalized to x86 arches should also default to "pc"
+ pc98)
+ cpu=i386
+ vendor=pc
;;
- stratus)
- basic_machine=i860-stratus
- os=-sysv4
+ x64 | amd64)
+ cpu=x86_64
+ vendor=pc
;;
- strongarm-* | thumb-*)
- basic_machine=arm-`echo $basic_machine | sed 's/^[^-]*-//'`
+ # Recognize the basic CPU types without company name.
+ *)
+ cpu=$basic_machine
+ vendor=unknown
;;
- sun2)
- basic_machine=m68000-sun
+esac
+
+unset -v basic_machine
+
+# Decode basic machines in the full and proper CPU-Company form.
+case $cpu-$vendor in
+ # Here we handle the default manufacturer of certain CPU types in canonical form. It is in
+ # some cases the only manufacturer, in others, it is the most popular.
+ craynv-unknown)
+ vendor=cray
+ os=${os:-unicosmp}
;;
- sun2os3)
- basic_machine=m68000-sun
- os=-sunos3
+ c90-unknown | c90-cray)
+ vendor=cray
+ os=${os:-unicos}
;;
- sun2os4)
- basic_machine=m68000-sun
- os=-sunos4
+ fx80-unknown)
+ vendor=alliant
;;
- sun3os3)
- basic_machine=m68k-sun
- os=-sunos3
+ romp-unknown)
+ vendor=ibm
;;
- sun3os4)
- basic_machine=m68k-sun
- os=-sunos4
+ mmix-unknown)
+ vendor=knuth
;;
- sun4os3)
- basic_machine=sparc-sun
- os=-sunos3
+ microblaze-unknown | microblazeel-unknown)
+ vendor=xilinx
;;
- sun4os4)
- basic_machine=sparc-sun
- os=-sunos4
+ rs6000-unknown)
+ vendor=ibm
;;
- sun4sol2)
- basic_machine=sparc-sun
- os=-solaris2
+ vax-unknown)
+ vendor=dec
;;
- sun3 | sun3-*)
- basic_machine=m68k-sun
+ pdp11-unknown)
+ vendor=dec
;;
- sun4)
- basic_machine=sparc-sun
+ we32k-unknown)
+ vendor=att
;;
- sun386 | sun386i | roadrunner)
- basic_machine=i386-sun
+ cydra-unknown)
+ vendor=cydrome
;;
- sv1)
- basic_machine=sv1-cray
- os=-unicos
+ i370-ibm*)
+ vendor=ibm
;;
- symmetry)
- basic_machine=i386-sequent
- os=-dynix
+ orion-unknown)
+ vendor=highlevel
;;
- t3e)
- basic_machine=alphaev5-cray
- os=-unicos
+ xps-unknown | xps100-unknown)
+ cpu=xps100
+ vendor=honeywell
;;
- t90)
- basic_machine=t90-cray
- os=-unicos
+
+ # Here we normalize CPU types with a missing or matching vendor
+ dpx20-unknown | dpx20-bull)
+ cpu=rs6000
+ vendor=bull
+ os=${os:-bosx}
;;
- tile*)
- basic_machine=$basic_machine-unknown
- os=-linux-gnu
+
+ # Here we normalize CPU types irrespective of the vendor
+ amd64-*)
+ cpu=x86_64
;;
- tx39)
- basic_machine=mipstx39-unknown
+ blackfin-*)
+ cpu=bfin
+ os=linux
;;
- tx39el)
- basic_machine=mipstx39el-unknown
+ c54x-*)
+ cpu=tic54x
;;
- toad1)
- basic_machine=pdp10-xkl
- os=-tops20
+ c55x-*)
+ cpu=tic55x
;;
- tower | tower-32)
- basic_machine=m68k-ncr
+ c6x-*)
+ cpu=tic6x
;;
- tpf)
- basic_machine=s390x-ibm
- os=-tpf
+ e500v[12]-*)
+ cpu=powerpc
+ os=$os"spe"
;;
- udi29k)
- basic_machine=a29k-amd
- os=-udi
+ mips3*-*)
+ cpu=mips64
;;
- ultra3)
- basic_machine=a29k-nyu
- os=-sym1
+ ms1-*)
+ cpu=mt
;;
- v810 | necv810)
- basic_machine=v810-nec
- os=-none
+ m68knommu-*)
+ cpu=m68k
+ os=linux
;;
- vaxv)
- basic_machine=vax-dec
- os=-sysv
+ m9s12z-* | m68hcs12z-* | hcs12z-* | s12z-*)
+ cpu=s12z
;;
- vms)
- basic_machine=vax-dec
- os=-vms
+ openrisc-*)
+ cpu=or32
;;
- vpp*|vx|vx-*)
- basic_machine=f301-fujitsu
+ parisc-*)
+ cpu=hppa
+ os=linux
;;
- vxworks960)
- basic_machine=i960-wrs
- os=-vxworks
+ pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*)
+ cpu=i586
;;
- vxworks68)
- basic_machine=m68k-wrs
- os=-vxworks
+ pentiumpro-* | p6-* | 6x86-* | athlon-* | athalon_*-*)
+ cpu=i686
;;
- vxworks29k)
- basic_machine=a29k-wrs
- os=-vxworks
+ pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*)
+ cpu=i686
;;
- w65*)
- basic_machine=w65-wdc
- os=-none
+ pentium4-*)
+ cpu=i786
;;
- w89k-*)
- basic_machine=hppa1.1-winbond
- os=-proelf
+ pc98-*)
+ cpu=i386
;;
- xbox)
- basic_machine=i686-pc
- os=-mingw32
+ ppc-* | ppcbe-*)
+ cpu=powerpc
;;
- xps | xps100)
- basic_machine=xps100-honeywell
+ ppcle-* | powerpclittle-*)
+ cpu=powerpcle
;;
- xscale-* | xscalee[bl]-*)
- basic_machine=`echo $basic_machine | sed 's/^xscale/arm/'`
+ ppc64-*)
+ cpu=powerpc64
;;
- ymp)
- basic_machine=ymp-cray
- os=-unicos
+ ppc64le-* | powerpc64little-*)
+ cpu=powerpc64le
;;
- z8k-*-coff)
- basic_machine=z8k-unknown
- os=-sim
+ sb1-*)
+ cpu=mipsisa64sb1
;;
- z80-*-coff)
- basic_machine=z80-unknown
- os=-sim
+ sb1el-*)
+ cpu=mipsisa64sb1el
;;
- none)
- basic_machine=none-none
- os=-none
+ sh5e[lb]-*)
+ cpu=`echo "$cpu" | sed 's/^\(sh.\)e\(.\)$/\1\2e/'`
;;
-
-# Here we handle the default manufacturer of certain CPU types. It is in
-# some cases the only manufacturer, in others, it is the most popular.
- w89k)
- basic_machine=hppa1.1-winbond
+ spur-*)
+ cpu=spur
;;
- op50n)
- basic_machine=hppa1.1-oki
+ strongarm-* | thumb-*)
+ cpu=arm
;;
- op60c)
- basic_machine=hppa1.1-oki
+ tx39-*)
+ cpu=mipstx39
;;
- romp)
- basic_machine=romp-ibm
+ tx39el-*)
+ cpu=mipstx39el
;;
- mmix)
- basic_machine=mmix-knuth
+ x64-*)
+ cpu=x86_64
;;
- rs6000)
- basic_machine=rs6000-ibm
+ xscale-* | xscalee[bl]-*)
+ cpu=`echo "$cpu" | sed 's/^xscale/arm/'`
;;
- vax)
- basic_machine=vax-dec
+
+ # Recognize the canonical CPU Types that limit and/or modify the
+ # company names they are paired with.
+ cr16-*)
+ os=${os:-elf}
;;
- pdp10)
- # there are many clones, so DEC is not a safe bet
- basic_machine=pdp10-unknown
+ crisv32-* | etraxfs*-*)
+ cpu=crisv32
+ vendor=axis
;;
- pdp11)
- basic_machine=pdp11-dec
+ cris-* | etrax*-*)
+ cpu=cris
+ vendor=axis
;;
- we32k)
- basic_machine=we32k-att
+ crx-*)
+ os=${os:-elf}
;;
- sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele)
- basic_machine=sh-unknown
+ neo-tandem)
+ cpu=neo
+ vendor=tandem
;;
- sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v)
- basic_machine=sparc-sun
+ nse-tandem)
+ cpu=nse
+ vendor=tandem
;;
- cydra)
- basic_machine=cydra-cydrome
+ nsr-tandem)
+ cpu=nsr
+ vendor=tandem
;;
- orion)
- basic_machine=orion-highlevel
+ nsv-tandem)
+ cpu=nsv
+ vendor=tandem
;;
- orion105)
- basic_machine=clipper-highlevel
+ nsx-tandem)
+ cpu=nsx
+ vendor=tandem
;;
- mac | mpw | mac-mpw)
- basic_machine=m68k-apple
+ s390-*)
+ cpu=s390
+ vendor=ibm
;;
- pmac | pmac-mpw)
- basic_machine=powerpc-apple
+ s390x-*)
+ cpu=s390x
+ vendor=ibm
;;
- *-unknown)
- # Make sure to match an already-canonicalized machine name.
+ tile*-*)
+ os=${os:-linux-gnu}
;;
+
*)
- echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
- exit 1
+ # Recognize the canonical CPU types that are allowed with any
+ # company name.
+ case $cpu in
+ 1750a | 580 \
+ | a29k \
+ | aarch64 | aarch64_be \
+ | abacus \
+ | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] \
+ | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] \
+ | alphapca5[67] | alpha64pca5[67] \
+ | am33_2.0 \
+ | amdgcn \
+ | arc | arceb \
+ | arm | arm[lb]e | arme[lb] | armv* \
+ | avr | avr32 \
+ | asmjs \
+ | ba \
+ | be32 | be64 \
+ | bfin | bpf | bs2000 \
+ | c[123]* | c30 | [cjt]90 | c4x \
+ | c8051 | clipper | craynv | csky | cydra \
+ | d10v | d30v | dlx | dsp16xx \
+ | e2k | elxsi | epiphany \
+ | f30[01] | f700 | fido | fr30 | frv | ft32 | fx80 \
+ | h8300 | h8500 \
+ | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
+ | hexagon \
+ | i370 | i*86 | i860 | i960 | ia16 | ia64 \
+ | ip2k | iq2000 \
+ | k1om \
+ | le32 | le64 \
+ | lm32 \
+ | m32c | m32r | m32rle \
+ | m5200 | m68000 | m680[012346]0 | m68360 | m683?2 | m68k \
+ | m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x \
+ | m88110 | m88k | maxq | mb | mcore | mep | metag \
+ | microblaze | microblazeel \
+ | mips | mipsbe | mipseb | mipsel | mipsle \
+ | mips16 \
+ | mips64 | mips64eb | mips64el \
+ | mips64octeon | mips64octeonel \
+ | mips64orion | mips64orionel \
+ | mips64r5900 | mips64r5900el \
+ | mips64vr | mips64vrel \
+ | mips64vr4100 | mips64vr4100el \
+ | mips64vr4300 | mips64vr4300el \
+ | mips64vr5000 | mips64vr5000el \
+ | mips64vr5900 | mips64vr5900el \
+ | mipsisa32 | mipsisa32el \
+ | mipsisa32r2 | mipsisa32r2el \
+ | mipsisa32r6 | mipsisa32r6el \
+ | mipsisa64 | mipsisa64el \
+ | mipsisa64r2 | mipsisa64r2el \
+ | mipsisa64r6 | mipsisa64r6el \
+ | mipsisa64sb1 | mipsisa64sb1el \
+ | mipsisa64sr71k | mipsisa64sr71kel \
+ | mipsr5900 | mipsr5900el \
+ | mipstx39 | mipstx39el \
+ | mmix \
+ | mn10200 | mn10300 \
+ | moxie \
+ | mt \
+ | msp430 \
+ | nds32 | nds32le | nds32be \
+ | nfp \
+ | nios | nios2 | nios2eb | nios2el \
+ | none | np1 | ns16k | ns32k | nvptx \
+ | open8 \
+ | or1k* \
+ | or32 \
+ | orion \
+ | picochip \
+ | pdp10 | pdp11 | pj | pjl | pn | power \
+ | powerpc | powerpc64 | powerpc64le | powerpcle | powerpcspe \
+ | pru \
+ | pyramid \
+ | riscv | riscv32 | riscv64 \
+ | rl78 | romp | rs6000 | rx \
+ | score \
+ | sh | shl \
+ | sh[1234] | sh[24]a | sh[24]ae[lb] | sh[23]e | she[lb] | sh[lb]e \
+ | sh[1234]e[lb] | sh[12345][lb]e | sh[23]ele | sh64 | sh64le \
+ | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet \
+ | sparclite \
+ | sparcv8 | sparcv9 | sparcv9b | sparcv9v | sv1 | sx* \
+ | spu \
+ | tahoe \
+ | tic30 | tic4x | tic54x | tic55x | tic6x | tic80 \
+ | tron \
+ | ubicom32 \
+ | v70 | v850 | v850e | v850e1 | v850es | v850e2 | v850e2v3 \
+ | vax \
+ | visium \
+ | w65 \
+ | wasm32 | wasm64 \
+ | we32k \
+ | x86 | x86_64 | xc16x | xgate | xps100 \
+ | xstormy16 | xtensa* \
+ | ymp \
+ | z8k | z80)
+ ;;
+
+ *)
+ echo Invalid configuration \`"$1"\': machine \`"$cpu-$vendor"\' not recognized 1>&2
+ exit 1
+ ;;
+ esac
;;
esac
# Here we canonicalize certain aliases for manufacturers.
-case $basic_machine in
- *-digital*)
- basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'`
+case $vendor in
+ digital*)
+ vendor=dec
;;
- *-commodore*)
- basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'`
+ commodore*)
+ vendor=cbm
;;
*)
;;
@@ -1353,200 +1275,244 @@ esac
# Decode manufacturer-specific aliases for certain operating systems.
-if [ x"$os" != x"" ]
+if [ x$os != x ]
then
case $os in
- # First match some system type aliases
- # that might get confused with valid system types.
- # -solaris* is a basic system type, with this one exception.
- -auroraux)
- os=-auroraux
+ # First match some system type aliases that might get confused
+ # with valid system types.
+ # solaris* is a basic system type, with this one exception.
+ auroraux)
+ os=auroraux
;;
- -solaris1 | -solaris1.*)
- os=`echo $os | sed -e 's|solaris1|sunos4|'`
+ bluegene*)
+ os=cnk
;;
- -solaris)
- os=-solaris2
+ solaris1 | solaris1.*)
+ os=`echo $os | sed -e 's|solaris1|sunos4|'`
;;
- -svr4*)
- os=-sysv4
+ solaris)
+ os=solaris2
;;
- -unixware*)
- os=-sysv4.2uw
+ unixware*)
+ os=sysv4.2uw
;;
- -gnu/linux*)
+ gnu/linux*)
os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'`
;;
- # First accept the basic system types.
+ # es1800 is here to avoid being matched by es* (a different OS)
+ es1800*)
+ os=ose
+ ;;
+ # Some version numbers need modification
+ chorusos*)
+ os=chorusos
+ ;;
+ isc)
+ os=isc2.2
+ ;;
+ sco6)
+ os=sco5v6
+ ;;
+ sco5)
+ os=sco3.2v5
+ ;;
+ sco4)
+ os=sco3.2v4
+ ;;
+ sco3.2.[4-9]*)
+ os=`echo $os | sed -e 's/sco3.2./sco3.2v/'`
+ ;;
+ sco3.2v[4-9]* | sco5v6*)
+ # Don't forget version if it is 3.2v4 or newer.
+ ;;
+ scout)
+ # Don't match below
+ ;;
+ sco*)
+ os=sco3.2v2
+ ;;
+ psos*)
+ os=psos
+ ;;
+ # Now accept the basic system types.
# The portable systems comes first.
- # Each alternative MUST END IN A *, to match a version number.
- # -sysv* is not here because it comes later, after sysvr4.
- -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
- | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\
- | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \
- | -sym* | -kopensolaris* | -plan9* \
- | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
- | -aos* | -aros* | -cloudabi* | -sortix* \
- | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
- | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
- | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \
- | -bitrig* | -openbsd* | -solidbsd* | -libertybsd* \
- | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \
- | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
- | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
- | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
- | -chorusos* | -chorusrdb* | -cegcc* \
- | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
- | -midipix* | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \
- | -linux-newlib* | -linux-musl* | -linux-uclibc* \
- | -uxpv* | -beos* | -mpeix* | -udk* | -moxiebox* \
- | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
- | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
- | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \
- | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
- | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
- | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \
- | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es* \
- | -onefs* | -tirtos* | -phoenix*)
+ # Each alternative MUST end in a * to match a version number.
+ # sysv* is not here because it comes later, after sysvr4.
+ gnu* | bsd* | mach* | minix* | genix* | ultrix* | irix* \
+ | *vms* | esix* | aix* | cnk* | sunos | sunos[34]*\
+ | hpux* | unos* | osf* | luna* | dgux* | auroraux* | solaris* \
+ | sym* | kopensolaris* | plan9* \
+ | amigaos* | amigados* | msdos* | newsos* | unicos* | aof* \
+ | aos* | aros* | cloudabi* | sortix* | twizzler* \
+ | nindy* | vxsim* | vxworks* | ebmon* | hms* | mvs* \
+ | clix* | riscos* | uniplus* | iris* | isc* | rtu* | xenix* \
+ | knetbsd* | mirbsd* | netbsd* \
+ | bitrig* | openbsd* | solidbsd* | libertybsd* | os108* \
+ | ekkobsd* | kfreebsd* | freebsd* | riscix* | lynxos* \
+ | bosx* | nextstep* | cxux* | aout* | elf* | oabi* \
+ | ptx* | coff* | ecoff* | winnt* | domain* | vsta* \
+ | udi* | eabi* | lites* | ieee* | go32* | aux* | hcos* \
+ | chorusrdb* | cegcc* | glidix* \
+ | cygwin* | msys* | pe* | moss* | proelf* | rtems* \
+ | midipix* | mingw32* | mingw64* | linux-gnu* | linux-android* \
+ | linux-newlib* | linux-musl* | linux-uclibc* \
+ | uxpv* | beos* | mpeix* | udk* | moxiebox* \
+ | interix* | uwin* | mks* | rhapsody* | darwin* \
+ | openstep* | oskit* | conix* | pw32* | nonstopux* \
+ | storm-chaos* | tops10* | tenex* | tops20* | its* \
+ | os2* | vos* | palmos* | uclinux* | nucleus* \
+ | morphos* | superux* | rtmk* | windiss* \
+ | powermax* | dnix* | nx6 | nx7 | sei* | dragonfly* \
+ | skyos* | haiku* | rdos* | toppers* | drops* | es* \
+ | onefs* | tirtos* | phoenix* | fuchsia* | redox* | bme* \
+ | midnightbsd* | amdhsa* | unleashed* | emscripten* | wasi* \
+ | nsk* | powerunix* | genode*)
# Remember, each alternative MUST END IN *, to match a version number.
;;
- -qnx*)
- case $basic_machine in
- x86-* | i*86-*)
+ qnx*)
+ case $cpu in
+ x86 | i*86)
;;
*)
- os=-nto$os
+ os=nto-$os
;;
esac
;;
- -nto-qnx*)
+ hiux*)
+ os=hiuxwe2
;;
- -nto*)
- os=`echo $os | sed -e 's|nto|nto-qnx|'`
+ nto-qnx*)
;;
- -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \
- | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \
- | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*)
+ nto*)
+ os=`echo $os | sed -e 's|nto|nto-qnx|'`
;;
- -mac*)
- os=`echo $os | sed -e 's|mac|macos|'`
+ sim | xray | os68k* | v88r* \
+ | windows* | osx | abug | netware* | os9* \
+ | macos* | mpw* | magic* | mmixware* | mon960* | lnews*)
;;
- -linux-dietlibc)
- os=-linux-dietlibc
+ linux-dietlibc)
+ os=linux-dietlibc
;;
- -linux*)
+ linux*)
os=`echo $os | sed -e 's|linux|linux-gnu|'`
;;
- -sunos5*)
- os=`echo $os | sed -e 's|sunos5|solaris2|'`
+ lynx*178)
+ os=lynxos178
+ ;;
+ lynx*5)
+ os=lynxos5
;;
- -sunos6*)
- os=`echo $os | sed -e 's|sunos6|solaris3|'`
+ lynx*)
+ os=lynxos
;;
- -opened*)
- os=-openedition
+ mac*)
+ os=`echo "$os" | sed -e 's|mac|macos|'`
;;
- -os400*)
- os=-os400
+ opened*)
+ os=openedition
;;
- -wince*)
- os=-wince
+ os400*)
+ os=os400
;;
- -osfrose*)
- os=-osfrose
+ sunos5*)
+ os=`echo "$os" | sed -e 's|sunos5|solaris2|'`
;;
- -osf*)
- os=-osf
+ sunos6*)
+ os=`echo "$os" | sed -e 's|sunos6|solaris3|'`
;;
- -utek*)
- os=-bsd
+ wince*)
+ os=wince
;;
- -dynix*)
- os=-bsd
+ utek*)
+ os=bsd
;;
- -acis*)
- os=-aos
+ dynix*)
+ os=bsd
;;
- -atheos*)
- os=-atheos
+ acis*)
+ os=aos
;;
- -syllable*)
- os=-syllable
+ atheos*)
+ os=atheos
;;
- -386bsd)
- os=-bsd
+ syllable*)
+ os=syllable
;;
- -ctix* | -uts*)
- os=-sysv
+ 386bsd)
+ os=bsd
;;
- -nova*)
- os=-rtmk-nova
+ ctix* | uts*)
+ os=sysv
;;
- -ns2 )
- os=-nextstep2
+ nova*)
+ os=rtmk-nova
;;
- -nsk*)
- os=-nsk
+ ns2)
+ os=nextstep2
;;
# Preserve the version number of sinix5.
- -sinix5.*)
+ sinix5.*)
os=`echo $os | sed -e 's|sinix|sysv|'`
;;
- -sinix*)
- os=-sysv4
+ sinix*)
+ os=sysv4
;;
- -tpf*)
- os=-tpf
+ tpf*)
+ os=tpf
;;
- -triton*)
- os=-sysv3
+ triton*)
+ os=sysv3
;;
- -oss*)
- os=-sysv3
+ oss*)
+ os=sysv3
;;
- -svr4)
- os=-sysv4
+ svr4*)
+ os=sysv4
;;
- -svr3)
- os=-sysv3
+ svr3)
+ os=sysv3
;;
- -sysvr4)
- os=-sysv4
+ sysvr4)
+ os=sysv4
;;
- # This must come after -sysvr4.
- -sysv*)
+ # This must come after sysvr4.
+ sysv*)
;;
- -ose*)
- os=-ose
+ ose*)
+ os=ose
;;
- -es1800*)
- os=-ose
+ *mint | mint[0-9]* | *MiNT | MiNT[0-9]*)
+ os=mint
;;
- -xenix)
- os=-xenix
+ zvmoe)
+ os=zvmoe
;;
- -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
- os=-mint
+ dicos*)
+ os=dicos
;;
- -aros*)
- os=-aros
- ;;
- -zvmoe)
- os=-zvmoe
+ pikeos*)
+ # Until real need of OS specific support for
+ # particular features comes up, bare metal
+ # configurations are quite functional.
+ case $cpu in
+ arm*)
+ os=eabi
+ ;;
+ *)
+ os=elf
+ ;;
+ esac
;;
- -dicos*)
- os=-dicos
+ nacl*)
;;
- -nacl*)
+ ios)
;;
- -ios)
+ none)
;;
- -none)
+ *-eabi)
;;
*)
- # Get rid of the `-' at the beginning of $os.
- os=`echo $os | sed 's/[^-]*-//'`
- echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2
+ echo Invalid configuration \`"$1"\': system \`"$os"\' not recognized 1>&2
exit 1
;;
esac
@@ -1562,261 +1528,265 @@ else
# will signal an error saying that MANUFACTURER isn't an operating
# system, and we'll never get to this point.
-case $basic_machine in
+case $cpu-$vendor in
score-*)
- os=-elf
+ os=elf
;;
spu-*)
- os=-elf
+ os=elf
;;
*-acorn)
- os=-riscix1.2
+ os=riscix1.2
;;
arm*-rebel)
- os=-linux
+ os=linux
;;
arm*-semi)
- os=-aout
+ os=aout
;;
c4x-* | tic4x-*)
- os=-coff
+ os=coff
;;
c8051-*)
- os=-elf
+ os=elf
+ ;;
+ clipper-intergraph)
+ os=clix
;;
hexagon-*)
- os=-elf
+ os=elf
;;
tic54x-*)
- os=-coff
+ os=coff
;;
tic55x-*)
- os=-coff
+ os=coff
;;
tic6x-*)
- os=-coff
+ os=coff
;;
# This must come before the *-dec entry.
pdp10-*)
- os=-tops20
+ os=tops20
;;
pdp11-*)
- os=-none
+ os=none
;;
*-dec | vax-*)
- os=-ultrix4.2
+ os=ultrix4.2
;;
m68*-apollo)
- os=-domain
+ os=domain
;;
i386-sun)
- os=-sunos4.0.2
+ os=sunos4.0.2
;;
m68000-sun)
- os=-sunos3
+ os=sunos3
;;
m68*-cisco)
- os=-aout
+ os=aout
;;
mep-*)
- os=-elf
+ os=elf
;;
mips*-cisco)
- os=-elf
+ os=elf
;;
mips*-*)
- os=-elf
+ os=elf
;;
or32-*)
- os=-coff
+ os=coff
;;
*-tti) # must be before sparc entry or we get the wrong os.
- os=-sysv3
+ os=sysv3
;;
sparc-* | *-sun)
- os=-sunos4.1.1
+ os=sunos4.1.1
;;
- *-be)
- os=-beos
+ pru-*)
+ os=elf
;;
- *-haiku)
- os=-haiku
+ *-be)
+ os=beos
;;
*-ibm)
- os=-aix
+ os=aix
;;
*-knuth)
- os=-mmixware
+ os=mmixware
;;
*-wec)
- os=-proelf
+ os=proelf
;;
*-winbond)
- os=-proelf
+ os=proelf
;;
*-oki)
- os=-proelf
+ os=proelf
;;
*-hp)
- os=-hpux
+ os=hpux
;;
*-hitachi)
- os=-hiux
+ os=hiux
;;
i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent)
- os=-sysv
+ os=sysv
;;
*-cbm)
- os=-amigaos
+ os=amigaos
;;
*-dg)
- os=-dgux
+ os=dgux
;;
*-dolphin)
- os=-sysv3
+ os=sysv3
;;
m68k-ccur)
- os=-rtu
+ os=rtu
;;
m88k-omron*)
- os=-luna
+ os=luna
;;
- *-next )
- os=-nextstep
+ *-next)
+ os=nextstep
;;
*-sequent)
- os=-ptx
+ os=ptx
;;
*-crds)
- os=-unos
+ os=unos
;;
*-ns)
- os=-genix
+ os=genix
;;
i370-*)
- os=-mvs
- ;;
- *-next)
- os=-nextstep3
+ os=mvs
;;
*-gould)
- os=-sysv
+ os=sysv
;;
*-highlevel)
- os=-bsd
+ os=bsd
;;
*-encore)
- os=-bsd
+ os=bsd
;;
*-sgi)
- os=-irix
+ os=irix
;;
*-siemens)
- os=-sysv4
+ os=sysv4
;;
*-masscomp)
- os=-rtu
+ os=rtu
;;
f30[01]-fujitsu | f700-fujitsu)
- os=-uxpv
+ os=uxpv
;;
*-rom68k)
- os=-coff
+ os=coff
;;
*-*bug)
- os=-coff
+ os=coff
;;
*-apple)
- os=-macos
+ os=macos
;;
*-atari*)
- os=-mint
+ os=mint
+ ;;
+ *-wrs)
+ os=vxworks
;;
*)
- os=-none
+ os=none
;;
esac
fi
# Here we handle the case where we know the os, and the CPU type, but not the
# manufacturer. We pick the logical manufacturer.
-vendor=unknown
-case $basic_machine in
- *-unknown)
+case $vendor in
+ unknown)
case $os in
- -riscix*)
+ riscix*)
vendor=acorn
;;
- -sunos*)
+ sunos*)
vendor=sun
;;
- -cnk*|-aix*)
+ cnk*|-aix*)
vendor=ibm
;;
- -beos*)
+ beos*)
vendor=be
;;
- -hpux*)
+ hpux*)
vendor=hp
;;
- -mpeix*)
+ mpeix*)
vendor=hp
;;
- -hiux*)
+ hiux*)
vendor=hitachi
;;
- -unos*)
+ unos*)
vendor=crds
;;
- -dgux*)
+ dgux*)
vendor=dg
;;
- -luna*)
+ luna*)
vendor=omron
;;
- -genix*)
+ genix*)
vendor=ns
;;
- -mvs* | -opened*)
+ clix*)
+ vendor=intergraph
+ ;;
+ mvs* | opened*)
vendor=ibm
;;
- -os400*)
+ os400*)
vendor=ibm
;;
- -ptx*)
+ ptx*)
vendor=sequent
;;
- -tpf*)
+ tpf*)
vendor=ibm
;;
- -vxsim* | -vxworks* | -windiss*)
+ vxsim* | vxworks* | windiss*)
vendor=wrs
;;
- -aux*)
+ aux*)
vendor=apple
;;
- -hms*)
+ hms*)
vendor=hitachi
;;
- -mpw* | -macos*)
+ mpw* | macos*)
vendor=apple
;;
- -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
+ *mint | mint[0-9]* | *MiNT | MiNT[0-9]*)
vendor=atari
;;
- -vos*)
+ vos*)
vendor=stratus
;;
esac
- basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"`
;;
esac
-echo $basic_machine$os
+echo "$cpu-$vendor-$os"
exit
# Local variables:
-# eval: (add-hook 'write-file-hooks 'time-stamp)
+# eval: (add-hook 'before-save-hook 'time-stamp)
# time-stamp-start: "timestamp='"
# time-stamp-format: "%:y-%02m-%02d"
# time-stamp-end: "'"
diff --git a/crypto/openssh/configure.ac b/crypto/openssh/configure.ac
index 538f389c6da3..dfcef796a3f1 100644
--- a/crypto/openssh/configure.ac
+++ b/crypto/openssh/configure.ac
@@ -14,12 +14,23 @@
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
AC_INIT([OpenSSH], [Portable], [openssh-unix-dev@mindrot.org])
-AC_REVISION($Revision: 1.583 $)
+AC_CONFIG_MACRO_DIR([m4])
AC_CONFIG_SRCDIR([ssh.c])
AC_LANG([C])
-AC_CONFIG_HEADER([config.h])
-AC_PROG_CC
+AC_CONFIG_HEADERS([config.h])
+AC_PROG_CC([cc gcc])
+
+# XXX relax this after reimplementing logit() etc.
+AC_MSG_CHECKING([if $CC supports C99-style variadic macros])
+AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
+int f(int a, int b, int c) { return a + b + c; }
+#define F(a, ...) f(a, __VA_ARGS__)
+]], [[return F(1, 2, -3);]])],
+ [ AC_MSG_RESULT([yes]) ],
+ [ AC_MSG_ERROR([*** OpenSSH requires support for C99-style variadic macros]) ]
+)
+
AC_CANONICAL_HOST
AC_C_BIGENDIAN
@@ -34,18 +45,16 @@ AC_CHECK_TOOLS([AR], [ar])
AC_PATH_PROG([CAT], [cat])
AC_PATH_PROG([KILL], [kill])
AC_PATH_PROG([SED], [sed])
-AC_PATH_PROG([ENT], [ent])
-AC_SUBST([ENT])
AC_PATH_PROG([TEST_MINUS_S_SH], [bash])
AC_PATH_PROG([TEST_MINUS_S_SH], [ksh])
AC_PATH_PROG([TEST_MINUS_S_SH], [sh])
AC_PATH_PROG([SH], [sh])
AC_PATH_PROG([GROFF], [groff])
-AC_PATH_PROG([NROFF], [nroff])
+AC_PATH_PROG([NROFF], [nroff awf])
AC_PATH_PROG([MANDOC], [mandoc])
AC_SUBST([TEST_SHELL], [sh])
-dnl select manpage formatter
+dnl select manpage formatter to be used to build "cat" format pages.
if test "x$MANDOC" != "x" ; then
MANFMT="$MANDOC"
elif test "x$NROFF" != "x" ; then
@@ -53,7 +62,7 @@ elif test "x$NROFF" != "x" ; then
elif test "x$GROFF" != "x" ; then
MANFMT="$GROFF -mandoc -Tascii"
else
- AC_MSG_WARN([no manpage formatted found])
+ AC_MSG_WARN([no manpage formatter found])
MANFMT="false"
fi
AC_SUBST([MANFMT])
@@ -93,6 +102,7 @@ AC_SUBST([LD])
AC_C_INLINE
AC_CHECK_DECL([LLONG_MAX], [have_llong_max=1], , [#include <limits.h>])
+AC_CHECK_DECL([LONG_LONG_MAX], [have_long_long_max=1], , [#include <limits.h>])
AC_CHECK_DECL([SYSTR_POLICY_KILL], [have_systr_policy_kill=1], , [
#include <sys/types.h>
#include <sys/param.h>
@@ -152,16 +162,20 @@ CFLAGS="$saved_CFLAGS"
if test "$GCC" = "yes" || test "$GCC" = "egcs"; then
OSSH_CHECK_CFLAG_COMPILE([-pipe])
- OSSH_CHECK_CFLAG_COMPILE([-Qunused-arguments])
OSSH_CHECK_CFLAG_COMPILE([-Wunknown-warning-option])
+ OSSH_CHECK_CFLAG_COMPILE([-Wno-error=format-truncation])
+ OSSH_CHECK_CFLAG_COMPILE([-Qunused-arguments])
OSSH_CHECK_CFLAG_COMPILE([-Wall])
+ OSSH_CHECK_CFLAG_COMPILE([-Wextra])
OSSH_CHECK_CFLAG_COMPILE([-Wpointer-arith])
OSSH_CHECK_CFLAG_COMPILE([-Wuninitialized])
OSSH_CHECK_CFLAG_COMPILE([-Wsign-compare])
OSSH_CHECK_CFLAG_COMPILE([-Wformat-security])
OSSH_CHECK_CFLAG_COMPILE([-Wsizeof-pointer-memaccess])
OSSH_CHECK_CFLAG_COMPILE([-Wpointer-sign], [-Wno-pointer-sign])
+ OSSH_CHECK_CFLAG_COMPILE([-Wunused-parameter], [-Wno-unused-parameter])
OSSH_CHECK_CFLAG_COMPILE([-Wunused-result], [-Wno-unused-result])
+ OSSH_CHECK_CFLAG_COMPILE([-Wimplicit-fallthrough])
OSSH_CHECK_CFLAG_COMPILE([-fno-strict-aliasing])
if test "x$use_toolchain_hardening" = "x1"; then
OSSH_CHECK_CFLAG_COMPILE([-mretpoline]) # clang
@@ -211,20 +225,26 @@ if test "$GCC" = "yes" || test "$GCC" = "egcs"; then
CFLAGS="$CFLAGS $t -Werror"
LDFLAGS="$LDFLAGS $t -Werror"
AC_LINK_IFELSE(
- [AC_LANG_PROGRAM([[ #include <stdio.h> ]],
+ [AC_LANG_PROGRAM([[
+ #include <stdio.h>
+ int func (int t) {char b[100]; snprintf(b,sizeof b,"%d",t); return t;}
+ ]],
[[
char x[256];
- snprintf(x, sizeof(x), "XXX");
+ snprintf(x, sizeof(x), "XXX%d", func(1));
]])],
[ AC_MSG_RESULT([yes])
CFLAGS="$saved_CFLAGS $t"
LDFLAGS="$saved_LDFLAGS $t"
AC_MSG_CHECKING([if $t works])
AC_RUN_IFELSE(
- [AC_LANG_PROGRAM([[ #include <stdio.h> ]],
+ [AC_LANG_PROGRAM([[
+ #include <stdio.h>
+ int func (int t) {char b[100]; snprintf(b,sizeof b,"%d",t); return t;}
+ ]],
[[
char x[256];
- snprintf(x, sizeof(x), "XXX");
+ snprintf(x, sizeof(x), "XXX%d", func(1));
]])],
[ AC_MSG_RESULT([yes])
break ],
@@ -277,6 +297,26 @@ typedef void foo(const char *, ...) __attribute__((format(printf, 1, 2)));]],
[compiler does not accept __attribute__ on prototype args]) ]
)
+AC_MSG_CHECKING([if compiler supports variable length arrays])
+AC_COMPILE_IFELSE(
+ [AC_LANG_PROGRAM([[#include <stdlib.h>]],
+ [[ int i; for (i=0; i<3; i++){int a[i]; a[i-1]=0;} exit(0); ]])],
+ [ AC_MSG_RESULT([yes])
+ AC_DEFINE(VARIABLE_LENGTH_ARRAYS, [1],
+ [compiler supports variable length arrays]) ],
+ [ AC_MSG_RESULT([no]) ]
+)
+
+AC_MSG_CHECKING([if compiler accepts variable declarations after code])
+AC_COMPILE_IFELSE(
+ [AC_LANG_PROGRAM([[#include <stdlib.h>]],
+ [[ int a; a = 1; int b = 1; exit(a-b); ]])],
+ [ AC_MSG_RESULT([yes])
+ AC_DEFINE(VARIABLE_DECLARATION_AFTER_CODE, [1],
+ [compiler variable declarations after code]) ],
+ [ AC_MSG_RESULT([no]) ]
+)
+
if test "x$no_attrib_nonnull" != "x1" ; then
AC_DEFINE([HAVE_ATTRIBUTE__NONNULL__], [1], [Have attribute nonnull])
fi
@@ -285,10 +325,11 @@ AC_ARG_WITH([rpath],
[ --without-rpath Disable auto-added -R linker paths],
[
if test "x$withval" = "xno" ; then
- need_dash_r=""
- fi
- if test "x$withval" = "xyes" ; then
- need_dash_r=1
+ rpath_opt=""
+ elif test "x$withval" = "xyes" ; then
+ rpath_opt="-R"
+ else
+ rpath_opt="$withval"
fi
]
)
@@ -373,6 +414,7 @@ AC_CHECK_HEADERS([ \
features.h \
fcntl.h \
floatingpoint.h \
+ fnmatch.h \
getopt.h \
glob.h \
ia.h \
@@ -402,6 +444,7 @@ AC_CHECK_HEADERS([ \
string.h \
strings.h \
sys/bitypes.h \
+ sys/byteorder.h \
sys/bsdtty.h \
sys/cdefs.h \
sys/dir.h \
@@ -587,7 +630,6 @@ case "$host" in
#include <fcntl.h> ]
)
check_for_aix_broken_getaddrinfo=1
- AC_DEFINE([BROKEN_REALPATH], [1], [Define if you have a broken realpath.])
AC_DEFINE([SETEUID_BREAKS_SETUID], [1],
[Define if your platform breaks doing a seteuid before a setuid])
AC_DEFINE([BROKEN_SETREUID], [1], [Define if your setreuid() is broken])
@@ -640,7 +682,9 @@ case "$host" in
*-*-darwin*)
use_pie=auto
AC_MSG_CHECKING([if we have working getaddrinfo])
- AC_RUN_IFELSE([AC_LANG_SOURCE([[ #include <mach-o/dyld.h>
+ AC_RUN_IFELSE([AC_LANG_SOURCE([[
+#include <mach-o/dyld.h>
+#include <stdlib.h>
main() { if (NSVersionOfRunTimeLibrary("System") >= (60 << 16))
exit(0);
else
@@ -679,6 +723,9 @@ main() { if (NSVersionOfRunTimeLibrary("System") >= (60 << 16))
AC_CHECK_LIB([sandbox], [sandbox_apply], [
SSHDLIBS="$SSHDLIBS -lsandbox"
])
+ # proc_pidinfo()-based closefrom() replacement.
+ AC_CHECK_HEADERS([libproc.h])
+ AC_CHECK_FUNCS([proc_pidinfo])
;;
*-*-dragonfly*)
SSHDLIBS="$SSHDLIBS -lcrypt"
@@ -686,8 +733,10 @@ main() { if (NSVersionOfRunTimeLibrary("System") >= (60 << 16))
;;
*-*-haiku*)
LIBS="$LIBS -lbsd "
+ CFLAGS="$CFLAGS -D_BSD_SOURCE"
AC_CHECK_LIB([network], [socket])
AC_DEFINE([HAVE_U_INT64_T])
+ AC_DEFINE([DISABLE_UTMPX], [1], [no utmpx])
MANTYPE=man
;;
*-*-hpux*)
@@ -816,7 +865,7 @@ main() { if (NSVersionOfRunTimeLibrary("System") >= (60 << 16))
AC_DEFINE([SYS_RDOMAIN_LINUX], [1],
[Support routing domains using Linux VRF]), [], [
#ifdef HAVE_SYS_TYPES_H
-# include <sys/types.H>
+# include <sys/types.h>
#endif
])
AC_CHECK_HEADERS([linux/seccomp.h linux/filter.h linux/audit.h], [],
@@ -895,6 +944,9 @@ main() { if (NSVersionOfRunTimeLibrary("System") >= (60 << 16))
;;
esac
;;
+ riscv64-*)
+ seccomp_audit_arch=AUDIT_ARCH_RISCV64
+ ;;
esac
if test "x$seccomp_audit_arch" != "x" ; then
AC_MSG_RESULT(["$seccomp_audit_arch"])
@@ -911,7 +963,7 @@ mips-sony-bsd|mips-sony-newsos4)
*-*-netbsd*)
check_for_libcrypt_before=1
if test "x$withval" != "xno" ; then
- need_dash_r=1
+ rpath_opt="-R"
fi
CPPFLAGS="$CPPFLAGS -D_OPENBSD_SOURCE"
AC_DEFINE([SSH_TUN_FREEBSD], [1], [Open tunnel devices the FreeBSD way])
@@ -947,7 +999,6 @@ mips-sony-bsd|mips-sony-newsos4)
conf_wtmp_location=/usr/adm/wtmp
maildir=/usr/spool/mail
AC_DEFINE([HAVE_NEXT], [1], [Define if you are on NeXT])
- AC_DEFINE([BROKEN_REALPATH])
AC_DEFINE([USE_PIPES])
AC_DEFINE([BROKEN_SAVED_UIDS], [1], [Needed for NeXT])
;;
@@ -962,7 +1013,7 @@ mips-sony-bsd|mips-sony-newsos4)
;;
*-*-solaris*)
if test "x$withval" != "xno" ; then
- need_dash_r=1
+ rpath_opt="-R"
fi
AC_DEFINE([PAM_SUN_CODEBASE])
AC_DEFINE([LOGIN_NEEDS_UTMPX])
@@ -1188,8 +1239,25 @@ mips-sony-bsd|mips-sony-newsos4)
*-*-ultrix*)
AC_DEFINE([BROKEN_GETGROUPS], [1], [getgroups(0,NULL) will return -1])
- AC_DEFINE([NEED_SETPGRP])
+ AC_DEFINE([NEED_SETPGRP], [1], [Need setpgrp to for controlling tty])
AC_DEFINE([HAVE_SYS_SYSLOG_H], [1], [Force use of sys/syslog.h on Ultrix])
+ AC_DEFINE([DISABLE_UTMPX], [1], [Disable utmpx])
+ # DISABLE_FD_PASSING so that we call setpgrp as root, otherwise we
+ # don't get a controlling tty.
+ AC_DEFINE([DISABLE_FD_PASSING], [1], [Need to call setpgrp as root])
+ # On Ultrix some headers are not protected against multiple includes,
+ # so we create wrappers and put it where the compiler will find it.
+ AC_MSG_WARN([creating compat wrappers for headers])
+ mkdir -p netinet
+ for header in netinet/ip.h netdb.h resolv.h; do
+ name=`echo $header | tr 'a-z/.' 'A-Z__'`
+ cat >$header <<EOD
+#ifndef _SSH_COMPAT_${name}
+#define _SSH_COMPAT_${name}
+#include "/usr/include/${header}"
+#endif
+EOD
+ done
;;
*-*-lynxos)
@@ -1200,7 +1268,7 @@ mips-sony-bsd|mips-sony-newsos4)
esac
AC_MSG_CHECKING([compiler and flags for sanity])
-AC_RUN_IFELSE([AC_LANG_PROGRAM([[ #include <stdio.h> ]], [[ exit(0); ]])],
+AC_RUN_IFELSE([AC_LANG_PROGRAM([[ #include <stdlib.h> ]], [[ exit(0); ]])],
[ AC_MSG_RESULT([yes]) ],
[
AC_MSG_RESULT([no])
@@ -1224,6 +1292,7 @@ AC_CHECK_FUNCS([dirname], [AC_CHECK_HEADERS([libgen.h])] , [
[AC_LANG_SOURCE([[
#include <libgen.h>
#include <string.h>
+#include <stdlib.h>
int main(int argc, char **argv) {
char *s, buf[32];
@@ -1256,21 +1325,22 @@ AC_CHECK_FUNC([getspnam], ,
AC_SEARCH_LIBS([basename], [gen], [AC_DEFINE([HAVE_BASENAME], [1],
[Define if you have the basename function.])])
-dnl zlib is required
+dnl zlib defaults to enabled
+zlib=yes
AC_ARG_WITH([zlib],
[ --with-zlib=PATH Use zlib in PATH],
[ if test "x$withval" = "xno" ; then
- AC_MSG_ERROR([*** zlib is required ***])
+ zlib=no
elif test "x$withval" != "xyes"; then
if test -d "$withval/lib"; then
- if test -n "${need_dash_r}"; then
- LDFLAGS="-L${withval}/lib -R${withval}/lib ${LDFLAGS}"
+ if test -n "${rpath_opt}"; then
+ LDFLAGS="-L${withval}/lib ${rpath_opt}${withval}/lib ${LDFLAGS}"
else
LDFLAGS="-L${withval}/lib ${LDFLAGS}"
fi
else
- if test -n "${need_dash_r}"; then
- LDFLAGS="-L${withval} -R${withval} ${LDFLAGS}"
+ if test -n "${rpath_opt}"; then
+ LDFLAGS="-L${withval} ${rpath_opt}${withval} ${LDFLAGS}"
else
LDFLAGS="-L${withval} ${LDFLAGS}"
fi
@@ -1283,15 +1353,21 @@ AC_ARG_WITH([zlib],
fi ]
)
-AC_CHECK_HEADER([zlib.h], ,[AC_MSG_ERROR([*** zlib.h missing - please install first or check config.log ***])])
-AC_CHECK_LIB([z], [deflate], ,
+AC_MSG_CHECKING([for zlib])
+if test "x${zlib}" = "xno"; then
+ AC_MSG_RESULT([no])
+else
+ AC_MSG_RESULT([yes])
+ AC_DEFINE([WITH_ZLIB], [1], [Enable zlib])
+ AC_CHECK_HEADER([zlib.h], ,[AC_MSG_ERROR([*** zlib.h missing - please install first or check config.log ***])])
+ AC_CHECK_LIB([z], [deflate], ,
[
saved_CPPFLAGS="$CPPFLAGS"
saved_LDFLAGS="$LDFLAGS"
save_LIBS="$LIBS"
dnl Check default zlib install dir
- if test -n "${need_dash_r}"; then
- LDFLAGS="-L/usr/local/lib -R/usr/local/lib ${saved_LDFLAGS}"
+ if test -n "${rpath_opt}"; then
+ LDFLAGS="-L/usr/local/lib ${rpath_opt}/usr/local/lib ${saved_LDFLAGS}"
else
LDFLAGS="-L/usr/local/lib ${saved_LDFLAGS}"
fi
@@ -1303,18 +1379,18 @@ AC_CHECK_LIB([z], [deflate], ,
]
)
]
-)
+ )
-AC_ARG_WITH([zlib-version-check],
+ AC_ARG_WITH([zlib-version-check],
[ --without-zlib-version-check Disable zlib version check],
[ if test "x$withval" = "xno" ; then
zlib_check_nonfatal=1
fi
]
-)
+ )
-AC_MSG_CHECKING([for possibly buggy zlib])
-AC_RUN_IFELSE([AC_LANG_PROGRAM([[
+ AC_MSG_CHECKING([for possibly buggy zlib])
+ AC_RUN_IFELSE([AC_LANG_PROGRAM([[
#include <stdio.h>
#include <stdlib.h>
#include <zlib.h>
@@ -1352,7 +1428,8 @@ See http://www.gzip.org/zlib/ for details.])
fi
],
[ AC_MSG_WARN([cross compiling: not checking zlib version]) ]
-)
+ )
+fi
dnl UnixWare 2.x
AC_CHECK_FUNC([strcasecmp],
@@ -1379,6 +1456,10 @@ AC_CHECK_FUNCS([fmt_scaled scan_scaled login logout openpty updwtmp logwtmp])
AC_SEARCH_LIBS([inet_ntop], [resolv nsl])
AC_SEARCH_LIBS([gethostbyname], [resolv nsl])
+# Some Linux distribtions ship the BSD libc hashing functions in
+# separate libraries.
+AC_SEARCH_LIBS([SHA256Update], [md bsd])
+
# "Particular Function Checks"
# see https://www.gnu.org/software/autoconf/manual/autoconf-2.69/html_node/Particular-Functions.html
AC_FUNC_STRFTIME
@@ -1467,7 +1548,9 @@ AC_MSG_CHECKING([whether struct dirent allocates space for d_name])
AC_RUN_IFELSE(
[AC_LANG_PROGRAM([[
#include <sys/types.h>
-#include <dirent.h>]],
+#include <dirent.h>
+#include <stdlib.h>
+ ]],
[[
struct dirent d;
exit(sizeof(d.d_name)<=sizeof(char));
@@ -1557,8 +1640,6 @@ AC_ARG_WITH(ldns,
if test "x$withval" = "xyes" ; then
AC_PATH_TOOL([LDNSCONFIG], [ldns-config], [no])
if test "x$LDNSCONFIG" = "xno"; then
- CPPFLAGS="$CPPFLAGS -I${withval}/include"
- LDFLAGS="$LDFLAGS -L${withval}/lib"
LIBS="-lldns $LIBS"
ldns=yes
else
@@ -1582,7 +1663,9 @@ AC_ARG_WITH(ldns,
[AC_LANG_SOURCE([[
#include <stdio.h>
#include <stdlib.h>
-#include <stdint.h>
+#ifdef HAVE_STDINT_H
+# include <stdint.h>
+#endif
#include <ldns/ldns.h>
int main() { ldns_status status = ldns_verify_trusted(NULL, NULL, NULL, NULL); status=LDNS_STATUS_OK; exit(0); }
]])
@@ -1613,8 +1696,8 @@ AC_ARG_WITH([libedit],
fi
else
CPPFLAGS="$CPPFLAGS -I${withval}/include"
- if test -n "${need_dash_r}"; then
- LDFLAGS="-L${withval}/lib -R${withval}/lib ${LDFLAGS}"
+ if test -n "${rpath_opt}"; then
+ LDFLAGS="-L${withval}/lib ${rpath_opt}${withval}/lib ${LDFLAGS}"
else
LDFLAGS="-L${withval}/lib ${LDFLAGS}"
fi
@@ -1636,7 +1719,10 @@ AC_ARG_WITH([libedit],
)
AC_MSG_CHECKING([if libedit version is compatible])
AC_COMPILE_IFELSE(
- [AC_LANG_PROGRAM([[ #include <histedit.h> ]],
+ [AC_LANG_PROGRAM([[
+#include <histedit.h>
+#include <stdlib.h>
+ ]],
[[
int i = H_SETSIZE;
el_init("", NULL, NULL, NULL);
@@ -1749,6 +1835,18 @@ if test "x$use_pie" != "xno"; then
fi
fi
+AC_MSG_CHECKING([whether -fPIC is accepted])
+SAVED_CFLAGS="$CFLAGS"
+CFLAGS="$CFLAGS -fPIC"
+AC_COMPILE_IFELSE(
+ [AC_LANG_PROGRAM( [[ #include <stdlib.h> ]], [[ exit(0); ]] )],
+ [AC_MSG_RESULT([yes])
+ PICFLAG="-fPIC"; ],
+ [AC_MSG_RESULT([no])
+ PICFLAG=""; ])
+CFLAGS="$SAVED_CFLAGS"
+AC_SUBST([PICFLAG])
+
dnl Checks for library functions. Please keep in alphabetical order
AC_CHECK_FUNCS([ \
auth_hostok \
@@ -1757,6 +1855,9 @@ AC_CHECK_FUNCS([ \
Blowfish_expandstate \
Blowfish_expand0state \
Blowfish_stream2word \
+ SHA256Update \
+ SHA384Update \
+ SHA512Update \
asprintf \
b64_ntop \
__b64_ntop \
@@ -1775,9 +1876,13 @@ AC_CHECK_FUNCS([ \
err \
errx \
explicit_bzero \
+ explicit_memset \
fchmod \
+ fchmodat \
fchown \
+ fchownat \
flock \
+ fnmatch \
freeaddrinfo \
freezero \
fstatfs \
@@ -1805,8 +1910,11 @@ AC_CHECK_FUNCS([ \
inet_ntop \
innetgr \
llabs \
+ localtime_r \
login_getcapbool \
+ login_getpwclass \
md5_crypt \
+ memmem \
memmove \
memset_s \
mkdtemp \
@@ -1817,10 +1925,12 @@ AC_CHECK_FUNCS([ \
pledge \
poll \
prctl \
+ pselect \
pstat \
raise \
readpassphrase \
reallocarray \
+ realpath \
recvmsg \
recallocarray \
rresvport_af \
@@ -1869,6 +1979,7 @@ AC_CHECK_FUNCS([ \
truncate \
unsetenv \
updwtmpx \
+ utimensat \
user_from_uid \
usleep \
vasprintf \
@@ -1877,7 +1988,7 @@ AC_CHECK_FUNCS([ \
warn \
])
-AC_CHECK_DECLS([bzero])
+AC_CHECK_DECLS([bzero, memmem])
dnl Wide character support.
AC_CHECK_FUNCS([mblen mbtowc nl_langinfo wcwidth])
@@ -1917,16 +2028,29 @@ AC_ARG_ENABLE([pkcs11],
]
)
-# PKCS11 depends on OpenSSL.
-if test "x$openssl" = "xyes" && test "x$disable_pkcs11" = "x"; then
- # PKCS#11 support requires dlopen() and co
- AC_SEARCH_LIBS([dlopen], [dl],
- AC_CHECK_DECL([RTLD_NOW],
- AC_DEFINE([ENABLE_PKCS11], [], [Enable for PKCS#11 support]),
- [], [#include <dlfcn.h>]
- )
- )
-fi
+disable_sk=
+AC_ARG_ENABLE([security-key],
+ [ --disable-security-key disable U2F/FIDO support code [no]],
+ [
+ if test "x$enableval" = "xno" ; then
+ disable_sk=1
+ fi
+ ]
+)
+enable_sk_internal=
+AC_ARG_WITH([security-key-builtin],
+ [ --with-security-key-builtin include builtin U2F/FIDO support],
+ [
+ if test "x$withval" != "xno" ; then
+ enable_sk_internal=yes
+ fi
+ ]
+)
+test "x$disable_sk" != "x" && enable_sk_internal=""
+
+AC_SEARCH_LIBS([dlopen], [dl])
+AC_CHECK_FUNCS([dlopen])
+AC_CHECK_DECL([RTLD_NOW], [], [], [#include <dlfcn.h>])
# IRIX has a const char return value for gai_strerror()
AC_CHECK_FUNCS([gai_strerror], [
@@ -1950,6 +2074,19 @@ AC_SEARCH_LIBS([nanosleep], [rt posix4], [AC_DEFINE([HAVE_NANOSLEEP], [1],
AC_SEARCH_LIBS([clock_gettime], [rt],
[AC_DEFINE([HAVE_CLOCK_GETTIME], [1], [Have clock_gettime])])
+dnl check if we need -D_REENTRANT for localtime_r declaration.
+AC_CHECK_DECL([localtime_r], [],
+ [ saved_CPPFLAGS="$CPPFLAGS"
+ CPPFLAGS="$CPPFLAGS -D_REENTRANT"
+ unset ac_cv_have_decl_localtime_r
+ AC_CHECK_DECL([localtime_r], [],
+ [ CPPFLAGS="$saved_CPPFLAGS" ],
+ [ #include <time.h> ]
+ )
+ ],
+ [ #include <time.h> ]
+)
+
dnl Make sure prototypes are defined for these before using them.
AC_CHECK_DECL([strsep],
[AC_CHECK_FUNCS([strsep])],
@@ -1969,10 +2106,11 @@ AC_CHECK_DECL([tcsendbreak],
AC_CHECK_DECLS([h_errno], , ,[#include <netdb.h>])
-AC_CHECK_DECLS([SHUT_RD], , ,
+AC_CHECK_DECLS([SHUT_RD, getpeereid], , ,
[
#include <sys/types.h>
#include <sys/socket.h>
+#include <unistd.h>
])
AC_CHECK_DECLS([O_NONBLOCK], , ,
@@ -2077,35 +2215,13 @@ AC_CHECK_FUNCS([setresgid], [
)
])
-AC_CHECK_FUNCS([realpath], [
- dnl the sftp v3 spec says SSH_FXP_REALPATH will "canonicalize any given
- dnl path name", however some implementations of realpath (and some
- dnl versions of the POSIX spec) do not work on non-existent files,
- dnl so we use the OpenBSD implementation on those platforms.
- AC_MSG_CHECKING([if realpath works with non-existent files])
- AC_RUN_IFELSE(
- [AC_LANG_PROGRAM([[
-#include <limits.h>
-#include <stdlib.h>
-#include <errno.h>
- ]], [[
- char buf[PATH_MAX];
- if (realpath("/opensshnonexistentfilename1234", buf) == NULL)
- if (errno == ENOENT)
- exit(1);
- exit(0);
- ]])],
- [AC_MSG_RESULT([yes])],
- [AC_DEFINE([BROKEN_REALPATH], [1],
- [realpath does not work with nonexistent files])
- AC_MSG_RESULT([no])],
- [AC_MSG_WARN([cross compiling: assuming working])]
- )
-])
-
AC_MSG_CHECKING([for working fflush(NULL)])
AC_RUN_IFELSE(
- [AC_LANG_PROGRAM([[#include <stdio.h>]], [[fflush(NULL); exit(0);]])],
+ [AC_LANG_PROGRAM([[
+#include <stdio.h>
+#include <stdlib.h>
+ ]],
+ [[fflush(NULL); exit(0);]])],
AC_MSG_RESULT([yes]),
[AC_MSG_RESULT([no])
AC_DEFINE([FFLUSH_NULL_BUG], [1],
@@ -2141,7 +2257,10 @@ AC_CHECK_FUNC([getpagesize],
if test "x$ac_cv_func_snprintf" = "xyes" ; then
AC_MSG_CHECKING([whether snprintf correctly terminates long strings])
AC_RUN_IFELSE(
- [AC_LANG_PROGRAM([[ #include <stdio.h> ]],
+ [AC_LANG_PROGRAM([[
+#include <stdio.h>
+#include <stdlib.h>
+ ]],
[[
char b[5];
snprintf(b,5,"123456789");
@@ -2164,6 +2283,8 @@ if test "x$ac_cv_func_snprintf" = "xyes" ; then
[AC_LANG_PROGRAM([[
#include <sys/types.h>
#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
]],
[[
size_t a = 1, b = 2;
@@ -2250,39 +2371,14 @@ if test "x$ac_cv_func_getpeereid" != "xyes" -a "x$ac_cv_func_getpeerucred" != "x
])
fi
-dnl see whether mkstemp() requires XXXXXX
-if test "x$ac_cv_func_mkdtemp" = "xyes" ; then
-AC_MSG_CHECKING([for (overly) strict mkstemp])
-AC_RUN_IFELSE(
- [AC_LANG_PROGRAM([[
-#include <stdlib.h>
- ]], [[
- char template[]="conftest.mkstemp-test";
- if (mkstemp(template) == -1)
- exit(1);
- unlink(template);
- exit(0);
- ]])],
- [
- AC_MSG_RESULT([no])
- ],
- [
- AC_MSG_RESULT([yes])
- AC_DEFINE([HAVE_STRICT_MKSTEMP], [1], [Silly mkstemp()])
- ],
- [
- AC_MSG_RESULT([yes])
- AC_DEFINE([HAVE_STRICT_MKSTEMP])
- ]
-)
-fi
-
dnl make sure that openpty does not reacquire controlling terminal
if test ! -z "$check_for_openpty_ctty_bug"; then
AC_MSG_CHECKING([if openpty correctly handles controlling tty])
AC_RUN_IFELSE(
[AC_LANG_PROGRAM([[
#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
#include <sys/fcntl.h>
#include <sys/types.h>
#include <sys/wait.h>
@@ -2329,6 +2425,7 @@ if test "x$ac_cv_func_getaddrinfo" = "xyes" && \
AC_RUN_IFELSE(
[AC_LANG_PROGRAM([[
#include <stdio.h>
+#include <stdlib.h>
#include <sys/socket.h>
#include <netdb.h>
#include <errno.h>
@@ -2397,6 +2494,7 @@ if test "x$ac_cv_func_getaddrinfo" = "xyes" && \
AC_RUN_IFELSE(
[AC_LANG_PROGRAM([[
#include <stdio.h>
+#include <stdlib.h>
#include <sys/socket.h>
#include <netdb.h>
#include <errno.h>
@@ -2459,7 +2557,10 @@ fi
if test "x$check_for_conflicting_getspnam" = "x1"; then
AC_MSG_CHECKING([for conflicting getspnam in shadow.h])
- AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include <shadow.h> ]],
+ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
+#include <shadow.h>
+#include <stdlib.h>
+ ]],
[[ exit(0); ]])],
[
AC_MSG_RESULT([no])
@@ -2489,6 +2590,7 @@ if test "x$ac_cv_func_strnvis" = "xyes"; then
#include <signal.h>
#include <stdlib.h>
#include <string.h>
+#include <unistd.h>
#include <vis.h>
static void sighandler(int sig) { _exit(1); }
]], [[
@@ -2507,6 +2609,46 @@ static void sighandler(int sig) { _exit(1); }
)
fi
+AC_MSG_CHECKING([if SA_RESTARTed signals interrupt select()])
+AC_RUN_IFELSE(
+ [AC_LANG_PROGRAM([[
+#ifdef HAVE_SYS_SELECT
+# include <sys/select.h>
+#endif
+#include <sys/types.h>
+#include <sys/time.h>
+#include <stdlib.h>
+#include <signal.h>
+#include <unistd.h>
+static void sighandler(int sig) { }
+ ]], [[
+ int r;
+ pid_t pid;
+ struct sigaction sa;
+
+ sa.sa_handler = sighandler;
+ sa.sa_flags = SA_RESTART;
+ (void)sigaction(SIGTERM, &sa, NULL);
+ if ((pid = fork()) == 0) { /* child */
+ pid = getppid();
+ sleep(1);
+ kill(pid, SIGTERM);
+ sleep(1);
+ if (getppid() == pid) /* if parent did not exit, shoot it */
+ kill(pid, SIGKILL);
+ exit(0);
+ } else { /* parent */
+ r = select(0, NULL, NULL, NULL, NULL);
+ }
+ exit(r == -1 ? 0 : 1);
+ ]])],
+ [AC_MSG_RESULT([yes])],
+ [AC_MSG_RESULT([no])
+ AC_DEFINE([NO_SA_RESTART], [1],
+ [SA_RESTARTed signals do no interrupt select])],
+ [AC_MSG_WARN([cross compiling: assuming yes])]
+)
+
AC_CHECK_FUNCS([getpgrp],[
AC_MSG_CHECKING([if getpgrp accepts zero args])
AC_COMPILE_IFELSE(
@@ -2533,20 +2675,20 @@ AC_ARG_WITH([ssl-dir],
./*|../*) withval="`pwd`/$withval"
esac
if test -d "$withval/lib"; then
- if test -n "${need_dash_r}"; then
- LDFLAGS="-L${withval}/lib -R${withval}/lib ${LDFLAGS}"
+ if test -n "${rpath_opt}"; then
+ LDFLAGS="-L${withval}/lib ${rpath_opt}${withval}/lib ${LDFLAGS}"
else
LDFLAGS="-L${withval}/lib ${LDFLAGS}"
fi
elif test -d "$withval/lib64"; then
- if test -n "${need_dash_r}"; then
- LDFLAGS="-L${withval}/lib64 -R${withval}/lib64 ${LDFLAGS}"
+ if test -n "${rpath_opt}"; then
+ LDFLAGS="-L${withval}/lib64 ${rpath_opt}${withval}/lib64 ${LDFLAGS}"
else
LDFLAGS="-L${withval}/lib64 ${LDFLAGS}"
fi
else
- if test -n "${need_dash_r}"; then
- LDFLAGS="-L${withval} -R${withval} ${LDFLAGS}"
+ if test -n "${rpath_opt}"; then
+ LDFLAGS="-L${withval} ${rpath_opt}${withval} ${LDFLAGS}"
else
LDFLAGS="-L${withval} ${LDFLAGS}"
fi
@@ -2584,26 +2726,10 @@ AC_ARG_WITH([ssl-engine],
if test "x$openssl" = "xyes" ; then
LIBS="-lcrypto $LIBS"
- AC_TRY_LINK_FUNC([RAND_add], [AC_DEFINE([HAVE_OPENSSL], [1],
- [Define if your ssl headers are included
- with #include <openssl/header.h>])],
- [
- dnl Check default openssl install dir
- if test -n "${need_dash_r}"; then
- LDFLAGS="-L/usr/local/ssl/lib -R/usr/local/ssl/lib ${saved_LDFLAGS}"
- else
- LDFLAGS="-L/usr/local/ssl/lib ${saved_LDFLAGS}"
- fi
- CPPFLAGS="-I/usr/local/ssl/include ${saved_CPPFLAGS}"
- AC_CHECK_HEADER([openssl/opensslv.h], ,
- [AC_MSG_ERROR([*** OpenSSL headers missing - please install first or check config.log ***])])
- AC_TRY_LINK_FUNC([RAND_add], [AC_DEFINE([HAVE_OPENSSL])],
- [
- AC_MSG_ERROR([*** Can't find recent OpenSSL libcrypto (see config.log for details) ***])
- ]
- )
- ]
- )
+ AC_TRY_LINK_FUNC([RAND_add], ,
+ [AC_MSG_ERROR([*** working libcrypto not found, check config.log])])
+ AC_CHECK_HEADER([openssl/opensslv.h], ,
+ [AC_MSG_ERROR([*** OpenSSL headers missing - please install first or check config.log ***])])
# Determine OpenSSL header version
AC_MSG_CHECKING([OpenSSL header version])
@@ -2642,11 +2768,15 @@ if test "x$openssl" = "xyes" ; then
]
)
+ # Determining OpenSSL library version is version dependent.
+ AC_CHECK_FUNCS([OpenSSL_version OpenSSL_version_num])
+
# Determine OpenSSL library version
AC_MSG_CHECKING([OpenSSL library version])
AC_RUN_IFELSE(
[AC_LANG_PROGRAM([[
#include <stdio.h>
+ #include <stdlib.h>
#include <string.h>
#include <openssl/opensslv.h>
#include <openssl/crypto.h>
@@ -2658,9 +2788,18 @@ if test "x$openssl" = "xyes" ; then
fd = fopen(DATA,"w");
if(fd == NULL)
exit(1);
-
- if ((rc = fprintf(fd, "%08lx (%s)\n", (unsigned long)SSLeay(),
- SSLeay_version(SSLEAY_VERSION))) < 0)
+#ifndef OPENSSL_VERSION
+# define OPENSSL_VERSION SSLEAY_VERSION
+#endif
+#ifndef HAVE_OPENSSL_VERSION
+# define OpenSSL_version SSLeay_version
+#endif
+#ifndef HAVE_OPENSSL_VERSION_NUM
+# define OpenSSL_version_num SSLeay
+#endif
+ if ((rc = fprintf(fd, "%08lx (%s)\n",
+ (unsigned long)OpenSSL_version_num(),
+ OpenSSL_version(OPENSSL_VERSION))) < 0)
exit(1);
exit(0);
@@ -2673,14 +2812,15 @@ if test "x$openssl" = "xyes" ; then
AC_MSG_ERROR([OpenSSL >= 1.0.1 required (have "$ssl_library_ver")])
;;
100*) ;; # 1.0.x
- 101000[0123456]*)
+ 101000[[0123456]]*)
# https://github.com/openssl/openssl/pull/4613
AC_MSG_ERROR([OpenSSL 1.1.x versions prior to 1.1.0g have a bug that breaks their use with OpenSSH (have "$ssl_library_ver")])
;;
101*) ;; # 1.1.x
200*) ;; # LibreSSL
+ 300*) ;; # OpenSSL development branch.
*)
- AC_MSG_ERROR([OpenSSL > 1.1.x is not yet supported (have "$ssl_library_ver")])
+ AC_MSG_ERROR([Unknown/unsupported OpenSSL version ("$ssl_library_ver")])
;;
esac
AC_MSG_RESULT([$ssl_library_ver])
@@ -2698,11 +2838,15 @@ if test "x$openssl" = "xyes" ; then
AC_MSG_CHECKING([whether OpenSSL's headers match the library])
AC_RUN_IFELSE(
[AC_LANG_PROGRAM([[
+ #include <stdlib.h>
#include <string.h>
#include <openssl/opensslv.h>
#include <openssl/crypto.h>
]], [[
- exit(SSLeay() == OPENSSL_VERSION_NUMBER ? 0 : 1);
+#ifndef HAVE_OPENSSL_VERSION_NUM
+# define OpenSSL_version_num SSLeay
+#endif
+ exit(OpenSSL_version_num() == OPENSSL_VERSION_NUMBER ? 0 : 1);
]])],
[
AC_MSG_RESULT([yes])
@@ -2729,8 +2873,8 @@ if test "x$openssl" = "xyes" ; then
AC_MSG_CHECKING([if programs using OpenSSL functions will link])
AC_LINK_IFELSE(
- [AC_LANG_PROGRAM([[ #include <openssl/evp.h> ]],
- [[ SSLeay_add_all_algorithms(); ]])],
+ [AC_LANG_PROGRAM([[ #include <openssl/err.h> ]],
+ [[ ERR_load_crypto_strings(); ]])],
[
AC_MSG_RESULT([yes])
],
@@ -2740,8 +2884,8 @@ if test "x$openssl" = "xyes" ; then
LIBS="$LIBS -ldl"
AC_MSG_CHECKING([if programs using OpenSSL need -ldl])
AC_LINK_IFELSE(
- [AC_LANG_PROGRAM([[ #include <openssl/evp.h> ]],
- [[ SSLeay_add_all_algorithms(); ]])],
+ [AC_LANG_PROGRAM([[ #include <openssl/err.h> ]],
+ [[ ERR_load_crypto_strings(); ]])],
[
AC_MSG_RESULT([yes])
],
@@ -2756,16 +2900,66 @@ if test "x$openssl" = "xyes" ; then
AC_CHECK_FUNCS([ \
BN_is_prime_ex \
DSA_generate_parameters_ex \
- EVP_DigestInit_ex \
+ EVP_CIPHER_CTX_ctrl \
EVP_DigestFinal_ex \
- EVP_MD_CTX_init \
+ EVP_DigestInit_ex \
EVP_MD_CTX_cleanup \
EVP_MD_CTX_copy_ex \
+ EVP_MD_CTX_init \
HMAC_CTX_init \
RSA_generate_key_ex \
RSA_get_default_method \
])
+ # OpenSSL_add_all_algorithms may be a macro.
+ AC_CHECK_FUNC(OpenSSL_add_all_algorithms,
+ AC_DEFINE(HAVE_OPENSSL_ADD_ALL_ALGORITHMS, 1, [as a function]),
+ AC_CHECK_DECL(OpenSSL_add_all_algorithms,
+ AC_DEFINE(HAVE_OPENSSL_ADD_ALL_ALGORITHMS, 1, [as a macro]), ,
+ [[#include <openssl/evp.h>]]
+ )
+ )
+
+ # LibreSSL/OpenSSL 1.1x API
+ AC_CHECK_FUNCS([ \
+ OPENSSL_init_crypto \
+ DH_get0_key \
+ DH_get0_pqg \
+ DH_set0_key \
+ DH_set_length \
+ DH_set0_pqg \
+ DSA_get0_key \
+ DSA_get0_pqg \
+ DSA_set0_key \
+ DSA_set0_pqg \
+ DSA_SIG_get0 \
+ DSA_SIG_set0 \
+ ECDSA_SIG_get0 \
+ ECDSA_SIG_set0 \
+ EVP_CIPHER_CTX_iv \
+ EVP_CIPHER_CTX_iv_noconst \
+ EVP_CIPHER_CTX_get_iv \
+ EVP_CIPHER_CTX_get_updated_iv \
+ EVP_CIPHER_CTX_set_iv \
+ RSA_get0_crt_params \
+ RSA_get0_factors \
+ RSA_get0_key \
+ RSA_set0_crt_params \
+ RSA_set0_factors \
+ RSA_set0_key \
+ RSA_meth_free \
+ RSA_meth_dup \
+ RSA_meth_set1_name \
+ RSA_meth_get_finish \
+ RSA_meth_set_priv_enc \
+ RSA_meth_set_priv_dec \
+ RSA_meth_set_finish \
+ EVP_PKEY_get0_RSA \
+ EVP_MD_CTX_new \
+ EVP_MD_CTX_free \
+ EVP_chacha20 \
+ ])
+
if test "x$openssl_engine" = "xyes" ; then
AC_MSG_CHECKING([for OpenSSL ENGINE support])
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
@@ -2785,6 +2979,7 @@ if test "x$openssl" = "xyes" ; then
AC_MSG_CHECKING([whether OpenSSL has crippled AES support])
AC_LINK_IFELSE(
[AC_LANG_PROGRAM([[
+ #include <stdlib.h>
#include <string.h>
#include <openssl/evp.h>
]], [[
@@ -2804,6 +2999,7 @@ if test "x$openssl" = "xyes" ; then
AC_MSG_CHECKING([whether OpenSSL has AES CTR via EVP])
AC_LINK_IFELSE(
[AC_LANG_PROGRAM([[
+ #include <stdlib.h>
#include <string.h>
#include <openssl/evp.h>
]], [[
@@ -2825,6 +3021,7 @@ if test "x$openssl" = "xyes" ; then
AC_MSG_CHECKING([whether OpenSSL has AES GCM via EVP])
AC_LINK_IFELSE(
[AC_LANG_PROGRAM([[
+ #include <stdlib.h>
#include <string.h>
#include <openssl/evp.h>
]], [[
@@ -2849,122 +3046,10 @@ if test "x$openssl" = "xyes" ; then
]
)
- AC_SEARCH_LIBS([EVP_CIPHER_CTX_ctrl], [crypto],
- [AC_DEFINE([HAVE_EVP_CIPHER_CTX_CTRL], [1],
- [Define if libcrypto has EVP_CIPHER_CTX_ctrl])])
-
- # LibreSSL/OpenSSL 1.1x API
- AC_SEARCH_LIBS([DH_get0_key], [crypto],
- [AC_DEFINE([HAVE_DH_GET0_KEY], [1],
- [Define if libcrypto has DH_get0_key])])
- AC_SEARCH_LIBS([DH_get0_pqg], [crypto],
- [AC_DEFINE([HAVE_DH_GET0_PQG], [1],
- [Define if libcrypto has DH_get0_pqg])])
- AC_SEARCH_LIBS([DH_set0_key], [crypto],
- [AC_DEFINE([HAVE_DH_SET0_KEY], [1],
- [Define if libcrypto has DH_set0_key])])
- AC_SEARCH_LIBS([DH_set_length], [crypto],
- [AC_DEFINE([HAVE_DH_SET_LENGTH], [1],
- [Define if libcrypto has DH_set_length])])
- AC_SEARCH_LIBS([DH_set0_pqg], [crypto],
- [AC_DEFINE([HAVE_DH_SET0_PQG], [1],
- [Define if libcrypto has DH_set0_pqg])])
-
- AC_SEARCH_LIBS([DSA_get0_key], [crypto],
- [AC_DEFINE([HAVE_DSA_GET0_KEY], [1],
- [Define if libcrypto has DSA_get0_key])])
- AC_SEARCH_LIBS([DSA_get0_pqg], [crypto],
- [AC_DEFINE([HAVE_DSA_GET0_PQG], [1],
- [Define if libcrypto has DSA_get0_pqg])])
- AC_SEARCH_LIBS([DSA_set0_key], [crypto],
- [AC_DEFINE([HAVE_DSA_SET0_KEY], [1],
- [Define if libcrypto has DSA_set0_key])])
- AC_SEARCH_LIBS([DSA_set0_pqg], [crypto],
- [AC_DEFINE([HAVE_DSA_SET0_PQG], [1],
- [Define if libcrypto has DSA_set0_pqg])])
-
- AC_SEARCH_LIBS([DSA_SIG_get0], [crypto],
- [AC_DEFINE([HAVE_DSA_SIG_GET0], [1],
- [Define if libcrypto has DSA_SIG_get0])])
- AC_SEARCH_LIBS([DSA_SIG_set0], [crypto],
- [AC_DEFINE([HAVE_DSA_SIG_SET0], [1],
- [Define if libcrypto has DSA_SIG_set0])])
-
- AC_SEARCH_LIBS([ECDSA_SIG_get0], [crypto],
- [AC_DEFINE([HAVE_ECDSA_SIG_GET0], [1],
- [Define if libcrypto has ECDSA_SIG_get0])])
- AC_SEARCH_LIBS([ECDSA_SIG_set0], [crypto],
- [AC_DEFINE([HAVE_ECDSA_SIG_SET0], [1],
- [Define if libcrypto has ECDSA_SIG_set0])])
-
- AC_SEARCH_LIBS([EVP_CIPHER_CTX_iv], [crypto],
- [AC_DEFINE([HAVE_EVP_CIPHER_CTX_IV], [1],
- [Define if libcrypto has EVP_CIPHER_CTX_iv])])
- AC_SEARCH_LIBS([EVP_CIPHER_CTX_iv_noconst], [crypto],
- [AC_DEFINE([HAVE_EVP_CIPHER_CTX_IV_NOCONST], [1],
- [Define if libcrypto has EVP_CIPHER_CTX_iv_noconst])])
- AC_SEARCH_LIBS([EVP_CIPHER_CTX_get_iv], [crypto],
- [AC_DEFINE([HAVE_EVP_CIPHER_CTX_GET_IV], [1],
- [Define if libcrypto has EVP_CIPHER_CTX_get_iv])])
- AC_SEARCH_LIBS([EVP_CIPHER_CTX_set_iv], [crypto],
- [AC_DEFINE([HAVE_EVP_CIPHER_CTX_GET_IV], [1],
- [Define if libcrypto has EVP_CIPHER_CTX_set_iv])])
-
- AC_SEARCH_LIBS([RSA_get0_crt_params], [crypto],
- [AC_DEFINE([HAVE_RSA_GET0_CRT_PARAMS], [1],
- [Define if libcrypto has RSA_get0_crt_params])])
- AC_SEARCH_LIBS([RSA_get0_factors], [crypto],
- [AC_DEFINE([HAVE_RSA_GET0_FACTORS], [1],
- [Define if libcrypto has RSA_get0_factors])])
- AC_SEARCH_LIBS([RSA_get0_key], [crypto],
- [AC_DEFINE([HAVE_RSA_GET0_KEY], [1],
- [Define if libcrypto has RSA_get0_key])])
- AC_SEARCH_LIBS([RSA_set0_crt_params], [crypto],
- [AC_DEFINE([HAVE_RSA_SET0_CRT_PARAMS], [1],
- [Define if libcrypto has RSA_get0_srt_params])])
- AC_SEARCH_LIBS([RSA_set0_factors], [crypto],
- [AC_DEFINE([HAVE_RSA_SET0_FACTORS], [1],
- [Define if libcrypto has RSA_set0_factors])])
- AC_SEARCH_LIBS([RSA_set0_key], [crypto],
- [AC_DEFINE([HAVE_RSA_SET0_KEY], [1],
- [Define if libcrypto has RSA_set0_key])])
-
- AC_SEARCH_LIBS([RSA_meth_free], [crypto],
- [AC_DEFINE([HAVE_RSA_METH_FREE], [1],
- [Define if libcrypto has RSA_meth_free])])
- AC_SEARCH_LIBS([RSA_meth_dup], [crypto],
- [AC_DEFINE([HAVE_RSA_METH_DUP], [1],
- [Define if libcrypto has RSA_meth_dup])])
- AC_SEARCH_LIBS([RSA_meth_set1_name], [crypto],
- [AC_DEFINE([HAVE_RSA_METH_SET1_NAME], [1],
- [Define if libcrypto has RSA_meth_set1_name])])
- AC_SEARCH_LIBS([RSA_meth_get_finish], [crypto],
- [AC_DEFINE([HAVE_RSA_METH_GET_FINISH], [1],
- [Define if libcrypto has RSA_meth_get_finish])])
- AC_SEARCH_LIBS([RSA_meth_set_priv_enc], [crypto],
- [AC_DEFINE([HAVE_RSA_METH_SET_PRIV_ENC], [1],
- [Define if libcrypto has RSA_meth_set_priv_enc])])
- AC_SEARCH_LIBS([RSA_meth_set_priv_dec], [crypto],
- [AC_DEFINE([HAVE_RSA_METH_SET_PRIV_DEC], [1],
- [Define if libcrypto has RSA_meth_set_priv_dec])])
- AC_SEARCH_LIBS([RSA_meth_set_finish], [crypto],
- [AC_DEFINE([HAVE_RSA_METH_SET_FINISH], [1],
- [Define if libcrypto has RSA_meth_set_finish])])
-
- AC_SEARCH_LIBS([EVP_PKEY_get0_RSA], [crypto],
- [AC_DEFINE([HAVE_EVP_PKEY_GET0_RSA], [1],
- [Define if libcrypto has EVP_PKEY_get0_RSA])])
-
- AC_SEARCH_LIBS([EVP_MD_CTX_new], [crypto],
- [AC_DEFINE([HAVE_EVP_MD_CTX_NEW], [1],
- [Define if libcrypto has EVP_MD_CTX_new])])
- AC_SEARCH_LIBS([EVP_MD_CTX_free], [crypto],
- [AC_DEFINE([HAVE_EVP_MD_CTX_FREE], [1],
- [Define if libcrypto has EVP_MD_CTX_free])])
-
AC_MSG_CHECKING([if EVP_DigestUpdate returns an int])
AC_LINK_IFELSE(
[AC_LANG_PROGRAM([[
+ #include <stdlib.h>
#include <string.h>
#include <openssl/evp.h>
]], [[
@@ -2994,24 +3079,8 @@ if test "x$openssl" = "xyes" ; then
fi
AC_CHECK_FUNCS([crypt DES_crypt])
- # Search for SHA256 support in libc and/or OpenSSL
- AC_CHECK_FUNCS([SHA256_Update EVP_sha256], ,
- [unsupported_algorithms="$unsupported_algorithms \
- hmac-sha2-256 \
- hmac-sha2-512 \
- diffie-hellman-group-exchange-sha256 \
- hmac-sha2-256-etm@openssh.com \
- hmac-sha2-512-etm@openssh.com"
- ]
- )
- # Search for RIPE-MD support in OpenSSL
- AC_CHECK_FUNCS([EVP_ripemd160], ,
- [unsupported_algorithms="$unsupported_algorithms \
- hmac-ripemd160 \
- hmac-ripemd160@openssh.com \
- hmac-ripemd160-etm@openssh.com"
- ]
- )
+ # Check for SHA256, SHA384 and SHA512 support in OpenSSL
+ AC_CHECK_FUNCS([EVP_sha256 EVP_sha384 EVP_sha512])
# Check complete ECC support in OpenSSL
AC_MSG_CHECKING([whether OpenSSL has NID_X9_62_prime256v1])
@@ -3067,6 +3136,7 @@ if test "x$openssl" = "xyes" ; then
AC_MSG_CHECKING([if OpenSSL's NID_secp521r1 is functional])
AC_RUN_IFELSE(
[AC_LANG_PROGRAM([[
+ #include <stdlib.h>
#include <openssl/ec.h>
#include <openssl/ecdh.h>
#include <openssl/ecdsa.h>
@@ -3093,6 +3163,10 @@ if test "x$openssl" = "xyes" ; then
if test x$enable_nistp256 = x1 || test x$enable_nistp384 = x1 || \
test x$enable_nistp521 = x1; then
AC_DEFINE(OPENSSL_HAS_ECC, [1], [OpenSSL has ECC])
+ AC_CHECK_FUNCS([EC_KEY_METHOD_new])
+ openssl_ecc=yes
+ else
+ openssl_ecc=no
fi
if test x$enable_nistp256 = x1; then
AC_DEFINE([OPENSSL_HAS_NISTP256], [1],
@@ -3133,6 +3207,94 @@ else
AC_CHECK_FUNCS([crypt])
fi
+# PKCS11/U2F depend on OpenSSL and dlopen().
+enable_pkcs11=yes
+enable_sk=yes
+if test "x$openssl" != "xyes" ; then
+ enable_pkcs11="disabled; missing libcrypto"
+ enable_sk="disabled; missing libcrypto"
+fi
+if test "x$openssl_ecc" != "xyes" ; then
+ enable_sk="disabled; OpenSSL has no ECC support"
+fi
+if test "x$ac_cv_func_dlopen" != "xyes" ; then
+ enable_pkcs11="disabled; missing dlopen(3)"
+ enable_sk="disabled; missing dlopen(3)"
+fi
+if test "x$ac_cv_have_decl_RTLD_NOW" != "xyes" ; then
+ enable_pkcs11="disabled; missing RTLD_NOW"
+ enable_sk="disabled; missing RTLD_NOW"
+fi
+if test ! -z "$disable_pkcs11" ; then
+ enable_pkcs11="disabled by user"
+fi
+if test ! -z "$disable_sk" ; then
+ enable_sk="disabled by user"
+fi
+
+AC_MSG_CHECKING([whether to enable PKCS11])
+if test "x$enable_pkcs11" = "xyes" ; then
+ AC_DEFINE([ENABLE_PKCS11], [], [Enable for PKCS#11 support])
+fi
+AC_MSG_RESULT([$enable_pkcs11])
+
+AC_MSG_CHECKING([whether to enable U2F])
+if test "x$enable_sk" = "xyes" ; then
+ AC_DEFINE([ENABLE_SK], [], [Enable for U2F/FIDO support])
+ AC_SUBST(SK_DUMMY_LIBRARY, [regress/misc/sk-dummy/sk-dummy.so])
+else
+ # Do not try to build sk-dummy library.
+ AC_SUBST(SK_DUMMY_LIBRARY, [""])
+fi
+AC_MSG_RESULT([$enable_sk])
+
+# Now check for built-in security key support.
+if test "x$enable_sk" = "xyes" -a "x$enable_sk_internal" = "xyes" ; then
+ AC_PATH_TOOL([PKGCONFIG], [pkg-config], [no])
+ use_pkgconfig_for_libfido2=
+ if test "x$PKGCONFIG" != "xno"; then
+ AC_MSG_CHECKING([if $PKGCONFIG knows about libfido2])
+ if "$PKGCONFIG" libfido2; then
+ AC_MSG_RESULT([yes])
+ use_pkgconfig_for_libfido2=yes
+ else
+ AC_MSG_RESULT([no])
+ fi
+ fi
+ if test "x$use_pkgconfig_for_libfido2" = "xyes"; then
+ LIBFIDO2=`$PKGCONFIG --libs libfido2`
+ CPPFLAGS="$CPPFLAGS `$PKGCONFIG --cflags libfido2`"
+ else
+ LIBFIDO2="-lfido2 -lcbor"
+ fi
+ OTHERLIBS=`echo $LIBFIDO2 | sed 's/-lfido2//'`
+ AC_CHECK_LIB([fido2], [fido_init],
+ [
+ AC_SUBST([LIBFIDO2])
+ AC_DEFINE([ENABLE_SK_INTERNAL], [],
+ [Enable for built-in U2F/FIDO support])
+ enable_sk="built-in"
+ ], [ AC_MSG_ERROR([no usable libfido2 found]) ],
+ [ $OTHERLIBS ]
+ )
+ saved_LIBS="$LIBS"
+ LIBS="$LIBS $LIBFIDO2"
+ AC_CHECK_FUNCS([ \
+ fido_cred_prot \
+ fido_cred_set_prot \
+ fido_dev_get_touch_begin \
+ fido_dev_get_touch_status \
+ fido_dev_supports_cred_prot \
+ ])
+ LIBS="$saved_LIBS"
+ AC_CHECK_HEADER([fido.h], [],
+ AC_MSG_ERROR([missing fido.h from libfido2]))
+ AC_CHECK_HEADER([fido/credman.h], [],
+ AC_MSG_ERROR([missing fido/credman.h from libfido2]),
+ [#include <fido.h>]
+ )
+fi
+
AC_CHECK_FUNCS([ \
arc4random \
arc4random_buf \
@@ -3157,6 +3319,7 @@ if test "x$openssl" = "xyes" ; then
AC_MSG_CHECKING([whether OpenSSL's PRNG is internally seeded])
AC_RUN_IFELSE(
[AC_LANG_PROGRAM([[
+ #include <stdlib.h>
#include <string.h>
#include <openssl/rand.h>
]], [[
@@ -3459,8 +3622,7 @@ AC_RUN_IFELSE(
#include <stdlib.h>
]],[[
struct rlimit rl_zero;
- int fd, r;
- fd_set fds;
+ int r;
rl_zero.rlim_cur = rl_zero.rlim_max = 0;
r = setrlimit(RLIMIT_NOFILE, &rl_zero);
@@ -3569,14 +3731,24 @@ if test ! -z "$SONY" ; then
LIBS="$LIBS -liberty";
fi
-# Check for long long datatypes
+# Check for long long datatypes
AC_CHECK_TYPES([long long, unsigned long long, long double])
# Check datatype sizes
-AC_CHECK_SIZEOF([short int], [2])
-AC_CHECK_SIZEOF([int], [4])
-AC_CHECK_SIZEOF([long int], [4])
-AC_CHECK_SIZEOF([long long int], [8])
+AC_CHECK_SIZEOF([short int])
+AC_CHECK_SIZEOF([int])
+AC_CHECK_SIZEOF([long int])
+AC_CHECK_SIZEOF([long long int])
+AC_CHECK_SIZEOF([time_t], [], [[
+ #include <sys/types.h>
+ #ifdef HAVE_SYS_TIME_H
+ # include <sys/time.h>
+ #endif
+ #ifdef HAVE_TIME_H
+ # include <time.h>
+ #endif
+ ]]
+)
# Sanity check long long for some platforms (AIX)
if test "x$ac_cv_sizeof_long_long_int" = "x4" ; then
@@ -3584,11 +3756,12 @@ if test "x$ac_cv_sizeof_long_long_int" = "x4" ; then
fi
# compute LLONG_MIN and LLONG_MAX if we don't know them.
-if test -z "$have_llong_max"; then
+if test -z "$have_llong_max" && test -z "$have_long_long_max"; then
AC_MSG_CHECKING([for max value of long long])
AC_RUN_IFELSE(
[AC_LANG_PROGRAM([[
#include <stdio.h>
+#include <stdlib.h>
/* Why is this so damn hard? */
#ifdef __GNUC__
# undef __GNUC__
@@ -3679,6 +3852,17 @@ fprint_ll(FILE *f, long long n)
)
fi
+AC_CHECK_DECLS([UINT32_MAX], , , [[
+#ifdef HAVE_SYS_LIMITS_H
+# include <sys/limits.h>
+#endif
+#ifdef HAVE_LIMITS_H
+# include <limits.h>
+#endif
+#ifdef HAVE_STDINT_H
+# include <stdint.h>
+#endif
+]])
# More checks for data types
AC_CACHE_CHECK([for u_int type], ac_cv_have_u_int, [
@@ -3859,12 +4043,14 @@ fi
AC_CHECK_TYPES([intmax_t, uintmax_t], , , [
#include <sys/types.h>
-#include <stdint.h>
+#ifdef HAVE_STDINT_H
+# include <stdint.h>
+#endif
])
TYPE_SOCKLEN_T
-AC_CHECK_TYPES([sig_atomic_t], , , [#include <signal.h>])
+AC_CHECK_TYPES([sig_atomic_t, sighandler_t], , , [#include <signal.h>])
AC_CHECK_TYPES([fsblkcnt_t, fsfilcnt_t], , , [
#include <sys/types.h>
#ifdef HAVE_SYS_BITYPES_H
@@ -3878,7 +4064,8 @@ AC_CHECK_TYPES([fsblkcnt_t, fsfilcnt_t], , , [
#endif
])
-AC_CHECK_MEMBERS([struct statfs.f_flags], [], [], [[
+AC_CHECK_MEMBERS([struct statfs.f_files, struct statfs.f_flags], [], [], [[
+#include <sys/param.h>
#include <sys/types.h>
#ifdef HAVE_SYS_BITYPES_H
#include <sys/bitypes.h>
@@ -3892,6 +4079,9 @@ AC_CHECK_MEMBERS([struct statfs.f_flags], [], [], [[
#ifdef HAVE_SYS_VFS_H
#include <sys/vfs.h>
#endif
+#ifdef HAVE_SYS_MOUNT_H
+#include <sys/mount.h>
+#endif
]])
@@ -4049,7 +4239,24 @@ if test "x$ac_cv_have_struct_timeval" = "xyes" ; then
have_struct_timeval=1
fi
-AC_CHECK_TYPES([struct timespec])
+AC_CACHE_CHECK([for struct timespec], ac_cv_have_struct_timespec, [
+ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
+ #ifdef HAVE_SYS_TIME_H
+ # include <sys/time.h>
+ #endif
+ #ifdef HAVE_TIME_H
+ # include <time.h>
+ #endif
+ ]],
+ [[ struct timespec ts; ts.tv_sec = 1;]])],
+ [ ac_cv_have_struct_timespec="yes" ],
+ [ ac_cv_have_struct_timespec="no"
+ ])
+])
+if test "x$ac_cv_have_struct_timespec" = "xyes" ; then
+ AC_DEFINE([HAVE_STRUCT_TIMESPEC], [1], [define if you have struct timespec])
+ have_struct_timespec=1
+fi
# We need int64_t or else certain parts of the compile will fail.
if test "x$ac_cv_have_int64_t" = "xno" && \
@@ -4064,6 +4271,7 @@ dnl test snprintf (broken on SCO w/gcc)
AC_RUN_IFELSE(
[AC_LANG_SOURCE([[
#include <stdio.h>
+#include <stdlib.h>
#include <string.h>
#ifdef HAVE_SNPRINTF
main()
@@ -4108,6 +4316,7 @@ OSSH_CHECK_HEADER_FOR_FIELD([ut_exit], [utmp.h], [HAVE_EXIT_IN_UTMP])
OSSH_CHECK_HEADER_FOR_FIELD([ut_time], [utmp.h], [HAVE_TIME_IN_UTMP])
OSSH_CHECK_HEADER_FOR_FIELD([ut_time], [utmpx.h], [HAVE_TIME_IN_UTMPX])
OSSH_CHECK_HEADER_FOR_FIELD([ut_tv], [utmpx.h], [HAVE_TV_IN_UTMPX])
+OSSH_CHECK_HEADER_FOR_FIELD([ut_ss], [utmpx.h], [HAVE_SS_IN_UTMPX])
AC_CHECK_MEMBERS([struct stat.st_blksize])
AC_CHECK_MEMBERS([struct stat.st_mtim])
@@ -4166,6 +4375,7 @@ AC_CACHE_CHECK([for msg_accrights field in struct msghdr],
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/uio.h>
+#include <stdlib.h>
]], [[
#ifdef msg_accrights
#error "msg_accrights is a macro"
@@ -4227,6 +4437,7 @@ AC_CACHE_CHECK([for msg_control field in struct msghdr],
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/uio.h>
+#include <stdlib.h>
]], [[
#ifdef msg_control
#error "msg_control is a macro"
@@ -4247,7 +4458,7 @@ if test "x$ac_cv_have_control_in_msghdr" = "xyes" ; then
fi
AC_CACHE_CHECK([if libc defines __progname], ac_cv_libc_defines___progname, [
- AC_LINK_IFELSE([AC_LANG_PROGRAM([[]],
+ AC_LINK_IFELSE([AC_LANG_PROGRAM([[ #include <stdio.h> ]],
[[ extern char *__progname; printf("%s", __progname); ]])],
[ ac_cv_libc_defines___progname="yes" ],
[ ac_cv_libc_defines___progname="no"
@@ -4319,7 +4530,7 @@ if test "x$ac_cv_have_getopt_optreset" = "xyes" ; then
fi
AC_CACHE_CHECK([if libc defines sys_errlist], ac_cv_libc_defines_sys_errlist, [
- AC_LINK_IFELSE([AC_LANG_PROGRAM([[]],
+ AC_LINK_IFELSE([AC_LANG_PROGRAM([[ #include <stdio.h> ]],
[[ extern const char *const sys_errlist[]; printf("%s", sys_errlist[0]);]])],
[ ac_cv_libc_defines_sys_errlist="yes" ],
[ ac_cv_libc_defines_sys_errlist="no"
@@ -4332,7 +4543,7 @@ fi
AC_CACHE_CHECK([if libc defines sys_nerr], ac_cv_libc_defines_sys_nerr, [
- AC_LINK_IFELSE([AC_LANG_PROGRAM([[]],
+ AC_LINK_IFELSE([AC_LANG_PROGRAM([[ #include <stdio.h> ]],
[[ extern int sys_nerr; printf("%i", sys_nerr);]])],
[ ac_cv_libc_defines_sys_nerr="yes" ],
[ ac_cv_libc_defines_sys_nerr="no"
@@ -4426,13 +4637,10 @@ AC_ARG_WITH([selinux],
LIBS="$LIBS -lselinux"
],
AC_MSG_ERROR([SELinux support requires libselinux library]))
- SSHLIBS="$SSHLIBS $LIBSELINUX"
- SSHDLIBS="$SSHDLIBS $LIBSELINUX"
AC_CHECK_FUNCS([getseuserbyname get_default_context_with_level])
- LIBS="$save_LIBS"
+ LIBS="$save_LIBS $LIBSELINUX"
fi ]
)
-AC_SUBST([SSHLIBS])
AC_SUBST([SSHDLIBS])
# Check whether user wants Kerberos 5 support
@@ -4449,22 +4657,30 @@ AC_ARG_WITH([kerberos5],
AC_DEFINE([KRB5], [1], [Define if you want Kerberos 5 support])
KRB5_MSG="yes"
- AC_PATH_TOOL([KRB5CONF], [krb5-config],
- [$KRB5ROOT/bin/krb5-config],
- [$KRB5ROOT/bin:$PATH])
- if test -x $KRB5CONF ; then
- K5CFLAGS="`$KRB5CONF --cflags`"
- K5LIBS="`$KRB5CONF --libs`"
+ AC_PATH_TOOL([PKGCONFIG], [pkg-config], [no])
+ use_pkgconfig_for_krb5=
+ if test "x$PKGCONFIG" != "xno"; then
+ AC_MSG_CHECKING([if $PKGCONFIG knows about kerberos5])
+ if "$PKGCONFIG" krb5; then
+ AC_MSG_RESULT([yes])
+ use_pkgconfig_for_krb5=yes
+ else
+ AC_MSG_RESULT([no])
+ fi
+ fi
+ if test "x$use_pkgconfig_for_krb5" = "xyes"; then
+ K5CFLAGS=`$PKGCONFIG --cflags krb5`
+ K5LIBS=`$PKGCONFIG --libs krb5`
CPPFLAGS="$CPPFLAGS $K5CFLAGS"
AC_MSG_CHECKING([for gssapi support])
- if $KRB5CONF | grep gssapi >/dev/null ; then
+ if "$PKGCONFIG" krb5-gssapi; then
AC_MSG_RESULT([yes])
AC_DEFINE([GSSAPI], [1],
[Define this if you want GSSAPI
support in the version 2 protocol])
- GSSCFLAGS="`$KRB5CONF --cflags gssapi`"
- GSSLIBS="`$KRB5CONF --libs gssapi`"
+ GSSCFLAGS="`$PKGCONFIG --cflags krb5-gssapi`"
+ GSSLIBS="`$PKGCONFIG --libs krb5-gssapi`"
CPPFLAGS="$CPPFLAGS $GSSCFLAGS"
else
AC_MSG_RESULT([no])
@@ -4479,54 +4695,85 @@ AC_ARG_WITH([kerberos5],
[AC_MSG_RESULT([no])
])
else
- CPPFLAGS="$CPPFLAGS -I${KRB5ROOT}/include"
- LDFLAGS="$LDFLAGS -L${KRB5ROOT}/lib"
- AC_MSG_CHECKING([whether we are using Heimdal])
- AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include <krb5.h>
- ]], [[ char *tmp = heimdal_version; ]])],
+ AC_PATH_TOOL([KRB5CONF], [krb5-config],
+ [$KRB5ROOT/bin/krb5-config],
+ [$KRB5ROOT/bin:$PATH])
+ if test -x $KRB5CONF ; then
+ K5CFLAGS="`$KRB5CONF --cflags`"
+ K5LIBS="`$KRB5CONF --libs`"
+ CPPFLAGS="$CPPFLAGS $K5CFLAGS"
+
+ AC_MSG_CHECKING([for gssapi support])
+ if $KRB5CONF | grep gssapi >/dev/null ; then
+ AC_MSG_RESULT([yes])
+ AC_DEFINE([GSSAPI], [1],
+ [Define this if you want GSSAPI
+ support in the version 2 protocol])
+ GSSCFLAGS="`$KRB5CONF --cflags gssapi`"
+ GSSLIBS="`$KRB5CONF --libs gssapi`"
+ CPPFLAGS="$CPPFLAGS $GSSCFLAGS"
+ else
+ AC_MSG_RESULT([no])
+ fi
+ AC_MSG_CHECKING([whether we are using Heimdal])
+ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include <krb5.h>
+ ]], [[ char *tmp = heimdal_version; ]])],
[ AC_MSG_RESULT([yes])
- AC_DEFINE([HEIMDAL])
- K5LIBS="-lkrb5"
- K5LIBS="$K5LIBS -lcom_err -lasn1"
- AC_CHECK_LIB([roken], [net_write],
- [K5LIBS="$K5LIBS -lroken"])
- AC_CHECK_LIB([des], [des_cbc_encrypt],
- [K5LIBS="$K5LIBS -ldes"])
- ], [ AC_MSG_RESULT([no])
- K5LIBS="-lkrb5 -lk5crypto -lcom_err"
- ])
- AC_SEARCH_LIBS([dn_expand], [resolv])
+ AC_DEFINE([HEIMDAL], [1],
+ [Define this if you are using the Heimdal
+ version of Kerberos V5]) ],
+ [AC_MSG_RESULT([no])
+ ])
+ else
+ CPPFLAGS="$CPPFLAGS -I${KRB5ROOT}/include"
+ LDFLAGS="$LDFLAGS -L${KRB5ROOT}/lib"
+ AC_MSG_CHECKING([whether we are using Heimdal])
+ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include <krb5.h>
+ ]], [[ char *tmp = heimdal_version; ]])],
+ [ AC_MSG_RESULT([yes])
+ AC_DEFINE([HEIMDAL])
+ K5LIBS="-lkrb5"
+ K5LIBS="$K5LIBS -lcom_err -lasn1"
+ AC_CHECK_LIB([roken], [net_write],
+ [K5LIBS="$K5LIBS -lroken"])
+ AC_CHECK_LIB([des], [des_cbc_encrypt],
+ [K5LIBS="$K5LIBS -ldes"])
+ ], [ AC_MSG_RESULT([no])
+ K5LIBS="-lkrb5 -lk5crypto -lcom_err"
+ ])
+ AC_SEARCH_LIBS([dn_expand], [resolv])
- AC_CHECK_LIB([gssapi_krb5], [gss_init_sec_context],
- [ AC_DEFINE([GSSAPI])
- GSSLIBS="-lgssapi_krb5" ],
- [ AC_CHECK_LIB([gssapi], [gss_init_sec_context],
+ AC_CHECK_LIB([gssapi_krb5], [gss_init_sec_context],
[ AC_DEFINE([GSSAPI])
- GSSLIBS="-lgssapi" ],
- [ AC_CHECK_LIB([gss], [gss_init_sec_context],
+ GSSLIBS="-lgssapi_krb5" ],
+ [ AC_CHECK_LIB([gssapi], [gss_init_sec_context],
[ AC_DEFINE([GSSAPI])
- GSSLIBS="-lgss" ],
- AC_MSG_WARN([Cannot find any suitable gss-api library - build may fail]))
+ GSSLIBS="-lgssapi" ],
+ [ AC_CHECK_LIB([gss], [gss_init_sec_context],
+ [ AC_DEFINE([GSSAPI])
+ GSSLIBS="-lgss" ],
+ AC_MSG_WARN([Cannot find any suitable gss-api library - build may fail]))
+ ])
])
- ])
- AC_CHECK_HEADER([gssapi.h], ,
- [ unset ac_cv_header_gssapi_h
- CPPFLAGS="$CPPFLAGS -I${KRB5ROOT}/include/gssapi"
- AC_CHECK_HEADERS([gssapi.h], ,
- AC_MSG_WARN([Cannot find any suitable gss-api header - build may fail])
- )
- ]
- )
+ AC_CHECK_HEADER([gssapi.h], ,
+ [ unset ac_cv_header_gssapi_h
+ CPPFLAGS="$CPPFLAGS -I${KRB5ROOT}/include/gssapi"
+ AC_CHECK_HEADERS([gssapi.h], ,
+ AC_MSG_WARN([Cannot find any suitable gss-api header - build may fail])
+ )
+ ]
+ )
- oldCPP="$CPPFLAGS"
- CPPFLAGS="$CPPFLAGS -I${KRB5ROOT}/include/gssapi"
- AC_CHECK_HEADER([gssapi_krb5.h], ,
- [ CPPFLAGS="$oldCPP" ])
+ oldCPP="$CPPFLAGS"
+ CPPFLAGS="$CPPFLAGS -I${KRB5ROOT}/include/gssapi"
+ AC_CHECK_HEADER([gssapi_krb5.h], ,
+ [ CPPFLAGS="$oldCPP" ])
+ fi
fi
- if test ! -z "$need_dash_r" ; then
- LDFLAGS="$LDFLAGS -R${KRB5ROOT}/lib"
+ if test -n "${rpath_opt}" ; then
+ LDFLAGS="$LDFLAGS ${rpath_opt}${KRB5ROOT}/lib"
fi
if test ! -z "$blibpath" ; then
blibpath="$blibpath:${KRB5ROOT}/lib"
@@ -4644,6 +4891,7 @@ AC_ARG_WITH([maildir],
AC_RUN_IFELSE(
[AC_LANG_PROGRAM([[
#include <stdio.h>
+#include <stdlib.h>
#include <string.h>
#ifdef HAVE_PATHS_H
#include <paths.h>
@@ -4744,9 +4992,9 @@ AC_ARG_WITH([mantype],
]
)
if test -z "$MANTYPE"; then
- TestPath="/usr/bin${PATH_SEPARATOR}/usr/ucb"
- AC_PATH_PROGS([NROFF], [nroff awf], [/bin/false], [$TestPath])
- if ${NROFF} -mdoc ${srcdir}/ssh.1 >/dev/null 2>&1; then
+ if ${MANDOC} ${srcdir}/ssh.1 >/dev/null 2>&1; then
+ MANTYPE=doc
+ elif ${NROFF} -mdoc ${srcdir}/ssh.1 >/dev/null 2>&1; then
MANTYPE=doc
elif ${NROFF} -man ${srcdir}/ssh.1 >/dev/null 2>&1; then
MANTYPE=man
@@ -4888,6 +5136,7 @@ otherwise scp will not work.])
[AC_LANG_PROGRAM([[
/* find out what STDPATH is */
#include <stdio.h>
+#include <stdlib.h>
#ifdef HAVE_PATHS_H
# include <paths.h>
#endif
@@ -5315,6 +5564,12 @@ AC_SUBST([DEPEND], [$(cat $srcdir/.depend)])
CFLAGS="${CFLAGS} ${CFLAGS_AFTER}"
LDFLAGS="${LDFLAGS} ${LDFLAGS_AFTER}"
+# Make a copy of CFLAGS/LDFLAGS without PIE options.
+LDFLAGS_NOPIE=`echo "$LDFLAGS" | sed 's/ -pie//'`
+CFLAGS_NOPIE=`echo "$CFLAGS" | sed 's/ -fPIE//'`
+AC_SUBST([LDFLAGS_NOPIE])
+AC_SUBST([CFLAGS_NOPIE])
+
AC_EXEEXT
AC_CONFIG_FILES([Makefile buildpkg.sh opensshd.init openssh.xml \
openbsd-compat/Makefile openbsd-compat/regress/Makefile \
@@ -5374,6 +5629,8 @@ echo " Translate v4 in v6 hack: $IPV4_IN6_HACK_MSG"
echo " BSD Auth support: $BSD_AUTH_MSG"
echo " Random number source: $RAND_MSG"
echo " Privsep sandbox style: $SANDBOX_STYLE"
+echo " PKCS#11 support: $enable_pkcs11"
+echo " U2F/FIDO support: $enable_sk"
echo ""
@@ -5386,9 +5643,6 @@ echo " Libraries: ${LIBS}"
if test ! -z "${SSHDLIBS}"; then
echo " +for sshd: ${SSHDLIBS}"
fi
-if test ! -z "${SSHLIBS}"; then
-echo " +for ssh: ${SSHLIBS}"
-fi
echo ""
diff --git a/crypto/openssh/contrib/Makefile b/crypto/openssh/contrib/Makefile
index 3a36387b3222..45d878bdcf22 100644
--- a/crypto/openssh/contrib/Makefile
+++ b/crypto/openssh/contrib/Makefile
@@ -1,7 +1,7 @@
PKG_CONFIG = pkg-config
all:
- @echo "Valid targets: gnome-ssh-askpass1 gnome-ssh-askpass2"
+ @echo "Valid targets: gnome-ssh-askpass1 gnome-ssh-askpass2 gnome-ssk-askpass3"
gnome-ssh-askpass1: gnome-ssh-askpass1.c
$(CC) $(CFLAGS) `gnome-config --cflags gnome gnomeui` \
@@ -13,9 +13,9 @@ gnome-ssh-askpass2: gnome-ssh-askpass2.c
gnome-ssh-askpass2.c -o gnome-ssh-askpass2 \
`$(PKG_CONFIG) --libs gtk+-2.0 x11`
-gnome-ssh-askpass3: gnome-ssh-askpass2.c
+gnome-ssh-askpass3: gnome-ssh-askpass3.c
$(CC) $(CFLAGS) `$(PKG_CONFIG) --cflags gtk+-3.0` \
- gnome-ssh-askpass2.c -o gnome-ssh-askpass3 \
+ gnome-ssh-askpass3.c -o gnome-ssh-askpass3 \
`$(PKG_CONFIG) --libs gtk+-3.0 x11`
clean:
diff --git a/crypto/openssh/contrib/cygwin/README b/crypto/openssh/contrib/cygwin/README
index a73a0f657ec4..3745051f5981 100644
--- a/crypto/openssh/contrib/cygwin/README
+++ b/crypto/openssh/contrib/cygwin/README
@@ -60,7 +60,7 @@ Options:
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
+If no home directory is set in /etc/passwd, the root directory
is used instead!
================
@@ -77,7 +77,7 @@ with the aforementioned cygport script:
zlib
crypt
- openssl-devel
+ libssl-devel
libedit-devel
libkrb5-devel
diff --git a/crypto/openssh/contrib/cygwin/ssh-host-config b/crypto/openssh/contrib/cygwin/ssh-host-config
index 261020af33e8..a8572e2ac879 100644
--- a/crypto/openssh/contrib/cygwin/ssh-host-config
+++ b/crypto/openssh/contrib/cygwin/ssh-host-config
@@ -61,7 +61,7 @@ LOCALSTATEDIR=/var
sshd_config_configured=no
port_number=22
-service_name=sshd
+service_name=cygsshd
strictmodes=yes
cygwin_value=""
user_account=
@@ -307,7 +307,7 @@ check_service_files_ownership() {
if [ -z "${run_service_as}" ]
then
- accnt_name=$(/usr/bin/cygrunsrv -VQ sshd |
+ accnt_name=$(/usr/bin/cygrunsrv -VQ "${service_name}" |
/usr/bin/sed -ne 's/^Account *: *//gp')
if [ "${accnt_name}" = "LocalSystem" ]
then
@@ -329,9 +329,9 @@ check_service_files_ownership() {
fi
if [ -z "${run_service_as}" ]
then
- csih_warning "Couldn't determine name of user running sshd service from account database!"
+ csih_warning "Couldn't determine name of user running ${service_name} 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."
+ csih_warning "by the ${service_name} service belong to the user running the service."
return 1
fi
fi
@@ -367,8 +367,8 @@ check_service_files_ownership() {
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 "This may cause the ${service_name} service to fail! Please make sure that"
+ csih_warning "you have sufficient permissions to change the ownership of files"
csih_warning "and try to run the ssh-host-config script again."
fi
return $ret
@@ -394,14 +394,24 @@ install_service() {
then
csih_get_cygenv "${cygwin_value}"
- if ( csih_is_nt2003 || [ "$csih_FORCE_PRIVILEGED_USER" = "yes" ] )
+ if ( [ "$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
+ # Enforce using privileged user on 64 bit Vista or W7 under WOW64
+ is_wow64=$(/usr/bin/uname | /usr/bin/grep -q 'WOW' && echo 1 || echo 0)
+ if ( csih_is_nt2003 && ! csih_is_windows8 && [ "${is_wow64}" = "1" ] )
+ then
+ csih_inform "Running 32 bit Cygwin on 64 bit Windows Vista or Windows 7"
+ csih_inform "the SYSTEM account is not sufficient to setuid to a local"
+ csih_inform "user account. You need to have or to create a privileged"
+ csih_inform "account. This script will help you do so."
+ echo
+ csih_FORCE_PRIVILEGED_USER=yes
+ fi
+ fi
+
+ if ( [ "$csih_FORCE_PRIVILEGED_USER" = "yes" ] )
+ then
[ "${opt_force}" = "yes" ] && opt_f=-f
[ -n "${user_account}" ] && opt_u="-u ""${user_account}"""
csih_select_privileged_username ${opt_f} ${opt_u} sshd
@@ -412,11 +422,12 @@ install_service() {
csih_request "Do you want to proceed anyway?" || exit 1
let ++ret
fi
+ # Never returns empty if NT or above
+ run_service_as=$(csih_service_should_run_as)
+ else
+ run_service_as="SYSTEM"
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}"
@@ -446,7 +457,7 @@ install_service() {
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 "\`net start ${service_name}' or \`cygrunsrv -S ${service_name}'. Otherwise, it"
csih_inform "will start automatically after the next reboot."
fi
else
@@ -669,14 +680,24 @@ then
fi
# handle sshd_config
+# make sure not to change the existing file
+mod_before=""
+if [ -e "${SYSCONFDIR}/sshd_config" ]
+then
+ mod_before=$(stat "${SYSCONFDIR}/sshd_config" | grep '^Modify:')
+fi
csih_install_config "${SYSCONFDIR}/sshd_config" "${SYSCONFDIR}/defaults" || let ++warning_cnt
+mod_now=$(stat "${SYSCONFDIR}/sshd_config" | grep '^Modify:')
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+=$?
+if [ "${mod_before}" != "${mod_now}" ]
+then
+ sshd_strictmodes || let warning_cnt+=$?
+ sshd_config_tweak || let warning_cnt+=$?
+fi
+#sshd_privsep || let warning_cnt+=$?
update_services_file || let warning_cnt+=$?
update_inetd_conf || let warning_cnt+=$?
install_service || let warning_cnt+=$?
diff --git a/crypto/openssh/contrib/findssl.sh b/crypto/openssh/contrib/findssl.sh
index 95a0d66dfe63..95a0d66dfe63 100755..100644
--- a/crypto/openssh/contrib/findssl.sh
+++ b/crypto/openssh/contrib/findssl.sh
diff --git a/crypto/openssh/contrib/gnome-ssh-askpass1.c b/crypto/openssh/contrib/gnome-ssh-askpass1.c
index 4d51032d1d36..4c92c177b5d2 100644
--- a/crypto/openssh/contrib/gnome-ssh-askpass1.c
+++ b/crypto/openssh/contrib/gnome-ssh-askpass1.c
@@ -137,9 +137,10 @@ passphrase_dialog(char *message)
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. */
+ /*
+ * 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:
diff --git a/crypto/openssh/contrib/gnome-ssh-askpass2.c b/crypto/openssh/contrib/gnome-ssh-askpass2.c
index 535a692749e9..a62f98152950 100644
--- a/crypto/openssh/contrib/gnome-ssh-askpass2.c
+++ b/crypto/openssh/contrib/gnome-ssh-askpass2.c
@@ -39,6 +39,10 @@
#define GRAB_TRIES 16
#define GRAB_WAIT 250 /* milliseconds */
+#define PROMPT_ENTRY 0
+#define PROMPT_CONFIRM 1
+#define PROMPT_NONE 2
+
/*
* Compile with:
*
@@ -52,9 +56,11 @@
#include <stdio.h>
#include <string.h>
#include <unistd.h>
+
#include <X11/Xlib.h>
#include <gtk/gtk.h>
#include <gdk/gdkx.h>
+#include <gdk/gdkkeysyms.h>
static void
report_failed_grab (GtkWidget *parent_window, const char *what)
@@ -62,11 +68,9 @@ report_failed_grab (GtkWidget *parent_window, const char *what)
GtkWidget *err;
err = gtk_message_dialog_new(GTK_WINDOW(parent_window), 0,
- GTK_MESSAGE_ERROR,
- GTK_BUTTONS_CLOSE,
- "Could not grab %s. "
- "A malicious client may be eavesdropping "
- "on your session.", what);
+ 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_dialog_run(GTK_DIALOG(err));
@@ -81,47 +85,147 @@ ok_dialog(GtkWidget *entry, gpointer dialog)
gtk_dialog_response(GTK_DIALOG(dialog), GTK_RESPONSE_OK);
}
+static gboolean
+check_none(GtkWidget *widget, GdkEventKey *event, gpointer dialog)
+{
+ switch (event->keyval) {
+ case GDK_KEY_Escape:
+ /* esc -> close dialog */
+ gtk_dialog_response(GTK_DIALOG(dialog), GTK_RESPONSE_CLOSE);
+ return TRUE;
+ case GDK_KEY_Tab:
+ /* tab -> focus close button */
+ gtk_widget_grab_focus(gtk_dialog_get_widget_for_response(
+ dialog, GTK_RESPONSE_CLOSE));
+ return TRUE;
+ default:
+ /* eat all other key events */
+ return TRUE;
+ }
+}
+
static int
-passphrase_dialog(char *message)
+parse_env_hex_color(const char *env, GdkColor *c)
+{
+ const char *s;
+ unsigned long ul;
+ char *ep;
+ size_t n;
+
+ if ((s = getenv(env)) == NULL)
+ return 0;
+
+ memset(c, 0, sizeof(*c));
+
+ /* Permit hex rgb or rrggbb optionally prefixed by '#' or '0x' */
+ if (*s == '#')
+ s++;
+ else if (strncmp(s, "0x", 2) == 0)
+ s += 2;
+ n = strlen(s);
+ if (n != 3 && n != 6)
+ goto bad;
+ ul = strtoul(s, &ep, 16);
+ if (*ep != '\0' || ul > 0xffffff) {
+ bad:
+ fprintf(stderr, "Invalid $%s - invalid hex color code\n", env);
+ return 0;
+ }
+ /* Valid hex sequence; expand into a GdkColor */
+ if (n == 3) {
+ /* 4-bit RGB */
+ c->red = ((ul >> 8) & 0xf) << 12;
+ c->green = ((ul >> 4) & 0xf) << 12;
+ c->blue = (ul & 0xf) << 12;
+ } else {
+ /* 8-bit RGB */
+ c->red = ((ul >> 16) & 0xff) << 8;
+ c->green = ((ul >> 8) & 0xff) << 8;
+ c->blue = (ul & 0xff) << 8;
+ }
+ return 1;
+}
+
+static int
+passphrase_dialog(char *message, int prompt_type)
{
const char *failed;
char *passphrase, *local;
int result, grab_tries, grab_server, grab_pointer;
+ int buttons, default_response;
GtkWidget *parent_window, *dialog, *entry;
GdkGrabStatus status;
+ GdkColor fg, bg;
+ int fg_set = 0, bg_set = 0;
grab_server = (getenv("GNOME_SSH_ASKPASS_GRAB_SERVER") != NULL);
grab_pointer = (getenv("GNOME_SSH_ASKPASS_GRAB_POINTER") != NULL);
grab_tries = 0;
+ fg_set = parse_env_hex_color("GNOME_SSH_ASKPASS_FG_COLOR", &fg);
+ bg_set = parse_env_hex_color("GNOME_SSH_ASKPASS_BG_COLOR", &bg);
+
/* Create an invisible parent window so that GtkDialog doesn't
* complain. */
parent_window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
+ switch (prompt_type) {
+ case PROMPT_CONFIRM:
+ buttons = GTK_BUTTONS_YES_NO;
+ default_response = GTK_RESPONSE_YES;
+ break;
+ case PROMPT_NONE:
+ buttons = GTK_BUTTONS_CLOSE;
+ default_response = GTK_RESPONSE_CLOSE;
+ break;
+ default:
+ buttons = GTK_BUTTONS_OK_CANCEL;
+ default_response = GTK_RESPONSE_OK;
+ break;
+ }
+
dialog = gtk_message_dialog_new(GTK_WINDOW(parent_window), 0,
- GTK_MESSAGE_QUESTION,
- GTK_BUTTONS_OK_CANCEL,
- "%s",
- message);
-
- entry = gtk_entry_new();
- gtk_box_pack_start(
- GTK_BOX(gtk_dialog_get_content_area(GTK_DIALOG(dialog))), entry,
- FALSE, FALSE, 0);
- gtk_entry_set_visibility(GTK_ENTRY(entry), FALSE);
- gtk_widget_grab_focus(entry);
- gtk_widget_show(entry);
+ GTK_MESSAGE_QUESTION, buttons, "%s", message);
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_dialog_set_default_response(GTK_DIALOG(dialog), default_response);
+ gtk_window_set_keep_above(GTK_WINDOW(dialog), TRUE);
- /* Make <enter> 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);
+ if (fg_set)
+ gtk_widget_modify_fg(dialog, GTK_STATE_NORMAL, &fg);
+ if (bg_set)
+ gtk_widget_modify_bg(dialog, GTK_STATE_NORMAL, &bg);
- gtk_window_set_keep_above(GTK_WINDOW(dialog), TRUE);
+ if (prompt_type == PROMPT_ENTRY || prompt_type == PROMPT_NONE) {
+ entry = gtk_entry_new();
+ if (fg_set)
+ gtk_widget_modify_fg(entry, GTK_STATE_NORMAL, &fg);
+ if (bg_set)
+ gtk_widget_modify_bg(entry, GTK_STATE_NORMAL, &bg);
+ gtk_box_pack_start(
+ GTK_BOX(gtk_dialog_get_content_area(GTK_DIALOG(dialog))),
+ entry, FALSE, FALSE, 0);
+ gtk_entry_set_visibility(GTK_ENTRY(entry), FALSE);
+ gtk_widget_grab_focus(entry);
+ if (prompt_type == PROMPT_ENTRY) {
+ gtk_widget_show(entry);
+ /* Make <enter> close dialog */
+ g_signal_connect(G_OBJECT(entry), "activate",
+ G_CALLBACK(ok_dialog), dialog);
+ } else {
+ /*
+ * Ensure the 'close' button is not focused by default
+ * but is still reachable via tab. This is a bit of a
+ * hack - it uses a hidden entry that responds to a
+ * couple of keypress events (escape and tab only).
+ */
+ gtk_widget_realize(entry);
+ g_signal_connect(G_OBJECT(entry), "key_press_event",
+ G_CALLBACK(check_none), dialog);
+ }
+ }
/* Grab focus */
gtk_widget_show_now(dialog);
@@ -166,32 +270,37 @@ passphrase_dialog(char *message)
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);
+ if (prompt_type == PROMPT_ENTRY) {
+ 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);
}
-
- /* 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);
+ if (result != GTK_RESPONSE_OK && result != GTK_RESPONSE_YES)
+ return -1;
+ return 0;
- /* At least one grab failed - ungrab what we got, and report
- the failure to the user. Note that XGrabServer() cannot
- fail. */
nograbkb:
+ /*
+ * At least one grab failed - ungrab what we got, and report
+ * the failure to the user. Note that XGrabServer() cannot
+ * fail.
+ */
gdk_pointer_ungrab(GDK_CURRENT_TIME);
nograb:
if (grab_server)
@@ -206,8 +315,8 @@ passphrase_dialog(char *message)
int
main(int argc, char **argv)
{
- char *message;
- int result;
+ char *message, *prompt_mode;
+ int result, prompt_type = PROMPT_ENTRY;
gtk_init(&argc, &argv);
@@ -217,8 +326,15 @@ main(int argc, char **argv)
message = g_strdup("Enter your OpenSSH passphrase:");
}
+ if ((prompt_mode = getenv("SSH_ASKPASS_PROMPT")) != NULL) {
+ if (strcasecmp(prompt_mode, "confirm") == 0)
+ prompt_type = PROMPT_CONFIRM;
+ else if (strcasecmp(prompt_mode, "none") == 0)
+ prompt_type = PROMPT_NONE;
+ }
+
setvbuf(stdout, 0, _IONBF, 0);
- result = passphrase_dialog(message);
+ result = passphrase_dialog(message, prompt_type);
g_free(message);
return (result);
diff --git a/crypto/openssh/contrib/gnome-ssh-askpass3.c b/crypto/openssh/contrib/gnome-ssh-askpass3.c
new file mode 100644
index 000000000000..e1a0533ef624
--- /dev/null
+++ b/crypto/openssh/contrib/gnome-ssh-askpass3.c
@@ -0,0 +1,305 @@
+/*
+ * 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 <nalin@redhat.com> */
+
+/*
+ * 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 */
+
+#define PROMPT_ENTRY 0
+#define PROMPT_CONFIRM 1
+#define PROMPT_NONE 2
+
+/*
+ * 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 <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <X11/Xlib.h>
+#include <gtk/gtk.h>
+#include <gdk/gdkx.h>
+#include <gdk/gdkkeysyms.h>
+
+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 gboolean
+check_none(GtkWidget *widget, GdkEventKey *event, gpointer dialog)
+{
+ switch (event->keyval) {
+ case GDK_KEY_Escape:
+ /* esc -> close dialog */
+ gtk_dialog_response(GTK_DIALOG(dialog), GTK_RESPONSE_CLOSE);
+ return TRUE;
+ case GDK_KEY_Tab:
+ /* tab -> focus close button */
+ gtk_widget_grab_focus(gtk_dialog_get_widget_for_response(
+ dialog, GTK_RESPONSE_CLOSE));
+ return TRUE;
+ default:
+ /* eat all other key events */
+ return TRUE;
+ }
+}
+
+static int
+parse_env_hex_color(const char *env, GdkColor *c)
+{
+ const char *s;
+ unsigned long ul;
+ char *ep;
+ size_t n;
+
+ if ((s = getenv(env)) == NULL)
+ return 0;
+
+ memset(c, 0, sizeof(*c));
+
+ /* Permit hex rgb or rrggbb optionally prefixed by '#' or '0x' */
+ if (*s == '#')
+ s++;
+ else if (strncmp(s, "0x", 2) == 0)
+ s += 2;
+ n = strlen(s);
+ if (n != 3 && n != 6)
+ goto bad;
+ ul = strtoul(s, &ep, 16);
+ if (*ep != '\0' || ul > 0xffffff) {
+ bad:
+ fprintf(stderr, "Invalid $%s - invalid hex color code\n", env);
+ return 0;
+ }
+ /* Valid hex sequence; expand into a GdkColor */
+ if (n == 3) {
+ /* 4-bit RGB */
+ c->red = ((ul >> 8) & 0xf) << 12;
+ c->green = ((ul >> 4) & 0xf) << 12;
+ c->blue = (ul & 0xf) << 12;
+ } else {
+ /* 8-bit RGB */
+ c->red = ((ul >> 16) & 0xff) << 8;
+ c->green = ((ul >> 8) & 0xff) << 8;
+ c->blue = (ul & 0xff) << 8;
+ }
+ return 1;
+}
+
+static int
+passphrase_dialog(char *message, int prompt_type)
+{
+ const char *failed;
+ char *passphrase, *local;
+ int result, grab_tries, grab_server, grab_pointer;
+ int buttons, default_response;
+ GtkWidget *parent_window, *dialog, *entry, *err;
+ GdkGrabStatus status;
+ GdkColor fg, bg;
+ GdkSeat *seat;
+ GdkDisplay *display;
+ GdkSeatCapabilities caps;
+ int fg_set = 0, bg_set = 0;
+
+ grab_server = (getenv("GNOME_SSH_ASKPASS_GRAB_SERVER") != NULL);
+ grab_pointer = (getenv("GNOME_SSH_ASKPASS_GRAB_POINTER") != NULL);
+ grab_tries = 0;
+
+ fg_set = parse_env_hex_color("GNOME_SSH_ASKPASS_FG_COLOR", &fg);
+ bg_set = parse_env_hex_color("GNOME_SSH_ASKPASS_BG_COLOR", &bg);
+
+ /* Create an invisible parent window so that GtkDialog doesn't
+ * complain. */
+ parent_window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
+
+ switch (prompt_type) {
+ case PROMPT_CONFIRM:
+ buttons = GTK_BUTTONS_YES_NO;
+ default_response = GTK_RESPONSE_YES;
+ break;
+ case PROMPT_NONE:
+ buttons = GTK_BUTTONS_CLOSE;
+ default_response = GTK_RESPONSE_CLOSE;
+ break;
+ default:
+ buttons = GTK_BUTTONS_OK_CANCEL;
+ default_response = GTK_RESPONSE_OK;
+ break;
+ }
+
+ dialog = gtk_message_dialog_new(GTK_WINDOW(parent_window), 0,
+ GTK_MESSAGE_QUESTION, buttons, "%s", message);
+
+ 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_dialog_set_default_response(GTK_DIALOG(dialog), default_response);
+ gtk_window_set_keep_above(GTK_WINDOW(dialog), TRUE);
+
+ if (fg_set)
+ gtk_widget_modify_fg(dialog, GTK_STATE_NORMAL, &fg);
+ if (bg_set)
+ gtk_widget_modify_bg(dialog, GTK_STATE_NORMAL, &bg);
+
+ if (prompt_type == PROMPT_ENTRY || prompt_type == PROMPT_NONE) {
+ entry = gtk_entry_new();
+ if (fg_set)
+ gtk_widget_modify_fg(entry, GTK_STATE_NORMAL, &fg);
+ if (bg_set)
+ gtk_widget_modify_bg(entry, GTK_STATE_NORMAL, &bg);
+ gtk_box_pack_start(
+ GTK_BOX(gtk_dialog_get_content_area(GTK_DIALOG(dialog))),
+ entry, FALSE, FALSE, 0);
+ gtk_entry_set_visibility(GTK_ENTRY(entry), FALSE);
+ gtk_widget_grab_focus(entry);
+ if (prompt_type == PROMPT_ENTRY) {
+ gtk_widget_show(entry);
+ /* Make <enter> close dialog */
+ g_signal_connect(G_OBJECT(entry), "activate",
+ G_CALLBACK(ok_dialog), dialog);
+ } else {
+ /*
+ * Ensure the 'close' button is not focused by default
+ * but is still reachable via tab. This is a bit of a
+ * hack - it uses a hidden entry that responds to a
+ * couple of keypress events (escape and tab only).
+ */
+ gtk_widget_realize(entry);
+ g_signal_connect(G_OBJECT(entry), "key_press_event",
+ G_CALLBACK(check_none), dialog);
+ }
+ }
+ /* Grab focus */
+ gtk_widget_show_now(dialog);
+ display = gtk_widget_get_display(GTK_WIDGET(dialog));
+ seat = gdk_display_get_default_seat(display);
+ caps = GDK_SEAT_CAPABILITY_KEYBOARD;
+ if (grab_pointer)
+ caps |= GDK_SEAT_CAPABILITY_ALL_POINTING;
+ if (grab_server)
+ caps = GDK_SEAT_CAPABILITY_ALL;
+ for (;;) {
+ status = gdk_seat_grab(seat, gtk_widget_get_window(dialog),
+ caps, TRUE, NULL, NULL, NULL, NULL);
+ if (status == GDK_GRAB_SUCCESS)
+ break;
+ usleep(GRAB_WAIT * 1000);
+ if (++grab_tries > GRAB_TRIES)
+ goto nograb;
+ }
+
+ result = gtk_dialog_run(GTK_DIALOG(dialog));
+
+ /* Ungrab */
+ gdk_seat_ungrab(seat);
+ gdk_display_flush(display);
+
+ /* Report passphrase if user selected OK */
+ if (prompt_type == PROMPT_ENTRY) {
+ 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);
+ if (result != GTK_RESPONSE_OK && result != GTK_RESPONSE_YES)
+ return -1;
+ return 0;
+
+ nograb:
+ gtk_widget_destroy(dialog);
+ err = gtk_message_dialog_new(GTK_WINDOW(parent_window), 0,
+ GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE,
+ "Could not grab input. A malicious client may be eavesdropping "
+ "on your session.");
+ gtk_window_set_position(GTK_WINDOW(err), GTK_WIN_POS_CENTER);
+ gtk_dialog_run(GTK_DIALOG(err));
+ gtk_widget_destroy(err);
+ return -1;
+}
+
+int
+main(int argc, char **argv)
+{
+ char *message, *prompt_mode;
+ int result, prompt_type = PROMPT_ENTRY;
+
+ gtk_init(&argc, &argv);
+
+ if (argc > 1) {
+ message = g_strjoinv(" ", argv + 1);
+ } else {
+ message = g_strdup("Enter your OpenSSH passphrase:");
+ }
+
+ if ((prompt_mode = getenv("SSH_ASKPASS_PROMPT")) != NULL) {
+ if (strcasecmp(prompt_mode, "confirm") == 0)
+ prompt_type = PROMPT_CONFIRM;
+ else if (strcasecmp(prompt_mode, "none") == 0)
+ prompt_type = PROMPT_NONE;
+ }
+
+ setvbuf(stdout, 0, _IONBF, 0);
+ result = passphrase_dialog(message, prompt_type);
+ g_free(message);
+
+ return (result);
+}
diff --git a/crypto/openssh/contrib/redhat/gnome-ssh-askpass.sh b/crypto/openssh/contrib/redhat/gnome-ssh-askpass.sh
index 355189f45cbe..355189f45cbe 100755..100644
--- a/crypto/openssh/contrib/redhat/gnome-ssh-askpass.sh
+++ b/crypto/openssh/contrib/redhat/gnome-ssh-askpass.sh
diff --git a/crypto/openssh/contrib/redhat/openssh.spec b/crypto/openssh/contrib/redhat/openssh.spec
index d7823483d10d..5fb81ce31491 100644
--- a/crypto/openssh/contrib/redhat/openssh.spec
+++ b/crypto/openssh/contrib/redhat/openssh.spec
@@ -1,78 +1,78 @@
-%define ver 7.9p1
-%define rel 1%{?dist}
+%global ver 8.7p1
+%global rel 1%{?dist}
# OpenSSH privilege separation requires a user & group ID
-%define sshd_uid 74
-%define sshd_gid 74
+%global sshd_uid 74
+%global sshd_gid 74
# Version of ssh-askpass
-%define aversion 1.2.4.1
+%global aversion 1.2.4.1
# Do we want to disable building of x11-askpass? (1=yes 0=no)
-%define no_x11_askpass 0
+%global no_x11_askpass 0
# Do we want to disable building of gnome-askpass? (1=yes 0=no)
-%define no_gnome_askpass 0
+%global no_gnome_askpass 0
# Do we want to link against a static libcrypto? (1=yes 0=no)
-%define static_libcrypto 0
+%global static_libcrypto 0
# Do we want smartcard support (1=yes 0=no)
-%define scard 0
+%global scard 0
# Use GTK2 instead of GNOME in gnome-ssh-askpass
-%define gtk2 1
+%global gtk2 1
# Use build6x options for older RHEL builds
# RHEL 7 not yet supported
%if 0%{?rhel} > 6
-%define build6x 0
+%global build6x 0
%else
-%define build6x 1
+%global build6x 1
%endif
%if 0%{?fedora} >= 26
-%define compat_openssl 1
+%global compat_openssl 1
%else
-%define compat_openssl 0
+%global compat_openssl 0
%endif
# Do we want kerberos5 support (1=yes 0=no)
-%define kerberos5 1
+%global 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}
+%{?skip_x11_askpass:%global no_x11_askpass 1}
+%{?skip_gnome_askpass:%global 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}
+%{?no_gtk2:%global gtk2 0}
# Is this a build for RHL 6.x or earlier?
-%{?build_6x:%define build6x 1}
+%{?build_6x:%global build6x 1}
# If this is RHL 6.x, the default configuration has sysconfdir in /usr/etc.
%if %{build6x}
-%define _sysconfdir /etc
+%global _sysconfdir /etc
%endif
# Options for static OpenSSL link:
# rpm -ba|--rebuild --define "static_openssl 1"
-%{?static_openssl:%define static_libcrypto 1}
+%{?static_openssl:%global static_libcrypto 1}
# Options for Smartcard support: (needs libsectok and openssl-engine)
# rpm -ba|--rebuild --define "smartcard 1"
-%{?smartcard:%define scard 1}
+%{?smartcard:%global 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}
+%global rescue 0
+%{?build_rescue:%global rescue 1}
# Turn off some stuff for resuce builds
%if %{rescue}
-%define kerberos5 0
+%global kerberos5 0
%endif
Summary: The OpenSSH implementation of SSH protocol version 2.
@@ -363,8 +363,10 @@ fi
%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(0755,root,root) %{_libexecdir}/openssh/ssh-sk-helper
%attr(0644,root,root) %{_mandir}/man8/ssh-keysign.8*
%attr(0644,root,root) %{_mandir}/man8/ssh-pkcs11-helper.8*
+%attr(0644,root,root) %{_mandir}/man8/ssh-sk-helper.8*
%endif
%if %{scard}
%attr(0755,root,root) %dir %{_datadir}/openssh
@@ -422,6 +424,9 @@ fi
%endif
%changelog
+* Mon Jul 20 2020 Damien Miller <djm@mindrto.org>
+- Add ssh-sk-helper and corresponding manual page.
+
* Sat Feb 10 2018 Darren Tucker <dtucker@dtucker.net>
- Update openssl-devel dependency to match current requirements.
- Handle Fedora >=6 openssl 1.0 compat libs.
diff --git a/crypto/openssh/contrib/solaris/README b/crypto/openssh/contrib/solaris/README
index cabecaa1a5c7..cabecaa1a5c7 100755..100644
--- a/crypto/openssh/contrib/solaris/README
+++ b/crypto/openssh/contrib/solaris/README
diff --git a/crypto/openssh/contrib/ssh-copy-id b/crypto/openssh/contrib/ssh-copy-id
index b83b83619896..cd122def30a1 100644
--- a/crypto/openssh/contrib/ssh-copy-id
+++ b/crypto/openssh/contrib/ssh-copy-id
@@ -1,6 +1,8 @@
#!/bin/sh
-# Copyright (c) 1999-2016 Philip Hands <phil@hands.com>
+# Copyright (c) 1999-2020 Philip Hands <phil@hands.com>
+# 2020 Matthias Blümel <blaimi@blaimi.de>
+# 2017 Sebastien Boyron <seb@boyron.eu>
# 2013 Martin Kletzander <mkletzan@redhat.com>
# 2010 Adeodato =?iso-8859-1?Q?Sim=F3?= <asp16@alu.ua.es>
# 2010 Eric Moret <eric.moret@gmail.com>
@@ -33,13 +35,15 @@
# Shell script to install your public key(s) on a remote machine
# See the ssh-copy-id(1) man page for details
+# shellcheck shell=dash
+
# 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"
+ printf "'%s' seems viable.\\n" "$SANE_SH"
exec "$SANE_SH" "$0" "$@"
else
cat <<-EOF
@@ -51,36 +55,39 @@ then
a bug describing your setup, and the shell you used to make it work.
EOF
- printf "%s: ERROR: Less dimwitted shell required.\n" "$0"
+ printf '%s: ERROR: Less dimwitted shell required.\n' "$0"
exit 1
fi
fi
-most_recent_id="$(cd "$HOME" ; ls -t .ssh/id*.pub 2>/dev/null | grep -v -- '-cert.pub$' | head -n 1)"
-DEFAULT_PUB_ID_FILE="${most_recent_id:+$HOME/}$most_recent_id"
+# shellcheck disable=SC2010
+DEFAULT_PUB_ID_FILE=$(ls -t "${HOME}"/.ssh/id*.pub 2>/dev/null | grep -v -- '-cert.pub$' | head -n 1)
+SSH="ssh -a -x"
+umask 0177
usage () {
- printf 'Usage: %s [-h|-?|-f|-n] [-i [identity_file]] [-p port] [[-o <ssh -o options>] ...] [user@]hostname\n' "$0" >&2
+ printf 'Usage: %s [-h|-?|-f|-n|-s] [-i [identity_file]] [-p port] [-F alternative ssh_config file] [[-o <ssh -o options>] ...] [user@]hostname\n' "$0" >&2
printf '\t-f: force mode -- copy keys without trying to check if they are already installed\n' >&2
printf '\t-n: dry run -- no keys are actually copied\n' >&2
+ printf '\t-s: use sftp -- use sftp instead of executing remote-commands. Can be useful if the remote only allows sftp\n' >&2
printf '\t-h|-?: print this help\n' >&2
exit 1
}
# escape any single quotes in an argument
quote() {
- printf "%s\n" "$1" | sed -e "s/'/'\\\\''/g"
+ printf '%s\n' "$1" | sed -e "s/'/'\\\\''/g"
}
use_id_file() {
- local L_ID_FILE="$1"
+ L_ID_FILE="$1"
if [ -z "$L_ID_FILE" ] ; then
- printf "%s: ERROR: no ID file found\n" "$0"
+ printf '%s: ERROR: no ID file found\n' "$0"
exit 1
fi
- if expr "$L_ID_FILE" : ".*\.pub$" >/dev/null ; then
+ if expr "$L_ID_FILE" : '.*\.pub$' >/dev/null ; then
PUB_ID_FILE="$L_ID_FILE"
else
PUB_ID_FILE="$L_ID_FILE.pub"
@@ -91,9 +98,9 @@ use_id_file() {
# check that the files are readable
for f in "$PUB_ID_FILE" ${PRIV_ID_FILE:+"$PRIV_ID_FILE"} ; do
ErrMSG=$( { : < "$f" ; } 2>&1 ) || {
- local L_PRIVMSG=""
+ L_PRIVMSG=""
[ "$f" = "$PRIV_ID_FILE" ] && L_PRIVMSG=" (to install the contents of '$PUB_ID_FILE' anyway, look at the -f option)"
- printf "\n%s: ERROR: failed to open ID file '%s': %s\n" "$0" "$f" "$(printf "%s\n%s\n" "$ErrMSG" "$L_PRIVMSG" | sed -e 's/.*: *//')"
+ printf "\\n%s: ERROR: failed to open ID file '%s': %s\\n" "$0" "$f" "$(printf '%s\n%s\n' "$ErrMSG" "$L_PRIVMSG" | sed -e 's/.*: *//')"
exit 1
}
done
@@ -105,80 +112,36 @@ if [ -n "$SSH_AUTH_SOCK" ] && ssh-add -L >/dev/null 2>&1 ; then
GET_ID="ssh-add -L"
fi
-while test "$#" -gt 0
+while getopts "i:o:p:F:fnsh?" OPT
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"
+ case "$OPT" in
+ i)
+ [ "${SEEN_OPT_I}" ] && {
+ 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
- ;;
- -f|-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")'"
+ o|p|F)
+ SSH_OPTS="${SSH_OPTS:+$SSH_OPTS }-$OPT '$(quote "${OPTARG}")'"
;;
- -f)
+ f)
FORCED=1
;;
- -n)
+ n)
DRY_RUN=1
;;
- -h|-\?)
+ s)
+ SFTP=sftp
+ ;;
+ h|\?)
usage
;;
esac
done
-
-eval set -- "$SAVEARGS"
+#shift all args to keep only USER_HOST
+shift $((OPTIND-1))
if [ $# = 0 ] ; then
usage
@@ -189,71 +152,74 @@ if [ $# != 1 ] ; then
fi
# drop trailing colon
-USER_HOST=$(printf "%s\n" "$1" | sed 's/:$//')
+USER_HOST="$*"
# 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"
+# shellcheck disable=SC2086
if [ -z "$(eval $GET_ID)" ] && [ -r "${PUB_ID_FILE:=$DEFAULT_PUB_ID_FILE}" ] ; then
use_id_file "$PUB_ID_FILE"
fi
+# shellcheck disable=SC2086
if [ -z "$(eval $GET_ID)" ] ; then
printf '%s: ERROR: No identities found\n' "$0" >&2
exit 1
fi
+# filter_ids()
+# tries to log in using the keys piped to it, and filters out any that work
+filter_ids() {
+ L_SUCCESS="$1"
+ L_TMP_ID_FILE="$SCRATCH_DIR"/popids_tmp_id
+ L_OUTPUT_FILE="$SCRATCH_DIR"/popids_output
+
+ # repopulate "$@" inside this function
+ eval set -- "$SSH_OPTS"
+
+ while read -r ID || [ "$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 ControlPath=none \
+ -o LogLevel=INFO \
+ -o PreferredAuthentications=publickey \
+ -o IdentitiesOnly=yes "$@" exit >"$L_OUTPUT_FILE" 2>&1 </dev/null
+ if [ "$?" = "$L_SUCCESS" ] || {
+ [ "$SFTP" ] && grep 'allows sftp connections only' "$L_OUTPUT_FILE" >/dev/null
+ # this error counts as a success if we're setting up an sftp connection
+ }
+ then
+ : > "$L_TMP_ID_FILE"
+ else
+ grep 'Permission denied' "$L_OUTPUT_FILE" >/dev/null || {
+ sed -e 's/^/ERROR: /' <"$L_OUTPUT_FILE" >"$L_TMP_ID_FILE"
+ cat >/dev/null #consume the other keys, causing loop to end
+ }
+ fi
+
+ cat "$L_TMP_ID_FILE"
+ done
+}
+
# 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"
-
if [ "$FORCED" ] ; then
+ # shellcheck disable=SC2086
NEW_IDS=$(eval $GET_ID)
return
fi
- # 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
- printf '%s: ERROR: mktemp failed\n' "$0" >&2
- exit 1
- fi
- local L_CLEANUP="rm -f \"$L_TMP_ID_FILE\" \"${L_TMP_ID_FILE}.stderr\""
- trap "$L_CLEANUP" 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 || [ "$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 ControlPath=none \
- -o LogLevel=INFO \
- -o PreferredAuthentications=publickey \
- -o IdentitiesOnly=yes "$@" exit 2>"$L_TMP_ID_FILE.stderr" </dev/null
- if [ "$?" = "$L_SUCCESS" ] ; then
- : > "$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
- }
- )
- eval "$L_CLEANUP" && trap - EXIT TERM INT QUIT
+ # shellcheck disable=SC2086
+ NEW_IDS=$(eval $GET_ID | filter_ids $1)
if expr "$NEW_IDS" : "^ERROR: " >/dev/null ; then
printf '\n%s: %s\n\n' "$0" "$NEW_IDS" >&2
@@ -261,45 +227,132 @@ populate_new_ids() {
fi
if [ -z "$NEW_IDS" ] ; then
printf '\n%s: WARNING: All keys were skipped because they already exist on the remote system.\n' "$0" >&2
- printf '\t\t(if you think this is a mistake, you may want to use -f option)\n\n' "$0" >&2
+ printf '\t\t(if you think this is a mistake, you may want to use -f option)\n\n' >&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=',' -o ControlPath=none "$@" 2>&1 |
+# installkey_sh [target_path]
+# produce a one-liner to add the keys to remote authorized_keys file
+# optionally takes an alternative path for authorized_keys
+installkeys_sh() {
+ AUTH_KEY_FILE=${1:-.ssh/authorized_keys}
+ AUTH_KEY_DIR=$(dirname "${AUTH_KEY_FILE}")
+
+ # In setting INSTALLKEYS_SH:
+ # the tr puts it all on one line (to placate tcsh)
+ # (hence the excessive use of semi-colons (;) )
+ # then in the command:
+ # cd to be at $HOME, just in case;
+ # the -z `tail ...` checks for a trailing newline. The echo adds one if was missing
+ # the cat adds the keys we're getting via STDIN
+ # and if available restorecon is used to restore the SELinux context
+ INSTALLKEYS_SH=$(tr '\t\n' ' ' <<-EOF
+ cd;
+ umask 077;
+ mkdir -p "${AUTH_KEY_DIR}" &&
+ { [ -z \`tail -1c ${AUTH_KEY_FILE} 2>/dev/null\` ] ||
+ echo >> "${AUTH_KEY_FILE}" || exit 1; } &&
+ cat >> "${AUTH_KEY_FILE}" || exit 1;
+ if type restorecon >/dev/null 2>&1; then
+ restorecon -F "${AUTH_KEY_DIR}" "${AUTH_KEY_FILE}";
+ fi
+ EOF
+ )
+
+ # to defend against quirky remote shells: use 'exec sh -c' to get POSIX;
+ printf "exec sh -c '%s'" "${INSTALLKEYS_SH}"
+}
+
+#shellcheck disable=SC2120 # the 'eval set' confuses this
+installkeys_via_sftp() {
+
+ # repopulate "$@" inside this function
+ eval set -- "$SSH_OPTS"
+
+ L_KEYS=$SCRATCH_DIR/authorized_keys
+ L_SHARED_CON=$SCRATCH_DIR/master-conn
+ $SSH -f -N -M -S "$L_SHARED_CON" "$@"
+ L_CLEANUP="$SSH -S $L_SHARED_CON -O exit 'ignored' >/dev/null 2>&1 ; $SCRATCH_CLEANUP"
+ #shellcheck disable=SC2064
+ trap "$L_CLEANUP" EXIT TERM INT QUIT
+ sftp -b - -o "ControlPath=$L_SHARED_CON" "ignored" <<-EOF || return 1
+ -get .ssh/authorized_keys $L_KEYS
+ EOF
+ # add a newline or create file if it's missing, same like above
+ [ -z "$(tail -1c "$L_KEYS" 2>/dev/null)" ] || echo >> "$L_KEYS"
+ # append the keys being piped in here
+ cat >> "$L_KEYS"
+ sftp -b - -o "ControlPath=$L_SHARED_CON" "ignored" <<-EOF || return 1
+ -mkdir .ssh
+ chmod 700 .ssh
+ put $L_KEYS .ssh/authorized_keys
+ chmod 600 .ssh/authorized_keys
+ EOF
+ #shellcheck disable=SC2064
+ eval "$L_CLEANUP" && trap "$SCRATCH_CLEANUP" EXIT TERM INT QUIT
+}
+
+
+# create a scratch dir for any temporary files needed
+if SCRATCH_DIR=$(mktemp -d ~/.ssh/ssh-copy-id.XXXXXXXXXX) &&
+ [ "$SCRATCH_DIR" ] && [ -d "$SCRATCH_DIR" ]
+then
+ chmod 0700 "$SCRATCH_DIR"
+ SCRATCH_CLEANUP="rm -rf \"$SCRATCH_DIR\""
+ #shellcheck disable=SC2064
+ trap "$SCRATCH_CLEANUP" EXIT TERM INT QUIT
+else
+ printf '%s: ERROR: failed to create required temporary directory under ~/.ssh\n' "$0" >&2
+ exit 1
+fi
+
+REMOTE_VERSION=$($SSH -v -o PreferredAuthentications=',' -o ControlPath=none "$@" 2>&1 |
sed -ne 's/.*remote software version //p')
+# shellcheck disable=SC2029
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 || {
+ 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
+ [ "$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))
+ 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
+ dropbear*)
populate_new_ids 0
- # in ssh below - to defend against quirky remote shells: use 'exec sh -c' to get POSIX;
- # 'cd' to be at $HOME; add a newline if it's missing; and all on one line, because tcsh.
[ "$DRY_RUN" ] || printf '%s\n' "$NEW_IDS" | \
- ssh "$@" "exec sh -c 'cd ; umask 077 ; mkdir -p .ssh && { [ -z "'`tail -1c .ssh/authorized_keys 2>/dev/null`'" ] || echo >> .ssh/authorized_keys ; } && cat >> .ssh/authorized_keys || exit 1 ; if type restorecon >/dev/null 2>&1 ; then restorecon -F .ssh .ssh/authorized_keys ; fi'" \
+ $SSH "$@" "$(installkeys_sh /etc/dropbear/authorized_keys)" \
|| exit 1
ADDED=$(printf '%s\n' "$NEW_IDS" | wc -l)
;;
+ *)
+ # Assuming that the remote host treats ~/.ssh/authorized_keys as one might expect
+ populate_new_ids 0
+ if ! [ "$DRY_RUN" ] ; then
+ printf '%s\n' "$NEW_IDS" | \
+ if [ "$SFTP" ] ; then
+ #shellcheck disable=SC2119
+ installkeys_via_sftp
+ else
+ $SSH "$@" "$(installkeys_sh)"
+ fi || exit 1
+ fi
+ ADDED=$(printf '%s\n' "$NEW_IDS" | wc -l)
+ ;;
esac
if [ "$DRY_RUN" ] ; then
@@ -315,7 +368,7 @@ else
Number of key(s) added: $ADDED
- Now try logging into the machine, with: "ssh $SSH_OPTS"
+ Now try logging into the machine, with: "${SFTP:-ssh} $SSH_OPTS"
and check to make sure that only the key(s) you wanted were added.
EOF
diff --git a/crypto/openssh/contrib/ssh-copy-id.1 b/crypto/openssh/contrib/ssh-copy-id.1
index 8850cceda0a9..c141a296f77a 100644
--- a/crypto/openssh/contrib/ssh-copy-id.1
+++ b/crypto/openssh/contrib/ssh-copy-id.1
@@ -1,5 +1,5 @@
.ig \" -*- nroff -*-
-Copyright (c) 1999-2013 hands.com Ltd. <http://hands.com/>
+Copyright (c) 1999-2020 hands.com Ltd. <http://hands.com/>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
@@ -31,6 +31,7 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
.Nm
.Op Fl f
.Op Fl n
+.Op Fl s
.Op Fl i Op Ar identity_file
.Op Fl p Ar port
.Op Fl o Ar ssh_option
@@ -84,6 +85,12 @@ in more than one copy of the key being installed on the remote system.
.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 s
+SFTP mode: usually the public keys are installed by executing commands on the remote side.
+With this option the user's
+.Pa ~/.ssh/authorized_keys
+file will be downloaded, modified locally and uploaded with sftp.
+This option is useful if the server has restrictions on commands which can be used on the remote side.
.It Fl h , Fl ?
Print Usage summary
.It Fl p Ar port , Fl o Ar ssh_option
@@ -158,7 +165,7 @@ asked for confirmation, which is your cue to log back out and run
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.
+file, rather than just the filename that was loaded into your 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 .
diff --git a/crypto/openssh/contrib/suse/openssh.spec b/crypto/openssh/contrib/suse/openssh.spec
index b43d8985abaf..6cd222e5a424 100644
--- a/crypto/openssh/contrib/suse/openssh.spec
+++ b/crypto/openssh/contrib/suse/openssh.spec
@@ -13,7 +13,7 @@
Summary: OpenSSH, a free Secure Shell (SSH) protocol implementation
Name: openssh
-Version: 7.9p1
+Version: 8.7p1
URL: https://www.openssh.com/
Release: 1
Source0: openssh-%{version}.tar.gz
@@ -75,6 +75,8 @@ patented algorithms to separate libraries (OpenSSL).
This package contains an X Window System passphrase dialog for OpenSSH.
%changelog
+* Mon Jul 20 2020 Damien Miller <djm@mindrto.org>
+- Add ssh-sk-helper and corresponding manual page.
* Wed Oct 26 2005 Iain Morgan <imorgan@nas.nasa.gov>
- Removed accidental inclusion of --without-zlib-version-check
* Tue Oct 25 2005 Iain Morgan <imorgan@nas.nasa.gov>
@@ -211,6 +213,7 @@ rm -rf $RPM_BUILD_ROOT
%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(0755,root,root) %{_libdir}/ssh/ssh-sk-helper
%attr(0644,root,root) %doc %{_mandir}/man1/scp.1*
%attr(0644,root,root) %doc %{_mandir}/man1/sftp.1*
%attr(0644,root,root) %doc %{_mandir}/man1/ssh.1*
@@ -224,6 +227,7 @@ rm -rf $RPM_BUILD_ROOT
%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/ssh-sk-helper.8*
%attr(0644,root,root) %doc %{_mandir}/man8/sshd.8*
%attr(0644,root,root) /var/adm/fillup-templates/sysconfig.ssh
diff --git a/crypto/openssh/crc32.c b/crypto/openssh/crc32.c
deleted file mode 100644
index c192eb4d66da..000000000000
--- a/crypto/openssh/crc32.c
+++ /dev/null
@@ -1,105 +0,0 @@
-/* $OpenBSD: crc32.c,v 1.11 2006/04/22 18:29:33 stevesk Exp $ */
-
-/*
- * 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"
-#include "crc32.h"
-
-static const u_int32_t crc32tab[] = {
- 0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL,
- 0x076dc419L, 0x706af48fL, 0xe963a535L, 0x9e6495a3L,
- 0x0edb8832L, 0x79dcb8a4L, 0xe0d5e91eL, 0x97d2d988L,
- 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L, 0x90bf1d91L,
- 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL,
- 0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L,
- 0x136c9856L, 0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL,
- 0x14015c4fL, 0x63066cd9L, 0xfa0f3d63L, 0x8d080df5L,
- 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L, 0xa2677172L,
- 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL,
- 0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L,
- 0x32d86ce3L, 0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L,
- 0x26d930acL, 0x51de003aL, 0xc8d75180L, 0xbfd06116L,
- 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L, 0xb8bda50fL,
- 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L,
- 0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL,
- 0x76dc4190L, 0x01db7106L, 0x98d220bcL, 0xefd5102aL,
- 0x71b18589L, 0x06b6b51fL, 0x9fbfe4a5L, 0xe8b8d433L,
- 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL, 0xe10e9818L,
- 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L,
- 0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL,
- 0x6c0695edL, 0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L,
- 0x65b0d9c6L, 0x12b7e950L, 0x8bbeb8eaL, 0xfcb9887cL,
- 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L, 0xfbd44c65L,
- 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L,
- 0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL,
- 0x4369e96aL, 0x346ed9fcL, 0xad678846L, 0xda60b8d0L,
- 0x44042d73L, 0x33031de5L, 0xaa0a4c5fL, 0xdd0d7cc9L,
- 0x5005713cL, 0x270241aaL, 0xbe0b1010L, 0xc90c2086L,
- 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL,
- 0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L,
- 0x59b33d17L, 0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL,
- 0xedb88320L, 0x9abfb3b6L, 0x03b6e20cL, 0x74b1d29aL,
- 0xead54739L, 0x9dd277afL, 0x04db2615L, 0x73dc1683L,
- 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L,
- 0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L,
- 0xf00f9344L, 0x8708a3d2L, 0x1e01f268L, 0x6906c2feL,
- 0xf762575dL, 0x806567cbL, 0x196c3671L, 0x6e6b06e7L,
- 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL, 0x67dd4accL,
- 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L,
- 0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L,
- 0xd1bb67f1L, 0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL,
- 0xd80d2bdaL, 0xaf0a1b4cL, 0x36034af6L, 0x41047a60L,
- 0xdf60efc3L, 0xa867df55L, 0x316e8eefL, 0x4669be79L,
- 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L,
- 0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL,
- 0xc5ba3bbeL, 0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L,
- 0xc2d7ffa7L, 0xb5d0cf31L, 0x2cd99e8bL, 0x5bdeae1dL,
- 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL, 0x026d930aL,
- 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L,
- 0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L,
- 0x92d28e9bL, 0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L,
- 0x86d3d2d4L, 0xf1d4e242L, 0x68ddb3f8L, 0x1fda836eL,
- 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L, 0x18b74777L,
- 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL,
- 0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L,
- 0xa00ae278L, 0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L,
- 0xa7672661L, 0xd06016f7L, 0x4969474dL, 0x3e6e77dbL,
- 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L, 0x37d83bf0L,
- 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L,
- 0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L,
- 0xbad03605L, 0xcdd70693L, 0x54de5729L, 0x23d967bfL,
- 0xb3667a2eL, 0xc4614ab8L, 0x5d681b02L, 0x2a6f2b94L,
- 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL, 0x2d02ef8dL
-};
-
-u_int32_t
-ssh_crc32(const u_char *buf, u_int32_t size)
-{
- u_int32_t i, crc;
-
- crc = 0;
- for (i = 0; i < size; i++)
- crc = crc32tab[(crc ^ buf[i]) & 0xff] ^ (crc >> 8);
- return crc;
-}
diff --git a/crypto/openssh/crc32.h b/crypto/openssh/crc32.h
deleted file mode 100644
index 5d7131aff2cb..000000000000
--- a/crypto/openssh/crc32.h
+++ /dev/null
@@ -1,30 +0,0 @@
-/* $OpenBSD: crc32.h,v 1.15 2006/03/25 22:22:43 djm Exp $ */
-
-/*
- * 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.
- */
-
-#ifndef SSH_CRC32_H
-#define SSH_CRC32_H
-u_int32_t ssh_crc32(const u_char *, u_int32_t);
-#endif
diff --git a/crypto/openssh/crypto_api.h b/crypto/openssh/crypto_api.h
index 7f45bbd69e77..5c3d97eaa401 100644
--- a/crypto/openssh/crypto_api.h
+++ b/crypto/openssh/crypto_api.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: crypto_api.h,v 1.4 2017/12/14 21:07:39 naddy Exp $ */
+/* $OpenBSD: crypto_api.h,v 1.7 2021/01/08 02:33:13 dtucker Exp $ */
/*
* Assembled from generated headers and source files by Markus Friedl.
@@ -15,10 +15,17 @@
#endif
#include <stdlib.h>
+typedef int8_t crypto_int8;
+typedef uint8_t crypto_uint8;
+typedef int16_t crypto_int16;
+typedef uint16_t crypto_uint16;
typedef int32_t crypto_int32;
typedef uint32_t crypto_uint32;
+typedef int64_t crypto_int64;
+typedef uint64_t crypto_uint64;
#define randombytes(buf, buf_len) arc4random_buf((buf), (buf_len))
+#define small_random32() arc4random()
#define crypto_hash_sha512_BYTES 64U
@@ -37,4 +44,15 @@ int crypto_sign_ed25519_open(unsigned char *, unsigned long long *,
const unsigned char *, unsigned long long, const unsigned char *);
int crypto_sign_ed25519_keypair(unsigned char *, unsigned char *);
+#define crypto_kem_sntrup761_PUBLICKEYBYTES 1158
+#define crypto_kem_sntrup761_SECRETKEYBYTES 1763
+#define crypto_kem_sntrup761_CIPHERTEXTBYTES 1039
+#define crypto_kem_sntrup761_BYTES 32
+
+int crypto_kem_sntrup761_enc(unsigned char *cstr, unsigned char *k,
+ const unsigned char *pk);
+int crypto_kem_sntrup761_dec(unsigned char *k,
+ const unsigned char *cstr, const unsigned char *sk);
+int crypto_kem_sntrup761_keypair(unsigned char *pk, unsigned char *sk);
+
#endif /* crypto_api_h */
diff --git a/crypto/openssh/defines.h b/crypto/openssh/defines.h
index 8f4213062a9c..857abb8b1d6f 100644
--- a/crypto/openssh/defines.h
+++ b/crypto/openssh/defines.h
@@ -96,6 +96,18 @@ enum
#ifndef IPTOS_DSCP_EF
# define IPTOS_DSCP_EF 0xb8
#endif /* IPTOS_DSCP_EF */
+#ifndef IPTOS_DSCP_LE
+# define IPTOS_DSCP_LE 0x01
+#endif /* IPTOS_DSCP_LE */
+#ifndef IPTOS_PREC_CRITIC_ECP
+# define IPTOS_PREC_CRITIC_ECP 0xa0
+#endif
+#ifndef IPTOS_PREC_INTERNETCONTROL
+# define IPTOS_PREC_INTERNETCONTROL 0xc0
+#endif
+#ifndef IPTOS_PREC_NETCONTROL
+# define IPTOS_PREC_NETCONTROL 0xe0
+#endif
#ifndef PATH_MAX
# ifdef _POSIX_PATH_MAX
@@ -108,10 +120,6 @@ enum
# 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 */
@@ -246,6 +254,21 @@ typedef unsigned int u_int32_t;
#define __BIT_TYPES_DEFINED__
#endif
+#if !defined(LLONG_MIN) && defined(LONG_LONG_MIN)
+#define LLONG_MIN LONG_LONG_MIN
+#endif
+#if !defined(LLONG_MAX) && defined(LONG_LONG_MAX)
+#define LLONG_MAX LONG_LONG_MAX
+#endif
+
+#ifndef UINT32_MAX
+# if defined(HAVE_DECL_UINT32_MAX) && (HAVE_DECL_UINT32_MAX == 0)
+# if (SIZEOF_INT == 4)
+# define UINT32_MAX UINT_MAX
+# endif
+# endif
+#endif
+
/* 64-bit types */
#ifndef HAVE_INT64_T
# if (SIZEOF_LONG_INT == 8)
@@ -281,6 +304,12 @@ typedef long long intmax_t;
typedef unsigned long long uintmax_t;
#endif
+#if SIZEOF_TIME_T == SIZEOF_LONG_LONG_INT
+# define SSH_TIME_T_MAX LLONG_MAX
+#else
+# define SSH_TIME_T_MAX INT_MAX
+#endif
+
#ifndef HAVE_U_CHAR
typedef unsigned char u_char;
# define HAVE_U_CHAR
@@ -328,6 +357,7 @@ typedef unsigned int size_t;
#ifndef HAVE_SSIZE_T
typedef int ssize_t;
+#define SSIZE_MAX INT_MAX
# define HAVE_SSIZE_T
#endif /* HAVE_SSIZE_T */
@@ -805,10 +835,6 @@ struct winsize {
# 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
@@ -834,9 +860,10 @@ struct winsize {
/*
* We want functions in openbsd-compat, if enabled, to override system ones.
* We no-op out the weak symbol definition rather than remove it to reduce
- * future sync problems.
+ * future sync problems. Some compilers (eg Unixware) do not allow an
+ * empty statement, so we use a bogus function declaration.
*/
-#define DEF_WEAK(x)
+#define DEF_WEAK(x) void __ssh_compat_weak_##x(void)
/*
* Platforms that have arc4random_uniform() and not arc4random_stir()
@@ -873,4 +900,11 @@ struct winsize {
# define USE_SYSTEM_GLOB
#endif
+/*
+ * sntrup761 uses variable length arrays and c99-style declarations after code,
+ * so only enable if the compiler supports them.
+ */
+#if defined(VARIABLE_LENGTH_ARRAYS) && defined(VARIABLE_DECLARATION_AFTER_CODE)
+# define USE_SNTRUP761X25519 1
+#endif
#endif /* _DEFINES_H */
diff --git a/crypto/openssh/dh.c b/crypto/openssh/dh.c
index 657b32da3d98..ce2eb4725e65 100644
--- a/crypto/openssh/dh.c
+++ b/crypto/openssh/dh.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: dh.c,v 1.68 2018/09/17 15:40:14 millert Exp $ */
+/* $OpenBSD: dh.c,v 1.74 2021/04/03 06:18:40 djm Exp $ */
/*
* Copyright (c) 2000 Niels Provos. All rights reserved.
*
@@ -27,9 +27,6 @@
#ifdef WITH_OPENSSL
-#include <openssl/bn.h>
-#include <openssl/dh.h>
-
#include <errno.h>
#include <stdarg.h>
#include <stdio.h>
@@ -37,6 +34,9 @@
#include <string.h>
#include <limits.h>
+#include <openssl/bn.h>
+#include <openssl/dh.h>
+
#include "dh.h"
#include "pathnames.h"
#include "log.h"
@@ -45,6 +45,18 @@
#include "openbsd-compat/openssl-compat.h"
+static const char *moduli_filename;
+
+void dh_set_moduli_file(const char *filename)
+{
+ moduli_filename = filename;
+}
+
+static const char * get_moduli_filename(void)
+{
+ return moduli_filename ? moduli_filename : _PATH_DH_MODULI;
+}
+
static int
parse_prime(int linenum, char *line, struct dhgroup *dhg)
{
@@ -152,9 +164,9 @@ choose_dh(int min, int wantbits, int max)
int best, bestcount, which, linenum;
struct dhgroup dhg;
- if ((f = fopen(_PATH_DH_MODULI, "r")) == NULL) {
+ if ((f = fopen(get_moduli_filename(), "r")) == NULL) {
logit("WARNING: could not open %s (%s), using fixed modulus",
- _PATH_DH_MODULI, strerror(errno));
+ get_moduli_filename(), strerror(errno));
return (dh_new_group_fallback(max));
}
@@ -185,7 +197,8 @@ choose_dh(int min, int wantbits, int max)
if (bestcount == 0) {
fclose(f);
- logit("WARNING: no suitable primes in %s", _PATH_DH_MODULI);
+ logit("WARNING: no suitable primes in %s",
+ get_moduli_filename());
return (dh_new_group_fallback(max));
}
which = arc4random_uniform(bestcount);
@@ -210,7 +223,7 @@ choose_dh(int min, int wantbits, int max)
fclose(f);
if (bestcount != which + 1) {
logit("WARNING: selected prime disappeared in %s, giving up",
- _PATH_DH_MODULI);
+ get_moduli_filename());
return (dh_new_group_fallback(max));
}
@@ -240,7 +253,7 @@ dh_pub_is_valid(const DH *dh, const BIGNUM *dh_pub)
}
if ((tmp = BN_new()) == NULL) {
- error("%s: BN_new failed", __func__);
+ error_f("BN_new failed");
return 0;
}
if (!BN_sub(tmp, dh_p, BN_value_one()) ||
@@ -261,7 +274,7 @@ dh_pub_is_valid(const DH *dh, const BIGNUM *dh_pub)
*/
if (bits_set < 4) {
logit("invalid public DH value (%d/%d)",
- bits_set, BN_num_bits(dh_p));
+ bits_set, BN_num_bits(dh_p));
return 0;
}
return 1;
@@ -406,7 +419,7 @@ dh_new_group16(void)
DH *
dh_new_group18(void)
{
- static char *gen = "2", *group16 =
+ static char *gen = "2", *group18 =
"FFFFFFFF" "FFFFFFFF" "C90FDAA2" "2168C234" "C4C6628B" "80DC1CD1"
"29024E08" "8A67CC74" "020BBEA6" "3B139B22" "514A0879" "8E3404DD"
"EF9519B3" "CD3A431B" "302B0A6D" "F25F1437" "4FE1356D" "6D51C245"
@@ -451,14 +464,14 @@ dh_new_group18(void)
"9558E447" "5677E9AA" "9E3050E2" "765694DF" "C81F56E8" "80B96E71"
"60C980DD" "98EDD3DF" "FFFFFFFF" "FFFFFFFF";
- return (dh_new_group_asc(gen, group16));
+ return (dh_new_group_asc(gen, group18));
}
/* Select fallback group used by DH-GEX if moduli file cannot be read. */
DH *
dh_new_group_fallback(int max)
{
- debug3("%s: requested max size %d", __func__, max);
+ debug3_f("requested max size %d", max);
if (max < 3072) {
debug3("using 2k bit group 14");
return dh_new_group14();
diff --git a/crypto/openssh/dh.h b/crypto/openssh/dh.h
index 344b29e356ce..c6326a39d532 100644
--- a/crypto/openssh/dh.h
+++ b/crypto/openssh/dh.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: dh.h,v 1.15 2016/05/02 10:26:04 djm Exp $ */
+/* $OpenBSD: dh.h,v 1.19 2021/03/12 04:08:19 dtucker Exp $ */
/*
* Copyright (c) 2000 Niels Provos. All rights reserved.
@@ -26,6 +26,8 @@
#ifndef DH_H
#define DH_H
+#ifdef WITH_OPENSSL
+
struct dhgroup {
int size;
BIGNUM *g;
@@ -45,10 +47,11 @@ int dh_gen_key(DH *, int);
int dh_pub_is_valid(const DH *, const BIGNUM *);
u_int dh_estimate(int);
+void dh_set_moduli_file(const char *);
/*
* Max value from RFC4419.
- * Miniumum increased in light of DH precomputation attacks.
+ * Min value from RFC8270.
*/
#define DH_GRP_MIN 2048
#define DH_GRP_MAX 8192
@@ -76,5 +79,6 @@ u_int dh_estimate(int);
#define MODULI_TESTS_JACOBI (0x08)
#define MODULI_TESTS_ELLIPTIC (0x10)
+#endif /* WITH_OPENSSL */
-#endif
+#endif /* DH_H */
diff --git a/crypto/openssh/digest-libc.c b/crypto/openssh/digest-libc.c
index c2b0b2403d11..86a1dbf291a8 100644
--- a/crypto/openssh/digest-libc.c
+++ b/crypto/openssh/digest-libc.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: digest-libc.c,v 1.6 2017/05/08 22:57:38 djm Exp $ */
+/* $OpenBSD: digest-libc.c,v 1.7 2020/02/26 13:40:09 jsg Exp $ */
/*
* Copyright (c) 2013 Damien Miller <djm@mindrot.org>
* Copyright (c) 2014 Markus Friedl. All rights reserved.
@@ -28,7 +28,11 @@
#if 0
#include <md5.h>
#include <rmd160.h>
+#endif
+#ifdef HAVE_SHA1_H
#include <sha1.h>
+#endif
+#ifdef HAVE_SHA2_H
#include <sha2.h>
#endif
@@ -83,30 +87,30 @@ const struct ssh_digest digests[SSH_DIGEST_MAX] = {
"SHA256",
SHA256_BLOCK_LENGTH,
SHA256_DIGEST_LENGTH,
- sizeof(SHA256_CTX),
- (md_init_fn *) SHA256_Init,
- (md_update_fn *) SHA256_Update,
- (md_final_fn *) SHA256_Final
+ sizeof(SHA2_CTX),
+ (md_init_fn *) SHA256Init,
+ (md_update_fn *) SHA256Update,
+ (md_final_fn *) SHA256Final
},
{
SSH_DIGEST_SHA384,
"SHA384",
SHA384_BLOCK_LENGTH,
SHA384_DIGEST_LENGTH,
- sizeof(SHA384_CTX),
- (md_init_fn *) SHA384_Init,
- (md_update_fn *) SHA384_Update,
- (md_final_fn *) SHA384_Final
+ sizeof(SHA2_CTX),
+ (md_init_fn *) SHA384Init,
+ (md_update_fn *) SHA384Update,
+ (md_final_fn *) SHA384Final
},
{
SSH_DIGEST_SHA512,
"SHA512",
SHA512_BLOCK_LENGTH,
SHA512_DIGEST_LENGTH,
- sizeof(SHA512_CTX),
- (md_init_fn *) SHA512_Init,
- (md_update_fn *) SHA512_Update,
- (md_final_fn *) SHA512_Final
+ sizeof(SHA2_CTX),
+ (md_init_fn *) SHA512Init,
+ (md_update_fn *) SHA512Update,
+ (md_final_fn *) SHA512Final
}
};
@@ -226,8 +230,7 @@ ssh_digest_free(struct ssh_digest_ctx *ctx)
if (digest) {
explicit_bzero(ctx->mdctx, digest->ctx_len);
free(ctx->mdctx);
- explicit_bzero(ctx, sizeof(*ctx));
- free(ctx);
+ freezero(ctx, sizeof(*ctx));
}
}
}
diff --git a/crypto/openssh/digest-openssl.c b/crypto/openssh/digest-openssl.c
index da7ed72bccbb..e073a807b148 100644
--- a/crypto/openssh/digest-openssl.c
+++ b/crypto/openssh/digest-openssl.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: digest-openssl.c,v 1.7 2017/05/08 22:57:38 djm Exp $ */
+/* $OpenBSD: digest-openssl.c,v 1.9 2020/10/29 02:52:43 djm Exp $ */
/*
* Copyright (c) 2013 Damien Miller <djm@mindrot.org>
*
@@ -32,14 +32,15 @@
#include "digest.h"
#include "ssherr.h"
-#ifndef HAVE_EVP_RIPEMD160
-# define EVP_ripemd160 NULL
-#endif /* HAVE_EVP_RIPEMD160 */
#ifndef HAVE_EVP_SHA256
# define EVP_sha256 NULL
+#endif
+#ifndef HAVE_EVP_SHA384
# define EVP_sha384 NULL
+#endif
+#ifndef HAVE_EVP_SHA512
# define EVP_sha512 NULL
-#endif /* HAVE_EVP_SHA256 */
+#endif
struct ssh_digest_ctx {
int alg;
@@ -55,11 +56,11 @@ struct ssh_digest {
/* NB. Indexed directly by algorithm number */
const struct ssh_digest digests[] = {
- { SSH_DIGEST_MD5, "MD5", 16, EVP_md5 },
- { SSH_DIGEST_SHA1, "SHA1", 20, EVP_sha1 },
- { SSH_DIGEST_SHA256, "SHA256", 32, EVP_sha256 },
+ { SSH_DIGEST_MD5, "MD5", 16, EVP_md5 },
+ { SSH_DIGEST_SHA1, "SHA1", 20, EVP_sha1 },
+ { SSH_DIGEST_SHA256, "SHA256", 32, EVP_sha256 },
{ SSH_DIGEST_SHA384, "SHA384", 48, EVP_sha384 },
- { SSH_DIGEST_SHA512, "SHA512", 64, EVP_sha512 },
+ { SSH_DIGEST_SHA512, "SHA512", 64, EVP_sha512 },
{ -1, NULL, 0, NULL },
};
diff --git a/crypto/openssh/dispatch.c b/crypto/openssh/dispatch.c
index 0b3ea614e150..6e4c501e0573 100644
--- a/crypto/openssh/dispatch.c
+++ b/crypto/openssh/dispatch.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: dispatch.c,v 1.31 2017/05/31 07:00:13 markus Exp $ */
+/* $OpenBSD: dispatch.c,v 1.32 2019/01/19 21:33:13 djm Exp $ */
/*
* Copyright (c) 2000 Markus Friedl. All rights reserved.
*
@@ -47,7 +47,7 @@ dispatch_protocol_error(int type, u_int32_t seq, struct ssh *ssh)
(r = sshpkt_put_u32(ssh, seq)) != 0 ||
(r = sshpkt_send(ssh)) != 0 ||
(r = ssh_packet_write_wait(ssh)) != 0)
- sshpkt_fatal(ssh, __func__, r);
+ sshpkt_fatal(ssh, r, "%s", __func__);
return 0;
}
@@ -131,5 +131,5 @@ ssh_dispatch_run_fatal(struct ssh *ssh, int mode, volatile sig_atomic_t *done)
int r;
if ((r = ssh_dispatch_run(ssh, mode, done)) != 0)
- sshpkt_fatal(ssh, __func__, r);
+ sshpkt_fatal(ssh, r, "%s", __func__);
}
diff --git a/crypto/openssh/dispatch.h b/crypto/openssh/dispatch.h
index 17a6f3db6338..a22d7749febb 100644
--- a/crypto/openssh/dispatch.h
+++ b/crypto/openssh/dispatch.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: dispatch.h,v 1.14 2017/05/31 07:00:13 markus Exp $ */
+/* $OpenBSD: dispatch.h,v 1.15 2019/01/19 21:45:31 djm Exp $ */
/*
* Copyright (c) 2000 Markus Friedl. All rights reserved.
@@ -46,11 +46,4 @@ void ssh_dispatch_range(struct ssh *, u_int, u_int, dispatch_fn *);
int ssh_dispatch_run(struct ssh *, int, volatile sig_atomic_t *);
void ssh_dispatch_run_fatal(struct ssh *, int, volatile sig_atomic_t *);
-#define dispatch_init(dflt) \
- ssh_dispatch_init(active_state, (dflt))
-#define dispatch_range(from, to, fn) \
- ssh_dispatch_range(active_state, (from), (to), (fn))
-#define dispatch_set(type, fn) \
- ssh_dispatch_set(active_state, (type), (fn))
-
#endif
diff --git a/crypto/openssh/dns.c b/crypto/openssh/dns.c
index ff1a2c41c29d..1cfc38e7cc43 100644
--- a/crypto/openssh/dns.c
+++ b/crypto/openssh/dns.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: dns.c,v 1.38 2018/02/23 15:58:37 markus Exp $ */
+/* $OpenBSD: dns.c,v 1.41 2021/07/19 03:13:28 dtucker Exp $ */
/*
* Copyright (c) 2003 Wesley Griffin. All rights reserved.
@@ -34,7 +34,6 @@
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
-#include <stdarg.h>
#include <stdlib.h>
#include "xmalloc.h"
@@ -76,6 +75,7 @@ dns_result_totext(unsigned int res)
/*
* Read SSHFP parameters from key buffer.
+ * Caller must free digest which is allocated by sshkey_fingerprint_raw().
*/
static int
dns_read_key(u_int8_t *algorithm, u_int8_t *digest_type,
@@ -87,32 +87,21 @@ dns_read_key(u_int8_t *algorithm, u_int8_t *digest_type,
switch (key->type) {
case KEY_RSA:
*algorithm = SSHFP_KEY_RSA;
- if (!*digest_type)
- *digest_type = SSHFP_HASH_SHA1;
break;
case KEY_DSA:
*algorithm = SSHFP_KEY_DSA;
- if (!*digest_type)
- *digest_type = SSHFP_HASH_SHA1;
break;
case KEY_ECDSA:
*algorithm = SSHFP_KEY_ECDSA;
- if (!*digest_type)
- *digest_type = SSHFP_HASH_SHA256;
break;
case KEY_ED25519:
*algorithm = SSHFP_KEY_ED25519;
- if (!*digest_type)
- *digest_type = SSHFP_HASH_SHA256;
break;
case KEY_XMSS:
*algorithm = SSHFP_KEY_XMSS;
- if (!*digest_type)
- *digest_type = SSHFP_HASH_SHA256;
break;
default:
*algorithm = SSHFP_KEY_RESERVED; /* 0 */
- *digest_type = SSHFP_HASH_RESERVED; /* 0 */
}
switch (*digest_type) {
@@ -129,13 +118,11 @@ dns_read_key(u_int8_t *algorithm, u_int8_t *digest_type,
if (*algorithm && *digest_type) {
if ((r = sshkey_fingerprint_raw(key, fp_alg, digest,
digest_len)) != 0)
- fatal("%s: sshkey_fingerprint_raw: %s", __func__,
- ssh_err(r));
+ fatal_fr(r, "sshkey_fingerprint_raw");
success = 1;
} else {
*digest = NULL;
*digest_len = 0;
- success = 0;
}
return success;
@@ -214,7 +201,6 @@ verify_host_key_dns(const char *hostname, struct sockaddr *address,
struct rrsetinfo *fingerprints = NULL;
u_int8_t hostkey_algorithm;
- u_int8_t hostkey_digest_type = SSHFP_HASH_RESERVED;
u_char *hostkey_digest;
size_t hostkey_digest_len;
@@ -250,14 +236,6 @@ verify_host_key_dns(const char *hostname, struct sockaddr *address,
fingerprints->rri_nrdatas);
}
- /* Initialize default host key parameters */
- if (!dns_read_key(&hostkey_algorithm, &hostkey_digest_type,
- &hostkey_digest, &hostkey_digest_len, hostkey)) {
- error("Error calculating host key fingerprint.");
- freerrset(fingerprints);
- return -1;
- }
-
if (fingerprints->rri_nrdatas)
*flags |= DNS_VERIFY_FOUND;
@@ -273,35 +251,41 @@ verify_host_key_dns(const char *hostname, struct sockaddr *address,
verbose("Error parsing fingerprint from DNS.");
continue;
}
-
- if (hostkey_digest_type != dnskey_digest_type) {
- hostkey_digest_type = dnskey_digest_type;
- free(hostkey_digest);
-
- /* Initialize host key parameters */
- if (!dns_read_key(&hostkey_algorithm,
- &hostkey_digest_type, &hostkey_digest,
- &hostkey_digest_len, hostkey)) {
- error("Error calculating key fingerprint.");
- freerrset(fingerprints);
- return -1;
- }
+ debug3_f("checking SSHFP type %d fptype %d", dnskey_algorithm,
+ dnskey_digest_type);
+
+ /* Calculate host key fingerprint. */
+ if (!dns_read_key(&hostkey_algorithm, &dnskey_digest_type,
+ &hostkey_digest, &hostkey_digest_len, hostkey)) {
+ error("Error calculating key fingerprint.");
+ freerrset(fingerprints);
+ return -1;
}
/* Check if the current key is the same as the given key */
if (hostkey_algorithm == dnskey_algorithm &&
- hostkey_digest_type == dnskey_digest_type) {
- if (hostkey_digest_len == dnskey_digest_len &&
- timingsafe_bcmp(hostkey_digest, dnskey_digest,
- hostkey_digest_len) == 0)
+ hostkey_digest_len == dnskey_digest_len) {
+ if (timingsafe_bcmp(hostkey_digest, dnskey_digest,
+ hostkey_digest_len) == 0) {
+ debug_f("matched SSHFP type %d fptype %d",
+ dnskey_algorithm, dnskey_digest_type);
*flags |= DNS_VERIFY_MATCH;
+ } else {
+ debug_f("failed SSHFP type %d fptype %d",
+ dnskey_algorithm, dnskey_digest_type);
+ *flags |= DNS_VERIFY_FAILED;
+ }
}
free(dnskey_digest);
+ free(hostkey_digest); /* from sshkey_fingerprint_raw() */
}
- free(hostkey_digest); /* from sshkey_fingerprint_raw() */
freerrset(fingerprints);
+ /* If any fingerprint failed to validate, return failure. */
+ if (*flags & DNS_VERIFY_FAILED)
+ *flags &= ~DNS_VERIFY_MATCH;
+
if (*flags & DNS_VERIFY_FOUND)
if (*flags & DNS_VERIFY_MATCH)
debug("matching host key fingerprint found in DNS");
@@ -349,7 +333,7 @@ export_dns_rr(const char *hostname, struct sshkey *key, FILE *f, int generic)
/* No SSHFP record was generated at all */
if (success == 0) {
- error("%s: unsupported algorithm and/or digest_type", __func__);
+ error_f("unsupported algorithm and/or digest_type");
}
return success;
diff --git a/crypto/openssh/dns.h b/crypto/openssh/dns.h
index 91f3c632dd1b..c9b61c4f28f8 100644
--- a/crypto/openssh/dns.h
+++ b/crypto/openssh/dns.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: dns.h,v 1.18 2018/02/23 15:58:37 markus Exp $ */
+/* $OpenBSD: dns.h,v 1.19 2021/07/19 03:13:28 dtucker Exp $ */
/*
* Copyright (c) 2003 Wesley Griffin. All rights reserved.
@@ -50,6 +50,7 @@ enum sshfp_hashes {
#define DNS_VERIFY_FOUND 0x00000001
#define DNS_VERIFY_MATCH 0x00000002
#define DNS_VERIFY_SECURE 0x00000004
+#define DNS_VERIFY_FAILED 0x00000008
int verify_host_key_dns(const char *, struct sockaddr *,
struct sshkey *, int *);
diff --git a/crypto/openssh/entropy.c b/crypto/openssh/entropy.c
index c178c00cf61c..a4088e43cdf8 100644
--- a/crypto/openssh/entropy.c
+++ b/crypto/openssh/entropy.c
@@ -24,22 +24,17 @@
#include "includes.h"
+#define RANDOM_SEED_SIZE 48
+
#ifdef WITH_OPENSSL
#include <sys/types.h>
-#include <sys/socket.h>
-#ifdef HAVE_SYS_UN_H
-# include <sys/un.h>
-#endif
-
-#include <netinet/in.h>
-#include <arpa/inet.h>
#include <errno.h>
#include <signal.h>
+#include <stdlib.h>
#include <string.h>
#include <unistd.h>
-#include <stddef.h> /* for offsetof */
#include <openssl/rand.h>
#include <openssl/crypto.h>
@@ -64,123 +59,6 @@
*/
#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 = signal(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:
- signal(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(struct sshbuf *m)
{
@@ -201,14 +79,15 @@ rexec_send_rng_seed(struct sshbuf *m)
void
rexec_recv_rng_seed(struct sshbuf *m)
{
- u_char *buf = NULL;
+ const u_char *buf = NULL;
size_t len = 0;
int r;
- if ((r = sshbuf_get_string_direct(m, &buf, &len)) != 0
+ if ((r = sshbuf_get_string_direct(m, &buf, &len)) != 0)
fatal("%s: buffer error: %s", __func__, ssh_err(r));
- debug3("rexec_recv_rng_seed: seeding rng with %u bytes", len);
+ debug3("rexec_recv_rng_seed: seeding rng with %lu bytes",
+ (unsigned long)len);
RAND_add(buf, len, len);
}
#endif /* OPENSSL_PRNG_ONLY */
@@ -216,35 +95,49 @@ rexec_recv_rng_seed(struct sshbuf *m)
void
seed_rng(void)
{
-#ifndef OPENSSL_PRNG_ONLY
unsigned char buf[RANDOM_SEED_SIZE];
-#endif
- if (!ssh_compatible_openssl(OPENSSL_VERSION_NUMBER, SSLeay()))
+
+ /* Initialise libcrypto */
+ ssh_libcrypto_init();
+
+ if (!ssh_compatible_openssl(OPENSSL_VERSION_NUMBER,
+ OpenSSL_version_num()))
fatal("OpenSSL version mismatch. Built against %lx, you "
- "have %lx", (u_long)OPENSSL_VERSION_NUMBER, SSLeay());
+ "have %lx", (u_long)OPENSSL_VERSION_NUMBER,
+ OpenSSL_version_num());
#ifndef OPENSSL_PRNG_ONLY
- if (RAND_status() == 1) {
+ if (RAND_status() == 1)
debug3("RNG is ready, skipping seeding");
- return;
+ else {
+ if (seed_from_prngd(buf, sizeof(buf)) == -1)
+ fatal("Could not obtain seed from PRNGd");
+ RAND_add(buf, sizeof(buf), sizeof(buf));
}
-
- 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");
+
+ /* Ensure arc4random() is primed */
+ arc4random_buf(buf, sizeof(buf));
+ explicit_bzero(buf, sizeof(buf));
}
#else /* WITH_OPENSSL */
-/* Handled in arc4random() */
+#include <stdlib.h>
+#include <string.h>
+
+/* Actual initialisation is handled in arc4random() */
void
seed_rng(void)
{
+ unsigned char buf[RANDOM_SEED_SIZE];
+
+ /* Ensure arc4random() is primed */
+ arc4random_buf(buf, sizeof(buf));
+ explicit_bzero(buf, sizeof(buf));
}
#endif /* WITH_OPENSSL */
diff --git a/crypto/openssh/fatal.c b/crypto/openssh/fatal.c
index 5e5aa3fe18df..16fbd320467a 100644
--- a/crypto/openssh/fatal.c
+++ b/crypto/openssh/fatal.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: fatal.c,v 1.7 2006/08/03 03:34:42 deraadt Exp $ */
+/* $OpenBSD: fatal.c,v 1.11 2020/10/19 08:07:08 djm Exp $ */
/*
* Copyright (c) 2002 Markus Friedl. All rights reserved.
*
@@ -34,12 +34,13 @@
/* Fatal messages. This function never returns. */
void
-fatal(const char *fmt,...)
+sshfatal(const char *file, const char *func, int line, int showfunc,
+ LogLevel level, const char *suffix, const char *fmt, ...)
{
va_list args;
va_start(args, fmt);
- do_log(SYSLOG_LEVEL_FATAL, fmt, args);
+ sshlogv(file, func, line, showfunc, level, suffix, fmt, args);
va_end(args);
cleanup_exit(255);
}
diff --git a/crypto/openssh/groupaccess.c b/crypto/openssh/groupaccess.c
index 9e4d25521647..80d3019152c2 100644
--- a/crypto/openssh/groupaccess.c
+++ b/crypto/openssh/groupaccess.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: groupaccess.c,v 1.16 2015/05/04 06:10:48 djm Exp $ */
+/* $OpenBSD: groupaccess.c,v 1.17 2019/03/06 22:14:23 dtucker Exp $ */
/*
* Copyright (c) 2001 Kevin Steves. All rights reserved.
*
@@ -103,7 +103,8 @@ ga_match_pattern_list(const char *group_pattern)
int i, found = 0;
for (i = 0; i < ngroups; i++) {
- switch (match_pattern_list(groups_byname[i], group_pattern, 0)) {
+ switch (match_usergroup_pattern_list(groups_byname[i],
+ group_pattern)) {
case -1:
return 0; /* Negated match wins */
case 0:
diff --git a/crypto/openssh/gss-genr.c b/crypto/openssh/gss-genr.c
index d56257b4a9f7..6852805171a8 100644
--- a/crypto/openssh/gss-genr.c
+++ b/crypto/openssh/gss-genr.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: gss-genr.c,v 1.26 2018/07/10 09:13:30 djm Exp $ */
+/* $OpenBSD: gss-genr.c,v 1.28 2021/01/27 10:05:28 djm Exp $ */
/*
* Copyright (c) 2001-2007 Simon Wilkinson. All rights reserved.
@@ -44,9 +44,6 @@
#include "ssh-gss.h"
-extern u_char *session_id2;
-extern u_int session_id2_len;
-
/* sshbuf_get for gss_buffer_desc */
int
ssh_gssapi_get_buffer_desc(struct sshbuf *b, gss_buffer_desc *g)
@@ -115,7 +112,7 @@ ssh_gssapi_last_error(Gssctxt *ctxt, OM_uint32 *major_status,
int r;
if ((b = sshbuf_new()) == NULL)
- fatal("%s: sshbuf_new failed", __func__);
+ fatal_f("sshbuf_new failed");
if (major_status != NULL)
*major_status = ctxt->major;
@@ -130,7 +127,7 @@ ssh_gssapi_last_error(Gssctxt *ctxt, OM_uint32 *major_status,
if ((r = sshbuf_put(b, msg.value, msg.length)) != 0 ||
(r = sshbuf_put_u8(b, '\n')) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "assemble GSS_CODE");
gss_release_buffer(&lmin, &msg);
} while (ctx != 0);
@@ -142,13 +139,13 @@ ssh_gssapi_last_error(Gssctxt *ctxt, OM_uint32 *major_status,
if ((r = sshbuf_put(b, msg.value, msg.length)) != 0 ||
(r = sshbuf_put_u8(b, '\n')) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "assemble MECH_CODE");
gss_release_buffer(&lmin, &msg);
} while (ctx != 0);
if ((r = sshbuf_put_u8(b, '\n')) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "assemble newline");
ret = xstrdup((const char *)sshbuf_ptr(b));
sshbuf_free(b);
return (ret);
@@ -259,17 +256,17 @@ ssh_gssapi_sign(Gssctxt *ctx, gss_buffer_t buffer, gss_buffer_t hash)
void
ssh_gssapi_buildmic(struct sshbuf *b, const char *user, const char *service,
- const char *context)
+ const char *context, const struct sshbuf *session_id)
{
int r;
sshbuf_reset(b);
- if ((r = sshbuf_put_string(b, session_id2, session_id2_len)) != 0 ||
+ if ((r = sshbuf_put_stringb(b, session_id)) != 0 ||
(r = sshbuf_put_u8(b, SSH2_MSG_USERAUTH_REQUEST)) != 0 ||
(r = sshbuf_put_cstring(b, user)) != 0 ||
(r = sshbuf_put_cstring(b, service)) != 0 ||
(r = sshbuf_put_cstring(b, context)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "assemble buildmic");
}
int
diff --git a/crypto/openssh/gss-serv.c b/crypto/openssh/gss-serv.c
index ab3a15f0f1dd..b5d4bb2d18b2 100644
--- a/crypto/openssh/gss-serv.c
+++ b/crypto/openssh/gss-serv.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: gss-serv.c,v 1.31 2018/07/09 21:37:55 markus Exp $ */
+/* $OpenBSD: gss-serv.c,v 1.32 2020/03/13 03:17:07 djm Exp $ */
/*
* Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved.
@@ -337,7 +337,7 @@ ssh_gssapi_storecreds(void)
debug("ssh_gssapi_storecreds: Not a GSSAPI mechanism");
}
-/* This allows GSSAPI methods to do things to the childs environment based
+/* This allows GSSAPI methods to do things to the child's environment based
* on the passed authentication process and credentials.
*/
/* As user */
diff --git a/crypto/openssh/hash.c b/crypto/openssh/hash.c
index 5875d41fafa7..b4f8f6c50d5e 100644
--- a/crypto/openssh/hash.c
+++ b/crypto/openssh/hash.c
@@ -1,27 +1,43 @@
-/* $OpenBSD: hash.c,v 1.4 2017/12/14 21:07:39 naddy Exp $ */
-
-/* $OpenBSD: hash.c,v 1.5 2018/01/13 00:24:09 naddy Exp $ */
+/* $OpenBSD: hash.c,v 1.6 2019/11/29 00:11:21 djm Exp $ */
/*
* Public domain. Author: Christian Weisgerber <naddy@openbsd.org>
* API compatible reimplementation of function from nacl
*/
+#include "includes.h"
+
#include "crypto_api.h"
#include <stdarg.h>
-#include "digest.h"
-#include "log.h"
-#include "ssherr.h"
+#ifdef WITH_OPENSSL
+#include <openssl/evp.h>
+
+int
+crypto_hash_sha512(unsigned char *out, const unsigned char *in,
+ unsigned long long inlen)
+{
+
+ if (!EVP_Digest(in, inlen, out, NULL, EVP_sha512(), NULL))
+ return -1;
+ return 0;
+}
+
+#else
+# ifdef HAVE_SHA2_H
+# include <sha2.h>
+# endif
int
crypto_hash_sha512(unsigned char *out, const unsigned char *in,
unsigned long long inlen)
{
- int r;
- if ((r = ssh_digest_memory(SSH_DIGEST_SHA512, in, inlen, out,
- crypto_hash_sha512_BYTES)) != 0)
- fatal("%s: %s", __func__, ssh_err(r));
+ SHA2_CTX ctx;
+
+ SHA512Init(&ctx);
+ SHA512Update(&ctx, in, inlen);
+ SHA512Final(out, &ctx);
return 0;
}
+#endif /* WITH_OPENSSL */
diff --git a/crypto/openssh/hmac.c b/crypto/openssh/hmac.c
index 1c879640cb3c..7b588019e74b 100644
--- a/crypto/openssh/hmac.c
+++ b/crypto/openssh/hmac.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: hmac.c,v 1.12 2015/03/24 20:03:44 markus Exp $ */
+/* $OpenBSD: hmac.c,v 1.14 2020/02/26 13:40:09 jsg Exp $ */
/*
* Copyright (c) 2014 Markus Friedl. All rights reserved.
*
@@ -18,6 +18,8 @@
#include "includes.h"
#include <sys/types.h>
+
+#include <stdlib.h>
#include <string.h>
#include "sshbuf.h"
@@ -129,8 +131,7 @@ ssh_hmac_free(struct ssh_hmac_ctx *ctx)
explicit_bzero(ctx->buf, ctx->buf_len);
free(ctx->buf);
}
- explicit_bzero(ctx, sizeof(*ctx));
- free(ctx);
+ freezero(ctx, sizeof(*ctx));
}
}
diff --git a/crypto/openssh/hostfile.c b/crypto/openssh/hostfile.c
index e1f826bddc9e..ce00cd713549 100644
--- a/crypto/openssh/hostfile.c
+++ b/crypto/openssh/hostfile.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: hostfile.c,v 1.73 2018/07/16 03:09:13 djm Exp $ */
+/* $OpenBSD: hostfile.c,v 1.91 2021/07/05 01:16:46 dtucker Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -49,7 +49,6 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#include <stdarg.h>
#include <unistd.h>
#include "xmalloc.h"
@@ -58,14 +57,11 @@
#include "hostfile.h"
#include "log.h"
#include "misc.h"
+#include "pathnames.h"
#include "ssherr.h"
#include "digest.h"
#include "hmac.h"
-
-struct hostkeys {
- struct hostkey_entry *entries;
- u_int num_entries;
-};
+#include "sshbuf.h"
/* XXX hmac is too easy to dictionary attack; use bcrypt? */
@@ -141,12 +137,12 @@ host_hash(const char *host, const char *name_from_hostfile, u_int src_len)
ssh_hmac_init(ctx, salt, len) < 0 ||
ssh_hmac_update(ctx, host, strlen(host)) < 0 ||
ssh_hmac_final(ctx, result, sizeof(result)))
- fatal("%s: ssh_hmac failed", __func__);
+ fatal_f("ssh_hmac failed");
ssh_hmac_free(ctx);
if (__b64_ntop(salt, len, uu_salt, sizeof(uu_salt)) == -1 ||
__b64_ntop(result, len, uu_result, sizeof(uu_result)) == -1)
- fatal("%s: __b64_ntop failed", __func__);
+ fatal_f("__b64_ntop failed");
snprintf(encoded, sizeof(encoded), "%s%s%c%s", HASH_MAGIC, uu_salt,
HASH_DELIM, uu_result);
@@ -163,13 +159,12 @@ int
hostfile_read_key(char **cpp, u_int *bitsp, struct sshkey *ret)
{
char *cp;
- int r;
/* Skip leading whitespace. */
for (cp = *cpp; *cp == ' ' || *cp == '\t'; cp++)
;
- if ((r = sshkey_read(ret, &cp)) != 0)
+ if (sshkey_read(ret, &cp) != 0)
return 0;
/* Skip trailing whitespace. */
@@ -247,7 +242,7 @@ record_hostkey(struct hostkey_foreach_line *l, void *_ctx)
return 0;
}
- debug3("%s: found %skey type %s in file %s:%lu", __func__,
+ debug3_f("found %skey type %s in file %s:%lu",
l->marker == MRK_NONE ? "" :
(l->marker == MRK_CA ? "ca " : "revoked "),
sshkey_type(l->key), l->path, l->linenum);
@@ -261,6 +256,7 @@ record_hostkey(struct hostkey_foreach_line *l, void *_ctx)
hostkeys->entries[hostkeys->num_entries].key = l->key;
l->key = NULL; /* steal it */
hostkeys->entries[hostkeys->num_entries].marker = l->marker;
+ hostkeys->entries[hostkeys->num_entries].note = l->note;
hostkeys->num_entries++;
ctx->num_loaded++;
@@ -268,7 +264,8 @@ record_hostkey(struct hostkey_foreach_line *l, void *_ctx)
}
void
-load_hostkeys(struct hostkeys *hostkeys, const char *host, const char *path)
+load_hostkeys_file(struct hostkeys *hostkeys, const char *host,
+ const char *path, FILE *f, u_int note)
{
int r;
struct load_callback_ctx ctx;
@@ -277,15 +274,28 @@ load_hostkeys(struct hostkeys *hostkeys, const char *host, const char *path)
ctx.num_loaded = 0;
ctx.hostkeys = hostkeys;
- if ((r = hostkeys_foreach(path, record_hostkey, &ctx, host, NULL,
- HKF_WANT_MATCH|HKF_WANT_PARSE_KEY)) != 0) {
+ if ((r = hostkeys_foreach_file(path, f, record_hostkey, &ctx, host,
+ NULL, HKF_WANT_MATCH|HKF_WANT_PARSE_KEY, note)) != 0) {
if (r != SSH_ERR_SYSTEM_ERROR && errno != ENOENT)
- debug("%s: hostkeys_foreach failed for %s: %s",
- __func__, path, ssh_err(r));
+ debug_fr(r, "hostkeys_foreach failed for %s", path);
}
if (ctx.num_loaded != 0)
- debug3("%s: loaded %lu keys from %s", __func__,
- ctx.num_loaded, host);
+ debug3_f("loaded %lu keys from %s", ctx.num_loaded, host);
+}
+
+void
+load_hostkeys(struct hostkeys *hostkeys, const char *host, const char *path,
+ u_int note)
+{
+ FILE *f;
+
+ if ((f = fopen(path, "r")) == NULL) {
+ debug_f("fopen %s: %s", path, strerror(errno));
+ return;
+ }
+
+ load_hostkeys_file(hostkeys, host, path, f, note);
+ fclose(f);
}
void
@@ -300,8 +310,7 @@ free_hostkeys(struct hostkeys *hostkeys)
explicit_bzero(hostkeys->entries + i, sizeof(*hostkeys->entries));
}
free(hostkeys->entries);
- explicit_bzero(hostkeys, sizeof(*hostkeys));
- free(hostkeys);
+ freezero(hostkeys, sizeof(*hostkeys));
}
static int
@@ -315,7 +324,7 @@ check_key_not_revoked(struct hostkeys *hostkeys, struct sshkey *k)
continue;
if (sshkey_equal_public(k, hostkeys->entries[i].key))
return -1;
- if (is_cert &&
+ if (is_cert && k != NULL &&
sshkey_equal_public(k->cert->signature_key,
hostkeys->entries[i].key))
return -1;
@@ -340,7 +349,7 @@ check_key_not_revoked(struct hostkeys *hostkeys, struct sshkey *k)
*/
static HostStatus
check_hostkeys_by_key_or_type(struct hostkeys *hostkeys,
- struct sshkey *k, int keytype, const struct hostkey_entry **found)
+ struct sshkey *k, int keytype, int nid, const struct hostkey_entry **found)
{
u_int i;
HostStatus end_return = HOST_NEW;
@@ -356,6 +365,10 @@ check_hostkeys_by_key_or_type(struct hostkeys *hostkeys,
if (k == NULL) {
if (hostkeys->entries[i].key->type != keytype)
continue;
+ if (nid != -1 &&
+ sshkey_type_plain(keytype) == KEY_ECDSA &&
+ hostkeys->entries[i].key->ecdsa_nid != nid)
+ continue;
end_return = HOST_FOUND;
if (found != NULL)
*found = hostkeys->entries + i;
@@ -378,7 +391,7 @@ check_hostkeys_by_key_or_type(struct hostkeys *hostkeys,
*found = hostkeys->entries + i;
break;
}
- /* A non-maching key exists */
+ /* A non-matching key exists */
end_return = HOST_CHANGED;
if (found != NULL)
*found = hostkeys->entries + i;
@@ -398,17 +411,29 @@ check_key_in_hostkeys(struct hostkeys *hostkeys, struct sshkey *key,
{
if (key == NULL)
fatal("no key to look up");
- return check_hostkeys_by_key_or_type(hostkeys, key, 0, found);
+ return check_hostkeys_by_key_or_type(hostkeys, key, 0, -1, found);
}
int
-lookup_key_in_hostkeys_by_type(struct hostkeys *hostkeys, int keytype,
+lookup_key_in_hostkeys_by_type(struct hostkeys *hostkeys, int keytype, int nid,
const struct hostkey_entry **found)
{
- return (check_hostkeys_by_key_or_type(hostkeys, NULL, keytype,
+ return (check_hostkeys_by_key_or_type(hostkeys, NULL, keytype, nid,
found) == HOST_FOUND);
}
+int
+lookup_marker_in_hostkeys(struct hostkeys *hostkeys, int want_marker)
+{
+ u_int i;
+
+ for (i = 0; i < hostkeys->num_entries; i++) {
+ if (hostkeys->entries[i].marker == (HostkeyMarker)want_marker)
+ return 1;
+ }
+ return 0;
+}
+
static int
write_host_entry(FILE *f, const char *host, const char *ip,
const struct sshkey *key, int store_hash)
@@ -421,7 +446,7 @@ write_host_entry(FILE *f, const char *host, const char *ip,
if (store_hash) {
if ((hashed_host = host_hash(lhost, NULL, 0)) == NULL) {
- error("%s: host_hash failed", __func__);
+ error_f("host_hash failed");
free(lhost);
return 0;
}
@@ -435,12 +460,53 @@ write_host_entry(FILE *f, const char *host, const char *ip,
if ((r = sshkey_write(key, f)) == 0)
success = 1;
else
- error("%s: sshkey_write failed: %s", __func__, ssh_err(r));
+ error_fr(r, "sshkey_write");
fputc('\n', f);
+ /* If hashing is enabled, the IP address needs to go on its own line */
+ if (success && store_hash && ip != NULL)
+ success = write_host_entry(f, ip, NULL, key, 1);
return success;
}
/*
+ * Create user ~/.ssh directory if it doesn't exist and we want to write to it.
+ * If notify is set, a message will be emitted if the directory is created.
+ */
+void
+hostfile_create_user_ssh_dir(const char *filename, int notify)
+{
+ char *dotsshdir = NULL, *p;
+ size_t len;
+ struct stat st;
+
+ if ((p = strrchr(filename, '/')) == NULL)
+ return;
+ len = p - filename;
+ dotsshdir = tilde_expand_filename("~/" _PATH_SSH_USER_DIR, getuid());
+ if (strlen(dotsshdir) > len || strncmp(filename, dotsshdir, len) != 0)
+ goto out; /* not ~/.ssh prefixed */
+ if (stat(dotsshdir, &st) == 0)
+ goto out; /* dir already exists */
+ else if (errno != ENOENT)
+ error("Could not stat %s: %s", dotsshdir, strerror(errno));
+ else {
+#ifdef WITH_SELINUX
+ ssh_selinux_setfscreatecon(dotsshdir);
+#endif
+ if (mkdir(dotsshdir, 0700) == -1)
+ error("Could not create directory '%.200s' (%s).",
+ dotsshdir, strerror(errno));
+ else if (notify)
+ logit("Created directory '%s'.", dotsshdir);
+#ifdef WITH_SELINUX
+ ssh_selinux_setfscreatecon(NULL);
+#endif
+ }
+ out:
+ free(dotsshdir);
+}
+
+/*
* Appends an entry to the host file. Returns false if the entry could not
* be appended.
*/
@@ -453,6 +519,7 @@ add_host_to_hostfile(const char *filename, const char *host,
if (key == NULL)
return 1; /* XXX ? */
+ hostfile_create_user_ssh_dir(filename, 0);
f = fopen(filename, "a");
if (!f)
return 0;
@@ -464,8 +531,8 @@ add_host_to_hostfile(const char *filename, const char *host,
struct host_delete_ctx {
FILE *out;
int quiet;
- const char *host;
- int *skip_keys; /* XXX split for host/ip? might want to ensure both */
+ const char *host, *ip;
+ u_int *match_keys; /* mask of HKF_MATCH_* for this key */
struct sshkey * const *keys;
size_t nkeys;
int modified;
@@ -478,26 +545,21 @@ host_delete(struct hostkey_foreach_line *l, void *_ctx)
int loglevel = ctx->quiet ? SYSLOG_LEVEL_DEBUG1 : SYSLOG_LEVEL_VERBOSE;
size_t i;
- if (l->status == HKF_STATUS_MATCHED) {
- if (l->marker != MRK_NONE) {
- /* Don't remove CA and revocation lines */
- fprintf(ctx->out, "%s\n", l->line);
- return 0;
- }
-
+ /* Don't remove CA and revocation lines */
+ if (l->status == HKF_STATUS_MATCHED && l->marker == MRK_NONE) {
/*
* If this line contains one of the keys that we will be
* adding later, then don't change it and mark the key for
* skipping.
*/
for (i = 0; i < ctx->nkeys; i++) {
- if (sshkey_equal(ctx->keys[i], l->key)) {
- ctx->skip_keys[i] = 1;
- fprintf(ctx->out, "%s\n", l->line);
- debug3("%s: %s key already at %s:%ld", __func__,
- sshkey_type(l->key), l->path, l->linenum);
- return 0;
- }
+ if (!sshkey_equal(ctx->keys[i], l->key))
+ continue;
+ ctx->match_keys[i] |= l->match;
+ fprintf(ctx->out, "%s\n", l->line);
+ debug3_f("%s key already at %s:%ld",
+ sshkey_type(l->key), l->path, l->linenum);
+ return 0;
}
/*
@@ -528,15 +590,19 @@ hostfile_replace_entries(const char *filename, const char *host, const char *ip,
int loglevel = quiet ? SYSLOG_LEVEL_DEBUG1 : SYSLOG_LEVEL_VERBOSE;
struct host_delete_ctx ctx;
char *fp, *temp = NULL, *back = NULL;
+ const char *what;
mode_t omask;
size_t i;
+ u_int want;
omask = umask(077);
memset(&ctx, 0, sizeof(ctx));
ctx.host = host;
+ ctx.ip = ip;
ctx.quiet = quiet;
- if ((ctx.skip_keys = calloc(nkeys, sizeof(*ctx.skip_keys))) == NULL)
+
+ if ((ctx.match_keys = calloc(nkeys, sizeof(*ctx.match_keys))) == NULL)
return SSH_ERR_ALLOC_FAIL;
ctx.keys = keys;
ctx.nkeys = nkeys;
@@ -545,50 +611,73 @@ hostfile_replace_entries(const char *filename, const char *host, const char *ip,
/*
* Prepare temporary file for in-place deletion.
*/
- if ((r = asprintf(&temp, "%s.XXXXXXXXXXX", filename)) < 0 ||
- (r = asprintf(&back, "%s.old", filename)) < 0) {
+ if ((r = asprintf(&temp, "%s.XXXXXXXXXXX", filename)) == -1 ||
+ (r = asprintf(&back, "%s.old", filename)) == -1) {
r = SSH_ERR_ALLOC_FAIL;
goto fail;
}
if ((fd = mkstemp(temp)) == -1) {
oerrno = errno;
- error("%s: mkstemp: %s", __func__, strerror(oerrno));
+ error_f("mkstemp: %s", strerror(oerrno));
r = SSH_ERR_SYSTEM_ERROR;
goto fail;
}
if ((ctx.out = fdopen(fd, "w")) == NULL) {
oerrno = errno;
close(fd);
- error("%s: fdopen: %s", __func__, strerror(oerrno));
+ error_f("fdopen: %s", strerror(oerrno));
r = SSH_ERR_SYSTEM_ERROR;
goto fail;
}
- /* Remove all entries for the specified host from the file */
+ /* Remove stale/mismatching entries for the specified host */
if ((r = hostkeys_foreach(filename, host_delete, &ctx, host, ip,
- HKF_WANT_PARSE_KEY)) != 0) {
- error("%s: hostkeys_foreach failed: %s", __func__, ssh_err(r));
+ HKF_WANT_PARSE_KEY, 0)) != 0) {
+ oerrno = errno;
+ error_fr(r, "hostkeys_foreach");
goto fail;
}
- /* Add the requested keys */
+ /* Re-add the requested keys */
+ want = HKF_MATCH_HOST | (ip == NULL ? 0 : HKF_MATCH_IP);
for (i = 0; i < nkeys; i++) {
- if (ctx.skip_keys[i])
+ if ((want & ctx.match_keys[i]) == want)
continue;
if ((fp = sshkey_fingerprint(keys[i], hash_alg,
SSH_FP_DEFAULT)) == NULL) {
r = SSH_ERR_ALLOC_FAIL;
goto fail;
}
- do_log2(loglevel, "%s%sAdding new key for %s to %s: %s %s",
- quiet ? __func__ : "", quiet ? ": " : "", host, filename,
+ /* write host/ip */
+ what = "";
+ if (ctx.match_keys[i] == 0) {
+ what = "Adding new key";
+ if (!write_host_entry(ctx.out, host, ip,
+ keys[i], store_hash)) {
+ r = SSH_ERR_INTERNAL_ERROR;
+ goto fail;
+ }
+ } else if ((want & ~ctx.match_keys[i]) == HKF_MATCH_HOST) {
+ what = "Fixing match (hostname)";
+ if (!write_host_entry(ctx.out, host, NULL,
+ keys[i], store_hash)) {
+ r = SSH_ERR_INTERNAL_ERROR;
+ goto fail;
+ }
+ } else if ((want & ~ctx.match_keys[i]) == HKF_MATCH_IP) {
+ what = "Fixing match (address)";
+ if (!write_host_entry(ctx.out, ip, NULL,
+ keys[i], store_hash)) {
+ r = SSH_ERR_INTERNAL_ERROR;
+ goto fail;
+ }
+ }
+ do_log2(loglevel, "%s%s%s for %s%s%s to %s: %s %s",
+ quiet ? __func__ : "", quiet ? ": " : "", what,
+ host, ip == NULL ? "" : ",", ip == NULL ? "" : ip, filename,
sshkey_ssh_name(keys[i]), fp);
free(fp);
- if (!write_host_entry(ctx.out, host, ip, keys[i], store_hash)) {
- r = SSH_ERR_INTERNAL_ERROR;
- goto fail;
- }
ctx.modified = 1;
}
fclose(ctx.out);
@@ -598,30 +687,28 @@ hostfile_replace_entries(const char *filename, const char *host, const char *ip,
/* Backup the original file and replace it with the temporary */
if (unlink(back) == -1 && errno != ENOENT) {
oerrno = errno;
- error("%s: unlink %.100s: %s", __func__,
- back, strerror(errno));
+ error_f("unlink %.100s: %s", back, strerror(errno));
r = SSH_ERR_SYSTEM_ERROR;
goto fail;
}
if (link(filename, back) == -1) {
oerrno = errno;
- error("%s: link %.100s to %.100s: %s", __func__,
- filename, back, strerror(errno));
+ error_f("link %.100s to %.100s: %s", filename,
+ back, strerror(errno));
r = SSH_ERR_SYSTEM_ERROR;
goto fail;
}
if (rename(temp, filename) == -1) {
oerrno = errno;
- error("%s: rename \"%s\" to \"%s\": %s", __func__,
- temp, filename, strerror(errno));
+ error_f("rename \"%s\" to \"%s\": %s", temp,
+ filename, strerror(errno));
r = SSH_ERR_SYSTEM_ERROR;
goto fail;
}
} else {
/* No changes made; just delete the temporary file */
if (unlink(temp) != 0)
- error("%s: unlink \"%s\": %s", __func__,
- temp, strerror(errno));
+ error_f("unlink \"%s\": %s", temp, strerror(errno));
}
/* success */
@@ -633,7 +720,7 @@ hostfile_replace_entries(const char *filename, const char *host, const char *ip,
free(back);
if (ctx.out != NULL)
fclose(ctx.out);
- free(ctx.skip_keys);
+ free(ctx.match_keys);
umask(omask);
if (r == SSH_ERR_SYSTEM_ERROR)
errno = oerrno;
@@ -659,10 +746,9 @@ match_maybe_hashed(const char *host, const char *names, int *was_hashed)
}
int
-hostkeys_foreach(const char *path, hostkeys_foreach_fn *callback, void *ctx,
- const char *host, const char *ip, u_int options)
+hostkeys_foreach_file(const char *path, FILE *f, hostkeys_foreach_fn *callback,
+ void *ctx, const char *host, const char *ip, u_int options, u_int note)
{
- FILE *f;
char *line = NULL, ktype[128];
u_long linenum = 0;
char *cp, *cp2;
@@ -675,10 +761,7 @@ hostkeys_foreach(const char *path, hostkeys_foreach_fn *callback, void *ctx,
memset(&lineinfo, 0, sizeof(lineinfo));
if (host == NULL && (options & HKF_WANT_MATCH) != 0)
return SSH_ERR_INVALID_ARGUMENT;
- if ((f = fopen(path, "r")) == NULL)
- return SSH_ERR_SYSTEM_ERROR;
- debug3("%s: reading file \"%s\"", __func__, path);
while (getline(&line, &linesize, f) != -1) {
linenum++;
line[strcspn(line, "\n")] = '\0';
@@ -692,6 +775,7 @@ hostkeys_foreach(const char *path, hostkeys_foreach_fn *callback, void *ctx,
lineinfo.marker = MRK_NONE;
lineinfo.status = HKF_STATUS_OK;
lineinfo.keytype = KEY_UNSPEC;
+ lineinfo.note = note;
/* Skip any leading whitespace, comments and empty lines. */
for (cp = line; *cp == ' ' || *cp == '\t'; cp++)
@@ -706,8 +790,7 @@ hostkeys_foreach(const char *path, hostkeys_foreach_fn *callback, void *ctx,
}
if ((lineinfo.marker = check_markers(&cp)) == MRK_ERROR) {
- verbose("%s: invalid marker at %s:%lu",
- __func__, path, linenum);
+ verbose_f("invalid marker at %s:%lu", path, linenum);
if ((options & HKF_WANT_MATCH) == 0)
goto bad;
continue;
@@ -723,8 +806,8 @@ hostkeys_foreach(const char *path, hostkeys_foreach_fn *callback, void *ctx,
if (host != NULL) {
if ((s = match_maybe_hashed(host, lineinfo.hosts,
&hashed)) == -1) {
- debug2("%s: %s:%ld: bad host hash \"%.32s\"",
- __func__, path, linenum, lineinfo.hosts);
+ debug2_f("%s:%ld: bad host hash \"%.32s\"",
+ path, linenum, lineinfo.hosts);
goto bad;
}
if (s == 1) {
@@ -736,9 +819,9 @@ hostkeys_foreach(const char *path, hostkeys_foreach_fn *callback, void *ctx,
if (ip != NULL) {
if ((s = match_maybe_hashed(ip, lineinfo.hosts,
&hashed)) == -1) {
- debug2("%s: %s:%ld: bad ip hash "
- "\"%.32s\"", __func__, path,
- linenum, lineinfo.hosts);
+ debug2_f("%s:%ld: bad ip hash "
+ "\"%.32s\"", path, linenum,
+ lineinfo.hosts);
goto bad;
}
if (s == 1) {
@@ -773,7 +856,7 @@ hostkeys_foreach(const char *path, hostkeys_foreach_fn *callback, void *ctx,
* lines.
*/
if ((lineinfo.key = sshkey_new(KEY_UNSPEC)) == NULL) {
- error("%s: sshkey_new failed", __func__);
+ error_f("sshkey_new failed");
r = SSH_ERR_ALLOC_FAIL;
break;
}
@@ -829,6 +912,24 @@ hostkeys_foreach(const char *path, hostkeys_foreach_fn *callback, void *ctx,
sshkey_free(lineinfo.key);
free(lineinfo.line);
free(line);
+ return r;
+}
+
+int
+hostkeys_foreach(const char *path, hostkeys_foreach_fn *callback, void *ctx,
+ const char *host, const char *ip, u_int options, u_int note)
+{
+ FILE *f;
+ int r, oerrno;
+
+ if ((f = fopen(path, "r")) == NULL)
+ return SSH_ERR_SYSTEM_ERROR;
+
+ debug3_f("reading file \"%s\"", path);
+ r = hostkeys_foreach_file(path, f, callback, ctx, host, ip,
+ options, note);
+ oerrno = errno;
fclose(f);
+ errno = oerrno;
return r;
}
diff --git a/crypto/openssh/hostfile.h b/crypto/openssh/hostfile.h
index bd2104373f82..a24a4e329059 100644
--- a/crypto/openssh/hostfile.h
+++ b/crypto/openssh/hostfile.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: hostfile.h,v 1.24 2015/02/16 22:08:57 djm Exp $ */
+/* $OpenBSD: hostfile.h,v 1.29 2021/01/26 00:51:30 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -28,17 +28,25 @@ struct hostkey_entry {
u_long line;
struct sshkey *key;
HostkeyMarker marker;
+ u_int note; /* caller-specific note/flag */
+};
+struct hostkeys {
+ struct hostkey_entry *entries;
+ u_int num_entries;
};
-struct hostkeys;
struct hostkeys *init_hostkeys(void);
-void load_hostkeys(struct hostkeys *, const char *, const char *);
+void load_hostkeys(struct hostkeys *, const char *,
+ const char *, u_int);
+void load_hostkeys_file(struct hostkeys *, const char *,
+ const char *, FILE *, u_int note);
void free_hostkeys(struct hostkeys *);
HostStatus check_key_in_hostkeys(struct hostkeys *, struct sshkey *,
const struct hostkey_entry **);
-int lookup_key_in_hostkeys_by_type(struct hostkeys *, int,
+int lookup_key_in_hostkeys_by_type(struct hostkeys *, int, int,
const struct hostkey_entry **);
+int lookup_marker_in_hostkeys(struct hostkeys *, int);
int hostfile_read_key(char **, u_int *, struct sshkey *);
int add_host_to_hostfile(const char *, const char *,
@@ -92,6 +100,7 @@ struct hostkey_foreach_line {
int keytype; /* Type of key; KEY_UNSPEC for invalid/comment lines */
struct sshkey *key; /* Key, if parsed ok and HKF_WANT_MATCH_HOST set */
const char *comment; /* Any comment following the key */
+ u_int note; /* caller-specified note copied from arguments */
};
/*
@@ -102,7 +111,13 @@ struct hostkey_foreach_line {
typedef int hostkeys_foreach_fn(struct hostkey_foreach_line *l, void *ctx);
/* Iterate over a hostkeys file */
-int hostkeys_foreach(const char *path, hostkeys_foreach_fn *callback, void *ctx,
- const char *host, const char *ip, u_int options);
+int hostkeys_foreach(const char *path,
+ hostkeys_foreach_fn *callback, void *ctx,
+ const char *host, const char *ip, u_int options, u_int note);
+int hostkeys_foreach_file(const char *path, FILE *f,
+ hostkeys_foreach_fn *callback, void *ctx,
+ const char *host, const char *ip, u_int options, u_int note);
+
+void hostfile_create_user_ssh_dir(const char *, int);
#endif
diff --git a/crypto/openssh/int32_minmax.inc b/crypto/openssh/int32_minmax.inc
new file mode 100644
index 000000000000..e69de29bb2d1
--- /dev/null
+++ b/crypto/openssh/int32_minmax.inc
diff --git a/crypto/openssh/kex.c b/crypto/openssh/kex.c
index 25f9f66f69af..709a0ec63aa0 100644
--- a/crypto/openssh/kex.c
+++ b/crypto/openssh/kex.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kex.c,v 1.141 2018/07/09 13:37:10 sf Exp $ */
+/* $OpenBSD: kex.c,v 1.168 2021/04/03 06:18:40 djm Exp $ */
/*
* Copyright (c) 2000, 2001 Markus Friedl. All rights reserved.
*
@@ -25,19 +25,27 @@
#include "includes.h"
-
+#include <sys/types.h>
+#include <errno.h>
#include <signal.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <unistd.h>
+#ifdef HAVE_POLL_H
+#include <poll.h>
+#endif
#ifdef WITH_OPENSSL
#include <openssl/crypto.h>
#include <openssl/dh.h>
#endif
+#include "ssh.h"
#include "ssh2.h"
+#include "atomicio.h"
+#include "version.h"
#include "packet.h"
#include "compat.h"
#include "cipher.h"
@@ -102,8 +110,12 @@ static const struct kexalg kexalgs[] = {
#if defined(HAVE_EVP_SHA256) || !defined(WITH_OPENSSL)
{ KEX_CURVE25519_SHA256, KEX_C25519_SHA256, 0, SSH_DIGEST_SHA256 },
{ KEX_CURVE25519_SHA256_OLD, KEX_C25519_SHA256, 0, SSH_DIGEST_SHA256 },
+#ifdef USE_SNTRUP761X25519
+ { KEX_SNTRUP761X25519_SHA512, KEX_KEM_SNTRUP761X25519_SHA512, 0,
+ SSH_DIGEST_SHA512 },
+#endif
#endif /* HAVE_EVP_SHA256 || !WITH_OPENSSL */
- { NULL, -1, -1, -1},
+ { NULL, 0, -1, -1},
};
char *
@@ -205,8 +217,9 @@ kex_names_cat(const char *a, const char *b)
/*
* Assemble a list of algorithms from a default list and a string from a
* configuration file. The user-provided string may begin with '+' to
- * indicate that it should be appended to the default or '-' that the
- * specified names should be removed.
+ * indicate that it should be appended to the default, '-' that the
+ * specified names should be removed, or '^' that they should be placed
+ * at the head.
*/
int
kex_assemble_names(char **listp, const char *def, const char *all)
@@ -215,7 +228,10 @@ kex_assemble_names(char **listp, const char *def, const char *all)
char *list = NULL, *ret = NULL, *matching = NULL, *opatterns = NULL;
int r = SSH_ERR_INTERNAL_ERROR;
- if (listp == NULL || *listp == NULL || **listp == '\0') {
+ if (listp == NULL || def == NULL || all == NULL)
+ return SSH_ERR_INVALID_ARGUMENT;
+
+ if (*listp == NULL || **listp == '\0') {
if ((*listp = strdup(def)) == NULL)
return SSH_ERR_ALLOC_FAIL;
return 0;
@@ -233,13 +249,21 @@ kex_assemble_names(char **listp, const char *def, const char *all)
list = tmp;
} else if (*list == '-') {
/* Remove names from default list */
- if ((*listp = match_filter_blacklist(def, list + 1)) == NULL) {
+ if ((*listp = match_filter_denylist(def, list + 1)) == NULL) {
r = SSH_ERR_ALLOC_FAIL;
goto fail;
}
free(list);
/* filtering has already been done */
return 0;
+ } else if (*list == '^') {
+ /* Place names at head of default list */
+ if ((tmp = kex_names_cat(list + 1, def)) == NULL) {
+ r = SSH_ERR_ALLOC_FAIL;
+ goto fail;
+ }
+ free(list);
+ list = tmp;
} else {
/* Explicit list, overrides default - just use "list" as is */
}
@@ -262,7 +286,7 @@ kex_assemble_names(char **listp, const char *def, const char *all)
goto fail;
}
free(matching);
- if ((matching = match_filter_whitelist(all, cp)) == NULL) {
+ if ((matching = match_filter_allowlist(all, cp)) == NULL) {
r = SSH_ERR_ALLOC_FAIL;
goto fail;
}
@@ -337,18 +361,24 @@ kex_buf2prop(struct sshbuf *raw, int *first_kex_follows, char ***propp)
r = SSH_ERR_ALLOC_FAIL;
goto out;
}
- if ((r = sshbuf_consume(b, KEX_COOKIE_LEN)) != 0) /* skip cookie */
+ if ((r = sshbuf_consume(b, KEX_COOKIE_LEN)) != 0) { /* skip cookie */
+ error_fr(r, "consume cookie");
goto out;
+ }
/* extract kex init proposal strings */
for (i = 0; i < PROPOSAL_MAX; i++) {
- if ((r = sshbuf_get_cstring(b, &(proposal[i]), NULL)) != 0)
+ if ((r = sshbuf_get_cstring(b, &(proposal[i]), NULL)) != 0) {
+ error_fr(r, "parse proposal %u", i);
goto out;
+ }
debug2("%s: %s", proposal_names[i], proposal[i]);
}
/* first kex follows / reserved */
if ((r = sshbuf_get_u8(b, &v)) != 0 || /* first_kex_follows */
- (r = sshbuf_get_u32(b, &i)) != 0) /* reserved */
+ (r = sshbuf_get_u32(b, &i)) != 0) { /* reserved */
+ error_fr(r, "parse");
goto out;
+ }
if (first_kex_follows != NULL)
*first_kex_follows = v;
debug2("first_kex_follows %d ", v);
@@ -375,7 +405,7 @@ kex_prop_free(char **proposal)
}
/* ARGSUSED */
-static int
+int
kex_protocol_error(int type, u_int32_t seq, struct ssh *ssh)
{
int r;
@@ -401,6 +431,7 @@ kex_send_ext_info(struct ssh *ssh)
int r;
char *algs;
+ debug("Sending SSH2_MSG_EXT_INFO");
if ((algs = sshkey_alg_list(0, 1, 1, ',')) == NULL)
return SSH_ERR_ALLOC_FAIL;
/* XXX filter algs list by allowed pubkey/hostbased types */
@@ -408,8 +439,10 @@ kex_send_ext_info(struct ssh *ssh)
(r = sshpkt_put_u32(ssh, 1)) != 0 ||
(r = sshpkt_put_cstring(ssh, "server-sig-algs")) != 0 ||
(r = sshpkt_put_cstring(ssh, algs)) != 0 ||
- (r = sshpkt_send(ssh)) != 0)
+ (r = sshpkt_send(ssh)) != 0) {
+ error_fr(r, "compose");
goto out;
+ }
/* success */
r = 0;
out:
@@ -427,11 +460,11 @@ kex_send_newkeys(struct ssh *ssh)
(r = sshpkt_send(ssh)) != 0)
return r;
debug("SSH2_MSG_NEWKEYS sent");
- debug("expecting SSH2_MSG_NEWKEYS");
ssh_dispatch_set(ssh, SSH2_MSG_NEWKEYS, &kex_input_newkeys);
- if (ssh->kex->ext_info_c)
+ if (ssh->kex->ext_info_c && (ssh->kex->flags & KEX_INITIAL) != 0)
if ((r = kex_send_ext_info(ssh)) != 0)
return r;
+ debug("expecting SSH2_MSG_NEWKEYS");
return 0;
}
@@ -459,14 +492,14 @@ kex_input_ext_info(int type, u_int32_t seq, struct ssh *ssh)
if (strcmp(name, "server-sig-algs") == 0) {
/* Ensure no \0 lurking in value */
if (memchr(val, '\0', vlen) != NULL) {
- error("%s: nul byte in %s", __func__, name);
+ error_f("nul byte in %s", name);
return SSH_ERR_INVALID_FORMAT;
}
- debug("%s: %s=<%s>", __func__, name, val);
+ debug_f("%s=<%s>", name, val);
kex->server_sig_algs = val;
val = NULL;
} else
- debug("%s: %s (unrecognised)", __func__, name);
+ debug_f("%s (unrecognised)", name);
free(name);
free(val);
}
@@ -487,6 +520,7 @@ kex_input_newkeys(int type, u_int32_t seq, struct ssh *ssh)
if ((r = ssh_set_newkeys(ssh, MODE_IN)) != 0)
return r;
kex->done = 1;
+ kex->flags &= ~KEX_INITIAL;
sshbuf_reset(kex->peer);
/* sshbuf_reset(kex->my); */
kex->flags &= ~KEX_INIT_SENT;
@@ -502,23 +536,32 @@ kex_send_kexinit(struct ssh *ssh)
struct kex *kex = ssh->kex;
int r;
- if (kex == NULL)
+ if (kex == NULL) {
+ error_f("no kex");
return SSH_ERR_INTERNAL_ERROR;
+ }
if (kex->flags & KEX_INIT_SENT)
return 0;
kex->done = 0;
/* generate a random cookie */
- if (sshbuf_len(kex->my) < KEX_COOKIE_LEN)
+ if (sshbuf_len(kex->my) < KEX_COOKIE_LEN) {
+ error_f("bad kex length: %zu < %d",
+ sshbuf_len(kex->my), KEX_COOKIE_LEN);
return SSH_ERR_INVALID_FORMAT;
- if ((cookie = sshbuf_mutable_ptr(kex->my)) == NULL)
+ }
+ if ((cookie = sshbuf_mutable_ptr(kex->my)) == NULL) {
+ error_f("buffer error");
return SSH_ERR_INTERNAL_ERROR;
+ }
arc4random_buf(cookie, KEX_COOKIE_LEN);
if ((r = sshpkt_start(ssh, SSH2_MSG_KEXINIT)) != 0 ||
(r = sshpkt_putb(ssh, kex->my)) != 0 ||
- (r = sshpkt_send(ssh)) != 0)
+ (r = sshpkt_send(ssh)) != 0) {
+ error_fr(r, "compose reply");
return r;
+ }
debug("SSH2_MSG_KEXINIT sent");
kex->flags |= KEX_INIT_SENT;
return 0;
@@ -535,21 +578,28 @@ kex_input_kexinit(int type, u_int32_t seq, struct ssh *ssh)
int r;
debug("SSH2_MSG_KEXINIT received");
- if (kex == NULL)
- return SSH_ERR_INVALID_ARGUMENT;
-
+ if (kex == NULL) {
+ error_f("no kex");
+ return SSH_ERR_INTERNAL_ERROR;
+ }
ssh_dispatch_set(ssh, SSH2_MSG_KEXINIT, NULL);
ptr = sshpkt_ptr(ssh, &dlen);
if ((r = sshbuf_put(kex->peer, ptr, dlen)) != 0)
return r;
/* discard packet */
- for (i = 0; i < KEX_COOKIE_LEN; i++)
- if ((r = sshpkt_get_u8(ssh, NULL)) != 0)
+ for (i = 0; i < KEX_COOKIE_LEN; i++) {
+ if ((r = sshpkt_get_u8(ssh, NULL)) != 0) {
+ error_fr(r, "discard cookie");
return r;
- for (i = 0; i < PROPOSAL_MAX; i++)
- if ((r = sshpkt_get_string(ssh, NULL, NULL)) != 0)
+ }
+ }
+ for (i = 0; i < PROPOSAL_MAX; i++) {
+ if ((r = sshpkt_get_string(ssh, NULL, NULL)) != 0) {
+ error_fr(r, "discard proposal");
return r;
+ }
+ }
/*
* XXX RFC4253 sec 7: "each side MAY guess" - currently no supported
* KEX method has the server move first, but a server might be using
@@ -574,34 +624,25 @@ kex_input_kexinit(int type, u_int32_t seq, struct ssh *ssh)
if (kex->kex_type < KEX_MAX && kex->kex[kex->kex_type] != NULL)
return (kex->kex[kex->kex_type])(ssh);
+ error_f("unknown kex type %u", kex->kex_type);
return SSH_ERR_INTERNAL_ERROR;
}
-int
-kex_new(struct ssh *ssh, char *proposal[PROPOSAL_MAX], struct kex **kexp)
+struct kex *
+kex_new(void)
{
struct kex *kex;
- int r;
- *kexp = NULL;
- if ((kex = calloc(1, sizeof(*kex))) == NULL)
- return SSH_ERR_ALLOC_FAIL;
- if ((kex->peer = sshbuf_new()) == NULL ||
- (kex->my = sshbuf_new()) == NULL) {
- r = SSH_ERR_ALLOC_FAIL;
- goto out;
- }
- if ((r = kex_prop2buf(kex->my, proposal)) != 0)
- goto out;
- kex->done = 0;
- kex_reset_dispatch(ssh);
- ssh_dispatch_set(ssh, SSH2_MSG_KEXINIT, &kex_input_kexinit);
- r = 0;
- *kexp = kex;
- out:
- if (r != 0)
+ if ((kex = calloc(1, sizeof(*kex))) == NULL ||
+ (kex->peer = sshbuf_new()) == NULL ||
+ (kex->my = sshbuf_new()) == NULL ||
+ (kex->client_version = sshbuf_new()) == NULL ||
+ (kex->server_version = sshbuf_new()) == NULL ||
+ (kex->session_id = sshbuf_new()) == NULL) {
kex_free(kex);
- return r;
+ return NULL;
+ }
+ return kex;
}
void
@@ -631,8 +672,7 @@ kex_free_newkeys(struct newkeys *newkeys)
}
free(newkeys->mac.name);
explicit_bzero(&newkeys->mac, sizeof(newkeys->mac));
- explicit_bzero(newkeys, sizeof(*newkeys));
- free(newkeys);
+ freezero(newkeys, sizeof(*newkeys));
}
void
@@ -640,6 +680,9 @@ kex_free(struct kex *kex)
{
u_int mode;
+ if (kex == NULL)
+ return;
+
#ifdef WITH_OPENSSL
DH_free(kex->dh);
#ifdef OPENSSL_HAS_ECC
@@ -652,9 +695,10 @@ kex_free(struct kex *kex)
}
sshbuf_free(kex->peer);
sshbuf_free(kex->my);
- free(kex->session_id);
- free(kex->client_version_string);
- free(kex->server_version_string);
+ sshbuf_free(kex->client_version);
+ sshbuf_free(kex->server_version);
+ sshbuf_free(kex->client_pub);
+ sshbuf_free(kex->session_id);
free(kex->failed_choice);
free(kex->hostkey_alg);
free(kex->name);
@@ -662,11 +706,24 @@ kex_free(struct kex *kex)
}
int
+kex_ready(struct ssh *ssh, char *proposal[PROPOSAL_MAX])
+{
+ int r;
+
+ if ((r = kex_prop2buf(ssh->kex->my, proposal)) != 0)
+ return r;
+ ssh->kex->flags = KEX_INITIAL;
+ kex_reset_dispatch(ssh);
+ ssh_dispatch_set(ssh, SSH2_MSG_KEXINIT, &kex_input_kexinit);
+ return 0;
+}
+
+int
kex_setup(struct ssh *ssh, char *proposal[PROPOSAL_MAX])
{
int r;
- if ((r = kex_new(ssh, proposal, &ssh->kex)) != 0)
+ if ((r = kex_ready(ssh, proposal)) != 0)
return r;
if ((r = kex_send_kexinit(ssh)) != 0) { /* we start */
kex_free(ssh->kex);
@@ -684,11 +741,11 @@ int
kex_start_rekex(struct ssh *ssh)
{
if (ssh->kex == NULL) {
- error("%s: no kex", __func__);
+ error_f("no kex");
return SSH_ERR_INTERNAL_ERROR;
}
if (ssh->kex->done == 0) {
- error("%s: requested twice", __func__);
+ error_f("requested twice");
return SSH_ERR_INTERNAL_ERROR;
}
ssh->kex->done = 0;
@@ -703,6 +760,7 @@ choose_enc(struct sshenc *enc, char *client, char *server)
if (name == NULL)
return SSH_ERR_NO_CIPHER_ALG_MATCH;
if ((enc->cipher = cipher_by_name(name)) == NULL) {
+ error_f("unsupported cipher %s", name);
free(name);
return SSH_ERR_INTERNAL_ERROR;
}
@@ -724,6 +782,7 @@ choose_mac(struct ssh *ssh, struct sshmac *mac, char *client, char *server)
if (name == NULL)
return SSH_ERR_NO_MAC_ALG_MATCH;
if (mac_setup(mac, name) < 0) {
+ error_f("unsupported MAC %s", name);
free(name);
return SSH_ERR_INTERNAL_ERROR;
}
@@ -740,13 +799,17 @@ choose_comp(struct sshcomp *comp, char *client, char *server)
if (name == NULL)
return SSH_ERR_NO_COMPRESS_ALG_MATCH;
+#ifdef WITH_ZLIB
if (strcmp(name, "zlib@openssh.com") == 0) {
comp->type = COMP_DELAYED;
} else if (strcmp(name, "zlib") == 0) {
comp->type = COMP_ZLIB;
- } else if (strcmp(name, "none") == 0) {
+ } else
+#endif /* WITH_ZLIB */
+ if (strcmp(name, "none") == 0) {
comp->type = COMP_NONE;
} else {
+ error_f("unsupported compression scheme %s", name);
free(name);
return SSH_ERR_INTERNAL_ERROR;
}
@@ -764,8 +827,10 @@ choose_kex(struct kex *k, char *client, char *server)
debug("kex: algorithm: %s", k->name ? k->name : "(no match)");
if (k->name == NULL)
return SSH_ERR_NO_KEX_ALG_MATCH;
- if ((kexalg = kex_alg_by_name(k->name)) == NULL)
+ if ((kexalg = kex_alg_by_name(k->name)) == NULL) {
+ error_f("unsupported KEX method %s", k->name);
return SSH_ERR_INTERNAL_ERROR;
+ }
k->kex_type = kexalg->type;
k->hash_alg = kexalg->hash_alg;
k->ec_nid = kexalg->ec_nid;
@@ -775,6 +840,7 @@ choose_kex(struct kex *k, char *client, char *server)
static int
choose_hostkeyalg(struct kex *k, char *client, char *server)
{
+ free(k->hostkey_alg);
k->hostkey_alg = match_list(client, server, NULL);
debug("kex: host key algorithm: %s",
@@ -782,8 +848,10 @@ choose_hostkeyalg(struct kex *k, char *client, char *server)
if (k->hostkey_alg == NULL)
return SSH_ERR_NO_HOSTKEY_ALG_MATCH;
k->hostkey_type = sshkey_type_from_name(k->hostkey_alg);
- if (k->hostkey_type == KEY_UNSPEC)
+ if (k->hostkey_type == KEY_UNSPEC) {
+ error_f("unsupported hostkey algorithm %s", k->hostkey_alg);
return SSH_ERR_INTERNAL_ERROR;
+ }
k->hostkey_nid = sshkey_ecdsa_nid_from_name(k->hostkey_alg);
return 0;
}
@@ -839,7 +907,7 @@ kex_choose_conf(struct ssh *ssh)
}
/* Check whether client supports ext_info_c */
- if (kex->server) {
+ if (kex->server && (kex->flags & KEX_INITIAL)) {
char *ext;
ext = match_list("ext-info-c", peer[PROPOSAL_KEX_ALGS], NULL);
@@ -948,10 +1016,10 @@ derive_key(struct ssh *ssh, int id, u_int need, u_char *hash, u_int hashlen,
ssh_digest_update_buffer(hashctx, shared_secret) != 0 ||
ssh_digest_update(hashctx, hash, hashlen) != 0 ||
ssh_digest_update(hashctx, &c, 1) != 0 ||
- ssh_digest_update(hashctx, kex->session_id,
- kex->session_id_len) != 0 ||
+ ssh_digest_update_buffer(hashctx, kex->session_id) != 0 ||
ssh_digest_final(hashctx, digest, mdsz) != 0) {
r = SSH_ERR_LIBCRYPTO_ERROR;
+ error_f("KEX hash failed");
goto out;
}
ssh_digest_free(hashctx);
@@ -968,6 +1036,7 @@ derive_key(struct ssh *ssh, int id, u_int need, u_char *hash, u_int hashlen,
ssh_digest_update(hashctx, hash, hashlen) != 0 ||
ssh_digest_update(hashctx, digest, have) != 0 ||
ssh_digest_final(hashctx, digest + have, mdsz) != 0) {
+ error_f("KDF failed");
r = SSH_ERR_LIBCRYPTO_ERROR;
goto out;
}
@@ -997,6 +1066,18 @@ kex_derive_keys(struct ssh *ssh, u_char *hash, u_int hashlen,
u_int i, j, mode, ctos;
int r;
+ /* save initial hash as session id */
+ if ((kex->flags & KEX_INITIAL) != 0) {
+ if (sshbuf_len(kex->session_id) != 0) {
+ error_f("already have session ID at kex");
+ return SSH_ERR_INTERNAL_ERROR;
+ }
+ if ((r = sshbuf_put(kex->session_id, hash, hashlen)) != 0)
+ return r;
+ } else if (sshbuf_len(kex->session_id) == 0) {
+ error_f("no session ID in rekex");
+ return SSH_ERR_INTERNAL_ERROR;
+ }
for (i = 0; i < NKEYS; i++) {
if ((r = derive_key(ssh, 'A'+i, kex->we_need, hash, hashlen,
shared_secret, &keys[i])) != 0) {
@@ -1015,29 +1096,284 @@ kex_derive_keys(struct ssh *ssh, u_char *hash, u_int hashlen,
return 0;
}
-#ifdef WITH_OPENSSL
int
-kex_derive_keys_bn(struct ssh *ssh, u_char *hash, u_int hashlen,
- const BIGNUM *secret)
+kex_load_hostkey(struct ssh *ssh, struct sshkey **prvp, struct sshkey **pubp)
{
- struct sshbuf *shared_secret;
- int r;
+ struct kex *kex = ssh->kex;
- if ((shared_secret = sshbuf_new()) == NULL)
- return SSH_ERR_ALLOC_FAIL;
- if ((r = sshbuf_put_bignum2(shared_secret, secret)) == 0)
- r = kex_derive_keys(ssh, hash, hashlen, shared_secret);
- sshbuf_free(shared_secret);
- return r;
+ *pubp = NULL;
+ *prvp = NULL;
+ if (kex->load_host_public_key == NULL ||
+ kex->load_host_private_key == NULL) {
+ error_f("missing hostkey loader");
+ return SSH_ERR_INVALID_ARGUMENT;
+ }
+ *pubp = kex->load_host_public_key(kex->hostkey_type,
+ kex->hostkey_nid, ssh);
+ *prvp = kex->load_host_private_key(kex->hostkey_type,
+ kex->hostkey_nid, ssh);
+ if (*pubp == NULL)
+ return SSH_ERR_NO_HOSTKEY_LOADED;
+ return 0;
}
-#endif
+int
+kex_verify_host_key(struct ssh *ssh, struct sshkey *server_host_key)
+{
+ struct kex *kex = ssh->kex;
+
+ if (kex->verify_host_key == NULL) {
+ error_f("missing hostkey verifier");
+ return SSH_ERR_INVALID_ARGUMENT;
+ }
+ if (server_host_key->type != kex->hostkey_type ||
+ (kex->hostkey_type == KEY_ECDSA &&
+ server_host_key->ecdsa_nid != kex->hostkey_nid))
+ return SSH_ERR_KEY_TYPE_MISMATCH;
+ if (kex->verify_host_key(server_host_key, ssh) == -1)
+ return SSH_ERR_SIGNATURE_INVALID;
+ return 0;
+}
#if defined(DEBUG_KEX) || defined(DEBUG_KEXDH) || defined(DEBUG_KEXECDH)
void
-dump_digest(char *msg, u_char *digest, int len)
+dump_digest(const char *msg, const u_char *digest, int len)
{
fprintf(stderr, "%s\n", msg);
sshbuf_dump_data(digest, len, stderr);
}
#endif
+
+/*
+ * Send a plaintext error message to the peer, suffixed by \r\n.
+ * Only used during banner exchange, and there only for the server.
+ */
+static void
+send_error(struct ssh *ssh, char *msg)
+{
+ char *crnl = "\r\n";
+
+ if (!ssh->kex->server)
+ return;
+
+ if (atomicio(vwrite, ssh_packet_get_connection_out(ssh),
+ msg, strlen(msg)) != strlen(msg) ||
+ atomicio(vwrite, ssh_packet_get_connection_out(ssh),
+ crnl, strlen(crnl)) != strlen(crnl))
+ error_f("write: %.100s", strerror(errno));
+}
+
+/*
+ * Sends our identification string and waits for the peer's. Will block for
+ * up to timeout_ms (or indefinitely if timeout_ms <= 0).
+ * Returns on 0 success or a ssherr.h code on failure.
+ */
+int
+kex_exchange_identification(struct ssh *ssh, int timeout_ms,
+ const char *version_addendum)
+{
+ int remote_major, remote_minor, mismatch, oerrno = 0;
+ size_t len, i, n;
+ int r, expect_nl;
+ u_char c;
+ struct sshbuf *our_version = ssh->kex->server ?
+ ssh->kex->server_version : ssh->kex->client_version;
+ struct sshbuf *peer_version = ssh->kex->server ?
+ ssh->kex->client_version : ssh->kex->server_version;
+ char *our_version_string = NULL, *peer_version_string = NULL;
+ char *cp, *remote_version = NULL;
+
+ /* Prepare and send our banner */
+ sshbuf_reset(our_version);
+ if (version_addendum != NULL && *version_addendum == '\0')
+ version_addendum = NULL;
+ if ((r = sshbuf_putf(our_version, "SSH-%d.%d-%.100s%s%s\r\n",
+ PROTOCOL_MAJOR_2, PROTOCOL_MINOR_2, SSH_VERSION,
+ version_addendum == NULL ? "" : " ",
+ version_addendum == NULL ? "" : version_addendum)) != 0) {
+ oerrno = errno;
+ error_fr(r, "sshbuf_putf");
+ goto out;
+ }
+
+ if (atomicio(vwrite, ssh_packet_get_connection_out(ssh),
+ sshbuf_mutable_ptr(our_version),
+ sshbuf_len(our_version)) != sshbuf_len(our_version)) {
+ oerrno = errno;
+ debug_f("write: %.100s", strerror(errno));
+ r = SSH_ERR_SYSTEM_ERROR;
+ goto out;
+ }
+ if ((r = sshbuf_consume_end(our_version, 2)) != 0) { /* trim \r\n */
+ oerrno = errno;
+ error_fr(r, "sshbuf_consume_end");
+ goto out;
+ }
+ our_version_string = sshbuf_dup_string(our_version);
+ if (our_version_string == NULL) {
+ error_f("sshbuf_dup_string failed");
+ r = SSH_ERR_ALLOC_FAIL;
+ goto out;
+ }
+ debug("Local version string %.100s", our_version_string);
+
+ /* Read other side's version identification. */
+ for (n = 0; ; n++) {
+ if (n >= SSH_MAX_PRE_BANNER_LINES) {
+ send_error(ssh, "No SSH identification string "
+ "received.");
+ error_f("No SSH version received in first %u lines "
+ "from server", SSH_MAX_PRE_BANNER_LINES);
+ r = SSH_ERR_INVALID_FORMAT;
+ goto out;
+ }
+ sshbuf_reset(peer_version);
+ expect_nl = 0;
+ for (i = 0; ; i++) {
+ if (timeout_ms > 0) {
+ r = waitrfd(ssh_packet_get_connection_in(ssh),
+ &timeout_ms);
+ if (r == -1 && errno == ETIMEDOUT) {
+ send_error(ssh, "Timed out waiting "
+ "for SSH identification string.");
+ error("Connection timed out during "
+ "banner exchange");
+ r = SSH_ERR_CONN_TIMEOUT;
+ goto out;
+ } else if (r == -1) {
+ oerrno = errno;
+ error_f("%s", strerror(errno));
+ r = SSH_ERR_SYSTEM_ERROR;
+ goto out;
+ }
+ }
+
+ len = atomicio(read, ssh_packet_get_connection_in(ssh),
+ &c, 1);
+ if (len != 1 && errno == EPIPE) {
+ error_f("Connection closed by remote host");
+ r = SSH_ERR_CONN_CLOSED;
+ goto out;
+ } else if (len != 1) {
+ oerrno = errno;
+ error_f("read: %.100s", strerror(errno));
+ r = SSH_ERR_SYSTEM_ERROR;
+ goto out;
+ }
+ if (c == '\r') {
+ expect_nl = 1;
+ continue;
+ }
+ if (c == '\n')
+ break;
+ if (c == '\0' || expect_nl) {
+ error_f("banner line contains invalid "
+ "characters");
+ goto invalid;
+ }
+ if ((r = sshbuf_put_u8(peer_version, c)) != 0) {
+ oerrno = errno;
+ error_fr(r, "sshbuf_put");
+ goto out;
+ }
+ if (sshbuf_len(peer_version) > SSH_MAX_BANNER_LEN) {
+ error_f("banner line too long");
+ goto invalid;
+ }
+ }
+ /* Is this an actual protocol banner? */
+ if (sshbuf_len(peer_version) > 4 &&
+ memcmp(sshbuf_ptr(peer_version), "SSH-", 4) == 0)
+ break;
+ /* If not, then just log the line and continue */
+ if ((cp = sshbuf_dup_string(peer_version)) == NULL) {
+ error_f("sshbuf_dup_string failed");
+ r = SSH_ERR_ALLOC_FAIL;
+ goto out;
+ }
+ /* Do not accept lines before the SSH ident from a client */
+ if (ssh->kex->server) {
+ error_f("client sent invalid protocol identifier "
+ "\"%.256s\"", cp);
+ free(cp);
+ goto invalid;
+ }
+ debug_f("banner line %zu: %s", n, cp);
+ free(cp);
+ }
+ peer_version_string = sshbuf_dup_string(peer_version);
+ if (peer_version_string == NULL)
+ error_f("sshbuf_dup_string failed");
+ /* XXX must be same size for sscanf */
+ if ((remote_version = calloc(1, sshbuf_len(peer_version))) == NULL) {
+ error_f("calloc failed");
+ r = SSH_ERR_ALLOC_FAIL;
+ goto out;
+ }
+
+ /*
+ * Check that the versions match. In future this might accept
+ * several versions and set appropriate flags to handle them.
+ */
+ if (sscanf(peer_version_string, "SSH-%d.%d-%[^\n]\n",
+ &remote_major, &remote_minor, remote_version) != 3) {
+ error("Bad remote protocol version identification: '%.100s'",
+ peer_version_string);
+ invalid:
+ send_error(ssh, "Invalid SSH identification string.");
+ r = SSH_ERR_INVALID_FORMAT;
+ goto out;
+ }
+ debug("Remote protocol version %d.%d, remote software version %.100s",
+ remote_major, remote_minor, remote_version);
+ compat_banner(ssh, remote_version);
+
+ mismatch = 0;
+ switch (remote_major) {
+ case 2:
+ break;
+ case 1:
+ if (remote_minor != 99)
+ mismatch = 1;
+ break;
+ default:
+ mismatch = 1;
+ break;
+ }
+ if (mismatch) {
+ error("Protocol major versions differ: %d vs. %d",
+ PROTOCOL_MAJOR_2, remote_major);
+ send_error(ssh, "Protocol major versions differ.");
+ r = SSH_ERR_NO_PROTOCOL_VERSION;
+ goto out;
+ }
+
+ if (ssh->kex->server && (ssh->compat & SSH_BUG_PROBE) != 0) {
+ logit("probed from %s port %d with %s. Don't panic.",
+ ssh_remote_ipaddr(ssh), ssh_remote_port(ssh),
+ peer_version_string);
+ r = SSH_ERR_CONN_CLOSED; /* XXX */
+ goto out;
+ }
+ if (ssh->kex->server && (ssh->compat & SSH_BUG_SCANNER) != 0) {
+ logit("scanned from %s port %d with %s. Don't panic.",
+ ssh_remote_ipaddr(ssh), ssh_remote_port(ssh),
+ peer_version_string);
+ r = SSH_ERR_CONN_CLOSED; /* XXX */
+ goto out;
+ }
+ if ((ssh->compat & SSH_BUG_RSASIGMD5) != 0) {
+ logit("Remote version \"%.100s\" uses unsafe RSA signature "
+ "scheme; disabling use of RSA keys", remote_version);
+ }
+ /* success */
+ r = 0;
+ out:
+ free(our_version_string);
+ free(peer_version_string);
+ free(remote_version);
+ if (r == SSH_ERR_SYSTEM_ERROR)
+ errno = oerrno;
+ return r;
+}
+
diff --git a/crypto/openssh/kex.h b/crypto/openssh/kex.h
index 593de120836e..9605ed528ea4 100644
--- a/crypto/openssh/kex.h
+++ b/crypto/openssh/kex.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: kex.h,v 1.91 2018/07/11 18:53:29 markus Exp $ */
+/* $OpenBSD: kex.h,v 1.114 2021/01/31 22:55:29 djm Exp $ */
/*
* Copyright (c) 2000, 2001 Markus Friedl. All rights reserved.
@@ -27,12 +27,12 @@
#define KEX_H
#include "mac.h"
-
-#ifdef WITH_LEAKMALLOC
-#include "leakmalloc.h"
-#endif
+#include "crypto_api.h"
#ifdef WITH_OPENSSL
+# include <openssl/bn.h>
+# include <openssl/dh.h>
+# include <openssl/ecdsa.h>
# ifdef OPENSSL_HAS_ECC
# include <openssl/ec.h>
# else /* OPENSSL_HAS_ECC */
@@ -62,6 +62,7 @@
#define KEX_ECDH_SHA2_NISTP521 "ecdh-sha2-nistp521"
#define KEX_CURVE25519_SHA256 "curve25519-sha256"
#define KEX_CURVE25519_SHA256_OLD "curve25519-sha256@libssh.org"
+#define KEX_SNTRUP761X25519_SHA512 "sntrup761x25519-sha512@openssh.com"
#define COMP_NONE 0
/* pre-auth compression (COMP_ZLIB) is only supported in the client */
@@ -100,10 +101,12 @@ enum kex_exchange {
KEX_DH_GEX_SHA256,
KEX_ECDH_SHA2,
KEX_C25519_SHA256,
+ KEX_KEM_SNTRUP761X25519_SHA512,
KEX_MAX
};
#define KEX_INIT_SENT 0x0001
+#define KEX_INITIAL 0x0002
struct sshenc {
char *name;
@@ -129,8 +132,6 @@ struct newkeys {
struct ssh;
struct kex {
- u_char *session_id;
- size_t session_id_len;
struct newkeys *newkeys[MODE_MAX];
u_int we_need;
u_int dh_need;
@@ -144,27 +145,30 @@ struct kex {
int ext_info_c;
struct sshbuf *my;
struct sshbuf *peer;
+ struct sshbuf *client_version;
+ struct sshbuf *server_version;
+ struct sshbuf *session_id;
sig_atomic_t done;
u_int flags;
int hash_alg;
int ec_nid;
- char *client_version_string;
- char *server_version_string;
char *failed_choice;
int (*verify_host_key)(struct sshkey *, struct ssh *);
struct sshkey *(*load_host_public_key)(int, int, struct ssh *);
struct sshkey *(*load_host_private_key)(int, int, struct ssh *);
int (*host_key_index)(struct sshkey *, int, struct ssh *);
- int (*sign)(struct sshkey *, struct sshkey *, u_char **, size_t *,
- const u_char *, size_t, const char *, u_int);
+ int (*sign)(struct ssh *, struct sshkey *, struct sshkey *,
+ u_char **, size_t *, const u_char *, size_t, const char *);
int (*kex[KEX_MAX])(struct ssh *);
/* kex specific state */
DH *dh; /* DH */
u_int min, max, nbits; /* GEX */
EC_KEY *ec_client_key; /* ECDH */
const EC_GROUP *ec_group; /* ECDH */
- u_char c25519_client_key[CURVE25519_SIZE]; /* 25519 */
+ u_char c25519_client_key[CURVE25519_SIZE]; /* 25519 + KEM */
u_char c25519_client_pubkey[CURVE25519_SIZE]; /* 25519 */
+ u_char sntrup761_client_key[crypto_kem_sntrup761_SECRETKEYBYTES]; /* KEM */
+ struct sshbuf *client_pub;
};
int kex_names_valid(const char *);
@@ -172,7 +176,10 @@ char *kex_alg_list(char);
char *kex_names_cat(const char *, const char *);
int kex_assemble_names(char **, const char *, const char *);
-int kex_new(struct ssh *, char *[PROPOSAL_MAX], struct kex **);
+int kex_exchange_identification(struct ssh *, int, const char *);
+
+struct kex *kex_new(void);
+int kex_ready(struct ssh *, char *[PROPOSAL_MAX]);
int kex_setup(struct ssh *, char *[PROPOSAL_MAX]);
void kex_free_newkeys(struct newkeys *);
void kex_free(struct kex *);
@@ -180,44 +187,53 @@ void kex_free(struct kex *);
int kex_buf2prop(struct sshbuf *, int *, char ***);
int kex_prop2buf(struct sshbuf *, char *proposal[PROPOSAL_MAX]);
void kex_prop_free(char **);
+int kex_load_hostkey(struct ssh *, struct sshkey **, struct sshkey **);
+int kex_verify_host_key(struct ssh *, struct sshkey *);
int kex_send_kexinit(struct ssh *);
int kex_input_kexinit(int, u_int32_t, struct ssh *);
int kex_input_ext_info(int, u_int32_t, struct ssh *);
+int kex_protocol_error(int, u_int32_t, struct ssh *);
int kex_derive_keys(struct ssh *, u_char *, u_int, const struct sshbuf *);
-int kex_derive_keys_bn(struct ssh *, u_char *, u_int, const BIGNUM *);
int kex_send_newkeys(struct ssh *);
int kex_start_rekex(struct ssh *);
-int kexdh_client(struct ssh *);
-int kexdh_server(struct ssh *);
int kexgex_client(struct ssh *);
int kexgex_server(struct ssh *);
-int kexecdh_client(struct ssh *);
-int kexecdh_server(struct ssh *);
-int kexc25519_client(struct ssh *);
-int kexc25519_server(struct ssh *);
+int kex_gen_client(struct ssh *);
+int kex_gen_server(struct ssh *);
+
+int kex_dh_keypair(struct kex *);
+int kex_dh_enc(struct kex *, const struct sshbuf *, struct sshbuf **,
+ struct sshbuf **);
+int kex_dh_dec(struct kex *, const struct sshbuf *, struct sshbuf **);
+
+int kex_ecdh_keypair(struct kex *);
+int kex_ecdh_enc(struct kex *, const struct sshbuf *, struct sshbuf **,
+ struct sshbuf **);
+int kex_ecdh_dec(struct kex *, const struct sshbuf *, struct sshbuf **);
+
+int kex_c25519_keypair(struct kex *);
+int kex_c25519_enc(struct kex *, const struct sshbuf *, struct sshbuf **,
+ struct sshbuf **);
+int kex_c25519_dec(struct kex *, const struct sshbuf *, struct sshbuf **);
-int kex_dh_hash(int, const char *, const char *,
- const u_char *, size_t, const u_char *, size_t, const u_char *, size_t,
- const BIGNUM *, const BIGNUM *, const BIGNUM *, u_char *, size_t *);
+int kex_kem_sntrup761x25519_keypair(struct kex *);
+int kex_kem_sntrup761x25519_enc(struct kex *, const struct sshbuf *,
+ struct sshbuf **, struct sshbuf **);
+int kex_kem_sntrup761x25519_dec(struct kex *, const struct sshbuf *,
+ struct sshbuf **);
-int kexgex_hash(int, const char *, const char *,
- const u_char *, size_t, const u_char *, size_t, const u_char *, size_t,
+int kex_dh_keygen(struct kex *);
+int kex_dh_compute_key(struct kex *, BIGNUM *, struct sshbuf *);
+
+int kexgex_hash(int, const struct sshbuf *, const struct sshbuf *,
+ const struct sshbuf *, const struct sshbuf *, const struct sshbuf *,
int, int, int,
const BIGNUM *, const BIGNUM *, const BIGNUM *,
- const BIGNUM *, const BIGNUM *,
+ const BIGNUM *, const u_char *, size_t,
u_char *, size_t *);
-int kex_ecdh_hash(int, const EC_GROUP *, const char *, const char *,
- const u_char *, size_t, const u_char *, size_t, const u_char *, size_t,
- const EC_POINT *, const EC_POINT *, const BIGNUM *, u_char *, size_t *);
-
-int kex_c25519_hash(int, const char *, const char *,
- const u_char *, size_t, const u_char *, size_t,
- const u_char *, size_t, const u_char *, const u_char *,
- const u_char *, size_t, u_char *, size_t *);
-
void kexc25519_keygen(u_char key[CURVE25519_SIZE], u_char pub[CURVE25519_SIZE])
__attribute__((__bounded__(__minbytes__, 1, CURVE25519_SIZE)))
__attribute__((__bounded__(__minbytes__, 2, CURVE25519_SIZE)));
@@ -225,9 +241,13 @@ int kexc25519_shared_key(const u_char key[CURVE25519_SIZE],
const u_char pub[CURVE25519_SIZE], struct sshbuf *out)
__attribute__((__bounded__(__minbytes__, 1, CURVE25519_SIZE)))
__attribute__((__bounded__(__minbytes__, 2, CURVE25519_SIZE)));
+int kexc25519_shared_key_ext(const u_char key[CURVE25519_SIZE],
+ const u_char pub[CURVE25519_SIZE], struct sshbuf *out, int)
+ __attribute__((__bounded__(__minbytes__, 1, CURVE25519_SIZE)))
+ __attribute__((__bounded__(__minbytes__, 2, CURVE25519_SIZE)));
#if defined(DEBUG_KEX) || defined(DEBUG_KEXDH) || defined(DEBUG_KEXECDH)
-void dump_digest(char *, u_char *, int);
+void dump_digest(const char *, const u_char *, int);
#endif
#if !defined(WITH_OPENSSL) || !defined(OPENSSL_HAS_ECC)
diff --git a/crypto/openssh/kexc25519.c b/crypto/openssh/kexc25519.c
index 0897b8c5190a..f13d766d7247 100644
--- a/crypto/openssh/kexc25519.c
+++ b/crypto/openssh/kexc25519.c
@@ -1,6 +1,6 @@
-/* $OpenBSD: kexc25519.c,v 1.10 2016/05/02 08:49:03 djm Exp $ */
+/* $OpenBSD: kexc25519.c,v 1.17 2019/01/21 10:40:11 djm Exp $ */
/*
- * Copyright (c) 2001, 2013 Markus Friedl. All rights reserved.
+ * Copyright (c) 2019 Markus Friedl. All rights reserved.
* Copyright (c) 2010 Damien Miller. All rights reserved.
* Copyright (c) 2013 Aris Adamantiadis. All rights reserved.
*
@@ -29,20 +29,16 @@
#include <sys/types.h>
-#include <signal.h>
+#include <stdio.h>
#include <string.h>
+#include <signal.h>
-#include <openssl/bn.h>
-#include <openssl/evp.h>
-
-#include "sshbuf.h"
-#include "ssh2.h"
#include "sshkey.h"
-#include "cipher.h"
#include "kex.h"
-#include "log.h"
+#include "sshbuf.h"
#include "digest.h"
#include "ssherr.h"
+#include "ssh2.h"
extern int crypto_scalarmult_curve25519(u_char a[CURVE25519_SIZE],
const u_char b[CURVE25519_SIZE], const u_char c[CURVE25519_SIZE])
@@ -60,74 +56,144 @@ kexc25519_keygen(u_char key[CURVE25519_SIZE], u_char pub[CURVE25519_SIZE])
}
int
-kexc25519_shared_key(const u_char key[CURVE25519_SIZE],
- const u_char pub[CURVE25519_SIZE], struct sshbuf *out)
+kexc25519_shared_key_ext(const u_char key[CURVE25519_SIZE],
+ const u_char pub[CURVE25519_SIZE], struct sshbuf *out, int raw)
{
u_char shared_key[CURVE25519_SIZE];
+ u_char zero[CURVE25519_SIZE];
int r;
- /* Check for all-zero public key */
- explicit_bzero(shared_key, CURVE25519_SIZE);
- if (timingsafe_bcmp(pub, shared_key, CURVE25519_SIZE) == 0)
+ crypto_scalarmult_curve25519(shared_key, key, pub);
+
+ /* Check for all-zero shared secret */
+ explicit_bzero(zero, CURVE25519_SIZE);
+ if (timingsafe_bcmp(zero, shared_key, CURVE25519_SIZE) == 0)
return SSH_ERR_KEY_INVALID_EC_VALUE;
- crypto_scalarmult_curve25519(shared_key, key, pub);
#ifdef DEBUG_KEXECDH
dump_digest("shared secret", shared_key, CURVE25519_SIZE);
#endif
- sshbuf_reset(out);
- r = sshbuf_put_bignum2_bytes(out, shared_key, CURVE25519_SIZE);
+ if (raw)
+ r = sshbuf_put(out, shared_key, CURVE25519_SIZE);
+ else
+ r = sshbuf_put_bignum2_bytes(out, shared_key, CURVE25519_SIZE);
explicit_bzero(shared_key, CURVE25519_SIZE);
return r;
}
int
-kex_c25519_hash(
- int hash_alg,
- const char *client_version_string,
- const char *server_version_string,
- const u_char *ckexinit, size_t ckexinitlen,
- const u_char *skexinit, size_t skexinitlen,
- const u_char *serverhostkeyblob, size_t sbloblen,
- const u_char client_dh_pub[CURVE25519_SIZE],
- const u_char server_dh_pub[CURVE25519_SIZE],
- const u_char *shared_secret, size_t secretlen,
- u_char *hash, size_t *hashlen)
+kexc25519_shared_key(const u_char key[CURVE25519_SIZE],
+ const u_char pub[CURVE25519_SIZE], struct sshbuf *out)
+{
+ return kexc25519_shared_key_ext(key, pub, out, 0);
+}
+
+int
+kex_c25519_keypair(struct kex *kex)
{
- struct sshbuf *b;
+ struct sshbuf *buf = NULL;
+ u_char *cp = NULL;
int r;
- if (*hashlen < ssh_digest_bytes(hash_alg))
- return SSH_ERR_INVALID_ARGUMENT;
- if ((b = sshbuf_new()) == NULL)
+ if ((buf = sshbuf_new()) == NULL)
return SSH_ERR_ALLOC_FAIL;
- if ((r = sshbuf_put_cstring(b, client_version_string)) < 0 ||
- (r = sshbuf_put_cstring(b, server_version_string)) < 0 ||
- /* kexinit messages: fake header: len+SSH2_MSG_KEXINIT */
- (r = sshbuf_put_u32(b, ckexinitlen+1)) < 0 ||
- (r = sshbuf_put_u8(b, SSH2_MSG_KEXINIT)) < 0 ||
- (r = sshbuf_put(b, ckexinit, ckexinitlen)) < 0 ||
- (r = sshbuf_put_u32(b, skexinitlen+1)) < 0 ||
- (r = sshbuf_put_u8(b, SSH2_MSG_KEXINIT)) < 0 ||
- (r = sshbuf_put(b, skexinit, skexinitlen)) < 0 ||
- (r = sshbuf_put_string(b, serverhostkeyblob, sbloblen)) < 0 ||
- (r = sshbuf_put_string(b, client_dh_pub, CURVE25519_SIZE)) < 0 ||
- (r = sshbuf_put_string(b, server_dh_pub, CURVE25519_SIZE)) < 0 ||
- (r = sshbuf_put(b, shared_secret, secretlen)) < 0) {
- sshbuf_free(b);
- return r;
+ if ((r = sshbuf_reserve(buf, CURVE25519_SIZE, &cp)) != 0)
+ goto out;
+ kexc25519_keygen(kex->c25519_client_key, cp);
+#ifdef DEBUG_KEXECDH
+ dump_digest("client public key c25519:", cp, CURVE25519_SIZE);
+#endif
+ kex->client_pub = buf;
+ buf = NULL;
+ out:
+ sshbuf_free(buf);
+ return r;
+}
+
+int
+kex_c25519_enc(struct kex *kex, const struct sshbuf *client_blob,
+ struct sshbuf **server_blobp, struct sshbuf **shared_secretp)
+{
+ struct sshbuf *server_blob = NULL;
+ struct sshbuf *buf = NULL;
+ const u_char *client_pub;
+ u_char *server_pub;
+ u_char server_key[CURVE25519_SIZE];
+ int r;
+
+ *server_blobp = NULL;
+ *shared_secretp = NULL;
+
+ if (sshbuf_len(client_blob) != CURVE25519_SIZE) {
+ r = SSH_ERR_SIGNATURE_INVALID;
+ goto out;
}
-#ifdef DEBUG_KEX
- sshbuf_dump(b, stderr);
+ client_pub = sshbuf_ptr(client_blob);
+#ifdef DEBUG_KEXECDH
+ dump_digest("client public key 25519:", client_pub, CURVE25519_SIZE);
#endif
- if (ssh_digest_buffer(hash_alg, b, hash, *hashlen) != 0) {
- sshbuf_free(b);
- return SSH_ERR_LIBCRYPTO_ERROR;
+ /* allocate space for encrypted KEM key and ECDH pub key */
+ if ((server_blob = sshbuf_new()) == NULL) {
+ r = SSH_ERR_ALLOC_FAIL;
+ goto out;
}
- sshbuf_free(b);
- *hashlen = ssh_digest_bytes(hash_alg);
-#ifdef DEBUG_KEX
- dump_digest("hash", hash, *hashlen);
+ if ((r = sshbuf_reserve(server_blob, CURVE25519_SIZE, &server_pub)) != 0)
+ goto out;
+ kexc25519_keygen(server_key, server_pub);
+ /* allocate shared secret */
+ if ((buf = sshbuf_new()) == NULL) {
+ r = SSH_ERR_ALLOC_FAIL;
+ goto out;
+ }
+ if ((r = kexc25519_shared_key_ext(server_key, client_pub, buf, 0)) < 0)
+ goto out;
+#ifdef DEBUG_KEXECDH
+ dump_digest("server public key 25519:", server_pub, CURVE25519_SIZE);
+ dump_digest("encoded shared secret:", sshbuf_ptr(buf), sshbuf_len(buf));
#endif
- return 0;
+ *server_blobp = server_blob;
+ *shared_secretp = buf;
+ server_blob = NULL;
+ buf = NULL;
+ out:
+ explicit_bzero(server_key, sizeof(server_key));
+ sshbuf_free(server_blob);
+ sshbuf_free(buf);
+ return r;
+}
+
+int
+kex_c25519_dec(struct kex *kex, const struct sshbuf *server_blob,
+ struct sshbuf **shared_secretp)
+{
+ struct sshbuf *buf = NULL;
+ const u_char *server_pub;
+ int r;
+
+ *shared_secretp = NULL;
+
+ if (sshbuf_len(server_blob) != CURVE25519_SIZE) {
+ r = SSH_ERR_SIGNATURE_INVALID;
+ goto out;
+ }
+ server_pub = sshbuf_ptr(server_blob);
+#ifdef DEBUG_KEXECDH
+ dump_digest("server public key c25519:", server_pub, CURVE25519_SIZE);
+#endif
+ /* shared secret */
+ if ((buf = sshbuf_new()) == NULL) {
+ r = SSH_ERR_ALLOC_FAIL;
+ goto out;
+ }
+ if ((r = kexc25519_shared_key_ext(kex->c25519_client_key, server_pub,
+ buf, 0)) < 0)
+ goto out;
+#ifdef DEBUG_KEXECDH
+ dump_digest("encoded shared secret:", sshbuf_ptr(buf), sshbuf_len(buf));
+#endif
+ *shared_secretp = buf;
+ buf = NULL;
+ out:
+ sshbuf_free(buf);
+ return r;
}
diff --git a/crypto/openssh/kexc25519c.c b/crypto/openssh/kexc25519c.c
deleted file mode 100644
index a8d92149c3fd..000000000000
--- a/crypto/openssh/kexc25519c.c
+++ /dev/null
@@ -1,169 +0,0 @@
-/* $OpenBSD: kexc25519c.c,v 1.9 2017/12/18 02:25:15 djm Exp $ */
-/*
- * Copyright (c) 2001 Markus Friedl. All rights reserved.
- * Copyright (c) 2010 Damien Miller. All rights reserved.
- * Copyright (c) 2013 Aris Adamantiadis. 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 <sys/types.h>
-
-#include <stdio.h>
-#include <string.h>
-#include <signal.h>
-
-#include "sshkey.h"
-#include "cipher.h"
-#include "kex.h"
-#include "log.h"
-#include "packet.h"
-#include "ssh2.h"
-#include "sshbuf.h"
-#include "digest.h"
-#include "ssherr.h"
-
-static int
-input_kex_c25519_reply(int type, u_int32_t seq, struct ssh *ssh);
-
-int
-kexc25519_client(struct ssh *ssh)
-{
- struct kex *kex = ssh->kex;
- int r;
-
- kexc25519_keygen(kex->c25519_client_key, kex->c25519_client_pubkey);
-#ifdef DEBUG_KEXECDH
- dump_digest("client private key:", kex->c25519_client_key,
- sizeof(kex->c25519_client_key));
-#endif
- if ((r = sshpkt_start(ssh, SSH2_MSG_KEX_ECDH_INIT)) != 0 ||
- (r = sshpkt_put_string(ssh, kex->c25519_client_pubkey,
- sizeof(kex->c25519_client_pubkey))) != 0 ||
- (r = sshpkt_send(ssh)) != 0)
- return r;
-
- debug("expecting SSH2_MSG_KEX_ECDH_REPLY");
- ssh_dispatch_set(ssh, SSH2_MSG_KEX_ECDH_REPLY, &input_kex_c25519_reply);
- return 0;
-}
-
-static int
-input_kex_c25519_reply(int type, u_int32_t seq, struct ssh *ssh)
-{
- struct kex *kex = ssh->kex;
- struct sshkey *server_host_key = NULL;
- struct sshbuf *shared_secret = NULL;
- u_char *server_pubkey = NULL;
- u_char *server_host_key_blob = NULL, *signature = NULL;
- u_char hash[SSH_DIGEST_MAX_LENGTH];
- size_t slen, pklen, sbloblen, hashlen;
- int r;
-
- if (kex->verify_host_key == NULL) {
- r = SSH_ERR_INVALID_ARGUMENT;
- goto out;
- }
-
- /* hostkey */
- if ((r = sshpkt_get_string(ssh, &server_host_key_blob,
- &sbloblen)) != 0 ||
- (r = sshkey_from_blob(server_host_key_blob, sbloblen,
- &server_host_key)) != 0)
- goto out;
- if (server_host_key->type != kex->hostkey_type ||
- (kex->hostkey_type == KEY_ECDSA &&
- server_host_key->ecdsa_nid != kex->hostkey_nid)) {
- r = SSH_ERR_KEY_TYPE_MISMATCH;
- goto out;
- }
- if (kex->verify_host_key(server_host_key, ssh) == -1) {
- r = SSH_ERR_SIGNATURE_INVALID;
- goto out;
- }
-
- /* Q_S, server public key */
- /* signed H */
- if ((r = sshpkt_get_string(ssh, &server_pubkey, &pklen)) != 0 ||
- (r = sshpkt_get_string(ssh, &signature, &slen)) != 0 ||
- (r = sshpkt_get_end(ssh)) != 0)
- goto out;
- if (pklen != CURVE25519_SIZE) {
- r = SSH_ERR_SIGNATURE_INVALID;
- goto out;
- }
-
-#ifdef DEBUG_KEXECDH
- dump_digest("server public key:", server_pubkey, CURVE25519_SIZE);
-#endif
-
- if ((shared_secret = sshbuf_new()) == NULL) {
- r = SSH_ERR_ALLOC_FAIL;
- goto out;
- }
- if ((r = kexc25519_shared_key(kex->c25519_client_key, server_pubkey,
- shared_secret)) < 0)
- goto out;
-
- /* calc and verify H */
- hashlen = sizeof(hash);
- if ((r = kex_c25519_hash(
- kex->hash_alg,
- kex->client_version_string,
- kex->server_version_string,
- sshbuf_ptr(kex->my), sshbuf_len(kex->my),
- sshbuf_ptr(kex->peer), sshbuf_len(kex->peer),
- server_host_key_blob, sbloblen,
- kex->c25519_client_pubkey,
- server_pubkey,
- sshbuf_ptr(shared_secret), sshbuf_len(shared_secret),
- hash, &hashlen)) < 0)
- goto out;
-
- if ((r = sshkey_verify(server_host_key, signature, slen, hash, hashlen,
- kex->hostkey_alg, ssh->compat)) != 0)
- goto out;
-
- /* save session id */
- if (kex->session_id == NULL) {
- kex->session_id_len = hashlen;
- kex->session_id = malloc(kex->session_id_len);
- if (kex->session_id == NULL) {
- r = SSH_ERR_ALLOC_FAIL;
- goto out;
- }
- memcpy(kex->session_id, hash, kex->session_id_len);
- }
-
- if ((r = kex_derive_keys(ssh, hash, hashlen, shared_secret)) == 0)
- r = kex_send_newkeys(ssh);
-out:
- explicit_bzero(hash, sizeof(hash));
- explicit_bzero(kex->c25519_client_key, sizeof(kex->c25519_client_key));
- free(server_host_key_blob);
- free(server_pubkey);
- free(signature);
- sshkey_free(server_host_key);
- sshbuf_free(shared_secret);
- return r;
-}
diff --git a/crypto/openssh/kexc25519s.c b/crypto/openssh/kexc25519s.c
deleted file mode 100644
index 0800a7a4bcf4..000000000000
--- a/crypto/openssh/kexc25519s.c
+++ /dev/null
@@ -1,158 +0,0 @@
-/* $OpenBSD: kexc25519s.c,v 1.11 2017/05/31 04:19:28 djm Exp $ */
-/*
- * Copyright (c) 2001 Markus Friedl. All rights reserved.
- * Copyright (c) 2010 Damien Miller. All rights reserved.
- * Copyright (c) 2013 Aris Adamantiadis. All rights reserved.
- *
- * 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 <sys/types.h>
-#include <stdio.h>
-#include <string.h>
-#include <signal.h>
-
-#include "sshkey.h"
-#include "cipher.h"
-#include "digest.h"
-#include "kex.h"
-#include "log.h"
-#include "packet.h"
-#include "ssh2.h"
-#include "sshbuf.h"
-#include "ssherr.h"
-
-static int input_kex_c25519_init(int, u_int32_t, struct ssh *);
-
-int
-kexc25519_server(struct ssh *ssh)
-{
- debug("expecting SSH2_MSG_KEX_ECDH_INIT");
- ssh_dispatch_set(ssh, SSH2_MSG_KEX_ECDH_INIT, &input_kex_c25519_init);
- return 0;
-}
-
-static int
-input_kex_c25519_init(int type, u_int32_t seq, struct ssh *ssh)
-{
- struct kex *kex = ssh->kex;
- struct sshkey *server_host_private, *server_host_public;
- struct sshbuf *shared_secret = NULL;
- u_char *server_host_key_blob = NULL, *signature = NULL;
- u_char server_key[CURVE25519_SIZE];
- u_char *client_pubkey = NULL;
- u_char server_pubkey[CURVE25519_SIZE];
- u_char hash[SSH_DIGEST_MAX_LENGTH];
- size_t slen, pklen, sbloblen, hashlen;
- int r;
-
- /* generate private key */
- kexc25519_keygen(server_key, server_pubkey);
-#ifdef DEBUG_KEXECDH
- dump_digest("server private key:", server_key, sizeof(server_key));
-#endif
- if (kex->load_host_public_key == NULL ||
- kex->load_host_private_key == NULL) {
- r = SSH_ERR_INVALID_ARGUMENT;
- goto out;
- }
- server_host_public = kex->load_host_public_key(kex->hostkey_type,
- kex->hostkey_nid, ssh);
- server_host_private = kex->load_host_private_key(kex->hostkey_type,
- kex->hostkey_nid, ssh);
- if (server_host_public == NULL) {
- r = SSH_ERR_NO_HOSTKEY_LOADED;
- goto out;
- }
-
- if ((r = sshpkt_get_string(ssh, &client_pubkey, &pklen)) != 0 ||
- (r = sshpkt_get_end(ssh)) != 0)
- goto out;
- if (pklen != CURVE25519_SIZE) {
- r = SSH_ERR_SIGNATURE_INVALID;
- goto out;
- }
-#ifdef DEBUG_KEXECDH
- dump_digest("client public key:", client_pubkey, CURVE25519_SIZE);
-#endif
-
- if ((shared_secret = sshbuf_new()) == NULL) {
- r = SSH_ERR_ALLOC_FAIL;
- goto out;
- }
- if ((r = kexc25519_shared_key(server_key, client_pubkey,
- shared_secret)) < 0)
- goto out;
-
- /* calc H */
- if ((r = sshkey_to_blob(server_host_public, &server_host_key_blob,
- &sbloblen)) != 0)
- goto out;
- hashlen = sizeof(hash);
- if ((r = kex_c25519_hash(
- kex->hash_alg,
- kex->client_version_string,
- kex->server_version_string,
- sshbuf_ptr(kex->peer), sshbuf_len(kex->peer),
- sshbuf_ptr(kex->my), sshbuf_len(kex->my),
- server_host_key_blob, sbloblen,
- client_pubkey,
- server_pubkey,
- sshbuf_ptr(shared_secret), sshbuf_len(shared_secret),
- hash, &hashlen)) < 0)
- goto out;
-
- /* save session id := H */
- if (kex->session_id == NULL) {
- kex->session_id_len = hashlen;
- kex->session_id = malloc(kex->session_id_len);
- if (kex->session_id == NULL) {
- r = SSH_ERR_ALLOC_FAIL;
- goto out;
- }
- memcpy(kex->session_id, hash, kex->session_id_len);
- }
-
- /* sign H */
- if ((r = kex->sign(server_host_private, server_host_public, &signature,
- &slen, hash, hashlen, kex->hostkey_alg, ssh->compat)) < 0)
- goto out;
-
- /* send server hostkey, ECDH pubkey 'Q_S' and signed H */
- if ((r = sshpkt_start(ssh, SSH2_MSG_KEX_ECDH_REPLY)) != 0 ||
- (r = sshpkt_put_string(ssh, server_host_key_blob, sbloblen)) != 0 ||
- (r = sshpkt_put_string(ssh, server_pubkey, sizeof(server_pubkey))) != 0 ||
- (r = sshpkt_put_string(ssh, signature, slen)) != 0 ||
- (r = sshpkt_send(ssh)) != 0)
- goto out;
-
- if ((r = kex_derive_keys(ssh, hash, hashlen, shared_secret)) == 0)
- r = kex_send_newkeys(ssh);
-out:
- explicit_bzero(hash, sizeof(hash));
- explicit_bzero(server_key, sizeof(server_key));
- free(server_host_key_blob);
- free(signature);
- free(client_pubkey);
- sshbuf_free(shared_secret);
- return r;
-}
diff --git a/crypto/openssh/kexdh.c b/crypto/openssh/kexdh.c
index e6925b186d82..c1084f2146e1 100644
--- a/crypto/openssh/kexdh.c
+++ b/crypto/openssh/kexdh.c
@@ -1,6 +1,6 @@
-/* $OpenBSD: kexdh.c,v 1.26 2016/05/02 10:26:04 djm Exp $ */
+/* $OpenBSD: kexdh.c,v 1.34 2020/12/04 02:29:25 djm Exp $ */
/*
- * Copyright (c) 2001 Markus Friedl. All rights reserved.
+ * Copyright (c) 2019 Markus Friedl. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -29,68 +29,175 @@
#include <sys/types.h>
+#include <stdio.h>
+#include <string.h>
#include <signal.h>
-#include <openssl/evp.h>
-
#include "openbsd-compat/openssl-compat.h"
+#include <openssl/dh.h>
-#include "ssh2.h"
#include "sshkey.h"
-#include "cipher.h"
#include "kex.h"
-#include "ssherr.h"
#include "sshbuf.h"
#include "digest.h"
+#include "ssherr.h"
+#include "dh.h"
+#include "log.h"
int
-kex_dh_hash(
- int hash_alg,
- const char *client_version_string,
- const char *server_version_string,
- const u_char *ckexinit, size_t ckexinitlen,
- const u_char *skexinit, size_t skexinitlen,
- const u_char *serverhostkeyblob, size_t sbloblen,
- const BIGNUM *client_dh_pub,
- const BIGNUM *server_dh_pub,
- const BIGNUM *shared_secret,
- u_char *hash, size_t *hashlen)
+kex_dh_keygen(struct kex *kex)
{
- struct sshbuf *b;
- int r;
-
- if (*hashlen < ssh_digest_bytes(hash_alg))
+ switch (kex->kex_type) {
+ case KEX_DH_GRP1_SHA1:
+ kex->dh = dh_new_group1();
+ break;
+ case KEX_DH_GRP14_SHA1:
+ case KEX_DH_GRP14_SHA256:
+ kex->dh = dh_new_group14();
+ break;
+ case KEX_DH_GRP16_SHA512:
+ kex->dh = dh_new_group16();
+ break;
+ case KEX_DH_GRP18_SHA512:
+ kex->dh = dh_new_group18();
+ break;
+ default:
return SSH_ERR_INVALID_ARGUMENT;
- if ((b = sshbuf_new()) == NULL)
- return SSH_ERR_ALLOC_FAIL;
- if ((r = sshbuf_put_cstring(b, client_version_string)) != 0 ||
- (r = sshbuf_put_cstring(b, server_version_string)) != 0 ||
- /* kexinit messages: fake header: len+SSH2_MSG_KEXINIT */
- (r = sshbuf_put_u32(b, ckexinitlen+1)) != 0 ||
- (r = sshbuf_put_u8(b, SSH2_MSG_KEXINIT)) != 0 ||
- (r = sshbuf_put(b, ckexinit, ckexinitlen)) != 0 ||
- (r = sshbuf_put_u32(b, skexinitlen+1)) != 0 ||
- (r = sshbuf_put_u8(b, SSH2_MSG_KEXINIT)) != 0 ||
- (r = sshbuf_put(b, skexinit, skexinitlen)) != 0 ||
- (r = sshbuf_put_string(b, serverhostkeyblob, sbloblen)) != 0 ||
- (r = sshbuf_put_bignum2(b, client_dh_pub)) != 0 ||
- (r = sshbuf_put_bignum2(b, server_dh_pub)) != 0 ||
- (r = sshbuf_put_bignum2(b, shared_secret)) != 0) {
- sshbuf_free(b);
- return r;
}
-#ifdef DEBUG_KEX
- sshbuf_dump(b, stderr);
+ if (kex->dh == NULL)
+ return SSH_ERR_ALLOC_FAIL;
+ return (dh_gen_key(kex->dh, kex->we_need * 8));
+}
+
+int
+kex_dh_compute_key(struct kex *kex, BIGNUM *dh_pub, struct sshbuf *out)
+{
+ BIGNUM *shared_secret = NULL;
+ u_char *kbuf = NULL;
+ size_t klen = 0;
+ int kout, r;
+
+#ifdef DEBUG_KEXDH
+ fprintf(stderr, "dh_pub= ");
+ BN_print_fp(stderr, dh_pub);
+ fprintf(stderr, "\n");
+ debug("bits %d", BN_num_bits(dh_pub));
+ DHparams_print_fp(stderr, kex->dh);
+ fprintf(stderr, "\n");
#endif
- if (ssh_digest_buffer(hash_alg, b, hash, *hashlen) != 0) {
- sshbuf_free(b);
- return SSH_ERR_LIBCRYPTO_ERROR;
+
+ if (!dh_pub_is_valid(kex->dh, dh_pub)) {
+ r = SSH_ERR_MESSAGE_INCOMPLETE;
+ goto out;
+ }
+ klen = DH_size(kex->dh);
+ if ((kbuf = malloc(klen)) == NULL ||
+ (shared_secret = BN_new()) == NULL) {
+ r = SSH_ERR_ALLOC_FAIL;
+ goto out;
+ }
+ if ((kout = DH_compute_key(kbuf, dh_pub, kex->dh)) < 0 ||
+ BN_bin2bn(kbuf, kout, shared_secret) == NULL) {
+ r = SSH_ERR_LIBCRYPTO_ERROR;
+ goto out;
}
- sshbuf_free(b);
- *hashlen = ssh_digest_bytes(hash_alg);
-#ifdef DEBUG_KEX
- dump_digest("hash", hash, *hashlen);
+#ifdef DEBUG_KEXDH
+ dump_digest("shared secret", kbuf, kout);
#endif
- return 0;
+ r = sshbuf_put_bignum2(out, shared_secret);
+ out:
+ freezero(kbuf, klen);
+ BN_clear_free(shared_secret);
+ return r;
+}
+
+int
+kex_dh_keypair(struct kex *kex)
+{
+ const BIGNUM *pub_key;
+ struct sshbuf *buf = NULL;
+ int r;
+
+ if ((r = kex_dh_keygen(kex)) != 0)
+ return r;
+ DH_get0_key(kex->dh, &pub_key, NULL);
+ if ((buf = sshbuf_new()) == NULL)
+ return SSH_ERR_ALLOC_FAIL;
+ if ((r = sshbuf_put_bignum2(buf, pub_key)) != 0 ||
+ (r = sshbuf_get_u32(buf, NULL)) != 0)
+ goto out;
+#ifdef DEBUG_KEXDH
+ DHparams_print_fp(stderr, kex->dh);
+ fprintf(stderr, "pub= ");
+ BN_print_fp(stderr, pub_key);
+ fprintf(stderr, "\n");
+#endif
+ kex->client_pub = buf;
+ buf = NULL;
+ out:
+ sshbuf_free(buf);
+ return r;
+}
+
+int
+kex_dh_enc(struct kex *kex, const struct sshbuf *client_blob,
+ struct sshbuf **server_blobp, struct sshbuf **shared_secretp)
+{
+ const BIGNUM *pub_key;
+ struct sshbuf *server_blob = NULL;
+ int r;
+
+ *server_blobp = NULL;
+ *shared_secretp = NULL;
+
+ if ((r = kex_dh_keygen(kex)) != 0)
+ goto out;
+ DH_get0_key(kex->dh, &pub_key, NULL);
+ if ((server_blob = sshbuf_new()) == NULL) {
+ r = SSH_ERR_ALLOC_FAIL;
+ goto out;
+ }
+ if ((r = sshbuf_put_bignum2(server_blob, pub_key)) != 0 ||
+ (r = sshbuf_get_u32(server_blob, NULL)) != 0)
+ goto out;
+ if ((r = kex_dh_dec(kex, client_blob, shared_secretp)) != 0)
+ goto out;
+ *server_blobp = server_blob;
+ server_blob = NULL;
+ out:
+ DH_free(kex->dh);
+ kex->dh = NULL;
+ sshbuf_free(server_blob);
+ return r;
+}
+
+int
+kex_dh_dec(struct kex *kex, const struct sshbuf *dh_blob,
+ struct sshbuf **shared_secretp)
+{
+ struct sshbuf *buf = NULL;
+ BIGNUM *dh_pub = NULL;
+ int r;
+
+ *shared_secretp = NULL;
+
+ if ((buf = sshbuf_new()) == NULL) {
+ r = SSH_ERR_ALLOC_FAIL;
+ goto out;
+ }
+ if ((r = sshbuf_put_stringb(buf, dh_blob)) != 0 ||
+ (r = sshbuf_get_bignum2(buf, &dh_pub)) != 0)
+ goto out;
+ sshbuf_reset(buf);
+ if ((r = kex_dh_compute_key(kex, dh_pub, buf)) != 0)
+ goto out;
+ *shared_secretp = buf;
+ buf = NULL;
+ out:
+ BN_free(dh_pub);
+ DH_free(kex->dh);
+ kex->dh = NULL;
+ sshbuf_free(buf);
+ return r;
}
#endif /* WITH_OPENSSL */
diff --git a/crypto/openssh/kexdhc.c b/crypto/openssh/kexdhc.c
deleted file mode 100644
index 8b56377ad09d..000000000000
--- a/crypto/openssh/kexdhc.c
+++ /dev/null
@@ -1,224 +0,0 @@
-/* $OpenBSD: kexdhc.c,v 1.22 2018/02/07 02:06:51 jsing 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.
- */
-
-#include "includes.h"
-
-#ifdef WITH_OPENSSL
-
-#include <sys/types.h>
-
-#include <openssl/dh.h>
-
-#include <stdarg.h>
-#include <stdio.h>
-#include <string.h>
-#include <signal.h>
-
-#include "openbsd-compat/openssl-compat.h"
-
-#include "sshkey.h"
-#include "cipher.h"
-#include "digest.h"
-#include "kex.h"
-#include "log.h"
-#include "packet.h"
-#include "dh.h"
-#include "ssh2.h"
-#include "dispatch.h"
-#include "compat.h"
-#include "ssherr.h"
-#include "sshbuf.h"
-
-static int input_kex_dh(int, u_int32_t, struct ssh *);
-
-int
-kexdh_client(struct ssh *ssh)
-{
- struct kex *kex = ssh->kex;
- int r;
- const BIGNUM *pub_key;
-
- /* generate and send 'e', client DH public key */
- switch (kex->kex_type) {
- case KEX_DH_GRP1_SHA1:
- kex->dh = dh_new_group1();
- break;
- case KEX_DH_GRP14_SHA1:
- case KEX_DH_GRP14_SHA256:
- kex->dh = dh_new_group14();
- break;
- case KEX_DH_GRP16_SHA512:
- kex->dh = dh_new_group16();
- break;
- case KEX_DH_GRP18_SHA512:
- kex->dh = dh_new_group18();
- break;
- default:
- r = SSH_ERR_INVALID_ARGUMENT;
- goto out;
- }
- if (kex->dh == NULL) {
- r = SSH_ERR_ALLOC_FAIL;
- goto out;
- }
- debug("sending SSH2_MSG_KEXDH_INIT");
- if ((r = dh_gen_key(kex->dh, kex->we_need * 8)) != 0)
- goto out;
- DH_get0_key(kex->dh, &pub_key, NULL);
- if ((r = sshpkt_start(ssh, SSH2_MSG_KEXDH_INIT)) != 0 ||
- (r = sshpkt_put_bignum2(ssh, pub_key)) != 0 ||
- (r = sshpkt_send(ssh)) != 0)
- goto out;
-#ifdef DEBUG_KEXDH
- DHparams_print_fp(stderr, kex->dh);
- fprintf(stderr, "pub= ");
- BN_print_fp(stderr, pub_key);
- fprintf(stderr, "\n");
-#endif
- debug("expecting SSH2_MSG_KEXDH_REPLY");
- ssh_dispatch_set(ssh, SSH2_MSG_KEXDH_REPLY, &input_kex_dh);
- r = 0;
- out:
- return r;
-}
-
-static int
-input_kex_dh(int type, u_int32_t seq, struct ssh *ssh)
-{
- struct kex *kex = ssh->kex;
- BIGNUM *dh_server_pub = NULL, *shared_secret = NULL;
- const BIGNUM *pub_key;
- struct sshkey *server_host_key = NULL;
- u_char *kbuf = NULL, *server_host_key_blob = NULL, *signature = NULL;
- u_char hash[SSH_DIGEST_MAX_LENGTH];
- size_t klen = 0, slen, sbloblen, hashlen;
- int kout, r;
-
- if (kex->verify_host_key == NULL) {
- r = SSH_ERR_INVALID_ARGUMENT;
- goto out;
- }
- /* key, cert */
- if ((r = sshpkt_get_string(ssh, &server_host_key_blob,
- &sbloblen)) != 0 ||
- (r = sshkey_from_blob(server_host_key_blob, sbloblen,
- &server_host_key)) != 0)
- goto out;
- if (server_host_key->type != kex->hostkey_type ||
- (kex->hostkey_type == KEY_ECDSA &&
- server_host_key->ecdsa_nid != kex->hostkey_nid)) {
- r = SSH_ERR_KEY_TYPE_MISMATCH;
- goto out;
- }
- if (kex->verify_host_key(server_host_key, ssh) == -1) {
- r = SSH_ERR_SIGNATURE_INVALID;
- goto out;
- }
- /* DH parameter f, server public DH key */
- if ((dh_server_pub = BN_new()) == NULL) {
- r = SSH_ERR_ALLOC_FAIL;
- goto out;
- }
- /* signed H */
- if ((r = sshpkt_get_bignum2(ssh, dh_server_pub)) != 0 ||
- (r = sshpkt_get_string(ssh, &signature, &slen)) != 0 ||
- (r = sshpkt_get_end(ssh)) != 0)
- goto out;
-#ifdef DEBUG_KEXDH
- fprintf(stderr, "dh_server_pub= ");
- BN_print_fp(stderr, dh_server_pub);
- fprintf(stderr, "\n");
- debug("bits %d", BN_num_bits(dh_server_pub));
-#endif
- if (!dh_pub_is_valid(kex->dh, dh_server_pub)) {
- sshpkt_disconnect(ssh, "bad server public DH value");
- r = SSH_ERR_MESSAGE_INCOMPLETE;
- goto out;
- }
-
- klen = DH_size(kex->dh);
- if ((kbuf = malloc(klen)) == NULL ||
- (shared_secret = BN_new()) == NULL) {
- r = SSH_ERR_ALLOC_FAIL;
- goto out;
- }
- if ((kout = DH_compute_key(kbuf, dh_server_pub, kex->dh)) < 0 ||
- BN_bin2bn(kbuf, kout, shared_secret) == NULL) {
- r = SSH_ERR_LIBCRYPTO_ERROR;
- goto out;
- }
-#ifdef DEBUG_KEXDH
- dump_digest("shared secret", kbuf, kout);
-#endif
-
- /* calc and verify H */
- DH_get0_key(kex->dh, &pub_key, NULL);
- hashlen = sizeof(hash);
- if ((r = kex_dh_hash(
- kex->hash_alg,
- kex->client_version_string,
- kex->server_version_string,
- sshbuf_ptr(kex->my), sshbuf_len(kex->my),
- sshbuf_ptr(kex->peer), sshbuf_len(kex->peer),
- server_host_key_blob, sbloblen,
- pub_key,
- dh_server_pub,
- shared_secret,
- hash, &hashlen)) != 0)
- goto out;
-
- if ((r = sshkey_verify(server_host_key, signature, slen, hash, hashlen,
- kex->hostkey_alg, ssh->compat)) != 0)
- goto out;
-
- /* save session id */
- if (kex->session_id == NULL) {
- kex->session_id_len = hashlen;
- kex->session_id = malloc(kex->session_id_len);
- if (kex->session_id == NULL) {
- r = SSH_ERR_ALLOC_FAIL;
- goto out;
- }
- memcpy(kex->session_id, hash, kex->session_id_len);
- }
-
- if ((r = kex_derive_keys_bn(ssh, hash, hashlen, shared_secret)) == 0)
- r = kex_send_newkeys(ssh);
- out:
- explicit_bzero(hash, sizeof(hash));
- DH_free(kex->dh);
- kex->dh = NULL;
- BN_clear_free(dh_server_pub);
- if (kbuf) {
- explicit_bzero(kbuf, klen);
- free(kbuf);
- }
- BN_clear_free(shared_secret);
- sshkey_free(server_host_key);
- free(server_host_key_blob);
- free(signature);
- return r;
-}
-#endif /* WITH_OPENSSL */
diff --git a/crypto/openssh/kexdhs.c b/crypto/openssh/kexdhs.c
deleted file mode 100644
index 337aab5beb41..000000000000
--- a/crypto/openssh/kexdhs.c
+++ /dev/null
@@ -1,222 +0,0 @@
-/* $OpenBSD: kexdhs.c,v 1.27 2018/04/10 00:10:49 djm 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.
- */
-
-#include "includes.h"
-
-#ifdef WITH_OPENSSL
-
-#include <sys/types.h>
-
-#include <stdarg.h>
-#include <string.h>
-#include <signal.h>
-
-#include <openssl/dh.h>
-
-#include "openbsd-compat/openssl-compat.h"
-
-#include "sshkey.h"
-#include "cipher.h"
-#include "digest.h"
-#include "kex.h"
-#include "log.h"
-#include "packet.h"
-#include "dh.h"
-#include "ssh2.h"
-
-#include "dispatch.h"
-#include "compat.h"
-#include "ssherr.h"
-#include "sshbuf.h"
-
-static int input_kex_dh_init(int, u_int32_t, struct ssh *);
-
-int
-kexdh_server(struct ssh *ssh)
-{
- struct kex *kex = ssh->kex;
- int r;
-
- /* generate server DH public key */
- switch (kex->kex_type) {
- case KEX_DH_GRP1_SHA1:
- kex->dh = dh_new_group1();
- break;
- case KEX_DH_GRP14_SHA1:
- case KEX_DH_GRP14_SHA256:
- kex->dh = dh_new_group14();
- break;
- case KEX_DH_GRP16_SHA512:
- kex->dh = dh_new_group16();
- break;
- case KEX_DH_GRP18_SHA512:
- kex->dh = dh_new_group18();
- break;
- default:
- r = SSH_ERR_INVALID_ARGUMENT;
- goto out;
- }
- if (kex->dh == NULL) {
- r = SSH_ERR_ALLOC_FAIL;
- goto out;
- }
- if ((r = dh_gen_key(kex->dh, kex->we_need * 8)) != 0)
- goto out;
-
- debug("expecting SSH2_MSG_KEXDH_INIT");
- ssh_dispatch_set(ssh, SSH2_MSG_KEXDH_INIT, &input_kex_dh_init);
- r = 0;
- out:
- return r;
-}
-
-int
-input_kex_dh_init(int type, u_int32_t seq, struct ssh *ssh)
-{
- struct kex *kex = ssh->kex;
- BIGNUM *shared_secret = NULL, *dh_client_pub = NULL;
- const BIGNUM *pub_key;
- struct sshkey *server_host_public, *server_host_private;
- u_char *kbuf = NULL, *signature = NULL, *server_host_key_blob = NULL;
- u_char hash[SSH_DIGEST_MAX_LENGTH];
- size_t sbloblen, slen;
- size_t klen = 0, hashlen;
- int kout, r;
-
- if (kex->load_host_public_key == NULL ||
- kex->load_host_private_key == NULL) {
- r = SSH_ERR_INVALID_ARGUMENT;
- goto out;
- }
- server_host_public = kex->load_host_public_key(kex->hostkey_type,
- kex->hostkey_nid, ssh);
- server_host_private = kex->load_host_private_key(kex->hostkey_type,
- kex->hostkey_nid, ssh);
- if (server_host_public == NULL) {
- r = SSH_ERR_NO_HOSTKEY_LOADED;
- goto out;
- }
-
- /* key, cert */
- if ((dh_client_pub = BN_new()) == NULL) {
- r = SSH_ERR_ALLOC_FAIL;
- goto out;
- }
- DH_get0_key(kex->dh, &pub_key, NULL);
- if ((r = sshpkt_get_bignum2(ssh, dh_client_pub)) != 0 ||
- (r = sshpkt_get_end(ssh)) != 0)
- goto out;
-
-#ifdef DEBUG_KEXDH
- fprintf(stderr, "dh_client_pub= ");
- BN_print_fp(stderr, dh_client_pub);
- fprintf(stderr, "\n");
- debug("bits %d", BN_num_bits(dh_client_pub));
- DHparams_print_fp(stderr, kex->dh);
- fprintf(stderr, "pub= ");
- BN_print_fp(stderr, pub_key);
- fprintf(stderr, "\n");
-#endif
- if (!dh_pub_is_valid(kex->dh, dh_client_pub)) {
- sshpkt_disconnect(ssh, "bad client public DH value");
- r = SSH_ERR_MESSAGE_INCOMPLETE;
- goto out;
- }
-
- klen = DH_size(kex->dh);
- if ((kbuf = malloc(klen)) == NULL ||
- (shared_secret = BN_new()) == NULL) {
- r = SSH_ERR_ALLOC_FAIL;
- goto out;
- }
- if ((kout = DH_compute_key(kbuf, dh_client_pub, kex->dh)) < 0 ||
- BN_bin2bn(kbuf, kout, shared_secret) == NULL) {
- r = SSH_ERR_LIBCRYPTO_ERROR;
- goto out;
- }
-#ifdef DEBUG_KEXDH
- dump_digest("shared secret", kbuf, kout);
-#endif
- if ((r = sshkey_to_blob(server_host_public, &server_host_key_blob,
- &sbloblen)) != 0)
- goto out;
- /* calc H */
- hashlen = sizeof(hash);
- if ((r = kex_dh_hash(
- kex->hash_alg,
- kex->client_version_string,
- kex->server_version_string,
- sshbuf_ptr(kex->peer), sshbuf_len(kex->peer),
- sshbuf_ptr(kex->my), sshbuf_len(kex->my),
- server_host_key_blob, sbloblen,
- dh_client_pub,
- pub_key,
- shared_secret,
- hash, &hashlen)) != 0)
- goto out;
-
- /* save session id := H */
- if (kex->session_id == NULL) {
- kex->session_id_len = hashlen;
- kex->session_id = malloc(kex->session_id_len);
- if (kex->session_id == NULL) {
- r = SSH_ERR_ALLOC_FAIL;
- goto out;
- }
- memcpy(kex->session_id, hash, kex->session_id_len);
- }
-
- /* sign H */
- if ((r = kex->sign(server_host_private, server_host_public, &signature,
- &slen, hash, hashlen, kex->hostkey_alg, ssh->compat)) < 0)
- goto out;
-
- /* destroy_sensitive_data(); */
-
- /* send server hostkey, DH pubkey 'f' and signed H */
- if ((r = sshpkt_start(ssh, SSH2_MSG_KEXDH_REPLY)) != 0 ||
- (r = sshpkt_put_string(ssh, server_host_key_blob, sbloblen)) != 0 ||
- (r = sshpkt_put_bignum2(ssh, pub_key)) != 0 || /* f */
- (r = sshpkt_put_string(ssh, signature, slen)) != 0 ||
- (r = sshpkt_send(ssh)) != 0)
- goto out;
-
- if ((r = kex_derive_keys_bn(ssh, hash, hashlen, shared_secret)) == 0)
- r = kex_send_newkeys(ssh);
- out:
- explicit_bzero(hash, sizeof(hash));
- DH_free(kex->dh);
- kex->dh = NULL;
- BN_clear_free(dh_client_pub);
- if (kbuf) {
- explicit_bzero(kbuf, klen);
- free(kbuf);
- }
- BN_clear_free(shared_secret);
- free(server_host_key_blob);
- free(signature);
- return r;
-}
-#endif /* WITH_OPENSSL */
diff --git a/crypto/openssh/kexecdh.c b/crypto/openssh/kexecdh.c
index 2a4fec6b124c..efb2e55a6d42 100644
--- a/crypto/openssh/kexecdh.c
+++ b/crypto/openssh/kexecdh.c
@@ -1,7 +1,7 @@
-/* $OpenBSD: kexecdh.c,v 1.6 2015/01/19 20:16:15 markus Exp $ */
+/* $OpenBSD: kexecdh.c,v 1.10 2019/01/21 10:40:11 djm Exp $ */
/*
- * Copyright (c) 2001 Markus Friedl. All rights reserved.
* Copyright (c) 2010 Damien Miller. All rights reserved.
+ * Copyright (c) 2019 Markus Friedl. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -30,71 +30,210 @@
#include <sys/types.h>
-#include <signal.h>
+#include <stdio.h>
#include <string.h>
+#include <signal.h>
-#include <openssl/bn.h>
-#include <openssl/evp.h>
-#include <openssl/ec.h>
#include <openssl/ecdh.h>
-#include "ssh2.h"
#include "sshkey.h"
-#include "cipher.h"
#include "kex.h"
#include "sshbuf.h"
#include "digest.h"
#include "ssherr.h"
+static int
+kex_ecdh_dec_key_group(struct kex *, const struct sshbuf *, EC_KEY *key,
+ const EC_GROUP *, struct sshbuf **);
+
int
-kex_ecdh_hash(
- int hash_alg,
- const EC_GROUP *ec_group,
- const char *client_version_string,
- const char *server_version_string,
- const u_char *ckexinit, size_t ckexinitlen,
- const u_char *skexinit, size_t skexinitlen,
- const u_char *serverhostkeyblob, size_t sbloblen,
- const EC_POINT *client_dh_pub,
- const EC_POINT *server_dh_pub,
- const BIGNUM *shared_secret,
- u_char *hash, size_t *hashlen)
+kex_ecdh_keypair(struct kex *kex)
{
- struct sshbuf *b;
+ EC_KEY *client_key = NULL;
+ const EC_GROUP *group;
+ const EC_POINT *public_key;
+ struct sshbuf *buf = NULL;
int r;
- if (*hashlen < ssh_digest_bytes(hash_alg))
- return SSH_ERR_INVALID_ARGUMENT;
- if ((b = sshbuf_new()) == NULL)
- return SSH_ERR_ALLOC_FAIL;
- if ((r = sshbuf_put_cstring(b, client_version_string)) != 0 ||
- (r = sshbuf_put_cstring(b, server_version_string)) != 0 ||
- /* kexinit messages: fake header: len+SSH2_MSG_KEXINIT */
- (r = sshbuf_put_u32(b, ckexinitlen+1)) != 0 ||
- (r = sshbuf_put_u8(b, SSH2_MSG_KEXINIT)) != 0 ||
- (r = sshbuf_put(b, ckexinit, ckexinitlen)) != 0 ||
- (r = sshbuf_put_u32(b, skexinitlen+1)) != 0 ||
- (r = sshbuf_put_u8(b, SSH2_MSG_KEXINIT)) != 0 ||
- (r = sshbuf_put(b, skexinit, skexinitlen)) != 0 ||
- (r = sshbuf_put_string(b, serverhostkeyblob, sbloblen)) != 0 ||
- (r = sshbuf_put_ec(b, client_dh_pub, ec_group)) != 0 ||
- (r = sshbuf_put_ec(b, server_dh_pub, ec_group)) != 0 ||
- (r = sshbuf_put_bignum2(b, shared_secret)) != 0) {
- sshbuf_free(b);
- return r;
+ if ((client_key = EC_KEY_new_by_curve_name(kex->ec_nid)) == NULL) {
+ r = SSH_ERR_ALLOC_FAIL;
+ goto out;
+ }
+ if (EC_KEY_generate_key(client_key) != 1) {
+ r = SSH_ERR_LIBCRYPTO_ERROR;
+ goto out;
}
-#ifdef DEBUG_KEX
- sshbuf_dump(b, stderr);
+ group = EC_KEY_get0_group(client_key);
+ public_key = EC_KEY_get0_public_key(client_key);
+
+ if ((buf = sshbuf_new()) == NULL) {
+ r = SSH_ERR_ALLOC_FAIL;
+ goto out;
+ }
+ if ((r = sshbuf_put_ec(buf, public_key, group)) != 0 ||
+ (r = sshbuf_get_u32(buf, NULL)) != 0)
+ goto out;
+#ifdef DEBUG_KEXECDH
+ fputs("client private key:\n", stderr);
+ sshkey_dump_ec_key(client_key);
#endif
- if (ssh_digest_buffer(hash_alg, b, hash, *hashlen) != 0) {
- sshbuf_free(b);
- return SSH_ERR_LIBCRYPTO_ERROR;
+ kex->ec_client_key = client_key;
+ kex->ec_group = group;
+ client_key = NULL; /* owned by the kex */
+ kex->client_pub = buf;
+ buf = NULL;
+ out:
+ EC_KEY_free(client_key);
+ sshbuf_free(buf);
+ return r;
+}
+
+int
+kex_ecdh_enc(struct kex *kex, const struct sshbuf *client_blob,
+ struct sshbuf **server_blobp, struct sshbuf **shared_secretp)
+{
+ const EC_GROUP *group;
+ const EC_POINT *pub_key;
+ EC_KEY *server_key = NULL;
+ struct sshbuf *server_blob = NULL;
+ int r;
+
+ *server_blobp = NULL;
+ *shared_secretp = NULL;
+
+ if ((server_key = EC_KEY_new_by_curve_name(kex->ec_nid)) == NULL) {
+ r = SSH_ERR_ALLOC_FAIL;
+ goto out;
+ }
+ if (EC_KEY_generate_key(server_key) != 1) {
+ r = SSH_ERR_LIBCRYPTO_ERROR;
+ goto out;
}
- sshbuf_free(b);
- *hashlen = ssh_digest_bytes(hash_alg);
-#ifdef DEBUG_KEX
- dump_digest("hash", hash, *hashlen);
+ group = EC_KEY_get0_group(server_key);
+
+#ifdef DEBUG_KEXECDH
+ fputs("server private key:\n", stderr);
+ sshkey_dump_ec_key(server_key);
+#endif
+ pub_key = EC_KEY_get0_public_key(server_key);
+ if ((server_blob = sshbuf_new()) == NULL) {
+ r = SSH_ERR_ALLOC_FAIL;
+ goto out;
+ }
+ if ((r = sshbuf_put_ec(server_blob, pub_key, group)) != 0 ||
+ (r = sshbuf_get_u32(server_blob, NULL)) != 0)
+ goto out;
+ if ((r = kex_ecdh_dec_key_group(kex, client_blob, server_key, group,
+ shared_secretp)) != 0)
+ goto out;
+ *server_blobp = server_blob;
+ server_blob = NULL;
+ out:
+ EC_KEY_free(server_key);
+ sshbuf_free(server_blob);
+ return r;
+}
+
+static int
+kex_ecdh_dec_key_group(struct kex *kex, const struct sshbuf *ec_blob,
+ EC_KEY *key, const EC_GROUP *group, struct sshbuf **shared_secretp)
+{
+ struct sshbuf *buf = NULL;
+ BIGNUM *shared_secret = NULL;
+ EC_POINT *dh_pub = NULL;
+ u_char *kbuf = NULL;
+ size_t klen = 0;
+ int r;
+
+ *shared_secretp = NULL;
+
+ if ((buf = sshbuf_new()) == NULL) {
+ r = SSH_ERR_ALLOC_FAIL;
+ goto out;
+ }
+ if ((r = sshbuf_put_stringb(buf, ec_blob)) != 0)
+ goto out;
+ if ((dh_pub = EC_POINT_new(group)) == NULL) {
+ r = SSH_ERR_ALLOC_FAIL;
+ goto out;
+ }
+ if ((r = sshbuf_get_ec(buf, dh_pub, group)) != 0) {
+ goto out;
+ }
+ sshbuf_reset(buf);
+
+#ifdef DEBUG_KEXECDH
+ fputs("public key:\n", stderr);
+ sshkey_dump_ec_point(group, dh_pub);
#endif
- return 0;
+ if (sshkey_ec_validate_public(group, dh_pub) != 0) {
+ r = SSH_ERR_MESSAGE_INCOMPLETE;
+ goto out;
+ }
+ klen = (EC_GROUP_get_degree(group) + 7) / 8;
+ if ((kbuf = malloc(klen)) == NULL ||
+ (shared_secret = BN_new()) == NULL) {
+ r = SSH_ERR_ALLOC_FAIL;
+ goto out;
+ }
+ if (ECDH_compute_key(kbuf, klen, dh_pub, key, NULL) != (int)klen ||
+ BN_bin2bn(kbuf, klen, shared_secret) == NULL) {
+ r = SSH_ERR_LIBCRYPTO_ERROR;
+ goto out;
+ }
+#ifdef DEBUG_KEXECDH
+ dump_digest("shared secret", kbuf, klen);
+#endif
+ if ((r = sshbuf_put_bignum2(buf, shared_secret)) != 0)
+ goto out;
+ *shared_secretp = buf;
+ buf = NULL;
+ out:
+ EC_POINT_clear_free(dh_pub);
+ BN_clear_free(shared_secret);
+ freezero(kbuf, klen);
+ sshbuf_free(buf);
+ return r;
+}
+
+int
+kex_ecdh_dec(struct kex *kex, const struct sshbuf *server_blob,
+ struct sshbuf **shared_secretp)
+{
+ int r;
+
+ r = kex_ecdh_dec_key_group(kex, server_blob, kex->ec_client_key,
+ kex->ec_group, shared_secretp);
+ EC_KEY_free(kex->ec_client_key);
+ kex->ec_client_key = NULL;
+ return r;
+}
+
+#else
+
+#include "ssherr.h"
+
+struct kex;
+struct sshbuf;
+struct sshkey;
+
+int
+kex_ecdh_keypair(struct kex *kex)
+{
+ return SSH_ERR_SIGN_ALG_UNSUPPORTED;
+}
+
+int
+kex_ecdh_enc(struct kex *kex, const struct sshbuf *client_blob,
+ struct sshbuf **server_blobp, struct sshbuf **shared_secretp)
+{
+ return SSH_ERR_SIGN_ALG_UNSUPPORTED;
+}
+
+int
+kex_ecdh_dec(struct kex *kex, const struct sshbuf *server_blob,
+ struct sshbuf **shared_secretp)
+{
+ return SSH_ERR_SIGN_ALG_UNSUPPORTED;
}
#endif /* defined(WITH_OPENSSL) && defined(OPENSSL_HAS_ECC) */
diff --git a/crypto/openssh/kexecdhc.c b/crypto/openssh/kexecdhc.c
deleted file mode 100644
index ac146a362ee0..000000000000
--- a/crypto/openssh/kexecdhc.c
+++ /dev/null
@@ -1,222 +0,0 @@
-/* $OpenBSD: kexecdhc.c,v 1.13 2018/02/07 02:06:51 jsing Exp $ */
-/*
- * Copyright (c) 2001 Markus Friedl. All rights reserved.
- * Copyright (c) 2010 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"
-
-#if defined(WITH_OPENSSL) && defined(OPENSSL_HAS_ECC)
-
-#include <sys/types.h>
-
-#include <stdio.h>
-#include <string.h>
-#include <signal.h>
-
-#include <openssl/ecdh.h>
-
-#include "sshkey.h"
-#include "cipher.h"
-#include "digest.h"
-#include "kex.h"
-#include "log.h"
-#include "packet.h"
-#include "dh.h"
-#include "ssh2.h"
-#include "dispatch.h"
-#include "compat.h"
-#include "ssherr.h"
-#include "sshbuf.h"
-
-static int input_kex_ecdh_reply(int, u_int32_t, struct ssh *);
-
-int
-kexecdh_client(struct ssh *ssh)
-{
- struct kex *kex = ssh->kex;
- EC_KEY *client_key = NULL;
- const EC_GROUP *group;
- const EC_POINT *public_key;
- int r;
-
- if ((client_key = EC_KEY_new_by_curve_name(kex->ec_nid)) == NULL) {
- r = SSH_ERR_ALLOC_FAIL;
- goto out;
- }
- if (EC_KEY_generate_key(client_key) != 1) {
- r = SSH_ERR_LIBCRYPTO_ERROR;
- goto out;
- }
- group = EC_KEY_get0_group(client_key);
- public_key = EC_KEY_get0_public_key(client_key);
-
- if ((r = sshpkt_start(ssh, SSH2_MSG_KEX_ECDH_INIT)) != 0 ||
- (r = sshpkt_put_ec(ssh, public_key, group)) != 0 ||
- (r = sshpkt_send(ssh)) != 0)
- goto out;
- debug("sending SSH2_MSG_KEX_ECDH_INIT");
-
-#ifdef DEBUG_KEXECDH
- fputs("client private key:\n", stderr);
- sshkey_dump_ec_key(client_key);
-#endif
- kex->ec_client_key = client_key;
- kex->ec_group = group;
- client_key = NULL; /* owned by the kex */
-
- debug("expecting SSH2_MSG_KEX_ECDH_REPLY");
- ssh_dispatch_set(ssh, SSH2_MSG_KEX_ECDH_REPLY, &input_kex_ecdh_reply);
- r = 0;
- out:
- EC_KEY_free(client_key);
- return r;
-}
-
-static int
-input_kex_ecdh_reply(int type, u_int32_t seq, struct ssh *ssh)
-{
- struct kex *kex = ssh->kex;
- const EC_GROUP *group;
- EC_POINT *server_public = NULL;
- EC_KEY *client_key;
- BIGNUM *shared_secret = NULL;
- struct sshkey *server_host_key = NULL;
- u_char *server_host_key_blob = NULL, *signature = NULL;
- u_char *kbuf = NULL;
- u_char hash[SSH_DIGEST_MAX_LENGTH];
- size_t slen, sbloblen;
- size_t klen = 0, hashlen;
- int r;
-
- if (kex->verify_host_key == NULL) {
- r = SSH_ERR_INVALID_ARGUMENT;
- goto out;
- }
- group = kex->ec_group;
- client_key = kex->ec_client_key;
-
- /* hostkey */
- if ((r = sshpkt_get_string(ssh, &server_host_key_blob,
- &sbloblen)) != 0 ||
- (r = sshkey_from_blob(server_host_key_blob, sbloblen,
- &server_host_key)) != 0)
- goto out;
- if (server_host_key->type != kex->hostkey_type ||
- (kex->hostkey_type == KEY_ECDSA &&
- server_host_key->ecdsa_nid != kex->hostkey_nid)) {
- r = SSH_ERR_KEY_TYPE_MISMATCH;
- goto out;
- }
- if (kex->verify_host_key(server_host_key, ssh) == -1) {
- r = SSH_ERR_SIGNATURE_INVALID;
- goto out;
- }
-
- /* Q_S, server public key */
- /* signed H */
- if ((server_public = EC_POINT_new(group)) == NULL) {
- r = SSH_ERR_ALLOC_FAIL;
- goto out;
- }
- if ((r = sshpkt_get_ec(ssh, server_public, group)) != 0 ||
- (r = sshpkt_get_string(ssh, &signature, &slen)) != 0 ||
- (r = sshpkt_get_end(ssh)) != 0)
- goto out;
-
-#ifdef DEBUG_KEXECDH
- fputs("server public key:\n", stderr);
- sshkey_dump_ec_point(group, server_public);
-#endif
- if (sshkey_ec_validate_public(group, server_public) != 0) {
- sshpkt_disconnect(ssh, "invalid server public key");
- r = SSH_ERR_MESSAGE_INCOMPLETE;
- goto out;
- }
-
- klen = (EC_GROUP_get_degree(group) + 7) / 8;
- if ((kbuf = malloc(klen)) == NULL ||
- (shared_secret = BN_new()) == NULL) {
- r = SSH_ERR_ALLOC_FAIL;
- goto out;
- }
- if (ECDH_compute_key(kbuf, klen, server_public,
- client_key, NULL) != (int)klen ||
- BN_bin2bn(kbuf, klen, shared_secret) == NULL) {
- r = SSH_ERR_LIBCRYPTO_ERROR;
- goto out;
- }
-
-#ifdef DEBUG_KEXECDH
- dump_digest("shared secret", kbuf, klen);
-#endif
- /* calc and verify H */
- hashlen = sizeof(hash);
- if ((r = kex_ecdh_hash(
- kex->hash_alg,
- group,
- kex->client_version_string,
- kex->server_version_string,
- sshbuf_ptr(kex->my), sshbuf_len(kex->my),
- sshbuf_ptr(kex->peer), sshbuf_len(kex->peer),
- server_host_key_blob, sbloblen,
- EC_KEY_get0_public_key(client_key),
- server_public,
- shared_secret,
- hash, &hashlen)) != 0)
- goto out;
-
- if ((r = sshkey_verify(server_host_key, signature, slen, hash,
- hashlen, kex->hostkey_alg, ssh->compat)) != 0)
- goto out;
-
- /* save session id */
- if (kex->session_id == NULL) {
- kex->session_id_len = hashlen;
- kex->session_id = malloc(kex->session_id_len);
- if (kex->session_id == NULL) {
- r = SSH_ERR_ALLOC_FAIL;
- goto out;
- }
- memcpy(kex->session_id, hash, kex->session_id_len);
- }
-
- if ((r = kex_derive_keys_bn(ssh, hash, hashlen, shared_secret)) == 0)
- r = kex_send_newkeys(ssh);
- out:
- explicit_bzero(hash, sizeof(hash));
- EC_KEY_free(kex->ec_client_key);
- kex->ec_client_key = NULL;
- EC_POINT_clear_free(server_public);
- if (kbuf) {
- explicit_bzero(kbuf, klen);
- free(kbuf);
- }
- BN_clear_free(shared_secret);
- sshkey_free(server_host_key);
- free(server_host_key_blob);
- free(signature);
- return r;
-}
-#endif /* defined(WITH_OPENSSL) && defined(OPENSSL_HAS_ECC) */
-
diff --git a/crypto/openssh/kexecdhs.c b/crypto/openssh/kexecdhs.c
deleted file mode 100644
index af4f30309971..000000000000
--- a/crypto/openssh/kexecdhs.c
+++ /dev/null
@@ -1,203 +0,0 @@
-/* $OpenBSD: kexecdhs.c,v 1.17 2018/02/07 02:06:51 jsing Exp $ */
-/*
- * Copyright (c) 2001 Markus Friedl. All rights reserved.
- * Copyright (c) 2010 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"
-
-#if defined(WITH_OPENSSL) && defined(OPENSSL_HAS_ECC)
-
-#include <sys/types.h>
-#include <string.h>
-#include <signal.h>
-
-#include <openssl/ecdh.h>
-
-#include "sshkey.h"
-#include "cipher.h"
-#include "digest.h"
-#include "kex.h"
-#include "log.h"
-#include "packet.h"
-#include "ssh2.h"
-
-#include "dispatch.h"
-#include "compat.h"
-#include "ssherr.h"
-#include "sshbuf.h"
-
-static int input_kex_ecdh_init(int, u_int32_t, struct ssh *);
-
-int
-kexecdh_server(struct ssh *ssh)
-{
- debug("expecting SSH2_MSG_KEX_ECDH_INIT");
- ssh_dispatch_set(ssh, SSH2_MSG_KEX_ECDH_INIT, &input_kex_ecdh_init);
- return 0;
-}
-
-static int
-input_kex_ecdh_init(int type, u_int32_t seq, struct ssh *ssh)
-{
- struct kex *kex = ssh->kex;
- EC_POINT *client_public;
- EC_KEY *server_key = NULL;
- const EC_GROUP *group;
- const EC_POINT *public_key;
- BIGNUM *shared_secret = NULL;
- struct sshkey *server_host_private, *server_host_public;
- u_char *server_host_key_blob = NULL, *signature = NULL;
- u_char *kbuf = NULL;
- u_char hash[SSH_DIGEST_MAX_LENGTH];
- size_t slen, sbloblen;
- size_t klen = 0, hashlen;
- int r;
-
- if ((server_key = EC_KEY_new_by_curve_name(kex->ec_nid)) == NULL) {
- r = SSH_ERR_ALLOC_FAIL;
- goto out;
- }
- if (EC_KEY_generate_key(server_key) != 1) {
- r = SSH_ERR_LIBCRYPTO_ERROR;
- goto out;
- }
- group = EC_KEY_get0_group(server_key);
-
-#ifdef DEBUG_KEXECDH
- fputs("server private key:\n", stderr);
- sshkey_dump_ec_key(server_key);
-#endif
-
- if (kex->load_host_public_key == NULL ||
- kex->load_host_private_key == NULL) {
- r = SSH_ERR_INVALID_ARGUMENT;
- goto out;
- }
- server_host_public = kex->load_host_public_key(kex->hostkey_type,
- kex->hostkey_nid, ssh);
- server_host_private = kex->load_host_private_key(kex->hostkey_type,
- kex->hostkey_nid, ssh);
- if (server_host_public == NULL) {
- r = SSH_ERR_NO_HOSTKEY_LOADED;
- goto out;
- }
- if ((client_public = EC_POINT_new(group)) == NULL) {
- r = SSH_ERR_ALLOC_FAIL;
- goto out;
- }
- if ((r = sshpkt_get_ec(ssh, client_public, group)) != 0 ||
- (r = sshpkt_get_end(ssh)) != 0)
- goto out;
-
-#ifdef DEBUG_KEXECDH
- fputs("client public key:\n", stderr);
- sshkey_dump_ec_point(group, client_public);
-#endif
- if (sshkey_ec_validate_public(group, client_public) != 0) {
- sshpkt_disconnect(ssh, "invalid client public key");
- r = SSH_ERR_MESSAGE_INCOMPLETE;
- goto out;
- }
-
- /* Calculate shared_secret */
- klen = (EC_GROUP_get_degree(group) + 7) / 8;
- if ((kbuf = malloc(klen)) == NULL ||
- (shared_secret = BN_new()) == NULL) {
- r = SSH_ERR_ALLOC_FAIL;
- goto out;
- }
- if (ECDH_compute_key(kbuf, klen, client_public,
- server_key, NULL) != (int)klen ||
- BN_bin2bn(kbuf, klen, shared_secret) == NULL) {
- r = SSH_ERR_LIBCRYPTO_ERROR;
- goto out;
- }
-
-#ifdef DEBUG_KEXECDH
- dump_digest("shared secret", kbuf, klen);
-#endif
- /* calc H */
- if ((r = sshkey_to_blob(server_host_public, &server_host_key_blob,
- &sbloblen)) != 0)
- goto out;
- hashlen = sizeof(hash);
- if ((r = kex_ecdh_hash(
- kex->hash_alg,
- group,
- kex->client_version_string,
- kex->server_version_string,
- sshbuf_ptr(kex->peer), sshbuf_len(kex->peer),
- sshbuf_ptr(kex->my), sshbuf_len(kex->my),
- server_host_key_blob, sbloblen,
- client_public,
- EC_KEY_get0_public_key(server_key),
- shared_secret,
- hash, &hashlen)) != 0)
- goto out;
-
- /* save session id := H */
- if (kex->session_id == NULL) {
- kex->session_id_len = hashlen;
- kex->session_id = malloc(kex->session_id_len);
- if (kex->session_id == NULL) {
- r = SSH_ERR_ALLOC_FAIL;
- goto out;
- }
- memcpy(kex->session_id, hash, kex->session_id_len);
- }
-
- /* sign H */
- if ((r = kex->sign(server_host_private, server_host_public, &signature,
- &slen, hash, hashlen, kex->hostkey_alg, ssh->compat)) < 0)
- goto out;
-
- /* destroy_sensitive_data(); */
-
- public_key = EC_KEY_get0_public_key(server_key);
- /* send server hostkey, ECDH pubkey 'Q_S' and signed H */
- if ((r = sshpkt_start(ssh, SSH2_MSG_KEX_ECDH_REPLY)) != 0 ||
- (r = sshpkt_put_string(ssh, server_host_key_blob, sbloblen)) != 0 ||
- (r = sshpkt_put_ec(ssh, public_key, group)) != 0 ||
- (r = sshpkt_put_string(ssh, signature, slen)) != 0 ||
- (r = sshpkt_send(ssh)) != 0)
- goto out;
-
- if ((r = kex_derive_keys_bn(ssh, hash, hashlen, shared_secret)) == 0)
- r = kex_send_newkeys(ssh);
- out:
- explicit_bzero(hash, sizeof(hash));
- EC_KEY_free(kex->ec_client_key);
- kex->ec_client_key = NULL;
- EC_KEY_free(server_key);
- if (kbuf) {
- explicit_bzero(kbuf, klen);
- free(kbuf);
- }
- BN_clear_free(shared_secret);
- free(server_host_key_blob);
- free(signature);
- return r;
-}
-#endif /* defined(WITH_OPENSSL) && defined(OPENSSL_HAS_ECC) */
-
diff --git a/crypto/openssh/kexgen.c b/crypto/openssh/kexgen.c
new file mode 100644
index 000000000000..bde28053ddf1
--- /dev/null
+++ b/crypto/openssh/kexgen.c
@@ -0,0 +1,346 @@
+/* $OpenBSD: kexgen.c,v 1.7 2021/04/03 06:18:40 djm Exp $ */
+/*
+ * Copyright (c) 2019 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"
+
+#include <sys/types.h>
+
+#include <stdarg.h>
+#include <stdio.h>
+#include <string.h>
+#include <signal.h>
+
+#include "sshkey.h"
+#include "kex.h"
+#include "log.h"
+#include "packet.h"
+#include "ssh2.h"
+#include "sshbuf.h"
+#include "digest.h"
+#include "ssherr.h"
+
+static int input_kex_gen_init(int, u_int32_t, struct ssh *);
+static int input_kex_gen_reply(int type, u_int32_t seq, struct ssh *ssh);
+
+static int
+kex_gen_hash(
+ int hash_alg,
+ const struct sshbuf *client_version,
+ const struct sshbuf *server_version,
+ const struct sshbuf *client_kexinit,
+ const struct sshbuf *server_kexinit,
+ const struct sshbuf *server_host_key_blob,
+ const struct sshbuf *client_pub,
+ const struct sshbuf *server_pub,
+ const struct sshbuf *shared_secret,
+ u_char *hash, size_t *hashlen)
+{
+ struct sshbuf *b;
+ int r;
+
+ if (*hashlen < ssh_digest_bytes(hash_alg))
+ return SSH_ERR_INVALID_ARGUMENT;
+ if ((b = sshbuf_new()) == NULL)
+ return SSH_ERR_ALLOC_FAIL;
+ if ((r = sshbuf_put_stringb(b, client_version)) != 0 ||
+ (r = sshbuf_put_stringb(b, server_version)) != 0 ||
+ /* kexinit messages: fake header: len+SSH2_MSG_KEXINIT */
+ (r = sshbuf_put_u32(b, sshbuf_len(client_kexinit) + 1)) != 0 ||
+ (r = sshbuf_put_u8(b, SSH2_MSG_KEXINIT)) != 0 ||
+ (r = sshbuf_putb(b, client_kexinit)) != 0 ||
+ (r = sshbuf_put_u32(b, sshbuf_len(server_kexinit) + 1)) != 0 ||
+ (r = sshbuf_put_u8(b, SSH2_MSG_KEXINIT)) != 0 ||
+ (r = sshbuf_putb(b, server_kexinit)) != 0 ||
+ (r = sshbuf_put_stringb(b, server_host_key_blob)) != 0 ||
+ (r = sshbuf_put_stringb(b, client_pub)) != 0 ||
+ (r = sshbuf_put_stringb(b, server_pub)) != 0 ||
+ (r = sshbuf_putb(b, shared_secret)) != 0) {
+ sshbuf_free(b);
+ return r;
+ }
+#ifdef DEBUG_KEX
+ sshbuf_dump(b, stderr);
+#endif
+ if (ssh_digest_buffer(hash_alg, b, hash, *hashlen) != 0) {
+ sshbuf_free(b);
+ return SSH_ERR_LIBCRYPTO_ERROR;
+ }
+ sshbuf_free(b);
+ *hashlen = ssh_digest_bytes(hash_alg);
+#ifdef DEBUG_KEX
+ dump_digest("hash", hash, *hashlen);
+#endif
+ return 0;
+}
+
+int
+kex_gen_client(struct ssh *ssh)
+{
+ struct kex *kex = ssh->kex;
+ int r;
+
+ switch (kex->kex_type) {
+#ifdef WITH_OPENSSL
+ case KEX_DH_GRP1_SHA1:
+ case KEX_DH_GRP14_SHA1:
+ case KEX_DH_GRP14_SHA256:
+ case KEX_DH_GRP16_SHA512:
+ case KEX_DH_GRP18_SHA512:
+ r = kex_dh_keypair(kex);
+ break;
+ case KEX_ECDH_SHA2:
+ r = kex_ecdh_keypair(kex);
+ break;
+#endif
+ case KEX_C25519_SHA256:
+ r = kex_c25519_keypair(kex);
+ break;
+ case KEX_KEM_SNTRUP761X25519_SHA512:
+ r = kex_kem_sntrup761x25519_keypair(kex);
+ break;
+ default:
+ r = SSH_ERR_INVALID_ARGUMENT;
+ break;
+ }
+ if (r != 0)
+ return r;
+ if ((r = sshpkt_start(ssh, SSH2_MSG_KEX_ECDH_INIT)) != 0 ||
+ (r = sshpkt_put_stringb(ssh, kex->client_pub)) != 0 ||
+ (r = sshpkt_send(ssh)) != 0)
+ return r;
+ debug("expecting SSH2_MSG_KEX_ECDH_REPLY");
+ ssh_dispatch_set(ssh, SSH2_MSG_KEX_ECDH_REPLY, &input_kex_gen_reply);
+ return 0;
+}
+
+static int
+input_kex_gen_reply(int type, u_int32_t seq, struct ssh *ssh)
+{
+ struct kex *kex = ssh->kex;
+ struct sshkey *server_host_key = NULL;
+ struct sshbuf *shared_secret = NULL;
+ struct sshbuf *server_blob = NULL;
+ struct sshbuf *tmp = NULL, *server_host_key_blob = NULL;
+ u_char *signature = NULL;
+ u_char hash[SSH_DIGEST_MAX_LENGTH];
+ size_t slen, hashlen;
+ int r;
+
+ debug("SSH2_MSG_KEX_ECDH_REPLY received");
+ ssh_dispatch_set(ssh, SSH2_MSG_KEX_ECDH_REPLY, &kex_protocol_error);
+
+ /* hostkey */
+ if ((r = sshpkt_getb_froms(ssh, &server_host_key_blob)) != 0)
+ goto out;
+ /* sshkey_fromb() consumes its buffer, so make a copy */
+ if ((tmp = sshbuf_fromb(server_host_key_blob)) == NULL) {
+ r = SSH_ERR_ALLOC_FAIL;
+ goto out;
+ }
+ if ((r = sshkey_fromb(tmp, &server_host_key)) != 0)
+ goto out;
+ if ((r = kex_verify_host_key(ssh, server_host_key)) != 0)
+ goto out;
+
+ /* Q_S, server public key */
+ /* signed H */
+ if ((r = sshpkt_getb_froms(ssh, &server_blob)) != 0 ||
+ (r = sshpkt_get_string(ssh, &signature, &slen)) != 0 ||
+ (r = sshpkt_get_end(ssh)) != 0)
+ goto out;
+
+ /* compute shared secret */
+ switch (kex->kex_type) {
+#ifdef WITH_OPENSSL
+ case KEX_DH_GRP1_SHA1:
+ case KEX_DH_GRP14_SHA1:
+ case KEX_DH_GRP14_SHA256:
+ case KEX_DH_GRP16_SHA512:
+ case KEX_DH_GRP18_SHA512:
+ r = kex_dh_dec(kex, server_blob, &shared_secret);
+ break;
+ case KEX_ECDH_SHA2:
+ r = kex_ecdh_dec(kex, server_blob, &shared_secret);
+ break;
+#endif
+ case KEX_C25519_SHA256:
+ r = kex_c25519_dec(kex, server_blob, &shared_secret);
+ break;
+ case KEX_KEM_SNTRUP761X25519_SHA512:
+ r = kex_kem_sntrup761x25519_dec(kex, server_blob,
+ &shared_secret);
+ break;
+ default:
+ r = SSH_ERR_INVALID_ARGUMENT;
+ break;
+ }
+ if (r !=0 )
+ goto out;
+
+ /* calc and verify H */
+ hashlen = sizeof(hash);
+ if ((r = kex_gen_hash(
+ kex->hash_alg,
+ kex->client_version,
+ kex->server_version,
+ kex->my,
+ kex->peer,
+ server_host_key_blob,
+ kex->client_pub,
+ server_blob,
+ shared_secret,
+ hash, &hashlen)) != 0)
+ goto out;
+
+ if ((r = sshkey_verify(server_host_key, signature, slen, hash, hashlen,
+ kex->hostkey_alg, ssh->compat, NULL)) != 0)
+ goto out;
+
+ if ((r = kex_derive_keys(ssh, hash, hashlen, shared_secret)) == 0)
+ r = kex_send_newkeys(ssh);
+out:
+ explicit_bzero(hash, sizeof(hash));
+ explicit_bzero(kex->c25519_client_key, sizeof(kex->c25519_client_key));
+ explicit_bzero(kex->sntrup761_client_key,
+ sizeof(kex->sntrup761_client_key));
+ sshbuf_free(server_host_key_blob);
+ free(signature);
+ sshbuf_free(tmp);
+ sshkey_free(server_host_key);
+ sshbuf_free(server_blob);
+ sshbuf_free(shared_secret);
+ sshbuf_free(kex->client_pub);
+ kex->client_pub = NULL;
+ return r;
+}
+
+int
+kex_gen_server(struct ssh *ssh)
+{
+ debug("expecting SSH2_MSG_KEX_ECDH_INIT");
+ ssh_dispatch_set(ssh, SSH2_MSG_KEX_ECDH_INIT, &input_kex_gen_init);
+ return 0;
+}
+
+static int
+input_kex_gen_init(int type, u_int32_t seq, struct ssh *ssh)
+{
+ struct kex *kex = ssh->kex;
+ struct sshkey *server_host_private, *server_host_public;
+ struct sshbuf *shared_secret = NULL;
+ struct sshbuf *server_pubkey = NULL;
+ struct sshbuf *client_pubkey = NULL;
+ struct sshbuf *server_host_key_blob = NULL;
+ u_char *signature = NULL, hash[SSH_DIGEST_MAX_LENGTH];
+ size_t slen, hashlen;
+ int r;
+
+ debug("SSH2_MSG_KEX_ECDH_INIT received");
+ ssh_dispatch_set(ssh, SSH2_MSG_KEX_ECDH_INIT, &kex_protocol_error);
+
+ if ((r = kex_load_hostkey(ssh, &server_host_private,
+ &server_host_public)) != 0)
+ goto out;
+
+ if ((r = sshpkt_getb_froms(ssh, &client_pubkey)) != 0 ||
+ (r = sshpkt_get_end(ssh)) != 0)
+ goto out;
+
+ /* compute shared secret */
+ switch (kex->kex_type) {
+#ifdef WITH_OPENSSL
+ case KEX_DH_GRP1_SHA1:
+ case KEX_DH_GRP14_SHA1:
+ case KEX_DH_GRP14_SHA256:
+ case KEX_DH_GRP16_SHA512:
+ case KEX_DH_GRP18_SHA512:
+ r = kex_dh_enc(kex, client_pubkey, &server_pubkey,
+ &shared_secret);
+ break;
+ case KEX_ECDH_SHA2:
+ r = kex_ecdh_enc(kex, client_pubkey, &server_pubkey,
+ &shared_secret);
+ break;
+#endif
+ case KEX_C25519_SHA256:
+ r = kex_c25519_enc(kex, client_pubkey, &server_pubkey,
+ &shared_secret);
+ break;
+ case KEX_KEM_SNTRUP761X25519_SHA512:
+ r = kex_kem_sntrup761x25519_enc(kex, client_pubkey,
+ &server_pubkey, &shared_secret);
+ break;
+ default:
+ r = SSH_ERR_INVALID_ARGUMENT;
+ break;
+ }
+ if (r !=0 )
+ goto out;
+
+ /* calc H */
+ if ((server_host_key_blob = sshbuf_new()) == NULL) {
+ r = SSH_ERR_ALLOC_FAIL;
+ goto out;
+ }
+ if ((r = sshkey_putb(server_host_public, server_host_key_blob)) != 0)
+ goto out;
+ hashlen = sizeof(hash);
+ if ((r = kex_gen_hash(
+ kex->hash_alg,
+ kex->client_version,
+ kex->server_version,
+ kex->peer,
+ kex->my,
+ server_host_key_blob,
+ client_pubkey,
+ server_pubkey,
+ shared_secret,
+ hash, &hashlen)) != 0)
+ goto out;
+
+ /* sign H */
+ if ((r = kex->sign(ssh, server_host_private, server_host_public,
+ &signature, &slen, hash, hashlen, kex->hostkey_alg)) != 0)
+ goto out;
+
+ /* send server hostkey, ECDH pubkey 'Q_S' and signed H */
+ if ((r = sshpkt_start(ssh, SSH2_MSG_KEX_ECDH_REPLY)) != 0 ||
+ (r = sshpkt_put_stringb(ssh, server_host_key_blob)) != 0 ||
+ (r = sshpkt_put_stringb(ssh, server_pubkey)) != 0 ||
+ (r = sshpkt_put_string(ssh, signature, slen)) != 0 ||
+ (r = sshpkt_send(ssh)) != 0)
+ goto out;
+
+ if ((r = kex_derive_keys(ssh, hash, hashlen, shared_secret)) == 0)
+ r = kex_send_newkeys(ssh);
+out:
+ explicit_bzero(hash, sizeof(hash));
+ sshbuf_free(server_host_key_blob);
+ free(signature);
+ sshbuf_free(shared_secret);
+ sshbuf_free(client_pubkey);
+ sshbuf_free(server_pubkey);
+ return r;
+}
diff --git a/crypto/openssh/kexgex.c b/crypto/openssh/kexgex.c
index 3ca4bd37000b..8040a13202fc 100644
--- a/crypto/openssh/kexgex.c
+++ b/crypto/openssh/kexgex.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kexgex.c,v 1.29 2015/01/19 20:16:15 markus Exp $ */
+/* $OpenBSD: kexgex.c,v 1.32 2019/01/23 00:30:41 djm Exp $ */
/*
* Copyright (c) 2000 Niels Provos. All rights reserved.
* Copyright (c) 2001 Markus Friedl. All rights reserved.
@@ -46,17 +46,17 @@
int
kexgex_hash(
int hash_alg,
- const char *client_version_string,
- const char *server_version_string,
- const u_char *ckexinit, size_t ckexinitlen,
- const u_char *skexinit, size_t skexinitlen,
- const u_char *serverhostkeyblob, size_t sbloblen,
+ const struct sshbuf *client_version,
+ const struct sshbuf *server_version,
+ const struct sshbuf *client_kexinit,
+ const struct sshbuf *server_kexinit,
+ const struct sshbuf *server_host_key_blob,
int min, int wantbits, int max,
const BIGNUM *prime,
const BIGNUM *gen,
const BIGNUM *client_dh_pub,
const BIGNUM *server_dh_pub,
- const BIGNUM *shared_secret,
+ const u_char *shared_secret, size_t secretlen,
u_char *hash, size_t *hashlen)
{
struct sshbuf *b;
@@ -66,16 +66,16 @@ kexgex_hash(
return SSH_ERR_INVALID_ARGUMENT;
if ((b = sshbuf_new()) == NULL)
return SSH_ERR_ALLOC_FAIL;
- if ((r = sshbuf_put_cstring(b, client_version_string)) != 0 ||
- (r = sshbuf_put_cstring(b, server_version_string)) != 0 ||
+ if ((r = sshbuf_put_stringb(b, client_version)) < 0 ||
+ (r = sshbuf_put_stringb(b, server_version)) < 0 ||
/* kexinit messages: fake header: len+SSH2_MSG_KEXINIT */
- (r = sshbuf_put_u32(b, ckexinitlen+1)) != 0 ||
+ (r = sshbuf_put_u32(b, sshbuf_len(client_kexinit) + 1)) != 0 ||
(r = sshbuf_put_u8(b, SSH2_MSG_KEXINIT)) != 0 ||
- (r = sshbuf_put(b, ckexinit, ckexinitlen)) != 0 ||
- (r = sshbuf_put_u32(b, skexinitlen+1)) != 0 ||
+ (r = sshbuf_putb(b, client_kexinit)) != 0 ||
+ (r = sshbuf_put_u32(b, sshbuf_len(server_kexinit) + 1)) != 0 ||
(r = sshbuf_put_u8(b, SSH2_MSG_KEXINIT)) != 0 ||
- (r = sshbuf_put(b, skexinit, skexinitlen)) != 0 ||
- (r = sshbuf_put_string(b, serverhostkeyblob, sbloblen)) != 0 ||
+ (r = sshbuf_putb(b, server_kexinit)) != 0 ||
+ (r = sshbuf_put_stringb(b, server_host_key_blob)) != 0 ||
(min != -1 && (r = sshbuf_put_u32(b, min)) != 0) ||
(r = sshbuf_put_u32(b, wantbits)) != 0 ||
(max != -1 && (r = sshbuf_put_u32(b, max)) != 0) ||
@@ -83,7 +83,7 @@ kexgex_hash(
(r = sshbuf_put_bignum2(b, gen)) != 0 ||
(r = sshbuf_put_bignum2(b, client_dh_pub)) != 0 ||
(r = sshbuf_put_bignum2(b, server_dh_pub)) != 0 ||
- (r = sshbuf_put_bignum2(b, shared_secret)) != 0) {
+ (r = sshbuf_put(b, shared_secret, secretlen)) != 0) {
sshbuf_free(b);
return r;
}
diff --git a/crypto/openssh/kexgexc.c b/crypto/openssh/kexgexc.c
index 0d07f73c794c..4a2e741d8458 100644
--- a/crypto/openssh/kexgexc.c
+++ b/crypto/openssh/kexgexc.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kexgexc.c,v 1.27 2018/02/07 02:06:51 jsing Exp $ */
+/* $OpenBSD: kexgexc.c,v 1.37 2021/01/31 22:55:29 djm Exp $ */
/*
* Copyright (c) 2000 Niels Provos. All rights reserved.
* Copyright (c) 2001 Markus Friedl. All rights reserved.
@@ -68,7 +68,7 @@ kexgex_client(struct ssh *ssh)
kex->min = DH_GRP_MIN;
kex->max = DH_GRP_MAX;
kex->nbits = nbits;
- if (datafellows & SSH_BUG_DHGEX_LARGE)
+ if (ssh->compat & SSH_BUG_DHGEX_LARGE)
kex->nbits = MINIMUM(kex->nbits, 4096);
/* New GEX request */
if ((r = sshpkt_start(ssh, SSH2_MSG_KEX_DH_GEX_REQUEST)) != 0 ||
@@ -83,6 +83,7 @@ kexgex_client(struct ssh *ssh)
fprintf(stderr, "\nmin = %d, nbits = %d, max = %d\n",
kex->min, kex->nbits, kex->max);
#endif
+ debug("expecting SSH2_MSG_KEX_DH_GEX_GROUP");
ssh_dispatch_set(ssh, SSH2_MSG_KEX_DH_GEX_GROUP,
&input_kex_dh_gex_group);
r = 0;
@@ -98,15 +99,11 @@ input_kex_dh_gex_group(int type, u_int32_t seq, struct ssh *ssh)
const BIGNUM *pub_key;
int r, bits;
- debug("got SSH2_MSG_KEX_DH_GEX_GROUP");
+ debug("SSH2_MSG_KEX_DH_GEX_GROUP received");
+ ssh_dispatch_set(ssh, SSH2_MSG_KEX_DH_GEX_GROUP, &kex_protocol_error);
- if ((p = BN_new()) == NULL ||
- (g = BN_new()) == NULL) {
- r = SSH_ERR_ALLOC_FAIL;
- goto out;
- }
- if ((r = sshpkt_get_bignum2(ssh, p)) != 0 ||
- (r = sshpkt_get_bignum2(ssh, g)) != 0 ||
+ if ((r = sshpkt_get_bignum2(ssh, &p)) != 0 ||
+ (r = sshpkt_get_bignum2(ssh, &g)) != 0 ||
(r = sshpkt_get_end(ssh)) != 0)
goto out;
if ((bits = BN_num_bits(p)) < 0 ||
@@ -135,7 +132,7 @@ input_kex_dh_gex_group(int type, u_int32_t seq, struct ssh *ssh)
BN_print_fp(stderr, pub_key);
fprintf(stderr, "\n");
#endif
- ssh_dispatch_set(ssh, SSH2_MSG_KEX_DH_GEX_GROUP, NULL);
+ debug("expecting SSH2_MSG_KEX_DH_GEX_REPLY");
ssh_dispatch_set(ssh, SSH2_MSG_KEX_DH_GEX_REPLY, &input_kex_dh_gex_reply);
r = 0;
out:
@@ -148,71 +145,41 @@ static int
input_kex_dh_gex_reply(int type, u_int32_t seq, struct ssh *ssh)
{
struct kex *kex = ssh->kex;
- BIGNUM *dh_server_pub = NULL, *shared_secret = NULL;
+ BIGNUM *dh_server_pub = NULL;
const BIGNUM *pub_key, *dh_p, *dh_g;
+ struct sshbuf *shared_secret = NULL;
+ struct sshbuf *tmp = NULL, *server_host_key_blob = NULL;
struct sshkey *server_host_key = NULL;
- u_char *kbuf = NULL, *signature = NULL, *server_host_key_blob = NULL;
+ u_char *signature = NULL;
u_char hash[SSH_DIGEST_MAX_LENGTH];
- size_t klen = 0, slen, sbloblen, hashlen;
- int kout, r;
+ size_t slen, hashlen;
+ int r;
+
+ debug("SSH2_MSG_KEX_DH_GEX_REPLY received");
+ ssh_dispatch_set(ssh, SSH2_MSG_KEX_DH_GEX_REPLY, &kex_protocol_error);
- debug("got SSH2_MSG_KEX_DH_GEX_REPLY");
- if (kex->verify_host_key == NULL) {
- r = SSH_ERR_INVALID_ARGUMENT;
- goto out;
- }
/* key, cert */
- if ((r = sshpkt_get_string(ssh, &server_host_key_blob,
- &sbloblen)) != 0 ||
- (r = sshkey_from_blob(server_host_key_blob, sbloblen,
- &server_host_key)) != 0)
- goto out;
- if (server_host_key->type != kex->hostkey_type ||
- (kex->hostkey_type == KEY_ECDSA &&
- server_host_key->ecdsa_nid != kex->hostkey_nid)) {
- r = SSH_ERR_KEY_TYPE_MISMATCH;
- goto out;
- }
- if (kex->verify_host_key(server_host_key, ssh) == -1) {
- r = SSH_ERR_SIGNATURE_INVALID;
+ if ((r = sshpkt_getb_froms(ssh, &server_host_key_blob)) != 0)
goto out;
- }
- /* DH parameter f, server public DH key */
- if ((dh_server_pub = BN_new()) == NULL) {
+ /* sshkey_fromb() consumes its buffer, so make a copy */
+ if ((tmp = sshbuf_fromb(server_host_key_blob)) == NULL) {
r = SSH_ERR_ALLOC_FAIL;
goto out;
}
- /* signed H */
- if ((r = sshpkt_get_bignum2(ssh, dh_server_pub)) != 0 ||
+ if ((r = sshkey_fromb(tmp, &server_host_key)) != 0 ||
+ (r = kex_verify_host_key(ssh, server_host_key)) != 0)
+ goto out;
+ /* DH parameter f, server public DH key, signed H */
+ if ((r = sshpkt_get_bignum2(ssh, &dh_server_pub)) != 0 ||
(r = sshpkt_get_string(ssh, &signature, &slen)) != 0 ||
(r = sshpkt_get_end(ssh)) != 0)
goto out;
-#ifdef DEBUG_KEXDH
- fprintf(stderr, "dh_server_pub= ");
- BN_print_fp(stderr, dh_server_pub);
- fprintf(stderr, "\n");
- debug("bits %d", BN_num_bits(dh_server_pub));
-#endif
- if (!dh_pub_is_valid(kex->dh, dh_server_pub)) {
- sshpkt_disconnect(ssh, "bad server public DH value");
- r = SSH_ERR_MESSAGE_INCOMPLETE;
- goto out;
- }
-
- klen = DH_size(kex->dh);
- if ((kbuf = malloc(klen)) == NULL ||
- (shared_secret = BN_new()) == NULL) {
+ if ((shared_secret = sshbuf_new()) == NULL) {
r = SSH_ERR_ALLOC_FAIL;
goto out;
}
- if ((kout = DH_compute_key(kbuf, dh_server_pub, kex->dh)) < 0 ||
- BN_bin2bn(kbuf, kout, shared_secret) == NULL) {
- r = SSH_ERR_LIBCRYPTO_ERROR;
+ if ((r = kex_dh_compute_key(kex, dh_server_pub, shared_secret)) != 0)
goto out;
- }
-#ifdef DEBUG_KEXDH
- dump_digest("shared secret", kbuf, kout);
-#endif
if (ssh->compat & SSH_OLD_DHGEX)
kex->min = kex->max = -1;
@@ -222,48 +189,34 @@ input_kex_dh_gex_reply(int type, u_int32_t seq, struct ssh *ssh)
hashlen = sizeof(hash);
if ((r = kexgex_hash(
kex->hash_alg,
- kex->client_version_string,
- kex->server_version_string,
- sshbuf_ptr(kex->my), sshbuf_len(kex->my),
- sshbuf_ptr(kex->peer), sshbuf_len(kex->peer),
- server_host_key_blob, sbloblen,
+ kex->client_version,
+ kex->server_version,
+ kex->my,
+ kex->peer,
+ server_host_key_blob,
kex->min, kex->nbits, kex->max,
dh_p, dh_g,
pub_key,
dh_server_pub,
- shared_secret,
+ sshbuf_ptr(shared_secret), sshbuf_len(shared_secret),
hash, &hashlen)) != 0)
goto out;
if ((r = sshkey_verify(server_host_key, signature, slen, hash,
- hashlen, kex->hostkey_alg, ssh->compat)) != 0)
+ hashlen, kex->hostkey_alg, ssh->compat, NULL)) != 0)
goto out;
- /* save session id */
- if (kex->session_id == NULL) {
- kex->session_id_len = hashlen;
- kex->session_id = malloc(kex->session_id_len);
- if (kex->session_id == NULL) {
- r = SSH_ERR_ALLOC_FAIL;
- goto out;
- }
- memcpy(kex->session_id, hash, kex->session_id_len);
- }
-
- if ((r = kex_derive_keys_bn(ssh, hash, hashlen, shared_secret)) == 0)
+ if ((r = kex_derive_keys(ssh, hash, hashlen, shared_secret)) == 0)
r = kex_send_newkeys(ssh);
out:
explicit_bzero(hash, sizeof(hash));
DH_free(kex->dh);
kex->dh = NULL;
BN_clear_free(dh_server_pub);
- if (kbuf) {
- explicit_bzero(kbuf, klen);
- free(kbuf);
- }
- BN_clear_free(shared_secret);
+ sshbuf_free(shared_secret);
sshkey_free(server_host_key);
- free(server_host_key_blob);
+ sshbuf_free(tmp);
+ sshbuf_free(server_host_key_blob);
free(signature);
return r;
}
diff --git a/crypto/openssh/kexgexs.c b/crypto/openssh/kexgexs.c
index dc9c0bc6024d..f0fbcb912543 100644
--- a/crypto/openssh/kexgexs.c
+++ b/crypto/openssh/kexgexs.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kexgexs.c,v 1.35 2018/10/04 00:04:41 djm Exp $ */
+/* $OpenBSD: kexgexs.c,v 1.43 2021/01/31 22:55:29 djm Exp $ */
/*
* Copyright (c) 2000 Niels Provos. All rights reserved.
* Copyright (c) 2001 Markus Friedl. All rights reserved.
@@ -77,6 +77,8 @@ input_kex_dh_gex_request(int type, u_int32_t seq, struct ssh *ssh)
const BIGNUM *dh_p, *dh_g;
debug("SSH2_MSG_KEX_DH_GEX_REQUEST received");
+ ssh_dispatch_set(ssh, SSH2_MSG_KEX_DH_GEX_REQUEST, &kex_protocol_error);
+
if ((r = sshpkt_get_u32(ssh, &min)) != 0 ||
(r = sshpkt_get_u32(ssh, &nbits)) != 0 ||
(r = sshpkt_get_u32(ssh, &max)) != 0 ||
@@ -126,130 +128,81 @@ static int
input_kex_dh_gex_init(int type, u_int32_t seq, struct ssh *ssh)
{
struct kex *kex = ssh->kex;
- BIGNUM *shared_secret = NULL, *dh_client_pub = NULL;
+ BIGNUM *dh_client_pub = NULL;
const BIGNUM *pub_key, *dh_p, *dh_g;
+ struct sshbuf *shared_secret = NULL;
+ struct sshbuf *server_host_key_blob = NULL;
struct sshkey *server_host_public, *server_host_private;
- u_char *kbuf = NULL, *signature = NULL, *server_host_key_blob = NULL;
+ u_char *signature = NULL;
u_char hash[SSH_DIGEST_MAX_LENGTH];
- size_t sbloblen, slen;
- size_t klen = 0, hashlen;
- int kout, r;
+ size_t slen, hashlen;
+ int r;
- if (kex->load_host_public_key == NULL ||
- kex->load_host_private_key == NULL) {
- r = SSH_ERR_INVALID_ARGUMENT;
- goto out;
- }
- server_host_public = kex->load_host_public_key(kex->hostkey_type,
- kex->hostkey_nid, ssh);
- server_host_private = kex->load_host_private_key(kex->hostkey_type,
- kex->hostkey_nid, ssh);
- if (server_host_public == NULL) {
- r = SSH_ERR_NO_HOSTKEY_LOADED;
+ debug("SSH2_MSG_KEX_DH_GEX_INIT received");
+ ssh_dispatch_set(ssh, SSH2_MSG_KEX_DH_GEX_INIT, &kex_protocol_error);
+
+ if ((r = kex_load_hostkey(ssh, &server_host_private,
+ &server_host_public)) != 0)
goto out;
- }
/* key, cert */
- if ((dh_client_pub = BN_new()) == NULL) {
- r = SSH_ERR_ALLOC_FAIL;
- goto out;
- }
- if ((r = sshpkt_get_bignum2(ssh, dh_client_pub)) != 0 ||
+ if ((r = sshpkt_get_bignum2(ssh, &dh_client_pub)) != 0 ||
(r = sshpkt_get_end(ssh)) != 0)
goto out;
-
- DH_get0_key(kex->dh, &pub_key, NULL);
- DH_get0_pqg(kex->dh, &dh_p, NULL, &dh_g);
-
-#ifdef DEBUG_KEXDH
- fprintf(stderr, "dh_client_pub= ");
- BN_print_fp(stderr, dh_client_pub);
- fprintf(stderr, "\n");
- debug("bits %d", BN_num_bits(dh_client_pub));
- DHparams_print_fp(stderr, kex->dh);
- fprintf(stderr, "pub= ");
- BN_print_fp(stderr, pub_key);
- fprintf(stderr, "\n");
-#endif
- if (!dh_pub_is_valid(kex->dh, dh_client_pub)) {
- sshpkt_disconnect(ssh, "bad client public DH value");
- r = SSH_ERR_MESSAGE_INCOMPLETE;
- goto out;
- }
-
- klen = DH_size(kex->dh);
- if ((kbuf = malloc(klen)) == NULL ||
- (shared_secret = BN_new()) == NULL) {
+ if ((shared_secret = sshbuf_new()) == NULL) {
r = SSH_ERR_ALLOC_FAIL;
goto out;
}
- if ((kout = DH_compute_key(kbuf, dh_client_pub, kex->dh)) < 0 ||
- BN_bin2bn(kbuf, kout, shared_secret) == NULL) {
- r = SSH_ERR_LIBCRYPTO_ERROR;
+ if ((r = kex_dh_compute_key(kex, dh_client_pub, shared_secret)) != 0)
+ goto out;
+ if ((server_host_key_blob = sshbuf_new()) == NULL) {
+ r = SSH_ERR_ALLOC_FAIL;
goto out;
}
-#ifdef DEBUG_KEXDH
- dump_digest("shared secret", kbuf, kout);
-#endif
- if ((r = sshkey_to_blob(server_host_public, &server_host_key_blob,
- &sbloblen)) != 0)
+ if ((r = sshkey_putb(server_host_public, server_host_key_blob)) != 0)
goto out;
+
/* calc H */
+ DH_get0_key(kex->dh, &pub_key, NULL);
+ DH_get0_pqg(kex->dh, &dh_p, NULL, &dh_g);
hashlen = sizeof(hash);
if ((r = kexgex_hash(
kex->hash_alg,
- kex->client_version_string,
- kex->server_version_string,
- sshbuf_ptr(kex->peer), sshbuf_len(kex->peer),
- sshbuf_ptr(kex->my), sshbuf_len(kex->my),
- server_host_key_blob, sbloblen,
+ kex->client_version,
+ kex->server_version,
+ kex->peer,
+ kex->my,
+ server_host_key_blob,
kex->min, kex->nbits, kex->max,
dh_p, dh_g,
dh_client_pub,
pub_key,
- shared_secret,
+ sshbuf_ptr(shared_secret), sshbuf_len(shared_secret),
hash, &hashlen)) != 0)
goto out;
- /* save session id := H */
- if (kex->session_id == NULL) {
- kex->session_id_len = hashlen;
- kex->session_id = malloc(kex->session_id_len);
- if (kex->session_id == NULL) {
- r = SSH_ERR_ALLOC_FAIL;
- goto out;
- }
- memcpy(kex->session_id, hash, kex->session_id_len);
- }
-
/* sign H */
- if ((r = kex->sign(server_host_private, server_host_public, &signature,
- &slen, hash, hashlen, kex->hostkey_alg, ssh->compat)) < 0)
+ if ((r = kex->sign(ssh, server_host_private, server_host_public,
+ &signature, &slen, hash, hashlen, kex->hostkey_alg)) < 0)
goto out;
- /* destroy_sensitive_data(); */
-
/* send server hostkey, DH pubkey 'f' and signed H */
if ((r = sshpkt_start(ssh, SSH2_MSG_KEX_DH_GEX_REPLY)) != 0 ||
- (r = sshpkt_put_string(ssh, server_host_key_blob, sbloblen)) != 0 ||
+ (r = sshpkt_put_stringb(ssh, server_host_key_blob)) != 0 ||
(r = sshpkt_put_bignum2(ssh, pub_key)) != 0 || /* f */
(r = sshpkt_put_string(ssh, signature, slen)) != 0 ||
(r = sshpkt_send(ssh)) != 0)
goto out;
- if ((r = kex_derive_keys_bn(ssh, hash, hashlen, shared_secret)) == 0)
+ if ((r = kex_derive_keys(ssh, hash, hashlen, shared_secret)) == 0)
r = kex_send_newkeys(ssh);
out:
explicit_bzero(hash, sizeof(hash));
DH_free(kex->dh);
kex->dh = NULL;
BN_clear_free(dh_client_pub);
- if (kbuf) {
- explicit_bzero(kbuf, klen);
- free(kbuf);
- }
- BN_clear_free(shared_secret);
- free(server_host_key_blob);
+ sshbuf_free(shared_secret);
+ sshbuf_free(server_host_key_blob);
free(signature);
return r;
}
diff --git a/crypto/openssh/kexsntrup761x25519.c b/crypto/openssh/kexsntrup761x25519.c
new file mode 100644
index 000000000000..e3007fa29125
--- /dev/null
+++ b/crypto/openssh/kexsntrup761x25519.c
@@ -0,0 +1,251 @@
+/* $OpenBSD: kexsntrup761x25519.c,v 1.1 2020/12/29 00:59:15 djm Exp $ */
+/*
+ * Copyright (c) 2019 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"
+
+#ifdef USE_SNTRUP761X25519
+
+#include <sys/types.h>
+
+#include <stdio.h>
+#include <string.h>
+#include <signal.h>
+
+#include "sshkey.h"
+#include "kex.h"
+#include "sshbuf.h"
+#include "digest.h"
+#include "ssherr.h"
+
+int
+kex_kem_sntrup761x25519_keypair(struct kex *kex)
+{
+ struct sshbuf *buf = NULL;
+ u_char *cp = NULL;
+ size_t need;
+ int r;
+
+ if ((buf = sshbuf_new()) == NULL)
+ return SSH_ERR_ALLOC_FAIL;
+ need = crypto_kem_sntrup761_PUBLICKEYBYTES + CURVE25519_SIZE;
+ if ((r = sshbuf_reserve(buf, need, &cp)) != 0)
+ goto out;
+ crypto_kem_sntrup761_keypair(cp, kex->sntrup761_client_key);
+#ifdef DEBUG_KEXECDH
+ dump_digest("client public key sntrup761:", cp,
+ crypto_kem_sntrup761_PUBLICKEYBYTES);
+#endif
+ cp += crypto_kem_sntrup761_PUBLICKEYBYTES;
+ kexc25519_keygen(kex->c25519_client_key, cp);
+#ifdef DEBUG_KEXECDH
+ dump_digest("client public key c25519:", cp, CURVE25519_SIZE);
+#endif
+ kex->client_pub = buf;
+ buf = NULL;
+ out:
+ sshbuf_free(buf);
+ return r;
+}
+
+int
+kex_kem_sntrup761x25519_enc(struct kex *kex,
+ const struct sshbuf *client_blob, struct sshbuf **server_blobp,
+ struct sshbuf **shared_secretp)
+{
+ struct sshbuf *server_blob = NULL;
+ struct sshbuf *buf = NULL;
+ const u_char *client_pub;
+ u_char *kem_key, *ciphertext, *server_pub;
+ u_char server_key[CURVE25519_SIZE];
+ u_char hash[SSH_DIGEST_MAX_LENGTH];
+ size_t need;
+ int r;
+
+ *server_blobp = NULL;
+ *shared_secretp = NULL;
+
+ /* client_blob contains both KEM and ECDH client pubkeys */
+ need = crypto_kem_sntrup761_PUBLICKEYBYTES + CURVE25519_SIZE;
+ if (sshbuf_len(client_blob) != need) {
+ r = SSH_ERR_SIGNATURE_INVALID;
+ goto out;
+ }
+ client_pub = sshbuf_ptr(client_blob);
+#ifdef DEBUG_KEXECDH
+ dump_digest("client public key sntrup761:", client_pub,
+ crypto_kem_sntrup761_PUBLICKEYBYTES);
+ dump_digest("client public key 25519:",
+ client_pub + crypto_kem_sntrup761_PUBLICKEYBYTES,
+ CURVE25519_SIZE);
+#endif
+ /* allocate buffer for concatenation of KEM key and ECDH shared key */
+ /* the buffer will be hashed and the result is the shared secret */
+ if ((buf = sshbuf_new()) == NULL) {
+ r = SSH_ERR_ALLOC_FAIL;
+ goto out;
+ }
+ if ((r = sshbuf_reserve(buf, crypto_kem_sntrup761_BYTES,
+ &kem_key)) != 0)
+ goto out;
+ /* allocate space for encrypted KEM key and ECDH pub key */
+ if ((server_blob = sshbuf_new()) == NULL) {
+ r = SSH_ERR_ALLOC_FAIL;
+ goto out;
+ }
+ need = crypto_kem_sntrup761_CIPHERTEXTBYTES + CURVE25519_SIZE;
+ if ((r = sshbuf_reserve(server_blob, need, &ciphertext)) != 0)
+ goto out;
+ /* generate and encrypt KEM key with client key */
+ crypto_kem_sntrup761_enc(ciphertext, kem_key, client_pub);
+ /* generate ECDH key pair, store server pubkey after ciphertext */
+ server_pub = ciphertext + crypto_kem_sntrup761_CIPHERTEXTBYTES;
+ kexc25519_keygen(server_key, server_pub);
+ /* append ECDH shared key */
+ client_pub += crypto_kem_sntrup761_PUBLICKEYBYTES;
+ if ((r = kexc25519_shared_key_ext(server_key, client_pub, buf, 1)) < 0)
+ goto out;
+ if ((r = ssh_digest_buffer(kex->hash_alg, buf, hash, sizeof(hash))) != 0)
+ goto out;
+#ifdef DEBUG_KEXECDH
+ dump_digest("server public key 25519:", server_pub, CURVE25519_SIZE);
+ dump_digest("server cipher text:", ciphertext,
+ crypto_kem_sntrup761_CIPHERTEXTBYTES);
+ dump_digest("server kem key:", kem_key, sizeof(kem_key));
+ dump_digest("concatenation of KEM key and ECDH shared key:",
+ sshbuf_ptr(buf), sshbuf_len(buf));
+#endif
+ /* string-encoded hash is resulting shared secret */
+ sshbuf_reset(buf);
+ if ((r = sshbuf_put_string(buf, hash,
+ ssh_digest_bytes(kex->hash_alg))) != 0)
+ goto out;
+#ifdef DEBUG_KEXECDH
+ dump_digest("encoded shared secret:", sshbuf_ptr(buf), sshbuf_len(buf));
+#endif
+ *server_blobp = server_blob;
+ *shared_secretp = buf;
+ server_blob = NULL;
+ buf = NULL;
+ out:
+ explicit_bzero(hash, sizeof(hash));
+ explicit_bzero(server_key, sizeof(server_key));
+ sshbuf_free(server_blob);
+ sshbuf_free(buf);
+ return r;
+}
+
+int
+kex_kem_sntrup761x25519_dec(struct kex *kex,
+ const struct sshbuf *server_blob, struct sshbuf **shared_secretp)
+{
+ struct sshbuf *buf = NULL;
+ u_char *kem_key = NULL;
+ const u_char *ciphertext, *server_pub;
+ u_char hash[SSH_DIGEST_MAX_LENGTH];
+ size_t need;
+ int r, decoded;
+
+ *shared_secretp = NULL;
+
+ need = crypto_kem_sntrup761_CIPHERTEXTBYTES + CURVE25519_SIZE;
+ if (sshbuf_len(server_blob) != need) {
+ r = SSH_ERR_SIGNATURE_INVALID;
+ goto out;
+ }
+ ciphertext = sshbuf_ptr(server_blob);
+ server_pub = ciphertext + crypto_kem_sntrup761_CIPHERTEXTBYTES;
+#ifdef DEBUG_KEXECDH
+ dump_digest("server cipher text:", ciphertext,
+ crypto_kem_sntrup761_CIPHERTEXTBYTES);
+ dump_digest("server public key c25519:", server_pub, CURVE25519_SIZE);
+#endif
+ /* hash concatenation of KEM key and ECDH shared key */
+ if ((buf = sshbuf_new()) == NULL) {
+ r = SSH_ERR_ALLOC_FAIL;
+ goto out;
+ }
+ if ((r = sshbuf_reserve(buf, crypto_kem_sntrup761_BYTES,
+ &kem_key)) != 0)
+ goto out;
+ decoded = crypto_kem_sntrup761_dec(kem_key, ciphertext,
+ kex->sntrup761_client_key);
+ if ((r = kexc25519_shared_key_ext(kex->c25519_client_key, server_pub,
+ buf, 1)) < 0)
+ goto out;
+ if ((r = ssh_digest_buffer(kex->hash_alg, buf, hash, sizeof(hash))) != 0)
+ goto out;
+#ifdef DEBUG_KEXECDH
+ dump_digest("client kem key:", kem_key, crypto_kem_sntrup761_BYTES);
+ dump_digest("concatenation of KEM key and ECDH shared key:",
+ sshbuf_ptr(buf), sshbuf_len(buf));
+#endif
+ sshbuf_reset(buf);
+ if ((r = sshbuf_put_string(buf, hash,
+ ssh_digest_bytes(kex->hash_alg))) != 0)
+ goto out;
+#ifdef DEBUG_KEXECDH
+ dump_digest("encoded shared secret:", sshbuf_ptr(buf), sshbuf_len(buf));
+#endif
+ if (decoded != 0) {
+ r = SSH_ERR_SIGNATURE_INVALID;
+ goto out;
+ }
+ *shared_secretp = buf;
+ buf = NULL;
+ out:
+ explicit_bzero(hash, sizeof(hash));
+ sshbuf_free(buf);
+ return r;
+}
+
+#else
+
+#include "ssherr.h"
+
+struct kex;
+struct sshbuf;
+struct sshkey;
+
+int
+kex_kem_sntrup761x25519_keypair(struct kex *kex)
+{
+ return SSH_ERR_SIGN_ALG_UNSUPPORTED;
+}
+
+int
+kex_kem_sntrup761x25519_enc(struct kex *kex,
+ const struct sshbuf *client_blob, struct sshbuf **server_blobp,
+ struct sshbuf **shared_secretp)
+{
+ return SSH_ERR_SIGN_ALG_UNSUPPORTED;
+}
+
+int
+kex_kem_sntrup761x25519_dec(struct kex *kex,
+ const struct sshbuf *server_blob, struct sshbuf **shared_secretp)
+{
+ return SSH_ERR_SIGN_ALG_UNSUPPORTED;
+}
+#endif /* USE_SNTRUP761X25519 */
diff --git a/crypto/openssh/krl.c b/crypto/openssh/krl.c
index 8e2d5d5df9f8..17b88edde777 100644
--- a/crypto/openssh/krl.c
+++ b/crypto/openssh/krl.c
@@ -14,7 +14,7 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-/* $OpenBSD: krl.c,v 1.42 2018/09/12 01:21:34 djm Exp $ */
+/* $OpenBSD: krl.c,v 1.53 2021/06/04 06:19:07 djm Exp $ */
#include "includes.h"
@@ -25,6 +25,7 @@
#include <errno.h>
#include <fcntl.h>
#include <limits.h>
+#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
@@ -37,12 +38,13 @@
#include "log.h"
#include "digest.h"
#include "bitmap.h"
+#include "utf8.h"
#include "krl.h"
/* #define DEBUG_KRL */
#ifdef DEBUG_KRL
-# define KRL_DBG(x) debug3 x
+# define KRL_DBG(x) debug3_f x
#else
# define KRL_DBG(x)
#endif
@@ -59,7 +61,7 @@ struct revoked_serial {
};
static int serial_cmp(struct revoked_serial *a, struct revoked_serial *b);
RB_HEAD(revoked_serial_tree, revoked_serial);
-RB_GENERATE_STATIC(revoked_serial_tree, revoked_serial, tree_entry, serial_cmp);
+RB_GENERATE_STATIC(revoked_serial_tree, revoked_serial, tree_entry, serial_cmp)
/* Tree of key IDs */
struct revoked_key_id {
@@ -68,7 +70,7 @@ struct revoked_key_id {
};
static int key_id_cmp(struct revoked_key_id *a, struct revoked_key_id *b);
RB_HEAD(revoked_key_id_tree, revoked_key_id);
-RB_GENERATE_STATIC(revoked_key_id_tree, revoked_key_id, tree_entry, key_id_cmp);
+RB_GENERATE_STATIC(revoked_key_id_tree, revoked_key_id, tree_entry, key_id_cmp)
/* Tree of blobs (used for keys and fingerprints) */
struct revoked_blob {
@@ -78,7 +80,7 @@ struct revoked_blob {
};
static int blob_cmp(struct revoked_blob *a, struct revoked_blob *b);
RB_HEAD(revoked_blob_tree, revoked_blob);
-RB_GENERATE_STATIC(revoked_blob_tree, revoked_blob, tree_entry, blob_cmp);
+RB_GENERATE_STATIC(revoked_blob_tree, revoked_blob, tree_entry, blob_cmp)
/* Tracks revoked certs for a single CA */
struct revoked_certs {
@@ -239,8 +241,7 @@ revoked_certs_for_ca_key(struct ssh_krl *krl, const struct sshkey *ca_key,
RB_INIT(&rc->revoked_serials);
RB_INIT(&rc->revoked_key_ids);
TAILQ_INSERT_TAIL(&krl->revoked_certs, rc, entry);
- KRL_DBG(("%s: new CA %s", __func__,
- ca_key == NULL ? "*" : sshkey_type(ca_key)));
+ KRL_DBG(("new CA %s", ca_key == NULL ? "*" : sshkey_type(ca_key)));
*rcp = rc;
return 0;
}
@@ -250,7 +251,7 @@ insert_serial_range(struct revoked_serial_tree *rt, u_int64_t lo, u_int64_t hi)
{
struct revoked_serial rs, *ers, *crs, *irs;
- KRL_DBG(("%s: insert %llu:%llu", __func__, lo, hi));
+ KRL_DBG(("insert %llu:%llu", lo, hi));
memset(&rs, 0, sizeof(rs));
rs.lo = lo;
rs.hi = hi;
@@ -262,15 +263,14 @@ insert_serial_range(struct revoked_serial_tree *rt, u_int64_t lo, u_int64_t hi)
memcpy(irs, &rs, sizeof(*irs));
ers = RB_INSERT(revoked_serial_tree, rt, irs);
if (ers != NULL) {
- KRL_DBG(("%s: bad: ers != NULL", __func__));
+ KRL_DBG(("bad: ers != NULL"));
/* Shouldn't happen */
free(irs);
return SSH_ERR_INTERNAL_ERROR;
}
ers = irs;
} else {
- KRL_DBG(("%s: overlap found %llu:%llu", __func__,
- ers->lo, ers->hi));
+ KRL_DBG(("overlap found %llu:%llu", ers->lo, ers->hi));
/*
* The inserted entry overlaps an existing one. Grow the
* existing entry.
@@ -288,33 +288,31 @@ insert_serial_range(struct revoked_serial_tree *rt, u_int64_t lo, u_int64_t hi)
/* Check predecessors */
while ((crs = RB_PREV(revoked_serial_tree, rt, ers)) != NULL) {
- KRL_DBG(("%s: pred %llu:%llu", __func__, crs->lo, crs->hi));
+ KRL_DBG(("pred %llu:%llu", crs->lo, crs->hi));
if (ers->lo != 0 && crs->hi < ers->lo - 1)
break;
/* This entry overlaps. */
if (crs->lo < ers->lo) {
ers->lo = crs->lo;
- KRL_DBG(("%s: pred extend %llu:%llu", __func__,
- ers->lo, ers->hi));
+ KRL_DBG(("pred extend %llu:%llu", ers->lo, ers->hi));
}
RB_REMOVE(revoked_serial_tree, rt, crs);
free(crs);
}
/* Check successors */
while ((crs = RB_NEXT(revoked_serial_tree, rt, ers)) != NULL) {
- KRL_DBG(("%s: succ %llu:%llu", __func__, crs->lo, crs->hi));
+ KRL_DBG(("succ %llu:%llu", crs->lo, crs->hi));
if (ers->hi != (u_int64_t)-1 && crs->lo > ers->hi + 1)
break;
/* This entry overlaps. */
if (crs->hi > ers->hi) {
ers->hi = crs->hi;
- KRL_DBG(("%s: succ extend %llu:%llu", __func__,
- ers->lo, ers->hi));
+ KRL_DBG(("succ extend %llu:%llu", ers->lo, ers->hi));
}
RB_REMOVE(revoked_serial_tree, rt, crs);
free(crs);
}
- KRL_DBG(("%s: done, final %llu:%llu", __func__, ers->lo, ers->hi));
+ KRL_DBG(("done, final %llu:%llu", ers->lo, ers->hi));
return 0;
}
@@ -350,7 +348,7 @@ ssh_krl_revoke_cert_by_key_id(struct ssh_krl *krl, const struct sshkey *ca_key,
if ((r = revoked_certs_for_ca_key(krl, ca_key, &rc, 1)) != 0)
return r;
- KRL_DBG(("%s: revoke %s", __func__, key_id));
+ KRL_DBG(("revoke %s", key_id));
if ((rki = calloc(1, sizeof(*rki))) == NULL ||
(rki->key_id = strdup(key_id)) == NULL) {
free(rki);
@@ -409,7 +407,7 @@ ssh_krl_revoke_key_explicit(struct ssh_krl *krl, const struct sshkey *key)
size_t len;
int r;
- debug3("%s: revoke type %s", __func__, sshkey_type(key));
+ debug3_f("revoke type %s", sshkey_type(key));
if ((r = plain_key_blob(key, &blob, &len)) != 0)
return r;
return revoke_blob(&krl->revoked_keys, blob, len);
@@ -435,7 +433,7 @@ revoke_by_hash(struct revoked_blob_tree *target, const u_char *p, size_t len)
int
ssh_krl_revoke_key_sha1(struct ssh_krl *krl, const u_char *p, size_t len)
{
- debug3("%s: revoke by sha1", __func__);
+ debug3_f("revoke by sha1");
if (len != 20)
return SSH_ERR_INVALID_FORMAT;
return revoke_by_hash(&krl->revoked_sha1s, p, len);
@@ -444,7 +442,7 @@ ssh_krl_revoke_key_sha1(struct ssh_krl *krl, const u_char *p, size_t len)
int
ssh_krl_revoke_key_sha256(struct ssh_krl *krl, const u_char *p, size_t len)
{
- debug3("%s: revoke by sha256", __func__);
+ debug3_f("revoke by sha256");
if (len != 32)
return SSH_ERR_INVALID_FORMAT;
return revoke_by_hash(&krl->revoked_sha256s, p, len);
@@ -540,9 +538,9 @@ choose_next_state(int current_state, u_int64_t contig, int final,
*force_new_section = 1;
cost = cost_bitmap_restart;
}
- KRL_DBG(("%s: contig %llu last_gap %llu next_gap %llu final %d, costs:"
+ KRL_DBG(("contig %llu last_gap %llu next_gap %llu final %d, costs:"
"list %llu range %llu bitmap %llu new bitmap %llu, "
- "selected 0x%02x%s", __func__, (long long unsigned)contig,
+ "selected 0x%02x%s", (long long unsigned)contig,
(long long unsigned)last_gap, (long long unsigned)next_gap, final,
(long long unsigned)cost_list, (long long unsigned)cost_range,
(long long unsigned)cost_bitmap,
@@ -600,7 +598,7 @@ revoked_certs_generate(struct revoked_certs *rc, struct sshbuf *buf)
for (rs = RB_MIN(revoked_serial_tree, &rc->revoked_serials);
rs != NULL;
rs = RB_NEXT(revoked_serial_tree, &rc->revoked_serials, rs)) {
- KRL_DBG(("%s: serial %llu:%llu state 0x%02x", __func__,
+ KRL_DBG(("serial %llu:%llu state 0x%02x",
(long long unsigned)rs->lo, (long long unsigned)rs->hi,
state));
@@ -620,7 +618,7 @@ revoked_certs_generate(struct revoked_certs *rc, struct sshbuf *buf)
*/
if (state != 0 && (force_new_sect || next_state != state ||
state == KRL_SECTION_CERT_SERIAL_RANGE)) {
- KRL_DBG(("%s: finish state 0x%02x", __func__, state));
+ KRL_DBG(("finish state 0x%02x", state));
switch (state) {
case KRL_SECTION_CERT_SERIAL_LIST:
case KRL_SECTION_CERT_SERIAL_RANGE:
@@ -640,7 +638,7 @@ revoked_certs_generate(struct revoked_certs *rc, struct sshbuf *buf)
/* If we are starting a new section then prepare it now */
if (next_state != state || force_new_sect) {
- KRL_DBG(("%s: start state 0x%02x", __func__,
+ KRL_DBG(("start state 0x%02x",
next_state));
state = next_state;
sshbuf_reset(sect);
@@ -676,7 +674,7 @@ revoked_certs_generate(struct revoked_certs *rc, struct sshbuf *buf)
break;
case KRL_SECTION_CERT_SERIAL_BITMAP:
if (rs->lo - bitmap_start > INT_MAX) {
- error("%s: insane bitmap gap", __func__);
+ error_f("insane bitmap gap");
goto out;
}
for (i = 0; i < contig; i++) {
@@ -692,8 +690,7 @@ revoked_certs_generate(struct revoked_certs *rc, struct sshbuf *buf)
}
/* Flush the remaining section, if any */
if (state != 0) {
- KRL_DBG(("%s: serial final flush for state 0x%02x",
- __func__, state));
+ KRL_DBG(("serial final flush for state 0x%02x", state));
switch (state) {
case KRL_SECTION_CERT_SERIAL_LIST:
case KRL_SECTION_CERT_SERIAL_RANGE:
@@ -709,12 +706,12 @@ revoked_certs_generate(struct revoked_certs *rc, struct sshbuf *buf)
(r = sshbuf_put_stringb(buf, sect)) != 0)
goto out;
}
- KRL_DBG(("%s: serial done ", __func__));
+ KRL_DBG(("serial done "));
/* Now output a section for any revocations by key ID */
sshbuf_reset(sect);
RB_FOREACH(rki, revoked_key_id_tree, &rc->revoked_key_ids) {
- KRL_DBG(("%s: key ID %s", __func__, rki->key_id));
+ KRL_DBG(("key ID %s", rki->key_id));
if ((r = sshbuf_put_cstring(sect, rki->key_id)) != 0)
goto out;
}
@@ -732,7 +729,7 @@ revoked_certs_generate(struct revoked_certs *rc, struct sshbuf *buf)
int
ssh_krl_to_blob(struct ssh_krl *krl, struct sshbuf *buf,
- const struct sshkey **sign_keys, u_int nsign_keys)
+ struct sshkey **sign_keys, u_int nsign_keys)
{
int r = SSH_ERR_INTERNAL_ERROR;
struct revoked_certs *rc;
@@ -770,7 +767,7 @@ ssh_krl_to_blob(struct ssh_krl *krl, struct sshbuf *buf,
/* Finally, output sections for revocations by public key/hash */
sshbuf_reset(sect);
RB_FOREACH(rb, revoked_blob_tree, &krl->revoked_keys) {
- KRL_DBG(("%s: key len %zu ", __func__, rb->len));
+ KRL_DBG(("key len %zu ", rb->len));
if ((r = sshbuf_put_string(sect, rb->blob, rb->len)) != 0)
goto out;
}
@@ -781,7 +778,7 @@ ssh_krl_to_blob(struct ssh_krl *krl, struct sshbuf *buf,
}
sshbuf_reset(sect);
RB_FOREACH(rb, revoked_blob_tree, &krl->revoked_sha1s) {
- KRL_DBG(("%s: hash len %zu ", __func__, rb->len));
+ KRL_DBG(("hash len %zu ", rb->len));
if ((r = sshbuf_put_string(sect, rb->blob, rb->len)) != 0)
goto out;
}
@@ -793,7 +790,7 @@ ssh_krl_to_blob(struct ssh_krl *krl, struct sshbuf *buf,
}
sshbuf_reset(sect);
RB_FOREACH(rb, revoked_blob_tree, &krl->revoked_sha256s) {
- KRL_DBG(("%s: hash len %zu ", __func__, rb->len));
+ KRL_DBG(("hash len %zu ", rb->len));
if ((r = sshbuf_put_string(sect, rb->blob, rb->len)) != 0)
goto out;
}
@@ -805,16 +802,16 @@ ssh_krl_to_blob(struct ssh_krl *krl, struct sshbuf *buf,
}
for (i = 0; i < nsign_keys; i++) {
- KRL_DBG(("%s: signature key %s", __func__,
- sshkey_ssh_name(sign_keys[i])));
+ KRL_DBG(("sig key %s", sshkey_ssh_name(sign_keys[i])));
if ((r = sshbuf_put_u8(buf, KRL_SECTION_SIGNATURE)) != 0 ||
(r = sshkey_puts(sign_keys[i], buf)) != 0)
goto out;
-
+ /* XXX support sk-* keys */
if ((r = sshkey_sign(sign_keys[i], &sblob, &slen,
- sshbuf_ptr(buf), sshbuf_len(buf), NULL, 0)) != 0)
+ sshbuf_ptr(buf), sshbuf_len(buf), NULL, NULL,
+ NULL, 0)) != 0)
goto out;
- KRL_DBG(("%s: signature sig len %zu", __func__, slen));
+ KRL_DBG(("signature sig len %zu", slen));
if ((r = sshbuf_put_string(buf, sblob, slen)) != 0)
goto out;
}
@@ -871,7 +868,7 @@ parse_revoked_certs(struct sshbuf *buf, struct ssh_krl *krl)
if ((r = sshbuf_get_u8(buf, &type)) != 0 ||
(r = sshbuf_froms(buf, &subsect)) != 0)
goto out;
- KRL_DBG(("%s: subsection type 0x%02x", __func__, type));
+ KRL_DBG(("subsection type 0x%02x", type));
/* sshbuf_dump(subsect, stderr); */
switch (type) {
@@ -908,7 +905,7 @@ parse_revoked_certs(struct sshbuf *buf, struct ssh_krl *krl)
nbits = bitmap_nbits(bitmap);
for (serial = 0; serial < (u_int64_t)nbits; serial++) {
if (serial > 0 && serial_lo + serial == 0) {
- error("%s: bitmap wraps u64", __func__);
+ error_f("bitmap wraps u64");
r = SSH_ERR_INVALID_FORMAT;
goto out;
}
@@ -967,7 +964,7 @@ blob_section(struct sshbuf *sect, struct revoked_blob_tree *target_tree,
if ((r = sshbuf_get_string(sect, &rdata, &rlen)) != 0)
return r;
if (expected_len != 0 && rlen != expected_len) {
- error("%s: bad length", __func__);
+ error_f("bad length");
free(rdata);
return SSH_ERR_INVALID_FORMAT;
}
@@ -998,7 +995,7 @@ ssh_krl_from_blob(struct sshbuf *buf, struct ssh_krl **krlp,
*krlp = NULL;
if (sshbuf_len(buf) < sizeof(KRL_MAGIC) - 1 ||
memcmp(sshbuf_ptr(buf), KRL_MAGIC, sizeof(KRL_MAGIC) - 1) != 0) {
- debug3("%s: not a KRL", __func__);
+ debug3_f("not a KRL");
return SSH_ERR_KRL_BAD_MAGIC;
}
@@ -1011,7 +1008,7 @@ ssh_krl_from_blob(struct sshbuf *buf, struct ssh_krl **krlp,
goto out;
if ((krl = ssh_krl_init()) == NULL) {
- error("%s: alloc failed", __func__);
+ error_f("alloc failed");
goto out;
}
@@ -1048,7 +1045,7 @@ ssh_krl_from_blob(struct sshbuf *buf, struct ssh_krl **krlp,
if ((r = sshbuf_get_u8(copy, &type)) != 0 ||
(r = sshbuf_get_string_direct(copy, &blob, &blen)) != 0)
goto out;
- KRL_DBG(("%s: first pass, section 0x%02x", __func__, type));
+ KRL_DBG(("first pass, section 0x%02x", type));
if (type != KRL_SECTION_SIGNATURE) {
if (sig_seen) {
error("KRL contains non-signature section "
@@ -1078,7 +1075,7 @@ ssh_krl_from_blob(struct sshbuf *buf, struct ssh_krl **krlp,
}
/* Check signature over entire KRL up to this point */
if ((r = sshkey_verify(key, blob, blen,
- sshbuf_ptr(buf), sig_off, NULL, 0)) != 0)
+ sshbuf_ptr(buf), sig_off, NULL, 0, NULL)) != 0)
goto out;
/* Check if this key has already signed this KRL */
for (i = 0; i < nca_used; i++) {
@@ -1124,7 +1121,7 @@ ssh_krl_from_blob(struct sshbuf *buf, struct ssh_krl **krlp,
if ((r = sshbuf_get_u8(copy, &type)) != 0 ||
(r = sshbuf_froms(copy, &sect)) != 0)
goto out;
- KRL_DBG(("%s: second pass, section 0x%02x", __func__, type));
+ KRL_DBG(("second pass, section 0x%02x", type));
switch (type) {
case KRL_SECTION_CERTIFICATES:
@@ -1227,7 +1224,7 @@ is_cert_revoked(const struct sshkey *key, struct revoked_certs *rc)
rki.key_id = key->cert->key_id;
erki = RB_FIND(revoked_key_id_tree, &rc->revoked_key_ids, &rki);
if (erki != NULL) {
- KRL_DBG(("%s: revoked by key ID", __func__));
+ KRL_DBG(("revoked by key ID"));
return SSH_ERR_KEY_REVOKED;
}
@@ -1242,7 +1239,7 @@ is_cert_revoked(const struct sshkey *key, struct revoked_certs *rc)
rs.lo = rs.hi = key->cert->serial;
ers = RB_FIND(revoked_serial_tree, &rc->revoked_serials, &rs);
if (ers != NULL) {
- KRL_DBG(("%s: revoked serial %llu matched %llu:%llu", __func__,
+ KRL_DBG(("revoked serial %llu matched %llu:%llu",
key->cert->serial, ers->lo, ers->hi));
return SSH_ERR_KEY_REVOKED;
}
@@ -1265,7 +1262,7 @@ is_key_revoked(struct ssh_krl *krl, const struct sshkey *key)
erb = RB_FIND(revoked_blob_tree, &krl->revoked_sha1s, &rb);
free(rb.blob);
if (erb != NULL) {
- KRL_DBG(("%s: revoked by key SHA1", __func__));
+ KRL_DBG(("revoked by key SHA1"));
return SSH_ERR_KEY_REVOKED;
}
memset(&rb, 0, sizeof(rb));
@@ -1275,7 +1272,7 @@ is_key_revoked(struct ssh_krl *krl, const struct sshkey *key)
erb = RB_FIND(revoked_blob_tree, &krl->revoked_sha256s, &rb);
free(rb.blob);
if (erb != NULL) {
- KRL_DBG(("%s: revoked by key SHA256", __func__));
+ KRL_DBG(("revoked by key SHA256"));
return SSH_ERR_KEY_REVOKED;
}
@@ -1286,7 +1283,7 @@ is_key_revoked(struct ssh_krl *krl, const struct sshkey *key)
erb = RB_FIND(revoked_blob_tree, &krl->revoked_keys, &rb);
free(rb.blob);
if (erb != NULL) {
- KRL_DBG(("%s: revoked by explicit key", __func__));
+ KRL_DBG(("revoked by explicit key"));
return SSH_ERR_KEY_REVOKED;
}
@@ -1309,7 +1306,7 @@ is_key_revoked(struct ssh_krl *krl, const struct sshkey *key)
return r;
}
- KRL_DBG(("%s: %llu no match", __func__, key->cert->serial));
+ KRL_DBG(("%llu no match", key->cert->serial));
return 0;
}
@@ -1318,15 +1315,15 @@ ssh_krl_check_key(struct ssh_krl *krl, const struct sshkey *key)
{
int r;
- KRL_DBG(("%s: checking key", __func__));
+ KRL_DBG(("checking key"));
if ((r = is_key_revoked(krl, key)) != 0)
return r;
if (sshkey_is_cert(key)) {
- debug2("%s: checking CA key", __func__);
+ debug2_f("checking CA key");
if ((r = is_key_revoked(krl, key->cert->signature_key)) != 0)
return r;
}
- KRL_DBG(("%s: key okay", __func__));
+ KRL_DBG(("key okay"));
return 0;
}
@@ -1335,32 +1332,116 @@ ssh_krl_file_contains_key(const char *path, const struct sshkey *key)
{
struct sshbuf *krlbuf = NULL;
struct ssh_krl *krl = NULL;
- int oerrno = 0, r, fd;
+ int oerrno = 0, r;
if (path == NULL)
return 0;
-
- if ((krlbuf = sshbuf_new()) == NULL)
- return SSH_ERR_ALLOC_FAIL;
- if ((fd = open(path, O_RDONLY)) == -1) {
- r = SSH_ERR_SYSTEM_ERROR;
- oerrno = errno;
- goto out;
- }
- if ((r = sshkey_load_file(fd, krlbuf)) != 0) {
+ if ((r = sshbuf_load_file(path, &krlbuf)) != 0) {
oerrno = errno;
goto out;
}
if ((r = ssh_krl_from_blob(krlbuf, &krl, NULL, 0)) != 0)
goto out;
- debug2("%s: checking KRL %s", __func__, path);
+ debug2_f("checking KRL %s", path);
r = ssh_krl_check_key(krl, key);
out:
- if (fd != -1)
- close(fd);
sshbuf_free(krlbuf);
ssh_krl_free(krl);
if (r != 0)
errno = oerrno;
return r;
}
+
+int
+krl_dump(struct ssh_krl *krl, FILE *f)
+{
+ struct sshkey *key = NULL;
+ struct revoked_blob *rb;
+ struct revoked_certs *rc;
+ struct revoked_serial *rs;
+ struct revoked_key_id *rki;
+ int r, ret = 0;
+ char *fp, timestamp[64];
+
+ /* Try to print in a KRL spec-compatible format */
+ format_timestamp(krl->generated_date, timestamp, sizeof(timestamp));
+ fprintf(f, "# KRL version %llu\n",
+ (unsigned long long)krl->krl_version);
+ fprintf(f, "# Generated at %s\n", timestamp);
+ if (krl->comment != NULL && *krl->comment != '\0') {
+ r = INT_MAX;
+ asmprintf(&fp, INT_MAX, &r, "%s", krl->comment);
+ fprintf(f, "# Comment: %s\n", fp);
+ free(fp);
+ }
+ fputc('\n', f);
+
+ RB_FOREACH(rb, revoked_blob_tree, &krl->revoked_keys) {
+ if ((r = sshkey_from_blob(rb->blob, rb->len, &key)) != 0) {
+ ret = SSH_ERR_INVALID_FORMAT;
+ error_r(r, "parse KRL key");
+ continue;
+ }
+ if ((fp = sshkey_fingerprint(key, SSH_FP_HASH_DEFAULT,
+ SSH_FP_DEFAULT)) == NULL) {
+ ret = SSH_ERR_INVALID_FORMAT;
+ error("sshkey_fingerprint failed");
+ continue;
+ }
+ fprintf(f, "hash: SHA256:%s # %s\n", fp, sshkey_ssh_name(key));
+ free(fp);
+ free(key);
+ }
+ RB_FOREACH(rb, revoked_blob_tree, &krl->revoked_sha256s) {
+ fp = tohex(rb->blob, rb->len);
+ fprintf(f, "hash: SHA256:%s\n", fp);
+ free(fp);
+ }
+ RB_FOREACH(rb, revoked_blob_tree, &krl->revoked_sha1s) {
+ /*
+ * There is not KRL spec keyword for raw SHA1 hashes, so
+ * print them as comments.
+ */
+ fp = tohex(rb->blob, rb->len);
+ fprintf(f, "# hash SHA1:%s\n", fp);
+ free(fp);
+ }
+
+ TAILQ_FOREACH(rc, &krl->revoked_certs, entry) {
+ fputc('\n', f);
+ if (rc->ca_key == NULL)
+ fprintf(f, "# Wildcard CA\n");
+ else {
+ if ((fp = sshkey_fingerprint(rc->ca_key,
+ SSH_FP_HASH_DEFAULT, SSH_FP_DEFAULT)) == NULL) {
+ ret = SSH_ERR_INVALID_FORMAT;
+ error("sshkey_fingerprint failed");
+ continue;
+ }
+ fprintf(f, "# CA key %s %s\n",
+ sshkey_ssh_name(rc->ca_key), fp);
+ free(fp);
+ }
+ RB_FOREACH(rs, revoked_serial_tree, &rc->revoked_serials) {
+ if (rs->lo == rs->hi) {
+ fprintf(f, "serial: %llu\n",
+ (unsigned long long)rs->lo);
+ } else {
+ fprintf(f, "serial: %llu-%llu\n",
+ (unsigned long long)rs->lo,
+ (unsigned long long)rs->hi);
+ }
+ }
+ RB_FOREACH(rki, revoked_key_id_tree, &rc->revoked_key_ids) {
+ /*
+ * We don't want key IDs with embedded newlines to
+ * mess up the display.
+ */
+ r = INT_MAX;
+ asmprintf(&fp, INT_MAX, &r, "%s", rki->key_id);
+ fprintf(f, "id: %s\n", fp);
+ free(fp);
+ }
+ }
+ return ret;
+}
diff --git a/crypto/openssh/krl.h b/crypto/openssh/krl.h
index 815a1df4ebab..ca6d3f2843fd 100644
--- a/crypto/openssh/krl.h
+++ b/crypto/openssh/krl.h
@@ -14,7 +14,7 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-/* $OpenBSD: krl.h,v 1.6 2018/09/12 01:21:34 djm Exp $ */
+/* $OpenBSD: krl.h,v 1.8 2020/04/03 02:26:56 djm Exp $ */
#ifndef _KRL_H
#define _KRL_H
@@ -56,11 +56,12 @@ int ssh_krl_revoke_key_sha1(struct ssh_krl *krl, const u_char *p, size_t len);
int ssh_krl_revoke_key_sha256(struct ssh_krl *krl, const u_char *p, size_t len);
int ssh_krl_revoke_key(struct ssh_krl *krl, const struct sshkey *key);
int ssh_krl_to_blob(struct ssh_krl *krl, struct sshbuf *buf,
- const struct sshkey **sign_keys, u_int nsign_keys);
+ struct sshkey **sign_keys, u_int nsign_keys);
int ssh_krl_from_blob(struct sshbuf *buf, struct ssh_krl **krlp,
const struct sshkey **sign_ca_keys, size_t nsign_ca_keys);
int ssh_krl_check_key(struct ssh_krl *krl, const struct sshkey *key);
int ssh_krl_file_contains_key(const char *path, const struct sshkey *key);
+int krl_dump(struct ssh_krl *krl, FILE *f);
#endif /* _KRL_H */
diff --git a/crypto/openssh/log.c b/crypto/openssh/log.c
index d9c2d136cc68..42c6f9a60d3e 100644
--- a/crypto/openssh/log.c
+++ b/crypto/openssh/log.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: log.c,v 1.51 2018/07/27 12:03:17 markus Exp $ */
+/* $OpenBSD: log.c,v 1.59 2021/05/07 04:11:51 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -51,14 +51,17 @@
#endif
#include "log.h"
+#include "match.h"
static LogLevel log_level = SYSLOG_LEVEL_INFO;
static int log_on_stderr = 1;
static int log_stderr_fd = STDERR_FILENO;
static int log_facility = LOG_AUTH;
-static char *argv0;
+static const char *argv0;
static log_handler_fn *log_handler;
static void *log_handler_ctx;
+static char **log_verbose;
+static size_t nlog_verbose;
extern char *__progname;
@@ -157,96 +160,30 @@ log_level_name(LogLevel level)
return NULL;
}
-/* Error messages that should be logged. */
-
-void
-error(const char *fmt,...)
-{
- va_list args;
-
- va_start(args, fmt);
- do_log(SYSLOG_LEVEL_ERROR, fmt, args);
- va_end(args);
-}
-
-void
-sigdie(const char *fmt,...)
-{
-#ifdef DO_LOG_SAFE_IN_SIGHAND
- va_list args;
-
- va_start(args, fmt);
- do_log(SYSLOG_LEVEL_FATAL, fmt, args);
- va_end(args);
-#endif
- _exit(1);
-}
-
void
-logdie(const char *fmt,...)
+log_verbose_add(const char *s)
{
- va_list args;
-
- va_start(args, fmt);
- do_log(SYSLOG_LEVEL_INFO, fmt, args);
- va_end(args);
- cleanup_exit(255);
-}
-
-/* Log this message (information that usually should go to the log). */
-
-void
-logit(const char *fmt,...)
-{
- va_list args;
-
- va_start(args, fmt);
- do_log(SYSLOG_LEVEL_INFO, fmt, args);
- va_end(args);
-}
-
-/* More detailed messages (information that does not need to go to the log). */
-
-void
-verbose(const char *fmt,...)
-{
- va_list args;
-
- va_start(args, fmt);
- do_log(SYSLOG_LEVEL_VERBOSE, fmt, args);
- va_end(args);
-}
-
-/* Debugging messages that should not be logged during normal operation. */
-
-void
-debug(const char *fmt,...)
-{
- va_list args;
-
- va_start(args, fmt);
- do_log(SYSLOG_LEVEL_DEBUG1, fmt, args);
- va_end(args);
-}
-
-void
-debug2(const char *fmt,...)
-{
- va_list args;
-
- va_start(args, fmt);
- do_log(SYSLOG_LEVEL_DEBUG2, fmt, args);
- va_end(args);
+ char **tmp;
+
+ /* Ignore failures here */
+ if ((tmp = recallocarray(log_verbose, nlog_verbose, nlog_verbose + 1,
+ sizeof(*log_verbose))) != NULL) {
+ log_verbose = tmp;
+ if ((log_verbose[nlog_verbose] = strdup(s)) != NULL)
+ nlog_verbose++;
+ }
}
void
-debug3(const char *fmt,...)
+log_verbose_reset(void)
{
- va_list args;
+ size_t i;
- va_start(args, fmt);
- do_log(SYSLOG_LEVEL_DEBUG3, fmt, args);
- va_end(args);
+ for (i = 0; i < nlog_verbose; i++)
+ free(log_verbose[i]);
+ free(log_verbose);
+ log_verbose = NULL;
+ nlog_verbose = 0;
}
/*
@@ -254,7 +191,8 @@ debug3(const char *fmt,...)
*/
void
-log_init(char *av0, LogLevel level, SyslogFacility facility, int on_stderr)
+log_init(const char *av0, LogLevel level, SyslogFacility facility,
+ int on_stderr)
{
#if defined(HAVE_OPENLOG_R) && defined(SYSLOG_DATA_INIT)
struct syslog_data sdata = SYSLOG_DATA_INIT;
@@ -370,9 +308,17 @@ log_redirect_stderr_to(const char *logfile)
{
int fd;
+ if (logfile == NULL) {
+ if (log_stderr_fd != STDERR_FILENO) {
+ close(log_stderr_fd);
+ log_stderr_fd = STDERR_FILENO;
+ }
+ return;
+ }
+
if ((fd = open(logfile, O_WRONLY|O_CREAT|O_APPEND, 0600)) == -1) {
fprintf(stderr, "Couldn't open logfile %s: %s\n", logfile,
- strerror(errno));
+ strerror(errno));
exit(1);
}
log_stderr_fd = fd;
@@ -387,18 +333,9 @@ set_log_handler(log_handler_fn *handler, void *ctx)
log_handler_ctx = ctx;
}
-void
-do_log2(LogLevel level, const char *fmt,...)
-{
- va_list args;
-
- va_start(args, fmt);
- do_log(level, fmt, args);
- va_end(args);
-}
-
-void
-do_log(LogLevel level, const char *fmt, va_list args)
+static void
+do_log(LogLevel level, int force, const char *suffix, const char *fmt,
+ va_list args)
{
#if defined(HAVE_OPENLOG_R) && defined(SYSLOG_DATA_INIT)
struct syslog_data sdata = SYSLOG_DATA_INIT;
@@ -410,7 +347,7 @@ do_log(LogLevel level, const char *fmt, va_list args)
int saved_errno = errno;
log_handler_fn *tmp_handler;
- if (level > log_level)
+ if (!force && level > log_level)
return;
switch (level) {
@@ -453,13 +390,17 @@ do_log(LogLevel level, const char *fmt, va_list args)
} else {
vsnprintf(msgbuf, sizeof(msgbuf), fmt, args);
}
+ if (suffix != NULL) {
+ snprintf(fmtbuf, sizeof(fmtbuf), "%s: %s", msgbuf, suffix);
+ strlcpy(msgbuf, fmtbuf, sizeof(msgbuf));
+ }
strnvis(fmtbuf, msgbuf, sizeof(fmtbuf),
log_on_stderr ? LOG_STDERR_VIS : LOG_SYSLOG_VIS);
if (log_handler != NULL) {
/* Avoid recursion */
tmp_handler = log_handler;
log_handler = NULL;
- tmp_handler(level, fmtbuf, log_handler_ctx);
+ tmp_handler(level, force, fmtbuf, log_handler_ctx);
log_handler = tmp_handler;
} else if (log_on_stderr) {
snprintf(msgbuf, sizeof msgbuf, "%.*s\r\n",
@@ -478,3 +419,79 @@ do_log(LogLevel level, const char *fmt, va_list args)
}
errno = saved_errno;
}
+
+void
+sshlog(const char *file, const char *func, int line, int showfunc,
+ LogLevel level, const char *suffix, const char *fmt, ...)
+{
+ va_list args;
+
+ va_start(args, fmt);
+ sshlogv(file, func, line, showfunc, level, suffix, fmt, args);
+ va_end(args);
+}
+
+void
+sshlogdie(const char *file, const char *func, int line, int showfunc,
+ LogLevel level, const char *suffix, const char *fmt, ...)
+{
+ va_list args;
+
+ va_start(args, fmt);
+ sshlogv(file, func, line, showfunc, SYSLOG_LEVEL_INFO,
+ suffix, fmt, args);
+ va_end(args);
+ cleanup_exit(255);
+}
+
+void
+sshsigdie(const char *file, const char *func, int line, int showfunc,
+ LogLevel level, const char *suffix, const char *fmt, ...)
+{
+ va_list args;
+
+ va_start(args, fmt);
+ sshlogv(file, func, line, showfunc, SYSLOG_LEVEL_FATAL,
+ suffix, fmt, args);
+ va_end(args);
+ _exit(1);
+}
+
+void
+sshlogv(const char *file, const char *func, int line, int showfunc,
+ LogLevel level, const char *suffix, const char *fmt, va_list args)
+{
+ char tag[128], fmt2[MSGBUFSIZ + 128];
+ int forced = 0;
+ const char *cp;
+ size_t i;
+
+ snprintf(tag, sizeof(tag), "%.48s:%.48s():%d (pid=%ld)",
+ (cp = strrchr(file, '/')) == NULL ? file : cp + 1, func, line,
+ (long)getpid());
+ for (i = 0; i < nlog_verbose; i++) {
+ if (match_pattern_list(tag, log_verbose[i], 0) == 1) {
+ forced = 1;
+ break;
+ }
+ }
+
+ if (forced)
+ snprintf(fmt2, sizeof(fmt2), "%s: %s", tag, fmt);
+ else if (showfunc)
+ snprintf(fmt2, sizeof(fmt2), "%s: %s", func, fmt);
+ else
+ strlcpy(fmt2, fmt, sizeof(fmt2));
+
+ do_log(level, forced, suffix, fmt2, args);
+}
+
+void
+sshlogdirect(LogLevel level, int forced, const char *fmt, ...)
+{
+ va_list args;
+
+ va_start(args, fmt);
+ do_log(level, forced, NULL, fmt, args);
+ va_end(args);
+}
diff --git a/crypto/openssh/log.h b/crypto/openssh/log.h
index ef7bea7e1aa2..6218b4177a6f 100644
--- a/crypto/openssh/log.h
+++ b/crypto/openssh/log.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: log.h,v 1.23 2018/07/27 12:03:17 markus Exp $ */
+/* $OpenBSD: log.h,v 1.33 2021/04/15 16:24:31 markus Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -15,6 +15,9 @@
#ifndef SSH_LOG_H
#define SSH_LOG_H
+#include <stdarg.h> /* va_list */
+#include "ssherr.h" /* ssh_err() */
+
/* Supported syslog facilities and levels. */
typedef enum {
SYSLOG_FACILITY_DAEMON,
@@ -46,36 +49,84 @@ typedef enum {
SYSLOG_LEVEL_NOT_SET = -1
} LogLevel;
-typedef void (log_handler_fn)(LogLevel, const char *, void *);
+typedef void (log_handler_fn)(LogLevel, int, const char *, void *);
-void log_init(char *, LogLevel, SyslogFacility, int);
+void log_init(const char *, LogLevel, SyslogFacility, int);
LogLevel log_level_get(void);
int log_change_level(LogLevel);
int log_is_on_stderr(void);
void log_redirect_stderr_to(const char *);
+void log_verbose_add(const char *);
+void log_verbose_reset(void);
SyslogFacility log_facility_number(char *);
-const char * log_facility_name(SyslogFacility);
+const char * log_facility_name(SyslogFacility);
LogLevel log_level_number(char *);
const char * log_level_name(LogLevel);
-void fatal(const char *, ...) __attribute__((noreturn))
- __attribute__((format(printf, 1, 2)));
-void error(const char *, ...) __attribute__((format(printf, 1, 2)));
-void sigdie(const char *, ...) __attribute__((noreturn))
- __attribute__((format(printf, 1, 2)));
-void logdie(const char *, ...) __attribute__((noreturn))
- __attribute__((format(printf, 1, 2)));
-void logit(const char *, ...) __attribute__((format(printf, 1, 2)));
-void verbose(const char *, ...) __attribute__((format(printf, 1, 2)));
-void debug(const char *, ...) __attribute__((format(printf, 1, 2)));
-void debug2(const char *, ...) __attribute__((format(printf, 1, 2)));
-void debug3(const char *, ...) __attribute__((format(printf, 1, 2)));
-
-
void set_log_handler(log_handler_fn *, void *);
-void do_log2(LogLevel, const char *, ...)
- __attribute__((format(printf, 2, 3)));
-void do_log(LogLevel, const char *, va_list);
void cleanup_exit(int) __attribute__((noreturn));
+
+void sshlog(const char *, const char *, int, int,
+ LogLevel, const char *, const char *, ...)
+ __attribute__((format(printf, 7, 8)));
+void sshlogv(const char *, const char *, int, int,
+ LogLevel, const char *, const char *, va_list);
+void sshsigdie(const char *, const char *, int, int,
+ LogLevel, const char *, const char *, ...) __attribute__((noreturn))
+ __attribute__((format(printf, 7, 8)));
+void sshlogdie(const char *, const char *, int, int,
+ LogLevel, const char *, const char *, ...) __attribute__((noreturn))
+ __attribute__((format(printf, 7, 8)));
+void sshfatal(const char *, const char *, int, int,
+ LogLevel, const char *, const char *, ...) __attribute__((noreturn))
+ __attribute__((format(printf, 7, 8)));
+void sshlogdirect(LogLevel, int, const char *, ...)
+ __attribute__((format(printf, 3, 4)));
+
+#define do_log2(level, ...) sshlog(__FILE__, __func__, __LINE__, 0, level, NULL, __VA_ARGS__)
+#define debug3(...) sshlog(__FILE__, __func__, __LINE__, 0, SYSLOG_LEVEL_DEBUG3, NULL, __VA_ARGS__)
+#define debug2(...) sshlog(__FILE__, __func__, __LINE__, 0, SYSLOG_LEVEL_DEBUG2, NULL, __VA_ARGS__)
+#define debug(...) sshlog(__FILE__, __func__, __LINE__, 0, SYSLOG_LEVEL_DEBUG1, NULL, __VA_ARGS__)
+#define verbose(...) sshlog(__FILE__, __func__, __LINE__, 0, SYSLOG_LEVEL_VERBOSE, NULL, __VA_ARGS__)
+#define logit(...) sshlog(__FILE__, __func__, __LINE__, 0, SYSLOG_LEVEL_INFO, NULL, __VA_ARGS__)
+#define error(...) sshlog(__FILE__, __func__, __LINE__, 0, SYSLOG_LEVEL_ERROR, NULL, __VA_ARGS__)
+#define fatal(...) sshfatal(__FILE__, __func__, __LINE__, 0, SYSLOG_LEVEL_FATAL, NULL, __VA_ARGS__)
+#define logdie(...) sshlogdie(__FILE__, __func__, __LINE__, 0, SYSLOG_LEVEL_ERROR, NULL, __VA_ARGS__)
+#define sigdie(...) sshsigdie(__FILE__, __func__, __LINE__, 0, SYSLOG_LEVEL_ERROR, NULL, __VA_ARGS__)
+
+/* Variants that prepend the caller's function */
+#define do_log2_f(level, ...) sshlog(__FILE__, __func__, __LINE__, 1, level, NULL, __VA_ARGS__)
+#define debug3_f(...) sshlog(__FILE__, __func__, __LINE__, 1, SYSLOG_LEVEL_DEBUG3, NULL, __VA_ARGS__)
+#define debug2_f(...) sshlog(__FILE__, __func__, __LINE__, 1, SYSLOG_LEVEL_DEBUG2, NULL, __VA_ARGS__)
+#define debug_f(...) sshlog(__FILE__, __func__, __LINE__, 1, SYSLOG_LEVEL_DEBUG1, NULL, __VA_ARGS__)
+#define verbose_f(...) sshlog(__FILE__, __func__, __LINE__, 1, SYSLOG_LEVEL_VERBOSE, NULL, __VA_ARGS__)
+#define logit_f(...) sshlog(__FILE__, __func__, __LINE__, 1, SYSLOG_LEVEL_INFO, NULL, __VA_ARGS__)
+#define error_f(...) sshlog(__FILE__, __func__, __LINE__, 1, SYSLOG_LEVEL_ERROR, NULL, __VA_ARGS__)
+#define fatal_f(...) sshfatal(__FILE__, __func__, __LINE__, 1, SYSLOG_LEVEL_FATAL, NULL, __VA_ARGS__)
+#define logdie_f(...) sshlogdie(__FILE__, __func__, __LINE__, 1, SYSLOG_LEVEL_ERROR, NULL, __VA_ARGS__)
+#define sigdie_f(...) sshsigdie(__FILE__, __func__, __LINE__, 1, SYSLOG_LEVEL_ERROR, NULL, __VA_ARGS__)
+
+/* Variants that appends a ssh_err message */
+#define do_log2_r(r, level, ...) sshlog(__FILE__, __func__, __LINE__, 0, level, ssh_err(r), __VA_ARGS__)
+#define debug3_r(r, ...) sshlog(__FILE__, __func__, __LINE__, 0, SYSLOG_LEVEL_DEBUG3, ssh_err(r), __VA_ARGS__)
+#define debug2_r(r, ...) sshlog(__FILE__, __func__, __LINE__, 0, SYSLOG_LEVEL_DEBUG2, ssh_err(r), __VA_ARGS__)
+#define debug_r(r, ...) sshlog(__FILE__, __func__, __LINE__, 0, SYSLOG_LEVEL_DEBUG1, ssh_err(r), __VA_ARGS__)
+#define verbose_r(r, ...) sshlog(__FILE__, __func__, __LINE__, 0, SYSLOG_LEVEL_VERBOSE, ssh_err(r), __VA_ARGS__)
+#define logit_r(r, ...) sshlog(__FILE__, __func__, __LINE__, 0, SYSLOG_LEVEL_INFO, ssh_err(r), __VA_ARGS__)
+#define error_r(r, ...) sshlog(__FILE__, __func__, __LINE__, 0, SYSLOG_LEVEL_ERROR, ssh_err(r), __VA_ARGS__)
+#define fatal_r(r, ...) sshfatal(__FILE__, __func__, __LINE__, 0, SYSLOG_LEVEL_FATAL, ssh_err(r), __VA_ARGS__)
+#define logdie_r(r, ...) sshlogdie(__FILE__, __func__, __LINE__, 0, SYSLOG_LEVEL_ERROR, ssh_err(r), __VA_ARGS__)
+#define sigdie_r(r, ...) sshsigdie(__FILE__, __func__, __LINE__, 0, SYSLOG_LEVEL_ERROR, ssh_err(r), __VA_ARGS__)
+#define do_log2_fr(r, level, ...) sshlog(__FILE__, __func__, __LINE__, 1, level, ssh_err(r), __VA_ARGS__)
+#define debug3_fr(r, ...) sshlog(__FILE__, __func__, __LINE__, 1, SYSLOG_LEVEL_DEBUG3, ssh_err(r), __VA_ARGS__)
+#define debug2_fr(r, ...) sshlog(__FILE__, __func__, __LINE__, 1, SYSLOG_LEVEL_DEBUG2, ssh_err(r), __VA_ARGS__)
+#define debug_fr(r, ...) sshlog(__FILE__, __func__, __LINE__, 1, SYSLOG_LEVEL_DEBUG1, ssh_err(r), __VA_ARGS__)
+#define verbose_fr(r, ...) sshlog(__FILE__, __func__, __LINE__, 1, SYSLOG_LEVEL_VERBOSE, ssh_err(r), __VA_ARGS__)
+#define logit_fr(r, ...) sshlog(__FILE__, __func__, __LINE__, 1, SYSLOG_LEVEL_INFO, ssh_err(r), __VA_ARGS__)
+#define error_fr(r, ...) sshlog(__FILE__, __func__, __LINE__, 1, SYSLOG_LEVEL_ERROR, ssh_err(r), __VA_ARGS__)
+#define fatal_fr(r, ...) sshfatal(__FILE__, __func__, __LINE__, 1, SYSLOG_LEVEL_FATAL, ssh_err(r), __VA_ARGS__)
+#define logdie_fr(r, ...) sshlogdie(__FILE__, __func__, __LINE__, 1, SYSLOG_LEVEL_ERROR, ssh_err(r), __VA_ARGS__)
+#define sigdie_fr(r, ...) sshsigdie(__FILE__, __func__, __LINE__, 1, SYSLOG_LEVEL_ERROR, ssh_err(r), __VA_ARGS__)
+
#endif
diff --git a/crypto/openssh/loginrec.c b/crypto/openssh/loginrec.c
index 9a427dec4125..ea058fd6fa75 100644
--- a/crypto/openssh/loginrec.c
+++ b/crypto/openssh/loginrec.c
@@ -156,6 +156,7 @@
#include <netinet/in.h>
+#include <stdlib.h>
#include <errno.h>
#include <fcntl.h>
#ifdef HAVE_PATHS_H
@@ -163,6 +164,7 @@
#endif
#include <pwd.h>
#include <stdarg.h>
+#include <stdio.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
@@ -467,7 +469,7 @@ login_write(struct logininfo *li)
#ifdef CUSTOM_SYS_AUTH_RECORD_LOGIN
if (li->type == LTYPE_LOGIN &&
!sys_auth_record_login(li->username,li->hostname,li->line,
- &loginmsg))
+ loginmsg))
logit("Writing login record failed for %s", li->username);
#endif
#ifdef SSH_AUDIT_EVENTS
@@ -776,6 +778,9 @@ construct_utmpx(struct logininfo *li, struct utmpx *utx)
strncpy(utx->ut_host, li->hostname,
MIN_SIZEOF(utx->ut_host, li->hostname));
# endif
+# ifdef HAVE_SS_IN_UTMPX
+ utx->ut_ss = li->hostaddr.sa_storage;
+# endif
# ifdef HAVE_ADDR_IN_UTMPX
/* this is just a 32-bit IP address */
if (li->hostaddr.sa.sa_family == AF_INET)
@@ -1653,7 +1658,7 @@ utmpx_get_entry(struct logininfo *li)
*/
void
-record_failed_login(const char *username, const char *hostname,
+record_failed_login(struct ssh *ssh, const char *username, const char *hostname,
const char *ttyn)
{
int fd;
@@ -1696,8 +1701,8 @@ record_failed_login(const char *username, const char *hostname,
/* 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(),
+ if (ssh_packet_connection_is_on_socket(ssh) &&
+ getpeername(ssh_packet_get_connection_in(ssh),
(struct sockaddr *)&from, &fromlen) == 0) {
ipv64_normalise_mapped(&from, &fromlen);
if (from.ss_family == AF_INET) {
diff --git a/crypto/openssh/loginrec.h b/crypto/openssh/loginrec.h
index 28923e7812e5..02bceb604c7f 100644
--- a/crypto/openssh/loginrec.h
+++ b/crypto/openssh/loginrec.h
@@ -31,6 +31,8 @@
#include "includes.h"
+struct ssh;
+
/**
** you should use the login_* calls to work around platform dependencies
**/
@@ -92,7 +94,7 @@ struct logininfo *login_alloc_entry(pid_t pid, const char *username,
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);
+ const char *hostname, const char *line);
/* place the current time in a logininfo struct */
void login_set_current_time(struct logininfo *li);
@@ -126,6 +128,7 @@ 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 *);
+void record_failed_login(struct ssh *, const char *, const char *,
+ const char *);
#endif /* _HAVE_LOGINREC_H_ */
diff --git a/crypto/openssh/logintest.c b/crypto/openssh/logintest.c
index 4897ae0f9e11..6ee1cdc23645 100644
--- a/crypto/openssh/logintest.c
+++ b/crypto/openssh/logintest.c
@@ -62,21 +62,21 @@ 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);
+ "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);
}
@@ -118,7 +118,7 @@ testAPI()
/* 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));
+ sizeof(struct in_addr));
login_set_addr(li1, (struct sockaddr *) &sa_in4, sizeof(sa_in4));
strlcpy(li1->hostname, "localhost", sizeof(li1->hostname));
}
@@ -145,8 +145,8 @@ testAPI()
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);
+ "lastlog time is %d - %s\n",
+ (int)t0, s_t0, (int)t1, s_t1);
#endif
printf("Performing a login on line %s ", stripline);
@@ -172,10 +172,10 @@ testAPI()
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");
+ "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);
@@ -187,24 +187,24 @@ testAPI()
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");
+ "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);
+ "** 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);
+ "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);
diff --git a/crypto/openssh/m4/openssh.m4 b/crypto/openssh/m4/openssh.m4
new file mode 100644
index 000000000000..4f9c3792dc17
--- /dev/null
+++ b/crypto/openssh/m4/openssh.m4
@@ -0,0 +1,200 @@
+dnl OpenSSH-specific autoconf macros
+dnl
+
+dnl OSSH_CHECK_CFLAG_COMPILE(check_flag[, define_flag])
+dnl Check that $CC accepts a flag 'check_flag'. If it is supported append
+dnl 'define_flag' to $CFLAGS. If 'define_flag' is not specified, then append
+dnl 'check_flag'.
+AC_DEFUN([OSSH_CHECK_CFLAG_COMPILE], [{
+ AC_MSG_CHECKING([if $CC supports compile flag $1])
+ saved_CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS $WERROR $1"
+ _define_flag="$2"
+ test "x$_define_flag" = "x" && _define_flag="$1"
+ AC_COMPILE_IFELSE([AC_LANG_SOURCE([[
+#include <stdlib.h>
+#include <stdio.h>
+int main(int argc, char **argv) {
+ (void)argv;
+ /* Some math to catch -ftrapv problems in the toolchain */
+ int i = 123 * argc, j = 456 + argc, k = 789 - argc;
+ float l = i * 2.1;
+ double m = l / 0.5;
+ long long int n = argc * 12345LL, o = 12345LL * (long long int)argc;
+ printf("%d %d %d %f %f %lld %lld\n", i, j, k, l, m, n, o);
+ /*
+ * Test fallthrough behaviour. clang 10's -Wimplicit-fallthrough does
+ * not understand comments and we don't use the "fallthrough" attribute
+ * that it's looking for.
+ */
+ switch(i){
+ case 0: j += i;
+ /* FALLTHROUGH */
+ default: j += k;
+ }
+ exit(0);
+}
+ ]])],
+ [
+if $ac_cv_path_EGREP -i "unrecognized option|warning.*ignored" conftest.err >/dev/null
+then
+ AC_MSG_RESULT([no])
+ CFLAGS="$saved_CFLAGS"
+else
+ AC_MSG_RESULT([yes])
+ CFLAGS="$saved_CFLAGS $_define_flag"
+fi],
+ [ AC_MSG_RESULT([no])
+ CFLAGS="$saved_CFLAGS" ]
+ )
+}])
+
+dnl OSSH_CHECK_CFLAG_LINK(check_flag[, define_flag])
+dnl Check that $CC accepts a flag 'check_flag'. If it is supported append
+dnl 'define_flag' to $CFLAGS. If 'define_flag' is not specified, then append
+dnl 'check_flag'.
+AC_DEFUN([OSSH_CHECK_CFLAG_LINK], [{
+ AC_MSG_CHECKING([if $CC supports compile flag $1 and linking succeeds])
+ saved_CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS $WERROR $1"
+ _define_flag="$2"
+ test "x$_define_flag" = "x" && _define_flag="$1"
+ AC_LINK_IFELSE([AC_LANG_SOURCE([[
+#include <stdlib.h>
+#include <stdio.h>
+int main(int argc, char **argv) {
+ (void)argv;
+ /* Some math to catch -ftrapv problems in the toolchain */
+ int i = 123 * argc, j = 456 + argc, k = 789 - argc;
+ float l = i * 2.1;
+ double m = l / 0.5;
+ long long int n = argc * 12345LL, o = 12345LL * (long long int)argc;
+ long long int p = n * o;
+ printf("%d %d %d %f %f %lld %lld %lld\n", i, j, k, l, m, n, o, p);
+ exit(0);
+}
+ ]])],
+ [
+if $ac_cv_path_EGREP -i "unrecognized option|warning.*ignored" conftest.err >/dev/null
+then
+ AC_MSG_RESULT([no])
+ CFLAGS="$saved_CFLAGS"
+else
+ AC_MSG_RESULT([yes])
+ CFLAGS="$saved_CFLAGS $_define_flag"
+fi],
+ [ AC_MSG_RESULT([no])
+ CFLAGS="$saved_CFLAGS" ]
+ )
+}])
+
+dnl OSSH_CHECK_LDFLAG_LINK(check_flag[, define_flag])
+dnl Check that $LD accepts a flag 'check_flag'. If it is supported append
+dnl 'define_flag' to $LDFLAGS. If 'define_flag' is not specified, then append
+dnl 'check_flag'.
+AC_DEFUN([OSSH_CHECK_LDFLAG_LINK], [{
+ AC_MSG_CHECKING([if $LD supports link flag $1])
+ saved_LDFLAGS="$LDFLAGS"
+ LDFLAGS="$LDFLAGS $WERROR $1"
+ _define_flag="$2"
+ test "x$_define_flag" = "x" && _define_flag="$1"
+ AC_LINK_IFELSE([AC_LANG_SOURCE([[
+#include <stdlib.h>
+#include <stdio.h>
+int main(int argc, char **argv) {
+ (void)argv;
+ /* Some math to catch -ftrapv problems in the toolchain */
+ int i = 123 * argc, j = 456 + argc, k = 789 - argc;
+ float l = i * 2.1;
+ double m = l / 0.5;
+ long long int n = argc * 12345LL, o = 12345LL * (long long int)argc;
+ long long p = n * o;
+ printf("%d %d %d %f %f %lld %lld %lld\n", i, j, k, l, m, n, o, p);
+ exit(0);
+}
+ ]])],
+ [
+if $ac_cv_path_EGREP -i "unrecognized option|warning.*ignored" conftest.err >/dev/null
+then
+ AC_MSG_RESULT([no])
+ LDFLAGS="$saved_LDFLAGS"
+else
+ AC_MSG_RESULT([yes])
+ LDFLAGS="$saved_LDFLAGS $_define_flag"
+fi ],
+ [ AC_MSG_RESULT([no])
+ LDFLAGS="$saved_LDFLAGS" ]
+ )
+}])
+
+dnl OSSH_CHECK_HEADER_FOR_FIELD(field, header, symbol)
+dnl Does AC_EGREP_HEADER on 'header' for the string 'field'
+dnl If found, set 'symbol' to be defined. Cache the result.
+dnl TODO: This is not foolproof, better to compile and read from there
+AC_DEFUN([OSSH_CHECK_HEADER_FOR_FIELD], [
+# look for field '$1' in header '$2'
+ dnl This strips characters illegal to m4 from the header filename
+ ossh_safe=`echo "$2" | sed 'y%./+-%__p_%'`
+ dnl
+ ossh_varname="ossh_cv_$ossh_safe""_has_"$1
+ AC_MSG_CHECKING(for $1 field in $2)
+ AC_CACHE_VAL($ossh_varname, [
+ AC_EGREP_HEADER($1, $2, [ dnl
+ eval "$ossh_varname=yes" dnl
+ ], [ dnl
+ eval "$ossh_varname=no" dnl
+ ]) dnl
+ ])
+ ossh_result=`eval 'echo $'"$ossh_varname"`
+ if test -n "`echo $ossh_varname`"; then
+ AC_MSG_RESULT($ossh_result)
+ if test "x$ossh_result" = "xyes"; then
+ AC_DEFINE($3, 1, [Define if you have $1 in $2])
+ fi
+ else
+ AC_MSG_RESULT(no)
+ fi
+])
+
+dnl Check for socklen_t: historically on BSD it is an int, and in
+dnl POSIX 1g it is a type of its own, but some platforms use different
+dnl types for the argument to getsockopt, getpeername, etc. So we
+dnl have to test to find something that will work.
+AC_DEFUN([TYPE_SOCKLEN_T],
+[
+ AC_CHECK_TYPE([socklen_t], ,[
+ AC_MSG_CHECKING([for socklen_t equivalent])
+ AC_CACHE_VAL([curl_cv_socklen_t_equiv],
+ [
+ # Systems have either "struct sockaddr *" or
+ # "void *" as the second argument to getpeername
+ curl_cv_socklen_t_equiv=
+ for arg2 in "struct sockaddr" void; do
+ for t in int size_t unsigned long "unsigned long"; do
+ AC_COMPILE_IFELSE([
+ AC_LANG_PROGRAM([[
+ #include <sys/types.h>
+ #include <sys/socket.h>
+ int getpeername (int, $arg2 *, $t *);
+ ]], [[
+ $t len;
+ getpeername(0,0,&len);
+ ]])
+ ],[
+ curl_cv_socklen_t_equiv="$t"
+ break
+ ])
+ done
+ done
+
+ if test "x$curl_cv_socklen_t_equiv" = x; then
+ AC_MSG_ERROR([Cannot find a type to use in place of socklen_t])
+ fi
+ ])
+ AC_MSG_RESULT($curl_cv_socklen_t_equiv)
+ AC_DEFINE_UNQUOTED(socklen_t, $curl_cv_socklen_t_equiv,
+ [type to use in place of socklen_t if not defined])],
+ [#include <sys/types.h>
+#include <sys/socket.h>])
+])
+
diff --git a/crypto/openssh/mac.c b/crypto/openssh/mac.c
index 51dc11d76b92..f3dda6692866 100644
--- a/crypto/openssh/mac.c
+++ b/crypto/openssh/mac.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: mac.c,v 1.34 2017/05/08 22:57:38 djm Exp $ */
+/* $OpenBSD: mac.c,v 1.35 2019/09/06 04:53:27 djm Exp $ */
/*
* Copyright (c) 2001 Markus Friedl. All rights reserved.
*
@@ -27,6 +27,7 @@
#include <sys/types.h>
+#include <stdlib.h>
#include <string.h>
#include <stdio.h>
@@ -58,10 +59,8 @@ static const struct macalg macs[] = {
/* Encrypt-and-MAC (encrypt-and-authenticate) variants */
{ "hmac-sha1", SSH_DIGEST, SSH_DIGEST_SHA1, 0, 0, 0, 0 },
{ "hmac-sha1-96", SSH_DIGEST, SSH_DIGEST_SHA1, 96, 0, 0, 0 },
-#ifdef HAVE_EVP_SHA256
{ "hmac-sha2-256", SSH_DIGEST, SSH_DIGEST_SHA256, 0, 0, 0, 0 },
{ "hmac-sha2-512", SSH_DIGEST, SSH_DIGEST_SHA512, 0, 0, 0, 0 },
-#endif
{ "hmac-md5", SSH_DIGEST, SSH_DIGEST_MD5, 0, 0, 0, 0 },
{ "hmac-md5-96", SSH_DIGEST, SSH_DIGEST_MD5, 96, 0, 0, 0 },
{ "umac-64@openssh.com", SSH_UMAC, 0, 0, 128, 64, 0 },
@@ -70,10 +69,8 @@ static const struct macalg macs[] = {
/* Encrypt-then-MAC variants */
{ "hmac-sha1-etm@openssh.com", SSH_DIGEST, SSH_DIGEST_SHA1, 0, 0, 0, 1 },
{ "hmac-sha1-96-etm@openssh.com", SSH_DIGEST, SSH_DIGEST_SHA1, 96, 0, 0, 1 },
-#ifdef HAVE_EVP_SHA256
{ "hmac-sha2-256-etm@openssh.com", SSH_DIGEST, SSH_DIGEST_SHA256, 0, 0, 0, 1 },
{ "hmac-sha2-512-etm@openssh.com", SSH_DIGEST, SSH_DIGEST_SHA512, 0, 0, 0, 1 },
-#endif
{ "hmac-md5-etm@openssh.com", SSH_DIGEST, SSH_DIGEST_MD5, 0, 0, 0, 1 },
{ "hmac-md5-96-etm@openssh.com", SSH_DIGEST, SSH_DIGEST_MD5, 96, 0, 0, 1 },
{ "umac-64-etm@openssh.com", SSH_UMAC, 0, 0, 128, 64, 1 },
diff --git a/crypto/openssh/match.c b/crypto/openssh/match.c
index bb3e95f678ca..3ac854d38f00 100644
--- a/crypto/openssh/match.c
+++ b/crypto/openssh/match.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: match.c,v 1.38 2018/07/04 13:49:31 djm Exp $ */
+/* $OpenBSD: match.c,v 1.43 2020/11/03 22:53:12 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -42,6 +42,7 @@
#include <ctype.h>
#include <stdlib.h>
#include <string.h>
+#include <stdarg.h>
#include <stdio.h>
#include "xmalloc.h"
@@ -52,7 +53,6 @@
* Returns true if the given string matches the pattern (which may contain ?
* and * as wildcards), and zero if it does not match.
*/
-
int
match_pattern(const char *s, const char *pattern)
{
@@ -62,8 +62,9 @@ match_pattern(const char *s, const char *pattern)
return !*s;
if (*pattern == '*') {
- /* Skip the asterisk. */
- pattern++;
+ /* Skip this and any consecutive asterisks. */
+ while (*pattern == '*')
+ pattern++;
/* If at end of pattern, accept immediately. */
if (!*pattern)
@@ -170,6 +171,19 @@ match_pattern_list(const char *string, const char *pattern, int dolower)
return got_positive;
}
+/* Match a list representing users or groups. */
+int
+match_usergroup_pattern_list(const char *string, const char *pattern)
+{
+#ifdef HAVE_CYGWIN
+ /* Windows usernames may be Unicode and are not case sensitive */
+ return cygwin_ug_match_pattern_list(string, pattern);
+#else
+ /* Case sensitive match */
+ return match_pattern_list(string, pattern, 0);
+#endif
+}
+
/*
* Tries to match the host name (which must be in all lowercase) against the
* comma-separated sequence of subpatterns (each possibly preceded by ! to
@@ -233,7 +247,7 @@ match_user(const char *user, const char *host, const char *ipaddr,
return 0;
}
- if ((p = strchr(pattern,'@')) == NULL)
+ if ((p = strchr(pattern, '@')) == NULL)
return match_pattern(user, pattern);
pat = xstrdup(pattern);
@@ -295,13 +309,13 @@ match_list(const char *client, const char *server, u_int *next)
/*
* Filter proposal using pattern-list filter.
- * "blacklist" determines sense of filter:
+ * "denylist" determines sense of filter:
* non-zero indicates that items matching filter should be excluded.
* zero indicates that only items matching filter should be included.
* returns NULL on allocation error, otherwise caller must free result.
*/
static char *
-filter_list(const char *proposal, const char *filter, int blacklist)
+filter_list(const char *proposal, const char *filter, int denylist)
{
size_t len = strlen(proposal) + 1;
char *fix_prop = malloc(len);
@@ -319,7 +333,7 @@ filter_list(const char *proposal, const char *filter, int blacklist)
*fix_prop = '\0';
while ((cp = strsep(&tmp, ",")) != NULL) {
r = match_pattern_list(cp, filter, 0);
- if ((blacklist && r != 1) || (!blacklist && r == 1)) {
+ if ((denylist && r != 1) || (!denylist && r == 1)) {
if (*fix_prop != '\0')
strlcat(fix_prop, ",", len);
strlcat(fix_prop, cp, len);
@@ -334,7 +348,7 @@ filter_list(const char *proposal, const char *filter, int blacklist)
* the 'filter' pattern list. Caller must free returned string.
*/
char *
-match_filter_blacklist(const char *proposal, const char *filter)
+match_filter_denylist(const char *proposal, const char *filter)
{
return filter_list(proposal, filter, 1);
}
@@ -344,7 +358,7 @@ match_filter_blacklist(const char *proposal, const char *filter)
* the 'filter' pattern list. Caller must free returned string.
*/
char *
-match_filter_whitelist(const char *proposal, const char *filter)
+match_filter_allowlist(const char *proposal, const char *filter)
{
return filter_list(proposal, filter, 0);
}
diff --git a/crypto/openssh/match.h b/crypto/openssh/match.h
index 852b1a5cb164..312ca6e1679c 100644
--- a/crypto/openssh/match.h
+++ b/crypto/openssh/match.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: match.h,v 1.18 2018/07/04 13:49:31 djm Exp $ */
+/* $OpenBSD: match.h,v 1.20 2020/07/05 23:59:45 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -16,12 +16,13 @@
int match_pattern(const char *, const char *);
int match_pattern_list(const char *, const char *, int);
+int match_usergroup_pattern_list(const char *, const char *);
int match_hostname(const char *, const char *);
int match_host_and_ip(const char *, const char *, const char *);
int match_user(const char *, const char *, const char *, const char *);
char *match_list(const char *, const char *, u_int *);
-char *match_filter_blacklist(const char *, const char *);
-char *match_filter_whitelist(const char *, const char *);
+char *match_filter_denylist(const char *, const char *);
+char *match_filter_allowlist(const char *, const char *);
/* addrmatch.c */
int addr_match_list(const char *, const char *);
diff --git a/crypto/openssh/misc.c b/crypto/openssh/misc.c
index bdc06fdb3332..b8d1040d1e3c 100644
--- a/crypto/openssh/misc.c
+++ b/crypto/openssh/misc.c
@@ -1,29 +1,23 @@
-/* $OpenBSD: misc.c,v 1.133 2018/10/05 14:26:09 naddy Exp $ */
+/* $OpenBSD: misc.c,v 1.169 2021/08/09 23:47:44 djm Exp $ */
/*
* Copyright (c) 2000 Markus Friedl. All rights reserved.
- * Copyright (c) 2005,2006 Damien Miller. All rights reserved.
+ * Copyright (c) 2005-2020 Damien Miller. All rights reserved.
+ * Copyright (c) 2004 Henning Brauer <henning@openbsd.org>
*
- * 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.
+ * 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.
*
- * 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 SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
+
#include "includes.h"
#include <sys/types.h>
@@ -38,6 +32,9 @@
#ifdef HAVE_LIBGEN_H
# include <libgen.h>
#endif
+#ifdef HAVE_POLL_H
+#include <poll.h>
+#endif
#include <signal.h>
#include <stdarg.h>
#include <stdio.h>
@@ -88,6 +85,20 @@ chop(char *s)
}
+/* remove whitespace from end of string */
+void
+rtrim(char *s)
+{
+ size_t i;
+
+ if ((i = strlen(s)) == 0)
+ return;
+ for (i--; i > 0; i--) {
+ if (isspace((int)s[i]))
+ s[i] = '\0';
+ }
+}
+
/* set/unset filedescriptor to non-blocking */
int
set_nonblock(int fd)
@@ -95,7 +106,7 @@ set_nonblock(int fd)
int val;
val = fcntl(fd, F_GETFL);
- if (val < 0) {
+ if (val == -1) {
error("fcntl(%d, F_GETFL): %s", fd, strerror(errno));
return (-1);
}
@@ -119,7 +130,7 @@ unset_nonblock(int fd)
int val;
val = fcntl(fd, F_GETFL);
- if (val < 0) {
+ if (val == -1) {
error("fcntl(%d, F_GETFL): %s", fd, strerror(errno));
return (-1);
}
@@ -234,6 +245,149 @@ set_rdomain(int fd, const char *name)
#endif
}
+int
+get_sock_af(int fd)
+{
+ struct sockaddr_storage to;
+ socklen_t tolen = sizeof(to);
+
+ memset(&to, 0, sizeof(to));
+ if (getsockname(fd, (struct sockaddr *)&to, &tolen) == -1)
+ return -1;
+#ifdef IPV4_IN_IPV6
+ if (to.ss_family == AF_INET6 &&
+ IN6_IS_ADDR_V4MAPPED(&((struct sockaddr_in6 *)&to)->sin6_addr))
+ return AF_INET;
+#endif
+ return to.ss_family;
+}
+
+void
+set_sock_tos(int fd, int tos)
+{
+#ifndef IP_TOS_IS_BROKEN
+ int af;
+
+ switch ((af = get_sock_af(fd))) {
+ case -1:
+ /* assume not a socket */
+ break;
+ case AF_INET:
+# ifdef IP_TOS
+ debug3_f("set socket %d IP_TOS 0x%02x", fd, tos);
+ if (setsockopt(fd, IPPROTO_IP, IP_TOS,
+ &tos, sizeof(tos)) == -1) {
+ error("setsockopt socket %d IP_TOS %d: %s:",
+ fd, tos, strerror(errno));
+ }
+# endif /* IP_TOS */
+ break;
+ case AF_INET6:
+# ifdef IPV6_TCLASS
+ debug3_f("set socket %d IPV6_TCLASS 0x%02x", fd, tos);
+ if (setsockopt(fd, IPPROTO_IPV6, IPV6_TCLASS,
+ &tos, sizeof(tos)) == -1) {
+ error("setsockopt socket %d IPV6_TCLASS %d: %.100s:",
+ fd, tos, strerror(errno));
+ }
+# endif /* IPV6_TCLASS */
+ break;
+ default:
+ debug2_f("unsupported socket family %d", af);
+ break;
+ }
+#endif /* IP_TOS_IS_BROKEN */
+}
+
+/*
+ * Wait up to *timeoutp milliseconds for events on fd. Updates
+ * *timeoutp with time remaining.
+ * Returns 0 if fd ready or -1 on timeout or error (see errno).
+ */
+static int
+waitfd(int fd, int *timeoutp, short events)
+{
+ struct pollfd pfd;
+ struct timeval t_start;
+ int oerrno, r;
+
+ pfd.fd = fd;
+ pfd.events = events;
+ for (; *timeoutp >= 0;) {
+ monotime_tv(&t_start);
+ r = poll(&pfd, 1, *timeoutp);
+ oerrno = errno;
+ ms_subtract_diff(&t_start, timeoutp);
+ errno = oerrno;
+ if (r > 0)
+ return 0;
+ else if (r == -1 && errno != EAGAIN && errno != EINTR)
+ return -1;
+ else if (r == 0)
+ break;
+ }
+ /* timeout */
+ errno = ETIMEDOUT;
+ return -1;
+}
+
+/*
+ * Wait up to *timeoutp milliseconds for fd to be readable. Updates
+ * *timeoutp with time remaining.
+ * Returns 0 if fd ready or -1 on timeout or error (see errno).
+ */
+int
+waitrfd(int fd, int *timeoutp) {
+ return waitfd(fd, timeoutp, POLLIN);
+}
+
+/*
+ * Attempt a non-blocking connect(2) to the specified address, waiting up to
+ * *timeoutp milliseconds for the connection to complete. If the timeout is
+ * <=0, then wait indefinitely.
+ *
+ * Returns 0 on success or -1 on failure.
+ */
+int
+timeout_connect(int sockfd, const struct sockaddr *serv_addr,
+ socklen_t addrlen, int *timeoutp)
+{
+ int optval = 0;
+ socklen_t optlen = sizeof(optval);
+
+ /* No timeout: just do a blocking connect() */
+ if (timeoutp == NULL || *timeoutp <= 0)
+ return connect(sockfd, serv_addr, addrlen);
+
+ set_nonblock(sockfd);
+ for (;;) {
+ if (connect(sockfd, serv_addr, addrlen) == 0) {
+ /* Succeeded already? */
+ unset_nonblock(sockfd);
+ return 0;
+ } else if (errno == EINTR)
+ continue;
+ else if (errno != EINPROGRESS)
+ return -1;
+ break;
+ }
+
+ if (waitfd(sockfd, timeoutp, POLLIN | POLLOUT) == -1)
+ return -1;
+
+ /* Completed or failed */
+ if (getsockopt(sockfd, SOL_SOCKET, SO_ERROR, &optval, &optlen) == -1) {
+ debug("getsockopt: %s", strerror(errno));
+ return -1;
+ }
+ if (optval != 0) {
+ errno = optval;
+ return -1;
+ }
+ unset_nonblock(sockfd);
+ return 0;
+}
+
/* Characters considered whitespace in strsep calls. */
#define WHITESPACE " \t\r\n"
#define QUOTE "\""
@@ -305,7 +459,7 @@ pwcopy(struct passwd *pw)
struct passwd *copy = xcalloc(1, sizeof(*copy));
copy->pw_name = xstrdup(pw->pw_name);
- copy->pw_passwd = xstrdup(pw->pw_passwd);
+ copy->pw_passwd = xstrdup(pw->pw_passwd == NULL ? "*" : pw->pw_passwd);
#ifdef HAVE_STRUCT_PASSWD_PW_GECOS
copy->pw_gecos = xstrdup(pw->pw_gecos);
#endif
@@ -403,10 +557,10 @@ a2tun(const char *s, int *remote)
*
* Return -1 if time string is invalid.
*/
-long
+int
convtime(const char *s)
{
- long total, secs, multiplier = 1;
+ long total, secs, multiplier;
const char *p;
char *endp;
@@ -420,10 +574,11 @@ convtime(const char *s)
while (*p) {
secs = strtol(p, &endp, 10);
if (p == endp ||
- (errno == ERANGE && (secs == LONG_MIN || secs == LONG_MAX)) ||
+ (errno == ERANGE && (secs == INT_MIN || secs == INT_MAX)) ||
secs < 0)
return -1;
+ multiplier = 1;
switch (*endp++) {
case '\0':
endp--;
@@ -450,10 +605,10 @@ convtime(const char *s)
default:
return -1;
}
- if (secs >= LONG_MAX / multiplier)
+ if (secs > INT_MAX / multiplier)
return -1;
secs *= multiplier;
- if (total >= LONG_MAX - secs)
+ if (total > INT_MAX - secs)
return -1;
total += secs;
if (total < 0)
@@ -464,6 +619,43 @@ convtime(const char *s)
return total;
}
+#define TF_BUFS 8
+#define TF_LEN 9
+
+const char *
+fmt_timeframe(time_t t)
+{
+ char *buf;
+ static char tfbuf[TF_BUFS][TF_LEN]; /* ring buffer */
+ static int idx = 0;
+ unsigned int sec, min, hrs, day;
+ unsigned long long week;
+
+ buf = tfbuf[idx++];
+ if (idx == TF_BUFS)
+ idx = 0;
+
+ week = t;
+
+ sec = week % 60;
+ week /= 60;
+ min = week % 60;
+ week /= 60;
+ hrs = week % 24;
+ week /= 24;
+ day = week % 7;
+ week /= 7;
+
+ if (week > 0)
+ snprintf(buf, TF_LEN, "%02lluw%01ud%02uh", week, day, hrs);
+ else if (day > 0)
+ snprintf(buf, TF_LEN, "%01ud%02uh%02um", day, hrs, min);
+ else
+ snprintf(buf, TF_LEN, "%02u:%02u:%02u", hrs, min, sec);
+
+ return (buf);
+}
+
/*
* Returns a standardized host+port identifier string.
* Caller must free returned string.
@@ -475,7 +667,7 @@ put_host_port(const char *host, u_short port)
if (port == 0 || port == SSH_DEFAULT_PORT)
return(xstrdup(host));
- if (asprintf(&hoststr, "[%s]:%d", host, (int)port) < 0)
+ if (asprintf(&hoststr, "[%s]:%d", host, (int)port) == -1)
fatal("put_host_port: asprintf: %s", strerror(errno));
debug3("put_host_port: %s", hoststr);
return hoststr;
@@ -489,7 +681,7 @@ put_host_port(const char *host, u_short port)
* The delimiter char, if present, is stored in delim.
* If this is the last field, *cp is set to NULL.
*/
-static char *
+char *
hpdelim2(char **cp, char *delim)
{
char *s, *old;
@@ -923,29 +1115,37 @@ freeargs(arglist *args)
* Expands tildes in the file name. Returns data allocated by xmalloc.
* Warning: this calls getpw*.
*/
-char *
-tilde_expand_filename(const char *filename, uid_t uid)
+int
+tilde_expand(const char *filename, uid_t uid, char **retp)
{
const char *path, *sep;
char user[128], *ret;
struct passwd *pw;
u_int len, slash;
- if (*filename != '~')
- return (xstrdup(filename));
+ if (*filename != '~') {
+ *retp = xstrdup(filename);
+ return 0;
+ }
filename++;
path = strchr(filename, '/');
if (path != NULL && path > filename) { /* ~user/path */
slash = path - filename;
- if (slash > sizeof(user) - 1)
- fatal("tilde_expand_filename: ~username too long");
+ if (slash > sizeof(user) - 1) {
+ error_f("~username too long");
+ return -1;
+ }
memcpy(user, filename, slash);
user[slash] = '\0';
- if ((pw = getpwnam(user)) == NULL)
- fatal("tilde_expand_filename: No such user %s", user);
- } else if ((pw = getpwuid(uid)) == NULL) /* ~/path */
- fatal("tilde_expand_filename: No such uid %ld", (long)uid);
+ if ((pw = getpwnam(user)) == NULL) {
+ error_f("No such user %s", user);
+ return -1;
+ }
+ } else if ((pw = getpwuid(uid)) == NULL) { /* ~/path */
+ error_f("No such uid %ld", (long)uid);
+ return -1;
+ }
/* Make sure directory has a trailing '/' */
len = strlen(pw->pw_dir);
@@ -958,76 +1158,201 @@ tilde_expand_filename(const char *filename, uid_t uid)
if (path != NULL)
filename = path + 1;
- if (xasprintf(&ret, "%s%s%s", pw->pw_dir, sep, filename) >= PATH_MAX)
- fatal("tilde_expand_filename: Path too long");
+ if (xasprintf(&ret, "%s%s%s", pw->pw_dir, sep, filename) >= PATH_MAX) {
+ error_f("Path too long");
+ return -1;
+ }
- return (ret);
+ *retp = ret;
+ return 0;
+}
+
+char *
+tilde_expand_filename(const char *filename, uid_t uid)
+{
+ char *ret;
+
+ if (tilde_expand(filename, uid, &ret) != 0)
+ cleanup_exit(255);
+ return ret;
}
/*
- * Expand a string with a set of %[char] escapes. A number of escapes may be
- * specified as (char *escape_chars, char *replacement) pairs. The list must
- * be terminated by a NULL escape_char. Returns replaced string in memory
- * allocated by xmalloc.
+ * Expand a string with a set of %[char] escapes and/or ${ENVIRONMENT}
+ * substitutions. A number of escapes may be specified as
+ * (char *escape_chars, char *replacement) pairs. The list must be terminated
+ * by a NULL escape_char. Returns replaced string in memory allocated by
+ * xmalloc which the caller must free.
*/
-char *
-percent_expand(const char *string, ...)
+static char *
+vdollar_percent_expand(int *parseerror, int dollar, int percent,
+ const char *string, va_list ap)
{
#define EXPAND_MAX_KEYS 16
- u_int num_keys, i, j;
+ u_int num_keys = 0, i;
struct {
const char *key;
const char *repl;
} keys[EXPAND_MAX_KEYS];
- char buf[4096];
- va_list ap;
+ struct sshbuf *buf;
+ int r, missingvar = 0;
+ char *ret = NULL, *var, *varend, *val;
+ size_t len;
- /* Gather keys */
- va_start(ap, string);
- for (num_keys = 0; num_keys < EXPAND_MAX_KEYS; num_keys++) {
- keys[num_keys].key = va_arg(ap, char *);
- if (keys[num_keys].key == NULL)
- break;
- keys[num_keys].repl = va_arg(ap, char *);
- if (keys[num_keys].repl == NULL)
- fatal("%s: NULL replacement", __func__);
+ if ((buf = sshbuf_new()) == NULL)
+ fatal_f("sshbuf_new failed");
+ if (parseerror == NULL)
+ fatal_f("null parseerror arg");
+ *parseerror = 1;
+
+ /* Gather keys if we're doing percent expansion. */
+ if (percent) {
+ for (num_keys = 0; num_keys < EXPAND_MAX_KEYS; num_keys++) {
+ keys[num_keys].key = va_arg(ap, char *);
+ if (keys[num_keys].key == NULL)
+ break;
+ keys[num_keys].repl = va_arg(ap, char *);
+ if (keys[num_keys].repl == NULL) {
+ fatal_f("NULL replacement for token %s",
+ keys[num_keys].key);
+ }
+ }
+ if (num_keys == EXPAND_MAX_KEYS && va_arg(ap, char *) != NULL)
+ fatal_f("too many keys");
+ if (num_keys == 0)
+ fatal_f("percent expansion without token list");
}
- if (num_keys == EXPAND_MAX_KEYS && va_arg(ap, char *) != NULL)
- fatal("%s: too many keys", __func__);
- va_end(ap);
/* Expand string */
- *buf = '\0';
for (i = 0; *string != '\0'; string++) {
- if (*string != '%') {
+ /* Optionally process ${ENVIRONMENT} expansions. */
+ if (dollar && string[0] == '$' && string[1] == '{') {
+ string += 2; /* skip over '${' */
+ if ((varend = strchr(string, '}')) == NULL) {
+ error_f("environment variable '%s' missing "
+ "closing '}'", string);
+ goto out;
+ }
+ len = varend - string;
+ if (len == 0) {
+ error_f("zero-length environment variable");
+ goto out;
+ }
+ var = xmalloc(len + 1);
+ (void)strlcpy(var, string, len + 1);
+ if ((val = getenv(var)) == NULL) {
+ error_f("env var ${%s} has no value", var);
+ missingvar = 1;
+ } else {
+ debug3_f("expand ${%s} -> '%s'", var, val);
+ if ((r = sshbuf_put(buf, val, strlen(val))) !=0)
+ fatal_fr(r, "sshbuf_put ${}");
+ }
+ free(var);
+ string += len;
+ continue;
+ }
+
+ /*
+ * Process percent expansions if we have a list of TOKENs.
+ * If we're not doing percent expansion everything just gets
+ * appended here.
+ */
+ if (*string != '%' || !percent) {
append:
- buf[i++] = *string;
- if (i >= sizeof(buf))
- fatal("%s: string too long", __func__);
- buf[i] = '\0';
+ if ((r = sshbuf_put_u8(buf, *string)) != 0)
+ fatal_fr(r, "sshbuf_put_u8 %%");
continue;
}
string++;
/* %% case */
if (*string == '%')
goto append;
- if (*string == '\0')
- fatal("%s: invalid format", __func__);
- for (j = 0; j < num_keys; j++) {
- if (strchr(keys[j].key, *string) != NULL) {
- i = strlcat(buf, keys[j].repl, sizeof(buf));
- if (i >= sizeof(buf))
- fatal("%s: string too long", __func__);
+ if (*string == '\0') {
+ error_f("invalid format");
+ goto out;
+ }
+ for (i = 0; i < num_keys; i++) {
+ if (strchr(keys[i].key, *string) != NULL) {
+ if ((r = sshbuf_put(buf, keys[i].repl,
+ strlen(keys[i].repl))) != 0)
+ fatal_fr(r, "sshbuf_put %%-repl");
break;
}
}
- if (j >= num_keys)
- fatal("%s: unknown key %%%c", __func__, *string);
+ if (i >= num_keys) {
+ error_f("unknown key %%%c", *string);
+ goto out;
+ }
}
- return (xstrdup(buf));
+ if (!missingvar && (ret = sshbuf_dup_string(buf)) == NULL)
+ fatal_f("sshbuf_dup_string failed");
+ *parseerror = 0;
+ out:
+ sshbuf_free(buf);
+ return *parseerror ? NULL : ret;
#undef EXPAND_MAX_KEYS
}
+/*
+ * Expand only environment variables.
+ * Note that although this function is variadic like the other similar
+ * functions, any such arguments will be unused.
+ */
+
+char *
+dollar_expand(int *parseerr, const char *string, ...)
+{
+ char *ret;
+ int err;
+ va_list ap;
+
+ va_start(ap, string);
+ ret = vdollar_percent_expand(&err, 1, 0, string, ap);
+ va_end(ap);
+ if (parseerr != NULL)
+ *parseerr = err;
+ return ret;
+}
+
+/*
+ * Returns expanded string or NULL if a specified environment variable is
+ * not defined, or calls fatal if the string is invalid.
+ */
+char *
+percent_expand(const char *string, ...)
+{
+ char *ret;
+ int err;
+ va_list ap;
+
+ va_start(ap, string);
+ ret = vdollar_percent_expand(&err, 0, 1, string, ap);
+ va_end(ap);
+ if (err)
+ fatal_f("failed");
+ return ret;
+}
+
+/*
+ * Returns expanded string or NULL if a specified environment variable is
+ * not defined, or calls fatal if the string is invalid.
+ */
+char *
+percent_dollar_expand(const char *string, ...)
+{
+ char *ret;
+ int err;
+ va_list ap;
+
+ va_start(ap, string);
+ ret = vdollar_percent_expand(&err, 1, 1, string, ap);
+ va_end(ap);
+ if (err)
+ fatal_f("failed");
+ return ret;
+}
+
int
tun_open(int tun, int mode, char **ifname)
{
@@ -1057,16 +1382,16 @@ tun_open(int tun, int mode, char **ifname)
break;
}
} else {
- debug("%s: invalid tunnel %u", __func__, tun);
+ debug_f("invalid tunnel %u", tun);
return -1;
}
- if (fd < 0) {
- debug("%s: %s open: %s", __func__, name, strerror(errno));
+ if (fd == -1) {
+ debug_f("%s open: %s", name, strerror(errno));
return -1;
}
- debug("%s: %s mode %d fd %d", __func__, name, mode, fd);
+ debug_f("%s mode %d fd %d", name, mode, fd);
/* Bring interface up if it is not already */
snprintf(ifr.ifr_name, sizeof(ifr.ifr_name), "%s%d", tunbase, tun);
@@ -1074,16 +1399,16 @@ tun_open(int tun, int mode, char **ifname)
goto failed;
if (ioctl(sock, SIOCGIFFLAGS, &ifr) == -1) {
- debug("%s: get interface %s flags: %s", __func__,
- ifr.ifr_name, strerror(errno));
+ debug_f("get interface %s flags: %s", ifr.ifr_name,
+ strerror(errno));
goto failed;
}
if (!(ifr.ifr_flags & IFF_UP)) {
ifr.ifr_flags |= IFF_UP;
if (ioctl(sock, SIOCSIFFLAGS, &ifr) == -1) {
- debug("%s: activate interface %s: %s", __func__,
- ifr.ifr_name, strerror(errno));
+ debug_f("activate interface %s: %s", ifr.ifr_name,
+ strerror(errno));
goto failed;
}
}
@@ -1148,6 +1473,33 @@ tohex(const void *vp, size_t l)
return (r);
}
+/*
+ * Extend string *sp by the specified format. If *sp is not NULL (or empty),
+ * then the separator 'sep' will be prepended before the formatted arguments.
+ * Extended strings are heap allocated.
+ */
+void
+xextendf(char **sp, const char *sep, const char *fmt, ...)
+{
+ va_list ap;
+ char *tmp1, *tmp2;
+
+ va_start(ap, fmt);
+ xvasprintf(&tmp1, fmt, ap);
+ va_end(ap);
+
+ if (*sp == NULL || **sp == '\0') {
+ free(*sp);
+ *sp = tmp1;
+ return;
+ }
+ xasprintf(&tmp2, "%s%s%s", *sp, sep == NULL ? "" : sep, tmp1);
+ free(tmp1);
+ free(*sp);
+ *sp = tmp2;
+}
+
+
u_int64_t
get_u64(const void *vp)
{
@@ -1335,11 +1687,11 @@ bandwidth_limit_init(struct bwlimit *bw, u_int64_t kbps, size_t buflen)
{
bw->buflen = buflen;
bw->rate = kbps;
- bw->thresh = bw->rate;
+ bw->thresh = buflen;
bw->lamt = 0;
timerclear(&bw->bwstart);
timerclear(&bw->bwend);
-}
+}
/* Callback from read/write loop to insert bandwidth-limiting delays */
void
@@ -1348,12 +1700,11 @@ bandwidth_limit(struct bwlimit *bw, size_t read_len)
u_int64_t waitlen;
struct timespec ts, rm;
+ bw->lamt += read_len;
if (!timerisset(&bw->bwstart)) {
monotime_tv(&bw->bwstart);
return;
}
-
- bw->lamt += read_len;
if (bw->lamt < bw->thresh)
return;
@@ -1408,7 +1759,7 @@ mktemp_proto(char *s, size_t len)
}
r = snprintf(s, len, "/tmp/ssh-XXXXXXXXXXXX");
if (r < 0 || (size_t)r >= len)
- fatal("%s: template string too short", __func__);
+ fatal_f("template string too short");
}
static const struct {
@@ -1437,6 +1788,7 @@ static const struct {
{ "cs6", IPTOS_DSCP_CS6 },
{ "cs7", IPTOS_DSCP_CS7 },
{ "ef", IPTOS_DSCP_EF },
+ { "le", IPTOS_DSCP_LE },
{ "lowdelay", IPTOS_LOWDELAY },
{ "throughput", IPTOS_THROUGHPUT },
{ "reliability", IPTOS_RELIABILITY },
@@ -1494,16 +1846,15 @@ unix_listener(const char *path, int backlog, int unlink_first)
sunaddr.sun_family = AF_UNIX;
if (strlcpy(sunaddr.sun_path, path,
sizeof(sunaddr.sun_path)) >= sizeof(sunaddr.sun_path)) {
- error("%s: path \"%s\" too long for Unix domain socket",
- __func__, path);
+ error_f("path \"%s\" too long for Unix domain socket", path);
errno = ENAMETOOLONG;
return -1;
}
sock = socket(PF_UNIX, SOCK_STREAM, 0);
- if (sock < 0) {
+ if (sock == -1) {
saved_errno = errno;
- error("%s: socket: %.100s", __func__, strerror(errno));
+ error_f("socket: %.100s", strerror(errno));
errno = saved_errno;
return -1;
}
@@ -1511,18 +1862,16 @@ unix_listener(const char *path, int backlog, int unlink_first)
if (unlink(path) != 0 && errno != ENOENT)
error("unlink(%s): %.100s", path, strerror(errno));
}
- if (bind(sock, (struct sockaddr *)&sunaddr, sizeof(sunaddr)) < 0) {
+ if (bind(sock, (struct sockaddr *)&sunaddr, sizeof(sunaddr)) == -1) {
saved_errno = errno;
- error("%s: cannot bind to path %s: %s",
- __func__, path, strerror(errno));
+ error_f("cannot bind to path %s: %s", path, strerror(errno));
close(sock);
errno = saved_errno;
return -1;
}
- if (listen(sock, backlog) < 0) {
+ if (listen(sock, backlog) == -1) {
saved_errno = errno;
- error("%s: cannot listen on path %s: %s",
- __func__, path, strerror(errno));
+ error_f("cannot listen on path %s: %s", path, strerror(errno));
close(sock);
unlink(path);
errno = saved_errno;
@@ -1598,14 +1947,13 @@ daemonized(void)
return 1;
}
-
/*
* Splits 's' into an argument vector. Handles quoted string and basic
* escape characters (\\, \", \'). Caller must free the argument vector
* and its members.
*/
int
-argv_split(const char *s, int *argcp, char ***argvp)
+argv_split(const char *s, int *argcp, char ***argvp, int terminate_on_comment)
{
int r = SSH_ERR_INTERNAL_ERROR;
int argc = 0, quote, i, j;
@@ -1618,14 +1966,10 @@ argv_split(const char *s, int *argcp, char ***argvp)
/* Skip leading whitespace */
if (s[i] == ' ' || s[i] == '\t')
continue;
-
+ if (terminate_on_comment && s[i] == '#')
+ break;
/* Start of a token */
quote = 0;
- if (s[i] == '\\' &&
- (s[i + 1] == '\'' || s[i + 1] == '\"' || s[i + 1] == '\\'))
- i++;
- else if (s[i] == '\'' || s[i] == '"')
- quote = s[i++];
argv = xreallocarray(argv, (argc + 2), sizeof(*argv));
arg = argv[argc++] = xcalloc(1, strlen(s + i) + 1);
@@ -1636,7 +1980,8 @@ argv_split(const char *s, int *argcp, char ***argvp)
if (s[i] == '\\') {
if (s[i + 1] == '\'' ||
s[i + 1] == '\"' ||
- s[i + 1] == '\\') {
+ s[i + 1] == '\\' ||
+ (quote == 0 && s[i + 1] == ' ')) {
i++; /* Skip '\' */
arg[j++] = s[i];
} else {
@@ -1645,8 +1990,10 @@ argv_split(const char *s, int *argcp, char ***argvp)
}
} else if (quote == 0 && (s[i] == ' ' || s[i] == '\t'))
break; /* done */
+ else if (quote == 0 && (s[i] == '\"' || s[i] == '\''))
+ quote = s[i]; /* quote start */
else if (quote != 0 && s[i] == quote)
- break; /* done */
+ quote = 0; /* quote end */
else
arg[j++] = s[i];
}
@@ -1686,7 +2033,7 @@ argv_assemble(int argc, char **argv)
struct sshbuf *buf, *arg;
if ((buf = sshbuf_new()) == NULL || (arg = sshbuf_new()) == NULL)
- fatal("%s: sshbuf_new failed", __func__);
+ fatal_f("sshbuf_new failed");
for (i = 0; i < argc; i++) {
ws = 0;
@@ -1711,17 +2058,16 @@ argv_assemble(int argc, char **argv)
break;
}
if (r != 0)
- fatal("%s: sshbuf_put_u8: %s",
- __func__, ssh_err(r));
+ fatal_fr(r, "sshbuf_put_u8");
}
if ((i != 0 && (r = sshbuf_put_u8(buf, ' ')) != 0) ||
(ws != 0 && (r = sshbuf_put_u8(buf, '"')) != 0) ||
(r = sshbuf_putb(buf, arg)) != 0 ||
(ws != 0 && (r = sshbuf_put_u8(buf, '"')) != 0))
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "assemble");
}
if ((ret = malloc(sshbuf_len(buf) + 1)) == NULL)
- fatal("%s: malloc failed", __func__);
+ fatal_f("malloc failed");
memcpy(ret, sshbuf_ptr(buf), sshbuf_len(buf));
ret[sshbuf_len(buf)] = '\0';
sshbuf_free(buf);
@@ -1729,6 +2075,36 @@ argv_assemble(int argc, char **argv)
return ret;
}
+char *
+argv_next(int *argcp, char ***argvp)
+{
+ char *ret = (*argvp)[0];
+
+ if (*argcp > 0 && ret != NULL) {
+ (*argcp)--;
+ (*argvp)++;
+ }
+ return ret;
+}
+
+void
+argv_consume(int *argcp)
+{
+ *argcp = 0;
+}
+
+void
+argv_free(char **av, int ac)
+{
+ int i;
+
+ if (av == NULL)
+ return;
+ for (i = 0; i < ac; i++)
+ free(av[i]);
+ free(av);
+}
+
/* Returns 0 if pid exited cleanly, non-zero otherwise */
int
exited_cleanly(pid_t pid, const char *tag, const char *cmd, int quiet)
@@ -1737,7 +2113,7 @@ exited_cleanly(pid_t pid, const char *tag, const char *cmd, int quiet)
while (waitpid(pid, &status, 0) == -1) {
if (errno != EINTR) {
- error("%s: waitpid: %s", tag, strerror(errno));
+ error("%s waitpid: %s", tag, strerror(errno));
return -1;
}
}
@@ -1801,7 +2177,7 @@ safe_path(const char *name, struct stat *stp, const char *pw_dir,
}
strlcpy(buf, cp, sizeof(buf));
- if (stat(buf, &st) < 0 ||
+ if (stat(buf, &st) == -1 ||
(!platform_sys_dir_uid(st.st_uid) && st.st_uid != uid) ||
(st.st_mode & 022) != 0) {
snprintf(err, errlen,
@@ -1836,7 +2212,7 @@ safe_path_fd(int fd, const char *file, struct passwd *pw,
struct stat st;
/* check the open file to avoid races */
- if (fstat(fd, &st) < 0) {
+ if (fstat(fd, &st) == -1) {
snprintf(err, errlen, "cannot stat file %s: %s",
file, strerror(errno));
return -1;
@@ -2028,12 +2404,354 @@ parse_absolute_time(const char *s, uint64_t *tp)
return 0;
}
+/* On OpenBSD time_t is int64_t which is long long. */
+/* #define SSH_TIME_T_MAX LLONG_MAX */
+
void
format_absolute_time(uint64_t t, char *buf, size_t len)
{
- time_t tt = t > INT_MAX ? INT_MAX : t; /* XXX revisit in 2038 :P */
+ time_t tt = t > SSH_TIME_T_MAX ? SSH_TIME_T_MAX : t;
struct tm tm;
localtime_r(&tt, &tm);
strftime(buf, len, "%Y-%m-%dT%H:%M:%S", &tm);
}
+
+/* check if path is absolute */
+int
+path_absolute(const char *path)
+{
+ return (*path == '/') ? 1 : 0;
+}
+
+void
+skip_space(char **cpp)
+{
+ char *cp;
+
+ for (cp = *cpp; *cp == ' ' || *cp == '\t'; cp++)
+ ;
+ *cpp = cp;
+}
+
+/* authorized_key-style options parsing helpers */
+
+/*
+ * Match flag 'opt' in *optsp, and if allow_negate is set then also match
+ * 'no-opt'. Returns -1 if option not matched, 1 if option matches or 0
+ * if negated option matches.
+ * If the option or negated option matches, then *optsp is updated to
+ * point to the first character after the option.
+ */
+int
+opt_flag(const char *opt, int allow_negate, const char **optsp)
+{
+ size_t opt_len = strlen(opt);
+ const char *opts = *optsp;
+ int negate = 0;
+
+ if (allow_negate && strncasecmp(opts, "no-", 3) == 0) {
+ opts += 3;
+ negate = 1;
+ }
+ if (strncasecmp(opts, opt, opt_len) == 0) {
+ *optsp = opts + opt_len;
+ return negate ? 0 : 1;
+ }
+ return -1;
+}
+
+char *
+opt_dequote(const char **sp, const char **errstrp)
+{
+ const char *s = *sp;
+ char *ret;
+ size_t i;
+
+ *errstrp = NULL;
+ if (*s != '"') {
+ *errstrp = "missing start quote";
+ return NULL;
+ }
+ s++;
+ if ((ret = malloc(strlen((s)) + 1)) == NULL) {
+ *errstrp = "memory allocation failed";
+ return NULL;
+ }
+ for (i = 0; *s != '\0' && *s != '"';) {
+ if (s[0] == '\\' && s[1] == '"')
+ s++;
+ ret[i++] = *s++;
+ }
+ if (*s == '\0') {
+ *errstrp = "missing end quote";
+ free(ret);
+ return NULL;
+ }
+ ret[i] = '\0';
+ s++;
+ *sp = s;
+ return ret;
+}
+
+int
+opt_match(const char **opts, const char *term)
+{
+ if (strncasecmp((*opts), term, strlen(term)) == 0 &&
+ (*opts)[strlen(term)] == '=') {
+ *opts += strlen(term) + 1;
+ return 1;
+ }
+ return 0;
+}
+
+void
+opt_array_append2(const char *file, const int line, const char *directive,
+ char ***array, int **iarray, u_int *lp, const char *s, int i)
+{
+
+ if (*lp >= INT_MAX)
+ fatal("%s line %d: Too many %s entries", file, line, directive);
+
+ if (iarray != NULL) {
+ *iarray = xrecallocarray(*iarray, *lp, *lp + 1,
+ sizeof(**iarray));
+ (*iarray)[*lp] = i;
+ }
+
+ *array = xrecallocarray(*array, *lp, *lp + 1, sizeof(**array));
+ (*array)[*lp] = xstrdup(s);
+ (*lp)++;
+}
+
+void
+opt_array_append(const char *file, const int line, const char *directive,
+ char ***array, u_int *lp, const char *s)
+{
+ opt_array_append2(file, line, directive, array, NULL, lp, s, 0);
+}
+
+sshsig_t
+ssh_signal(int signum, sshsig_t handler)
+{
+ struct sigaction sa, osa;
+
+ /* mask all other signals while in handler */
+ memset(&sa, 0, sizeof(sa));
+ sa.sa_handler = handler;
+ sigfillset(&sa.sa_mask);
+#if defined(SA_RESTART) && !defined(NO_SA_RESTART)
+ if (signum != SIGALRM)
+ sa.sa_flags = SA_RESTART;
+#endif
+ if (sigaction(signum, &sa, &osa) == -1) {
+ debug3("sigaction(%s): %s", strsignal(signum), strerror(errno));
+ return SIG_ERR;
+ }
+ return osa.sa_handler;
+}
+
+int
+stdfd_devnull(int do_stdin, int do_stdout, int do_stderr)
+{
+ int devnull, ret = 0;
+
+ if ((devnull = open(_PATH_DEVNULL, O_RDWR)) == -1) {
+ error_f("open %s: %s", _PATH_DEVNULL,
+ strerror(errno));
+ return -1;
+ }
+ if ((do_stdin && dup2(devnull, STDIN_FILENO) == -1) ||
+ (do_stdout && dup2(devnull, STDOUT_FILENO) == -1) ||
+ (do_stderr && dup2(devnull, STDERR_FILENO) == -1)) {
+ error_f("dup2: %s", strerror(errno));
+ ret = -1;
+ }
+ if (devnull > STDERR_FILENO)
+ close(devnull);
+ return ret;
+}
+
+/*
+ * Runs command in a subprocess with a minimal environment.
+ * Returns pid on success, 0 on failure.
+ * The child stdout and stderr maybe captured, left attached or sent to
+ * /dev/null depending on the contents of flags.
+ * "tag" is prepended to log messages.
+ * NB. "command" is only used for logging; the actual command executed is
+ * av[0].
+ */
+pid_t
+subprocess(const char *tag, const char *command,
+ int ac, char **av, FILE **child, u_int flags,
+ struct passwd *pw, privdrop_fn *drop_privs, privrestore_fn *restore_privs)
+{
+ FILE *f = NULL;
+ struct stat st;
+ int fd, devnull, p[2], i;
+ pid_t pid;
+ char *cp, errmsg[512];
+ u_int nenv = 0;
+ char **env = NULL;
+
+ /* If dropping privs, then must specify user and restore function */
+ if (drop_privs != NULL && (pw == NULL || restore_privs == NULL)) {
+ error("%s: inconsistent arguments", tag); /* XXX fatal? */
+ return 0;
+ }
+ if (pw == NULL && (pw = getpwuid(getuid())) == NULL) {
+ error("%s: no user for current uid", tag);
+ return 0;
+ }
+ if (child != NULL)
+ *child = NULL;
+
+ debug3_f("%s command \"%s\" running as %s (flags 0x%x)",
+ tag, command, pw->pw_name, flags);
+
+ /* Check consistency */
+ if ((flags & SSH_SUBPROCESS_STDOUT_DISCARD) != 0 &&
+ (flags & SSH_SUBPROCESS_STDOUT_CAPTURE) != 0) {
+ error_f("inconsistent flags");
+ return 0;
+ }
+ if (((flags & SSH_SUBPROCESS_STDOUT_CAPTURE) == 0) != (child == NULL)) {
+ error_f("inconsistent flags/output");
+ return 0;
+ }
+
+ /*
+ * If executing an explicit binary, then verify the it exists
+ * and appears safe-ish to execute
+ */
+ if (!path_absolute(av[0])) {
+ error("%s path is not absolute", tag);
+ return 0;
+ }
+ if (drop_privs != NULL)
+ drop_privs(pw);
+ if (stat(av[0], &st) == -1) {
+ error("Could not stat %s \"%s\": %s", tag,
+ av[0], strerror(errno));
+ goto restore_return;
+ }
+ if ((flags & SSH_SUBPROCESS_UNSAFE_PATH) == 0 &&
+ safe_path(av[0], &st, NULL, 0, errmsg, sizeof(errmsg)) != 0) {
+ error("Unsafe %s \"%s\": %s", tag, av[0], errmsg);
+ goto restore_return;
+ }
+ /* Prepare to keep the child's stdout if requested */
+ if (pipe(p) == -1) {
+ error("%s: pipe: %s", tag, strerror(errno));
+ restore_return:
+ if (restore_privs != NULL)
+ restore_privs();
+ return 0;
+ }
+ if (restore_privs != NULL)
+ restore_privs();
+
+ switch ((pid = fork())) {
+ case -1: /* error */
+ error("%s: fork: %s", tag, strerror(errno));
+ close(p[0]);
+ close(p[1]);
+ return 0;
+ case 0: /* child */
+ /* Prepare a minimal environment for the child. */
+ if ((flags & SSH_SUBPROCESS_PRESERVE_ENV) == 0) {
+ nenv = 5;
+ env = xcalloc(sizeof(*env), nenv);
+ child_set_env(&env, &nenv, "PATH", _PATH_STDPATH);
+ child_set_env(&env, &nenv, "USER", pw->pw_name);
+ child_set_env(&env, &nenv, "LOGNAME", pw->pw_name);
+ child_set_env(&env, &nenv, "HOME", pw->pw_dir);
+ if ((cp = getenv("LANG")) != NULL)
+ child_set_env(&env, &nenv, "LANG", cp);
+ }
+
+ for (i = 1; i < NSIG; i++)
+ ssh_signal(i, SIG_DFL);
+
+ if ((devnull = open(_PATH_DEVNULL, O_RDWR)) == -1) {
+ error("%s: open %s: %s", tag, _PATH_DEVNULL,
+ strerror(errno));
+ _exit(1);
+ }
+ if (dup2(devnull, STDIN_FILENO) == -1) {
+ error("%s: dup2: %s", tag, strerror(errno));
+ _exit(1);
+ }
+
+ /* Set up stdout as requested; leave stderr in place for now. */
+ fd = -1;
+ if ((flags & SSH_SUBPROCESS_STDOUT_CAPTURE) != 0)
+ fd = p[1];
+ else if ((flags & SSH_SUBPROCESS_STDOUT_DISCARD) != 0)
+ fd = devnull;
+ if (fd != -1 && dup2(fd, STDOUT_FILENO) == -1) {
+ error("%s: dup2: %s", tag, strerror(errno));
+ _exit(1);
+ }
+ closefrom(STDERR_FILENO + 1);
+
+ if (setresgid(pw->pw_gid, pw->pw_gid, pw->pw_gid) == -1) {
+ error("%s: setresgid %u: %s", tag, (u_int)pw->pw_gid,
+ strerror(errno));
+ _exit(1);
+ }
+ if (setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid) == -1) {
+ error("%s: setresuid %u: %s", tag, (u_int)pw->pw_uid,
+ strerror(errno));
+ _exit(1);
+ }
+ /* stdin is pointed to /dev/null at this point */
+ if ((flags & SSH_SUBPROCESS_STDOUT_DISCARD) != 0 &&
+ dup2(STDIN_FILENO, STDERR_FILENO) == -1) {
+ error("%s: dup2: %s", tag, strerror(errno));
+ _exit(1);
+ }
+ if (env != NULL)
+ execve(av[0], av, env);
+ else
+ execv(av[0], av);
+ error("%s %s \"%s\": %s", tag, env == NULL ? "execv" : "execve",
+ command, strerror(errno));
+ _exit(127);
+ default: /* parent */
+ break;
+ }
+
+ close(p[1]);
+ if ((flags & SSH_SUBPROCESS_STDOUT_CAPTURE) == 0)
+ close(p[0]);
+ else if ((f = fdopen(p[0], "r")) == NULL) {
+ error("%s: fdopen: %s", tag, strerror(errno));
+ close(p[0]);
+ /* Don't leave zombie child */
+ kill(pid, SIGTERM);
+ while (waitpid(pid, NULL, 0) == -1 && errno == EINTR)
+ ;
+ return 0;
+ }
+ /* Success */
+ debug3_f("%s pid %ld", tag, (long)pid);
+ if (child != NULL)
+ *child = f;
+ return pid;
+}
+
+const char *
+lookup_env_in_list(const char *env, char * const *envs, size_t nenvs)
+{
+ size_t i, envlen;
+
+ envlen = strlen(env);
+ for (i = 0; i < nenvs; i++) {
+ if (strncmp(envs[i], env, envlen) == 0 &&
+ envs[i][envlen] == '=') {
+ return envs[i] + envlen + 1;
+ }
+ }
+ return NULL;
+}
diff --git a/crypto/openssh/misc.h b/crypto/openssh/misc.h
index 31b207a8d9d9..2e2dca54bf45 100644
--- a/crypto/openssh/misc.h
+++ b/crypto/openssh/misc.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: misc.h,v 1.75 2018/10/03 06:38:35 djm Exp $ */
+/* $OpenBSD: misc.h,v 1.98 2021/08/09 23:47:44 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -17,6 +17,8 @@
#include <sys/time.h>
#include <sys/types.h>
+#include <sys/socket.h>
+#include <stdio.h>
/* Data structure for representing a forwarding request. */
struct Forward {
@@ -43,6 +45,8 @@ struct ForwardOptions {
/* misc.c */
char *chop(char *);
+void rtrim(char *);
+void skip_space(char **);
char *strdelim(char **);
char *strdelimw(char **);
int set_nonblock(int);
@@ -51,19 +55,31 @@ void set_nodelay(int);
int set_reuseaddr(int);
char *get_rdomain(int);
int set_rdomain(int, const char *);
+int get_sock_af(int);
+void set_sock_tos(int, int);
+int waitrfd(int, int *);
+int timeout_connect(int, const struct sockaddr *, socklen_t, int *);
int a2port(const char *);
int a2tun(const char *, int *);
char *put_host_port(const char *, u_short);
+char *hpdelim2(char **, char *);
char *hpdelim(char **);
char *cleanhostname(char *);
char *colon(char *);
int parse_user_host_path(const char *, char **, char **, char **);
int parse_user_host_port(const char *, char **, char **, int *);
int parse_uri(const char *, const char *, char **, char **, int *, char **);
-long convtime(const char *);
+int convtime(const char *);
+const char *fmt_timeframe(time_t t);
+int tilde_expand(const char *, uid_t, char **);
char *tilde_expand_filename(const char *, uid_t);
+
+char *dollar_expand(int *, const char *string, ...);
char *percent_expand(const char *, ...) __attribute__((__sentinel__));
+char *percent_dollar_expand(const char *, ...) __attribute__((__sentinel__));
char *tohex(const void *, size_t);
+void xextendf(char **s, const char *sep, const char *fmt, ...)
+ __attribute__((__format__ (printf, 3, 4))) __attribute__((__nonnull__ (3)));
void sanitise_stdfd(void);
void ms_subtract_diff(struct timeval *, int *);
void ms_to_timeval(struct timeval *, int);
@@ -78,12 +94,24 @@ int valid_env_name(const char *);
const char *atoi_err(const char *, int *);
int parse_absolute_time(const char *, uint64_t *);
void format_absolute_time(uint64_t, char *, size_t);
+int path_absolute(const char *);
+int stdfd_devnull(int, int, int);
void sock_set_v6only(int);
struct passwd *pwcopy(struct passwd *);
const char *ssh_gai_strerror(int);
+typedef void privdrop_fn(struct passwd *);
+typedef void privrestore_fn(void);
+#define SSH_SUBPROCESS_STDOUT_DISCARD (1) /* Discard stdout */
+#define SSH_SUBPROCESS_STDOUT_CAPTURE (1<<1) /* Redirect stdout */
+#define SSH_SUBPROCESS_STDERR_DISCARD (1<<2) /* Discard stderr */
+#define SSH_SUBPROCESS_UNSAFE_PATH (1<<3) /* Don't check for safe cmd */
+#define SSH_SUBPROCESS_PRESERVE_ENV (1<<4) /* Keep parent environment */
+pid_t subprocess(const char *, const char *, int, char **, FILE **, u_int,
+ struct passwd *, privdrop_fn *, privrestore_fn *);
+
typedef struct arglist arglist;
struct arglist {
char **list;
@@ -91,9 +119,9 @@ struct arglist {
u_int nalloc;
};
void addargs(arglist *, char *, ...)
- __attribute__((format(printf, 2, 3)));
+ __attribute__((format(printf, 2, 3)));
void replacearg(arglist *, u_int, char *, ...)
- __attribute__((format(printf, 3, 4)));
+ __attribute__((format(printf, 3, 4)));
void freeargs(arglist *);
int tun_open(int, int, char **);
@@ -134,7 +162,9 @@ void put_u32_le(void *, u_int32_t)
struct bwlimit {
size_t buflen;
- u_int64_t rate, thresh, lamt;
+ u_int64_t rate; /* desired rate in kbit/s */
+ u_int64_t thresh; /* threshold after which we'll check timers */
+ u_int64_t lamt; /* amount written in last timer interval */
struct timeval bwstart, bwend;
};
@@ -146,17 +176,35 @@ const char *iptos2str(int);
void mktemp_proto(char *, size_t);
void child_set_env(char ***envp, u_int *envsizep, const char *name,
- const char *value);
+ const char *value);
+const char *lookup_env_in_list(const char *env,
+ char * const *envs, size_t nenvs);
-int argv_split(const char *, int *, char ***);
+int argv_split(const char *, int *, char ***, int);
char *argv_assemble(int, char **argv);
+char *argv_next(int *, char ***);
+void argv_consume(int *);
+void argv_free(char **, int);
+
int exited_cleanly(pid_t, const char *, const char *, int);
struct stat;
int safe_path(const char *, struct stat *, const char *, uid_t,
- char *, size_t);
+ char *, size_t);
int safe_path_fd(int, const char *, struct passwd *,
- char *err, size_t errlen);
+ char *err, size_t errlen);
+
+/* authorized_key-style options parsing helpers */
+int opt_flag(const char *opt, int allow_negate, const char **optsp);
+char *opt_dequote(const char **sp, const char **errstrp);
+int opt_match(const char **opts, const char *term);
+
+/* readconf/servconf option lists */
+void opt_array_append(const char *file, const int line,
+ const char *directive, char ***array, u_int *lp, const char *s);
+void opt_array_append2(const char *file, const int line,
+ const char *directive, char ***array, int **iarray, u_int *lp,
+ const char *s, int i);
/* readpass.c */
@@ -165,11 +213,20 @@ int safe_path_fd(int, const char *, struct passwd *,
#define RP_ALLOW_EOF 0x0004
#define RP_USE_ASKPASS 0x0008
+struct notifier_ctx;
+
char *read_passphrase(const char *, int);
int ask_permission(const char *, ...) __attribute__((format(printf, 1, 2)));
+struct notifier_ctx *notify_start(int, const char *, ...)
+ __attribute__((format(printf, 2, 3)));
+void notify_complete(struct notifier_ctx *, const char *, ...)
+ __attribute__((format(printf, 2, 3)));
#define MINIMUM(a, b) (((a) < (b)) ? (a) : (b))
#define MAXIMUM(a, b) (((a) > (b)) ? (a) : (b))
#define ROUNDUP(x, y) ((((x)+((y)-1))/(y))*(y))
+typedef void (*sshsig_t)(int);
+sshsig_t ssh_signal(int, sshsig_t);
+
#endif /* _MISC_H */
diff --git a/crypto/openssh/moduli b/crypto/openssh/moduli
index 372c382a270c..81afe331b3b6 100644
--- a/crypto/openssh/moduli
+++ b/crypto/openssh/moduli
@@ -1,428 +1,450 @@
-# $OpenBSD: moduli,v 1.22 2018/09/20 08:07:03 dtucker Exp $
+# $OpenBSD: moduli,v 1.30 2021/05/17 07:22:45 dtucker Exp $
# Time Type Tests Tries Size Generator Modulus
-20180403031539 2 6 100 2047 5 F78A3F3A47AFE34101F186DF022B970FB51586E65B1D1875E41D02EDDD4BDF6D6D8BA1CC296EA6A8BD7036297A0C01C636A55493E3ADEC2F1DAB9D8D7E0CCD39D7FFC9D4011C3F57A944AA1EEB1AC1784E28ACF7B6FB3AC49185F4E638B567DA6B4903CB8C6D815ED1253D512670FAF71E6BF1ED6669863B552B3BB2173A7F16262454142B7B928F91E60EED00BDFA465F2C46665BD30C1426F9B8D9611D086D6BAB672CB472E8F8E6990F623C2E7458991D982E199BB168C93F96F71974181F898D6C56C02D9DABA852E7E51CA0DC723255B49CAA122D2A6CC64F1389128A0E3298B0E155EC8A4D9BF1D1671B808DDD835015381C1F16C35A84D20A591E4B57
-20180403031604 2 6 100 2047 2 F78A3F3A47AFE34101F186DF022B970FB51586E65B1D1875E41D02EDDD4BDF6D6D8BA1CC296EA6A8BD7036297A0C01C636A55493E3ADEC2F1DAB9D8D7E0CCD39D7FFC9D4011C3F57A944AA1EEB1AC1784E28ACF7B6FB3AC49185F4E638B567DA6B4903CB8C6D815ED1253D512670FAF71E6BF1ED6669863B552B3BB2173A7F16262454142B7B928F91E60EED00BDFA465F2C46665BD30C1426F9B8D9611D086D6BAB672CB472E8F8E6990F623C2E7458991D982E199BB168C93F96F71974181F898D6C56C02D9DABA852E7E51CA0DC723255B49CAA122D2A6CC64F1389128A0E3298B0E155EC8A4D9BF1D1671B808DDD835015381C1F16C35A84D20A5923D0DB
-20180403031626 2 6 100 2047 5 F78A3F3A47AFE34101F186DF022B970FB51586E65B1D1875E41D02EDDD4BDF6D6D8BA1CC296EA6A8BD7036297A0C01C636A55493E3ADEC2F1DAB9D8D7E0CCD39D7FFC9D4011C3F57A944AA1EEB1AC1784E28ACF7B6FB3AC49185F4E638B567DA6B4903CB8C6D815ED1253D512670FAF71E6BF1ED6669863B552B3BB2173A7F16262454142B7B928F91E60EED00BDFA465F2C46665BD30C1426F9B8D9611D086D6BAB672CB472E8F8E6990F623C2E7458991D982E199BB168C93F96F71974181F898D6C56C02D9DABA852E7E51CA0DC723255B49CAA122D2A6CC64F1389128A0E3298B0E155EC8A4D9BF1D1671B808DDD835015381C1F16C35A84D20A592B11B7
-20180403031845 2 6 100 2047 2 F78A3F3A47AFE34101F186DF022B970FB51586E65B1D1875E41D02EDDD4BDF6D6D8BA1CC296EA6A8BD7036297A0C01C636A55493E3ADEC2F1DAB9D8D7E0CCD39D7FFC9D4011C3F57A944AA1EEB1AC1784E28ACF7B6FB3AC49185F4E638B567DA6B4903CB8C6D815ED1253D512670FAF71E6BF1ED6669863B552B3BB2173A7F16262454142B7B928F91E60EED00BDFA465F2C46665BD30C1426F9B8D9611D086D6BAB672CB472E8F8E6990F623C2E7458991D982E199BB168C93F96F71974181F898D6C56C02D9DABA852E7E51CA0DC723255B49CAA122D2A6CC64F1389128A0E3298B0E155EC8A4D9BF1D1671B808DDD835015381C1F16C35A84D20A59715A73
-20180403032143 2 6 100 2047 2 F78A3F3A47AFE34101F186DF022B970FB51586E65B1D1875E41D02EDDD4BDF6D6D8BA1CC296EA6A8BD7036297A0C01C636A55493E3ADEC2F1DAB9D8D7E0CCD39D7FFC9D4011C3F57A944AA1EEB1AC1784E28ACF7B6FB3AC49185F4E638B567DA6B4903CB8C6D815ED1253D512670FAF71E6BF1ED6669863B552B3BB2173A7F16262454142B7B928F91E60EED00BDFA465F2C46665BD30C1426F9B8D9611D086D6BAB672CB472E8F8E6990F623C2E7458991D982E199BB168C93F96F71974181F898D6C56C02D9DABA852E7E51CA0DC723255B49CAA122D2A6CC64F1389128A0E3298B0E155EC8A4D9BF1D1671B808DDD835015381C1F16C35A84D20A59CDE963
-20180403032347 2 6 100 2047 2 F78A3F3A47AFE34101F186DF022B970FB51586E65B1D1875E41D02EDDD4BDF6D6D8BA1CC296EA6A8BD7036297A0C01C636A55493E3ADEC2F1DAB9D8D7E0CCD39D7FFC9D4011C3F57A944AA1EEB1AC1784E28ACF7B6FB3AC49185F4E638B567DA6B4903CB8C6D815ED1253D512670FAF71E6BF1ED6669863B552B3BB2173A7F16262454142B7B928F91E60EED00BDFA465F2C46665BD30C1426F9B8D9611D086D6BAB672CB472E8F8E6990F623C2E7458991D982E199BB168C93F96F71974181F898D6C56C02D9DABA852E7E51CA0DC723255B49CAA122D2A6CC64F1389128A0E3298B0E155EC8A4D9BF1D1671B808DDD835015381C1F16C35A84D20A5A11B463
-20180403032438 2 6 100 2047 5 F78A3F3A47AFE34101F186DF022B970FB51586E65B1D1875E41D02EDDD4BDF6D6D8BA1CC296EA6A8BD7036297A0C01C636A55493E3ADEC2F1DAB9D8D7E0CCD39D7FFC9D4011C3F57A944AA1EEB1AC1784E28ACF7B6FB3AC49185F4E638B567DA6B4903CB8C6D815ED1253D512670FAF71E6BF1ED6669863B552B3BB2173A7F16262454142B7B928F91E60EED00BDFA465F2C46665BD30C1426F9B8D9611D086D6BAB672CB472E8F8E6990F623C2E7458991D982E199BB168C93F96F71974181F898D6C56C02D9DABA852E7E51CA0DC723255B49CAA122D2A6CC64F1389128A0E3298B0E155EC8A4D9BF1D1671B808DDD835015381C1F16C35A84D20A5A2BBC5F
-20180403032617 2 6 100 2047 2 F78A3F3A47AFE34101F186DF022B970FB51586E65B1D1875E41D02EDDD4BDF6D6D8BA1CC296EA6A8BD7036297A0C01C636A55493E3ADEC2F1DAB9D8D7E0CCD39D7FFC9D4011C3F57A944AA1EEB1AC1784E28ACF7B6FB3AC49185F4E638B567DA6B4903CB8C6D815ED1253D512670FAF71E6BF1ED6669863B552B3BB2173A7F16262454142B7B928F91E60EED00BDFA465F2C46665BD30C1426F9B8D9611D086D6BAB672CB472E8F8E6990F623C2E7458991D982E199BB168C93F96F71974181F898D6C56C02D9DABA852E7E51CA0DC723255B49CAA122D2A6CC64F1389128A0E3298B0E155EC8A4D9BF1D1671B808DDD835015381C1F16C35A84D20A5A6308C3
-20180403032923 2 6 100 2047 2 F78A3F3A47AFE34101F186DF022B970FB51586E65B1D1875E41D02EDDD4BDF6D6D8BA1CC296EA6A8BD7036297A0C01C636A55493E3ADEC2F1DAB9D8D7E0CCD39D7FFC9D4011C3F57A944AA1EEB1AC1784E28ACF7B6FB3AC49185F4E638B567DA6B4903CB8C6D815ED1253D512670FAF71E6BF1ED6669863B552B3BB2173A7F16262454142B7B928F91E60EED00BDFA465F2C46665BD30C1426F9B8D9611D086D6BAB672CB472E8F8E6990F623C2E7458991D982E199BB168C93F96F71974181F898D6C56C02D9DABA852E7E51CA0DC723255B49CAA122D2A6CC64F1389128A0E3298B0E155EC8A4D9BF1D1671B808DDD835015381C1F16C35A84D20A5ADA5523
-20180403033405 2 6 100 2047 5 F78A3F3A47AFE34101F186DF022B970FB51586E65B1D1875E41D02EDDD4BDF6D6D8BA1CC296EA6A8BD7036297A0C01C636A55493E3ADEC2F1DAB9D8D7E0CCD39D7FFC9D4011C3F57A944AA1EEB1AC1784E28ACF7B6FB3AC49185F4E638B567DA6B4903CB8C6D815ED1253D512670FAF71E6BF1ED6669863B552B3BB2173A7F16262454142B7B928F91E60EED00BDFA465F2C46665BD30C1426F9B8D9611D086D6BAB672CB472E8F8E6990F623C2E7458991D982E199BB168C93F96F71974181F898D6C56C02D9DABA852E7E51CA0DC723255B49CAA122D2A6CC64F1389128A0E3298B0E155EC8A4D9BF1D1671B808DDD835015381C1F16C35A84D20A5B9A6B37
-20180403033427 2 6 100 2047 5 F78A3F3A47AFE34101F186DF022B970FB51586E65B1D1875E41D02EDDD4BDF6D6D8BA1CC296EA6A8BD7036297A0C01C636A55493E3ADEC2F1DAB9D8D7E0CCD39D7FFC9D4011C3F57A944AA1EEB1AC1784E28ACF7B6FB3AC49185F4E638B567DA6B4903CB8C6D815ED1253D512670FAF71E6BF1ED6669863B552B3BB2173A7F16262454142B7B928F91E60EED00BDFA465F2C46665BD30C1426F9B8D9611D086D6BAB672CB472E8F8E6990F623C2E7458991D982E199BB168C93F96F71974181F898D6C56C02D9DABA852E7E51CA0DC723255B49CAA122D2A6CC64F1389128A0E3298B0E155EC8A4D9BF1D1671B808DDD835015381C1F16C35A84D20A5B9F8E27
-20180403033655 2 6 100 2047 5 F78A3F3A47AFE34101F186DF022B970FB51586E65B1D1875E41D02EDDD4BDF6D6D8BA1CC296EA6A8BD7036297A0C01C636A55493E3ADEC2F1DAB9D8D7E0CCD39D7FFC9D4011C3F57A944AA1EEB1AC1784E28ACF7B6FB3AC49185F4E638B567DA6B4903CB8C6D815ED1253D512670FAF71E6BF1ED6669863B552B3BB2173A7F16262454142B7B928F91E60EED00BDFA465F2C46665BD30C1426F9B8D9611D086D6BAB672CB472E8F8E6990F623C2E7458991D982E199BB168C93F96F71974181F898D6C56C02D9DABA852E7E51CA0DC723255B49CAA122D2A6CC64F1389128A0E3298B0E155EC8A4D9BF1D1671B808DDD835015381C1F16C35A84D20A5C00897F
-20180403033742 2 6 100 2047 2 F78A3F3A47AFE34101F186DF022B970FB51586E65B1D1875E41D02EDDD4BDF6D6D8BA1CC296EA6A8BD7036297A0C01C636A55493E3ADEC2F1DAB9D8D7E0CCD39D7FFC9D4011C3F57A944AA1EEB1AC1784E28ACF7B6FB3AC49185F4E638B567DA6B4903CB8C6D815ED1253D512670FAF71E6BF1ED6669863B552B3BB2173A7F16262454142B7B928F91E60EED00BDFA465F2C46665BD30C1426F9B8D9611D086D6BAB672CB472E8F8E6990F623C2E7458991D982E199BB168C93F96F71974181F898D6C56C02D9DABA852E7E51CA0DC723255B49CAA122D2A6CC64F1389128A0E3298B0E155EC8A4D9BF1D1671B808DDD835015381C1F16C35A84D20A5C172DBB
-20180403033837 2 6 100 2047 2 F78A3F3A47AFE34101F186DF022B970FB51586E65B1D1875E41D02EDDD4BDF6D6D8BA1CC296EA6A8BD7036297A0C01C636A55493E3ADEC2F1DAB9D8D7E0CCD39D7FFC9D4011C3F57A944AA1EEB1AC1784E28ACF7B6FB3AC49185F4E638B567DA6B4903CB8C6D815ED1253D512670FAF71E6BF1ED6669863B552B3BB2173A7F16262454142B7B928F91E60EED00BDFA465F2C46665BD30C1426F9B8D9611D086D6BAB672CB472E8F8E6990F623C2E7458991D982E199BB168C93F96F71974181F898D6C56C02D9DABA852E7E51CA0DC723255B49CAA122D2A6CC64F1389128A0E3298B0E155EC8A4D9BF1D1671B808DDD835015381C1F16C35A84D20A5C33AEAB
-20180403033952 2 6 100 2047 5 F78A3F3A47AFE34101F186DF022B970FB51586E65B1D1875E41D02EDDD4BDF6D6D8BA1CC296EA6A8BD7036297A0C01C636A55493E3ADEC2F1DAB9D8D7E0CCD39D7FFC9D4011C3F57A944AA1EEB1AC1784E28ACF7B6FB3AC49185F4E638B567DA6B4903CB8C6D815ED1253D512670FAF71E6BF1ED6669863B552B3BB2173A7F16262454142B7B928F91E60EED00BDFA465F2C46665BD30C1426F9B8D9611D086D6BAB672CB472E8F8E6990F623C2E7458991D982E199BB168C93F96F71974181F898D6C56C02D9DABA852E7E51CA0DC723255B49CAA122D2A6CC64F1389128A0E3298B0E155EC8A4D9BF1D1671B808DDD835015381C1F16C35A84D20A5C5F6067
-20180403034409 2 6 100 2047 5 F78A3F3A47AFE34101F186DF022B970FB51586E65B1D1875E41D02EDDD4BDF6D6D8BA1CC296EA6A8BD7036297A0C01C636A55493E3ADEC2F1DAB9D8D7E0CCD39D7FFC9D4011C3F57A944AA1EEB1AC1784E28ACF7B6FB3AC49185F4E638B567DA6B4903CB8C6D815ED1253D512670FAF71E6BF1ED6669863B552B3BB2173A7F16262454142B7B928F91E60EED00BDFA465F2C46665BD30C1426F9B8D9611D086D6BAB672CB472E8F8E6990F623C2E7458991D982E199BB168C93F96F71974181F898D6C56C02D9DABA852E7E51CA0DC723255B49CAA122D2A6CC64F1389128A0E3298B0E155EC8A4D9BF1D1671B808DDD835015381C1F16C35A84D20A5CEE2AD7
-20180403034453 2 6 100 2047 2 F78A3F3A47AFE34101F186DF022B970FB51586E65B1D1875E41D02EDDD4BDF6D6D8BA1CC296EA6A8BD7036297A0C01C636A55493E3ADEC2F1DAB9D8D7E0CCD39D7FFC9D4011C3F57A944AA1EEB1AC1784E28ACF7B6FB3AC49185F4E638B567DA6B4903CB8C6D815ED1253D512670FAF71E6BF1ED6669863B552B3BB2173A7F16262454142B7B928F91E60EED00BDFA465F2C46665BD30C1426F9B8D9611D086D6BAB672CB472E8F8E6990F623C2E7458991D982E199BB168C93F96F71974181F898D6C56C02D9DABA852E7E51CA0DC723255B49CAA122D2A6CC64F1389128A0E3298B0E155EC8A4D9BF1D1671B808DDD835015381C1F16C35A84D20A5CFFE4F3
-20180403034601 2 6 100 2047 2 F78A3F3A47AFE34101F186DF022B970FB51586E65B1D1875E41D02EDDD4BDF6D6D8BA1CC296EA6A8BD7036297A0C01C636A55493E3ADEC2F1DAB9D8D7E0CCD39D7FFC9D4011C3F57A944AA1EEB1AC1784E28ACF7B6FB3AC49185F4E638B567DA6B4903CB8C6D815ED1253D512670FAF71E6BF1ED6669863B552B3BB2173A7F16262454142B7B928F91E60EED00BDFA465F2C46665BD30C1426F9B8D9611D086D6BAB672CB472E8F8E6990F623C2E7458991D982E199BB168C93F96F71974181F898D6C56C02D9DABA852E7E51CA0DC723255B49CAA122D2A6CC64F1389128A0E3298B0E155EC8A4D9BF1D1671B808DDD835015381C1F16C35A84D20A5D1A691B
-20180403035311 2 6 100 2047 2 F78A3F3A47AFE34101F186DF022B970FB51586E65B1D1875E41D02EDDD4BDF6D6D8BA1CC296EA6A8BD7036297A0C01C636A55493E3ADEC2F1DAB9D8D7E0CCD39D7FFC9D4011C3F57A944AA1EEB1AC1784E28ACF7B6FB3AC49185F4E638B567DA6B4903CB8C6D815ED1253D512670FAF71E6BF1ED6669863B552B3BB2173A7F16262454142B7B928F91E60EED00BDFA465F2C46665BD30C1426F9B8D9611D086D6BAB672CB472E8F8E6990F623C2E7458991D982E199BB168C93F96F71974181F898D6C56C02D9DABA852E7E51CA0DC723255B49CAA122D2A6CC64F1389128A0E3298B0E155EC8A4D9BF1D1671B808DDD835015381C1F16C35A84D20A5E04B193
-20180403035645 2 6 100 2047 5 F78A3F3A47AFE34101F186DF022B970FB51586E65B1D1875E41D02EDDD4BDF6D6D8BA1CC296EA6A8BD7036297A0C01C636A55493E3ADEC2F1DAB9D8D7E0CCD39D7FFC9D4011C3F57A944AA1EEB1AC1784E28ACF7B6FB3AC49185F4E638B567DA6B4903CB8C6D815ED1253D512670FAF71E6BF1ED6669863B552B3BB2173A7F16262454142B7B928F91E60EED00BDFA465F2C46665BD30C1426F9B8D9611D086D6BAB672CB472E8F8E6990F623C2E7458991D982E199BB168C93F96F71974181F898D6C56C02D9DABA852E7E51CA0DC723255B49CAA122D2A6CC64F1389128A0E3298B0E155EC8A4D9BF1D1671B808DDD835015381C1F16C35A84D20A5E75D66F
-20180403035724 2 6 100 2047 5 F78A3F3A47AFE34101F186DF022B970FB51586E65B1D1875E41D02EDDD4BDF6D6D8BA1CC296EA6A8BD7036297A0C01C636A55493E3ADEC2F1DAB9D8D7E0CCD39D7FFC9D4011C3F57A944AA1EEB1AC1784E28ACF7B6FB3AC49185F4E638B567DA6B4903CB8C6D815ED1253D512670FAF71E6BF1ED6669863B552B3BB2173A7F16262454142B7B928F91E60EED00BDFA465F2C46665BD30C1426F9B8D9611D086D6BAB672CB472E8F8E6990F623C2E7458991D982E199BB168C93F96F71974181F898D6C56C02D9DABA852E7E51CA0DC723255B49CAA122D2A6CC64F1389128A0E3298B0E155EC8A4D9BF1D1671B808DDD835015381C1F16C35A84D20A5E864847
-20180403035828 2 6 100 2047 5 F78A3F3A47AFE34101F186DF022B970FB51586E65B1D1875E41D02EDDD4BDF6D6D8BA1CC296EA6A8BD7036297A0C01C636A55493E3ADEC2F1DAB9D8D7E0CCD39D7FFC9D4011C3F57A944AA1EEB1AC1784E28ACF7B6FB3AC49185F4E638B567DA6B4903CB8C6D815ED1253D512670FAF71E6BF1ED6669863B552B3BB2173A7F16262454142B7B928F91E60EED00BDFA465F2C46665BD30C1426F9B8D9611D086D6BAB672CB472E8F8E6990F623C2E7458991D982E199BB168C93F96F71974181F898D6C56C02D9DABA852E7E51CA0DC723255B49CAA122D2A6CC64F1389128A0E3298B0E155EC8A4D9BF1D1671B808DDD835015381C1F16C35A84D20A5EA44DCF
-20180403035953 2 6 100 2047 2 F78A3F3A47AFE34101F186DF022B970FB51586E65B1D1875E41D02EDDD4BDF6D6D8BA1CC296EA6A8BD7036297A0C01C636A55493E3ADEC2F1DAB9D8D7E0CCD39D7FFC9D4011C3F57A944AA1EEB1AC1784E28ACF7B6FB3AC49185F4E638B567DA6B4903CB8C6D815ED1253D512670FAF71E6BF1ED6669863B552B3BB2173A7F16262454142B7B928F91E60EED00BDFA465F2C46665BD30C1426F9B8D9611D086D6BAB672CB472E8F8E6990F623C2E7458991D982E199BB168C93F96F71974181F898D6C56C02D9DABA852E7E51CA0DC723255B49CAA122D2A6CC64F1389128A0E3298B0E155EC8A4D9BF1D1671B808DDD835015381C1F16C35A84D20A5ECCB51B
-20180403040048 2 6 100 2047 5 F78A3F3A47AFE34101F186DF022B970FB51586E65B1D1875E41D02EDDD4BDF6D6D8BA1CC296EA6A8BD7036297A0C01C636A55493E3ADEC2F1DAB9D8D7E0CCD39D7FFC9D4011C3F57A944AA1EEB1AC1784E28ACF7B6FB3AC49185F4E638B567DA6B4903CB8C6D815ED1253D512670FAF71E6BF1ED6669863B552B3BB2173A7F16262454142B7B928F91E60EED00BDFA465F2C46665BD30C1426F9B8D9611D086D6BAB672CB472E8F8E6990F623C2E7458991D982E199BB168C93F96F71974181F898D6C56C02D9DABA852E7E51CA0DC723255B49CAA122D2A6CC64F1389128A0E3298B0E155EC8A4D9BF1D1671B808DDD835015381C1F16C35A84D20A5EE55A9F
-20180403040339 2 6 100 2047 5 F78A3F3A47AFE34101F186DF022B970FB51586E65B1D1875E41D02EDDD4BDF6D6D8BA1CC296EA6A8BD7036297A0C01C636A55493E3ADEC2F1DAB9D8D7E0CCD39D7FFC9D4011C3F57A944AA1EEB1AC1784E28ACF7B6FB3AC49185F4E638B567DA6B4903CB8C6D815ED1253D512670FAF71E6BF1ED6669863B552B3BB2173A7F16262454142B7B928F91E60EED00BDFA465F2C46665BD30C1426F9B8D9611D086D6BAB672CB472E8F8E6990F623C2E7458991D982E199BB168C93F96F71974181F898D6C56C02D9DABA852E7E51CA0DC723255B49CAA122D2A6CC64F1389128A0E3298B0E155EC8A4D9BF1D1671B808DDD835015381C1F16C35A84D20A5F4D5E6F
-20180403040523 2 6 100 2047 2 F78A3F3A47AFE34101F186DF022B970FB51586E65B1D1875E41D02EDDD4BDF6D6D8BA1CC296EA6A8BD7036297A0C01C636A55493E3ADEC2F1DAB9D8D7E0CCD39D7FFC9D4011C3F57A944AA1EEB1AC1784E28ACF7B6FB3AC49185F4E638B567DA6B4903CB8C6D815ED1253D512670FAF71E6BF1ED6669863B552B3BB2173A7F16262454142B7B928F91E60EED00BDFA465F2C46665BD30C1426F9B8D9611D086D6BAB672CB472E8F8E6990F623C2E7458991D982E199BB168C93F96F71974181F898D6C56C02D9DABA852E7E51CA0DC723255B49CAA122D2A6CC64F1389128A0E3298B0E155EC8A4D9BF1D1671B808DDD835015381C1F16C35A84D20A5F8939A3
-20180403040638 2 6 100 2047 2 F78A3F3A47AFE34101F186DF022B970FB51586E65B1D1875E41D02EDDD4BDF6D6D8BA1CC296EA6A8BD7036297A0C01C636A55493E3ADEC2F1DAB9D8D7E0CCD39D7FFC9D4011C3F57A944AA1EEB1AC1784E28ACF7B6FB3AC49185F4E638B567DA6B4903CB8C6D815ED1253D512670FAF71E6BF1ED6669863B552B3BB2173A7F16262454142B7B928F91E60EED00BDFA465F2C46665BD30C1426F9B8D9611D086D6BAB672CB472E8F8E6990F623C2E7458991D982E199BB168C93F96F71974181F898D6C56C02D9DABA852E7E51CA0DC723255B49CAA122D2A6CC64F1389128A0E3298B0E155EC8A4D9BF1D1671B808DDD835015381C1F16C35A84D20A5FB85E8B
-20180403040715 2 6 100 2047 2 F78A3F3A47AFE34101F186DF022B970FB51586E65B1D1875E41D02EDDD4BDF6D6D8BA1CC296EA6A8BD7036297A0C01C636A55493E3ADEC2F1DAB9D8D7E0CCD39D7FFC9D4011C3F57A944AA1EEB1AC1784E28ACF7B6FB3AC49185F4E638B567DA6B4903CB8C6D815ED1253D512670FAF71E6BF1ED6669863B552B3BB2173A7F16262454142B7B928F91E60EED00BDFA465F2C46665BD30C1426F9B8D9611D086D6BAB672CB472E8F8E6990F623C2E7458991D982E199BB168C93F96F71974181F898D6C56C02D9DABA852E7E51CA0DC723255B49CAA122D2A6CC64F1389128A0E3298B0E155EC8A4D9BF1D1671B808DDD835015381C1F16C35A84D20A5FCC3033
-20180403041128 2 6 100 2047 5 F78A3F3A47AFE34101F186DF022B970FB51586E65B1D1875E41D02EDDD4BDF6D6D8BA1CC296EA6A8BD7036297A0C01C636A55493E3ADEC2F1DAB9D8D7E0CCD39D7FFC9D4011C3F57A944AA1EEB1AC1784E28ACF7B6FB3AC49185F4E638B567DA6B4903CB8C6D815ED1253D512670FAF71E6BF1ED6669863B552B3BB2173A7F16262454142B7B928F91E60EED00BDFA465F2C46665BD30C1426F9B8D9611D086D6BAB672CB472E8F8E6990F623C2E7458991D982E199BB168C93F96F71974181F898D6C56C02D9DABA852E7E51CA0DC723255B49CAA122D2A6CC64F1389128A0E3298B0E155EC8A4D9BF1D1671B808DDD835015381C1F16C35A84D20A60755C57
-20180403041637 2 6 100 2047 5 EA0303D03FF69BCABDC25DDEA6AC9CFEE8C36EF48C7F2882B65D568B0D14A7DACCF4A6E8E905727C0B982FA4D7C4E59DDAF4704D0EC767D79B13A32467C8D39F615B5268E4338DD70C6072C702CDF6F39153C472E668ABF0B85B8D08454027AA52E3227C5BA017B2558F7A611F09C7BE5E28A472FAB51C71FF7E8C758CD5205C562F3674D941EF2DEC7F3B3F49C4CE3A9DD7B4275BD537BF04A4A8E98FAA42AD0A2280CFC0D4692339EEC803B69FDC33057837FBD233DB6B78920F7049B5F9CA9CFDD98351B9E7947265439F48429306D6CAB08774F2B7427A61DA757375D26C08B99BCAFB8085E41DBA0E49D142EEC164CC3153AB3119FB76033B336541B76F
-20180403041935 2 6 100 2047 2 EA0303D03FF69BCABDC25DDEA6AC9CFEE8C36EF48C7F2882B65D568B0D14A7DACCF4A6E8E905727C0B982FA4D7C4E59DDAF4704D0EC767D79B13A32467C8D39F615B5268E4338DD70C6072C702CDF6F39153C472E668ABF0B85B8D08454027AA52E3227C5BA017B2558F7A611F09C7BE5E28A472FAB51C71FF7E8C758CD5205C562F3674D941EF2DEC7F3B3F49C4CE3A9DD7B4275BD537BF04A4A8E98FAA42AD0A2280CFC0D4692339EEC803B69FDC33057837FBD233DB6B78920F7049B5F9CA9CFDD98351B9E7947265439F48429306D6CAB08774F2B7427A61DA757375D26C08B99BCAFB8085E41DBA0E49D142EEC164CC3153AB3119FB76033B3365BF1D13
-20180403042035 2 6 100 2047 5 EA0303D03FF69BCABDC25DDEA6AC9CFEE8C36EF48C7F2882B65D568B0D14A7DACCF4A6E8E905727C0B982FA4D7C4E59DDAF4704D0EC767D79B13A32467C8D39F615B5268E4338DD70C6072C702CDF6F39153C472E668ABF0B85B8D08454027AA52E3227C5BA017B2558F7A611F09C7BE5E28A472FAB51C71FF7E8C758CD5205C562F3674D941EF2DEC7F3B3F49C4CE3A9DD7B4275BD537BF04A4A8E98FAA42AD0A2280CFC0D4692339EEC803B69FDC33057837FBD233DB6B78920F7049B5F9CA9CFDD98351B9E7947265439F48429306D6CAB08774F2B7427A61DA757375D26C08B99BCAFB8085E41DBA0E49D142EEC164CC3153AB3119FB76033B3365E41E47
-20180403042109 2 6 100 2047 2 EA0303D03FF69BCABDC25DDEA6AC9CFEE8C36EF48C7F2882B65D568B0D14A7DACCF4A6E8E905727C0B982FA4D7C4E59DDAF4704D0EC767D79B13A32467C8D39F615B5268E4338DD70C6072C702CDF6F39153C472E668ABF0B85B8D08454027AA52E3227C5BA017B2558F7A611F09C7BE5E28A472FAB51C71FF7E8C758CD5205C562F3674D941EF2DEC7F3B3F49C4CE3A9DD7B4275BD537BF04A4A8E98FAA42AD0A2280CFC0D4692339EEC803B69FDC33057837FBD233DB6B78920F7049B5F9CA9CFDD98351B9E7947265439F48429306D6CAB08774F2B7427A61DA757375D26C08B99BCAFB8085E41DBA0E49D142EEC164CC3153AB3119FB76033B3365F700BB
-20180403042214 2 6 100 2047 2 EA0303D03FF69BCABDC25DDEA6AC9CFEE8C36EF48C7F2882B65D568B0D14A7DACCF4A6E8E905727C0B982FA4D7C4E59DDAF4704D0EC767D79B13A32467C8D39F615B5268E4338DD70C6072C702CDF6F39153C472E668ABF0B85B8D08454027AA52E3227C5BA017B2558F7A611F09C7BE5E28A472FAB51C71FF7E8C758CD5205C562F3674D941EF2DEC7F3B3F49C4CE3A9DD7B4275BD537BF04A4A8E98FAA42AD0A2280CFC0D4692339EEC803B69FDC33057837FBD233DB6B78920F7049B5F9CA9CFDD98351B9E7947265439F48429306D6CAB08774F2B7427A61DA757375D26C08B99BCAFB8085E41DBA0E49D142EEC164CC3153AB3119FB76033B336624FF2B
-20180403042419 2 6 100 2047 2 EA0303D03FF69BCABDC25DDEA6AC9CFEE8C36EF48C7F2882B65D568B0D14A7DACCF4A6E8E905727C0B982FA4D7C4E59DDAF4704D0EC767D79B13A32467C8D39F615B5268E4338DD70C6072C702CDF6F39153C472E668ABF0B85B8D08454027AA52E3227C5BA017B2558F7A611F09C7BE5E28A472FAB51C71FF7E8C758CD5205C562F3674D941EF2DEC7F3B3F49C4CE3A9DD7B4275BD537BF04A4A8E98FAA42AD0A2280CFC0D4692339EEC803B69FDC33057837FBD233DB6B78920F7049B5F9CA9CFDD98351B9E7947265439F48429306D6CAB08774F2B7427A61DA757375D26C08B99BCAFB8085E41DBA0E49D142EEC164CC3153AB3119FB76033B336687845B
-20180403042507 2 6 100 2047 2 EA0303D03FF69BCABDC25DDEA6AC9CFEE8C36EF48C7F2882B65D568B0D14A7DACCF4A6E8E905727C0B982FA4D7C4E59DDAF4704D0EC767D79B13A32467C8D39F615B5268E4338DD70C6072C702CDF6F39153C472E668ABF0B85B8D08454027AA52E3227C5BA017B2558F7A611F09C7BE5E28A472FAB51C71FF7E8C758CD5205C562F3674D941EF2DEC7F3B3F49C4CE3A9DD7B4275BD537BF04A4A8E98FAA42AD0A2280CFC0D4692339EEC803B69FDC33057837FBD233DB6B78920F7049B5F9CA9CFDD98351B9E7947265439F48429306D6CAB08774F2B7427A61DA757375D26C08B99BCAFB8085E41DBA0E49D142EEC164CC3153AB3119FB76033B3366A8266B
-20180403042626 2 6 100 2047 2 EA0303D03FF69BCABDC25DDEA6AC9CFEE8C36EF48C7F2882B65D568B0D14A7DACCF4A6E8E905727C0B982FA4D7C4E59DDAF4704D0EC767D79B13A32467C8D39F615B5268E4338DD70C6072C702CDF6F39153C472E668ABF0B85B8D08454027AA52E3227C5BA017B2558F7A611F09C7BE5E28A472FAB51C71FF7E8C758CD5205C562F3674D941EF2DEC7F3B3F49C4CE3A9DD7B4275BD537BF04A4A8E98FAA42AD0A2280CFC0D4692339EEC803B69FDC33057837FBD233DB6B78920F7049B5F9CA9CFDD98351B9E7947265439F48429306D6CAB08774F2B7427A61DA757375D26C08B99BCAFB8085E41DBA0E49D142EEC164CC3153AB3119FB76033B3366E23603
-20180403042722 2 6 100 2047 2 EA0303D03FF69BCABDC25DDEA6AC9CFEE8C36EF48C7F2882B65D568B0D14A7DACCF4A6E8E905727C0B982FA4D7C4E59DDAF4704D0EC767D79B13A32467C8D39F615B5268E4338DD70C6072C702CDF6F39153C472E668ABF0B85B8D08454027AA52E3227C5BA017B2558F7A611F09C7BE5E28A472FAB51C71FF7E8C758CD5205C562F3674D941EF2DEC7F3B3F49C4CE3A9DD7B4275BD537BF04A4A8E98FAA42AD0A2280CFC0D4692339EEC803B69FDC33057837FBD233DB6B78920F7049B5F9CA9CFDD98351B9E7947265439F48429306D6CAB08774F2B7427A61DA757375D26C08B99BCAFB8085E41DBA0E49D142EEC164CC3153AB3119FB76033B3367059073
-20180403042819 2 6 100 2047 2 EA0303D03FF69BCABDC25DDEA6AC9CFEE8C36EF48C7F2882B65D568B0D14A7DACCF4A6E8E905727C0B982FA4D7C4E59DDAF4704D0EC767D79B13A32467C8D39F615B5268E4338DD70C6072C702CDF6F39153C472E668ABF0B85B8D08454027AA52E3227C5BA017B2558F7A611F09C7BE5E28A472FAB51C71FF7E8C758CD5205C562F3674D941EF2DEC7F3B3F49C4CE3A9DD7B4275BD537BF04A4A8E98FAA42AD0A2280CFC0D4692339EEC803B69FDC33057837FBD233DB6B78920F7049B5F9CA9CFDD98351B9E7947265439F48429306D6CAB08774F2B7427A61DA757375D26C08B99BCAFB8085E41DBA0E49D142EEC164CC3153AB3119FB76033B3367289EC3
-20180403042928 2 6 100 2047 2 EA0303D03FF69BCABDC25DDEA6AC9CFEE8C36EF48C7F2882B65D568B0D14A7DACCF4A6E8E905727C0B982FA4D7C4E59DDAF4704D0EC767D79B13A32467C8D39F615B5268E4338DD70C6072C702CDF6F39153C472E668ABF0B85B8D08454027AA52E3227C5BA017B2558F7A611F09C7BE5E28A472FAB51C71FF7E8C758CD5205C562F3674D941EF2DEC7F3B3F49C4CE3A9DD7B4275BD537BF04A4A8E98FAA42AD0A2280CFC0D4692339EEC803B69FDC33057837FBD233DB6B78920F7049B5F9CA9CFDD98351B9E7947265439F48429306D6CAB08774F2B7427A61DA757375D26C08B99BCAFB8085E41DBA0E49D142EEC164CC3153AB3119FB76033B3367519D23
-20180403042946 2 6 100 2047 2 EA0303D03FF69BCABDC25DDEA6AC9CFEE8C36EF48C7F2882B65D568B0D14A7DACCF4A6E8E905727C0B982FA4D7C4E59DDAF4704D0EC767D79B13A32467C8D39F615B5268E4338DD70C6072C702CDF6F39153C472E668ABF0B85B8D08454027AA52E3227C5BA017B2558F7A611F09C7BE5E28A472FAB51C71FF7E8C758CD5205C562F3674D941EF2DEC7F3B3F49C4CE3A9DD7B4275BD537BF04A4A8E98FAA42AD0A2280CFC0D4692339EEC803B69FDC33057837FBD233DB6B78920F7049B5F9CA9CFDD98351B9E7947265439F48429306D6CAB08774F2B7427A61DA757375D26C08B99BCAFB8085E41DBA0E49D142EEC164CC3153AB3119FB76033B336758BFC3
-20180403043032 2 6 100 2047 2 EA0303D03FF69BCABDC25DDEA6AC9CFEE8C36EF48C7F2882B65D568B0D14A7DACCF4A6E8E905727C0B982FA4D7C4E59DDAF4704D0EC767D79B13A32467C8D39F615B5268E4338DD70C6072C702CDF6F39153C472E668ABF0B85B8D08454027AA52E3227C5BA017B2558F7A611F09C7BE5E28A472FAB51C71FF7E8C758CD5205C562F3674D941EF2DEC7F3B3F49C4CE3A9DD7B4275BD537BF04A4A8E98FAA42AD0A2280CFC0D4692339EEC803B69FDC33057837FBD233DB6B78920F7049B5F9CA9CFDD98351B9E7947265439F48429306D6CAB08774F2B7427A61DA757375D26C08B99BCAFB8085E41DBA0E49D142EEC164CC3153AB3119FB76033B336774A8EB
-20180403043218 2 6 100 2047 5 EA0303D03FF69BCABDC25DDEA6AC9CFEE8C36EF48C7F2882B65D568B0D14A7DACCF4A6E8E905727C0B982FA4D7C4E59DDAF4704D0EC767D79B13A32467C8D39F615B5268E4338DD70C6072C702CDF6F39153C472E668ABF0B85B8D08454027AA52E3227C5BA017B2558F7A611F09C7BE5E28A472FAB51C71FF7E8C758CD5205C562F3674D941EF2DEC7F3B3F49C4CE3A9DD7B4275BD537BF04A4A8E98FAA42AD0A2280CFC0D4692339EEC803B69FDC33057837FBD233DB6B78920F7049B5F9CA9CFDD98351B9E7947265439F48429306D6CAB08774F2B7427A61DA757375D26C08B99BCAFB8085E41DBA0E49D142EEC164CC3153AB3119FB76033B3367BAAE3F
-20180403043245 2 6 100 2047 2 EA0303D03FF69BCABDC25DDEA6AC9CFEE8C36EF48C7F2882B65D568B0D14A7DACCF4A6E8E905727C0B982FA4D7C4E59DDAF4704D0EC767D79B13A32467C8D39F615B5268E4338DD70C6072C702CDF6F39153C472E668ABF0B85B8D08454027AA52E3227C5BA017B2558F7A611F09C7BE5E28A472FAB51C71FF7E8C758CD5205C562F3674D941EF2DEC7F3B3F49C4CE3A9DD7B4275BD537BF04A4A8E98FAA42AD0A2280CFC0D4692339EEC803B69FDC33057837FBD233DB6B78920F7049B5F9CA9CFDD98351B9E7947265439F48429306D6CAB08774F2B7427A61DA757375D26C08B99BCAFB8085E41DBA0E49D142EEC164CC3153AB3119FB76033B3367C6B5CB
-20180403043522 2 6 100 2047 2 EA0303D03FF69BCABDC25DDEA6AC9CFEE8C36EF48C7F2882B65D568B0D14A7DACCF4A6E8E905727C0B982FA4D7C4E59DDAF4704D0EC767D79B13A32467C8D39F615B5268E4338DD70C6072C702CDF6F39153C472E668ABF0B85B8D08454027AA52E3227C5BA017B2558F7A611F09C7BE5E28A472FAB51C71FF7E8C758CD5205C562F3674D941EF2DEC7F3B3F49C4CE3A9DD7B4275BD537BF04A4A8E98FAA42AD0A2280CFC0D4692339EEC803B69FDC33057837FBD233DB6B78920F7049B5F9CA9CFDD98351B9E7947265439F48429306D6CAB08774F2B7427A61DA757375D26C08B99BCAFB8085E41DBA0E49D142EEC164CC3153AB3119FB76033B3368340BB3
-20180403043954 2 6 100 2047 2 EA0303D03FF69BCABDC25DDEA6AC9CFEE8C36EF48C7F2882B65D568B0D14A7DACCF4A6E8E905727C0B982FA4D7C4E59DDAF4704D0EC767D79B13A32467C8D39F615B5268E4338DD70C6072C702CDF6F39153C472E668ABF0B85B8D08454027AA52E3227C5BA017B2558F7A611F09C7BE5E28A472FAB51C71FF7E8C758CD5205C562F3674D941EF2DEC7F3B3F49C4CE3A9DD7B4275BD537BF04A4A8E98FAA42AD0A2280CFC0D4692339EEC803B69FDC33057837FBD233DB6B78920F7049B5F9CA9CFDD98351B9E7947265439F48429306D6CAB08774F2B7427A61DA757375D26C08B99BCAFB8085E41DBA0E49D142EEC164CC3153AB3119FB76033B33690CEBC3
-20180403044107 2 6 100 2047 2 EA0303D03FF69BCABDC25DDEA6AC9CFEE8C36EF48C7F2882B65D568B0D14A7DACCF4A6E8E905727C0B982FA4D7C4E59DDAF4704D0EC767D79B13A32467C8D39F615B5268E4338DD70C6072C702CDF6F39153C472E668ABF0B85B8D08454027AA52E3227C5BA017B2558F7A611F09C7BE5E28A472FAB51C71FF7E8C758CD5205C562F3674D941EF2DEC7F3B3F49C4CE3A9DD7B4275BD537BF04A4A8E98FAA42AD0A2280CFC0D4692339EEC803B69FDC33057837FBD233DB6B78920F7049B5F9CA9CFDD98351B9E7947265439F48429306D6CAB08774F2B7427A61DA757375D26C08B99BCAFB8085E41DBA0E49D142EEC164CC3153AB3119FB76033B33693DA563
-20180403044245 2 6 100 2047 2 EA0303D03FF69BCABDC25DDEA6AC9CFEE8C36EF48C7F2882B65D568B0D14A7DACCF4A6E8E905727C0B982FA4D7C4E59DDAF4704D0EC767D79B13A32467C8D39F615B5268E4338DD70C6072C702CDF6F39153C472E668ABF0B85B8D08454027AA52E3227C5BA017B2558F7A611F09C7BE5E28A472FAB51C71FF7E8C758CD5205C562F3674D941EF2DEC7F3B3F49C4CE3A9DD7B4275BD537BF04A4A8E98FAA42AD0A2280CFC0D4692339EEC803B69FDC33057837FBD233DB6B78920F7049B5F9CA9CFDD98351B9E7947265439F48429306D6CAB08774F2B7427A61DA757375D26C08B99BCAFB8085E41DBA0E49D142EEC164CC3153AB3119FB76033B33697A63FB
-20180403044527 2 6 100 2047 5 EA0303D03FF69BCABDC25DDEA6AC9CFEE8C36EF48C7F2882B65D568B0D14A7DACCF4A6E8E905727C0B982FA4D7C4E59DDAF4704D0EC767D79B13A32467C8D39F615B5268E4338DD70C6072C702CDF6F39153C472E668ABF0B85B8D08454027AA52E3227C5BA017B2558F7A611F09C7BE5E28A472FAB51C71FF7E8C758CD5205C562F3674D941EF2DEC7F3B3F49C4CE3A9DD7B4275BD537BF04A4A8E98FAA42AD0A2280CFC0D4692339EEC803B69FDC33057837FBD233DB6B78920F7049B5F9CA9CFDD98351B9E7947265439F48429306D6CAB08774F2B7427A61DA757375D26C08B99BCAFB8085E41DBA0E49D142EEC164CC3153AB3119FB76033B3369F3CAFF
-20180403044559 2 6 100 2047 2 EA0303D03FF69BCABDC25DDEA6AC9CFEE8C36EF48C7F2882B65D568B0D14A7DACCF4A6E8E905727C0B982FA4D7C4E59DDAF4704D0EC767D79B13A32467C8D39F615B5268E4338DD70C6072C702CDF6F39153C472E668ABF0B85B8D08454027AA52E3227C5BA017B2558F7A611F09C7BE5E28A472FAB51C71FF7E8C758CD5205C562F3674D941EF2DEC7F3B3F49C4CE3A9DD7B4275BD537BF04A4A8E98FAA42AD0A2280CFC0D4692339EEC803B69FDC33057837FBD233DB6B78920F7049B5F9CA9CFDD98351B9E7947265439F48429306D6CAB08774F2B7427A61DA757375D26C08B99BCAFB8085E41DBA0E49D142EEC164CC3153AB3119FB76033B336A09E6EB
-20180403044611 2 6 100 2047 2 EA0303D03FF69BCABDC25DDEA6AC9CFEE8C36EF48C7F2882B65D568B0D14A7DACCF4A6E8E905727C0B982FA4D7C4E59DDAF4704D0EC767D79B13A32467C8D39F615B5268E4338DD70C6072C702CDF6F39153C472E668ABF0B85B8D08454027AA52E3227C5BA017B2558F7A611F09C7BE5E28A472FAB51C71FF7E8C758CD5205C562F3674D941EF2DEC7F3B3F49C4CE3A9DD7B4275BD537BF04A4A8E98FAA42AD0A2280CFC0D4692339EEC803B69FDC33057837FBD233DB6B78920F7049B5F9CA9CFDD98351B9E7947265439F48429306D6CAB08774F2B7427A61DA757375D26C08B99BCAFB8085E41DBA0E49D142EEC164CC3153AB3119FB76033B336A0C4F53
-20180403044719 2 6 100 2047 5 EA0303D03FF69BCABDC25DDEA6AC9CFEE8C36EF48C7F2882B65D568B0D14A7DACCF4A6E8E905727C0B982FA4D7C4E59DDAF4704D0EC767D79B13A32467C8D39F615B5268E4338DD70C6072C702CDF6F39153C472E668ABF0B85B8D08454027AA52E3227C5BA017B2558F7A611F09C7BE5E28A472FAB51C71FF7E8C758CD5205C562F3674D941EF2DEC7F3B3F49C4CE3A9DD7B4275BD537BF04A4A8E98FAA42AD0A2280CFC0D4692339EEC803B69FDC33057837FBD233DB6B78920F7049B5F9CA9CFDD98351B9E7947265439F48429306D6CAB08774F2B7427A61DA757375D26C08B99BCAFB8085E41DBA0E49D142EEC164CC3153AB3119FB76033B336A4348BF
-20180403044820 2 6 100 2047 2 EA0303D03FF69BCABDC25DDEA6AC9CFEE8C36EF48C7F2882B65D568B0D14A7DACCF4A6E8E905727C0B982FA4D7C4E59DDAF4704D0EC767D79B13A32467C8D39F615B5268E4338DD70C6072C702CDF6F39153C472E668ABF0B85B8D08454027AA52E3227C5BA017B2558F7A611F09C7BE5E28A472FAB51C71FF7E8C758CD5205C562F3674D941EF2DEC7F3B3F49C4CE3A9DD7B4275BD537BF04A4A8E98FAA42AD0A2280CFC0D4692339EEC803B69FDC33057837FBD233DB6B78920F7049B5F9CA9CFDD98351B9E7947265439F48429306D6CAB08774F2B7427A61DA757375D26C08B99BCAFB8085E41DBA0E49D142EEC164CC3153AB3119FB76033B336A6E3193
-20180403044844 2 6 100 2047 5 EA0303D03FF69BCABDC25DDEA6AC9CFEE8C36EF48C7F2882B65D568B0D14A7DACCF4A6E8E905727C0B982FA4D7C4E59DDAF4704D0EC767D79B13A32467C8D39F615B5268E4338DD70C6072C702CDF6F39153C472E668ABF0B85B8D08454027AA52E3227C5BA017B2558F7A611F09C7BE5E28A472FAB51C71FF7E8C758CD5205C562F3674D941EF2DEC7F3B3F49C4CE3A9DD7B4275BD537BF04A4A8E98FAA42AD0A2280CFC0D4692339EEC803B69FDC33057837FBD233DB6B78920F7049B5F9CA9CFDD98351B9E7947265439F48429306D6CAB08774F2B7427A61DA757375D26C08B99BCAFB8085E41DBA0E49D142EEC164CC3153AB3119FB76033B336A7A9C7F
-20180403045235 2 6 100 2047 2 EA0303D03FF69BCABDC25DDEA6AC9CFEE8C36EF48C7F2882B65D568B0D14A7DACCF4A6E8E905727C0B982FA4D7C4E59DDAF4704D0EC767D79B13A32467C8D39F615B5268E4338DD70C6072C702CDF6F39153C472E668ABF0B85B8D08454027AA52E3227C5BA017B2558F7A611F09C7BE5E28A472FAB51C71FF7E8C758CD5205C562F3674D941EF2DEC7F3B3F49C4CE3A9DD7B4275BD537BF04A4A8E98FAA42AD0A2280CFC0D4692339EEC803B69FDC33057837FBD233DB6B78920F7049B5F9CA9CFDD98351B9E7947265439F48429306D6CAB08774F2B7427A61DA757375D26C08B99BCAFB8085E41DBA0E49D142EEC164CC3153AB3119FB76033B336B2E2173
-20180403045518 2 6 100 2047 2 EA0303D03FF69BCABDC25DDEA6AC9CFEE8C36EF48C7F2882B65D568B0D14A7DACCF4A6E8E905727C0B982FA4D7C4E59DDAF4704D0EC767D79B13A32467C8D39F615B5268E4338DD70C6072C702CDF6F39153C472E668ABF0B85B8D08454027AA52E3227C5BA017B2558F7A611F09C7BE5E28A472FAB51C71FF7E8C758CD5205C562F3674D941EF2DEC7F3B3F49C4CE3A9DD7B4275BD537BF04A4A8E98FAA42AD0A2280CFC0D4692339EEC803B69FDC33057837FBD233DB6B78920F7049B5F9CA9CFDD98351B9E7947265439F48429306D6CAB08774F2B7427A61DA757375D26C08B99BCAFB8085E41DBA0E49D142EEC164CC3153AB3119FB76033B336BAD847B
-20180403045629 2 6 100 2047 2 EA0303D03FF69BCABDC25DDEA6AC9CFEE8C36EF48C7F2882B65D568B0D14A7DACCF4A6E8E905727C0B982FA4D7C4E59DDAF4704D0EC767D79B13A32467C8D39F615B5268E4338DD70C6072C702CDF6F39153C472E668ABF0B85B8D08454027AA52E3227C5BA017B2558F7A611F09C7BE5E28A472FAB51C71FF7E8C758CD5205C562F3674D941EF2DEC7F3B3F49C4CE3A9DD7B4275BD537BF04A4A8E98FAA42AD0A2280CFC0D4692339EEC803B69FDC33057837FBD233DB6B78920F7049B5F9CA9CFDD98351B9E7947265439F48429306D6CAB08774F2B7427A61DA757375D26C08B99BCAFB8085E41DBA0E49D142EEC164CC3153AB3119FB76033B336BE29A4B
-20180403045953 2 6 100 2047 2 EA0303D03FF69BCABDC25DDEA6AC9CFEE8C36EF48C7F2882B65D568B0D14A7DACCF4A6E8E905727C0B982FA4D7C4E59DDAF4704D0EC767D79B13A32467C8D39F615B5268E4338DD70C6072C702CDF6F39153C472E668ABF0B85B8D08454027AA52E3227C5BA017B2558F7A611F09C7BE5E28A472FAB51C71FF7E8C758CD5205C562F3674D941EF2DEC7F3B3F49C4CE3A9DD7B4275BD537BF04A4A8E98FAA42AD0A2280CFC0D4692339EEC803B69FDC33057837FBD233DB6B78920F7049B5F9CA9CFDD98351B9E7947265439F48429306D6CAB08774F2B7427A61DA757375D26C08B99BCAFB8085E41DBA0E49D142EEC164CC3153AB3119FB76033B336C865153
-20180403050042 2 6 100 2047 5 EA0303D03FF69BCABDC25DDEA6AC9CFEE8C36EF48C7F2882B65D568B0D14A7DACCF4A6E8E905727C0B982FA4D7C4E59DDAF4704D0EC767D79B13A32467C8D39F615B5268E4338DD70C6072C702CDF6F39153C472E668ABF0B85B8D08454027AA52E3227C5BA017B2558F7A611F09C7BE5E28A472FAB51C71FF7E8C758CD5205C562F3674D941EF2DEC7F3B3F49C4CE3A9DD7B4275BD537BF04A4A8E98FAA42AD0A2280CFC0D4692339EEC803B69FDC33057837FBD233DB6B78920F7049B5F9CA9CFDD98351B9E7947265439F48429306D6CAB08774F2B7427A61DA757375D26C08B99BCAFB8085E41DBA0E49D142EEC164CC3153AB3119FB76033B336CA6948F
-20180403055314 2 6 100 3071 2 FF8DCF143A9E3CC447F8D3D03206E386572BFAC54F4BDE233C8B1223CC9CBA99689328E35F8F83F0922A9F0AB33E7C7892E940377CE0064700ECDCC8532F0FEF888913E1894054707878511DD84455BEACCA35E8418D6CAD03111BC1842581D40E280A13055030CB35339E2A0E422DB9EC47916AD6302BE248AD5EBCCE7CF087CB2285A6B8D227DC7130ADB14163BE4D1AA779DBCD36710AA080F219B535B1887392DE9EF44116C933F5CA2234A7A82A8A48F1691A39434D70E3C3995AEE7CEAFF86DAA2326CF367B7E3C7939E4B78A00EE58E52F7BB36C8A89525CA4D44173E30AA6B40FD0B60C29F6CBC763241AC5DA16E2A9FB9B78F360EED32704B686AD6D40DAE8127C9351A2B21C140292E77592A7159000FB2AA9561DA10B2AC3167CC8E41C10CDF86E9041A3A114F42EF4AA5134C716893E81C3A7488ED5131073FC76B20358549BF1B0858B571550663DA9CF73B7B28BF9CA1FAF8EC96966D493C174B03DBCF9B5470DD9A79FB3E14A0B73B6E6C09D531886ACF60E51B57012EEDBB
-20180403055637 2 6 100 3071 2 FF8DCF143A9E3CC447F8D3D03206E386572BFAC54F4BDE233C8B1223CC9CBA99689328E35F8F83F0922A9F0AB33E7C7892E940377CE0064700ECDCC8532F0FEF888913E1894054707878511DD84455BEACCA35E8418D6CAD03111BC1842581D40E280A13055030CB35339E2A0E422DB9EC47916AD6302BE248AD5EBCCE7CF087CB2285A6B8D227DC7130ADB14163BE4D1AA779DBCD36710AA080F219B535B1887392DE9EF44116C933F5CA2234A7A82A8A48F1691A39434D70E3C3995AEE7CEAFF86DAA2326CF367B7E3C7939E4B78A00EE58E52F7BB36C8A89525CA4D44173E30AA6B40FD0B60C29F6CBC763241AC5DA16E2A9FB9B78F360EED32704B686AD6D40DAE8127C9351A2B21C140292E77592A7159000FB2AA9561DA10B2AC3167CC8E41C10CDF86E9041A3A114F42EF4AA5134C716893E81C3A7488ED5131073FC76B20358549BF1B0858B571550663DA9CF73B7B28BF9CA1FAF8EC96966D493C174B03DBCF9B5470DD9A79FB3E14A0B73B6E6C09D531886ACF60E51B57015FFFAB
-20180403060753 2 6 100 3071 2 FF8DCF143A9E3CC447F8D3D03206E386572BFAC54F4BDE233C8B1223CC9CBA99689328E35F8F83F0922A9F0AB33E7C7892E940377CE0064700ECDCC8532F0FEF888913E1894054707878511DD84455BEACCA35E8418D6CAD03111BC1842581D40E280A13055030CB35339E2A0E422DB9EC47916AD6302BE248AD5EBCCE7CF087CB2285A6B8D227DC7130ADB14163BE4D1AA779DBCD36710AA080F219B535B1887392DE9EF44116C933F5CA2234A7A82A8A48F1691A39434D70E3C3995AEE7CEAFF86DAA2326CF367B7E3C7939E4B78A00EE58E52F7BB36C8A89525CA4D44173E30AA6B40FD0B60C29F6CBC763241AC5DA16E2A9FB9B78F360EED32704B686AD6D40DAE8127C9351A2B21C140292E77592A7159000FB2AA9561DA10B2AC3167CC8E41C10CDF86E9041A3A114F42EF4AA5134C716893E81C3A7488ED5131073FC76B20358549BF1B0858B571550663DA9CF73B7B28BF9CA1FAF8EC96966D493C174B03DBCF9B5470DD9A79FB3E14A0B73B6E6C09D531886ACF60E51B57021C5763
-20180403061035 2 6 100 3071 2 FF8DCF143A9E3CC447F8D3D03206E386572BFAC54F4BDE233C8B1223CC9CBA99689328E35F8F83F0922A9F0AB33E7C7892E940377CE0064700ECDCC8532F0FEF888913E1894054707878511DD84455BEACCA35E8418D6CAD03111BC1842581D40E280A13055030CB35339E2A0E422DB9EC47916AD6302BE248AD5EBCCE7CF087CB2285A6B8D227DC7130ADB14163BE4D1AA779DBCD36710AA080F219B535B1887392DE9EF44116C933F5CA2234A7A82A8A48F1691A39434D70E3C3995AEE7CEAFF86DAA2326CF367B7E3C7939E4B78A00EE58E52F7BB36C8A89525CA4D44173E30AA6B40FD0B60C29F6CBC763241AC5DA16E2A9FB9B78F360EED32704B686AD6D40DAE8127C9351A2B21C140292E77592A7159000FB2AA9561DA10B2AC3167CC8E41C10CDF86E9041A3A114F42EF4AA5134C716893E81C3A7488ED5131073FC76B20358549BF1B0858B571550663DA9CF73B7B28BF9CA1FAF8EC96966D493C174B03DBCF9B5470DD9A79FB3E14A0B73B6E6C09D531886ACF60E51B570243FBBB
-20180403061925 2 6 100 3071 2 FF8DCF143A9E3CC447F8D3D03206E386572BFAC54F4BDE233C8B1223CC9CBA99689328E35F8F83F0922A9F0AB33E7C7892E940377CE0064700ECDCC8532F0FEF888913E1894054707878511DD84455BEACCA35E8418D6CAD03111BC1842581D40E280A13055030CB35339E2A0E422DB9EC47916AD6302BE248AD5EBCCE7CF087CB2285A6B8D227DC7130ADB14163BE4D1AA779DBCD36710AA080F219B535B1887392DE9EF44116C933F5CA2234A7A82A8A48F1691A39434D70E3C3995AEE7CEAFF86DAA2326CF367B7E3C7939E4B78A00EE58E52F7BB36C8A89525CA4D44173E30AA6B40FD0B60C29F6CBC763241AC5DA16E2A9FB9B78F360EED32704B686AD6D40DAE8127C9351A2B21C140292E77592A7159000FB2AA9561DA10B2AC3167CC8E41C10CDF86E9041A3A114F42EF4AA5134C716893E81C3A7488ED5131073FC76B20358549BF1B0858B571550663DA9CF73B7B28BF9CA1FAF8EC96966D493C174B03DBCF9B5470DD9A79FB3E14A0B73B6E6C09D531886ACF60E51B5702CE55A3
-20180403062241 2 6 100 3071 2 FF8DCF143A9E3CC447F8D3D03206E386572BFAC54F4BDE233C8B1223CC9CBA99689328E35F8F83F0922A9F0AB33E7C7892E940377CE0064700ECDCC8532F0FEF888913E1894054707878511DD84455BEACCA35E8418D6CAD03111BC1842581D40E280A13055030CB35339E2A0E422DB9EC47916AD6302BE248AD5EBCCE7CF087CB2285A6B8D227DC7130ADB14163BE4D1AA779DBCD36710AA080F219B535B1887392DE9EF44116C933F5CA2234A7A82A8A48F1691A39434D70E3C3995AEE7CEAFF86DAA2326CF367B7E3C7939E4B78A00EE58E52F7BB36C8A89525CA4D44173E30AA6B40FD0B60C29F6CBC763241AC5DA16E2A9FB9B78F360EED32704B686AD6D40DAE8127C9351A2B21C140292E77592A7159000FB2AA9561DA10B2AC3167CC8E41C10CDF86E9041A3A114F42EF4AA5134C716893E81C3A7488ED5131073FC76B20358549BF1B0858B571550663DA9CF73B7B28BF9CA1FAF8EC96966D493C174B03DBCF9B5470DD9A79FB3E14A0B73B6E6C09D531886ACF60E51B5702FA4263
-20180403062828 2 6 100 3071 5 FF8DCF143A9E3CC447F8D3D03206E386572BFAC54F4BDE233C8B1223CC9CBA99689328E35F8F83F0922A9F0AB33E7C7892E940377CE0064700ECDCC8532F0FEF888913E1894054707878511DD84455BEACCA35E8418D6CAD03111BC1842581D40E280A13055030CB35339E2A0E422DB9EC47916AD6302BE248AD5EBCCE7CF087CB2285A6B8D227DC7130ADB14163BE4D1AA779DBCD36710AA080F219B535B1887392DE9EF44116C933F5CA2234A7A82A8A48F1691A39434D70E3C3995AEE7CEAFF86DAA2326CF367B7E3C7939E4B78A00EE58E52F7BB36C8A89525CA4D44173E30AA6B40FD0B60C29F6CBC763241AC5DA16E2A9FB9B78F360EED32704B686AD6D40DAE8127C9351A2B21C140292E77592A7159000FB2AA9561DA10B2AC3167CC8E41C10CDF86E9041A3A114F42EF4AA5134C716893E81C3A7488ED5131073FC76B20358549BF1B0858B571550663DA9CF73B7B28BF9CA1FAF8EC96966D493C174B03DBCF9B5470DD9A79FB3E14A0B73B6E6C09D531886ACF60E51B5703495AD7
-20180403063232 2 6 100 3071 5 FF8DCF143A9E3CC447F8D3D03206E386572BFAC54F4BDE233C8B1223CC9CBA99689328E35F8F83F0922A9F0AB33E7C7892E940377CE0064700ECDCC8532F0FEF888913E1894054707878511DD84455BEACCA35E8418D6CAD03111BC1842581D40E280A13055030CB35339E2A0E422DB9EC47916AD6302BE248AD5EBCCE7CF087CB2285A6B8D227DC7130ADB14163BE4D1AA779DBCD36710AA080F219B535B1887392DE9EF44116C933F5CA2234A7A82A8A48F1691A39434D70E3C3995AEE7CEAFF86DAA2326CF367B7E3C7939E4B78A00EE58E52F7BB36C8A89525CA4D44173E30AA6B40FD0B60C29F6CBC763241AC5DA16E2A9FB9B78F360EED32704B686AD6D40DAE8127C9351A2B21C140292E77592A7159000FB2AA9561DA10B2AC3167CC8E41C10CDF86E9041A3A114F42EF4AA5134C716893E81C3A7488ED5131073FC76B20358549BF1B0858B571550663DA9CF73B7B28BF9CA1FAF8EC96966D493C174B03DBCF9B5470DD9A79FB3E14A0B73B6E6C09D531886ACF60E51B570383322F
-20180403063441 2 6 100 3071 5 FF8DCF143A9E3CC447F8D3D03206E386572BFAC54F4BDE233C8B1223CC9CBA99689328E35F8F83F0922A9F0AB33E7C7892E940377CE0064700ECDCC8532F0FEF888913E1894054707878511DD84455BEACCA35E8418D6CAD03111BC1842581D40E280A13055030CB35339E2A0E422DB9EC47916AD6302BE248AD5EBCCE7CF087CB2285A6B8D227DC7130ADB14163BE4D1AA779DBCD36710AA080F219B535B1887392DE9EF44116C933F5CA2234A7A82A8A48F1691A39434D70E3C3995AEE7CEAFF86DAA2326CF367B7E3C7939E4B78A00EE58E52F7BB36C8A89525CA4D44173E30AA6B40FD0B60C29F6CBC763241AC5DA16E2A9FB9B78F360EED32704B686AD6D40DAE8127C9351A2B21C140292E77592A7159000FB2AA9561DA10B2AC3167CC8E41C10CDF86E9041A3A114F42EF4AA5134C716893E81C3A7488ED5131073FC76B20358549BF1B0858B571550663DA9CF73B7B28BF9CA1FAF8EC96966D493C174B03DBCF9B5470DD9A79FB3E14A0B73B6E6C09D531886ACF60E51B57039D0EE7
-20180403065803 2 6 100 3071 2 FF8DCF143A9E3CC447F8D3D03206E386572BFAC54F4BDE233C8B1223CC9CBA99689328E35F8F83F0922A9F0AB33E7C7892E940377CE0064700ECDCC8532F0FEF888913E1894054707878511DD84455BEACCA35E8418D6CAD03111BC1842581D40E280A13055030CB35339E2A0E422DB9EC47916AD6302BE248AD5EBCCE7CF087CB2285A6B8D227DC7130ADB14163BE4D1AA779DBCD36710AA080F219B535B1887392DE9EF44116C933F5CA2234A7A82A8A48F1691A39434D70E3C3995AEE7CEAFF86DAA2326CF367B7E3C7939E4B78A00EE58E52F7BB36C8A89525CA4D44173E30AA6B40FD0B60C29F6CBC763241AC5DA16E2A9FB9B78F360EED32704B686AD6D40DAE8127C9351A2B21C140292E77592A7159000FB2AA9561DA10B2AC3167CC8E41C10CDF86E9041A3A114F42EF4AA5134C716893E81C3A7488ED5131073FC76B20358549BF1B0858B571550663DA9CF73B7B28BF9CA1FAF8EC96966D493C174B03DBCF9B5470DD9A79FB3E14A0B73B6E6C09D531886ACF60E51B5704F5DFCB
-20180403070250 2 6 100 3071 5 FF8DCF143A9E3CC447F8D3D03206E386572BFAC54F4BDE233C8B1223CC9CBA99689328E35F8F83F0922A9F0AB33E7C7892E940377CE0064700ECDCC8532F0FEF888913E1894054707878511DD84455BEACCA35E8418D6CAD03111BC1842581D40E280A13055030CB35339E2A0E422DB9EC47916AD6302BE248AD5EBCCE7CF087CB2285A6B8D227DC7130ADB14163BE4D1AA779DBCD36710AA080F219B535B1887392DE9EF44116C933F5CA2234A7A82A8A48F1691A39434D70E3C3995AEE7CEAFF86DAA2326CF367B7E3C7939E4B78A00EE58E52F7BB36C8A89525CA4D44173E30AA6B40FD0B60C29F6CBC763241AC5DA16E2A9FB9B78F360EED32704B686AD6D40DAE8127C9351A2B21C140292E77592A7159000FB2AA9561DA10B2AC3167CC8E41C10CDF86E9041A3A114F42EF4AA5134C716893E81C3A7488ED5131073FC76B20358549BF1B0858B571550663DA9CF73B7B28BF9CA1FAF8EC96966D493C174B03DBCF9B5470DD9A79FB3E14A0B73B6E6C09D531886ACF60E51B570535A157
-20180403071043 2 6 100 3071 2 FF8DCF143A9E3CC447F8D3D03206E386572BFAC54F4BDE233C8B1223CC9CBA99689328E35F8F83F0922A9F0AB33E7C7892E940377CE0064700ECDCC8532F0FEF888913E1894054707878511DD84455BEACCA35E8418D6CAD03111BC1842581D40E280A13055030CB35339E2A0E422DB9EC47916AD6302BE248AD5EBCCE7CF087CB2285A6B8D227DC7130ADB14163BE4D1AA779DBCD36710AA080F219B535B1887392DE9EF44116C933F5CA2234A7A82A8A48F1691A39434D70E3C3995AEE7CEAFF86DAA2326CF367B7E3C7939E4B78A00EE58E52F7BB36C8A89525CA4D44173E30AA6B40FD0B60C29F6CBC763241AC5DA16E2A9FB9B78F360EED32704B686AD6D40DAE8127C9351A2B21C140292E77592A7159000FB2AA9561DA10B2AC3167CC8E41C10CDF86E9041A3A114F42EF4AA5134C716893E81C3A7488ED5131073FC76B20358549BF1B0858B571550663DA9CF73B7B28BF9CA1FAF8EC96966D493C174B03DBCF9B5470DD9A79FB3E14A0B73B6E6C09D531886ACF60E51B5705AD5B2B
-20180403072237 2 6 100 3071 5 FF8DCF143A9E3CC447F8D3D03206E386572BFAC54F4BDE233C8B1223CC9CBA99689328E35F8F83F0922A9F0AB33E7C7892E940377CE0064700ECDCC8532F0FEF888913E1894054707878511DD84455BEACCA35E8418D6CAD03111BC1842581D40E280A13055030CB35339E2A0E422DB9EC47916AD6302BE248AD5EBCCE7CF087CB2285A6B8D227DC7130ADB14163BE4D1AA779DBCD36710AA080F219B535B1887392DE9EF44116C933F5CA2234A7A82A8A48F1691A39434D70E3C3995AEE7CEAFF86DAA2326CF367B7E3C7939E4B78A00EE58E52F7BB36C8A89525CA4D44173E30AA6B40FD0B60C29F6CBC763241AC5DA16E2A9FB9B78F360EED32704B686AD6D40DAE8127C9351A2B21C140292E77592A7159000FB2AA9561DA10B2AC3167CC8E41C10CDF86E9041A3A114F42EF4AA5134C716893E81C3A7488ED5131073FC76B20358549BF1B0858B571550663DA9CF73B7B28BF9CA1FAF8EC96966D493C174B03DBCF9B5470DD9A79FB3E14A0B73B6E6C09D531886ACF60E51B57066B3AFF
-20180403072347 2 6 100 3071 2 FF8DCF143A9E3CC447F8D3D03206E386572BFAC54F4BDE233C8B1223CC9CBA99689328E35F8F83F0922A9F0AB33E7C7892E940377CE0064700ECDCC8532F0FEF888913E1894054707878511DD84455BEACCA35E8418D6CAD03111BC1842581D40E280A13055030CB35339E2A0E422DB9EC47916AD6302BE248AD5EBCCE7CF087CB2285A6B8D227DC7130ADB14163BE4D1AA779DBCD36710AA080F219B535B1887392DE9EF44116C933F5CA2234A7A82A8A48F1691A39434D70E3C3995AEE7CEAFF86DAA2326CF367B7E3C7939E4B78A00EE58E52F7BB36C8A89525CA4D44173E30AA6B40FD0B60C29F6CBC763241AC5DA16E2A9FB9B78F360EED32704B686AD6D40DAE8127C9351A2B21C140292E77592A7159000FB2AA9561DA10B2AC3167CC8E41C10CDF86E9041A3A114F42EF4AA5134C716893E81C3A7488ED5131073FC76B20358549BF1B0858B571550663DA9CF73B7B28BF9CA1FAF8EC96966D493C174B03DBCF9B5470DD9A79FB3E14A0B73B6E6C09D531886ACF60E51B5706763D5B
-20180403072612 2 6 100 3071 2 FF8DCF143A9E3CC447F8D3D03206E386572BFAC54F4BDE233C8B1223CC9CBA99689328E35F8F83F0922A9F0AB33E7C7892E940377CE0064700ECDCC8532F0FEF888913E1894054707878511DD84455BEACCA35E8418D6CAD03111BC1842581D40E280A13055030CB35339E2A0E422DB9EC47916AD6302BE248AD5EBCCE7CF087CB2285A6B8D227DC7130ADB14163BE4D1AA779DBCD36710AA080F219B535B1887392DE9EF44116C933F5CA2234A7A82A8A48F1691A39434D70E3C3995AEE7CEAFF86DAA2326CF367B7E3C7939E4B78A00EE58E52F7BB36C8A89525CA4D44173E30AA6B40FD0B60C29F6CBC763241AC5DA16E2A9FB9B78F360EED32704B686AD6D40DAE8127C9351A2B21C140292E77592A7159000FB2AA9561DA10B2AC3167CC8E41C10CDF86E9041A3A114F42EF4AA5134C716893E81C3A7488ED5131073FC76B20358549BF1B0858B571550663DA9CF73B7B28BF9CA1FAF8EC96966D493C174B03DBCF9B5470DD9A79FB3E14A0B73B6E6C09D531886ACF60E51B570696B733
-20180403073322 2 6 100 3071 2 FF8DCF143A9E3CC447F8D3D03206E386572BFAC54F4BDE233C8B1223CC9CBA99689328E35F8F83F0922A9F0AB33E7C7892E940377CE0064700ECDCC8532F0FEF888913E1894054707878511DD84455BEACCA35E8418D6CAD03111BC1842581D40E280A13055030CB35339E2A0E422DB9EC47916AD6302BE248AD5EBCCE7CF087CB2285A6B8D227DC7130ADB14163BE4D1AA779DBCD36710AA080F219B535B1887392DE9EF44116C933F5CA2234A7A82A8A48F1691A39434D70E3C3995AEE7CEAFF86DAA2326CF367B7E3C7939E4B78A00EE58E52F7BB36C8A89525CA4D44173E30AA6B40FD0B60C29F6CBC763241AC5DA16E2A9FB9B78F360EED32704B686AD6D40DAE8127C9351A2B21C140292E77592A7159000FB2AA9561DA10B2AC3167CC8E41C10CDF86E9041A3A114F42EF4AA5134C716893E81C3A7488ED5131073FC76B20358549BF1B0858B571550663DA9CF73B7B28BF9CA1FAF8EC96966D493C174B03DBCF9B5470DD9A79FB3E14A0B73B6E6C09D531886ACF60E51B5707062E2B
-20180403073825 2 6 100 3071 5 FF8DCF143A9E3CC447F8D3D03206E386572BFAC54F4BDE233C8B1223CC9CBA99689328E35F8F83F0922A9F0AB33E7C7892E940377CE0064700ECDCC8532F0FEF888913E1894054707878511DD84455BEACCA35E8418D6CAD03111BC1842581D40E280A13055030CB35339E2A0E422DB9EC47916AD6302BE248AD5EBCCE7CF087CB2285A6B8D227DC7130ADB14163BE4D1AA779DBCD36710AA080F219B535B1887392DE9EF44116C933F5CA2234A7A82A8A48F1691A39434D70E3C3995AEE7CEAFF86DAA2326CF367B7E3C7939E4B78A00EE58E52F7BB36C8A89525CA4D44173E30AA6B40FD0B60C29F6CBC763241AC5DA16E2A9FB9B78F360EED32704B686AD6D40DAE8127C9351A2B21C140292E77592A7159000FB2AA9561DA10B2AC3167CC8E41C10CDF86E9041A3A114F42EF4AA5134C716893E81C3A7488ED5131073FC76B20358549BF1B0858B571550663DA9CF73B7B28BF9CA1FAF8EC96966D493C174B03DBCF9B5470DD9A79FB3E14A0B73B6E6C09D531886ACF60E51B5707547607
-20180403073948 2 6 100 3071 5 FF8DCF143A9E3CC447F8D3D03206E386572BFAC54F4BDE233C8B1223CC9CBA99689328E35F8F83F0922A9F0AB33E7C7892E940377CE0064700ECDCC8532F0FEF888913E1894054707878511DD84455BEACCA35E8418D6CAD03111BC1842581D40E280A13055030CB35339E2A0E422DB9EC47916AD6302BE248AD5EBCCE7CF087CB2285A6B8D227DC7130ADB14163BE4D1AA779DBCD36710AA080F219B535B1887392DE9EF44116C933F5CA2234A7A82A8A48F1691A39434D70E3C3995AEE7CEAFF86DAA2326CF367B7E3C7939E4B78A00EE58E52F7BB36C8A89525CA4D44173E30AA6B40FD0B60C29F6CBC763241AC5DA16E2A9FB9B78F360EED32704B686AD6D40DAE8127C9351A2B21C140292E77592A7159000FB2AA9561DA10B2AC3167CC8E41C10CDF86E9041A3A114F42EF4AA5134C716893E81C3A7488ED5131073FC76B20358549BF1B0858B571550663DA9CF73B7B28BF9CA1FAF8EC96966D493C174B03DBCF9B5470DD9A79FB3E14A0B73B6E6C09D531886ACF60E51B570762843F
-20180403074104 2 6 100 3071 2 FF8DCF143A9E3CC447F8D3D03206E386572BFAC54F4BDE233C8B1223CC9CBA99689328E35F8F83F0922A9F0AB33E7C7892E940377CE0064700ECDCC8532F0FEF888913E1894054707878511DD84455BEACCA35E8418D6CAD03111BC1842581D40E280A13055030CB35339E2A0E422DB9EC47916AD6302BE248AD5EBCCE7CF087CB2285A6B8D227DC7130ADB14163BE4D1AA779DBCD36710AA080F219B535B1887392DE9EF44116C933F5CA2234A7A82A8A48F1691A39434D70E3C3995AEE7CEAFF86DAA2326CF367B7E3C7939E4B78A00EE58E52F7BB36C8A89525CA4D44173E30AA6B40FD0B60C29F6CBC763241AC5DA16E2A9FB9B78F360EED32704B686AD6D40DAE8127C9351A2B21C140292E77592A7159000FB2AA9561DA10B2AC3167CC8E41C10CDF86E9041A3A114F42EF4AA5134C716893E81C3A7488ED5131073FC76B20358549BF1B0858B571550663DA9CF73B7B28BF9CA1FAF8EC96966D493C174B03DBCF9B5470DD9A79FB3E14A0B73B6E6C09D531886ACF60E51B57076EC3DB
-20180403074403 2 6 100 3071 2 FF8DCF143A9E3CC447F8D3D03206E386572BFAC54F4BDE233C8B1223CC9CBA99689328E35F8F83F0922A9F0AB33E7C7892E940377CE0064700ECDCC8532F0FEF888913E1894054707878511DD84455BEACCA35E8418D6CAD03111BC1842581D40E280A13055030CB35339E2A0E422DB9EC47916AD6302BE248AD5EBCCE7CF087CB2285A6B8D227DC7130ADB14163BE4D1AA779DBCD36710AA080F219B535B1887392DE9EF44116C933F5CA2234A7A82A8A48F1691A39434D70E3C3995AEE7CEAFF86DAA2326CF367B7E3C7939E4B78A00EE58E52F7BB36C8A89525CA4D44173E30AA6B40FD0B60C29F6CBC763241AC5DA16E2A9FB9B78F360EED32704B686AD6D40DAE8127C9351A2B21C140292E77592A7159000FB2AA9561DA10B2AC3167CC8E41C10CDF86E9041A3A114F42EF4AA5134C716893E81C3A7488ED5131073FC76B20358549BF1B0858B571550663DA9CF73B7B28BF9CA1FAF8EC96966D493C174B03DBCF9B5470DD9A79FB3E14A0B73B6E6C09D531886ACF60E51B570799DD63
-20180403074828 2 6 100 3071 2 FF8DCF143A9E3CC447F8D3D03206E386572BFAC54F4BDE233C8B1223CC9CBA99689328E35F8F83F0922A9F0AB33E7C7892E940377CE0064700ECDCC8532F0FEF888913E1894054707878511DD84455BEACCA35E8418D6CAD03111BC1842581D40E280A13055030CB35339E2A0E422DB9EC47916AD6302BE248AD5EBCCE7CF087CB2285A6B8D227DC7130ADB14163BE4D1AA779DBCD36710AA080F219B535B1887392DE9EF44116C933F5CA2234A7A82A8A48F1691A39434D70E3C3995AEE7CEAFF86DAA2326CF367B7E3C7939E4B78A00EE58E52F7BB36C8A89525CA4D44173E30AA6B40FD0B60C29F6CBC763241AC5DA16E2A9FB9B78F360EED32704B686AD6D40DAE8127C9351A2B21C140292E77592A7159000FB2AA9561DA10B2AC3167CC8E41C10CDF86E9041A3A114F42EF4AA5134C716893E81C3A7488ED5131073FC76B20358549BF1B0858B571550663DA9CF73B7B28BF9CA1FAF8EC96966D493C174B03DBCF9B5470DD9A79FB3E14A0B73B6E6C09D531886ACF60E51B5707D93973
-20180403075240 2 6 100 3071 2 FF8DCF143A9E3CC447F8D3D03206E386572BFAC54F4BDE233C8B1223CC9CBA99689328E35F8F83F0922A9F0AB33E7C7892E940377CE0064700ECDCC8532F0FEF888913E1894054707878511DD84455BEACCA35E8418D6CAD03111BC1842581D40E280A13055030CB35339E2A0E422DB9EC47916AD6302BE248AD5EBCCE7CF087CB2285A6B8D227DC7130ADB14163BE4D1AA779DBCD36710AA080F219B535B1887392DE9EF44116C933F5CA2234A7A82A8A48F1691A39434D70E3C3995AEE7CEAFF86DAA2326CF367B7E3C7939E4B78A00EE58E52F7BB36C8A89525CA4D44173E30AA6B40FD0B60C29F6CBC763241AC5DA16E2A9FB9B78F360EED32704B686AD6D40DAE8127C9351A2B21C140292E77592A7159000FB2AA9561DA10B2AC3167CC8E41C10CDF86E9041A3A114F42EF4AA5134C716893E81C3A7488ED5131073FC76B20358549BF1B0858B571550663DA9CF73B7B28BF9CA1FAF8EC96966D493C174B03DBCF9B5470DD9A79FB3E14A0B73B6E6C09D531886ACF60E51B570814F21B
-20180403075918 2 6 100 3071 2 FF8DCF143A9E3CC447F8D3D03206E386572BFAC54F4BDE233C8B1223CC9CBA99689328E35F8F83F0922A9F0AB33E7C7892E940377CE0064700ECDCC8532F0FEF888913E1894054707878511DD84455BEACCA35E8418D6CAD03111BC1842581D40E280A13055030CB35339E2A0E422DB9EC47916AD6302BE248AD5EBCCE7CF087CB2285A6B8D227DC7130ADB14163BE4D1AA779DBCD36710AA080F219B535B1887392DE9EF44116C933F5CA2234A7A82A8A48F1691A39434D70E3C3995AEE7CEAFF86DAA2326CF367B7E3C7939E4B78A00EE58E52F7BB36C8A89525CA4D44173E30AA6B40FD0B60C29F6CBC763241AC5DA16E2A9FB9B78F360EED32704B686AD6D40DAE8127C9351A2B21C140292E77592A7159000FB2AA9561DA10B2AC3167CC8E41C10CDF86E9041A3A114F42EF4AA5134C716893E81C3A7488ED5131073FC76B20358549BF1B0858B571550663DA9CF73B7B28BF9CA1FAF8EC96966D493C174B03DBCF9B5470DD9A79FB3E14A0B73B6E6C09D531886ACF60E51B570878D0DB
-20180403080045 2 6 100 3071 5 FF8DCF143A9E3CC447F8D3D03206E386572BFAC54F4BDE233C8B1223CC9CBA99689328E35F8F83F0922A9F0AB33E7C7892E940377CE0064700ECDCC8532F0FEF888913E1894054707878511DD84455BEACCA35E8418D6CAD03111BC1842581D40E280A13055030CB35339E2A0E422DB9EC47916AD6302BE248AD5EBCCE7CF087CB2285A6B8D227DC7130ADB14163BE4D1AA779DBCD36710AA080F219B535B1887392DE9EF44116C933F5CA2234A7A82A8A48F1691A39434D70E3C3995AEE7CEAFF86DAA2326CF367B7E3C7939E4B78A00EE58E52F7BB36C8A89525CA4D44173E30AA6B40FD0B60C29F6CBC763241AC5DA16E2A9FB9B78F360EED32704B686AD6D40DAE8127C9351A2B21C140292E77592A7159000FB2AA9561DA10B2AC3167CC8E41C10CDF86E9041A3A114F42EF4AA5134C716893E81C3A7488ED5131073FC76B20358549BF1B0858B571550663DA9CF73B7B28BF9CA1FAF8EC96966D493C174B03DBCF9B5470DD9A79FB3E14A0B73B6E6C09D531886ACF60E51B5708890F47
-20180403080212 2 6 100 3071 2 FF8DCF143A9E3CC447F8D3D03206E386572BFAC54F4BDE233C8B1223CC9CBA99689328E35F8F83F0922A9F0AB33E7C7892E940377CE0064700ECDCC8532F0FEF888913E1894054707878511DD84455BEACCA35E8418D6CAD03111BC1842581D40E280A13055030CB35339E2A0E422DB9EC47916AD6302BE248AD5EBCCE7CF087CB2285A6B8D227DC7130ADB14163BE4D1AA779DBCD36710AA080F219B535B1887392DE9EF44116C933F5CA2234A7A82A8A48F1691A39434D70E3C3995AEE7CEAFF86DAA2326CF367B7E3C7939E4B78A00EE58E52F7BB36C8A89525CA4D44173E30AA6B40FD0B60C29F6CBC763241AC5DA16E2A9FB9B78F360EED32704B686AD6D40DAE8127C9351A2B21C140292E77592A7159000FB2AA9561DA10B2AC3167CC8E41C10CDF86E9041A3A114F42EF4AA5134C716893E81C3A7488ED5131073FC76B20358549BF1B0858B571550663DA9CF73B7B28BF9CA1FAF8EC96966D493C174B03DBCF9B5470DD9A79FB3E14A0B73B6E6C09D531886ACF60E51B570898D8B3
-20180403080523 2 6 100 3071 2 FF8DCF143A9E3CC447F8D3D03206E386572BFAC54F4BDE233C8B1223CC9CBA99689328E35F8F83F0922A9F0AB33E7C7892E940377CE0064700ECDCC8532F0FEF888913E1894054707878511DD84455BEACCA35E8418D6CAD03111BC1842581D40E280A13055030CB35339E2A0E422DB9EC47916AD6302BE248AD5EBCCE7CF087CB2285A6B8D227DC7130ADB14163BE4D1AA779DBCD36710AA080F219B535B1887392DE9EF44116C933F5CA2234A7A82A8A48F1691A39434D70E3C3995AEE7CEAFF86DAA2326CF367B7E3C7939E4B78A00EE58E52F7BB36C8A89525CA4D44173E30AA6B40FD0B60C29F6CBC763241AC5DA16E2A9FB9B78F360EED32704B686AD6D40DAE8127C9351A2B21C140292E77592A7159000FB2AA9561DA10B2AC3167CC8E41C10CDF86E9041A3A114F42EF4AA5134C716893E81C3A7488ED5131073FC76B20358549BF1B0858B571550663DA9CF73B7B28BF9CA1FAF8EC96966D493C174B03DBCF9B5470DD9A79FB3E14A0B73B6E6C09D531886ACF60E51B5708C1E14B
-20180403080854 2 6 100 3071 5 FF8DCF143A9E3CC447F8D3D03206E386572BFAC54F4BDE233C8B1223CC9CBA99689328E35F8F83F0922A9F0AB33E7C7892E940377CE0064700ECDCC8532F0FEF888913E1894054707878511DD84455BEACCA35E8418D6CAD03111BC1842581D40E280A13055030CB35339E2A0E422DB9EC47916AD6302BE248AD5EBCCE7CF087CB2285A6B8D227DC7130ADB14163BE4D1AA779DBCD36710AA080F219B535B1887392DE9EF44116C933F5CA2234A7A82A8A48F1691A39434D70E3C3995AEE7CEAFF86DAA2326CF367B7E3C7939E4B78A00EE58E52F7BB36C8A89525CA4D44173E30AA6B40FD0B60C29F6CBC763241AC5DA16E2A9FB9B78F360EED32704B686AD6D40DAE8127C9351A2B21C140292E77592A7159000FB2AA9561DA10B2AC3167CC8E41C10CDF86E9041A3A114F42EF4AA5134C716893E81C3A7488ED5131073FC76B20358549BF1B0858B571550663DA9CF73B7B28BF9CA1FAF8EC96966D493C174B03DBCF9B5470DD9A79FB3E14A0B73B6E6C09D531886ACF60E51B5708EEE0AF
-20180403081003 2 6 100 3071 5 FF8DCF143A9E3CC447F8D3D03206E386572BFAC54F4BDE233C8B1223CC9CBA99689328E35F8F83F0922A9F0AB33E7C7892E940377CE0064700ECDCC8532F0FEF888913E1894054707878511DD84455BEACCA35E8418D6CAD03111BC1842581D40E280A13055030CB35339E2A0E422DB9EC47916AD6302BE248AD5EBCCE7CF087CB2285A6B8D227DC7130ADB14163BE4D1AA779DBCD36710AA080F219B535B1887392DE9EF44116C933F5CA2234A7A82A8A48F1691A39434D70E3C3995AEE7CEAFF86DAA2326CF367B7E3C7939E4B78A00EE58E52F7BB36C8A89525CA4D44173E30AA6B40FD0B60C29F6CBC763241AC5DA16E2A9FB9B78F360EED32704B686AD6D40DAE8127C9351A2B21C140292E77592A7159000FB2AA9561DA10B2AC3167CC8E41C10CDF86E9041A3A114F42EF4AA5134C716893E81C3A7488ED5131073FC76B20358549BF1B0858B571550663DA9CF73B7B28BF9CA1FAF8EC96966D493C174B03DBCF9B5470DD9A79FB3E14A0B73B6E6C09D531886ACF60E51B5708F7F537
-20180403081710 2 6 100 3071 2 FF8DCF143A9E3CC447F8D3D03206E386572BFAC54F4BDE233C8B1223CC9CBA99689328E35F8F83F0922A9F0AB33E7C7892E940377CE0064700ECDCC8532F0FEF888913E1894054707878511DD84455BEACCA35E8418D6CAD03111BC1842581D40E280A13055030CB35339E2A0E422DB9EC47916AD6302BE248AD5EBCCE7CF087CB2285A6B8D227DC7130ADB14163BE4D1AA779DBCD36710AA080F219B535B1887392DE9EF44116C933F5CA2234A7A82A8A48F1691A39434D70E3C3995AEE7CEAFF86DAA2326CF367B7E3C7939E4B78A00EE58E52F7BB36C8A89525CA4D44173E30AA6B40FD0B60C29F6CBC763241AC5DA16E2A9FB9B78F360EED32704B686AD6D40DAE8127C9351A2B21C140292E77592A7159000FB2AA9561DA10B2AC3167CC8E41C10CDF86E9041A3A114F42EF4AA5134C716893E81C3A7488ED5131073FC76B20358549BF1B0858B571550663DA9CF73B7B28BF9CA1FAF8EC96966D493C174B03DBCF9B5470DD9A79FB3E14A0B73B6E6C09D531886ACF60E51B570961D7DB
-20180403082007 2 6 100 3071 2 FF8DCF143A9E3CC447F8D3D03206E386572BFAC54F4BDE233C8B1223CC9CBA99689328E35F8F83F0922A9F0AB33E7C7892E940377CE0064700ECDCC8532F0FEF888913E1894054707878511DD84455BEACCA35E8418D6CAD03111BC1842581D40E280A13055030CB35339E2A0E422DB9EC47916AD6302BE248AD5EBCCE7CF087CB2285A6B8D227DC7130ADB14163BE4D1AA779DBCD36710AA080F219B535B1887392DE9EF44116C933F5CA2234A7A82A8A48F1691A39434D70E3C3995AEE7CEAFF86DAA2326CF367B7E3C7939E4B78A00EE58E52F7BB36C8A89525CA4D44173E30AA6B40FD0B60C29F6CBC763241AC5DA16E2A9FB9B78F360EED32704B686AD6D40DAE8127C9351A2B21C140292E77592A7159000FB2AA9561DA10B2AC3167CC8E41C10CDF86E9041A3A114F42EF4AA5134C716893E81C3A7488ED5131073FC76B20358549BF1B0858B571550663DA9CF73B7B28BF9CA1FAF8EC96966D493C174B03DBCF9B5470DD9A79FB3E14A0B73B6E6C09D531886ACF60E51B570988E91B
-20180403082804 2 6 100 3071 2 FF8DCF143A9E3CC447F8D3D03206E386572BFAC54F4BDE233C8B1223CC9CBA99689328E35F8F83F0922A9F0AB33E7C7892E940377CE0064700ECDCC8532F0FEF888913E1894054707878511DD84455BEACCA35E8418D6CAD03111BC1842581D40E280A13055030CB35339E2A0E422DB9EC47916AD6302BE248AD5EBCCE7CF087CB2285A6B8D227DC7130ADB14163BE4D1AA779DBCD36710AA080F219B535B1887392DE9EF44116C933F5CA2234A7A82A8A48F1691A39434D70E3C3995AEE7CEAFF86DAA2326CF367B7E3C7939E4B78A00EE58E52F7BB36C8A89525CA4D44173E30AA6B40FD0B60C29F6CBC763241AC5DA16E2A9FB9B78F360EED32704B686AD6D40DAE8127C9351A2B21C140292E77592A7159000FB2AA9561DA10B2AC3167CC8E41C10CDF86E9041A3A114F42EF4AA5134C716893E81C3A7488ED5131073FC76B20358549BF1B0858B571550663DA9CF73B7B28BF9CA1FAF8EC96966D493C174B03DBCF9B5470DD9A79FB3E14A0B73B6E6C09D531886ACF60E51B570A02958B
-20180403084609 2 6 100 3071 5 FF8DCF143A9E3CC447F8D3D03206E386572BFAC54F4BDE233C8B1223CC9CBA99689328E35F8F83F0922A9F0AB33E7C7892E940377CE0064700ECDCC8532F0FEF888913E1894054707878511DD84455BEACCA35E8418D6CAD03111BC1842581D40E280A13055030CB35339E2A0E422DB9EC47916AD6302BE248AD5EBCCE7CF087CB2285A6B8D227DC7130ADB14163BE4D1AA779DBCD36710AA080F219B535B1887392DE9EF44116C933F5CA2234A7A82A8A48F1691A39434D70E3C3995AEE7CEAFF86DAA2326CF367B7E3C7939E4B78A00EE58E52F7BB36C8A89525CA4D44173E30AA6B40FD0B60C29F6CBC763241AC5DA16E2A9FB9B78F360EED32704B686AD6D40DAE8127C9351A2B21C140292E77592A7159000FB2AA9561DA10B2AC3167CC8E41C10CDF86E9041A3A114F42EF4AA5134C716893E81C3A7488ED5131073FC76B20358549BF1B0858B571550663DA9CF73B7B28BF9CA1FAF8EC96966D493C174B03DBCF9B5470DD9A79FB3E14A0B73B6E6C09D531886ACF60E51B570B1FC24F
-20180403084705 2 6 100 3071 2 FF8DCF143A9E3CC447F8D3D03206E386572BFAC54F4BDE233C8B1223CC9CBA99689328E35F8F83F0922A9F0AB33E7C7892E940377CE0064700ECDCC8532F0FEF888913E1894054707878511DD84455BEACCA35E8418D6CAD03111BC1842581D40E280A13055030CB35339E2A0E422DB9EC47916AD6302BE248AD5EBCCE7CF087CB2285A6B8D227DC7130ADB14163BE4D1AA779DBCD36710AA080F219B535B1887392DE9EF44116C933F5CA2234A7A82A8A48F1691A39434D70E3C3995AEE7CEAFF86DAA2326CF367B7E3C7939E4B78A00EE58E52F7BB36C8A89525CA4D44173E30AA6B40FD0B60C29F6CBC763241AC5DA16E2A9FB9B78F360EED32704B686AD6D40DAE8127C9351A2B21C140292E77592A7159000FB2AA9561DA10B2AC3167CC8E41C10CDF86E9041A3A114F42EF4AA5134C716893E81C3A7488ED5131073FC76B20358549BF1B0858B571550663DA9CF73B7B28BF9CA1FAF8EC96966D493C174B03DBCF9B5470DD9A79FB3E14A0B73B6E6C09D531886ACF60E51B570B262033
-20180403084905 2 6 100 3071 2 FF8DCF143A9E3CC447F8D3D03206E386572BFAC54F4BDE233C8B1223CC9CBA99689328E35F8F83F0922A9F0AB33E7C7892E940377CE0064700ECDCC8532F0FEF888913E1894054707878511DD84455BEACCA35E8418D6CAD03111BC1842581D40E280A13055030CB35339E2A0E422DB9EC47916AD6302BE248AD5EBCCE7CF087CB2285A6B8D227DC7130ADB14163BE4D1AA779DBCD36710AA080F219B535B1887392DE9EF44116C933F5CA2234A7A82A8A48F1691A39434D70E3C3995AEE7CEAFF86DAA2326CF367B7E3C7939E4B78A00EE58E52F7BB36C8A89525CA4D44173E30AA6B40FD0B60C29F6CBC763241AC5DA16E2A9FB9B78F360EED32704B686AD6D40DAE8127C9351A2B21C140292E77592A7159000FB2AA9561DA10B2AC3167CC8E41C10CDF86E9041A3A114F42EF4AA5134C716893E81C3A7488ED5131073FC76B20358549BF1B0858B571550663DA9CF73B7B28BF9CA1FAF8EC96966D493C174B03DBCF9B5470DD9A79FB3E14A0B73B6E6C09D531886ACF60E51B570B3DD5AB
-20180403085348 2 6 100 3071 2 FF8DCF143A9E3CC447F8D3D03206E386572BFAC54F4BDE233C8B1223CC9CBA99689328E35F8F83F0922A9F0AB33E7C7892E940377CE0064700ECDCC8532F0FEF888913E1894054707878511DD84455BEACCA35E8418D6CAD03111BC1842581D40E280A13055030CB35339E2A0E422DB9EC47916AD6302BE248AD5EBCCE7CF087CB2285A6B8D227DC7130ADB14163BE4D1AA779DBCD36710AA080F219B535B1887392DE9EF44116C933F5CA2234A7A82A8A48F1691A39434D70E3C3995AEE7CEAFF86DAA2326CF367B7E3C7939E4B78A00EE58E52F7BB36C8A89525CA4D44173E30AA6B40FD0B60C29F6CBC763241AC5DA16E2A9FB9B78F360EED32704B686AD6D40DAE8127C9351A2B21C140292E77592A7159000FB2AA9561DA10B2AC3167CC8E41C10CDF86E9041A3A114F42EF4AA5134C716893E81C3A7488ED5131073FC76B20358549BF1B0858B571550663DA9CF73B7B28BF9CA1FAF8EC96966D493C174B03DBCF9B5470DD9A79FB3E14A0B73B6E6C09D531886ACF60E51B570B82B95B
-20180403090858 2 6 100 3071 5 FF8DCF143A9E3CC447F8D3D03206E386572BFAC54F4BDE233C8B1223CC9CBA99689328E35F8F83F0922A9F0AB33E7C7892E940377CE0064700ECDCC8532F0FEF888913E1894054707878511DD84455BEACCA35E8418D6CAD03111BC1842581D40E280A13055030CB35339E2A0E422DB9EC47916AD6302BE248AD5EBCCE7CF087CB2285A6B8D227DC7130ADB14163BE4D1AA779DBCD36710AA080F219B535B1887392DE9EF44116C933F5CA2234A7A82A8A48F1691A39434D70E3C3995AEE7CEAFF86DAA2326CF367B7E3C7939E4B78A00EE58E52F7BB36C8A89525CA4D44173E30AA6B40FD0B60C29F6CBC763241AC5DA16E2A9FB9B78F360EED32704B686AD6D40DAE8127C9351A2B21C140292E77592A7159000FB2AA9561DA10B2AC3167CC8E41C10CDF86E9041A3A114F42EF4AA5134C716893E81C3A7488ED5131073FC76B20358549BF1B0858B571550663DA9CF73B7B28BF9CA1FAF8EC96966D493C174B03DBCF9B5470DD9A79FB3E14A0B73B6E6C09D531886ACF60E51B570C6C2E5F
-20180403091014 2 6 100 3071 2 FF8DCF143A9E3CC447F8D3D03206E386572BFAC54F4BDE233C8B1223CC9CBA99689328E35F8F83F0922A9F0AB33E7C7892E940377CE0064700ECDCC8532F0FEF888913E1894054707878511DD84455BEACCA35E8418D6CAD03111BC1842581D40E280A13055030CB35339E2A0E422DB9EC47916AD6302BE248AD5EBCCE7CF087CB2285A6B8D227DC7130ADB14163BE4D1AA779DBCD36710AA080F219B535B1887392DE9EF44116C933F5CA2234A7A82A8A48F1691A39434D70E3C3995AEE7CEAFF86DAA2326CF367B7E3C7939E4B78A00EE58E52F7BB36C8A89525CA4D44173E30AA6B40FD0B60C29F6CBC763241AC5DA16E2A9FB9B78F360EED32704B686AD6D40DAE8127C9351A2B21C140292E77592A7159000FB2AA9561DA10B2AC3167CC8E41C10CDF86E9041A3A114F42EF4AA5134C716893E81C3A7488ED5131073FC76B20358549BF1B0858B571550663DA9CF73B7B28BF9CA1FAF8EC96966D493C174B03DBCF9B5470DD9A79FB3E14A0B73B6E6C09D531886ACF60E51B570C766563
-20180403092356 2 6 100 3071 5 FF8DCF143A9E3CC447F8D3D03206E386572BFAC54F4BDE233C8B1223CC9CBA99689328E35F8F83F0922A9F0AB33E7C7892E940377CE0064700ECDCC8532F0FEF888913E1894054707878511DD84455BEACCA35E8418D6CAD03111BC1842581D40E280A13055030CB35339E2A0E422DB9EC47916AD6302BE248AD5EBCCE7CF087CB2285A6B8D227DC7130ADB14163BE4D1AA779DBCD36710AA080F219B535B1887392DE9EF44116C933F5CA2234A7A82A8A48F1691A39434D70E3C3995AEE7CEAFF86DAA2326CF367B7E3C7939E4B78A00EE58E52F7BB36C8A89525CA4D44173E30AA6B40FD0B60C29F6CBC763241AC5DA16E2A9FB9B78F360EED32704B686AD6D40DAE8127C9351A2B21C140292E77592A7159000FB2AA9561DA10B2AC3167CC8E41C10CDF86E9041A3A114F42EF4AA5134C716893E81C3A7488ED5131073FC76B20358549BF1B0858B571550663DA9CF73B7B28BF9CA1FAF8EC96966D493C174B03DBCF9B5470DD9A79FB3E14A0B73B6E6C09D531886ACF60E51B570D49B077
-20180403092842 2 6 100 3071 2 FF8DCF143A9E3CC447F8D3D03206E386572BFAC54F4BDE233C8B1223CC9CBA99689328E35F8F83F0922A9F0AB33E7C7892E940377CE0064700ECDCC8532F0FEF888913E1894054707878511DD84455BEACCA35E8418D6CAD03111BC1842581D40E280A13055030CB35339E2A0E422DB9EC47916AD6302BE248AD5EBCCE7CF087CB2285A6B8D227DC7130ADB14163BE4D1AA779DBCD36710AA080F219B535B1887392DE9EF44116C933F5CA2234A7A82A8A48F1691A39434D70E3C3995AEE7CEAFF86DAA2326CF367B7E3C7939E4B78A00EE58E52F7BB36C8A89525CA4D44173E30AA6B40FD0B60C29F6CBC763241AC5DA16E2A9FB9B78F360EED32704B686AD6D40DAE8127C9351A2B21C140292E77592A7159000FB2AA9561DA10B2AC3167CC8E41C10CDF86E9041A3A114F42EF4AA5134C716893E81C3A7488ED5131073FC76B20358549BF1B0858B571550663DA9CF73B7B28BF9CA1FAF8EC96966D493C174B03DBCF9B5470DD9A79FB3E14A0B73B6E6C09D531886ACF60E51B570D8D7FEB
-20180403093424 2 6 100 3071 5 FF8DCF143A9E3CC447F8D3D03206E386572BFAC54F4BDE233C8B1223CC9CBA99689328E35F8F83F0922A9F0AB33E7C7892E940377CE0064700ECDCC8532F0FEF888913E1894054707878511DD84455BEACCA35E8418D6CAD03111BC1842581D40E280A13055030CB35339E2A0E422DB9EC47916AD6302BE248AD5EBCCE7CF087CB2285A6B8D227DC7130ADB14163BE4D1AA779DBCD36710AA080F219B535B1887392DE9EF44116C933F5CA2234A7A82A8A48F1691A39434D70E3C3995AEE7CEAFF86DAA2326CF367B7E3C7939E4B78A00EE58E52F7BB36C8A89525CA4D44173E30AA6B40FD0B60C29F6CBC763241AC5DA16E2A9FB9B78F360EED32704B686AD6D40DAE8127C9351A2B21C140292E77592A7159000FB2AA9561DA10B2AC3167CC8E41C10CDF86E9041A3A114F42EF4AA5134C716893E81C3A7488ED5131073FC76B20358549BF1B0858B571550663DA9CF73B7B28BF9CA1FAF8EC96966D493C174B03DBCF9B5470DD9A79FB3E14A0B73B6E6C09D531886ACF60E51B570DE274D7
-20180403093850 2 6 100 3071 2 FF8DCF143A9E3CC447F8D3D03206E386572BFAC54F4BDE233C8B1223CC9CBA99689328E35F8F83F0922A9F0AB33E7C7892E940377CE0064700ECDCC8532F0FEF888913E1894054707878511DD84455BEACCA35E8418D6CAD03111BC1842581D40E280A13055030CB35339E2A0E422DB9EC47916AD6302BE248AD5EBCCE7CF087CB2285A6B8D227DC7130ADB14163BE4D1AA779DBCD36710AA080F219B535B1887392DE9EF44116C933F5CA2234A7A82A8A48F1691A39434D70E3C3995AEE7CEAFF86DAA2326CF367B7E3C7939E4B78A00EE58E52F7BB36C8A89525CA4D44173E30AA6B40FD0B60C29F6CBC763241AC5DA16E2A9FB9B78F360EED32704B686AD6D40DAE8127C9351A2B21C140292E77592A7159000FB2AA9561DA10B2AC3167CC8E41C10CDF86E9041A3A114F42EF4AA5134C716893E81C3A7488ED5131073FC76B20358549BF1B0858B571550663DA9CF73B7B28BF9CA1FAF8EC96966D493C174B03DBCF9B5470DD9A79FB3E14A0B73B6E6C09D531886ACF60E51B570E28C2BB
-20180403094634 2 6 100 3071 5 FF8DCF143A9E3CC447F8D3D03206E386572BFAC54F4BDE233C8B1223CC9CBA99689328E35F8F83F0922A9F0AB33E7C7892E940377CE0064700ECDCC8532F0FEF888913E1894054707878511DD84455BEACCA35E8418D6CAD03111BC1842581D40E280A13055030CB35339E2A0E422DB9EC47916AD6302BE248AD5EBCCE7CF087CB2285A6B8D227DC7130ADB14163BE4D1AA779DBCD36710AA080F219B535B1887392DE9EF44116C933F5CA2234A7A82A8A48F1691A39434D70E3C3995AEE7CEAFF86DAA2326CF367B7E3C7939E4B78A00EE58E52F7BB36C8A89525CA4D44173E30AA6B40FD0B60C29F6CBC763241AC5DA16E2A9FB9B78F360EED32704B686AD6D40DAE8127C9351A2B21C140292E77592A7159000FB2AA9561DA10B2AC3167CC8E41C10CDF86E9041A3A114F42EF4AA5134C716893E81C3A7488ED5131073FC76B20358549BF1B0858B571550663DA9CF73B7B28BF9CA1FAF8EC96966D493C174B03DBCF9B5470DD9A79FB3E14A0B73B6E6C09D531886ACF60E51B570EA36EDF
-20180403094738 2 6 100 3071 2 FF8DCF143A9E3CC447F8D3D03206E386572BFAC54F4BDE233C8B1223CC9CBA99689328E35F8F83F0922A9F0AB33E7C7892E940377CE0064700ECDCC8532F0FEF888913E1894054707878511DD84455BEACCA35E8418D6CAD03111BC1842581D40E280A13055030CB35339E2A0E422DB9EC47916AD6302BE248AD5EBCCE7CF087CB2285A6B8D227DC7130ADB14163BE4D1AA779DBCD36710AA080F219B535B1887392DE9EF44116C933F5CA2234A7A82A8A48F1691A39434D70E3C3995AEE7CEAFF86DAA2326CF367B7E3C7939E4B78A00EE58E52F7BB36C8A89525CA4D44173E30AA6B40FD0B60C29F6CBC763241AC5DA16E2A9FB9B78F360EED32704B686AD6D40DAE8127C9351A2B21C140292E77592A7159000FB2AA9561DA10B2AC3167CC8E41C10CDF86E9041A3A114F42EF4AA5134C716893E81C3A7488ED5131073FC76B20358549BF1B0858B571550663DA9CF73B7B28BF9CA1FAF8EC96966D493C174B03DBCF9B5470DD9A79FB3E14A0B73B6E6C09D531886ACF60E51B570EACDABB
-20180403095906 2 6 100 3071 2 FF8DCF143A9E3CC447F8D3D03206E386572BFAC54F4BDE233C8B1223CC9CBA99689328E35F8F83F0922A9F0AB33E7C7892E940377CE0064700ECDCC8532F0FEF888913E1894054707878511DD84455BEACCA35E8418D6CAD03111BC1842581D40E280A13055030CB35339E2A0E422DB9EC47916AD6302BE248AD5EBCCE7CF087CB2285A6B8D227DC7130ADB14163BE4D1AA779DBCD36710AA080F219B535B1887392DE9EF44116C933F5CA2234A7A82A8A48F1691A39434D70E3C3995AEE7CEAFF86DAA2326CF367B7E3C7939E4B78A00EE58E52F7BB36C8A89525CA4D44173E30AA6B40FD0B60C29F6CBC763241AC5DA16E2A9FB9B78F360EED32704B686AD6D40DAE8127C9351A2B21C140292E77592A7159000FB2AA9561DA10B2AC3167CC8E41C10CDF86E9041A3A114F42EF4AA5134C716893E81C3A7488ED5131073FC76B20358549BF1B0858B571550663DA9CF73B7B28BF9CA1FAF8EC96966D493C174B03DBCF9B5470DD9A79FB3E14A0B73B6E6C09D531886ACF60E51B570F67B813
-20180403101909 2 6 100 3071 5 FF8DCF143A9E3CC447F8D3D03206E386572BFAC54F4BDE233C8B1223CC9CBA99689328E35F8F83F0922A9F0AB33E7C7892E940377CE0064700ECDCC8532F0FEF888913E1894054707878511DD84455BEACCA35E8418D6CAD03111BC1842581D40E280A13055030CB35339E2A0E422DB9EC47916AD6302BE248AD5EBCCE7CF087CB2285A6B8D227DC7130ADB14163BE4D1AA779DBCD36710AA080F219B535B1887392DE9EF44116C933F5CA2234A7A82A8A48F1691A39434D70E3C3995AEE7CEAFF86DAA2326CF367B7E3C7939E4B78A00EE58E52F7BB36C8A89525CA4D44173E30AA6B40FD0B60C29F6CBC763241AC5DA16E2A9FB9B78F360EED32704B686AD6D40DAE8127C9351A2B21C140292E77592A7159000FB2AA9561DA10B2AC3167CC8E41C10CDF86E9041A3A114F42EF4AA5134C716893E81C3A7488ED5131073FC76B20358549BF1B0858B571550663DA9CF73B7B28BF9CA1FAF8EC96966D493C174B03DBCF9B5470DD9A79FB3E14A0B73B6E6C09D531886ACF60E51B5710AFC157
-20180403102057 2 6 100 3071 2 FF8DCF143A9E3CC447F8D3D03206E386572BFAC54F4BDE233C8B1223CC9CBA99689328E35F8F83F0922A9F0AB33E7C7892E940377CE0064700ECDCC8532F0FEF888913E1894054707878511DD84455BEACCA35E8418D6CAD03111BC1842581D40E280A13055030CB35339E2A0E422DB9EC47916AD6302BE248AD5EBCCE7CF087CB2285A6B8D227DC7130ADB14163BE4D1AA779DBCD36710AA080F219B535B1887392DE9EF44116C933F5CA2234A7A82A8A48F1691A39434D70E3C3995AEE7CEAFF86DAA2326CF367B7E3C7939E4B78A00EE58E52F7BB36C8A89525CA4D44173E30AA6B40FD0B60C29F6CBC763241AC5DA16E2A9FB9B78F360EED32704B686AD6D40DAE8127C9351A2B21C140292E77592A7159000FB2AA9561DA10B2AC3167CC8E41C10CDF86E9041A3A114F42EF4AA5134C716893E81C3A7488ED5131073FC76B20358549BF1B0858B571550663DA9CF73B7B28BF9CA1FAF8EC96966D493C174B03DBCF9B5470DD9A79FB3E14A0B73B6E6C09D531886ACF60E51B5710C6E1FB
-20180403102257 2 6 100 3071 5 FF8DCF143A9E3CC447F8D3D03206E386572BFAC54F4BDE233C8B1223CC9CBA99689328E35F8F83F0922A9F0AB33E7C7892E940377CE0064700ECDCC8532F0FEF888913E1894054707878511DD84455BEACCA35E8418D6CAD03111BC1842581D40E280A13055030CB35339E2A0E422DB9EC47916AD6302BE248AD5EBCCE7CF087CB2285A6B8D227DC7130ADB14163BE4D1AA779DBCD36710AA080F219B535B1887392DE9EF44116C933F5CA2234A7A82A8A48F1691A39434D70E3C3995AEE7CEAFF86DAA2326CF367B7E3C7939E4B78A00EE58E52F7BB36C8A89525CA4D44173E30AA6B40FD0B60C29F6CBC763241AC5DA16E2A9FB9B78F360EED32704B686AD6D40DAE8127C9351A2B21C140292E77592A7159000FB2AA9561DA10B2AC3167CC8E41C10CDF86E9041A3A114F42EF4AA5134C716893E81C3A7488ED5131073FC76B20358549BF1B0858B571550663DA9CF73B7B28BF9CA1FAF8EC96966D493C174B03DBCF9B5470DD9A79FB3E14A0B73B6E6C09D531886ACF60E51B5710DF2FD7
-20180403102711 2 6 100 3071 5 FF8DCF143A9E3CC447F8D3D03206E386572BFAC54F4BDE233C8B1223CC9CBA99689328E35F8F83F0922A9F0AB33E7C7892E940377CE0064700ECDCC8532F0FEF888913E1894054707878511DD84455BEACCA35E8418D6CAD03111BC1842581D40E280A13055030CB35339E2A0E422DB9EC47916AD6302BE248AD5EBCCE7CF087CB2285A6B8D227DC7130ADB14163BE4D1AA779DBCD36710AA080F219B535B1887392DE9EF44116C933F5CA2234A7A82A8A48F1691A39434D70E3C3995AEE7CEAFF86DAA2326CF367B7E3C7939E4B78A00EE58E52F7BB36C8A89525CA4D44173E30AA6B40FD0B60C29F6CBC763241AC5DA16E2A9FB9B78F360EED32704B686AD6D40DAE8127C9351A2B21C140292E77592A7159000FB2AA9561DA10B2AC3167CC8E41C10CDF86E9041A3A114F42EF4AA5134C716893E81C3A7488ED5131073FC76B20358549BF1B0858B571550663DA9CF73B7B28BF9CA1FAF8EC96966D493C174B03DBCF9B5470DD9A79FB3E14A0B73B6E6C09D531886ACF60E51B57111EFB2F
-20180403104106 2 6 100 3071 5 FF8DCF143A9E3CC447F8D3D03206E386572BFAC54F4BDE233C8B1223CC9CBA99689328E35F8F83F0922A9F0AB33E7C7892E940377CE0064700ECDCC8532F0FEF888913E1894054707878511DD84455BEACCA35E8418D6CAD03111BC1842581D40E280A13055030CB35339E2A0E422DB9EC47916AD6302BE248AD5EBCCE7CF087CB2285A6B8D227DC7130ADB14163BE4D1AA779DBCD36710AA080F219B535B1887392DE9EF44116C933F5CA2234A7A82A8A48F1691A39434D70E3C3995AEE7CEAFF86DAA2326CF367B7E3C7939E4B78A00EE58E52F7BB36C8A89525CA4D44173E30AA6B40FD0B60C29F6CBC763241AC5DA16E2A9FB9B78F360EED32704B686AD6D40DAE8127C9351A2B21C140292E77592A7159000FB2AA9561DA10B2AC3167CC8E41C10CDF86E9041A3A114F42EF4AA5134C716893E81C3A7488ED5131073FC76B20358549BF1B0858B571550663DA9CF73B7B28BF9CA1FAF8EC96966D493C174B03DBCF9B5470DD9A79FB3E14A0B73B6E6C09D531886ACF60E51B5711F3B14F
-20180403104411 2 6 100 3071 5 FF8DCF143A9E3CC447F8D3D03206E386572BFAC54F4BDE233C8B1223CC9CBA99689328E35F8F83F0922A9F0AB33E7C7892E940377CE0064700ECDCC8532F0FEF888913E1894054707878511DD84455BEACCA35E8418D6CAD03111BC1842581D40E280A13055030CB35339E2A0E422DB9EC47916AD6302BE248AD5EBCCE7CF087CB2285A6B8D227DC7130ADB14163BE4D1AA779DBCD36710AA080F219B535B1887392DE9EF44116C933F5CA2234A7A82A8A48F1691A39434D70E3C3995AEE7CEAFF86DAA2326CF367B7E3C7939E4B78A00EE58E52F7BB36C8A89525CA4D44173E30AA6B40FD0B60C29F6CBC763241AC5DA16E2A9FB9B78F360EED32704B686AD6D40DAE8127C9351A2B21C140292E77592A7159000FB2AA9561DA10B2AC3167CC8E41C10CDF86E9041A3A114F42EF4AA5134C716893E81C3A7488ED5131073FC76B20358549BF1B0858B571550663DA9CF73B7B28BF9CA1FAF8EC96966D493C174B03DBCF9B5470DD9A79FB3E14A0B73B6E6C09D531886ACF60E51B5712188817
-20180403104503 2 6 100 3071 5 FF8DCF143A9E3CC447F8D3D03206E386572BFAC54F4BDE233C8B1223CC9CBA99689328E35F8F83F0922A9F0AB33E7C7892E940377CE0064700ECDCC8532F0FEF888913E1894054707878511DD84455BEACCA35E8418D6CAD03111BC1842581D40E280A13055030CB35339E2A0E422DB9EC47916AD6302BE248AD5EBCCE7CF087CB2285A6B8D227DC7130ADB14163BE4D1AA779DBCD36710AA080F219B535B1887392DE9EF44116C933F5CA2234A7A82A8A48F1691A39434D70E3C3995AEE7CEAFF86DAA2326CF367B7E3C7939E4B78A00EE58E52F7BB36C8A89525CA4D44173E30AA6B40FD0B60C29F6CBC763241AC5DA16E2A9FB9B78F360EED32704B686AD6D40DAE8127C9351A2B21C140292E77592A7159000FB2AA9561DA10B2AC3167CC8E41C10CDF86E9041A3A114F42EF4AA5134C716893E81C3A7488ED5131073FC76B20358549BF1B0858B571550663DA9CF73B7B28BF9CA1FAF8EC96966D493C174B03DBCF9B5470DD9A79FB3E14A0B73B6E6C09D531886ACF60E51B57121EA02F
-20180403104712 2 6 100 3071 2 FF8DCF143A9E3CC447F8D3D03206E386572BFAC54F4BDE233C8B1223CC9CBA99689328E35F8F83F0922A9F0AB33E7C7892E940377CE0064700ECDCC8532F0FEF888913E1894054707878511DD84455BEACCA35E8418D6CAD03111BC1842581D40E280A13055030CB35339E2A0E422DB9EC47916AD6302BE248AD5EBCCE7CF087CB2285A6B8D227DC7130ADB14163BE4D1AA779DBCD36710AA080F219B535B1887392DE9EF44116C933F5CA2234A7A82A8A48F1691A39434D70E3C3995AEE7CEAFF86DAA2326CF367B7E3C7939E4B78A00EE58E52F7BB36C8A89525CA4D44173E30AA6B40FD0B60C29F6CBC763241AC5DA16E2A9FB9B78F360EED32704B686AD6D40DAE8127C9351A2B21C140292E77592A7159000FB2AA9561DA10B2AC3167CC8E41C10CDF86E9041A3A114F42EF4AA5134C716893E81C3A7488ED5131073FC76B20358549BF1B0858B571550663DA9CF73B7B28BF9CA1FAF8EC96966D493C174B03DBCF9B5470DD9A79FB3E14A0B73B6E6C09D531886ACF60E51B57123CDA13
-20180403104901 2 6 100 3071 2 FF8DCF143A9E3CC447F8D3D03206E386572BFAC54F4BDE233C8B1223CC9CBA99689328E35F8F83F0922A9F0AB33E7C7892E940377CE0064700ECDCC8532F0FEF888913E1894054707878511DD84455BEACCA35E8418D6CAD03111BC1842581D40E280A13055030CB35339E2A0E422DB9EC47916AD6302BE248AD5EBCCE7CF087CB2285A6B8D227DC7130ADB14163BE4D1AA779DBCD36710AA080F219B535B1887392DE9EF44116C933F5CA2234A7A82A8A48F1691A39434D70E3C3995AEE7CEAFF86DAA2326CF367B7E3C7939E4B78A00EE58E52F7BB36C8A89525CA4D44173E30AA6B40FD0B60C29F6CBC763241AC5DA16E2A9FB9B78F360EED32704B686AD6D40DAE8127C9351A2B21C140292E77592A7159000FB2AA9561DA10B2AC3167CC8E41C10CDF86E9041A3A114F42EF4AA5134C716893E81C3A7488ED5131073FC76B20358549BF1B0858B571550663DA9CF73B7B28BF9CA1FAF8EC96966D493C174B03DBCF9B5470DD9A79FB3E14A0B73B6E6C09D531886ACF60E51B57125332B3
-20180403105756 2 6 100 3071 5 D9FA0132FCCAAE8116BD22861CD21A859841BA7D566829E10ACC15A7EFEEB381774F839F7228AE3C627F5765944DCDB6866618E187903EBDB558C9186BD84D2521630A379E161FDCEC19BA02A8E4B5A3C4A66D02CA0FEB7BEB75BA3BE87F26BB99122217A4FFEB1F730B430AA0A70BA4A91EFB248DF689E95957E93B9E5D2AC13FBD3896759F77C6CBB6664BA6FEB31C4FD7BF081D4F2D800AB8D979D89A5EFB34675A904F4B332ADD7340116E7D5D4F72F7E3940A30036ACA889C27D8E2E11C0668A2E8A43DFF411FA03F0AFB420262947A60528805A7E0F4B2CC6AC0EF62CBCB807BC131A8D51E7784A13C77DB461A9FDF01C0E97EA8B7C5A13BB4A86784C2FFA34FC1EF094ACB858A919951AA55508E468CBB889EA63B606D45455AAB75883A75A813E9EC6A3A49CADB05A62C2F5CA32013A4FC73E8B5DE1C14A39539A4716B157C08C74CD99EA23AE018A89C838B6C0EAEECDFCF78A447594033ED3D63F4623BFC05C0F6701A36420D60D9C99339F9486395CBE534D66CE66AAE03762997
-20180403111214 2 6 100 3071 2 D9FA0132FCCAAE8116BD22861CD21A859841BA7D566829E10ACC15A7EFEEB381774F839F7228AE3C627F5765944DCDB6866618E187903EBDB558C9186BD84D2521630A379E161FDCEC19BA02A8E4B5A3C4A66D02CA0FEB7BEB75BA3BE87F26BB99122217A4FFEB1F730B430AA0A70BA4A91EFB248DF689E95957E93B9E5D2AC13FBD3896759F77C6CBB6664BA6FEB31C4FD7BF081D4F2D800AB8D979D89A5EFB34675A904F4B332ADD7340116E7D5D4F72F7E3940A30036ACA889C27D8E2E11C0668A2E8A43DFF411FA03F0AFB420262947A60528805A7E0F4B2CC6AC0EF62CBCB807BC131A8D51E7784A13C77DB461A9FDF01C0E97EA8B7C5A13BB4A86784C2FFA34FC1EF094ACB858A919951AA55508E468CBB889EA63B606D45455AAB75883A75A813E9EC6A3A49CADB05A62C2F5CA32013A4FC73E8B5DE1C14A39539A4716B157C08C74CD99EA23AE018A89C838B6C0EAEECDFCF78A447594033ED3D63F4623BFC05C0F6701A36420D60D9C99339F9486395CBE534D66CE66AAE0468815B
-20180403111819 2 6 100 3071 2 D9FA0132FCCAAE8116BD22861CD21A859841BA7D566829E10ACC15A7EFEEB381774F839F7228AE3C627F5765944DCDB6866618E187903EBDB558C9186BD84D2521630A379E161FDCEC19BA02A8E4B5A3C4A66D02CA0FEB7BEB75BA3BE87F26BB99122217A4FFEB1F730B430AA0A70BA4A91EFB248DF689E95957E93B9E5D2AC13FBD3896759F77C6CBB6664BA6FEB31C4FD7BF081D4F2D800AB8D979D89A5EFB34675A904F4B332ADD7340116E7D5D4F72F7E3940A30036ACA889C27D8E2E11C0668A2E8A43DFF411FA03F0AFB420262947A60528805A7E0F4B2CC6AC0EF62CBCB807BC131A8D51E7784A13C77DB461A9FDF01C0E97EA8B7C5A13BB4A86784C2FFA34FC1EF094ACB858A919951AA55508E468CBB889EA63B606D45455AAB75883A75A813E9EC6A3A49CADB05A62C2F5CA32013A4FC73E8B5DE1C14A39539A4716B157C08C74CD99EA23AE018A89C838B6C0EAEECDFCF78A447594033ED3D63F4623BFC05C0F6701A36420D60D9C99339F9486395CBE534D66CE66AAE04C53C43
-20180403111907 2 6 100 3071 5 D9FA0132FCCAAE8116BD22861CD21A859841BA7D566829E10ACC15A7EFEEB381774F839F7228AE3C627F5765944DCDB6866618E187903EBDB558C9186BD84D2521630A379E161FDCEC19BA02A8E4B5A3C4A66D02CA0FEB7BEB75BA3BE87F26BB99122217A4FFEB1F730B430AA0A70BA4A91EFB248DF689E95957E93B9E5D2AC13FBD3896759F77C6CBB6664BA6FEB31C4FD7BF081D4F2D800AB8D979D89A5EFB34675A904F4B332ADD7340116E7D5D4F72F7E3940A30036ACA889C27D8E2E11C0668A2E8A43DFF411FA03F0AFB420262947A60528805A7E0F4B2CC6AC0EF62CBCB807BC131A8D51E7784A13C77DB461A9FDF01C0E97EA8B7C5A13BB4A86784C2FFA34FC1EF094ACB858A919951AA55508E468CBB889EA63B606D45455AAB75883A75A813E9EC6A3A49CADB05A62C2F5CA32013A4FC73E8B5DE1C14A39539A4716B157C08C74CD99EA23AE018A89C838B6C0EAEECDFCF78A447594033ED3D63F4623BFC05C0F6701A36420D60D9C99339F9486395CBE534D66CE66AAE04CAC50F
-20180403112635 2 6 100 3071 5 D9FA0132FCCAAE8116BD22861CD21A859841BA7D566829E10ACC15A7EFEEB381774F839F7228AE3C627F5765944DCDB6866618E187903EBDB558C9186BD84D2521630A379E161FDCEC19BA02A8E4B5A3C4A66D02CA0FEB7BEB75BA3BE87F26BB99122217A4FFEB1F730B430AA0A70BA4A91EFB248DF689E95957E93B9E5D2AC13FBD3896759F77C6CBB6664BA6FEB31C4FD7BF081D4F2D800AB8D979D89A5EFB34675A904F4B332ADD7340116E7D5D4F72F7E3940A30036ACA889C27D8E2E11C0668A2E8A43DFF411FA03F0AFB420262947A60528805A7E0F4B2CC6AC0EF62CBCB807BC131A8D51E7784A13C77DB461A9FDF01C0E97EA8B7C5A13BB4A86784C2FFA34FC1EF094ACB858A919951AA55508E468CBB889EA63B606D45455AAB75883A75A813E9EC6A3A49CADB05A62C2F5CA32013A4FC73E8B5DE1C14A39539A4716B157C08C74CD99EA23AE018A89C838B6C0EAEECDFCF78A447594033ED3D63F4623BFC05C0F6701A36420D60D9C99339F9486395CBE534D66CE66AAE0540031F
-20180403113403 2 6 100 3071 5 D9FA0132FCCAAE8116BD22861CD21A859841BA7D566829E10ACC15A7EFEEB381774F839F7228AE3C627F5765944DCDB6866618E187903EBDB558C9186BD84D2521630A379E161FDCEC19BA02A8E4B5A3C4A66D02CA0FEB7BEB75BA3BE87F26BB99122217A4FFEB1F730B430AA0A70BA4A91EFB248DF689E95957E93B9E5D2AC13FBD3896759F77C6CBB6664BA6FEB31C4FD7BF081D4F2D800AB8D979D89A5EFB34675A904F4B332ADD7340116E7D5D4F72F7E3940A30036ACA889C27D8E2E11C0668A2E8A43DFF411FA03F0AFB420262947A60528805A7E0F4B2CC6AC0EF62CBCB807BC131A8D51E7784A13C77DB461A9FDF01C0E97EA8B7C5A13BB4A86784C2FFA34FC1EF094ACB858A919951AA55508E468CBB889EA63B606D45455AAB75883A75A813E9EC6A3A49CADB05A62C2F5CA32013A4FC73E8B5DE1C14A39539A4716B157C08C74CD99EA23AE018A89C838B6C0EAEECDFCF78A447594033ED3D63F4623BFC05C0F6701A36420D60D9C99339F9486395CBE534D66CE66AAE05B956F7
-20180403113943 2 6 100 3071 2 D9FA0132FCCAAE8116BD22861CD21A859841BA7D566829E10ACC15A7EFEEB381774F839F7228AE3C627F5765944DCDB6866618E187903EBDB558C9186BD84D2521630A379E161FDCEC19BA02A8E4B5A3C4A66D02CA0FEB7BEB75BA3BE87F26BB99122217A4FFEB1F730B430AA0A70BA4A91EFB248DF689E95957E93B9E5D2AC13FBD3896759F77C6CBB6664BA6FEB31C4FD7BF081D4F2D800AB8D979D89A5EFB34675A904F4B332ADD7340116E7D5D4F72F7E3940A30036ACA889C27D8E2E11C0668A2E8A43DFF411FA03F0AFB420262947A60528805A7E0F4B2CC6AC0EF62CBCB807BC131A8D51E7784A13C77DB461A9FDF01C0E97EA8B7C5A13BB4A86784C2FFA34FC1EF094ACB858A919951AA55508E468CBB889EA63B606D45455AAB75883A75A813E9EC6A3A49CADB05A62C2F5CA32013A4FC73E8B5DE1C14A39539A4716B157C08C74CD99EA23AE018A89C838B6C0EAEECDFCF78A447594033ED3D63F4623BFC05C0F6701A36420D60D9C99339F9486395CBE534D66CE66AAE0619B7F3
-20180403114045 2 6 100 3071 5 D9FA0132FCCAAE8116BD22861CD21A859841BA7D566829E10ACC15A7EFEEB381774F839F7228AE3C627F5765944DCDB6866618E187903EBDB558C9186BD84D2521630A379E161FDCEC19BA02A8E4B5A3C4A66D02CA0FEB7BEB75BA3BE87F26BB99122217A4FFEB1F730B430AA0A70BA4A91EFB248DF689E95957E93B9E5D2AC13FBD3896759F77C6CBB6664BA6FEB31C4FD7BF081D4F2D800AB8D979D89A5EFB34675A904F4B332ADD7340116E7D5D4F72F7E3940A30036ACA889C27D8E2E11C0668A2E8A43DFF411FA03F0AFB420262947A60528805A7E0F4B2CC6AC0EF62CBCB807BC131A8D51E7784A13C77DB461A9FDF01C0E97EA8B7C5A13BB4A86784C2FFA34FC1EF094ACB858A919951AA55508E468CBB889EA63B606D45455AAB75883A75A813E9EC6A3A49CADB05A62C2F5CA32013A4FC73E8B5DE1C14A39539A4716B157C08C74CD99EA23AE018A89C838B6C0EAEECDFCF78A447594033ED3D63F4623BFC05C0F6701A36420D60D9C99339F9486395CBE534D66CE66AAE06220B07
-20180403114120 2 6 100 3071 5 D9FA0132FCCAAE8116BD22861CD21A859841BA7D566829E10ACC15A7EFEEB381774F839F7228AE3C627F5765944DCDB6866618E187903EBDB558C9186BD84D2521630A379E161FDCEC19BA02A8E4B5A3C4A66D02CA0FEB7BEB75BA3BE87F26BB99122217A4FFEB1F730B430AA0A70BA4A91EFB248DF689E95957E93B9E5D2AC13FBD3896759F77C6CBB6664BA6FEB31C4FD7BF081D4F2D800AB8D979D89A5EFB34675A904F4B332ADD7340116E7D5D4F72F7E3940A30036ACA889C27D8E2E11C0668A2E8A43DFF411FA03F0AFB420262947A60528805A7E0F4B2CC6AC0EF62CBCB807BC131A8D51E7784A13C77DB461A9FDF01C0E97EA8B7C5A13BB4A86784C2FFA34FC1EF094ACB858A919951AA55508E468CBB889EA63B606D45455AAB75883A75A813E9EC6A3A49CADB05A62C2F5CA32013A4FC73E8B5DE1C14A39539A4716B157C08C74CD99EA23AE018A89C838B6C0EAEECDFCF78A447594033ED3D63F4623BFC05C0F6701A36420D60D9C99339F9486395CBE534D66CE66AAE0622E517
-20180403115211 2 6 100 3071 5 D9FA0132FCCAAE8116BD22861CD21A859841BA7D566829E10ACC15A7EFEEB381774F839F7228AE3C627F5765944DCDB6866618E187903EBDB558C9186BD84D2521630A379E161FDCEC19BA02A8E4B5A3C4A66D02CA0FEB7BEB75BA3BE87F26BB99122217A4FFEB1F730B430AA0A70BA4A91EFB248DF689E95957E93B9E5D2AC13FBD3896759F77C6CBB6664BA6FEB31C4FD7BF081D4F2D800AB8D979D89A5EFB34675A904F4B332ADD7340116E7D5D4F72F7E3940A30036ACA889C27D8E2E11C0668A2E8A43DFF411FA03F0AFB420262947A60528805A7E0F4B2CC6AC0EF62CBCB807BC131A8D51E7784A13C77DB461A9FDF01C0E97EA8B7C5A13BB4A86784C2FFA34FC1EF094ACB858A919951AA55508E468CBB889EA63B606D45455AAB75883A75A813E9EC6A3A49CADB05A62C2F5CA32013A4FC73E8B5DE1C14A39539A4716B157C08C74CD99EA23AE018A89C838B6C0EAEECDFCF78A447594033ED3D63F4623BFC05C0F6701A36420D60D9C99339F9486395CBE534D66CE66AAE06D363E7
-20180403115424 2 6 100 3071 5 D9FA0132FCCAAE8116BD22861CD21A859841BA7D566829E10ACC15A7EFEEB381774F839F7228AE3C627F5765944DCDB6866618E187903EBDB558C9186BD84D2521630A379E161FDCEC19BA02A8E4B5A3C4A66D02CA0FEB7BEB75BA3BE87F26BB99122217A4FFEB1F730B430AA0A70BA4A91EFB248DF689E95957E93B9E5D2AC13FBD3896759F77C6CBB6664BA6FEB31C4FD7BF081D4F2D800AB8D979D89A5EFB34675A904F4B332ADD7340116E7D5D4F72F7E3940A30036ACA889C27D8E2E11C0668A2E8A43DFF411FA03F0AFB420262947A60528805A7E0F4B2CC6AC0EF62CBCB807BC131A8D51E7784A13C77DB461A9FDF01C0E97EA8B7C5A13BB4A86784C2FFA34FC1EF094ACB858A919951AA55508E468CBB889EA63B606D45455AAB75883A75A813E9EC6A3A49CADB05A62C2F5CA32013A4FC73E8B5DE1C14A39539A4716B157C08C74CD99EA23AE018A89C838B6C0EAEECDFCF78A447594033ED3D63F4623BFC05C0F6701A36420D60D9C99339F9486395CBE534D66CE66AAE06F22507
-20180403115558 2 6 100 3071 2 D9FA0132FCCAAE8116BD22861CD21A859841BA7D566829E10ACC15A7EFEEB381774F839F7228AE3C627F5765944DCDB6866618E187903EBDB558C9186BD84D2521630A379E161FDCEC19BA02A8E4B5A3C4A66D02CA0FEB7BEB75BA3BE87F26BB99122217A4FFEB1F730B430AA0A70BA4A91EFB248DF689E95957E93B9E5D2AC13FBD3896759F77C6CBB6664BA6FEB31C4FD7BF081D4F2D800AB8D979D89A5EFB34675A904F4B332ADD7340116E7D5D4F72F7E3940A30036ACA889C27D8E2E11C0668A2E8A43DFF411FA03F0AFB420262947A60528805A7E0F4B2CC6AC0EF62CBCB807BC131A8D51E7784A13C77DB461A9FDF01C0E97EA8B7C5A13BB4A86784C2FFA34FC1EF094ACB858A919951AA55508E468CBB889EA63B606D45455AAB75883A75A813E9EC6A3A49CADB05A62C2F5CA32013A4FC73E8B5DE1C14A39539A4716B157C08C74CD99EA23AE018A89C838B6C0EAEECDFCF78A447594033ED3D63F4623BFC05C0F6701A36420D60D9C99339F9486395CBE534D66CE66AAE070516F3
-20180403115753 2 6 100 3071 5 D9FA0132FCCAAE8116BD22861CD21A859841BA7D566829E10ACC15A7EFEEB381774F839F7228AE3C627F5765944DCDB6866618E187903EBDB558C9186BD84D2521630A379E161FDCEC19BA02A8E4B5A3C4A66D02CA0FEB7BEB75BA3BE87F26BB99122217A4FFEB1F730B430AA0A70BA4A91EFB248DF689E95957E93B9E5D2AC13FBD3896759F77C6CBB6664BA6FEB31C4FD7BF081D4F2D800AB8D979D89A5EFB34675A904F4B332ADD7340116E7D5D4F72F7E3940A30036ACA889C27D8E2E11C0668A2E8A43DFF411FA03F0AFB420262947A60528805A7E0F4B2CC6AC0EF62CBCB807BC131A8D51E7784A13C77DB461A9FDF01C0E97EA8B7C5A13BB4A86784C2FFA34FC1EF094ACB858A919951AA55508E468CBB889EA63B606D45455AAB75883A75A813E9EC6A3A49CADB05A62C2F5CA32013A4FC73E8B5DE1C14A39539A4716B157C08C74CD99EA23AE018A89C838B6C0EAEECDFCF78A447594033ED3D63F4623BFC05C0F6701A36420D60D9C99339F9486395CBE534D66CE66AAE071E3297
-20180403115927 2 6 100 3071 5 D9FA0132FCCAAE8116BD22861CD21A859841BA7D566829E10ACC15A7EFEEB381774F839F7228AE3C627F5765944DCDB6866618E187903EBDB558C9186BD84D2521630A379E161FDCEC19BA02A8E4B5A3C4A66D02CA0FEB7BEB75BA3BE87F26BB99122217A4FFEB1F730B430AA0A70BA4A91EFB248DF689E95957E93B9E5D2AC13FBD3896759F77C6CBB6664BA6FEB31C4FD7BF081D4F2D800AB8D979D89A5EFB34675A904F4B332ADD7340116E7D5D4F72F7E3940A30036ACA889C27D8E2E11C0668A2E8A43DFF411FA03F0AFB420262947A60528805A7E0F4B2CC6AC0EF62CBCB807BC131A8D51E7784A13C77DB461A9FDF01C0E97EA8B7C5A13BB4A86784C2FFA34FC1EF094ACB858A919951AA55508E468CBB889EA63B606D45455AAB75883A75A813E9EC6A3A49CADB05A62C2F5CA32013A4FC73E8B5DE1C14A39539A4716B157C08C74CD99EA23AE018A89C838B6C0EAEECDFCF78A447594033ED3D63F4623BFC05C0F6701A36420D60D9C99339F9486395CBE534D66CE66AAE0731011F
-20180403121723 2 6 100 3071 2 D9FA0132FCCAAE8116BD22861CD21A859841BA7D566829E10ACC15A7EFEEB381774F839F7228AE3C627F5765944DCDB6866618E187903EBDB558C9186BD84D2521630A379E161FDCEC19BA02A8E4B5A3C4A66D02CA0FEB7BEB75BA3BE87F26BB99122217A4FFEB1F730B430AA0A70BA4A91EFB248DF689E95957E93B9E5D2AC13FBD3896759F77C6CBB6664BA6FEB31C4FD7BF081D4F2D800AB8D979D89A5EFB34675A904F4B332ADD7340116E7D5D4F72F7E3940A30036ACA889C27D8E2E11C0668A2E8A43DFF411FA03F0AFB420262947A60528805A7E0F4B2CC6AC0EF62CBCB807BC131A8D51E7784A13C77DB461A9FDF01C0E97EA8B7C5A13BB4A86784C2FFA34FC1EF094ACB858A919951AA55508E468CBB889EA63B606D45455AAB75883A75A813E9EC6A3A49CADB05A62C2F5CA32013A4FC73E8B5DE1C14A39539A4716B157C08C74CD99EA23AE018A89C838B6C0EAEECDFCF78A447594033ED3D63F4623BFC05C0F6701A36420D60D9C99339F9486395CBE534D66CE66AAE085D2303
-20180403122312 2 6 100 3071 5 D9FA0132FCCAAE8116BD22861CD21A859841BA7D566829E10ACC15A7EFEEB381774F839F7228AE3C627F5765944DCDB6866618E187903EBDB558C9186BD84D2521630A379E161FDCEC19BA02A8E4B5A3C4A66D02CA0FEB7BEB75BA3BE87F26BB99122217A4FFEB1F730B430AA0A70BA4A91EFB248DF689E95957E93B9E5D2AC13FBD3896759F77C6CBB6664BA6FEB31C4FD7BF081D4F2D800AB8D979D89A5EFB34675A904F4B332ADD7340116E7D5D4F72F7E3940A30036ACA889C27D8E2E11C0668A2E8A43DFF411FA03F0AFB420262947A60528805A7E0F4B2CC6AC0EF62CBCB807BC131A8D51E7784A13C77DB461A9FDF01C0E97EA8B7C5A13BB4A86784C2FFA34FC1EF094ACB858A919951AA55508E468CBB889EA63B606D45455AAB75883A75A813E9EC6A3A49CADB05A62C2F5CA32013A4FC73E8B5DE1C14A39539A4716B157C08C74CD99EA23AE018A89C838B6C0EAEECDFCF78A447594033ED3D63F4623BFC05C0F6701A36420D60D9C99339F9486395CBE534D66CE66AAE08B88A7F
-20180403123158 2 6 100 3071 2 D9FA0132FCCAAE8116BD22861CD21A859841BA7D566829E10ACC15A7EFEEB381774F839F7228AE3C627F5765944DCDB6866618E187903EBDB558C9186BD84D2521630A379E161FDCEC19BA02A8E4B5A3C4A66D02CA0FEB7BEB75BA3BE87F26BB99122217A4FFEB1F730B430AA0A70BA4A91EFB248DF689E95957E93B9E5D2AC13FBD3896759F77C6CBB6664BA6FEB31C4FD7BF081D4F2D800AB8D979D89A5EFB34675A904F4B332ADD7340116E7D5D4F72F7E3940A30036ACA889C27D8E2E11C0668A2E8A43DFF411FA03F0AFB420262947A60528805A7E0F4B2CC6AC0EF62CBCB807BC131A8D51E7784A13C77DB461A9FDF01C0E97EA8B7C5A13BB4A86784C2FFA34FC1EF094ACB858A919951AA55508E468CBB889EA63B606D45455AAB75883A75A813E9EC6A3A49CADB05A62C2F5CA32013A4FC73E8B5DE1C14A39539A4716B157C08C74CD99EA23AE018A89C838B6C0EAEECDFCF78A447594033ED3D63F4623BFC05C0F6701A36420D60D9C99339F9486395CBE534D66CE66AAE09563C53
-20180403123328 2 6 100 3071 5 D9FA0132FCCAAE8116BD22861CD21A859841BA7D566829E10ACC15A7EFEEB381774F839F7228AE3C627F5765944DCDB6866618E187903EBDB558C9186BD84D2521630A379E161FDCEC19BA02A8E4B5A3C4A66D02CA0FEB7BEB75BA3BE87F26BB99122217A4FFEB1F730B430AA0A70BA4A91EFB248DF689E95957E93B9E5D2AC13FBD3896759F77C6CBB6664BA6FEB31C4FD7BF081D4F2D800AB8D979D89A5EFB34675A904F4B332ADD7340116E7D5D4F72F7E3940A30036ACA889C27D8E2E11C0668A2E8A43DFF411FA03F0AFB420262947A60528805A7E0F4B2CC6AC0EF62CBCB807BC131A8D51E7784A13C77DB461A9FDF01C0E97EA8B7C5A13BB4A86784C2FFA34FC1EF094ACB858A919951AA55508E468CBB889EA63B606D45455AAB75883A75A813E9EC6A3A49CADB05A62C2F5CA32013A4FC73E8B5DE1C14A39539A4716B157C08C74CD99EA23AE018A89C838B6C0EAEECDFCF78A447594033ED3D63F4623BFC05C0F6701A36420D60D9C99339F9486395CBE534D66CE66AAE0969A18F
-20180403123534 2 6 100 3071 5 D9FA0132FCCAAE8116BD22861CD21A859841BA7D566829E10ACC15A7EFEEB381774F839F7228AE3C627F5765944DCDB6866618E187903EBDB558C9186BD84D2521630A379E161FDCEC19BA02A8E4B5A3C4A66D02CA0FEB7BEB75BA3BE87F26BB99122217A4FFEB1F730B430AA0A70BA4A91EFB248DF689E95957E93B9E5D2AC13FBD3896759F77C6CBB6664BA6FEB31C4FD7BF081D4F2D800AB8D979D89A5EFB34675A904F4B332ADD7340116E7D5D4F72F7E3940A30036ACA889C27D8E2E11C0668A2E8A43DFF411FA03F0AFB420262947A60528805A7E0F4B2CC6AC0EF62CBCB807BC131A8D51E7784A13C77DB461A9FDF01C0E97EA8B7C5A13BB4A86784C2FFA34FC1EF094ACB858A919951AA55508E468CBB889EA63B606D45455AAB75883A75A813E9EC6A3A49CADB05A62C2F5CA32013A4FC73E8B5DE1C14A39539A4716B157C08C74CD99EA23AE018A89C838B6C0EAEECDFCF78A447594033ED3D63F4623BFC05C0F6701A36420D60D9C99339F9486395CBE534D66CE66AAE09876D27
-20180403124247 2 6 100 3071 5 D9FA0132FCCAAE8116BD22861CD21A859841BA7D566829E10ACC15A7EFEEB381774F839F7228AE3C627F5765944DCDB6866618E187903EBDB558C9186BD84D2521630A379E161FDCEC19BA02A8E4B5A3C4A66D02CA0FEB7BEB75BA3BE87F26BB99122217A4FFEB1F730B430AA0A70BA4A91EFB248DF689E95957E93B9E5D2AC13FBD3896759F77C6CBB6664BA6FEB31C4FD7BF081D4F2D800AB8D979D89A5EFB34675A904F4B332ADD7340116E7D5D4F72F7E3940A30036ACA889C27D8E2E11C0668A2E8A43DFF411FA03F0AFB420262947A60528805A7E0F4B2CC6AC0EF62CBCB807BC131A8D51E7784A13C77DB461A9FDF01C0E97EA8B7C5A13BB4A86784C2FFA34FC1EF094ACB858A919951AA55508E468CBB889EA63B606D45455AAB75883A75A813E9EC6A3A49CADB05A62C2F5CA32013A4FC73E8B5DE1C14A39539A4716B157C08C74CD99EA23AE018A89C838B6C0EAEECDFCF78A447594033ED3D63F4623BFC05C0F6701A36420D60D9C99339F9486395CBE534D66CE66AAE09F3F4CF
-20180403124446 2 6 100 3071 5 D9FA0132FCCAAE8116BD22861CD21A859841BA7D566829E10ACC15A7EFEEB381774F839F7228AE3C627F5765944DCDB6866618E187903EBDB558C9186BD84D2521630A379E161FDCEC19BA02A8E4B5A3C4A66D02CA0FEB7BEB75BA3BE87F26BB99122217A4FFEB1F730B430AA0A70BA4A91EFB248DF689E95957E93B9E5D2AC13FBD3896759F77C6CBB6664BA6FEB31C4FD7BF081D4F2D800AB8D979D89A5EFB34675A904F4B332ADD7340116E7D5D4F72F7E3940A30036ACA889C27D8E2E11C0668A2E8A43DFF411FA03F0AFB420262947A60528805A7E0F4B2CC6AC0EF62CBCB807BC131A8D51E7784A13C77DB461A9FDF01C0E97EA8B7C5A13BB4A86784C2FFA34FC1EF094ACB858A919951AA55508E468CBB889EA63B606D45455AAB75883A75A813E9EC6A3A49CADB05A62C2F5CA32013A4FC73E8B5DE1C14A39539A4716B157C08C74CD99EA23AE018A89C838B6C0EAEECDFCF78A447594033ED3D63F4623BFC05C0F6701A36420D60D9C99339F9486395CBE534D66CE66AAE0A10443F
-20180403125400 2 6 100 3071 5 D9FA0132FCCAAE8116BD22861CD21A859841BA7D566829E10ACC15A7EFEEB381774F839F7228AE3C627F5765944DCDB6866618E187903EBDB558C9186BD84D2521630A379E161FDCEC19BA02A8E4B5A3C4A66D02CA0FEB7BEB75BA3BE87F26BB99122217A4FFEB1F730B430AA0A70BA4A91EFB248DF689E95957E93B9E5D2AC13FBD3896759F77C6CBB6664BA6FEB31C4FD7BF081D4F2D800AB8D979D89A5EFB34675A904F4B332ADD7340116E7D5D4F72F7E3940A30036ACA889C27D8E2E11C0668A2E8A43DFF411FA03F0AFB420262947A60528805A7E0F4B2CC6AC0EF62CBCB807BC131A8D51E7784A13C77DB461A9FDF01C0E97EA8B7C5A13BB4A86784C2FFA34FC1EF094ACB858A919951AA55508E468CBB889EA63B606D45455AAB75883A75A813E9EC6A3A49CADB05A62C2F5CA32013A4FC73E8B5DE1C14A39539A4716B157C08C74CD99EA23AE018A89C838B6C0EAEECDFCF78A447594033ED3D63F4623BFC05C0F6701A36420D60D9C99339F9486395CBE534D66CE66AAE0AA6560F
-20180403131328 2 6 100 3071 2 D9FA0132FCCAAE8116BD22861CD21A859841BA7D566829E10ACC15A7EFEEB381774F839F7228AE3C627F5765944DCDB6866618E187903EBDB558C9186BD84D2521630A379E161FDCEC19BA02A8E4B5A3C4A66D02CA0FEB7BEB75BA3BE87F26BB99122217A4FFEB1F730B430AA0A70BA4A91EFB248DF689E95957E93B9E5D2AC13FBD3896759F77C6CBB6664BA6FEB31C4FD7BF081D4F2D800AB8D979D89A5EFB34675A904F4B332ADD7340116E7D5D4F72F7E3940A30036ACA889C27D8E2E11C0668A2E8A43DFF411FA03F0AFB420262947A60528805A7E0F4B2CC6AC0EF62CBCB807BC131A8D51E7784A13C77DB461A9FDF01C0E97EA8B7C5A13BB4A86784C2FFA34FC1EF094ACB858A919951AA55508E468CBB889EA63B606D45455AAB75883A75A813E9EC6A3A49CADB05A62C2F5CA32013A4FC73E8B5DE1C14A39539A4716B157C08C74CD99EA23AE018A89C838B6C0EAEECDFCF78A447594033ED3D63F4623BFC05C0F6701A36420D60D9C99339F9486395CBE534D66CE66AAE0BF05873
-20180403131708 2 6 100 3071 2 D9FA0132FCCAAE8116BD22861CD21A859841BA7D566829E10ACC15A7EFEEB381774F839F7228AE3C627F5765944DCDB6866618E187903EBDB558C9186BD84D2521630A379E161FDCEC19BA02A8E4B5A3C4A66D02CA0FEB7BEB75BA3BE87F26BB99122217A4FFEB1F730B430AA0A70BA4A91EFB248DF689E95957E93B9E5D2AC13FBD3896759F77C6CBB6664BA6FEB31C4FD7BF081D4F2D800AB8D979D89A5EFB34675A904F4B332ADD7340116E7D5D4F72F7E3940A30036ACA889C27D8E2E11C0668A2E8A43DFF411FA03F0AFB420262947A60528805A7E0F4B2CC6AC0EF62CBCB807BC131A8D51E7784A13C77DB461A9FDF01C0E97EA8B7C5A13BB4A86784C2FFA34FC1EF094ACB858A919951AA55508E468CBB889EA63B606D45455AAB75883A75A813E9EC6A3A49CADB05A62C2F5CA32013A4FC73E8B5DE1C14A39539A4716B157C08C74CD99EA23AE018A89C838B6C0EAEECDFCF78A447594033ED3D63F4623BFC05C0F6701A36420D60D9C99339F9486395CBE534D66CE66AAE0C28FCF3
-20180403132618 2 6 100 3071 2 D9FA0132FCCAAE8116BD22861CD21A859841BA7D566829E10ACC15A7EFEEB381774F839F7228AE3C627F5765944DCDB6866618E187903EBDB558C9186BD84D2521630A379E161FDCEC19BA02A8E4B5A3C4A66D02CA0FEB7BEB75BA3BE87F26BB99122217A4FFEB1F730B430AA0A70BA4A91EFB248DF689E95957E93B9E5D2AC13FBD3896759F77C6CBB6664BA6FEB31C4FD7BF081D4F2D800AB8D979D89A5EFB34675A904F4B332ADD7340116E7D5D4F72F7E3940A30036ACA889C27D8E2E11C0668A2E8A43DFF411FA03F0AFB420262947A60528805A7E0F4B2CC6AC0EF62CBCB807BC131A8D51E7784A13C77DB461A9FDF01C0E97EA8B7C5A13BB4A86784C2FFA34FC1EF094ACB858A919951AA55508E468CBB889EA63B606D45455AAB75883A75A813E9EC6A3A49CADB05A62C2F5CA32013A4FC73E8B5DE1C14A39539A4716B157C08C74CD99EA23AE018A89C838B6C0EAEECDFCF78A447594033ED3D63F4623BFC05C0F6701A36420D60D9C99339F9486395CBE534D66CE66AAE0CC05D43
-20180403140905 2 6 100 3071 2 D9FA0132FCCAAE8116BD22861CD21A859841BA7D566829E10ACC15A7EFEEB381774F839F7228AE3C627F5765944DCDB6866618E187903EBDB558C9186BD84D2521630A379E161FDCEC19BA02A8E4B5A3C4A66D02CA0FEB7BEB75BA3BE87F26BB99122217A4FFEB1F730B430AA0A70BA4A91EFB248DF689E95957E93B9E5D2AC13FBD3896759F77C6CBB6664BA6FEB31C4FD7BF081D4F2D800AB8D979D89A5EFB34675A904F4B332ADD7340116E7D5D4F72F7E3940A30036ACA889C27D8E2E11C0668A2E8A43DFF411FA03F0AFB420262947A60528805A7E0F4B2CC6AC0EF62CBCB807BC131A8D51E7784A13C77DB461A9FDF01C0E97EA8B7C5A13BB4A86784C2FFA34FC1EF094ACB858A919951AA55508E468CBB889EA63B606D45455AAB75883A75A813E9EC6A3A49CADB05A62C2F5CA32013A4FC73E8B5DE1C14A39539A4716B157C08C74CD99EA23AE018A89C838B6C0EAEECDFCF78A447594033ED3D63F4623BFC05C0F6701A36420D60D9C99339F9486395CBE534D66CE66AAE0FBCA05B
-20180403141813 2 6 100 3071 5 D9FA0132FCCAAE8116BD22861CD21A859841BA7D566829E10ACC15A7EFEEB381774F839F7228AE3C627F5765944DCDB6866618E187903EBDB558C9186BD84D2521630A379E161FDCEC19BA02A8E4B5A3C4A66D02CA0FEB7BEB75BA3BE87F26BB99122217A4FFEB1F730B430AA0A70BA4A91EFB248DF689E95957E93B9E5D2AC13FBD3896759F77C6CBB6664BA6FEB31C4FD7BF081D4F2D800AB8D979D89A5EFB34675A904F4B332ADD7340116E7D5D4F72F7E3940A30036ACA889C27D8E2E11C0668A2E8A43DFF411FA03F0AFB420262947A60528805A7E0F4B2CC6AC0EF62CBCB807BC131A8D51E7784A13C77DB461A9FDF01C0E97EA8B7C5A13BB4A86784C2FFA34FC1EF094ACB858A919951AA55508E468CBB889EA63B606D45455AAB75883A75A813E9EC6A3A49CADB05A62C2F5CA32013A4FC73E8B5DE1C14A39539A4716B157C08C74CD99EA23AE018A89C838B6C0EAEECDFCF78A447594033ED3D63F4623BFC05C0F6701A36420D60D9C99339F9486395CBE534D66CE66AAE1054C7EF
-20180403143434 2 6 100 3071 2 D9FA0132FCCAAE8116BD22861CD21A859841BA7D566829E10ACC15A7EFEEB381774F839F7228AE3C627F5765944DCDB6866618E187903EBDB558C9186BD84D2521630A379E161FDCEC19BA02A8E4B5A3C4A66D02CA0FEB7BEB75BA3BE87F26BB99122217A4FFEB1F730B430AA0A70BA4A91EFB248DF689E95957E93B9E5D2AC13FBD3896759F77C6CBB6664BA6FEB31C4FD7BF081D4F2D800AB8D979D89A5EFB34675A904F4B332ADD7340116E7D5D4F72F7E3940A30036ACA889C27D8E2E11C0668A2E8A43DFF411FA03F0AFB420262947A60528805A7E0F4B2CC6AC0EF62CBCB807BC131A8D51E7784A13C77DB461A9FDF01C0E97EA8B7C5A13BB4A86784C2FFA34FC1EF094ACB858A919951AA55508E468CBB889EA63B606D45455AAB75883A75A813E9EC6A3A49CADB05A62C2F5CA32013A4FC73E8B5DE1C14A39539A4716B157C08C74CD99EA23AE018A89C838B6C0EAEECDFCF78A447594033ED3D63F4623BFC05C0F6701A36420D60D9C99339F9486395CBE534D66CE66AAE1176152B
-20180403143933 2 6 100 3071 2 D9FA0132FCCAAE8116BD22861CD21A859841BA7D566829E10ACC15A7EFEEB381774F839F7228AE3C627F5765944DCDB6866618E187903EBDB558C9186BD84D2521630A379E161FDCEC19BA02A8E4B5A3C4A66D02CA0FEB7BEB75BA3BE87F26BB99122217A4FFEB1F730B430AA0A70BA4A91EFB248DF689E95957E93B9E5D2AC13FBD3896759F77C6CBB6664BA6FEB31C4FD7BF081D4F2D800AB8D979D89A5EFB34675A904F4B332ADD7340116E7D5D4F72F7E3940A30036ACA889C27D8E2E11C0668A2E8A43DFF411FA03F0AFB420262947A60528805A7E0F4B2CC6AC0EF62CBCB807BC131A8D51E7784A13C77DB461A9FDF01C0E97EA8B7C5A13BB4A86784C2FFA34FC1EF094ACB858A919951AA55508E468CBB889EA63B606D45455AAB75883A75A813E9EC6A3A49CADB05A62C2F5CA32013A4FC73E8B5DE1C14A39539A4716B157C08C74CD99EA23AE018A89C838B6C0EAEECDFCF78A447594033ED3D63F4623BFC05C0F6701A36420D60D9C99339F9486395CBE534D66CE66AAE11C90E93
-20180403144751 2 6 100 3071 2 D9FA0132FCCAAE8116BD22861CD21A859841BA7D566829E10ACC15A7EFEEB381774F839F7228AE3C627F5765944DCDB6866618E187903EBDB558C9186BD84D2521630A379E161FDCEC19BA02A8E4B5A3C4A66D02CA0FEB7BEB75BA3BE87F26BB99122217A4FFEB1F730B430AA0A70BA4A91EFB248DF689E95957E93B9E5D2AC13FBD3896759F77C6CBB6664BA6FEB31C4FD7BF081D4F2D800AB8D979D89A5EFB34675A904F4B332ADD7340116E7D5D4F72F7E3940A30036ACA889C27D8E2E11C0668A2E8A43DFF411FA03F0AFB420262947A60528805A7E0F4B2CC6AC0EF62CBCB807BC131A8D51E7784A13C77DB461A9FDF01C0E97EA8B7C5A13BB4A86784C2FFA34FC1EF094ACB858A919951AA55508E468CBB889EA63B606D45455AAB75883A75A813E9EC6A3A49CADB05A62C2F5CA32013A4FC73E8B5DE1C14A39539A4716B157C08C74CD99EA23AE018A89C838B6C0EAEECDFCF78A447594033ED3D63F4623BFC05C0F6701A36420D60D9C99339F9486395CBE534D66CE66AAE125A12D3
-20180403145406 2 6 100 3071 5 D9FA0132FCCAAE8116BD22861CD21A859841BA7D566829E10ACC15A7EFEEB381774F839F7228AE3C627F5765944DCDB6866618E187903EBDB558C9186BD84D2521630A379E161FDCEC19BA02A8E4B5A3C4A66D02CA0FEB7BEB75BA3BE87F26BB99122217A4FFEB1F730B430AA0A70BA4A91EFB248DF689E95957E93B9E5D2AC13FBD3896759F77C6CBB6664BA6FEB31C4FD7BF081D4F2D800AB8D979D89A5EFB34675A904F4B332ADD7340116E7D5D4F72F7E3940A30036ACA889C27D8E2E11C0668A2E8A43DFF411FA03F0AFB420262947A60528805A7E0F4B2CC6AC0EF62CBCB807BC131A8D51E7784A13C77DB461A9FDF01C0E97EA8B7C5A13BB4A86784C2FFA34FC1EF094ACB858A919951AA55508E468CBB889EA63B606D45455AAB75883A75A813E9EC6A3A49CADB05A62C2F5CA32013A4FC73E8B5DE1C14A39539A4716B157C08C74CD99EA23AE018A89C838B6C0EAEECDFCF78A447594033ED3D63F4623BFC05C0F6701A36420D60D9C99339F9486395CBE534D66CE66AAE12C4F6CF
-20180403145448 2 6 100 3071 5 D9FA0132FCCAAE8116BD22861CD21A859841BA7D566829E10ACC15A7EFEEB381774F839F7228AE3C627F5765944DCDB6866618E187903EBDB558C9186BD84D2521630A379E161FDCEC19BA02A8E4B5A3C4A66D02CA0FEB7BEB75BA3BE87F26BB99122217A4FFEB1F730B430AA0A70BA4A91EFB248DF689E95957E93B9E5D2AC13FBD3896759F77C6CBB6664BA6FEB31C4FD7BF081D4F2D800AB8D979D89A5EFB34675A904F4B332ADD7340116E7D5D4F72F7E3940A30036ACA889C27D8E2E11C0668A2E8A43DFF411FA03F0AFB420262947A60528805A7E0F4B2CC6AC0EF62CBCB807BC131A8D51E7784A13C77DB461A9FDF01C0E97EA8B7C5A13BB4A86784C2FFA34FC1EF094ACB858A919951AA55508E468CBB889EA63B606D45455AAB75883A75A813E9EC6A3A49CADB05A62C2F5CA32013A4FC73E8B5DE1C14A39539A4716B157C08C74CD99EA23AE018A89C838B6C0EAEECDFCF78A447594033ED3D63F4623BFC05C0F6701A36420D60D9C99339F9486395CBE534D66CE66AAE12CA246F
-20180403145549 2 6 100 3071 2 D9FA0132FCCAAE8116BD22861CD21A859841BA7D566829E10ACC15A7EFEEB381774F839F7228AE3C627F5765944DCDB6866618E187903EBDB558C9186BD84D2521630A379E161FDCEC19BA02A8E4B5A3C4A66D02CA0FEB7BEB75BA3BE87F26BB99122217A4FFEB1F730B430AA0A70BA4A91EFB248DF689E95957E93B9E5D2AC13FBD3896759F77C6CBB6664BA6FEB31C4FD7BF081D4F2D800AB8D979D89A5EFB34675A904F4B332ADD7340116E7D5D4F72F7E3940A30036ACA889C27D8E2E11C0668A2E8A43DFF411FA03F0AFB420262947A60528805A7E0F4B2CC6AC0EF62CBCB807BC131A8D51E7784A13C77DB461A9FDF01C0E97EA8B7C5A13BB4A86784C2FFA34FC1EF094ACB858A919951AA55508E468CBB889EA63B606D45455AAB75883A75A813E9EC6A3A49CADB05A62C2F5CA32013A4FC73E8B5DE1C14A39539A4716B157C08C74CD99EA23AE018A89C838B6C0EAEECDFCF78A447594033ED3D63F4623BFC05C0F6701A36420D60D9C99339F9486395CBE534D66CE66AAE12D582AB
-20180403150132 2 6 100 3071 2 D9FA0132FCCAAE8116BD22861CD21A859841BA7D566829E10ACC15A7EFEEB381774F839F7228AE3C627F5765944DCDB6866618E187903EBDB558C9186BD84D2521630A379E161FDCEC19BA02A8E4B5A3C4A66D02CA0FEB7BEB75BA3BE87F26BB99122217A4FFEB1F730B430AA0A70BA4A91EFB248DF689E95957E93B9E5D2AC13FBD3896759F77C6CBB6664BA6FEB31C4FD7BF081D4F2D800AB8D979D89A5EFB34675A904F4B332ADD7340116E7D5D4F72F7E3940A30036ACA889C27D8E2E11C0668A2E8A43DFF411FA03F0AFB420262947A60528805A7E0F4B2CC6AC0EF62CBCB807BC131A8D51E7784A13C77DB461A9FDF01C0E97EA8B7C5A13BB4A86784C2FFA34FC1EF094ACB858A919951AA55508E468CBB889EA63B606D45455AAB75883A75A813E9EC6A3A49CADB05A62C2F5CA32013A4FC73E8B5DE1C14A39539A4716B157C08C74CD99EA23AE018A89C838B6C0EAEECDFCF78A447594033ED3D63F4623BFC05C0F6701A36420D60D9C99339F9486395CBE534D66CE66AAE13386F43
-20180403150512 2 6 100 3071 2 D9FA0132FCCAAE8116BD22861CD21A859841BA7D566829E10ACC15A7EFEEB381774F839F7228AE3C627F5765944DCDB6866618E187903EBDB558C9186BD84D2521630A379E161FDCEC19BA02A8E4B5A3C4A66D02CA0FEB7BEB75BA3BE87F26BB99122217A4FFEB1F730B430AA0A70BA4A91EFB248DF689E95957E93B9E5D2AC13FBD3896759F77C6CBB6664BA6FEB31C4FD7BF081D4F2D800AB8D979D89A5EFB34675A904F4B332ADD7340116E7D5D4F72F7E3940A30036ACA889C27D8E2E11C0668A2E8A43DFF411FA03F0AFB420262947A60528805A7E0F4B2CC6AC0EF62CBCB807BC131A8D51E7784A13C77DB461A9FDF01C0E97EA8B7C5A13BB4A86784C2FFA34FC1EF094ACB858A919951AA55508E468CBB889EA63B606D45455AAB75883A75A813E9EC6A3A49CADB05A62C2F5CA32013A4FC73E8B5DE1C14A39539A4716B157C08C74CD99EA23AE018A89C838B6C0EAEECDFCF78A447594033ED3D63F4623BFC05C0F6701A36420D60D9C99339F9486395CBE534D66CE66AAE1373A2CB
-20180403150605 2 6 100 3071 2 D9FA0132FCCAAE8116BD22861CD21A859841BA7D566829E10ACC15A7EFEEB381774F839F7228AE3C627F5765944DCDB6866618E187903EBDB558C9186BD84D2521630A379E161FDCEC19BA02A8E4B5A3C4A66D02CA0FEB7BEB75BA3BE87F26BB99122217A4FFEB1F730B430AA0A70BA4A91EFB248DF689E95957E93B9E5D2AC13FBD3896759F77C6CBB6664BA6FEB31C4FD7BF081D4F2D800AB8D979D89A5EFB34675A904F4B332ADD7340116E7D5D4F72F7E3940A30036ACA889C27D8E2E11C0668A2E8A43DFF411FA03F0AFB420262947A60528805A7E0F4B2CC6AC0EF62CBCB807BC131A8D51E7784A13C77DB461A9FDF01C0E97EA8B7C5A13BB4A86784C2FFA34FC1EF094ACB858A919951AA55508E468CBB889EA63B606D45455AAB75883A75A813E9EC6A3A49CADB05A62C2F5CA32013A4FC73E8B5DE1C14A39539A4716B157C08C74CD99EA23AE018A89C838B6C0EAEECDFCF78A447594033ED3D63F4623BFC05C0F6701A36420D60D9C99339F9486395CBE534D66CE66AAE137CA7DB
-20180403151404 2 6 100 3071 2 D9FA0132FCCAAE8116BD22861CD21A859841BA7D566829E10ACC15A7EFEEB381774F839F7228AE3C627F5765944DCDB6866618E187903EBDB558C9186BD84D2521630A379E161FDCEC19BA02A8E4B5A3C4A66D02CA0FEB7BEB75BA3BE87F26BB99122217A4FFEB1F730B430AA0A70BA4A91EFB248DF689E95957E93B9E5D2AC13FBD3896759F77C6CBB6664BA6FEB31C4FD7BF081D4F2D800AB8D979D89A5EFB34675A904F4B332ADD7340116E7D5D4F72F7E3940A30036ACA889C27D8E2E11C0668A2E8A43DFF411FA03F0AFB420262947A60528805A7E0F4B2CC6AC0EF62CBCB807BC131A8D51E7784A13C77DB461A9FDF01C0E97EA8B7C5A13BB4A86784C2FFA34FC1EF094ACB858A919951AA55508E468CBB889EA63B606D45455AAB75883A75A813E9EC6A3A49CADB05A62C2F5CA32013A4FC73E8B5DE1C14A39539A4716B157C08C74CD99EA23AE018A89C838B6C0EAEECDFCF78A447594033ED3D63F4623BFC05C0F6701A36420D60D9C99339F9486395CBE534D66CE66AAE140AEF53
-20180403152834 2 6 100 3071 2 D9FA0132FCCAAE8116BD22861CD21A859841BA7D566829E10ACC15A7EFEEB381774F839F7228AE3C627F5765944DCDB6866618E187903EBDB558C9186BD84D2521630A379E161FDCEC19BA02A8E4B5A3C4A66D02CA0FEB7BEB75BA3BE87F26BB99122217A4FFEB1F730B430AA0A70BA4A91EFB248DF689E95957E93B9E5D2AC13FBD3896759F77C6CBB6664BA6FEB31C4FD7BF081D4F2D800AB8D979D89A5EFB34675A904F4B332ADD7340116E7D5D4F72F7E3940A30036ACA889C27D8E2E11C0668A2E8A43DFF411FA03F0AFB420262947A60528805A7E0F4B2CC6AC0EF62CBCB807BC131A8D51E7784A13C77DB461A9FDF01C0E97EA8B7C5A13BB4A86784C2FFA34FC1EF094ACB858A919951AA55508E468CBB889EA63B606D45455AAB75883A75A813E9EC6A3A49CADB05A62C2F5CA32013A4FC73E8B5DE1C14A39539A4716B157C08C74CD99EA23AE018A89C838B6C0EAEECDFCF78A447594033ED3D63F4623BFC05C0F6701A36420D60D9C99339F9486395CBE534D66CE66AAE14BB5263
-20180403164629 2 6 100 4095 2 D6A36D53FE335EAC6C6F21F2963EEF44BF055FBE1D529CAC77341CADF25097607135D53FBDF5ED5B3BB2CE243834E344600627AB46C3F3952C0E59AAD95A13E0B299073FA6C02260432090C66B7DFA4C06633B8D31E7376024958AEF0B57A6A1519DC39CCFD65E33B19DA7C52C0C6DA0E5990A5DCDE9CB16C36408E6CC825FA464EC6CF3848202E6197281C8176600BEAABAB5E2C0598A97C9A5AC7606A0583DFFBD20FA424D1B62E0E5FAF7DA56C1CEB3C309C999C5B574322B8E511BA14342DAA24EA688E16B05CFC6B89696FF17BF21EC5AF75FB3A6258E6EA4CEE93B06299FC2D32441238B8EBF78124347A0E56522079641D5CB6F8858A91F9C7B1047E7CFCF6A80A0884BE39E9FB8CACE70865A022E538E80C899A43E5842C753E8332A8972249E4EAEB2C327FCD2777488CD9A1F03A242889D3F33A5C5047721605727486E3B97F3BEC6D8BF7C7B4512FB6AC8B854BD92B0ECC9F65408254BDDD8428F0F68EEF4FC61F033C56FF65C566B81994C1B92308771151DEBE7C814C608F99B784251C1CC4E5F110F5D9B9104BC8D60544FC4955204EF21F429E3D618C10F5F3A178BD71CEFD02ADF8AA5A3B79EB2038BC31467EE98AD1EA501B492EEF950B5B3E95AD0D792B585E3F6164E6B5EC52701DE13B6C7D832D339618E4C7372F8D02E48E743FB7477FDF8ED746987F72F4FFD46F1CEEA5340ABFC82D445F2ACFC43
-20180403173943 2 6 100 4095 2 D6A36D53FE335EAC6C6F21F2963EEF44BF055FBE1D529CAC77341CADF25097607135D53FBDF5ED5B3BB2CE243834E344600627AB46C3F3952C0E59AAD95A13E0B299073FA6C02260432090C66B7DFA4C06633B8D31E7376024958AEF0B57A6A1519DC39CCFD65E33B19DA7C52C0C6DA0E5990A5DCDE9CB16C36408E6CC825FA464EC6CF3848202E6197281C8176600BEAABAB5E2C0598A97C9A5AC7606A0583DFFBD20FA424D1B62E0E5FAF7DA56C1CEB3C309C999C5B574322B8E511BA14342DAA24EA688E16B05CFC6B89696FF17BF21EC5AF75FB3A6258E6EA4CEE93B06299FC2D32441238B8EBF78124347A0E56522079641D5CB6F8858A91F9C7B1047E7CFCF6A80A0884BE39E9FB8CACE70865A022E538E80C899A43E5842C753E8332A8972249E4EAEB2C327FCD2777488CD9A1F03A242889D3F33A5C5047721605727486E3B97F3BEC6D8BF7C7B4512FB6AC8B854BD92B0ECC9F65408254BDDD8428F0F68EEF4FC61F033C56FF65C566B81994C1B92308771151DEBE7C814C608F99B784251C1CC4E5F110F5D9B9104BC8D60544FC4955204EF21F429E3D618C10F5F3A178BD71CEFD02ADF8AA5A3B79EB2038BC31467EE98AD1EA501B492EEF950B5B3E95AD0D792B585E3F6164E6B5EC52701DE13B6C7D832D339618E4C7372F8D02E48E743FB7477FDF8ED746987F72F4FFD46F1CEEA5340ABFC82D445F45D568B
-20180403183028 2 6 100 4095 2 D6A36D53FE335EAC6C6F21F2963EEF44BF055FBE1D529CAC77341CADF25097607135D53FBDF5ED5B3BB2CE243834E344600627AB46C3F3952C0E59AAD95A13E0B299073FA6C02260432090C66B7DFA4C06633B8D31E7376024958AEF0B57A6A1519DC39CCFD65E33B19DA7C52C0C6DA0E5990A5DCDE9CB16C36408E6CC825FA464EC6CF3848202E6197281C8176600BEAABAB5E2C0598A97C9A5AC7606A0583DFFBD20FA424D1B62E0E5FAF7DA56C1CEB3C309C999C5B574322B8E511BA14342DAA24EA688E16B05CFC6B89696FF17BF21EC5AF75FB3A6258E6EA4CEE93B06299FC2D32441238B8EBF78124347A0E56522079641D5CB6F8858A91F9C7B1047E7CFCF6A80A0884BE39E9FB8CACE70865A022E538E80C899A43E5842C753E8332A8972249E4EAEB2C327FCD2777488CD9A1F03A242889D3F33A5C5047721605727486E3B97F3BEC6D8BF7C7B4512FB6AC8B854BD92B0ECC9F65408254BDDD8428F0F68EEF4FC61F033C56FF65C566B81994C1B92308771151DEBE7C814C608F99B784251C1CC4E5F110F5D9B9104BC8D60544FC4955204EF21F429E3D618C10F5F3A178BD71CEFD02ADF8AA5A3B79EB2038BC31467EE98AD1EA501B492EEF950B5B3E95AD0D792B585E3F6164E6B5EC52701DE13B6C7D832D339618E4C7372F8D02E48E743FB7477FDF8ED746987F72F4FFD46F1CEEA5340ABFC82D445F603359B
-20180403183423 2 6 100 4095 5 D6A36D53FE335EAC6C6F21F2963EEF44BF055FBE1D529CAC77341CADF25097607135D53FBDF5ED5B3BB2CE243834E344600627AB46C3F3952C0E59AAD95A13E0B299073FA6C02260432090C66B7DFA4C06633B8D31E7376024958AEF0B57A6A1519DC39CCFD65E33B19DA7C52C0C6DA0E5990A5DCDE9CB16C36408E6CC825FA464EC6CF3848202E6197281C8176600BEAABAB5E2C0598A97C9A5AC7606A0583DFFBD20FA424D1B62E0E5FAF7DA56C1CEB3C309C999C5B574322B8E511BA14342DAA24EA688E16B05CFC6B89696FF17BF21EC5AF75FB3A6258E6EA4CEE93B06299FC2D32441238B8EBF78124347A0E56522079641D5CB6F8858A91F9C7B1047E7CFCF6A80A0884BE39E9FB8CACE70865A022E538E80C899A43E5842C753E8332A8972249E4EAEB2C327FCD2777488CD9A1F03A242889D3F33A5C5047721605727486E3B97F3BEC6D8BF7C7B4512FB6AC8B854BD92B0ECC9F65408254BDDD8428F0F68EEF4FC61F033C56FF65C566B81994C1B92308771151DEBE7C814C608F99B784251C1CC4E5F110F5D9B9104BC8D60544FC4955204EF21F429E3D618C10F5F3A178BD71CEFD02ADF8AA5A3B79EB2038BC31467EE98AD1EA501B492EEF950B5B3E95AD0D792B585E3F6164E6B5EC52701DE13B6C7D832D339618E4C7372F8D02E48E743FB7477FDF8ED746987F72F4FFD46F1CEEA5340ABFC82D445F61BDC27
-20180403194550 2 6 100 4095 2 D6A36D53FE335EAC6C6F21F2963EEF44BF055FBE1D529CAC77341CADF25097607135D53FBDF5ED5B3BB2CE243834E344600627AB46C3F3952C0E59AAD95A13E0B299073FA6C02260432090C66B7DFA4C06633B8D31E7376024958AEF0B57A6A1519DC39CCFD65E33B19DA7C52C0C6DA0E5990A5DCDE9CB16C36408E6CC825FA464EC6CF3848202E6197281C8176600BEAABAB5E2C0598A97C9A5AC7606A0583DFFBD20FA424D1B62E0E5FAF7DA56C1CEB3C309C999C5B574322B8E511BA14342DAA24EA688E16B05CFC6B89696FF17BF21EC5AF75FB3A6258E6EA4CEE93B06299FC2D32441238B8EBF78124347A0E56522079641D5CB6F8858A91F9C7B1047E7CFCF6A80A0884BE39E9FB8CACE70865A022E538E80C899A43E5842C753E8332A8972249E4EAEB2C327FCD2777488CD9A1F03A242889D3F33A5C5047721605727486E3B97F3BEC6D8BF7C7B4512FB6AC8B854BD92B0ECC9F65408254BDDD8428F0F68EEF4FC61F033C56FF65C566B81994C1B92308771151DEBE7C814C608F99B784251C1CC4E5F110F5D9B9104BC8D60544FC4955204EF21F429E3D618C10F5F3A178BD71CEFD02ADF8AA5A3B79EB2038BC31467EE98AD1EA501B492EEF950B5B3E95AD0D792B585E3F6164E6B5EC52701DE13B6C7D832D339618E4C7372F8D02E48E743FB7477FDF8ED746987F72F4FFD46F1CEEA5340ABFC82D445F877D863
-20180403202122 2 6 100 4095 2 D6A36D53FE335EAC6C6F21F2963EEF44BF055FBE1D529CAC77341CADF25097607135D53FBDF5ED5B3BB2CE243834E344600627AB46C3F3952C0E59AAD95A13E0B299073FA6C02260432090C66B7DFA4C06633B8D31E7376024958AEF0B57A6A1519DC39CCFD65E33B19DA7C52C0C6DA0E5990A5DCDE9CB16C36408E6CC825FA464EC6CF3848202E6197281C8176600BEAABAB5E2C0598A97C9A5AC7606A0583DFFBD20FA424D1B62E0E5FAF7DA56C1CEB3C309C999C5B574322B8E511BA14342DAA24EA688E16B05CFC6B89696FF17BF21EC5AF75FB3A6258E6EA4CEE93B06299FC2D32441238B8EBF78124347A0E56522079641D5CB6F8858A91F9C7B1047E7CFCF6A80A0884BE39E9FB8CACE70865A022E538E80C899A43E5842C753E8332A8972249E4EAEB2C327FCD2777488CD9A1F03A242889D3F33A5C5047721605727486E3B97F3BEC6D8BF7C7B4512FB6AC8B854BD92B0ECC9F65408254BDDD8428F0F68EEF4FC61F033C56FF65C566B81994C1B92308771151DEBE7C814C608F99B784251C1CC4E5F110F5D9B9104BC8D60544FC4955204EF21F429E3D618C10F5F3A178BD71CEFD02ADF8AA5A3B79EB2038BC31467EE98AD1EA501B492EEF950B5B3E95AD0D792B585E3F6164E6B5EC52701DE13B6C7D832D339618E4C7372F8D02E48E743FB7477FDF8ED746987F72F4FFD46F1CEEA5340ABFC82D445F9A0304B
-20180403210313 2 6 100 4095 2 D6A36D53FE335EAC6C6F21F2963EEF44BF055FBE1D529CAC77341CADF25097607135D53FBDF5ED5B3BB2CE243834E344600627AB46C3F3952C0E59AAD95A13E0B299073FA6C02260432090C66B7DFA4C06633B8D31E7376024958AEF0B57A6A1519DC39CCFD65E33B19DA7C52C0C6DA0E5990A5DCDE9CB16C36408E6CC825FA464EC6CF3848202E6197281C8176600BEAABAB5E2C0598A97C9A5AC7606A0583DFFBD20FA424D1B62E0E5FAF7DA56C1CEB3C309C999C5B574322B8E511BA14342DAA24EA688E16B05CFC6B89696FF17BF21EC5AF75FB3A6258E6EA4CEE93B06299FC2D32441238B8EBF78124347A0E56522079641D5CB6F8858A91F9C7B1047E7CFCF6A80A0884BE39E9FB8CACE70865A022E538E80C899A43E5842C753E8332A8972249E4EAEB2C327FCD2777488CD9A1F03A242889D3F33A5C5047721605727486E3B97F3BEC6D8BF7C7B4512FB6AC8B854BD92B0ECC9F65408254BDDD8428F0F68EEF4FC61F033C56FF65C566B81994C1B92308771151DEBE7C814C608F99B784251C1CC4E5F110F5D9B9104BC8D60544FC4955204EF21F429E3D618C10F5F3A178BD71CEFD02ADF8AA5A3B79EB2038BC31467EE98AD1EA501B492EEF950B5B3E95AD0D792B585E3F6164E6B5EC52701DE13B6C7D832D339618E4C7372F8D02E48E743FB7477FDF8ED746987F72F4FFD46F1CEEA5340ABFC82D445FAFCEC73
-20180403213851 2 6 100 4095 5 D6A36D53FE335EAC6C6F21F2963EEF44BF055FBE1D529CAC77341CADF25097607135D53FBDF5ED5B3BB2CE243834E344600627AB46C3F3952C0E59AAD95A13E0B299073FA6C02260432090C66B7DFA4C06633B8D31E7376024958AEF0B57A6A1519DC39CCFD65E33B19DA7C52C0C6DA0E5990A5DCDE9CB16C36408E6CC825FA464EC6CF3848202E6197281C8176600BEAABAB5E2C0598A97C9A5AC7606A0583DFFBD20FA424D1B62E0E5FAF7DA56C1CEB3C309C999C5B574322B8E511BA14342DAA24EA688E16B05CFC6B89696FF17BF21EC5AF75FB3A6258E6EA4CEE93B06299FC2D32441238B8EBF78124347A0E56522079641D5CB6F8858A91F9C7B1047E7CFCF6A80A0884BE39E9FB8CACE70865A022E538E80C899A43E5842C753E8332A8972249E4EAEB2C327FCD2777488CD9A1F03A242889D3F33A5C5047721605727486E3B97F3BEC6D8BF7C7B4512FB6AC8B854BD92B0ECC9F65408254BDDD8428F0F68EEF4FC61F033C56FF65C566B81994C1B92308771151DEBE7C814C608F99B784251C1CC4E5F110F5D9B9104BC8D60544FC4955204EF21F429E3D618C10F5F3A178BD71CEFD02ADF8AA5A3B79EB2038BC31467EE98AD1EA501B492EEF950B5B3E95AD0D792B585E3F6164E6B5EC52701DE13B6C7D832D339618E4C7372F8D02E48E743FB7477FDF8ED746987F72F4FFD46F1CEEA5340ABFC82D445FC2F80FF
-20180403215353 2 6 100 4095 5 D6A36D53FE335EAC6C6F21F2963EEF44BF055FBE1D529CAC77341CADF25097607135D53FBDF5ED5B3BB2CE243834E344600627AB46C3F3952C0E59AAD95A13E0B299073FA6C02260432090C66B7DFA4C06633B8D31E7376024958AEF0B57A6A1519DC39CCFD65E33B19DA7C52C0C6DA0E5990A5DCDE9CB16C36408E6CC825FA464EC6CF3848202E6197281C8176600BEAABAB5E2C0598A97C9A5AC7606A0583DFFBD20FA424D1B62E0E5FAF7DA56C1CEB3C309C999C5B574322B8E511BA14342DAA24EA688E16B05CFC6B89696FF17BF21EC5AF75FB3A6258E6EA4CEE93B06299FC2D32441238B8EBF78124347A0E56522079641D5CB6F8858A91F9C7B1047E7CFCF6A80A0884BE39E9FB8CACE70865A022E538E80C899A43E5842C753E8332A8972249E4EAEB2C327FCD2777488CD9A1F03A242889D3F33A5C5047721605727486E3B97F3BEC6D8BF7C7B4512FB6AC8B854BD92B0ECC9F65408254BDDD8428F0F68EEF4FC61F033C56FF65C566B81994C1B92308771151DEBE7C814C608F99B784251C1CC4E5F110F5D9B9104BC8D60544FC4955204EF21F429E3D618C10F5F3A178BD71CEFD02ADF8AA5A3B79EB2038BC31467EE98AD1EA501B492EEF950B5B3E95AD0D792B585E3F6164E6B5EC52701DE13B6C7D832D339618E4C7372F8D02E48E743FB7477FDF8ED746987F72F4FFD46F1CEEA5340ABFC82D445FCA8B737
-20180403222440 2 6 100 4095 5 D6A36D53FE335EAC6C6F21F2963EEF44BF055FBE1D529CAC77341CADF25097607135D53FBDF5ED5B3BB2CE243834E344600627AB46C3F3952C0E59AAD95A13E0B299073FA6C02260432090C66B7DFA4C06633B8D31E7376024958AEF0B57A6A1519DC39CCFD65E33B19DA7C52C0C6DA0E5990A5DCDE9CB16C36408E6CC825FA464EC6CF3848202E6197281C8176600BEAABAB5E2C0598A97C9A5AC7606A0583DFFBD20FA424D1B62E0E5FAF7DA56C1CEB3C309C999C5B574322B8E511BA14342DAA24EA688E16B05CFC6B89696FF17BF21EC5AF75FB3A6258E6EA4CEE93B06299FC2D32441238B8EBF78124347A0E56522079641D5CB6F8858A91F9C7B1047E7CFCF6A80A0884BE39E9FB8CACE70865A022E538E80C899A43E5842C753E8332A8972249E4EAEB2C327FCD2777488CD9A1F03A242889D3F33A5C5047721605727486E3B97F3BEC6D8BF7C7B4512FB6AC8B854BD92B0ECC9F65408254BDDD8428F0F68EEF4FC61F033C56FF65C566B81994C1B92308771151DEBE7C814C608F99B784251C1CC4E5F110F5D9B9104BC8D60544FC4955204EF21F429E3D618C10F5F3A178BD71CEFD02ADF8AA5A3B79EB2038BC31467EE98AD1EA501B492EEF950B5B3E95AD0D792B585E3F6164E6B5EC52701DE13B6C7D832D339618E4C7372F8D02E48E743FB7477FDF8ED746987F72F4FFD46F1CEEA5340ABFC82D445FDAD53EF
-20180403224035 2 6 100 4095 2 D6A36D53FE335EAC6C6F21F2963EEF44BF055FBE1D529CAC77341CADF25097607135D53FBDF5ED5B3BB2CE243834E344600627AB46C3F3952C0E59AAD95A13E0B299073FA6C02260432090C66B7DFA4C06633B8D31E7376024958AEF0B57A6A1519DC39CCFD65E33B19DA7C52C0C6DA0E5990A5DCDE9CB16C36408E6CC825FA464EC6CF3848202E6197281C8176600BEAABAB5E2C0598A97C9A5AC7606A0583DFFBD20FA424D1B62E0E5FAF7DA56C1CEB3C309C999C5B574322B8E511BA14342DAA24EA688E16B05CFC6B89696FF17BF21EC5AF75FB3A6258E6EA4CEE93B06299FC2D32441238B8EBF78124347A0E56522079641D5CB6F8858A91F9C7B1047E7CFCF6A80A0884BE39E9FB8CACE70865A022E538E80C899A43E5842C753E8332A8972249E4EAEB2C327FCD2777488CD9A1F03A242889D3F33A5C5047721605727486E3B97F3BEC6D8BF7C7B4512FB6AC8B854BD92B0ECC9F65408254BDDD8428F0F68EEF4FC61F033C56FF65C566B81994C1B92308771151DEBE7C814C608F99B784251C1CC4E5F110F5D9B9104BC8D60544FC4955204EF21F429E3D618C10F5F3A178BD71CEFD02ADF8AA5A3B79EB2038BC31467EE98AD1EA501B492EEF950B5B3E95AD0D792B585E3F6164E6B5EC52701DE13B6C7D832D339618E4C7372F8D02E48E743FB7477FDF8ED746987F72F4FFD46F1CEEA5340ABFC82D445FE2EF2E3
-20180403224214 2 6 100 4095 2 D6A36D53FE335EAC6C6F21F2963EEF44BF055FBE1D529CAC77341CADF25097607135D53FBDF5ED5B3BB2CE243834E344600627AB46C3F3952C0E59AAD95A13E0B299073FA6C02260432090C66B7DFA4C06633B8D31E7376024958AEF0B57A6A1519DC39CCFD65E33B19DA7C52C0C6DA0E5990A5DCDE9CB16C36408E6CC825FA464EC6CF3848202E6197281C8176600BEAABAB5E2C0598A97C9A5AC7606A0583DFFBD20FA424D1B62E0E5FAF7DA56C1CEB3C309C999C5B574322B8E511BA14342DAA24EA688E16B05CFC6B89696FF17BF21EC5AF75FB3A6258E6EA4CEE93B06299FC2D32441238B8EBF78124347A0E56522079641D5CB6F8858A91F9C7B1047E7CFCF6A80A0884BE39E9FB8CACE70865A022E538E80C899A43E5842C753E8332A8972249E4EAEB2C327FCD2777488CD9A1F03A242889D3F33A5C5047721605727486E3B97F3BEC6D8BF7C7B4512FB6AC8B854BD92B0ECC9F65408254BDDD8428F0F68EEF4FC61F033C56FF65C566B81994C1B92308771151DEBE7C814C608F99B784251C1CC4E5F110F5D9B9104BC8D60544FC4955204EF21F429E3D618C10F5F3A178BD71CEFD02ADF8AA5A3B79EB2038BC31467EE98AD1EA501B492EEF950B5B3E95AD0D792B585E3F6164E6B5EC52701DE13B6C7D832D339618E4C7372F8D02E48E743FB7477FDF8ED746987F72F4FFD46F1CEEA5340ABFC82D445FE343553
-20180403234157 2 6 100 4095 5 D6A36D53FE335EAC6C6F21F2963EEF44BF055FBE1D529CAC77341CADF25097607135D53FBDF5ED5B3BB2CE243834E344600627AB46C3F3952C0E59AAD95A13E0B299073FA6C02260432090C66B7DFA4C06633B8D31E7376024958AEF0B57A6A1519DC39CCFD65E33B19DA7C52C0C6DA0E5990A5DCDE9CB16C36408E6CC825FA464EC6CF3848202E6197281C8176600BEAABAB5E2C0598A97C9A5AC7606A0583DFFBD20FA424D1B62E0E5FAF7DA56C1CEB3C309C999C5B574322B8E511BA14342DAA24EA688E16B05CFC6B89696FF17BF21EC5AF75FB3A6258E6EA4CEE93B06299FC2D32441238B8EBF78124347A0E56522079641D5CB6F8858A91F9C7B1047E7CFCF6A80A0884BE39E9FB8CACE70865A022E538E80C899A43E5842C753E8332A8972249E4EAEB2C327FCD2777488CD9A1F03A242889D3F33A5C5047721605727486E3B97F3BEC6D8BF7C7B4512FB6AC8B854BD92B0ECC9F65408254BDDD8428F0F68EEF4FC61F033C56FF65C566B81994C1B92308771151DEBE7C814C608F99B784251C1CC4E5F110F5D9B9104BC8D60544FC4955204EF21F429E3D618C10F5F3A178BD71CEFD02ADF8AA5A3B79EB2038BC31467EE98AD1EA501B492EEF950B5B3E95AD0D792B585E3F6164E6B5EC52701DE13B6C7D832D339618E4C7372F8D02E48E743FB7477FDF8ED746987F72F4FFD46F1CEEA5340ABFC82D446002B2C0F
-20180404012449 2 6 100 4095 5 D6A36D53FE335EAC6C6F21F2963EEF44BF055FBE1D529CAC77341CADF25097607135D53FBDF5ED5B3BB2CE243834E344600627AB46C3F3952C0E59AAD95A13E0B299073FA6C02260432090C66B7DFA4C06633B8D31E7376024958AEF0B57A6A1519DC39CCFD65E33B19DA7C52C0C6DA0E5990A5DCDE9CB16C36408E6CC825FA464EC6CF3848202E6197281C8176600BEAABAB5E2C0598A97C9A5AC7606A0583DFFBD20FA424D1B62E0E5FAF7DA56C1CEB3C309C999C5B574322B8E511BA14342DAA24EA688E16B05CFC6B89696FF17BF21EC5AF75FB3A6258E6EA4CEE93B06299FC2D32441238B8EBF78124347A0E56522079641D5CB6F8858A91F9C7B1047E7CFCF6A80A0884BE39E9FB8CACE70865A022E538E80C899A43E5842C753E8332A8972249E4EAEB2C327FCD2777488CD9A1F03A242889D3F33A5C5047721605727486E3B97F3BEC6D8BF7C7B4512FB6AC8B854BD92B0ECC9F65408254BDDD8428F0F68EEF4FC61F033C56FF65C566B81994C1B92308771151DEBE7C814C608F99B784251C1CC4E5F110F5D9B9104BC8D60544FC4955204EF21F429E3D618C10F5F3A178BD71CEFD02ADF8AA5A3B79EB2038BC31467EE98AD1EA501B492EEF950B5B3E95AD0D792B585E3F6164E6B5EC52701DE13B6C7D832D339618E4C7372F8D02E48E743FB7477FDF8ED746987F72F4FFD46F1CEEA5340ABFC82D446038F5C77
-20180404012740 2 6 100 4095 2 D6A36D53FE335EAC6C6F21F2963EEF44BF055FBE1D529CAC77341CADF25097607135D53FBDF5ED5B3BB2CE243834E344600627AB46C3F3952C0E59AAD95A13E0B299073FA6C02260432090C66B7DFA4C06633B8D31E7376024958AEF0B57A6A1519DC39CCFD65E33B19DA7C52C0C6DA0E5990A5DCDE9CB16C36408E6CC825FA464EC6CF3848202E6197281C8176600BEAABAB5E2C0598A97C9A5AC7606A0583DFFBD20FA424D1B62E0E5FAF7DA56C1CEB3C309C999C5B574322B8E511BA14342DAA24EA688E16B05CFC6B89696FF17BF21EC5AF75FB3A6258E6EA4CEE93B06299FC2D32441238B8EBF78124347A0E56522079641D5CB6F8858A91F9C7B1047E7CFCF6A80A0884BE39E9FB8CACE70865A022E538E80C899A43E5842C753E8332A8972249E4EAEB2C327FCD2777488CD9A1F03A242889D3F33A5C5047721605727486E3B97F3BEC6D8BF7C7B4512FB6AC8B854BD92B0ECC9F65408254BDDD8428F0F68EEF4FC61F033C56FF65C566B81994C1B92308771151DEBE7C814C608F99B784251C1CC4E5F110F5D9B9104BC8D60544FC4955204EF21F429E3D618C10F5F3A178BD71CEFD02ADF8AA5A3B79EB2038BC31467EE98AD1EA501B492EEF950B5B3E95AD0D792B585E3F6164E6B5EC52701DE13B6C7D832D339618E4C7372F8D02E48E743FB7477FDF8ED746987F72F4FFD46F1CEEA5340ABFC82D446039F760B
-20180404013701 2 6 100 4095 5 D6A36D53FE335EAC6C6F21F2963EEF44BF055FBE1D529CAC77341CADF25097607135D53FBDF5ED5B3BB2CE243834E344600627AB46C3F3952C0E59AAD95A13E0B299073FA6C02260432090C66B7DFA4C06633B8D31E7376024958AEF0B57A6A1519DC39CCFD65E33B19DA7C52C0C6DA0E5990A5DCDE9CB16C36408E6CC825FA464EC6CF3848202E6197281C8176600BEAABAB5E2C0598A97C9A5AC7606A0583DFFBD20FA424D1B62E0E5FAF7DA56C1CEB3C309C999C5B574322B8E511BA14342DAA24EA688E16B05CFC6B89696FF17BF21EC5AF75FB3A6258E6EA4CEE93B06299FC2D32441238B8EBF78124347A0E56522079641D5CB6F8858A91F9C7B1047E7CFCF6A80A0884BE39E9FB8CACE70865A022E538E80C899A43E5842C753E8332A8972249E4EAEB2C327FCD2777488CD9A1F03A242889D3F33A5C5047721605727486E3B97F3BEC6D8BF7C7B4512FB6AC8B854BD92B0ECC9F65408254BDDD8428F0F68EEF4FC61F033C56FF65C566B81994C1B92308771151DEBE7C814C608F99B784251C1CC4E5F110F5D9B9104BC8D60544FC4955204EF21F429E3D618C10F5F3A178BD71CEFD02ADF8AA5A3B79EB2038BC31467EE98AD1EA501B492EEF950B5B3E95AD0D792B585E3F6164E6B5EC52701DE13B6C7D832D339618E4C7372F8D02E48E743FB7477FDF8ED746987F72F4FFD46F1CEEA5340ABFC82D44603E742CF
-20180404024209 2 6 100 4095 2 D6A36D53FE335EAC6C6F21F2963EEF44BF055FBE1D529CAC77341CADF25097607135D53FBDF5ED5B3BB2CE243834E344600627AB46C3F3952C0E59AAD95A13E0B299073FA6C02260432090C66B7DFA4C06633B8D31E7376024958AEF0B57A6A1519DC39CCFD65E33B19DA7C52C0C6DA0E5990A5DCDE9CB16C36408E6CC825FA464EC6CF3848202E6197281C8176600BEAABAB5E2C0598A97C9A5AC7606A0583DFFBD20FA424D1B62E0E5FAF7DA56C1CEB3C309C999C5B574322B8E511BA14342DAA24EA688E16B05CFC6B89696FF17BF21EC5AF75FB3A6258E6EA4CEE93B06299FC2D32441238B8EBF78124347A0E56522079641D5CB6F8858A91F9C7B1047E7CFCF6A80A0884BE39E9FB8CACE70865A022E538E80C899A43E5842C753E8332A8972249E4EAEB2C327FCD2777488CD9A1F03A242889D3F33A5C5047721605727486E3B97F3BEC6D8BF7C7B4512FB6AC8B854BD92B0ECC9F65408254BDDD8428F0F68EEF4FC61F033C56FF65C566B81994C1B92308771151DEBE7C814C608F99B784251C1CC4E5F110F5D9B9104BC8D60544FC4955204EF21F429E3D618C10F5F3A178BD71CEFD02ADF8AA5A3B79EB2038BC31467EE98AD1EA501B492EEF950B5B3E95AD0D792B585E3F6164E6B5EC52701DE13B6C7D832D339618E4C7372F8D02E48E743FB7477FDF8ED746987F72F4FFD46F1CEEA5340ABFC82D4460610756B
-20180404034850 2 6 100 4095 5 D6A36D53FE335EAC6C6F21F2963EEF44BF055FBE1D529CAC77341CADF25097607135D53FBDF5ED5B3BB2CE243834E344600627AB46C3F3952C0E59AAD95A13E0B299073FA6C02260432090C66B7DFA4C06633B8D31E7376024958AEF0B57A6A1519DC39CCFD65E33B19DA7C52C0C6DA0E5990A5DCDE9CB16C36408E6CC825FA464EC6CF3848202E6197281C8176600BEAABAB5E2C0598A97C9A5AC7606A0583DFFBD20FA424D1B62E0E5FAF7DA56C1CEB3C309C999C5B574322B8E511BA14342DAA24EA688E16B05CFC6B89696FF17BF21EC5AF75FB3A6258E6EA4CEE93B06299FC2D32441238B8EBF78124347A0E56522079641D5CB6F8858A91F9C7B1047E7CFCF6A80A0884BE39E9FB8CACE70865A022E538E80C899A43E5842C753E8332A8972249E4EAEB2C327FCD2777488CD9A1F03A242889D3F33A5C5047721605727486E3B97F3BEC6D8BF7C7B4512FB6AC8B854BD92B0ECC9F65408254BDDD8428F0F68EEF4FC61F033C56FF65C566B81994C1B92308771151DEBE7C814C608F99B784251C1CC4E5F110F5D9B9104BC8D60544FC4955204EF21F429E3D618C10F5F3A178BD71CEFD02ADF8AA5A3B79EB2038BC31467EE98AD1EA501B492EEF950B5B3E95AD0D792B585E3F6164E6B5EC52701DE13B6C7D832D339618E4C7372F8D02E48E743FB7477FDF8ED746987F72F4FFD46F1CEEA5340ABFC82D446083DCDA7
-20180404035100 2 6 100 4095 2 D6A36D53FE335EAC6C6F21F2963EEF44BF055FBE1D529CAC77341CADF25097607135D53FBDF5ED5B3BB2CE243834E344600627AB46C3F3952C0E59AAD95A13E0B299073FA6C02260432090C66B7DFA4C06633B8D31E7376024958AEF0B57A6A1519DC39CCFD65E33B19DA7C52C0C6DA0E5990A5DCDE9CB16C36408E6CC825FA464EC6CF3848202E6197281C8176600BEAABAB5E2C0598A97C9A5AC7606A0583DFFBD20FA424D1B62E0E5FAF7DA56C1CEB3C309C999C5B574322B8E511BA14342DAA24EA688E16B05CFC6B89696FF17BF21EC5AF75FB3A6258E6EA4CEE93B06299FC2D32441238B8EBF78124347A0E56522079641D5CB6F8858A91F9C7B1047E7CFCF6A80A0884BE39E9FB8CACE70865A022E538E80C899A43E5842C753E8332A8972249E4EAEB2C327FCD2777488CD9A1F03A242889D3F33A5C5047721605727486E3B97F3BEC6D8BF7C7B4512FB6AC8B854BD92B0ECC9F65408254BDDD8428F0F68EEF4FC61F033C56FF65C566B81994C1B92308771151DEBE7C814C608F99B784251C1CC4E5F110F5D9B9104BC8D60544FC4955204EF21F429E3D618C10F5F3A178BD71CEFD02ADF8AA5A3B79EB2038BC31467EE98AD1EA501B492EEF950B5B3E95AD0D792B585E3F6164E6B5EC52701DE13B6C7D832D339618E4C7372F8D02E48E743FB7477FDF8ED746987F72F4FFD46F1CEEA5340ABFC82D446084796E3
-20180404035224 2 6 100 4095 2 D6A36D53FE335EAC6C6F21F2963EEF44BF055FBE1D529CAC77341CADF25097607135D53FBDF5ED5B3BB2CE243834E344600627AB46C3F3952C0E59AAD95A13E0B299073FA6C02260432090C66B7DFA4C06633B8D31E7376024958AEF0B57A6A1519DC39CCFD65E33B19DA7C52C0C6DA0E5990A5DCDE9CB16C36408E6CC825FA464EC6CF3848202E6197281C8176600BEAABAB5E2C0598A97C9A5AC7606A0583DFFBD20FA424D1B62E0E5FAF7DA56C1CEB3C309C999C5B574322B8E511BA14342DAA24EA688E16B05CFC6B89696FF17BF21EC5AF75FB3A6258E6EA4CEE93B06299FC2D32441238B8EBF78124347A0E56522079641D5CB6F8858A91F9C7B1047E7CFCF6A80A0884BE39E9FB8CACE70865A022E538E80C899A43E5842C753E8332A8972249E4EAEB2C327FCD2777488CD9A1F03A242889D3F33A5C5047721605727486E3B97F3BEC6D8BF7C7B4512FB6AC8B854BD92B0ECC9F65408254BDDD8428F0F68EEF4FC61F033C56FF65C566B81994C1B92308771151DEBE7C814C608F99B784251C1CC4E5F110F5D9B9104BC8D60544FC4955204EF21F429E3D618C10F5F3A178BD71CEFD02ADF8AA5A3B79EB2038BC31467EE98AD1EA501B492EEF950B5B3E95AD0D792B585E3F6164E6B5EC52701DE13B6C7D832D339618E4C7372F8D02E48E743FB7477FDF8ED746987F72F4FFD46F1CEEA5340ABFC82D446084ACD8B
-20180404040621 2 6 100 4095 2 D6A36D53FE335EAC6C6F21F2963EEF44BF055FBE1D529CAC77341CADF25097607135D53FBDF5ED5B3BB2CE243834E344600627AB46C3F3952C0E59AAD95A13E0B299073FA6C02260432090C66B7DFA4C06633B8D31E7376024958AEF0B57A6A1519DC39CCFD65E33B19DA7C52C0C6DA0E5990A5DCDE9CB16C36408E6CC825FA464EC6CF3848202E6197281C8176600BEAABAB5E2C0598A97C9A5AC7606A0583DFFBD20FA424D1B62E0E5FAF7DA56C1CEB3C309C999C5B574322B8E511BA14342DAA24EA688E16B05CFC6B89696FF17BF21EC5AF75FB3A6258E6EA4CEE93B06299FC2D32441238B8EBF78124347A0E56522079641D5CB6F8858A91F9C7B1047E7CFCF6A80A0884BE39E9FB8CACE70865A022E538E80C899A43E5842C753E8332A8972249E4EAEB2C327FCD2777488CD9A1F03A242889D3F33A5C5047721605727486E3B97F3BEC6D8BF7C7B4512FB6AC8B854BD92B0ECC9F65408254BDDD8428F0F68EEF4FC61F033C56FF65C566B81994C1B92308771151DEBE7C814C608F99B784251C1CC4E5F110F5D9B9104BC8D60544FC4955204EF21F429E3D618C10F5F3A178BD71CEFD02ADF8AA5A3B79EB2038BC31467EE98AD1EA501B492EEF950B5B3E95AD0D792B585E3F6164E6B5EC52701DE13B6C7D832D339618E4C7372F8D02E48E743FB7477FDF8ED746987F72F4FFD46F1CEEA5340ABFC82D44608BABFE3
-20180404043706 2 6 100 4095 2 D6A36D53FE335EAC6C6F21F2963EEF44BF055FBE1D529CAC77341CADF25097607135D53FBDF5ED5B3BB2CE243834E344600627AB46C3F3952C0E59AAD95A13E0B299073FA6C02260432090C66B7DFA4C06633B8D31E7376024958AEF0B57A6A1519DC39CCFD65E33B19DA7C52C0C6DA0E5990A5DCDE9CB16C36408E6CC825FA464EC6CF3848202E6197281C8176600BEAABAB5E2C0598A97C9A5AC7606A0583DFFBD20FA424D1B62E0E5FAF7DA56C1CEB3C309C999C5B574322B8E511BA14342DAA24EA688E16B05CFC6B89696FF17BF21EC5AF75FB3A6258E6EA4CEE93B06299FC2D32441238B8EBF78124347A0E56522079641D5CB6F8858A91F9C7B1047E7CFCF6A80A0884BE39E9FB8CACE70865A022E538E80C899A43E5842C753E8332A8972249E4EAEB2C327FCD2777488CD9A1F03A242889D3F33A5C5047721605727486E3B97F3BEC6D8BF7C7B4512FB6AC8B854BD92B0ECC9F65408254BDDD8428F0F68EEF4FC61F033C56FF65C566B81994C1B92308771151DEBE7C814C608F99B784251C1CC4E5F110F5D9B9104BC8D60544FC4955204EF21F429E3D618C10F5F3A178BD71CEFD02ADF8AA5A3B79EB2038BC31467EE98AD1EA501B492EEF950B5B3E95AD0D792B585E3F6164E6B5EC52701DE13B6C7D832D339618E4C7372F8D02E48E743FB7477FDF8ED746987F72F4FFD46F1CEEA5340ABFC82D44609B60613
-20180404044213 2 6 100 4095 5 D6A36D53FE335EAC6C6F21F2963EEF44BF055FBE1D529CAC77341CADF25097607135D53FBDF5ED5B3BB2CE243834E344600627AB46C3F3952C0E59AAD95A13E0B299073FA6C02260432090C66B7DFA4C06633B8D31E7376024958AEF0B57A6A1519DC39CCFD65E33B19DA7C52C0C6DA0E5990A5DCDE9CB16C36408E6CC825FA464EC6CF3848202E6197281C8176600BEAABAB5E2C0598A97C9A5AC7606A0583DFFBD20FA424D1B62E0E5FAF7DA56C1CEB3C309C999C5B574322B8E511BA14342DAA24EA688E16B05CFC6B89696FF17BF21EC5AF75FB3A6258E6EA4CEE93B06299FC2D32441238B8EBF78124347A0E56522079641D5CB6F8858A91F9C7B1047E7CFCF6A80A0884BE39E9FB8CACE70865A022E538E80C899A43E5842C753E8332A8972249E4EAEB2C327FCD2777488CD9A1F03A242889D3F33A5C5047721605727486E3B97F3BEC6D8BF7C7B4512FB6AC8B854BD92B0ECC9F65408254BDDD8428F0F68EEF4FC61F033C56FF65C566B81994C1B92308771151DEBE7C814C608F99B784251C1CC4E5F110F5D9B9104BC8D60544FC4955204EF21F429E3D618C10F5F3A178BD71CEFD02ADF8AA5A3B79EB2038BC31467EE98AD1EA501B492EEF950B5B3E95AD0D792B585E3F6164E6B5EC52701DE13B6C7D832D339618E4C7372F8D02E48E743FB7477FDF8ED746987F72F4FFD46F1CEEA5340ABFC82D44609DB5067
-20180404050247 2 6 100 4095 2 D6A36D53FE335EAC6C6F21F2963EEF44BF055FBE1D529CAC77341CADF25097607135D53FBDF5ED5B3BB2CE243834E344600627AB46C3F3952C0E59AAD95A13E0B299073FA6C02260432090C66B7DFA4C06633B8D31E7376024958AEF0B57A6A1519DC39CCFD65E33B19DA7C52C0C6DA0E5990A5DCDE9CB16C36408E6CC825FA464EC6CF3848202E6197281C8176600BEAABAB5E2C0598A97C9A5AC7606A0583DFFBD20FA424D1B62E0E5FAF7DA56C1CEB3C309C999C5B574322B8E511BA14342DAA24EA688E16B05CFC6B89696FF17BF21EC5AF75FB3A6258E6EA4CEE93B06299FC2D32441238B8EBF78124347A0E56522079641D5CB6F8858A91F9C7B1047E7CFCF6A80A0884BE39E9FB8CACE70865A022E538E80C899A43E5842C753E8332A8972249E4EAEB2C327FCD2777488CD9A1F03A242889D3F33A5C5047721605727486E3B97F3BEC6D8BF7C7B4512FB6AC8B854BD92B0ECC9F65408254BDDD8428F0F68EEF4FC61F033C56FF65C566B81994C1B92308771151DEBE7C814C608F99B784251C1CC4E5F110F5D9B9104BC8D60544FC4955204EF21F429E3D618C10F5F3A178BD71CEFD02ADF8AA5A3B79EB2038BC31467EE98AD1EA501B492EEF950B5B3E95AD0D792B585E3F6164E6B5EC52701DE13B6C7D832D339618E4C7372F8D02E48E743FB7477FDF8ED746987F72F4FFD46F1CEEA5340ABFC82D4460A8585C3
-20180404053546 2 6 100 4095 2 D6A36D53FE335EAC6C6F21F2963EEF44BF055FBE1D529CAC77341CADF25097607135D53FBDF5ED5B3BB2CE243834E344600627AB46C3F3952C0E59AAD95A13E0B299073FA6C02260432090C66B7DFA4C06633B8D31E7376024958AEF0B57A6A1519DC39CCFD65E33B19DA7C52C0C6DA0E5990A5DCDE9CB16C36408E6CC825FA464EC6CF3848202E6197281C8176600BEAABAB5E2C0598A97C9A5AC7606A0583DFFBD20FA424D1B62E0E5FAF7DA56C1CEB3C309C999C5B574322B8E511BA14342DAA24EA688E16B05CFC6B89696FF17BF21EC5AF75FB3A6258E6EA4CEE93B06299FC2D32441238B8EBF78124347A0E56522079641D5CB6F8858A91F9C7B1047E7CFCF6A80A0884BE39E9FB8CACE70865A022E538E80C899A43E5842C753E8332A8972249E4EAEB2C327FCD2777488CD9A1F03A242889D3F33A5C5047721605727486E3B97F3BEC6D8BF7C7B4512FB6AC8B854BD92B0ECC9F65408254BDDD8428F0F68EEF4FC61F033C56FF65C566B81994C1B92308771151DEBE7C814C608F99B784251C1CC4E5F110F5D9B9104BC8D60544FC4955204EF21F429E3D618C10F5F3A178BD71CEFD02ADF8AA5A3B79EB2038BC31467EE98AD1EA501B492EEF950B5B3E95AD0D792B585E3F6164E6B5EC52701DE13B6C7D832D339618E4C7372F8D02E48E743FB7477FDF8ED746987F72F4FFD46F1CEEA5340ABFC82D4460B94238B
-20180404054127 2 6 100 4095 2 D6A36D53FE335EAC6C6F21F2963EEF44BF055FBE1D529CAC77341CADF25097607135D53FBDF5ED5B3BB2CE243834E344600627AB46C3F3952C0E59AAD95A13E0B299073FA6C02260432090C66B7DFA4C06633B8D31E7376024958AEF0B57A6A1519DC39CCFD65E33B19DA7C52C0C6DA0E5990A5DCDE9CB16C36408E6CC825FA464EC6CF3848202E6197281C8176600BEAABAB5E2C0598A97C9A5AC7606A0583DFFBD20FA424D1B62E0E5FAF7DA56C1CEB3C309C999C5B574322B8E511BA14342DAA24EA688E16B05CFC6B89696FF17BF21EC5AF75FB3A6258E6EA4CEE93B06299FC2D32441238B8EBF78124347A0E56522079641D5CB6F8858A91F9C7B1047E7CFCF6A80A0884BE39E9FB8CACE70865A022E538E80C899A43E5842C753E8332A8972249E4EAEB2C327FCD2777488CD9A1F03A242889D3F33A5C5047721605727486E3B97F3BEC6D8BF7C7B4512FB6AC8B854BD92B0ECC9F65408254BDDD8428F0F68EEF4FC61F033C56FF65C566B81994C1B92308771151DEBE7C814C608F99B784251C1CC4E5F110F5D9B9104BC8D60544FC4955204EF21F429E3D618C10F5F3A178BD71CEFD02ADF8AA5A3B79EB2038BC31467EE98AD1EA501B492EEF950B5B3E95AD0D792B585E3F6164E6B5EC52701DE13B6C7D832D339618E4C7372F8D02E48E743FB7477FDF8ED746987F72F4FFD46F1CEEA5340ABFC82D4460BBC6C0B
-20180404060250 2 6 100 4095 5 D6A36D53FE335EAC6C6F21F2963EEF44BF055FBE1D529CAC77341CADF25097607135D53FBDF5ED5B3BB2CE243834E344600627AB46C3F3952C0E59AAD95A13E0B299073FA6C02260432090C66B7DFA4C06633B8D31E7376024958AEF0B57A6A1519DC39CCFD65E33B19DA7C52C0C6DA0E5990A5DCDE9CB16C36408E6CC825FA464EC6CF3848202E6197281C8176600BEAABAB5E2C0598A97C9A5AC7606A0583DFFBD20FA424D1B62E0E5FAF7DA56C1CEB3C309C999C5B574322B8E511BA14342DAA24EA688E16B05CFC6B89696FF17BF21EC5AF75FB3A6258E6EA4CEE93B06299FC2D32441238B8EBF78124347A0E56522079641D5CB6F8858A91F9C7B1047E7CFCF6A80A0884BE39E9FB8CACE70865A022E538E80C899A43E5842C753E8332A8972249E4EAEB2C327FCD2777488CD9A1F03A242889D3F33A5C5047721605727486E3B97F3BEC6D8BF7C7B4512FB6AC8B854BD92B0ECC9F65408254BDDD8428F0F68EEF4FC61F033C56FF65C566B81994C1B92308771151DEBE7C814C608F99B784251C1CC4E5F110F5D9B9104BC8D60544FC4955204EF21F429E3D618C10F5F3A178BD71CEFD02ADF8AA5A3B79EB2038BC31467EE98AD1EA501B492EEF950B5B3E95AD0D792B585E3F6164E6B5EC52701DE13B6C7D832D339618E4C7372F8D02E48E743FB7477FDF8ED746987F72F4FFD46F1CEEA5340ABFC82D4460C67CBB7
-20180404061330 2 6 100 4095 2 D6A36D53FE335EAC6C6F21F2963EEF44BF055FBE1D529CAC77341CADF25097607135D53FBDF5ED5B3BB2CE243834E344600627AB46C3F3952C0E59AAD95A13E0B299073FA6C02260432090C66B7DFA4C06633B8D31E7376024958AEF0B57A6A1519DC39CCFD65E33B19DA7C52C0C6DA0E5990A5DCDE9CB16C36408E6CC825FA464EC6CF3848202E6197281C8176600BEAABAB5E2C0598A97C9A5AC7606A0583DFFBD20FA424D1B62E0E5FAF7DA56C1CEB3C309C999C5B574322B8E511BA14342DAA24EA688E16B05CFC6B89696FF17BF21EC5AF75FB3A6258E6EA4CEE93B06299FC2D32441238B8EBF78124347A0E56522079641D5CB6F8858A91F9C7B1047E7CFCF6A80A0884BE39E9FB8CACE70865A022E538E80C899A43E5842C753E8332A8972249E4EAEB2C327FCD2777488CD9A1F03A242889D3F33A5C5047721605727486E3B97F3BEC6D8BF7C7B4512FB6AC8B854BD92B0ECC9F65408254BDDD8428F0F68EEF4FC61F033C56FF65C566B81994C1B92308771151DEBE7C814C608F99B784251C1CC4E5F110F5D9B9104BC8D60544FC4955204EF21F429E3D618C10F5F3A178BD71CEFD02ADF8AA5A3B79EB2038BC31467EE98AD1EA501B492EEF950B5B3E95AD0D792B585E3F6164E6B5EC52701DE13B6C7D832D339618E4C7372F8D02E48E743FB7477FDF8ED746987F72F4FFD46F1CEEA5340ABFC82D4460CA93683
-20180404084828 2 6 100 4095 2 D6A36D53FE335EAC6C6F21F2963EEF44BF055FBE1D529CAC77341CADF25097607135D53FBDF5ED5B3BB2CE243834E344600627AB46C3F3952C0E59AAD95A13E0B299073FA6C02260432090C66B7DFA4C06633B8D31E7376024958AEF0B57A6A1519DC39CCFD65E33B19DA7C52C0C6DA0E5990A5DCDE9CB16C36408E6CC825FA464EC6CF3848202E6197281C8176600BEAABAB5E2C0598A97C9A5AC7606A0583DFFBD20FA424D1B62E0E5FAF7DA56C1CEB3C309C999C5B574322B8E511BA14342DAA24EA688E16B05CFC6B89696FF17BF21EC5AF75FB3A6258E6EA4CEE93B06299FC2D32441238B8EBF78124347A0E56522079641D5CB6F8858A91F9C7B1047E7CFCF6A80A0884BE39E9FB8CACE70865A022E538E80C899A43E5842C753E8332A8972249E4EAEB2C327FCD2777488CD9A1F03A242889D3F33A5C5047721605727486E3B97F3BEC6D8BF7C7B4512FB6AC8B854BD92B0ECC9F65408254BDDD8428F0F68EEF4FC61F033C56FF65C566B81994C1B92308771151DEBE7C814C608F99B784251C1CC4E5F110F5D9B9104BC8D60544FC4955204EF21F429E3D618C10F5F3A178BD71CEFD02ADF8AA5A3B79EB2038BC31467EE98AD1EA501B492EEF950B5B3E95AD0D792B585E3F6164E6B5EC52701DE13B6C7D832D339618E4C7372F8D02E48E743FB7477FDF8ED746987F72F4FFD46F1CEEA5340ABFC82D446115943A3
-20180404085435 2 6 100 4095 5 D6A36D53FE335EAC6C6F21F2963EEF44BF055FBE1D529CAC77341CADF25097607135D53FBDF5ED5B3BB2CE243834E344600627AB46C3F3952C0E59AAD95A13E0B299073FA6C02260432090C66B7DFA4C06633B8D31E7376024958AEF0B57A6A1519DC39CCFD65E33B19DA7C52C0C6DA0E5990A5DCDE9CB16C36408E6CC825FA464EC6CF3848202E6197281C8176600BEAABAB5E2C0598A97C9A5AC7606A0583DFFBD20FA424D1B62E0E5FAF7DA56C1CEB3C309C999C5B574322B8E511BA14342DAA24EA688E16B05CFC6B89696FF17BF21EC5AF75FB3A6258E6EA4CEE93B06299FC2D32441238B8EBF78124347A0E56522079641D5CB6F8858A91F9C7B1047E7CFCF6A80A0884BE39E9FB8CACE70865A022E538E80C899A43E5842C753E8332A8972249E4EAEB2C327FCD2777488CD9A1F03A242889D3F33A5C5047721605727486E3B97F3BEC6D8BF7C7B4512FB6AC8B854BD92B0ECC9F65408254BDDD8428F0F68EEF4FC61F033C56FF65C566B81994C1B92308771151DEBE7C814C608F99B784251C1CC4E5F110F5D9B9104BC8D60544FC4955204EF21F429E3D618C10F5F3A178BD71CEFD02ADF8AA5A3B79EB2038BC31467EE98AD1EA501B492EEF950B5B3E95AD0D792B585E3F6164E6B5EC52701DE13B6C7D832D339618E4C7372F8D02E48E743FB7477FDF8ED746987F72F4FFD46F1CEEA5340ABFC82D4461181EE57
-20180404093010 2 6 100 4095 5 C287DA1692C8760D889CABEA6A7055FADB13C9F064C87322D569B9C574001DEBA1685DA8DFFB9A11253F685A3045E2CEBA057C35DD417F717110949007702B25A37AEE60C3A1A9AA6A1667C15BBFFFF173DF27813A74959756822AB34A2BB97B2F408CC6A994ADC83F05CB8028784B859A25032D691F1DDFB1A87F47EDC289FE4452BE4E4D7B07745C1D5A901E7EF0521465DFFC1EECAB7E4F15172A90257AFFCA11B455ADD24067B20C20EDF9B5B59BDFDAE03BF0AB39A13E60515CA8ADE3273BBCA8290D3B581F92B61F1A893ABFF16255A9226638159640F7869B5C30C8FFF3C3378B14E1A5529C8DE120A9E2099388E1217BDDFCC1708F37E74BDE5D0A2DCFDC4DD27BA697C3F8238182DA7C5D02431E086067358CC9A9B4EFF7C8D7FC9F0C8C0528887A194A6D0613AEE1EEDDC7A315AC1A178E9377E488F49367573BA8EDF80FD6EDE2D256F0614AF81B8FB1B243EA7F04CA6BE0E0BE9F43525D3B6718DAA5E2FD3D20BE3F37ED402DAFD7F19C39E51A40868D3F79D45CD422A9F7454DB3FEFF205BE4C10234914FD8882B344DBFB5C2BE5B576EA94EB62C3AFCD012EE7F82F0744BE067736E9A78EF38E6F06474E025776F138AF84E4093AB36683A60D0DB5CB9F75CA7C4303059E0DDCE3A641A3278F5015FD42EAA79B72E5F0D2EFDAADE3B76B23DD4C2A39F359B3CA00F7584B729800B3E01DC3D4CD4B396361597
-20180404100034 2 6 100 4095 2 C287DA1692C8760D889CABEA6A7055FADB13C9F064C87322D569B9C574001DEBA1685DA8DFFB9A11253F685A3045E2CEBA057C35DD417F717110949007702B25A37AEE60C3A1A9AA6A1667C15BBFFFF173DF27813A74959756822AB34A2BB97B2F408CC6A994ADC83F05CB8028784B859A25032D691F1DDFB1A87F47EDC289FE4452BE4E4D7B07745C1D5A901E7EF0521465DFFC1EECAB7E4F15172A90257AFFCA11B455ADD24067B20C20EDF9B5B59BDFDAE03BF0AB39A13E60515CA8ADE3273BBCA8290D3B581F92B61F1A893ABFF16255A9226638159640F7869B5C30C8FFF3C3378B14E1A5529C8DE120A9E2099388E1217BDDFCC1708F37E74BDE5D0A2DCFDC4DD27BA697C3F8238182DA7C5D02431E086067358CC9A9B4EFF7C8D7FC9F0C8C0528887A194A6D0613AEE1EEDDC7A315AC1A178E9377E488F49367573BA8EDF80FD6EDE2D256F0614AF81B8FB1B243EA7F04CA6BE0E0BE9F43525D3B6718DAA5E2FD3D20BE3F37ED402DAFD7F19C39E51A40868D3F79D45CD422A9F7454DB3FEFF205BE4C10234914FD8882B344DBFB5C2BE5B576EA94EB62C3AFCD012EE7F82F0744BE067736E9A78EF38E6F06474E025776F138AF84E4093AB36683A60D0DB5CB9F75CA7C4303059E0DDCE3A641A3278F5015FD42EAA79B72E5F0D2EFDAADE3B76B23DD4C2A39F359B3CA00F7584B729800B3E01DC3D4CD4B3973953BB
-20180404112136 2 6 100 4095 5 C287DA1692C8760D889CABEA6A7055FADB13C9F064C87322D569B9C574001DEBA1685DA8DFFB9A11253F685A3045E2CEBA057C35DD417F717110949007702B25A37AEE60C3A1A9AA6A1667C15BBFFFF173DF27813A74959756822AB34A2BB97B2F408CC6A994ADC83F05CB8028784B859A25032D691F1DDFB1A87F47EDC289FE4452BE4E4D7B07745C1D5A901E7EF0521465DFFC1EECAB7E4F15172A90257AFFCA11B455ADD24067B20C20EDF9B5B59BDFDAE03BF0AB39A13E60515CA8ADE3273BBCA8290D3B581F92B61F1A893ABFF16255A9226638159640F7869B5C30C8FFF3C3378B14E1A5529C8DE120A9E2099388E1217BDDFCC1708F37E74BDE5D0A2DCFDC4DD27BA697C3F8238182DA7C5D02431E086067358CC9A9B4EFF7C8D7FC9F0C8C0528887A194A6D0613AEE1EEDDC7A315AC1A178E9377E488F49367573BA8EDF80FD6EDE2D256F0614AF81B8FB1B243EA7F04CA6BE0E0BE9F43525D3B6718DAA5E2FD3D20BE3F37ED402DAFD7F19C39E51A40868D3F79D45CD422A9F7454DB3FEFF205BE4C10234914FD8882B344DBFB5C2BE5B576EA94EB62C3AFCD012EE7F82F0744BE067736E9A78EF38E6F06474E025776F138AF84E4093AB36683A60D0DB5CB9F75CA7C4303059E0DDCE3A641A3278F5015FD42EAA79B72E5F0D2EFDAADE3B76B23DD4C2A39F359B3CA00F7584B729800B3E01DC3D4CD4B399EA8DDF
-20180404112714 2 6 100 4095 2 C287DA1692C8760D889CABEA6A7055FADB13C9F064C87322D569B9C574001DEBA1685DA8DFFB9A11253F685A3045E2CEBA057C35DD417F717110949007702B25A37AEE60C3A1A9AA6A1667C15BBFFFF173DF27813A74959756822AB34A2BB97B2F408CC6A994ADC83F05CB8028784B859A25032D691F1DDFB1A87F47EDC289FE4452BE4E4D7B07745C1D5A901E7EF0521465DFFC1EECAB7E4F15172A90257AFFCA11B455ADD24067B20C20EDF9B5B59BDFDAE03BF0AB39A13E60515CA8ADE3273BBCA8290D3B581F92B61F1A893ABFF16255A9226638159640F7869B5C30C8FFF3C3378B14E1A5529C8DE120A9E2099388E1217BDDFCC1708F37E74BDE5D0A2DCFDC4DD27BA697C3F8238182DA7C5D02431E086067358CC9A9B4EFF7C8D7FC9F0C8C0528887A194A6D0613AEE1EEDDC7A315AC1A178E9377E488F49367573BA8EDF80FD6EDE2D256F0614AF81B8FB1B243EA7F04CA6BE0E0BE9F43525D3B6718DAA5E2FD3D20BE3F37ED402DAFD7F19C39E51A40868D3F79D45CD422A9F7454DB3FEFF205BE4C10234914FD8882B344DBFB5C2BE5B576EA94EB62C3AFCD012EE7F82F0744BE067736E9A78EF38E6F06474E025776F138AF84E4093AB36683A60D0DB5CB9F75CA7C4303059E0DDCE3A641A3278F5015FD42EAA79B72E5F0D2EFDAADE3B76B23DD4C2A39F359B3CA00F7584B729800B3E01DC3D4CD4B39A1427A3
-20180404115040 2 6 100 4095 2 C287DA1692C8760D889CABEA6A7055FADB13C9F064C87322D569B9C574001DEBA1685DA8DFFB9A11253F685A3045E2CEBA057C35DD417F717110949007702B25A37AEE60C3A1A9AA6A1667C15BBFFFF173DF27813A74959756822AB34A2BB97B2F408CC6A994ADC83F05CB8028784B859A25032D691F1DDFB1A87F47EDC289FE4452BE4E4D7B07745C1D5A901E7EF0521465DFFC1EECAB7E4F15172A90257AFFCA11B455ADD24067B20C20EDF9B5B59BDFDAE03BF0AB39A13E60515CA8ADE3273BBCA8290D3B581F92B61F1A893ABFF16255A9226638159640F7869B5C30C8FFF3C3378B14E1A5529C8DE120A9E2099388E1217BDDFCC1708F37E74BDE5D0A2DCFDC4DD27BA697C3F8238182DA7C5D02431E086067358CC9A9B4EFF7C8D7FC9F0C8C0528887A194A6D0613AEE1EEDDC7A315AC1A178E9377E488F49367573BA8EDF80FD6EDE2D256F0614AF81B8FB1B243EA7F04CA6BE0E0BE9F43525D3B6718DAA5E2FD3D20BE3F37ED402DAFD7F19C39E51A40868D3F79D45CD422A9F7454DB3FEFF205BE4C10234914FD8882B344DBFB5C2BE5B576EA94EB62C3AFCD012EE7F82F0744BE067736E9A78EF38E6F06474E025776F138AF84E4093AB36683A60D0DB5CB9F75CA7C4303059E0DDCE3A641A3278F5015FD42EAA79B72E5F0D2EFDAADE3B76B23DD4C2A39F359B3CA00F7584B729800B3E01DC3D4CD4B39AD94553
-20180404130727 2 6 100 4095 2 C287DA1692C8760D889CABEA6A7055FADB13C9F064C87322D569B9C574001DEBA1685DA8DFFB9A11253F685A3045E2CEBA057C35DD417F717110949007702B25A37AEE60C3A1A9AA6A1667C15BBFFFF173DF27813A74959756822AB34A2BB97B2F408CC6A994ADC83F05CB8028784B859A25032D691F1DDFB1A87F47EDC289FE4452BE4E4D7B07745C1D5A901E7EF0521465DFFC1EECAB7E4F15172A90257AFFCA11B455ADD24067B20C20EDF9B5B59BDFDAE03BF0AB39A13E60515CA8ADE3273BBCA8290D3B581F92B61F1A893ABFF16255A9226638159640F7869B5C30C8FFF3C3378B14E1A5529C8DE120A9E2099388E1217BDDFCC1708F37E74BDE5D0A2DCFDC4DD27BA697C3F8238182DA7C5D02431E086067358CC9A9B4EFF7C8D7FC9F0C8C0528887A194A6D0613AEE1EEDDC7A315AC1A178E9377E488F49367573BA8EDF80FD6EDE2D256F0614AF81B8FB1B243EA7F04CA6BE0E0BE9F43525D3B6718DAA5E2FD3D20BE3F37ED402DAFD7F19C39E51A40868D3F79D45CD422A9F7454DB3FEFF205BE4C10234914FD8882B344DBFB5C2BE5B576EA94EB62C3AFCD012EE7F82F0744BE067736E9A78EF38E6F06474E025776F138AF84E4093AB36683A60D0DB5CB9F75CA7C4303059E0DDCE3A641A3278F5015FD42EAA79B72E5F0D2EFDAADE3B76B23DD4C2A39F359B3CA00F7584B729800B3E01DC3D4CD4B39D6ABE8B
-20180404132841 2 6 100 4095 5 C287DA1692C8760D889CABEA6A7055FADB13C9F064C87322D569B9C574001DEBA1685DA8DFFB9A11253F685A3045E2CEBA057C35DD417F717110949007702B25A37AEE60C3A1A9AA6A1667C15BBFFFF173DF27813A74959756822AB34A2BB97B2F408CC6A994ADC83F05CB8028784B859A25032D691F1DDFB1A87F47EDC289FE4452BE4E4D7B07745C1D5A901E7EF0521465DFFC1EECAB7E4F15172A90257AFFCA11B455ADD24067B20C20EDF9B5B59BDFDAE03BF0AB39A13E60515CA8ADE3273BBCA8290D3B581F92B61F1A893ABFF16255A9226638159640F7869B5C30C8FFF3C3378B14E1A5529C8DE120A9E2099388E1217BDDFCC1708F37E74BDE5D0A2DCFDC4DD27BA697C3F8238182DA7C5D02431E086067358CC9A9B4EFF7C8D7FC9F0C8C0528887A194A6D0613AEE1EEDDC7A315AC1A178E9377E488F49367573BA8EDF80FD6EDE2D256F0614AF81B8FB1B243EA7F04CA6BE0E0BE9F43525D3B6718DAA5E2FD3D20BE3F37ED402DAFD7F19C39E51A40868D3F79D45CD422A9F7454DB3FEFF205BE4C10234914FD8882B344DBFB5C2BE5B576EA94EB62C3AFCD012EE7F82F0744BE067736E9A78EF38E6F06474E025776F138AF84E4093AB36683A60D0DB5CB9F75CA7C4303059E0DDCE3A641A3278F5015FD42EAA79B72E5F0D2EFDAADE3B76B23DD4C2A39F359B3CA00F7584B729800B3E01DC3D4CD4B39E19247F
-20180404140647 2 6 100 4095 2 C287DA1692C8760D889CABEA6A7055FADB13C9F064C87322D569B9C574001DEBA1685DA8DFFB9A11253F685A3045E2CEBA057C35DD417F717110949007702B25A37AEE60C3A1A9AA6A1667C15BBFFFF173DF27813A74959756822AB34A2BB97B2F408CC6A994ADC83F05CB8028784B859A25032D691F1DDFB1A87F47EDC289FE4452BE4E4D7B07745C1D5A901E7EF0521465DFFC1EECAB7E4F15172A90257AFFCA11B455ADD24067B20C20EDF9B5B59BDFDAE03BF0AB39A13E60515CA8ADE3273BBCA8290D3B581F92B61F1A893ABFF16255A9226638159640F7869B5C30C8FFF3C3378B14E1A5529C8DE120A9E2099388E1217BDDFCC1708F37E74BDE5D0A2DCFDC4DD27BA697C3F8238182DA7C5D02431E086067358CC9A9B4EFF7C8D7FC9F0C8C0528887A194A6D0613AEE1EEDDC7A315AC1A178E9377E488F49367573BA8EDF80FD6EDE2D256F0614AF81B8FB1B243EA7F04CA6BE0E0BE9F43525D3B6718DAA5E2FD3D20BE3F37ED402DAFD7F19C39E51A40868D3F79D45CD422A9F7454DB3FEFF205BE4C10234914FD8882B344DBFB5C2BE5B576EA94EB62C3AFCD012EE7F82F0744BE067736E9A78EF38E6F06474E025776F138AF84E4093AB36683A60D0DB5CB9F75CA7C4303059E0DDCE3A641A3278F5015FD42EAA79B72E5F0D2EFDAADE3B76B23DD4C2A39F359B3CA00F7584B729800B3E01DC3D4CD4B39F5CFEAB
-20180404144308 2 6 100 4095 5 C287DA1692C8760D889CABEA6A7055FADB13C9F064C87322D569B9C574001DEBA1685DA8DFFB9A11253F685A3045E2CEBA057C35DD417F717110949007702B25A37AEE60C3A1A9AA6A1667C15BBFFFF173DF27813A74959756822AB34A2BB97B2F408CC6A994ADC83F05CB8028784B859A25032D691F1DDFB1A87F47EDC289FE4452BE4E4D7B07745C1D5A901E7EF0521465DFFC1EECAB7E4F15172A90257AFFCA11B455ADD24067B20C20EDF9B5B59BDFDAE03BF0AB39A13E60515CA8ADE3273BBCA8290D3B581F92B61F1A893ABFF16255A9226638159640F7869B5C30C8FFF3C3378B14E1A5529C8DE120A9E2099388E1217BDDFCC1708F37E74BDE5D0A2DCFDC4DD27BA697C3F8238182DA7C5D02431E086067358CC9A9B4EFF7C8D7FC9F0C8C0528887A194A6D0613AEE1EEDDC7A315AC1A178E9377E488F49367573BA8EDF80FD6EDE2D256F0614AF81B8FB1B243EA7F04CA6BE0E0BE9F43525D3B6718DAA5E2FD3D20BE3F37ED402DAFD7F19C39E51A40868D3F79D45CD422A9F7454DB3FEFF205BE4C10234914FD8882B344DBFB5C2BE5B576EA94EB62C3AFCD012EE7F82F0744BE067736E9A78EF38E6F06474E025776F138AF84E4093AB36683A60D0DB5CB9F75CA7C4303059E0DDCE3A641A3278F5015FD42EAA79B72E5F0D2EFDAADE3B76B23DD4C2A39F359B3CA00F7584B729800B3E01DC3D4CD4B3A087B8A7
-20180404154403 2 6 100 4095 5 C287DA1692C8760D889CABEA6A7055FADB13C9F064C87322D569B9C574001DEBA1685DA8DFFB9A11253F685A3045E2CEBA057C35DD417F717110949007702B25A37AEE60C3A1A9AA6A1667C15BBFFFF173DF27813A74959756822AB34A2BB97B2F408CC6A994ADC83F05CB8028784B859A25032D691F1DDFB1A87F47EDC289FE4452BE4E4D7B07745C1D5A901E7EF0521465DFFC1EECAB7E4F15172A90257AFFCA11B455ADD24067B20C20EDF9B5B59BDFDAE03BF0AB39A13E60515CA8ADE3273BBCA8290D3B581F92B61F1A893ABFF16255A9226638159640F7869B5C30C8FFF3C3378B14E1A5529C8DE120A9E2099388E1217BDDFCC1708F37E74BDE5D0A2DCFDC4DD27BA697C3F8238182DA7C5D02431E086067358CC9A9B4EFF7C8D7FC9F0C8C0528887A194A6D0613AEE1EEDDC7A315AC1A178E9377E488F49367573BA8EDF80FD6EDE2D256F0614AF81B8FB1B243EA7F04CA6BE0E0BE9F43525D3B6718DAA5E2FD3D20BE3F37ED402DAFD7F19C39E51A40868D3F79D45CD422A9F7454DB3FEFF205BE4C10234914FD8882B344DBFB5C2BE5B576EA94EB62C3AFCD012EE7F82F0744BE067736E9A78EF38E6F06474E025776F138AF84E4093AB36683A60D0DB5CB9F75CA7C4303059E0DDCE3A641A3278F5015FD42EAA79B72E5F0D2EFDAADE3B76B23DD4C2A39F359B3CA00F7584B729800B3E01DC3D4CD4B3A271BD2F
-20180404155315 2 6 100 4095 5 C287DA1692C8760D889CABEA6A7055FADB13C9F064C87322D569B9C574001DEBA1685DA8DFFB9A11253F685A3045E2CEBA057C35DD417F717110949007702B25A37AEE60C3A1A9AA6A1667C15BBFFFF173DF27813A74959756822AB34A2BB97B2F408CC6A994ADC83F05CB8028784B859A25032D691F1DDFB1A87F47EDC289FE4452BE4E4D7B07745C1D5A901E7EF0521465DFFC1EECAB7E4F15172A90257AFFCA11B455ADD24067B20C20EDF9B5B59BDFDAE03BF0AB39A13E60515CA8ADE3273BBCA8290D3B581F92B61F1A893ABFF16255A9226638159640F7869B5C30C8FFF3C3378B14E1A5529C8DE120A9E2099388E1217BDDFCC1708F37E74BDE5D0A2DCFDC4DD27BA697C3F8238182DA7C5D02431E086067358CC9A9B4EFF7C8D7FC9F0C8C0528887A194A6D0613AEE1EEDDC7A315AC1A178E9377E488F49367573BA8EDF80FD6EDE2D256F0614AF81B8FB1B243EA7F04CA6BE0E0BE9F43525D3B6718DAA5E2FD3D20BE3F37ED402DAFD7F19C39E51A40868D3F79D45CD422A9F7454DB3FEFF205BE4C10234914FD8882B344DBFB5C2BE5B576EA94EB62C3AFCD012EE7F82F0744BE067736E9A78EF38E6F06474E025776F138AF84E4093AB36683A60D0DB5CB9F75CA7C4303059E0DDCE3A641A3278F5015FD42EAA79B72E5F0D2EFDAADE3B76B23DD4C2A39F359B3CA00F7584B729800B3E01DC3D4CD4B3A2B7E4DF
-20180404164237 2 6 100 4095 2 C287DA1692C8760D889CABEA6A7055FADB13C9F064C87322D569B9C574001DEBA1685DA8DFFB9A11253F685A3045E2CEBA057C35DD417F717110949007702B25A37AEE60C3A1A9AA6A1667C15BBFFFF173DF27813A74959756822AB34A2BB97B2F408CC6A994ADC83F05CB8028784B859A25032D691F1DDFB1A87F47EDC289FE4452BE4E4D7B07745C1D5A901E7EF0521465DFFC1EECAB7E4F15172A90257AFFCA11B455ADD24067B20C20EDF9B5B59BDFDAE03BF0AB39A13E60515CA8ADE3273BBCA8290D3B581F92B61F1A893ABFF16255A9226638159640F7869B5C30C8FFF3C3378B14E1A5529C8DE120A9E2099388E1217BDDFCC1708F37E74BDE5D0A2DCFDC4DD27BA697C3F8238182DA7C5D02431E086067358CC9A9B4EFF7C8D7FC9F0C8C0528887A194A6D0613AEE1EEDDC7A315AC1A178E9377E488F49367573BA8EDF80FD6EDE2D256F0614AF81B8FB1B243EA7F04CA6BE0E0BE9F43525D3B6718DAA5E2FD3D20BE3F37ED402DAFD7F19C39E51A40868D3F79D45CD422A9F7454DB3FEFF205BE4C10234914FD8882B344DBFB5C2BE5B576EA94EB62C3AFCD012EE7F82F0744BE067736E9A78EF38E6F06474E025776F138AF84E4093AB36683A60D0DB5CB9F75CA7C4303059E0DDCE3A641A3278F5015FD42EAA79B72E5F0D2EFDAADE3B76B23DD4C2A39F359B3CA00F7584B729800B3E01DC3D4CD4B3A451FC23
-20180404165126 2 6 100 4095 5 C287DA1692C8760D889CABEA6A7055FADB13C9F064C87322D569B9C574001DEBA1685DA8DFFB9A11253F685A3045E2CEBA057C35DD417F717110949007702B25A37AEE60C3A1A9AA6A1667C15BBFFFF173DF27813A74959756822AB34A2BB97B2F408CC6A994ADC83F05CB8028784B859A25032D691F1DDFB1A87F47EDC289FE4452BE4E4D7B07745C1D5A901E7EF0521465DFFC1EECAB7E4F15172A90257AFFCA11B455ADD24067B20C20EDF9B5B59BDFDAE03BF0AB39A13E60515CA8ADE3273BBCA8290D3B581F92B61F1A893ABFF16255A9226638159640F7869B5C30C8FFF3C3378B14E1A5529C8DE120A9E2099388E1217BDDFCC1708F37E74BDE5D0A2DCFDC4DD27BA697C3F8238182DA7C5D02431E086067358CC9A9B4EFF7C8D7FC9F0C8C0528887A194A6D0613AEE1EEDDC7A315AC1A178E9377E488F49367573BA8EDF80FD6EDE2D256F0614AF81B8FB1B243EA7F04CA6BE0E0BE9F43525D3B6718DAA5E2FD3D20BE3F37ED402DAFD7F19C39E51A40868D3F79D45CD422A9F7454DB3FEFF205BE4C10234914FD8882B344DBFB5C2BE5B576EA94EB62C3AFCD012EE7F82F0744BE067736E9A78EF38E6F06474E025776F138AF84E4093AB36683A60D0DB5CB9F75CA7C4303059E0DDCE3A641A3278F5015FD42EAA79B72E5F0D2EFDAADE3B76B23DD4C2A39F359B3CA00F7584B729800B3E01DC3D4CD4B3A494B437
-20180404172833 2 6 100 4095 2 C287DA1692C8760D889CABEA6A7055FADB13C9F064C87322D569B9C574001DEBA1685DA8DFFB9A11253F685A3045E2CEBA057C35DD417F717110949007702B25A37AEE60C3A1A9AA6A1667C15BBFFFF173DF27813A74959756822AB34A2BB97B2F408CC6A994ADC83F05CB8028784B859A25032D691F1DDFB1A87F47EDC289FE4452BE4E4D7B07745C1D5A901E7EF0521465DFFC1EECAB7E4F15172A90257AFFCA11B455ADD24067B20C20EDF9B5B59BDFDAE03BF0AB39A13E60515CA8ADE3273BBCA8290D3B581F92B61F1A893ABFF16255A9226638159640F7869B5C30C8FFF3C3378B14E1A5529C8DE120A9E2099388E1217BDDFCC1708F37E74BDE5D0A2DCFDC4DD27BA697C3F8238182DA7C5D02431E086067358CC9A9B4EFF7C8D7FC9F0C8C0528887A194A6D0613AEE1EEDDC7A315AC1A178E9377E488F49367573BA8EDF80FD6EDE2D256F0614AF81B8FB1B243EA7F04CA6BE0E0BE9F43525D3B6718DAA5E2FD3D20BE3F37ED402DAFD7F19C39E51A40868D3F79D45CD422A9F7454DB3FEFF205BE4C10234914FD8882B344DBFB5C2BE5B576EA94EB62C3AFCD012EE7F82F0744BE067736E9A78EF38E6F06474E025776F138AF84E4093AB36683A60D0DB5CB9F75CA7C4303059E0DDCE3A641A3278F5015FD42EAA79B72E5F0D2EFDAADE3B76B23DD4C2A39F359B3CA00F7584B729800B3E01DC3D4CD4B3A5C78E83
-20180404175448 2 6 100 4095 2 C287DA1692C8760D889CABEA6A7055FADB13C9F064C87322D569B9C574001DEBA1685DA8DFFB9A11253F685A3045E2CEBA057C35DD417F717110949007702B25A37AEE60C3A1A9AA6A1667C15BBFFFF173DF27813A74959756822AB34A2BB97B2F408CC6A994ADC83F05CB8028784B859A25032D691F1DDFB1A87F47EDC289FE4452BE4E4D7B07745C1D5A901E7EF0521465DFFC1EECAB7E4F15172A90257AFFCA11B455ADD24067B20C20EDF9B5B59BDFDAE03BF0AB39A13E60515CA8ADE3273BBCA8290D3B581F92B61F1A893ABFF16255A9226638159640F7869B5C30C8FFF3C3378B14E1A5529C8DE120A9E2099388E1217BDDFCC1708F37E74BDE5D0A2DCFDC4DD27BA697C3F8238182DA7C5D02431E086067358CC9A9B4EFF7C8D7FC9F0C8C0528887A194A6D0613AEE1EEDDC7A315AC1A178E9377E488F49367573BA8EDF80FD6EDE2D256F0614AF81B8FB1B243EA7F04CA6BE0E0BE9F43525D3B6718DAA5E2FD3D20BE3F37ED402DAFD7F19C39E51A40868D3F79D45CD422A9F7454DB3FEFF205BE4C10234914FD8882B344DBFB5C2BE5B576EA94EB62C3AFCD012EE7F82F0744BE067736E9A78EF38E6F06474E025776F138AF84E4093AB36683A60D0DB5CB9F75CA7C4303059E0DDCE3A641A3278F5015FD42EAA79B72E5F0D2EFDAADE3B76B23DD4C2A39F359B3CA00F7584B729800B3E01DC3D4CD4B3A6A037D3
-20180404183147 2 6 100 4095 2 C287DA1692C8760D889CABEA6A7055FADB13C9F064C87322D569B9C574001DEBA1685DA8DFFB9A11253F685A3045E2CEBA057C35DD417F717110949007702B25A37AEE60C3A1A9AA6A1667C15BBFFFF173DF27813A74959756822AB34A2BB97B2F408CC6A994ADC83F05CB8028784B859A25032D691F1DDFB1A87F47EDC289FE4452BE4E4D7B07745C1D5A901E7EF0521465DFFC1EECAB7E4F15172A90257AFFCA11B455ADD24067B20C20EDF9B5B59BDFDAE03BF0AB39A13E60515CA8ADE3273BBCA8290D3B581F92B61F1A893ABFF16255A9226638159640F7869B5C30C8FFF3C3378B14E1A5529C8DE120A9E2099388E1217BDDFCC1708F37E74BDE5D0A2DCFDC4DD27BA697C3F8238182DA7C5D02431E086067358CC9A9B4EFF7C8D7FC9F0C8C0528887A194A6D0613AEE1EEDDC7A315AC1A178E9377E488F49367573BA8EDF80FD6EDE2D256F0614AF81B8FB1B243EA7F04CA6BE0E0BE9F43525D3B6718DAA5E2FD3D20BE3F37ED402DAFD7F19C39E51A40868D3F79D45CD422A9F7454DB3FEFF205BE4C10234914FD8882B344DBFB5C2BE5B576EA94EB62C3AFCD012EE7F82F0744BE067736E9A78EF38E6F06474E025776F138AF84E4093AB36683A60D0DB5CB9F75CA7C4303059E0DDCE3A641A3278F5015FD42EAA79B72E5F0D2EFDAADE3B76B23DD4C2A39F359B3CA00F7584B729800B3E01DC3D4CD4B3A7D443E3
-20180404183316 2 6 100 4095 2 C287DA1692C8760D889CABEA6A7055FADB13C9F064C87322D569B9C574001DEBA1685DA8DFFB9A11253F685A3045E2CEBA057C35DD417F717110949007702B25A37AEE60C3A1A9AA6A1667C15BBFFFF173DF27813A74959756822AB34A2BB97B2F408CC6A994ADC83F05CB8028784B859A25032D691F1DDFB1A87F47EDC289FE4452BE4E4D7B07745C1D5A901E7EF0521465DFFC1EECAB7E4F15172A90257AFFCA11B455ADD24067B20C20EDF9B5B59BDFDAE03BF0AB39A13E60515CA8ADE3273BBCA8290D3B581F92B61F1A893ABFF16255A9226638159640F7869B5C30C8FFF3C3378B14E1A5529C8DE120A9E2099388E1217BDDFCC1708F37E74BDE5D0A2DCFDC4DD27BA697C3F8238182DA7C5D02431E086067358CC9A9B4EFF7C8D7FC9F0C8C0528887A194A6D0613AEE1EEDDC7A315AC1A178E9377E488F49367573BA8EDF80FD6EDE2D256F0614AF81B8FB1B243EA7F04CA6BE0E0BE9F43525D3B6718DAA5E2FD3D20BE3F37ED402DAFD7F19C39E51A40868D3F79D45CD422A9F7454DB3FEFF205BE4C10234914FD8882B344DBFB5C2BE5B576EA94EB62C3AFCD012EE7F82F0744BE067736E9A78EF38E6F06474E025776F138AF84E4093AB36683A60D0DB5CB9F75CA7C4303059E0DDCE3A641A3278F5015FD42EAA79B72E5F0D2EFDAADE3B76B23DD4C2A39F359B3CA00F7584B729800B3E01DC3D4CD4B3A7D883F3
-20180404190024 2 6 100 4095 5 C287DA1692C8760D889CABEA6A7055FADB13C9F064C87322D569B9C574001DEBA1685DA8DFFB9A11253F685A3045E2CEBA057C35DD417F717110949007702B25A37AEE60C3A1A9AA6A1667C15BBFFFF173DF27813A74959756822AB34A2BB97B2F408CC6A994ADC83F05CB8028784B859A25032D691F1DDFB1A87F47EDC289FE4452BE4E4D7B07745C1D5A901E7EF0521465DFFC1EECAB7E4F15172A90257AFFCA11B455ADD24067B20C20EDF9B5B59BDFDAE03BF0AB39A13E60515CA8ADE3273BBCA8290D3B581F92B61F1A893ABFF16255A9226638159640F7869B5C30C8FFF3C3378B14E1A5529C8DE120A9E2099388E1217BDDFCC1708F37E74BDE5D0A2DCFDC4DD27BA697C3F8238182DA7C5D02431E086067358CC9A9B4EFF7C8D7FC9F0C8C0528887A194A6D0613AEE1EEDDC7A315AC1A178E9377E488F49367573BA8EDF80FD6EDE2D256F0614AF81B8FB1B243EA7F04CA6BE0E0BE9F43525D3B6718DAA5E2FD3D20BE3F37ED402DAFD7F19C39E51A40868D3F79D45CD422A9F7454DB3FEFF205BE4C10234914FD8882B344DBFB5C2BE5B576EA94EB62C3AFCD012EE7F82F0744BE067736E9A78EF38E6F06474E025776F138AF84E4093AB36683A60D0DB5CB9F75CA7C4303059E0DDCE3A641A3278F5015FD42EAA79B72E5F0D2EFDAADE3B76B23DD4C2A39F359B3CA00F7584B729800B3E01DC3D4CD4B3A8B7BF5F
-20180404194132 2 6 100 4095 2 C287DA1692C8760D889CABEA6A7055FADB13C9F064C87322D569B9C574001DEBA1685DA8DFFB9A11253F685A3045E2CEBA057C35DD417F717110949007702B25A37AEE60C3A1A9AA6A1667C15BBFFFF173DF27813A74959756822AB34A2BB97B2F408CC6A994ADC83F05CB8028784B859A25032D691F1DDFB1A87F47EDC289FE4452BE4E4D7B07745C1D5A901E7EF0521465DFFC1EECAB7E4F15172A90257AFFCA11B455ADD24067B20C20EDF9B5B59BDFDAE03BF0AB39A13E60515CA8ADE3273BBCA8290D3B581F92B61F1A893ABFF16255A9226638159640F7869B5C30C8FFF3C3378B14E1A5529C8DE120A9E2099388E1217BDDFCC1708F37E74BDE5D0A2DCFDC4DD27BA697C3F8238182DA7C5D02431E086067358CC9A9B4EFF7C8D7FC9F0C8C0528887A194A6D0613AEE1EEDDC7A315AC1A178E9377E488F49367573BA8EDF80FD6EDE2D256F0614AF81B8FB1B243EA7F04CA6BE0E0BE9F43525D3B6718DAA5E2FD3D20BE3F37ED402DAFD7F19C39E51A40868D3F79D45CD422A9F7454DB3FEFF205BE4C10234914FD8882B344DBFB5C2BE5B576EA94EB62C3AFCD012EE7F82F0744BE067736E9A78EF38E6F06474E025776F138AF84E4093AB36683A60D0DB5CB9F75CA7C4303059E0DDCE3A641A3278F5015FD42EAA79B72E5F0D2EFDAADE3B76B23DD4C2A39F359B3CA00F7584B729800B3E01DC3D4CD4B3AA11DC3B
-20180404195020 2 6 100 4095 2 C287DA1692C8760D889CABEA6A7055FADB13C9F064C87322D569B9C574001DEBA1685DA8DFFB9A11253F685A3045E2CEBA057C35DD417F717110949007702B25A37AEE60C3A1A9AA6A1667C15BBFFFF173DF27813A74959756822AB34A2BB97B2F408CC6A994ADC83F05CB8028784B859A25032D691F1DDFB1A87F47EDC289FE4452BE4E4D7B07745C1D5A901E7EF0521465DFFC1EECAB7E4F15172A90257AFFCA11B455ADD24067B20C20EDF9B5B59BDFDAE03BF0AB39A13E60515CA8ADE3273BBCA8290D3B581F92B61F1A893ABFF16255A9226638159640F7869B5C30C8FFF3C3378B14E1A5529C8DE120A9E2099388E1217BDDFCC1708F37E74BDE5D0A2DCFDC4DD27BA697C3F8238182DA7C5D02431E086067358CC9A9B4EFF7C8D7FC9F0C8C0528887A194A6D0613AEE1EEDDC7A315AC1A178E9377E488F49367573BA8EDF80FD6EDE2D256F0614AF81B8FB1B243EA7F04CA6BE0E0BE9F43525D3B6718DAA5E2FD3D20BE3F37ED402DAFD7F19C39E51A40868D3F79D45CD422A9F7454DB3FEFF205BE4C10234914FD8882B344DBFB5C2BE5B576EA94EB62C3AFCD012EE7F82F0744BE067736E9A78EF38E6F06474E025776F138AF84E4093AB36683A60D0DB5CB9F75CA7C4303059E0DDCE3A641A3278F5015FD42EAA79B72E5F0D2EFDAADE3B76B23DD4C2A39F359B3CA00F7584B729800B3E01DC3D4CD4B3AA5664E3
-20180404195123 2 6 100 4095 2 C287DA1692C8760D889CABEA6A7055FADB13C9F064C87322D569B9C574001DEBA1685DA8DFFB9A11253F685A3045E2CEBA057C35DD417F717110949007702B25A37AEE60C3A1A9AA6A1667C15BBFFFF173DF27813A74959756822AB34A2BB97B2F408CC6A994ADC83F05CB8028784B859A25032D691F1DDFB1A87F47EDC289FE4452BE4E4D7B07745C1D5A901E7EF0521465DFFC1EECAB7E4F15172A90257AFFCA11B455ADD24067B20C20EDF9B5B59BDFDAE03BF0AB39A13E60515CA8ADE3273BBCA8290D3B581F92B61F1A893ABFF16255A9226638159640F7869B5C30C8FFF3C3378B14E1A5529C8DE120A9E2099388E1217BDDFCC1708F37E74BDE5D0A2DCFDC4DD27BA697C3F8238182DA7C5D02431E086067358CC9A9B4EFF7C8D7FC9F0C8C0528887A194A6D0613AEE1EEDDC7A315AC1A178E9377E488F49367573BA8EDF80FD6EDE2D256F0614AF81B8FB1B243EA7F04CA6BE0E0BE9F43525D3B6718DAA5E2FD3D20BE3F37ED402DAFD7F19C39E51A40868D3F79D45CD422A9F7454DB3FEFF205BE4C10234914FD8882B344DBFB5C2BE5B576EA94EB62C3AFCD012EE7F82F0744BE067736E9A78EF38E6F06474E025776F138AF84E4093AB36683A60D0DB5CB9F75CA7C4303059E0DDCE3A641A3278F5015FD42EAA79B72E5F0D2EFDAADE3B76B23DD4C2A39F359B3CA00F7584B729800B3E01DC3D4CD4B3AA56EAF3
-20180404202233 2 6 100 4095 5 C287DA1692C8760D889CABEA6A7055FADB13C9F064C87322D569B9C574001DEBA1685DA8DFFB9A11253F685A3045E2CEBA057C35DD417F717110949007702B25A37AEE60C3A1A9AA6A1667C15BBFFFF173DF27813A74959756822AB34A2BB97B2F408CC6A994ADC83F05CB8028784B859A25032D691F1DDFB1A87F47EDC289FE4452BE4E4D7B07745C1D5A901E7EF0521465DFFC1EECAB7E4F15172A90257AFFCA11B455ADD24067B20C20EDF9B5B59BDFDAE03BF0AB39A13E60515CA8ADE3273BBCA8290D3B581F92B61F1A893ABFF16255A9226638159640F7869B5C30C8FFF3C3378B14E1A5529C8DE120A9E2099388E1217BDDFCC1708F37E74BDE5D0A2DCFDC4DD27BA697C3F8238182DA7C5D02431E086067358CC9A9B4EFF7C8D7FC9F0C8C0528887A194A6D0613AEE1EEDDC7A315AC1A178E9377E488F49367573BA8EDF80FD6EDE2D256F0614AF81B8FB1B243EA7F04CA6BE0E0BE9F43525D3B6718DAA5E2FD3D20BE3F37ED402DAFD7F19C39E51A40868D3F79D45CD422A9F7454DB3FEFF205BE4C10234914FD8882B344DBFB5C2BE5B576EA94EB62C3AFCD012EE7F82F0744BE067736E9A78EF38E6F06474E025776F138AF84E4093AB36683A60D0DB5CB9F75CA7C4303059E0DDCE3A641A3278F5015FD42EAA79B72E5F0D2EFDAADE3B76B23DD4C2A39F359B3CA00F7584B729800B3E01DC3D4CD4B3AB5A9C37
-20180404202802 2 6 100 4095 2 C287DA1692C8760D889CABEA6A7055FADB13C9F064C87322D569B9C574001DEBA1685DA8DFFB9A11253F685A3045E2CEBA057C35DD417F717110949007702B25A37AEE60C3A1A9AA6A1667C15BBFFFF173DF27813A74959756822AB34A2BB97B2F408CC6A994ADC83F05CB8028784B859A25032D691F1DDFB1A87F47EDC289FE4452BE4E4D7B07745C1D5A901E7EF0521465DFFC1EECAB7E4F15172A90257AFFCA11B455ADD24067B20C20EDF9B5B59BDFDAE03BF0AB39A13E60515CA8ADE3273BBCA8290D3B581F92B61F1A893ABFF16255A9226638159640F7869B5C30C8FFF3C3378B14E1A5529C8DE120A9E2099388E1217BDDFCC1708F37E74BDE5D0A2DCFDC4DD27BA697C3F8238182DA7C5D02431E086067358CC9A9B4EFF7C8D7FC9F0C8C0528887A194A6D0613AEE1EEDDC7A315AC1A178E9377E488F49367573BA8EDF80FD6EDE2D256F0614AF81B8FB1B243EA7F04CA6BE0E0BE9F43525D3B6718DAA5E2FD3D20BE3F37ED402DAFD7F19C39E51A40868D3F79D45CD422A9F7454DB3FEFF205BE4C10234914FD8882B344DBFB5C2BE5B576EA94EB62C3AFCD012EE7F82F0744BE067736E9A78EF38E6F06474E025776F138AF84E4093AB36683A60D0DB5CB9F75CA7C4303059E0DDCE3A641A3278F5015FD42EAA79B72E5F0D2EFDAADE3B76B23DD4C2A39F359B3CA00F7584B729800B3E01DC3D4CD4B3AB8229D3
-20180404203244 2 6 100 4095 2 C287DA1692C8760D889CABEA6A7055FADB13C9F064C87322D569B9C574001DEBA1685DA8DFFB9A11253F685A3045E2CEBA057C35DD417F717110949007702B25A37AEE60C3A1A9AA6A1667C15BBFFFF173DF27813A74959756822AB34A2BB97B2F408CC6A994ADC83F05CB8028784B859A25032D691F1DDFB1A87F47EDC289FE4452BE4E4D7B07745C1D5A901E7EF0521465DFFC1EECAB7E4F15172A90257AFFCA11B455ADD24067B20C20EDF9B5B59BDFDAE03BF0AB39A13E60515CA8ADE3273BBCA8290D3B581F92B61F1A893ABFF16255A9226638159640F7869B5C30C8FFF3C3378B14E1A5529C8DE120A9E2099388E1217BDDFCC1708F37E74BDE5D0A2DCFDC4DD27BA697C3F8238182DA7C5D02431E086067358CC9A9B4EFF7C8D7FC9F0C8C0528887A194A6D0613AEE1EEDDC7A315AC1A178E9377E488F49367573BA8EDF80FD6EDE2D256F0614AF81B8FB1B243EA7F04CA6BE0E0BE9F43525D3B6718DAA5E2FD3D20BE3F37ED402DAFD7F19C39E51A40868D3F79D45CD422A9F7454DB3FEFF205BE4C10234914FD8882B344DBFB5C2BE5B576EA94EB62C3AFCD012EE7F82F0744BE067736E9A78EF38E6F06474E025776F138AF84E4093AB36683A60D0DB5CB9F75CA7C4303059E0DDCE3A641A3278F5015FD42EAA79B72E5F0D2EFDAADE3B76B23DD4C2A39F359B3CA00F7584B729800B3E01DC3D4CD4B3ABA0DD8B
-20180404203913 2 6 100 4095 5 C287DA1692C8760D889CABEA6A7055FADB13C9F064C87322D569B9C574001DEBA1685DA8DFFB9A11253F685A3045E2CEBA057C35DD417F717110949007702B25A37AEE60C3A1A9AA6A1667C15BBFFFF173DF27813A74959756822AB34A2BB97B2F408CC6A994ADC83F05CB8028784B859A25032D691F1DDFB1A87F47EDC289FE4452BE4E4D7B07745C1D5A901E7EF0521465DFFC1EECAB7E4F15172A90257AFFCA11B455ADD24067B20C20EDF9B5B59BDFDAE03BF0AB39A13E60515CA8ADE3273BBCA8290D3B581F92B61F1A893ABFF16255A9226638159640F7869B5C30C8FFF3C3378B14E1A5529C8DE120A9E2099388E1217BDDFCC1708F37E74BDE5D0A2DCFDC4DD27BA697C3F8238182DA7C5D02431E086067358CC9A9B4EFF7C8D7FC9F0C8C0528887A194A6D0613AEE1EEDDC7A315AC1A178E9377E488F49367573BA8EDF80FD6EDE2D256F0614AF81B8FB1B243EA7F04CA6BE0E0BE9F43525D3B6718DAA5E2FD3D20BE3F37ED402DAFD7F19C39E51A40868D3F79D45CD422A9F7454DB3FEFF205BE4C10234914FD8882B344DBFB5C2BE5B576EA94EB62C3AFCD012EE7F82F0744BE067736E9A78EF38E6F06474E025776F138AF84E4093AB36683A60D0DB5CB9F75CA7C4303059E0DDCE3A641A3278F5015FD42EAA79B72E5F0D2EFDAADE3B76B23DD4C2A39F359B3CA00F7584B729800B3E01DC3D4CD4B3ABCF8F47
-20180404210704 2 6 100 4095 2 C287DA1692C8760D889CABEA6A7055FADB13C9F064C87322D569B9C574001DEBA1685DA8DFFB9A11253F685A3045E2CEBA057C35DD417F717110949007702B25A37AEE60C3A1A9AA6A1667C15BBFFFF173DF27813A74959756822AB34A2BB97B2F408CC6A994ADC83F05CB8028784B859A25032D691F1DDFB1A87F47EDC289FE4452BE4E4D7B07745C1D5A901E7EF0521465DFFC1EECAB7E4F15172A90257AFFCA11B455ADD24067B20C20EDF9B5B59BDFDAE03BF0AB39A13E60515CA8ADE3273BBCA8290D3B581F92B61F1A893ABFF16255A9226638159640F7869B5C30C8FFF3C3378B14E1A5529C8DE120A9E2099388E1217BDDFCC1708F37E74BDE5D0A2DCFDC4DD27BA697C3F8238182DA7C5D02431E086067358CC9A9B4EFF7C8D7FC9F0C8C0528887A194A6D0613AEE1EEDDC7A315AC1A178E9377E488F49367573BA8EDF80FD6EDE2D256F0614AF81B8FB1B243EA7F04CA6BE0E0BE9F43525D3B6718DAA5E2FD3D20BE3F37ED402DAFD7F19C39E51A40868D3F79D45CD422A9F7454DB3FEFF205BE4C10234914FD8882B344DBFB5C2BE5B576EA94EB62C3AFCD012EE7F82F0744BE067736E9A78EF38E6F06474E025776F138AF84E4093AB36683A60D0DB5CB9F75CA7C4303059E0DDCE3A641A3278F5015FD42EAA79B72E5F0D2EFDAADE3B76B23DD4C2A39F359B3CA00F7584B729800B3E01DC3D4CD4B3ACB6CB0B
-20180404213123 2 6 100 4095 5 C287DA1692C8760D889CABEA6A7055FADB13C9F064C87322D569B9C574001DEBA1685DA8DFFB9A11253F685A3045E2CEBA057C35DD417F717110949007702B25A37AEE60C3A1A9AA6A1667C15BBFFFF173DF27813A74959756822AB34A2BB97B2F408CC6A994ADC83F05CB8028784B859A25032D691F1DDFB1A87F47EDC289FE4452BE4E4D7B07745C1D5A901E7EF0521465DFFC1EECAB7E4F15172A90257AFFCA11B455ADD24067B20C20EDF9B5B59BDFDAE03BF0AB39A13E60515CA8ADE3273BBCA8290D3B581F92B61F1A893ABFF16255A9226638159640F7869B5C30C8FFF3C3378B14E1A5529C8DE120A9E2099388E1217BDDFCC1708F37E74BDE5D0A2DCFDC4DD27BA697C3F8238182DA7C5D02431E086067358CC9A9B4EFF7C8D7FC9F0C8C0528887A194A6D0613AEE1EEDDC7A315AC1A178E9377E488F49367573BA8EDF80FD6EDE2D256F0614AF81B8FB1B243EA7F04CA6BE0E0BE9F43525D3B6718DAA5E2FD3D20BE3F37ED402DAFD7F19C39E51A40868D3F79D45CD422A9F7454DB3FEFF205BE4C10234914FD8882B344DBFB5C2BE5B576EA94EB62C3AFCD012EE7F82F0744BE067736E9A78EF38E6F06474E025776F138AF84E4093AB36683A60D0DB5CB9F75CA7C4303059E0DDCE3A641A3278F5015FD42EAA79B72E5F0D2EFDAADE3B76B23DD4C2A39F359B3CA00F7584B729800B3E01DC3D4CD4B3AD7FE977
-20180404223506 2 6 100 4095 2 C287DA1692C8760D889CABEA6A7055FADB13C9F064C87322D569B9C574001DEBA1685DA8DFFB9A11253F685A3045E2CEBA057C35DD417F717110949007702B25A37AEE60C3A1A9AA6A1667C15BBFFFF173DF27813A74959756822AB34A2BB97B2F408CC6A994ADC83F05CB8028784B859A25032D691F1DDFB1A87F47EDC289FE4452BE4E4D7B07745C1D5A901E7EF0521465DFFC1EECAB7E4F15172A90257AFFCA11B455ADD24067B20C20EDF9B5B59BDFDAE03BF0AB39A13E60515CA8ADE3273BBCA8290D3B581F92B61F1A893ABFF16255A9226638159640F7869B5C30C8FFF3C3378B14E1A5529C8DE120A9E2099388E1217BDDFCC1708F37E74BDE5D0A2DCFDC4DD27BA697C3F8238182DA7C5D02431E086067358CC9A9B4EFF7C8D7FC9F0C8C0528887A194A6D0613AEE1EEDDC7A315AC1A178E9377E488F49367573BA8EDF80FD6EDE2D256F0614AF81B8FB1B243EA7F04CA6BE0E0BE9F43525D3B6718DAA5E2FD3D20BE3F37ED402DAFD7F19C39E51A40868D3F79D45CD422A9F7454DB3FEFF205BE4C10234914FD8882B344DBFB5C2BE5B576EA94EB62C3AFCD012EE7F82F0744BE067736E9A78EF38E6F06474E025776F138AF84E4093AB36683A60D0DB5CB9F75CA7C4303059E0DDCE3A641A3278F5015FD42EAA79B72E5F0D2EFDAADE3B76B23DD4C2A39F359B3CA00F7584B729800B3E01DC3D4CD4B3AF9772FB
-20180404225041 2 6 100 4095 5 C287DA1692C8760D889CABEA6A7055FADB13C9F064C87322D569B9C574001DEBA1685DA8DFFB9A11253F685A3045E2CEBA057C35DD417F717110949007702B25A37AEE60C3A1A9AA6A1667C15BBFFFF173DF27813A74959756822AB34A2BB97B2F408CC6A994ADC83F05CB8028784B859A25032D691F1DDFB1A87F47EDC289FE4452BE4E4D7B07745C1D5A901E7EF0521465DFFC1EECAB7E4F15172A90257AFFCA11B455ADD24067B20C20EDF9B5B59BDFDAE03BF0AB39A13E60515CA8ADE3273BBCA8290D3B581F92B61F1A893ABFF16255A9226638159640F7869B5C30C8FFF3C3378B14E1A5529C8DE120A9E2099388E1217BDDFCC1708F37E74BDE5D0A2DCFDC4DD27BA697C3F8238182DA7C5D02431E086067358CC9A9B4EFF7C8D7FC9F0C8C0528887A194A6D0613AEE1EEDDC7A315AC1A178E9377E488F49367573BA8EDF80FD6EDE2D256F0614AF81B8FB1B243EA7F04CA6BE0E0BE9F43525D3B6718DAA5E2FD3D20BE3F37ED402DAFD7F19C39E51A40868D3F79D45CD422A9F7454DB3FEFF205BE4C10234914FD8882B344DBFB5C2BE5B576EA94EB62C3AFCD012EE7F82F0744BE067736E9A78EF38E6F06474E025776F138AF84E4093AB36683A60D0DB5CB9F75CA7C4303059E0DDCE3A641A3278F5015FD42EAA79B72E5F0D2EFDAADE3B76B23DD4C2A39F359B3CA00F7584B729800B3E01DC3D4CD4B3B016049F
-20180404225753 2 6 100 4095 5 C287DA1692C8760D889CABEA6A7055FADB13C9F064C87322D569B9C574001DEBA1685DA8DFFB9A11253F685A3045E2CEBA057C35DD417F717110949007702B25A37AEE60C3A1A9AA6A1667C15BBFFFF173DF27813A74959756822AB34A2BB97B2F408CC6A994ADC83F05CB8028784B859A25032D691F1DDFB1A87F47EDC289FE4452BE4E4D7B07745C1D5A901E7EF0521465DFFC1EECAB7E4F15172A90257AFFCA11B455ADD24067B20C20EDF9B5B59BDFDAE03BF0AB39A13E60515CA8ADE3273BBCA8290D3B581F92B61F1A893ABFF16255A9226638159640F7869B5C30C8FFF3C3378B14E1A5529C8DE120A9E2099388E1217BDDFCC1708F37E74BDE5D0A2DCFDC4DD27BA697C3F8238182DA7C5D02431E086067358CC9A9B4EFF7C8D7FC9F0C8C0528887A194A6D0613AEE1EEDDC7A315AC1A178E9377E488F49367573BA8EDF80FD6EDE2D256F0614AF81B8FB1B243EA7F04CA6BE0E0BE9F43525D3B6718DAA5E2FD3D20BE3F37ED402DAFD7F19C39E51A40868D3F79D45CD422A9F7454DB3FEFF205BE4C10234914FD8882B344DBFB5C2BE5B576EA94EB62C3AFCD012EE7F82F0744BE067736E9A78EF38E6F06474E025776F138AF84E4093AB36683A60D0DB5CB9F75CA7C4303059E0DDCE3A641A3278F5015FD42EAA79B72E5F0D2EFDAADE3B76B23DD4C2A39F359B3CA00F7584B729800B3E01DC3D4CD4B3B04C3C37
-20180404230652 2 6 100 4095 2 C287DA1692C8760D889CABEA6A7055FADB13C9F064C87322D569B9C574001DEBA1685DA8DFFB9A11253F685A3045E2CEBA057C35DD417F717110949007702B25A37AEE60C3A1A9AA6A1667C15BBFFFF173DF27813A74959756822AB34A2BB97B2F408CC6A994ADC83F05CB8028784B859A25032D691F1DDFB1A87F47EDC289FE4452BE4E4D7B07745C1D5A901E7EF0521465DFFC1EECAB7E4F15172A90257AFFCA11B455ADD24067B20C20EDF9B5B59BDFDAE03BF0AB39A13E60515CA8ADE3273BBCA8290D3B581F92B61F1A893ABFF16255A9226638159640F7869B5C30C8FFF3C3378B14E1A5529C8DE120A9E2099388E1217BDDFCC1708F37E74BDE5D0A2DCFDC4DD27BA697C3F8238182DA7C5D02431E086067358CC9A9B4EFF7C8D7FC9F0C8C0528887A194A6D0613AEE1EEDDC7A315AC1A178E9377E488F49367573BA8EDF80FD6EDE2D256F0614AF81B8FB1B243EA7F04CA6BE0E0BE9F43525D3B6718DAA5E2FD3D20BE3F37ED402DAFD7F19C39E51A40868D3F79D45CD422A9F7454DB3FEFF205BE4C10234914FD8882B344DBFB5C2BE5B576EA94EB62C3AFCD012EE7F82F0744BE067736E9A78EF38E6F06474E025776F138AF84E4093AB36683A60D0DB5CB9F75CA7C4303059E0DDCE3A641A3278F5015FD42EAA79B72E5F0D2EFDAADE3B76B23DD4C2A39F359B3CA00F7584B729800B3E01DC3D4CD4B3B092364B
-20180404231941 2 6 100 4095 5 C287DA1692C8760D889CABEA6A7055FADB13C9F064C87322D569B9C574001DEBA1685DA8DFFB9A11253F685A3045E2CEBA057C35DD417F717110949007702B25A37AEE60C3A1A9AA6A1667C15BBFFFF173DF27813A74959756822AB34A2BB97B2F408CC6A994ADC83F05CB8028784B859A25032D691F1DDFB1A87F47EDC289FE4452BE4E4D7B07745C1D5A901E7EF0521465DFFC1EECAB7E4F15172A90257AFFCA11B455ADD24067B20C20EDF9B5B59BDFDAE03BF0AB39A13E60515CA8ADE3273BBCA8290D3B581F92B61F1A893ABFF16255A9226638159640F7869B5C30C8FFF3C3378B14E1A5529C8DE120A9E2099388E1217BDDFCC1708F37E74BDE5D0A2DCFDC4DD27BA697C3F8238182DA7C5D02431E086067358CC9A9B4EFF7C8D7FC9F0C8C0528887A194A6D0613AEE1EEDDC7A315AC1A178E9377E488F49367573BA8EDF80FD6EDE2D256F0614AF81B8FB1B243EA7F04CA6BE0E0BE9F43525D3B6718DAA5E2FD3D20BE3F37ED402DAFD7F19C39E51A40868D3F79D45CD422A9F7454DB3FEFF205BE4C10234914FD8882B344DBFB5C2BE5B576EA94EB62C3AFCD012EE7F82F0744BE067736E9A78EF38E6F06474E025776F138AF84E4093AB36683A60D0DB5CB9F75CA7C4303059E0DDCE3A641A3278F5015FD42EAA79B72E5F0D2EFDAADE3B76B23DD4C2A39F359B3CA00F7584B729800B3E01DC3D4CD4B3B0F7D807
-20180404232637 2 6 100 4095 2 C287DA1692C8760D889CABEA6A7055FADB13C9F064C87322D569B9C574001DEBA1685DA8DFFB9A11253F685A3045E2CEBA057C35DD417F717110949007702B25A37AEE60C3A1A9AA6A1667C15BBFFFF173DF27813A74959756822AB34A2BB97B2F408CC6A994ADC83F05CB8028784B859A25032D691F1DDFB1A87F47EDC289FE4452BE4E4D7B07745C1D5A901E7EF0521465DFFC1EECAB7E4F15172A90257AFFCA11B455ADD24067B20C20EDF9B5B59BDFDAE03BF0AB39A13E60515CA8ADE3273BBCA8290D3B581F92B61F1A893ABFF16255A9226638159640F7869B5C30C8FFF3C3378B14E1A5529C8DE120A9E2099388E1217BDDFCC1708F37E74BDE5D0A2DCFDC4DD27BA697C3F8238182DA7C5D02431E086067358CC9A9B4EFF7C8D7FC9F0C8C0528887A194A6D0613AEE1EEDDC7A315AC1A178E9377E488F49367573BA8EDF80FD6EDE2D256F0614AF81B8FB1B243EA7F04CA6BE0E0BE9F43525D3B6718DAA5E2FD3D20BE3F37ED402DAFD7F19C39E51A40868D3F79D45CD422A9F7454DB3FEFF205BE4C10234914FD8882B344DBFB5C2BE5B576EA94EB62C3AFCD012EE7F82F0744BE067736E9A78EF38E6F06474E025776F138AF84E4093AB36683A60D0DB5CB9F75CA7C4303059E0DDCE3A641A3278F5015FD42EAA79B72E5F0D2EFDAADE3B76B23DD4C2A39F359B3CA00F7584B729800B3E01DC3D4CD4B3B127CC5B
-20180404233306 2 6 100 4095 2 C287DA1692C8760D889CABEA6A7055FADB13C9F064C87322D569B9C574001DEBA1685DA8DFFB9A11253F685A3045E2CEBA057C35DD417F717110949007702B25A37AEE60C3A1A9AA6A1667C15BBFFFF173DF27813A74959756822AB34A2BB97B2F408CC6A994ADC83F05CB8028784B859A25032D691F1DDFB1A87F47EDC289FE4452BE4E4D7B07745C1D5A901E7EF0521465DFFC1EECAB7E4F15172A90257AFFCA11B455ADD24067B20C20EDF9B5B59BDFDAE03BF0AB39A13E60515CA8ADE3273BBCA8290D3B581F92B61F1A893ABFF16255A9226638159640F7869B5C30C8FFF3C3378B14E1A5529C8DE120A9E2099388E1217BDDFCC1708F37E74BDE5D0A2DCFDC4DD27BA697C3F8238182DA7C5D02431E086067358CC9A9B4EFF7C8D7FC9F0C8C0528887A194A6D0613AEE1EEDDC7A315AC1A178E9377E488F49367573BA8EDF80FD6EDE2D256F0614AF81B8FB1B243EA7F04CA6BE0E0BE9F43525D3B6718DAA5E2FD3D20BE3F37ED402DAFD7F19C39E51A40868D3F79D45CD422A9F7454DB3FEFF205BE4C10234914FD8882B344DBFB5C2BE5B576EA94EB62C3AFCD012EE7F82F0744BE067736E9A78EF38E6F06474E025776F138AF84E4093AB36683A60D0DB5CB9F75CA7C4303059E0DDCE3A641A3278F5015FD42EAA79B72E5F0D2EFDAADE3B76B23DD4C2A39F359B3CA00F7584B729800B3E01DC3D4CD4B3B154E443
-20180405003707 2 6 100 4095 2 C287DA1692C8760D889CABEA6A7055FADB13C9F064C87322D569B9C574001DEBA1685DA8DFFB9A11253F685A3045E2CEBA057C35DD417F717110949007702B25A37AEE60C3A1A9AA6A1667C15BBFFFF173DF27813A74959756822AB34A2BB97B2F408CC6A994ADC83F05CB8028784B859A25032D691F1DDFB1A87F47EDC289FE4452BE4E4D7B07745C1D5A901E7EF0521465DFFC1EECAB7E4F15172A90257AFFCA11B455ADD24067B20C20EDF9B5B59BDFDAE03BF0AB39A13E60515CA8ADE3273BBCA8290D3B581F92B61F1A893ABFF16255A9226638159640F7869B5C30C8FFF3C3378B14E1A5529C8DE120A9E2099388E1217BDDFCC1708F37E74BDE5D0A2DCFDC4DD27BA697C3F8238182DA7C5D02431E086067358CC9A9B4EFF7C8D7FC9F0C8C0528887A194A6D0613AEE1EEDDC7A315AC1A178E9377E488F49367573BA8EDF80FD6EDE2D256F0614AF81B8FB1B243EA7F04CA6BE0E0BE9F43525D3B6718DAA5E2FD3D20BE3F37ED402DAFD7F19C39E51A40868D3F79D45CD422A9F7454DB3FEFF205BE4C10234914FD8882B344DBFB5C2BE5B576EA94EB62C3AFCD012EE7F82F0744BE067736E9A78EF38E6F06474E025776F138AF84E4093AB36683A60D0DB5CB9F75CA7C4303059E0DDCE3A641A3278F5015FD42EAA79B72E5F0D2EFDAADE3B76B23DD4C2A39F359B3CA00F7584B729800B3E01DC3D4CD4B3B373FAF3
-20180405012137 2 6 100 4095 2 C287DA1692C8760D889CABEA6A7055FADB13C9F064C87322D569B9C574001DEBA1685DA8DFFB9A11253F685A3045E2CEBA057C35DD417F717110949007702B25A37AEE60C3A1A9AA6A1667C15BBFFFF173DF27813A74959756822AB34A2BB97B2F408CC6A994ADC83F05CB8028784B859A25032D691F1DDFB1A87F47EDC289FE4452BE4E4D7B07745C1D5A901E7EF0521465DFFC1EECAB7E4F15172A90257AFFCA11B455ADD24067B20C20EDF9B5B59BDFDAE03BF0AB39A13E60515CA8ADE3273BBCA8290D3B581F92B61F1A893ABFF16255A9226638159640F7869B5C30C8FFF3C3378B14E1A5529C8DE120A9E2099388E1217BDDFCC1708F37E74BDE5D0A2DCFDC4DD27BA697C3F8238182DA7C5D02431E086067358CC9A9B4EFF7C8D7FC9F0C8C0528887A194A6D0613AEE1EEDDC7A315AC1A178E9377E488F49367573BA8EDF80FD6EDE2D256F0614AF81B8FB1B243EA7F04CA6BE0E0BE9F43525D3B6718DAA5E2FD3D20BE3F37ED402DAFD7F19C39E51A40868D3F79D45CD422A9F7454DB3FEFF205BE4C10234914FD8882B344DBFB5C2BE5B576EA94EB62C3AFCD012EE7F82F0744BE067736E9A78EF38E6F06474E025776F138AF84E4093AB36683A60D0DB5CB9F75CA7C4303059E0DDCE3A641A3278F5015FD42EAA79B72E5F0D2EFDAADE3B76B23DD4C2A39F359B3CA00F7584B729800B3E01DC3D4CD4B3B4E4FE3B
-20180405071813 2 6 100 6143 2 E0CFB3582CE2D136E662908DCAA4CD666F574807FFFFF04BFB357D087BD132C8B569A579EC7FEDA39DA9FDBC7A8B289953FC1793F1B5D0F13A317C5F25554892D8A4F4EE9E85B9737D1412316C8169810745D8AC420ED45AA5419137F86E811AA101CD8746EDC5AF653499CA5585851205807E7EC4A3241FDD4C302AAC131FE24B2AC3700D3D21A82EB999FD0005E810811CEB2B1279D95E028269503DBF65FB23CBFC595B12BC67EC4A77D00324909088B6FDF511ABA41732957D32CC436FB0BE95E04F46DF57EC93E4FBD8FF12E18288384CBFABB1BD58F4A047CBF1AB831B43C550515DA98CA33697ECEE8AFAC110E7DD284D531324AC21013C86CFBC9DC286B6669534D8E2D40319E9BA9DC5ACE1825354E1869614CBCB708586A9455D20FC3B724C6FBF941EAAB3FFA61647906B890D9C8F2831A59B7A9A4EB6305DAEDE94A0525C8150EA3B27FC405430B82885E8EAA64A46E2E24DA089A0008C09C5B8117F5E5F397DCAC43906067AE2C6A1B7C1D1B2D233EFF6CBC472F328053EB666EC826604ADA4E27CA01FF98B7A5ADCF8FD3A6E2F6AEC4F36CE8D1D847E611CFDDA7B53AE4F0BA6481A2265D134B5B78F8416164B262CF58FA8806090613D09FA2E8CC417AF2A3208F5BB210CA87927C4FB980C9B97A743CC1B3A7BB9E22DD78EDFB52669C4DB24F796C5D99038E140CE81A9DFECE675F200DC0DEC203FB94380EAA8D13F30530A410BCBD393137FBF89AB80D872D6A4A46B303F01E79FA05DEF4F0F2A2ABD0788459E4C678F3952072570971EA5A686E5964D1C3A61E2311F57E7AB8519809243EB88A87A21B6589A16862EE1B9B4DD452950DDBB5D5482099FC667B5F9A43E3F803D9D0030D0D6E0F86DBFD2B0C2A67B9BFB1F318C6DF0745F75F9F59C7CC62F4763FBBFE3517BF28D9B68372674CBB759E150F6F06FB3053343D54DB7959B79C3764FE57AC25EF6728F1A6A2C6D98E56841DC461BBF12BD23E8C058D500435777431ADC23CA373B0F4A43B5E18787925E79113199A368F30692429BF3041D9BC82BFF88147C3DE432169578E304C72D595320436983FC590B
-20180405072141 2 6 100 6143 5 E0CFB3582CE2D136E662908DCAA4CD666F574807FFFFF04BFB357D087BD132C8B569A579EC7FEDA39DA9FDBC7A8B289953FC1793F1B5D0F13A317C5F25554892D8A4F4EE9E85B9737D1412316C8169810745D8AC420ED45AA5419137F86E811AA101CD8746EDC5AF653499CA5585851205807E7EC4A3241FDD4C302AAC131FE24B2AC3700D3D21A82EB999FD0005E810811CEB2B1279D95E028269503DBF65FB23CBFC595B12BC67EC4A77D00324909088B6FDF511ABA41732957D32CC436FB0BE95E04F46DF57EC93E4FBD8FF12E18288384CBFABB1BD58F4A047CBF1AB831B43C550515DA98CA33697ECEE8AFAC110E7DD284D531324AC21013C86CFBC9DC286B6669534D8E2D40319E9BA9DC5ACE1825354E1869614CBCB708586A9455D20FC3B724C6FBF941EAAB3FFA61647906B890D9C8F2831A59B7A9A4EB6305DAEDE94A0525C8150EA3B27FC405430B82885E8EAA64A46E2E24DA089A0008C09C5B8117F5E5F397DCAC43906067AE2C6A1B7C1D1B2D233EFF6CBC472F328053EB666EC826604ADA4E27CA01FF98B7A5ADCF8FD3A6E2F6AEC4F36CE8D1D847E611CFDDA7B53AE4F0BA6481A2265D134B5B78F8416164B262CF58FA8806090613D09FA2E8CC417AF2A3208F5BB210CA87927C4FB980C9B97A743CC1B3A7BB9E22DD78EDFB52669C4DB24F796C5D99038E140CE81A9DFECE675F200DC0DEC203FB94380EAA8D13F30530A410BCBD393137FBF89AB80D872D6A4A46B303F01E79FA05DEF4F0F2A2ABD0788459E4C678F3952072570971EA5A686E5964D1C3A61E2311F57E7AB8519809243EB88A87A21B6589A16862EE1B9B4DD452950DDBB5D5482099FC667B5F9A43E3F803D9D0030D0D6E0F86DBFD2B0C2A67B9BFB1F318C6DF0745F75F9F59C7CC62F4763FBBFE3517BF28D9B68372674CBB759E150F6F06FB3053343D54DB7959B79C3764FE57AC25EF6728F1A6A2C6D98E56841DC461BBF12BD23E8C058D500435777431ADC23CA373B0F4A43B5E18787925E79113199A368F30692429BF3041D9BC82BFF88147C3DE432169578E304C72D595320436983FCDA2F
-20180405132535 2 6 100 6143 2 E0CFB3582CE2D136E662908DCAA4CD666F574807FFFFF04BFB357D087BD132C8B569A579EC7FEDA39DA9FDBC7A8B289953FC1793F1B5D0F13A317C5F25554892D8A4F4EE9E85B9737D1412316C8169810745D8AC420ED45AA5419137F86E811AA101CD8746EDC5AF653499CA5585851205807E7EC4A3241FDD4C302AAC131FE24B2AC3700D3D21A82EB999FD0005E810811CEB2B1279D95E028269503DBF65FB23CBFC595B12BC67EC4A77D00324909088B6FDF511ABA41732957D32CC436FB0BE95E04F46DF57EC93E4FBD8FF12E18288384CBFABB1BD58F4A047CBF1AB831B43C550515DA98CA33697ECEE8AFAC110E7DD284D531324AC21013C86CFBC9DC286B6669534D8E2D40319E9BA9DC5ACE1825354E1869614CBCB708586A9455D20FC3B724C6FBF941EAAB3FFA61647906B890D9C8F2831A59B7A9A4EB6305DAEDE94A0525C8150EA3B27FC405430B82885E8EAA64A46E2E24DA089A0008C09C5B8117F5E5F397DCAC43906067AE2C6A1B7C1D1B2D233EFF6CBC472F328053EB666EC826604ADA4E27CA01FF98B7A5ADCF8FD3A6E2F6AEC4F36CE8D1D847E611CFDDA7B53AE4F0BA6481A2265D134B5B78F8416164B262CF58FA8806090613D09FA2E8CC417AF2A3208F5BB210CA87927C4FB980C9B97A743CC1B3A7BB9E22DD78EDFB52669C4DB24F796C5D99038E140CE81A9DFECE675F200DC0DEC203FB94380EAA8D13F30530A410BCBD393137FBF89AB80D872D6A4A46B303F01E79FA05DEF4F0F2A2ABD0788459E4C678F3952072570971EA5A686E5964D1C3A61E2311F57E7AB8519809243EB88A87A21B6589A16862EE1B9B4DD452950DDBB5D5482099FC667B5F9A43E3F803D9D0030D0D6E0F86DBFD2B0C2A67B9BFB1F318C6DF0745F75F9F59C7CC62F4763FBBFE3517BF28D9B68372674CBB759E150F6F06FB3053343D54DB7959B79C3764FE57AC25EF6728F1A6A2C6D98E56841DC461BBF12BD23E8C058D500435777431ADC23CA373B0F4A43B5E18787925E79113199A368F30692429BF3041D9BC82BFF88147C3DE432169578E304C72D59532043698806F173
-20180405133926 2 6 100 6143 5 E0CFB3582CE2D136E662908DCAA4CD666F574807FFFFF04BFB357D087BD132C8B569A579EC7FEDA39DA9FDBC7A8B289953FC1793F1B5D0F13A317C5F25554892D8A4F4EE9E85B9737D1412316C8169810745D8AC420ED45AA5419137F86E811AA101CD8746EDC5AF653499CA5585851205807E7EC4A3241FDD4C302AAC131FE24B2AC3700D3D21A82EB999FD0005E810811CEB2B1279D95E028269503DBF65FB23CBFC595B12BC67EC4A77D00324909088B6FDF511ABA41732957D32CC436FB0BE95E04F46DF57EC93E4FBD8FF12E18288384CBFABB1BD58F4A047CBF1AB831B43C550515DA98CA33697ECEE8AFAC110E7DD284D531324AC21013C86CFBC9DC286B6669534D8E2D40319E9BA9DC5ACE1825354E1869614CBCB708586A9455D20FC3B724C6FBF941EAAB3FFA61647906B890D9C8F2831A59B7A9A4EB6305DAEDE94A0525C8150EA3B27FC405430B82885E8EAA64A46E2E24DA089A0008C09C5B8117F5E5F397DCAC43906067AE2C6A1B7C1D1B2D233EFF6CBC472F328053EB666EC826604ADA4E27CA01FF98B7A5ADCF8FD3A6E2F6AEC4F36CE8D1D847E611CFDDA7B53AE4F0BA6481A2265D134B5B78F8416164B262CF58FA8806090613D09FA2E8CC417AF2A3208F5BB210CA87927C4FB980C9B97A743CC1B3A7BB9E22DD78EDFB52669C4DB24F796C5D99038E140CE81A9DFECE675F200DC0DEC203FB94380EAA8D13F30530A410BCBD393137FBF89AB80D872D6A4A46B303F01E79FA05DEF4F0F2A2ABD0788459E4C678F3952072570971EA5A686E5964D1C3A61E2311F57E7AB8519809243EB88A87A21B6589A16862EE1B9B4DD452950DDBB5D5482099FC667B5F9A43E3F803D9D0030D0D6E0F86DBFD2B0C2A67B9BFB1F318C6DF0745F75F9F59C7CC62F4763FBBFE3517BF28D9B68372674CBB759E150F6F06FB3053343D54DB7959B79C3764FE57AC25EF6728F1A6A2C6D98E56841DC461BBF12BD23E8C058D500435777431ADC23CA373B0F4A43B5E18787925E79113199A368F30692429BF3041D9BC82BFF88147C3DE432169578E304C72D595320436988262AB7
-20180405165648 2 6 100 6143 2 E0CFB3582CE2D136E662908DCAA4CD666F574807FFFFF04BFB357D087BD132C8B569A579EC7FEDA39DA9FDBC7A8B289953FC1793F1B5D0F13A317C5F25554892D8A4F4EE9E85B9737D1412316C8169810745D8AC420ED45AA5419137F86E811AA101CD8746EDC5AF653499CA5585851205807E7EC4A3241FDD4C302AAC131FE24B2AC3700D3D21A82EB999FD0005E810811CEB2B1279D95E028269503DBF65FB23CBFC595B12BC67EC4A77D00324909088B6FDF511ABA41732957D32CC436FB0BE95E04F46DF57EC93E4FBD8FF12E18288384CBFABB1BD58F4A047CBF1AB831B43C550515DA98CA33697ECEE8AFAC110E7DD284D531324AC21013C86CFBC9DC286B6669534D8E2D40319E9BA9DC5ACE1825354E1869614CBCB708586A9455D20FC3B724C6FBF941EAAB3FFA61647906B890D9C8F2831A59B7A9A4EB6305DAEDE94A0525C8150EA3B27FC405430B82885E8EAA64A46E2E24DA089A0008C09C5B8117F5E5F397DCAC43906067AE2C6A1B7C1D1B2D233EFF6CBC472F328053EB666EC826604ADA4E27CA01FF98B7A5ADCF8FD3A6E2F6AEC4F36CE8D1D847E611CFDDA7B53AE4F0BA6481A2265D134B5B78F8416164B262CF58FA8806090613D09FA2E8CC417AF2A3208F5BB210CA87927C4FB980C9B97A743CC1B3A7BB9E22DD78EDFB52669C4DB24F796C5D99038E140CE81A9DFECE675F200DC0DEC203FB94380EAA8D13F30530A410BCBD393137FBF89AB80D872D6A4A46B303F01E79FA05DEF4F0F2A2ABD0788459E4C678F3952072570971EA5A686E5964D1C3A61E2311F57E7AB8519809243EB88A87A21B6589A16862EE1B9B4DD452950DDBB5D5482099FC667B5F9A43E3F803D9D0030D0D6E0F86DBFD2B0C2A67B9BFB1F318C6DF0745F75F9F59C7CC62F4763FBBFE3517BF28D9B68372674CBB759E150F6F06FB3053343D54DB7959B79C3764FE57AC25EF6728F1A6A2C6D98E56841DC461BBF12BD23E8C058D500435777431ADC23CA373B0F4A43B5E18787925E79113199A368F30692429BF3041D9BC82BFF88147C3DE432169578E304C72D59532043698A47BC0B
-20180405195101 2 6 100 6143 5 E0CFB3582CE2D136E662908DCAA4CD666F574807FFFFF04BFB357D087BD132C8B569A579EC7FEDA39DA9FDBC7A8B289953FC1793F1B5D0F13A317C5F25554892D8A4F4EE9E85B9737D1412316C8169810745D8AC420ED45AA5419137F86E811AA101CD8746EDC5AF653499CA5585851205807E7EC4A3241FDD4C302AAC131FE24B2AC3700D3D21A82EB999FD0005E810811CEB2B1279D95E028269503DBF65FB23CBFC595B12BC67EC4A77D00324909088B6FDF511ABA41732957D32CC436FB0BE95E04F46DF57EC93E4FBD8FF12E18288384CBFABB1BD58F4A047CBF1AB831B43C550515DA98CA33697ECEE8AFAC110E7DD284D531324AC21013C86CFBC9DC286B6669534D8E2D40319E9BA9DC5ACE1825354E1869614CBCB708586A9455D20FC3B724C6FBF941EAAB3FFA61647906B890D9C8F2831A59B7A9A4EB6305DAEDE94A0525C8150EA3B27FC405430B82885E8EAA64A46E2E24DA089A0008C09C5B8117F5E5F397DCAC43906067AE2C6A1B7C1D1B2D233EFF6CBC472F328053EB666EC826604ADA4E27CA01FF98B7A5ADCF8FD3A6E2F6AEC4F36CE8D1D847E611CFDDA7B53AE4F0BA6481A2265D134B5B78F8416164B262CF58FA8806090613D09FA2E8CC417AF2A3208F5BB210CA87927C4FB980C9B97A743CC1B3A7BB9E22DD78EDFB52669C4DB24F796C5D99038E140CE81A9DFECE675F200DC0DEC203FB94380EAA8D13F30530A410BCBD393137FBF89AB80D872D6A4A46B303F01E79FA05DEF4F0F2A2ABD0788459E4C678F3952072570971EA5A686E5964D1C3A61E2311F57E7AB8519809243EB88A87A21B6589A16862EE1B9B4DD452950DDBB5D5482099FC667B5F9A43E3F803D9D0030D0D6E0F86DBFD2B0C2A67B9BFB1F318C6DF0745F75F9F59C7CC62F4763FBBFE3517BF28D9B68372674CBB759E150F6F06FB3053343D54DB7959B79C3764FE57AC25EF6728F1A6A2C6D98E56841DC461BBF12BD23E8C058D500435777431ADC23CA373B0F4A43B5E18787925E79113199A368F30692429BF3041D9BC82BFF88147C3DE432169578E304C72D59532043698C28BB2F
-20180405213026 2 6 100 6143 2 E0CFB3582CE2D136E662908DCAA4CD666F574807FFFFF04BFB357D087BD132C8B569A579EC7FEDA39DA9FDBC7A8B289953FC1793F1B5D0F13A317C5F25554892D8A4F4EE9E85B9737D1412316C8169810745D8AC420ED45AA5419137F86E811AA101CD8746EDC5AF653499CA5585851205807E7EC4A3241FDD4C302AAC131FE24B2AC3700D3D21A82EB999FD0005E810811CEB2B1279D95E028269503DBF65FB23CBFC595B12BC67EC4A77D00324909088B6FDF511ABA41732957D32CC436FB0BE95E04F46DF57EC93E4FBD8FF12E18288384CBFABB1BD58F4A047CBF1AB831B43C550515DA98CA33697ECEE8AFAC110E7DD284D531324AC21013C86CFBC9DC286B6669534D8E2D40319E9BA9DC5ACE1825354E1869614CBCB708586A9455D20FC3B724C6FBF941EAAB3FFA61647906B890D9C8F2831A59B7A9A4EB6305DAEDE94A0525C8150EA3B27FC405430B82885E8EAA64A46E2E24DA089A0008C09C5B8117F5E5F397DCAC43906067AE2C6A1B7C1D1B2D233EFF6CBC472F328053EB666EC826604ADA4E27CA01FF98B7A5ADCF8FD3A6E2F6AEC4F36CE8D1D847E611CFDDA7B53AE4F0BA6481A2265D134B5B78F8416164B262CF58FA8806090613D09FA2E8CC417AF2A3208F5BB210CA87927C4FB980C9B97A743CC1B3A7BB9E22DD78EDFB52669C4DB24F796C5D99038E140CE81A9DFECE675F200DC0DEC203FB94380EAA8D13F30530A410BCBD393137FBF89AB80D872D6A4A46B303F01E79FA05DEF4F0F2A2ABD0788459E4C678F3952072570971EA5A686E5964D1C3A61E2311F57E7AB8519809243EB88A87A21B6589A16862EE1B9B4DD452950DDBB5D5482099FC667B5F9A43E3F803D9D0030D0D6E0F86DBFD2B0C2A67B9BFB1F318C6DF0745F75F9F59C7CC62F4763FBBFE3517BF28D9B68372674CBB759E150F6F06FB3053343D54DB7959B79C3764FE57AC25EF6728F1A6A2C6D98E56841DC461BBF12BD23E8C058D500435777431ADC23CA373B0F4A43B5E18787925E79113199A368F30692429BF3041D9BC82BFF88147C3DE432169578E304C72D59532043698D395FBB
-20180405220015 2 6 100 6143 5 E0CFB3582CE2D136E662908DCAA4CD666F574807FFFFF04BFB357D087BD132C8B569A579EC7FEDA39DA9FDBC7A8B289953FC1793F1B5D0F13A317C5F25554892D8A4F4EE9E85B9737D1412316C8169810745D8AC420ED45AA5419137F86E811AA101CD8746EDC5AF653499CA5585851205807E7EC4A3241FDD4C302AAC131FE24B2AC3700D3D21A82EB999FD0005E810811CEB2B1279D95E028269503DBF65FB23CBFC595B12BC67EC4A77D00324909088B6FDF511ABA41732957D32CC436FB0BE95E04F46DF57EC93E4FBD8FF12E18288384CBFABB1BD58F4A047CBF1AB831B43C550515DA98CA33697ECEE8AFAC110E7DD284D531324AC21013C86CFBC9DC286B6669534D8E2D40319E9BA9DC5ACE1825354E1869614CBCB708586A9455D20FC3B724C6FBF941EAAB3FFA61647906B890D9C8F2831A59B7A9A4EB6305DAEDE94A0525C8150EA3B27FC405430B82885E8EAA64A46E2E24DA089A0008C09C5B8117F5E5F397DCAC43906067AE2C6A1B7C1D1B2D233EFF6CBC472F328053EB666EC826604ADA4E27CA01FF98B7A5ADCF8FD3A6E2F6AEC4F36CE8D1D847E611CFDDA7B53AE4F0BA6481A2265D134B5B78F8416164B262CF58FA8806090613D09FA2E8CC417AF2A3208F5BB210CA87927C4FB980C9B97A743CC1B3A7BB9E22DD78EDFB52669C4DB24F796C5D99038E140CE81A9DFECE675F200DC0DEC203FB94380EAA8D13F30530A410BCBD393137FBF89AB80D872D6A4A46B303F01E79FA05DEF4F0F2A2ABD0788459E4C678F3952072570971EA5A686E5964D1C3A61E2311F57E7AB8519809243EB88A87A21B6589A16862EE1B9B4DD452950DDBB5D5482099FC667B5F9A43E3F803D9D0030D0D6E0F86DBFD2B0C2A67B9BFB1F318C6DF0745F75F9F59C7CC62F4763FBBFE3517BF28D9B68372674CBB759E150F6F06FB3053343D54DB7959B79C3764FE57AC25EF6728F1A6A2C6D98E56841DC461BBF12BD23E8C058D500435777431ADC23CA373B0F4A43B5E18787925E79113199A368F30692429BF3041D9BC82BFF88147C3DE432169578E304C72D59532043698D843327
-20180405231702 2 6 100 6143 5 E0CFB3582CE2D136E662908DCAA4CD666F574807FFFFF04BFB357D087BD132C8B569A579EC7FEDA39DA9FDBC7A8B289953FC1793F1B5D0F13A317C5F25554892D8A4F4EE9E85B9737D1412316C8169810745D8AC420ED45AA5419137F86E811AA101CD8746EDC5AF653499CA5585851205807E7EC4A3241FDD4C302AAC131FE24B2AC3700D3D21A82EB999FD0005E810811CEB2B1279D95E028269503DBF65FB23CBFC595B12BC67EC4A77D00324909088B6FDF511ABA41732957D32CC436FB0BE95E04F46DF57EC93E4FBD8FF12E18288384CBFABB1BD58F4A047CBF1AB831B43C550515DA98CA33697ECEE8AFAC110E7DD284D531324AC21013C86CFBC9DC286B6669534D8E2D40319E9BA9DC5ACE1825354E1869614CBCB708586A9455D20FC3B724C6FBF941EAAB3FFA61647906B890D9C8F2831A59B7A9A4EB6305DAEDE94A0525C8150EA3B27FC405430B82885E8EAA64A46E2E24DA089A0008C09C5B8117F5E5F397DCAC43906067AE2C6A1B7C1D1B2D233EFF6CBC472F328053EB666EC826604ADA4E27CA01FF98B7A5ADCF8FD3A6E2F6AEC4F36CE8D1D847E611CFDDA7B53AE4F0BA6481A2265D134B5B78F8416164B262CF58FA8806090613D09FA2E8CC417AF2A3208F5BB210CA87927C4FB980C9B97A743CC1B3A7BB9E22DD78EDFB52669C4DB24F796C5D99038E140CE81A9DFECE675F200DC0DEC203FB94380EAA8D13F30530A410BCBD393137FBF89AB80D872D6A4A46B303F01E79FA05DEF4F0F2A2ABD0788459E4C678F3952072570971EA5A686E5964D1C3A61E2311F57E7AB8519809243EB88A87A21B6589A16862EE1B9B4DD452950DDBB5D5482099FC667B5F9A43E3F803D9D0030D0D6E0F86DBFD2B0C2A67B9BFB1F318C6DF0745F75F9F59C7CC62F4763FBBFE3517BF28D9B68372674CBB759E150F6F06FB3053343D54DB7959B79C3764FE57AC25EF6728F1A6A2C6D98E56841DC461BBF12BD23E8C058D500435777431ADC23CA373B0F4A43B5E18787925E79113199A368F30692429BF3041D9BC82BFF88147C3DE432169578E304C72D59532043698E544067
-20180406025336 2 6 100 6143 2 E0CFB3582CE2D136E662908DCAA4CD666F574807FFFFF04BFB357D087BD132C8B569A579EC7FEDA39DA9FDBC7A8B289953FC1793F1B5D0F13A317C5F25554892D8A4F4EE9E85B9737D1412316C8169810745D8AC420ED45AA5419137F86E811AA101CD8746EDC5AF653499CA5585851205807E7EC4A3241FDD4C302AAC131FE24B2AC3700D3D21A82EB999FD0005E810811CEB2B1279D95E028269503DBF65FB23CBFC595B12BC67EC4A77D00324909088B6FDF511ABA41732957D32CC436FB0BE95E04F46DF57EC93E4FBD8FF12E18288384CBFABB1BD58F4A047CBF1AB831B43C550515DA98CA33697ECEE8AFAC110E7DD284D531324AC21013C86CFBC9DC286B6669534D8E2D40319E9BA9DC5ACE1825354E1869614CBCB708586A9455D20FC3B724C6FBF941EAAB3FFA61647906B890D9C8F2831A59B7A9A4EB6305DAEDE94A0525C8150EA3B27FC405430B82885E8EAA64A46E2E24DA089A0008C09C5B8117F5E5F397DCAC43906067AE2C6A1B7C1D1B2D233EFF6CBC472F328053EB666EC826604ADA4E27CA01FF98B7A5ADCF8FD3A6E2F6AEC4F36CE8D1D847E611CFDDA7B53AE4F0BA6481A2265D134B5B78F8416164B262CF58FA8806090613D09FA2E8CC417AF2A3208F5BB210CA87927C4FB980C9B97A743CC1B3A7BB9E22DD78EDFB52669C4DB24F796C5D99038E140CE81A9DFECE675F200DC0DEC203FB94380EAA8D13F30530A410BCBD393137FBF89AB80D872D6A4A46B303F01E79FA05DEF4F0F2A2ABD0788459E4C678F3952072570971EA5A686E5964D1C3A61E2311F57E7AB8519809243EB88A87A21B6589A16862EE1B9B4DD452950DDBB5D5482099FC667B5F9A43E3F803D9D0030D0D6E0F86DBFD2B0C2A67B9BFB1F318C6DF0745F75F9F59C7CC62F4763FBBFE3517BF28D9B68372674CBB759E150F6F06FB3053343D54DB7959B79C3764FE57AC25EF6728F1A6A2C6D98E56841DC461BBF12BD23E8C058D500435777431ADC23CA373B0F4A43B5E18787925E79113199A368F30692429BF3041D9BC82BFF88147C3DE432169578E304C72D595320436990AEC063
-20180406035121 2 6 100 6143 2 E0CFB3582CE2D136E662908DCAA4CD666F574807FFFFF04BFB357D087BD132C8B569A579EC7FEDA39DA9FDBC7A8B289953FC1793F1B5D0F13A317C5F25554892D8A4F4EE9E85B9737D1412316C8169810745D8AC420ED45AA5419137F86E811AA101CD8746EDC5AF653499CA5585851205807E7EC4A3241FDD4C302AAC131FE24B2AC3700D3D21A82EB999FD0005E810811CEB2B1279D95E028269503DBF65FB23CBFC595B12BC67EC4A77D00324909088B6FDF511ABA41732957D32CC436FB0BE95E04F46DF57EC93E4FBD8FF12E18288384CBFABB1BD58F4A047CBF1AB831B43C550515DA98CA33697ECEE8AFAC110E7DD284D531324AC21013C86CFBC9DC286B6669534D8E2D40319E9BA9DC5ACE1825354E1869614CBCB708586A9455D20FC3B724C6FBF941EAAB3FFA61647906B890D9C8F2831A59B7A9A4EB6305DAEDE94A0525C8150EA3B27FC405430B82885E8EAA64A46E2E24DA089A0008C09C5B8117F5E5F397DCAC43906067AE2C6A1B7C1D1B2D233EFF6CBC472F328053EB666EC826604ADA4E27CA01FF98B7A5ADCF8FD3A6E2F6AEC4F36CE8D1D847E611CFDDA7B53AE4F0BA6481A2265D134B5B78F8416164B262CF58FA8806090613D09FA2E8CC417AF2A3208F5BB210CA87927C4FB980C9B97A743CC1B3A7BB9E22DD78EDFB52669C4DB24F796C5D99038E140CE81A9DFECE675F200DC0DEC203FB94380EAA8D13F30530A410BCBD393137FBF89AB80D872D6A4A46B303F01E79FA05DEF4F0F2A2ABD0788459E4C678F3952072570971EA5A686E5964D1C3A61E2311F57E7AB8519809243EB88A87A21B6589A16862EE1B9B4DD452950DDBB5D5482099FC667B5F9A43E3F803D9D0030D0D6E0F86DBFD2B0C2A67B9BFB1F318C6DF0745F75F9F59C7CC62F4763FBBFE3517BF28D9B68372674CBB759E150F6F06FB3053343D54DB7959B79C3764FE57AC25EF6728F1A6A2C6D98E56841DC461BBF12BD23E8C058D500435777431ADC23CA373B0F4A43B5E18787925E79113199A368F30692429BF3041D9BC82BFF88147C3DE432169578E304C72D59532043699149227B
-20180406063935 2 6 100 6143 2 E0CFB3582CE2D136E662908DCAA4CD666F574807FFFFF04BFB357D087BD132C8B569A579EC7FEDA39DA9FDBC7A8B289953FC1793F1B5D0F13A317C5F25554892D8A4F4EE9E85B9737D1412316C8169810745D8AC420ED45AA5419137F86E811AA101CD8746EDC5AF653499CA5585851205807E7EC4A3241FDD4C302AAC131FE24B2AC3700D3D21A82EB999FD0005E810811CEB2B1279D95E028269503DBF65FB23CBFC595B12BC67EC4A77D00324909088B6FDF511ABA41732957D32CC436FB0BE95E04F46DF57EC93E4FBD8FF12E18288384CBFABB1BD58F4A047CBF1AB831B43C550515DA98CA33697ECEE8AFAC110E7DD284D531324AC21013C86CFBC9DC286B6669534D8E2D40319E9BA9DC5ACE1825354E1869614CBCB708586A9455D20FC3B724C6FBF941EAAB3FFA61647906B890D9C8F2831A59B7A9A4EB6305DAEDE94A0525C8150EA3B27FC405430B82885E8EAA64A46E2E24DA089A0008C09C5B8117F5E5F397DCAC43906067AE2C6A1B7C1D1B2D233EFF6CBC472F328053EB666EC826604ADA4E27CA01FF98B7A5ADCF8FD3A6E2F6AEC4F36CE8D1D847E611CFDDA7B53AE4F0BA6481A2265D134B5B78F8416164B262CF58FA8806090613D09FA2E8CC417AF2A3208F5BB210CA87927C4FB980C9B97A743CC1B3A7BB9E22DD78EDFB52669C4DB24F796C5D99038E140CE81A9DFECE675F200DC0DEC203FB94380EAA8D13F30530A410BCBD393137FBF89AB80D872D6A4A46B303F01E79FA05DEF4F0F2A2ABD0788459E4C678F3952072570971EA5A686E5964D1C3A61E2311F57E7AB8519809243EB88A87A21B6589A16862EE1B9B4DD452950DDBB5D5482099FC667B5F9A43E3F803D9D0030D0D6E0F86DBFD2B0C2A67B9BFB1F318C6DF0745F75F9F59C7CC62F4763FBBFE3517BF28D9B68372674CBB759E150F6F06FB3053343D54DB7959B79C3764FE57AC25EF6728F1A6A2C6D98E56841DC461BBF12BD23E8C058D500435777431ADC23CA373B0F4A43B5E18787925E79113199A368F30692429BF3041D9BC82BFF88147C3DE432169578E304C72D595320436992C6FC43
-20180406115213 2 6 100 6143 5 E0CFB3582CE2D136E662908DCAA4CD666F574807FFFFF04BFB357D087BD132C8B569A579EC7FEDA39DA9FDBC7A8B289953FC1793F1B5D0F13A317C5F25554892D8A4F4EE9E85B9737D1412316C8169810745D8AC420ED45AA5419137F86E811AA101CD8746EDC5AF653499CA5585851205807E7EC4A3241FDD4C302AAC131FE24B2AC3700D3D21A82EB999FD0005E810811CEB2B1279D95E028269503DBF65FB23CBFC595B12BC67EC4A77D00324909088B6FDF511ABA41732957D32CC436FB0BE95E04F46DF57EC93E4FBD8FF12E18288384CBFABB1BD58F4A047CBF1AB831B43C550515DA98CA33697ECEE8AFAC110E7DD284D531324AC21013C86CFBC9DC286B6669534D8E2D40319E9BA9DC5ACE1825354E1869614CBCB708586A9455D20FC3B724C6FBF941EAAB3FFA61647906B890D9C8F2831A59B7A9A4EB6305DAEDE94A0525C8150EA3B27FC405430B82885E8EAA64A46E2E24DA089A0008C09C5B8117F5E5F397DCAC43906067AE2C6A1B7C1D1B2D233EFF6CBC472F328053EB666EC826604ADA4E27CA01FF98B7A5ADCF8FD3A6E2F6AEC4F36CE8D1D847E611CFDDA7B53AE4F0BA6481A2265D134B5B78F8416164B262CF58FA8806090613D09FA2E8CC417AF2A3208F5BB210CA87927C4FB980C9B97A743CC1B3A7BB9E22DD78EDFB52669C4DB24F796C5D99038E140CE81A9DFECE675F200DC0DEC203FB94380EAA8D13F30530A410BCBD393137FBF89AB80D872D6A4A46B303F01E79FA05DEF4F0F2A2ABD0788459E4C678F3952072570971EA5A686E5964D1C3A61E2311F57E7AB8519809243EB88A87A21B6589A16862EE1B9B4DD452950DDBB5D5482099FC667B5F9A43E3F803D9D0030D0D6E0F86DBFD2B0C2A67B9BFB1F318C6DF0745F75F9F59C7CC62F4763FBBFE3517BF28D9B68372674CBB759E150F6F06FB3053343D54DB7959B79C3764FE57AC25EF6728F1A6A2C6D98E56841DC461BBF12BD23E8C058D500435777431ADC23CA373B0F4A43B5E18787925E79113199A368F30692429BF3041D9BC82BFF88147C3DE432169578E304C72D595320436995ACE13F
-20180406155248 2 6 100 6143 5 E0CFB3582CE2D136E662908DCAA4CD666F574807FFFFF04BFB357D087BD132C8B569A579EC7FEDA39DA9FDBC7A8B289953FC1793F1B5D0F13A317C5F25554892D8A4F4EE9E85B9737D1412316C8169810745D8AC420ED45AA5419137F86E811AA101CD8746EDC5AF653499CA5585851205807E7EC4A3241FDD4C302AAC131FE24B2AC3700D3D21A82EB999FD0005E810811CEB2B1279D95E028269503DBF65FB23CBFC595B12BC67EC4A77D00324909088B6FDF511ABA41732957D32CC436FB0BE95E04F46DF57EC93E4FBD8FF12E18288384CBFABB1BD58F4A047CBF1AB831B43C550515DA98CA33697ECEE8AFAC110E7DD284D531324AC21013C86CFBC9DC286B6669534D8E2D40319E9BA9DC5ACE1825354E1869614CBCB708586A9455D20FC3B724C6FBF941EAAB3FFA61647906B890D9C8F2831A59B7A9A4EB6305DAEDE94A0525C8150EA3B27FC405430B82885E8EAA64A46E2E24DA089A0008C09C5B8117F5E5F397DCAC43906067AE2C6A1B7C1D1B2D233EFF6CBC472F328053EB666EC826604ADA4E27CA01FF98B7A5ADCF8FD3A6E2F6AEC4F36CE8D1D847E611CFDDA7B53AE4F0BA6481A2265D134B5B78F8416164B262CF58FA8806090613D09FA2E8CC417AF2A3208F5BB210CA87927C4FB980C9B97A743CC1B3A7BB9E22DD78EDFB52669C4DB24F796C5D99038E140CE81A9DFECE675F200DC0DEC203FB94380EAA8D13F30530A410BCBD393137FBF89AB80D872D6A4A46B303F01E79FA05DEF4F0F2A2ABD0788459E4C678F3952072570971EA5A686E5964D1C3A61E2311F57E7AB8519809243EB88A87A21B6589A16862EE1B9B4DD452950DDBB5D5482099FC667B5F9A43E3F803D9D0030D0D6E0F86DBFD2B0C2A67B9BFB1F318C6DF0745F75F9F59C7CC62F4763FBBFE3517BF28D9B68372674CBB759E150F6F06FB3053343D54DB7959B79C3764FE57AC25EF6728F1A6A2C6D98E56841DC461BBF12BD23E8C058D500435777431ADC23CA373B0F4A43B5E18787925E79113199A368F30692429BF3041D9BC82BFF88147C3DE432169578E304C72D595320436997C8EA27
-20180406170431 2 6 100 6143 2 E0CFB3582CE2D136E662908DCAA4CD666F574807FFFFF04BFB357D087BD132C8B569A579EC7FEDA39DA9FDBC7A8B289953FC1793F1B5D0F13A317C5F25554892D8A4F4EE9E85B9737D1412316C8169810745D8AC420ED45AA5419137F86E811AA101CD8746EDC5AF653499CA5585851205807E7EC4A3241FDD4C302AAC131FE24B2AC3700D3D21A82EB999FD0005E810811CEB2B1279D95E028269503DBF65FB23CBFC595B12BC67EC4A77D00324909088B6FDF511ABA41732957D32CC436FB0BE95E04F46DF57EC93E4FBD8FF12E18288384CBFABB1BD58F4A047CBF1AB831B43C550515DA98CA33697ECEE8AFAC110E7DD284D531324AC21013C86CFBC9DC286B6669534D8E2D40319E9BA9DC5ACE1825354E1869614CBCB708586A9455D20FC3B724C6FBF941EAAB3FFA61647906B890D9C8F2831A59B7A9A4EB6305DAEDE94A0525C8150EA3B27FC405430B82885E8EAA64A46E2E24DA089A0008C09C5B8117F5E5F397DCAC43906067AE2C6A1B7C1D1B2D233EFF6CBC472F328053EB666EC826604ADA4E27CA01FF98B7A5ADCF8FD3A6E2F6AEC4F36CE8D1D847E611CFDDA7B53AE4F0BA6481A2265D134B5B78F8416164B262CF58FA8806090613D09FA2E8CC417AF2A3208F5BB210CA87927C4FB980C9B97A743CC1B3A7BB9E22DD78EDFB52669C4DB24F796C5D99038E140CE81A9DFECE675F200DC0DEC203FB94380EAA8D13F30530A410BCBD393137FBF89AB80D872D6A4A46B303F01E79FA05DEF4F0F2A2ABD0788459E4C678F3952072570971EA5A686E5964D1C3A61E2311F57E7AB8519809243EB88A87A21B6589A16862EE1B9B4DD452950DDBB5D5482099FC667B5F9A43E3F803D9D0030D0D6E0F86DBFD2B0C2A67B9BFB1F318C6DF0745F75F9F59C7CC62F4763FBBFE3517BF28D9B68372674CBB759E150F6F06FB3053343D54DB7959B79C3764FE57AC25EF6728F1A6A2C6D98E56841DC461BBF12BD23E8C058D500435777431ADC23CA373B0F4A43B5E18787925E79113199A368F30692429BF3041D9BC82BFF88147C3DE432169578E304C72D595320436998593AD3
-20180406184640 2 6 100 6143 5 E0CFB3582CE2D136E662908DCAA4CD666F574807FFFFF04BFB357D087BD132C8B569A579EC7FEDA39DA9FDBC7A8B289953FC1793F1B5D0F13A317C5F25554892D8A4F4EE9E85B9737D1412316C8169810745D8AC420ED45AA5419137F86E811AA101CD8746EDC5AF653499CA5585851205807E7EC4A3241FDD4C302AAC131FE24B2AC3700D3D21A82EB999FD0005E810811CEB2B1279D95E028269503DBF65FB23CBFC595B12BC67EC4A77D00324909088B6FDF511ABA41732957D32CC436FB0BE95E04F46DF57EC93E4FBD8FF12E18288384CBFABB1BD58F4A047CBF1AB831B43C550515DA98CA33697ECEE8AFAC110E7DD284D531324AC21013C86CFBC9DC286B6669534D8E2D40319E9BA9DC5ACE1825354E1869614CBCB708586A9455D20FC3B724C6FBF941EAAB3FFA61647906B890D9C8F2831A59B7A9A4EB6305DAEDE94A0525C8150EA3B27FC405430B82885E8EAA64A46E2E24DA089A0008C09C5B8117F5E5F397DCAC43906067AE2C6A1B7C1D1B2D233EFF6CBC472F328053EB666EC826604ADA4E27CA01FF98B7A5ADCF8FD3A6E2F6AEC4F36CE8D1D847E611CFDDA7B53AE4F0BA6481A2265D134B5B78F8416164B262CF58FA8806090613D09FA2E8CC417AF2A3208F5BB210CA87927C4FB980C9B97A743CC1B3A7BB9E22DD78EDFB52669C4DB24F796C5D99038E140CE81A9DFECE675F200DC0DEC203FB94380EAA8D13F30530A410BCBD393137FBF89AB80D872D6A4A46B303F01E79FA05DEF4F0F2A2ABD0788459E4C678F3952072570971EA5A686E5964D1C3A61E2311F57E7AB8519809243EB88A87A21B6589A16862EE1B9B4DD452950DDBB5D5482099FC667B5F9A43E3F803D9D0030D0D6E0F86DBFD2B0C2A67B9BFB1F318C6DF0745F75F9F59C7CC62F4763FBBFE3517BF28D9B68372674CBB759E150F6F06FB3053343D54DB7959B79C3764FE57AC25EF6728F1A6A2C6D98E56841DC461BBF12BD23E8C058D500435777431ADC23CA373B0F4A43B5E18787925E79113199A368F30692429BF3041D9BC82BFF88147C3DE432169578E304C72D59532043699940ADB7
-20180407000748 2 6 100 6143 2 E0CFB3582CE2D136E662908DCAA4CD666F574807FFFFF04BFB357D087BD132C8B569A579EC7FEDA39DA9FDBC7A8B289953FC1793F1B5D0F13A317C5F25554892D8A4F4EE9E85B9737D1412316C8169810745D8AC420ED45AA5419137F86E811AA101CD8746EDC5AF653499CA5585851205807E7EC4A3241FDD4C302AAC131FE24B2AC3700D3D21A82EB999FD0005E810811CEB2B1279D95E028269503DBF65FB23CBFC595B12BC67EC4A77D00324909088B6FDF511ABA41732957D32CC436FB0BE95E04F46DF57EC93E4FBD8FF12E18288384CBFABB1BD58F4A047CBF1AB831B43C550515DA98CA33697ECEE8AFAC110E7DD284D531324AC21013C86CFBC9DC286B6669534D8E2D40319E9BA9DC5ACE1825354E1869614CBCB708586A9455D20FC3B724C6FBF941EAAB3FFA61647906B890D9C8F2831A59B7A9A4EB6305DAEDE94A0525C8150EA3B27FC405430B82885E8EAA64A46E2E24DA089A0008C09C5B8117F5E5F397DCAC43906067AE2C6A1B7C1D1B2D233EFF6CBC472F328053EB666EC826604ADA4E27CA01FF98B7A5ADCF8FD3A6E2F6AEC4F36CE8D1D847E611CFDDA7B53AE4F0BA6481A2265D134B5B78F8416164B262CF58FA8806090613D09FA2E8CC417AF2A3208F5BB210CA87927C4FB980C9B97A743CC1B3A7BB9E22DD78EDFB52669C4DB24F796C5D99038E140CE81A9DFECE675F200DC0DEC203FB94380EAA8D13F30530A410BCBD393137FBF89AB80D872D6A4A46B303F01E79FA05DEF4F0F2A2ABD0788459E4C678F3952072570971EA5A686E5964D1C3A61E2311F57E7AB8519809243EB88A87A21B6589A16862EE1B9B4DD452950DDBB5D5482099FC667B5F9A43E3F803D9D0030D0D6E0F86DBFD2B0C2A67B9BFB1F318C6DF0745F75F9F59C7CC62F4763FBBFE3517BF28D9B68372674CBB759E150F6F06FB3053343D54DB7959B79C3764FE57AC25EF6728F1A6A2C6D98E56841DC461BBF12BD23E8C058D500435777431ADC23CA373B0F4A43B5E18787925E79113199A368F30692429BF3041D9BC82BFF88147C3DE432169578E304C72D59532043699C562CCB
-20180407041558 2 6 100 6143 2 E0CFB3582CE2D136E662908DCAA4CD666F574807FFFFF04BFB357D087BD132C8B569A579EC7FEDA39DA9FDBC7A8B289953FC1793F1B5D0F13A317C5F25554892D8A4F4EE9E85B9737D1412316C8169810745D8AC420ED45AA5419137F86E811AA101CD8746EDC5AF653499CA5585851205807E7EC4A3241FDD4C302AAC131FE24B2AC3700D3D21A82EB999FD0005E810811CEB2B1279D95E028269503DBF65FB23CBFC595B12BC67EC4A77D00324909088B6FDF511ABA41732957D32CC436FB0BE95E04F46DF57EC93E4FBD8FF12E18288384CBFABB1BD58F4A047CBF1AB831B43C550515DA98CA33697ECEE8AFAC110E7DD284D531324AC21013C86CFBC9DC286B6669534D8E2D40319E9BA9DC5ACE1825354E1869614CBCB708586A9455D20FC3B724C6FBF941EAAB3FFA61647906B890D9C8F2831A59B7A9A4EB6305DAEDE94A0525C8150EA3B27FC405430B82885E8EAA64A46E2E24DA089A0008C09C5B8117F5E5F397DCAC43906067AE2C6A1B7C1D1B2D233EFF6CBC472F328053EB666EC826604ADA4E27CA01FF98B7A5ADCF8FD3A6E2F6AEC4F36CE8D1D847E611CFDDA7B53AE4F0BA6481A2265D134B5B78F8416164B262CF58FA8806090613D09FA2E8CC417AF2A3208F5BB210CA87927C4FB980C9B97A743CC1B3A7BB9E22DD78EDFB52669C4DB24F796C5D99038E140CE81A9DFECE675F200DC0DEC203FB94380EAA8D13F30530A410BCBD393137FBF89AB80D872D6A4A46B303F01E79FA05DEF4F0F2A2ABD0788459E4C678F3952072570971EA5A686E5964D1C3A61E2311F57E7AB8519809243EB88A87A21B6589A16862EE1B9B4DD452950DDBB5D5482099FC667B5F9A43E3F803D9D0030D0D6E0F86DBFD2B0C2A67B9BFB1F318C6DF0745F75F9F59C7CC62F4763FBBFE3517BF28D9B68372674CBB759E150F6F06FB3053343D54DB7959B79C3764FE57AC25EF6728F1A6A2C6D98E56841DC461BBF12BD23E8C058D500435777431ADC23CA373B0F4A43B5E18787925E79113199A368F30692429BF3041D9BC82BFF88147C3DE432169578E304C72D59532043699EECE453
-20180407070330 2 6 100 6143 5 E0CFB3582CE2D136E662908DCAA4CD666F574807FFFFF04BFB357D087BD132C8B569A579EC7FEDA39DA9FDBC7A8B289953FC1793F1B5D0F13A317C5F25554892D8A4F4EE9E85B9737D1412316C8169810745D8AC420ED45AA5419137F86E811AA101CD8746EDC5AF653499CA5585851205807E7EC4A3241FDD4C302AAC131FE24B2AC3700D3D21A82EB999FD0005E810811CEB2B1279D95E028269503DBF65FB23CBFC595B12BC67EC4A77D00324909088B6FDF511ABA41732957D32CC436FB0BE95E04F46DF57EC93E4FBD8FF12E18288384CBFABB1BD58F4A047CBF1AB831B43C550515DA98CA33697ECEE8AFAC110E7DD284D531324AC21013C86CFBC9DC286B6669534D8E2D40319E9BA9DC5ACE1825354E1869614CBCB708586A9455D20FC3B724C6FBF941EAAB3FFA61647906B890D9C8F2831A59B7A9A4EB6305DAEDE94A0525C8150EA3B27FC405430B82885E8EAA64A46E2E24DA089A0008C09C5B8117F5E5F397DCAC43906067AE2C6A1B7C1D1B2D233EFF6CBC472F328053EB666EC826604ADA4E27CA01FF98B7A5ADCF8FD3A6E2F6AEC4F36CE8D1D847E611CFDDA7B53AE4F0BA6481A2265D134B5B78F8416164B262CF58FA8806090613D09FA2E8CC417AF2A3208F5BB210CA87927C4FB980C9B97A743CC1B3A7BB9E22DD78EDFB52669C4DB24F796C5D99038E140CE81A9DFECE675F200DC0DEC203FB94380EAA8D13F30530A410BCBD393137FBF89AB80D872D6A4A46B303F01E79FA05DEF4F0F2A2ABD0788459E4C678F3952072570971EA5A686E5964D1C3A61E2311F57E7AB8519809243EB88A87A21B6589A16862EE1B9B4DD452950DDBB5D5482099FC667B5F9A43E3F803D9D0030D0D6E0F86DBFD2B0C2A67B9BFB1F318C6DF0745F75F9F59C7CC62F4763FBBFE3517BF28D9B68372674CBB759E150F6F06FB3053343D54DB7959B79C3764FE57AC25EF6728F1A6A2C6D98E56841DC461BBF12BD23E8C058D500435777431ADC23CA373B0F4A43B5E18787925E79113199A368F30692429BF3041D9BC82BFF88147C3DE432169578E304C72D5953204369A0B1D577
-20180407100408 2 6 100 6143 2 E0CFB3582CE2D136E662908DCAA4CD666F574807FFFFF04BFB357D087BD132C8B569A579EC7FEDA39DA9FDBC7A8B289953FC1793F1B5D0F13A317C5F25554892D8A4F4EE9E85B9737D1412316C8169810745D8AC420ED45AA5419137F86E811AA101CD8746EDC5AF653499CA5585851205807E7EC4A3241FDD4C302AAC131FE24B2AC3700D3D21A82EB999FD0005E810811CEB2B1279D95E028269503DBF65FB23CBFC595B12BC67EC4A77D00324909088B6FDF511ABA41732957D32CC436FB0BE95E04F46DF57EC93E4FBD8FF12E18288384CBFABB1BD58F4A047CBF1AB831B43C550515DA98CA33697ECEE8AFAC110E7DD284D531324AC21013C86CFBC9DC286B6669534D8E2D40319E9BA9DC5ACE1825354E1869614CBCB708586A9455D20FC3B724C6FBF941EAAB3FFA61647906B890D9C8F2831A59B7A9A4EB6305DAEDE94A0525C8150EA3B27FC405430B82885E8EAA64A46E2E24DA089A0008C09C5B8117F5E5F397DCAC43906067AE2C6A1B7C1D1B2D233EFF6CBC472F328053EB666EC826604ADA4E27CA01FF98B7A5ADCF8FD3A6E2F6AEC4F36CE8D1D847E611CFDDA7B53AE4F0BA6481A2265D134B5B78F8416164B262CF58FA8806090613D09FA2E8CC417AF2A3208F5BB210CA87927C4FB980C9B97A743CC1B3A7BB9E22DD78EDFB52669C4DB24F796C5D99038E140CE81A9DFECE675F200DC0DEC203FB94380EAA8D13F30530A410BCBD393137FBF89AB80D872D6A4A46B303F01E79FA05DEF4F0F2A2ABD0788459E4C678F3952072570971EA5A686E5964D1C3A61E2311F57E7AB8519809243EB88A87A21B6589A16862EE1B9B4DD452950DDBB5D5482099FC667B5F9A43E3F803D9D0030D0D6E0F86DBFD2B0C2A67B9BFB1F318C6DF0745F75F9F59C7CC62F4763FBBFE3517BF28D9B68372674CBB759E150F6F06FB3053343D54DB7959B79C3764FE57AC25EF6728F1A6A2C6D98E56841DC461BBF12BD23E8C058D500435777431ADC23CA373B0F4A43B5E18787925E79113199A368F30692429BF3041D9BC82BFF88147C3DE432169578E304C72D5953204369A29D405B
-20180407103952 2 6 100 6143 2 E0CFB3582CE2D136E662908DCAA4CD666F574807FFFFF04BFB357D087BD132C8B569A579EC7FEDA39DA9FDBC7A8B289953FC1793F1B5D0F13A317C5F25554892D8A4F4EE9E85B9737D1412316C8169810745D8AC420ED45AA5419137F86E811AA101CD8746EDC5AF653499CA5585851205807E7EC4A3241FDD4C302AAC131FE24B2AC3700D3D21A82EB999FD0005E810811CEB2B1279D95E028269503DBF65FB23CBFC595B12BC67EC4A77D00324909088B6FDF511ABA41732957D32CC436FB0BE95E04F46DF57EC93E4FBD8FF12E18288384CBFABB1BD58F4A047CBF1AB831B43C550515DA98CA33697ECEE8AFAC110E7DD284D531324AC21013C86CFBC9DC286B6669534D8E2D40319E9BA9DC5ACE1825354E1869614CBCB708586A9455D20FC3B724C6FBF941EAAB3FFA61647906B890D9C8F2831A59B7A9A4EB6305DAEDE94A0525C8150EA3B27FC405430B82885E8EAA64A46E2E24DA089A0008C09C5B8117F5E5F397DCAC43906067AE2C6A1B7C1D1B2D233EFF6CBC472F328053EB666EC826604ADA4E27CA01FF98B7A5ADCF8FD3A6E2F6AEC4F36CE8D1D847E611CFDDA7B53AE4F0BA6481A2265D134B5B78F8416164B262CF58FA8806090613D09FA2E8CC417AF2A3208F5BB210CA87927C4FB980C9B97A743CC1B3A7BB9E22DD78EDFB52669C4DB24F796C5D99038E140CE81A9DFECE675F200DC0DEC203FB94380EAA8D13F30530A410BCBD393137FBF89AB80D872D6A4A46B303F01E79FA05DEF4F0F2A2ABD0788459E4C678F3952072570971EA5A686E5964D1C3A61E2311F57E7AB8519809243EB88A87A21B6589A16862EE1B9B4DD452950DDBB5D5482099FC667B5F9A43E3F803D9D0030D0D6E0F86DBFD2B0C2A67B9BFB1F318C6DF0745F75F9F59C7CC62F4763FBBFE3517BF28D9B68372674CBB759E150F6F06FB3053343D54DB7959B79C3764FE57AC25EF6728F1A6A2C6D98E56841DC461BBF12BD23E8C058D500435777431ADC23CA373B0F4A43B5E18787925E79113199A368F30692429BF3041D9BC82BFF88147C3DE432169578E304C72D5953204369A2F83A33
-20180407123940 2 6 100 6143 2 E0CFB3582CE2D136E662908DCAA4CD666F574807FFFFF04BFB357D087BD132C8B569A579EC7FEDA39DA9FDBC7A8B289953FC1793F1B5D0F13A317C5F25554892D8A4F4EE9E85B9737D1412316C8169810745D8AC420ED45AA5419137F86E811AA101CD8746EDC5AF653499CA5585851205807E7EC4A3241FDD4C302AAC131FE24B2AC3700D3D21A82EB999FD0005E810811CEB2B1279D95E028269503DBF65FB23CBFC595B12BC67EC4A77D00324909088B6FDF511ABA41732957D32CC436FB0BE95E04F46DF57EC93E4FBD8FF12E18288384CBFABB1BD58F4A047CBF1AB831B43C550515DA98CA33697ECEE8AFAC110E7DD284D531324AC21013C86CFBC9DC286B6669534D8E2D40319E9BA9DC5ACE1825354E1869614CBCB708586A9455D20FC3B724C6FBF941EAAB3FFA61647906B890D9C8F2831A59B7A9A4EB6305DAEDE94A0525C8150EA3B27FC405430B82885E8EAA64A46E2E24DA089A0008C09C5B8117F5E5F397DCAC43906067AE2C6A1B7C1D1B2D233EFF6CBC472F328053EB666EC826604ADA4E27CA01FF98B7A5ADCF8FD3A6E2F6AEC4F36CE8D1D847E611CFDDA7B53AE4F0BA6481A2265D134B5B78F8416164B262CF58FA8806090613D09FA2E8CC417AF2A3208F5BB210CA87927C4FB980C9B97A743CC1B3A7BB9E22DD78EDFB52669C4DB24F796C5D99038E140CE81A9DFECE675F200DC0DEC203FB94380EAA8D13F30530A410BCBD393137FBF89AB80D872D6A4A46B303F01E79FA05DEF4F0F2A2ABD0788459E4C678F3952072570971EA5A686E5964D1C3A61E2311F57E7AB8519809243EB88A87A21B6589A16862EE1B9B4DD452950DDBB5D5482099FC667B5F9A43E3F803D9D0030D0D6E0F86DBFD2B0C2A67B9BFB1F318C6DF0745F75F9F59C7CC62F4763FBBFE3517BF28D9B68372674CBB759E150F6F06FB3053343D54DB7959B79C3764FE57AC25EF6728F1A6A2C6D98E56841DC461BBF12BD23E8C058D500435777431ADC23CA373B0F4A43B5E18787925E79113199A368F30692429BF3041D9BC82BFF88147C3DE432169578E304C72D5953204369A43ACBEB
-20180407154812 2 6 100 6143 5 E0CFB3582CE2D136E662908DCAA4CD666F574807FFFFF04BFB357D087BD132C8B569A579EC7FEDA39DA9FDBC7A8B289953FC1793F1B5D0F13A317C5F25554892D8A4F4EE9E85B9737D1412316C8169810745D8AC420ED45AA5419137F86E811AA101CD8746EDC5AF653499CA5585851205807E7EC4A3241FDD4C302AAC131FE24B2AC3700D3D21A82EB999FD0005E810811CEB2B1279D95E028269503DBF65FB23CBFC595B12BC67EC4A77D00324909088B6FDF511ABA41732957D32CC436FB0BE95E04F46DF57EC93E4FBD8FF12E18288384CBFABB1BD58F4A047CBF1AB831B43C550515DA98CA33697ECEE8AFAC110E7DD284D531324AC21013C86CFBC9DC286B6669534D8E2D40319E9BA9DC5ACE1825354E1869614CBCB708586A9455D20FC3B724C6FBF941EAAB3FFA61647906B890D9C8F2831A59B7A9A4EB6305DAEDE94A0525C8150EA3B27FC405430B82885E8EAA64A46E2E24DA089A0008C09C5B8117F5E5F397DCAC43906067AE2C6A1B7C1D1B2D233EFF6CBC472F328053EB666EC826604ADA4E27CA01FF98B7A5ADCF8FD3A6E2F6AEC4F36CE8D1D847E611CFDDA7B53AE4F0BA6481A2265D134B5B78F8416164B262CF58FA8806090613D09FA2E8CC417AF2A3208F5BB210CA87927C4FB980C9B97A743CC1B3A7BB9E22DD78EDFB52669C4DB24F796C5D99038E140CE81A9DFECE675F200DC0DEC203FB94380EAA8D13F30530A410BCBD393137FBF89AB80D872D6A4A46B303F01E79FA05DEF4F0F2A2ABD0788459E4C678F3952072570971EA5A686E5964D1C3A61E2311F57E7AB8519809243EB88A87A21B6589A16862EE1B9B4DD452950DDBB5D5482099FC667B5F9A43E3F803D9D0030D0D6E0F86DBFD2B0C2A67B9BFB1F318C6DF0745F75F9F59C7CC62F4763FBBFE3517BF28D9B68372674CBB759E150F6F06FB3053343D54DB7959B79C3764FE57AC25EF6728F1A6A2C6D98E56841DC461BBF12BD23E8C058D500435777431ADC23CA373B0F4A43B5E18787925E79113199A368F30692429BF3041D9BC82BFF88147C3DE432169578E304C72D5953204369A62F48B7
-20180407170835 2 6 100 6143 5 E0CFB3582CE2D136E662908DCAA4CD666F574807FFFFF04BFB357D087BD132C8B569A579EC7FEDA39DA9FDBC7A8B289953FC1793F1B5D0F13A317C5F25554892D8A4F4EE9E85B9737D1412316C8169810745D8AC420ED45AA5419137F86E811AA101CD8746EDC5AF653499CA5585851205807E7EC4A3241FDD4C302AAC131FE24B2AC3700D3D21A82EB999FD0005E810811CEB2B1279D95E028269503DBF65FB23CBFC595B12BC67EC4A77D00324909088B6FDF511ABA41732957D32CC436FB0BE95E04F46DF57EC93E4FBD8FF12E18288384CBFABB1BD58F4A047CBF1AB831B43C550515DA98CA33697ECEE8AFAC110E7DD284D531324AC21013C86CFBC9DC286B6669534D8E2D40319E9BA9DC5ACE1825354E1869614CBCB708586A9455D20FC3B724C6FBF941EAAB3FFA61647906B890D9C8F2831A59B7A9A4EB6305DAEDE94A0525C8150EA3B27FC405430B82885E8EAA64A46E2E24DA089A0008C09C5B8117F5E5F397DCAC43906067AE2C6A1B7C1D1B2D233EFF6CBC472F328053EB666EC826604ADA4E27CA01FF98B7A5ADCF8FD3A6E2F6AEC4F36CE8D1D847E611CFDDA7B53AE4F0BA6481A2265D134B5B78F8416164B262CF58FA8806090613D09FA2E8CC417AF2A3208F5BB210CA87927C4FB980C9B97A743CC1B3A7BB9E22DD78EDFB52669C4DB24F796C5D99038E140CE81A9DFECE675F200DC0DEC203FB94380EAA8D13F30530A410BCBD393137FBF89AB80D872D6A4A46B303F01E79FA05DEF4F0F2A2ABD0788459E4C678F3952072570971EA5A686E5964D1C3A61E2311F57E7AB8519809243EB88A87A21B6589A16862EE1B9B4DD452950DDBB5D5482099FC667B5F9A43E3F803D9D0030D0D6E0F86DBFD2B0C2A67B9BFB1F318C6DF0745F75F9F59C7CC62F4763FBBFE3517BF28D9B68372674CBB759E150F6F06FB3053343D54DB7959B79C3764FE57AC25EF6728F1A6A2C6D98E56841DC461BBF12BD23E8C058D500435777431ADC23CA373B0F4A43B5E18787925E79113199A368F30692429BF3041D9BC82BFF88147C3DE432169578E304C72D5953204369A704C5AF
-20180407175007 2 6 100 6143 5 E0CFB3582CE2D136E662908DCAA4CD666F574807FFFFF04BFB357D087BD132C8B569A579EC7FEDA39DA9FDBC7A8B289953FC1793F1B5D0F13A317C5F25554892D8A4F4EE9E85B9737D1412316C8169810745D8AC420ED45AA5419137F86E811AA101CD8746EDC5AF653499CA5585851205807E7EC4A3241FDD4C302AAC131FE24B2AC3700D3D21A82EB999FD0005E810811CEB2B1279D95E028269503DBF65FB23CBFC595B12BC67EC4A77D00324909088B6FDF511ABA41732957D32CC436FB0BE95E04F46DF57EC93E4FBD8FF12E18288384CBFABB1BD58F4A047CBF1AB831B43C550515DA98CA33697ECEE8AFAC110E7DD284D531324AC21013C86CFBC9DC286B6669534D8E2D40319E9BA9DC5ACE1825354E1869614CBCB708586A9455D20FC3B724C6FBF941EAAB3FFA61647906B890D9C8F2831A59B7A9A4EB6305DAEDE94A0525C8150EA3B27FC405430B82885E8EAA64A46E2E24DA089A0008C09C5B8117F5E5F397DCAC43906067AE2C6A1B7C1D1B2D233EFF6CBC472F328053EB666EC826604ADA4E27CA01FF98B7A5ADCF8FD3A6E2F6AEC4F36CE8D1D847E611CFDDA7B53AE4F0BA6481A2265D134B5B78F8416164B262CF58FA8806090613D09FA2E8CC417AF2A3208F5BB210CA87927C4FB980C9B97A743CC1B3A7BB9E22DD78EDFB52669C4DB24F796C5D99038E140CE81A9DFECE675F200DC0DEC203FB94380EAA8D13F30530A410BCBD393137FBF89AB80D872D6A4A46B303F01E79FA05DEF4F0F2A2ABD0788459E4C678F3952072570971EA5A686E5964D1C3A61E2311F57E7AB8519809243EB88A87A21B6589A16862EE1B9B4DD452950DDBB5D5482099FC667B5F9A43E3F803D9D0030D0D6E0F86DBFD2B0C2A67B9BFB1F318C6DF0745F75F9F59C7CC62F4763FBBFE3517BF28D9B68372674CBB759E150F6F06FB3053343D54DB7959B79C3764FE57AC25EF6728F1A6A2C6D98E56841DC461BBF12BD23E8C058D500435777431ADC23CA373B0F4A43B5E18787925E79113199A368F30692429BF3041D9BC82BFF88147C3DE432169578E304C72D5953204369A76C88B7
-20180407184438 2 6 100 6143 2 E0CFB3582CE2D136E662908DCAA4CD666F574807FFFFF04BFB357D087BD132C8B569A579EC7FEDA39DA9FDBC7A8B289953FC1793F1B5D0F13A317C5F25554892D8A4F4EE9E85B9737D1412316C8169810745D8AC420ED45AA5419137F86E811AA101CD8746EDC5AF653499CA5585851205807E7EC4A3241FDD4C302AAC131FE24B2AC3700D3D21A82EB999FD0005E810811CEB2B1279D95E028269503DBF65FB23CBFC595B12BC67EC4A77D00324909088B6FDF511ABA41732957D32CC436FB0BE95E04F46DF57EC93E4FBD8FF12E18288384CBFABB1BD58F4A047CBF1AB831B43C550515DA98CA33697ECEE8AFAC110E7DD284D531324AC21013C86CFBC9DC286B6669534D8E2D40319E9BA9DC5ACE1825354E1869614CBCB708586A9455D20FC3B724C6FBF941EAAB3FFA61647906B890D9C8F2831A59B7A9A4EB6305DAEDE94A0525C8150EA3B27FC405430B82885E8EAA64A46E2E24DA089A0008C09C5B8117F5E5F397DCAC43906067AE2C6A1B7C1D1B2D233EFF6CBC472F328053EB666EC826604ADA4E27CA01FF98B7A5ADCF8FD3A6E2F6AEC4F36CE8D1D847E611CFDDA7B53AE4F0BA6481A2265D134B5B78F8416164B262CF58FA8806090613D09FA2E8CC417AF2A3208F5BB210CA87927C4FB980C9B97A743CC1B3A7BB9E22DD78EDFB52669C4DB24F796C5D99038E140CE81A9DFECE675F200DC0DEC203FB94380EAA8D13F30530A410BCBD393137FBF89AB80D872D6A4A46B303F01E79FA05DEF4F0F2A2ABD0788459E4C678F3952072570971EA5A686E5964D1C3A61E2311F57E7AB8519809243EB88A87A21B6589A16862EE1B9B4DD452950DDBB5D5482099FC667B5F9A43E3F803D9D0030D0D6E0F86DBFD2B0C2A67B9BFB1F318C6DF0745F75F9F59C7CC62F4763FBBFE3517BF28D9B68372674CBB759E150F6F06FB3053343D54DB7959B79C3764FE57AC25EF6728F1A6A2C6D98E56841DC461BBF12BD23E8C058D500435777431ADC23CA373B0F4A43B5E18787925E79113199A368F30692429BF3041D9BC82BFF88147C3DE432169578E304C72D5953204369A7F65E03
-20180407195743 2 6 100 6143 5 E0CFB3582CE2D136E662908DCAA4CD666F574807FFFFF04BFB357D087BD132C8B569A579EC7FEDA39DA9FDBC7A8B289953FC1793F1B5D0F13A317C5F25554892D8A4F4EE9E85B9737D1412316C8169810745D8AC420ED45AA5419137F86E811AA101CD8746EDC5AF653499CA5585851205807E7EC4A3241FDD4C302AAC131FE24B2AC3700D3D21A82EB999FD0005E810811CEB2B1279D95E028269503DBF65FB23CBFC595B12BC67EC4A77D00324909088B6FDF511ABA41732957D32CC436FB0BE95E04F46DF57EC93E4FBD8FF12E18288384CBFABB1BD58F4A047CBF1AB831B43C550515DA98CA33697ECEE8AFAC110E7DD284D531324AC21013C86CFBC9DC286B6669534D8E2D40319E9BA9DC5ACE1825354E1869614CBCB708586A9455D20FC3B724C6FBF941EAAB3FFA61647906B890D9C8F2831A59B7A9A4EB6305DAEDE94A0525C8150EA3B27FC405430B82885E8EAA64A46E2E24DA089A0008C09C5B8117F5E5F397DCAC43906067AE2C6A1B7C1D1B2D233EFF6CBC472F328053EB666EC826604ADA4E27CA01FF98B7A5ADCF8FD3A6E2F6AEC4F36CE8D1D847E611CFDDA7B53AE4F0BA6481A2265D134B5B78F8416164B262CF58FA8806090613D09FA2E8CC417AF2A3208F5BB210CA87927C4FB980C9B97A743CC1B3A7BB9E22DD78EDFB52669C4DB24F796C5D99038E140CE81A9DFECE675F200DC0DEC203FB94380EAA8D13F30530A410BCBD393137FBF89AB80D872D6A4A46B303F01E79FA05DEF4F0F2A2ABD0788459E4C678F3952072570971EA5A686E5964D1C3A61E2311F57E7AB8519809243EB88A87A21B6589A16862EE1B9B4DD452950DDBB5D5482099FC667B5F9A43E3F803D9D0030D0D6E0F86DBFD2B0C2A67B9BFB1F318C6DF0745F75F9F59C7CC62F4763FBBFE3517BF28D9B68372674CBB759E150F6F06FB3053343D54DB7959B79C3764FE57AC25EF6728F1A6A2C6D98E56841DC461BBF12BD23E8C058D500435777431ADC23CA373B0F4A43B5E18787925E79113199A368F30692429BF3041D9BC82BFF88147C3DE432169578E304C72D5953204369A8B41617
-20180408071229 2 6 100 6143 2 E0CFB3582CE2D136E662908DCAA4CD666F574807FFFFF04BFB357D087BD132C8B569A579EC7FEDA39DA9FDBC7A8B289953FC1793F1B5D0F13A317C5F25554892D8A4F4EE9E85B9737D1412316C8169810745D8AC420ED45AA5419137F86E811AA101CD8746EDC5AF653499CA5585851205807E7EC4A3241FDD4C302AAC131FE24B2AC3700D3D21A82EB999FD0005E810811CEB2B1279D95E028269503DBF65FB23CBFC595B12BC67EC4A77D00324909088B6FDF511ABA41732957D32CC436FB0BE95E04F46DF57EC93E4FBD8FF12E18288384CBFABB1BD58F4A047CBF1AB831B43C550515DA98CA33697ECEE8AFAC110E7DD284D531324AC21013C86CFBC9DC286B6669534D8E2D40319E9BA9DC5ACE1825354E1869614CBCB708586A9455D20FC3B724C6FBF941EAAB3FFA61647906B890D9C8F2831A59B7A9A4EB6305DAEDE94A0525C8150EA3B27FC405430B82885E8EAA64A46E2E24DA089A0008C09C5B8117F5E5F397DCAC43906067AE2C6A1B7C1D1B2D233EFF6CBC472F328053EB666EC826604ADA4E27CA01FF98B7A5ADCF8FD3A6E2F6AEC4F36CE8D1D847E611CFDDA7B53AE4F0BA6481A2265D134B5B78F8416164B262CF58FA8806090613D09FA2E8CC417AF2A3208F5BB210CA87927C4FB980C9B97A743CC1B3A7BB9E22DD78EDFB52669C4DB24F796C5D99038E140CE81A9DFECE675F200DC0DEC203FB94380EAA8D13F30530A410BCBD393137FBF89AB80D872D6A4A46B303F01E79FA05DEF4F0F2A2ABD0788459E4C678F3952072570971EA5A686E5964D1C3A61E2311F57E7AB8519809243EB88A87A21B6589A16862EE1B9B4DD452950DDBB5D5482099FC667B5F9A43E3F803D9D0030D0D6E0F86DBFD2B0C2A67B9BFB1F318C6DF0745F75F9F59C7CC62F4763FBBFE3517BF28D9B68372674CBB759E150F6F06FB3053343D54DB7959B79C3764FE57AC25EF6728F1A6A2C6D98E56841DC461BBF12BD23E8C058D500435777431ADC23CA373B0F4A43B5E18787925E79113199A368F30692429BF3041D9BC82BFF88147C3DE432169578E304C72D5953204369AFC7905B
-20180408075553 2 6 100 6143 5 E0CFB3582CE2D136E662908DCAA4CD666F574807FFFFF04BFB357D087BD132C8B569A579EC7FEDA39DA9FDBC7A8B289953FC1793F1B5D0F13A317C5F25554892D8A4F4EE9E85B9737D1412316C8169810745D8AC420ED45AA5419137F86E811AA101CD8746EDC5AF653499CA5585851205807E7EC4A3241FDD4C302AAC131FE24B2AC3700D3D21A82EB999FD0005E810811CEB2B1279D95E028269503DBF65FB23CBFC595B12BC67EC4A77D00324909088B6FDF511ABA41732957D32CC436FB0BE95E04F46DF57EC93E4FBD8FF12E18288384CBFABB1BD58F4A047CBF1AB831B43C550515DA98CA33697ECEE8AFAC110E7DD284D531324AC21013C86CFBC9DC286B6669534D8E2D40319E9BA9DC5ACE1825354E1869614CBCB708586A9455D20FC3B724C6FBF941EAAB3FFA61647906B890D9C8F2831A59B7A9A4EB6305DAEDE94A0525C8150EA3B27FC405430B82885E8EAA64A46E2E24DA089A0008C09C5B8117F5E5F397DCAC43906067AE2C6A1B7C1D1B2D233EFF6CBC472F328053EB666EC826604ADA4E27CA01FF98B7A5ADCF8FD3A6E2F6AEC4F36CE8D1D847E611CFDDA7B53AE4F0BA6481A2265D134B5B78F8416164B262CF58FA8806090613D09FA2E8CC417AF2A3208F5BB210CA87927C4FB980C9B97A743CC1B3A7BB9E22DD78EDFB52669C4DB24F796C5D99038E140CE81A9DFECE675F200DC0DEC203FB94380EAA8D13F30530A410BCBD393137FBF89AB80D872D6A4A46B303F01E79FA05DEF4F0F2A2ABD0788459E4C678F3952072570971EA5A686E5964D1C3A61E2311F57E7AB8519809243EB88A87A21B6589A16862EE1B9B4DD452950DDBB5D5482099FC667B5F9A43E3F803D9D0030D0D6E0F86DBFD2B0C2A67B9BFB1F318C6DF0745F75F9F59C7CC62F4763FBBFE3517BF28D9B68372674CBB759E150F6F06FB3053343D54DB7959B79C3764FE57AC25EF6728F1A6A2C6D98E56841DC461BBF12BD23E8C058D500435777431ADC23CA373B0F4A43B5E18787925E79113199A368F30692429BF3041D9BC82BFF88147C3DE432169578E304C72D5953204369B03562E7
-20180408124736 2 6 100 6143 5 E0CFB3582CE2D136E662908DCAA4CD666F574807FFFFF04BFB357D087BD132C8B569A579EC7FEDA39DA9FDBC7A8B289953FC1793F1B5D0F13A317C5F25554892D8A4F4EE9E85B9737D1412316C8169810745D8AC420ED45AA5419137F86E811AA101CD8746EDC5AF653499CA5585851205807E7EC4A3241FDD4C302AAC131FE24B2AC3700D3D21A82EB999FD0005E810811CEB2B1279D95E028269503DBF65FB23CBFC595B12BC67EC4A77D00324909088B6FDF511ABA41732957D32CC436FB0BE95E04F46DF57EC93E4FBD8FF12E18288384CBFABB1BD58F4A047CBF1AB831B43C550515DA98CA33697ECEE8AFAC110E7DD284D531324AC21013C86CFBC9DC286B6669534D8E2D40319E9BA9DC5ACE1825354E1869614CBCB708586A9455D20FC3B724C6FBF941EAAB3FFA61647906B890D9C8F2831A59B7A9A4EB6305DAEDE94A0525C8150EA3B27FC405430B82885E8EAA64A46E2E24DA089A0008C09C5B8117F5E5F397DCAC43906067AE2C6A1B7C1D1B2D233EFF6CBC472F328053EB666EC826604ADA4E27CA01FF98B7A5ADCF8FD3A6E2F6AEC4F36CE8D1D847E611CFDDA7B53AE4F0BA6481A2265D134B5B78F8416164B262CF58FA8806090613D09FA2E8CC417AF2A3208F5BB210CA87927C4FB980C9B97A743CC1B3A7BB9E22DD78EDFB52669C4DB24F796C5D99038E140CE81A9DFECE675F200DC0DEC203FB94380EAA8D13F30530A410BCBD393137FBF89AB80D872D6A4A46B303F01E79FA05DEF4F0F2A2ABD0788459E4C678F3952072570971EA5A686E5964D1C3A61E2311F57E7AB8519809243EB88A87A21B6589A16862EE1B9B4DD452950DDBB5D5482099FC667B5F9A43E3F803D9D0030D0D6E0F86DBFD2B0C2A67B9BFB1F318C6DF0745F75F9F59C7CC62F4763FBBFE3517BF28D9B68372674CBB759E150F6F06FB3053343D54DB7959B79C3764FE57AC25EF6728F1A6A2C6D98E56841DC461BBF12BD23E8C058D500435777431ADC23CA373B0F4A43B5E18787925E79113199A368F30692429BF3041D9BC82BFF88147C3DE432169578E304C72D5953204369B3416E27
-20180408125929 2 6 100 6143 2 E0CFB3582CE2D136E662908DCAA4CD666F574807FFFFF04BFB357D087BD132C8B569A579EC7FEDA39DA9FDBC7A8B289953FC1793F1B5D0F13A317C5F25554892D8A4F4EE9E85B9737D1412316C8169810745D8AC420ED45AA5419137F86E811AA101CD8746EDC5AF653499CA5585851205807E7EC4A3241FDD4C302AAC131FE24B2AC3700D3D21A82EB999FD0005E810811CEB2B1279D95E028269503DBF65FB23CBFC595B12BC67EC4A77D00324909088B6FDF511ABA41732957D32CC436FB0BE95E04F46DF57EC93E4FBD8FF12E18288384CBFABB1BD58F4A047CBF1AB831B43C550515DA98CA33697ECEE8AFAC110E7DD284D531324AC21013C86CFBC9DC286B6669534D8E2D40319E9BA9DC5ACE1825354E1869614CBCB708586A9455D20FC3B724C6FBF941EAAB3FFA61647906B890D9C8F2831A59B7A9A4EB6305DAEDE94A0525C8150EA3B27FC405430B82885E8EAA64A46E2E24DA089A0008C09C5B8117F5E5F397DCAC43906067AE2C6A1B7C1D1B2D233EFF6CBC472F328053EB666EC826604ADA4E27CA01FF98B7A5ADCF8FD3A6E2F6AEC4F36CE8D1D847E611CFDDA7B53AE4F0BA6481A2265D134B5B78F8416164B262CF58FA8806090613D09FA2E8CC417AF2A3208F5BB210CA87927C4FB980C9B97A743CC1B3A7BB9E22DD78EDFB52669C4DB24F796C5D99038E140CE81A9DFECE675F200DC0DEC203FB94380EAA8D13F30530A410BCBD393137FBF89AB80D872D6A4A46B303F01E79FA05DEF4F0F2A2ABD0788459E4C678F3952072570971EA5A686E5964D1C3A61E2311F57E7AB8519809243EB88A87A21B6589A16862EE1B9B4DD452950DDBB5D5482099FC667B5F9A43E3F803D9D0030D0D6E0F86DBFD2B0C2A67B9BFB1F318C6DF0745F75F9F59C7CC62F4763FBBFE3517BF28D9B68372674CBB759E150F6F06FB3053343D54DB7959B79C3764FE57AC25EF6728F1A6A2C6D98E56841DC461BBF12BD23E8C058D500435777431ADC23CA373B0F4A43B5E18787925E79113199A368F30692429BF3041D9BC82BFF88147C3DE432169578E304C72D5953204369B35942B3
-20180409023705 2 6 100 6143 2 E0CFB3582CE2D136E662908DCAA4CD666F574807FFFFF04BFB357D087BD132C8B569A579EC7FEDA39DA9FDBC7A8B289953FC1793F1B5D0F13A317C5F25554892D8A4F4EE9E85B9737D1412316C8169810745D8AC420ED45AA5419137F86E811AA101CD8746EDC5AF653499CA5585851205807E7EC4A3241FDD4C302AAC131FE24B2AC3700D3D21A82EB999FD0005E810811CEB2B1279D95E028269503DBF65FB23CBFC595B12BC67EC4A77D00324909088B6FDF511ABA41732957D32CC436FB0BE95E04F46DF57EC93E4FBD8FF12E18288384CBFABB1BD58F4A047CBF1AB831B43C550515DA98CA33697ECEE8AFAC110E7DD284D531324AC21013C86CFBC9DC286B6669534D8E2D40319E9BA9DC5ACE1825354E1869614CBCB708586A9455D20FC3B724C6FBF941EAAB3FFA61647906B890D9C8F2831A59B7A9A4EB6305DAEDE94A0525C8150EA3B27FC405430B82885E8EAA64A46E2E24DA089A0008C09C5B8117F5E5F397DCAC43906067AE2C6A1B7C1D1B2D233EFF6CBC472F328053EB666EC826604ADA4E27CA01FF98B7A5ADCF8FD3A6E2F6AEC4F36CE8D1D847E611CFDDA7B53AE4F0BA6481A2265D134B5B78F8416164B262CF58FA8806090613D09FA2E8CC417AF2A3208F5BB210CA87927C4FB980C9B97A743CC1B3A7BB9E22DD78EDFB52669C4DB24F796C5D99038E140CE81A9DFECE675F200DC0DEC203FB94380EAA8D13F30530A410BCBD393137FBF89AB80D872D6A4A46B303F01E79FA05DEF4F0F2A2ABD0788459E4C678F3952072570971EA5A686E5964D1C3A61E2311F57E7AB8519809243EB88A87A21B6589A16862EE1B9B4DD452950DDBB5D5482099FC667B5F9A43E3F803D9D0030D0D6E0F86DBFD2B0C2A67B9BFB1F318C6DF0745F75F9F59C7CC62F4763FBBFE3517BF28D9B68372674CBB759E150F6F06FB3053343D54DB7959B79C3764FE57AC25EF6728F1A6A2C6D98E56841DC461BBF12BD23E8C058D500435777431ADC23CA373B0F4A43B5E18787925E79113199A368F30692429BF3041D9BC82BFF88147C3DE432169578E304C72D5953204369BBCCDCBB
-20180409072217 2 6 100 6143 5 E0CFB3582CE2D136E662908DCAA4CD666F574807FFFFF04BFB357D087BD132C8B569A579EC7FEDA39DA9FDBC7A8B289953FC1793F1B5D0F13A317C5F25554892D8A4F4EE9E85B9737D1412316C8169810745D8AC420ED45AA5419137F86E811AA101CD8746EDC5AF653499CA5585851205807E7EC4A3241FDD4C302AAC131FE24B2AC3700D3D21A82EB999FD0005E810811CEB2B1279D95E028269503DBF65FB23CBFC595B12BC67EC4A77D00324909088B6FDF511ABA41732957D32CC436FB0BE95E04F46DF57EC93E4FBD8FF12E18288384CBFABB1BD58F4A047CBF1AB831B43C550515DA98CA33697ECEE8AFAC110E7DD284D531324AC21013C86CFBC9DC286B6669534D8E2D40319E9BA9DC5ACE1825354E1869614CBCB708586A9455D20FC3B724C6FBF941EAAB3FFA61647906B890D9C8F2831A59B7A9A4EB6305DAEDE94A0525C8150EA3B27FC405430B82885E8EAA64A46E2E24DA089A0008C09C5B8117F5E5F397DCAC43906067AE2C6A1B7C1D1B2D233EFF6CBC472F328053EB666EC826604ADA4E27CA01FF98B7A5ADCF8FD3A6E2F6AEC4F36CE8D1D847E611CFDDA7B53AE4F0BA6481A2265D134B5B78F8416164B262CF58FA8806090613D09FA2E8CC417AF2A3208F5BB210CA87927C4FB980C9B97A743CC1B3A7BB9E22DD78EDFB52669C4DB24F796C5D99038E140CE81A9DFECE675F200DC0DEC203FB94380EAA8D13F30530A410BCBD393137FBF89AB80D872D6A4A46B303F01E79FA05DEF4F0F2A2ABD0788459E4C678F3952072570971EA5A686E5964D1C3A61E2311F57E7AB8519809243EB88A87A21B6589A16862EE1B9B4DD452950DDBB5D5482099FC667B5F9A43E3F803D9D0030D0D6E0F86DBFD2B0C2A67B9BFB1F318C6DF0745F75F9F59C7CC62F4763FBBFE3517BF28D9B68372674CBB759E150F6F06FB3053343D54DB7959B79C3764FE57AC25EF6728F1A6A2C6D98E56841DC461BBF12BD23E8C058D500435777431ADC23CA373B0F4A43B5E18787925E79113199A368F30692429BF3041D9BC82BFF88147C3DE432169578E304C72D5953204369BEB6303F
-20180409124237 2 6 100 6143 2 E0CFB3582CE2D136E662908DCAA4CD666F574807FFFFF04BFB357D087BD132C8B569A579EC7FEDA39DA9FDBC7A8B289953FC1793F1B5D0F13A317C5F25554892D8A4F4EE9E85B9737D1412316C8169810745D8AC420ED45AA5419137F86E811AA101CD8746EDC5AF653499CA5585851205807E7EC4A3241FDD4C302AAC131FE24B2AC3700D3D21A82EB999FD0005E810811CEB2B1279D95E028269503DBF65FB23CBFC595B12BC67EC4A77D00324909088B6FDF511ABA41732957D32CC436FB0BE95E04F46DF57EC93E4FBD8FF12E18288384CBFABB1BD58F4A047CBF1AB831B43C550515DA98CA33697ECEE8AFAC110E7DD284D531324AC21013C86CFBC9DC286B6669534D8E2D40319E9BA9DC5ACE1825354E1869614CBCB708586A9455D20FC3B724C6FBF941EAAB3FFA61647906B890D9C8F2831A59B7A9A4EB6305DAEDE94A0525C8150EA3B27FC405430B82885E8EAA64A46E2E24DA089A0008C09C5B8117F5E5F397DCAC43906067AE2C6A1B7C1D1B2D233EFF6CBC472F328053EB666EC826604ADA4E27CA01FF98B7A5ADCF8FD3A6E2F6AEC4F36CE8D1D847E611CFDDA7B53AE4F0BA6481A2265D134B5B78F8416164B262CF58FA8806090613D09FA2E8CC417AF2A3208F5BB210CA87927C4FB980C9B97A743CC1B3A7BB9E22DD78EDFB52669C4DB24F796C5D99038E140CE81A9DFECE675F200DC0DEC203FB94380EAA8D13F30530A410BCBD393137FBF89AB80D872D6A4A46B303F01E79FA05DEF4F0F2A2ABD0788459E4C678F3952072570971EA5A686E5964D1C3A61E2311F57E7AB8519809243EB88A87A21B6589A16862EE1B9B4DD452950DDBB5D5482099FC667B5F9A43E3F803D9D0030D0D6E0F86DBFD2B0C2A67B9BFB1F318C6DF0745F75F9F59C7CC62F4763FBBFE3517BF28D9B68372674CBB759E150F6F06FB3053343D54DB7959B79C3764FE57AC25EF6728F1A6A2C6D98E56841DC461BBF12BD23E8C058D500435777431ADC23CA373B0F4A43B5E18787925E79113199A368F30692429BF3041D9BC82BFF88147C3DE432169578E304C72D5953204369C1F95DB3
-20180409150941 2 6 100 6143 5 E0CFB3582CE2D136E662908DCAA4CD666F574807FFFFF04BFB357D087BD132C8B569A579EC7FEDA39DA9FDBC7A8B289953FC1793F1B5D0F13A317C5F25554892D8A4F4EE9E85B9737D1412316C8169810745D8AC420ED45AA5419137F86E811AA101CD8746EDC5AF653499CA5585851205807E7EC4A3241FDD4C302AAC131FE24B2AC3700D3D21A82EB999FD0005E810811CEB2B1279D95E028269503DBF65FB23CBFC595B12BC67EC4A77D00324909088B6FDF511ABA41732957D32CC436FB0BE95E04F46DF57EC93E4FBD8FF12E18288384CBFABB1BD58F4A047CBF1AB831B43C550515DA98CA33697ECEE8AFAC110E7DD284D531324AC21013C86CFBC9DC286B6669534D8E2D40319E9BA9DC5ACE1825354E1869614CBCB708586A9455D20FC3B724C6FBF941EAAB3FFA61647906B890D9C8F2831A59B7A9A4EB6305DAEDE94A0525C8150EA3B27FC405430B82885E8EAA64A46E2E24DA089A0008C09C5B8117F5E5F397DCAC43906067AE2C6A1B7C1D1B2D233EFF6CBC472F328053EB666EC826604ADA4E27CA01FF98B7A5ADCF8FD3A6E2F6AEC4F36CE8D1D847E611CFDDA7B53AE4F0BA6481A2265D134B5B78F8416164B262CF58FA8806090613D09FA2E8CC417AF2A3208F5BB210CA87927C4FB980C9B97A743CC1B3A7BB9E22DD78EDFB52669C4DB24F796C5D99038E140CE81A9DFECE675F200DC0DEC203FB94380EAA8D13F30530A410BCBD393137FBF89AB80D872D6A4A46B303F01E79FA05DEF4F0F2A2ABD0788459E4C678F3952072570971EA5A686E5964D1C3A61E2311F57E7AB8519809243EB88A87A21B6589A16862EE1B9B4DD452950DDBB5D5482099FC667B5F9A43E3F803D9D0030D0D6E0F86DBFD2B0C2A67B9BFB1F318C6DF0745F75F9F59C7CC62F4763FBBFE3517BF28D9B68372674CBB759E150F6F06FB3053343D54DB7959B79C3764FE57AC25EF6728F1A6A2C6D98E56841DC461BBF12BD23E8C058D500435777431ADC23CA373B0F4A43B5E18787925E79113199A368F30692429BF3041D9BC82BFF88147C3DE432169578E304C72D5953204369C3A97BA7
-20180409162805 2 6 100 6143 5 E0CFB3582CE2D136E662908DCAA4CD666F574807FFFFF04BFB357D087BD132C8B569A579EC7FEDA39DA9FDBC7A8B289953FC1793F1B5D0F13A317C5F25554892D8A4F4EE9E85B9737D1412316C8169810745D8AC420ED45AA5419137F86E811AA101CD8746EDC5AF653499CA5585851205807E7EC4A3241FDD4C302AAC131FE24B2AC3700D3D21A82EB999FD0005E810811CEB2B1279D95E028269503DBF65FB23CBFC595B12BC67EC4A77D00324909088B6FDF511ABA41732957D32CC436FB0BE95E04F46DF57EC93E4FBD8FF12E18288384CBFABB1BD58F4A047CBF1AB831B43C550515DA98CA33697ECEE8AFAC110E7DD284D531324AC21013C86CFBC9DC286B6669534D8E2D40319E9BA9DC5ACE1825354E1869614CBCB708586A9455D20FC3B724C6FBF941EAAB3FFA61647906B890D9C8F2831A59B7A9A4EB6305DAEDE94A0525C8150EA3B27FC405430B82885E8EAA64A46E2E24DA089A0008C09C5B8117F5E5F397DCAC43906067AE2C6A1B7C1D1B2D233EFF6CBC472F328053EB666EC826604ADA4E27CA01FF98B7A5ADCF8FD3A6E2F6AEC4F36CE8D1D847E611CFDDA7B53AE4F0BA6481A2265D134B5B78F8416164B262CF58FA8806090613D09FA2E8CC417AF2A3208F5BB210CA87927C4FB980C9B97A743CC1B3A7BB9E22DD78EDFB52669C4DB24F796C5D99038E140CE81A9DFECE675F200DC0DEC203FB94380EAA8D13F30530A410BCBD393137FBF89AB80D872D6A4A46B303F01E79FA05DEF4F0F2A2ABD0788459E4C678F3952072570971EA5A686E5964D1C3A61E2311F57E7AB8519809243EB88A87A21B6589A16862EE1B9B4DD452950DDBB5D5482099FC667B5F9A43E3F803D9D0030D0D6E0F86DBFD2B0C2A67B9BFB1F318C6DF0745F75F9F59C7CC62F4763FBBFE3517BF28D9B68372674CBB759E150F6F06FB3053343D54DB7959B79C3764FE57AC25EF6728F1A6A2C6D98E56841DC461BBF12BD23E8C058D500435777431ADC23CA373B0F4A43B5E18787925E79113199A368F30692429BF3041D9BC82BFF88147C3DE432169578E304C72D5953204369C56C92A7
-20180409185627 2 6 100 6143 5 E0CFB3582CE2D136E662908DCAA4CD666F574807FFFFF04BFB357D087BD132C8B569A579EC7FEDA39DA9FDBC7A8B289953FC1793F1B5D0F13A317C5F25554892D8A4F4EE9E85B9737D1412316C8169810745D8AC420ED45AA5419137F86E811AA101CD8746EDC5AF653499CA5585851205807E7EC4A3241FDD4C302AAC131FE24B2AC3700D3D21A82EB999FD0005E810811CEB2B1279D95E028269503DBF65FB23CBFC595B12BC67EC4A77D00324909088B6FDF511ABA41732957D32CC436FB0BE95E04F46DF57EC93E4FBD8FF12E18288384CBFABB1BD58F4A047CBF1AB831B43C550515DA98CA33697ECEE8AFAC110E7DD284D531324AC21013C86CFBC9DC286B6669534D8E2D40319E9BA9DC5ACE1825354E1869614CBCB708586A9455D20FC3B724C6FBF941EAAB3FFA61647906B890D9C8F2831A59B7A9A4EB6305DAEDE94A0525C8150EA3B27FC405430B82885E8EAA64A46E2E24DA089A0008C09C5B8117F5E5F397DCAC43906067AE2C6A1B7C1D1B2D233EFF6CBC472F328053EB666EC826604ADA4E27CA01FF98B7A5ADCF8FD3A6E2F6AEC4F36CE8D1D847E611CFDDA7B53AE4F0BA6481A2265D134B5B78F8416164B262CF58FA8806090613D09FA2E8CC417AF2A3208F5BB210CA87927C4FB980C9B97A743CC1B3A7BB9E22DD78EDFB52669C4DB24F796C5D99038E140CE81A9DFECE675F200DC0DEC203FB94380EAA8D13F30530A410BCBD393137FBF89AB80D872D6A4A46B303F01E79FA05DEF4F0F2A2ABD0788459E4C678F3952072570971EA5A686E5964D1C3A61E2311F57E7AB8519809243EB88A87A21B6589A16862EE1B9B4DD452950DDBB5D5482099FC667B5F9A43E3F803D9D0030D0D6E0F86DBFD2B0C2A67B9BFB1F318C6DF0745F75F9F59C7CC62F4763FBBFE3517BF28D9B68372674CBB759E150F6F06FB3053343D54DB7959B79C3764FE57AC25EF6728F1A6A2C6D98E56841DC461BBF12BD23E8C058D500435777431ADC23CA373B0F4A43B5E18787925E79113199A368F30692429BF3041D9BC82BFF88147C3DE432169578E304C72D5953204369C8DC8A0F
-20180409201511 2 6 100 6143 5 E01FFD7EC91328929E4FD6183C9C9EDF4EF8CFC608D943A1011CEE0B49D7322663D64028F7205A4F008A0C8F393F91FF42D1C7ACB6B4041D0DC79BB0DA6D394532A0E33BC96FEA6EC2E67987F13D2F218B9E8A46D20125D822B6AA1C9615087E5C667CCA74414305E3382E20792B058F61D9DBFD93EF80A2E30E17FDB883F79989B540A6E467D9CEF07C849B659890706CAC7FF6F95669DAD0D9170D485C298AA940C6B7B3092E265FB512C70F36E3D6515B7B799E20FFE9DA35F932C3F2C238F5D8BCB92193216563D6163EB9FAAFEDD0E8A1A3F8CE292E8A1BEF630C5E75D845444B414017844E9560C8309CD54BF9EEAB2CAAE888226AB8031F1569A728256BB6FCC14DF314314F9F2DF75E781E8A4A5411ACCB4D9E3103131F52E0D14386A6E107AA7A522E42F1A41C8A8E46CE69E824492B87BC8B34A457EC25A7508B3E1A33BCC9E99EA754163AEC31161A83A80780DF46D36E757CF90C0F002DF73AB406F7DF81FDA75AD7F3F052EEA91955FA737616D8D4BB87A60FF471400D50688146BC3C10FF60A35D8BB9EF6BEF26497361118125FBEE607726AA408674A45931C87666146BE520503A5241D49B964406A864749C50F9B2718B8E0F62614DB27F35F53D57F70CB4ECE081BD377CDBA5C4AD75BEA63CB8E2653E52D11C0CAC67916B0C24232FC9D90091C7CDD317D4F60D8271D81E70B79031BE25CD5D6CC1E7A04FAF98C25B143B9D7B08D94160B1737AB49F55A01AF3A9BB7C8C261E8F2F84A1995C752276F5F03E54EE22A973F63C73083377DD6851634AA5568AA1173E5BE96606D946AAC82951E326750E18C2AD12C311EF784AD9014BEE322032B45244BD6EEDA224CCDA93983C8FB326F8C8B02F5574B0BC0CD7BFD1C524CD66ACD8A7AC1619E57136F2FEB5F49E9791D4E0F0C9AB8B9E7A98E49E5603D4E02771EFC9993ED15974CD0EEA50510C410FD884CB5D83D0FCD0AF7218D49523F95C4C396CBC0359DABD75EC138910788E1766649130AD089F565ED926B4F26FEBAF9CA4F768E6CA6E6BB7E43769B7D46E2F0D6A63254B41715567635FC1D38DCD7E047122A7
-20180409212042 2 6 100 6143 5 E01FFD7EC91328929E4FD6183C9C9EDF4EF8CFC608D943A1011CEE0B49D7322663D64028F7205A4F008A0C8F393F91FF42D1C7ACB6B4041D0DC79BB0DA6D394532A0E33BC96FEA6EC2E67987F13D2F218B9E8A46D20125D822B6AA1C9615087E5C667CCA74414305E3382E20792B058F61D9DBFD93EF80A2E30E17FDB883F79989B540A6E467D9CEF07C849B659890706CAC7FF6F95669DAD0D9170D485C298AA940C6B7B3092E265FB512C70F36E3D6515B7B799E20FFE9DA35F932C3F2C238F5D8BCB92193216563D6163EB9FAAFEDD0E8A1A3F8CE292E8A1BEF630C5E75D845444B414017844E9560C8309CD54BF9EEAB2CAAE888226AB8031F1569A728256BB6FCC14DF314314F9F2DF75E781E8A4A5411ACCB4D9E3103131F52E0D14386A6E107AA7A522E42F1A41C8A8E46CE69E824492B87BC8B34A457EC25A7508B3E1A33BCC9E99EA754163AEC31161A83A80780DF46D36E757CF90C0F002DF73AB406F7DF81FDA75AD7F3F052EEA91955FA737616D8D4BB87A60FF471400D50688146BC3C10FF60A35D8BB9EF6BEF26497361118125FBEE607726AA408674A45931C87666146BE520503A5241D49B964406A864749C50F9B2718B8E0F62614DB27F35F53D57F70CB4ECE081BD377CDBA5C4AD75BEA63CB8E2653E52D11C0CAC67916B0C24232FC9D90091C7CDD317D4F60D8271D81E70B79031BE25CD5D6CC1E7A04FAF98C25B143B9D7B08D94160B1737AB49F55A01AF3A9BB7C8C261E8F2F84A1995C752276F5F03E54EE22A973F63C73083377DD6851634AA5568AA1173E5BE96606D946AAC82951E326750E18C2AD12C311EF784AD9014BEE322032B45244BD6EEDA224CCDA93983C8FB326F8C8B02F5574B0BC0CD7BFD1C524CD66ACD8A7AC1619E57136F2FEB5F49E9791D4E0F0C9AB8B9E7A98E49E5603D4E02771EFC9993ED15974CD0EEA50510C410FD884CB5D83D0FCD0AF7218D49523F95C4C396CBC0359DABD75EC138910788E1766649130AD089F565ED926B4F26FEBAF9CA4F768E6CA6E6BB7E43769B7D46E2F0D6A63254B41715567635FC1D38DCD7E06189297
-20180410021123 2 6 100 6143 5 E01FFD7EC91328929E4FD6183C9C9EDF4EF8CFC608D943A1011CEE0B49D7322663D64028F7205A4F008A0C8F393F91FF42D1C7ACB6B4041D0DC79BB0DA6D394532A0E33BC96FEA6EC2E67987F13D2F218B9E8A46D20125D822B6AA1C9615087E5C667CCA74414305E3382E20792B058F61D9DBFD93EF80A2E30E17FDB883F79989B540A6E467D9CEF07C849B659890706CAC7FF6F95669DAD0D9170D485C298AA940C6B7B3092E265FB512C70F36E3D6515B7B799E20FFE9DA35F932C3F2C238F5D8BCB92193216563D6163EB9FAAFEDD0E8A1A3F8CE292E8A1BEF630C5E75D845444B414017844E9560C8309CD54BF9EEAB2CAAE888226AB8031F1569A728256BB6FCC14DF314314F9F2DF75E781E8A4A5411ACCB4D9E3103131F52E0D14386A6E107AA7A522E42F1A41C8A8E46CE69E824492B87BC8B34A457EC25A7508B3E1A33BCC9E99EA754163AEC31161A83A80780DF46D36E757CF90C0F002DF73AB406F7DF81FDA75AD7F3F052EEA91955FA737616D8D4BB87A60FF471400D50688146BC3C10FF60A35D8BB9EF6BEF26497361118125FBEE607726AA408674A45931C87666146BE520503A5241D49B964406A864749C50F9B2718B8E0F62614DB27F35F53D57F70CB4ECE081BD377CDBA5C4AD75BEA63CB8E2653E52D11C0CAC67916B0C24232FC9D90091C7CDD317D4F60D8271D81E70B79031BE25CD5D6CC1E7A04FAF98C25B143B9D7B08D94160B1737AB49F55A01AF3A9BB7C8C261E8F2F84A1995C752276F5F03E54EE22A973F63C73083377DD6851634AA5568AA1173E5BE96606D946AAC82951E326750E18C2AD12C311EF784AD9014BEE322032B45244BD6EEDA224CCDA93983C8FB326F8C8B02F5574B0BC0CD7BFD1C524CD66ACD8A7AC1619E57136F2FEB5F49E9791D4E0F0C9AB8B9E7A98E49E5603D4E02771EFC9993ED15974CD0EEA50510C410FD884CB5D83D0FCD0AF7218D49523F95C4C396CBC0359DABD75EC138910788E1766649130AD089F565ED926B4F26FEBAF9CA4F768E6CA6E6BB7E43769B7D46E2F0D6A63254B41715567635FC1D38DCD7E0D35B28F
-20180410022638 2 6 100 6143 2 E01FFD7EC91328929E4FD6183C9C9EDF4EF8CFC608D943A1011CEE0B49D7322663D64028F7205A4F008A0C8F393F91FF42D1C7ACB6B4041D0DC79BB0DA6D394532A0E33BC96FEA6EC2E67987F13D2F218B9E8A46D20125D822B6AA1C9615087E5C667CCA74414305E3382E20792B058F61D9DBFD93EF80A2E30E17FDB883F79989B540A6E467D9CEF07C849B659890706CAC7FF6F95669DAD0D9170D485C298AA940C6B7B3092E265FB512C70F36E3D6515B7B799E20FFE9DA35F932C3F2C238F5D8BCB92193216563D6163EB9FAAFEDD0E8A1A3F8CE292E8A1BEF630C5E75D845444B414017844E9560C8309CD54BF9EEAB2CAAE888226AB8031F1569A728256BB6FCC14DF314314F9F2DF75E781E8A4A5411ACCB4D9E3103131F52E0D14386A6E107AA7A522E42F1A41C8A8E46CE69E824492B87BC8B34A457EC25A7508B3E1A33BCC9E99EA754163AEC31161A83A80780DF46D36E757CF90C0F002DF73AB406F7DF81FDA75AD7F3F052EEA91955FA737616D8D4BB87A60FF471400D50688146BC3C10FF60A35D8BB9EF6BEF26497361118125FBEE607726AA408674A45931C87666146BE520503A5241D49B964406A864749C50F9B2718B8E0F62614DB27F35F53D57F70CB4ECE081BD377CDBA5C4AD75BEA63CB8E2653E52D11C0CAC67916B0C24232FC9D90091C7CDD317D4F60D8271D81E70B79031BE25CD5D6CC1E7A04FAF98C25B143B9D7B08D94160B1737AB49F55A01AF3A9BB7C8C261E8F2F84A1995C752276F5F03E54EE22A973F63C73083377DD6851634AA5568AA1173E5BE96606D946AAC82951E326750E18C2AD12C311EF784AD9014BEE322032B45244BD6EEDA224CCDA93983C8FB326F8C8B02F5574B0BC0CD7BFD1C524CD66ACD8A7AC1619E57136F2FEB5F49E9791D4E0F0C9AB8B9E7A98E49E5603D4E02771EFC9993ED15974CD0EEA50510C410FD884CB5D83D0FCD0AF7218D49523F95C4C396CBC0359DABD75EC138910788E1766649130AD089F565ED926B4F26FEBAF9CA4F768E6CA6E6BB7E43769B7D46E2F0D6A63254B41715567635FC1D38DCD7E0D8CA623
-20180410024637 2 6 100 6143 5 E01FFD7EC91328929E4FD6183C9C9EDF4EF8CFC608D943A1011CEE0B49D7322663D64028F7205A4F008A0C8F393F91FF42D1C7ACB6B4041D0DC79BB0DA6D394532A0E33BC96FEA6EC2E67987F13D2F218B9E8A46D20125D822B6AA1C9615087E5C667CCA74414305E3382E20792B058F61D9DBFD93EF80A2E30E17FDB883F79989B540A6E467D9CEF07C849B659890706CAC7FF6F95669DAD0D9170D485C298AA940C6B7B3092E265FB512C70F36E3D6515B7B799E20FFE9DA35F932C3F2C238F5D8BCB92193216563D6163EB9FAAFEDD0E8A1A3F8CE292E8A1BEF630C5E75D845444B414017844E9560C8309CD54BF9EEAB2CAAE888226AB8031F1569A728256BB6FCC14DF314314F9F2DF75E781E8A4A5411ACCB4D9E3103131F52E0D14386A6E107AA7A522E42F1A41C8A8E46CE69E824492B87BC8B34A457EC25A7508B3E1A33BCC9E99EA754163AEC31161A83A80780DF46D36E757CF90C0F002DF73AB406F7DF81FDA75AD7F3F052EEA91955FA737616D8D4BB87A60FF471400D50688146BC3C10FF60A35D8BB9EF6BEF26497361118125FBEE607726AA408674A45931C87666146BE520503A5241D49B964406A864749C50F9B2718B8E0F62614DB27F35F53D57F70CB4ECE081BD377CDBA5C4AD75BEA63CB8E2653E52D11C0CAC67916B0C24232FC9D90091C7CDD317D4F60D8271D81E70B79031BE25CD5D6CC1E7A04FAF98C25B143B9D7B08D94160B1737AB49F55A01AF3A9BB7C8C261E8F2F84A1995C752276F5F03E54EE22A973F63C73083377DD6851634AA5568AA1173E5BE96606D946AAC82951E326750E18C2AD12C311EF784AD9014BEE322032B45244BD6EEDA224CCDA93983C8FB326F8C8B02F5574B0BC0CD7BFD1C524CD66ACD8A7AC1619E57136F2FEB5F49E9791D4E0F0C9AB8B9E7A98E49E5603D4E02771EFC9993ED15974CD0EEA50510C410FD884CB5D83D0FCD0AF7218D49523F95C4C396CBC0359DABD75EC138910788E1766649130AD089F565ED926B4F26FEBAF9CA4F768E6CA6E6BB7E43769B7D46E2F0D6A63254B41715567635FC1D38DCD7E0E02E03F
-20180410063306 2 6 100 6143 2 E01FFD7EC91328929E4FD6183C9C9EDF4EF8CFC608D943A1011CEE0B49D7322663D64028F7205A4F008A0C8F393F91FF42D1C7ACB6B4041D0DC79BB0DA6D394532A0E33BC96FEA6EC2E67987F13D2F218B9E8A46D20125D822B6AA1C9615087E5C667CCA74414305E3382E20792B058F61D9DBFD93EF80A2E30E17FDB883F79989B540A6E467D9CEF07C849B659890706CAC7FF6F95669DAD0D9170D485C298AA940C6B7B3092E265FB512C70F36E3D6515B7B799E20FFE9DA35F932C3F2C238F5D8BCB92193216563D6163EB9FAAFEDD0E8A1A3F8CE292E8A1BEF630C5E75D845444B414017844E9560C8309CD54BF9EEAB2CAAE888226AB8031F1569A728256BB6FCC14DF314314F9F2DF75E781E8A4A5411ACCB4D9E3103131F52E0D14386A6E107AA7A522E42F1A41C8A8E46CE69E824492B87BC8B34A457EC25A7508B3E1A33BCC9E99EA754163AEC31161A83A80780DF46D36E757CF90C0F002DF73AB406F7DF81FDA75AD7F3F052EEA91955FA737616D8D4BB87A60FF471400D50688146BC3C10FF60A35D8BB9EF6BEF26497361118125FBEE607726AA408674A45931C87666146BE520503A5241D49B964406A864749C50F9B2718B8E0F62614DB27F35F53D57F70CB4ECE081BD377CDBA5C4AD75BEA63CB8E2653E52D11C0CAC67916B0C24232FC9D90091C7CDD317D4F60D8271D81E70B79031BE25CD5D6CC1E7A04FAF98C25B143B9D7B08D94160B1737AB49F55A01AF3A9BB7C8C261E8F2F84A1995C752276F5F03E54EE22A973F63C73083377DD6851634AA5568AA1173E5BE96606D946AAC82951E326750E18C2AD12C311EF784AD9014BEE322032B45244BD6EEDA224CCDA93983C8FB326F8C8B02F5574B0BC0CD7BFD1C524CD66ACD8A7AC1619E57136F2FEB5F49E9791D4E0F0C9AB8B9E7A98E49E5603D4E02771EFC9993ED15974CD0EEA50510C410FD884CB5D83D0FCD0AF7218D49523F95C4C396CBC0359DABD75EC138910788E1766649130AD089F565ED926B4F26FEBAF9CA4F768E6CA6E6BB7E43769B7D46E2F0D6A63254B41715567635FC1D38DCD7E1393582B
-20180410063848 2 6 100 6143 2 E01FFD7EC91328929E4FD6183C9C9EDF4EF8CFC608D943A1011CEE0B49D7322663D64028F7205A4F008A0C8F393F91FF42D1C7ACB6B4041D0DC79BB0DA6D394532A0E33BC96FEA6EC2E67987F13D2F218B9E8A46D20125D822B6AA1C9615087E5C667CCA74414305E3382E20792B058F61D9DBFD93EF80A2E30E17FDB883F79989B540A6E467D9CEF07C849B659890706CAC7FF6F95669DAD0D9170D485C298AA940C6B7B3092E265FB512C70F36E3D6515B7B799E20FFE9DA35F932C3F2C238F5D8BCB92193216563D6163EB9FAAFEDD0E8A1A3F8CE292E8A1BEF630C5E75D845444B414017844E9560C8309CD54BF9EEAB2CAAE888226AB8031F1569A728256BB6FCC14DF314314F9F2DF75E781E8A4A5411ACCB4D9E3103131F52E0D14386A6E107AA7A522E42F1A41C8A8E46CE69E824492B87BC8B34A457EC25A7508B3E1A33BCC9E99EA754163AEC31161A83A80780DF46D36E757CF90C0F002DF73AB406F7DF81FDA75AD7F3F052EEA91955FA737616D8D4BB87A60FF471400D50688146BC3C10FF60A35D8BB9EF6BEF26497361118125FBEE607726AA408674A45931C87666146BE520503A5241D49B964406A864749C50F9B2718B8E0F62614DB27F35F53D57F70CB4ECE081BD377CDBA5C4AD75BEA63CB8E2653E52D11C0CAC67916B0C24232FC9D90091C7CDD317D4F60D8271D81E70B79031BE25CD5D6CC1E7A04FAF98C25B143B9D7B08D94160B1737AB49F55A01AF3A9BB7C8C261E8F2F84A1995C752276F5F03E54EE22A973F63C73083377DD6851634AA5568AA1173E5BE96606D946AAC82951E326750E18C2AD12C311EF784AD9014BEE322032B45244BD6EEDA224CCDA93983C8FB326F8C8B02F5574B0BC0CD7BFD1C524CD66ACD8A7AC1619E57136F2FEB5F49E9791D4E0F0C9AB8B9E7A98E49E5603D4E02771EFC9993ED15974CD0EEA50510C410FD884CB5D83D0FCD0AF7218D49523F95C4C396CBC0359DABD75EC138910788E1766649130AD089F565ED926B4F26FEBAF9CA4F768E6CA6E6BB7E43769B7D46E2F0D6A63254B41715567635FC1D38DCD7E13B0682B
-20180410071153 2 6 100 6143 2 E01FFD7EC91328929E4FD6183C9C9EDF4EF8CFC608D943A1011CEE0B49D7322663D64028F7205A4F008A0C8F393F91FF42D1C7ACB6B4041D0DC79BB0DA6D394532A0E33BC96FEA6EC2E67987F13D2F218B9E8A46D20125D822B6AA1C9615087E5C667CCA74414305E3382E20792B058F61D9DBFD93EF80A2E30E17FDB883F79989B540A6E467D9CEF07C849B659890706CAC7FF6F95669DAD0D9170D485C298AA940C6B7B3092E265FB512C70F36E3D6515B7B799E20FFE9DA35F932C3F2C238F5D8BCB92193216563D6163EB9FAAFEDD0E8A1A3F8CE292E8A1BEF630C5E75D845444B414017844E9560C8309CD54BF9EEAB2CAAE888226AB8031F1569A728256BB6FCC14DF314314F9F2DF75E781E8A4A5411ACCB4D9E3103131F52E0D14386A6E107AA7A522E42F1A41C8A8E46CE69E824492B87BC8B34A457EC25A7508B3E1A33BCC9E99EA754163AEC31161A83A80780DF46D36E757CF90C0F002DF73AB406F7DF81FDA75AD7F3F052EEA91955FA737616D8D4BB87A60FF471400D50688146BC3C10FF60A35D8BB9EF6BEF26497361118125FBEE607726AA408674A45931C87666146BE520503A5241D49B964406A864749C50F9B2718B8E0F62614DB27F35F53D57F70CB4ECE081BD377CDBA5C4AD75BEA63CB8E2653E52D11C0CAC67916B0C24232FC9D90091C7CDD317D4F60D8271D81E70B79031BE25CD5D6CC1E7A04FAF98C25B143B9D7B08D94160B1737AB49F55A01AF3A9BB7C8C261E8F2F84A1995C752276F5F03E54EE22A973F63C73083377DD6851634AA5568AA1173E5BE96606D946AAC82951E326750E18C2AD12C311EF784AD9014BEE322032B45244BD6EEDA224CCDA93983C8FB326F8C8B02F5574B0BC0CD7BFD1C524CD66ACD8A7AC1619E57136F2FEB5F49E9791D4E0F0C9AB8B9E7A98E49E5603D4E02771EFC9993ED15974CD0EEA50510C410FD884CB5D83D0FCD0AF7218D49523F95C4C396CBC0359DABD75EC138910788E1766649130AD089F565ED926B4F26FEBAF9CA4F768E6CA6E6BB7E43769B7D46E2F0D6A63254B41715567635FC1D38DCD7E147AB73B
-20180410082253 2 6 100 6143 5 E01FFD7EC91328929E4FD6183C9C9EDF4EF8CFC608D943A1011CEE0B49D7322663D64028F7205A4F008A0C8F393F91FF42D1C7ACB6B4041D0DC79BB0DA6D394532A0E33BC96FEA6EC2E67987F13D2F218B9E8A46D20125D822B6AA1C9615087E5C667CCA74414305E3382E20792B058F61D9DBFD93EF80A2E30E17FDB883F79989B540A6E467D9CEF07C849B659890706CAC7FF6F95669DAD0D9170D485C298AA940C6B7B3092E265FB512C70F36E3D6515B7B799E20FFE9DA35F932C3F2C238F5D8BCB92193216563D6163EB9FAAFEDD0E8A1A3F8CE292E8A1BEF630C5E75D845444B414017844E9560C8309CD54BF9EEAB2CAAE888226AB8031F1569A728256BB6FCC14DF314314F9F2DF75E781E8A4A5411ACCB4D9E3103131F52E0D14386A6E107AA7A522E42F1A41C8A8E46CE69E824492B87BC8B34A457EC25A7508B3E1A33BCC9E99EA754163AEC31161A83A80780DF46D36E757CF90C0F002DF73AB406F7DF81FDA75AD7F3F052EEA91955FA737616D8D4BB87A60FF471400D50688146BC3C10FF60A35D8BB9EF6BEF26497361118125FBEE607726AA408674A45931C87666146BE520503A5241D49B964406A864749C50F9B2718B8E0F62614DB27F35F53D57F70CB4ECE081BD377CDBA5C4AD75BEA63CB8E2653E52D11C0CAC67916B0C24232FC9D90091C7CDD317D4F60D8271D81E70B79031BE25CD5D6CC1E7A04FAF98C25B143B9D7B08D94160B1737AB49F55A01AF3A9BB7C8C261E8F2F84A1995C752276F5F03E54EE22A973F63C73083377DD6851634AA5568AA1173E5BE96606D946AAC82951E326750E18C2AD12C311EF784AD9014BEE322032B45244BD6EEDA224CCDA93983C8FB326F8C8B02F5574B0BC0CD7BFD1C524CD66ACD8A7AC1619E57136F2FEB5F49E9791D4E0F0C9AB8B9E7A98E49E5603D4E02771EFC9993ED15974CD0EEA50510C410FD884CB5D83D0FCD0AF7218D49523F95C4C396CBC0359DABD75EC138910788E1766649130AD089F565ED926B4F26FEBAF9CA4F768E6CA6E6BB7E43769B7D46E2F0D6A63254B41715567635FC1D38DCD7E16363257
-20180410101335 2 6 100 6143 2 E01FFD7EC91328929E4FD6183C9C9EDF4EF8CFC608D943A1011CEE0B49D7322663D64028F7205A4F008A0C8F393F91FF42D1C7ACB6B4041D0DC79BB0DA6D394532A0E33BC96FEA6EC2E67987F13D2F218B9E8A46D20125D822B6AA1C9615087E5C667CCA74414305E3382E20792B058F61D9DBFD93EF80A2E30E17FDB883F79989B540A6E467D9CEF07C849B659890706CAC7FF6F95669DAD0D9170D485C298AA940C6B7B3092E265FB512C70F36E3D6515B7B799E20FFE9DA35F932C3F2C238F5D8BCB92193216563D6163EB9FAAFEDD0E8A1A3F8CE292E8A1BEF630C5E75D845444B414017844E9560C8309CD54BF9EEAB2CAAE888226AB8031F1569A728256BB6FCC14DF314314F9F2DF75E781E8A4A5411ACCB4D9E3103131F52E0D14386A6E107AA7A522E42F1A41C8A8E46CE69E824492B87BC8B34A457EC25A7508B3E1A33BCC9E99EA754163AEC31161A83A80780DF46D36E757CF90C0F002DF73AB406F7DF81FDA75AD7F3F052EEA91955FA737616D8D4BB87A60FF471400D50688146BC3C10FF60A35D8BB9EF6BEF26497361118125FBEE607726AA408674A45931C87666146BE520503A5241D49B964406A864749C50F9B2718B8E0F62614DB27F35F53D57F70CB4ECE081BD377CDBA5C4AD75BEA63CB8E2653E52D11C0CAC67916B0C24232FC9D90091C7CDD317D4F60D8271D81E70B79031BE25CD5D6CC1E7A04FAF98C25B143B9D7B08D94160B1737AB49F55A01AF3A9BB7C8C261E8F2F84A1995C752276F5F03E54EE22A973F63C73083377DD6851634AA5568AA1173E5BE96606D946AAC82951E326750E18C2AD12C311EF784AD9014BEE322032B45244BD6EEDA224CCDA93983C8FB326F8C8B02F5574B0BC0CD7BFD1C524CD66ACD8A7AC1619E57136F2FEB5F49E9791D4E0F0C9AB8B9E7A98E49E5603D4E02771EFC9993ED15974CD0EEA50510C410FD884CB5D83D0FCD0AF7218D49523F95C4C396CBC0359DABD75EC138910788E1766649130AD089F565ED926B4F26FEBAF9CA4F768E6CA6E6BB7E43769B7D46E2F0D6A63254B41715567635FC1D38DCD7E18F03B13
-20180410105609 2 6 100 6143 5 E01FFD7EC91328929E4FD6183C9C9EDF4EF8CFC608D943A1011CEE0B49D7322663D64028F7205A4F008A0C8F393F91FF42D1C7ACB6B4041D0DC79BB0DA6D394532A0E33BC96FEA6EC2E67987F13D2F218B9E8A46D20125D822B6AA1C9615087E5C667CCA74414305E3382E20792B058F61D9DBFD93EF80A2E30E17FDB883F79989B540A6E467D9CEF07C849B659890706CAC7FF6F95669DAD0D9170D485C298AA940C6B7B3092E265FB512C70F36E3D6515B7B799E20FFE9DA35F932C3F2C238F5D8BCB92193216563D6163EB9FAAFEDD0E8A1A3F8CE292E8A1BEF630C5E75D845444B414017844E9560C8309CD54BF9EEAB2CAAE888226AB8031F1569A728256BB6FCC14DF314314F9F2DF75E781E8A4A5411ACCB4D9E3103131F52E0D14386A6E107AA7A522E42F1A41C8A8E46CE69E824492B87BC8B34A457EC25A7508B3E1A33BCC9E99EA754163AEC31161A83A80780DF46D36E757CF90C0F002DF73AB406F7DF81FDA75AD7F3F052EEA91955FA737616D8D4BB87A60FF471400D50688146BC3C10FF60A35D8BB9EF6BEF26497361118125FBEE607726AA408674A45931C87666146BE520503A5241D49B964406A864749C50F9B2718B8E0F62614DB27F35F53D57F70CB4ECE081BD377CDBA5C4AD75BEA63CB8E2653E52D11C0CAC67916B0C24232FC9D90091C7CDD317D4F60D8271D81E70B79031BE25CD5D6CC1E7A04FAF98C25B143B9D7B08D94160B1737AB49F55A01AF3A9BB7C8C261E8F2F84A1995C752276F5F03E54EE22A973F63C73083377DD6851634AA5568AA1173E5BE96606D946AAC82951E326750E18C2AD12C311EF784AD9014BEE322032B45244BD6EEDA224CCDA93983C8FB326F8C8B02F5574B0BC0CD7BFD1C524CD66ACD8A7AC1619E57136F2FEB5F49E9791D4E0F0C9AB8B9E7A98E49E5603D4E02771EFC9993ED15974CD0EEA50510C410FD884CB5D83D0FCD0AF7218D49523F95C4C396CBC0359DABD75EC138910788E1766649130AD089F565ED926B4F26FEBAF9CA4F768E6CA6E6BB7E43769B7D46E2F0D6A63254B41715567635FC1D38DCD7E19F1DE37
-20180410152104 2 6 100 6143 2 E01FFD7EC91328929E4FD6183C9C9EDF4EF8CFC608D943A1011CEE0B49D7322663D64028F7205A4F008A0C8F393F91FF42D1C7ACB6B4041D0DC79BB0DA6D394532A0E33BC96FEA6EC2E67987F13D2F218B9E8A46D20125D822B6AA1C9615087E5C667CCA74414305E3382E20792B058F61D9DBFD93EF80A2E30E17FDB883F79989B540A6E467D9CEF07C849B659890706CAC7FF6F95669DAD0D9170D485C298AA940C6B7B3092E265FB512C70F36E3D6515B7B799E20FFE9DA35F932C3F2C238F5D8BCB92193216563D6163EB9FAAFEDD0E8A1A3F8CE292E8A1BEF630C5E75D845444B414017844E9560C8309CD54BF9EEAB2CAAE888226AB8031F1569A728256BB6FCC14DF314314F9F2DF75E781E8A4A5411ACCB4D9E3103131F52E0D14386A6E107AA7A522E42F1A41C8A8E46CE69E824492B87BC8B34A457EC25A7508B3E1A33BCC9E99EA754163AEC31161A83A80780DF46D36E757CF90C0F002DF73AB406F7DF81FDA75AD7F3F052EEA91955FA737616D8D4BB87A60FF471400D50688146BC3C10FF60A35D8BB9EF6BEF26497361118125FBEE607726AA408674A45931C87666146BE520503A5241D49B964406A864749C50F9B2718B8E0F62614DB27F35F53D57F70CB4ECE081BD377CDBA5C4AD75BEA63CB8E2653E52D11C0CAC67916B0C24232FC9D90091C7CDD317D4F60D8271D81E70B79031BE25CD5D6CC1E7A04FAF98C25B143B9D7B08D94160B1737AB49F55A01AF3A9BB7C8C261E8F2F84A1995C752276F5F03E54EE22A973F63C73083377DD6851634AA5568AA1173E5BE96606D946AAC82951E326750E18C2AD12C311EF784AD9014BEE322032B45244BD6EEDA224CCDA93983C8FB326F8C8B02F5574B0BC0CD7BFD1C524CD66ACD8A7AC1619E57136F2FEB5F49E9791D4E0F0C9AB8B9E7A98E49E5603D4E02771EFC9993ED15974CD0EEA50510C410FD884CB5D83D0FCD0AF7218D49523F95C4C396CBC0359DABD75EC138910788E1766649130AD089F565ED926B4F26FEBAF9CA4F768E6CA6E6BB7E43769B7D46E2F0D6A63254B41715567635FC1D38DCD7E205A4ACB
-20180410153733 2 6 100 6143 5 E01FFD7EC91328929E4FD6183C9C9EDF4EF8CFC608D943A1011CEE0B49D7322663D64028F7205A4F008A0C8F393F91FF42D1C7ACB6B4041D0DC79BB0DA6D394532A0E33BC96FEA6EC2E67987F13D2F218B9E8A46D20125D822B6AA1C9615087E5C667CCA74414305E3382E20792B058F61D9DBFD93EF80A2E30E17FDB883F79989B540A6E467D9CEF07C849B659890706CAC7FF6F95669DAD0D9170D485C298AA940C6B7B3092E265FB512C70F36E3D6515B7B799E20FFE9DA35F932C3F2C238F5D8BCB92193216563D6163EB9FAAFEDD0E8A1A3F8CE292E8A1BEF630C5E75D845444B414017844E9560C8309CD54BF9EEAB2CAAE888226AB8031F1569A728256BB6FCC14DF314314F9F2DF75E781E8A4A5411ACCB4D9E3103131F52E0D14386A6E107AA7A522E42F1A41C8A8E46CE69E824492B87BC8B34A457EC25A7508B3E1A33BCC9E99EA754163AEC31161A83A80780DF46D36E757CF90C0F002DF73AB406F7DF81FDA75AD7F3F052EEA91955FA737616D8D4BB87A60FF471400D50688146BC3C10FF60A35D8BB9EF6BEF26497361118125FBEE607726AA408674A45931C87666146BE520503A5241D49B964406A864749C50F9B2718B8E0F62614DB27F35F53D57F70CB4ECE081BD377CDBA5C4AD75BEA63CB8E2653E52D11C0CAC67916B0C24232FC9D90091C7CDD317D4F60D8271D81E70B79031BE25CD5D6CC1E7A04FAF98C25B143B9D7B08D94160B1737AB49F55A01AF3A9BB7C8C261E8F2F84A1995C752276F5F03E54EE22A973F63C73083377DD6851634AA5568AA1173E5BE96606D946AAC82951E326750E18C2AD12C311EF784AD9014BEE322032B45244BD6EEDA224CCDA93983C8FB326F8C8B02F5574B0BC0CD7BFD1C524CD66ACD8A7AC1619E57136F2FEB5F49E9791D4E0F0C9AB8B9E7A98E49E5603D4E02771EFC9993ED15974CD0EEA50510C410FD884CB5D83D0FCD0AF7218D49523F95C4C396CBC0359DABD75EC138910788E1766649130AD089F565ED926B4F26FEBAF9CA4F768E6CA6E6BB7E43769B7D46E2F0D6A63254B41715567635FC1D38DCD7E20B2606F
-20180410175655 2 6 100 6143 5 E01FFD7EC91328929E4FD6183C9C9EDF4EF8CFC608D943A1011CEE0B49D7322663D64028F7205A4F008A0C8F393F91FF42D1C7ACB6B4041D0DC79BB0DA6D394532A0E33BC96FEA6EC2E67987F13D2F218B9E8A46D20125D822B6AA1C9615087E5C667CCA74414305E3382E20792B058F61D9DBFD93EF80A2E30E17FDB883F79989B540A6E467D9CEF07C849B659890706CAC7FF6F95669DAD0D9170D485C298AA940C6B7B3092E265FB512C70F36E3D6515B7B799E20FFE9DA35F932C3F2C238F5D8BCB92193216563D6163EB9FAAFEDD0E8A1A3F8CE292E8A1BEF630C5E75D845444B414017844E9560C8309CD54BF9EEAB2CAAE888226AB8031F1569A728256BB6FCC14DF314314F9F2DF75E781E8A4A5411ACCB4D9E3103131F52E0D14386A6E107AA7A522E42F1A41C8A8E46CE69E824492B87BC8B34A457EC25A7508B3E1A33BCC9E99EA754163AEC31161A83A80780DF46D36E757CF90C0F002DF73AB406F7DF81FDA75AD7F3F052EEA91955FA737616D8D4BB87A60FF471400D50688146BC3C10FF60A35D8BB9EF6BEF26497361118125FBEE607726AA408674A45931C87666146BE520503A5241D49B964406A864749C50F9B2718B8E0F62614DB27F35F53D57F70CB4ECE081BD377CDBA5C4AD75BEA63CB8E2653E52D11C0CAC67916B0C24232FC9D90091C7CDD317D4F60D8271D81E70B79031BE25CD5D6CC1E7A04FAF98C25B143B9D7B08D94160B1737AB49F55A01AF3A9BB7C8C261E8F2F84A1995C752276F5F03E54EE22A973F63C73083377DD6851634AA5568AA1173E5BE96606D946AAC82951E326750E18C2AD12C311EF784AD9014BEE322032B45244BD6EEDA224CCDA93983C8FB326F8C8B02F5574B0BC0CD7BFD1C524CD66ACD8A7AC1619E57136F2FEB5F49E9791D4E0F0C9AB8B9E7A98E49E5603D4E02771EFC9993ED15974CD0EEA50510C410FD884CB5D83D0FCD0AF7218D49523F95C4C396CBC0359DABD75EC138910788E1766649130AD089F565ED926B4F26FEBAF9CA4F768E6CA6E6BB7E43769B7D46E2F0D6A63254B41715567635FC1D38DCD7E240655BF
-20180410204830 2 6 100 6143 5 E01FFD7EC91328929E4FD6183C9C9EDF4EF8CFC608D943A1011CEE0B49D7322663D64028F7205A4F008A0C8F393F91FF42D1C7ACB6B4041D0DC79BB0DA6D394532A0E33BC96FEA6EC2E67987F13D2F218B9E8A46D20125D822B6AA1C9615087E5C667CCA74414305E3382E20792B058F61D9DBFD93EF80A2E30E17FDB883F79989B540A6E467D9CEF07C849B659890706CAC7FF6F95669DAD0D9170D485C298AA940C6B7B3092E265FB512C70F36E3D6515B7B799E20FFE9DA35F932C3F2C238F5D8BCB92193216563D6163EB9FAAFEDD0E8A1A3F8CE292E8A1BEF630C5E75D845444B414017844E9560C8309CD54BF9EEAB2CAAE888226AB8031F1569A728256BB6FCC14DF314314F9F2DF75E781E8A4A5411ACCB4D9E3103131F52E0D14386A6E107AA7A522E42F1A41C8A8E46CE69E824492B87BC8B34A457EC25A7508B3E1A33BCC9E99EA754163AEC31161A83A80780DF46D36E757CF90C0F002DF73AB406F7DF81FDA75AD7F3F052EEA91955FA737616D8D4BB87A60FF471400D50688146BC3C10FF60A35D8BB9EF6BEF26497361118125FBEE607726AA408674A45931C87666146BE520503A5241D49B964406A864749C50F9B2718B8E0F62614DB27F35F53D57F70CB4ECE081BD377CDBA5C4AD75BEA63CB8E2653E52D11C0CAC67916B0C24232FC9D90091C7CDD317D4F60D8271D81E70B79031BE25CD5D6CC1E7A04FAF98C25B143B9D7B08D94160B1737AB49F55A01AF3A9BB7C8C261E8F2F84A1995C752276F5F03E54EE22A973F63C73083377DD6851634AA5568AA1173E5BE96606D946AAC82951E326750E18C2AD12C311EF784AD9014BEE322032B45244BD6EEDA224CCDA93983C8FB326F8C8B02F5574B0BC0CD7BFD1C524CD66ACD8A7AC1619E57136F2FEB5F49E9791D4E0F0C9AB8B9E7A98E49E5603D4E02771EFC9993ED15974CD0EEA50510C410FD884CB5D83D0FCD0AF7218D49523F95C4C396CBC0359DABD75EC138910788E1766649130AD089F565ED926B4F26FEBAF9CA4F768E6CA6E6BB7E43769B7D46E2F0D6A63254B41715567635FC1D38DCD7E281EDA87
-20180410231426 2 6 100 6143 2 E01FFD7EC91328929E4FD6183C9C9EDF4EF8CFC608D943A1011CEE0B49D7322663D64028F7205A4F008A0C8F393F91FF42D1C7ACB6B4041D0DC79BB0DA6D394532A0E33BC96FEA6EC2E67987F13D2F218B9E8A46D20125D822B6AA1C9615087E5C667CCA74414305E3382E20792B058F61D9DBFD93EF80A2E30E17FDB883F79989B540A6E467D9CEF07C849B659890706CAC7FF6F95669DAD0D9170D485C298AA940C6B7B3092E265FB512C70F36E3D6515B7B799E20FFE9DA35F932C3F2C238F5D8BCB92193216563D6163EB9FAAFEDD0E8A1A3F8CE292E8A1BEF630C5E75D845444B414017844E9560C8309CD54BF9EEAB2CAAE888226AB8031F1569A728256BB6FCC14DF314314F9F2DF75E781E8A4A5411ACCB4D9E3103131F52E0D14386A6E107AA7A522E42F1A41C8A8E46CE69E824492B87BC8B34A457EC25A7508B3E1A33BCC9E99EA754163AEC31161A83A80780DF46D36E757CF90C0F002DF73AB406F7DF81FDA75AD7F3F052EEA91955FA737616D8D4BB87A60FF471400D50688146BC3C10FF60A35D8BB9EF6BEF26497361118125FBEE607726AA408674A45931C87666146BE520503A5241D49B964406A864749C50F9B2718B8E0F62614DB27F35F53D57F70CB4ECE081BD377CDBA5C4AD75BEA63CB8E2653E52D11C0CAC67916B0C24232FC9D90091C7CDD317D4F60D8271D81E70B79031BE25CD5D6CC1E7A04FAF98C25B143B9D7B08D94160B1737AB49F55A01AF3A9BB7C8C261E8F2F84A1995C752276F5F03E54EE22A973F63C73083377DD6851634AA5568AA1173E5BE96606D946AAC82951E326750E18C2AD12C311EF784AD9014BEE322032B45244BD6EEDA224CCDA93983C8FB326F8C8B02F5574B0BC0CD7BFD1C524CD66ACD8A7AC1619E57136F2FEB5F49E9791D4E0F0C9AB8B9E7A98E49E5603D4E02771EFC9993ED15974CD0EEA50510C410FD884CB5D83D0FCD0AF7218D49523F95C4C396CBC0359DABD75EC138910788E1766649130AD089F565ED926B4F26FEBAF9CA4F768E6CA6E6BB7E43769B7D46E2F0D6A63254B41715567635FC1D38DCD7E2B95718B
-20180410233438 2 6 100 6143 5 E01FFD7EC91328929E4FD6183C9C9EDF4EF8CFC608D943A1011CEE0B49D7322663D64028F7205A4F008A0C8F393F91FF42D1C7ACB6B4041D0DC79BB0DA6D394532A0E33BC96FEA6EC2E67987F13D2F218B9E8A46D20125D822B6AA1C9615087E5C667CCA74414305E3382E20792B058F61D9DBFD93EF80A2E30E17FDB883F79989B540A6E467D9CEF07C849B659890706CAC7FF6F95669DAD0D9170D485C298AA940C6B7B3092E265FB512C70F36E3D6515B7B799E20FFE9DA35F932C3F2C238F5D8BCB92193216563D6163EB9FAAFEDD0E8A1A3F8CE292E8A1BEF630C5E75D845444B414017844E9560C8309CD54BF9EEAB2CAAE888226AB8031F1569A728256BB6FCC14DF314314F9F2DF75E781E8A4A5411ACCB4D9E3103131F52E0D14386A6E107AA7A522E42F1A41C8A8E46CE69E824492B87BC8B34A457EC25A7508B3E1A33BCC9E99EA754163AEC31161A83A80780DF46D36E757CF90C0F002DF73AB406F7DF81FDA75AD7F3F052EEA91955FA737616D8D4BB87A60FF471400D50688146BC3C10FF60A35D8BB9EF6BEF26497361118125FBEE607726AA408674A45931C87666146BE520503A5241D49B964406A864749C50F9B2718B8E0F62614DB27F35F53D57F70CB4ECE081BD377CDBA5C4AD75BEA63CB8E2653E52D11C0CAC67916B0C24232FC9D90091C7CDD317D4F60D8271D81E70B79031BE25CD5D6CC1E7A04FAF98C25B143B9D7B08D94160B1737AB49F55A01AF3A9BB7C8C261E8F2F84A1995C752276F5F03E54EE22A973F63C73083377DD6851634AA5568AA1173E5BE96606D946AAC82951E326750E18C2AD12C311EF784AD9014BEE322032B45244BD6EEDA224CCDA93983C8FB326F8C8B02F5574B0BC0CD7BFD1C524CD66ACD8A7AC1619E57136F2FEB5F49E9791D4E0F0C9AB8B9E7A98E49E5603D4E02771EFC9993ED15974CD0EEA50510C410FD884CB5D83D0FCD0AF7218D49523F95C4C396CBC0359DABD75EC138910788E1766649130AD089F565ED926B4F26FEBAF9CA4F768E6CA6E6BB7E43769B7D46E2F0D6A63254B41715567635FC1D38DCD7E2C0621C7
-20180410234833 2 6 100 6143 2 E01FFD7EC91328929E4FD6183C9C9EDF4EF8CFC608D943A1011CEE0B49D7322663D64028F7205A4F008A0C8F393F91FF42D1C7ACB6B4041D0DC79BB0DA6D394532A0E33BC96FEA6EC2E67987F13D2F218B9E8A46D20125D822B6AA1C9615087E5C667CCA74414305E3382E20792B058F61D9DBFD93EF80A2E30E17FDB883F79989B540A6E467D9CEF07C849B659890706CAC7FF6F95669DAD0D9170D485C298AA940C6B7B3092E265FB512C70F36E3D6515B7B799E20FFE9DA35F932C3F2C238F5D8BCB92193216563D6163EB9FAAFEDD0E8A1A3F8CE292E8A1BEF630C5E75D845444B414017844E9560C8309CD54BF9EEAB2CAAE888226AB8031F1569A728256BB6FCC14DF314314F9F2DF75E781E8A4A5411ACCB4D9E3103131F52E0D14386A6E107AA7A522E42F1A41C8A8E46CE69E824492B87BC8B34A457EC25A7508B3E1A33BCC9E99EA754163AEC31161A83A80780DF46D36E757CF90C0F002DF73AB406F7DF81FDA75AD7F3F052EEA91955FA737616D8D4BB87A60FF471400D50688146BC3C10FF60A35D8BB9EF6BEF26497361118125FBEE607726AA408674A45931C87666146BE520503A5241D49B964406A864749C50F9B2718B8E0F62614DB27F35F53D57F70CB4ECE081BD377CDBA5C4AD75BEA63CB8E2653E52D11C0CAC67916B0C24232FC9D90091C7CDD317D4F60D8271D81E70B79031BE25CD5D6CC1E7A04FAF98C25B143B9D7B08D94160B1737AB49F55A01AF3A9BB7C8C261E8F2F84A1995C752276F5F03E54EE22A973F63C73083377DD6851634AA5568AA1173E5BE96606D946AAC82951E326750E18C2AD12C311EF784AD9014BEE322032B45244BD6EEDA224CCDA93983C8FB326F8C8B02F5574B0BC0CD7BFD1C524CD66ACD8A7AC1619E57136F2FEB5F49E9791D4E0F0C9AB8B9E7A98E49E5603D4E02771EFC9993ED15974CD0EEA50510C410FD884CB5D83D0FCD0AF7218D49523F95C4C396CBC0359DABD75EC138910788E1766649130AD089F565ED926B4F26FEBAF9CA4F768E6CA6E6BB7E43769B7D46E2F0D6A63254B41715567635FC1D38DCD7E2C5297E3
-20180411035657 2 6 100 6143 2 E01FFD7EC91328929E4FD6183C9C9EDF4EF8CFC608D943A1011CEE0B49D7322663D64028F7205A4F008A0C8F393F91FF42D1C7ACB6B4041D0DC79BB0DA6D394532A0E33BC96FEA6EC2E67987F13D2F218B9E8A46D20125D822B6AA1C9615087E5C667CCA74414305E3382E20792B058F61D9DBFD93EF80A2E30E17FDB883F79989B540A6E467D9CEF07C849B659890706CAC7FF6F95669DAD0D9170D485C298AA940C6B7B3092E265FB512C70F36E3D6515B7B799E20FFE9DA35F932C3F2C238F5D8BCB92193216563D6163EB9FAAFEDD0E8A1A3F8CE292E8A1BEF630C5E75D845444B414017844E9560C8309CD54BF9EEAB2CAAE888226AB8031F1569A728256BB6FCC14DF314314F9F2DF75E781E8A4A5411ACCB4D9E3103131F52E0D14386A6E107AA7A522E42F1A41C8A8E46CE69E824492B87BC8B34A457EC25A7508B3E1A33BCC9E99EA754163AEC31161A83A80780DF46D36E757CF90C0F002DF73AB406F7DF81FDA75AD7F3F052EEA91955FA737616D8D4BB87A60FF471400D50688146BC3C10FF60A35D8BB9EF6BEF26497361118125FBEE607726AA408674A45931C87666146BE520503A5241D49B964406A864749C50F9B2718B8E0F62614DB27F35F53D57F70CB4ECE081BD377CDBA5C4AD75BEA63CB8E2653E52D11C0CAC67916B0C24232FC9D90091C7CDD317D4F60D8271D81E70B79031BE25CD5D6CC1E7A04FAF98C25B143B9D7B08D94160B1737AB49F55A01AF3A9BB7C8C261E8F2F84A1995C752276F5F03E54EE22A973F63C73083377DD6851634AA5568AA1173E5BE96606D946AAC82951E326750E18C2AD12C311EF784AD9014BEE322032B45244BD6EEDA224CCDA93983C8FB326F8C8B02F5574B0BC0CD7BFD1C524CD66ACD8A7AC1619E57136F2FEB5F49E9791D4E0F0C9AB8B9E7A98E49E5603D4E02771EFC9993ED15974CD0EEA50510C410FD884CB5D83D0FCD0AF7218D49523F95C4C396CBC0359DABD75EC138910788E1766649130AD089F565ED926B4F26FEBAF9CA4F768E6CA6E6BB7E43769B7D46E2F0D6A63254B41715567635FC1D38DCD7E32375BE3
-20180411053901 2 6 100 6143 5 E01FFD7EC91328929E4FD6183C9C9EDF4EF8CFC608D943A1011CEE0B49D7322663D64028F7205A4F008A0C8F393F91FF42D1C7ACB6B4041D0DC79BB0DA6D394532A0E33BC96FEA6EC2E67987F13D2F218B9E8A46D20125D822B6AA1C9615087E5C667CCA74414305E3382E20792B058F61D9DBFD93EF80A2E30E17FDB883F79989B540A6E467D9CEF07C849B659890706CAC7FF6F95669DAD0D9170D485C298AA940C6B7B3092E265FB512C70F36E3D6515B7B799E20FFE9DA35F932C3F2C238F5D8BCB92193216563D6163EB9FAAFEDD0E8A1A3F8CE292E8A1BEF630C5E75D845444B414017844E9560C8309CD54BF9EEAB2CAAE888226AB8031F1569A728256BB6FCC14DF314314F9F2DF75E781E8A4A5411ACCB4D9E3103131F52E0D14386A6E107AA7A522E42F1A41C8A8E46CE69E824492B87BC8B34A457EC25A7508B3E1A33BCC9E99EA754163AEC31161A83A80780DF46D36E757CF90C0F002DF73AB406F7DF81FDA75AD7F3F052EEA91955FA737616D8D4BB87A60FF471400D50688146BC3C10FF60A35D8BB9EF6BEF26497361118125FBEE607726AA408674A45931C87666146BE520503A5241D49B964406A864749C50F9B2718B8E0F62614DB27F35F53D57F70CB4ECE081BD377CDBA5C4AD75BEA63CB8E2653E52D11C0CAC67916B0C24232FC9D90091C7CDD317D4F60D8271D81E70B79031BE25CD5D6CC1E7A04FAF98C25B143B9D7B08D94160B1737AB49F55A01AF3A9BB7C8C261E8F2F84A1995C752276F5F03E54EE22A973F63C73083377DD6851634AA5568AA1173E5BE96606D946AAC82951E326750E18C2AD12C311EF784AD9014BEE322032B45244BD6EEDA224CCDA93983C8FB326F8C8B02F5574B0BC0CD7BFD1C524CD66ACD8A7AC1619E57136F2FEB5F49E9791D4E0F0C9AB8B9E7A98E49E5603D4E02771EFC9993ED15974CD0EEA50510C410FD884CB5D83D0FCD0AF7218D49523F95C4C396CBC0359DABD75EC138910788E1766649130AD089F565ED926B4F26FEBAF9CA4F768E6CA6E6BB7E43769B7D46E2F0D6A63254B41715567635FC1D38DCD7E3499E12F
-20180411073150 2 6 100 6143 2 E01FFD7EC91328929E4FD6183C9C9EDF4EF8CFC608D943A1011CEE0B49D7322663D64028F7205A4F008A0C8F393F91FF42D1C7ACB6B4041D0DC79BB0DA6D394532A0E33BC96FEA6EC2E67987F13D2F218B9E8A46D20125D822B6AA1C9615087E5C667CCA74414305E3382E20792B058F61D9DBFD93EF80A2E30E17FDB883F79989B540A6E467D9CEF07C849B659890706CAC7FF6F95669DAD0D9170D485C298AA940C6B7B3092E265FB512C70F36E3D6515B7B799E20FFE9DA35F932C3F2C238F5D8BCB92193216563D6163EB9FAAFEDD0E8A1A3F8CE292E8A1BEF630C5E75D845444B414017844E9560C8309CD54BF9EEAB2CAAE888226AB8031F1569A728256BB6FCC14DF314314F9F2DF75E781E8A4A5411ACCB4D9E3103131F52E0D14386A6E107AA7A522E42F1A41C8A8E46CE69E824492B87BC8B34A457EC25A7508B3E1A33BCC9E99EA754163AEC31161A83A80780DF46D36E757CF90C0F002DF73AB406F7DF81FDA75AD7F3F052EEA91955FA737616D8D4BB87A60FF471400D50688146BC3C10FF60A35D8BB9EF6BEF26497361118125FBEE607726AA408674A45931C87666146BE520503A5241D49B964406A864749C50F9B2718B8E0F62614DB27F35F53D57F70CB4ECE081BD377CDBA5C4AD75BEA63CB8E2653E52D11C0CAC67916B0C24232FC9D90091C7CDD317D4F60D8271D81E70B79031BE25CD5D6CC1E7A04FAF98C25B143B9D7B08D94160B1737AB49F55A01AF3A9BB7C8C261E8F2F84A1995C752276F5F03E54EE22A973F63C73083377DD6851634AA5568AA1173E5BE96606D946AAC82951E326750E18C2AD12C311EF784AD9014BEE322032B45244BD6EEDA224CCDA93983C8FB326F8C8B02F5574B0BC0CD7BFD1C524CD66ACD8A7AC1619E57136F2FEB5F49E9791D4E0F0C9AB8B9E7A98E49E5603D4E02771EFC9993ED15974CD0EEA50510C410FD884CB5D83D0FCD0AF7218D49523F95C4C396CBC0359DABD75EC138910788E1766649130AD089F565ED926B4F26FEBAF9CA4F768E6CA6E6BB7E43769B7D46E2F0D6A63254B41715567635FC1D38DCD7E3738967B
-20180411073910 2 6 100 6143 5 E01FFD7EC91328929E4FD6183C9C9EDF4EF8CFC608D943A1011CEE0B49D7322663D64028F7205A4F008A0C8F393F91FF42D1C7ACB6B4041D0DC79BB0DA6D394532A0E33BC96FEA6EC2E67987F13D2F218B9E8A46D20125D822B6AA1C9615087E5C667CCA74414305E3382E20792B058F61D9DBFD93EF80A2E30E17FDB883F79989B540A6E467D9CEF07C849B659890706CAC7FF6F95669DAD0D9170D485C298AA940C6B7B3092E265FB512C70F36E3D6515B7B799E20FFE9DA35F932C3F2C238F5D8BCB92193216563D6163EB9FAAFEDD0E8A1A3F8CE292E8A1BEF630C5E75D845444B414017844E9560C8309CD54BF9EEAB2CAAE888226AB8031F1569A728256BB6FCC14DF314314F9F2DF75E781E8A4A5411ACCB4D9E3103131F52E0D14386A6E107AA7A522E42F1A41C8A8E46CE69E824492B87BC8B34A457EC25A7508B3E1A33BCC9E99EA754163AEC31161A83A80780DF46D36E757CF90C0F002DF73AB406F7DF81FDA75AD7F3F052EEA91955FA737616D8D4BB87A60FF471400D50688146BC3C10FF60A35D8BB9EF6BEF26497361118125FBEE607726AA408674A45931C87666146BE520503A5241D49B964406A864749C50F9B2718B8E0F62614DB27F35F53D57F70CB4ECE081BD377CDBA5C4AD75BEA63CB8E2653E52D11C0CAC67916B0C24232FC9D90091C7CDD317D4F60D8271D81E70B79031BE25CD5D6CC1E7A04FAF98C25B143B9D7B08D94160B1737AB49F55A01AF3A9BB7C8C261E8F2F84A1995C752276F5F03E54EE22A973F63C73083377DD6851634AA5568AA1173E5BE96606D946AAC82951E326750E18C2AD12C311EF784AD9014BEE322032B45244BD6EEDA224CCDA93983C8FB326F8C8B02F5574B0BC0CD7BFD1C524CD66ACD8A7AC1619E57136F2FEB5F49E9791D4E0F0C9AB8B9E7A98E49E5603D4E02771EFC9993ED15974CD0EEA50510C410FD884CB5D83D0FCD0AF7218D49523F95C4C396CBC0359DABD75EC138910788E1766649130AD089F565ED926B4F26FEBAF9CA4F768E6CA6E6BB7E43769B7D46E2F0D6A63254B41715567635FC1D38DCD7E375B7807
-20180411075734 2 6 100 6143 2 E01FFD7EC91328929E4FD6183C9C9EDF4EF8CFC608D943A1011CEE0B49D7322663D64028F7205A4F008A0C8F393F91FF42D1C7ACB6B4041D0DC79BB0DA6D394532A0E33BC96FEA6EC2E67987F13D2F218B9E8A46D20125D822B6AA1C9615087E5C667CCA74414305E3382E20792B058F61D9DBFD93EF80A2E30E17FDB883F79989B540A6E467D9CEF07C849B659890706CAC7FF6F95669DAD0D9170D485C298AA940C6B7B3092E265FB512C70F36E3D6515B7B799E20FFE9DA35F932C3F2C238F5D8BCB92193216563D6163EB9FAAFEDD0E8A1A3F8CE292E8A1BEF630C5E75D845444B414017844E9560C8309CD54BF9EEAB2CAAE888226AB8031F1569A728256BB6FCC14DF314314F9F2DF75E781E8A4A5411ACCB4D9E3103131F52E0D14386A6E107AA7A522E42F1A41C8A8E46CE69E824492B87BC8B34A457EC25A7508B3E1A33BCC9E99EA754163AEC31161A83A80780DF46D36E757CF90C0F002DF73AB406F7DF81FDA75AD7F3F052EEA91955FA737616D8D4BB87A60FF471400D50688146BC3C10FF60A35D8BB9EF6BEF26497361118125FBEE607726AA408674A45931C87666146BE520503A5241D49B964406A864749C50F9B2718B8E0F62614DB27F35F53D57F70CB4ECE081BD377CDBA5C4AD75BEA63CB8E2653E52D11C0CAC67916B0C24232FC9D90091C7CDD317D4F60D8271D81E70B79031BE25CD5D6CC1E7A04FAF98C25B143B9D7B08D94160B1737AB49F55A01AF3A9BB7C8C261E8F2F84A1995C752276F5F03E54EE22A973F63C73083377DD6851634AA5568AA1173E5BE96606D946AAC82951E326750E18C2AD12C311EF784AD9014BEE322032B45244BD6EEDA224CCDA93983C8FB326F8C8B02F5574B0BC0CD7BFD1C524CD66ACD8A7AC1619E57136F2FEB5F49E9791D4E0F0C9AB8B9E7A98E49E5603D4E02771EFC9993ED15974CD0EEA50510C410FD884CB5D83D0FCD0AF7218D49523F95C4C396CBC0359DABD75EC138910788E1766649130AD089F565ED926B4F26FEBAF9CA4F768E6CA6E6BB7E43769B7D46E2F0D6A63254B41715567635FC1D38DCD7E37C0C66B
-20180411081855 2 6 100 6143 2 E01FFD7EC91328929E4FD6183C9C9EDF4EF8CFC608D943A1011CEE0B49D7322663D64028F7205A4F008A0C8F393F91FF42D1C7ACB6B4041D0DC79BB0DA6D394532A0E33BC96FEA6EC2E67987F13D2F218B9E8A46D20125D822B6AA1C9615087E5C667CCA74414305E3382E20792B058F61D9DBFD93EF80A2E30E17FDB883F79989B540A6E467D9CEF07C849B659890706CAC7FF6F95669DAD0D9170D485C298AA940C6B7B3092E265FB512C70F36E3D6515B7B799E20FFE9DA35F932C3F2C238F5D8BCB92193216563D6163EB9FAAFEDD0E8A1A3F8CE292E8A1BEF630C5E75D845444B414017844E9560C8309CD54BF9EEAB2CAAE888226AB8031F1569A728256BB6FCC14DF314314F9F2DF75E781E8A4A5411ACCB4D9E3103131F52E0D14386A6E107AA7A522E42F1A41C8A8E46CE69E824492B87BC8B34A457EC25A7508B3E1A33BCC9E99EA754163AEC31161A83A80780DF46D36E757CF90C0F002DF73AB406F7DF81FDA75AD7F3F052EEA91955FA737616D8D4BB87A60FF471400D50688146BC3C10FF60A35D8BB9EF6BEF26497361118125FBEE607726AA408674A45931C87666146BE520503A5241D49B964406A864749C50F9B2718B8E0F62614DB27F35F53D57F70CB4ECE081BD377CDBA5C4AD75BEA63CB8E2653E52D11C0CAC67916B0C24232FC9D90091C7CDD317D4F60D8271D81E70B79031BE25CD5D6CC1E7A04FAF98C25B143B9D7B08D94160B1737AB49F55A01AF3A9BB7C8C261E8F2F84A1995C752276F5F03E54EE22A973F63C73083377DD6851634AA5568AA1173E5BE96606D946AAC82951E326750E18C2AD12C311EF784AD9014BEE322032B45244BD6EEDA224CCDA93983C8FB326F8C8B02F5574B0BC0CD7BFD1C524CD66ACD8A7AC1619E57136F2FEB5F49E9791D4E0F0C9AB8B9E7A98E49E5603D4E02771EFC9993ED15974CD0EEA50510C410FD884CB5D83D0FCD0AF7218D49523F95C4C396CBC0359DABD75EC138910788E1766649130AD089F565ED926B4F26FEBAF9CA4F768E6CA6E6BB7E43769B7D46E2F0D6A63254B41715567635FC1D38DCD7E383A5BCB
-20180411093848 2 6 100 6143 2 E01FFD7EC91328929E4FD6183C9C9EDF4EF8CFC608D943A1011CEE0B49D7322663D64028F7205A4F008A0C8F393F91FF42D1C7ACB6B4041D0DC79BB0DA6D394532A0E33BC96FEA6EC2E67987F13D2F218B9E8A46D20125D822B6AA1C9615087E5C667CCA74414305E3382E20792B058F61D9DBFD93EF80A2E30E17FDB883F79989B540A6E467D9CEF07C849B659890706CAC7FF6F95669DAD0D9170D485C298AA940C6B7B3092E265FB512C70F36E3D6515B7B799E20FFE9DA35F932C3F2C238F5D8BCB92193216563D6163EB9FAAFEDD0E8A1A3F8CE292E8A1BEF630C5E75D845444B414017844E9560C8309CD54BF9EEAB2CAAE888226AB8031F1569A728256BB6FCC14DF314314F9F2DF75E781E8A4A5411ACCB4D9E3103131F52E0D14386A6E107AA7A522E42F1A41C8A8E46CE69E824492B87BC8B34A457EC25A7508B3E1A33BCC9E99EA754163AEC31161A83A80780DF46D36E757CF90C0F002DF73AB406F7DF81FDA75AD7F3F052EEA91955FA737616D8D4BB87A60FF471400D50688146BC3C10FF60A35D8BB9EF6BEF26497361118125FBEE607726AA408674A45931C87666146BE520503A5241D49B964406A864749C50F9B2718B8E0F62614DB27F35F53D57F70CB4ECE081BD377CDBA5C4AD75BEA63CB8E2653E52D11C0CAC67916B0C24232FC9D90091C7CDD317D4F60D8271D81E70B79031BE25CD5D6CC1E7A04FAF98C25B143B9D7B08D94160B1737AB49F55A01AF3A9BB7C8C261E8F2F84A1995C752276F5F03E54EE22A973F63C73083377DD6851634AA5568AA1173E5BE96606D946AAC82951E326750E18C2AD12C311EF784AD9014BEE322032B45244BD6EEDA224CCDA93983C8FB326F8C8B02F5574B0BC0CD7BFD1C524CD66ACD8A7AC1619E57136F2FEB5F49E9791D4E0F0C9AB8B9E7A98E49E5603D4E02771EFC9993ED15974CD0EEA50510C410FD884CB5D83D0FCD0AF7218D49523F95C4C396CBC0359DABD75EC138910788E1766649130AD089F565ED926B4F26FEBAF9CA4F768E6CA6E6BB7E43769B7D46E2F0D6A63254B41715567635FC1D38DCD7E3A0D60EB
-20180411094657 2 6 100 6143 5 E01FFD7EC91328929E4FD6183C9C9EDF4EF8CFC608D943A1011CEE0B49D7322663D64028F7205A4F008A0C8F393F91FF42D1C7ACB6B4041D0DC79BB0DA6D394532A0E33BC96FEA6EC2E67987F13D2F218B9E8A46D20125D822B6AA1C9615087E5C667CCA74414305E3382E20792B058F61D9DBFD93EF80A2E30E17FDB883F79989B540A6E467D9CEF07C849B659890706CAC7FF6F95669DAD0D9170D485C298AA940C6B7B3092E265FB512C70F36E3D6515B7B799E20FFE9DA35F932C3F2C238F5D8BCB92193216563D6163EB9FAAFEDD0E8A1A3F8CE292E8A1BEF630C5E75D845444B414017844E9560C8309CD54BF9EEAB2CAAE888226AB8031F1569A728256BB6FCC14DF314314F9F2DF75E781E8A4A5411ACCB4D9E3103131F52E0D14386A6E107AA7A522E42F1A41C8A8E46CE69E824492B87BC8B34A457EC25A7508B3E1A33BCC9E99EA754163AEC31161A83A80780DF46D36E757CF90C0F002DF73AB406F7DF81FDA75AD7F3F052EEA91955FA737616D8D4BB87A60FF471400D50688146BC3C10FF60A35D8BB9EF6BEF26497361118125FBEE607726AA408674A45931C87666146BE520503A5241D49B964406A864749C50F9B2718B8E0F62614DB27F35F53D57F70CB4ECE081BD377CDBA5C4AD75BEA63CB8E2653E52D11C0CAC67916B0C24232FC9D90091C7CDD317D4F60D8271D81E70B79031BE25CD5D6CC1E7A04FAF98C25B143B9D7B08D94160B1737AB49F55A01AF3A9BB7C8C261E8F2F84A1995C752276F5F03E54EE22A973F63C73083377DD6851634AA5568AA1173E5BE96606D946AAC82951E326750E18C2AD12C311EF784AD9014BEE322032B45244BD6EEDA224CCDA93983C8FB326F8C8B02F5574B0BC0CD7BFD1C524CD66ACD8A7AC1619E57136F2FEB5F49E9791D4E0F0C9AB8B9E7A98E49E5603D4E02771EFC9993ED15974CD0EEA50510C410FD884CB5D83D0FCD0AF7218D49523F95C4C396CBC0359DABD75EC138910788E1766649130AD089F565ED926B4F26FEBAF9CA4F768E6CA6E6BB7E43769B7D46E2F0D6A63254B41715567635FC1D38DCD7E3A351317
-20180411110541 2 6 100 6143 5 E01FFD7EC91328929E4FD6183C9C9EDF4EF8CFC608D943A1011CEE0B49D7322663D64028F7205A4F008A0C8F393F91FF42D1C7ACB6B4041D0DC79BB0DA6D394532A0E33BC96FEA6EC2E67987F13D2F218B9E8A46D20125D822B6AA1C9615087E5C667CCA74414305E3382E20792B058F61D9DBFD93EF80A2E30E17FDB883F79989B540A6E467D9CEF07C849B659890706CAC7FF6F95669DAD0D9170D485C298AA940C6B7B3092E265FB512C70F36E3D6515B7B799E20FFE9DA35F932C3F2C238F5D8BCB92193216563D6163EB9FAAFEDD0E8A1A3F8CE292E8A1BEF630C5E75D845444B414017844E9560C8309CD54BF9EEAB2CAAE888226AB8031F1569A728256BB6FCC14DF314314F9F2DF75E781E8A4A5411ACCB4D9E3103131F52E0D14386A6E107AA7A522E42F1A41C8A8E46CE69E824492B87BC8B34A457EC25A7508B3E1A33BCC9E99EA754163AEC31161A83A80780DF46D36E757CF90C0F002DF73AB406F7DF81FDA75AD7F3F052EEA91955FA737616D8D4BB87A60FF471400D50688146BC3C10FF60A35D8BB9EF6BEF26497361118125FBEE607726AA408674A45931C87666146BE520503A5241D49B964406A864749C50F9B2718B8E0F62614DB27F35F53D57F70CB4ECE081BD377CDBA5C4AD75BEA63CB8E2653E52D11C0CAC67916B0C24232FC9D90091C7CDD317D4F60D8271D81E70B79031BE25CD5D6CC1E7A04FAF98C25B143B9D7B08D94160B1737AB49F55A01AF3A9BB7C8C261E8F2F84A1995C752276F5F03E54EE22A973F63C73083377DD6851634AA5568AA1173E5BE96606D946AAC82951E326750E18C2AD12C311EF784AD9014BEE322032B45244BD6EEDA224CCDA93983C8FB326F8C8B02F5574B0BC0CD7BFD1C524CD66ACD8A7AC1619E57136F2FEB5F49E9791D4E0F0C9AB8B9E7A98E49E5603D4E02771EFC9993ED15974CD0EEA50510C410FD884CB5D83D0FCD0AF7218D49523F95C4C396CBC0359DABD75EC138910788E1766649130AD089F565ED926B4F26FEBAF9CA4F768E6CA6E6BB7E43769B7D46E2F0D6A63254B41715567635FC1D38DCD7E3C08A7A7
-20180411120731 2 6 100 6143 2 E01FFD7EC91328929E4FD6183C9C9EDF4EF8CFC608D943A1011CEE0B49D7322663D64028F7205A4F008A0C8F393F91FF42D1C7ACB6B4041D0DC79BB0DA6D394532A0E33BC96FEA6EC2E67987F13D2F218B9E8A46D20125D822B6AA1C9615087E5C667CCA74414305E3382E20792B058F61D9DBFD93EF80A2E30E17FDB883F79989B540A6E467D9CEF07C849B659890706CAC7FF6F95669DAD0D9170D485C298AA940C6B7B3092E265FB512C70F36E3D6515B7B799E20FFE9DA35F932C3F2C238F5D8BCB92193216563D6163EB9FAAFEDD0E8A1A3F8CE292E8A1BEF630C5E75D845444B414017844E9560C8309CD54BF9EEAB2CAAE888226AB8031F1569A728256BB6FCC14DF314314F9F2DF75E781E8A4A5411ACCB4D9E3103131F52E0D14386A6E107AA7A522E42F1A41C8A8E46CE69E824492B87BC8B34A457EC25A7508B3E1A33BCC9E99EA754163AEC31161A83A80780DF46D36E757CF90C0F002DF73AB406F7DF81FDA75AD7F3F052EEA91955FA737616D8D4BB87A60FF471400D50688146BC3C10FF60A35D8BB9EF6BEF26497361118125FBEE607726AA408674A45931C87666146BE520503A5241D49B964406A864749C50F9B2718B8E0F62614DB27F35F53D57F70CB4ECE081BD377CDBA5C4AD75BEA63CB8E2653E52D11C0CAC67916B0C24232FC9D90091C7CDD317D4F60D8271D81E70B79031BE25CD5D6CC1E7A04FAF98C25B143B9D7B08D94160B1737AB49F55A01AF3A9BB7C8C261E8F2F84A1995C752276F5F03E54EE22A973F63C73083377DD6851634AA5568AA1173E5BE96606D946AAC82951E326750E18C2AD12C311EF784AD9014BEE322032B45244BD6EEDA224CCDA93983C8FB326F8C8B02F5574B0BC0CD7BFD1C524CD66ACD8A7AC1619E57136F2FEB5F49E9791D4E0F0C9AB8B9E7A98E49E5603D4E02771EFC9993ED15974CD0EEA50510C410FD884CB5D83D0FCD0AF7218D49523F95C4C396CBC0359DABD75EC138910788E1766649130AD089F565ED926B4F26FEBAF9CA4F768E6CA6E6BB7E43769B7D46E2F0D6A63254B41715567635FC1D38DCD7E3D6EB9BB
-20180411130125 2 6 100 6143 2 E01FFD7EC91328929E4FD6183C9C9EDF4EF8CFC608D943A1011CEE0B49D7322663D64028F7205A4F008A0C8F393F91FF42D1C7ACB6B4041D0DC79BB0DA6D394532A0E33BC96FEA6EC2E67987F13D2F218B9E8A46D20125D822B6AA1C9615087E5C667CCA74414305E3382E20792B058F61D9DBFD93EF80A2E30E17FDB883F79989B540A6E467D9CEF07C849B659890706CAC7FF6F95669DAD0D9170D485C298AA940C6B7B3092E265FB512C70F36E3D6515B7B799E20FFE9DA35F932C3F2C238F5D8BCB92193216563D6163EB9FAAFEDD0E8A1A3F8CE292E8A1BEF630C5E75D845444B414017844E9560C8309CD54BF9EEAB2CAAE888226AB8031F1569A728256BB6FCC14DF314314F9F2DF75E781E8A4A5411ACCB4D9E3103131F52E0D14386A6E107AA7A522E42F1A41C8A8E46CE69E824492B87BC8B34A457EC25A7508B3E1A33BCC9E99EA754163AEC31161A83A80780DF46D36E757CF90C0F002DF73AB406F7DF81FDA75AD7F3F052EEA91955FA737616D8D4BB87A60FF471400D50688146BC3C10FF60A35D8BB9EF6BEF26497361118125FBEE607726AA408674A45931C87666146BE520503A5241D49B964406A864749C50F9B2718B8E0F62614DB27F35F53D57F70CB4ECE081BD377CDBA5C4AD75BEA63CB8E2653E52D11C0CAC67916B0C24232FC9D90091C7CDD317D4F60D8271D81E70B79031BE25CD5D6CC1E7A04FAF98C25B143B9D7B08D94160B1737AB49F55A01AF3A9BB7C8C261E8F2F84A1995C752276F5F03E54EE22A973F63C73083377DD6851634AA5568AA1173E5BE96606D946AAC82951E326750E18C2AD12C311EF784AD9014BEE322032B45244BD6EEDA224CCDA93983C8FB326F8C8B02F5574B0BC0CD7BFD1C524CD66ACD8A7AC1619E57136F2FEB5F49E9791D4E0F0C9AB8B9E7A98E49E5603D4E02771EFC9993ED15974CD0EEA50510C410FD884CB5D83D0FCD0AF7218D49523F95C4C396CBC0359DABD75EC138910788E1766649130AD089F565ED926B4F26FEBAF9CA4F768E6CA6E6BB7E43769B7D46E2F0D6A63254B41715567635FC1D38DCD7E3EAD50F3
-20180411151653 2 6 100 6143 5 E01FFD7EC91328929E4FD6183C9C9EDF4EF8CFC608D943A1011CEE0B49D7322663D64028F7205A4F008A0C8F393F91FF42D1C7ACB6B4041D0DC79BB0DA6D394532A0E33BC96FEA6EC2E67987F13D2F218B9E8A46D20125D822B6AA1C9615087E5C667CCA74414305E3382E20792B058F61D9DBFD93EF80A2E30E17FDB883F79989B540A6E467D9CEF07C849B659890706CAC7FF6F95669DAD0D9170D485C298AA940C6B7B3092E265FB512C70F36E3D6515B7B799E20FFE9DA35F932C3F2C238F5D8BCB92193216563D6163EB9FAAFEDD0E8A1A3F8CE292E8A1BEF630C5E75D845444B414017844E9560C8309CD54BF9EEAB2CAAE888226AB8031F1569A728256BB6FCC14DF314314F9F2DF75E781E8A4A5411ACCB4D9E3103131F52E0D14386A6E107AA7A522E42F1A41C8A8E46CE69E824492B87BC8B34A457EC25A7508B3E1A33BCC9E99EA754163AEC31161A83A80780DF46D36E757CF90C0F002DF73AB406F7DF81FDA75AD7F3F052EEA91955FA737616D8D4BB87A60FF471400D50688146BC3C10FF60A35D8BB9EF6BEF26497361118125FBEE607726AA408674A45931C87666146BE520503A5241D49B964406A864749C50F9B2718B8E0F62614DB27F35F53D57F70CB4ECE081BD377CDBA5C4AD75BEA63CB8E2653E52D11C0CAC67916B0C24232FC9D90091C7CDD317D4F60D8271D81E70B79031BE25CD5D6CC1E7A04FAF98C25B143B9D7B08D94160B1737AB49F55A01AF3A9BB7C8C261E8F2F84A1995C752276F5F03E54EE22A973F63C73083377DD6851634AA5568AA1173E5BE96606D946AAC82951E326750E18C2AD12C311EF784AD9014BEE322032B45244BD6EEDA224CCDA93983C8FB326F8C8B02F5574B0BC0CD7BFD1C524CD66ACD8A7AC1619E57136F2FEB5F49E9791D4E0F0C9AB8B9E7A98E49E5603D4E02771EFC9993ED15974CD0EEA50510C410FD884CB5D83D0FCD0AF7218D49523F95C4C396CBC0359DABD75EC138910788E1766649130AD089F565ED926B4F26FEBAF9CA4F768E6CA6E6BB7E43769B7D46E2F0D6A63254B41715567635FC1D38DCD7E41CC6D9F
-20180411152943 2 6 100 6143 2 E01FFD7EC91328929E4FD6183C9C9EDF4EF8CFC608D943A1011CEE0B49D7322663D64028F7205A4F008A0C8F393F91FF42D1C7ACB6B4041D0DC79BB0DA6D394532A0E33BC96FEA6EC2E67987F13D2F218B9E8A46D20125D822B6AA1C9615087E5C667CCA74414305E3382E20792B058F61D9DBFD93EF80A2E30E17FDB883F79989B540A6E467D9CEF07C849B659890706CAC7FF6F95669DAD0D9170D485C298AA940C6B7B3092E265FB512C70F36E3D6515B7B799E20FFE9DA35F932C3F2C238F5D8BCB92193216563D6163EB9FAAFEDD0E8A1A3F8CE292E8A1BEF630C5E75D845444B414017844E9560C8309CD54BF9EEAB2CAAE888226AB8031F1569A728256BB6FCC14DF314314F9F2DF75E781E8A4A5411ACCB4D9E3103131F52E0D14386A6E107AA7A522E42F1A41C8A8E46CE69E824492B87BC8B34A457EC25A7508B3E1A33BCC9E99EA754163AEC31161A83A80780DF46D36E757CF90C0F002DF73AB406F7DF81FDA75AD7F3F052EEA91955FA737616D8D4BB87A60FF471400D50688146BC3C10FF60A35D8BB9EF6BEF26497361118125FBEE607726AA408674A45931C87666146BE520503A5241D49B964406A864749C50F9B2718B8E0F62614DB27F35F53D57F70CB4ECE081BD377CDBA5C4AD75BEA63CB8E2653E52D11C0CAC67916B0C24232FC9D90091C7CDD317D4F60D8271D81E70B79031BE25CD5D6CC1E7A04FAF98C25B143B9D7B08D94160B1737AB49F55A01AF3A9BB7C8C261E8F2F84A1995C752276F5F03E54EE22A973F63C73083377DD6851634AA5568AA1173E5BE96606D946AAC82951E326750E18C2AD12C311EF784AD9014BEE322032B45244BD6EEDA224CCDA93983C8FB326F8C8B02F5574B0BC0CD7BFD1C524CD66ACD8A7AC1619E57136F2FEB5F49E9791D4E0F0C9AB8B9E7A98E49E5603D4E02771EFC9993ED15974CD0EEA50510C410FD884CB5D83D0FCD0AF7218D49523F95C4C396CBC0359DABD75EC138910788E1766649130AD089F565ED926B4F26FEBAF9CA4F768E6CA6E6BB7E43769B7D46E2F0D6A63254B41715567635FC1D38DCD7E4210423B
-20180411184911 2 6 100 6143 2 E01FFD7EC91328929E4FD6183C9C9EDF4EF8CFC608D943A1011CEE0B49D7322663D64028F7205A4F008A0C8F393F91FF42D1C7ACB6B4041D0DC79BB0DA6D394532A0E33BC96FEA6EC2E67987F13D2F218B9E8A46D20125D822B6AA1C9615087E5C667CCA74414305E3382E20792B058F61D9DBFD93EF80A2E30E17FDB883F79989B540A6E467D9CEF07C849B659890706CAC7FF6F95669DAD0D9170D485C298AA940C6B7B3092E265FB512C70F36E3D6515B7B799E20FFE9DA35F932C3F2C238F5D8BCB92193216563D6163EB9FAAFEDD0E8A1A3F8CE292E8A1BEF630C5E75D845444B414017844E9560C8309CD54BF9EEAB2CAAE888226AB8031F1569A728256BB6FCC14DF314314F9F2DF75E781E8A4A5411ACCB4D9E3103131F52E0D14386A6E107AA7A522E42F1A41C8A8E46CE69E824492B87BC8B34A457EC25A7508B3E1A33BCC9E99EA754163AEC31161A83A80780DF46D36E757CF90C0F002DF73AB406F7DF81FDA75AD7F3F052EEA91955FA737616D8D4BB87A60FF471400D50688146BC3C10FF60A35D8BB9EF6BEF26497361118125FBEE607726AA408674A45931C87666146BE520503A5241D49B964406A864749C50F9B2718B8E0F62614DB27F35F53D57F70CB4ECE081BD377CDBA5C4AD75BEA63CB8E2653E52D11C0CAC67916B0C24232FC9D90091C7CDD317D4F60D8271D81E70B79031BE25CD5D6CC1E7A04FAF98C25B143B9D7B08D94160B1737AB49F55A01AF3A9BB7C8C261E8F2F84A1995C752276F5F03E54EE22A973F63C73083377DD6851634AA5568AA1173E5BE96606D946AAC82951E326750E18C2AD12C311EF784AD9014BEE322032B45244BD6EEDA224CCDA93983C8FB326F8C8B02F5574B0BC0CD7BFD1C524CD66ACD8A7AC1619E57136F2FEB5F49E9791D4E0F0C9AB8B9E7A98E49E5603D4E02771EFC9993ED15974CD0EEA50510C410FD884CB5D83D0FCD0AF7218D49523F95C4C396CBC0359DABD75EC138910788E1766649130AD089F565ED926B4F26FEBAF9CA4F768E6CA6E6BB7E43769B7D46E2F0D6A63254B41715567635FC1D38DCD7E46A13843
-20180411191726 2 6 100 6143 5 E01FFD7EC91328929E4FD6183C9C9EDF4EF8CFC608D943A1011CEE0B49D7322663D64028F7205A4F008A0C8F393F91FF42D1C7ACB6B4041D0DC79BB0DA6D394532A0E33BC96FEA6EC2E67987F13D2F218B9E8A46D20125D822B6AA1C9615087E5C667CCA74414305E3382E20792B058F61D9DBFD93EF80A2E30E17FDB883F79989B540A6E467D9CEF07C849B659890706CAC7FF6F95669DAD0D9170D485C298AA940C6B7B3092E265FB512C70F36E3D6515B7B799E20FFE9DA35F932C3F2C238F5D8BCB92193216563D6163EB9FAAFEDD0E8A1A3F8CE292E8A1BEF630C5E75D845444B414017844E9560C8309CD54BF9EEAB2CAAE888226AB8031F1569A728256BB6FCC14DF314314F9F2DF75E781E8A4A5411ACCB4D9E3103131F52E0D14386A6E107AA7A522E42F1A41C8A8E46CE69E824492B87BC8B34A457EC25A7508B3E1A33BCC9E99EA754163AEC31161A83A80780DF46D36E757CF90C0F002DF73AB406F7DF81FDA75AD7F3F052EEA91955FA737616D8D4BB87A60FF471400D50688146BC3C10FF60A35D8BB9EF6BEF26497361118125FBEE607726AA408674A45931C87666146BE520503A5241D49B964406A864749C50F9B2718B8E0F62614DB27F35F53D57F70CB4ECE081BD377CDBA5C4AD75BEA63CB8E2653E52D11C0CAC67916B0C24232FC9D90091C7CDD317D4F60D8271D81E70B79031BE25CD5D6CC1E7A04FAF98C25B143B9D7B08D94160B1737AB49F55A01AF3A9BB7C8C261E8F2F84A1995C752276F5F03E54EE22A973F63C73083377DD6851634AA5568AA1173E5BE96606D946AAC82951E326750E18C2AD12C311EF784AD9014BEE322032B45244BD6EEDA224CCDA93983C8FB326F8C8B02F5574B0BC0CD7BFD1C524CD66ACD8A7AC1619E57136F2FEB5F49E9791D4E0F0C9AB8B9E7A98E49E5603D4E02771EFC9993ED15974CD0EEA50510C410FD884CB5D83D0FCD0AF7218D49523F95C4C396CBC0359DABD75EC138910788E1766649130AD089F565ED926B4F26FEBAF9CA4F768E6CA6E6BB7E43769B7D46E2F0D6A63254B41715567635FC1D38DCD7E473E26CF
-20180411205712 2 6 100 6143 2 E01FFD7EC91328929E4FD6183C9C9EDF4EF8CFC608D943A1011CEE0B49D7322663D64028F7205A4F008A0C8F393F91FF42D1C7ACB6B4041D0DC79BB0DA6D394532A0E33BC96FEA6EC2E67987F13D2F218B9E8A46D20125D822B6AA1C9615087E5C667CCA74414305E3382E20792B058F61D9DBFD93EF80A2E30E17FDB883F79989B540A6E467D9CEF07C849B659890706CAC7FF6F95669DAD0D9170D485C298AA940C6B7B3092E265FB512C70F36E3D6515B7B799E20FFE9DA35F932C3F2C238F5D8BCB92193216563D6163EB9FAAFEDD0E8A1A3F8CE292E8A1BEF630C5E75D845444B414017844E9560C8309CD54BF9EEAB2CAAE888226AB8031F1569A728256BB6FCC14DF314314F9F2DF75E781E8A4A5411ACCB4D9E3103131F52E0D14386A6E107AA7A522E42F1A41C8A8E46CE69E824492B87BC8B34A457EC25A7508B3E1A33BCC9E99EA754163AEC31161A83A80780DF46D36E757CF90C0F002DF73AB406F7DF81FDA75AD7F3F052EEA91955FA737616D8D4BB87A60FF471400D50688146BC3C10FF60A35D8BB9EF6BEF26497361118125FBEE607726AA408674A45931C87666146BE520503A5241D49B964406A864749C50F9B2718B8E0F62614DB27F35F53D57F70CB4ECE081BD377CDBA5C4AD75BEA63CB8E2653E52D11C0CAC67916B0C24232FC9D90091C7CDD317D4F60D8271D81E70B79031BE25CD5D6CC1E7A04FAF98C25B143B9D7B08D94160B1737AB49F55A01AF3A9BB7C8C261E8F2F84A1995C752276F5F03E54EE22A973F63C73083377DD6851634AA5568AA1173E5BE96606D946AAC82951E326750E18C2AD12C311EF784AD9014BEE322032B45244BD6EEDA224CCDA93983C8FB326F8C8B02F5574B0BC0CD7BFD1C524CD66ACD8A7AC1619E57136F2FEB5F49E9791D4E0F0C9AB8B9E7A98E49E5603D4E02771EFC9993ED15974CD0EEA50510C410FD884CB5D83D0FCD0AF7218D49523F95C4C396CBC0359DABD75EC138910788E1766649130AD089F565ED926B4F26FEBAF9CA4F768E6CA6E6BB7E43769B7D46E2F0D6A63254B41715567635FC1D38DCD7E498A1853
-20180411212652 2 6 100 6143 5 E01FFD7EC91328929E4FD6183C9C9EDF4EF8CFC608D943A1011CEE0B49D7322663D64028F7205A4F008A0C8F393F91FF42D1C7ACB6B4041D0DC79BB0DA6D394532A0E33BC96FEA6EC2E67987F13D2F218B9E8A46D20125D822B6AA1C9615087E5C667CCA74414305E3382E20792B058F61D9DBFD93EF80A2E30E17FDB883F79989B540A6E467D9CEF07C849B659890706CAC7FF6F95669DAD0D9170D485C298AA940C6B7B3092E265FB512C70F36E3D6515B7B799E20FFE9DA35F932C3F2C238F5D8BCB92193216563D6163EB9FAAFEDD0E8A1A3F8CE292E8A1BEF630C5E75D845444B414017844E9560C8309CD54BF9EEAB2CAAE888226AB8031F1569A728256BB6FCC14DF314314F9F2DF75E781E8A4A5411ACCB4D9E3103131F52E0D14386A6E107AA7A522E42F1A41C8A8E46CE69E824492B87BC8B34A457EC25A7508B3E1A33BCC9E99EA754163AEC31161A83A80780DF46D36E757CF90C0F002DF73AB406F7DF81FDA75AD7F3F052EEA91955FA737616D8D4BB87A60FF471400D50688146BC3C10FF60A35D8BB9EF6BEF26497361118125FBEE607726AA408674A45931C87666146BE520503A5241D49B964406A864749C50F9B2718B8E0F62614DB27F35F53D57F70CB4ECE081BD377CDBA5C4AD75BEA63CB8E2653E52D11C0CAC67916B0C24232FC9D90091C7CDD317D4F60D8271D81E70B79031BE25CD5D6CC1E7A04FAF98C25B143B9D7B08D94160B1737AB49F55A01AF3A9BB7C8C261E8F2F84A1995C752276F5F03E54EE22A973F63C73083377DD6851634AA5568AA1173E5BE96606D946AAC82951E326750E18C2AD12C311EF784AD9014BEE322032B45244BD6EEDA224CCDA93983C8FB326F8C8B02F5574B0BC0CD7BFD1C524CD66ACD8A7AC1619E57136F2FEB5F49E9791D4E0F0C9AB8B9E7A98E49E5603D4E02771EFC9993ED15974CD0EEA50510C410FD884CB5D83D0FCD0AF7218D49523F95C4C396CBC0359DABD75EC138910788E1766649130AD089F565ED926B4F26FEBAF9CA4F768E6CA6E6BB7E43769B7D46E2F0D6A63254B41715567635FC1D38DCD7E4A2D607F
-20180411215657 2 6 100 6143 2 E01FFD7EC91328929E4FD6183C9C9EDF4EF8CFC608D943A1011CEE0B49D7322663D64028F7205A4F008A0C8F393F91FF42D1C7ACB6B4041D0DC79BB0DA6D394532A0E33BC96FEA6EC2E67987F13D2F218B9E8A46D20125D822B6AA1C9615087E5C667CCA74414305E3382E20792B058F61D9DBFD93EF80A2E30E17FDB883F79989B540A6E467D9CEF07C849B659890706CAC7FF6F95669DAD0D9170D485C298AA940C6B7B3092E265FB512C70F36E3D6515B7B799E20FFE9DA35F932C3F2C238F5D8BCB92193216563D6163EB9FAAFEDD0E8A1A3F8CE292E8A1BEF630C5E75D845444B414017844E9560C8309CD54BF9EEAB2CAAE888226AB8031F1569A728256BB6FCC14DF314314F9F2DF75E781E8A4A5411ACCB4D9E3103131F52E0D14386A6E107AA7A522E42F1A41C8A8E46CE69E824492B87BC8B34A457EC25A7508B3E1A33BCC9E99EA754163AEC31161A83A80780DF46D36E757CF90C0F002DF73AB406F7DF81FDA75AD7F3F052EEA91955FA737616D8D4BB87A60FF471400D50688146BC3C10FF60A35D8BB9EF6BEF26497361118125FBEE607726AA408674A45931C87666146BE520503A5241D49B964406A864749C50F9B2718B8E0F62614DB27F35F53D57F70CB4ECE081BD377CDBA5C4AD75BEA63CB8E2653E52D11C0CAC67916B0C24232FC9D90091C7CDD317D4F60D8271D81E70B79031BE25CD5D6CC1E7A04FAF98C25B143B9D7B08D94160B1737AB49F55A01AF3A9BB7C8C261E8F2F84A1995C752276F5F03E54EE22A973F63C73083377DD6851634AA5568AA1173E5BE96606D946AAC82951E326750E18C2AD12C311EF784AD9014BEE322032B45244BD6EEDA224CCDA93983C8FB326F8C8B02F5574B0BC0CD7BFD1C524CD66ACD8A7AC1619E57136F2FEB5F49E9791D4E0F0C9AB8B9E7A98E49E5603D4E02771EFC9993ED15974CD0EEA50510C410FD884CB5D83D0FCD0AF7218D49523F95C4C396CBC0359DABD75EC138910788E1766649130AD089F565ED926B4F26FEBAF9CA4F768E6CA6E6BB7E43769B7D46E2F0D6A63254B41715567635FC1D38DCD7E4AD99963
-20180412095549 2 6 100 7679 5 FBED7F3DD7CF86B0A6EEDC1930C6958C3C00695DAF4347560C5AC1AA4B22F4DC76F190D63E230EB0CB4344A370A471F17FFCA8DA3B5B0A903F9D1258370125F6C172F3EC5F56D7B8EBD07B2072C45D6141DA3CDC01C3D95DE279C5FAA1E042651028141085EB68AFAC473600F75F4A373DC234D5405DCE7AB5B5854960ABC550FCEFEE8FD578810201DE6B4A5EF616F0CBF5707466D7ECBFD488EB68AD4B2EAC889BA2B7FEFE19CD8AA2C78F61D5DA08B4BC2738E1997F951A525EEF9F668148996D1ABFD1620F9276D741A46BECC0B7868A54745E0B16589A4AA7B938AF92FCA0FC9BBC193504D7EBFEFFEC996746DC6CAD3C192D724FB51E6228915789FF18314B3EB690359ADED802F35F48EC0D9C85AA1A20A2E5CF6EB795F2CCD03284547688B1B80A07EFC31668D30836C59C958BBBF6C1EE3940CC43A9334289C872302BB70368FDAC1653AF132F3E398E9310159C839E72555FD889E4E3B05E714E44E116804BF3748F62EF46E6A05DEC58A55185E43E2310EC945004AD61945BD2AD923B7B3C69A01C0393C15B6000BF542A55274ACA20B8A6EB96FAF83E27023FE0EA9EE564959A91BE17110176FB10D1A094947A23EFDE15DD093EF477EF798BCA8F5E14F85411242BC9C9492081444490C072BE8511B3C961AAAC80477897B54BDABE78C533F2E149FA64B51936E31F126625566CAFBB57E9F36CE0DF72A45E61AB27B6D25DEA3BA35910E16BB00AD300CEE2535CE75F9411DD43943250B03EBBA60C5C788974F2F695967103045F3A90A587AEFD0613F9C8E10A273DD827A314C75C7DBCE4326191DBCB92020CDB75129BCA032B6FD59D368C3E2404B2832398E40F43ACE284A91DED8812AA23E5B5A1D36AE204C53F1C6EF0E89AD31D1552E70538451847D7332D8FCACB62A1E56C1E5643E4F7AF63C67E082AC95DCB190795FA53522FA046F1919C81A088D7A8A452124E562BE2A702139670E94524D3110B9DFF35AE73F43280600B8304FA2E776089AF2ED929695967998E29A343FF62C4CAD7618222C01735734342FD33284BE9BDA4976DA1BC3B384E6F813FCBDFA3DC57B841515836CB2B37116EB6D417BBE6AEA7604AA915530AD803DF1C13656753C1A5867F4A3AE94BA7347580EE5A6CEBD2F3EB9B7F83E7B74F38995168F08A15A4CDF5702EA9DC907FC45910586D59537582DB1D5F155BF0050866CE3087560F1F44D1F275FD2B422038F9D8643C3BEBA49938D514848AC4F68F4CF44329C7E806B911B0CB7FF0020F3277A3E2B4FF17090D012B641E24D67A962E2FE361504DB014155F074F30F52078CB31DFC51B32746A42EDBF013F9920CFB17D1E908A07
-20180412222127 2 6 100 7679 2 FBED7F3DD7CF86B0A6EEDC1930C6958C3C00695DAF4347560C5AC1AA4B22F4DC76F190D63E230EB0CB4344A370A471F17FFCA8DA3B5B0A903F9D1258370125F6C172F3EC5F56D7B8EBD07B2072C45D6141DA3CDC01C3D95DE279C5FAA1E042651028141085EB68AFAC473600F75F4A373DC234D5405DCE7AB5B5854960ABC550FCEFEE8FD578810201DE6B4A5EF616F0CBF5707466D7ECBFD488EB68AD4B2EAC889BA2B7FEFE19CD8AA2C78F61D5DA08B4BC2738E1997F951A525EEF9F668148996D1ABFD1620F9276D741A46BECC0B7868A54745E0B16589A4AA7B938AF92FCA0FC9BBC193504D7EBFEFFEC996746DC6CAD3C192D724FB51E6228915789FF18314B3EB690359ADED802F35F48EC0D9C85AA1A20A2E5CF6EB795F2CCD03284547688B1B80A07EFC31668D30836C59C958BBBF6C1EE3940CC43A9334289C872302BB70368FDAC1653AF132F3E398E9310159C839E72555FD889E4E3B05E714E44E116804BF3748F62EF46E6A05DEC58A55185E43E2310EC945004AD61945BD2AD923B7B3C69A01C0393C15B6000BF542A55274ACA20B8A6EB96FAF83E27023FE0EA9EE564959A91BE17110176FB10D1A094947A23EFDE15DD093EF477EF798BCA8F5E14F85411242BC9C9492081444490C072BE8511B3C961AAAC80477897B54BDABE78C533F2E149FA64B51936E31F126625566CAFBB57E9F36CE0DF72A45E61AB27B6D25DEA3BA35910E16BB00AD300CEE2535CE75F9411DD43943250B03EBBA60C5C788974F2F695967103045F3A90A587AEFD0613F9C8E10A273DD827A314C75C7DBCE4326191DBCB92020CDB75129BCA032B6FD59D368C3E2404B2832398E40F43ACE284A91DED8812AA23E5B5A1D36AE204C53F1C6EF0E89AD31D1552E70538451847D7332D8FCACB62A1E56C1E5643E4F7AF63C67E082AC95DCB190795FA53522FA046F1919C81A088D7A8A452124E562BE2A702139670E94524D3110B9DFF35AE73F43280600B8304FA2E776089AF2ED929695967998E29A343FF62C4CAD7618222C01735734342FD33284BE9BDA4976DA1BC3B384E6F813FCBDFA3DC57B841515836CB2B37116EB6D417BBE6AEA7604AA915530AD803DF1C13656753C1A5867F4A3AE94BA7347580EE5A6CEBD2F3EB9B7F83E7B74F38995168F08A15A4CDF5702EA9DC907FC45910586D59537582DB1D5F155BF0050866CE3087560F1F44D1F275FD2B422038F9D8643C3BEBA49938D514848AC4F68F4CF44329C7E806B911B0CB7FF0020F3277A3E2B4FF17090D012B641E24D67A962E2FE361504DB014155F074F30F52078CB31DFC51B32746A42EDBF013F9920CFB17D28C808CB
-20180413014812 2 6 100 7679 2 FBED7F3DD7CF86B0A6EEDC1930C6958C3C00695DAF4347560C5AC1AA4B22F4DC76F190D63E230EB0CB4344A370A471F17FFCA8DA3B5B0A903F9D1258370125F6C172F3EC5F56D7B8EBD07B2072C45D6141DA3CDC01C3D95DE279C5FAA1E042651028141085EB68AFAC473600F75F4A373DC234D5405DCE7AB5B5854960ABC550FCEFEE8FD578810201DE6B4A5EF616F0CBF5707466D7ECBFD488EB68AD4B2EAC889BA2B7FEFE19CD8AA2C78F61D5DA08B4BC2738E1997F951A525EEF9F668148996D1ABFD1620F9276D741A46BECC0B7868A54745E0B16589A4AA7B938AF92FCA0FC9BBC193504D7EBFEFFEC996746DC6CAD3C192D724FB51E6228915789FF18314B3EB690359ADED802F35F48EC0D9C85AA1A20A2E5CF6EB795F2CCD03284547688B1B80A07EFC31668D30836C59C958BBBF6C1EE3940CC43A9334289C872302BB70368FDAC1653AF132F3E398E9310159C839E72555FD889E4E3B05E714E44E116804BF3748F62EF46E6A05DEC58A55185E43E2310EC945004AD61945BD2AD923B7B3C69A01C0393C15B6000BF542A55274ACA20B8A6EB96FAF83E27023FE0EA9EE564959A91BE17110176FB10D1A094947A23EFDE15DD093EF477EF798BCA8F5E14F85411242BC9C9492081444490C072BE8511B3C961AAAC80477897B54BDABE78C533F2E149FA64B51936E31F126625566CAFBB57E9F36CE0DF72A45E61AB27B6D25DEA3BA35910E16BB00AD300CEE2535CE75F9411DD43943250B03EBBA60C5C788974F2F695967103045F3A90A587AEFD0613F9C8E10A273DD827A314C75C7DBCE4326191DBCB92020CDB75129BCA032B6FD59D368C3E2404B2832398E40F43ACE284A91DED8812AA23E5B5A1D36AE204C53F1C6EF0E89AD31D1552E70538451847D7332D8FCACB62A1E56C1E5643E4F7AF63C67E082AC95DCB190795FA53522FA046F1919C81A088D7A8A452124E562BE2A702139670E94524D3110B9DFF35AE73F43280600B8304FA2E776089AF2ED929695967998E29A343FF62C4CAD7618222C01735734342FD33284BE9BDA4976DA1BC3B384E6F813FCBDFA3DC57B841515836CB2B37116EB6D417BBE6AEA7604AA915530AD803DF1C13656753C1A5867F4A3AE94BA7347580EE5A6CEBD2F3EB9B7F83E7B74F38995168F08A15A4CDF5702EA9DC907FC45910586D59537582DB1D5F155BF0050866CE3087560F1F44D1F275FD2B422038F9D8643C3BEBA49938D514848AC4F68F4CF44329C7E806B911B0CB7FF0020F3277A3E2B4FF17090D012B641E24D67A962E2FE361504DB014155F074F30F52078CB31DFC51B32746A42EDBF013F9920CFB17D2B32FFD3
-20180413033600 2 6 100 7679 5 FBED7F3DD7CF86B0A6EEDC1930C6958C3C00695DAF4347560C5AC1AA4B22F4DC76F190D63E230EB0CB4344A370A471F17FFCA8DA3B5B0A903F9D1258370125F6C172F3EC5F56D7B8EBD07B2072C45D6141DA3CDC01C3D95DE279C5FAA1E042651028141085EB68AFAC473600F75F4A373DC234D5405DCE7AB5B5854960ABC550FCEFEE8FD578810201DE6B4A5EF616F0CBF5707466D7ECBFD488EB68AD4B2EAC889BA2B7FEFE19CD8AA2C78F61D5DA08B4BC2738E1997F951A525EEF9F668148996D1ABFD1620F9276D741A46BECC0B7868A54745E0B16589A4AA7B938AF92FCA0FC9BBC193504D7EBFEFFEC996746DC6CAD3C192D724FB51E6228915789FF18314B3EB690359ADED802F35F48EC0D9C85AA1A20A2E5CF6EB795F2CCD03284547688B1B80A07EFC31668D30836C59C958BBBF6C1EE3940CC43A9334289C872302BB70368FDAC1653AF132F3E398E9310159C839E72555FD889E4E3B05E714E44E116804BF3748F62EF46E6A05DEC58A55185E43E2310EC945004AD61945BD2AD923B7B3C69A01C0393C15B6000BF542A55274ACA20B8A6EB96FAF83E27023FE0EA9EE564959A91BE17110176FB10D1A094947A23EFDE15DD093EF477EF798BCA8F5E14F85411242BC9C9492081444490C072BE8511B3C961AAAC80477897B54BDABE78C533F2E149FA64B51936E31F126625566CAFBB57E9F36CE0DF72A45E61AB27B6D25DEA3BA35910E16BB00AD300CEE2535CE75F9411DD43943250B03EBBA60C5C788974F2F695967103045F3A90A587AEFD0613F9C8E10A273DD827A314C75C7DBCE4326191DBCB92020CDB75129BCA032B6FD59D368C3E2404B2832398E40F43ACE284A91DED8812AA23E5B5A1D36AE204C53F1C6EF0E89AD31D1552E70538451847D7332D8FCACB62A1E56C1E5643E4F7AF63C67E082AC95DCB190795FA53522FA046F1919C81A088D7A8A452124E562BE2A702139670E94524D3110B9DFF35AE73F43280600B8304FA2E776089AF2ED929695967998E29A343FF62C4CAD7618222C01735734342FD33284BE9BDA4976DA1BC3B384E6F813FCBDFA3DC57B841515836CB2B37116EB6D417BBE6AEA7604AA915530AD803DF1C13656753C1A5867F4A3AE94BA7347580EE5A6CEBD2F3EB9B7F83E7B74F38995168F08A15A4CDF5702EA9DC907FC45910586D59537582DB1D5F155BF0050866CE3087560F1F44D1F275FD2B422038F9D8643C3BEBA49938D514848AC4F68F4CF44329C7E806B911B0CB7FF0020F3277A3E2B4FF17090D012B641E24D67A962E2FE361504DB014155F074F30F52078CB31DFC51B32746A42EDBF013F9920CFB17D2C8AD64F
-20180413142737 2 6 100 7679 2 FBED7F3DD7CF86B0A6EEDC1930C6958C3C00695DAF4347560C5AC1AA4B22F4DC76F190D63E230EB0CB4344A370A471F17FFCA8DA3B5B0A903F9D1258370125F6C172F3EC5F56D7B8EBD07B2072C45D6141DA3CDC01C3D95DE279C5FAA1E042651028141085EB68AFAC473600F75F4A373DC234D5405DCE7AB5B5854960ABC550FCEFEE8FD578810201DE6B4A5EF616F0CBF5707466D7ECBFD488EB68AD4B2EAC889BA2B7FEFE19CD8AA2C78F61D5DA08B4BC2738E1997F951A525EEF9F668148996D1ABFD1620F9276D741A46BECC0B7868A54745E0B16589A4AA7B938AF92FCA0FC9BBC193504D7EBFEFFEC996746DC6CAD3C192D724FB51E6228915789FF18314B3EB690359ADED802F35F48EC0D9C85AA1A20A2E5CF6EB795F2CCD03284547688B1B80A07EFC31668D30836C59C958BBBF6C1EE3940CC43A9334289C872302BB70368FDAC1653AF132F3E398E9310159C839E72555FD889E4E3B05E714E44E116804BF3748F62EF46E6A05DEC58A55185E43E2310EC945004AD61945BD2AD923B7B3C69A01C0393C15B6000BF542A55274ACA20B8A6EB96FAF83E27023FE0EA9EE564959A91BE17110176FB10D1A094947A23EFDE15DD093EF477EF798BCA8F5E14F85411242BC9C9492081444490C072BE8511B3C961AAAC80477897B54BDABE78C533F2E149FA64B51936E31F126625566CAFBB57E9F36CE0DF72A45E61AB27B6D25DEA3BA35910E16BB00AD300CEE2535CE75F9411DD43943250B03EBBA60C5C788974F2F695967103045F3A90A587AEFD0613F9C8E10A273DD827A314C75C7DBCE4326191DBCB92020CDB75129BCA032B6FD59D368C3E2404B2832398E40F43ACE284A91DED8812AA23E5B5A1D36AE204C53F1C6EF0E89AD31D1552E70538451847D7332D8FCACB62A1E56C1E5643E4F7AF63C67E082AC95DCB190795FA53522FA046F1919C81A088D7A8A452124E562BE2A702139670E94524D3110B9DFF35AE73F43280600B8304FA2E776089AF2ED929695967998E29A343FF62C4CAD7618222C01735734342FD33284BE9BDA4976DA1BC3B384E6F813FCBDFA3DC57B841515836CB2B37116EB6D417BBE6AEA7604AA915530AD803DF1C13656753C1A5867F4A3AE94BA7347580EE5A6CEBD2F3EB9B7F83E7B74F38995168F08A15A4CDF5702EA9DC907FC45910586D59537582DB1D5F155BF0050866CE3087560F1F44D1F275FD2B422038F9D8643C3BEBA49938D514848AC4F68F4CF44329C7E806B911B0CB7FF0020F3277A3E2B4FF17090D012B641E24D67A962E2FE361504DB014155F074F30F52078CB31DFC51B32746A42EDBF013F9920CFB17D34F03213
-20180413150907 2 6 100 7679 5 FBED7F3DD7CF86B0A6EEDC1930C6958C3C00695DAF4347560C5AC1AA4B22F4DC76F190D63E230EB0CB4344A370A471F17FFCA8DA3B5B0A903F9D1258370125F6C172F3EC5F56D7B8EBD07B2072C45D6141DA3CDC01C3D95DE279C5FAA1E042651028141085EB68AFAC473600F75F4A373DC234D5405DCE7AB5B5854960ABC550FCEFEE8FD578810201DE6B4A5EF616F0CBF5707466D7ECBFD488EB68AD4B2EAC889BA2B7FEFE19CD8AA2C78F61D5DA08B4BC2738E1997F951A525EEF9F668148996D1ABFD1620F9276D741A46BECC0B7868A54745E0B16589A4AA7B938AF92FCA0FC9BBC193504D7EBFEFFEC996746DC6CAD3C192D724FB51E6228915789FF18314B3EB690359ADED802F35F48EC0D9C85AA1A20A2E5CF6EB795F2CCD03284547688B1B80A07EFC31668D30836C59C958BBBF6C1EE3940CC43A9334289C872302BB70368FDAC1653AF132F3E398E9310159C839E72555FD889E4E3B05E714E44E116804BF3748F62EF46E6A05DEC58A55185E43E2310EC945004AD61945BD2AD923B7B3C69A01C0393C15B6000BF542A55274ACA20B8A6EB96FAF83E27023FE0EA9EE564959A91BE17110176FB10D1A094947A23EFDE15DD093EF477EF798BCA8F5E14F85411242BC9C9492081444490C072BE8511B3C961AAAC80477897B54BDABE78C533F2E149FA64B51936E31F126625566CAFBB57E9F36CE0DF72A45E61AB27B6D25DEA3BA35910E16BB00AD300CEE2535CE75F9411DD43943250B03EBBA60C5C788974F2F695967103045F3A90A587AEFD0613F9C8E10A273DD827A314C75C7DBCE4326191DBCB92020CDB75129BCA032B6FD59D368C3E2404B2832398E40F43ACE284A91DED8812AA23E5B5A1D36AE204C53F1C6EF0E89AD31D1552E70538451847D7332D8FCACB62A1E56C1E5643E4F7AF63C67E082AC95DCB190795FA53522FA046F1919C81A088D7A8A452124E562BE2A702139670E94524D3110B9DFF35AE73F43280600B8304FA2E776089AF2ED929695967998E29A343FF62C4CAD7618222C01735734342FD33284BE9BDA4976DA1BC3B384E6F813FCBDFA3DC57B841515836CB2B37116EB6D417BBE6AEA7604AA915530AD803DF1C13656753C1A5867F4A3AE94BA7347580EE5A6CEBD2F3EB9B7F83E7B74F38995168F08A15A4CDF5702EA9DC907FC45910586D59537582DB1D5F155BF0050866CE3087560F1F44D1F275FD2B422038F9D8643C3BEBA49938D514848AC4F68F4CF44329C7E806B911B0CB7FF0020F3277A3E2B4FF17090D012B641E24D67A962E2FE361504DB014155F074F30F52078CB31DFC51B32746A42EDBF013F9920CFB17D35714FEF
-20180413164654 2 6 100 7679 2 FBED7F3DD7CF86B0A6EEDC1930C6958C3C00695DAF4347560C5AC1AA4B22F4DC76F190D63E230EB0CB4344A370A471F17FFCA8DA3B5B0A903F9D1258370125F6C172F3EC5F56D7B8EBD07B2072C45D6141DA3CDC01C3D95DE279C5FAA1E042651028141085EB68AFAC473600F75F4A373DC234D5405DCE7AB5B5854960ABC550FCEFEE8FD578810201DE6B4A5EF616F0CBF5707466D7ECBFD488EB68AD4B2EAC889BA2B7FEFE19CD8AA2C78F61D5DA08B4BC2738E1997F951A525EEF9F668148996D1ABFD1620F9276D741A46BECC0B7868A54745E0B16589A4AA7B938AF92FCA0FC9BBC193504D7EBFEFFEC996746DC6CAD3C192D724FB51E6228915789FF18314B3EB690359ADED802F35F48EC0D9C85AA1A20A2E5CF6EB795F2CCD03284547688B1B80A07EFC31668D30836C59C958BBBF6C1EE3940CC43A9334289C872302BB70368FDAC1653AF132F3E398E9310159C839E72555FD889E4E3B05E714E44E116804BF3748F62EF46E6A05DEC58A55185E43E2310EC945004AD61945BD2AD923B7B3C69A01C0393C15B6000BF542A55274ACA20B8A6EB96FAF83E27023FE0EA9EE564959A91BE17110176FB10D1A094947A23EFDE15DD093EF477EF798BCA8F5E14F85411242BC9C9492081444490C072BE8511B3C961AAAC80477897B54BDABE78C533F2E149FA64B51936E31F126625566CAFBB57E9F36CE0DF72A45E61AB27B6D25DEA3BA35910E16BB00AD300CEE2535CE75F9411DD43943250B03EBBA60C5C788974F2F695967103045F3A90A587AEFD0613F9C8E10A273DD827A314C75C7DBCE4326191DBCB92020CDB75129BCA032B6FD59D368C3E2404B2832398E40F43ACE284A91DED8812AA23E5B5A1D36AE204C53F1C6EF0E89AD31D1552E70538451847D7332D8FCACB62A1E56C1E5643E4F7AF63C67E082AC95DCB190795FA53522FA046F1919C81A088D7A8A452124E562BE2A702139670E94524D3110B9DFF35AE73F43280600B8304FA2E776089AF2ED929695967998E29A343FF62C4CAD7618222C01735734342FD33284BE9BDA4976DA1BC3B384E6F813FCBDFA3DC57B841515836CB2B37116EB6D417BBE6AEA7604AA915530AD803DF1C13656753C1A5867F4A3AE94BA7347580EE5A6CEBD2F3EB9B7F83E7B74F38995168F08A15A4CDF5702EA9DC907FC45910586D59537582DB1D5F155BF0050866CE3087560F1F44D1F275FD2B422038F9D8643C3BEBA49938D514848AC4F68F4CF44329C7E806B911B0CB7FF0020F3277A3E2B4FF17090D012B641E24D67A962E2FE361504DB014155F074F30F52078CB31DFC51B32746A42EDBF013F9920CFB17D36BB8D1B
-20180413202724 2 6 100 7679 2 FBED7F3DD7CF86B0A6EEDC1930C6958C3C00695DAF4347560C5AC1AA4B22F4DC76F190D63E230EB0CB4344A370A471F17FFCA8DA3B5B0A903F9D1258370125F6C172F3EC5F56D7B8EBD07B2072C45D6141DA3CDC01C3D95DE279C5FAA1E042651028141085EB68AFAC473600F75F4A373DC234D5405DCE7AB5B5854960ABC550FCEFEE8FD578810201DE6B4A5EF616F0CBF5707466D7ECBFD488EB68AD4B2EAC889BA2B7FEFE19CD8AA2C78F61D5DA08B4BC2738E1997F951A525EEF9F668148996D1ABFD1620F9276D741A46BECC0B7868A54745E0B16589A4AA7B938AF92FCA0FC9BBC193504D7EBFEFFEC996746DC6CAD3C192D724FB51E6228915789FF18314B3EB690359ADED802F35F48EC0D9C85AA1A20A2E5CF6EB795F2CCD03284547688B1B80A07EFC31668D30836C59C958BBBF6C1EE3940CC43A9334289C872302BB70368FDAC1653AF132F3E398E9310159C839E72555FD889E4E3B05E714E44E116804BF3748F62EF46E6A05DEC58A55185E43E2310EC945004AD61945BD2AD923B7B3C69A01C0393C15B6000BF542A55274ACA20B8A6EB96FAF83E27023FE0EA9EE564959A91BE17110176FB10D1A094947A23EFDE15DD093EF477EF798BCA8F5E14F85411242BC9C9492081444490C072BE8511B3C961AAAC80477897B54BDABE78C533F2E149FA64B51936E31F126625566CAFBB57E9F36CE0DF72A45E61AB27B6D25DEA3BA35910E16BB00AD300CEE2535CE75F9411DD43943250B03EBBA60C5C788974F2F695967103045F3A90A587AEFD0613F9C8E10A273DD827A314C75C7DBCE4326191DBCB92020CDB75129BCA032B6FD59D368C3E2404B2832398E40F43ACE284A91DED8812AA23E5B5A1D36AE204C53F1C6EF0E89AD31D1552E70538451847D7332D8FCACB62A1E56C1E5643E4F7AF63C67E082AC95DCB190795FA53522FA046F1919C81A088D7A8A452124E562BE2A702139670E94524D3110B9DFF35AE73F43280600B8304FA2E776089AF2ED929695967998E29A343FF62C4CAD7618222C01735734342FD33284BE9BDA4976DA1BC3B384E6F813FCBDFA3DC57B841515836CB2B37116EB6D417BBE6AEA7604AA915530AD803DF1C13656753C1A5867F4A3AE94BA7347580EE5A6CEBD2F3EB9B7F83E7B74F38995168F08A15A4CDF5702EA9DC907FC45910586D59537582DB1D5F155BF0050866CE3087560F1F44D1F275FD2B422038F9D8643C3BEBA49938D514848AC4F68F4CF44329C7E806B911B0CB7FF0020F3277A3E2B4FF17090D012B641E24D67A962E2FE361504DB014155F074F30F52078CB31DFC51B32746A42EDBF013F9920CFB17D39A4E13B
-20180413203949 2 6 100 7679 2 FBED7F3DD7CF86B0A6EEDC1930C6958C3C00695DAF4347560C5AC1AA4B22F4DC76F190D63E230EB0CB4344A370A471F17FFCA8DA3B5B0A903F9D1258370125F6C172F3EC5F56D7B8EBD07B2072C45D6141DA3CDC01C3D95DE279C5FAA1E042651028141085EB68AFAC473600F75F4A373DC234D5405DCE7AB5B5854960ABC550FCEFEE8FD578810201DE6B4A5EF616F0CBF5707466D7ECBFD488EB68AD4B2EAC889BA2B7FEFE19CD8AA2C78F61D5DA08B4BC2738E1997F951A525EEF9F668148996D1ABFD1620F9276D741A46BECC0B7868A54745E0B16589A4AA7B938AF92FCA0FC9BBC193504D7EBFEFFEC996746DC6CAD3C192D724FB51E6228915789FF18314B3EB690359ADED802F35F48EC0D9C85AA1A20A2E5CF6EB795F2CCD03284547688B1B80A07EFC31668D30836C59C958BBBF6C1EE3940CC43A9334289C872302BB70368FDAC1653AF132F3E398E9310159C839E72555FD889E4E3B05E714E44E116804BF3748F62EF46E6A05DEC58A55185E43E2310EC945004AD61945BD2AD923B7B3C69A01C0393C15B6000BF542A55274ACA20B8A6EB96FAF83E27023FE0EA9EE564959A91BE17110176FB10D1A094947A23EFDE15DD093EF477EF798BCA8F5E14F85411242BC9C9492081444490C072BE8511B3C961AAAC80477897B54BDABE78C533F2E149FA64B51936E31F126625566CAFBB57E9F36CE0DF72A45E61AB27B6D25DEA3BA35910E16BB00AD300CEE2535CE75F9411DD43943250B03EBBA60C5C788974F2F695967103045F3A90A587AEFD0613F9C8E10A273DD827A314C75C7DBCE4326191DBCB92020CDB75129BCA032B6FD59D368C3E2404B2832398E40F43ACE284A91DED8812AA23E5B5A1D36AE204C53F1C6EF0E89AD31D1552E70538451847D7332D8FCACB62A1E56C1E5643E4F7AF63C67E082AC95DCB190795FA53522FA046F1919C81A088D7A8A452124E562BE2A702139670E94524D3110B9DFF35AE73F43280600B8304FA2E776089AF2ED929695967998E29A343FF62C4CAD7618222C01735734342FD33284BE9BDA4976DA1BC3B384E6F813FCBDFA3DC57B841515836CB2B37116EB6D417BBE6AEA7604AA915530AD803DF1C13656753C1A5867F4A3AE94BA7347580EE5A6CEBD2F3EB9B7F83E7B74F38995168F08A15A4CDF5702EA9DC907FC45910586D59537582DB1D5F155BF0050866CE3087560F1F44D1F275FD2B422038F9D8643C3BEBA49938D514848AC4F68F4CF44329C7E806B911B0CB7FF0020F3277A3E2B4FF17090D012B641E24D67A962E2FE361504DB014155F074F30F52078CB31DFC51B32746A42EDBF013F9920CFB17D39C6A4FB
-20180413211909 2 6 100 7679 2 FBED7F3DD7CF86B0A6EEDC1930C6958C3C00695DAF4347560C5AC1AA4B22F4DC76F190D63E230EB0CB4344A370A471F17FFCA8DA3B5B0A903F9D1258370125F6C172F3EC5F56D7B8EBD07B2072C45D6141DA3CDC01C3D95DE279C5FAA1E042651028141085EB68AFAC473600F75F4A373DC234D5405DCE7AB5B5854960ABC550FCEFEE8FD578810201DE6B4A5EF616F0CBF5707466D7ECBFD488EB68AD4B2EAC889BA2B7FEFE19CD8AA2C78F61D5DA08B4BC2738E1997F951A525EEF9F668148996D1ABFD1620F9276D741A46BECC0B7868A54745E0B16589A4AA7B938AF92FCA0FC9BBC193504D7EBFEFFEC996746DC6CAD3C192D724FB51E6228915789FF18314B3EB690359ADED802F35F48EC0D9C85AA1A20A2E5CF6EB795F2CCD03284547688B1B80A07EFC31668D30836C59C958BBBF6C1EE3940CC43A9334289C872302BB70368FDAC1653AF132F3E398E9310159C839E72555FD889E4E3B05E714E44E116804BF3748F62EF46E6A05DEC58A55185E43E2310EC945004AD61945BD2AD923B7B3C69A01C0393C15B6000BF542A55274ACA20B8A6EB96FAF83E27023FE0EA9EE564959A91BE17110176FB10D1A094947A23EFDE15DD093EF477EF798BCA8F5E14F85411242BC9C9492081444490C072BE8511B3C961AAAC80477897B54BDABE78C533F2E149FA64B51936E31F126625566CAFBB57E9F36CE0DF72A45E61AB27B6D25DEA3BA35910E16BB00AD300CEE2535CE75F9411DD43943250B03EBBA60C5C788974F2F695967103045F3A90A587AEFD0613F9C8E10A273DD827A314C75C7DBCE4326191DBCB92020CDB75129BCA032B6FD59D368C3E2404B2832398E40F43ACE284A91DED8812AA23E5B5A1D36AE204C53F1C6EF0E89AD31D1552E70538451847D7332D8FCACB62A1E56C1E5643E4F7AF63C67E082AC95DCB190795FA53522FA046F1919C81A088D7A8A452124E562BE2A702139670E94524D3110B9DFF35AE73F43280600B8304FA2E776089AF2ED929695967998E29A343FF62C4CAD7618222C01735734342FD33284BE9BDA4976DA1BC3B384E6F813FCBDFA3DC57B841515836CB2B37116EB6D417BBE6AEA7604AA915530AD803DF1C13656753C1A5867F4A3AE94BA7347580EE5A6CEBD2F3EB9B7F83E7B74F38995168F08A15A4CDF5702EA9DC907FC45910586D59537582DB1D5F155BF0050866CE3087560F1F44D1F275FD2B422038F9D8643C3BEBA49938D514848AC4F68F4CF44329C7E806B911B0CB7FF0020F3277A3E2B4FF17090D012B641E24D67A962E2FE361504DB014155F074F30F52078CB31DFC51B32746A42EDBF013F9920CFB17D3A44F883
-20180414010718 2 6 100 7679 5 FBED7F3DD7CF86B0A6EEDC1930C6958C3C00695DAF4347560C5AC1AA4B22F4DC76F190D63E230EB0CB4344A370A471F17FFCA8DA3B5B0A903F9D1258370125F6C172F3EC5F56D7B8EBD07B2072C45D6141DA3CDC01C3D95DE279C5FAA1E042651028141085EB68AFAC473600F75F4A373DC234D5405DCE7AB5B5854960ABC550FCEFEE8FD578810201DE6B4A5EF616F0CBF5707466D7ECBFD488EB68AD4B2EAC889BA2B7FEFE19CD8AA2C78F61D5DA08B4BC2738E1997F951A525EEF9F668148996D1ABFD1620F9276D741A46BECC0B7868A54745E0B16589A4AA7B938AF92FCA0FC9BBC193504D7EBFEFFEC996746DC6CAD3C192D724FB51E6228915789FF18314B3EB690359ADED802F35F48EC0D9C85AA1A20A2E5CF6EB795F2CCD03284547688B1B80A07EFC31668D30836C59C958BBBF6C1EE3940CC43A9334289C872302BB70368FDAC1653AF132F3E398E9310159C839E72555FD889E4E3B05E714E44E116804BF3748F62EF46E6A05DEC58A55185E43E2310EC945004AD61945BD2AD923B7B3C69A01C0393C15B6000BF542A55274ACA20B8A6EB96FAF83E27023FE0EA9EE564959A91BE17110176FB10D1A094947A23EFDE15DD093EF477EF798BCA8F5E14F85411242BC9C9492081444490C072BE8511B3C961AAAC80477897B54BDABE78C533F2E149FA64B51936E31F126625566CAFBB57E9F36CE0DF72A45E61AB27B6D25DEA3BA35910E16BB00AD300CEE2535CE75F9411DD43943250B03EBBA60C5C788974F2F695967103045F3A90A587AEFD0613F9C8E10A273DD827A314C75C7DBCE4326191DBCB92020CDB75129BCA032B6FD59D368C3E2404B2832398E40F43ACE284A91DED8812AA23E5B5A1D36AE204C53F1C6EF0E89AD31D1552E70538451847D7332D8FCACB62A1E56C1E5643E4F7AF63C67E082AC95DCB190795FA53522FA046F1919C81A088D7A8A452124E562BE2A702139670E94524D3110B9DFF35AE73F43280600B8304FA2E776089AF2ED929695967998E29A343FF62C4CAD7618222C01735734342FD33284BE9BDA4976DA1BC3B384E6F813FCBDFA3DC57B841515836CB2B37116EB6D417BBE6AEA7604AA915530AD803DF1C13656753C1A5867F4A3AE94BA7347580EE5A6CEBD2F3EB9B7F83E7B74F38995168F08A15A4CDF5702EA9DC907FC45910586D59537582DB1D5F155BF0050866CE3087560F1F44D1F275FD2B422038F9D8643C3BEBA49938D514848AC4F68F4CF44329C7E806B911B0CB7FF0020F3277A3E2B4FF17090D012B641E24D67A962E2FE361504DB014155F074F30F52078CB31DFC51B32746A42EDBF013F9920CFB17D3D3D3257
-20180414125221 2 6 100 7679 2 FBED7F3DD7CF86B0A6EEDC1930C6958C3C00695DAF4347560C5AC1AA4B22F4DC76F190D63E230EB0CB4344A370A471F17FFCA8DA3B5B0A903F9D1258370125F6C172F3EC5F56D7B8EBD07B2072C45D6141DA3CDC01C3D95DE279C5FAA1E042651028141085EB68AFAC473600F75F4A373DC234D5405DCE7AB5B5854960ABC550FCEFEE8FD578810201DE6B4A5EF616F0CBF5707466D7ECBFD488EB68AD4B2EAC889BA2B7FEFE19CD8AA2C78F61D5DA08B4BC2738E1997F951A525EEF9F668148996D1ABFD1620F9276D741A46BECC0B7868A54745E0B16589A4AA7B938AF92FCA0FC9BBC193504D7EBFEFFEC996746DC6CAD3C192D724FB51E6228915789FF18314B3EB690359ADED802F35F48EC0D9C85AA1A20A2E5CF6EB795F2CCD03284547688B1B80A07EFC31668D30836C59C958BBBF6C1EE3940CC43A9334289C872302BB70368FDAC1653AF132F3E398E9310159C839E72555FD889E4E3B05E714E44E116804BF3748F62EF46E6A05DEC58A55185E43E2310EC945004AD61945BD2AD923B7B3C69A01C0393C15B6000BF542A55274ACA20B8A6EB96FAF83E27023FE0EA9EE564959A91BE17110176FB10D1A094947A23EFDE15DD093EF477EF798BCA8F5E14F85411242BC9C9492081444490C072BE8511B3C961AAAC80477897B54BDABE78C533F2E149FA64B51936E31F126625566CAFBB57E9F36CE0DF72A45E61AB27B6D25DEA3BA35910E16BB00AD300CEE2535CE75F9411DD43943250B03EBBA60C5C788974F2F695967103045F3A90A587AEFD0613F9C8E10A273DD827A314C75C7DBCE4326191DBCB92020CDB75129BCA032B6FD59D368C3E2404B2832398E40F43ACE284A91DED8812AA23E5B5A1D36AE204C53F1C6EF0E89AD31D1552E70538451847D7332D8FCACB62A1E56C1E5643E4F7AF63C67E082AC95DCB190795FA53522FA046F1919C81A088D7A8A452124E562BE2A702139670E94524D3110B9DFF35AE73F43280600B8304FA2E776089AF2ED929695967998E29A343FF62C4CAD7618222C01735734342FD33284BE9BDA4976DA1BC3B384E6F813FCBDFA3DC57B841515836CB2B37116EB6D417BBE6AEA7604AA915530AD803DF1C13656753C1A5867F4A3AE94BA7347580EE5A6CEBD2F3EB9B7F83E7B74F38995168F08A15A4CDF5702EA9DC907FC45910586D59537582DB1D5F155BF0050866CE3087560F1F44D1F275FD2B422038F9D8643C3BEBA49938D514848AC4F68F4CF44329C7E806B911B0CB7FF0020F3277A3E2B4FF17090D012B641E24D67A962E2FE361504DB014155F074F30F52078CB31DFC51B32746A42EDBF013F9920CFB17D467C1523
-20180414181319 2 6 100 7679 2 FBED7F3DD7CF86B0A6EEDC1930C6958C3C00695DAF4347560C5AC1AA4B22F4DC76F190D63E230EB0CB4344A370A471F17FFCA8DA3B5B0A903F9D1258370125F6C172F3EC5F56D7B8EBD07B2072C45D6141DA3CDC01C3D95DE279C5FAA1E042651028141085EB68AFAC473600F75F4A373DC234D5405DCE7AB5B5854960ABC550FCEFEE8FD578810201DE6B4A5EF616F0CBF5707466D7ECBFD488EB68AD4B2EAC889BA2B7FEFE19CD8AA2C78F61D5DA08B4BC2738E1997F951A525EEF9F668148996D1ABFD1620F9276D741A46BECC0B7868A54745E0B16589A4AA7B938AF92FCA0FC9BBC193504D7EBFEFFEC996746DC6CAD3C192D724FB51E6228915789FF18314B3EB690359ADED802F35F48EC0D9C85AA1A20A2E5CF6EB795F2CCD03284547688B1B80A07EFC31668D30836C59C958BBBF6C1EE3940CC43A9334289C872302BB70368FDAC1653AF132F3E398E9310159C839E72555FD889E4E3B05E714E44E116804BF3748F62EF46E6A05DEC58A55185E43E2310EC945004AD61945BD2AD923B7B3C69A01C0393C15B6000BF542A55274ACA20B8A6EB96FAF83E27023FE0EA9EE564959A91BE17110176FB10D1A094947A23EFDE15DD093EF477EF798BCA8F5E14F85411242BC9C9492081444490C072BE8511B3C961AAAC80477897B54BDABE78C533F2E149FA64B51936E31F126625566CAFBB57E9F36CE0DF72A45E61AB27B6D25DEA3BA35910E16BB00AD300CEE2535CE75F9411DD43943250B03EBBA60C5C788974F2F695967103045F3A90A587AEFD0613F9C8E10A273DD827A314C75C7DBCE4326191DBCB92020CDB75129BCA032B6FD59D368C3E2404B2832398E40F43ACE284A91DED8812AA23E5B5A1D36AE204C53F1C6EF0E89AD31D1552E70538451847D7332D8FCACB62A1E56C1E5643E4F7AF63C67E082AC95DCB190795FA53522FA046F1919C81A088D7A8A452124E562BE2A702139670E94524D3110B9DFF35AE73F43280600B8304FA2E776089AF2ED929695967998E29A343FF62C4CAD7618222C01735734342FD33284BE9BDA4976DA1BC3B384E6F813FCBDFA3DC57B841515836CB2B37116EB6D417BBE6AEA7604AA915530AD803DF1C13656753C1A5867F4A3AE94BA7347580EE5A6CEBD2F3EB9B7F83E7B74F38995168F08A15A4CDF5702EA9DC907FC45910586D59537582DB1D5F155BF0050866CE3087560F1F44D1F275FD2B422038F9D8643C3BEBA49938D514848AC4F68F4CF44329C7E806B911B0CB7FF0020F3277A3E2B4FF17090D012B641E24D67A962E2FE361504DB014155F074F30F52078CB31DFC51B32746A42EDBF013F9920CFB17D4AA2837B
-20180414202910 2 6 100 7679 5 FBED7F3DD7CF86B0A6EEDC1930C6958C3C00695DAF4347560C5AC1AA4B22F4DC76F190D63E230EB0CB4344A370A471F17FFCA8DA3B5B0A903F9D1258370125F6C172F3EC5F56D7B8EBD07B2072C45D6141DA3CDC01C3D95DE279C5FAA1E042651028141085EB68AFAC473600F75F4A373DC234D5405DCE7AB5B5854960ABC550FCEFEE8FD578810201DE6B4A5EF616F0CBF5707466D7ECBFD488EB68AD4B2EAC889BA2B7FEFE19CD8AA2C78F61D5DA08B4BC2738E1997F951A525EEF9F668148996D1ABFD1620F9276D741A46BECC0B7868A54745E0B16589A4AA7B938AF92FCA0FC9BBC193504D7EBFEFFEC996746DC6CAD3C192D724FB51E6228915789FF18314B3EB690359ADED802F35F48EC0D9C85AA1A20A2E5CF6EB795F2CCD03284547688B1B80A07EFC31668D30836C59C958BBBF6C1EE3940CC43A9334289C872302BB70368FDAC1653AF132F3E398E9310159C839E72555FD889E4E3B05E714E44E116804BF3748F62EF46E6A05DEC58A55185E43E2310EC945004AD61945BD2AD923B7B3C69A01C0393C15B6000BF542A55274ACA20B8A6EB96FAF83E27023FE0EA9EE564959A91BE17110176FB10D1A094947A23EFDE15DD093EF477EF798BCA8F5E14F85411242BC9C9492081444490C072BE8511B3C961AAAC80477897B54BDABE78C533F2E149FA64B51936E31F126625566CAFBB57E9F36CE0DF72A45E61AB27B6D25DEA3BA35910E16BB00AD300CEE2535CE75F9411DD43943250B03EBBA60C5C788974F2F695967103045F3A90A587AEFD0613F9C8E10A273DD827A314C75C7DBCE4326191DBCB92020CDB75129BCA032B6FD59D368C3E2404B2832398E40F43ACE284A91DED8812AA23E5B5A1D36AE204C53F1C6EF0E89AD31D1552E70538451847D7332D8FCACB62A1E56C1E5643E4F7AF63C67E082AC95DCB190795FA53522FA046F1919C81A088D7A8A452124E562BE2A702139670E94524D3110B9DFF35AE73F43280600B8304FA2E776089AF2ED929695967998E29A343FF62C4CAD7618222C01735734342FD33284BE9BDA4976DA1BC3B384E6F813FCBDFA3DC57B841515836CB2B37116EB6D417BBE6AEA7604AA915530AD803DF1C13656753C1A5867F4A3AE94BA7347580EE5A6CEBD2F3EB9B7F83E7B74F38995168F08A15A4CDF5702EA9DC907FC45910586D59537582DB1D5F155BF0050866CE3087560F1F44D1F275FD2B422038F9D8643C3BEBA49938D514848AC4F68F4CF44329C7E806B911B0CB7FF0020F3277A3E2B4FF17090D012B641E24D67A962E2FE361504DB014155F074F30F52078CB31DFC51B32746A42EDBF013F9920CFB17D4C60657F
-20180414210359 2 6 100 7679 5 FBED7F3DD7CF86B0A6EEDC1930C6958C3C00695DAF4347560C5AC1AA4B22F4DC76F190D63E230EB0CB4344A370A471F17FFCA8DA3B5B0A903F9D1258370125F6C172F3EC5F56D7B8EBD07B2072C45D6141DA3CDC01C3D95DE279C5FAA1E042651028141085EB68AFAC473600F75F4A373DC234D5405DCE7AB5B5854960ABC550FCEFEE8FD578810201DE6B4A5EF616F0CBF5707466D7ECBFD488EB68AD4B2EAC889BA2B7FEFE19CD8AA2C78F61D5DA08B4BC2738E1997F951A525EEF9F668148996D1ABFD1620F9276D741A46BECC0B7868A54745E0B16589A4AA7B938AF92FCA0FC9BBC193504D7EBFEFFEC996746DC6CAD3C192D724FB51E6228915789FF18314B3EB690359ADED802F35F48EC0D9C85AA1A20A2E5CF6EB795F2CCD03284547688B1B80A07EFC31668D30836C59C958BBBF6C1EE3940CC43A9334289C872302BB70368FDAC1653AF132F3E398E9310159C839E72555FD889E4E3B05E714E44E116804BF3748F62EF46E6A05DEC58A55185E43E2310EC945004AD61945BD2AD923B7B3C69A01C0393C15B6000BF542A55274ACA20B8A6EB96FAF83E27023FE0EA9EE564959A91BE17110176FB10D1A094947A23EFDE15DD093EF477EF798BCA8F5E14F85411242BC9C9492081444490C072BE8511B3C961AAAC80477897B54BDABE78C533F2E149FA64B51936E31F126625566CAFBB57E9F36CE0DF72A45E61AB27B6D25DEA3BA35910E16BB00AD300CEE2535CE75F9411DD43943250B03EBBA60C5C788974F2F695967103045F3A90A587AEFD0613F9C8E10A273DD827A314C75C7DBCE4326191DBCB92020CDB75129BCA032B6FD59D368C3E2404B2832398E40F43ACE284A91DED8812AA23E5B5A1D36AE204C53F1C6EF0E89AD31D1552E70538451847D7332D8FCACB62A1E56C1E5643E4F7AF63C67E082AC95DCB190795FA53522FA046F1919C81A088D7A8A452124E562BE2A702139670E94524D3110B9DFF35AE73F43280600B8304FA2E776089AF2ED929695967998E29A343FF62C4CAD7618222C01735734342FD33284BE9BDA4976DA1BC3B384E6F813FCBDFA3DC57B841515836CB2B37116EB6D417BBE6AEA7604AA915530AD803DF1C13656753C1A5867F4A3AE94BA7347580EE5A6CEBD2F3EB9B7F83E7B74F38995168F08A15A4CDF5702EA9DC907FC45910586D59537582DB1D5F155BF0050866CE3087560F1F44D1F275FD2B422038F9D8643C3BEBA49938D514848AC4F68F4CF44329C7E806B911B0CB7FF0020F3277A3E2B4FF17090D012B641E24D67A962E2FE361504DB014155F074F30F52078CB31DFC51B32746A42EDBF013F9920CFB17D4CCB3D87
-20180415054313 2 6 100 7679 5 FBED7F3DD7CF86B0A6EEDC1930C6958C3C00695DAF4347560C5AC1AA4B22F4DC76F190D63E230EB0CB4344A370A471F17FFCA8DA3B5B0A903F9D1258370125F6C172F3EC5F56D7B8EBD07B2072C45D6141DA3CDC01C3D95DE279C5FAA1E042651028141085EB68AFAC473600F75F4A373DC234D5405DCE7AB5B5854960ABC550FCEFEE8FD578810201DE6B4A5EF616F0CBF5707466D7ECBFD488EB68AD4B2EAC889BA2B7FEFE19CD8AA2C78F61D5DA08B4BC2738E1997F951A525EEF9F668148996D1ABFD1620F9276D741A46BECC0B7868A54745E0B16589A4AA7B938AF92FCA0FC9BBC193504D7EBFEFFEC996746DC6CAD3C192D724FB51E6228915789FF18314B3EB690359ADED802F35F48EC0D9C85AA1A20A2E5CF6EB795F2CCD03284547688B1B80A07EFC31668D30836C59C958BBBF6C1EE3940CC43A9334289C872302BB70368FDAC1653AF132F3E398E9310159C839E72555FD889E4E3B05E714E44E116804BF3748F62EF46E6A05DEC58A55185E43E2310EC945004AD61945BD2AD923B7B3C69A01C0393C15B6000BF542A55274ACA20B8A6EB96FAF83E27023FE0EA9EE564959A91BE17110176FB10D1A094947A23EFDE15DD093EF477EF798BCA8F5E14F85411242BC9C9492081444490C072BE8511B3C961AAAC80477897B54BDABE78C533F2E149FA64B51936E31F126625566CAFBB57E9F36CE0DF72A45E61AB27B6D25DEA3BA35910E16BB00AD300CEE2535CE75F9411DD43943250B03EBBA60C5C788974F2F695967103045F3A90A587AEFD0613F9C8E10A273DD827A314C75C7DBCE4326191DBCB92020CDB75129BCA032B6FD59D368C3E2404B2832398E40F43ACE284A91DED8812AA23E5B5A1D36AE204C53F1C6EF0E89AD31D1552E70538451847D7332D8FCACB62A1E56C1E5643E4F7AF63C67E082AC95DCB190795FA53522FA046F1919C81A088D7A8A452124E562BE2A702139670E94524D3110B9DFF35AE73F43280600B8304FA2E776089AF2ED929695967998E29A343FF62C4CAD7618222C01735734342FD33284BE9BDA4976DA1BC3B384E6F813FCBDFA3DC57B841515836CB2B37116EB6D417BBE6AEA7604AA915530AD803DF1C13656753C1A5867F4A3AE94BA7347580EE5A6CEBD2F3EB9B7F83E7B74F38995168F08A15A4CDF5702EA9DC907FC45910586D59537582DB1D5F155BF0050866CE3087560F1F44D1F275FD2B422038F9D8643C3BEBA49938D514848AC4F68F4CF44329C7E806B911B0CB7FF0020F3277A3E2B4FF17090D012B641E24D67A962E2FE361504DB014155F074F30F52078CB31DFC51B32746A42EDBF013F9920CFB17D53659F57
-20180415133017 2 6 100 7679 5 FBED7F3DD7CF86B0A6EEDC1930C6958C3C00695DAF4347560C5AC1AA4B22F4DC76F190D63E230EB0CB4344A370A471F17FFCA8DA3B5B0A903F9D1258370125F6C172F3EC5F56D7B8EBD07B2072C45D6141DA3CDC01C3D95DE279C5FAA1E042651028141085EB68AFAC473600F75F4A373DC234D5405DCE7AB5B5854960ABC550FCEFEE8FD578810201DE6B4A5EF616F0CBF5707466D7ECBFD488EB68AD4B2EAC889BA2B7FEFE19CD8AA2C78F61D5DA08B4BC2738E1997F951A525EEF9F668148996D1ABFD1620F9276D741A46BECC0B7868A54745E0B16589A4AA7B938AF92FCA0FC9BBC193504D7EBFEFFEC996746DC6CAD3C192D724FB51E6228915789FF18314B3EB690359ADED802F35F48EC0D9C85AA1A20A2E5CF6EB795F2CCD03284547688B1B80A07EFC31668D30836C59C958BBBF6C1EE3940CC43A9334289C872302BB70368FDAC1653AF132F3E398E9310159C839E72555FD889E4E3B05E714E44E116804BF3748F62EF46E6A05DEC58A55185E43E2310EC945004AD61945BD2AD923B7B3C69A01C0393C15B6000BF542A55274ACA20B8A6EB96FAF83E27023FE0EA9EE564959A91BE17110176FB10D1A094947A23EFDE15DD093EF477EF798BCA8F5E14F85411242BC9C9492081444490C072BE8511B3C961AAAC80477897B54BDABE78C533F2E149FA64B51936E31F126625566CAFBB57E9F36CE0DF72A45E61AB27B6D25DEA3BA35910E16BB00AD300CEE2535CE75F9411DD43943250B03EBBA60C5C788974F2F695967103045F3A90A587AEFD0613F9C8E10A273DD827A314C75C7DBCE4326191DBCB92020CDB75129BCA032B6FD59D368C3E2404B2832398E40F43ACE284A91DED8812AA23E5B5A1D36AE204C53F1C6EF0E89AD31D1552E70538451847D7332D8FCACB62A1E56C1E5643E4F7AF63C67E082AC95DCB190795FA53522FA046F1919C81A088D7A8A452124E562BE2A702139670E94524D3110B9DFF35AE73F43280600B8304FA2E776089AF2ED929695967998E29A343FF62C4CAD7618222C01735734342FD33284BE9BDA4976DA1BC3B384E6F813FCBDFA3DC57B841515836CB2B37116EB6D417BBE6AEA7604AA915530AD803DF1C13656753C1A5867F4A3AE94BA7347580EE5A6CEBD2F3EB9B7F83E7B74F38995168F08A15A4CDF5702EA9DC907FC45910586D59537582DB1D5F155BF0050866CE3087560F1F44D1F275FD2B422038F9D8643C3BEBA49938D514848AC4F68F4CF44329C7E806B911B0CB7FF0020F3277A3E2B4FF17090D012B641E24D67A962E2FE361504DB014155F074F30F52078CB31DFC51B32746A42EDBF013F9920CFB17D596ABEFF
-20180415160204 2 6 100 7679 5 FBED7F3DD7CF86B0A6EEDC1930C6958C3C00695DAF4347560C5AC1AA4B22F4DC76F190D63E230EB0CB4344A370A471F17FFCA8DA3B5B0A903F9D1258370125F6C172F3EC5F56D7B8EBD07B2072C45D6141DA3CDC01C3D95DE279C5FAA1E042651028141085EB68AFAC473600F75F4A373DC234D5405DCE7AB5B5854960ABC550FCEFEE8FD578810201DE6B4A5EF616F0CBF5707466D7ECBFD488EB68AD4B2EAC889BA2B7FEFE19CD8AA2C78F61D5DA08B4BC2738E1997F951A525EEF9F668148996D1ABFD1620F9276D741A46BECC0B7868A54745E0B16589A4AA7B938AF92FCA0FC9BBC193504D7EBFEFFEC996746DC6CAD3C192D724FB51E6228915789FF18314B3EB690359ADED802F35F48EC0D9C85AA1A20A2E5CF6EB795F2CCD03284547688B1B80A07EFC31668D30836C59C958BBBF6C1EE3940CC43A9334289C872302BB70368FDAC1653AF132F3E398E9310159C839E72555FD889E4E3B05E714E44E116804BF3748F62EF46E6A05DEC58A55185E43E2310EC945004AD61945BD2AD923B7B3C69A01C0393C15B6000BF542A55274ACA20B8A6EB96FAF83E27023FE0EA9EE564959A91BE17110176FB10D1A094947A23EFDE15DD093EF477EF798BCA8F5E14F85411242BC9C9492081444490C072BE8511B3C961AAAC80477897B54BDABE78C533F2E149FA64B51936E31F126625566CAFBB57E9F36CE0DF72A45E61AB27B6D25DEA3BA35910E16BB00AD300CEE2535CE75F9411DD43943250B03EBBA60C5C788974F2F695967103045F3A90A587AEFD0613F9C8E10A273DD827A314C75C7DBCE4326191DBCB92020CDB75129BCA032B6FD59D368C3E2404B2832398E40F43ACE284A91DED8812AA23E5B5A1D36AE204C53F1C6EF0E89AD31D1552E70538451847D7332D8FCACB62A1E56C1E5643E4F7AF63C67E082AC95DCB190795FA53522FA046F1919C81A088D7A8A452124E562BE2A702139670E94524D3110B9DFF35AE73F43280600B8304FA2E776089AF2ED929695967998E29A343FF62C4CAD7618222C01735734342FD33284BE9BDA4976DA1BC3B384E6F813FCBDFA3DC57B841515836CB2B37116EB6D417BBE6AEA7604AA915530AD803DF1C13656753C1A5867F4A3AE94BA7347580EE5A6CEBD2F3EB9B7F83E7B74F38995168F08A15A4CDF5702EA9DC907FC45910586D59537582DB1D5F155BF0050866CE3087560F1F44D1F275FD2B422038F9D8643C3BEBA49938D514848AC4F68F4CF44329C7E806B911B0CB7FF0020F3277A3E2B4FF17090D012B641E24D67A962E2FE361504DB014155F074F30F52078CB31DFC51B32746A42EDBF013F9920CFB17D5B5415B7
-20180415222232 2 6 100 7679 2 FBED7F3DD7CF86B0A6EEDC1930C6958C3C00695DAF4347560C5AC1AA4B22F4DC76F190D63E230EB0CB4344A370A471F17FFCA8DA3B5B0A903F9D1258370125F6C172F3EC5F56D7B8EBD07B2072C45D6141DA3CDC01C3D95DE279C5FAA1E042651028141085EB68AFAC473600F75F4A373DC234D5405DCE7AB5B5854960ABC550FCEFEE8FD578810201DE6B4A5EF616F0CBF5707466D7ECBFD488EB68AD4B2EAC889BA2B7FEFE19CD8AA2C78F61D5DA08B4BC2738E1997F951A525EEF9F668148996D1ABFD1620F9276D741A46BECC0B7868A54745E0B16589A4AA7B938AF92FCA0FC9BBC193504D7EBFEFFEC996746DC6CAD3C192D724FB51E6228915789FF18314B3EB690359ADED802F35F48EC0D9C85AA1A20A2E5CF6EB795F2CCD03284547688B1B80A07EFC31668D30836C59C958BBBF6C1EE3940CC43A9334289C872302BB70368FDAC1653AF132F3E398E9310159C839E72555FD889E4E3B05E714E44E116804BF3748F62EF46E6A05DEC58A55185E43E2310EC945004AD61945BD2AD923B7B3C69A01C0393C15B6000BF542A55274ACA20B8A6EB96FAF83E27023FE0EA9EE564959A91BE17110176FB10D1A094947A23EFDE15DD093EF477EF798BCA8F5E14F85411242BC9C9492081444490C072BE8511B3C961AAAC80477897B54BDABE78C533F2E149FA64B51936E31F126625566CAFBB57E9F36CE0DF72A45E61AB27B6D25DEA3BA35910E16BB00AD300CEE2535CE75F9411DD43943250B03EBBA60C5C788974F2F695967103045F3A90A587AEFD0613F9C8E10A273DD827A314C75C7DBCE4326191DBCB92020CDB75129BCA032B6FD59D368C3E2404B2832398E40F43ACE284A91DED8812AA23E5B5A1D36AE204C53F1C6EF0E89AD31D1552E70538451847D7332D8FCACB62A1E56C1E5643E4F7AF63C67E082AC95DCB190795FA53522FA046F1919C81A088D7A8A452124E562BE2A702139670E94524D3110B9DFF35AE73F43280600B8304FA2E776089AF2ED929695967998E29A343FF62C4CAD7618222C01735734342FD33284BE9BDA4976DA1BC3B384E6F813FCBDFA3DC57B841515836CB2B37116EB6D417BBE6AEA7604AA915530AD803DF1C13656753C1A5867F4A3AE94BA7347580EE5A6CEBD2F3EB9B7F83E7B74F38995168F08A15A4CDF5702EA9DC907FC45910586D59537582DB1D5F155BF0050866CE3087560F1F44D1F275FD2B422038F9D8643C3BEBA49938D514848AC4F68F4CF44329C7E806B911B0CB7FF0020F3277A3E2B4FF17090D012B641E24D67A962E2FE361504DB014155F074F30F52078CB31DFC51B32746A42EDBF013F9920CFB17D6018A3AB
-20180415224834 2 6 100 7679 2 FBED7F3DD7CF86B0A6EEDC1930C6958C3C00695DAF4347560C5AC1AA4B22F4DC76F190D63E230EB0CB4344A370A471F17FFCA8DA3B5B0A903F9D1258370125F6C172F3EC5F56D7B8EBD07B2072C45D6141DA3CDC01C3D95DE279C5FAA1E042651028141085EB68AFAC473600F75F4A373DC234D5405DCE7AB5B5854960ABC550FCEFEE8FD578810201DE6B4A5EF616F0CBF5707466D7ECBFD488EB68AD4B2EAC889BA2B7FEFE19CD8AA2C78F61D5DA08B4BC2738E1997F951A525EEF9F668148996D1ABFD1620F9276D741A46BECC0B7868A54745E0B16589A4AA7B938AF92FCA0FC9BBC193504D7EBFEFFEC996746DC6CAD3C192D724FB51E6228915789FF18314B3EB690359ADED802F35F48EC0D9C85AA1A20A2E5CF6EB795F2CCD03284547688B1B80A07EFC31668D30836C59C958BBBF6C1EE3940CC43A9334289C872302BB70368FDAC1653AF132F3E398E9310159C839E72555FD889E4E3B05E714E44E116804BF3748F62EF46E6A05DEC58A55185E43E2310EC945004AD61945BD2AD923B7B3C69A01C0393C15B6000BF542A55274ACA20B8A6EB96FAF83E27023FE0EA9EE564959A91BE17110176FB10D1A094947A23EFDE15DD093EF477EF798BCA8F5E14F85411242BC9C9492081444490C072BE8511B3C961AAAC80477897B54BDABE78C533F2E149FA64B51936E31F126625566CAFBB57E9F36CE0DF72A45E61AB27B6D25DEA3BA35910E16BB00AD300CEE2535CE75F9411DD43943250B03EBBA60C5C788974F2F695967103045F3A90A587AEFD0613F9C8E10A273DD827A314C75C7DBCE4326191DBCB92020CDB75129BCA032B6FD59D368C3E2404B2832398E40F43ACE284A91DED8812AA23E5B5A1D36AE204C53F1C6EF0E89AD31D1552E70538451847D7332D8FCACB62A1E56C1E5643E4F7AF63C67E082AC95DCB190795FA53522FA046F1919C81A088D7A8A452124E562BE2A702139670E94524D3110B9DFF35AE73F43280600B8304FA2E776089AF2ED929695967998E29A343FF62C4CAD7618222C01735734342FD33284BE9BDA4976DA1BC3B384E6F813FCBDFA3DC57B841515836CB2B37116EB6D417BBE6AEA7604AA915530AD803DF1C13656753C1A5867F4A3AE94BA7347580EE5A6CEBD2F3EB9B7F83E7B74F38995168F08A15A4CDF5702EA9DC907FC45910586D59537582DB1D5F155BF0050866CE3087560F1F44D1F275FD2B422038F9D8643C3BEBA49938D514848AC4F68F4CF44329C7E806B911B0CB7FF0020F3277A3E2B4FF17090D012B641E24D67A962E2FE361504DB014155F074F30F52078CB31DFC51B32746A42EDBF013F9920CFB17D6064EF13
-20180416005338 2 6 100 7679 5 FBED7F3DD7CF86B0A6EEDC1930C6958C3C00695DAF4347560C5AC1AA4B22F4DC76F190D63E230EB0CB4344A370A471F17FFCA8DA3B5B0A903F9D1258370125F6C172F3EC5F56D7B8EBD07B2072C45D6141DA3CDC01C3D95DE279C5FAA1E042651028141085EB68AFAC473600F75F4A373DC234D5405DCE7AB5B5854960ABC550FCEFEE8FD578810201DE6B4A5EF616F0CBF5707466D7ECBFD488EB68AD4B2EAC889BA2B7FEFE19CD8AA2C78F61D5DA08B4BC2738E1997F951A525EEF9F668148996D1ABFD1620F9276D741A46BECC0B7868A54745E0B16589A4AA7B938AF92FCA0FC9BBC193504D7EBFEFFEC996746DC6CAD3C192D724FB51E6228915789FF18314B3EB690359ADED802F35F48EC0D9C85AA1A20A2E5CF6EB795F2CCD03284547688B1B80A07EFC31668D30836C59C958BBBF6C1EE3940CC43A9334289C872302BB70368FDAC1653AF132F3E398E9310159C839E72555FD889E4E3B05E714E44E116804BF3748F62EF46E6A05DEC58A55185E43E2310EC945004AD61945BD2AD923B7B3C69A01C0393C15B6000BF542A55274ACA20B8A6EB96FAF83E27023FE0EA9EE564959A91BE17110176FB10D1A094947A23EFDE15DD093EF477EF798BCA8F5E14F85411242BC9C9492081444490C072BE8511B3C961AAAC80477897B54BDABE78C533F2E149FA64B51936E31F126625566CAFBB57E9F36CE0DF72A45E61AB27B6D25DEA3BA35910E16BB00AD300CEE2535CE75F9411DD43943250B03EBBA60C5C788974F2F695967103045F3A90A587AEFD0613F9C8E10A273DD827A314C75C7DBCE4326191DBCB92020CDB75129BCA032B6FD59D368C3E2404B2832398E40F43ACE284A91DED8812AA23E5B5A1D36AE204C53F1C6EF0E89AD31D1552E70538451847D7332D8FCACB62A1E56C1E5643E4F7AF63C67E082AC95DCB190795FA53522FA046F1919C81A088D7A8A452124E562BE2A702139670E94524D3110B9DFF35AE73F43280600B8304FA2E776089AF2ED929695967998E29A343FF62C4CAD7618222C01735734342FD33284BE9BDA4976DA1BC3B384E6F813FCBDFA3DC57B841515836CB2B37116EB6D417BBE6AEA7604AA915530AD803DF1C13656753C1A5867F4A3AE94BA7347580EE5A6CEBD2F3EB9B7F83E7B74F38995168F08A15A4CDF5702EA9DC907FC45910586D59537582DB1D5F155BF0050866CE3087560F1F44D1F275FD2B422038F9D8643C3BEBA49938D514848AC4F68F4CF44329C7E806B911B0CB7FF0020F3277A3E2B4FF17090D012B641E24D67A962E2FE361504DB014155F074F30F52078CB31DFC51B32746A42EDBF013F9920CFB17D61F17307
-20180416021119 2 6 100 7679 5 FBED7F3DD7CF86B0A6EEDC1930C6958C3C00695DAF4347560C5AC1AA4B22F4DC76F190D63E230EB0CB4344A370A471F17FFCA8DA3B5B0A903F9D1258370125F6C172F3EC5F56D7B8EBD07B2072C45D6141DA3CDC01C3D95DE279C5FAA1E042651028141085EB68AFAC473600F75F4A373DC234D5405DCE7AB5B5854960ABC550FCEFEE8FD578810201DE6B4A5EF616F0CBF5707466D7ECBFD488EB68AD4B2EAC889BA2B7FEFE19CD8AA2C78F61D5DA08B4BC2738E1997F951A525EEF9F668148996D1ABFD1620F9276D741A46BECC0B7868A54745E0B16589A4AA7B938AF92FCA0FC9BBC193504D7EBFEFFEC996746DC6CAD3C192D724FB51E6228915789FF18314B3EB690359ADED802F35F48EC0D9C85AA1A20A2E5CF6EB795F2CCD03284547688B1B80A07EFC31668D30836C59C958BBBF6C1EE3940CC43A9334289C872302BB70368FDAC1653AF132F3E398E9310159C839E72555FD889E4E3B05E714E44E116804BF3748F62EF46E6A05DEC58A55185E43E2310EC945004AD61945BD2AD923B7B3C69A01C0393C15B6000BF542A55274ACA20B8A6EB96FAF83E27023FE0EA9EE564959A91BE17110176FB10D1A094947A23EFDE15DD093EF477EF798BCA8F5E14F85411242BC9C9492081444490C072BE8511B3C961AAAC80477897B54BDABE78C533F2E149FA64B51936E31F126625566CAFBB57E9F36CE0DF72A45E61AB27B6D25DEA3BA35910E16BB00AD300CEE2535CE75F9411DD43943250B03EBBA60C5C788974F2F695967103045F3A90A587AEFD0613F9C8E10A273DD827A314C75C7DBCE4326191DBCB92020CDB75129BCA032B6FD59D368C3E2404B2832398E40F43ACE284A91DED8812AA23E5B5A1D36AE204C53F1C6EF0E89AD31D1552E70538451847D7332D8FCACB62A1E56C1E5643E4F7AF63C67E082AC95DCB190795FA53522FA046F1919C81A088D7A8A452124E562BE2A702139670E94524D3110B9DFF35AE73F43280600B8304FA2E776089AF2ED929695967998E29A343FF62C4CAD7618222C01735734342FD33284BE9BDA4976DA1BC3B384E6F813FCBDFA3DC57B841515836CB2B37116EB6D417BBE6AEA7604AA915530AD803DF1C13656753C1A5867F4A3AE94BA7347580EE5A6CEBD2F3EB9B7F83E7B74F38995168F08A15A4CDF5702EA9DC907FC45910586D59537582DB1D5F155BF0050866CE3087560F1F44D1F275FD2B422038F9D8643C3BEBA49938D514848AC4F68F4CF44329C7E806B911B0CB7FF0020F3277A3E2B4FF17090D012B641E24D67A962E2FE361504DB014155F074F30F52078CB31DFC51B32746A42EDBF013F9920CFB17D62E1D04F
-20180416083930 2 6 100 7679 5 FBED7F3DD7CF86B0A6EEDC1930C6958C3C00695DAF4347560C5AC1AA4B22F4DC76F190D63E230EB0CB4344A370A471F17FFCA8DA3B5B0A903F9D1258370125F6C172F3EC5F56D7B8EBD07B2072C45D6141DA3CDC01C3D95DE279C5FAA1E042651028141085EB68AFAC473600F75F4A373DC234D5405DCE7AB5B5854960ABC550FCEFEE8FD578810201DE6B4A5EF616F0CBF5707466D7ECBFD488EB68AD4B2EAC889BA2B7FEFE19CD8AA2C78F61D5DA08B4BC2738E1997F951A525EEF9F668148996D1ABFD1620F9276D741A46BECC0B7868A54745E0B16589A4AA7B938AF92FCA0FC9BBC193504D7EBFEFFEC996746DC6CAD3C192D724FB51E6228915789FF18314B3EB690359ADED802F35F48EC0D9C85AA1A20A2E5CF6EB795F2CCD03284547688B1B80A07EFC31668D30836C59C958BBBF6C1EE3940CC43A9334289C872302BB70368FDAC1653AF132F3E398E9310159C839E72555FD889E4E3B05E714E44E116804BF3748F62EF46E6A05DEC58A55185E43E2310EC945004AD61945BD2AD923B7B3C69A01C0393C15B6000BF542A55274ACA20B8A6EB96FAF83E27023FE0EA9EE564959A91BE17110176FB10D1A094947A23EFDE15DD093EF477EF798BCA8F5E14F85411242BC9C9492081444490C072BE8511B3C961AAAC80477897B54BDABE78C533F2E149FA64B51936E31F126625566CAFBB57E9F36CE0DF72A45E61AB27B6D25DEA3BA35910E16BB00AD300CEE2535CE75F9411DD43943250B03EBBA60C5C788974F2F695967103045F3A90A587AEFD0613F9C8E10A273DD827A314C75C7DBCE4326191DBCB92020CDB75129BCA032B6FD59D368C3E2404B2832398E40F43ACE284A91DED8812AA23E5B5A1D36AE204C53F1C6EF0E89AD31D1552E70538451847D7332D8FCACB62A1E56C1E5643E4F7AF63C67E082AC95DCB190795FA53522FA046F1919C81A088D7A8A452124E562BE2A702139670E94524D3110B9DFF35AE73F43280600B8304FA2E776089AF2ED929695967998E29A343FF62C4CAD7618222C01735734342FD33284BE9BDA4976DA1BC3B384E6F813FCBDFA3DC57B841515836CB2B37116EB6D417BBE6AEA7604AA915530AD803DF1C13656753C1A5867F4A3AE94BA7347580EE5A6CEBD2F3EB9B7F83E7B74F38995168F08A15A4CDF5702EA9DC907FC45910586D59537582DB1D5F155BF0050866CE3087560F1F44D1F275FD2B422038F9D8643C3BEBA49938D514848AC4F68F4CF44329C7E806B911B0CB7FF0020F3277A3E2B4FF17090D012B641E24D67A962E2FE361504DB014155F074F30F52078CB31DFC51B32746A42EDBF013F9920CFB17D67B78127
-20180416182014 2 6 100 7679 2 FBED7F3DD7CF86B0A6EEDC1930C6958C3C00695DAF4347560C5AC1AA4B22F4DC76F190D63E230EB0CB4344A370A471F17FFCA8DA3B5B0A903F9D1258370125F6C172F3EC5F56D7B8EBD07B2072C45D6141DA3CDC01C3D95DE279C5FAA1E042651028141085EB68AFAC473600F75F4A373DC234D5405DCE7AB5B5854960ABC550FCEFEE8FD578810201DE6B4A5EF616F0CBF5707466D7ECBFD488EB68AD4B2EAC889BA2B7FEFE19CD8AA2C78F61D5DA08B4BC2738E1997F951A525EEF9F668148996D1ABFD1620F9276D741A46BECC0B7868A54745E0B16589A4AA7B938AF92FCA0FC9BBC193504D7EBFEFFEC996746DC6CAD3C192D724FB51E6228915789FF18314B3EB690359ADED802F35F48EC0D9C85AA1A20A2E5CF6EB795F2CCD03284547688B1B80A07EFC31668D30836C59C958BBBF6C1EE3940CC43A9334289C872302BB70368FDAC1653AF132F3E398E9310159C839E72555FD889E4E3B05E714E44E116804BF3748F62EF46E6A05DEC58A55185E43E2310EC945004AD61945BD2AD923B7B3C69A01C0393C15B6000BF542A55274ACA20B8A6EB96FAF83E27023FE0EA9EE564959A91BE17110176FB10D1A094947A23EFDE15DD093EF477EF798BCA8F5E14F85411242BC9C9492081444490C072BE8511B3C961AAAC80477897B54BDABE78C533F2E149FA64B51936E31F126625566CAFBB57E9F36CE0DF72A45E61AB27B6D25DEA3BA35910E16BB00AD300CEE2535CE75F9411DD43943250B03EBBA60C5C788974F2F695967103045F3A90A587AEFD0613F9C8E10A273DD827A314C75C7DBCE4326191DBCB92020CDB75129BCA032B6FD59D368C3E2404B2832398E40F43ACE284A91DED8812AA23E5B5A1D36AE204C53F1C6EF0E89AD31D1552E70538451847D7332D8FCACB62A1E56C1E5643E4F7AF63C67E082AC95DCB190795FA53522FA046F1919C81A088D7A8A452124E562BE2A702139670E94524D3110B9DFF35AE73F43280600B8304FA2E776089AF2ED929695967998E29A343FF62C4CAD7618222C01735734342FD33284BE9BDA4976DA1BC3B384E6F813FCBDFA3DC57B841515836CB2B37116EB6D417BBE6AEA7604AA915530AD803DF1C13656753C1A5867F4A3AE94BA7347580EE5A6CEBD2F3EB9B7F83E7B74F38995168F08A15A4CDF5702EA9DC907FC45910586D59537582DB1D5F155BF0050866CE3087560F1F44D1F275FD2B422038F9D8643C3BEBA49938D514848AC4F68F4CF44329C7E806B911B0CB7FF0020F3277A3E2B4FF17090D012B641E24D67A962E2FE361504DB014155F074F30F52078CB31DFC51B32746A42EDBF013F9920CFB17D6EDFEF6B
-20180416190916 2 6 100 7679 5 FBED7F3DD7CF86B0A6EEDC1930C6958C3C00695DAF4347560C5AC1AA4B22F4DC76F190D63E230EB0CB4344A370A471F17FFCA8DA3B5B0A903F9D1258370125F6C172F3EC5F56D7B8EBD07B2072C45D6141DA3CDC01C3D95DE279C5FAA1E042651028141085EB68AFAC473600F75F4A373DC234D5405DCE7AB5B5854960ABC550FCEFEE8FD578810201DE6B4A5EF616F0CBF5707466D7ECBFD488EB68AD4B2EAC889BA2B7FEFE19CD8AA2C78F61D5DA08B4BC2738E1997F951A525EEF9F668148996D1ABFD1620F9276D741A46BECC0B7868A54745E0B16589A4AA7B938AF92FCA0FC9BBC193504D7EBFEFFEC996746DC6CAD3C192D724FB51E6228915789FF18314B3EB690359ADED802F35F48EC0D9C85AA1A20A2E5CF6EB795F2CCD03284547688B1B80A07EFC31668D30836C59C958BBBF6C1EE3940CC43A9334289C872302BB70368FDAC1653AF132F3E398E9310159C839E72555FD889E4E3B05E714E44E116804BF3748F62EF46E6A05DEC58A55185E43E2310EC945004AD61945BD2AD923B7B3C69A01C0393C15B6000BF542A55274ACA20B8A6EB96FAF83E27023FE0EA9EE564959A91BE17110176FB10D1A094947A23EFDE15DD093EF477EF798BCA8F5E14F85411242BC9C9492081444490C072BE8511B3C961AAAC80477897B54BDABE78C533F2E149FA64B51936E31F126625566CAFBB57E9F36CE0DF72A45E61AB27B6D25DEA3BA35910E16BB00AD300CEE2535CE75F9411DD43943250B03EBBA60C5C788974F2F695967103045F3A90A587AEFD0613F9C8E10A273DD827A314C75C7DBCE4326191DBCB92020CDB75129BCA032B6FD59D368C3E2404B2832398E40F43ACE284A91DED8812AA23E5B5A1D36AE204C53F1C6EF0E89AD31D1552E70538451847D7332D8FCACB62A1E56C1E5643E4F7AF63C67E082AC95DCB190795FA53522FA046F1919C81A088D7A8A452124E562BE2A702139670E94524D3110B9DFF35AE73F43280600B8304FA2E776089AF2ED929695967998E29A343FF62C4CAD7618222C01735734342FD33284BE9BDA4976DA1BC3B384E6F813FCBDFA3DC57B841515836CB2B37116EB6D417BBE6AEA7604AA915530AD803DF1C13656753C1A5867F4A3AE94BA7347580EE5A6CEBD2F3EB9B7F83E7B74F38995168F08A15A4CDF5702EA9DC907FC45910586D59537582DB1D5F155BF0050866CE3087560F1F44D1F275FD2B422038F9D8643C3BEBA49938D514848AC4F68F4CF44329C7E806B911B0CB7FF0020F3277A3E2B4FF17090D012B641E24D67A962E2FE361504DB014155F074F30F52078CB31DFC51B32746A42EDBF013F9920CFB17D6F71FA97
-20180416195012 2 6 100 7679 5 FBED7F3DD7CF86B0A6EEDC1930C6958C3C00695DAF4347560C5AC1AA4B22F4DC76F190D63E230EB0CB4344A370A471F17FFCA8DA3B5B0A903F9D1258370125F6C172F3EC5F56D7B8EBD07B2072C45D6141DA3CDC01C3D95DE279C5FAA1E042651028141085EB68AFAC473600F75F4A373DC234D5405DCE7AB5B5854960ABC550FCEFEE8FD578810201DE6B4A5EF616F0CBF5707466D7ECBFD488EB68AD4B2EAC889BA2B7FEFE19CD8AA2C78F61D5DA08B4BC2738E1997F951A525EEF9F668148996D1ABFD1620F9276D741A46BECC0B7868A54745E0B16589A4AA7B938AF92FCA0FC9BBC193504D7EBFEFFEC996746DC6CAD3C192D724FB51E6228915789FF18314B3EB690359ADED802F35F48EC0D9C85AA1A20A2E5CF6EB795F2CCD03284547688B1B80A07EFC31668D30836C59C958BBBF6C1EE3940CC43A9334289C872302BB70368FDAC1653AF132F3E398E9310159C839E72555FD889E4E3B05E714E44E116804BF3748F62EF46E6A05DEC58A55185E43E2310EC945004AD61945BD2AD923B7B3C69A01C0393C15B6000BF542A55274ACA20B8A6EB96FAF83E27023FE0EA9EE564959A91BE17110176FB10D1A094947A23EFDE15DD093EF477EF798BCA8F5E14F85411242BC9C9492081444490C072BE8511B3C961AAAC80477897B54BDABE78C533F2E149FA64B51936E31F126625566CAFBB57E9F36CE0DF72A45E61AB27B6D25DEA3BA35910E16BB00AD300CEE2535CE75F9411DD43943250B03EBBA60C5C788974F2F695967103045F3A90A587AEFD0613F9C8E10A273DD827A314C75C7DBCE4326191DBCB92020CDB75129BCA032B6FD59D368C3E2404B2832398E40F43ACE284A91DED8812AA23E5B5A1D36AE204C53F1C6EF0E89AD31D1552E70538451847D7332D8FCACB62A1E56C1E5643E4F7AF63C67E082AC95DCB190795FA53522FA046F1919C81A088D7A8A452124E562BE2A702139670E94524D3110B9DFF35AE73F43280600B8304FA2E776089AF2ED929695967998E29A343FF62C4CAD7618222C01735734342FD33284BE9BDA4976DA1BC3B384E6F813FCBDFA3DC57B841515836CB2B37116EB6D417BBE6AEA7604AA915530AD803DF1C13656753C1A5867F4A3AE94BA7347580EE5A6CEBD2F3EB9B7F83E7B74F38995168F08A15A4CDF5702EA9DC907FC45910586D59537582DB1D5F155BF0050866CE3087560F1F44D1F275FD2B422038F9D8643C3BEBA49938D514848AC4F68F4CF44329C7E806B911B0CB7FF0020F3277A3E2B4FF17090D012B641E24D67A962E2FE361504DB014155F074F30F52078CB31DFC51B32746A42EDBF013F9920CFB17D6FE60F77
-20180417005002 2 6 100 7679 5 FBED7F3DD7CF86B0A6EEDC1930C6958C3C00695DAF4347560C5AC1AA4B22F4DC76F190D63E230EB0CB4344A370A471F17FFCA8DA3B5B0A903F9D1258370125F6C172F3EC5F56D7B8EBD07B2072C45D6141DA3CDC01C3D95DE279C5FAA1E042651028141085EB68AFAC473600F75F4A373DC234D5405DCE7AB5B5854960ABC550FCEFEE8FD578810201DE6B4A5EF616F0CBF5707466D7ECBFD488EB68AD4B2EAC889BA2B7FEFE19CD8AA2C78F61D5DA08B4BC2738E1997F951A525EEF9F668148996D1ABFD1620F9276D741A46BECC0B7868A54745E0B16589A4AA7B938AF92FCA0FC9BBC193504D7EBFEFFEC996746DC6CAD3C192D724FB51E6228915789FF18314B3EB690359ADED802F35F48EC0D9C85AA1A20A2E5CF6EB795F2CCD03284547688B1B80A07EFC31668D30836C59C958BBBF6C1EE3940CC43A9334289C872302BB70368FDAC1653AF132F3E398E9310159C839E72555FD889E4E3B05E714E44E116804BF3748F62EF46E6A05DEC58A55185E43E2310EC945004AD61945BD2AD923B7B3C69A01C0393C15B6000BF542A55274ACA20B8A6EB96FAF83E27023FE0EA9EE564959A91BE17110176FB10D1A094947A23EFDE15DD093EF477EF798BCA8F5E14F85411242BC9C9492081444490C072BE8511B3C961AAAC80477897B54BDABE78C533F2E149FA64B51936E31F126625566CAFBB57E9F36CE0DF72A45E61AB27B6D25DEA3BA35910E16BB00AD300CEE2535CE75F9411DD43943250B03EBBA60C5C788974F2F695967103045F3A90A587AEFD0613F9C8E10A273DD827A314C75C7DBCE4326191DBCB92020CDB75129BCA032B6FD59D368C3E2404B2832398E40F43ACE284A91DED8812AA23E5B5A1D36AE204C53F1C6EF0E89AD31D1552E70538451847D7332D8FCACB62A1E56C1E5643E4F7AF63C67E082AC95DCB190795FA53522FA046F1919C81A088D7A8A452124E562BE2A702139670E94524D3110B9DFF35AE73F43280600B8304FA2E776089AF2ED929695967998E29A343FF62C4CAD7618222C01735734342FD33284BE9BDA4976DA1BC3B384E6F813FCBDFA3DC57B841515836CB2B37116EB6D417BBE6AEA7604AA915530AD803DF1C13656753C1A5867F4A3AE94BA7347580EE5A6CEBD2F3EB9B7F83E7B74F38995168F08A15A4CDF5702EA9DC907FC45910586D59537582DB1D5F155BF0050866CE3087560F1F44D1F275FD2B422038F9D8643C3BEBA49938D514848AC4F68F4CF44329C7E806B911B0CB7FF0020F3277A3E2B4FF17090D012B641E24D67A962E2FE361504DB014155F074F30F52078CB31DFC51B32746A42EDBF013F9920CFB17D737F03EF
-20180417031611 2 6 100 7679 2 FBED7F3DD7CF86B0A6EEDC1930C6958C3C00695DAF4347560C5AC1AA4B22F4DC76F190D63E230EB0CB4344A370A471F17FFCA8DA3B5B0A903F9D1258370125F6C172F3EC5F56D7B8EBD07B2072C45D6141DA3CDC01C3D95DE279C5FAA1E042651028141085EB68AFAC473600F75F4A373DC234D5405DCE7AB5B5854960ABC550FCEFEE8FD578810201DE6B4A5EF616F0CBF5707466D7ECBFD488EB68AD4B2EAC889BA2B7FEFE19CD8AA2C78F61D5DA08B4BC2738E1997F951A525EEF9F668148996D1ABFD1620F9276D741A46BECC0B7868A54745E0B16589A4AA7B938AF92FCA0FC9BBC193504D7EBFEFFEC996746DC6CAD3C192D724FB51E6228915789FF18314B3EB690359ADED802F35F48EC0D9C85AA1A20A2E5CF6EB795F2CCD03284547688B1B80A07EFC31668D30836C59C958BBBF6C1EE3940CC43A9334289C872302BB70368FDAC1653AF132F3E398E9310159C839E72555FD889E4E3B05E714E44E116804BF3748F62EF46E6A05DEC58A55185E43E2310EC945004AD61945BD2AD923B7B3C69A01C0393C15B6000BF542A55274ACA20B8A6EB96FAF83E27023FE0EA9EE564959A91BE17110176FB10D1A094947A23EFDE15DD093EF477EF798BCA8F5E14F85411242BC9C9492081444490C072BE8511B3C961AAAC80477897B54BDABE78C533F2E149FA64B51936E31F126625566CAFBB57E9F36CE0DF72A45E61AB27B6D25DEA3BA35910E16BB00AD300CEE2535CE75F9411DD43943250B03EBBA60C5C788974F2F695967103045F3A90A587AEFD0613F9C8E10A273DD827A314C75C7DBCE4326191DBCB92020CDB75129BCA032B6FD59D368C3E2404B2832398E40F43ACE284A91DED8812AA23E5B5A1D36AE204C53F1C6EF0E89AD31D1552E70538451847D7332D8FCACB62A1E56C1E5643E4F7AF63C67E082AC95DCB190795FA53522FA046F1919C81A088D7A8A452124E562BE2A702139670E94524D3110B9DFF35AE73F43280600B8304FA2E776089AF2ED929695967998E29A343FF62C4CAD7618222C01735734342FD33284BE9BDA4976DA1BC3B384E6F813FCBDFA3DC57B841515836CB2B37116EB6D417BBE6AEA7604AA915530AD803DF1C13656753C1A5867F4A3AE94BA7347580EE5A6CEBD2F3EB9B7F83E7B74F38995168F08A15A4CDF5702EA9DC907FC45910586D59537582DB1D5F155BF0050866CE3087560F1F44D1F275FD2B422038F9D8643C3BEBA49938D514848AC4F68F4CF44329C7E806B911B0CB7FF0020F3277A3E2B4FF17090D012B641E24D67A962E2FE361504DB014155F074F30F52078CB31DFC51B32746A42EDBF013F9920CFB17D75497E7B
-20180417042601 2 6 100 7679 5 FBED7F3DD7CF86B0A6EEDC1930C6958C3C00695DAF4347560C5AC1AA4B22F4DC76F190D63E230EB0CB4344A370A471F17FFCA8DA3B5B0A903F9D1258370125F6C172F3EC5F56D7B8EBD07B2072C45D6141DA3CDC01C3D95DE279C5FAA1E042651028141085EB68AFAC473600F75F4A373DC234D5405DCE7AB5B5854960ABC550FCEFEE8FD578810201DE6B4A5EF616F0CBF5707466D7ECBFD488EB68AD4B2EAC889BA2B7FEFE19CD8AA2C78F61D5DA08B4BC2738E1997F951A525EEF9F668148996D1ABFD1620F9276D741A46BECC0B7868A54745E0B16589A4AA7B938AF92FCA0FC9BBC193504D7EBFEFFEC996746DC6CAD3C192D724FB51E6228915789FF18314B3EB690359ADED802F35F48EC0D9C85AA1A20A2E5CF6EB795F2CCD03284547688B1B80A07EFC31668D30836C59C958BBBF6C1EE3940CC43A9334289C872302BB70368FDAC1653AF132F3E398E9310159C839E72555FD889E4E3B05E714E44E116804BF3748F62EF46E6A05DEC58A55185E43E2310EC945004AD61945BD2AD923B7B3C69A01C0393C15B6000BF542A55274ACA20B8A6EB96FAF83E27023FE0EA9EE564959A91BE17110176FB10D1A094947A23EFDE15DD093EF477EF798BCA8F5E14F85411242BC9C9492081444490C072BE8511B3C961AAAC80477897B54BDABE78C533F2E149FA64B51936E31F126625566CAFBB57E9F36CE0DF72A45E61AB27B6D25DEA3BA35910E16BB00AD300CEE2535CE75F9411DD43943250B03EBBA60C5C788974F2F695967103045F3A90A587AEFD0613F9C8E10A273DD827A314C75C7DBCE4326191DBCB92020CDB75129BCA032B6FD59D368C3E2404B2832398E40F43ACE284A91DED8812AA23E5B5A1D36AE204C53F1C6EF0E89AD31D1552E70538451847D7332D8FCACB62A1E56C1E5643E4F7AF63C67E082AC95DCB190795FA53522FA046F1919C81A088D7A8A452124E562BE2A702139670E94524D3110B9DFF35AE73F43280600B8304FA2E776089AF2ED929695967998E29A343FF62C4CAD7618222C01735734342FD33284BE9BDA4976DA1BC3B384E6F813FCBDFA3DC57B841515836CB2B37116EB6D417BBE6AEA7604AA915530AD803DF1C13656753C1A5867F4A3AE94BA7347580EE5A6CEBD2F3EB9B7F83E7B74F38995168F08A15A4CDF5702EA9DC907FC45910586D59537582DB1D5F155BF0050866CE3087560F1F44D1F275FD2B422038F9D8643C3BEBA49938D514848AC4F68F4CF44329C7E806B911B0CB7FF0020F3277A3E2B4FF17090D012B641E24D67A962E2FE361504DB014155F074F30F52078CB31DFC51B32746A42EDBF013F9920CFB17D761E7D7F
-20180417230051 2 6 100 7679 5 FBED7F3DD7CF86B0A6EEDC1930C6958C3C00695DAF4347560C5AC1AA4B22F4DC76F190D63E230EB0CB4344A370A471F17FFCA8DA3B5B0A903F9D1258370125F6C172F3EC5F56D7B8EBD07B2072C45D6141DA3CDC01C3D95DE279C5FAA1E042651028141085EB68AFAC473600F75F4A373DC234D5405DCE7AB5B5854960ABC550FCEFEE8FD578810201DE6B4A5EF616F0CBF5707466D7ECBFD488EB68AD4B2EAC889BA2B7FEFE19CD8AA2C78F61D5DA08B4BC2738E1997F951A525EEF9F668148996D1ABFD1620F9276D741A46BECC0B7868A54745E0B16589A4AA7B938AF92FCA0FC9BBC193504D7EBFEFFEC996746DC6CAD3C192D724FB51E6228915789FF18314B3EB690359ADED802F35F48EC0D9C85AA1A20A2E5CF6EB795F2CCD03284547688B1B80A07EFC31668D30836C59C958BBBF6C1EE3940CC43A9334289C872302BB70368FDAC1653AF132F3E398E9310159C839E72555FD889E4E3B05E714E44E116804BF3748F62EF46E6A05DEC58A55185E43E2310EC945004AD61945BD2AD923B7B3C69A01C0393C15B6000BF542A55274ACA20B8A6EB96FAF83E27023FE0EA9EE564959A91BE17110176FB10D1A094947A23EFDE15DD093EF477EF798BCA8F5E14F85411242BC9C9492081444490C072BE8511B3C961AAAC80477897B54BDABE78C533F2E149FA64B51936E31F126625566CAFBB57E9F36CE0DF72A45E61AB27B6D25DEA3BA35910E16BB00AD300CEE2535CE75F9411DD43943250B03EBBA60C5C788974F2F695967103045F3A90A587AEFD0613F9C8E10A273DD827A314C75C7DBCE4326191DBCB92020CDB75129BCA032B6FD59D368C3E2404B2832398E40F43ACE284A91DED8812AA23E5B5A1D36AE204C53F1C6EF0E89AD31D1552E70538451847D7332D8FCACB62A1E56C1E5643E4F7AF63C67E082AC95DCB190795FA53522FA046F1919C81A088D7A8A452124E562BE2A702139670E94524D3110B9DFF35AE73F43280600B8304FA2E776089AF2ED929695967998E29A343FF62C4CAD7618222C01735734342FD33284BE9BDA4976DA1BC3B384E6F813FCBDFA3DC57B841515836CB2B37116EB6D417BBE6AEA7604AA915530AD803DF1C13656753C1A5867F4A3AE94BA7347580EE5A6CEBD2F3EB9B7F83E7B74F38995168F08A15A4CDF5702EA9DC907FC45910586D59537582DB1D5F155BF0050866CE3087560F1F44D1F275FD2B422038F9D8643C3BEBA49938D514848AC4F68F4CF44329C7E806B911B0CB7FF0020F3277A3E2B4FF17090D012B641E24D67A962E2FE361504DB014155F074F30F52078CB31DFC51B32746A42EDBF013F9920CFB17D83ABCCEF
-20180417231044 2 6 100 7679 5 FBED7F3DD7CF86B0A6EEDC1930C6958C3C00695DAF4347560C5AC1AA4B22F4DC76F190D63E230EB0CB4344A370A471F17FFCA8DA3B5B0A903F9D1258370125F6C172F3EC5F56D7B8EBD07B2072C45D6141DA3CDC01C3D95DE279C5FAA1E042651028141085EB68AFAC473600F75F4A373DC234D5405DCE7AB5B5854960ABC550FCEFEE8FD578810201DE6B4A5EF616F0CBF5707466D7ECBFD488EB68AD4B2EAC889BA2B7FEFE19CD8AA2C78F61D5DA08B4BC2738E1997F951A525EEF9F668148996D1ABFD1620F9276D741A46BECC0B7868A54745E0B16589A4AA7B938AF92FCA0FC9BBC193504D7EBFEFFEC996746DC6CAD3C192D724FB51E6228915789FF18314B3EB690359ADED802F35F48EC0D9C85AA1A20A2E5CF6EB795F2CCD03284547688B1B80A07EFC31668D30836C59C958BBBF6C1EE3940CC43A9334289C872302BB70368FDAC1653AF132F3E398E9310159C839E72555FD889E4E3B05E714E44E116804BF3748F62EF46E6A05DEC58A55185E43E2310EC945004AD61945BD2AD923B7B3C69A01C0393C15B6000BF542A55274ACA20B8A6EB96FAF83E27023FE0EA9EE564959A91BE17110176FB10D1A094947A23EFDE15DD093EF477EF798BCA8F5E14F85411242BC9C9492081444490C072BE8511B3C961AAAC80477897B54BDABE78C533F2E149FA64B51936E31F126625566CAFBB57E9F36CE0DF72A45E61AB27B6D25DEA3BA35910E16BB00AD300CEE2535CE75F9411DD43943250B03EBBA60C5C788974F2F695967103045F3A90A587AEFD0613F9C8E10A273DD827A314C75C7DBCE4326191DBCB92020CDB75129BCA032B6FD59D368C3E2404B2832398E40F43ACE284A91DED8812AA23E5B5A1D36AE204C53F1C6EF0E89AD31D1552E70538451847D7332D8FCACB62A1E56C1E5643E4F7AF63C67E082AC95DCB190795FA53522FA046F1919C81A088D7A8A452124E562BE2A702139670E94524D3110B9DFF35AE73F43280600B8304FA2E776089AF2ED929695967998E29A343FF62C4CAD7618222C01735734342FD33284BE9BDA4976DA1BC3B384E6F813FCBDFA3DC57B841515836CB2B37116EB6D417BBE6AEA7604AA915530AD803DF1C13656753C1A5867F4A3AE94BA7347580EE5A6CEBD2F3EB9B7F83E7B74F38995168F08A15A4CDF5702EA9DC907FC45910586D59537582DB1D5F155BF0050866CE3087560F1F44D1F275FD2B422038F9D8643C3BEBA49938D514848AC4F68F4CF44329C7E806B911B0CB7FF0020F3277A3E2B4FF17090D012B641E24D67A962E2FE361504DB014155F074F30F52078CB31DFC51B32746A42EDBF013F9920CFB17D83C22B2F
-20180418011858 2 6 100 7679 2 FBED7F3DD7CF86B0A6EEDC1930C6958C3C00695DAF4347560C5AC1AA4B22F4DC76F190D63E230EB0CB4344A370A471F17FFCA8DA3B5B0A903F9D1258370125F6C172F3EC5F56D7B8EBD07B2072C45D6141DA3CDC01C3D95DE279C5FAA1E042651028141085EB68AFAC473600F75F4A373DC234D5405DCE7AB5B5854960ABC550FCEFEE8FD578810201DE6B4A5EF616F0CBF5707466D7ECBFD488EB68AD4B2EAC889BA2B7FEFE19CD8AA2C78F61D5DA08B4BC2738E1997F951A525EEF9F668148996D1ABFD1620F9276D741A46BECC0B7868A54745E0B16589A4AA7B938AF92FCA0FC9BBC193504D7EBFEFFEC996746DC6CAD3C192D724FB51E6228915789FF18314B3EB690359ADED802F35F48EC0D9C85AA1A20A2E5CF6EB795F2CCD03284547688B1B80A07EFC31668D30836C59C958BBBF6C1EE3940CC43A9334289C872302BB70368FDAC1653AF132F3E398E9310159C839E72555FD889E4E3B05E714E44E116804BF3748F62EF46E6A05DEC58A55185E43E2310EC945004AD61945BD2AD923B7B3C69A01C0393C15B6000BF542A55274ACA20B8A6EB96FAF83E27023FE0EA9EE564959A91BE17110176FB10D1A094947A23EFDE15DD093EF477EF798BCA8F5E14F85411242BC9C9492081444490C072BE8511B3C961AAAC80477897B54BDABE78C533F2E149FA64B51936E31F126625566CAFBB57E9F36CE0DF72A45E61AB27B6D25DEA3BA35910E16BB00AD300CEE2535CE75F9411DD43943250B03EBBA60C5C788974F2F695967103045F3A90A587AEFD0613F9C8E10A273DD827A314C75C7DBCE4326191DBCB92020CDB75129BCA032B6FD59D368C3E2404B2832398E40F43ACE284A91DED8812AA23E5B5A1D36AE204C53F1C6EF0E89AD31D1552E70538451847D7332D8FCACB62A1E56C1E5643E4F7AF63C67E082AC95DCB190795FA53522FA046F1919C81A088D7A8A452124E562BE2A702139670E94524D3110B9DFF35AE73F43280600B8304FA2E776089AF2ED929695967998E29A343FF62C4CAD7618222C01735734342FD33284BE9BDA4976DA1BC3B384E6F813FCBDFA3DC57B841515836CB2B37116EB6D417BBE6AEA7604AA915530AD803DF1C13656753C1A5867F4A3AE94BA7347580EE5A6CEBD2F3EB9B7F83E7B74F38995168F08A15A4CDF5702EA9DC907FC45910586D59537582DB1D5F155BF0050866CE3087560F1F44D1F275FD2B422038F9D8643C3BEBA49938D514848AC4F68F4CF44329C7E806B911B0CB7FF0020F3277A3E2B4FF17090D012B641E24D67A962E2FE361504DB014155F074F30F52078CB31DFC51B32746A42EDBF013F9920CFB17D8545B2B3
-20180418054538 2 6 100 7679 2 ECCC9B93ED119552D36A774B288F541A81536A13B8D687B23174D680CE3F21B8FA088685F5B965215AFA69736E741A3AFC2AC82CE16162A1E4F0012F28998A638AA98D0789D6C58D92F207EAAA33E467C801891B8D37651B66E0942CF6AB7FD8E0D09A6D597D582BA48563F1450C3300218874730D26EE8B6505059C95C1C764D5FD736BF0A64FAD10F0C7D52A8A57C3FBD653887AAA890DA7AFEDA55DAF702EFF06CC722D147DAA2C8B78F0707F51D2B326BEF8972F5A289829E998B94D98E0ED663143797B569F3A6B56897B5726A38B042806FDFDAA367A4F63C4BA31114300B6290828321C30B25DF97F273041E30A404836E84BB32E0620DC558047FC011A1205126F84D9F8EA5E607FC297E5C9FA00D803026D8126C08EF68B49F6A6C55DCB06EED0B666880CD49FCBFF598055D5E40303669CBC55D85F583DA5EF4F320D6E6A50ECBBFAF8C1F7209655EEAA58BFC18EB9FA20B29EC63FBC810C3A2EDCF8E27FD98975C87D59D9C909895AA10CEA5F7594ADD3ED1EBDFE01BE0559423475592A0E2936E4671504337221F897AE3016BC4670C6B765F5FF1185933B26B1183BCB1E5591970F40A1402EB19EF2644E941F67ABB31935259308B4A5271541F41653EB5E77CCA82214C9C6F4E42E8A3C46CC9BE15BC868BC45B28027E515A16554B9D4F6AB57CFFE42CFE0B42BF83E53F27B39AD95E000C329F716E51D15D6CD211E87AAA83A0F1175F5E1E8963A57DA656FBC19FB42661F14328B05CA7F1A83F49044A5086E6AF56225B8783450E43CB1B6F19061441AF58053BBFAACBC3A80FF5F19A8BD873F487A8FFE3DECD35E77EB2C26387EF66A3EED98C773211914115AFD0776FDAC90CB65479DFE59C0D199F195BBE9E4B2F70A9B1A41429002C2998FAB0F2D6956731819D9F5175B92FECE43178BC69ABEC6E2C18EA88289C5B14C58227640D02F614A9A881633816B9DCAC79E4721EF6E42691902AD1CF565600BAA8019310CAA0AC1087A86846C2E9B96B82C3F0CE52EE73760111061EF090DCBF47882710302A65FBDCF380F84703FE3D4FF7ADD0CB7ED65C889DD6EEC24D01F92771DF3F3D8DFB4BDE234D4A35AB20B22BF5D749398C9B6AE5C7B62DC11ACD887A49586238F5B6D37B47EA6953C3E339A9B40EF3EB01DD70F69253BA9A262777C75DF175195D172BD8233FC7B6F207154EF6E2F47533E359D24EB312A292C756C34A2D55A16452829DAD7A9731E2026E56486F6A3C07380DCA1AFFF270464DA8FF34621FBA715C5853EB1D4EA1C4E23B43CD1CDE1F252B728875F187626A813B4166CC34A62A5D6867E0B605641CEE8025F0AD73DBE4443286CA00823770B
-20180418071157 2 6 100 7679 2 ECCC9B93ED119552D36A774B288F541A81536A13B8D687B23174D680CE3F21B8FA088685F5B965215AFA69736E741A3AFC2AC82CE16162A1E4F0012F28998A638AA98D0789D6C58D92F207EAAA33E467C801891B8D37651B66E0942CF6AB7FD8E0D09A6D597D582BA48563F1450C3300218874730D26EE8B6505059C95C1C764D5FD736BF0A64FAD10F0C7D52A8A57C3FBD653887AAA890DA7AFEDA55DAF702EFF06CC722D147DAA2C8B78F0707F51D2B326BEF8972F5A289829E998B94D98E0ED663143797B569F3A6B56897B5726A38B042806FDFDAA367A4F63C4BA31114300B6290828321C30B25DF97F273041E30A404836E84BB32E0620DC558047FC011A1205126F84D9F8EA5E607FC297E5C9FA00D803026D8126C08EF68B49F6A6C55DCB06EED0B666880CD49FCBFF598055D5E40303669CBC55D85F583DA5EF4F320D6E6A50ECBBFAF8C1F7209655EEAA58BFC18EB9FA20B29EC63FBC810C3A2EDCF8E27FD98975C87D59D9C909895AA10CEA5F7594ADD3ED1EBDFE01BE0559423475592A0E2936E4671504337221F897AE3016BC4670C6B765F5FF1185933B26B1183BCB1E5591970F40A1402EB19EF2644E941F67ABB31935259308B4A5271541F41653EB5E77CCA82214C9C6F4E42E8A3C46CC9BE15BC868BC45B28027E515A16554B9D4F6AB57CFFE42CFE0B42BF83E53F27B39AD95E000C329F716E51D15D6CD211E87AAA83A0F1175F5E1E8963A57DA656FBC19FB42661F14328B05CA7F1A83F49044A5086E6AF56225B8783450E43CB1B6F19061441AF58053BBFAACBC3A80FF5F19A8BD873F487A8FFE3DECD35E77EB2C26387EF66A3EED98C773211914115AFD0776FDAC90CB65479DFE59C0D199F195BBE9E4B2F70A9B1A41429002C2998FAB0F2D6956731819D9F5175B92FECE43178BC69ABEC6E2C18EA88289C5B14C58227640D02F614A9A881633816B9DCAC79E4721EF6E42691902AD1CF565600BAA8019310CAA0AC1087A86846C2E9B96B82C3F0CE52EE73760111061EF090DCBF47882710302A65FBDCF380F84703FE3D4FF7ADD0CB7ED65C889DD6EEC24D01F92771DF3F3D8DFB4BDE234D4A35AB20B22BF5D749398C9B6AE5C7B62DC11ACD887A49586238F5B6D37B47EA6953C3E339A9B40EF3EB01DD70F69253BA9A262777C75DF175195D172BD8233FC7B6F207154EF6E2F47533E359D24EB312A292C756C34A2D55A16452829DAD7A9731E2026E56486F6A3C07380DCA1AFFF270464DA8FF34621FBA715C5853EB1D4EA1C4E23B43CD1CDE1F252B728875F187626A813B4166CC34A62A5D6867E0B605641CEE8025F0AD73DBE4443286CA00950BDC3
-20180418085254 2 6 100 7679 2 ECCC9B93ED119552D36A774B288F541A81536A13B8D687B23174D680CE3F21B8FA088685F5B965215AFA69736E741A3AFC2AC82CE16162A1E4F0012F28998A638AA98D0789D6C58D92F207EAAA33E467C801891B8D37651B66E0942CF6AB7FD8E0D09A6D597D582BA48563F1450C3300218874730D26EE8B6505059C95C1C764D5FD736BF0A64FAD10F0C7D52A8A57C3FBD653887AAA890DA7AFEDA55DAF702EFF06CC722D147DAA2C8B78F0707F51D2B326BEF8972F5A289829E998B94D98E0ED663143797B569F3A6B56897B5726A38B042806FDFDAA367A4F63C4BA31114300B6290828321C30B25DF97F273041E30A404836E84BB32E0620DC558047FC011A1205126F84D9F8EA5E607FC297E5C9FA00D803026D8126C08EF68B49F6A6C55DCB06EED0B666880CD49FCBFF598055D5E40303669CBC55D85F583DA5EF4F320D6E6A50ECBBFAF8C1F7209655EEAA58BFC18EB9FA20B29EC63FBC810C3A2EDCF8E27FD98975C87D59D9C909895AA10CEA5F7594ADD3ED1EBDFE01BE0559423475592A0E2936E4671504337221F897AE3016BC4670C6B765F5FF1185933B26B1183BCB1E5591970F40A1402EB19EF2644E941F67ABB31935259308B4A5271541F41653EB5E77CCA82214C9C6F4E42E8A3C46CC9BE15BC868BC45B28027E515A16554B9D4F6AB57CFFE42CFE0B42BF83E53F27B39AD95E000C329F716E51D15D6CD211E87AAA83A0F1175F5E1E8963A57DA656FBC19FB42661F14328B05CA7F1A83F49044A5086E6AF56225B8783450E43CB1B6F19061441AF58053BBFAACBC3A80FF5F19A8BD873F487A8FFE3DECD35E77EB2C26387EF66A3EED98C773211914115AFD0776FDAC90CB65479DFE59C0D199F195BBE9E4B2F70A9B1A41429002C2998FAB0F2D6956731819D9F5175B92FECE43178BC69ABEC6E2C18EA88289C5B14C58227640D02F614A9A881633816B9DCAC79E4721EF6E42691902AD1CF565600BAA8019310CAA0AC1087A86846C2E9B96B82C3F0CE52EE73760111061EF090DCBF47882710302A65FBDCF380F84703FE3D4FF7ADD0CB7ED65C889DD6EEC24D01F92771DF3F3D8DFB4BDE234D4A35AB20B22BF5D749398C9B6AE5C7B62DC11ACD887A49586238F5B6D37B47EA6953C3E339A9B40EF3EB01DD70F69253BA9A262777C75DF175195D172BD8233FC7B6F207154EF6E2F47533E359D24EB312A292C756C34A2D55A16452829DAD7A9731E2026E56486F6A3C07380DCA1AFFF270464DA8FF34621FBA715C5853EB1D4EA1C4E23B43CD1CDE1F252B728875F187626A813B4166CC34A62A5D6867E0B605641CEE8025F0AD73DBE4443286CA00AAFBDDB
-20180418174929 2 6 100 7679 2 ECCC9B93ED119552D36A774B288F541A81536A13B8D687B23174D680CE3F21B8FA088685F5B965215AFA69736E741A3AFC2AC82CE16162A1E4F0012F28998A638AA98D0789D6C58D92F207EAAA33E467C801891B8D37651B66E0942CF6AB7FD8E0D09A6D597D582BA48563F1450C3300218874730D26EE8B6505059C95C1C764D5FD736BF0A64FAD10F0C7D52A8A57C3FBD653887AAA890DA7AFEDA55DAF702EFF06CC722D147DAA2C8B78F0707F51D2B326BEF8972F5A289829E998B94D98E0ED663143797B569F3A6B56897B5726A38B042806FDFDAA367A4F63C4BA31114300B6290828321C30B25DF97F273041E30A404836E84BB32E0620DC558047FC011A1205126F84D9F8EA5E607FC297E5C9FA00D803026D8126C08EF68B49F6A6C55DCB06EED0B666880CD49FCBFF598055D5E40303669CBC55D85F583DA5EF4F320D6E6A50ECBBFAF8C1F7209655EEAA58BFC18EB9FA20B29EC63FBC810C3A2EDCF8E27FD98975C87D59D9C909895AA10CEA5F7594ADD3ED1EBDFE01BE0559423475592A0E2936E4671504337221F897AE3016BC4670C6B765F5FF1185933B26B1183BCB1E5591970F40A1402EB19EF2644E941F67ABB31935259308B4A5271541F41653EB5E77CCA82214C9C6F4E42E8A3C46CC9BE15BC868BC45B28027E515A16554B9D4F6AB57CFFE42CFE0B42BF83E53F27B39AD95E000C329F716E51D15D6CD211E87AAA83A0F1175F5E1E8963A57DA656FBC19FB42661F14328B05CA7F1A83F49044A5086E6AF56225B8783450E43CB1B6F19061441AF58053BBFAACBC3A80FF5F19A8BD873F487A8FFE3DECD35E77EB2C26387EF66A3EED98C773211914115AFD0776FDAC90CB65479DFE59C0D199F195BBE9E4B2F70A9B1A41429002C2998FAB0F2D6956731819D9F5175B92FECE43178BC69ABEC6E2C18EA88289C5B14C58227640D02F614A9A881633816B9DCAC79E4721EF6E42691902AD1CF565600BAA8019310CAA0AC1087A86846C2E9B96B82C3F0CE52EE73760111061EF090DCBF47882710302A65FBDCF380F84703FE3D4FF7ADD0CB7ED65C889DD6EEC24D01F92771DF3F3D8DFB4BDE234D4A35AB20B22BF5D749398C9B6AE5C7B62DC11ACD887A49586238F5B6D37B47EA6953C3E339A9B40EF3EB01DD70F69253BA9A262777C75DF175195D172BD8233FC7B6F207154EF6E2F47533E359D24EB312A292C756C34A2D55A16452829DAD7A9731E2026E56486F6A3C07380DCA1AFFF270464DA8FF34621FBA715C5853EB1D4EA1C4E23B43CD1CDE1F252B728875F187626A813B4166CC34A62A5D6867E0B605641CEE8025F0AD73DBE4443286CA01225DA53
-20180418210652 2 6 100 7679 5 ECCC9B93ED119552D36A774B288F541A81536A13B8D687B23174D680CE3F21B8FA088685F5B965215AFA69736E741A3AFC2AC82CE16162A1E4F0012F28998A638AA98D0789D6C58D92F207EAAA33E467C801891B8D37651B66E0942CF6AB7FD8E0D09A6D597D582BA48563F1450C3300218874730D26EE8B6505059C95C1C764D5FD736BF0A64FAD10F0C7D52A8A57C3FBD653887AAA890DA7AFEDA55DAF702EFF06CC722D147DAA2C8B78F0707F51D2B326BEF8972F5A289829E998B94D98E0ED663143797B569F3A6B56897B5726A38B042806FDFDAA367A4F63C4BA31114300B6290828321C30B25DF97F273041E30A404836E84BB32E0620DC558047FC011A1205126F84D9F8EA5E607FC297E5C9FA00D803026D8126C08EF68B49F6A6C55DCB06EED0B666880CD49FCBFF598055D5E40303669CBC55D85F583DA5EF4F320D6E6A50ECBBFAF8C1F7209655EEAA58BFC18EB9FA20B29EC63FBC810C3A2EDCF8E27FD98975C87D59D9C909895AA10CEA5F7594ADD3ED1EBDFE01BE0559423475592A0E2936E4671504337221F897AE3016BC4670C6B765F5FF1185933B26B1183BCB1E5591970F40A1402EB19EF2644E941F67ABB31935259308B4A5271541F41653EB5E77CCA82214C9C6F4E42E8A3C46CC9BE15BC868BC45B28027E515A16554B9D4F6AB57CFFE42CFE0B42BF83E53F27B39AD95E000C329F716E51D15D6CD211E87AAA83A0F1175F5E1E8963A57DA656FBC19FB42661F14328B05CA7F1A83F49044A5086E6AF56225B8783450E43CB1B6F19061441AF58053BBFAACBC3A80FF5F19A8BD873F487A8FFE3DECD35E77EB2C26387EF66A3EED98C773211914115AFD0776FDAC90CB65479DFE59C0D199F195BBE9E4B2F70A9B1A41429002C2998FAB0F2D6956731819D9F5175B92FECE43178BC69ABEC6E2C18EA88289C5B14C58227640D02F614A9A881633816B9DCAC79E4721EF6E42691902AD1CF565600BAA8019310CAA0AC1087A86846C2E9B96B82C3F0CE52EE73760111061EF090DCBF47882710302A65FBDCF380F84703FE3D4FF7ADD0CB7ED65C889DD6EEC24D01F92771DF3F3D8DFB4BDE234D4A35AB20B22BF5D749398C9B6AE5C7B62DC11ACD887A49586238F5B6D37B47EA6953C3E339A9B40EF3EB01DD70F69253BA9A262777C75DF175195D172BD8233FC7B6F207154EF6E2F47533E359D24EB312A292C756C34A2D55A16452829DAD7A9731E2026E56486F6A3C07380DCA1AFFF270464DA8FF34621FBA715C5853EB1D4EA1C4E23B43CD1CDE1F252B728875F187626A813B4166CC34A62A5D6867E0B605641CEE8025F0AD73DBE4443286CA014D6E5DF
-20180418211238 2 6 100 7679 2 ECCC9B93ED119552D36A774B288F541A81536A13B8D687B23174D680CE3F21B8FA088685F5B965215AFA69736E741A3AFC2AC82CE16162A1E4F0012F28998A638AA98D0789D6C58D92F207EAAA33E467C801891B8D37651B66E0942CF6AB7FD8E0D09A6D597D582BA48563F1450C3300218874730D26EE8B6505059C95C1C764D5FD736BF0A64FAD10F0C7D52A8A57C3FBD653887AAA890DA7AFEDA55DAF702EFF06CC722D147DAA2C8B78F0707F51D2B326BEF8972F5A289829E998B94D98E0ED663143797B569F3A6B56897B5726A38B042806FDFDAA367A4F63C4BA31114300B6290828321C30B25DF97F273041E30A404836E84BB32E0620DC558047FC011A1205126F84D9F8EA5E607FC297E5C9FA00D803026D8126C08EF68B49F6A6C55DCB06EED0B666880CD49FCBFF598055D5E40303669CBC55D85F583DA5EF4F320D6E6A50ECBBFAF8C1F7209655EEAA58BFC18EB9FA20B29EC63FBC810C3A2EDCF8E27FD98975C87D59D9C909895AA10CEA5F7594ADD3ED1EBDFE01BE0559423475592A0E2936E4671504337221F897AE3016BC4670C6B765F5FF1185933B26B1183BCB1E5591970F40A1402EB19EF2644E941F67ABB31935259308B4A5271541F41653EB5E77CCA82214C9C6F4E42E8A3C46CC9BE15BC868BC45B28027E515A16554B9D4F6AB57CFFE42CFE0B42BF83E53F27B39AD95E000C329F716E51D15D6CD211E87AAA83A0F1175F5E1E8963A57DA656FBC19FB42661F14328B05CA7F1A83F49044A5086E6AF56225B8783450E43CB1B6F19061441AF58053BBFAACBC3A80FF5F19A8BD873F487A8FFE3DECD35E77EB2C26387EF66A3EED98C773211914115AFD0776FDAC90CB65479DFE59C0D199F195BBE9E4B2F70A9B1A41429002C2998FAB0F2D6956731819D9F5175B92FECE43178BC69ABEC6E2C18EA88289C5B14C58227640D02F614A9A881633816B9DCAC79E4721EF6E42691902AD1CF565600BAA8019310CAA0AC1087A86846C2E9B96B82C3F0CE52EE73760111061EF090DCBF47882710302A65FBDCF380F84703FE3D4FF7ADD0CB7ED65C889DD6EEC24D01F92771DF3F3D8DFB4BDE234D4A35AB20B22BF5D749398C9B6AE5C7B62DC11ACD887A49586238F5B6D37B47EA6953C3E339A9B40EF3EB01DD70F69253BA9A262777C75DF175195D172BD8233FC7B6F207154EF6E2F47533E359D24EB312A292C756C34A2D55A16452829DAD7A9731E2026E56486F6A3C07380DCA1AFFF270464DA8FF34621FBA715C5853EB1D4EA1C4E23B43CD1CDE1F252B728875F187626A813B4166CC34A62A5D6867E0B605641CEE8025F0AD73DBE4443286CA014E1D75B
-20180418224228 2 6 100 7679 2 ECCC9B93ED119552D36A774B288F541A81536A13B8D687B23174D680CE3F21B8FA088685F5B965215AFA69736E741A3AFC2AC82CE16162A1E4F0012F28998A638AA98D0789D6C58D92F207EAAA33E467C801891B8D37651B66E0942CF6AB7FD8E0D09A6D597D582BA48563F1450C3300218874730D26EE8B6505059C95C1C764D5FD736BF0A64FAD10F0C7D52A8A57C3FBD653887AAA890DA7AFEDA55DAF702EFF06CC722D147DAA2C8B78F0707F51D2B326BEF8972F5A289829E998B94D98E0ED663143797B569F3A6B56897B5726A38B042806FDFDAA367A4F63C4BA31114300B6290828321C30B25DF97F273041E30A404836E84BB32E0620DC558047FC011A1205126F84D9F8EA5E607FC297E5C9FA00D803026D8126C08EF68B49F6A6C55DCB06EED0B666880CD49FCBFF598055D5E40303669CBC55D85F583DA5EF4F320D6E6A50ECBBFAF8C1F7209655EEAA58BFC18EB9FA20B29EC63FBC810C3A2EDCF8E27FD98975C87D59D9C909895AA10CEA5F7594ADD3ED1EBDFE01BE0559423475592A0E2936E4671504337221F897AE3016BC4670C6B765F5FF1185933B26B1183BCB1E5591970F40A1402EB19EF2644E941F67ABB31935259308B4A5271541F41653EB5E77CCA82214C9C6F4E42E8A3C46CC9BE15BC868BC45B28027E515A16554B9D4F6AB57CFFE42CFE0B42BF83E53F27B39AD95E000C329F716E51D15D6CD211E87AAA83A0F1175F5E1E8963A57DA656FBC19FB42661F14328B05CA7F1A83F49044A5086E6AF56225B8783450E43CB1B6F19061441AF58053BBFAACBC3A80FF5F19A8BD873F487A8FFE3DECD35E77EB2C26387EF66A3EED98C773211914115AFD0776FDAC90CB65479DFE59C0D199F195BBE9E4B2F70A9B1A41429002C2998FAB0F2D6956731819D9F5175B92FECE43178BC69ABEC6E2C18EA88289C5B14C58227640D02F614A9A881633816B9DCAC79E4721EF6E42691902AD1CF565600BAA8019310CAA0AC1087A86846C2E9B96B82C3F0CE52EE73760111061EF090DCBF47882710302A65FBDCF380F84703FE3D4FF7ADD0CB7ED65C889DD6EEC24D01F92771DF3F3D8DFB4BDE234D4A35AB20B22BF5D749398C9B6AE5C7B62DC11ACD887A49586238F5B6D37B47EA6953C3E339A9B40EF3EB01DD70F69253BA9A262777C75DF175195D172BD8233FC7B6F207154EF6E2F47533E359D24EB312A292C756C34A2D55A16452829DAD7A9731E2026E56486F6A3C07380DCA1AFFF270464DA8FF34621FBA715C5853EB1D4EA1C4E23B43CD1CDE1F252B728875F187626A813B4166CC34A62A5D6867E0B605641CEE8025F0AD73DBE4443286CA016133603
-20180418233547 2 6 100 7679 5 ECCC9B93ED119552D36A774B288F541A81536A13B8D687B23174D680CE3F21B8FA088685F5B965215AFA69736E741A3AFC2AC82CE16162A1E4F0012F28998A638AA98D0789D6C58D92F207EAAA33E467C801891B8D37651B66E0942CF6AB7FD8E0D09A6D597D582BA48563F1450C3300218874730D26EE8B6505059C95C1C764D5FD736BF0A64FAD10F0C7D52A8A57C3FBD653887AAA890DA7AFEDA55DAF702EFF06CC722D147DAA2C8B78F0707F51D2B326BEF8972F5A289829E998B94D98E0ED663143797B569F3A6B56897B5726A38B042806FDFDAA367A4F63C4BA31114300B6290828321C30B25DF97F273041E30A404836E84BB32E0620DC558047FC011A1205126F84D9F8EA5E607FC297E5C9FA00D803026D8126C08EF68B49F6A6C55DCB06EED0B666880CD49FCBFF598055D5E40303669CBC55D85F583DA5EF4F320D6E6A50ECBBFAF8C1F7209655EEAA58BFC18EB9FA20B29EC63FBC810C3A2EDCF8E27FD98975C87D59D9C909895AA10CEA5F7594ADD3ED1EBDFE01BE0559423475592A0E2936E4671504337221F897AE3016BC4670C6B765F5FF1185933B26B1183BCB1E5591970F40A1402EB19EF2644E941F67ABB31935259308B4A5271541F41653EB5E77CCA82214C9C6F4E42E8A3C46CC9BE15BC868BC45B28027E515A16554B9D4F6AB57CFFE42CFE0B42BF83E53F27B39AD95E000C329F716E51D15D6CD211E87AAA83A0F1175F5E1E8963A57DA656FBC19FB42661F14328B05CA7F1A83F49044A5086E6AF56225B8783450E43CB1B6F19061441AF58053BBFAACBC3A80FF5F19A8BD873F487A8FFE3DECD35E77EB2C26387EF66A3EED98C773211914115AFD0776FDAC90CB65479DFE59C0D199F195BBE9E4B2F70A9B1A41429002C2998FAB0F2D6956731819D9F5175B92FECE43178BC69ABEC6E2C18EA88289C5B14C58227640D02F614A9A881633816B9DCAC79E4721EF6E42691902AD1CF565600BAA8019310CAA0AC1087A86846C2E9B96B82C3F0CE52EE73760111061EF090DCBF47882710302A65FBDCF380F84703FE3D4FF7ADD0CB7ED65C889DD6EEC24D01F92771DF3F3D8DFB4BDE234D4A35AB20B22BF5D749398C9B6AE5C7B62DC11ACD887A49586238F5B6D37B47EA6953C3E339A9B40EF3EB01DD70F69253BA9A262777C75DF175195D172BD8233FC7B6F207154EF6E2F47533E359D24EB312A292C756C34A2D55A16452829DAD7A9731E2026E56486F6A3C07380DCA1AFFF270464DA8FF34621FBA715C5853EB1D4EA1C4E23B43CD1CDE1F252B728875F187626A813B4166CC34A62A5D6867E0B605641CEE8025F0AD73DBE4443286CA016C53D1F
-20180419053435 2 6 100 7679 2 ECCC9B93ED119552D36A774B288F541A81536A13B8D687B23174D680CE3F21B8FA088685F5B965215AFA69736E741A3AFC2AC82CE16162A1E4F0012F28998A638AA98D0789D6C58D92F207EAAA33E467C801891B8D37651B66E0942CF6AB7FD8E0D09A6D597D582BA48563F1450C3300218874730D26EE8B6505059C95C1C764D5FD736BF0A64FAD10F0C7D52A8A57C3FBD653887AAA890DA7AFEDA55DAF702EFF06CC722D147DAA2C8B78F0707F51D2B326BEF8972F5A289829E998B94D98E0ED663143797B569F3A6B56897B5726A38B042806FDFDAA367A4F63C4BA31114300B6290828321C30B25DF97F273041E30A404836E84BB32E0620DC558047FC011A1205126F84D9F8EA5E607FC297E5C9FA00D803026D8126C08EF68B49F6A6C55DCB06EED0B666880CD49FCBFF598055D5E40303669CBC55D85F583DA5EF4F320D6E6A50ECBBFAF8C1F7209655EEAA58BFC18EB9FA20B29EC63FBC810C3A2EDCF8E27FD98975C87D59D9C909895AA10CEA5F7594ADD3ED1EBDFE01BE0559423475592A0E2936E4671504337221F897AE3016BC4670C6B765F5FF1185933B26B1183BCB1E5591970F40A1402EB19EF2644E941F67ABB31935259308B4A5271541F41653EB5E77CCA82214C9C6F4E42E8A3C46CC9BE15BC868BC45B28027E515A16554B9D4F6AB57CFFE42CFE0B42BF83E53F27B39AD95E000C329F716E51D15D6CD211E87AAA83A0F1175F5E1E8963A57DA656FBC19FB42661F14328B05CA7F1A83F49044A5086E6AF56225B8783450E43CB1B6F19061441AF58053BBFAACBC3A80FF5F19A8BD873F487A8FFE3DECD35E77EB2C26387EF66A3EED98C773211914115AFD0776FDAC90CB65479DFE59C0D199F195BBE9E4B2F70A9B1A41429002C2998FAB0F2D6956731819D9F5175B92FECE43178BC69ABEC6E2C18EA88289C5B14C58227640D02F614A9A881633816B9DCAC79E4721EF6E42691902AD1CF565600BAA8019310CAA0AC1087A86846C2E9B96B82C3F0CE52EE73760111061EF090DCBF47882710302A65FBDCF380F84703FE3D4FF7ADD0CB7ED65C889DD6EEC24D01F92771DF3F3D8DFB4BDE234D4A35AB20B22BF5D749398C9B6AE5C7B62DC11ACD887A49586238F5B6D37B47EA6953C3E339A9B40EF3EB01DD70F69253BA9A262777C75DF175195D172BD8233FC7B6F207154EF6E2F47533E359D24EB312A292C756C34A2D55A16452829DAD7A9731E2026E56486F6A3C07380DCA1AFFF270464DA8FF34621FBA715C5853EB1D4EA1C4E23B43CD1CDE1F252B728875F187626A813B4166CC34A62A5D6867E0B605641CEE8025F0AD73DBE4443286CA01B7B0413
-20180419055744 2 6 100 7679 2 ECCC9B93ED119552D36A774B288F541A81536A13B8D687B23174D680CE3F21B8FA088685F5B965215AFA69736E741A3AFC2AC82CE16162A1E4F0012F28998A638AA98D0789D6C58D92F207EAAA33E467C801891B8D37651B66E0942CF6AB7FD8E0D09A6D597D582BA48563F1450C3300218874730D26EE8B6505059C95C1C764D5FD736BF0A64FAD10F0C7D52A8A57C3FBD653887AAA890DA7AFEDA55DAF702EFF06CC722D147DAA2C8B78F0707F51D2B326BEF8972F5A289829E998B94D98E0ED663143797B569F3A6B56897B5726A38B042806FDFDAA367A4F63C4BA31114300B6290828321C30B25DF97F273041E30A404836E84BB32E0620DC558047FC011A1205126F84D9F8EA5E607FC297E5C9FA00D803026D8126C08EF68B49F6A6C55DCB06EED0B666880CD49FCBFF598055D5E40303669CBC55D85F583DA5EF4F320D6E6A50ECBBFAF8C1F7209655EEAA58BFC18EB9FA20B29EC63FBC810C3A2EDCF8E27FD98975C87D59D9C909895AA10CEA5F7594ADD3ED1EBDFE01BE0559423475592A0E2936E4671504337221F897AE3016BC4670C6B765F5FF1185933B26B1183BCB1E5591970F40A1402EB19EF2644E941F67ABB31935259308B4A5271541F41653EB5E77CCA82214C9C6F4E42E8A3C46CC9BE15BC868BC45B28027E515A16554B9D4F6AB57CFFE42CFE0B42BF83E53F27B39AD95E000C329F716E51D15D6CD211E87AAA83A0F1175F5E1E8963A57DA656FBC19FB42661F14328B05CA7F1A83F49044A5086E6AF56225B8783450E43CB1B6F19061441AF58053BBFAACBC3A80FF5F19A8BD873F487A8FFE3DECD35E77EB2C26387EF66A3EED98C773211914115AFD0776FDAC90CB65479DFE59C0D199F195BBE9E4B2F70A9B1A41429002C2998FAB0F2D6956731819D9F5175B92FECE43178BC69ABEC6E2C18EA88289C5B14C58227640D02F614A9A881633816B9DCAC79E4721EF6E42691902AD1CF565600BAA8019310CAA0AC1087A86846C2E9B96B82C3F0CE52EE73760111061EF090DCBF47882710302A65FBDCF380F84703FE3D4FF7ADD0CB7ED65C889DD6EEC24D01F92771DF3F3D8DFB4BDE234D4A35AB20B22BF5D749398C9B6AE5C7B62DC11ACD887A49586238F5B6D37B47EA6953C3E339A9B40EF3EB01DD70F69253BA9A262777C75DF175195D172BD8233FC7B6F207154EF6E2F47533E359D24EB312A292C756C34A2D55A16452829DAD7A9731E2026E56486F6A3C07380DCA1AFFF270464DA8FF34621FBA715C5853EB1D4EA1C4E23B43CD1CDE1F252B728875F187626A813B4166CC34A62A5D6867E0B605641CEE8025F0AD73DBE4443286CA01BC212DB
-20180419135850 2 6 100 7679 2 ECCC9B93ED119552D36A774B288F541A81536A13B8D687B23174D680CE3F21B8FA088685F5B965215AFA69736E741A3AFC2AC82CE16162A1E4F0012F28998A638AA98D0789D6C58D92F207EAAA33E467C801891B8D37651B66E0942CF6AB7FD8E0D09A6D597D582BA48563F1450C3300218874730D26EE8B6505059C95C1C764D5FD736BF0A64FAD10F0C7D52A8A57C3FBD653887AAA890DA7AFEDA55DAF702EFF06CC722D147DAA2C8B78F0707F51D2B326BEF8972F5A289829E998B94D98E0ED663143797B569F3A6B56897B5726A38B042806FDFDAA367A4F63C4BA31114300B6290828321C30B25DF97F273041E30A404836E84BB32E0620DC558047FC011A1205126F84D9F8EA5E607FC297E5C9FA00D803026D8126C08EF68B49F6A6C55DCB06EED0B666880CD49FCBFF598055D5E40303669CBC55D85F583DA5EF4F320D6E6A50ECBBFAF8C1F7209655EEAA58BFC18EB9FA20B29EC63FBC810C3A2EDCF8E27FD98975C87D59D9C909895AA10CEA5F7594ADD3ED1EBDFE01BE0559423475592A0E2936E4671504337221F897AE3016BC4670C6B765F5FF1185933B26B1183BCB1E5591970F40A1402EB19EF2644E941F67ABB31935259308B4A5271541F41653EB5E77CCA82214C9C6F4E42E8A3C46CC9BE15BC868BC45B28027E515A16554B9D4F6AB57CFFE42CFE0B42BF83E53F27B39AD95E000C329F716E51D15D6CD211E87AAA83A0F1175F5E1E8963A57DA656FBC19FB42661F14328B05CA7F1A83F49044A5086E6AF56225B8783450E43CB1B6F19061441AF58053BBFAACBC3A80FF5F19A8BD873F487A8FFE3DECD35E77EB2C26387EF66A3EED98C773211914115AFD0776FDAC90CB65479DFE59C0D199F195BBE9E4B2F70A9B1A41429002C2998FAB0F2D6956731819D9F5175B92FECE43178BC69ABEC6E2C18EA88289C5B14C58227640D02F614A9A881633816B9DCAC79E4721EF6E42691902AD1CF565600BAA8019310CAA0AC1087A86846C2E9B96B82C3F0CE52EE73760111061EF090DCBF47882710302A65FBDCF380F84703FE3D4FF7ADD0CB7ED65C889DD6EEC24D01F92771DF3F3D8DFB4BDE234D4A35AB20B22BF5D749398C9B6AE5C7B62DC11ACD887A49586238F5B6D37B47EA6953C3E339A9B40EF3EB01DD70F69253BA9A262777C75DF175195D172BD8233FC7B6F207154EF6E2F47533E359D24EB312A292C756C34A2D55A16452829DAD7A9731E2026E56486F6A3C07380DCA1AFFF270464DA8FF34621FBA715C5853EB1D4EA1C4E23B43CD1CDE1F252B728875F187626A813B4166CC34A62A5D6867E0B605641CEE8025F0AD73DBE4443286CA022362F53
-20180419162659 2 6 100 7679 2 ECCC9B93ED119552D36A774B288F541A81536A13B8D687B23174D680CE3F21B8FA088685F5B965215AFA69736E741A3AFC2AC82CE16162A1E4F0012F28998A638AA98D0789D6C58D92F207EAAA33E467C801891B8D37651B66E0942CF6AB7FD8E0D09A6D597D582BA48563F1450C3300218874730D26EE8B6505059C95C1C764D5FD736BF0A64FAD10F0C7D52A8A57C3FBD653887AAA890DA7AFEDA55DAF702EFF06CC722D147DAA2C8B78F0707F51D2B326BEF8972F5A289829E998B94D98E0ED663143797B569F3A6B56897B5726A38B042806FDFDAA367A4F63C4BA31114300B6290828321C30B25DF97F273041E30A404836E84BB32E0620DC558047FC011A1205126F84D9F8EA5E607FC297E5C9FA00D803026D8126C08EF68B49F6A6C55DCB06EED0B666880CD49FCBFF598055D5E40303669CBC55D85F583DA5EF4F320D6E6A50ECBBFAF8C1F7209655EEAA58BFC18EB9FA20B29EC63FBC810C3A2EDCF8E27FD98975C87D59D9C909895AA10CEA5F7594ADD3ED1EBDFE01BE0559423475592A0E2936E4671504337221F897AE3016BC4670C6B765F5FF1185933B26B1183BCB1E5591970F40A1402EB19EF2644E941F67ABB31935259308B4A5271541F41653EB5E77CCA82214C9C6F4E42E8A3C46CC9BE15BC868BC45B28027E515A16554B9D4F6AB57CFFE42CFE0B42BF83E53F27B39AD95E000C329F716E51D15D6CD211E87AAA83A0F1175F5E1E8963A57DA656FBC19FB42661F14328B05CA7F1A83F49044A5086E6AF56225B8783450E43CB1B6F19061441AF58053BBFAACBC3A80FF5F19A8BD873F487A8FFE3DECD35E77EB2C26387EF66A3EED98C773211914115AFD0776FDAC90CB65479DFE59C0D199F195BBE9E4B2F70A9B1A41429002C2998FAB0F2D6956731819D9F5175B92FECE43178BC69ABEC6E2C18EA88289C5B14C58227640D02F614A9A881633816B9DCAC79E4721EF6E42691902AD1CF565600BAA8019310CAA0AC1087A86846C2E9B96B82C3F0CE52EE73760111061EF090DCBF47882710302A65FBDCF380F84703FE3D4FF7ADD0CB7ED65C889DD6EEC24D01F92771DF3F3D8DFB4BDE234D4A35AB20B22BF5D749398C9B6AE5C7B62DC11ACD887A49586238F5B6D37B47EA6953C3E339A9B40EF3EB01DD70F69253BA9A262777C75DF175195D172BD8233FC7B6F207154EF6E2F47533E359D24EB312A292C756C34A2D55A16452829DAD7A9731E2026E56486F6A3C07380DCA1AFFF270464DA8FF34621FBA715C5853EB1D4EA1C4E23B43CD1CDE1F252B728875F187626A813B4166CC34A62A5D6867E0B605641CEE8025F0AD73DBE4443286CA02429C813
-20180419214419 2 6 100 7679 5 ECCC9B93ED119552D36A774B288F541A81536A13B8D687B23174D680CE3F21B8FA088685F5B965215AFA69736E741A3AFC2AC82CE16162A1E4F0012F28998A638AA98D0789D6C58D92F207EAAA33E467C801891B8D37651B66E0942CF6AB7FD8E0D09A6D597D582BA48563F1450C3300218874730D26EE8B6505059C95C1C764D5FD736BF0A64FAD10F0C7D52A8A57C3FBD653887AAA890DA7AFEDA55DAF702EFF06CC722D147DAA2C8B78F0707F51D2B326BEF8972F5A289829E998B94D98E0ED663143797B569F3A6B56897B5726A38B042806FDFDAA367A4F63C4BA31114300B6290828321C30B25DF97F273041E30A404836E84BB32E0620DC558047FC011A1205126F84D9F8EA5E607FC297E5C9FA00D803026D8126C08EF68B49F6A6C55DCB06EED0B666880CD49FCBFF598055D5E40303669CBC55D85F583DA5EF4F320D6E6A50ECBBFAF8C1F7209655EEAA58BFC18EB9FA20B29EC63FBC810C3A2EDCF8E27FD98975C87D59D9C909895AA10CEA5F7594ADD3ED1EBDFE01BE0559423475592A0E2936E4671504337221F897AE3016BC4670C6B765F5FF1185933B26B1183BCB1E5591970F40A1402EB19EF2644E941F67ABB31935259308B4A5271541F41653EB5E77CCA82214C9C6F4E42E8A3C46CC9BE15BC868BC45B28027E515A16554B9D4F6AB57CFFE42CFE0B42BF83E53F27B39AD95E000C329F716E51D15D6CD211E87AAA83A0F1175F5E1E8963A57DA656FBC19FB42661F14328B05CA7F1A83F49044A5086E6AF56225B8783450E43CB1B6F19061441AF58053BBFAACBC3A80FF5F19A8BD873F487A8FFE3DECD35E77EB2C26387EF66A3EED98C773211914115AFD0776FDAC90CB65479DFE59C0D199F195BBE9E4B2F70A9B1A41429002C2998FAB0F2D6956731819D9F5175B92FECE43178BC69ABEC6E2C18EA88289C5B14C58227640D02F614A9A881633816B9DCAC79E4721EF6E42691902AD1CF565600BAA8019310CAA0AC1087A86846C2E9B96B82C3F0CE52EE73760111061EF090DCBF47882710302A65FBDCF380F84703FE3D4FF7ADD0CB7ED65C889DD6EEC24D01F92771DF3F3D8DFB4BDE234D4A35AB20B22BF5D749398C9B6AE5C7B62DC11ACD887A49586238F5B6D37B47EA6953C3E339A9B40EF3EB01DD70F69253BA9A262777C75DF175195D172BD8233FC7B6F207154EF6E2F47533E359D24EB312A292C756C34A2D55A16452829DAD7A9731E2026E56486F6A3C07380DCA1AFFF270464DA8FF34621FBA715C5853EB1D4EA1C4E23B43CD1CDE1F252B728875F187626A813B4166CC34A62A5D6867E0B605641CEE8025F0AD73DBE4443286CA0286020EF
-20180420033054 2 6 100 7679 5 ECCC9B93ED119552D36A774B288F541A81536A13B8D687B23174D680CE3F21B8FA088685F5B965215AFA69736E741A3AFC2AC82CE16162A1E4F0012F28998A638AA98D0789D6C58D92F207EAAA33E467C801891B8D37651B66E0942CF6AB7FD8E0D09A6D597D582BA48563F1450C3300218874730D26EE8B6505059C95C1C764D5FD736BF0A64FAD10F0C7D52A8A57C3FBD653887AAA890DA7AFEDA55DAF702EFF06CC722D147DAA2C8B78F0707F51D2B326BEF8972F5A289829E998B94D98E0ED663143797B569F3A6B56897B5726A38B042806FDFDAA367A4F63C4BA31114300B6290828321C30B25DF97F273041E30A404836E84BB32E0620DC558047FC011A1205126F84D9F8EA5E607FC297E5C9FA00D803026D8126C08EF68B49F6A6C55DCB06EED0B666880CD49FCBFF598055D5E40303669CBC55D85F583DA5EF4F320D6E6A50ECBBFAF8C1F7209655EEAA58BFC18EB9FA20B29EC63FBC810C3A2EDCF8E27FD98975C87D59D9C909895AA10CEA5F7594ADD3ED1EBDFE01BE0559423475592A0E2936E4671504337221F897AE3016BC4670C6B765F5FF1185933B26B1183BCB1E5591970F40A1402EB19EF2644E941F67ABB31935259308B4A5271541F41653EB5E77CCA82214C9C6F4E42E8A3C46CC9BE15BC868BC45B28027E515A16554B9D4F6AB57CFFE42CFE0B42BF83E53F27B39AD95E000C329F716E51D15D6CD211E87AAA83A0F1175F5E1E8963A57DA656FBC19FB42661F14328B05CA7F1A83F49044A5086E6AF56225B8783450E43CB1B6F19061441AF58053BBFAACBC3A80FF5F19A8BD873F487A8FFE3DECD35E77EB2C26387EF66A3EED98C773211914115AFD0776FDAC90CB65479DFE59C0D199F195BBE9E4B2F70A9B1A41429002C2998FAB0F2D6956731819D9F5175B92FECE43178BC69ABEC6E2C18EA88289C5B14C58227640D02F614A9A881633816B9DCAC79E4721EF6E42691902AD1CF565600BAA8019310CAA0AC1087A86846C2E9B96B82C3F0CE52EE73760111061EF090DCBF47882710302A65FBDCF380F84703FE3D4FF7ADD0CB7ED65C889DD6EEC24D01F92771DF3F3D8DFB4BDE234D4A35AB20B22BF5D749398C9B6AE5C7B62DC11ACD887A49586238F5B6D37B47EA6953C3E339A9B40EF3EB01DD70F69253BA9A262777C75DF175195D172BD8233FC7B6F207154EF6E2F47533E359D24EB312A292C756C34A2D55A16452829DAD7A9731E2026E56486F6A3C07380DCA1AFFF270464DA8FF34621FBA715C5853EB1D4EA1C4E23B43CD1CDE1F252B728875F187626A813B4166CC34A62A5D6867E0B605641CEE8025F0AD73DBE4443286CA02CE157FF
-20180420033355 2 6 100 7679 5 ECCC9B93ED119552D36A774B288F541A81536A13B8D687B23174D680CE3F21B8FA088685F5B965215AFA69736E741A3AFC2AC82CE16162A1E4F0012F28998A638AA98D0789D6C58D92F207EAAA33E467C801891B8D37651B66E0942CF6AB7FD8E0D09A6D597D582BA48563F1450C3300218874730D26EE8B6505059C95C1C764D5FD736BF0A64FAD10F0C7D52A8A57C3FBD653887AAA890DA7AFEDA55DAF702EFF06CC722D147DAA2C8B78F0707F51D2B326BEF8972F5A289829E998B94D98E0ED663143797B569F3A6B56897B5726A38B042806FDFDAA367A4F63C4BA31114300B6290828321C30B25DF97F273041E30A404836E84BB32E0620DC558047FC011A1205126F84D9F8EA5E607FC297E5C9FA00D803026D8126C08EF68B49F6A6C55DCB06EED0B666880CD49FCBFF598055D5E40303669CBC55D85F583DA5EF4F320D6E6A50ECBBFAF8C1F7209655EEAA58BFC18EB9FA20B29EC63FBC810C3A2EDCF8E27FD98975C87D59D9C909895AA10CEA5F7594ADD3ED1EBDFE01BE0559423475592A0E2936E4671504337221F897AE3016BC4670C6B765F5FF1185933B26B1183BCB1E5591970F40A1402EB19EF2644E941F67ABB31935259308B4A5271541F41653EB5E77CCA82214C9C6F4E42E8A3C46CC9BE15BC868BC45B28027E515A16554B9D4F6AB57CFFE42CFE0B42BF83E53F27B39AD95E000C329F716E51D15D6CD211E87AAA83A0F1175F5E1E8963A57DA656FBC19FB42661F14328B05CA7F1A83F49044A5086E6AF56225B8783450E43CB1B6F19061441AF58053BBFAACBC3A80FF5F19A8BD873F487A8FFE3DECD35E77EB2C26387EF66A3EED98C773211914115AFD0776FDAC90CB65479DFE59C0D199F195BBE9E4B2F70A9B1A41429002C2998FAB0F2D6956731819D9F5175B92FECE43178BC69ABEC6E2C18EA88289C5B14C58227640D02F614A9A881633816B9DCAC79E4721EF6E42691902AD1CF565600BAA8019310CAA0AC1087A86846C2E9B96B82C3F0CE52EE73760111061EF090DCBF47882710302A65FBDCF380F84703FE3D4FF7ADD0CB7ED65C889DD6EEC24D01F92771DF3F3D8DFB4BDE234D4A35AB20B22BF5D749398C9B6AE5C7B62DC11ACD887A49586238F5B6D37B47EA6953C3E339A9B40EF3EB01DD70F69253BA9A262777C75DF175195D172BD8233FC7B6F207154EF6E2F47533E359D24EB312A292C756C34A2D55A16452829DAD7A9731E2026E56486F6A3C07380DCA1AFFF270464DA8FF34621FBA715C5853EB1D4EA1C4E23B43CD1CDE1F252B728875F187626A813B4166CC34A62A5D6867E0B605641CEE8025F0AD73DBE4443286CA02CE22F0F
-20180420131137 2 6 100 7679 2 ECCC9B93ED119552D36A774B288F541A81536A13B8D687B23174D680CE3F21B8FA088685F5B965215AFA69736E741A3AFC2AC82CE16162A1E4F0012F28998A638AA98D0789D6C58D92F207EAAA33E467C801891B8D37651B66E0942CF6AB7FD8E0D09A6D597D582BA48563F1450C3300218874730D26EE8B6505059C95C1C764D5FD736BF0A64FAD10F0C7D52A8A57C3FBD653887AAA890DA7AFEDA55DAF702EFF06CC722D147DAA2C8B78F0707F51D2B326BEF8972F5A289829E998B94D98E0ED663143797B569F3A6B56897B5726A38B042806FDFDAA367A4F63C4BA31114300B6290828321C30B25DF97F273041E30A404836E84BB32E0620DC558047FC011A1205126F84D9F8EA5E607FC297E5C9FA00D803026D8126C08EF68B49F6A6C55DCB06EED0B666880CD49FCBFF598055D5E40303669CBC55D85F583DA5EF4F320D6E6A50ECBBFAF8C1F7209655EEAA58BFC18EB9FA20B29EC63FBC810C3A2EDCF8E27FD98975C87D59D9C909895AA10CEA5F7594ADD3ED1EBDFE01BE0559423475592A0E2936E4671504337221F897AE3016BC4670C6B765F5FF1185933B26B1183BCB1E5591970F40A1402EB19EF2644E941F67ABB31935259308B4A5271541F41653EB5E77CCA82214C9C6F4E42E8A3C46CC9BE15BC868BC45B28027E515A16554B9D4F6AB57CFFE42CFE0B42BF83E53F27B39AD95E000C329F716E51D15D6CD211E87AAA83A0F1175F5E1E8963A57DA656FBC19FB42661F14328B05CA7F1A83F49044A5086E6AF56225B8783450E43CB1B6F19061441AF58053BBFAACBC3A80FF5F19A8BD873F487A8FFE3DECD35E77EB2C26387EF66A3EED98C773211914115AFD0776FDAC90CB65479DFE59C0D199F195BBE9E4B2F70A9B1A41429002C2998FAB0F2D6956731819D9F5175B92FECE43178BC69ABEC6E2C18EA88289C5B14C58227640D02F614A9A881633816B9DCAC79E4721EF6E42691902AD1CF565600BAA8019310CAA0AC1087A86846C2E9B96B82C3F0CE52EE73760111061EF090DCBF47882710302A65FBDCF380F84703FE3D4FF7ADD0CB7ED65C889DD6EEC24D01F92771DF3F3D8DFB4BDE234D4A35AB20B22BF5D749398C9B6AE5C7B62DC11ACD887A49586238F5B6D37B47EA6953C3E339A9B40EF3EB01DD70F69253BA9A262777C75DF175195D172BD8233FC7B6F207154EF6E2F47533E359D24EB312A292C756C34A2D55A16452829DAD7A9731E2026E56486F6A3C07380DCA1AFFF270464DA8FF34621FBA715C5853EB1D4EA1C4E23B43CD1CDE1F252B728875F187626A813B4166CC34A62A5D6867E0B605641CEE8025F0AD73DBE4443286CA03463D903
-20180420174655 2 6 100 7679 2 ECCC9B93ED119552D36A774B288F541A81536A13B8D687B23174D680CE3F21B8FA088685F5B965215AFA69736E741A3AFC2AC82CE16162A1E4F0012F28998A638AA98D0789D6C58D92F207EAAA33E467C801891B8D37651B66E0942CF6AB7FD8E0D09A6D597D582BA48563F1450C3300218874730D26EE8B6505059C95C1C764D5FD736BF0A64FAD10F0C7D52A8A57C3FBD653887AAA890DA7AFEDA55DAF702EFF06CC722D147DAA2C8B78F0707F51D2B326BEF8972F5A289829E998B94D98E0ED663143797B569F3A6B56897B5726A38B042806FDFDAA367A4F63C4BA31114300B6290828321C30B25DF97F273041E30A404836E84BB32E0620DC558047FC011A1205126F84D9F8EA5E607FC297E5C9FA00D803026D8126C08EF68B49F6A6C55DCB06EED0B666880CD49FCBFF598055D5E40303669CBC55D85F583DA5EF4F320D6E6A50ECBBFAF8C1F7209655EEAA58BFC18EB9FA20B29EC63FBC810C3A2EDCF8E27FD98975C87D59D9C909895AA10CEA5F7594ADD3ED1EBDFE01BE0559423475592A0E2936E4671504337221F897AE3016BC4670C6B765F5FF1185933B26B1183BCB1E5591970F40A1402EB19EF2644E941F67ABB31935259308B4A5271541F41653EB5E77CCA82214C9C6F4E42E8A3C46CC9BE15BC868BC45B28027E515A16554B9D4F6AB57CFFE42CFE0B42BF83E53F27B39AD95E000C329F716E51D15D6CD211E87AAA83A0F1175F5E1E8963A57DA656FBC19FB42661F14328B05CA7F1A83F49044A5086E6AF56225B8783450E43CB1B6F19061441AF58053BBFAACBC3A80FF5F19A8BD873F487A8FFE3DECD35E77EB2C26387EF66A3EED98C773211914115AFD0776FDAC90CB65479DFE59C0D199F195BBE9E4B2F70A9B1A41429002C2998FAB0F2D6956731819D9F5175B92FECE43178BC69ABEC6E2C18EA88289C5B14C58227640D02F614A9A881633816B9DCAC79E4721EF6E42691902AD1CF565600BAA8019310CAA0AC1087A86846C2E9B96B82C3F0CE52EE73760111061EF090DCBF47882710302A65FBDCF380F84703FE3D4FF7ADD0CB7ED65C889DD6EEC24D01F92771DF3F3D8DFB4BDE234D4A35AB20B22BF5D749398C9B6AE5C7B62DC11ACD887A49586238F5B6D37B47EA6953C3E339A9B40EF3EB01DD70F69253BA9A262777C75DF175195D172BD8233FC7B6F207154EF6E2F47533E359D24EB312A292C756C34A2D55A16452829DAD7A9731E2026E56486F6A3C07380DCA1AFFF270464DA8FF34621FBA715C5853EB1D4EA1C4E23B43CD1CDE1F252B728875F187626A813B4166CC34A62A5D6867E0B605641CEE8025F0AD73DBE4443286CA037E8E853
-20180420224816 2 6 100 7679 2 ECCC9B93ED119552D36A774B288F541A81536A13B8D687B23174D680CE3F21B8FA088685F5B965215AFA69736E741A3AFC2AC82CE16162A1E4F0012F28998A638AA98D0789D6C58D92F207EAAA33E467C801891B8D37651B66E0942CF6AB7FD8E0D09A6D597D582BA48563F1450C3300218874730D26EE8B6505059C95C1C764D5FD736BF0A64FAD10F0C7D52A8A57C3FBD653887AAA890DA7AFEDA55DAF702EFF06CC722D147DAA2C8B78F0707F51D2B326BEF8972F5A289829E998B94D98E0ED663143797B569F3A6B56897B5726A38B042806FDFDAA367A4F63C4BA31114300B6290828321C30B25DF97F273041E30A404836E84BB32E0620DC558047FC011A1205126F84D9F8EA5E607FC297E5C9FA00D803026D8126C08EF68B49F6A6C55DCB06EED0B666880CD49FCBFF598055D5E40303669CBC55D85F583DA5EF4F320D6E6A50ECBBFAF8C1F7209655EEAA58BFC18EB9FA20B29EC63FBC810C3A2EDCF8E27FD98975C87D59D9C909895AA10CEA5F7594ADD3ED1EBDFE01BE0559423475592A0E2936E4671504337221F897AE3016BC4670C6B765F5FF1185933B26B1183BCB1E5591970F40A1402EB19EF2644E941F67ABB31935259308B4A5271541F41653EB5E77CCA82214C9C6F4E42E8A3C46CC9BE15BC868BC45B28027E515A16554B9D4F6AB57CFFE42CFE0B42BF83E53F27B39AD95E000C329F716E51D15D6CD211E87AAA83A0F1175F5E1E8963A57DA656FBC19FB42661F14328B05CA7F1A83F49044A5086E6AF56225B8783450E43CB1B6F19061441AF58053BBFAACBC3A80FF5F19A8BD873F487A8FFE3DECD35E77EB2C26387EF66A3EED98C773211914115AFD0776FDAC90CB65479DFE59C0D199F195BBE9E4B2F70A9B1A41429002C2998FAB0F2D6956731819D9F5175B92FECE43178BC69ABEC6E2C18EA88289C5B14C58227640D02F614A9A881633816B9DCAC79E4721EF6E42691902AD1CF565600BAA8019310CAA0AC1087A86846C2E9B96B82C3F0CE52EE73760111061EF090DCBF47882710302A65FBDCF380F84703FE3D4FF7ADD0CB7ED65C889DD6EEC24D01F92771DF3F3D8DFB4BDE234D4A35AB20B22BF5D749398C9B6AE5C7B62DC11ACD887A49586238F5B6D37B47EA6953C3E339A9B40EF3EB01DD70F69253BA9A262777C75DF175195D172BD8233FC7B6F207154EF6E2F47533E359D24EB312A292C756C34A2D55A16452829DAD7A9731E2026E56486F6A3C07380DCA1AFFF270464DA8FF34621FBA715C5853EB1D4EA1C4E23B43CD1CDE1F252B728875F187626A813B4166CC34A62A5D6867E0B605641CEE8025F0AD73DBE4443286CA03BC5BAEB
-20180421002804 2 6 100 7679 2 ECCC9B93ED119552D36A774B288F541A81536A13B8D687B23174D680CE3F21B8FA088685F5B965215AFA69736E741A3AFC2AC82CE16162A1E4F0012F28998A638AA98D0789D6C58D92F207EAAA33E467C801891B8D37651B66E0942CF6AB7FD8E0D09A6D597D582BA48563F1450C3300218874730D26EE8B6505059C95C1C764D5FD736BF0A64FAD10F0C7D52A8A57C3FBD653887AAA890DA7AFEDA55DAF702EFF06CC722D147DAA2C8B78F0707F51D2B326BEF8972F5A289829E998B94D98E0ED663143797B569F3A6B56897B5726A38B042806FDFDAA367A4F63C4BA31114300B6290828321C30B25DF97F273041E30A404836E84BB32E0620DC558047FC011A1205126F84D9F8EA5E607FC297E5C9FA00D803026D8126C08EF68B49F6A6C55DCB06EED0B666880CD49FCBFF598055D5E40303669CBC55D85F583DA5EF4F320D6E6A50ECBBFAF8C1F7209655EEAA58BFC18EB9FA20B29EC63FBC810C3A2EDCF8E27FD98975C87D59D9C909895AA10CEA5F7594ADD3ED1EBDFE01BE0559423475592A0E2936E4671504337221F897AE3016BC4670C6B765F5FF1185933B26B1183BCB1E5591970F40A1402EB19EF2644E941F67ABB31935259308B4A5271541F41653EB5E77CCA82214C9C6F4E42E8A3C46CC9BE15BC868BC45B28027E515A16554B9D4F6AB57CFFE42CFE0B42BF83E53F27B39AD95E000C329F716E51D15D6CD211E87AAA83A0F1175F5E1E8963A57DA656FBC19FB42661F14328B05CA7F1A83F49044A5086E6AF56225B8783450E43CB1B6F19061441AF58053BBFAACBC3A80FF5F19A8BD873F487A8FFE3DECD35E77EB2C26387EF66A3EED98C773211914115AFD0776FDAC90CB65479DFE59C0D199F195BBE9E4B2F70A9B1A41429002C2998FAB0F2D6956731819D9F5175B92FECE43178BC69ABEC6E2C18EA88289C5B14C58227640D02F614A9A881633816B9DCAC79E4721EF6E42691902AD1CF565600BAA8019310CAA0AC1087A86846C2E9B96B82C3F0CE52EE73760111061EF090DCBF47882710302A65FBDCF380F84703FE3D4FF7ADD0CB7ED65C889DD6EEC24D01F92771DF3F3D8DFB4BDE234D4A35AB20B22BF5D749398C9B6AE5C7B62DC11ACD887A49586238F5B6D37B47EA6953C3E339A9B40EF3EB01DD70F69253BA9A262777C75DF175195D172BD8233FC7B6F207154EF6E2F47533E359D24EB312A292C756C34A2D55A16452829DAD7A9731E2026E56486F6A3C07380DCA1AFFF270464DA8FF34621FBA715C5853EB1D4EA1C4E23B43CD1CDE1F252B728875F187626A813B4166CC34A62A5D6867E0B605641CEE8025F0AD73DBE4443286CA03CFF8483
-20180421033707 2 6 100 7679 5 ECCC9B93ED119552D36A774B288F541A81536A13B8D687B23174D680CE3F21B8FA088685F5B965215AFA69736E741A3AFC2AC82CE16162A1E4F0012F28998A638AA98D0789D6C58D92F207EAAA33E467C801891B8D37651B66E0942CF6AB7FD8E0D09A6D597D582BA48563F1450C3300218874730D26EE8B6505059C95C1C764D5FD736BF0A64FAD10F0C7D52A8A57C3FBD653887AAA890DA7AFEDA55DAF702EFF06CC722D147DAA2C8B78F0707F51D2B326BEF8972F5A289829E998B94D98E0ED663143797B569F3A6B56897B5726A38B042806FDFDAA367A4F63C4BA31114300B6290828321C30B25DF97F273041E30A404836E84BB32E0620DC558047FC011A1205126F84D9F8EA5E607FC297E5C9FA00D803026D8126C08EF68B49F6A6C55DCB06EED0B666880CD49FCBFF598055D5E40303669CBC55D85F583DA5EF4F320D6E6A50ECBBFAF8C1F7209655EEAA58BFC18EB9FA20B29EC63FBC810C3A2EDCF8E27FD98975C87D59D9C909895AA10CEA5F7594ADD3ED1EBDFE01BE0559423475592A0E2936E4671504337221F897AE3016BC4670C6B765F5FF1185933B26B1183BCB1E5591970F40A1402EB19EF2644E941F67ABB31935259308B4A5271541F41653EB5E77CCA82214C9C6F4E42E8A3C46CC9BE15BC868BC45B28027E515A16554B9D4F6AB57CFFE42CFE0B42BF83E53F27B39AD95E000C329F716E51D15D6CD211E87AAA83A0F1175F5E1E8963A57DA656FBC19FB42661F14328B05CA7F1A83F49044A5086E6AF56225B8783450E43CB1B6F19061441AF58053BBFAACBC3A80FF5F19A8BD873F487A8FFE3DECD35E77EB2C26387EF66A3EED98C773211914115AFD0776FDAC90CB65479DFE59C0D199F195BBE9E4B2F70A9B1A41429002C2998FAB0F2D6956731819D9F5175B92FECE43178BC69ABEC6E2C18EA88289C5B14C58227640D02F614A9A881633816B9DCAC79E4721EF6E42691902AD1CF565600BAA8019310CAA0AC1087A86846C2E9B96B82C3F0CE52EE73760111061EF090DCBF47882710302A65FBDCF380F84703FE3D4FF7ADD0CB7ED65C889DD6EEC24D01F92771DF3F3D8DFB4BDE234D4A35AB20B22BF5D749398C9B6AE5C7B62DC11ACD887A49586238F5B6D37B47EA6953C3E339A9B40EF3EB01DD70F69253BA9A262777C75DF175195D172BD8233FC7B6F207154EF6E2F47533E359D24EB312A292C756C34A2D55A16452829DAD7A9731E2026E56486F6A3C07380DCA1AFFF270464DA8FF34621FBA715C5853EB1D4EA1C4E23B43CD1CDE1F252B728875F187626A813B4166CC34A62A5D6867E0B605641CEE8025F0AD73DBE4443286CA03F5CEF07
-20180421044121 2 6 100 7679 2 ECCC9B93ED119552D36A774B288F541A81536A13B8D687B23174D680CE3F21B8FA088685F5B965215AFA69736E741A3AFC2AC82CE16162A1E4F0012F28998A638AA98D0789D6C58D92F207EAAA33E467C801891B8D37651B66E0942CF6AB7FD8E0D09A6D597D582BA48563F1450C3300218874730D26EE8B6505059C95C1C764D5FD736BF0A64FAD10F0C7D52A8A57C3FBD653887AAA890DA7AFEDA55DAF702EFF06CC722D147DAA2C8B78F0707F51D2B326BEF8972F5A289829E998B94D98E0ED663143797B569F3A6B56897B5726A38B042806FDFDAA367A4F63C4BA31114300B6290828321C30B25DF97F273041E30A404836E84BB32E0620DC558047FC011A1205126F84D9F8EA5E607FC297E5C9FA00D803026D8126C08EF68B49F6A6C55DCB06EED0B666880CD49FCBFF598055D5E40303669CBC55D85F583DA5EF4F320D6E6A50ECBBFAF8C1F7209655EEAA58BFC18EB9FA20B29EC63FBC810C3A2EDCF8E27FD98975C87D59D9C909895AA10CEA5F7594ADD3ED1EBDFE01BE0559423475592A0E2936E4671504337221F897AE3016BC4670C6B765F5FF1185933B26B1183BCB1E5591970F40A1402EB19EF2644E941F67ABB31935259308B4A5271541F41653EB5E77CCA82214C9C6F4E42E8A3C46CC9BE15BC868BC45B28027E515A16554B9D4F6AB57CFFE42CFE0B42BF83E53F27B39AD95E000C329F716E51D15D6CD211E87AAA83A0F1175F5E1E8963A57DA656FBC19FB42661F14328B05CA7F1A83F49044A5086E6AF56225B8783450E43CB1B6F19061441AF58053BBFAACBC3A80FF5F19A8BD873F487A8FFE3DECD35E77EB2C26387EF66A3EED98C773211914115AFD0776FDAC90CB65479DFE59C0D199F195BBE9E4B2F70A9B1A41429002C2998FAB0F2D6956731819D9F5175B92FECE43178BC69ABEC6E2C18EA88289C5B14C58227640D02F614A9A881633816B9DCAC79E4721EF6E42691902AD1CF565600BAA8019310CAA0AC1087A86846C2E9B96B82C3F0CE52EE73760111061EF090DCBF47882710302A65FBDCF380F84703FE3D4FF7ADD0CB7ED65C889DD6EEC24D01F92771DF3F3D8DFB4BDE234D4A35AB20B22BF5D749398C9B6AE5C7B62DC11ACD887A49586238F5B6D37B47EA6953C3E339A9B40EF3EB01DD70F69253BA9A262777C75DF175195D172BD8233FC7B6F207154EF6E2F47533E359D24EB312A292C756C34A2D55A16452829DAD7A9731E2026E56486F6A3C07380DCA1AFFF270464DA8FF34621FBA715C5853EB1D4EA1C4E23B43CD1CDE1F252B728875F187626A813B4166CC34A62A5D6867E0B605641CEE8025F0AD73DBE4443286CA04029ED83
-20180421054539 2 6 100 7679 2 ECCC9B93ED119552D36A774B288F541A81536A13B8D687B23174D680CE3F21B8FA088685F5B965215AFA69736E741A3AFC2AC82CE16162A1E4F0012F28998A638AA98D0789D6C58D92F207EAAA33E467C801891B8D37651B66E0942CF6AB7FD8E0D09A6D597D582BA48563F1450C3300218874730D26EE8B6505059C95C1C764D5FD736BF0A64FAD10F0C7D52A8A57C3FBD653887AAA890DA7AFEDA55DAF702EFF06CC722D147DAA2C8B78F0707F51D2B326BEF8972F5A289829E998B94D98E0ED663143797B569F3A6B56897B5726A38B042806FDFDAA367A4F63C4BA31114300B6290828321C30B25DF97F273041E30A404836E84BB32E0620DC558047FC011A1205126F84D9F8EA5E607FC297E5C9FA00D803026D8126C08EF68B49F6A6C55DCB06EED0B666880CD49FCBFF598055D5E40303669CBC55D85F583DA5EF4F320D6E6A50ECBBFAF8C1F7209655EEAA58BFC18EB9FA20B29EC63FBC810C3A2EDCF8E27FD98975C87D59D9C909895AA10CEA5F7594ADD3ED1EBDFE01BE0559423475592A0E2936E4671504337221F897AE3016BC4670C6B765F5FF1185933B26B1183BCB1E5591970F40A1402EB19EF2644E941F67ABB31935259308B4A5271541F41653EB5E77CCA82214C9C6F4E42E8A3C46CC9BE15BC868BC45B28027E515A16554B9D4F6AB57CFFE42CFE0B42BF83E53F27B39AD95E000C329F716E51D15D6CD211E87AAA83A0F1175F5E1E8963A57DA656FBC19FB42661F14328B05CA7F1A83F49044A5086E6AF56225B8783450E43CB1B6F19061441AF58053BBFAACBC3A80FF5F19A8BD873F487A8FFE3DECD35E77EB2C26387EF66A3EED98C773211914115AFD0776FDAC90CB65479DFE59C0D199F195BBE9E4B2F70A9B1A41429002C2998FAB0F2D6956731819D9F5175B92FECE43178BC69ABEC6E2C18EA88289C5B14C58227640D02F614A9A881633816B9DCAC79E4721EF6E42691902AD1CF565600BAA8019310CAA0AC1087A86846C2E9B96B82C3F0CE52EE73760111061EF090DCBF47882710302A65FBDCF380F84703FE3D4FF7ADD0CB7ED65C889DD6EEC24D01F92771DF3F3D8DFB4BDE234D4A35AB20B22BF5D749398C9B6AE5C7B62DC11ACD887A49586238F5B6D37B47EA6953C3E339A9B40EF3EB01DD70F69253BA9A262777C75DF175195D172BD8233FC7B6F207154EF6E2F47533E359D24EB312A292C756C34A2D55A16452829DAD7A9731E2026E56486F6A3C07380DCA1AFFF270464DA8FF34621FBA715C5853EB1D4EA1C4E23B43CD1CDE1F252B728875F187626A813B4166CC34A62A5D6867E0B605641CEE8025F0AD73DBE4443286CA040F07753
-20180421080206 2 6 100 7679 5 ECCC9B93ED119552D36A774B288F541A81536A13B8D687B23174D680CE3F21B8FA088685F5B965215AFA69736E741A3AFC2AC82CE16162A1E4F0012F28998A638AA98D0789D6C58D92F207EAAA33E467C801891B8D37651B66E0942CF6AB7FD8E0D09A6D597D582BA48563F1450C3300218874730D26EE8B6505059C95C1C764D5FD736BF0A64FAD10F0C7D52A8A57C3FBD653887AAA890DA7AFEDA55DAF702EFF06CC722D147DAA2C8B78F0707F51D2B326BEF8972F5A289829E998B94D98E0ED663143797B569F3A6B56897B5726A38B042806FDFDAA367A4F63C4BA31114300B6290828321C30B25DF97F273041E30A404836E84BB32E0620DC558047FC011A1205126F84D9F8EA5E607FC297E5C9FA00D803026D8126C08EF68B49F6A6C55DCB06EED0B666880CD49FCBFF598055D5E40303669CBC55D85F583DA5EF4F320D6E6A50ECBBFAF8C1F7209655EEAA58BFC18EB9FA20B29EC63FBC810C3A2EDCF8E27FD98975C87D59D9C909895AA10CEA5F7594ADD3ED1EBDFE01BE0559423475592A0E2936E4671504337221F897AE3016BC4670C6B765F5FF1185933B26B1183BCB1E5591970F40A1402EB19EF2644E941F67ABB31935259308B4A5271541F41653EB5E77CCA82214C9C6F4E42E8A3C46CC9BE15BC868BC45B28027E515A16554B9D4F6AB57CFFE42CFE0B42BF83E53F27B39AD95E000C329F716E51D15D6CD211E87AAA83A0F1175F5E1E8963A57DA656FBC19FB42661F14328B05CA7F1A83F49044A5086E6AF56225B8783450E43CB1B6F19061441AF58053BBFAACBC3A80FF5F19A8BD873F487A8FFE3DECD35E77EB2C26387EF66A3EED98C773211914115AFD0776FDAC90CB65479DFE59C0D199F195BBE9E4B2F70A9B1A41429002C2998FAB0F2D6956731819D9F5175B92FECE43178BC69ABEC6E2C18EA88289C5B14C58227640D02F614A9A881633816B9DCAC79E4721EF6E42691902AD1CF565600BAA8019310CAA0AC1087A86846C2E9B96B82C3F0CE52EE73760111061EF090DCBF47882710302A65FBDCF380F84703FE3D4FF7ADD0CB7ED65C889DD6EEC24D01F92771DF3F3D8DFB4BDE234D4A35AB20B22BF5D749398C9B6AE5C7B62DC11ACD887A49586238F5B6D37B47EA6953C3E339A9B40EF3EB01DD70F69253BA9A262777C75DF175195D172BD8233FC7B6F207154EF6E2F47533E359D24EB312A292C756C34A2D55A16452829DAD7A9731E2026E56486F6A3C07380DCA1AFFF270464DA8FF34621FBA715C5853EB1D4EA1C4E23B43CD1CDE1F252B728875F187626A813B4166CC34A62A5D6867E0B605641CEE8025F0AD73DBE4443286CA042A70927
-20180421084346 2 6 100 7679 2 ECCC9B93ED119552D36A774B288F541A81536A13B8D687B23174D680CE3F21B8FA088685F5B965215AFA69736E741A3AFC2AC82CE16162A1E4F0012F28998A638AA98D0789D6C58D92F207EAAA33E467C801891B8D37651B66E0942CF6AB7FD8E0D09A6D597D582BA48563F1450C3300218874730D26EE8B6505059C95C1C764D5FD736BF0A64FAD10F0C7D52A8A57C3FBD653887AAA890DA7AFEDA55DAF702EFF06CC722D147DAA2C8B78F0707F51D2B326BEF8972F5A289829E998B94D98E0ED663143797B569F3A6B56897B5726A38B042806FDFDAA367A4F63C4BA31114300B6290828321C30B25DF97F273041E30A404836E84BB32E0620DC558047FC011A1205126F84D9F8EA5E607FC297E5C9FA00D803026D8126C08EF68B49F6A6C55DCB06EED0B666880CD49FCBFF598055D5E40303669CBC55D85F583DA5EF4F320D6E6A50ECBBFAF8C1F7209655EEAA58BFC18EB9FA20B29EC63FBC810C3A2EDCF8E27FD98975C87D59D9C909895AA10CEA5F7594ADD3ED1EBDFE01BE0559423475592A0E2936E4671504337221F897AE3016BC4670C6B765F5FF1185933B26B1183BCB1E5591970F40A1402EB19EF2644E941F67ABB31935259308B4A5271541F41653EB5E77CCA82214C9C6F4E42E8A3C46CC9BE15BC868BC45B28027E515A16554B9D4F6AB57CFFE42CFE0B42BF83E53F27B39AD95E000C329F716E51D15D6CD211E87AAA83A0F1175F5E1E8963A57DA656FBC19FB42661F14328B05CA7F1A83F49044A5086E6AF56225B8783450E43CB1B6F19061441AF58053BBFAACBC3A80FF5F19A8BD873F487A8FFE3DECD35E77EB2C26387EF66A3EED98C773211914115AFD0776FDAC90CB65479DFE59C0D199F195BBE9E4B2F70A9B1A41429002C2998FAB0F2D6956731819D9F5175B92FECE43178BC69ABEC6E2C18EA88289C5B14C58227640D02F614A9A881633816B9DCAC79E4721EF6E42691902AD1CF565600BAA8019310CAA0AC1087A86846C2E9B96B82C3F0CE52EE73760111061EF090DCBF47882710302A65FBDCF380F84703FE3D4FF7ADD0CB7ED65C889DD6EEC24D01F92771DF3F3D8DFB4BDE234D4A35AB20B22BF5D749398C9B6AE5C7B62DC11ACD887A49586238F5B6D37B47EA6953C3E339A9B40EF3EB01DD70F69253BA9A262777C75DF175195D172BD8233FC7B6F207154EF6E2F47533E359D24EB312A292C756C34A2D55A16452829DAD7A9731E2026E56486F6A3C07380DCA1AFFF270464DA8FF34621FBA715C5853EB1D4EA1C4E23B43CD1CDE1F252B728875F187626A813B4166CC34A62A5D6867E0B605641CEE8025F0AD73DBE4443286CA04323E033
-20180421135101 2 6 100 7679 5 ECCC9B93ED119552D36A774B288F541A81536A13B8D687B23174D680CE3F21B8FA088685F5B965215AFA69736E741A3AFC2AC82CE16162A1E4F0012F28998A638AA98D0789D6C58D92F207EAAA33E467C801891B8D37651B66E0942CF6AB7FD8E0D09A6D597D582BA48563F1450C3300218874730D26EE8B6505059C95C1C764D5FD736BF0A64FAD10F0C7D52A8A57C3FBD653887AAA890DA7AFEDA55DAF702EFF06CC722D147DAA2C8B78F0707F51D2B326BEF8972F5A289829E998B94D98E0ED663143797B569F3A6B56897B5726A38B042806FDFDAA367A4F63C4BA31114300B6290828321C30B25DF97F273041E30A404836E84BB32E0620DC558047FC011A1205126F84D9F8EA5E607FC297E5C9FA00D803026D8126C08EF68B49F6A6C55DCB06EED0B666880CD49FCBFF598055D5E40303669CBC55D85F583DA5EF4F320D6E6A50ECBBFAF8C1F7209655EEAA58BFC18EB9FA20B29EC63FBC810C3A2EDCF8E27FD98975C87D59D9C909895AA10CEA5F7594ADD3ED1EBDFE01BE0559423475592A0E2936E4671504337221F897AE3016BC4670C6B765F5FF1185933B26B1183BCB1E5591970F40A1402EB19EF2644E941F67ABB31935259308B4A5271541F41653EB5E77CCA82214C9C6F4E42E8A3C46CC9BE15BC868BC45B28027E515A16554B9D4F6AB57CFFE42CFE0B42BF83E53F27B39AD95E000C329F716E51D15D6CD211E87AAA83A0F1175F5E1E8963A57DA656FBC19FB42661F14328B05CA7F1A83F49044A5086E6AF56225B8783450E43CB1B6F19061441AF58053BBFAACBC3A80FF5F19A8BD873F487A8FFE3DECD35E77EB2C26387EF66A3EED98C773211914115AFD0776FDAC90CB65479DFE59C0D199F195BBE9E4B2F70A9B1A41429002C2998FAB0F2D6956731819D9F5175B92FECE43178BC69ABEC6E2C18EA88289C5B14C58227640D02F614A9A881633816B9DCAC79E4721EF6E42691902AD1CF565600BAA8019310CAA0AC1087A86846C2E9B96B82C3F0CE52EE73760111061EF090DCBF47882710302A65FBDCF380F84703FE3D4FF7ADD0CB7ED65C889DD6EEC24D01F92771DF3F3D8DFB4BDE234D4A35AB20B22BF5D749398C9B6AE5C7B62DC11ACD887A49586238F5B6D37B47EA6953C3E339A9B40EF3EB01DD70F69253BA9A262777C75DF175195D172BD8233FC7B6F207154EF6E2F47533E359D24EB312A292C756C34A2D55A16452829DAD7A9731E2026E56486F6A3C07380DCA1AFFF270464DA8FF34621FBA715C5853EB1D4EA1C4E23B43CD1CDE1F252B728875F187626A813B4166CC34A62A5D6867E0B605641CEE8025F0AD73DBE4443286CA04708373F
-20180421220150 2 6 100 7679 2 ECCC9B93ED119552D36A774B288F541A81536A13B8D687B23174D680CE3F21B8FA088685F5B965215AFA69736E741A3AFC2AC82CE16162A1E4F0012F28998A638AA98D0789D6C58D92F207EAAA33E467C801891B8D37651B66E0942CF6AB7FD8E0D09A6D597D582BA48563F1450C3300218874730D26EE8B6505059C95C1C764D5FD736BF0A64FAD10F0C7D52A8A57C3FBD653887AAA890DA7AFEDA55DAF702EFF06CC722D147DAA2C8B78F0707F51D2B326BEF8972F5A289829E998B94D98E0ED663143797B569F3A6B56897B5726A38B042806FDFDAA367A4F63C4BA31114300B6290828321C30B25DF97F273041E30A404836E84BB32E0620DC558047FC011A1205126F84D9F8EA5E607FC297E5C9FA00D803026D8126C08EF68B49F6A6C55DCB06EED0B666880CD49FCBFF598055D5E40303669CBC55D85F583DA5EF4F320D6E6A50ECBBFAF8C1F7209655EEAA58BFC18EB9FA20B29EC63FBC810C3A2EDCF8E27FD98975C87D59D9C909895AA10CEA5F7594ADD3ED1EBDFE01BE0559423475592A0E2936E4671504337221F897AE3016BC4670C6B765F5FF1185933B26B1183BCB1E5591970F40A1402EB19EF2644E941F67ABB31935259308B4A5271541F41653EB5E77CCA82214C9C6F4E42E8A3C46CC9BE15BC868BC45B28027E515A16554B9D4F6AB57CFFE42CFE0B42BF83E53F27B39AD95E000C329F716E51D15D6CD211E87AAA83A0F1175F5E1E8963A57DA656FBC19FB42661F14328B05CA7F1A83F49044A5086E6AF56225B8783450E43CB1B6F19061441AF58053BBFAACBC3A80FF5F19A8BD873F487A8FFE3DECD35E77EB2C26387EF66A3EED98C773211914115AFD0776FDAC90CB65479DFE59C0D199F195BBE9E4B2F70A9B1A41429002C2998FAB0F2D6956731819D9F5175B92FECE43178BC69ABEC6E2C18EA88289C5B14C58227640D02F614A9A881633816B9DCAC79E4721EF6E42691902AD1CF565600BAA8019310CAA0AC1087A86846C2E9B96B82C3F0CE52EE73760111061EF090DCBF47882710302A65FBDCF380F84703FE3D4FF7ADD0CB7ED65C889DD6EEC24D01F92771DF3F3D8DFB4BDE234D4A35AB20B22BF5D749398C9B6AE5C7B62DC11ACD887A49586238F5B6D37B47EA6953C3E339A9B40EF3EB01DD70F69253BA9A262777C75DF175195D172BD8233FC7B6F207154EF6E2F47533E359D24EB312A292C756C34A2D55A16452829DAD7A9731E2026E56486F6A3C07380DCA1AFFF270464DA8FF34621FBA715C5853EB1D4EA1C4E23B43CD1CDE1F252B728875F187626A813B4166CC34A62A5D6867E0B605641CEE8025F0AD73DBE4443286CA04D33A023
-20180421233337 2 6 100 7679 5 ECCC9B93ED119552D36A774B288F541A81536A13B8D687B23174D680CE3F21B8FA088685F5B965215AFA69736E741A3AFC2AC82CE16162A1E4F0012F28998A638AA98D0789D6C58D92F207EAAA33E467C801891B8D37651B66E0942CF6AB7FD8E0D09A6D597D582BA48563F1450C3300218874730D26EE8B6505059C95C1C764D5FD736BF0A64FAD10F0C7D52A8A57C3FBD653887AAA890DA7AFEDA55DAF702EFF06CC722D147DAA2C8B78F0707F51D2B326BEF8972F5A289829E998B94D98E0ED663143797B569F3A6B56897B5726A38B042806FDFDAA367A4F63C4BA31114300B6290828321C30B25DF97F273041E30A404836E84BB32E0620DC558047FC011A1205126F84D9F8EA5E607FC297E5C9FA00D803026D8126C08EF68B49F6A6C55DCB06EED0B666880CD49FCBFF598055D5E40303669CBC55D85F583DA5EF4F320D6E6A50ECBBFAF8C1F7209655EEAA58BFC18EB9FA20B29EC63FBC810C3A2EDCF8E27FD98975C87D59D9C909895AA10CEA5F7594ADD3ED1EBDFE01BE0559423475592A0E2936E4671504337221F897AE3016BC4670C6B765F5FF1185933B26B1183BCB1E5591970F40A1402EB19EF2644E941F67ABB31935259308B4A5271541F41653EB5E77CCA82214C9C6F4E42E8A3C46CC9BE15BC868BC45B28027E515A16554B9D4F6AB57CFFE42CFE0B42BF83E53F27B39AD95E000C329F716E51D15D6CD211E87AAA83A0F1175F5E1E8963A57DA656FBC19FB42661F14328B05CA7F1A83F49044A5086E6AF56225B8783450E43CB1B6F19061441AF58053BBFAACBC3A80FF5F19A8BD873F487A8FFE3DECD35E77EB2C26387EF66A3EED98C773211914115AFD0776FDAC90CB65479DFE59C0D199F195BBE9E4B2F70A9B1A41429002C2998FAB0F2D6956731819D9F5175B92FECE43178BC69ABEC6E2C18EA88289C5B14C58227640D02F614A9A881633816B9DCAC79E4721EF6E42691902AD1CF565600BAA8019310CAA0AC1087A86846C2E9B96B82C3F0CE52EE73760111061EF090DCBF47882710302A65FBDCF380F84703FE3D4FF7ADD0CB7ED65C889DD6EEC24D01F92771DF3F3D8DFB4BDE234D4A35AB20B22BF5D749398C9B6AE5C7B62DC11ACD887A49586238F5B6D37B47EA6953C3E339A9B40EF3EB01DD70F69253BA9A262777C75DF175195D172BD8233FC7B6F207154EF6E2F47533E359D24EB312A292C756C34A2D55A16452829DAD7A9731E2026E56486F6A3C07380DCA1AFFF270464DA8FF34621FBA715C5853EB1D4EA1C4E23B43CD1CDE1F252B728875F187626A813B4166CC34A62A5D6867E0B605641CEE8025F0AD73DBE4443286CA04E52D9FF
-20180422094542 2 6 100 7679 2 ECCC9B93ED119552D36A774B288F541A81536A13B8D687B23174D680CE3F21B8FA088685F5B965215AFA69736E741A3AFC2AC82CE16162A1E4F0012F28998A638AA98D0789D6C58D92F207EAAA33E467C801891B8D37651B66E0942CF6AB7FD8E0D09A6D597D582BA48563F1450C3300218874730D26EE8B6505059C95C1C764D5FD736BF0A64FAD10F0C7D52A8A57C3FBD653887AAA890DA7AFEDA55DAF702EFF06CC722D147DAA2C8B78F0707F51D2B326BEF8972F5A289829E998B94D98E0ED663143797B569F3A6B56897B5726A38B042806FDFDAA367A4F63C4BA31114300B6290828321C30B25DF97F273041E30A404836E84BB32E0620DC558047FC011A1205126F84D9F8EA5E607FC297E5C9FA00D803026D8126C08EF68B49F6A6C55DCB06EED0B666880CD49FCBFF598055D5E40303669CBC55D85F583DA5EF4F320D6E6A50ECBBFAF8C1F7209655EEAA58BFC18EB9FA20B29EC63FBC810C3A2EDCF8E27FD98975C87D59D9C909895AA10CEA5F7594ADD3ED1EBDFE01BE0559423475592A0E2936E4671504337221F897AE3016BC4670C6B765F5FF1185933B26B1183BCB1E5591970F40A1402EB19EF2644E941F67ABB31935259308B4A5271541F41653EB5E77CCA82214C9C6F4E42E8A3C46CC9BE15BC868BC45B28027E515A16554B9D4F6AB57CFFE42CFE0B42BF83E53F27B39AD95E000C329F716E51D15D6CD211E87AAA83A0F1175F5E1E8963A57DA656FBC19FB42661F14328B05CA7F1A83F49044A5086E6AF56225B8783450E43CB1B6F19061441AF58053BBFAACBC3A80FF5F19A8BD873F487A8FFE3DECD35E77EB2C26387EF66A3EED98C773211914115AFD0776FDAC90CB65479DFE59C0D199F195BBE9E4B2F70A9B1A41429002C2998FAB0F2D6956731819D9F5175B92FECE43178BC69ABEC6E2C18EA88289C5B14C58227640D02F614A9A881633816B9DCAC79E4721EF6E42691902AD1CF565600BAA8019310CAA0AC1087A86846C2E9B96B82C3F0CE52EE73760111061EF090DCBF47882710302A65FBDCF380F84703FE3D4FF7ADD0CB7ED65C889DD6EEC24D01F92771DF3F3D8DFB4BDE234D4A35AB20B22BF5D749398C9B6AE5C7B62DC11ACD887A49586238F5B6D37B47EA6953C3E339A9B40EF3EB01DD70F69253BA9A262777C75DF175195D172BD8233FC7B6F207154EF6E2F47533E359D24EB312A292C756C34A2D55A16452829DAD7A9731E2026E56486F6A3C07380DCA1AFFF270464DA8FF34621FBA715C5853EB1D4EA1C4E23B43CD1CDE1F252B728875F187626A813B4166CC34A62A5D6867E0B605641CEE8025F0AD73DBE4443286CA055FBBC03
-20180422151643 2 6 100 7679 2 ECCC9B93ED119552D36A774B288F541A81536A13B8D687B23174D680CE3F21B8FA088685F5B965215AFA69736E741A3AFC2AC82CE16162A1E4F0012F28998A638AA98D0789D6C58D92F207EAAA33E467C801891B8D37651B66E0942CF6AB7FD8E0D09A6D597D582BA48563F1450C3300218874730D26EE8B6505059C95C1C764D5FD736BF0A64FAD10F0C7D52A8A57C3FBD653887AAA890DA7AFEDA55DAF702EFF06CC722D147DAA2C8B78F0707F51D2B326BEF8972F5A289829E998B94D98E0ED663143797B569F3A6B56897B5726A38B042806FDFDAA367A4F63C4BA31114300B6290828321C30B25DF97F273041E30A404836E84BB32E0620DC558047FC011A1205126F84D9F8EA5E607FC297E5C9FA00D803026D8126C08EF68B49F6A6C55DCB06EED0B666880CD49FCBFF598055D5E40303669CBC55D85F583DA5EF4F320D6E6A50ECBBFAF8C1F7209655EEAA58BFC18EB9FA20B29EC63FBC810C3A2EDCF8E27FD98975C87D59D9C909895AA10CEA5F7594ADD3ED1EBDFE01BE0559423475592A0E2936E4671504337221F897AE3016BC4670C6B765F5FF1185933B26B1183BCB1E5591970F40A1402EB19EF2644E941F67ABB31935259308B4A5271541F41653EB5E77CCA82214C9C6F4E42E8A3C46CC9BE15BC868BC45B28027E515A16554B9D4F6AB57CFFE42CFE0B42BF83E53F27B39AD95E000C329F716E51D15D6CD211E87AAA83A0F1175F5E1E8963A57DA656FBC19FB42661F14328B05CA7F1A83F49044A5086E6AF56225B8783450E43CB1B6F19061441AF58053BBFAACBC3A80FF5F19A8BD873F487A8FFE3DECD35E77EB2C26387EF66A3EED98C773211914115AFD0776FDAC90CB65479DFE59C0D199F195BBE9E4B2F70A9B1A41429002C2998FAB0F2D6956731819D9F5175B92FECE43178BC69ABEC6E2C18EA88289C5B14C58227640D02F614A9A881633816B9DCAC79E4721EF6E42691902AD1CF565600BAA8019310CAA0AC1087A86846C2E9B96B82C3F0CE52EE73760111061EF090DCBF47882710302A65FBDCF380F84703FE3D4FF7ADD0CB7ED65C889DD6EEC24D01F92771DF3F3D8DFB4BDE234D4A35AB20B22BF5D749398C9B6AE5C7B62DC11ACD887A49586238F5B6D37B47EA6953C3E339A9B40EF3EB01DD70F69253BA9A262777C75DF175195D172BD8233FC7B6F207154EF6E2F47533E359D24EB312A292C756C34A2D55A16452829DAD7A9731E2026E56486F6A3C07380DCA1AFFF270464DA8FF34621FBA715C5853EB1D4EA1C4E23B43CD1CDE1F252B728875F187626A813B4166CC34A62A5D6867E0B605641CEE8025F0AD73DBE4443286CA05A0B8E53
-20180422163933 2 6 100 7679 2 ECCC9B93ED119552D36A774B288F541A81536A13B8D687B23174D680CE3F21B8FA088685F5B965215AFA69736E741A3AFC2AC82CE16162A1E4F0012F28998A638AA98D0789D6C58D92F207EAAA33E467C801891B8D37651B66E0942CF6AB7FD8E0D09A6D597D582BA48563F1450C3300218874730D26EE8B6505059C95C1C764D5FD736BF0A64FAD10F0C7D52A8A57C3FBD653887AAA890DA7AFEDA55DAF702EFF06CC722D147DAA2C8B78F0707F51D2B326BEF8972F5A289829E998B94D98E0ED663143797B569F3A6B56897B5726A38B042806FDFDAA367A4F63C4BA31114300B6290828321C30B25DF97F273041E30A404836E84BB32E0620DC558047FC011A1205126F84D9F8EA5E607FC297E5C9FA00D803026D8126C08EF68B49F6A6C55DCB06EED0B666880CD49FCBFF598055D5E40303669CBC55D85F583DA5EF4F320D6E6A50ECBBFAF8C1F7209655EEAA58BFC18EB9FA20B29EC63FBC810C3A2EDCF8E27FD98975C87D59D9C909895AA10CEA5F7594ADD3ED1EBDFE01BE0559423475592A0E2936E4671504337221F897AE3016BC4670C6B765F5FF1185933B26B1183BCB1E5591970F40A1402EB19EF2644E941F67ABB31935259308B4A5271541F41653EB5E77CCA82214C9C6F4E42E8A3C46CC9BE15BC868BC45B28027E515A16554B9D4F6AB57CFFE42CFE0B42BF83E53F27B39AD95E000C329F716E51D15D6CD211E87AAA83A0F1175F5E1E8963A57DA656FBC19FB42661F14328B05CA7F1A83F49044A5086E6AF56225B8783450E43CB1B6F19061441AF58053BBFAACBC3A80FF5F19A8BD873F487A8FFE3DECD35E77EB2C26387EF66A3EED98C773211914115AFD0776FDAC90CB65479DFE59C0D199F195BBE9E4B2F70A9B1A41429002C2998FAB0F2D6956731819D9F5175B92FECE43178BC69ABEC6E2C18EA88289C5B14C58227640D02F614A9A881633816B9DCAC79E4721EF6E42691902AD1CF565600BAA8019310CAA0AC1087A86846C2E9B96B82C3F0CE52EE73760111061EF090DCBF47882710302A65FBDCF380F84703FE3D4FF7ADD0CB7ED65C889DD6EEC24D01F92771DF3F3D8DFB4BDE234D4A35AB20B22BF5D749398C9B6AE5C7B62DC11ACD887A49586238F5B6D37B47EA6953C3E339A9B40EF3EB01DD70F69253BA9A262777C75DF175195D172BD8233FC7B6F207154EF6E2F47533E359D24EB312A292C756C34A2D55A16452829DAD7A9731E2026E56486F6A3C07380DCA1AFFF270464DA8FF34621FBA715C5853EB1D4EA1C4E23B43CD1CDE1F252B728875F187626A813B4166CC34A62A5D6867E0B605641CEE8025F0AD73DBE4443286CA05B02DF5B
-20180423004105 2 6 100 7679 2 ECCC9B93ED119552D36A774B288F541A81536A13B8D687B23174D680CE3F21B8FA088685F5B965215AFA69736E741A3AFC2AC82CE16162A1E4F0012F28998A638AA98D0789D6C58D92F207EAAA33E467C801891B8D37651B66E0942CF6AB7FD8E0D09A6D597D582BA48563F1450C3300218874730D26EE8B6505059C95C1C764D5FD736BF0A64FAD10F0C7D52A8A57C3FBD653887AAA890DA7AFEDA55DAF702EFF06CC722D147DAA2C8B78F0707F51D2B326BEF8972F5A289829E998B94D98E0ED663143797B569F3A6B56897B5726A38B042806FDFDAA367A4F63C4BA31114300B6290828321C30B25DF97F273041E30A404836E84BB32E0620DC558047FC011A1205126F84D9F8EA5E607FC297E5C9FA00D803026D8126C08EF68B49F6A6C55DCB06EED0B666880CD49FCBFF598055D5E40303669CBC55D85F583DA5EF4F320D6E6A50ECBBFAF8C1F7209655EEAA58BFC18EB9FA20B29EC63FBC810C3A2EDCF8E27FD98975C87D59D9C909895AA10CEA5F7594ADD3ED1EBDFE01BE0559423475592A0E2936E4671504337221F897AE3016BC4670C6B765F5FF1185933B26B1183BCB1E5591970F40A1402EB19EF2644E941F67ABB31935259308B4A5271541F41653EB5E77CCA82214C9C6F4E42E8A3C46CC9BE15BC868BC45B28027E515A16554B9D4F6AB57CFFE42CFE0B42BF83E53F27B39AD95E000C329F716E51D15D6CD211E87AAA83A0F1175F5E1E8963A57DA656FBC19FB42661F14328B05CA7F1A83F49044A5086E6AF56225B8783450E43CB1B6F19061441AF58053BBFAACBC3A80FF5F19A8BD873F487A8FFE3DECD35E77EB2C26387EF66A3EED98C773211914115AFD0776FDAC90CB65479DFE59C0D199F195BBE9E4B2F70A9B1A41429002C2998FAB0F2D6956731819D9F5175B92FECE43178BC69ABEC6E2C18EA88289C5B14C58227640D02F614A9A881633816B9DCAC79E4721EF6E42691902AD1CF565600BAA8019310CAA0AC1087A86846C2E9B96B82C3F0CE52EE73760111061EF090DCBF47882710302A65FBDCF380F84703FE3D4FF7ADD0CB7ED65C889DD6EEC24D01F92771DF3F3D8DFB4BDE234D4A35AB20B22BF5D749398C9B6AE5C7B62DC11ACD887A49586238F5B6D37B47EA6953C3E339A9B40EF3EB01DD70F69253BA9A262777C75DF175195D172BD8233FC7B6F207154EF6E2F47533E359D24EB312A292C756C34A2D55A16452829DAD7A9731E2026E56486F6A3C07380DCA1AFFF270464DA8FF34621FBA715C5853EB1D4EA1C4E23B43CD1CDE1F252B728875F187626A813B4166CC34A62A5D6867E0B605641CEE8025F0AD73DBE4443286CA060EDD493
-20180423045850 2 6 100 7679 5 ECCC9B93ED119552D36A774B288F541A81536A13B8D687B23174D680CE3F21B8FA088685F5B965215AFA69736E741A3AFC2AC82CE16162A1E4F0012F28998A638AA98D0789D6C58D92F207EAAA33E467C801891B8D37651B66E0942CF6AB7FD8E0D09A6D597D582BA48563F1450C3300218874730D26EE8B6505059C95C1C764D5FD736BF0A64FAD10F0C7D52A8A57C3FBD653887AAA890DA7AFEDA55DAF702EFF06CC722D147DAA2C8B78F0707F51D2B326BEF8972F5A289829E998B94D98E0ED663143797B569F3A6B56897B5726A38B042806FDFDAA367A4F63C4BA31114300B6290828321C30B25DF97F273041E30A404836E84BB32E0620DC558047FC011A1205126F84D9F8EA5E607FC297E5C9FA00D803026D8126C08EF68B49F6A6C55DCB06EED0B666880CD49FCBFF598055D5E40303669CBC55D85F583DA5EF4F320D6E6A50ECBBFAF8C1F7209655EEAA58BFC18EB9FA20B29EC63FBC810C3A2EDCF8E27FD98975C87D59D9C909895AA10CEA5F7594ADD3ED1EBDFE01BE0559423475592A0E2936E4671504337221F897AE3016BC4670C6B765F5FF1185933B26B1183BCB1E5591970F40A1402EB19EF2644E941F67ABB31935259308B4A5271541F41653EB5E77CCA82214C9C6F4E42E8A3C46CC9BE15BC868BC45B28027E515A16554B9D4F6AB57CFFE42CFE0B42BF83E53F27B39AD95E000C329F716E51D15D6CD211E87AAA83A0F1175F5E1E8963A57DA656FBC19FB42661F14328B05CA7F1A83F49044A5086E6AF56225B8783450E43CB1B6F19061441AF58053BBFAACBC3A80FF5F19A8BD873F487A8FFE3DECD35E77EB2C26387EF66A3EED98C773211914115AFD0776FDAC90CB65479DFE59C0D199F195BBE9E4B2F70A9B1A41429002C2998FAB0F2D6956731819D9F5175B92FECE43178BC69ABEC6E2C18EA88289C5B14C58227640D02F614A9A881633816B9DCAC79E4721EF6E42691902AD1CF565600BAA8019310CAA0AC1087A86846C2E9B96B82C3F0CE52EE73760111061EF090DCBF47882710302A65FBDCF380F84703FE3D4FF7ADD0CB7ED65C889DD6EEC24D01F92771DF3F3D8DFB4BDE234D4A35AB20B22BF5D749398C9B6AE5C7B62DC11ACD887A49586238F5B6D37B47EA6953C3E339A9B40EF3EB01DD70F69253BA9A262777C75DF175195D172BD8233FC7B6F207154EF6E2F47533E359D24EB312A292C756C34A2D55A16452829DAD7A9731E2026E56486F6A3C07380DCA1AFFF270464DA8FF34621FBA715C5853EB1D4EA1C4E23B43CD1CDE1F252B728875F187626A813B4166CC34A62A5D6867E0B605641CEE8025F0AD73DBE4443286CA06410777F
-20180423175352 2 6 100 7679 2 ECCC9B93ED119552D36A774B288F541A81536A13B8D687B23174D680CE3F21B8FA088685F5B965215AFA69736E741A3AFC2AC82CE16162A1E4F0012F28998A638AA98D0789D6C58D92F207EAAA33E467C801891B8D37651B66E0942CF6AB7FD8E0D09A6D597D582BA48563F1450C3300218874730D26EE8B6505059C95C1C764D5FD736BF0A64FAD10F0C7D52A8A57C3FBD653887AAA890DA7AFEDA55DAF702EFF06CC722D147DAA2C8B78F0707F51D2B326BEF8972F5A289829E998B94D98E0ED663143797B569F3A6B56897B5726A38B042806FDFDAA367A4F63C4BA31114300B6290828321C30B25DF97F273041E30A404836E84BB32E0620DC558047FC011A1205126F84D9F8EA5E607FC297E5C9FA00D803026D8126C08EF68B49F6A6C55DCB06EED0B666880CD49FCBFF598055D5E40303669CBC55D85F583DA5EF4F320D6E6A50ECBBFAF8C1F7209655EEAA58BFC18EB9FA20B29EC63FBC810C3A2EDCF8E27FD98975C87D59D9C909895AA10CEA5F7594ADD3ED1EBDFE01BE0559423475592A0E2936E4671504337221F897AE3016BC4670C6B765F5FF1185933B26B1183BCB1E5591970F40A1402EB19EF2644E941F67ABB31935259308B4A5271541F41653EB5E77CCA82214C9C6F4E42E8A3C46CC9BE15BC868BC45B28027E515A16554B9D4F6AB57CFFE42CFE0B42BF83E53F27B39AD95E000C329F716E51D15D6CD211E87AAA83A0F1175F5E1E8963A57DA656FBC19FB42661F14328B05CA7F1A83F49044A5086E6AF56225B8783450E43CB1B6F19061441AF58053BBFAACBC3A80FF5F19A8BD873F487A8FFE3DECD35E77EB2C26387EF66A3EED98C773211914115AFD0776FDAC90CB65479DFE59C0D199F195BBE9E4B2F70A9B1A41429002C2998FAB0F2D6956731819D9F5175B92FECE43178BC69ABEC6E2C18EA88289C5B14C58227640D02F614A9A881633816B9DCAC79E4721EF6E42691902AD1CF565600BAA8019310CAA0AC1087A86846C2E9B96B82C3F0CE52EE73760111061EF090DCBF47882710302A65FBDCF380F84703FE3D4FF7ADD0CB7ED65C889DD6EEC24D01F92771DF3F3D8DFB4BDE234D4A35AB20B22BF5D749398C9B6AE5C7B62DC11ACD887A49586238F5B6D37B47EA6953C3E339A9B40EF3EB01DD70F69253BA9A262777C75DF175195D172BD8233FC7B6F207154EF6E2F47533E359D24EB312A292C756C34A2D55A16452829DAD7A9731E2026E56486F6A3C07380DCA1AFFF270464DA8FF34621FBA715C5853EB1D4EA1C4E23B43CD1CDE1F252B728875F187626A813B4166CC34A62A5D6867E0B605641CEE8025F0AD73DBE4443286CA06D85A5C3
-20180424034739 2 6 100 7679 5 ECCC9B93ED119552D36A774B288F541A81536A13B8D687B23174D680CE3F21B8FA088685F5B965215AFA69736E741A3AFC2AC82CE16162A1E4F0012F28998A638AA98D0789D6C58D92F207EAAA33E467C801891B8D37651B66E0942CF6AB7FD8E0D09A6D597D582BA48563F1450C3300218874730D26EE8B6505059C95C1C764D5FD736BF0A64FAD10F0C7D52A8A57C3FBD653887AAA890DA7AFEDA55DAF702EFF06CC722D147DAA2C8B78F0707F51D2B326BEF8972F5A289829E998B94D98E0ED663143797B569F3A6B56897B5726A38B042806FDFDAA367A4F63C4BA31114300B6290828321C30B25DF97F273041E30A404836E84BB32E0620DC558047FC011A1205126F84D9F8EA5E607FC297E5C9FA00D803026D8126C08EF68B49F6A6C55DCB06EED0B666880CD49FCBFF598055D5E40303669CBC55D85F583DA5EF4F320D6E6A50ECBBFAF8C1F7209655EEAA58BFC18EB9FA20B29EC63FBC810C3A2EDCF8E27FD98975C87D59D9C909895AA10CEA5F7594ADD3ED1EBDFE01BE0559423475592A0E2936E4671504337221F897AE3016BC4670C6B765F5FF1185933B26B1183BCB1E5591970F40A1402EB19EF2644E941F67ABB31935259308B4A5271541F41653EB5E77CCA82214C9C6F4E42E8A3C46CC9BE15BC868BC45B28027E515A16554B9D4F6AB57CFFE42CFE0B42BF83E53F27B39AD95E000C329F716E51D15D6CD211E87AAA83A0F1175F5E1E8963A57DA656FBC19FB42661F14328B05CA7F1A83F49044A5086E6AF56225B8783450E43CB1B6F19061441AF58053BBFAACBC3A80FF5F19A8BD873F487A8FFE3DECD35E77EB2C26387EF66A3EED98C773211914115AFD0776FDAC90CB65479DFE59C0D199F195BBE9E4B2F70A9B1A41429002C2998FAB0F2D6956731819D9F5175B92FECE43178BC69ABEC6E2C18EA88289C5B14C58227640D02F614A9A881633816B9DCAC79E4721EF6E42691902AD1CF565600BAA8019310CAA0AC1087A86846C2E9B96B82C3F0CE52EE73760111061EF090DCBF47882710302A65FBDCF380F84703FE3D4FF7ADD0CB7ED65C889DD6EEC24D01F92771DF3F3D8DFB4BDE234D4A35AB20B22BF5D749398C9B6AE5C7B62DC11ACD887A49586238F5B6D37B47EA6953C3E339A9B40EF3EB01DD70F69253BA9A262777C75DF175195D172BD8233FC7B6F207154EF6E2F47533E359D24EB312A292C756C34A2D55A16452829DAD7A9731E2026E56486F6A3C07380DCA1AFFF270464DA8FF34621FBA715C5853EB1D4EA1C4E23B43CD1CDE1F252B728875F187626A813B4166CC34A62A5D6867E0B605641CEE8025F0AD73DBE4443286CA074B2314F
-20180424155916 2 6 100 8191 5 FAEE1044985A5E9005F621D69401F45F006C4AC70C849E5C17F3D28A22FE2C86DEF3780E73C15BC778C65638702E1DF6193E19C79BC8A9CEC1D64759E6E8E1B3754AAD1F82819BDB1F1E224F7D7BFF62061D89F6AE8D8EAF444A543333A4E71A4EBEE16AA9FEAE434FD965B90E6B57A198C12619CC31EF4F2BA3ACEA4C0D31EDD7BD715FE76FCD9282221F27F6CFD678ABC0458E4EDFBB72FB23333A3137C1C9AEB0AE4E5D98148527A5670311C0181861C1305901FF9704C64F88B75AD76574ABE3B5CEAAC2F675F5A56B807B2D9FFEDC975C7CFC6C697A18ED7F3D76C164FE108255F43971A3CCEE8FDC5E95F38B6ED8F8B150E17A7780E2D5CFD9A4D35BC4E2B3C3F4F286DC9DD0A8A53A22E643AD29753AAAB58E4C268A4145B1958050895F7FF5EB300FD0435824024F6DA4C38039A621D8E553493D964479DB2C1647C5123A9ED27955117CB966D41BAB3FA2F6AE1CE0E9787E3C815B1E3A3E3002B0BC54A89D66A3B532E8152BB0FD681D134374B4F2197F0B451E4C68C589E1F213D42CB62FC749D0883D9A68B39B93A1582F957AC989E5664266BB53BB8A07C84F662D5E3B4D4B277840A98B37F8A2CDF892085AF77A0AD370B2A4649F2381B7136AEB189421C6C801DC4F20273922A57C76DB4DB487DFC33DA2AC490C77E8ABA4AC719E6F0428A37ADBBE04F776199ACE29C1BC3B8A1F8E0D049628FDA016735559589D660FB23421D29745528E160F60B5D1923E685D0E04BE9DAC15C90BCAC4F4A7FD5CE52950734F2A849CAAB083DD18324EE82D1679146E60C290A97E2C94FBFEEDD88DE9EBEB346DF9E11AE14F4540A84F98B210E5366A03A82128986543C48FC3867431B2531AF99B379CE7E8D3105C574B0D4974295E98EFA2C01AC31C80CB1654BCEFA8467A55BC7B55ADB92DC1BE438006E5392ED521B5817558DE5E38172D023E3236EEAE34037E92EA61D6DA463212E012E603709D65EBE8062644A17B1A00FF5DE6E42FD4B3812DACC8C85754616A5539AB60FEF0F9170413E94D3052CBA3A7B9FCF46F318D30DD88DD988C9C16F5BB8823538A8DBC4830B00E7CE5346277E4DAD464128025955E7E5FD184C40EEC184B6143FC4720DA45C7DE3ED4849D6ABC89B1C01D6761660EA595B65E7F70457A32A4D63CCC6FC9736ABDDB9AE9FC8FB90388DAB7BD2189B38488B17DA76B96DAB6871475F59FC36BD53076293EBF9970A1081BA84E44A3A109F6B7231E64C1C54BF9AABD2320185DC054672B2F8F52172CD262F14CCA3237542F421A2413DF5E371DD4F1297E01D81E392A6C4F3BBABAA3091B2F10DB1C4A2C12B0DDDC279F7AD45992225ACA55ADA7CB6370B07B0CD5B935B8DF18BFFA2567EBF77658772D043318B6BA159DBD3AA48C7A509A1F887A05118CBE1470599C2683D9C00DAA5480A05FFDDF7612E6CFACFC9C07
-20180424222331 2 6 100 8191 5 FAEE1044985A5E9005F621D69401F45F006C4AC70C849E5C17F3D28A22FE2C86DEF3780E73C15BC778C65638702E1DF6193E19C79BC8A9CEC1D64759E6E8E1B3754AAD1F82819BDB1F1E224F7D7BFF62061D89F6AE8D8EAF444A543333A4E71A4EBEE16AA9FEAE434FD965B90E6B57A198C12619CC31EF4F2BA3ACEA4C0D31EDD7BD715FE76FCD9282221F27F6CFD678ABC0458E4EDFBB72FB23333A3137C1C9AEB0AE4E5D98148527A5670311C0181861C1305901FF9704C64F88B75AD76574ABE3B5CEAAC2F675F5A56B807B2D9FFEDC975C7CFC6C697A18ED7F3D76C164FE108255F43971A3CCEE8FDC5E95F38B6ED8F8B150E17A7780E2D5CFD9A4D35BC4E2B3C3F4F286DC9DD0A8A53A22E643AD29753AAAB58E4C268A4145B1958050895F7FF5EB300FD0435824024F6DA4C38039A621D8E553493D964479DB2C1647C5123A9ED27955117CB966D41BAB3FA2F6AE1CE0E9787E3C815B1E3A3E3002B0BC54A89D66A3B532E8152BB0FD681D134374B4F2197F0B451E4C68C589E1F213D42CB62FC749D0883D9A68B39B93A1582F957AC989E5664266BB53BB8A07C84F662D5E3B4D4B277840A98B37F8A2CDF892085AF77A0AD370B2A4649F2381B7136AEB189421C6C801DC4F20273922A57C76DB4DB487DFC33DA2AC490C77E8ABA4AC719E6F0428A37ADBBE04F776199ACE29C1BC3B8A1F8E0D049628FDA016735559589D660FB23421D29745528E160F60B5D1923E685D0E04BE9DAC15C90BCAC4F4A7FD5CE52950734F2A849CAAB083DD18324EE82D1679146E60C290A97E2C94FBFEEDD88DE9EBEB346DF9E11AE14F4540A84F98B210E5366A03A82128986543C48FC3867431B2531AF99B379CE7E8D3105C574B0D4974295E98EFA2C01AC31C80CB1654BCEFA8467A55BC7B55ADB92DC1BE438006E5392ED521B5817558DE5E38172D023E3236EEAE34037E92EA61D6DA463212E012E603709D65EBE8062644A17B1A00FF5DE6E42FD4B3812DACC8C85754616A5539AB60FEF0F9170413E94D3052CBA3A7B9FCF46F318D30DD88DD988C9C16F5BB8823538A8DBC4830B00E7CE5346277E4DAD464128025955E7E5FD184C40EEC184B6143FC4720DA45C7DE3ED4849D6ABC89B1C01D6761660EA595B65E7F70457A32A4D63CCC6FC9736ABDDB9AE9FC8FB90388DAB7BD2189B38488B17DA76B96DAB6871475F59FC36BD53076293EBF9970A1081BA84E44A3A109F6B7231E64C1C54BF9AABD2320185DC054672B2F8F52172CD262F14CCA3237542F421A2413DF5E371DD4F1297E01D81E392A6C4F3BBABAA3091B2F10DB1C4A2C12B0DDDC279F7AD45992225ACA55ADA7CB6370B07B0CD5B935B8DF18BFFA2567EBF77658772D043318B6BA159DBD3AA48C7A509A1F887A05118CBE1470599C2683D9C00DAA5480A05FFDDF7612E6CFB180A887
-20180425154127 2 6 100 8191 2 FAEE1044985A5E9005F621D69401F45F006C4AC70C849E5C17F3D28A22FE2C86DEF3780E73C15BC778C65638702E1DF6193E19C79BC8A9CEC1D64759E6E8E1B3754AAD1F82819BDB1F1E224F7D7BFF62061D89F6AE8D8EAF444A543333A4E71A4EBEE16AA9FEAE434FD965B90E6B57A198C12619CC31EF4F2BA3ACEA4C0D31EDD7BD715FE76FCD9282221F27F6CFD678ABC0458E4EDFBB72FB23333A3137C1C9AEB0AE4E5D98148527A5670311C0181861C1305901FF9704C64F88B75AD76574ABE3B5CEAAC2F675F5A56B807B2D9FFEDC975C7CFC6C697A18ED7F3D76C164FE108255F43971A3CCEE8FDC5E95F38B6ED8F8B150E17A7780E2D5CFD9A4D35BC4E2B3C3F4F286DC9DD0A8A53A22E643AD29753AAAB58E4C268A4145B1958050895F7FF5EB300FD0435824024F6DA4C38039A621D8E553493D964479DB2C1647C5123A9ED27955117CB966D41BAB3FA2F6AE1CE0E9787E3C815B1E3A3E3002B0BC54A89D66A3B532E8152BB0FD681D134374B4F2197F0B451E4C68C589E1F213D42CB62FC749D0883D9A68B39B93A1582F957AC989E5664266BB53BB8A07C84F662D5E3B4D4B277840A98B37F8A2CDF892085AF77A0AD370B2A4649F2381B7136AEB189421C6C801DC4F20273922A57C76DB4DB487DFC33DA2AC490C77E8ABA4AC719E6F0428A37ADBBE04F776199ACE29C1BC3B8A1F8E0D049628FDA016735559589D660FB23421D29745528E160F60B5D1923E685D0E04BE9DAC15C90BCAC4F4A7FD5CE52950734F2A849CAAB083DD18324EE82D1679146E60C290A97E2C94FBFEEDD88DE9EBEB346DF9E11AE14F4540A84F98B210E5366A03A82128986543C48FC3867431B2531AF99B379CE7E8D3105C574B0D4974295E98EFA2C01AC31C80CB1654BCEFA8467A55BC7B55ADB92DC1BE438006E5392ED521B5817558DE5E38172D023E3236EEAE34037E92EA61D6DA463212E012E603709D65EBE8062644A17B1A00FF5DE6E42FD4B3812DACC8C85754616A5539AB60FEF0F9170413E94D3052CBA3A7B9FCF46F318D30DD88DD988C9C16F5BB8823538A8DBC4830B00E7CE5346277E4DAD464128025955E7E5FD184C40EEC184B6143FC4720DA45C7DE3ED4849D6ABC89B1C01D6761660EA595B65E7F70457A32A4D63CCC6FC9736ABDDB9AE9FC8FB90388DAB7BD2189B38488B17DA76B96DAB6871475F59FC36BD53076293EBF9970A1081BA84E44A3A109F6B7231E64C1C54BF9AABD2320185DC054672B2F8F52172CD262F14CCA3237542F421A2413DF5E371DD4F1297E01D81E392A6C4F3BBABAA3091B2F10DB1C4A2C12B0DDDC279F7AD45992225ACA55ADA7CB6370B07B0CD5B935B8DF18BFFA2567EBF77658772D043318B6BA159DBD3AA48C7A509A1F887A05118CBE1470599C2683D9C00DAA5480A05FFDDF7612E6CFBD59073B
-20180426001519 2 6 100 8191 2 FAEE1044985A5E9005F621D69401F45F006C4AC70C849E5C17F3D28A22FE2C86DEF3780E73C15BC778C65638702E1DF6193E19C79BC8A9CEC1D64759E6E8E1B3754AAD1F82819BDB1F1E224F7D7BFF62061D89F6AE8D8EAF444A543333A4E71A4EBEE16AA9FEAE434FD965B90E6B57A198C12619CC31EF4F2BA3ACEA4C0D31EDD7BD715FE76FCD9282221F27F6CFD678ABC0458E4EDFBB72FB23333A3137C1C9AEB0AE4E5D98148527A5670311C0181861C1305901FF9704C64F88B75AD76574ABE3B5CEAAC2F675F5A56B807B2D9FFEDC975C7CFC6C697A18ED7F3D76C164FE108255F43971A3CCEE8FDC5E95F38B6ED8F8B150E17A7780E2D5CFD9A4D35BC4E2B3C3F4F286DC9DD0A8A53A22E643AD29753AAAB58E4C268A4145B1958050895F7FF5EB300FD0435824024F6DA4C38039A621D8E553493D964479DB2C1647C5123A9ED27955117CB966D41BAB3FA2F6AE1CE0E9787E3C815B1E3A3E3002B0BC54A89D66A3B532E8152BB0FD681D134374B4F2197F0B451E4C68C589E1F213D42CB62FC749D0883D9A68B39B93A1582F957AC989E5664266BB53BB8A07C84F662D5E3B4D4B277840A98B37F8A2CDF892085AF77A0AD370B2A4649F2381B7136AEB189421C6C801DC4F20273922A57C76DB4DB487DFC33DA2AC490C77E8ABA4AC719E6F0428A37ADBBE04F776199ACE29C1BC3B8A1F8E0D049628FDA016735559589D660FB23421D29745528E160F60B5D1923E685D0E04BE9DAC15C90BCAC4F4A7FD5CE52950734F2A849CAAB083DD18324EE82D1679146E60C290A97E2C94FBFEEDD88DE9EBEB346DF9E11AE14F4540A84F98B210E5366A03A82128986543C48FC3867431B2531AF99B379CE7E8D3105C574B0D4974295E98EFA2C01AC31C80CB1654BCEFA8467A55BC7B55ADB92DC1BE438006E5392ED521B5817558DE5E38172D023E3236EEAE34037E92EA61D6DA463212E012E603709D65EBE8062644A17B1A00FF5DE6E42FD4B3812DACC8C85754616A5539AB60FEF0F9170413E94D3052CBA3A7B9FCF46F318D30DD88DD988C9C16F5BB8823538A8DBC4830B00E7CE5346277E4DAD464128025955E7E5FD184C40EEC184B6143FC4720DA45C7DE3ED4849D6ABC89B1C01D6761660EA595B65E7F70457A32A4D63CCC6FC9736ABDDB9AE9FC8FB90388DAB7BD2189B38488B17DA76B96DAB6871475F59FC36BD53076293EBF9970A1081BA84E44A3A109F6B7231E64C1C54BF9AABD2320185DC054672B2F8F52172CD262F14CCA3237542F421A2413DF5E371DD4F1297E01D81E392A6C4F3BBABAA3091B2F10DB1C4A2C12B0DDDC279F7AD45992225ACA55ADA7CB6370B07B0CD5B935B8DF18BFFA2567EBF77658772D043318B6BA159DBD3AA48C7A509A1F887A05118CBE1470599C2683D9C00DAA5480A05FFDDF7612E6CFC3391D93
-20180426011753 2 6 100 8191 5 FAEE1044985A5E9005F621D69401F45F006C4AC70C849E5C17F3D28A22FE2C86DEF3780E73C15BC778C65638702E1DF6193E19C79BC8A9CEC1D64759E6E8E1B3754AAD1F82819BDB1F1E224F7D7BFF62061D89F6AE8D8EAF444A543333A4E71A4EBEE16AA9FEAE434FD965B90E6B57A198C12619CC31EF4F2BA3ACEA4C0D31EDD7BD715FE76FCD9282221F27F6CFD678ABC0458E4EDFBB72FB23333A3137C1C9AEB0AE4E5D98148527A5670311C0181861C1305901FF9704C64F88B75AD76574ABE3B5CEAAC2F675F5A56B807B2D9FFEDC975C7CFC6C697A18ED7F3D76C164FE108255F43971A3CCEE8FDC5E95F38B6ED8F8B150E17A7780E2D5CFD9A4D35BC4E2B3C3F4F286DC9DD0A8A53A22E643AD29753AAAB58E4C268A4145B1958050895F7FF5EB300FD0435824024F6DA4C38039A621D8E553493D964479DB2C1647C5123A9ED27955117CB966D41BAB3FA2F6AE1CE0E9787E3C815B1E3A3E3002B0BC54A89D66A3B532E8152BB0FD681D134374B4F2197F0B451E4C68C589E1F213D42CB62FC749D0883D9A68B39B93A1582F957AC989E5664266BB53BB8A07C84F662D5E3B4D4B277840A98B37F8A2CDF892085AF77A0AD370B2A4649F2381B7136AEB189421C6C801DC4F20273922A57C76DB4DB487DFC33DA2AC490C77E8ABA4AC719E6F0428A37ADBBE04F776199ACE29C1BC3B8A1F8E0D049628FDA016735559589D660FB23421D29745528E160F60B5D1923E685D0E04BE9DAC15C90BCAC4F4A7FD5CE52950734F2A849CAAB083DD18324EE82D1679146E60C290A97E2C94FBFEEDD88DE9EBEB346DF9E11AE14F4540A84F98B210E5366A03A82128986543C48FC3867431B2531AF99B379CE7E8D3105C574B0D4974295E98EFA2C01AC31C80CB1654BCEFA8467A55BC7B55ADB92DC1BE438006E5392ED521B5817558DE5E38172D023E3236EEAE34037E92EA61D6DA463212E012E603709D65EBE8062644A17B1A00FF5DE6E42FD4B3812DACC8C85754616A5539AB60FEF0F9170413E94D3052CBA3A7B9FCF46F318D30DD88DD988C9C16F5BB8823538A8DBC4830B00E7CE5346277E4DAD464128025955E7E5FD184C40EEC184B6143FC4720DA45C7DE3ED4849D6ABC89B1C01D6761660EA595B65E7F70457A32A4D63CCC6FC9736ABDDB9AE9FC8FB90388DAB7BD2189B38488B17DA76B96DAB6871475F59FC36BD53076293EBF9970A1081BA84E44A3A109F6B7231E64C1C54BF9AABD2320185DC054672B2F8F52172CD262F14CCA3237542F421A2413DF5E371DD4F1297E01D81E392A6C4F3BBABAA3091B2F10DB1C4A2C12B0DDDC279F7AD45992225ACA55ADA7CB6370B07B0CD5B935B8DF18BFFA2567EBF77658772D043318B6BA159DBD3AA48C7A509A1F887A05118CBE1470599C2683D9C00DAA5480A05FFDDF7612E6CFC3E66CFF
-20180426121313 2 6 100 8191 5 FAEE1044985A5E9005F621D69401F45F006C4AC70C849E5C17F3D28A22FE2C86DEF3780E73C15BC778C65638702E1DF6193E19C79BC8A9CEC1D64759E6E8E1B3754AAD1F82819BDB1F1E224F7D7BFF62061D89F6AE8D8EAF444A543333A4E71A4EBEE16AA9FEAE434FD965B90E6B57A198C12619CC31EF4F2BA3ACEA4C0D31EDD7BD715FE76FCD9282221F27F6CFD678ABC0458E4EDFBB72FB23333A3137C1C9AEB0AE4E5D98148527A5670311C0181861C1305901FF9704C64F88B75AD76574ABE3B5CEAAC2F675F5A56B807B2D9FFEDC975C7CFC6C697A18ED7F3D76C164FE108255F43971A3CCEE8FDC5E95F38B6ED8F8B150E17A7780E2D5CFD9A4D35BC4E2B3C3F4F286DC9DD0A8A53A22E643AD29753AAAB58E4C268A4145B1958050895F7FF5EB300FD0435824024F6DA4C38039A621D8E553493D964479DB2C1647C5123A9ED27955117CB966D41BAB3FA2F6AE1CE0E9787E3C815B1E3A3E3002B0BC54A89D66A3B532E8152BB0FD681D134374B4F2197F0B451E4C68C589E1F213D42CB62FC749D0883D9A68B39B93A1582F957AC989E5664266BB53BB8A07C84F662D5E3B4D4B277840A98B37F8A2CDF892085AF77A0AD370B2A4649F2381B7136AEB189421C6C801DC4F20273922A57C76DB4DB487DFC33DA2AC490C77E8ABA4AC719E6F0428A37ADBBE04F776199ACE29C1BC3B8A1F8E0D049628FDA016735559589D660FB23421D29745528E160F60B5D1923E685D0E04BE9DAC15C90BCAC4F4A7FD5CE52950734F2A849CAAB083DD18324EE82D1679146E60C290A97E2C94FBFEEDD88DE9EBEB346DF9E11AE14F4540A84F98B210E5366A03A82128986543C48FC3867431B2531AF99B379CE7E8D3105C574B0D4974295E98EFA2C01AC31C80CB1654BCEFA8467A55BC7B55ADB92DC1BE438006E5392ED521B5817558DE5E38172D023E3236EEAE34037E92EA61D6DA463212E012E603709D65EBE8062644A17B1A00FF5DE6E42FD4B3812DACC8C85754616A5539AB60FEF0F9170413E94D3052CBA3A7B9FCF46F318D30DD88DD988C9C16F5BB8823538A8DBC4830B00E7CE5346277E4DAD464128025955E7E5FD184C40EEC184B6143FC4720DA45C7DE3ED4849D6ABC89B1C01D6761660EA595B65E7F70457A32A4D63CCC6FC9736ABDDB9AE9FC8FB90388DAB7BD2189B38488B17DA76B96DAB6871475F59FC36BD53076293EBF9970A1081BA84E44A3A109F6B7231E64C1C54BF9AABD2320185DC054672B2F8F52172CD262F14CCA3237542F421A2413DF5E371DD4F1297E01D81E392A6C4F3BBABAA3091B2F10DB1C4A2C12B0DDDC279F7AD45992225ACA55ADA7CB6370B07B0CD5B935B8DF18BFFA2567EBF77658772D043318B6BA159DBD3AA48C7A509A1F887A05118CBE1470599C2683D9C00DAA5480A05FFDDF7612E6CFCB4C31C7
-20180426192735 2 6 100 8191 5 FAEE1044985A5E9005F621D69401F45F006C4AC70C849E5C17F3D28A22FE2C86DEF3780E73C15BC778C65638702E1DF6193E19C79BC8A9CEC1D64759E6E8E1B3754AAD1F82819BDB1F1E224F7D7BFF62061D89F6AE8D8EAF444A543333A4E71A4EBEE16AA9FEAE434FD965B90E6B57A198C12619CC31EF4F2BA3ACEA4C0D31EDD7BD715FE76FCD9282221F27F6CFD678ABC0458E4EDFBB72FB23333A3137C1C9AEB0AE4E5D98148527A5670311C0181861C1305901FF9704C64F88B75AD76574ABE3B5CEAAC2F675F5A56B807B2D9FFEDC975C7CFC6C697A18ED7F3D76C164FE108255F43971A3CCEE8FDC5E95F38B6ED8F8B150E17A7780E2D5CFD9A4D35BC4E2B3C3F4F286DC9DD0A8A53A22E643AD29753AAAB58E4C268A4145B1958050895F7FF5EB300FD0435824024F6DA4C38039A621D8E553493D964479DB2C1647C5123A9ED27955117CB966D41BAB3FA2F6AE1CE0E9787E3C815B1E3A3E3002B0BC54A89D66A3B532E8152BB0FD681D134374B4F2197F0B451E4C68C589E1F213D42CB62FC749D0883D9A68B39B93A1582F957AC989E5664266BB53BB8A07C84F662D5E3B4D4B277840A98B37F8A2CDF892085AF77A0AD370B2A4649F2381B7136AEB189421C6C801DC4F20273922A57C76DB4DB487DFC33DA2AC490C77E8ABA4AC719E6F0428A37ADBBE04F776199ACE29C1BC3B8A1F8E0D049628FDA016735559589D660FB23421D29745528E160F60B5D1923E685D0E04BE9DAC15C90BCAC4F4A7FD5CE52950734F2A849CAAB083DD18324EE82D1679146E60C290A97E2C94FBFEEDD88DE9EBEB346DF9E11AE14F4540A84F98B210E5366A03A82128986543C48FC3867431B2531AF99B379CE7E8D3105C574B0D4974295E98EFA2C01AC31C80CB1654BCEFA8467A55BC7B55ADB92DC1BE438006E5392ED521B5817558DE5E38172D023E3236EEAE34037E92EA61D6DA463212E012E603709D65EBE8062644A17B1A00FF5DE6E42FD4B3812DACC8C85754616A5539AB60FEF0F9170413E94D3052CBA3A7B9FCF46F318D30DD88DD988C9C16F5BB8823538A8DBC4830B00E7CE5346277E4DAD464128025955E7E5FD184C40EEC184B6143FC4720DA45C7DE3ED4849D6ABC89B1C01D6761660EA595B65E7F70457A32A4D63CCC6FC9736ABDDB9AE9FC8FB90388DAB7BD2189B38488B17DA76B96DAB6871475F59FC36BD53076293EBF9970A1081BA84E44A3A109F6B7231E64C1C54BF9AABD2320185DC054672B2F8F52172CD262F14CCA3237542F421A2413DF5E371DD4F1297E01D81E392A6C4F3BBABAA3091B2F10DB1C4A2C12B0DDDC279F7AD45992225ACA55ADA7CB6370B07B0CD5B935B8DF18BFFA2567EBF77658772D043318B6BA159DBD3AA48C7A509A1F887A05118CBE1470599C2683D9C00DAA5480A05FFDDF7612E6CFD02C1487
-20180427041246 2 6 100 8191 2 FAEE1044985A5E9005F621D69401F45F006C4AC70C849E5C17F3D28A22FE2C86DEF3780E73C15BC778C65638702E1DF6193E19C79BC8A9CEC1D64759E6E8E1B3754AAD1F82819BDB1F1E224F7D7BFF62061D89F6AE8D8EAF444A543333A4E71A4EBEE16AA9FEAE434FD965B90E6B57A198C12619CC31EF4F2BA3ACEA4C0D31EDD7BD715FE76FCD9282221F27F6CFD678ABC0458E4EDFBB72FB23333A3137C1C9AEB0AE4E5D98148527A5670311C0181861C1305901FF9704C64F88B75AD76574ABE3B5CEAAC2F675F5A56B807B2D9FFEDC975C7CFC6C697A18ED7F3D76C164FE108255F43971A3CCEE8FDC5E95F38B6ED8F8B150E17A7780E2D5CFD9A4D35BC4E2B3C3F4F286DC9DD0A8A53A22E643AD29753AAAB58E4C268A4145B1958050895F7FF5EB300FD0435824024F6DA4C38039A621D8E553493D964479DB2C1647C5123A9ED27955117CB966D41BAB3FA2F6AE1CE0E9787E3C815B1E3A3E3002B0BC54A89D66A3B532E8152BB0FD681D134374B4F2197F0B451E4C68C589E1F213D42CB62FC749D0883D9A68B39B93A1582F957AC989E5664266BB53BB8A07C84F662D5E3B4D4B277840A98B37F8A2CDF892085AF77A0AD370B2A4649F2381B7136AEB189421C6C801DC4F20273922A57C76DB4DB487DFC33DA2AC490C77E8ABA4AC719E6F0428A37ADBBE04F776199ACE29C1BC3B8A1F8E0D049628FDA016735559589D660FB23421D29745528E160F60B5D1923E685D0E04BE9DAC15C90BCAC4F4A7FD5CE52950734F2A849CAAB083DD18324EE82D1679146E60C290A97E2C94FBFEEDD88DE9EBEB346DF9E11AE14F4540A84F98B210E5366A03A82128986543C48FC3867431B2531AF99B379CE7E8D3105C574B0D4974295E98EFA2C01AC31C80CB1654BCEFA8467A55BC7B55ADB92DC1BE438006E5392ED521B5817558DE5E38172D023E3236EEAE34037E92EA61D6DA463212E012E603709D65EBE8062644A17B1A00FF5DE6E42FD4B3812DACC8C85754616A5539AB60FEF0F9170413E94D3052CBA3A7B9FCF46F318D30DD88DD988C9C16F5BB8823538A8DBC4830B00E7CE5346277E4DAD464128025955E7E5FD184C40EEC184B6143FC4720DA45C7DE3ED4849D6ABC89B1C01D6761660EA595B65E7F70457A32A4D63CCC6FC9736ABDDB9AE9FC8FB90388DAB7BD2189B38488B17DA76B96DAB6871475F59FC36BD53076293EBF9970A1081BA84E44A3A109F6B7231E64C1C54BF9AABD2320185DC054672B2F8F52172CD262F14CCA3237542F421A2413DF5E371DD4F1297E01D81E392A6C4F3BBABAA3091B2F10DB1C4A2C12B0DDDC279F7AD45992225ACA55ADA7CB6370B07B0CD5B935B8DF18BFFA2567EBF77658772D043318B6BA159DBD3AA48C7A509A1F887A05118CBE1470599C2683D9C00DAA5480A05FFDDF7612E6CFD60EF383
-20180427102113 2 6 100 8191 2 FAEE1044985A5E9005F621D69401F45F006C4AC70C849E5C17F3D28A22FE2C86DEF3780E73C15BC778C65638702E1DF6193E19C79BC8A9CEC1D64759E6E8E1B3754AAD1F82819BDB1F1E224F7D7BFF62061D89F6AE8D8EAF444A543333A4E71A4EBEE16AA9FEAE434FD965B90E6B57A198C12619CC31EF4F2BA3ACEA4C0D31EDD7BD715FE76FCD9282221F27F6CFD678ABC0458E4EDFBB72FB23333A3137C1C9AEB0AE4E5D98148527A5670311C0181861C1305901FF9704C64F88B75AD76574ABE3B5CEAAC2F675F5A56B807B2D9FFEDC975C7CFC6C697A18ED7F3D76C164FE108255F43971A3CCEE8FDC5E95F38B6ED8F8B150E17A7780E2D5CFD9A4D35BC4E2B3C3F4F286DC9DD0A8A53A22E643AD29753AAAB58E4C268A4145B1958050895F7FF5EB300FD0435824024F6DA4C38039A621D8E553493D964479DB2C1647C5123A9ED27955117CB966D41BAB3FA2F6AE1CE0E9787E3C815B1E3A3E3002B0BC54A89D66A3B532E8152BB0FD681D134374B4F2197F0B451E4C68C589E1F213D42CB62FC749D0883D9A68B39B93A1582F957AC989E5664266BB53BB8A07C84F662D5E3B4D4B277840A98B37F8A2CDF892085AF77A0AD370B2A4649F2381B7136AEB189421C6C801DC4F20273922A57C76DB4DB487DFC33DA2AC490C77E8ABA4AC719E6F0428A37ADBBE04F776199ACE29C1BC3B8A1F8E0D049628FDA016735559589D660FB23421D29745528E160F60B5D1923E685D0E04BE9DAC15C90BCAC4F4A7FD5CE52950734F2A849CAAB083DD18324EE82D1679146E60C290A97E2C94FBFEEDD88DE9EBEB346DF9E11AE14F4540A84F98B210E5366A03A82128986543C48FC3867431B2531AF99B379CE7E8D3105C574B0D4974295E98EFA2C01AC31C80CB1654BCEFA8467A55BC7B55ADB92DC1BE438006E5392ED521B5817558DE5E38172D023E3236EEAE34037E92EA61D6DA463212E012E603709D65EBE8062644A17B1A00FF5DE6E42FD4B3812DACC8C85754616A5539AB60FEF0F9170413E94D3052CBA3A7B9FCF46F318D30DD88DD988C9C16F5BB8823538A8DBC4830B00E7CE5346277E4DAD464128025955E7E5FD184C40EEC184B6143FC4720DA45C7DE3ED4849D6ABC89B1C01D6761660EA595B65E7F70457A32A4D63CCC6FC9736ABDDB9AE9FC8FB90388DAB7BD2189B38488B17DA76B96DAB6871475F59FC36BD53076293EBF9970A1081BA84E44A3A109F6B7231E64C1C54BF9AABD2320185DC054672B2F8F52172CD262F14CCA3237542F421A2413DF5E371DD4F1297E01D81E392A6C4F3BBABAA3091B2F10DB1C4A2C12B0DDDC279F7AD45992225ACA55ADA7CB6370B07B0CD5B935B8DF18BFFA2567EBF77658772D043318B6BA159DBD3AA48C7A509A1F887A05118CBE1470599C2683D9C00DAA5480A05FFDDF7612E6CFD9FE975B
-20180427110709 2 6 100 8191 5 FAEE1044985A5E9005F621D69401F45F006C4AC70C849E5C17F3D28A22FE2C86DEF3780E73C15BC778C65638702E1DF6193E19C79BC8A9CEC1D64759E6E8E1B3754AAD1F82819BDB1F1E224F7D7BFF62061D89F6AE8D8EAF444A543333A4E71A4EBEE16AA9FEAE434FD965B90E6B57A198C12619CC31EF4F2BA3ACEA4C0D31EDD7BD715FE76FCD9282221F27F6CFD678ABC0458E4EDFBB72FB23333A3137C1C9AEB0AE4E5D98148527A5670311C0181861C1305901FF9704C64F88B75AD76574ABE3B5CEAAC2F675F5A56B807B2D9FFEDC975C7CFC6C697A18ED7F3D76C164FE108255F43971A3CCEE8FDC5E95F38B6ED8F8B150E17A7780E2D5CFD9A4D35BC4E2B3C3F4F286DC9DD0A8A53A22E643AD29753AAAB58E4C268A4145B1958050895F7FF5EB300FD0435824024F6DA4C38039A621D8E553493D964479DB2C1647C5123A9ED27955117CB966D41BAB3FA2F6AE1CE0E9787E3C815B1E3A3E3002B0BC54A89D66A3B532E8152BB0FD681D134374B4F2197F0B451E4C68C589E1F213D42CB62FC749D0883D9A68B39B93A1582F957AC989E5664266BB53BB8A07C84F662D5E3B4D4B277840A98B37F8A2CDF892085AF77A0AD370B2A4649F2381B7136AEB189421C6C801DC4F20273922A57C76DB4DB487DFC33DA2AC490C77E8ABA4AC719E6F0428A37ADBBE04F776199ACE29C1BC3B8A1F8E0D049628FDA016735559589D660FB23421D29745528E160F60B5D1923E685D0E04BE9DAC15C90BCAC4F4A7FD5CE52950734F2A849CAAB083DD18324EE82D1679146E60C290A97E2C94FBFEEDD88DE9EBEB346DF9E11AE14F4540A84F98B210E5366A03A82128986543C48FC3867431B2531AF99B379CE7E8D3105C574B0D4974295E98EFA2C01AC31C80CB1654BCEFA8467A55BC7B55ADB92DC1BE438006E5392ED521B5817558DE5E38172D023E3236EEAE34037E92EA61D6DA463212E012E603709D65EBE8062644A17B1A00FF5DE6E42FD4B3812DACC8C85754616A5539AB60FEF0F9170413E94D3052CBA3A7B9FCF46F318D30DD88DD988C9C16F5BB8823538A8DBC4830B00E7CE5346277E4DAD464128025955E7E5FD184C40EEC184B6143FC4720DA45C7DE3ED4849D6ABC89B1C01D6761660EA595B65E7F70457A32A4D63CCC6FC9736ABDDB9AE9FC8FB90388DAB7BD2189B38488B17DA76B96DAB6871475F59FC36BD53076293EBF9970A1081BA84E44A3A109F6B7231E64C1C54BF9AABD2320185DC054672B2F8F52172CD262F14CCA3237542F421A2413DF5E371DD4F1297E01D81E392A6C4F3BBABAA3091B2F10DB1C4A2C12B0DDDC279F7AD45992225ACA55ADA7CB6370B07B0CD5B935B8DF18BFFA2567EBF77658772D043318B6BA159DBD3AA48C7A509A1F887A05118CBE1470599C2683D9C00DAA5480A05FFDDF7612E6CFDA77CFC7
-20180427115833 2 6 100 8191 5 FAEE1044985A5E9005F621D69401F45F006C4AC70C849E5C17F3D28A22FE2C86DEF3780E73C15BC778C65638702E1DF6193E19C79BC8A9CEC1D64759E6E8E1B3754AAD1F82819BDB1F1E224F7D7BFF62061D89F6AE8D8EAF444A543333A4E71A4EBEE16AA9FEAE434FD965B90E6B57A198C12619CC31EF4F2BA3ACEA4C0D31EDD7BD715FE76FCD9282221F27F6CFD678ABC0458E4EDFBB72FB23333A3137C1C9AEB0AE4E5D98148527A5670311C0181861C1305901FF9704C64F88B75AD76574ABE3B5CEAAC2F675F5A56B807B2D9FFEDC975C7CFC6C697A18ED7F3D76C164FE108255F43971A3CCEE8FDC5E95F38B6ED8F8B150E17A7780E2D5CFD9A4D35BC4E2B3C3F4F286DC9DD0A8A53A22E643AD29753AAAB58E4C268A4145B1958050895F7FF5EB300FD0435824024F6DA4C38039A621D8E553493D964479DB2C1647C5123A9ED27955117CB966D41BAB3FA2F6AE1CE0E9787E3C815B1E3A3E3002B0BC54A89D66A3B532E8152BB0FD681D134374B4F2197F0B451E4C68C589E1F213D42CB62FC749D0883D9A68B39B93A1582F957AC989E5664266BB53BB8A07C84F662D5E3B4D4B277840A98B37F8A2CDF892085AF77A0AD370B2A4649F2381B7136AEB189421C6C801DC4F20273922A57C76DB4DB487DFC33DA2AC490C77E8ABA4AC719E6F0428A37ADBBE04F776199ACE29C1BC3B8A1F8E0D049628FDA016735559589D660FB23421D29745528E160F60B5D1923E685D0E04BE9DAC15C90BCAC4F4A7FD5CE52950734F2A849CAAB083DD18324EE82D1679146E60C290A97E2C94FBFEEDD88DE9EBEB346DF9E11AE14F4540A84F98B210E5366A03A82128986543C48FC3867431B2531AF99B379CE7E8D3105C574B0D4974295E98EFA2C01AC31C80CB1654BCEFA8467A55BC7B55ADB92DC1BE438006E5392ED521B5817558DE5E38172D023E3236EEAE34037E92EA61D6DA463212E012E603709D65EBE8062644A17B1A00FF5DE6E42FD4B3812DACC8C85754616A5539AB60FEF0F9170413E94D3052CBA3A7B9FCF46F318D30DD88DD988C9C16F5BB8823538A8DBC4830B00E7CE5346277E4DAD464128025955E7E5FD184C40EEC184B6143FC4720DA45C7DE3ED4849D6ABC89B1C01D6761660EA595B65E7F70457A32A4D63CCC6FC9736ABDDB9AE9FC8FB90388DAB7BD2189B38488B17DA76B96DAB6871475F59FC36BD53076293EBF9970A1081BA84E44A3A109F6B7231E64C1C54BF9AABD2320185DC054672B2F8F52172CD262F14CCA3237542F421A2413DF5E371DD4F1297E01D81E392A6C4F3BBABAA3091B2F10DB1C4A2C12B0DDDC279F7AD45992225ACA55ADA7CB6370B07B0CD5B935B8DF18BFFA2567EBF77658772D043318B6BA159DBD3AA48C7A509A1F887A05118CBE1470599C2683D9C00DAA5480A05FFDDF7612E6CFDB032A8F
-20180427231209 2 6 100 8191 5 FAEE1044985A5E9005F621D69401F45F006C4AC70C849E5C17F3D28A22FE2C86DEF3780E73C15BC778C65638702E1DF6193E19C79BC8A9CEC1D64759E6E8E1B3754AAD1F82819BDB1F1E224F7D7BFF62061D89F6AE8D8EAF444A543333A4E71A4EBEE16AA9FEAE434FD965B90E6B57A198C12619CC31EF4F2BA3ACEA4C0D31EDD7BD715FE76FCD9282221F27F6CFD678ABC0458E4EDFBB72FB23333A3137C1C9AEB0AE4E5D98148527A5670311C0181861C1305901FF9704C64F88B75AD76574ABE3B5CEAAC2F675F5A56B807B2D9FFEDC975C7CFC6C697A18ED7F3D76C164FE108255F43971A3CCEE8FDC5E95F38B6ED8F8B150E17A7780E2D5CFD9A4D35BC4E2B3C3F4F286DC9DD0A8A53A22E643AD29753AAAB58E4C268A4145B1958050895F7FF5EB300FD0435824024F6DA4C38039A621D8E553493D964479DB2C1647C5123A9ED27955117CB966D41BAB3FA2F6AE1CE0E9787E3C815B1E3A3E3002B0BC54A89D66A3B532E8152BB0FD681D134374B4F2197F0B451E4C68C589E1F213D42CB62FC749D0883D9A68B39B93A1582F957AC989E5664266BB53BB8A07C84F662D5E3B4D4B277840A98B37F8A2CDF892085AF77A0AD370B2A4649F2381B7136AEB189421C6C801DC4F20273922A57C76DB4DB487DFC33DA2AC490C77E8ABA4AC719E6F0428A37ADBBE04F776199ACE29C1BC3B8A1F8E0D049628FDA016735559589D660FB23421D29745528E160F60B5D1923E685D0E04BE9DAC15C90BCAC4F4A7FD5CE52950734F2A849CAAB083DD18324EE82D1679146E60C290A97E2C94FBFEEDD88DE9EBEB346DF9E11AE14F4540A84F98B210E5366A03A82128986543C48FC3867431B2531AF99B379CE7E8D3105C574B0D4974295E98EFA2C01AC31C80CB1654BCEFA8467A55BC7B55ADB92DC1BE438006E5392ED521B5817558DE5E38172D023E3236EEAE34037E92EA61D6DA463212E012E603709D65EBE8062644A17B1A00FF5DE6E42FD4B3812DACC8C85754616A5539AB60FEF0F9170413E94D3052CBA3A7B9FCF46F318D30DD88DD988C9C16F5BB8823538A8DBC4830B00E7CE5346277E4DAD464128025955E7E5FD184C40EEC184B6143FC4720DA45C7DE3ED4849D6ABC89B1C01D6761660EA595B65E7F70457A32A4D63CCC6FC9736ABDDB9AE9FC8FB90388DAB7BD2189B38488B17DA76B96DAB6871475F59FC36BD53076293EBF9970A1081BA84E44A3A109F6B7231E64C1C54BF9AABD2320185DC054672B2F8F52172CD262F14CCA3237542F421A2413DF5E371DD4F1297E01D81E392A6C4F3BBABAA3091B2F10DB1C4A2C12B0DDDC279F7AD45992225ACA55ADA7CB6370B07B0CD5B935B8DF18BFFA2567EBF77658772D043318B6BA159DBD3AA48C7A509A1F887A05118CBE1470599C2683D9C00DAA5480A05FFDDF7612E6CFE24BAFE7
-20180428032748 2 6 100 8191 2 FAEE1044985A5E9005F621D69401F45F006C4AC70C849E5C17F3D28A22FE2C86DEF3780E73C15BC778C65638702E1DF6193E19C79BC8A9CEC1D64759E6E8E1B3754AAD1F82819BDB1F1E224F7D7BFF62061D89F6AE8D8EAF444A543333A4E71A4EBEE16AA9FEAE434FD965B90E6B57A198C12619CC31EF4F2BA3ACEA4C0D31EDD7BD715FE76FCD9282221F27F6CFD678ABC0458E4EDFBB72FB23333A3137C1C9AEB0AE4E5D98148527A5670311C0181861C1305901FF9704C64F88B75AD76574ABE3B5CEAAC2F675F5A56B807B2D9FFEDC975C7CFC6C697A18ED7F3D76C164FE108255F43971A3CCEE8FDC5E95F38B6ED8F8B150E17A7780E2D5CFD9A4D35BC4E2B3C3F4F286DC9DD0A8A53A22E643AD29753AAAB58E4C268A4145B1958050895F7FF5EB300FD0435824024F6DA4C38039A621D8E553493D964479DB2C1647C5123A9ED27955117CB966D41BAB3FA2F6AE1CE0E9787E3C815B1E3A3E3002B0BC54A89D66A3B532E8152BB0FD681D134374B4F2197F0B451E4C68C589E1F213D42CB62FC749D0883D9A68B39B93A1582F957AC989E5664266BB53BB8A07C84F662D5E3B4D4B277840A98B37F8A2CDF892085AF77A0AD370B2A4649F2381B7136AEB189421C6C801DC4F20273922A57C76DB4DB487DFC33DA2AC490C77E8ABA4AC719E6F0428A37ADBBE04F776199ACE29C1BC3B8A1F8E0D049628FDA016735559589D660FB23421D29745528E160F60B5D1923E685D0E04BE9DAC15C90BCAC4F4A7FD5CE52950734F2A849CAAB083DD18324EE82D1679146E60C290A97E2C94FBFEEDD88DE9EBEB346DF9E11AE14F4540A84F98B210E5366A03A82128986543C48FC3867431B2531AF99B379CE7E8D3105C574B0D4974295E98EFA2C01AC31C80CB1654BCEFA8467A55BC7B55ADB92DC1BE438006E5392ED521B5817558DE5E38172D023E3236EEAE34037E92EA61D6DA463212E012E603709D65EBE8062644A17B1A00FF5DE6E42FD4B3812DACC8C85754616A5539AB60FEF0F9170413E94D3052CBA3A7B9FCF46F318D30DD88DD988C9C16F5BB8823538A8DBC4830B00E7CE5346277E4DAD464128025955E7E5FD184C40EEC184B6143FC4720DA45C7DE3ED4849D6ABC89B1C01D6761660EA595B65E7F70457A32A4D63CCC6FC9736ABDDB9AE9FC8FB90388DAB7BD2189B38488B17DA76B96DAB6871475F59FC36BD53076293EBF9970A1081BA84E44A3A109F6B7231E64C1C54BF9AABD2320185DC054672B2F8F52172CD262F14CCA3237542F421A2413DF5E371DD4F1297E01D81E392A6C4F3BBABAA3091B2F10DB1C4A2C12B0DDDC279F7AD45992225ACA55ADA7CB6370B07B0CD5B935B8DF18BFFA2567EBF77658772D043318B6BA159DBD3AA48C7A509A1F887A05118CBE1470599C2683D9C00DAA5480A05FFDDF7612E6CFE509AE73
-20180428050334 2 6 100 8191 2 FAEE1044985A5E9005F621D69401F45F006C4AC70C849E5C17F3D28A22FE2C86DEF3780E73C15BC778C65638702E1DF6193E19C79BC8A9CEC1D64759E6E8E1B3754AAD1F82819BDB1F1E224F7D7BFF62061D89F6AE8D8EAF444A543333A4E71A4EBEE16AA9FEAE434FD965B90E6B57A198C12619CC31EF4F2BA3ACEA4C0D31EDD7BD715FE76FCD9282221F27F6CFD678ABC0458E4EDFBB72FB23333A3137C1C9AEB0AE4E5D98148527A5670311C0181861C1305901FF9704C64F88B75AD76574ABE3B5CEAAC2F675F5A56B807B2D9FFEDC975C7CFC6C697A18ED7F3D76C164FE108255F43971A3CCEE8FDC5E95F38B6ED8F8B150E17A7780E2D5CFD9A4D35BC4E2B3C3F4F286DC9DD0A8A53A22E643AD29753AAAB58E4C268A4145B1958050895F7FF5EB300FD0435824024F6DA4C38039A621D8E553493D964479DB2C1647C5123A9ED27955117CB966D41BAB3FA2F6AE1CE0E9787E3C815B1E3A3E3002B0BC54A89D66A3B532E8152BB0FD681D134374B4F2197F0B451E4C68C589E1F213D42CB62FC749D0883D9A68B39B93A1582F957AC989E5664266BB53BB8A07C84F662D5E3B4D4B277840A98B37F8A2CDF892085AF77A0AD370B2A4649F2381B7136AEB189421C6C801DC4F20273922A57C76DB4DB487DFC33DA2AC490C77E8ABA4AC719E6F0428A37ADBBE04F776199ACE29C1BC3B8A1F8E0D049628FDA016735559589D660FB23421D29745528E160F60B5D1923E685D0E04BE9DAC15C90BCAC4F4A7FD5CE52950734F2A849CAAB083DD18324EE82D1679146E60C290A97E2C94FBFEEDD88DE9EBEB346DF9E11AE14F4540A84F98B210E5366A03A82128986543C48FC3867431B2531AF99B379CE7E8D3105C574B0D4974295E98EFA2C01AC31C80CB1654BCEFA8467A55BC7B55ADB92DC1BE438006E5392ED521B5817558DE5E38172D023E3236EEAE34037E92EA61D6DA463212E012E603709D65EBE8062644A17B1A00FF5DE6E42FD4B3812DACC8C85754616A5539AB60FEF0F9170413E94D3052CBA3A7B9FCF46F318D30DD88DD988C9C16F5BB8823538A8DBC4830B00E7CE5346277E4DAD464128025955E7E5FD184C40EEC184B6143FC4720DA45C7DE3ED4849D6ABC89B1C01D6761660EA595B65E7F70457A32A4D63CCC6FC9736ABDDB9AE9FC8FB90388DAB7BD2189B38488B17DA76B96DAB6871475F59FC36BD53076293EBF9970A1081BA84E44A3A109F6B7231E64C1C54BF9AABD2320185DC054672B2F8F52172CD262F14CCA3237542F421A2413DF5E371DD4F1297E01D81E392A6C4F3BBABAA3091B2F10DB1C4A2C12B0DDDC279F7AD45992225ACA55ADA7CB6370B07B0CD5B935B8DF18BFFA2567EBF77658772D043318B6BA159DBD3AA48C7A509A1F887A05118CBE1470599C2683D9C00DAA5480A05FFDDF7612E6CFE60622B3
-20180428204832 2 6 100 8191 5 FAEE1044985A5E9005F621D69401F45F006C4AC70C849E5C17F3D28A22FE2C86DEF3780E73C15BC778C65638702E1DF6193E19C79BC8A9CEC1D64759E6E8E1B3754AAD1F82819BDB1F1E224F7D7BFF62061D89F6AE8D8EAF444A543333A4E71A4EBEE16AA9FEAE434FD965B90E6B57A198C12619CC31EF4F2BA3ACEA4C0D31EDD7BD715FE76FCD9282221F27F6CFD678ABC0458E4EDFBB72FB23333A3137C1C9AEB0AE4E5D98148527A5670311C0181861C1305901FF9704C64F88B75AD76574ABE3B5CEAAC2F675F5A56B807B2D9FFEDC975C7CFC6C697A18ED7F3D76C164FE108255F43971A3CCEE8FDC5E95F38B6ED8F8B150E17A7780E2D5CFD9A4D35BC4E2B3C3F4F286DC9DD0A8A53A22E643AD29753AAAB58E4C268A4145B1958050895F7FF5EB300FD0435824024F6DA4C38039A621D8E553493D964479DB2C1647C5123A9ED27955117CB966D41BAB3FA2F6AE1CE0E9787E3C815B1E3A3E3002B0BC54A89D66A3B532E8152BB0FD681D134374B4F2197F0B451E4C68C589E1F213D42CB62FC749D0883D9A68B39B93A1582F957AC989E5664266BB53BB8A07C84F662D5E3B4D4B277840A98B37F8A2CDF892085AF77A0AD370B2A4649F2381B7136AEB189421C6C801DC4F20273922A57C76DB4DB487DFC33DA2AC490C77E8ABA4AC719E6F0428A37ADBBE04F776199ACE29C1BC3B8A1F8E0D049628FDA016735559589D660FB23421D29745528E160F60B5D1923E685D0E04BE9DAC15C90BCAC4F4A7FD5CE52950734F2A849CAAB083DD18324EE82D1679146E60C290A97E2C94FBFEEDD88DE9EBEB346DF9E11AE14F4540A84F98B210E5366A03A82128986543C48FC3867431B2531AF99B379CE7E8D3105C574B0D4974295E98EFA2C01AC31C80CB1654BCEFA8467A55BC7B55ADB92DC1BE438006E5392ED521B5817558DE5E38172D023E3236EEAE34037E92EA61D6DA463212E012E603709D65EBE8062644A17B1A00FF5DE6E42FD4B3812DACC8C85754616A5539AB60FEF0F9170413E94D3052CBA3A7B9FCF46F318D30DD88DD988C9C16F5BB8823538A8DBC4830B00E7CE5346277E4DAD464128025955E7E5FD184C40EEC184B6143FC4720DA45C7DE3ED4849D6ABC89B1C01D6761660EA595B65E7F70457A32A4D63CCC6FC9736ABDDB9AE9FC8FB90388DAB7BD2189B38488B17DA76B96DAB6871475F59FC36BD53076293EBF9970A1081BA84E44A3A109F6B7231E64C1C54BF9AABD2320185DC054672B2F8F52172CD262F14CCA3237542F421A2413DF5E371DD4F1297E01D81E392A6C4F3BBABAA3091B2F10DB1C4A2C12B0DDDC279F7AD45992225ACA55ADA7CB6370B07B0CD5B935B8DF18BFFA2567EBF77658772D043318B6BA159DBD3AA48C7A509A1F887A05118CBE1470599C2683D9C00DAA5480A05FFDDF7612E6CFF035C75F
-20180428220506 2 6 100 8191 2 FAEE1044985A5E9005F621D69401F45F006C4AC70C849E5C17F3D28A22FE2C86DEF3780E73C15BC778C65638702E1DF6193E19C79BC8A9CEC1D64759E6E8E1B3754AAD1F82819BDB1F1E224F7D7BFF62061D89F6AE8D8EAF444A543333A4E71A4EBEE16AA9FEAE434FD965B90E6B57A198C12619CC31EF4F2BA3ACEA4C0D31EDD7BD715FE76FCD9282221F27F6CFD678ABC0458E4EDFBB72FB23333A3137C1C9AEB0AE4E5D98148527A5670311C0181861C1305901FF9704C64F88B75AD76574ABE3B5CEAAC2F675F5A56B807B2D9FFEDC975C7CFC6C697A18ED7F3D76C164FE108255F43971A3CCEE8FDC5E95F38B6ED8F8B150E17A7780E2D5CFD9A4D35BC4E2B3C3F4F286DC9DD0A8A53A22E643AD29753AAAB58E4C268A4145B1958050895F7FF5EB300FD0435824024F6DA4C38039A621D8E553493D964479DB2C1647C5123A9ED27955117CB966D41BAB3FA2F6AE1CE0E9787E3C815B1E3A3E3002B0BC54A89D66A3B532E8152BB0FD681D134374B4F2197F0B451E4C68C589E1F213D42CB62FC749D0883D9A68B39B93A1582F957AC989E5664266BB53BB8A07C84F662D5E3B4D4B277840A98B37F8A2CDF892085AF77A0AD370B2A4649F2381B7136AEB189421C6C801DC4F20273922A57C76DB4DB487DFC33DA2AC490C77E8ABA4AC719E6F0428A37ADBBE04F776199ACE29C1BC3B8A1F8E0D049628FDA016735559589D660FB23421D29745528E160F60B5D1923E685D0E04BE9DAC15C90BCAC4F4A7FD5CE52950734F2A849CAAB083DD18324EE82D1679146E60C290A97E2C94FBFEEDD88DE9EBEB346DF9E11AE14F4540A84F98B210E5366A03A82128986543C48FC3867431B2531AF99B379CE7E8D3105C574B0D4974295E98EFA2C01AC31C80CB1654BCEFA8467A55BC7B55ADB92DC1BE438006E5392ED521B5817558DE5E38172D023E3236EEAE34037E92EA61D6DA463212E012E603709D65EBE8062644A17B1A00FF5DE6E42FD4B3812DACC8C85754616A5539AB60FEF0F9170413E94D3052CBA3A7B9FCF46F318D30DD88DD988C9C16F5BB8823538A8DBC4830B00E7CE5346277E4DAD464128025955E7E5FD184C40EEC184B6143FC4720DA45C7DE3ED4849D6ABC89B1C01D6761660EA595B65E7F70457A32A4D63CCC6FC9736ABDDB9AE9FC8FB90388DAB7BD2189B38488B17DA76B96DAB6871475F59FC36BD53076293EBF9970A1081BA84E44A3A109F6B7231E64C1C54BF9AABD2320185DC054672B2F8F52172CD262F14CCA3237542F421A2413DF5E371DD4F1297E01D81E392A6C4F3BBABAA3091B2F10DB1C4A2C12B0DDDC279F7AD45992225ACA55ADA7CB6370B07B0CD5B935B8DF18BFFA2567EBF77658772D043318B6BA159DBD3AA48C7A509A1F887A05118CBE1470599C2683D9C00DAA5480A05FFDDF7612E6CFF0FF9743
-20180428221212 2 6 100 8191 5 FAEE1044985A5E9005F621D69401F45F006C4AC70C849E5C17F3D28A22FE2C86DEF3780E73C15BC778C65638702E1DF6193E19C79BC8A9CEC1D64759E6E8E1B3754AAD1F82819BDB1F1E224F7D7BFF62061D89F6AE8D8EAF444A543333A4E71A4EBEE16AA9FEAE434FD965B90E6B57A198C12619CC31EF4F2BA3ACEA4C0D31EDD7BD715FE76FCD9282221F27F6CFD678ABC0458E4EDFBB72FB23333A3137C1C9AEB0AE4E5D98148527A5670311C0181861C1305901FF9704C64F88B75AD76574ABE3B5CEAAC2F675F5A56B807B2D9FFEDC975C7CFC6C697A18ED7F3D76C164FE108255F43971A3CCEE8FDC5E95F38B6ED8F8B150E17A7780E2D5CFD9A4D35BC4E2B3C3F4F286DC9DD0A8A53A22E643AD29753AAAB58E4C268A4145B1958050895F7FF5EB300FD0435824024F6DA4C38039A621D8E553493D964479DB2C1647C5123A9ED27955117CB966D41BAB3FA2F6AE1CE0E9787E3C815B1E3A3E3002B0BC54A89D66A3B532E8152BB0FD681D134374B4F2197F0B451E4C68C589E1F213D42CB62FC749D0883D9A68B39B93A1582F957AC989E5664266BB53BB8A07C84F662D5E3B4D4B277840A98B37F8A2CDF892085AF77A0AD370B2A4649F2381B7136AEB189421C6C801DC4F20273922A57C76DB4DB487DFC33DA2AC490C77E8ABA4AC719E6F0428A37ADBBE04F776199ACE29C1BC3B8A1F8E0D049628FDA016735559589D660FB23421D29745528E160F60B5D1923E685D0E04BE9DAC15C90BCAC4F4A7FD5CE52950734F2A849CAAB083DD18324EE82D1679146E60C290A97E2C94FBFEEDD88DE9EBEB346DF9E11AE14F4540A84F98B210E5366A03A82128986543C48FC3867431B2531AF99B379CE7E8D3105C574B0D4974295E98EFA2C01AC31C80CB1654BCEFA8467A55BC7B55ADB92DC1BE438006E5392ED521B5817558DE5E38172D023E3236EEAE34037E92EA61D6DA463212E012E603709D65EBE8062644A17B1A00FF5DE6E42FD4B3812DACC8C85754616A5539AB60FEF0F9170413E94D3052CBA3A7B9FCF46F318D30DD88DD988C9C16F5BB8823538A8DBC4830B00E7CE5346277E4DAD464128025955E7E5FD184C40EEC184B6143FC4720DA45C7DE3ED4849D6ABC89B1C01D6761660EA595B65E7F70457A32A4D63CCC6FC9736ABDDB9AE9FC8FB90388DAB7BD2189B38488B17DA76B96DAB6871475F59FC36BD53076293EBF9970A1081BA84E44A3A109F6B7231E64C1C54BF9AABD2320185DC054672B2F8F52172CD262F14CCA3237542F421A2413DF5E371DD4F1297E01D81E392A6C4F3BBABAA3091B2F10DB1C4A2C12B0DDDC279F7AD45992225ACA55ADA7CB6370B07B0CD5B935B8DF18BFFA2567EBF77658772D043318B6BA159DBD3AA48C7A509A1F887A05118CBE1470599C2683D9C00DAA5480A05FFDDF7612E6CFF108842F
-20180429040829 2 6 100 8191 5 FAEE1044985A5E9005F621D69401F45F006C4AC70C849E5C17F3D28A22FE2C86DEF3780E73C15BC778C65638702E1DF6193E19C79BC8A9CEC1D64759E6E8E1B3754AAD1F82819BDB1F1E224F7D7BFF62061D89F6AE8D8EAF444A543333A4E71A4EBEE16AA9FEAE434FD965B90E6B57A198C12619CC31EF4F2BA3ACEA4C0D31EDD7BD715FE76FCD9282221F27F6CFD678ABC0458E4EDFBB72FB23333A3137C1C9AEB0AE4E5D98148527A5670311C0181861C1305901FF9704C64F88B75AD76574ABE3B5CEAAC2F675F5A56B807B2D9FFEDC975C7CFC6C697A18ED7F3D76C164FE108255F43971A3CCEE8FDC5E95F38B6ED8F8B150E17A7780E2D5CFD9A4D35BC4E2B3C3F4F286DC9DD0A8A53A22E643AD29753AAAB58E4C268A4145B1958050895F7FF5EB300FD0435824024F6DA4C38039A621D8E553493D964479DB2C1647C5123A9ED27955117CB966D41BAB3FA2F6AE1CE0E9787E3C815B1E3A3E3002B0BC54A89D66A3B532E8152BB0FD681D134374B4F2197F0B451E4C68C589E1F213D42CB62FC749D0883D9A68B39B93A1582F957AC989E5664266BB53BB8A07C84F662D5E3B4D4B277840A98B37F8A2CDF892085AF77A0AD370B2A4649F2381B7136AEB189421C6C801DC4F20273922A57C76DB4DB487DFC33DA2AC490C77E8ABA4AC719E6F0428A37ADBBE04F776199ACE29C1BC3B8A1F8E0D049628FDA016735559589D660FB23421D29745528E160F60B5D1923E685D0E04BE9DAC15C90BCAC4F4A7FD5CE52950734F2A849CAAB083DD18324EE82D1679146E60C290A97E2C94FBFEEDD88DE9EBEB346DF9E11AE14F4540A84F98B210E5366A03A82128986543C48FC3867431B2531AF99B379CE7E8D3105C574B0D4974295E98EFA2C01AC31C80CB1654BCEFA8467A55BC7B55ADB92DC1BE438006E5392ED521B5817558DE5E38172D023E3236EEAE34037E92EA61D6DA463212E012E603709D65EBE8062644A17B1A00FF5DE6E42FD4B3812DACC8C85754616A5539AB60FEF0F9170413E94D3052CBA3A7B9FCF46F318D30DD88DD988C9C16F5BB8823538A8DBC4830B00E7CE5346277E4DAD464128025955E7E5FD184C40EEC184B6143FC4720DA45C7DE3ED4849D6ABC89B1C01D6761660EA595B65E7F70457A32A4D63CCC6FC9736ABDDB9AE9FC8FB90388DAB7BD2189B38488B17DA76B96DAB6871475F59FC36BD53076293EBF9970A1081BA84E44A3A109F6B7231E64C1C54BF9AABD2320185DC054672B2F8F52172CD262F14CCA3237542F421A2413DF5E371DD4F1297E01D81E392A6C4F3BBABAA3091B2F10DB1C4A2C12B0DDDC279F7AD45992225ACA55ADA7CB6370B07B0CD5B935B8DF18BFFA2567EBF77658772D043318B6BA159DBD3AA48C7A509A1F887A05118CBE1470599C2683D9C00DAA5480A05FFDDF7612E6CFF4BDEDDF
-20180429045604 2 6 100 8191 5 FAEE1044985A5E9005F621D69401F45F006C4AC70C849E5C17F3D28A22FE2C86DEF3780E73C15BC778C65638702E1DF6193E19C79BC8A9CEC1D64759E6E8E1B3754AAD1F82819BDB1F1E224F7D7BFF62061D89F6AE8D8EAF444A543333A4E71A4EBEE16AA9FEAE434FD965B90E6B57A198C12619CC31EF4F2BA3ACEA4C0D31EDD7BD715FE76FCD9282221F27F6CFD678ABC0458E4EDFBB72FB23333A3137C1C9AEB0AE4E5D98148527A5670311C0181861C1305901FF9704C64F88B75AD76574ABE3B5CEAAC2F675F5A56B807B2D9FFEDC975C7CFC6C697A18ED7F3D76C164FE108255F43971A3CCEE8FDC5E95F38B6ED8F8B150E17A7780E2D5CFD9A4D35BC4E2B3C3F4F286DC9DD0A8A53A22E643AD29753AAAB58E4C268A4145B1958050895F7FF5EB300FD0435824024F6DA4C38039A621D8E553493D964479DB2C1647C5123A9ED27955117CB966D41BAB3FA2F6AE1CE0E9787E3C815B1E3A3E3002B0BC54A89D66A3B532E8152BB0FD681D134374B4F2197F0B451E4C68C589E1F213D42CB62FC749D0883D9A68B39B93A1582F957AC989E5664266BB53BB8A07C84F662D5E3B4D4B277840A98B37F8A2CDF892085AF77A0AD370B2A4649F2381B7136AEB189421C6C801DC4F20273922A57C76DB4DB487DFC33DA2AC490C77E8ABA4AC719E6F0428A37ADBBE04F776199ACE29C1BC3B8A1F8E0D049628FDA016735559589D660FB23421D29745528E160F60B5D1923E685D0E04BE9DAC15C90BCAC4F4A7FD5CE52950734F2A849CAAB083DD18324EE82D1679146E60C290A97E2C94FBFEEDD88DE9EBEB346DF9E11AE14F4540A84F98B210E5366A03A82128986543C48FC3867431B2531AF99B379CE7E8D3105C574B0D4974295E98EFA2C01AC31C80CB1654BCEFA8467A55BC7B55ADB92DC1BE438006E5392ED521B5817558DE5E38172D023E3236EEAE34037E92EA61D6DA463212E012E603709D65EBE8062644A17B1A00FF5DE6E42FD4B3812DACC8C85754616A5539AB60FEF0F9170413E94D3052CBA3A7B9FCF46F318D30DD88DD988C9C16F5BB8823538A8DBC4830B00E7CE5346277E4DAD464128025955E7E5FD184C40EEC184B6143FC4720DA45C7DE3ED4849D6ABC89B1C01D6761660EA595B65E7F70457A32A4D63CCC6FC9736ABDDB9AE9FC8FB90388DAB7BD2189B38488B17DA76B96DAB6871475F59FC36BD53076293EBF9970A1081BA84E44A3A109F6B7231E64C1C54BF9AABD2320185DC054672B2F8F52172CD262F14CCA3237542F421A2413DF5E371DD4F1297E01D81E392A6C4F3BBABAA3091B2F10DB1C4A2C12B0DDDC279F7AD45992225ACA55ADA7CB6370B07B0CD5B935B8DF18BFFA2567EBF77658772D043318B6BA159DBD3AA48C7A509A1F887A05118CBE1470599C2683D9C00DAA5480A05FFDDF7612E6CFF5372357
-20180429052346 2 6 100 8191 2 FAEE1044985A5E9005F621D69401F45F006C4AC70C849E5C17F3D28A22FE2C86DEF3780E73C15BC778C65638702E1DF6193E19C79BC8A9CEC1D64759E6E8E1B3754AAD1F82819BDB1F1E224F7D7BFF62061D89F6AE8D8EAF444A543333A4E71A4EBEE16AA9FEAE434FD965B90E6B57A198C12619CC31EF4F2BA3ACEA4C0D31EDD7BD715FE76FCD9282221F27F6CFD678ABC0458E4EDFBB72FB23333A3137C1C9AEB0AE4E5D98148527A5670311C0181861C1305901FF9704C64F88B75AD76574ABE3B5CEAAC2F675F5A56B807B2D9FFEDC975C7CFC6C697A18ED7F3D76C164FE108255F43971A3CCEE8FDC5E95F38B6ED8F8B150E17A7780E2D5CFD9A4D35BC4E2B3C3F4F286DC9DD0A8A53A22E643AD29753AAAB58E4C268A4145B1958050895F7FF5EB300FD0435824024F6DA4C38039A621D8E553493D964479DB2C1647C5123A9ED27955117CB966D41BAB3FA2F6AE1CE0E9787E3C815B1E3A3E3002B0BC54A89D66A3B532E8152BB0FD681D134374B4F2197F0B451E4C68C589E1F213D42CB62FC749D0883D9A68B39B93A1582F957AC989E5664266BB53BB8A07C84F662D5E3B4D4B277840A98B37F8A2CDF892085AF77A0AD370B2A4649F2381B7136AEB189421C6C801DC4F20273922A57C76DB4DB487DFC33DA2AC490C77E8ABA4AC719E6F0428A37ADBBE04F776199ACE29C1BC3B8A1F8E0D049628FDA016735559589D660FB23421D29745528E160F60B5D1923E685D0E04BE9DAC15C90BCAC4F4A7FD5CE52950734F2A849CAAB083DD18324EE82D1679146E60C290A97E2C94FBFEEDD88DE9EBEB346DF9E11AE14F4540A84F98B210E5366A03A82128986543C48FC3867431B2531AF99B379CE7E8D3105C574B0D4974295E98EFA2C01AC31C80CB1654BCEFA8467A55BC7B55ADB92DC1BE438006E5392ED521B5817558DE5E38172D023E3236EEAE34037E92EA61D6DA463212E012E603709D65EBE8062644A17B1A00FF5DE6E42FD4B3812DACC8C85754616A5539AB60FEF0F9170413E94D3052CBA3A7B9FCF46F318D30DD88DD988C9C16F5BB8823538A8DBC4830B00E7CE5346277E4DAD464128025955E7E5FD184C40EEC184B6143FC4720DA45C7DE3ED4849D6ABC89B1C01D6761660EA595B65E7F70457A32A4D63CCC6FC9736ABDDB9AE9FC8FB90388DAB7BD2189B38488B17DA76B96DAB6871475F59FC36BD53076293EBF9970A1081BA84E44A3A109F6B7231E64C1C54BF9AABD2320185DC054672B2F8F52172CD262F14CCA3237542F421A2413DF5E371DD4F1297E01D81E392A6C4F3BBABAA3091B2F10DB1C4A2C12B0DDDC279F7AD45992225ACA55ADA7CB6370B07B0CD5B935B8DF18BFFA2567EBF77658772D043318B6BA159DBD3AA48C7A509A1F887A05118CBE1470599C2683D9C00DAA5480A05FFDDF7612E6CFF57C9113
-20180429053535 2 6 100 8191 2 FAEE1044985A5E9005F621D69401F45F006C4AC70C849E5C17F3D28A22FE2C86DEF3780E73C15BC778C65638702E1DF6193E19C79BC8A9CEC1D64759E6E8E1B3754AAD1F82819BDB1F1E224F7D7BFF62061D89F6AE8D8EAF444A543333A4E71A4EBEE16AA9FEAE434FD965B90E6B57A198C12619CC31EF4F2BA3ACEA4C0D31EDD7BD715FE76FCD9282221F27F6CFD678ABC0458E4EDFBB72FB23333A3137C1C9AEB0AE4E5D98148527A5670311C0181861C1305901FF9704C64F88B75AD76574ABE3B5CEAAC2F675F5A56B807B2D9FFEDC975C7CFC6C697A18ED7F3D76C164FE108255F43971A3CCEE8FDC5E95F38B6ED8F8B150E17A7780E2D5CFD9A4D35BC4E2B3C3F4F286DC9DD0A8A53A22E643AD29753AAAB58E4C268A4145B1958050895F7FF5EB300FD0435824024F6DA4C38039A621D8E553493D964479DB2C1647C5123A9ED27955117CB966D41BAB3FA2F6AE1CE0E9787E3C815B1E3A3E3002B0BC54A89D66A3B532E8152BB0FD681D134374B4F2197F0B451E4C68C589E1F213D42CB62FC749D0883D9A68B39B93A1582F957AC989E5664266BB53BB8A07C84F662D5E3B4D4B277840A98B37F8A2CDF892085AF77A0AD370B2A4649F2381B7136AEB189421C6C801DC4F20273922A57C76DB4DB487DFC33DA2AC490C77E8ABA4AC719E6F0428A37ADBBE04F776199ACE29C1BC3B8A1F8E0D049628FDA016735559589D660FB23421D29745528E160F60B5D1923E685D0E04BE9DAC15C90BCAC4F4A7FD5CE52950734F2A849CAAB083DD18324EE82D1679146E60C290A97E2C94FBFEEDD88DE9EBEB346DF9E11AE14F4540A84F98B210E5366A03A82128986543C48FC3867431B2531AF99B379CE7E8D3105C574B0D4974295E98EFA2C01AC31C80CB1654BCEFA8467A55BC7B55ADB92DC1BE438006E5392ED521B5817558DE5E38172D023E3236EEAE34037E92EA61D6DA463212E012E603709D65EBE8062644A17B1A00FF5DE6E42FD4B3812DACC8C85754616A5539AB60FEF0F9170413E94D3052CBA3A7B9FCF46F318D30DD88DD988C9C16F5BB8823538A8DBC4830B00E7CE5346277E4DAD464128025955E7E5FD184C40EEC184B6143FC4720DA45C7DE3ED4849D6ABC89B1C01D6761660EA595B65E7F70457A32A4D63CCC6FC9736ABDDB9AE9FC8FB90388DAB7BD2189B38488B17DA76B96DAB6871475F59FC36BD53076293EBF9970A1081BA84E44A3A109F6B7231E64C1C54BF9AABD2320185DC054672B2F8F52172CD262F14CCA3237542F421A2413DF5E371DD4F1297E01D81E392A6C4F3BBABAA3091B2F10DB1C4A2C12B0DDDC279F7AD45992225ACA55ADA7CB6370B07B0CD5B935B8DF18BFFA2567EBF77658772D043318B6BA159DBD3AA48C7A509A1F887A05118CBE1470599C2683D9C00DAA5480A05FFDDF7612E6CFF591B0F3
-20180429234833 2 6 100 8191 2 FAEE1044985A5E9005F621D69401F45F006C4AC70C849E5C17F3D28A22FE2C86DEF3780E73C15BC778C65638702E1DF6193E19C79BC8A9CEC1D64759E6E8E1B3754AAD1F82819BDB1F1E224F7D7BFF62061D89F6AE8D8EAF444A543333A4E71A4EBEE16AA9FEAE434FD965B90E6B57A198C12619CC31EF4F2BA3ACEA4C0D31EDD7BD715FE76FCD9282221F27F6CFD678ABC0458E4EDFBB72FB23333A3137C1C9AEB0AE4E5D98148527A5670311C0181861C1305901FF9704C64F88B75AD76574ABE3B5CEAAC2F675F5A56B807B2D9FFEDC975C7CFC6C697A18ED7F3D76C164FE108255F43971A3CCEE8FDC5E95F38B6ED8F8B150E17A7780E2D5CFD9A4D35BC4E2B3C3F4F286DC9DD0A8A53A22E643AD29753AAAB58E4C268A4145B1958050895F7FF5EB300FD0435824024F6DA4C38039A621D8E553493D964479DB2C1647C5123A9ED27955117CB966D41BAB3FA2F6AE1CE0E9787E3C815B1E3A3E3002B0BC54A89D66A3B532E8152BB0FD681D134374B4F2197F0B451E4C68C589E1F213D42CB62FC749D0883D9A68B39B93A1582F957AC989E5664266BB53BB8A07C84F662D5E3B4D4B277840A98B37F8A2CDF892085AF77A0AD370B2A4649F2381B7136AEB189421C6C801DC4F20273922A57C76DB4DB487DFC33DA2AC490C77E8ABA4AC719E6F0428A37ADBBE04F776199ACE29C1BC3B8A1F8E0D049628FDA016735559589D660FB23421D29745528E160F60B5D1923E685D0E04BE9DAC15C90BCAC4F4A7FD5CE52950734F2A849CAAB083DD18324EE82D1679146E60C290A97E2C94FBFEEDD88DE9EBEB346DF9E11AE14F4540A84F98B210E5366A03A82128986543C48FC3867431B2531AF99B379CE7E8D3105C574B0D4974295E98EFA2C01AC31C80CB1654BCEFA8467A55BC7B55ADB92DC1BE438006E5392ED521B5817558DE5E38172D023E3236EEAE34037E92EA61D6DA463212E012E603709D65EBE8062644A17B1A00FF5DE6E42FD4B3812DACC8C85754616A5539AB60FEF0F9170413E94D3052CBA3A7B9FCF46F318D30DD88DD988C9C16F5BB8823538A8DBC4830B00E7CE5346277E4DAD464128025955E7E5FD184C40EEC184B6143FC4720DA45C7DE3ED4849D6ABC89B1C01D6761660EA595B65E7F70457A32A4D63CCC6FC9736ABDDB9AE9FC8FB90388DAB7BD2189B38488B17DA76B96DAB6871475F59FC36BD53076293EBF9970A1081BA84E44A3A109F6B7231E64C1C54BF9AABD2320185DC054672B2F8F52172CD262F14CCA3237542F421A2413DF5E371DD4F1297E01D81E392A6C4F3BBABAA3091B2F10DB1C4A2C12B0DDDC279F7AD45992225ACA55ADA7CB6370B07B0CD5B935B8DF18BFFA2567EBF77658772D043318B6BA159DBD3AA48C7A509A1F887A05118CBE1470599C2683D9C00DAA5480A05FFDDF7612E6D000DBC47B
-20180430061137 2 6 100 8191 2 FAEE1044985A5E9005F621D69401F45F006C4AC70C849E5C17F3D28A22FE2C86DEF3780E73C15BC778C65638702E1DF6193E19C79BC8A9CEC1D64759E6E8E1B3754AAD1F82819BDB1F1E224F7D7BFF62061D89F6AE8D8EAF444A543333A4E71A4EBEE16AA9FEAE434FD965B90E6B57A198C12619CC31EF4F2BA3ACEA4C0D31EDD7BD715FE76FCD9282221F27F6CFD678ABC0458E4EDFBB72FB23333A3137C1C9AEB0AE4E5D98148527A5670311C0181861C1305901FF9704C64F88B75AD76574ABE3B5CEAAC2F675F5A56B807B2D9FFEDC975C7CFC6C697A18ED7F3D76C164FE108255F43971A3CCEE8FDC5E95F38B6ED8F8B150E17A7780E2D5CFD9A4D35BC4E2B3C3F4F286DC9DD0A8A53A22E643AD29753AAAB58E4C268A4145B1958050895F7FF5EB300FD0435824024F6DA4C38039A621D8E553493D964479DB2C1647C5123A9ED27955117CB966D41BAB3FA2F6AE1CE0E9787E3C815B1E3A3E3002B0BC54A89D66A3B532E8152BB0FD681D134374B4F2197F0B451E4C68C589E1F213D42CB62FC749D0883D9A68B39B93A1582F957AC989E5664266BB53BB8A07C84F662D5E3B4D4B277840A98B37F8A2CDF892085AF77A0AD370B2A4649F2381B7136AEB189421C6C801DC4F20273922A57C76DB4DB487DFC33DA2AC490C77E8ABA4AC719E6F0428A37ADBBE04F776199ACE29C1BC3B8A1F8E0D049628FDA016735559589D660FB23421D29745528E160F60B5D1923E685D0E04BE9DAC15C90BCAC4F4A7FD5CE52950734F2A849CAAB083DD18324EE82D1679146E60C290A97E2C94FBFEEDD88DE9EBEB346DF9E11AE14F4540A84F98B210E5366A03A82128986543C48FC3867431B2531AF99B379CE7E8D3105C574B0D4974295E98EFA2C01AC31C80CB1654BCEFA8467A55BC7B55ADB92DC1BE438006E5392ED521B5817558DE5E38172D023E3236EEAE34037E92EA61D6DA463212E012E603709D65EBE8062644A17B1A00FF5DE6E42FD4B3812DACC8C85754616A5539AB60FEF0F9170413E94D3052CBA3A7B9FCF46F318D30DD88DD988C9C16F5BB8823538A8DBC4830B00E7CE5346277E4DAD464128025955E7E5FD184C40EEC184B6143FC4720DA45C7DE3ED4849D6ABC89B1C01D6761660EA595B65E7F70457A32A4D63CCC6FC9736ABDDB9AE9FC8FB90388DAB7BD2189B38488B17DA76B96DAB6871475F59FC36BD53076293EBF9970A1081BA84E44A3A109F6B7231E64C1C54BF9AABD2320185DC054672B2F8F52172CD262F14CCA3237542F421A2413DF5E371DD4F1297E01D81E392A6C4F3BBABAA3091B2F10DB1C4A2C12B0DDDC279F7AD45992225ACA55ADA7CB6370B07B0CD5B935B8DF18BFFA2567EBF77658772D043318B6BA159DBD3AA48C7A509A1F887A05118CBE1470599C2683D9C00DAA5480A05FFDDF7612E6D004DD4873
-20180430071004 2 6 100 8191 5 FAEE1044985A5E9005F621D69401F45F006C4AC70C849E5C17F3D28A22FE2C86DEF3780E73C15BC778C65638702E1DF6193E19C79BC8A9CEC1D64759E6E8E1B3754AAD1F82819BDB1F1E224F7D7BFF62061D89F6AE8D8EAF444A543333A4E71A4EBEE16AA9FEAE434FD965B90E6B57A198C12619CC31EF4F2BA3ACEA4C0D31EDD7BD715FE76FCD9282221F27F6CFD678ABC0458E4EDFBB72FB23333A3137C1C9AEB0AE4E5D98148527A5670311C0181861C1305901FF9704C64F88B75AD76574ABE3B5CEAAC2F675F5A56B807B2D9FFEDC975C7CFC6C697A18ED7F3D76C164FE108255F43971A3CCEE8FDC5E95F38B6ED8F8B150E17A7780E2D5CFD9A4D35BC4E2B3C3F4F286DC9DD0A8A53A22E643AD29753AAAB58E4C268A4145B1958050895F7FF5EB300FD0435824024F6DA4C38039A621D8E553493D964479DB2C1647C5123A9ED27955117CB966D41BAB3FA2F6AE1CE0E9787E3C815B1E3A3E3002B0BC54A89D66A3B532E8152BB0FD681D134374B4F2197F0B451E4C68C589E1F213D42CB62FC749D0883D9A68B39B93A1582F957AC989E5664266BB53BB8A07C84F662D5E3B4D4B277840A98B37F8A2CDF892085AF77A0AD370B2A4649F2381B7136AEB189421C6C801DC4F20273922A57C76DB4DB487DFC33DA2AC490C77E8ABA4AC719E6F0428A37ADBBE04F776199ACE29C1BC3B8A1F8E0D049628FDA016735559589D660FB23421D29745528E160F60B5D1923E685D0E04BE9DAC15C90BCAC4F4A7FD5CE52950734F2A849CAAB083DD18324EE82D1679146E60C290A97E2C94FBFEEDD88DE9EBEB346DF9E11AE14F4540A84F98B210E5366A03A82128986543C48FC3867431B2531AF99B379CE7E8D3105C574B0D4974295E98EFA2C01AC31C80CB1654BCEFA8467A55BC7B55ADB92DC1BE438006E5392ED521B5817558DE5E38172D023E3236EEAE34037E92EA61D6DA463212E012E603709D65EBE8062644A17B1A00FF5DE6E42FD4B3812DACC8C85754616A5539AB60FEF0F9170413E94D3052CBA3A7B9FCF46F318D30DD88DD988C9C16F5BB8823538A8DBC4830B00E7CE5346277E4DAD464128025955E7E5FD184C40EEC184B6143FC4720DA45C7DE3ED4849D6ABC89B1C01D6761660EA595B65E7F70457A32A4D63CCC6FC9736ABDDB9AE9FC8FB90388DAB7BD2189B38488B17DA76B96DAB6871475F59FC36BD53076293EBF9970A1081BA84E44A3A109F6B7231E64C1C54BF9AABD2320185DC054672B2F8F52172CD262F14CCA3237542F421A2413DF5E371DD4F1297E01D81E392A6C4F3BBABAA3091B2F10DB1C4A2C12B0DDDC279F7AD45992225ACA55ADA7CB6370B07B0CD5B935B8DF18BFFA2567EBF77658772D043318B6BA159DBD3AA48C7A509A1F887A05118CBE1470599C2683D9C00DAA5480A05FFDDF7612E6D0056DDF9F
-20180430074559 2 6 100 8191 2 FAEE1044985A5E9005F621D69401F45F006C4AC70C849E5C17F3D28A22FE2C86DEF3780E73C15BC778C65638702E1DF6193E19C79BC8A9CEC1D64759E6E8E1B3754AAD1F82819BDB1F1E224F7D7BFF62061D89F6AE8D8EAF444A543333A4E71A4EBEE16AA9FEAE434FD965B90E6B57A198C12619CC31EF4F2BA3ACEA4C0D31EDD7BD715FE76FCD9282221F27F6CFD678ABC0458E4EDFBB72FB23333A3137C1C9AEB0AE4E5D98148527A5670311C0181861C1305901FF9704C64F88B75AD76574ABE3B5CEAAC2F675F5A56B807B2D9FFEDC975C7CFC6C697A18ED7F3D76C164FE108255F43971A3CCEE8FDC5E95F38B6ED8F8B150E17A7780E2D5CFD9A4D35BC4E2B3C3F4F286DC9DD0A8A53A22E643AD29753AAAB58E4C268A4145B1958050895F7FF5EB300FD0435824024F6DA4C38039A621D8E553493D964479DB2C1647C5123A9ED27955117CB966D41BAB3FA2F6AE1CE0E9787E3C815B1E3A3E3002B0BC54A89D66A3B532E8152BB0FD681D134374B4F2197F0B451E4C68C589E1F213D42CB62FC749D0883D9A68B39B93A1582F957AC989E5664266BB53BB8A07C84F662D5E3B4D4B277840A98B37F8A2CDF892085AF77A0AD370B2A4649F2381B7136AEB189421C6C801DC4F20273922A57C76DB4DB487DFC33DA2AC490C77E8ABA4AC719E6F0428A37ADBBE04F776199ACE29C1BC3B8A1F8E0D049628FDA016735559589D660FB23421D29745528E160F60B5D1923E685D0E04BE9DAC15C90BCAC4F4A7FD5CE52950734F2A849CAAB083DD18324EE82D1679146E60C290A97E2C94FBFEEDD88DE9EBEB346DF9E11AE14F4540A84F98B210E5366A03A82128986543C48FC3867431B2531AF99B379CE7E8D3105C574B0D4974295E98EFA2C01AC31C80CB1654BCEFA8467A55BC7B55ADB92DC1BE438006E5392ED521B5817558DE5E38172D023E3236EEAE34037E92EA61D6DA463212E012E603709D65EBE8062644A17B1A00FF5DE6E42FD4B3812DACC8C85754616A5539AB60FEF0F9170413E94D3052CBA3A7B9FCF46F318D30DD88DD988C9C16F5BB8823538A8DBC4830B00E7CE5346277E4DAD464128025955E7E5FD184C40EEC184B6143FC4720DA45C7DE3ED4849D6ABC89B1C01D6761660EA595B65E7F70457A32A4D63CCC6FC9736ABDDB9AE9FC8FB90388DAB7BD2189B38488B17DA76B96DAB6871475F59FC36BD53076293EBF9970A1081BA84E44A3A109F6B7231E64C1C54BF9AABD2320185DC054672B2F8F52172CD262F14CCA3237542F421A2413DF5E371DD4F1297E01D81E392A6C4F3BBABAA3091B2F10DB1C4A2C12B0DDDC279F7AD45992225ACA55ADA7CB6370B07B0CD5B935B8DF18BFFA2567EBF77658772D043318B6BA159DBD3AA48C7A509A1F887A05118CBE1470599C2683D9C00DAA5480A05FFDDF7612E6D005C5181B
-20180430091811 2 6 100 8191 5 FAEE1044985A5E9005F621D69401F45F006C4AC70C849E5C17F3D28A22FE2C86DEF3780E73C15BC778C65638702E1DF6193E19C79BC8A9CEC1D64759E6E8E1B3754AAD1F82819BDB1F1E224F7D7BFF62061D89F6AE8D8EAF444A543333A4E71A4EBEE16AA9FEAE434FD965B90E6B57A198C12619CC31EF4F2BA3ACEA4C0D31EDD7BD715FE76FCD9282221F27F6CFD678ABC0458E4EDFBB72FB23333A3137C1C9AEB0AE4E5D98148527A5670311C0181861C1305901FF9704C64F88B75AD76574ABE3B5CEAAC2F675F5A56B807B2D9FFEDC975C7CFC6C697A18ED7F3D76C164FE108255F43971A3CCEE8FDC5E95F38B6ED8F8B150E17A7780E2D5CFD9A4D35BC4E2B3C3F4F286DC9DD0A8A53A22E643AD29753AAAB58E4C268A4145B1958050895F7FF5EB300FD0435824024F6DA4C38039A621D8E553493D964479DB2C1647C5123A9ED27955117CB966D41BAB3FA2F6AE1CE0E9787E3C815B1E3A3E3002B0BC54A89D66A3B532E8152BB0FD681D134374B4F2197F0B451E4C68C589E1F213D42CB62FC749D0883D9A68B39B93A1582F957AC989E5664266BB53BB8A07C84F662D5E3B4D4B277840A98B37F8A2CDF892085AF77A0AD370B2A4649F2381B7136AEB189421C6C801DC4F20273922A57C76DB4DB487DFC33DA2AC490C77E8ABA4AC719E6F0428A37ADBBE04F776199ACE29C1BC3B8A1F8E0D049628FDA016735559589D660FB23421D29745528E160F60B5D1923E685D0E04BE9DAC15C90BCAC4F4A7FD5CE52950734F2A849CAAB083DD18324EE82D1679146E60C290A97E2C94FBFEEDD88DE9EBEB346DF9E11AE14F4540A84F98B210E5366A03A82128986543C48FC3867431B2531AF99B379CE7E8D3105C574B0D4974295E98EFA2C01AC31C80CB1654BCEFA8467A55BC7B55ADB92DC1BE438006E5392ED521B5817558DE5E38172D023E3236EEAE34037E92EA61D6DA463212E012E603709D65EBE8062644A17B1A00FF5DE6E42FD4B3812DACC8C85754616A5539AB60FEF0F9170413E94D3052CBA3A7B9FCF46F318D30DD88DD988C9C16F5BB8823538A8DBC4830B00E7CE5346277E4DAD464128025955E7E5FD184C40EEC184B6143FC4720DA45C7DE3ED4849D6ABC89B1C01D6761660EA595B65E7F70457A32A4D63CCC6FC9736ABDDB9AE9FC8FB90388DAB7BD2189B38488B17DA76B96DAB6871475F59FC36BD53076293EBF9970A1081BA84E44A3A109F6B7231E64C1C54BF9AABD2320185DC054672B2F8F52172CD262F14CCA3237542F421A2413DF5E371DD4F1297E01D81E392A6C4F3BBABAA3091B2F10DB1C4A2C12B0DDDC279F7AD45992225ACA55ADA7CB6370B07B0CD5B935B8DF18BFFA2567EBF77658772D043318B6BA159DBD3AA48C7A509A1F887A05118CBE1470599C2683D9C00DAA5480A05FFDDF7612E6D006B26D17
-20180430191732 2 6 100 8191 2 FAEE1044985A5E9005F621D69401F45F006C4AC70C849E5C17F3D28A22FE2C86DEF3780E73C15BC778C65638702E1DF6193E19C79BC8A9CEC1D64759E6E8E1B3754AAD1F82819BDB1F1E224F7D7BFF62061D89F6AE8D8EAF444A543333A4E71A4EBEE16AA9FEAE434FD965B90E6B57A198C12619CC31EF4F2BA3ACEA4C0D31EDD7BD715FE76FCD9282221F27F6CFD678ABC0458E4EDFBB72FB23333A3137C1C9AEB0AE4E5D98148527A5670311C0181861C1305901FF9704C64F88B75AD76574ABE3B5CEAAC2F675F5A56B807B2D9FFEDC975C7CFC6C697A18ED7F3D76C164FE108255F43971A3CCEE8FDC5E95F38B6ED8F8B150E17A7780E2D5CFD9A4D35BC4E2B3C3F4F286DC9DD0A8A53A22E643AD29753AAAB58E4C268A4145B1958050895F7FF5EB300FD0435824024F6DA4C38039A621D8E553493D964479DB2C1647C5123A9ED27955117CB966D41BAB3FA2F6AE1CE0E9787E3C815B1E3A3E3002B0BC54A89D66A3B532E8152BB0FD681D134374B4F2197F0B451E4C68C589E1F213D42CB62FC749D0883D9A68B39B93A1582F957AC989E5664266BB53BB8A07C84F662D5E3B4D4B277840A98B37F8A2CDF892085AF77A0AD370B2A4649F2381B7136AEB189421C6C801DC4F20273922A57C76DB4DB487DFC33DA2AC490C77E8ABA4AC719E6F0428A37ADBBE04F776199ACE29C1BC3B8A1F8E0D049628FDA016735559589D660FB23421D29745528E160F60B5D1923E685D0E04BE9DAC15C90BCAC4F4A7FD5CE52950734F2A849CAAB083DD18324EE82D1679146E60C290A97E2C94FBFEEDD88DE9EBEB346DF9E11AE14F4540A84F98B210E5366A03A82128986543C48FC3867431B2531AF99B379CE7E8D3105C574B0D4974295E98EFA2C01AC31C80CB1654BCEFA8467A55BC7B55ADB92DC1BE438006E5392ED521B5817558DE5E38172D023E3236EEAE34037E92EA61D6DA463212E012E603709D65EBE8062644A17B1A00FF5DE6E42FD4B3812DACC8C85754616A5539AB60FEF0F9170413E94D3052CBA3A7B9FCF46F318D30DD88DD988C9C16F5BB8823538A8DBC4830B00E7CE5346277E4DAD464128025955E7E5FD184C40EEC184B6143FC4720DA45C7DE3ED4849D6ABC89B1C01D6761660EA595B65E7F70457A32A4D63CCC6FC9736ABDDB9AE9FC8FB90388DAB7BD2189B38488B17DA76B96DAB6871475F59FC36BD53076293EBF9970A1081BA84E44A3A109F6B7231E64C1C54BF9AABD2320185DC054672B2F8F52172CD262F14CCA3237542F421A2413DF5E371DD4F1297E01D81E392A6C4F3BBABAA3091B2F10DB1C4A2C12B0DDDC279F7AD45992225ACA55ADA7CB6370B07B0CD5B935B8DF18BFFA2567EBF77658772D043318B6BA159DBD3AA48C7A509A1F887A05118CBE1470599C2683D9C00DAA5480A05FFDDF7612E6D00CD17013
-20180501005739 2 6 100 8191 2 FAEE1044985A5E9005F621D69401F45F006C4AC70C849E5C17F3D28A22FE2C86DEF3780E73C15BC778C65638702E1DF6193E19C79BC8A9CEC1D64759E6E8E1B3754AAD1F82819BDB1F1E224F7D7BFF62061D89F6AE8D8EAF444A543333A4E71A4EBEE16AA9FEAE434FD965B90E6B57A198C12619CC31EF4F2BA3ACEA4C0D31EDD7BD715FE76FCD9282221F27F6CFD678ABC0458E4EDFBB72FB23333A3137C1C9AEB0AE4E5D98148527A5670311C0181861C1305901FF9704C64F88B75AD76574ABE3B5CEAAC2F675F5A56B807B2D9FFEDC975C7CFC6C697A18ED7F3D76C164FE108255F43971A3CCEE8FDC5E95F38B6ED8F8B150E17A7780E2D5CFD9A4D35BC4E2B3C3F4F286DC9DD0A8A53A22E643AD29753AAAB58E4C268A4145B1958050895F7FF5EB300FD0435824024F6DA4C38039A621D8E553493D964479DB2C1647C5123A9ED27955117CB966D41BAB3FA2F6AE1CE0E9787E3C815B1E3A3E3002B0BC54A89D66A3B532E8152BB0FD681D134374B4F2197F0B451E4C68C589E1F213D42CB62FC749D0883D9A68B39B93A1582F957AC989E5664266BB53BB8A07C84F662D5E3B4D4B277840A98B37F8A2CDF892085AF77A0AD370B2A4649F2381B7136AEB189421C6C801DC4F20273922A57C76DB4DB487DFC33DA2AC490C77E8ABA4AC719E6F0428A37ADBBE04F776199ACE29C1BC3B8A1F8E0D049628FDA016735559589D660FB23421D29745528E160F60B5D1923E685D0E04BE9DAC15C90BCAC4F4A7FD5CE52950734F2A849CAAB083DD18324EE82D1679146E60C290A97E2C94FBFEEDD88DE9EBEB346DF9E11AE14F4540A84F98B210E5366A03A82128986543C48FC3867431B2531AF99B379CE7E8D3105C574B0D4974295E98EFA2C01AC31C80CB1654BCEFA8467A55BC7B55ADB92DC1BE438006E5392ED521B5817558DE5E38172D023E3236EEAE34037E92EA61D6DA463212E012E603709D65EBE8062644A17B1A00FF5DE6E42FD4B3812DACC8C85754616A5539AB60FEF0F9170413E94D3052CBA3A7B9FCF46F318D30DD88DD988C9C16F5BB8823538A8DBC4830B00E7CE5346277E4DAD464128025955E7E5FD184C40EEC184B6143FC4720DA45C7DE3ED4849D6ABC89B1C01D6761660EA595B65E7F70457A32A4D63CCC6FC9736ABDDB9AE9FC8FB90388DAB7BD2189B38488B17DA76B96DAB6871475F59FC36BD53076293EBF9970A1081BA84E44A3A109F6B7231E64C1C54BF9AABD2320185DC054672B2F8F52172CD262F14CCA3237542F421A2413DF5E371DD4F1297E01D81E392A6C4F3BBABAA3091B2F10DB1C4A2C12B0DDDC279F7AD45992225ACA55ADA7CB6370B07B0CD5B935B8DF18BFFA2567EBF77658772D043318B6BA159DBD3AA48C7A509A1F887A05118CBE1470599C2683D9C00DAA5480A05FFDDF7612E6D01047BA13
-20180501022059 2 6 100 8191 2 FAEE1044985A5E9005F621D69401F45F006C4AC70C849E5C17F3D28A22FE2C86DEF3780E73C15BC778C65638702E1DF6193E19C79BC8A9CEC1D64759E6E8E1B3754AAD1F82819BDB1F1E224F7D7BFF62061D89F6AE8D8EAF444A543333A4E71A4EBEE16AA9FEAE434FD965B90E6B57A198C12619CC31EF4F2BA3ACEA4C0D31EDD7BD715FE76FCD9282221F27F6CFD678ABC0458E4EDFBB72FB23333A3137C1C9AEB0AE4E5D98148527A5670311C0181861C1305901FF9704C64F88B75AD76574ABE3B5CEAAC2F675F5A56B807B2D9FFEDC975C7CFC6C697A18ED7F3D76C164FE108255F43971A3CCEE8FDC5E95F38B6ED8F8B150E17A7780E2D5CFD9A4D35BC4E2B3C3F4F286DC9DD0A8A53A22E643AD29753AAAB58E4C268A4145B1958050895F7FF5EB300FD0435824024F6DA4C38039A621D8E553493D964479DB2C1647C5123A9ED27955117CB966D41BAB3FA2F6AE1CE0E9787E3C815B1E3A3E3002B0BC54A89D66A3B532E8152BB0FD681D134374B4F2197F0B451E4C68C589E1F213D42CB62FC749D0883D9A68B39B93A1582F957AC989E5664266BB53BB8A07C84F662D5E3B4D4B277840A98B37F8A2CDF892085AF77A0AD370B2A4649F2381B7136AEB189421C6C801DC4F20273922A57C76DB4DB487DFC33DA2AC490C77E8ABA4AC719E6F0428A37ADBBE04F776199ACE29C1BC3B8A1F8E0D049628FDA016735559589D660FB23421D29745528E160F60B5D1923E685D0E04BE9DAC15C90BCAC4F4A7FD5CE52950734F2A849CAAB083DD18324EE82D1679146E60C290A97E2C94FBFEEDD88DE9EBEB346DF9E11AE14F4540A84F98B210E5366A03A82128986543C48FC3867431B2531AF99B379CE7E8D3105C574B0D4974295E98EFA2C01AC31C80CB1654BCEFA8467A55BC7B55ADB92DC1BE438006E5392ED521B5817558DE5E38172D023E3236EEAE34037E92EA61D6DA463212E012E603709D65EBE8062644A17B1A00FF5DE6E42FD4B3812DACC8C85754616A5539AB60FEF0F9170413E94D3052CBA3A7B9FCF46F318D30DD88DD988C9C16F5BB8823538A8DBC4830B00E7CE5346277E4DAD464128025955E7E5FD184C40EEC184B6143FC4720DA45C7DE3ED4849D6ABC89B1C01D6761660EA595B65E7F70457A32A4D63CCC6FC9736ABDDB9AE9FC8FB90388DAB7BD2189B38488B17DA76B96DAB6871475F59FC36BD53076293EBF9970A1081BA84E44A3A109F6B7231E64C1C54BF9AABD2320185DC054672B2F8F52172CD262F14CCA3237542F421A2413DF5E371DD4F1297E01D81E392A6C4F3BBABAA3091B2F10DB1C4A2C12B0DDDC279F7AD45992225ACA55ADA7CB6370B07B0CD5B935B8DF18BFFA2567EBF77658772D043318B6BA159DBD3AA48C7A509A1F887A05118CBE1470599C2683D9C00DAA5480A05FFDDF7612E6D01117B47B
-20180501025617 2 6 100 8191 5 FAEE1044985A5E9005F621D69401F45F006C4AC70C849E5C17F3D28A22FE2C86DEF3780E73C15BC778C65638702E1DF6193E19C79BC8A9CEC1D64759E6E8E1B3754AAD1F82819BDB1F1E224F7D7BFF62061D89F6AE8D8EAF444A543333A4E71A4EBEE16AA9FEAE434FD965B90E6B57A198C12619CC31EF4F2BA3ACEA4C0D31EDD7BD715FE76FCD9282221F27F6CFD678ABC0458E4EDFBB72FB23333A3137C1C9AEB0AE4E5D98148527A5670311C0181861C1305901FF9704C64F88B75AD76574ABE3B5CEAAC2F675F5A56B807B2D9FFEDC975C7CFC6C697A18ED7F3D76C164FE108255F43971A3CCEE8FDC5E95F38B6ED8F8B150E17A7780E2D5CFD9A4D35BC4E2B3C3F4F286DC9DD0A8A53A22E643AD29753AAAB58E4C268A4145B1958050895F7FF5EB300FD0435824024F6DA4C38039A621D8E553493D964479DB2C1647C5123A9ED27955117CB966D41BAB3FA2F6AE1CE0E9787E3C815B1E3A3E3002B0BC54A89D66A3B532E8152BB0FD681D134374B4F2197F0B451E4C68C589E1F213D42CB62FC749D0883D9A68B39B93A1582F957AC989E5664266BB53BB8A07C84F662D5E3B4D4B277840A98B37F8A2CDF892085AF77A0AD370B2A4649F2381B7136AEB189421C6C801DC4F20273922A57C76DB4DB487DFC33DA2AC490C77E8ABA4AC719E6F0428A37ADBBE04F776199ACE29C1BC3B8A1F8E0D049628FDA016735559589D660FB23421D29745528E160F60B5D1923E685D0E04BE9DAC15C90BCAC4F4A7FD5CE52950734F2A849CAAB083DD18324EE82D1679146E60C290A97E2C94FBFEEDD88DE9EBEB346DF9E11AE14F4540A84F98B210E5366A03A82128986543C48FC3867431B2531AF99B379CE7E8D3105C574B0D4974295E98EFA2C01AC31C80CB1654BCEFA8467A55BC7B55ADB92DC1BE438006E5392ED521B5817558DE5E38172D023E3236EEAE34037E92EA61D6DA463212E012E603709D65EBE8062644A17B1A00FF5DE6E42FD4B3812DACC8C85754616A5539AB60FEF0F9170413E94D3052CBA3A7B9FCF46F318D30DD88DD988C9C16F5BB8823538A8DBC4830B00E7CE5346277E4DAD464128025955E7E5FD184C40EEC184B6143FC4720DA45C7DE3ED4849D6ABC89B1C01D6761660EA595B65E7F70457A32A4D63CCC6FC9736ABDDB9AE9FC8FB90388DAB7BD2189B38488B17DA76B96DAB6871475F59FC36BD53076293EBF9970A1081BA84E44A3A109F6B7231E64C1C54BF9AABD2320185DC054672B2F8F52172CD262F14CCA3237542F421A2413DF5E371DD4F1297E01D81E392A6C4F3BBABAA3091B2F10DB1C4A2C12B0DDDC279F7AD45992225ACA55ADA7CB6370B07B0CD5B935B8DF18BFFA2567EBF77658772D043318B6BA159DBD3AA48C7A509A1F887A05118CBE1470599C2683D9C00DAA5480A05FFDDF7612E6D0116B88A7
-20180501031400 2 6 100 8191 5 FAEE1044985A5E9005F621D69401F45F006C4AC70C849E5C17F3D28A22FE2C86DEF3780E73C15BC778C65638702E1DF6193E19C79BC8A9CEC1D64759E6E8E1B3754AAD1F82819BDB1F1E224F7D7BFF62061D89F6AE8D8EAF444A543333A4E71A4EBEE16AA9FEAE434FD965B90E6B57A198C12619CC31EF4F2BA3ACEA4C0D31EDD7BD715FE76FCD9282221F27F6CFD678ABC0458E4EDFBB72FB23333A3137C1C9AEB0AE4E5D98148527A5670311C0181861C1305901FF9704C64F88B75AD76574ABE3B5CEAAC2F675F5A56B807B2D9FFEDC975C7CFC6C697A18ED7F3D76C164FE108255F43971A3CCEE8FDC5E95F38B6ED8F8B150E17A7780E2D5CFD9A4D35BC4E2B3C3F4F286DC9DD0A8A53A22E643AD29753AAAB58E4C268A4145B1958050895F7FF5EB300FD0435824024F6DA4C38039A621D8E553493D964479DB2C1647C5123A9ED27955117CB966D41BAB3FA2F6AE1CE0E9787E3C815B1E3A3E3002B0BC54A89D66A3B532E8152BB0FD681D134374B4F2197F0B451E4C68C589E1F213D42CB62FC749D0883D9A68B39B93A1582F957AC989E5664266BB53BB8A07C84F662D5E3B4D4B277840A98B37F8A2CDF892085AF77A0AD370B2A4649F2381B7136AEB189421C6C801DC4F20273922A57C76DB4DB487DFC33DA2AC490C77E8ABA4AC719E6F0428A37ADBBE04F776199ACE29C1BC3B8A1F8E0D049628FDA016735559589D660FB23421D29745528E160F60B5D1923E685D0E04BE9DAC15C90BCAC4F4A7FD5CE52950734F2A849CAAB083DD18324EE82D1679146E60C290A97E2C94FBFEEDD88DE9EBEB346DF9E11AE14F4540A84F98B210E5366A03A82128986543C48FC3867431B2531AF99B379CE7E8D3105C574B0D4974295E98EFA2C01AC31C80CB1654BCEFA8467A55BC7B55ADB92DC1BE438006E5392ED521B5817558DE5E38172D023E3236EEAE34037E92EA61D6DA463212E012E603709D65EBE8062644A17B1A00FF5DE6E42FD4B3812DACC8C85754616A5539AB60FEF0F9170413E94D3052CBA3A7B9FCF46F318D30DD88DD988C9C16F5BB8823538A8DBC4830B00E7CE5346277E4DAD464128025955E7E5FD184C40EEC184B6143FC4720DA45C7DE3ED4849D6ABC89B1C01D6761660EA595B65E7F70457A32A4D63CCC6FC9736ABDDB9AE9FC8FB90388DAB7BD2189B38488B17DA76B96DAB6871475F59FC36BD53076293EBF9970A1081BA84E44A3A109F6B7231E64C1C54BF9AABD2320185DC054672B2F8F52172CD262F14CCA3237542F421A2413DF5E371DD4F1297E01D81E392A6C4F3BBABAA3091B2F10DB1C4A2C12B0DDDC279F7AD45992225ACA55ADA7CB6370B07B0CD5B935B8DF18BFFA2567EBF77658772D043318B6BA159DBD3AA48C7A509A1F887A05118CBE1470599C2683D9C00DAA5480A05FFDDF7612E6D01190866F
-20180501201356 2 6 100 8191 2 FAEE1044985A5E9005F621D69401F45F006C4AC70C849E5C17F3D28A22FE2C86DEF3780E73C15BC778C65638702E1DF6193E19C79BC8A9CEC1D64759E6E8E1B3754AAD1F82819BDB1F1E224F7D7BFF62061D89F6AE8D8EAF444A543333A4E71A4EBEE16AA9FEAE434FD965B90E6B57A198C12619CC31EF4F2BA3ACEA4C0D31EDD7BD715FE76FCD9282221F27F6CFD678ABC0458E4EDFBB72FB23333A3137C1C9AEB0AE4E5D98148527A5670311C0181861C1305901FF9704C64F88B75AD76574ABE3B5CEAAC2F675F5A56B807B2D9FFEDC975C7CFC6C697A18ED7F3D76C164FE108255F43971A3CCEE8FDC5E95F38B6ED8F8B150E17A7780E2D5CFD9A4D35BC4E2B3C3F4F286DC9DD0A8A53A22E643AD29753AAAB58E4C268A4145B1958050895F7FF5EB300FD0435824024F6DA4C38039A621D8E553493D964479DB2C1647C5123A9ED27955117CB966D41BAB3FA2F6AE1CE0E9787E3C815B1E3A3E3002B0BC54A89D66A3B532E8152BB0FD681D134374B4F2197F0B451E4C68C589E1F213D42CB62FC749D0883D9A68B39B93A1582F957AC989E5664266BB53BB8A07C84F662D5E3B4D4B277840A98B37F8A2CDF892085AF77A0AD370B2A4649F2381B7136AEB189421C6C801DC4F20273922A57C76DB4DB487DFC33DA2AC490C77E8ABA4AC719E6F0428A37ADBBE04F776199ACE29C1BC3B8A1F8E0D049628FDA016735559589D660FB23421D29745528E160F60B5D1923E685D0E04BE9DAC15C90BCAC4F4A7FD5CE52950734F2A849CAAB083DD18324EE82D1679146E60C290A97E2C94FBFEEDD88DE9EBEB346DF9E11AE14F4540A84F98B210E5366A03A82128986543C48FC3867431B2531AF99B379CE7E8D3105C574B0D4974295E98EFA2C01AC31C80CB1654BCEFA8467A55BC7B55ADB92DC1BE438006E5392ED521B5817558DE5E38172D023E3236EEAE34037E92EA61D6DA463212E012E603709D65EBE8062644A17B1A00FF5DE6E42FD4B3812DACC8C85754616A5539AB60FEF0F9170413E94D3052CBA3A7B9FCF46F318D30DD88DD988C9C16F5BB8823538A8DBC4830B00E7CE5346277E4DAD464128025955E7E5FD184C40EEC184B6143FC4720DA45C7DE3ED4849D6ABC89B1C01D6761660EA595B65E7F70457A32A4D63CCC6FC9736ABDDB9AE9FC8FB90388DAB7BD2189B38488B17DA76B96DAB6871475F59FC36BD53076293EBF9970A1081BA84E44A3A109F6B7231E64C1C54BF9AABD2320185DC054672B2F8F52172CD262F14CCA3237542F421A2413DF5E371DD4F1297E01D81E392A6C4F3BBABAA3091B2F10DB1C4A2C12B0DDDC279F7AD45992225ACA55ADA7CB6370B07B0CD5B935B8DF18BFFA2567EBF77658772D043318B6BA159DBD3AA48C7A509A1F887A05118CBE1470599C2683D9C00DAA5480A05FFDDF7612E6D01BDDAB3B
-20180501204003 2 6 100 8191 5 FAEE1044985A5E9005F621D69401F45F006C4AC70C849E5C17F3D28A22FE2C86DEF3780E73C15BC778C65638702E1DF6193E19C79BC8A9CEC1D64759E6E8E1B3754AAD1F82819BDB1F1E224F7D7BFF62061D89F6AE8D8EAF444A543333A4E71A4EBEE16AA9FEAE434FD965B90E6B57A198C12619CC31EF4F2BA3ACEA4C0D31EDD7BD715FE76FCD9282221F27F6CFD678ABC0458E4EDFBB72FB23333A3137C1C9AEB0AE4E5D98148527A5670311C0181861C1305901FF9704C64F88B75AD76574ABE3B5CEAAC2F675F5A56B807B2D9FFEDC975C7CFC6C697A18ED7F3D76C164FE108255F43971A3CCEE8FDC5E95F38B6ED8F8B150E17A7780E2D5CFD9A4D35BC4E2B3C3F4F286DC9DD0A8A53A22E643AD29753AAAB58E4C268A4145B1958050895F7FF5EB300FD0435824024F6DA4C38039A621D8E553493D964479DB2C1647C5123A9ED27955117CB966D41BAB3FA2F6AE1CE0E9787E3C815B1E3A3E3002B0BC54A89D66A3B532E8152BB0FD681D134374B4F2197F0B451E4C68C589E1F213D42CB62FC749D0883D9A68B39B93A1582F957AC989E5664266BB53BB8A07C84F662D5E3B4D4B277840A98B37F8A2CDF892085AF77A0AD370B2A4649F2381B7136AEB189421C6C801DC4F20273922A57C76DB4DB487DFC33DA2AC490C77E8ABA4AC719E6F0428A37ADBBE04F776199ACE29C1BC3B8A1F8E0D049628FDA016735559589D660FB23421D29745528E160F60B5D1923E685D0E04BE9DAC15C90BCAC4F4A7FD5CE52950734F2A849CAAB083DD18324EE82D1679146E60C290A97E2C94FBFEEDD88DE9EBEB346DF9E11AE14F4540A84F98B210E5366A03A82128986543C48FC3867431B2531AF99B379CE7E8D3105C574B0D4974295E98EFA2C01AC31C80CB1654BCEFA8467A55BC7B55ADB92DC1BE438006E5392ED521B5817558DE5E38172D023E3236EEAE34037E92EA61D6DA463212E012E603709D65EBE8062644A17B1A00FF5DE6E42FD4B3812DACC8C85754616A5539AB60FEF0F9170413E94D3052CBA3A7B9FCF46F318D30DD88DD988C9C16F5BB8823538A8DBC4830B00E7CE5346277E4DAD464128025955E7E5FD184C40EEC184B6143FC4720DA45C7DE3ED4849D6ABC89B1C01D6761660EA595B65E7F70457A32A4D63CCC6FC9736ABDDB9AE9FC8FB90388DAB7BD2189B38488B17DA76B96DAB6871475F59FC36BD53076293EBF9970A1081BA84E44A3A109F6B7231E64C1C54BF9AABD2320185DC054672B2F8F52172CD262F14CCA3237542F421A2413DF5E371DD4F1297E01D81E392A6C4F3BBABAA3091B2F10DB1C4A2C12B0DDDC279F7AD45992225ACA55ADA7CB6370B07B0CD5B935B8DF18BFFA2567EBF77658772D043318B6BA159DBD3AA48C7A509A1F887A05118CBE1470599C2683D9C00DAA5480A05FFDDF7612E6D01C18942F
-20180502033416 2 6 100 8191 2 FAEE1044985A5E9005F621D69401F45F006C4AC70C849E5C17F3D28A22FE2C86DEF3780E73C15BC778C65638702E1DF6193E19C79BC8A9CEC1D64759E6E8E1B3754AAD1F82819BDB1F1E224F7D7BFF62061D89F6AE8D8EAF444A543333A4E71A4EBEE16AA9FEAE434FD965B90E6B57A198C12619CC31EF4F2BA3ACEA4C0D31EDD7BD715FE76FCD9282221F27F6CFD678ABC0458E4EDFBB72FB23333A3137C1C9AEB0AE4E5D98148527A5670311C0181861C1305901FF9704C64F88B75AD76574ABE3B5CEAAC2F675F5A56B807B2D9FFEDC975C7CFC6C697A18ED7F3D76C164FE108255F43971A3CCEE8FDC5E95F38B6ED8F8B150E17A7780E2D5CFD9A4D35BC4E2B3C3F4F286DC9DD0A8A53A22E643AD29753AAAB58E4C268A4145B1958050895F7FF5EB300FD0435824024F6DA4C38039A621D8E553493D964479DB2C1647C5123A9ED27955117CB966D41BAB3FA2F6AE1CE0E9787E3C815B1E3A3E3002B0BC54A89D66A3B532E8152BB0FD681D134374B4F2197F0B451E4C68C589E1F213D42CB62FC749D0883D9A68B39B93A1582F957AC989E5664266BB53BB8A07C84F662D5E3B4D4B277840A98B37F8A2CDF892085AF77A0AD370B2A4649F2381B7136AEB189421C6C801DC4F20273922A57C76DB4DB487DFC33DA2AC490C77E8ABA4AC719E6F0428A37ADBBE04F776199ACE29C1BC3B8A1F8E0D049628FDA016735559589D660FB23421D29745528E160F60B5D1923E685D0E04BE9DAC15C90BCAC4F4A7FD5CE52950734F2A849CAAB083DD18324EE82D1679146E60C290A97E2C94FBFEEDD88DE9EBEB346DF9E11AE14F4540A84F98B210E5366A03A82128986543C48FC3867431B2531AF99B379CE7E8D3105C574B0D4974295E98EFA2C01AC31C80CB1654BCEFA8467A55BC7B55ADB92DC1BE438006E5392ED521B5817558DE5E38172D023E3236EEAE34037E92EA61D6DA463212E012E603709D65EBE8062644A17B1A00FF5DE6E42FD4B3812DACC8C85754616A5539AB60FEF0F9170413E94D3052CBA3A7B9FCF46F318D30DD88DD988C9C16F5BB8823538A8DBC4830B00E7CE5346277E4DAD464128025955E7E5FD184C40EEC184B6143FC4720DA45C7DE3ED4849D6ABC89B1C01D6761660EA595B65E7F70457A32A4D63CCC6FC9736ABDDB9AE9FC8FB90388DAB7BD2189B38488B17DA76B96DAB6871475F59FC36BD53076293EBF9970A1081BA84E44A3A109F6B7231E64C1C54BF9AABD2320185DC054672B2F8F52172CD262F14CCA3237542F421A2413DF5E371DD4F1297E01D81E392A6C4F3BBABAA3091B2F10DB1C4A2C12B0DDDC279F7AD45992225ACA55ADA7CB6370B07B0CD5B935B8DF18BFFA2567EBF77658772D043318B6BA159DBD3AA48C7A509A1F887A05118CBE1470599C2683D9C00DAA5480A05FFDDF7612E6D02024C2DB
-20180502214537 2 6 100 8191 2 E3FCBDCFD41A409C58BE083B6485A2D67E20931B1F469774BAE0F1AB2898B800032581B1C4FC71FE136087937A885AFB6FC9E582DD97B8DE3AD2AF861419D5F06278316DFA78BAE7EF099889F0E99575C7812E7240B67623E7877737013A7D5DB3638040083400E8F27600BAC0650D24220CA1B3C05FB7DD70469A201DBFF1308ECA1C7152A6016BB89BFB6C625715EE91A92EA1848F0B2491AA92187468D9E8442679D7F5F6B64BC9D5A3D4E9B58C59EEEB65F8D6B70A71099E1B420BC0FD750CB2F333C23C97966BE727A6B6D9AEC8C0EB2436E01770F03840BFEC9228BB6DD46CE27D5739E18429F464FFF6812B0F66A8B0024BE03294900B8D0BC3CA6785F8C418EFE7068B2CD190A54BB9F90E05885A5C85DC069495C2009F79DBFD7774D7D65B9831FDC295CE146F4EB91DC56ABBD0B64BEAF3C340E0BF123A115D12289D44B650FF8461734308F4701CF2C199676DB3B4804FCDBD6B08C5D4875073AD5C575CA0B64597472A5C23EB4277B52B1128F3B1AE363E36A2C2D6EF5FCE00EE1573A40AD5ACDCDADE3E2672979CF68E87530520B2CA2C1110CBE4B631F3ABE83CFFDB7D5ACDD6DCA5916E30B1771FE29C4F60163B62349B66C0EDDCE8502F7C49DD4089EA5AE31FFB220A88C8D232367B52FAB7644F02E7EC10378697213CF0D90DA83A9941C217C559F88DEC6587AD953C95F11C575F0EFA9CC0650955C733910F2F90C78AE367F67B0F496A100E0B018731404D2BAEC7420F8C2B1FB6612AF69ECF369F236DD0BFB0ACBAED4141B2A14591C6475FC5C3D4E9B6229ECF7E288C015D59A35DE67F633DC586609AB3AB85A02B99DDF1B6FA7D54D4B2DDB767CAAB797C9FB29594B80B5BAACF777666D0B35CE6EFD8E46270C4D715B74FEA64FE34FBF4332BB4E8477CA438645C24444417EA5769B507925FB4B8FC59E429F1EC593C397F71087A080B39A192B5147D04D9F30DC237764C810E519B74EE90F047D0829104B6BA1A01F1CC18C85BE79F52084FAD6D7BF3EDA36D63981D8B75676740DB1AA6E06AD0C1F6A3B665D2D9D0E363FCE37B581C682A5F554D820849CEE7066A7DB011EA7D916B4A45212CBBC7A56ADAD33D203B8A1EDA03064A34351916C243E65D45425974C1468A626B773B48962108203F02814F15640149BCC2325C40F2457F0618CAAFDE26162326F2F81E8C727FAFED1B43E3AC8752E9F4EDFF5B58BD316882B555E63278FEB00B61144703C060B6188F3528E176E9B2D5996579048B723EB678CD56FA979004270E9F88F235404C522ED076E9F287097F2F7600A2D4566D2F6EFB600A9854B61CDB4363040D4F30D96BB011EF4BB0E0F21192F72B106B4F38A79FA384978C3C2A9AB94534BE01C83927BC95A9C5E55E618D7C5D77A9FA39664EEF11B2D50F59396DAD7CDC23F17948585BD88342EED639CFC883
-20180503020255 2 6 100 8191 2 E3FCBDCFD41A409C58BE083B6485A2D67E20931B1F469774BAE0F1AB2898B800032581B1C4FC71FE136087937A885AFB6FC9E582DD97B8DE3AD2AF861419D5F06278316DFA78BAE7EF099889F0E99575C7812E7240B67623E7877737013A7D5DB3638040083400E8F27600BAC0650D24220CA1B3C05FB7DD70469A201DBFF1308ECA1C7152A6016BB89BFB6C625715EE91A92EA1848F0B2491AA92187468D9E8442679D7F5F6B64BC9D5A3D4E9B58C59EEEB65F8D6B70A71099E1B420BC0FD750CB2F333C23C97966BE727A6B6D9AEC8C0EB2436E01770F03840BFEC9228BB6DD46CE27D5739E18429F464FFF6812B0F66A8B0024BE03294900B8D0BC3CA6785F8C418EFE7068B2CD190A54BB9F90E05885A5C85DC069495C2009F79DBFD7774D7D65B9831FDC295CE146F4EB91DC56ABBD0B64BEAF3C340E0BF123A115D12289D44B650FF8461734308F4701CF2C199676DB3B4804FCDBD6B08C5D4875073AD5C575CA0B64597472A5C23EB4277B52B1128F3B1AE363E36A2C2D6EF5FCE00EE1573A40AD5ACDCDADE3E2672979CF68E87530520B2CA2C1110CBE4B631F3ABE83CFFDB7D5ACDD6DCA5916E30B1771FE29C4F60163B62349B66C0EDDCE8502F7C49DD4089EA5AE31FFB220A88C8D232367B52FAB7644F02E7EC10378697213CF0D90DA83A9941C217C559F88DEC6587AD953C95F11C575F0EFA9CC0650955C733910F2F90C78AE367F67B0F496A100E0B018731404D2BAEC7420F8C2B1FB6612AF69ECF369F236DD0BFB0ACBAED4141B2A14591C6475FC5C3D4E9B6229ECF7E288C015D59A35DE67F633DC586609AB3AB85A02B99DDF1B6FA7D54D4B2DDB767CAAB797C9FB29594B80B5BAACF777666D0B35CE6EFD8E46270C4D715B74FEA64FE34FBF4332BB4E8477CA438645C24444417EA5769B507925FB4B8FC59E429F1EC593C397F71087A080B39A192B5147D04D9F30DC237764C810E519B74EE90F047D0829104B6BA1A01F1CC18C85BE79F52084FAD6D7BF3EDA36D63981D8B75676740DB1AA6E06AD0C1F6A3B665D2D9D0E363FCE37B581C682A5F554D820849CEE7066A7DB011EA7D916B4A45212CBBC7A56ADAD33D203B8A1EDA03064A34351916C243E65D45425974C1468A626B773B48962108203F02814F15640149BCC2325C40F2457F0618CAAFDE26162326F2F81E8C727FAFED1B43E3AC8752E9F4EDFF5B58BD316882B555E63278FEB00B61144703C060B6188F3528E176E9B2D5996579048B723EB678CD56FA979004270E9F88F235404C522ED076E9F287097F2F7600A2D4566D2F6EFB600A9854B61CDB4363040D4F30D96BB011EF4BB0E0F21192F72B106B4F38A79FA384978C3C2A9AB94534BE01C83927BC95A9C5E55E618D7C5D77A9FA39664EEF11B2D50F59396DAD7CDC23F17948585BD88342EED63CD06DCB
-20180503022319 2 6 100 8191 5 E3FCBDCFD41A409C58BE083B6485A2D67E20931B1F469774BAE0F1AB2898B800032581B1C4FC71FE136087937A885AFB6FC9E582DD97B8DE3AD2AF861419D5F06278316DFA78BAE7EF099889F0E99575C7812E7240B67623E7877737013A7D5DB3638040083400E8F27600BAC0650D24220CA1B3C05FB7DD70469A201DBFF1308ECA1C7152A6016BB89BFB6C625715EE91A92EA1848F0B2491AA92187468D9E8442679D7F5F6B64BC9D5A3D4E9B58C59EEEB65F8D6B70A71099E1B420BC0FD750CB2F333C23C97966BE727A6B6D9AEC8C0EB2436E01770F03840BFEC9228BB6DD46CE27D5739E18429F464FFF6812B0F66A8B0024BE03294900B8D0BC3CA6785F8C418EFE7068B2CD190A54BB9F90E05885A5C85DC069495C2009F79DBFD7774D7D65B9831FDC295CE146F4EB91DC56ABBD0B64BEAF3C340E0BF123A115D12289D44B650FF8461734308F4701CF2C199676DB3B4804FCDBD6B08C5D4875073AD5C575CA0B64597472A5C23EB4277B52B1128F3B1AE363E36A2C2D6EF5FCE00EE1573A40AD5ACDCDADE3E2672979CF68E87530520B2CA2C1110CBE4B631F3ABE83CFFDB7D5ACDD6DCA5916E30B1771FE29C4F60163B62349B66C0EDDCE8502F7C49DD4089EA5AE31FFB220A88C8D232367B52FAB7644F02E7EC10378697213CF0D90DA83A9941C217C559F88DEC6587AD953C95F11C575F0EFA9CC0650955C733910F2F90C78AE367F67B0F496A100E0B018731404D2BAEC7420F8C2B1FB6612AF69ECF369F236DD0BFB0ACBAED4141B2A14591C6475FC5C3D4E9B6229ECF7E288C015D59A35DE67F633DC586609AB3AB85A02B99DDF1B6FA7D54D4B2DDB767CAAB797C9FB29594B80B5BAACF777666D0B35CE6EFD8E46270C4D715B74FEA64FE34FBF4332BB4E8477CA438645C24444417EA5769B507925FB4B8FC59E429F1EC593C397F71087A080B39A192B5147D04D9F30DC237764C810E519B74EE90F047D0829104B6BA1A01F1CC18C85BE79F52084FAD6D7BF3EDA36D63981D8B75676740DB1AA6E06AD0C1F6A3B665D2D9D0E363FCE37B581C682A5F554D820849CEE7066A7DB011EA7D916B4A45212CBBC7A56ADAD33D203B8A1EDA03064A34351916C243E65D45425974C1468A626B773B48962108203F02814F15640149BCC2325C40F2457F0618CAAFDE26162326F2F81E8C727FAFED1B43E3AC8752E9F4EDFF5B58BD316882B555E63278FEB00B61144703C060B6188F3528E176E9B2D5996579048B723EB678CD56FA979004270E9F88F235404C522ED076E9F287097F2F7600A2D4566D2F6EFB600A9854B61CDB4363040D4F30D96BB011EF4BB0E0F21192F72B106B4F38A79FA384978C3C2A9AB94534BE01C83927BC95A9C5E55E618D7C5D77A9FA39664EEF11B2D50F59396DAD7CDC23F17948585BD88342EED63D0368DF
-20180503125648 2 6 100 8191 5 E3FCBDCFD41A409C58BE083B6485A2D67E20931B1F469774BAE0F1AB2898B800032581B1C4FC71FE136087937A885AFB6FC9E582DD97B8DE3AD2AF861419D5F06278316DFA78BAE7EF099889F0E99575C7812E7240B67623E7877737013A7D5DB3638040083400E8F27600BAC0650D24220CA1B3C05FB7DD70469A201DBFF1308ECA1C7152A6016BB89BFB6C625715EE91A92EA1848F0B2491AA92187468D9E8442679D7F5F6B64BC9D5A3D4E9B58C59EEEB65F8D6B70A71099E1B420BC0FD750CB2F333C23C97966BE727A6B6D9AEC8C0EB2436E01770F03840BFEC9228BB6DD46CE27D5739E18429F464FFF6812B0F66A8B0024BE03294900B8D0BC3CA6785F8C418EFE7068B2CD190A54BB9F90E05885A5C85DC069495C2009F79DBFD7774D7D65B9831FDC295CE146F4EB91DC56ABBD0B64BEAF3C340E0BF123A115D12289D44B650FF8461734308F4701CF2C199676DB3B4804FCDBD6B08C5D4875073AD5C575CA0B64597472A5C23EB4277B52B1128F3B1AE363E36A2C2D6EF5FCE00EE1573A40AD5ACDCDADE3E2672979CF68E87530520B2CA2C1110CBE4B631F3ABE83CFFDB7D5ACDD6DCA5916E30B1771FE29C4F60163B62349B66C0EDDCE8502F7C49DD4089EA5AE31FFB220A88C8D232367B52FAB7644F02E7EC10378697213CF0D90DA83A9941C217C559F88DEC6587AD953C95F11C575F0EFA9CC0650955C733910F2F90C78AE367F67B0F496A100E0B018731404D2BAEC7420F8C2B1FB6612AF69ECF369F236DD0BFB0ACBAED4141B2A14591C6475FC5C3D4E9B6229ECF7E288C015D59A35DE67F633DC586609AB3AB85A02B99DDF1B6FA7D54D4B2DDB767CAAB797C9FB29594B80B5BAACF777666D0B35CE6EFD8E46270C4D715B74FEA64FE34FBF4332BB4E8477CA438645C24444417EA5769B507925FB4B8FC59E429F1EC593C397F71087A080B39A192B5147D04D9F30DC237764C810E519B74EE90F047D0829104B6BA1A01F1CC18C85BE79F52084FAD6D7BF3EDA36D63981D8B75676740DB1AA6E06AD0C1F6A3B665D2D9D0E363FCE37B581C682A5F554D820849CEE7066A7DB011EA7D916B4A45212CBBC7A56ADAD33D203B8A1EDA03064A34351916C243E65D45425974C1468A626B773B48962108203F02814F15640149BCC2325C40F2457F0618CAAFDE26162326F2F81E8C727FAFED1B43E3AC8752E9F4EDFF5B58BD316882B555E63278FEB00B61144703C060B6188F3528E176E9B2D5996579048B723EB678CD56FA979004270E9F88F235404C522ED076E9F287097F2F7600A2D4566D2F6EFB600A9854B61CDB4363040D4F30D96BB011EF4BB0E0F21192F72B106B4F38A79FA384978C3C2A9AB94534BE01C83927BC95A9C5E55E618D7C5D77A9FA39664EEF11B2D50F59396DAD7CDC23F17948585BD88342EED6446836FF
-20180503155809 2 6 100 8191 5 E3FCBDCFD41A409C58BE083B6485A2D67E20931B1F469774BAE0F1AB2898B800032581B1C4FC71FE136087937A885AFB6FC9E582DD97B8DE3AD2AF861419D5F06278316DFA78BAE7EF099889F0E99575C7812E7240B67623E7877737013A7D5DB3638040083400E8F27600BAC0650D24220CA1B3C05FB7DD70469A201DBFF1308ECA1C7152A6016BB89BFB6C625715EE91A92EA1848F0B2491AA92187468D9E8442679D7F5F6B64BC9D5A3D4E9B58C59EEEB65F8D6B70A71099E1B420BC0FD750CB2F333C23C97966BE727A6B6D9AEC8C0EB2436E01770F03840BFEC9228BB6DD46CE27D5739E18429F464FFF6812B0F66A8B0024BE03294900B8D0BC3CA6785F8C418EFE7068B2CD190A54BB9F90E05885A5C85DC069495C2009F79DBFD7774D7D65B9831FDC295CE146F4EB91DC56ABBD0B64BEAF3C340E0BF123A115D12289D44B650FF8461734308F4701CF2C199676DB3B4804FCDBD6B08C5D4875073AD5C575CA0B64597472A5C23EB4277B52B1128F3B1AE363E36A2C2D6EF5FCE00EE1573A40AD5ACDCDADE3E2672979CF68E87530520B2CA2C1110CBE4B631F3ABE83CFFDB7D5ACDD6DCA5916E30B1771FE29C4F60163B62349B66C0EDDCE8502F7C49DD4089EA5AE31FFB220A88C8D232367B52FAB7644F02E7EC10378697213CF0D90DA83A9941C217C559F88DEC6587AD953C95F11C575F0EFA9CC0650955C733910F2F90C78AE367F67B0F496A100E0B018731404D2BAEC7420F8C2B1FB6612AF69ECF369F236DD0BFB0ACBAED4141B2A14591C6475FC5C3D4E9B6229ECF7E288C015D59A35DE67F633DC586609AB3AB85A02B99DDF1B6FA7D54D4B2DDB767CAAB797C9FB29594B80B5BAACF777666D0B35CE6EFD8E46270C4D715B74FEA64FE34FBF4332BB4E8477CA438645C24444417EA5769B507925FB4B8FC59E429F1EC593C397F71087A080B39A192B5147D04D9F30DC237764C810E519B74EE90F047D0829104B6BA1A01F1CC18C85BE79F52084FAD6D7BF3EDA36D63981D8B75676740DB1AA6E06AD0C1F6A3B665D2D9D0E363FCE37B581C682A5F554D820849CEE7066A7DB011EA7D916B4A45212CBBC7A56ADAD33D203B8A1EDA03064A34351916C243E65D45425974C1468A626B773B48962108203F02814F15640149BCC2325C40F2457F0618CAAFDE26162326F2F81E8C727FAFED1B43E3AC8752E9F4EDFF5B58BD316882B555E63278FEB00B61144703C060B6188F3528E176E9B2D5996579048B723EB678CD56FA979004270E9F88F235404C522ED076E9F287097F2F7600A2D4566D2F6EFB600A9854B61CDB4363040D4F30D96BB011EF4BB0E0F21192F72B106B4F38A79FA384978C3C2A9AB94534BE01C83927BC95A9C5E55E618D7C5D77A9FA39664EEF11B2D50F59396DAD7CDC23F17948585BD88342EED64679B30F
-20180503191156 2 6 100 8191 5 E3FCBDCFD41A409C58BE083B6485A2D67E20931B1F469774BAE0F1AB2898B800032581B1C4FC71FE136087937A885AFB6FC9E582DD97B8DE3AD2AF861419D5F06278316DFA78BAE7EF099889F0E99575C7812E7240B67623E7877737013A7D5DB3638040083400E8F27600BAC0650D24220CA1B3C05FB7DD70469A201DBFF1308ECA1C7152A6016BB89BFB6C625715EE91A92EA1848F0B2491AA92187468D9E8442679D7F5F6B64BC9D5A3D4E9B58C59EEEB65F8D6B70A71099E1B420BC0FD750CB2F333C23C97966BE727A6B6D9AEC8C0EB2436E01770F03840BFEC9228BB6DD46CE27D5739E18429F464FFF6812B0F66A8B0024BE03294900B8D0BC3CA6785F8C418EFE7068B2CD190A54BB9F90E05885A5C85DC069495C2009F79DBFD7774D7D65B9831FDC295CE146F4EB91DC56ABBD0B64BEAF3C340E0BF123A115D12289D44B650FF8461734308F4701CF2C199676DB3B4804FCDBD6B08C5D4875073AD5C575CA0B64597472A5C23EB4277B52B1128F3B1AE363E36A2C2D6EF5FCE00EE1573A40AD5ACDCDADE3E2672979CF68E87530520B2CA2C1110CBE4B631F3ABE83CFFDB7D5ACDD6DCA5916E30B1771FE29C4F60163B62349B66C0EDDCE8502F7C49DD4089EA5AE31FFB220A88C8D232367B52FAB7644F02E7EC10378697213CF0D90DA83A9941C217C559F88DEC6587AD953C95F11C575F0EFA9CC0650955C733910F2F90C78AE367F67B0F496A100E0B018731404D2BAEC7420F8C2B1FB6612AF69ECF369F236DD0BFB0ACBAED4141B2A14591C6475FC5C3D4E9B6229ECF7E288C015D59A35DE67F633DC586609AB3AB85A02B99DDF1B6FA7D54D4B2DDB767CAAB797C9FB29594B80B5BAACF777666D0B35CE6EFD8E46270C4D715B74FEA64FE34FBF4332BB4E8477CA438645C24444417EA5769B507925FB4B8FC59E429F1EC593C397F71087A080B39A192B5147D04D9F30DC237764C810E519B74EE90F047D0829104B6BA1A01F1CC18C85BE79F52084FAD6D7BF3EDA36D63981D8B75676740DB1AA6E06AD0C1F6A3B665D2D9D0E363FCE37B581C682A5F554D820849CEE7066A7DB011EA7D916B4A45212CBBC7A56ADAD33D203B8A1EDA03064A34351916C243E65D45425974C1468A626B773B48962108203F02814F15640149BCC2325C40F2457F0618CAAFDE26162326F2F81E8C727FAFED1B43E3AC8752E9F4EDFF5B58BD316882B555E63278FEB00B61144703C060B6188F3528E176E9B2D5996579048B723EB678CD56FA979004270E9F88F235404C522ED076E9F287097F2F7600A2D4566D2F6EFB600A9854B61CDB4363040D4F30D96BB011EF4BB0E0F21192F72B106B4F38A79FA384978C3C2A9AB94534BE01C83927BC95A9C5E55E618D7C5D77A9FA39664EEF11B2D50F59396DAD7CDC23F17948585BD88342EED648AEA87F
-20180504050354 2 6 100 8191 5 E3FCBDCFD41A409C58BE083B6485A2D67E20931B1F469774BAE0F1AB2898B800032581B1C4FC71FE136087937A885AFB6FC9E582DD97B8DE3AD2AF861419D5F06278316DFA78BAE7EF099889F0E99575C7812E7240B67623E7877737013A7D5DB3638040083400E8F27600BAC0650D24220CA1B3C05FB7DD70469A201DBFF1308ECA1C7152A6016BB89BFB6C625715EE91A92EA1848F0B2491AA92187468D9E8442679D7F5F6B64BC9D5A3D4E9B58C59EEEB65F8D6B70A71099E1B420BC0FD750CB2F333C23C97966BE727A6B6D9AEC8C0EB2436E01770F03840BFEC9228BB6DD46CE27D5739E18429F464FFF6812B0F66A8B0024BE03294900B8D0BC3CA6785F8C418EFE7068B2CD190A54BB9F90E05885A5C85DC069495C2009F79DBFD7774D7D65B9831FDC295CE146F4EB91DC56ABBD0B64BEAF3C340E0BF123A115D12289D44B650FF8461734308F4701CF2C199676DB3B4804FCDBD6B08C5D4875073AD5C575CA0B64597472A5C23EB4277B52B1128F3B1AE363E36A2C2D6EF5FCE00EE1573A40AD5ACDCDADE3E2672979CF68E87530520B2CA2C1110CBE4B631F3ABE83CFFDB7D5ACDD6DCA5916E30B1771FE29C4F60163B62349B66C0EDDCE8502F7C49DD4089EA5AE31FFB220A88C8D232367B52FAB7644F02E7EC10378697213CF0D90DA83A9941C217C559F88DEC6587AD953C95F11C575F0EFA9CC0650955C733910F2F90C78AE367F67B0F496A100E0B018731404D2BAEC7420F8C2B1FB6612AF69ECF369F236DD0BFB0ACBAED4141B2A14591C6475FC5C3D4E9B6229ECF7E288C015D59A35DE67F633DC586609AB3AB85A02B99DDF1B6FA7D54D4B2DDB767CAAB797C9FB29594B80B5BAACF777666D0B35CE6EFD8E46270C4D715B74FEA64FE34FBF4332BB4E8477CA438645C24444417EA5769B507925FB4B8FC59E429F1EC593C397F71087A080B39A192B5147D04D9F30DC237764C810E519B74EE90F047D0829104B6BA1A01F1CC18C85BE79F52084FAD6D7BF3EDA36D63981D8B75676740DB1AA6E06AD0C1F6A3B665D2D9D0E363FCE37B581C682A5F554D820849CEE7066A7DB011EA7D916B4A45212CBBC7A56ADAD33D203B8A1EDA03064A34351916C243E65D45425974C1468A626B773B48962108203F02814F15640149BCC2325C40F2457F0618CAAFDE26162326F2F81E8C727FAFED1B43E3AC8752E9F4EDFF5B58BD316882B555E63278FEB00B61144703C060B6188F3528E176E9B2D5996579048B723EB678CD56FA979004270E9F88F235404C522ED076E9F287097F2F7600A2D4566D2F6EFB600A9854B61CDB4363040D4F30D96BB011EF4BB0E0F21192F72B106B4F38A79FA384978C3C2A9AB94534BE01C83927BC95A9C5E55E618D7C5D77A9FA39664EEF11B2D50F59396DAD7CDC23F17948585BD88342EED64F75441F
-20180504071143 2 6 100 8191 2 E3FCBDCFD41A409C58BE083B6485A2D67E20931B1F469774BAE0F1AB2898B800032581B1C4FC71FE136087937A885AFB6FC9E582DD97B8DE3AD2AF861419D5F06278316DFA78BAE7EF099889F0E99575C7812E7240B67623E7877737013A7D5DB3638040083400E8F27600BAC0650D24220CA1B3C05FB7DD70469A201DBFF1308ECA1C7152A6016BB89BFB6C625715EE91A92EA1848F0B2491AA92187468D9E8442679D7F5F6B64BC9D5A3D4E9B58C59EEEB65F8D6B70A71099E1B420BC0FD750CB2F333C23C97966BE727A6B6D9AEC8C0EB2436E01770F03840BFEC9228BB6DD46CE27D5739E18429F464FFF6812B0F66A8B0024BE03294900B8D0BC3CA6785F8C418EFE7068B2CD190A54BB9F90E05885A5C85DC069495C2009F79DBFD7774D7D65B9831FDC295CE146F4EB91DC56ABBD0B64BEAF3C340E0BF123A115D12289D44B650FF8461734308F4701CF2C199676DB3B4804FCDBD6B08C5D4875073AD5C575CA0B64597472A5C23EB4277B52B1128F3B1AE363E36A2C2D6EF5FCE00EE1573A40AD5ACDCDADE3E2672979CF68E87530520B2CA2C1110CBE4B631F3ABE83CFFDB7D5ACDD6DCA5916E30B1771FE29C4F60163B62349B66C0EDDCE8502F7C49DD4089EA5AE31FFB220A88C8D232367B52FAB7644F02E7EC10378697213CF0D90DA83A9941C217C559F88DEC6587AD953C95F11C575F0EFA9CC0650955C733910F2F90C78AE367F67B0F496A100E0B018731404D2BAEC7420F8C2B1FB6612AF69ECF369F236DD0BFB0ACBAED4141B2A14591C6475FC5C3D4E9B6229ECF7E288C015D59A35DE67F633DC586609AB3AB85A02B99DDF1B6FA7D54D4B2DDB767CAAB797C9FB29594B80B5BAACF777666D0B35CE6EFD8E46270C4D715B74FEA64FE34FBF4332BB4E8477CA438645C24444417EA5769B507925FB4B8FC59E429F1EC593C397F71087A080B39A192B5147D04D9F30DC237764C810E519B74EE90F047D0829104B6BA1A01F1CC18C85BE79F52084FAD6D7BF3EDA36D63981D8B75676740DB1AA6E06AD0C1F6A3B665D2D9D0E363FCE37B581C682A5F554D820849CEE7066A7DB011EA7D916B4A45212CBBC7A56ADAD33D203B8A1EDA03064A34351916C243E65D45425974C1468A626B773B48962108203F02814F15640149BCC2325C40F2457F0618CAAFDE26162326F2F81E8C727FAFED1B43E3AC8752E9F4EDFF5B58BD316882B555E63278FEB00B61144703C060B6188F3528E176E9B2D5996579048B723EB678CD56FA979004270E9F88F235404C522ED076E9F287097F2F7600A2D4566D2F6EFB600A9854B61CDB4363040D4F30D96BB011EF4BB0E0F21192F72B106B4F38A79FA384978C3C2A9AB94534BE01C83927BC95A9C5E55E618D7C5D77A9FA39664EEF11B2D50F59396DAD7CDC23F17948585BD88342EED650DC49F3
-20180504084722 2 6 100 8191 2 E3FCBDCFD41A409C58BE083B6485A2D67E20931B1F469774BAE0F1AB2898B800032581B1C4FC71FE136087937A885AFB6FC9E582DD97B8DE3AD2AF861419D5F06278316DFA78BAE7EF099889F0E99575C7812E7240B67623E7877737013A7D5DB3638040083400E8F27600BAC0650D24220CA1B3C05FB7DD70469A201DBFF1308ECA1C7152A6016BB89BFB6C625715EE91A92EA1848F0B2491AA92187468D9E8442679D7F5F6B64BC9D5A3D4E9B58C59EEEB65F8D6B70A71099E1B420BC0FD750CB2F333C23C97966BE727A6B6D9AEC8C0EB2436E01770F03840BFEC9228BB6DD46CE27D5739E18429F464FFF6812B0F66A8B0024BE03294900B8D0BC3CA6785F8C418EFE7068B2CD190A54BB9F90E05885A5C85DC069495C2009F79DBFD7774D7D65B9831FDC295CE146F4EB91DC56ABBD0B64BEAF3C340E0BF123A115D12289D44B650FF8461734308F4701CF2C199676DB3B4804FCDBD6B08C5D4875073AD5C575CA0B64597472A5C23EB4277B52B1128F3B1AE363E36A2C2D6EF5FCE00EE1573A40AD5ACDCDADE3E2672979CF68E87530520B2CA2C1110CBE4B631F3ABE83CFFDB7D5ACDD6DCA5916E30B1771FE29C4F60163B62349B66C0EDDCE8502F7C49DD4089EA5AE31FFB220A88C8D232367B52FAB7644F02E7EC10378697213CF0D90DA83A9941C217C559F88DEC6587AD953C95F11C575F0EFA9CC0650955C733910F2F90C78AE367F67B0F496A100E0B018731404D2BAEC7420F8C2B1FB6612AF69ECF369F236DD0BFB0ACBAED4141B2A14591C6475FC5C3D4E9B6229ECF7E288C015D59A35DE67F633DC586609AB3AB85A02B99DDF1B6FA7D54D4B2DDB767CAAB797C9FB29594B80B5BAACF777666D0B35CE6EFD8E46270C4D715B74FEA64FE34FBF4332BB4E8477CA438645C24444417EA5769B507925FB4B8FC59E429F1EC593C397F71087A080B39A192B5147D04D9F30DC237764C810E519B74EE90F047D0829104B6BA1A01F1CC18C85BE79F52084FAD6D7BF3EDA36D63981D8B75676740DB1AA6E06AD0C1F6A3B665D2D9D0E363FCE37B581C682A5F554D820849CEE7066A7DB011EA7D916B4A45212CBBC7A56ADAD33D203B8A1EDA03064A34351916C243E65D45425974C1468A626B773B48962108203F02814F15640149BCC2325C40F2457F0618CAAFDE26162326F2F81E8C727FAFED1B43E3AC8752E9F4EDFF5B58BD316882B555E63278FEB00B61144703C060B6188F3528E176E9B2D5996579048B723EB678CD56FA979004270E9F88F235404C522ED076E9F287097F2F7600A2D4566D2F6EFB600A9854B61CDB4363040D4F30D96BB011EF4BB0E0F21192F72B106B4F38A79FA384978C3C2A9AB94534BE01C83927BC95A9C5E55E618D7C5D77A9FA39664EEF11B2D50F59396DAD7CDC23F17948585BD88342EED651F00D33
-20180504103430 2 6 100 8191 5 E3FCBDCFD41A409C58BE083B6485A2D67E20931B1F469774BAE0F1AB2898B800032581B1C4FC71FE136087937A885AFB6FC9E582DD97B8DE3AD2AF861419D5F06278316DFA78BAE7EF099889F0E99575C7812E7240B67623E7877737013A7D5DB3638040083400E8F27600BAC0650D24220CA1B3C05FB7DD70469A201DBFF1308ECA1C7152A6016BB89BFB6C625715EE91A92EA1848F0B2491AA92187468D9E8442679D7F5F6B64BC9D5A3D4E9B58C59EEEB65F8D6B70A71099E1B420BC0FD750CB2F333C23C97966BE727A6B6D9AEC8C0EB2436E01770F03840BFEC9228BB6DD46CE27D5739E18429F464FFF6812B0F66A8B0024BE03294900B8D0BC3CA6785F8C418EFE7068B2CD190A54BB9F90E05885A5C85DC069495C2009F79DBFD7774D7D65B9831FDC295CE146F4EB91DC56ABBD0B64BEAF3C340E0BF123A115D12289D44B650FF8461734308F4701CF2C199676DB3B4804FCDBD6B08C5D4875073AD5C575CA0B64597472A5C23EB4277B52B1128F3B1AE363E36A2C2D6EF5FCE00EE1573A40AD5ACDCDADE3E2672979CF68E87530520B2CA2C1110CBE4B631F3ABE83CFFDB7D5ACDD6DCA5916E30B1771FE29C4F60163B62349B66C0EDDCE8502F7C49DD4089EA5AE31FFB220A88C8D232367B52FAB7644F02E7EC10378697213CF0D90DA83A9941C217C559F88DEC6587AD953C95F11C575F0EFA9CC0650955C733910F2F90C78AE367F67B0F496A100E0B018731404D2BAEC7420F8C2B1FB6612AF69ECF369F236DD0BFB0ACBAED4141B2A14591C6475FC5C3D4E9B6229ECF7E288C015D59A35DE67F633DC586609AB3AB85A02B99DDF1B6FA7D54D4B2DDB767CAAB797C9FB29594B80B5BAACF777666D0B35CE6EFD8E46270C4D715B74FEA64FE34FBF4332BB4E8477CA438645C24444417EA5769B507925FB4B8FC59E429F1EC593C397F71087A080B39A192B5147D04D9F30DC237764C810E519B74EE90F047D0829104B6BA1A01F1CC18C85BE79F52084FAD6D7BF3EDA36D63981D8B75676740DB1AA6E06AD0C1F6A3B665D2D9D0E363FCE37B581C682A5F554D820849CEE7066A7DB011EA7D916B4A45212CBBC7A56ADAD33D203B8A1EDA03064A34351916C243E65D45425974C1468A626B773B48962108203F02814F15640149BCC2325C40F2457F0618CAAFDE26162326F2F81E8C727FAFED1B43E3AC8752E9F4EDFF5B58BD316882B555E63278FEB00B61144703C060B6188F3528E176E9B2D5996579048B723EB678CD56FA979004270E9F88F235404C522ED076E9F287097F2F7600A2D4566D2F6EFB600A9854B61CDB4363040D4F30D96BB011EF4BB0E0F21192F72B106B4F38A79FA384978C3C2A9AB94534BE01C83927BC95A9C5E55E618D7C5D77A9FA39664EEF11B2D50F59396DAD7CDC23F17948585BD88342EED65316D0B7
-20180504105453 2 6 100 8191 2 E3FCBDCFD41A409C58BE083B6485A2D67E20931B1F469774BAE0F1AB2898B800032581B1C4FC71FE136087937A885AFB6FC9E582DD97B8DE3AD2AF861419D5F06278316DFA78BAE7EF099889F0E99575C7812E7240B67623E7877737013A7D5DB3638040083400E8F27600BAC0650D24220CA1B3C05FB7DD70469A201DBFF1308ECA1C7152A6016BB89BFB6C625715EE91A92EA1848F0B2491AA92187468D9E8442679D7F5F6B64BC9D5A3D4E9B58C59EEEB65F8D6B70A71099E1B420BC0FD750CB2F333C23C97966BE727A6B6D9AEC8C0EB2436E01770F03840BFEC9228BB6DD46CE27D5739E18429F464FFF6812B0F66A8B0024BE03294900B8D0BC3CA6785F8C418EFE7068B2CD190A54BB9F90E05885A5C85DC069495C2009F79DBFD7774D7D65B9831FDC295CE146F4EB91DC56ABBD0B64BEAF3C340E0BF123A115D12289D44B650FF8461734308F4701CF2C199676DB3B4804FCDBD6B08C5D4875073AD5C575CA0B64597472A5C23EB4277B52B1128F3B1AE363E36A2C2D6EF5FCE00EE1573A40AD5ACDCDADE3E2672979CF68E87530520B2CA2C1110CBE4B631F3ABE83CFFDB7D5ACDD6DCA5916E30B1771FE29C4F60163B62349B66C0EDDCE8502F7C49DD4089EA5AE31FFB220A88C8D232367B52FAB7644F02E7EC10378697213CF0D90DA83A9941C217C559F88DEC6587AD953C95F11C575F0EFA9CC0650955C733910F2F90C78AE367F67B0F496A100E0B018731404D2BAEC7420F8C2B1FB6612AF69ECF369F236DD0BFB0ACBAED4141B2A14591C6475FC5C3D4E9B6229ECF7E288C015D59A35DE67F633DC586609AB3AB85A02B99DDF1B6FA7D54D4B2DDB767CAAB797C9FB29594B80B5BAACF777666D0B35CE6EFD8E46270C4D715B74FEA64FE34FBF4332BB4E8477CA438645C24444417EA5769B507925FB4B8FC59E429F1EC593C397F71087A080B39A192B5147D04D9F30DC237764C810E519B74EE90F047D0829104B6BA1A01F1CC18C85BE79F52084FAD6D7BF3EDA36D63981D8B75676740DB1AA6E06AD0C1F6A3B665D2D9D0E363FCE37B581C682A5F554D820849CEE7066A7DB011EA7D916B4A45212CBBC7A56ADAD33D203B8A1EDA03064A34351916C243E65D45425974C1468A626B773B48962108203F02814F15640149BCC2325C40F2457F0618CAAFDE26162326F2F81E8C727FAFED1B43E3AC8752E9F4EDFF5B58BD316882B555E63278FEB00B61144703C060B6188F3528E176E9B2D5996579048B723EB678CD56FA979004270E9F88F235404C522ED076E9F287097F2F7600A2D4566D2F6EFB600A9854B61CDB4363040D4F30D96BB011EF4BB0E0F21192F72B106B4F38A79FA384978C3C2A9AB94534BE01C83927BC95A9C5E55E618D7C5D77A9FA39664EEF11B2D50F59396DAD7CDC23F17948585BD88342EED65348CDBB
-20180504234946 2 6 100 8191 5 E3FCBDCFD41A409C58BE083B6485A2D67E20931B1F469774BAE0F1AB2898B800032581B1C4FC71FE136087937A885AFB6FC9E582DD97B8DE3AD2AF861419D5F06278316DFA78BAE7EF099889F0E99575C7812E7240B67623E7877737013A7D5DB3638040083400E8F27600BAC0650D24220CA1B3C05FB7DD70469A201DBFF1308ECA1C7152A6016BB89BFB6C625715EE91A92EA1848F0B2491AA92187468D9E8442679D7F5F6B64BC9D5A3D4E9B58C59EEEB65F8D6B70A71099E1B420BC0FD750CB2F333C23C97966BE727A6B6D9AEC8C0EB2436E01770F03840BFEC9228BB6DD46CE27D5739E18429F464FFF6812B0F66A8B0024BE03294900B8D0BC3CA6785F8C418EFE7068B2CD190A54BB9F90E05885A5C85DC069495C2009F79DBFD7774D7D65B9831FDC295CE146F4EB91DC56ABBD0B64BEAF3C340E0BF123A115D12289D44B650FF8461734308F4701CF2C199676DB3B4804FCDBD6B08C5D4875073AD5C575CA0B64597472A5C23EB4277B52B1128F3B1AE363E36A2C2D6EF5FCE00EE1573A40AD5ACDCDADE3E2672979CF68E87530520B2CA2C1110CBE4B631F3ABE83CFFDB7D5ACDD6DCA5916E30B1771FE29C4F60163B62349B66C0EDDCE8502F7C49DD4089EA5AE31FFB220A88C8D232367B52FAB7644F02E7EC10378697213CF0D90DA83A9941C217C559F88DEC6587AD953C95F11C575F0EFA9CC0650955C733910F2F90C78AE367F67B0F496A100E0B018731404D2BAEC7420F8C2B1FB6612AF69ECF369F236DD0BFB0ACBAED4141B2A14591C6475FC5C3D4E9B6229ECF7E288C015D59A35DE67F633DC586609AB3AB85A02B99DDF1B6FA7D54D4B2DDB767CAAB797C9FB29594B80B5BAACF777666D0B35CE6EFD8E46270C4D715B74FEA64FE34FBF4332BB4E8477CA438645C24444417EA5769B507925FB4B8FC59E429F1EC593C397F71087A080B39A192B5147D04D9F30DC237764C810E519B74EE90F047D0829104B6BA1A01F1CC18C85BE79F52084FAD6D7BF3EDA36D63981D8B75676740DB1AA6E06AD0C1F6A3B665D2D9D0E363FCE37B581C682A5F554D820849CEE7066A7DB011EA7D916B4A45212CBBC7A56ADAD33D203B8A1EDA03064A34351916C243E65D45425974C1468A626B773B48962108203F02814F15640149BCC2325C40F2457F0618CAAFDE26162326F2F81E8C727FAFED1B43E3AC8752E9F4EDFF5B58BD316882B555E63278FEB00B61144703C060B6188F3528E176E9B2D5996579048B723EB678CD56FA979004270E9F88F235404C522ED076E9F287097F2F7600A2D4566D2F6EFB600A9854B61CDB4363040D4F30D96BB011EF4BB0E0F21192F72B106B4F38A79FA384978C3C2A9AB94534BE01C83927BC95A9C5E55E618D7C5D77A9FA39664EEF11B2D50F59396DAD7CDC23F17948585BD88342EED65BF5CBBF
-20180505042813 2 6 100 8191 5 E3FCBDCFD41A409C58BE083B6485A2D67E20931B1F469774BAE0F1AB2898B800032581B1C4FC71FE136087937A885AFB6FC9E582DD97B8DE3AD2AF861419D5F06278316DFA78BAE7EF099889F0E99575C7812E7240B67623E7877737013A7D5DB3638040083400E8F27600BAC0650D24220CA1B3C05FB7DD70469A201DBFF1308ECA1C7152A6016BB89BFB6C625715EE91A92EA1848F0B2491AA92187468D9E8442679D7F5F6B64BC9D5A3D4E9B58C59EEEB65F8D6B70A71099E1B420BC0FD750CB2F333C23C97966BE727A6B6D9AEC8C0EB2436E01770F03840BFEC9228BB6DD46CE27D5739E18429F464FFF6812B0F66A8B0024BE03294900B8D0BC3CA6785F8C418EFE7068B2CD190A54BB9F90E05885A5C85DC069495C2009F79DBFD7774D7D65B9831FDC295CE146F4EB91DC56ABBD0B64BEAF3C340E0BF123A115D12289D44B650FF8461734308F4701CF2C199676DB3B4804FCDBD6B08C5D4875073AD5C575CA0B64597472A5C23EB4277B52B1128F3B1AE363E36A2C2D6EF5FCE00EE1573A40AD5ACDCDADE3E2672979CF68E87530520B2CA2C1110CBE4B631F3ABE83CFFDB7D5ACDD6DCA5916E30B1771FE29C4F60163B62349B66C0EDDCE8502F7C49DD4089EA5AE31FFB220A88C8D232367B52FAB7644F02E7EC10378697213CF0D90DA83A9941C217C559F88DEC6587AD953C95F11C575F0EFA9CC0650955C733910F2F90C78AE367F67B0F496A100E0B018731404D2BAEC7420F8C2B1FB6612AF69ECF369F236DD0BFB0ACBAED4141B2A14591C6475FC5C3D4E9B6229ECF7E288C015D59A35DE67F633DC586609AB3AB85A02B99DDF1B6FA7D54D4B2DDB767CAAB797C9FB29594B80B5BAACF777666D0B35CE6EFD8E46270C4D715B74FEA64FE34FBF4332BB4E8477CA438645C24444417EA5769B507925FB4B8FC59E429F1EC593C397F71087A080B39A192B5147D04D9F30DC237764C810E519B74EE90F047D0829104B6BA1A01F1CC18C85BE79F52084FAD6D7BF3EDA36D63981D8B75676740DB1AA6E06AD0C1F6A3B665D2D9D0E363FCE37B581C682A5F554D820849CEE7066A7DB011EA7D916B4A45212CBBC7A56ADAD33D203B8A1EDA03064A34351916C243E65D45425974C1468A626B773B48962108203F02814F15640149BCC2325C40F2457F0618CAAFDE26162326F2F81E8C727FAFED1B43E3AC8752E9F4EDFF5B58BD316882B555E63278FEB00B61144703C060B6188F3528E176E9B2D5996579048B723EB678CD56FA979004270E9F88F235404C522ED076E9F287097F2F7600A2D4566D2F6EFB600A9854B61CDB4363040D4F30D96BB011EF4BB0E0F21192F72B106B4F38A79FA384978C3C2A9AB94534BE01C83927BC95A9C5E55E618D7C5D77A9FA39664EEF11B2D50F59396DAD7CDC23F17948585BD88342EED65F0A04E7
-20180505043446 2 6 100 8191 5 E3FCBDCFD41A409C58BE083B6485A2D67E20931B1F469774BAE0F1AB2898B800032581B1C4FC71FE136087937A885AFB6FC9E582DD97B8DE3AD2AF861419D5F06278316DFA78BAE7EF099889F0E99575C7812E7240B67623E7877737013A7D5DB3638040083400E8F27600BAC0650D24220CA1B3C05FB7DD70469A201DBFF1308ECA1C7152A6016BB89BFB6C625715EE91A92EA1848F0B2491AA92187468D9E8442679D7F5F6B64BC9D5A3D4E9B58C59EEEB65F8D6B70A71099E1B420BC0FD750CB2F333C23C97966BE727A6B6D9AEC8C0EB2436E01770F03840BFEC9228BB6DD46CE27D5739E18429F464FFF6812B0F66A8B0024BE03294900B8D0BC3CA6785F8C418EFE7068B2CD190A54BB9F90E05885A5C85DC069495C2009F79DBFD7774D7D65B9831FDC295CE146F4EB91DC56ABBD0B64BEAF3C340E0BF123A115D12289D44B650FF8461734308F4701CF2C199676DB3B4804FCDBD6B08C5D4875073AD5C575CA0B64597472A5C23EB4277B52B1128F3B1AE363E36A2C2D6EF5FCE00EE1573A40AD5ACDCDADE3E2672979CF68E87530520B2CA2C1110CBE4B631F3ABE83CFFDB7D5ACDD6DCA5916E30B1771FE29C4F60163B62349B66C0EDDCE8502F7C49DD4089EA5AE31FFB220A88C8D232367B52FAB7644F02E7EC10378697213CF0D90DA83A9941C217C559F88DEC6587AD953C95F11C575F0EFA9CC0650955C733910F2F90C78AE367F67B0F496A100E0B018731404D2BAEC7420F8C2B1FB6612AF69ECF369F236DD0BFB0ACBAED4141B2A14591C6475FC5C3D4E9B6229ECF7E288C015D59A35DE67F633DC586609AB3AB85A02B99DDF1B6FA7D54D4B2DDB767CAAB797C9FB29594B80B5BAACF777666D0B35CE6EFD8E46270C4D715B74FEA64FE34FBF4332BB4E8477CA438645C24444417EA5769B507925FB4B8FC59E429F1EC593C397F71087A080B39A192B5147D04D9F30DC237764C810E519B74EE90F047D0829104B6BA1A01F1CC18C85BE79F52084FAD6D7BF3EDA36D63981D8B75676740DB1AA6E06AD0C1F6A3B665D2D9D0E363FCE37B581C682A5F554D820849CEE7066A7DB011EA7D916B4A45212CBBC7A56ADAD33D203B8A1EDA03064A34351916C243E65D45425974C1468A626B773B48962108203F02814F15640149BCC2325C40F2457F0618CAAFDE26162326F2F81E8C727FAFED1B43E3AC8752E9F4EDFF5B58BD316882B555E63278FEB00B61144703C060B6188F3528E176E9B2D5996579048B723EB678CD56FA979004270E9F88F235404C522ED076E9F287097F2F7600A2D4566D2F6EFB600A9854B61CDB4363040D4F30D96BB011EF4BB0E0F21192F72B106B4F38A79FA384978C3C2A9AB94534BE01C83927BC95A9C5E55E618D7C5D77A9FA39664EEF11B2D50F59396DAD7CDC23F17948585BD88342EED65F133337
-20180505082348 2 6 100 8191 2 E3FCBDCFD41A409C58BE083B6485A2D67E20931B1F469774BAE0F1AB2898B800032581B1C4FC71FE136087937A885AFB6FC9E582DD97B8DE3AD2AF861419D5F06278316DFA78BAE7EF099889F0E99575C7812E7240B67623E7877737013A7D5DB3638040083400E8F27600BAC0650D24220CA1B3C05FB7DD70469A201DBFF1308ECA1C7152A6016BB89BFB6C625715EE91A92EA1848F0B2491AA92187468D9E8442679D7F5F6B64BC9D5A3D4E9B58C59EEEB65F8D6B70A71099E1B420BC0FD750CB2F333C23C97966BE727A6B6D9AEC8C0EB2436E01770F03840BFEC9228BB6DD46CE27D5739E18429F464FFF6812B0F66A8B0024BE03294900B8D0BC3CA6785F8C418EFE7068B2CD190A54BB9F90E05885A5C85DC069495C2009F79DBFD7774D7D65B9831FDC295CE146F4EB91DC56ABBD0B64BEAF3C340E0BF123A115D12289D44B650FF8461734308F4701CF2C199676DB3B4804FCDBD6B08C5D4875073AD5C575CA0B64597472A5C23EB4277B52B1128F3B1AE363E36A2C2D6EF5FCE00EE1573A40AD5ACDCDADE3E2672979CF68E87530520B2CA2C1110CBE4B631F3ABE83CFFDB7D5ACDD6DCA5916E30B1771FE29C4F60163B62349B66C0EDDCE8502F7C49DD4089EA5AE31FFB220A88C8D232367B52FAB7644F02E7EC10378697213CF0D90DA83A9941C217C559F88DEC6587AD953C95F11C575F0EFA9CC0650955C733910F2F90C78AE367F67B0F496A100E0B018731404D2BAEC7420F8C2B1FB6612AF69ECF369F236DD0BFB0ACBAED4141B2A14591C6475FC5C3D4E9B6229ECF7E288C015D59A35DE67F633DC586609AB3AB85A02B99DDF1B6FA7D54D4B2DDB767CAAB797C9FB29594B80B5BAACF777666D0B35CE6EFD8E46270C4D715B74FEA64FE34FBF4332BB4E8477CA438645C24444417EA5769B507925FB4B8FC59E429F1EC593C397F71087A080B39A192B5147D04D9F30DC237764C810E519B74EE90F047D0829104B6BA1A01F1CC18C85BE79F52084FAD6D7BF3EDA36D63981D8B75676740DB1AA6E06AD0C1F6A3B665D2D9D0E363FCE37B581C682A5F554D820849CEE7066A7DB011EA7D916B4A45212CBBC7A56ADAD33D203B8A1EDA03064A34351916C243E65D45425974C1468A626B773B48962108203F02814F15640149BCC2325C40F2457F0618CAAFDE26162326F2F81E8C727FAFED1B43E3AC8752E9F4EDFF5B58BD316882B555E63278FEB00B61144703C060B6188F3528E176E9B2D5996579048B723EB678CD56FA979004270E9F88F235404C522ED076E9F287097F2F7600A2D4566D2F6EFB600A9854B61CDB4363040D4F30D96BB011EF4BB0E0F21192F72B106B4F38A79FA384978C3C2A9AB94534BE01C83927BC95A9C5E55E618D7C5D77A9FA39664EEF11B2D50F59396DAD7CDC23F17948585BD88342EED6618FACC3
-20180505142452 2 6 100 8191 2 E3FCBDCFD41A409C58BE083B6485A2D67E20931B1F469774BAE0F1AB2898B800032581B1C4FC71FE136087937A885AFB6FC9E582DD97B8DE3AD2AF861419D5F06278316DFA78BAE7EF099889F0E99575C7812E7240B67623E7877737013A7D5DB3638040083400E8F27600BAC0650D24220CA1B3C05FB7DD70469A201DBFF1308ECA1C7152A6016BB89BFB6C625715EE91A92EA1848F0B2491AA92187468D9E8442679D7F5F6B64BC9D5A3D4E9B58C59EEEB65F8D6B70A71099E1B420BC0FD750CB2F333C23C97966BE727A6B6D9AEC8C0EB2436E01770F03840BFEC9228BB6DD46CE27D5739E18429F464FFF6812B0F66A8B0024BE03294900B8D0BC3CA6785F8C418EFE7068B2CD190A54BB9F90E05885A5C85DC069495C2009F79DBFD7774D7D65B9831FDC295CE146F4EB91DC56ABBD0B64BEAF3C340E0BF123A115D12289D44B650FF8461734308F4701CF2C199676DB3B4804FCDBD6B08C5D4875073AD5C575CA0B64597472A5C23EB4277B52B1128F3B1AE363E36A2C2D6EF5FCE00EE1573A40AD5ACDCDADE3E2672979CF68E87530520B2CA2C1110CBE4B631F3ABE83CFFDB7D5ACDD6DCA5916E30B1771FE29C4F60163B62349B66C0EDDCE8502F7C49DD4089EA5AE31FFB220A88C8D232367B52FAB7644F02E7EC10378697213CF0D90DA83A9941C217C559F88DEC6587AD953C95F11C575F0EFA9CC0650955C733910F2F90C78AE367F67B0F496A100E0B018731404D2BAEC7420F8C2B1FB6612AF69ECF369F236DD0BFB0ACBAED4141B2A14591C6475FC5C3D4E9B6229ECF7E288C015D59A35DE67F633DC586609AB3AB85A02B99DDF1B6FA7D54D4B2DDB767CAAB797C9FB29594B80B5BAACF777666D0B35CE6EFD8E46270C4D715B74FEA64FE34FBF4332BB4E8477CA438645C24444417EA5769B507925FB4B8FC59E429F1EC593C397F71087A080B39A192B5147D04D9F30DC237764C810E519B74EE90F047D0829104B6BA1A01F1CC18C85BE79F52084FAD6D7BF3EDA36D63981D8B75676740DB1AA6E06AD0C1F6A3B665D2D9D0E363FCE37B581C682A5F554D820849CEE7066A7DB011EA7D916B4A45212CBBC7A56ADAD33D203B8A1EDA03064A34351916C243E65D45425974C1468A626B773B48962108203F02814F15640149BCC2325C40F2457F0618CAAFDE26162326F2F81E8C727FAFED1B43E3AC8752E9F4EDFF5B58BD316882B555E63278FEB00B61144703C060B6188F3528E176E9B2D5996579048B723EB678CD56FA979004270E9F88F235404C522ED076E9F287097F2F7600A2D4566D2F6EFB600A9854B61CDB4363040D4F30D96BB011EF4BB0E0F21192F72B106B4F38A79FA384978C3C2A9AB94534BE01C83927BC95A9C5E55E618D7C5D77A9FA39664EEF11B2D50F59396DAD7CDC23F17948585BD88342EED665916E9B
-20180505191845 2 6 100 8191 2 E3FCBDCFD41A409C58BE083B6485A2D67E20931B1F469774BAE0F1AB2898B800032581B1C4FC71FE136087937A885AFB6FC9E582DD97B8DE3AD2AF861419D5F06278316DFA78BAE7EF099889F0E99575C7812E7240B67623E7877737013A7D5DB3638040083400E8F27600BAC0650D24220CA1B3C05FB7DD70469A201DBFF1308ECA1C7152A6016BB89BFB6C625715EE91A92EA1848F0B2491AA92187468D9E8442679D7F5F6B64BC9D5A3D4E9B58C59EEEB65F8D6B70A71099E1B420BC0FD750CB2F333C23C97966BE727A6B6D9AEC8C0EB2436E01770F03840BFEC9228BB6DD46CE27D5739E18429F464FFF6812B0F66A8B0024BE03294900B8D0BC3CA6785F8C418EFE7068B2CD190A54BB9F90E05885A5C85DC069495C2009F79DBFD7774D7D65B9831FDC295CE146F4EB91DC56ABBD0B64BEAF3C340E0BF123A115D12289D44B650FF8461734308F4701CF2C199676DB3B4804FCDBD6B08C5D4875073AD5C575CA0B64597472A5C23EB4277B52B1128F3B1AE363E36A2C2D6EF5FCE00EE1573A40AD5ACDCDADE3E2672979CF68E87530520B2CA2C1110CBE4B631F3ABE83CFFDB7D5ACDD6DCA5916E30B1771FE29C4F60163B62349B66C0EDDCE8502F7C49DD4089EA5AE31FFB220A88C8D232367B52FAB7644F02E7EC10378697213CF0D90DA83A9941C217C559F88DEC6587AD953C95F11C575F0EFA9CC0650955C733910F2F90C78AE367F67B0F496A100E0B018731404D2BAEC7420F8C2B1FB6612AF69ECF369F236DD0BFB0ACBAED4141B2A14591C6475FC5C3D4E9B6229ECF7E288C015D59A35DE67F633DC586609AB3AB85A02B99DDF1B6FA7D54D4B2DDB767CAAB797C9FB29594B80B5BAACF777666D0B35CE6EFD8E46270C4D715B74FEA64FE34FBF4332BB4E8477CA438645C24444417EA5769B507925FB4B8FC59E429F1EC593C397F71087A080B39A192B5147D04D9F30DC237764C810E519B74EE90F047D0829104B6BA1A01F1CC18C85BE79F52084FAD6D7BF3EDA36D63981D8B75676740DB1AA6E06AD0C1F6A3B665D2D9D0E363FCE37B581C682A5F554D820849CEE7066A7DB011EA7D916B4A45212CBBC7A56ADAD33D203B8A1EDA03064A34351916C243E65D45425974C1468A626B773B48962108203F02814F15640149BCC2325C40F2457F0618CAAFDE26162326F2F81E8C727FAFED1B43E3AC8752E9F4EDFF5B58BD316882B555E63278FEB00B61144703C060B6188F3528E176E9B2D5996579048B723EB678CD56FA979004270E9F88F235404C522ED076E9F287097F2F7600A2D4566D2F6EFB600A9854B61CDB4363040D4F30D96BB011EF4BB0E0F21192F72B106B4F38A79FA384978C3C2A9AB94534BE01C83927BC95A9C5E55E618D7C5D77A9FA39664EEF11B2D50F59396DAD7CDC23F17948585BD88342EED668B9BE0B
-20180506011717 2 6 100 8191 5 E3FCBDCFD41A409C58BE083B6485A2D67E20931B1F469774BAE0F1AB2898B800032581B1C4FC71FE136087937A885AFB6FC9E582DD97B8DE3AD2AF861419D5F06278316DFA78BAE7EF099889F0E99575C7812E7240B67623E7877737013A7D5DB3638040083400E8F27600BAC0650D24220CA1B3C05FB7DD70469A201DBFF1308ECA1C7152A6016BB89BFB6C625715EE91A92EA1848F0B2491AA92187468D9E8442679D7F5F6B64BC9D5A3D4E9B58C59EEEB65F8D6B70A71099E1B420BC0FD750CB2F333C23C97966BE727A6B6D9AEC8C0EB2436E01770F03840BFEC9228BB6DD46CE27D5739E18429F464FFF6812B0F66A8B0024BE03294900B8D0BC3CA6785F8C418EFE7068B2CD190A54BB9F90E05885A5C85DC069495C2009F79DBFD7774D7D65B9831FDC295CE146F4EB91DC56ABBD0B64BEAF3C340E0BF123A115D12289D44B650FF8461734308F4701CF2C199676DB3B4804FCDBD6B08C5D4875073AD5C575CA0B64597472A5C23EB4277B52B1128F3B1AE363E36A2C2D6EF5FCE00EE1573A40AD5ACDCDADE3E2672979CF68E87530520B2CA2C1110CBE4B631F3ABE83CFFDB7D5ACDD6DCA5916E30B1771FE29C4F60163B62349B66C0EDDCE8502F7C49DD4089EA5AE31FFB220A88C8D232367B52FAB7644F02E7EC10378697213CF0D90DA83A9941C217C559F88DEC6587AD953C95F11C575F0EFA9CC0650955C733910F2F90C78AE367F67B0F496A100E0B018731404D2BAEC7420F8C2B1FB6612AF69ECF369F236DD0BFB0ACBAED4141B2A14591C6475FC5C3D4E9B6229ECF7E288C015D59A35DE67F633DC586609AB3AB85A02B99DDF1B6FA7D54D4B2DDB767CAAB797C9FB29594B80B5BAACF777666D0B35CE6EFD8E46270C4D715B74FEA64FE34FBF4332BB4E8477CA438645C24444417EA5769B507925FB4B8FC59E429F1EC593C397F71087A080B39A192B5147D04D9F30DC237764C810E519B74EE90F047D0829104B6BA1A01F1CC18C85BE79F52084FAD6D7BF3EDA36D63981D8B75676740DB1AA6E06AD0C1F6A3B665D2D9D0E363FCE37B581C682A5F554D820849CEE7066A7DB011EA7D916B4A45212CBBC7A56ADAD33D203B8A1EDA03064A34351916C243E65D45425974C1468A626B773B48962108203F02814F15640149BCC2325C40F2457F0618CAAFDE26162326F2F81E8C727FAFED1B43E3AC8752E9F4EDFF5B58BD316882B555E63278FEB00B61144703C060B6188F3528E176E9B2D5996579048B723EB678CD56FA979004270E9F88F235404C522ED076E9F287097F2F7600A2D4566D2F6EFB600A9854B61CDB4363040D4F30D96BB011EF4BB0E0F21192F72B106B4F38A79FA384978C3C2A9AB94534BE01C83927BC95A9C5E55E618D7C5D77A9FA39664EEF11B2D50F59396DAD7CDC23F17948585BD88342EED66CA10377
-20180506064643 2 6 100 8191 2 E3FCBDCFD41A409C58BE083B6485A2D67E20931B1F469774BAE0F1AB2898B800032581B1C4FC71FE136087937A885AFB6FC9E582DD97B8DE3AD2AF861419D5F06278316DFA78BAE7EF099889F0E99575C7812E7240B67623E7877737013A7D5DB3638040083400E8F27600BAC0650D24220CA1B3C05FB7DD70469A201DBFF1308ECA1C7152A6016BB89BFB6C625715EE91A92EA1848F0B2491AA92187468D9E8442679D7F5F6B64BC9D5A3D4E9B58C59EEEB65F8D6B70A71099E1B420BC0FD750CB2F333C23C97966BE727A6B6D9AEC8C0EB2436E01770F03840BFEC9228BB6DD46CE27D5739E18429F464FFF6812B0F66A8B0024BE03294900B8D0BC3CA6785F8C418EFE7068B2CD190A54BB9F90E05885A5C85DC069495C2009F79DBFD7774D7D65B9831FDC295CE146F4EB91DC56ABBD0B64BEAF3C340E0BF123A115D12289D44B650FF8461734308F4701CF2C199676DB3B4804FCDBD6B08C5D4875073AD5C575CA0B64597472A5C23EB4277B52B1128F3B1AE363E36A2C2D6EF5FCE00EE1573A40AD5ACDCDADE3E2672979CF68E87530520B2CA2C1110CBE4B631F3ABE83CFFDB7D5ACDD6DCA5916E30B1771FE29C4F60163B62349B66C0EDDCE8502F7C49DD4089EA5AE31FFB220A88C8D232367B52FAB7644F02E7EC10378697213CF0D90DA83A9941C217C559F88DEC6587AD953C95F11C575F0EFA9CC0650955C733910F2F90C78AE367F67B0F496A100E0B018731404D2BAEC7420F8C2B1FB6612AF69ECF369F236DD0BFB0ACBAED4141B2A14591C6475FC5C3D4E9B6229ECF7E288C015D59A35DE67F633DC586609AB3AB85A02B99DDF1B6FA7D54D4B2DDB767CAAB797C9FB29594B80B5BAACF777666D0B35CE6EFD8E46270C4D715B74FEA64FE34FBF4332BB4E8477CA438645C24444417EA5769B507925FB4B8FC59E429F1EC593C397F71087A080B39A192B5147D04D9F30DC237764C810E519B74EE90F047D0829104B6BA1A01F1CC18C85BE79F52084FAD6D7BF3EDA36D63981D8B75676740DB1AA6E06AD0C1F6A3B665D2D9D0E363FCE37B581C682A5F554D820849CEE7066A7DB011EA7D916B4A45212CBBC7A56ADAD33D203B8A1EDA03064A34351916C243E65D45425974C1468A626B773B48962108203F02814F15640149BCC2325C40F2457F0618CAAFDE26162326F2F81E8C727FAFED1B43E3AC8752E9F4EDFF5B58BD316882B555E63278FEB00B61144703C060B6188F3528E176E9B2D5996579048B723EB678CD56FA979004270E9F88F235404C522ED076E9F287097F2F7600A2D4566D2F6EFB600A9854B61CDB4363040D4F30D96BB011EF4BB0E0F21192F72B106B4F38A79FA384978C3C2A9AB94534BE01C83927BC95A9C5E55E618D7C5D77A9FA39664EEF11B2D50F59396DAD7CDC23F17948585BD88342EED67028E243
-20180506091931 2 6 100 8191 5 E3FCBDCFD41A409C58BE083B6485A2D67E20931B1F469774BAE0F1AB2898B800032581B1C4FC71FE136087937A885AFB6FC9E582DD97B8DE3AD2AF861419D5F06278316DFA78BAE7EF099889F0E99575C7812E7240B67623E7877737013A7D5DB3638040083400E8F27600BAC0650D24220CA1B3C05FB7DD70469A201DBFF1308ECA1C7152A6016BB89BFB6C625715EE91A92EA1848F0B2491AA92187468D9E8442679D7F5F6B64BC9D5A3D4E9B58C59EEEB65F8D6B70A71099E1B420BC0FD750CB2F333C23C97966BE727A6B6D9AEC8C0EB2436E01770F03840BFEC9228BB6DD46CE27D5739E18429F464FFF6812B0F66A8B0024BE03294900B8D0BC3CA6785F8C418EFE7068B2CD190A54BB9F90E05885A5C85DC069495C2009F79DBFD7774D7D65B9831FDC295CE146F4EB91DC56ABBD0B64BEAF3C340E0BF123A115D12289D44B650FF8461734308F4701CF2C199676DB3B4804FCDBD6B08C5D4875073AD5C575CA0B64597472A5C23EB4277B52B1128F3B1AE363E36A2C2D6EF5FCE00EE1573A40AD5ACDCDADE3E2672979CF68E87530520B2CA2C1110CBE4B631F3ABE83CFFDB7D5ACDD6DCA5916E30B1771FE29C4F60163B62349B66C0EDDCE8502F7C49DD4089EA5AE31FFB220A88C8D232367B52FAB7644F02E7EC10378697213CF0D90DA83A9941C217C559F88DEC6587AD953C95F11C575F0EFA9CC0650955C733910F2F90C78AE367F67B0F496A100E0B018731404D2BAEC7420F8C2B1FB6612AF69ECF369F236DD0BFB0ACBAED4141B2A14591C6475FC5C3D4E9B6229ECF7E288C015D59A35DE67F633DC586609AB3AB85A02B99DDF1B6FA7D54D4B2DDB767CAAB797C9FB29594B80B5BAACF777666D0B35CE6EFD8E46270C4D715B74FEA64FE34FBF4332BB4E8477CA438645C24444417EA5769B507925FB4B8FC59E429F1EC593C397F71087A080B39A192B5147D04D9F30DC237764C810E519B74EE90F047D0829104B6BA1A01F1CC18C85BE79F52084FAD6D7BF3EDA36D63981D8B75676740DB1AA6E06AD0C1F6A3B665D2D9D0E363FCE37B581C682A5F554D820849CEE7066A7DB011EA7D916B4A45212CBBC7A56ADAD33D203B8A1EDA03064A34351916C243E65D45425974C1468A626B773B48962108203F02814F15640149BCC2325C40F2457F0618CAAFDE26162326F2F81E8C727FAFED1B43E3AC8752E9F4EDFF5B58BD316882B555E63278FEB00B61144703C060B6188F3528E176E9B2D5996579048B723EB678CD56FA979004270E9F88F235404C522ED076E9F287097F2F7600A2D4566D2F6EFB600A9854B61CDB4363040D4F30D96BB011EF4BB0E0F21192F72B106B4F38A79FA384978C3C2A9AB94534BE01C83927BC95A9C5E55E618D7C5D77A9FA39664EEF11B2D50F59396DAD7CDC23F17948585BD88342EED671CB9597
-20180506094237 2 6 100 8191 2 E3FCBDCFD41A409C58BE083B6485A2D67E20931B1F469774BAE0F1AB2898B800032581B1C4FC71FE136087937A885AFB6FC9E582DD97B8DE3AD2AF861419D5F06278316DFA78BAE7EF099889F0E99575C7812E7240B67623E7877737013A7D5DB3638040083400E8F27600BAC0650D24220CA1B3C05FB7DD70469A201DBFF1308ECA1C7152A6016BB89BFB6C625715EE91A92EA1848F0B2491AA92187468D9E8442679D7F5F6B64BC9D5A3D4E9B58C59EEEB65F8D6B70A71099E1B420BC0FD750CB2F333C23C97966BE727A6B6D9AEC8C0EB2436E01770F03840BFEC9228BB6DD46CE27D5739E18429F464FFF6812B0F66A8B0024BE03294900B8D0BC3CA6785F8C418EFE7068B2CD190A54BB9F90E05885A5C85DC069495C2009F79DBFD7774D7D65B9831FDC295CE146F4EB91DC56ABBD0B64BEAF3C340E0BF123A115D12289D44B650FF8461734308F4701CF2C199676DB3B4804FCDBD6B08C5D4875073AD5C575CA0B64597472A5C23EB4277B52B1128F3B1AE363E36A2C2D6EF5FCE00EE1573A40AD5ACDCDADE3E2672979CF68E87530520B2CA2C1110CBE4B631F3ABE83CFFDB7D5ACDD6DCA5916E30B1771FE29C4F60163B62349B66C0EDDCE8502F7C49DD4089EA5AE31FFB220A88C8D232367B52FAB7644F02E7EC10378697213CF0D90DA83A9941C217C559F88DEC6587AD953C95F11C575F0EFA9CC0650955C733910F2F90C78AE367F67B0F496A100E0B018731404D2BAEC7420F8C2B1FB6612AF69ECF369F236DD0BFB0ACBAED4141B2A14591C6475FC5C3D4E9B6229ECF7E288C015D59A35DE67F633DC586609AB3AB85A02B99DDF1B6FA7D54D4B2DDB767CAAB797C9FB29594B80B5BAACF777666D0B35CE6EFD8E46270C4D715B74FEA64FE34FBF4332BB4E8477CA438645C24444417EA5769B507925FB4B8FC59E429F1EC593C397F71087A080B39A192B5147D04D9F30DC237764C810E519B74EE90F047D0829104B6BA1A01F1CC18C85BE79F52084FAD6D7BF3EDA36D63981D8B75676740DB1AA6E06AD0C1F6A3B665D2D9D0E363FCE37B581C682A5F554D820849CEE7066A7DB011EA7D916B4A45212CBBC7A56ADAD33D203B8A1EDA03064A34351916C243E65D45425974C1468A626B773B48962108203F02814F15640149BCC2325C40F2457F0618CAAFDE26162326F2F81E8C727FAFED1B43E3AC8752E9F4EDFF5B58BD316882B555E63278FEB00B61144703C060B6188F3528E176E9B2D5996579048B723EB678CD56FA979004270E9F88F235404C522ED076E9F287097F2F7600A2D4566D2F6EFB600A9854B61CDB4363040D4F30D96BB011EF4BB0E0F21192F72B106B4F38A79FA384978C3C2A9AB94534BE01C83927BC95A9C5E55E618D7C5D77A9FA39664EEF11B2D50F59396DAD7CDC23F17948585BD88342EED67201565B
-20180506200807 2 6 100 8191 2 E3FCBDCFD41A409C58BE083B6485A2D67E20931B1F469774BAE0F1AB2898B800032581B1C4FC71FE136087937A885AFB6FC9E582DD97B8DE3AD2AF861419D5F06278316DFA78BAE7EF099889F0E99575C7812E7240B67623E7877737013A7D5DB3638040083400E8F27600BAC0650D24220CA1B3C05FB7DD70469A201DBFF1308ECA1C7152A6016BB89BFB6C625715EE91A92EA1848F0B2491AA92187468D9E8442679D7F5F6B64BC9D5A3D4E9B58C59EEEB65F8D6B70A71099E1B420BC0FD750CB2F333C23C97966BE727A6B6D9AEC8C0EB2436E01770F03840BFEC9228BB6DD46CE27D5739E18429F464FFF6812B0F66A8B0024BE03294900B8D0BC3CA6785F8C418EFE7068B2CD190A54BB9F90E05885A5C85DC069495C2009F79DBFD7774D7D65B9831FDC295CE146F4EB91DC56ABBD0B64BEAF3C340E0BF123A115D12289D44B650FF8461734308F4701CF2C199676DB3B4804FCDBD6B08C5D4875073AD5C575CA0B64597472A5C23EB4277B52B1128F3B1AE363E36A2C2D6EF5FCE00EE1573A40AD5ACDCDADE3E2672979CF68E87530520B2CA2C1110CBE4B631F3ABE83CFFDB7D5ACDD6DCA5916E30B1771FE29C4F60163B62349B66C0EDDCE8502F7C49DD4089EA5AE31FFB220A88C8D232367B52FAB7644F02E7EC10378697213CF0D90DA83A9941C217C559F88DEC6587AD953C95F11C575F0EFA9CC0650955C733910F2F90C78AE367F67B0F496A100E0B018731404D2BAEC7420F8C2B1FB6612AF69ECF369F236DD0BFB0ACBAED4141B2A14591C6475FC5C3D4E9B6229ECF7E288C015D59A35DE67F633DC586609AB3AB85A02B99DDF1B6FA7D54D4B2DDB767CAAB797C9FB29594B80B5BAACF777666D0B35CE6EFD8E46270C4D715B74FEA64FE34FBF4332BB4E8477CA438645C24444417EA5769B507925FB4B8FC59E429F1EC593C397F71087A080B39A192B5147D04D9F30DC237764C810E519B74EE90F047D0829104B6BA1A01F1CC18C85BE79F52084FAD6D7BF3EDA36D63981D8B75676740DB1AA6E06AD0C1F6A3B665D2D9D0E363FCE37B581C682A5F554D820849CEE7066A7DB011EA7D916B4A45212CBBC7A56ADAD33D203B8A1EDA03064A34351916C243E65D45425974C1468A626B773B48962108203F02814F15640149BCC2325C40F2457F0618CAAFDE26162326F2F81E8C727FAFED1B43E3AC8752E9F4EDFF5B58BD316882B555E63278FEB00B61144703C060B6188F3528E176E9B2D5996579048B723EB678CD56FA979004270E9F88F235404C522ED076E9F287097F2F7600A2D4566D2F6EFB600A9854B61CDB4363040D4F30D96BB011EF4BB0E0F21192F72B106B4F38A79FA384978C3C2A9AB94534BE01C83927BC95A9C5E55E618D7C5D77A9FA39664EEF11B2D50F59396DAD7CDC23F17948585BD88342EED678BDEA8B
-20180507012051 2 6 100 8191 2 E3FCBDCFD41A409C58BE083B6485A2D67E20931B1F469774BAE0F1AB2898B800032581B1C4FC71FE136087937A885AFB6FC9E582DD97B8DE3AD2AF861419D5F06278316DFA78BAE7EF099889F0E99575C7812E7240B67623E7877737013A7D5DB3638040083400E8F27600BAC0650D24220CA1B3C05FB7DD70469A201DBFF1308ECA1C7152A6016BB89BFB6C625715EE91A92EA1848F0B2491AA92187468D9E8442679D7F5F6B64BC9D5A3D4E9B58C59EEEB65F8D6B70A71099E1B420BC0FD750CB2F333C23C97966BE727A6B6D9AEC8C0EB2436E01770F03840BFEC9228BB6DD46CE27D5739E18429F464FFF6812B0F66A8B0024BE03294900B8D0BC3CA6785F8C418EFE7068B2CD190A54BB9F90E05885A5C85DC069495C2009F79DBFD7774D7D65B9831FDC295CE146F4EB91DC56ABBD0B64BEAF3C340E0BF123A115D12289D44B650FF8461734308F4701CF2C199676DB3B4804FCDBD6B08C5D4875073AD5C575CA0B64597472A5C23EB4277B52B1128F3B1AE363E36A2C2D6EF5FCE00EE1573A40AD5ACDCDADE3E2672979CF68E87530520B2CA2C1110CBE4B631F3ABE83CFFDB7D5ACDD6DCA5916E30B1771FE29C4F60163B62349B66C0EDDCE8502F7C49DD4089EA5AE31FFB220A88C8D232367B52FAB7644F02E7EC10378697213CF0D90DA83A9941C217C559F88DEC6587AD953C95F11C575F0EFA9CC0650955C733910F2F90C78AE367F67B0F496A100E0B018731404D2BAEC7420F8C2B1FB6612AF69ECF369F236DD0BFB0ACBAED4141B2A14591C6475FC5C3D4E9B6229ECF7E288C015D59A35DE67F633DC586609AB3AB85A02B99DDF1B6FA7D54D4B2DDB767CAAB797C9FB29594B80B5BAACF777666D0B35CE6EFD8E46270C4D715B74FEA64FE34FBF4332BB4E8477CA438645C24444417EA5769B507925FB4B8FC59E429F1EC593C397F71087A080B39A192B5147D04D9F30DC237764C810E519B74EE90F047D0829104B6BA1A01F1CC18C85BE79F52084FAD6D7BF3EDA36D63981D8B75676740DB1AA6E06AD0C1F6A3B665D2D9D0E363FCE37B581C682A5F554D820849CEE7066A7DB011EA7D916B4A45212CBBC7A56ADAD33D203B8A1EDA03064A34351916C243E65D45425974C1468A626B773B48962108203F02814F15640149BCC2325C40F2457F0618CAAFDE26162326F2F81E8C727FAFED1B43E3AC8752E9F4EDFF5B58BD316882B555E63278FEB00B61144703C060B6188F3528E176E9B2D5996579048B723EB678CD56FA979004270E9F88F235404C522ED076E9F287097F2F7600A2D4566D2F6EFB600A9854B61CDB4363040D4F30D96BB011EF4BB0E0F21192F72B106B4F38A79FA384978C3C2A9AB94534BE01C83927BC95A9C5E55E618D7C5D77A9FA39664EEF11B2D50F59396DAD7CDC23F17948585BD88342EED67C15F093
-20180507102714 2 6 100 8191 5 E3FCBDCFD41A409C58BE083B6485A2D67E20931B1F469774BAE0F1AB2898B800032581B1C4FC71FE136087937A885AFB6FC9E582DD97B8DE3AD2AF861419D5F06278316DFA78BAE7EF099889F0E99575C7812E7240B67623E7877737013A7D5DB3638040083400E8F27600BAC0650D24220CA1B3C05FB7DD70469A201DBFF1308ECA1C7152A6016BB89BFB6C625715EE91A92EA1848F0B2491AA92187468D9E8442679D7F5F6B64BC9D5A3D4E9B58C59EEEB65F8D6B70A71099E1B420BC0FD750CB2F333C23C97966BE727A6B6D9AEC8C0EB2436E01770F03840BFEC9228BB6DD46CE27D5739E18429F464FFF6812B0F66A8B0024BE03294900B8D0BC3CA6785F8C418EFE7068B2CD190A54BB9F90E05885A5C85DC069495C2009F79DBFD7774D7D65B9831FDC295CE146F4EB91DC56ABBD0B64BEAF3C340E0BF123A115D12289D44B650FF8461734308F4701CF2C199676DB3B4804FCDBD6B08C5D4875073AD5C575CA0B64597472A5C23EB4277B52B1128F3B1AE363E36A2C2D6EF5FCE00EE1573A40AD5ACDCDADE3E2672979CF68E87530520B2CA2C1110CBE4B631F3ABE83CFFDB7D5ACDD6DCA5916E30B1771FE29C4F60163B62349B66C0EDDCE8502F7C49DD4089EA5AE31FFB220A88C8D232367B52FAB7644F02E7EC10378697213CF0D90DA83A9941C217C559F88DEC6587AD953C95F11C575F0EFA9CC0650955C733910F2F90C78AE367F67B0F496A100E0B018731404D2BAEC7420F8C2B1FB6612AF69ECF369F236DD0BFB0ACBAED4141B2A14591C6475FC5C3D4E9B6229ECF7E288C015D59A35DE67F633DC586609AB3AB85A02B99DDF1B6FA7D54D4B2DDB767CAAB797C9FB29594B80B5BAACF777666D0B35CE6EFD8E46270C4D715B74FEA64FE34FBF4332BB4E8477CA438645C24444417EA5769B507925FB4B8FC59E429F1EC593C397F71087A080B39A192B5147D04D9F30DC237764C810E519B74EE90F047D0829104B6BA1A01F1CC18C85BE79F52084FAD6D7BF3EDA36D63981D8B75676740DB1AA6E06AD0C1F6A3B665D2D9D0E363FCE37B581C682A5F554D820849CEE7066A7DB011EA7D916B4A45212CBBC7A56ADAD33D203B8A1EDA03064A34351916C243E65D45425974C1468A626B773B48962108203F02814F15640149BCC2325C40F2457F0618CAAFDE26162326F2F81E8C727FAFED1B43E3AC8752E9F4EDFF5B58BD316882B555E63278FEB00B61144703C060B6188F3528E176E9B2D5996579048B723EB678CD56FA979004270E9F88F235404C522ED076E9F287097F2F7600A2D4566D2F6EFB600A9854B61CDB4363040D4F30D96BB011EF4BB0E0F21192F72B106B4F38A79FA384978C3C2A9AB94534BE01C83927BC95A9C5E55E618D7C5D77A9FA39664EEF11B2D50F59396DAD7CDC23F17948585BD88342EED681E510A7
-20180507105523 2 6 100 8191 2 E3FCBDCFD41A409C58BE083B6485A2D67E20931B1F469774BAE0F1AB2898B800032581B1C4FC71FE136087937A885AFB6FC9E582DD97B8DE3AD2AF861419D5F06278316DFA78BAE7EF099889F0E99575C7812E7240B67623E7877737013A7D5DB3638040083400E8F27600BAC0650D24220CA1B3C05FB7DD70469A201DBFF1308ECA1C7152A6016BB89BFB6C625715EE91A92EA1848F0B2491AA92187468D9E8442679D7F5F6B64BC9D5A3D4E9B58C59EEEB65F8D6B70A71099E1B420BC0FD750CB2F333C23C97966BE727A6B6D9AEC8C0EB2436E01770F03840BFEC9228BB6DD46CE27D5739E18429F464FFF6812B0F66A8B0024BE03294900B8D0BC3CA6785F8C418EFE7068B2CD190A54BB9F90E05885A5C85DC069495C2009F79DBFD7774D7D65B9831FDC295CE146F4EB91DC56ABBD0B64BEAF3C340E0BF123A115D12289D44B650FF8461734308F4701CF2C199676DB3B4804FCDBD6B08C5D4875073AD5C575CA0B64597472A5C23EB4277B52B1128F3B1AE363E36A2C2D6EF5FCE00EE1573A40AD5ACDCDADE3E2672979CF68E87530520B2CA2C1110CBE4B631F3ABE83CFFDB7D5ACDD6DCA5916E30B1771FE29C4F60163B62349B66C0EDDCE8502F7C49DD4089EA5AE31FFB220A88C8D232367B52FAB7644F02E7EC10378697213CF0D90DA83A9941C217C559F88DEC6587AD953C95F11C575F0EFA9CC0650955C733910F2F90C78AE367F67B0F496A100E0B018731404D2BAEC7420F8C2B1FB6612AF69ECF369F236DD0BFB0ACBAED4141B2A14591C6475FC5C3D4E9B6229ECF7E288C015D59A35DE67F633DC586609AB3AB85A02B99DDF1B6FA7D54D4B2DDB767CAAB797C9FB29594B80B5BAACF777666D0B35CE6EFD8E46270C4D715B74FEA64FE34FBF4332BB4E8477CA438645C24444417EA5769B507925FB4B8FC59E429F1EC593C397F71087A080B39A192B5147D04D9F30DC237764C810E519B74EE90F047D0829104B6BA1A01F1CC18C85BE79F52084FAD6D7BF3EDA36D63981D8B75676740DB1AA6E06AD0C1F6A3B665D2D9D0E363FCE37B581C682A5F554D820849CEE7066A7DB011EA7D916B4A45212CBBC7A56ADAD33D203B8A1EDA03064A34351916C243E65D45425974C1468A626B773B48962108203F02814F15640149BCC2325C40F2457F0618CAAFDE26162326F2F81E8C727FAFED1B43E3AC8752E9F4EDFF5B58BD316882B555E63278FEB00B61144703C060B6188F3528E176E9B2D5996579048B723EB678CD56FA979004270E9F88F235404C522ED076E9F287097F2F7600A2D4566D2F6EFB600A9854B61CDB4363040D4F30D96BB011EF4BB0E0F21192F72B106B4F38A79FA384978C3C2A9AB94534BE01C83927BC95A9C5E55E618D7C5D77A9FA39664EEF11B2D50F59396DAD7CDC23F17948585BD88342EED6822806B3
-20180507204038 2 6 100 8191 2 E3FCBDCFD41A409C58BE083B6485A2D67E20931B1F469774BAE0F1AB2898B800032581B1C4FC71FE136087937A885AFB6FC9E582DD97B8DE3AD2AF861419D5F06278316DFA78BAE7EF099889F0E99575C7812E7240B67623E7877737013A7D5DB3638040083400E8F27600BAC0650D24220CA1B3C05FB7DD70469A201DBFF1308ECA1C7152A6016BB89BFB6C625715EE91A92EA1848F0B2491AA92187468D9E8442679D7F5F6B64BC9D5A3D4E9B58C59EEEB65F8D6B70A71099E1B420BC0FD750CB2F333C23C97966BE727A6B6D9AEC8C0EB2436E01770F03840BFEC9228BB6DD46CE27D5739E18429F464FFF6812B0F66A8B0024BE03294900B8D0BC3CA6785F8C418EFE7068B2CD190A54BB9F90E05885A5C85DC069495C2009F79DBFD7774D7D65B9831FDC295CE146F4EB91DC56ABBD0B64BEAF3C340E0BF123A115D12289D44B650FF8461734308F4701CF2C199676DB3B4804FCDBD6B08C5D4875073AD5C575CA0B64597472A5C23EB4277B52B1128F3B1AE363E36A2C2D6EF5FCE00EE1573A40AD5ACDCDADE3E2672979CF68E87530520B2CA2C1110CBE4B631F3ABE83CFFDB7D5ACDD6DCA5916E30B1771FE29C4F60163B62349B66C0EDDCE8502F7C49DD4089EA5AE31FFB220A88C8D232367B52FAB7644F02E7EC10378697213CF0D90DA83A9941C217C559F88DEC6587AD953C95F11C575F0EFA9CC0650955C733910F2F90C78AE367F67B0F496A100E0B018731404D2BAEC7420F8C2B1FB6612AF69ECF369F236DD0BFB0ACBAED4141B2A14591C6475FC5C3D4E9B6229ECF7E288C015D59A35DE67F633DC586609AB3AB85A02B99DDF1B6FA7D54D4B2DDB767CAAB797C9FB29594B80B5BAACF777666D0B35CE6EFD8E46270C4D715B74FEA64FE34FBF4332BB4E8477CA438645C24444417EA5769B507925FB4B8FC59E429F1EC593C397F71087A080B39A192B5147D04D9F30DC237764C810E519B74EE90F047D0829104B6BA1A01F1CC18C85BE79F52084FAD6D7BF3EDA36D63981D8B75676740DB1AA6E06AD0C1F6A3B665D2D9D0E363FCE37B581C682A5F554D820849CEE7066A7DB011EA7D916B4A45212CBBC7A56ADAD33D203B8A1EDA03064A34351916C243E65D45425974C1468A626B773B48962108203F02814F15640149BCC2325C40F2457F0618CAAFDE26162326F2F81E8C727FAFED1B43E3AC8752E9F4EDFF5B58BD316882B555E63278FEB00B61144703C060B6188F3528E176E9B2D5996579048B723EB678CD56FA979004270E9F88F235404C522ED076E9F287097F2F7600A2D4566D2F6EFB600A9854B61CDB4363040D4F30D96BB011EF4BB0E0F21192F72B106B4F38A79FA384978C3C2A9AB94534BE01C83927BC95A9C5E55E618D7C5D77A9FA39664EEF11B2D50F59396DAD7CDC23F17948585BD88342EED6885CE023
-20180508025258 2 6 100 8191 5 E3FCBDCFD41A409C58BE083B6485A2D67E20931B1F469774BAE0F1AB2898B800032581B1C4FC71FE136087937A885AFB6FC9E582DD97B8DE3AD2AF861419D5F06278316DFA78BAE7EF099889F0E99575C7812E7240B67623E7877737013A7D5DB3638040083400E8F27600BAC0650D24220CA1B3C05FB7DD70469A201DBFF1308ECA1C7152A6016BB89BFB6C625715EE91A92EA1848F0B2491AA92187468D9E8442679D7F5F6B64BC9D5A3D4E9B58C59EEEB65F8D6B70A71099E1B420BC0FD750CB2F333C23C97966BE727A6B6D9AEC8C0EB2436E01770F03840BFEC9228BB6DD46CE27D5739E18429F464FFF6812B0F66A8B0024BE03294900B8D0BC3CA6785F8C418EFE7068B2CD190A54BB9F90E05885A5C85DC069495C2009F79DBFD7774D7D65B9831FDC295CE146F4EB91DC56ABBD0B64BEAF3C340E0BF123A115D12289D44B650FF8461734308F4701CF2C199676DB3B4804FCDBD6B08C5D4875073AD5C575CA0B64597472A5C23EB4277B52B1128F3B1AE363E36A2C2D6EF5FCE00EE1573A40AD5ACDCDADE3E2672979CF68E87530520B2CA2C1110CBE4B631F3ABE83CFFDB7D5ACDD6DCA5916E30B1771FE29C4F60163B62349B66C0EDDCE8502F7C49DD4089EA5AE31FFB220A88C8D232367B52FAB7644F02E7EC10378697213CF0D90DA83A9941C217C559F88DEC6587AD953C95F11C575F0EFA9CC0650955C733910F2F90C78AE367F67B0F496A100E0B018731404D2BAEC7420F8C2B1FB6612AF69ECF369F236DD0BFB0ACBAED4141B2A14591C6475FC5C3D4E9B6229ECF7E288C015D59A35DE67F633DC586609AB3AB85A02B99DDF1B6FA7D54D4B2DDB767CAAB797C9FB29594B80B5BAACF777666D0B35CE6EFD8E46270C4D715B74FEA64FE34FBF4332BB4E8477CA438645C24444417EA5769B507925FB4B8FC59E429F1EC593C397F71087A080B39A192B5147D04D9F30DC237764C810E519B74EE90F047D0829104B6BA1A01F1CC18C85BE79F52084FAD6D7BF3EDA36D63981D8B75676740DB1AA6E06AD0C1F6A3B665D2D9D0E363FCE37B581C682A5F554D820849CEE7066A7DB011EA7D916B4A45212CBBC7A56ADAD33D203B8A1EDA03064A34351916C243E65D45425974C1468A626B773B48962108203F02814F15640149BCC2325C40F2457F0618CAAFDE26162326F2F81E8C727FAFED1B43E3AC8752E9F4EDFF5B58BD316882B555E63278FEB00B61144703C060B6188F3528E176E9B2D5996579048B723EB678CD56FA979004270E9F88F235404C522ED076E9F287097F2F7600A2D4566D2F6EFB600A9854B61CDB4363040D4F30D96BB011EF4BB0E0F21192F72B106B4F38A79FA384978C3C2A9AB94534BE01C83927BC95A9C5E55E618D7C5D77A9FA39664EEF11B2D50F59396DAD7CDC23F17948585BD88342EED68C4A13A7
-20180508064503 2 6 100 8191 5 E3FCBDCFD41A409C58BE083B6485A2D67E20931B1F469774BAE0F1AB2898B800032581B1C4FC71FE136087937A885AFB6FC9E582DD97B8DE3AD2AF861419D5F06278316DFA78BAE7EF099889F0E99575C7812E7240B67623E7877737013A7D5DB3638040083400E8F27600BAC0650D24220CA1B3C05FB7DD70469A201DBFF1308ECA1C7152A6016BB89BFB6C625715EE91A92EA1848F0B2491AA92187468D9E8442679D7F5F6B64BC9D5A3D4E9B58C59EEEB65F8D6B70A71099E1B420BC0FD750CB2F333C23C97966BE727A6B6D9AEC8C0EB2436E01770F03840BFEC9228BB6DD46CE27D5739E18429F464FFF6812B0F66A8B0024BE03294900B8D0BC3CA6785F8C418EFE7068B2CD190A54BB9F90E05885A5C85DC069495C2009F79DBFD7774D7D65B9831FDC295CE146F4EB91DC56ABBD0B64BEAF3C340E0BF123A115D12289D44B650FF8461734308F4701CF2C199676DB3B4804FCDBD6B08C5D4875073AD5C575CA0B64597472A5C23EB4277B52B1128F3B1AE363E36A2C2D6EF5FCE00EE1573A40AD5ACDCDADE3E2672979CF68E87530520B2CA2C1110CBE4B631F3ABE83CFFDB7D5ACDD6DCA5916E30B1771FE29C4F60163B62349B66C0EDDCE8502F7C49DD4089EA5AE31FFB220A88C8D232367B52FAB7644F02E7EC10378697213CF0D90DA83A9941C217C559F88DEC6587AD953C95F11C575F0EFA9CC0650955C733910F2F90C78AE367F67B0F496A100E0B018731404D2BAEC7420F8C2B1FB6612AF69ECF369F236DD0BFB0ACBAED4141B2A14591C6475FC5C3D4E9B6229ECF7E288C015D59A35DE67F633DC586609AB3AB85A02B99DDF1B6FA7D54D4B2DDB767CAAB797C9FB29594B80B5BAACF777666D0B35CE6EFD8E46270C4D715B74FEA64FE34FBF4332BB4E8477CA438645C24444417EA5769B507925FB4B8FC59E429F1EC593C397F71087A080B39A192B5147D04D9F30DC237764C810E519B74EE90F047D0829104B6BA1A01F1CC18C85BE79F52084FAD6D7BF3EDA36D63981D8B75676740DB1AA6E06AD0C1F6A3B665D2D9D0E363FCE37B581C682A5F554D820849CEE7066A7DB011EA7D916B4A45212CBBC7A56ADAD33D203B8A1EDA03064A34351916C243E65D45425974C1468A626B773B48962108203F02814F15640149BCC2325C40F2457F0618CAAFDE26162326F2F81E8C727FAFED1B43E3AC8752E9F4EDFF5B58BD316882B555E63278FEB00B61144703C060B6188F3528E176E9B2D5996579048B723EB678CD56FA979004270E9F88F235404C522ED076E9F287097F2F7600A2D4566D2F6EFB600A9854B61CDB4363040D4F30D96BB011EF4BB0E0F21192F72B106B4F38A79FA384978C3C2A9AB94534BE01C83927BC95A9C5E55E618D7C5D77A9FA39664EEF11B2D50F59396DAD7CDC23F17948585BD88342EED68EAB2CC7
-20180508094511 2 6 100 8191 2 E3FCBDCFD41A409C58BE083B6485A2D67E20931B1F469774BAE0F1AB2898B800032581B1C4FC71FE136087937A885AFB6FC9E582DD97B8DE3AD2AF861419D5F06278316DFA78BAE7EF099889F0E99575C7812E7240B67623E7877737013A7D5DB3638040083400E8F27600BAC0650D24220CA1B3C05FB7DD70469A201DBFF1308ECA1C7152A6016BB89BFB6C625715EE91A92EA1848F0B2491AA92187468D9E8442679D7F5F6B64BC9D5A3D4E9B58C59EEEB65F8D6B70A71099E1B420BC0FD750CB2F333C23C97966BE727A6B6D9AEC8C0EB2436E01770F03840BFEC9228BB6DD46CE27D5739E18429F464FFF6812B0F66A8B0024BE03294900B8D0BC3CA6785F8C418EFE7068B2CD190A54BB9F90E05885A5C85DC069495C2009F79DBFD7774D7D65B9831FDC295CE146F4EB91DC56ABBD0B64BEAF3C340E0BF123A115D12289D44B650FF8461734308F4701CF2C199676DB3B4804FCDBD6B08C5D4875073AD5C575CA0B64597472A5C23EB4277B52B1128F3B1AE363E36A2C2D6EF5FCE00EE1573A40AD5ACDCDADE3E2672979CF68E87530520B2CA2C1110CBE4B631F3ABE83CFFDB7D5ACDD6DCA5916E30B1771FE29C4F60163B62349B66C0EDDCE8502F7C49DD4089EA5AE31FFB220A88C8D232367B52FAB7644F02E7EC10378697213CF0D90DA83A9941C217C559F88DEC6587AD953C95F11C575F0EFA9CC0650955C733910F2F90C78AE367F67B0F496A100E0B018731404D2BAEC7420F8C2B1FB6612AF69ECF369F236DD0BFB0ACBAED4141B2A14591C6475FC5C3D4E9B6229ECF7E288C015D59A35DE67F633DC586609AB3AB85A02B99DDF1B6FA7D54D4B2DDB767CAAB797C9FB29594B80B5BAACF777666D0B35CE6EFD8E46270C4D715B74FEA64FE34FBF4332BB4E8477CA438645C24444417EA5769B507925FB4B8FC59E429F1EC593C397F71087A080B39A192B5147D04D9F30DC237764C810E519B74EE90F047D0829104B6BA1A01F1CC18C85BE79F52084FAD6D7BF3EDA36D63981D8B75676740DB1AA6E06AD0C1F6A3B665D2D9D0E363FCE37B581C682A5F554D820849CEE7066A7DB011EA7D916B4A45212CBBC7A56ADAD33D203B8A1EDA03064A34351916C243E65D45425974C1468A626B773B48962108203F02814F15640149BCC2325C40F2457F0618CAAFDE26162326F2F81E8C727FAFED1B43E3AC8752E9F4EDFF5B58BD316882B555E63278FEB00B61144703C060B6188F3528E176E9B2D5996579048B723EB678CD56FA979004270E9F88F235404C522ED076E9F287097F2F7600A2D4566D2F6EFB600A9854B61CDB4363040D4F30D96BB011EF4BB0E0F21192F72B106B4F38A79FA384978C3C2A9AB94534BE01C83927BC95A9C5E55E618D7C5D77A9FA39664EEF11B2D50F59396DAD7CDC23F17948585BD88342EED69078137B
-20180509200633 2 6 100 8191 5 E3FCBDCFD41A409C58BE083B6485A2D67E20931B1F469774BAE0F1AB2898B800032581B1C4FC71FE136087937A885AFB6FC9E582DD97B8DE3AD2AF861419D5F06278316DFA78BAE7EF099889F0E99575C7812E7240B67623E7877737013A7D5DB3638040083400E8F27600BAC0650D24220CA1B3C05FB7DD70469A201DBFF1308ECA1C7152A6016BB89BFB6C625715EE91A92EA1848F0B2491AA92187468D9E8442679D7F5F6B64BC9D5A3D4E9B58C59EEEB65F8D6B70A71099E1B420BC0FD750CB2F333C23C97966BE727A6B6D9AEC8C0EB2436E01770F03840BFEC9228BB6DD46CE27D5739E18429F464FFF6812B0F66A8B0024BE03294900B8D0BC3CA6785F8C418EFE7068B2CD190A54BB9F90E05885A5C85DC069495C2009F79DBFD7774D7D65B9831FDC295CE146F4EB91DC56ABBD0B64BEAF3C340E0BF123A115D12289D44B650FF8461734308F4701CF2C199676DB3B4804FCDBD6B08C5D4875073AD5C575CA0B64597472A5C23EB4277B52B1128F3B1AE363E36A2C2D6EF5FCE00EE1573A40AD5ACDCDADE3E2672979CF68E87530520B2CA2C1110CBE4B631F3ABE83CFFDB7D5ACDD6DCA5916E30B1771FE29C4F60163B62349B66C0EDDCE8502F7C49DD4089EA5AE31FFB220A88C8D232367B52FAB7644F02E7EC10378697213CF0D90DA83A9941C217C559F88DEC6587AD953C95F11C575F0EFA9CC0650955C733910F2F90C78AE367F67B0F496A100E0B018731404D2BAEC7420F8C2B1FB6612AF69ECF369F236DD0BFB0ACBAED4141B2A14591C6475FC5C3D4E9B6229ECF7E288C015D59A35DE67F633DC586609AB3AB85A02B99DDF1B6FA7D54D4B2DDB767CAAB797C9FB29594B80B5BAACF777666D0B35CE6EFD8E46270C4D715B74FEA64FE34FBF4332BB4E8477CA438645C24444417EA5769B507925FB4B8FC59E429F1EC593C397F71087A080B39A192B5147D04D9F30DC237764C810E519B74EE90F047D0829104B6BA1A01F1CC18C85BE79F52084FAD6D7BF3EDA36D63981D8B75676740DB1AA6E06AD0C1F6A3B665D2D9D0E363FCE37B581C682A5F554D820849CEE7066A7DB011EA7D916B4A45212CBBC7A56ADAD33D203B8A1EDA03064A34351916C243E65D45425974C1468A626B773B48962108203F02814F15640149BCC2325C40F2457F0618CAAFDE26162326F2F81E8C727FAFED1B43E3AC8752E9F4EDFF5B58BD316882B555E63278FEB00B61144703C060B6188F3528E176E9B2D5996579048B723EB678CD56FA979004270E9F88F235404C522ED076E9F287097F2F7600A2D4566D2F6EFB600A9854B61CDB4363040D4F30D96BB011EF4BB0E0F21192F72B106B4F38A79FA384978C3C2A9AB94534BE01C83927BC95A9C5E55E618D7C5D77A9FA39664EEF11B2D50F59396DAD7CDC23F17948585BD88342EED6A5AB6E77
-20180509233450 2 6 100 8191 5 E3FCBDCFD41A409C58BE083B6485A2D67E20931B1F469774BAE0F1AB2898B800032581B1C4FC71FE136087937A885AFB6FC9E582DD97B8DE3AD2AF861419D5F06278316DFA78BAE7EF099889F0E99575C7812E7240B67623E7877737013A7D5DB3638040083400E8F27600BAC0650D24220CA1B3C05FB7DD70469A201DBFF1308ECA1C7152A6016BB89BFB6C625715EE91A92EA1848F0B2491AA92187468D9E8442679D7F5F6B64BC9D5A3D4E9B58C59EEEB65F8D6B70A71099E1B420BC0FD750CB2F333C23C97966BE727A6B6D9AEC8C0EB2436E01770F03840BFEC9228BB6DD46CE27D5739E18429F464FFF6812B0F66A8B0024BE03294900B8D0BC3CA6785F8C418EFE7068B2CD190A54BB9F90E05885A5C85DC069495C2009F79DBFD7774D7D65B9831FDC295CE146F4EB91DC56ABBD0B64BEAF3C340E0BF123A115D12289D44B650FF8461734308F4701CF2C199676DB3B4804FCDBD6B08C5D4875073AD5C575CA0B64597472A5C23EB4277B52B1128F3B1AE363E36A2C2D6EF5FCE00EE1573A40AD5ACDCDADE3E2672979CF68E87530520B2CA2C1110CBE4B631F3ABE83CFFDB7D5ACDD6DCA5916E30B1771FE29C4F60163B62349B66C0EDDCE8502F7C49DD4089EA5AE31FFB220A88C8D232367B52FAB7644F02E7EC10378697213CF0D90DA83A9941C217C559F88DEC6587AD953C95F11C575F0EFA9CC0650955C733910F2F90C78AE367F67B0F496A100E0B018731404D2BAEC7420F8C2B1FB6612AF69ECF369F236DD0BFB0ACBAED4141B2A14591C6475FC5C3D4E9B6229ECF7E288C015D59A35DE67F633DC586609AB3AB85A02B99DDF1B6FA7D54D4B2DDB767CAAB797C9FB29594B80B5BAACF777666D0B35CE6EFD8E46270C4D715B74FEA64FE34FBF4332BB4E8477CA438645C24444417EA5769B507925FB4B8FC59E429F1EC593C397F71087A080B39A192B5147D04D9F30DC237764C810E519B74EE90F047D0829104B6BA1A01F1CC18C85BE79F52084FAD6D7BF3EDA36D63981D8B75676740DB1AA6E06AD0C1F6A3B665D2D9D0E363FCE37B581C682A5F554D820849CEE7066A7DB011EA7D916B4A45212CBBC7A56ADAD33D203B8A1EDA03064A34351916C243E65D45425974C1468A626B773B48962108203F02814F15640149BCC2325C40F2457F0618CAAFDE26162326F2F81E8C727FAFED1B43E3AC8752E9F4EDFF5B58BD316882B555E63278FEB00B61144703C060B6188F3528E176E9B2D5996579048B723EB678CD56FA979004270E9F88F235404C522ED076E9F287097F2F7600A2D4566D2F6EFB600A9854B61CDB4363040D4F30D96BB011EF4BB0E0F21192F72B106B4F38A79FA384978C3C2A9AB94534BE01C83927BC95A9C5E55E618D7C5D77A9FA39664EEF11B2D50F59396DAD7CDC23F17948585BD88342EED6A7C34C7F
-20180510003712 2 6 100 8191 5 E3FCBDCFD41A409C58BE083B6485A2D67E20931B1F469774BAE0F1AB2898B800032581B1C4FC71FE136087937A885AFB6FC9E582DD97B8DE3AD2AF861419D5F06278316DFA78BAE7EF099889F0E99575C7812E7240B67623E7877737013A7D5DB3638040083400E8F27600BAC0650D24220CA1B3C05FB7DD70469A201DBFF1308ECA1C7152A6016BB89BFB6C625715EE91A92EA1848F0B2491AA92187468D9E8442679D7F5F6B64BC9D5A3D4E9B58C59EEEB65F8D6B70A71099E1B420BC0FD750CB2F333C23C97966BE727A6B6D9AEC8C0EB2436E01770F03840BFEC9228BB6DD46CE27D5739E18429F464FFF6812B0F66A8B0024BE03294900B8D0BC3CA6785F8C418EFE7068B2CD190A54BB9F90E05885A5C85DC069495C2009F79DBFD7774D7D65B9831FDC295CE146F4EB91DC56ABBD0B64BEAF3C340E0BF123A115D12289D44B650FF8461734308F4701CF2C199676DB3B4804FCDBD6B08C5D4875073AD5C575CA0B64597472A5C23EB4277B52B1128F3B1AE363E36A2C2D6EF5FCE00EE1573A40AD5ACDCDADE3E2672979CF68E87530520B2CA2C1110CBE4B631F3ABE83CFFDB7D5ACDD6DCA5916E30B1771FE29C4F60163B62349B66C0EDDCE8502F7C49DD4089EA5AE31FFB220A88C8D232367B52FAB7644F02E7EC10378697213CF0D90DA83A9941C217C559F88DEC6587AD953C95F11C575F0EFA9CC0650955C733910F2F90C78AE367F67B0F496A100E0B018731404D2BAEC7420F8C2B1FB6612AF69ECF369F236DD0BFB0ACBAED4141B2A14591C6475FC5C3D4E9B6229ECF7E288C015D59A35DE67F633DC586609AB3AB85A02B99DDF1B6FA7D54D4B2DDB767CAAB797C9FB29594B80B5BAACF777666D0B35CE6EFD8E46270C4D715B74FEA64FE34FBF4332BB4E8477CA438645C24444417EA5769B507925FB4B8FC59E429F1EC593C397F71087A080B39A192B5147D04D9F30DC237764C810E519B74EE90F047D0829104B6BA1A01F1CC18C85BE79F52084FAD6D7BF3EDA36D63981D8B75676740DB1AA6E06AD0C1F6A3B665D2D9D0E363FCE37B581C682A5F554D820849CEE7066A7DB011EA7D916B4A45212CBBC7A56ADAD33D203B8A1EDA03064A34351916C243E65D45425974C1468A626B773B48962108203F02814F15640149BCC2325C40F2457F0618CAAFDE26162326F2F81E8C727FAFED1B43E3AC8752E9F4EDFF5B58BD316882B555E63278FEB00B61144703C060B6188F3528E176E9B2D5996579048B723EB678CD56FA979004270E9F88F235404C522ED076E9F287097F2F7600A2D4566D2F6EFB600A9854B61CDB4363040D4F30D96BB011EF4BB0E0F21192F72B106B4F38A79FA384978C3C2A9AB94534BE01C83927BC95A9C5E55E618D7C5D77A9FA39664EEF11B2D50F59396DAD7CDC23F17948585BD88342EED6A85E2007
-20180510011010 2 6 100 8191 2 E3FCBDCFD41A409C58BE083B6485A2D67E20931B1F469774BAE0F1AB2898B800032581B1C4FC71FE136087937A885AFB6FC9E582DD97B8DE3AD2AF861419D5F06278316DFA78BAE7EF099889F0E99575C7812E7240B67623E7877737013A7D5DB3638040083400E8F27600BAC0650D24220CA1B3C05FB7DD70469A201DBFF1308ECA1C7152A6016BB89BFB6C625715EE91A92EA1848F0B2491AA92187468D9E8442679D7F5F6B64BC9D5A3D4E9B58C59EEEB65F8D6B70A71099E1B420BC0FD750CB2F333C23C97966BE727A6B6D9AEC8C0EB2436E01770F03840BFEC9228BB6DD46CE27D5739E18429F464FFF6812B0F66A8B0024BE03294900B8D0BC3CA6785F8C418EFE7068B2CD190A54BB9F90E05885A5C85DC069495C2009F79DBFD7774D7D65B9831FDC295CE146F4EB91DC56ABBD0B64BEAF3C340E0BF123A115D12289D44B650FF8461734308F4701CF2C199676DB3B4804FCDBD6B08C5D4875073AD5C575CA0B64597472A5C23EB4277B52B1128F3B1AE363E36A2C2D6EF5FCE00EE1573A40AD5ACDCDADE3E2672979CF68E87530520B2CA2C1110CBE4B631F3ABE83CFFDB7D5ACDD6DCA5916E30B1771FE29C4F60163B62349B66C0EDDCE8502F7C49DD4089EA5AE31FFB220A88C8D232367B52FAB7644F02E7EC10378697213CF0D90DA83A9941C217C559F88DEC6587AD953C95F11C575F0EFA9CC0650955C733910F2F90C78AE367F67B0F496A100E0B018731404D2BAEC7420F8C2B1FB6612AF69ECF369F236DD0BFB0ACBAED4141B2A14591C6475FC5C3D4E9B6229ECF7E288C015D59A35DE67F633DC586609AB3AB85A02B99DDF1B6FA7D54D4B2DDB767CAAB797C9FB29594B80B5BAACF777666D0B35CE6EFD8E46270C4D715B74FEA64FE34FBF4332BB4E8477CA438645C24444417EA5769B507925FB4B8FC59E429F1EC593C397F71087A080B39A192B5147D04D9F30DC237764C810E519B74EE90F047D0829104B6BA1A01F1CC18C85BE79F52084FAD6D7BF3EDA36D63981D8B75676740DB1AA6E06AD0C1F6A3B665D2D9D0E363FCE37B581C682A5F554D820849CEE7066A7DB011EA7D916B4A45212CBBC7A56ADAD33D203B8A1EDA03064A34351916C243E65D45425974C1468A626B773B48962108203F02814F15640149BCC2325C40F2457F0618CAAFDE26162326F2F81E8C727FAFED1B43E3AC8752E9F4EDFF5B58BD316882B555E63278FEB00B61144703C060B6188F3528E176E9B2D5996579048B723EB678CD56FA979004270E9F88F235404C522ED076E9F287097F2F7600A2D4566D2F6EFB600A9854B61CDB4363040D4F30D96BB011EF4BB0E0F21192F72B106B4F38A79FA384978C3C2A9AB94534BE01C83927BC95A9C5E55E618D7C5D77A9FA39664EEF11B2D50F59396DAD7CDC23F17948585BD88342EED6A8ABBDA3
-20180510075358 2 6 100 8191 2 E3FCBDCFD41A409C58BE083B6485A2D67E20931B1F469774BAE0F1AB2898B800032581B1C4FC71FE136087937A885AFB6FC9E582DD97B8DE3AD2AF861419D5F06278316DFA78BAE7EF099889F0E99575C7812E7240B67623E7877737013A7D5DB3638040083400E8F27600BAC0650D24220CA1B3C05FB7DD70469A201DBFF1308ECA1C7152A6016BB89BFB6C625715EE91A92EA1848F0B2491AA92187468D9E8442679D7F5F6B64BC9D5A3D4E9B58C59EEEB65F8D6B70A71099E1B420BC0FD750CB2F333C23C97966BE727A6B6D9AEC8C0EB2436E01770F03840BFEC9228BB6DD46CE27D5739E18429F464FFF6812B0F66A8B0024BE03294900B8D0BC3CA6785F8C418EFE7068B2CD190A54BB9F90E05885A5C85DC069495C2009F79DBFD7774D7D65B9831FDC295CE146F4EB91DC56ABBD0B64BEAF3C340E0BF123A115D12289D44B650FF8461734308F4701CF2C199676DB3B4804FCDBD6B08C5D4875073AD5C575CA0B64597472A5C23EB4277B52B1128F3B1AE363E36A2C2D6EF5FCE00EE1573A40AD5ACDCDADE3E2672979CF68E87530520B2CA2C1110CBE4B631F3ABE83CFFDB7D5ACDD6DCA5916E30B1771FE29C4F60163B62349B66C0EDDCE8502F7C49DD4089EA5AE31FFB220A88C8D232367B52FAB7644F02E7EC10378697213CF0D90DA83A9941C217C559F88DEC6587AD953C95F11C575F0EFA9CC0650955C733910F2F90C78AE367F67B0F496A100E0B018731404D2BAEC7420F8C2B1FB6612AF69ECF369F236DD0BFB0ACBAED4141B2A14591C6475FC5C3D4E9B6229ECF7E288C015D59A35DE67F633DC586609AB3AB85A02B99DDF1B6FA7D54D4B2DDB767CAAB797C9FB29594B80B5BAACF777666D0B35CE6EFD8E46270C4D715B74FEA64FE34FBF4332BB4E8477CA438645C24444417EA5769B507925FB4B8FC59E429F1EC593C397F71087A080B39A192B5147D04D9F30DC237764C810E519B74EE90F047D0829104B6BA1A01F1CC18C85BE79F52084FAD6D7BF3EDA36D63981D8B75676740DB1AA6E06AD0C1F6A3B665D2D9D0E363FCE37B581C682A5F554D820849CEE7066A7DB011EA7D916B4A45212CBBC7A56ADAD33D203B8A1EDA03064A34351916C243E65D45425974C1468A626B773B48962108203F02814F15640149BCC2325C40F2457F0618CAAFDE26162326F2F81E8C727FAFED1B43E3AC8752E9F4EDFF5B58BD316882B555E63278FEB00B61144703C060B6188F3528E176E9B2D5996579048B723EB678CD56FA979004270E9F88F235404C522ED076E9F287097F2F7600A2D4566D2F6EFB600A9854B61CDB4363040D4F30D96BB011EF4BB0E0F21192F72B106B4F38A79FA384978C3C2A9AB94534BE01C83927BC95A9C5E55E618D7C5D77A9FA39664EEF11B2D50F59396DAD7CDC23F17948585BD88342EED6AC65344B
-20180510102028 2 6 100 8191 2 E3FCBDCFD41A409C58BE083B6485A2D67E20931B1F469774BAE0F1AB2898B800032581B1C4FC71FE136087937A885AFB6FC9E582DD97B8DE3AD2AF861419D5F06278316DFA78BAE7EF099889F0E99575C7812E7240B67623E7877737013A7D5DB3638040083400E8F27600BAC0650D24220CA1B3C05FB7DD70469A201DBFF1308ECA1C7152A6016BB89BFB6C625715EE91A92EA1848F0B2491AA92187468D9E8442679D7F5F6B64BC9D5A3D4E9B58C59EEEB65F8D6B70A71099E1B420BC0FD750CB2F333C23C97966BE727A6B6D9AEC8C0EB2436E01770F03840BFEC9228BB6DD46CE27D5739E18429F464FFF6812B0F66A8B0024BE03294900B8D0BC3CA6785F8C418EFE7068B2CD190A54BB9F90E05885A5C85DC069495C2009F79DBFD7774D7D65B9831FDC295CE146F4EB91DC56ABBD0B64BEAF3C340E0BF123A115D12289D44B650FF8461734308F4701CF2C199676DB3B4804FCDBD6B08C5D4875073AD5C575CA0B64597472A5C23EB4277B52B1128F3B1AE363E36A2C2D6EF5FCE00EE1573A40AD5ACDCDADE3E2672979CF68E87530520B2CA2C1110CBE4B631F3ABE83CFFDB7D5ACDD6DCA5916E30B1771FE29C4F60163B62349B66C0EDDCE8502F7C49DD4089EA5AE31FFB220A88C8D232367B52FAB7644F02E7EC10378697213CF0D90DA83A9941C217C559F88DEC6587AD953C95F11C575F0EFA9CC0650955C733910F2F90C78AE367F67B0F496A100E0B018731404D2BAEC7420F8C2B1FB6612AF69ECF369F236DD0BFB0ACBAED4141B2A14591C6475FC5C3D4E9B6229ECF7E288C015D59A35DE67F633DC586609AB3AB85A02B99DDF1B6FA7D54D4B2DDB767CAAB797C9FB29594B80B5BAACF777666D0B35CE6EFD8E46270C4D715B74FEA64FE34FBF4332BB4E8477CA438645C24444417EA5769B507925FB4B8FC59E429F1EC593C397F71087A080B39A192B5147D04D9F30DC237764C810E519B74EE90F047D0829104B6BA1A01F1CC18C85BE79F52084FAD6D7BF3EDA36D63981D8B75676740DB1AA6E06AD0C1F6A3B665D2D9D0E363FCE37B581C682A5F554D820849CEE7066A7DB011EA7D916B4A45212CBBC7A56ADAD33D203B8A1EDA03064A34351916C243E65D45425974C1468A626B773B48962108203F02814F15640149BCC2325C40F2457F0618CAAFDE26162326F2F81E8C727FAFED1B43E3AC8752E9F4EDFF5B58BD316882B555E63278FEB00B61144703C060B6188F3528E176E9B2D5996579048B723EB678CD56FA979004270E9F88F235404C522ED076E9F287097F2F7600A2D4566D2F6EFB600A9854B61CDB4363040D4F30D96BB011EF4BB0E0F21192F72B106B4F38A79FA384978C3C2A9AB94534BE01C83927BC95A9C5E55E618D7C5D77A9FA39664EEF11B2D50F59396DAD7CDC23F17948585BD88342EED6ADD74BF3
-20180510111207 2 6 100 8191 2 E3FCBDCFD41A409C58BE083B6485A2D67E20931B1F469774BAE0F1AB2898B800032581B1C4FC71FE136087937A885AFB6FC9E582DD97B8DE3AD2AF861419D5F06278316DFA78BAE7EF099889F0E99575C7812E7240B67623E7877737013A7D5DB3638040083400E8F27600BAC0650D24220CA1B3C05FB7DD70469A201DBFF1308ECA1C7152A6016BB89BFB6C625715EE91A92EA1848F0B2491AA92187468D9E8442679D7F5F6B64BC9D5A3D4E9B58C59EEEB65F8D6B70A71099E1B420BC0FD750CB2F333C23C97966BE727A6B6D9AEC8C0EB2436E01770F03840BFEC9228BB6DD46CE27D5739E18429F464FFF6812B0F66A8B0024BE03294900B8D0BC3CA6785F8C418EFE7068B2CD190A54BB9F90E05885A5C85DC069495C2009F79DBFD7774D7D65B9831FDC295CE146F4EB91DC56ABBD0B64BEAF3C340E0BF123A115D12289D44B650FF8461734308F4701CF2C199676DB3B4804FCDBD6B08C5D4875073AD5C575CA0B64597472A5C23EB4277B52B1128F3B1AE363E36A2C2D6EF5FCE00EE1573A40AD5ACDCDADE3E2672979CF68E87530520B2CA2C1110CBE4B631F3ABE83CFFDB7D5ACDD6DCA5916E30B1771FE29C4F60163B62349B66C0EDDCE8502F7C49DD4089EA5AE31FFB220A88C8D232367B52FAB7644F02E7EC10378697213CF0D90DA83A9941C217C559F88DEC6587AD953C95F11C575F0EFA9CC0650955C733910F2F90C78AE367F67B0F496A100E0B018731404D2BAEC7420F8C2B1FB6612AF69ECF369F236DD0BFB0ACBAED4141B2A14591C6475FC5C3D4E9B6229ECF7E288C015D59A35DE67F633DC586609AB3AB85A02B99DDF1B6FA7D54D4B2DDB767CAAB797C9FB29594B80B5BAACF777666D0B35CE6EFD8E46270C4D715B74FEA64FE34FBF4332BB4E8477CA438645C24444417EA5769B507925FB4B8FC59E429F1EC593C397F71087A080B39A192B5147D04D9F30DC237764C810E519B74EE90F047D0829104B6BA1A01F1CC18C85BE79F52084FAD6D7BF3EDA36D63981D8B75676740DB1AA6E06AD0C1F6A3B665D2D9D0E363FCE37B581C682A5F554D820849CEE7066A7DB011EA7D916B4A45212CBBC7A56ADAD33D203B8A1EDA03064A34351916C243E65D45425974C1468A626B773B48962108203F02814F15640149BCC2325C40F2457F0618CAAFDE26162326F2F81E8C727FAFED1B43E3AC8752E9F4EDFF5B58BD316882B555E63278FEB00B61144703C060B6188F3528E176E9B2D5996579048B723EB678CD56FA979004270E9F88F235404C522ED076E9F287097F2F7600A2D4566D2F6EFB600A9854B61CDB4363040D4F30D96BB011EF4BB0E0F21192F72B106B4F38A79FA384978C3C2A9AB94534BE01C83927BC95A9C5E55E618D7C5D77A9FA39664EEF11B2D50F59396DAD7CDC23F17948585BD88342EED6AE56234B
-20180510122304 2 6 100 8191 5 E3FCBDCFD41A409C58BE083B6485A2D67E20931B1F469774BAE0F1AB2898B800032581B1C4FC71FE136087937A885AFB6FC9E582DD97B8DE3AD2AF861419D5F06278316DFA78BAE7EF099889F0E99575C7812E7240B67623E7877737013A7D5DB3638040083400E8F27600BAC0650D24220CA1B3C05FB7DD70469A201DBFF1308ECA1C7152A6016BB89BFB6C625715EE91A92EA1848F0B2491AA92187468D9E8442679D7F5F6B64BC9D5A3D4E9B58C59EEEB65F8D6B70A71099E1B420BC0FD750CB2F333C23C97966BE727A6B6D9AEC8C0EB2436E01770F03840BFEC9228BB6DD46CE27D5739E18429F464FFF6812B0F66A8B0024BE03294900B8D0BC3CA6785F8C418EFE7068B2CD190A54BB9F90E05885A5C85DC069495C2009F79DBFD7774D7D65B9831FDC295CE146F4EB91DC56ABBD0B64BEAF3C340E0BF123A115D12289D44B650FF8461734308F4701CF2C199676DB3B4804FCDBD6B08C5D4875073AD5C575CA0B64597472A5C23EB4277B52B1128F3B1AE363E36A2C2D6EF5FCE00EE1573A40AD5ACDCDADE3E2672979CF68E87530520B2CA2C1110CBE4B631F3ABE83CFFDB7D5ACDD6DCA5916E30B1771FE29C4F60163B62349B66C0EDDCE8502F7C49DD4089EA5AE31FFB220A88C8D232367B52FAB7644F02E7EC10378697213CF0D90DA83A9941C217C559F88DEC6587AD953C95F11C575F0EFA9CC0650955C733910F2F90C78AE367F67B0F496A100E0B018731404D2BAEC7420F8C2B1FB6612AF69ECF369F236DD0BFB0ACBAED4141B2A14591C6475FC5C3D4E9B6229ECF7E288C015D59A35DE67F633DC586609AB3AB85A02B99DDF1B6FA7D54D4B2DDB767CAAB797C9FB29594B80B5BAACF777666D0B35CE6EFD8E46270C4D715B74FEA64FE34FBF4332BB4E8477CA438645C24444417EA5769B507925FB4B8FC59E429F1EC593C397F71087A080B39A192B5147D04D9F30DC237764C810E519B74EE90F047D0829104B6BA1A01F1CC18C85BE79F52084FAD6D7BF3EDA36D63981D8B75676740DB1AA6E06AD0C1F6A3B665D2D9D0E363FCE37B581C682A5F554D820849CEE7066A7DB011EA7D916B4A45212CBBC7A56ADAD33D203B8A1EDA03064A34351916C243E65D45425974C1468A626B773B48962108203F02814F15640149BCC2325C40F2457F0618CAAFDE26162326F2F81E8C727FAFED1B43E3AC8752E9F4EDFF5B58BD316882B555E63278FEB00B61144703C060B6188F3528E176E9B2D5996579048B723EB678CD56FA979004270E9F88F235404C522ED076E9F287097F2F7600A2D4566D2F6EFB600A9854B61CDB4363040D4F30D96BB011EF4BB0E0F21192F72B106B4F38A79FA384978C3C2A9AB94534BE01C83927BC95A9C5E55E618D7C5D77A9FA39664EEF11B2D50F59396DAD7CDC23F17948585BD88342EED6AF06789F
+20210510040256 2 6 100 2047 5 C7CE688A891B095F8844E2381248DFAE8FA10F704F18EC478287964C92B6931F4DCEF6250CEE631DC7217BB9BCEDF38B29FBFE1E62C4461F3B4FB0DD872C3D7B1AF59DF757564EFFEADFBCD4529760A9B8F277E31BAF8F986BB5C5298ECF5E0760977111396ACB3782D2F6D91B6059160F28A667B6BD61ABDCFBDA374930FFF31A2620DF9AA6BFE8C2C27E78A8423FDD0DBDAF6D3E52EC80E345D5D64D5F6B20BD8D12E13D415788B69868EBA41360E1C88A25BE04B7E0182284276EC4E3BF2CE45C373C2E43C6B575C2A579209FEAEA885E20C11471DD884942266B9E3847B8839FC2A79F8F1594ADD8A10ABAC9C7881B2CF99D762B5E2E7A0BC52B6F7F372F
+20210510040337 2 6 100 2047 2 C7CE688A891B095F8844E2381248DFAE8FA10F704F18EC478287964C92B6931F4DCEF6250CEE631DC7217BB9BCEDF38B29FBFE1E62C4461F3B4FB0DD872C3D7B1AF59DF757564EFFEADFBCD4529760A9B8F277E31BAF8F986BB5C5298ECF5E0760977111396ACB3782D2F6D91B6059160F28A667B6BD61ABDCFBDA374930FFF31A2620DF9AA6BFE8C2C27E78A8423FDD0DBDAF6D3E52EC80E345D5D64D5F6B20BD8D12E13D415788B69868EBA41360E1C88A25BE04B7E0182284276EC4E3BF2CE45C373C2E43C6B575C2A579209FEAEA885E20C11471DD884942266B9E3847B8839FC2A79F8F1594ADD8A10ABAC9C7881B2CF99D762B5E2E7A0BC52B6FC9DF33
+20210510040415 2 6 100 2047 2 C7CE688A891B095F8844E2381248DFAE8FA10F704F18EC478287964C92B6931F4DCEF6250CEE631DC7217BB9BCEDF38B29FBFE1E62C4461F3B4FB0DD872C3D7B1AF59DF757564EFFEADFBCD4529760A9B8F277E31BAF8F986BB5C5298ECF5E0760977111396ACB3782D2F6D91B6059160F28A667B6BD61ABDCFBDA374930FFF31A2620DF9AA6BFE8C2C27E78A8423FDD0DBDAF6D3E52EC80E345D5D64D5F6B20BD8D12E13D415788B69868EBA41360E1C88A25BE04B7E0182284276EC4E3BF2CE45C373C2E43C6B575C2A579209FEAEA885E20C11471DD884942266B9E3847B8839FC2A79F8F1594ADD8A10ABAC9C7881B2CF99D762B5E2E7A0BC52B700C2C43
+20210510040454 2 6 100 2047 5 C7CE688A891B095F8844E2381248DFAE8FA10F704F18EC478287964C92B6931F4DCEF6250CEE631DC7217BB9BCEDF38B29FBFE1E62C4461F3B4FB0DD872C3D7B1AF59DF757564EFFEADFBCD4529760A9B8F277E31BAF8F986BB5C5298ECF5E0760977111396ACB3782D2F6D91B6059160F28A667B6BD61ABDCFBDA374930FFF31A2620DF9AA6BFE8C2C27E78A8423FDD0DBDAF6D3E52EC80E345D5D64D5F6B20BD8D12E13D415788B69868EBA41360E1C88A25BE04B7E0182284276EC4E3BF2CE45C373C2E43C6B575C2A579209FEAEA885E20C11471DD884942266B9E3847B8839FC2A79F8F1594ADD8A10ABAC9C7881B2CF99D762B5E2E7A0BC52B7052E7EF
+20210510040524 2 6 100 2047 5 C7CE688A891B095F8844E2381248DFAE8FA10F704F18EC478287964C92B6931F4DCEF6250CEE631DC7217BB9BCEDF38B29FBFE1E62C4461F3B4FB0DD872C3D7B1AF59DF757564EFFEADFBCD4529760A9B8F277E31BAF8F986BB5C5298ECF5E0760977111396ACB3782D2F6D91B6059160F28A667B6BD61ABDCFBDA374930FFF31A2620DF9AA6BFE8C2C27E78A8423FDD0DBDAF6D3E52EC80E345D5D64D5F6B20BD8D12E13D415788B69868EBA41360E1C88A25BE04B7E0182284276EC4E3BF2CE45C373C2E43C6B575C2A579209FEAEA885E20C11471DD884942266B9E3847B8839FC2A79F8F1594ADD8A10ABAC9C7881B2CF99D762B5E2E7A0BC52B708A4C17
+20210510040600 2 6 100 2047 5 C7CE688A891B095F8844E2381248DFAE8FA10F704F18EC478287964C92B6931F4DCEF6250CEE631DC7217BB9BCEDF38B29FBFE1E62C4461F3B4FB0DD872C3D7B1AF59DF757564EFFEADFBCD4529760A9B8F277E31BAF8F986BB5C5298ECF5E0760977111396ACB3782D2F6D91B6059160F28A667B6BD61ABDCFBDA374930FFF31A2620DF9AA6BFE8C2C27E78A8423FDD0DBDAF6D3E52EC80E345D5D64D5F6B20BD8D12E13D415788B69868EBA41360E1C88A25BE04B7E0182284276EC4E3BF2CE45C373C2E43C6B575C2A579209FEAEA885E20C11471DD884942266B9E3847B8839FC2A79F8F1594ADD8A10ABAC9C7881B2CF99D762B5E2E7A0BC52B70CAD2BF
+20210510040723 2 6 100 2047 2 C7CE688A891B095F8844E2381248DFAE8FA10F704F18EC478287964C92B6931F4DCEF6250CEE631DC7217BB9BCEDF38B29FBFE1E62C4461F3B4FB0DD872C3D7B1AF59DF757564EFFEADFBCD4529760A9B8F277E31BAF8F986BB5C5298ECF5E0760977111396ACB3782D2F6D91B6059160F28A667B6BD61ABDCFBDA374930FFF31A2620DF9AA6BFE8C2C27E78A8423FDD0DBDAF6D3E52EC80E345D5D64D5F6B20BD8D12E13D415788B69868EBA41360E1C88A25BE04B7E0182284276EC4E3BF2CE45C373C2E43C6B575C2A579209FEAEA885E20C11471DD884942266B9E3847B8839FC2A79F8F1594ADD8A10ABAC9C7881B2CF99D762B5E2E7A0BC52B716449C3
+20210510040743 2 6 100 2047 5 C7CE688A891B095F8844E2381248DFAE8FA10F704F18EC478287964C92B6931F4DCEF6250CEE631DC7217BB9BCEDF38B29FBFE1E62C4461F3B4FB0DD872C3D7B1AF59DF757564EFFEADFBCD4529760A9B8F277E31BAF8F986BB5C5298ECF5E0760977111396ACB3782D2F6D91B6059160F28A667B6BD61ABDCFBDA374930FFF31A2620DF9AA6BFE8C2C27E78A8423FDD0DBDAF6D3E52EC80E345D5D64D5F6B20BD8D12E13D415788B69868EBA41360E1C88A25BE04B7E0182284276EC4E3BF2CE45C373C2E43C6B575C2A579209FEAEA885E20C11471DD884942266B9E3847B8839FC2A79F8F1594ADD8A10ABAC9C7881B2CF99D762B5E2E7A0BC52B718416DF
+20210510040805 2 6 100 2047 2 C7CE688A891B095F8844E2381248DFAE8FA10F704F18EC478287964C92B6931F4DCEF6250CEE631DC7217BB9BCEDF38B29FBFE1E62C4461F3B4FB0DD872C3D7B1AF59DF757564EFFEADFBCD4529760A9B8F277E31BAF8F986BB5C5298ECF5E0760977111396ACB3782D2F6D91B6059160F28A667B6BD61ABDCFBDA374930FFF31A2620DF9AA6BFE8C2C27E78A8423FDD0DBDAF6D3E52EC80E345D5D64D5F6B20BD8D12E13D415788B69868EBA41360E1C88A25BE04B7E0182284276EC4E3BF2CE45C373C2E43C6B575C2A579209FEAEA885E20C11471DD884942266B9E3847B8839FC2A79F8F1594ADD8A10ABAC9C7881B2CF99D762B5E2E7A0BC52B71A5291B
+20210510040833 2 6 100 2047 2 C7CE688A891B095F8844E2381248DFAE8FA10F704F18EC478287964C92B6931F4DCEF6250CEE631DC7217BB9BCEDF38B29FBFE1E62C4461F3B4FB0DD872C3D7B1AF59DF757564EFFEADFBCD4529760A9B8F277E31BAF8F986BB5C5298ECF5E0760977111396ACB3782D2F6D91B6059160F28A667B6BD61ABDCFBDA374930FFF31A2620DF9AA6BFE8C2C27E78A8423FDD0DBDAF6D3E52EC80E345D5D64D5F6B20BD8D12E13D415788B69868EBA41360E1C88A25BE04B7E0182284276EC4E3BF2CE45C373C2E43C6B575C2A579209FEAEA885E20C11471DD884942266B9E3847B8839FC2A79F8F1594ADD8A10ABAC9C7881B2CF99D762B5E2E7A0BC52B71D2EB43
+20210510040926 2 6 100 2047 2 C7CE688A891B095F8844E2381248DFAE8FA10F704F18EC478287964C92B6931F4DCEF6250CEE631DC7217BB9BCEDF38B29FBFE1E62C4461F3B4FB0DD872C3D7B1AF59DF757564EFFEADFBCD4529760A9B8F277E31BAF8F986BB5C5298ECF5E0760977111396ACB3782D2F6D91B6059160F28A667B6BD61ABDCFBDA374930FFF31A2620DF9AA6BFE8C2C27E78A8423FDD0DBDAF6D3E52EC80E345D5D64D5F6B20BD8D12E13D415788B69868EBA41360E1C88A25BE04B7E0182284276EC4E3BF2CE45C373C2E43C6B575C2A579209FEAEA885E20C11471DD884942266B9E3847B8839FC2A79F8F1594ADD8A10ABAC9C7881B2CF99D762B5E2E7A0BC52B7233C20B
+20210510040945 2 6 100 2047 5 C7CE688A891B095F8844E2381248DFAE8FA10F704F18EC478287964C92B6931F4DCEF6250CEE631DC7217BB9BCEDF38B29FBFE1E62C4461F3B4FB0DD872C3D7B1AF59DF757564EFFEADFBCD4529760A9B8F277E31BAF8F986BB5C5298ECF5E0760977111396ACB3782D2F6D91B6059160F28A667B6BD61ABDCFBDA374930FFF31A2620DF9AA6BFE8C2C27E78A8423FDD0DBDAF6D3E52EC80E345D5D64D5F6B20BD8D12E13D415788B69868EBA41360E1C88A25BE04B7E0182284276EC4E3BF2CE45C373C2E43C6B575C2A579209FEAEA885E20C11471DD884942266B9E3847B8839FC2A79F8F1594ADD8A10ABAC9C7881B2CF99D762B5E2E7A0BC52B7250533F
+20210510040952 2 6 100 2047 5 C7CE688A891B095F8844E2381248DFAE8FA10F704F18EC478287964C92B6931F4DCEF6250CEE631DC7217BB9BCEDF38B29FBFE1E62C4461F3B4FB0DD872C3D7B1AF59DF757564EFFEADFBCD4529760A9B8F277E31BAF8F986BB5C5298ECF5E0760977111396ACB3782D2F6D91B6059160F28A667B6BD61ABDCFBDA374930FFF31A2620DF9AA6BFE8C2C27E78A8423FDD0DBDAF6D3E52EC80E345D5D64D5F6B20BD8D12E13D415788B69868EBA41360E1C88A25BE04B7E0182284276EC4E3BF2CE45C373C2E43C6B575C2A579209FEAEA885E20C11471DD884942266B9E3847B8839FC2A79F8F1594ADD8A10ABAC9C7881B2CF99D762B5E2E7A0BC52B7255E727
+20210510041013 2 6 100 2047 5 C7CE688A891B095F8844E2381248DFAE8FA10F704F18EC478287964C92B6931F4DCEF6250CEE631DC7217BB9BCEDF38B29FBFE1E62C4461F3B4FB0DD872C3D7B1AF59DF757564EFFEADFBCD4529760A9B8F277E31BAF8F986BB5C5298ECF5E0760977111396ACB3782D2F6D91B6059160F28A667B6BD61ABDCFBDA374930FFF31A2620DF9AA6BFE8C2C27E78A8423FDD0DBDAF6D3E52EC80E345D5D64D5F6B20BD8D12E13D415788B69868EBA41360E1C88A25BE04B7E0182284276EC4E3BF2CE45C373C2E43C6B575C2A579209FEAEA885E20C11471DD884942266B9E3847B8839FC2A79F8F1594ADD8A10ABAC9C7881B2CF99D762B5E2E7A0BC52B7276D7F7
+20210510041024 2 6 100 2047 2 C7CE688A891B095F8844E2381248DFAE8FA10F704F18EC478287964C92B6931F4DCEF6250CEE631DC7217BB9BCEDF38B29FBFE1E62C4461F3B4FB0DD872C3D7B1AF59DF757564EFFEADFBCD4529760A9B8F277E31BAF8F986BB5C5298ECF5E0760977111396ACB3782D2F6D91B6059160F28A667B6BD61ABDCFBDA374930FFF31A2620DF9AA6BFE8C2C27E78A8423FDD0DBDAF6D3E52EC80E345D5D64D5F6B20BD8D12E13D415788B69868EBA41360E1C88A25BE04B7E0182284276EC4E3BF2CE45C373C2E43C6B575C2A579209FEAEA885E20C11471DD884942266B9E3847B8839FC2A79F8F1594ADD8A10ABAC9C7881B2CF99D762B5E2E7A0BC52B7285067B
+20210510041122 2 6 100 2047 2 C7CE688A891B095F8844E2381248DFAE8FA10F704F18EC478287964C92B6931F4DCEF6250CEE631DC7217BB9BCEDF38B29FBFE1E62C4461F3B4FB0DD872C3D7B1AF59DF757564EFFEADFBCD4529760A9B8F277E31BAF8F986BB5C5298ECF5E0760977111396ACB3782D2F6D91B6059160F28A667B6BD61ABDCFBDA374930FFF31A2620DF9AA6BFE8C2C27E78A8423FDD0DBDAF6D3E52EC80E345D5D64D5F6B20BD8D12E13D415788B69868EBA41360E1C88A25BE04B7E0182284276EC4E3BF2CE45C373C2E43C6B575C2A579209FEAEA885E20C11471DD884942266B9E3847B8839FC2A79F8F1594ADD8A10ABAC9C7881B2CF99D762B5E2E7A0BC52B72EF5963
+20210510041140 2 6 100 2047 2 C7CE688A891B095F8844E2381248DFAE8FA10F704F18EC478287964C92B6931F4DCEF6250CEE631DC7217BB9BCEDF38B29FBFE1E62C4461F3B4FB0DD872C3D7B1AF59DF757564EFFEADFBCD4529760A9B8F277E31BAF8F986BB5C5298ECF5E0760977111396ACB3782D2F6D91B6059160F28A667B6BD61ABDCFBDA374930FFF31A2620DF9AA6BFE8C2C27E78A8423FDD0DBDAF6D3E52EC80E345D5D64D5F6B20BD8D12E13D415788B69868EBA41360E1C88A25BE04B7E0182284276EC4E3BF2CE45C373C2E43C6B575C2A579209FEAEA885E20C11471DD884942266B9E3847B8839FC2A79F8F1594ADD8A10ABAC9C7881B2CF99D762B5E2E7A0BC52B730BC05B
+20210510041146 2 6 100 2047 2 C7CE688A891B095F8844E2381248DFAE8FA10F704F18EC478287964C92B6931F4DCEF6250CEE631DC7217BB9BCEDF38B29FBFE1E62C4461F3B4FB0DD872C3D7B1AF59DF757564EFFEADFBCD4529760A9B8F277E31BAF8F986BB5C5298ECF5E0760977111396ACB3782D2F6D91B6059160F28A667B6BD61ABDCFBDA374930FFF31A2620DF9AA6BFE8C2C27E78A8423FDD0DBDAF6D3E52EC80E345D5D64D5F6B20BD8D12E13D415788B69868EBA41360E1C88A25BE04B7E0182284276EC4E3BF2CE45C373C2E43C6B575C2A579209FEAEA885E20C11471DD884942266B9E3847B8839FC2A79F8F1594ADD8A10ABAC9C7881B2CF99D762B5E2E7A0BC52B730F5103
+20210510041159 2 6 100 2047 2 C7CE688A891B095F8844E2381248DFAE8FA10F704F18EC478287964C92B6931F4DCEF6250CEE631DC7217BB9BCEDF38B29FBFE1E62C4461F3B4FB0DD872C3D7B1AF59DF757564EFFEADFBCD4529760A9B8F277E31BAF8F986BB5C5298ECF5E0760977111396ACB3782D2F6D91B6059160F28A667B6BD61ABDCFBDA374930FFF31A2620DF9AA6BFE8C2C27E78A8423FDD0DBDAF6D3E52EC80E345D5D64D5F6B20BD8D12E13D415788B69868EBA41360E1C88A25BE04B7E0182284276EC4E3BF2CE45C373C2E43C6B575C2A579209FEAEA885E20C11471DD884942266B9E3847B8839FC2A79F8F1594ADD8A10ABAC9C7881B2CF99D762B5E2E7A0BC52B7321C19B
+20210510041220 2 6 100 2047 2 C7CE688A891B095F8844E2381248DFAE8FA10F704F18EC478287964C92B6931F4DCEF6250CEE631DC7217BB9BCEDF38B29FBFE1E62C4461F3B4FB0DD872C3D7B1AF59DF757564EFFEADFBCD4529760A9B8F277E31BAF8F986BB5C5298ECF5E0760977111396ACB3782D2F6D91B6059160F28A667B6BD61ABDCFBDA374930FFF31A2620DF9AA6BFE8C2C27E78A8423FDD0DBDAF6D3E52EC80E345D5D64D5F6B20BD8D12E13D415788B69868EBA41360E1C88A25BE04B7E0182284276EC4E3BF2CE45C373C2E43C6B575C2A579209FEAEA885E20C11471DD884942266B9E3847B8839FC2A79F8F1594ADD8A10ABAC9C7881B2CF99D762B5E2E7A0BC52B7341D4E3
+20210510041337 2 6 100 2047 2 C7CE688A891B095F8844E2381248DFAE8FA10F704F18EC478287964C92B6931F4DCEF6250CEE631DC7217BB9BCEDF38B29FBFE1E62C4461F3B4FB0DD872C3D7B1AF59DF757564EFFEADFBCD4529760A9B8F277E31BAF8F986BB5C5298ECF5E0760977111396ACB3782D2F6D91B6059160F28A667B6BD61ABDCFBDA374930FFF31A2620DF9AA6BFE8C2C27E78A8423FDD0DBDAF6D3E52EC80E345D5D64D5F6B20BD8D12E13D415788B69868EBA41360E1C88A25BE04B7E0182284276EC4E3BF2CE45C373C2E43C6B575C2A579209FEAEA885E20C11471DD884942266B9E3847B8839FC2A79F8F1594ADD8A10ABAC9C7881B2CF99D762B5E2E7A0BC52B73D507FB
+20210510041353 2 6 100 2047 2 C7CE688A891B095F8844E2381248DFAE8FA10F704F18EC478287964C92B6931F4DCEF6250CEE631DC7217BB9BCEDF38B29FBFE1E62C4461F3B4FB0DD872C3D7B1AF59DF757564EFFEADFBCD4529760A9B8F277E31BAF8F986BB5C5298ECF5E0760977111396ACB3782D2F6D91B6059160F28A667B6BD61ABDCFBDA374930FFF31A2620DF9AA6BFE8C2C27E78A8423FDD0DBDAF6D3E52EC80E345D5D64D5F6B20BD8D12E13D415788B69868EBA41360E1C88A25BE04B7E0182284276EC4E3BF2CE45C373C2E43C6B575C2A579209FEAEA885E20C11471DD884942266B9E3847B8839FC2A79F8F1594ADD8A10ABAC9C7881B2CF99D762B5E2E7A0BC52B73EBBAB3
+20210510041423 2 6 100 2047 5 C7CE688A891B095F8844E2381248DFAE8FA10F704F18EC478287964C92B6931F4DCEF6250CEE631DC7217BB9BCEDF38B29FBFE1E62C4461F3B4FB0DD872C3D7B1AF59DF757564EFFEADFBCD4529760A9B8F277E31BAF8F986BB5C5298ECF5E0760977111396ACB3782D2F6D91B6059160F28A667B6BD61ABDCFBDA374930FFF31A2620DF9AA6BFE8C2C27E78A8423FDD0DBDAF6D3E52EC80E345D5D64D5F6B20BD8D12E13D415788B69868EBA41360E1C88A25BE04B7E0182284276EC4E3BF2CE45C373C2E43C6B575C2A579209FEAEA885E20C11471DD884942266B9E3847B8839FC2A79F8F1594ADD8A10ABAC9C7881B2CF99D762B5E2E7A0BC52B741F0C37
+20210510041442 2 6 100 2047 5 C7CE688A891B095F8844E2381248DFAE8FA10F704F18EC478287964C92B6931F4DCEF6250CEE631DC7217BB9BCEDF38B29FBFE1E62C4461F3B4FB0DD872C3D7B1AF59DF757564EFFEADFBCD4529760A9B8F277E31BAF8F986BB5C5298ECF5E0760977111396ACB3782D2F6D91B6059160F28A667B6BD61ABDCFBDA374930FFF31A2620DF9AA6BFE8C2C27E78A8423FDD0DBDAF6D3E52EC80E345D5D64D5F6B20BD8D12E13D415788B69868EBA41360E1C88A25BE04B7E0182284276EC4E3BF2CE45C373C2E43C6B575C2A579209FEAEA885E20C11471DD884942266B9E3847B8839FC2A79F8F1594ADD8A10ABAC9C7881B2CF99D762B5E2E7A0BC52B743B9717
+20210510041457 2 6 100 2047 2 C7CE688A891B095F8844E2381248DFAE8FA10F704F18EC478287964C92B6931F4DCEF6250CEE631DC7217BB9BCEDF38B29FBFE1E62C4461F3B4FB0DD872C3D7B1AF59DF757564EFFEADFBCD4529760A9B8F277E31BAF8F986BB5C5298ECF5E0760977111396ACB3782D2F6D91B6059160F28A667B6BD61ABDCFBDA374930FFF31A2620DF9AA6BFE8C2C27E78A8423FDD0DBDAF6D3E52EC80E345D5D64D5F6B20BD8D12E13D415788B69868EBA41360E1C88A25BE04B7E0182284276EC4E3BF2CE45C373C2E43C6B575C2A579209FEAEA885E20C11471DD884942266B9E3847B8839FC2A79F8F1594ADD8A10ABAC9C7881B2CF99D762B5E2E7A0BC52B74537023
+20210510041516 2 6 100 2047 2 C7CE688A891B095F8844E2381248DFAE8FA10F704F18EC478287964C92B6931F4DCEF6250CEE631DC7217BB9BCEDF38B29FBFE1E62C4461F3B4FB0DD872C3D7B1AF59DF757564EFFEADFBCD4529760A9B8F277E31BAF8F986BB5C5298ECF5E0760977111396ACB3782D2F6D91B6059160F28A667B6BD61ABDCFBDA374930FFF31A2620DF9AA6BFE8C2C27E78A8423FDD0DBDAF6D3E52EC80E345D5D64D5F6B20BD8D12E13D415788B69868EBA41360E1C88A25BE04B7E0182284276EC4E3BF2CE45C373C2E43C6B575C2A579209FEAEA885E20C11471DD884942266B9E3847B8839FC2A79F8F1594ADD8A10ABAC9C7881B2CF99D762B5E2E7A0BC52B74718223
+20210510041554 2 6 100 2047 5 C7CE688A891B095F8844E2381248DFAE8FA10F704F18EC478287964C92B6931F4DCEF6250CEE631DC7217BB9BCEDF38B29FBFE1E62C4461F3B4FB0DD872C3D7B1AF59DF757564EFFEADFBCD4529760A9B8F277E31BAF8F986BB5C5298ECF5E0760977111396ACB3782D2F6D91B6059160F28A667B6BD61ABDCFBDA374930FFF31A2620DF9AA6BFE8C2C27E78A8423FDD0DBDAF6D3E52EC80E345D5D64D5F6B20BD8D12E13D415788B69868EBA41360E1C88A25BE04B7E0182284276EC4E3BF2CE45C373C2E43C6B575C2A579209FEAEA885E20C11471DD884942266B9E3847B8839FC2A79F8F1594ADD8A10ABAC9C7881B2CF99D762B5E2E7A0BC52B74B62DE7
+20210510041603 2 6 100 2047 2 C7CE688A891B095F8844E2381248DFAE8FA10F704F18EC478287964C92B6931F4DCEF6250CEE631DC7217BB9BCEDF38B29FBFE1E62C4461F3B4FB0DD872C3D7B1AF59DF757564EFFEADFBCD4529760A9B8F277E31BAF8F986BB5C5298ECF5E0760977111396ACB3782D2F6D91B6059160F28A667B6BD61ABDCFBDA374930FFF31A2620DF9AA6BFE8C2C27E78A8423FDD0DBDAF6D3E52EC80E345D5D64D5F6B20BD8D12E13D415788B69868EBA41360E1C88A25BE04B7E0182284276EC4E3BF2CE45C373C2E43C6B575C2A579209FEAEA885E20C11471DD884942266B9E3847B8839FC2A79F8F1594ADD8A10ABAC9C7881B2CF99D762B5E2E7A0BC52B74BF7D13
+20210510041611 2 6 100 2047 5 C7CE688A891B095F8844E2381248DFAE8FA10F704F18EC478287964C92B6931F4DCEF6250CEE631DC7217BB9BCEDF38B29FBFE1E62C4461F3B4FB0DD872C3D7B1AF59DF757564EFFEADFBCD4529760A9B8F277E31BAF8F986BB5C5298ECF5E0760977111396ACB3782D2F6D91B6059160F28A667B6BD61ABDCFBDA374930FFF31A2620DF9AA6BFE8C2C27E78A8423FDD0DBDAF6D3E52EC80E345D5D64D5F6B20BD8D12E13D415788B69868EBA41360E1C88A25BE04B7E0182284276EC4E3BF2CE45C373C2E43C6B575C2A579209FEAEA885E20C11471DD884942266B9E3847B8839FC2A79F8F1594ADD8A10ABAC9C7881B2CF99D762B5E2E7A0BC52B74C76FC7
+20210510041709 2 6 100 2047 2 C7CE688A891B095F8844E2381248DFAE8FA10F704F18EC478287964C92B6931F4DCEF6250CEE631DC7217BB9BCEDF38B29FBFE1E62C4461F3B4FB0DD872C3D7B1AF59DF757564EFFEADFBCD4529760A9B8F277E31BAF8F986BB5C5298ECF5E0760977111396ACB3782D2F6D91B6059160F28A667B6BD61ABDCFBDA374930FFF31A2620DF9AA6BFE8C2C27E78A8423FDD0DBDAF6D3E52EC80E345D5D64D5F6B20BD8D12E13D415788B69868EBA41360E1C88A25BE04B7E0182284276EC4E3BF2CE45C373C2E43C6B575C2A579209FEAEA885E20C11471DD884942266B9E3847B8839FC2A79F8F1594ADD8A10ABAC9C7881B2CF99D762B5E2E7A0BC52B7534B763
+20210510041738 2 6 100 2047 2 C7CE688A891B095F8844E2381248DFAE8FA10F704F18EC478287964C92B6931F4DCEF6250CEE631DC7217BB9BCEDF38B29FBFE1E62C4461F3B4FB0DD872C3D7B1AF59DF757564EFFEADFBCD4529760A9B8F277E31BAF8F986BB5C5298ECF5E0760977111396ACB3782D2F6D91B6059160F28A667B6BD61ABDCFBDA374930FFF31A2620DF9AA6BFE8C2C27E78A8423FDD0DBDAF6D3E52EC80E345D5D64D5F6B20BD8D12E13D415788B69868EBA41360E1C88A25BE04B7E0182284276EC4E3BF2CE45C373C2E43C6B575C2A579209FEAEA885E20C11471DD884942266B9E3847B8839FC2A79F8F1594ADD8A10ABAC9C7881B2CF99D762B5E2E7A0BC52B75649FDB
+20210510041815 2 6 100 2047 2 C7CE688A891B095F8844E2381248DFAE8FA10F704F18EC478287964C92B6931F4DCEF6250CEE631DC7217BB9BCEDF38B29FBFE1E62C4461F3B4FB0DD872C3D7B1AF59DF757564EFFEADFBCD4529760A9B8F277E31BAF8F986BB5C5298ECF5E0760977111396ACB3782D2F6D91B6059160F28A667B6BD61ABDCFBDA374930FFF31A2620DF9AA6BFE8C2C27E78A8423FDD0DBDAF6D3E52EC80E345D5D64D5F6B20BD8D12E13D415788B69868EBA41360E1C88A25BE04B7E0182284276EC4E3BF2CE45C373C2E43C6B575C2A579209FEAEA885E20C11471DD884942266B9E3847B8839FC2A79F8F1594ADD8A10ABAC9C7881B2CF99D762B5E2E7A0BC52B75A664CB
+20210510041822 2 6 100 2047 5 C7CE688A891B095F8844E2381248DFAE8FA10F704F18EC478287964C92B6931F4DCEF6250CEE631DC7217BB9BCEDF38B29FBFE1E62C4461F3B4FB0DD872C3D7B1AF59DF757564EFFEADFBCD4529760A9B8F277E31BAF8F986BB5C5298ECF5E0760977111396ACB3782D2F6D91B6059160F28A667B6BD61ABDCFBDA374930FFF31A2620DF9AA6BFE8C2C27E78A8423FDD0DBDAF6D3E52EC80E345D5D64D5F6B20BD8D12E13D415788B69868EBA41360E1C88A25BE04B7E0182284276EC4E3BF2CE45C373C2E43C6B575C2A579209FEAEA885E20C11471DD884942266B9E3847B8839FC2A79F8F1594ADD8A10ABAC9C7881B2CF99D762B5E2E7A0BC52B75AAA067
+20210510041829 2 6 100 2047 2 C7CE688A891B095F8844E2381248DFAE8FA10F704F18EC478287964C92B6931F4DCEF6250CEE631DC7217BB9BCEDF38B29FBFE1E62C4461F3B4FB0DD872C3D7B1AF59DF757564EFFEADFBCD4529760A9B8F277E31BAF8F986BB5C5298ECF5E0760977111396ACB3782D2F6D91B6059160F28A667B6BD61ABDCFBDA374930FFF31A2620DF9AA6BFE8C2C27E78A8423FDD0DBDAF6D3E52EC80E345D5D64D5F6B20BD8D12E13D415788B69868EBA41360E1C88A25BE04B7E0182284276EC4E3BF2CE45C373C2E43C6B575C2A579209FEAEA885E20C11471DD884942266B9E3847B8839FC2A79F8F1594ADD8A10ABAC9C7881B2CF99D762B5E2E7A0BC52B75B05003
+20210510041939 2 6 100 2047 2 C7CE688A891B095F8844E2381248DFAE8FA10F704F18EC478287964C92B6931F4DCEF6250CEE631DC7217BB9BCEDF38B29FBFE1E62C4461F3B4FB0DD872C3D7B1AF59DF757564EFFEADFBCD4529760A9B8F277E31BAF8F986BB5C5298ECF5E0760977111396ACB3782D2F6D91B6059160F28A667B6BD61ABDCFBDA374930FFF31A2620DF9AA6BFE8C2C27E78A8423FDD0DBDAF6D3E52EC80E345D5D64D5F6B20BD8D12E13D415788B69868EBA41360E1C88A25BE04B7E0182284276EC4E3BF2CE45C373C2E43C6B575C2A579209FEAEA885E20C11471DD884942266B9E3847B8839FC2A79F8F1594ADD8A10ABAC9C7881B2CF99D762B5E2E7A0BC52B76327F4B
+20210510042001 2 6 100 2047 5 C7CE688A891B095F8844E2381248DFAE8FA10F704F18EC478287964C92B6931F4DCEF6250CEE631DC7217BB9BCEDF38B29FBFE1E62C4461F3B4FB0DD872C3D7B1AF59DF757564EFFEADFBCD4529760A9B8F277E31BAF8F986BB5C5298ECF5E0760977111396ACB3782D2F6D91B6059160F28A667B6BD61ABDCFBDA374930FFF31A2620DF9AA6BFE8C2C27E78A8423FDD0DBDAF6D3E52EC80E345D5D64D5F6B20BD8D12E13D415788B69868EBA41360E1C88A25BE04B7E0182284276EC4E3BF2CE45C373C2E43C6B575C2A579209FEAEA885E20C11471DD884942266B9E3847B8839FC2A79F8F1594ADD8A10ABAC9C7881B2CF99D762B5E2E7A0BC52B7657FF9F
+20210510042024 2 6 100 2047 5 C7CE688A891B095F8844E2381248DFAE8FA10F704F18EC478287964C92B6931F4DCEF6250CEE631DC7217BB9BCEDF38B29FBFE1E62C4461F3B4FB0DD872C3D7B1AF59DF757564EFFEADFBCD4529760A9B8F277E31BAF8F986BB5C5298ECF5E0760977111396ACB3782D2F6D91B6059160F28A667B6BD61ABDCFBDA374930FFF31A2620DF9AA6BFE8C2C27E78A8423FDD0DBDAF6D3E52EC80E345D5D64D5F6B20BD8D12E13D415788B69868EBA41360E1C88A25BE04B7E0182284276EC4E3BF2CE45C373C2E43C6B575C2A579209FEAEA885E20C11471DD884942266B9E3847B8839FC2A79F8F1594ADD8A10ABAC9C7881B2CF99D762B5E2E7A0BC52B767BF81F
+20210510042108 2 6 100 2047 2 C7CE688A891B095F8844E2381248DFAE8FA10F704F18EC478287964C92B6931F4DCEF6250CEE631DC7217BB9BCEDF38B29FBFE1E62C4461F3B4FB0DD872C3D7B1AF59DF757564EFFEADFBCD4529760A9B8F277E31BAF8F986BB5C5298ECF5E0760977111396ACB3782D2F6D91B6059160F28A667B6BD61ABDCFBDA374930FFF31A2620DF9AA6BFE8C2C27E78A8423FDD0DBDAF6D3E52EC80E345D5D64D5F6B20BD8D12E13D415788B69868EBA41360E1C88A25BE04B7E0182284276EC4E3BF2CE45C373C2E43C6B575C2A579209FEAEA885E20C11471DD884942266B9E3847B8839FC2A79F8F1594ADD8A10ABAC9C7881B2CF99D762B5E2E7A0BC52B76CC8253
+20210510042208 2 6 100 2047 2 C7CE688A891B095F8844E2381248DFAE8FA10F704F18EC478287964C92B6931F4DCEF6250CEE631DC7217BB9BCEDF38B29FBFE1E62C4461F3B4FB0DD872C3D7B1AF59DF757564EFFEADFBCD4529760A9B8F277E31BAF8F986BB5C5298ECF5E0760977111396ACB3782D2F6D91B6059160F28A667B6BD61ABDCFBDA374930FFF31A2620DF9AA6BFE8C2C27E78A8423FDD0DBDAF6D3E52EC80E345D5D64D5F6B20BD8D12E13D415788B69868EBA41360E1C88A25BE04B7E0182284276EC4E3BF2CE45C373C2E43C6B575C2A579209FEAEA885E20C11471DD884942266B9E3847B8839FC2A79F8F1594ADD8A10ABAC9C7881B2CF99D762B5E2E7A0BC52B773A4483
+20210510042307 2 6 100 2047 5 C9E8F5A2E2CD5EF3BA0F9EEC69453B2B69DC4E7B7A250B773348A24D152ED220DDE0084C99D5F24904BA1D98907FBEB17DC1BA0E347D7B0A370A57CE6AC47D0339B639F4BCD0CF1FF1B10EE95513CF3CF9A912CFBACFBB779B4D696778940E7A0D0B43CADC0908358EA85CF8B1E8E5AAEA96BACFFDA93C9DAF9B717717302BEB039E4A17BBC93CE228E9AA9D35D560B3A6F1C60A7FD610D8449C6C0828464FB8DBD3F328371449BCF34FD693927F63F58047FD190B30EF16B45157C7ABCA21347C12BC652B2A4C5024963400DB5131B67D371691C6C27081C433CA7C158CB99F6E4C89E744EA42018DB79D6FF78BB316B700370B813B81112456D75DB9689F57
+20210510042318 2 6 100 2047 2 C9E8F5A2E2CD5EF3BA0F9EEC69453B2B69DC4E7B7A250B773348A24D152ED220DDE0084C99D5F24904BA1D98907FBEB17DC1BA0E347D7B0A370A57CE6AC47D0339B639F4BCD0CF1FF1B10EE95513CF3CF9A912CFBACFBB779B4D696778940E7A0D0B43CADC0908358EA85CF8B1E8E5AAEA96BACFFDA93C9DAF9B717717302BEB039E4A17BBC93CE228E9AA9D35D560B3A6F1C60A7FD610D8449C6C0828464FB8DBD3F328371449BCF34FD693927F63F58047FD190B30EF16B45157C7ABCA21347C12BC652B2A4C5024963400DB5131B67D371691C6C27081C433CA7C158CB99F6E4C89E744EA42018DB79D6FF78BB316B700370B813B81112456D75DB9759EDB
+20210510042544 2 6 100 2047 2 C9E8F5A2E2CD5EF3BA0F9EEC69453B2B69DC4E7B7A250B773348A24D152ED220DDE0084C99D5F24904BA1D98907FBEB17DC1BA0E347D7B0A370A57CE6AC47D0339B639F4BCD0CF1FF1B10EE95513CF3CF9A912CFBACFBB779B4D696778940E7A0D0B43CADC0908358EA85CF8B1E8E5AAEA96BACFFDA93C9DAF9B717717302BEB039E4A17BBC93CE228E9AA9D35D560B3A6F1C60A7FD610D8449C6C0828464FB8DBD3F328371449BCF34FD693927F63F58047FD190B30EF16B45157C7ABCA21347C12BC652B2A4C5024963400DB5131B67D371691C6C27081C433CA7C158CB99F6E4C89E744EA42018DB79D6FF78BB316B700370B813B81112456D75DBA901DE3
+20210510042605 2 6 100 2047 5 C9E8F5A2E2CD5EF3BA0F9EEC69453B2B69DC4E7B7A250B773348A24D152ED220DDE0084C99D5F24904BA1D98907FBEB17DC1BA0E347D7B0A370A57CE6AC47D0339B639F4BCD0CF1FF1B10EE95513CF3CF9A912CFBACFBB779B4D696778940E7A0D0B43CADC0908358EA85CF8B1E8E5AAEA96BACFFDA93C9DAF9B717717302BEB039E4A17BBC93CE228E9AA9D35D560B3A6F1C60A7FD610D8449C6C0828464FB8DBD3F328371449BCF34FD693927F63F58047FD190B30EF16B45157C7ABCA21347C12BC652B2A4C5024963400DB5131B67D371691C6C27081C433CA7C158CB99F6E4C89E744EA42018DB79D6FF78BB316B700370B813B81112456D75DBAAFDBFF
+20210510042627 2 6 100 2047 2 C9E8F5A2E2CD5EF3BA0F9EEC69453B2B69DC4E7B7A250B773348A24D152ED220DDE0084C99D5F24904BA1D98907FBEB17DC1BA0E347D7B0A370A57CE6AC47D0339B639F4BCD0CF1FF1B10EE95513CF3CF9A912CFBACFBB779B4D696778940E7A0D0B43CADC0908358EA85CF8B1E8E5AAEA96BACFFDA93C9DAF9B717717302BEB039E4A17BBC93CE228E9AA9D35D560B3A6F1C60A7FD610D8449C6C0828464FB8DBD3F328371449BCF34FD693927F63F58047FD190B30EF16B45157C7ABCA21347C12BC652B2A4C5024963400DB5131B67D371691C6C27081C433CA7C158CB99F6E4C89E744EA42018DB79D6FF78BB316B700370B813B81112456D75DBAD1CA43
+20210510042651 2 6 100 2047 2 C9E8F5A2E2CD5EF3BA0F9EEC69453B2B69DC4E7B7A250B773348A24D152ED220DDE0084C99D5F24904BA1D98907FBEB17DC1BA0E347D7B0A370A57CE6AC47D0339B639F4BCD0CF1FF1B10EE95513CF3CF9A912CFBACFBB779B4D696778940E7A0D0B43CADC0908358EA85CF8B1E8E5AAEA96BACFFDA93C9DAF9B717717302BEB039E4A17BBC93CE228E9AA9D35D560B3A6F1C60A7FD610D8449C6C0828464FB8DBD3F328371449BCF34FD693927F63F58047FD190B30EF16B45157C7ABCA21347C12BC652B2A4C5024963400DB5131B67D371691C6C27081C433CA7C158CB99F6E4C89E744EA42018DB79D6FF78BB316B700370B813B81112456D75DBAF89D2B
+20210510042714 2 6 100 2047 5 C9E8F5A2E2CD5EF3BA0F9EEC69453B2B69DC4E7B7A250B773348A24D152ED220DDE0084C99D5F24904BA1D98907FBEB17DC1BA0E347D7B0A370A57CE6AC47D0339B639F4BCD0CF1FF1B10EE95513CF3CF9A912CFBACFBB779B4D696778940E7A0D0B43CADC0908358EA85CF8B1E8E5AAEA96BACFFDA93C9DAF9B717717302BEB039E4A17BBC93CE228E9AA9D35D560B3A6F1C60A7FD610D8449C6C0828464FB8DBD3F328371449BCF34FD693927F63F58047FD190B30EF16B45157C7ABCA21347C12BC652B2A4C5024963400DB5131B67D371691C6C27081C433CA7C158CB99F6E4C89E744EA42018DB79D6FF78BB316B700370B813B81112456D75DBB1B9777
+20210510042739 2 6 100 2047 5 C9E8F5A2E2CD5EF3BA0F9EEC69453B2B69DC4E7B7A250B773348A24D152ED220DDE0084C99D5F24904BA1D98907FBEB17DC1BA0E347D7B0A370A57CE6AC47D0339B639F4BCD0CF1FF1B10EE95513CF3CF9A912CFBACFBB779B4D696778940E7A0D0B43CADC0908358EA85CF8B1E8E5AAEA96BACFFDA93C9DAF9B717717302BEB039E4A17BBC93CE228E9AA9D35D560B3A6F1C60A7FD610D8449C6C0828464FB8DBD3F328371449BCF34FD693927F63F58047FD190B30EF16B45157C7ABCA21347C12BC652B2A4C5024963400DB5131B67D371691C6C27081C433CA7C158CB99F6E4C89E744EA42018DB79D6FF78BB316B700370B813B81112456D75DBB467097
+20210510042750 2 6 100 2047 2 C9E8F5A2E2CD5EF3BA0F9EEC69453B2B69DC4E7B7A250B773348A24D152ED220DDE0084C99D5F24904BA1D98907FBEB17DC1BA0E347D7B0A370A57CE6AC47D0339B639F4BCD0CF1FF1B10EE95513CF3CF9A912CFBACFBB779B4D696778940E7A0D0B43CADC0908358EA85CF8B1E8E5AAEA96BACFFDA93C9DAF9B717717302BEB039E4A17BBC93CE228E9AA9D35D560B3A6F1C60A7FD610D8449C6C0828464FB8DBD3F328371449BCF34FD693927F63F58047FD190B30EF16B45157C7ABCA21347C12BC652B2A4C5024963400DB5131B67D371691C6C27081C433CA7C158CB99F6E4C89E744EA42018DB79D6FF78BB316B700370B813B81112456D75DBB55E393
+20210510042822 2 6 100 2047 5 C9E8F5A2E2CD5EF3BA0F9EEC69453B2B69DC4E7B7A250B773348A24D152ED220DDE0084C99D5F24904BA1D98907FBEB17DC1BA0E347D7B0A370A57CE6AC47D0339B639F4BCD0CF1FF1B10EE95513CF3CF9A912CFBACFBB779B4D696778940E7A0D0B43CADC0908358EA85CF8B1E8E5AAEA96BACFFDA93C9DAF9B717717302BEB039E4A17BBC93CE228E9AA9D35D560B3A6F1C60A7FD610D8449C6C0828464FB8DBD3F328371449BCF34FD693927F63F58047FD190B30EF16B45157C7ABCA21347C12BC652B2A4C5024963400DB5131B67D371691C6C27081C433CA7C158CB99F6E4C89E744EA42018DB79D6FF78BB316B700370B813B81112456D75DBB90099F
+20210510042827 2 6 100 2047 2 C9E8F5A2E2CD5EF3BA0F9EEC69453B2B69DC4E7B7A250B773348A24D152ED220DDE0084C99D5F24904BA1D98907FBEB17DC1BA0E347D7B0A370A57CE6AC47D0339B639F4BCD0CF1FF1B10EE95513CF3CF9A912CFBACFBB779B4D696778940E7A0D0B43CADC0908358EA85CF8B1E8E5AAEA96BACFFDA93C9DAF9B717717302BEB039E4A17BBC93CE228E9AA9D35D560B3A6F1C60A7FD610D8449C6C0828464FB8DBD3F328371449BCF34FD693927F63F58047FD190B30EF16B45157C7ABCA21347C12BC652B2A4C5024963400DB5131B67D371691C6C27081C433CA7C158CB99F6E4C89E744EA42018DB79D6FF78BB316B700370B813B81112456D75DBB9285DB
+20210510042900 2 6 100 2047 2 C9E8F5A2E2CD5EF3BA0F9EEC69453B2B69DC4E7B7A250B773348A24D152ED220DDE0084C99D5F24904BA1D98907FBEB17DC1BA0E347D7B0A370A57CE6AC47D0339B639F4BCD0CF1FF1B10EE95513CF3CF9A912CFBACFBB779B4D696778940E7A0D0B43CADC0908358EA85CF8B1E8E5AAEA96BACFFDA93C9DAF9B717717302BEB039E4A17BBC93CE228E9AA9D35D560B3A6F1C60A7FD610D8449C6C0828464FB8DBD3F328371449BCF34FD693927F63F58047FD190B30EF16B45157C7ABCA21347C12BC652B2A4C5024963400DB5131B67D371691C6C27081C433CA7C158CB99F6E4C89E744EA42018DB79D6FF78BB316B700370B813B81112456D75DBBCC8583
+20210510042912 2 6 100 2047 2 C9E8F5A2E2CD5EF3BA0F9EEC69453B2B69DC4E7B7A250B773348A24D152ED220DDE0084C99D5F24904BA1D98907FBEB17DC1BA0E347D7B0A370A57CE6AC47D0339B639F4BCD0CF1FF1B10EE95513CF3CF9A912CFBACFBB779B4D696778940E7A0D0B43CADC0908358EA85CF8B1E8E5AAEA96BACFFDA93C9DAF9B717717302BEB039E4A17BBC93CE228E9AA9D35D560B3A6F1C60A7FD610D8449C6C0828464FB8DBD3F328371449BCF34FD693927F63F58047FD190B30EF16B45157C7ABCA21347C12BC652B2A4C5024963400DB5131B67D371691C6C27081C433CA7C158CB99F6E4C89E744EA42018DB79D6FF78BB316B700370B813B81112456D75DBBDABFB3
+20210510042934 2 6 100 2047 2 C9E8F5A2E2CD5EF3BA0F9EEC69453B2B69DC4E7B7A250B773348A24D152ED220DDE0084C99D5F24904BA1D98907FBEB17DC1BA0E347D7B0A370A57CE6AC47D0339B639F4BCD0CF1FF1B10EE95513CF3CF9A912CFBACFBB779B4D696778940E7A0D0B43CADC0908358EA85CF8B1E8E5AAEA96BACFFDA93C9DAF9B717717302BEB039E4A17BBC93CE228E9AA9D35D560B3A6F1C60A7FD610D8449C6C0828464FB8DBD3F328371449BCF34FD693927F63F58047FD190B30EF16B45157C7ABCA21347C12BC652B2A4C5024963400DB5131B67D371691C6C27081C433CA7C158CB99F6E4C89E744EA42018DB79D6FF78BB316B700370B813B81112456D75DBBFE3253
+20210510043037 2 6 100 2047 2 C9E8F5A2E2CD5EF3BA0F9EEC69453B2B69DC4E7B7A250B773348A24D152ED220DDE0084C99D5F24904BA1D98907FBEB17DC1BA0E347D7B0A370A57CE6AC47D0339B639F4BCD0CF1FF1B10EE95513CF3CF9A912CFBACFBB779B4D696778940E7A0D0B43CADC0908358EA85CF8B1E8E5AAEA96BACFFDA93C9DAF9B717717302BEB039E4A17BBC93CE228E9AA9D35D560B3A6F1C60A7FD610D8449C6C0828464FB8DBD3F328371449BCF34FD693927F63F58047FD190B30EF16B45157C7ABCA21347C12BC652B2A4C5024963400DB5131B67D371691C6C27081C433CA7C158CB99F6E4C89E744EA42018DB79D6FF78BB316B700370B813B81112456D75DBC711233
+20210510043054 2 6 100 2047 2 C9E8F5A2E2CD5EF3BA0F9EEC69453B2B69DC4E7B7A250B773348A24D152ED220DDE0084C99D5F24904BA1D98907FBEB17DC1BA0E347D7B0A370A57CE6AC47D0339B639F4BCD0CF1FF1B10EE95513CF3CF9A912CFBACFBB779B4D696778940E7A0D0B43CADC0908358EA85CF8B1E8E5AAEA96BACFFDA93C9DAF9B717717302BEB039E4A17BBC93CE228E9AA9D35D560B3A6F1C60A7FD610D8449C6C0828464FB8DBD3F328371449BCF34FD693927F63F58047FD190B30EF16B45157C7ABCA21347C12BC652B2A4C5024963400DB5131B67D371691C6C27081C433CA7C158CB99F6E4C89E744EA42018DB79D6FF78BB316B700370B813B81112456D75DBC8A48CB
+20210510043100 2 6 100 2047 5 C9E8F5A2E2CD5EF3BA0F9EEC69453B2B69DC4E7B7A250B773348A24D152ED220DDE0084C99D5F24904BA1D98907FBEB17DC1BA0E347D7B0A370A57CE6AC47D0339B639F4BCD0CF1FF1B10EE95513CF3CF9A912CFBACFBB779B4D696778940E7A0D0B43CADC0908358EA85CF8B1E8E5AAEA96BACFFDA93C9DAF9B717717302BEB039E4A17BBC93CE228E9AA9D35D560B3A6F1C60A7FD610D8449C6C0828464FB8DBD3F328371449BCF34FD693927F63F58047FD190B30EF16B45157C7ABCA21347C12BC652B2A4C5024963400DB5131B67D371691C6C27081C433CA7C158CB99F6E4C89E744EA42018DB79D6FF78BB316B700370B813B81112456D75DBC8DDC1F
+20210510043115 2 6 100 2047 5 C9E8F5A2E2CD5EF3BA0F9EEC69453B2B69DC4E7B7A250B773348A24D152ED220DDE0084C99D5F24904BA1D98907FBEB17DC1BA0E347D7B0A370A57CE6AC47D0339B639F4BCD0CF1FF1B10EE95513CF3CF9A912CFBACFBB779B4D696778940E7A0D0B43CADC0908358EA85CF8B1E8E5AAEA96BACFFDA93C9DAF9B717717302BEB039E4A17BBC93CE228E9AA9D35D560B3A6F1C60A7FD610D8449C6C0828464FB8DBD3F328371449BCF34FD693927F63F58047FD190B30EF16B45157C7ABCA21347C12BC652B2A4C5024963400DB5131B67D371691C6C27081C433CA7C158CB99F6E4C89E744EA42018DB79D6FF78BB316B700370B813B81112456D75DBCA597AF
+20210510043209 2 6 100 2047 2 C9E8F5A2E2CD5EF3BA0F9EEC69453B2B69DC4E7B7A250B773348A24D152ED220DDE0084C99D5F24904BA1D98907FBEB17DC1BA0E347D7B0A370A57CE6AC47D0339B639F4BCD0CF1FF1B10EE95513CF3CF9A912CFBACFBB779B4D696778940E7A0D0B43CADC0908358EA85CF8B1E8E5AAEA96BACFFDA93C9DAF9B717717302BEB039E4A17BBC93CE228E9AA9D35D560B3A6F1C60A7FD610D8449C6C0828464FB8DBD3F328371449BCF34FD693927F63F58047FD190B30EF16B45157C7ABCA21347C12BC652B2A4C5024963400DB5131B67D371691C6C27081C433CA7C158CB99F6E4C89E744EA42018DB79D6FF78BB316B700370B813B81112456D75DBD076783
+20210510043220 2 6 100 2047 2 C9E8F5A2E2CD5EF3BA0F9EEC69453B2B69DC4E7B7A250B773348A24D152ED220DDE0084C99D5F24904BA1D98907FBEB17DC1BA0E347D7B0A370A57CE6AC47D0339B639F4BCD0CF1FF1B10EE95513CF3CF9A912CFBACFBB779B4D696778940E7A0D0B43CADC0908358EA85CF8B1E8E5AAEA96BACFFDA93C9DAF9B717717302BEB039E4A17BBC93CE228E9AA9D35D560B3A6F1C60A7FD610D8449C6C0828464FB8DBD3F328371449BCF34FD693927F63F58047FD190B30EF16B45157C7ABCA21347C12BC652B2A4C5024963400DB5131B67D371691C6C27081C433CA7C158CB99F6E4C89E744EA42018DB79D6FF78BB316B700370B813B81112456D75DBD14801B
+20210510043228 2 6 100 2047 2 C9E8F5A2E2CD5EF3BA0F9EEC69453B2B69DC4E7B7A250B773348A24D152ED220DDE0084C99D5F24904BA1D98907FBEB17DC1BA0E347D7B0A370A57CE6AC47D0339B639F4BCD0CF1FF1B10EE95513CF3CF9A912CFBACFBB779B4D696778940E7A0D0B43CADC0908358EA85CF8B1E8E5AAEA96BACFFDA93C9DAF9B717717302BEB039E4A17BBC93CE228E9AA9D35D560B3A6F1C60A7FD610D8449C6C0828464FB8DBD3F328371449BCF34FD693927F63F58047FD190B30EF16B45157C7ABCA21347C12BC652B2A4C5024963400DB5131B67D371691C6C27081C433CA7C158CB99F6E4C89E744EA42018DB79D6FF78BB316B700370B813B81112456D75DBD1D92AB
+20210510043239 2 6 100 2047 2 C9E8F5A2E2CD5EF3BA0F9EEC69453B2B69DC4E7B7A250B773348A24D152ED220DDE0084C99D5F24904BA1D98907FBEB17DC1BA0E347D7B0A370A57CE6AC47D0339B639F4BCD0CF1FF1B10EE95513CF3CF9A912CFBACFBB779B4D696778940E7A0D0B43CADC0908358EA85CF8B1E8E5AAEA96BACFFDA93C9DAF9B717717302BEB039E4A17BBC93CE228E9AA9D35D560B3A6F1C60A7FD610D8449C6C0828464FB8DBD3F328371449BCF34FD693927F63F58047FD190B30EF16B45157C7ABCA21347C12BC652B2A4C5024963400DB5131B67D371691C6C27081C433CA7C158CB99F6E4C89E744EA42018DB79D6FF78BB316B700370B813B81112456D75DBD28D563
+20210510043253 2 6 100 2047 2 C9E8F5A2E2CD5EF3BA0F9EEC69453B2B69DC4E7B7A250B773348A24D152ED220DDE0084C99D5F24904BA1D98907FBEB17DC1BA0E347D7B0A370A57CE6AC47D0339B639F4BCD0CF1FF1B10EE95513CF3CF9A912CFBACFBB779B4D696778940E7A0D0B43CADC0908358EA85CF8B1E8E5AAEA96BACFFDA93C9DAF9B717717302BEB039E4A17BBC93CE228E9AA9D35D560B3A6F1C60A7FD610D8449C6C0828464FB8DBD3F328371449BCF34FD693927F63F58047FD190B30EF16B45157C7ABCA21347C12BC652B2A4C5024963400DB5131B67D371691C6C27081C433CA7C158CB99F6E4C89E744EA42018DB79D6FF78BB316B700370B813B81112456D75DBD3BDADB
+20210510043313 2 6 100 2047 2 C9E8F5A2E2CD5EF3BA0F9EEC69453B2B69DC4E7B7A250B773348A24D152ED220DDE0084C99D5F24904BA1D98907FBEB17DC1BA0E347D7B0A370A57CE6AC47D0339B639F4BCD0CF1FF1B10EE95513CF3CF9A912CFBACFBB779B4D696778940E7A0D0B43CADC0908358EA85CF8B1E8E5AAEA96BACFFDA93C9DAF9B717717302BEB039E4A17BBC93CE228E9AA9D35D560B3A6F1C60A7FD610D8449C6C0828464FB8DBD3F328371449BCF34FD693927F63F58047FD190B30EF16B45157C7ABCA21347C12BC652B2A4C5024963400DB5131B67D371691C6C27081C433CA7C158CB99F6E4C89E744EA42018DB79D6FF78BB316B700370B813B81112456D75DBD5D71B3
+20210510043347 2 6 100 2047 2 C9E8F5A2E2CD5EF3BA0F9EEC69453B2B69DC4E7B7A250B773348A24D152ED220DDE0084C99D5F24904BA1D98907FBEB17DC1BA0E347D7B0A370A57CE6AC47D0339B639F4BCD0CF1FF1B10EE95513CF3CF9A912CFBACFBB779B4D696778940E7A0D0B43CADC0908358EA85CF8B1E8E5AAEA96BACFFDA93C9DAF9B717717302BEB039E4A17BBC93CE228E9AA9D35D560B3A6F1C60A7FD610D8449C6C0828464FB8DBD3F328371449BCF34FD693927F63F58047FD190B30EF16B45157C7ABCA21347C12BC652B2A4C5024963400DB5131B67D371691C6C27081C433CA7C158CB99F6E4C89E744EA42018DB79D6FF78BB316B700370B813B81112456D75DBD9B7913
+20210510043419 2 6 100 2047 5 C9E8F5A2E2CD5EF3BA0F9EEC69453B2B69DC4E7B7A250B773348A24D152ED220DDE0084C99D5F24904BA1D98907FBEB17DC1BA0E347D7B0A370A57CE6AC47D0339B639F4BCD0CF1FF1B10EE95513CF3CF9A912CFBACFBB779B4D696778940E7A0D0B43CADC0908358EA85CF8B1E8E5AAEA96BACFFDA93C9DAF9B717717302BEB039E4A17BBC93CE228E9AA9D35D560B3A6F1C60A7FD610D8449C6C0828464FB8DBD3F328371449BCF34FD693927F63F58047FD190B30EF16B45157C7ABCA21347C12BC652B2A4C5024963400DB5131B67D371691C6C27081C433CA7C158CB99F6E4C89E744EA42018DB79D6FF78BB316B700370B813B81112456D75DBDD144B7
+20210510043448 2 6 100 2047 2 C9E8F5A2E2CD5EF3BA0F9EEC69453B2B69DC4E7B7A250B773348A24D152ED220DDE0084C99D5F24904BA1D98907FBEB17DC1BA0E347D7B0A370A57CE6AC47D0339B639F4BCD0CF1FF1B10EE95513CF3CF9A912CFBACFBB779B4D696778940E7A0D0B43CADC0908358EA85CF8B1E8E5AAEA96BACFFDA93C9DAF9B717717302BEB039E4A17BBC93CE228E9AA9D35D560B3A6F1C60A7FD610D8449C6C0828464FB8DBD3F328371449BCF34FD693927F63F58047FD190B30EF16B45157C7ABCA21347C12BC652B2A4C5024963400DB5131B67D371691C6C27081C433CA7C158CB99F6E4C89E744EA42018DB79D6FF78BB316B700370B813B81112456D75DBE03F6C3
+20210510043524 2 6 100 2047 5 C9E8F5A2E2CD5EF3BA0F9EEC69453B2B69DC4E7B7A250B773348A24D152ED220DDE0084C99D5F24904BA1D98907FBEB17DC1BA0E347D7B0A370A57CE6AC47D0339B639F4BCD0CF1FF1B10EE95513CF3CF9A912CFBACFBB779B4D696778940E7A0D0B43CADC0908358EA85CF8B1E8E5AAEA96BACFFDA93C9DAF9B717717302BEB039E4A17BBC93CE228E9AA9D35D560B3A6F1C60A7FD610D8449C6C0828464FB8DBD3F328371449BCF34FD693927F63F58047FD190B30EF16B45157C7ABCA21347C12BC652B2A4C5024963400DB5131B67D371691C6C27081C433CA7C158CB99F6E4C89E744EA42018DB79D6FF78BB316B700370B813B81112456D75DBE40DB47
+20210510043553 2 6 100 2047 5 C9E8F5A2E2CD5EF3BA0F9EEC69453B2B69DC4E7B7A250B773348A24D152ED220DDE0084C99D5F24904BA1D98907FBEB17DC1BA0E347D7B0A370A57CE6AC47D0339B639F4BCD0CF1FF1B10EE95513CF3CF9A912CFBACFBB779B4D696778940E7A0D0B43CADC0908358EA85CF8B1E8E5AAEA96BACFFDA93C9DAF9B717717302BEB039E4A17BBC93CE228E9AA9D35D560B3A6F1C60A7FD610D8449C6C0828464FB8DBD3F328371449BCF34FD693927F63F58047FD190B30EF16B45157C7ABCA21347C12BC652B2A4C5024963400DB5131B67D371691C6C27081C433CA7C158CB99F6E4C89E744EA42018DB79D6FF78BB316B700370B813B81112456D75DBE70EA8F
+20210510043611 2 6 100 2047 2 C9E8F5A2E2CD5EF3BA0F9EEC69453B2B69DC4E7B7A250B773348A24D152ED220DDE0084C99D5F24904BA1D98907FBEB17DC1BA0E347D7B0A370A57CE6AC47D0339B639F4BCD0CF1FF1B10EE95513CF3CF9A912CFBACFBB779B4D696778940E7A0D0B43CADC0908358EA85CF8B1E8E5AAEA96BACFFDA93C9DAF9B717717302BEB039E4A17BBC93CE228E9AA9D35D560B3A6F1C60A7FD610D8449C6C0828464FB8DBD3F328371449BCF34FD693927F63F58047FD190B30EF16B45157C7ABCA21347C12BC652B2A4C5024963400DB5131B67D371691C6C27081C433CA7C158CB99F6E4C89E744EA42018DB79D6FF78BB316B700370B813B81112456D75DBE8DE163
+20210510043637 2 6 100 2047 5 C9E8F5A2E2CD5EF3BA0F9EEC69453B2B69DC4E7B7A250B773348A24D152ED220DDE0084C99D5F24904BA1D98907FBEB17DC1BA0E347D7B0A370A57CE6AC47D0339B639F4BCD0CF1FF1B10EE95513CF3CF9A912CFBACFBB779B4D696778940E7A0D0B43CADC0908358EA85CF8B1E8E5AAEA96BACFFDA93C9DAF9B717717302BEB039E4A17BBC93CE228E9AA9D35D560B3A6F1C60A7FD610D8449C6C0828464FB8DBD3F328371449BCF34FD693927F63F58047FD190B30EF16B45157C7ABCA21347C12BC652B2A4C5024963400DB5131B67D371691C6C27081C433CA7C158CB99F6E4C89E744EA42018DB79D6FF78BB316B700370B813B81112456D75DBEB894F7
+20210510043702 2 6 100 2047 2 C9E8F5A2E2CD5EF3BA0F9EEC69453B2B69DC4E7B7A250B773348A24D152ED220DDE0084C99D5F24904BA1D98907FBEB17DC1BA0E347D7B0A370A57CE6AC47D0339B639F4BCD0CF1FF1B10EE95513CF3CF9A912CFBACFBB779B4D696778940E7A0D0B43CADC0908358EA85CF8B1E8E5AAEA96BACFFDA93C9DAF9B717717302BEB039E4A17BBC93CE228E9AA9D35D560B3A6F1C60A7FD610D8449C6C0828464FB8DBD3F328371449BCF34FD693927F63F58047FD190B30EF16B45157C7ABCA21347C12BC652B2A4C5024963400DB5131B67D371691C6C27081C433CA7C158CB99F6E4C89E744EA42018DB79D6FF78BB316B700370B813B81112456D75DBEE0932B
+20210510043916 2 6 100 2047 2 C9E8F5A2E2CD5EF3BA0F9EEC69453B2B69DC4E7B7A250B773348A24D152ED220DDE0084C99D5F24904BA1D98907FBEB17DC1BA0E347D7B0A370A57CE6AC47D0339B639F4BCD0CF1FF1B10EE95513CF3CF9A912CFBACFBB779B4D696778940E7A0D0B43CADC0908358EA85CF8B1E8E5AAEA96BACFFDA93C9DAF9B717717302BEB039E4A17BBC93CE228E9AA9D35D560B3A6F1C60A7FD610D8449C6C0828464FB8DBD3F328371449BCF34FD693927F63F58047FD190B30EF16B45157C7ABCA21347C12BC652B2A4C5024963400DB5131B67D371691C6C27081C433CA7C158CB99F6E4C89E744EA42018DB79D6FF78BB316B700370B813B81112456D75DBFDE81CB
+20210510043947 2 6 100 2047 5 C9E8F5A2E2CD5EF3BA0F9EEC69453B2B69DC4E7B7A250B773348A24D152ED220DDE0084C99D5F24904BA1D98907FBEB17DC1BA0E347D7B0A370A57CE6AC47D0339B639F4BCD0CF1FF1B10EE95513CF3CF9A912CFBACFBB779B4D696778940E7A0D0B43CADC0908358EA85CF8B1E8E5AAEA96BACFFDA93C9DAF9B717717302BEB039E4A17BBC93CE228E9AA9D35D560B3A6F1C60A7FD610D8449C6C0828464FB8DBD3F328371449BCF34FD693927F63F58047FD190B30EF16B45157C7ABCA21347C12BC652B2A4C5024963400DB5131B67D371691C6C27081C433CA7C158CB99F6E4C89E744EA42018DB79D6FF78BB316B700370B813B81112456D75DC015B74F
+20210510044005 2 6 100 2047 2 C9E8F5A2E2CD5EF3BA0F9EEC69453B2B69DC4E7B7A250B773348A24D152ED220DDE0084C99D5F24904BA1D98907FBEB17DC1BA0E347D7B0A370A57CE6AC47D0339B639F4BCD0CF1FF1B10EE95513CF3CF9A912CFBACFBB779B4D696778940E7A0D0B43CADC0908358EA85CF8B1E8E5AAEA96BACFFDA93C9DAF9B717717302BEB039E4A17BBC93CE228E9AA9D35D560B3A6F1C60A7FD610D8449C6C0828464FB8DBD3F328371449BCF34FD693927F63F58047FD190B30EF16B45157C7ABCA21347C12BC652B2A4C5024963400DB5131B67D371691C6C27081C433CA7C158CB99F6E4C89E744EA42018DB79D6FF78BB316B700370B813B81112456D75DC02F7D33
+20210510044107 2 6 100 2047 2 C9E8F5A2E2CD5EF3BA0F9EEC69453B2B69DC4E7B7A250B773348A24D152ED220DDE0084C99D5F24904BA1D98907FBEB17DC1BA0E347D7B0A370A57CE6AC47D0339B639F4BCD0CF1FF1B10EE95513CF3CF9A912CFBACFBB779B4D696778940E7A0D0B43CADC0908358EA85CF8B1E8E5AAEA96BACFFDA93C9DAF9B717717302BEB039E4A17BBC93CE228E9AA9D35D560B3A6F1C60A7FD610D8449C6C0828464FB8DBD3F328371449BCF34FD693927F63F58047FD190B30EF16B45157C7ABCA21347C12BC652B2A4C5024963400DB5131B67D371691C6C27081C433CA7C158CB99F6E4C89E744EA42018DB79D6FF78BB316B700370B813B81112456D75DC0A0FCAB
+20210510044154 2 6 100 2047 2 C9E8F5A2E2CD5EF3BA0F9EEC69453B2B69DC4E7B7A250B773348A24D152ED220DDE0084C99D5F24904BA1D98907FBEB17DC1BA0E347D7B0A370A57CE6AC47D0339B639F4BCD0CF1FF1B10EE95513CF3CF9A912CFBACFBB779B4D696778940E7A0D0B43CADC0908358EA85CF8B1E8E5AAEA96BACFFDA93C9DAF9B717717302BEB039E4A17BBC93CE228E9AA9D35D560B3A6F1C60A7FD610D8449C6C0828464FB8DBD3F328371449BCF34FD693927F63F58047FD190B30EF16B45157C7ABCA21347C12BC652B2A4C5024963400DB5131B67D371691C6C27081C433CA7C158CB99F6E4C89E744EA42018DB79D6FF78BB316B700370B813B81112456D75DC0F49F4B
+20210510053053 2 6 100 3071 5 EAC054F0A6595901FCD8F7F8FCC4BA738ED1B3A5EBCBA6F7616CAF48A071E1407283441719C3FE1C10D43799F3BF87492ABDBF0F3B0662504AE552C6B670DB5F75553BAEE273BEFA160C918C0C1039AAB3BC058505CA05328B198C797296B70B2F5F73BAB292EDE06955F59541F73EF820DC7F4BFD4DE54C99F16A798266472540D8819F43ED29390271A2A57785AAD3B8BC142D7F3C5A179D6E4DE94C37DC0D278807119989836DA3A8DB918A2786D41753F774F5760095306B15AF307D86E6A9681950F2510C3FB3FC39820F216EA08689D085A89434CF3D98EB5ABFFCEDCBD0E6AAFE9C9BE072814730678B9082B5B62CA113D9243C83199C940D18D748D64B929A94F68268C8D5B976A32041580B2BFFD5D5FE21A338F65FB1FC494416BA804A920AEF90353F4924D30183908D2C56ECBDC381446CB0F8F4162B3F9C050FF4B226EBFC86D7DEFFB20445255A836762B18183E9F932B8775C21CBECB9C31B64A855FF4D1B5B77E6EDBC31776FD0AD5C23E53603074C118F6936C86B3A3D47
+20210510053442 2 6 100 3071 2 EAC054F0A6595901FCD8F7F8FCC4BA738ED1B3A5EBCBA6F7616CAF48A071E1407283441719C3FE1C10D43799F3BF87492ABDBF0F3B0662504AE552C6B670DB5F75553BAEE273BEFA160C918C0C1039AAB3BC058505CA05328B198C797296B70B2F5F73BAB292EDE06955F59541F73EF820DC7F4BFD4DE54C99F16A798266472540D8819F43ED29390271A2A57785AAD3B8BC142D7F3C5A179D6E4DE94C37DC0D278807119989836DA3A8DB918A2786D41753F774F5760095306B15AF307D86E6A9681950F2510C3FB3FC39820F216EA08689D085A89434CF3D98EB5ABFFCEDCBD0E6AAFE9C9BE072814730678B9082B5B62CA113D9243C83199C940D18D748D64B929A94F68268C8D5B976A32041580B2BFFD5D5FE21A338F65FB1FC494416BA804A920AEF90353F4924D30183908D2C56ECBDC381446CB0F8F4162B3F9C050FF4B226EBFC86D7DEFFB20445255A836762B18183E9F932B8775C21CBECB9C31B64A855FF4D1B5B77E6EDBC31776FD0AD5C23E53603074C118F6936C86BCD69AB
+20210510053741 2 6 100 3071 2 EAC054F0A6595901FCD8F7F8FCC4BA738ED1B3A5EBCBA6F7616CAF48A071E1407283441719C3FE1C10D43799F3BF87492ABDBF0F3B0662504AE552C6B670DB5F75553BAEE273BEFA160C918C0C1039AAB3BC058505CA05328B198C797296B70B2F5F73BAB292EDE06955F59541F73EF820DC7F4BFD4DE54C99F16A798266472540D8819F43ED29390271A2A57785AAD3B8BC142D7F3C5A179D6E4DE94C37DC0D278807119989836DA3A8DB918A2786D41753F774F5760095306B15AF307D86E6A9681950F2510C3FB3FC39820F216EA08689D085A89434CF3D98EB5ABFFCEDCBD0E6AAFE9C9BE072814730678B9082B5B62CA113D9243C83199C940D18D748D64B929A94F68268C8D5B976A32041580B2BFFD5D5FE21A338F65FB1FC494416BA804A920AEF90353F4924D30183908D2C56ECBDC381446CB0F8F4162B3F9C050FF4B226EBFC86D7DEFFB20445255A836762B18183E9F932B8775C21CBECB9C31B64A855FF4D1B5B77E6EDBC31776FD0AD5C23E53603074C118F6936C86C3A162B
+20210510054118 2 6 100 3071 5 EAC054F0A6595901FCD8F7F8FCC4BA738ED1B3A5EBCBA6F7616CAF48A071E1407283441719C3FE1C10D43799F3BF87492ABDBF0F3B0662504AE552C6B670DB5F75553BAEE273BEFA160C918C0C1039AAB3BC058505CA05328B198C797296B70B2F5F73BAB292EDE06955F59541F73EF820DC7F4BFD4DE54C99F16A798266472540D8819F43ED29390271A2A57785AAD3B8BC142D7F3C5A179D6E4DE94C37DC0D278807119989836DA3A8DB918A2786D41753F774F5760095306B15AF307D86E6A9681950F2510C3FB3FC39820F216EA08689D085A89434CF3D98EB5ABFFCEDCBD0E6AAFE9C9BE072814730678B9082B5B62CA113D9243C83199C940D18D748D64B929A94F68268C8D5B976A32041580B2BFFD5D5FE21A338F65FB1FC494416BA804A920AEF90353F4924D30183908D2C56ECBDC381446CB0F8F4162B3F9C050FF4B226EBFC86D7DEFFB20445255A836762B18183E9F932B8775C21CBECB9C31B64A855FF4D1B5B77E6EDBC31776FD0AD5C23E53603074C118F6936C86CC74307
+20210510054156 2 6 100 3071 2 EAC054F0A6595901FCD8F7F8FCC4BA738ED1B3A5EBCBA6F7616CAF48A071E1407283441719C3FE1C10D43799F3BF87492ABDBF0F3B0662504AE552C6B670DB5F75553BAEE273BEFA160C918C0C1039AAB3BC058505CA05328B198C797296B70B2F5F73BAB292EDE06955F59541F73EF820DC7F4BFD4DE54C99F16A798266472540D8819F43ED29390271A2A57785AAD3B8BC142D7F3C5A179D6E4DE94C37DC0D278807119989836DA3A8DB918A2786D41753F774F5760095306B15AF307D86E6A9681950F2510C3FB3FC39820F216EA08689D085A89434CF3D98EB5ABFFCEDCBD0E6AAFE9C9BE072814730678B9082B5B62CA113D9243C83199C940D18D748D64B929A94F68268C8D5B976A32041580B2BFFD5D5FE21A338F65FB1FC494416BA804A920AEF90353F4924D30183908D2C56ECBDC381446CB0F8F4162B3F9C050FF4B226EBFC86D7DEFFB20445255A836762B18183E9F932B8775C21CBECB9C31B64A855FF4D1B5B77E6EDBC31776FD0AD5C23E53603074C118F6936C86CD6DE3B
+20210510054349 2 6 100 3071 5 EAC054F0A6595901FCD8F7F8FCC4BA738ED1B3A5EBCBA6F7616CAF48A071E1407283441719C3FE1C10D43799F3BF87492ABDBF0F3B0662504AE552C6B670DB5F75553BAEE273BEFA160C918C0C1039AAB3BC058505CA05328B198C797296B70B2F5F73BAB292EDE06955F59541F73EF820DC7F4BFD4DE54C99F16A798266472540D8819F43ED29390271A2A57785AAD3B8BC142D7F3C5A179D6E4DE94C37DC0D278807119989836DA3A8DB918A2786D41753F774F5760095306B15AF307D86E6A9681950F2510C3FB3FC39820F216EA08689D085A89434CF3D98EB5ABFFCEDCBD0E6AAFE9C9BE072814730678B9082B5B62CA113D9243C83199C940D18D748D64B929A94F68268C8D5B976A32041580B2BFFD5D5FE21A338F65FB1FC494416BA804A920AEF90353F4924D30183908D2C56ECBDC381446CB0F8F4162B3F9C050FF4B226EBFC86D7DEFFB20445255A836762B18183E9F932B8775C21CBECB9C31B64A855FF4D1B5B77E6EDBC31776FD0AD5C23E53603074C118F6936C86D19E8FF
+20210510054413 2 6 100 3071 2 EAC054F0A6595901FCD8F7F8FCC4BA738ED1B3A5EBCBA6F7616CAF48A071E1407283441719C3FE1C10D43799F3BF87492ABDBF0F3B0662504AE552C6B670DB5F75553BAEE273BEFA160C918C0C1039AAB3BC058505CA05328B198C797296B70B2F5F73BAB292EDE06955F59541F73EF820DC7F4BFD4DE54C99F16A798266472540D8819F43ED29390271A2A57785AAD3B8BC142D7F3C5A179D6E4DE94C37DC0D278807119989836DA3A8DB918A2786D41753F774F5760095306B15AF307D86E6A9681950F2510C3FB3FC39820F216EA08689D085A89434CF3D98EB5ABFFCEDCBD0E6AAFE9C9BE072814730678B9082B5B62CA113D9243C83199C940D18D748D64B929A94F68268C8D5B976A32041580B2BFFD5D5FE21A338F65FB1FC494416BA804A920AEF90353F4924D30183908D2C56ECBDC381446CB0F8F4162B3F9C050FF4B226EBFC86D7DEFFB20445255A836762B18183E9F932B8775C21CBECB9C31B64A855FF4D1B5B77E6EDBC31776FD0AD5C23E53603074C118F6936C86D2241CB
+20210510054752 2 6 100 3071 2 EAC054F0A6595901FCD8F7F8FCC4BA738ED1B3A5EBCBA6F7616CAF48A071E1407283441719C3FE1C10D43799F3BF87492ABDBF0F3B0662504AE552C6B670DB5F75553BAEE273BEFA160C918C0C1039AAB3BC058505CA05328B198C797296B70B2F5F73BAB292EDE06955F59541F73EF820DC7F4BFD4DE54C99F16A798266472540D8819F43ED29390271A2A57785AAD3B8BC142D7F3C5A179D6E4DE94C37DC0D278807119989836DA3A8DB918A2786D41753F774F5760095306B15AF307D86E6A9681950F2510C3FB3FC39820F216EA08689D085A89434CF3D98EB5ABFFCEDCBD0E6AAFE9C9BE072814730678B9082B5B62CA113D9243C83199C940D18D748D64B929A94F68268C8D5B976A32041580B2BFFD5D5FE21A338F65FB1FC494416BA804A920AEF90353F4924D30183908D2C56ECBDC381446CB0F8F4162B3F9C050FF4B226EBFC86D7DEFFB20445255A836762B18183E9F932B8775C21CBECB9C31B64A855FF4D1B5B77E6EDBC31776FD0AD5C23E53603074C118F6936C86DB1B4E3
+20210510054845 2 6 100 3071 2 EAC054F0A6595901FCD8F7F8FCC4BA738ED1B3A5EBCBA6F7616CAF48A071E1407283441719C3FE1C10D43799F3BF87492ABDBF0F3B0662504AE552C6B670DB5F75553BAEE273BEFA160C918C0C1039AAB3BC058505CA05328B198C797296B70B2F5F73BAB292EDE06955F59541F73EF820DC7F4BFD4DE54C99F16A798266472540D8819F43ED29390271A2A57785AAD3B8BC142D7F3C5A179D6E4DE94C37DC0D278807119989836DA3A8DB918A2786D41753F774F5760095306B15AF307D86E6A9681950F2510C3FB3FC39820F216EA08689D085A89434CF3D98EB5ABFFCEDCBD0E6AAFE9C9BE072814730678B9082B5B62CA113D9243C83199C940D18D748D64B929A94F68268C8D5B976A32041580B2BFFD5D5FE21A338F65FB1FC494416BA804A920AEF90353F4924D30183908D2C56ECBDC381446CB0F8F4162B3F9C050FF4B226EBFC86D7DEFFB20445255A836762B18183E9F932B8775C21CBECB9C31B64A855FF4D1B5B77E6EDBC31776FD0AD5C23E53603074C118F6936C86DCDC3BB
+20210510054924 2 6 100 3071 5 EAC054F0A6595901FCD8F7F8FCC4BA738ED1B3A5EBCBA6F7616CAF48A071E1407283441719C3FE1C10D43799F3BF87492ABDBF0F3B0662504AE552C6B670DB5F75553BAEE273BEFA160C918C0C1039AAB3BC058505CA05328B198C797296B70B2F5F73BAB292EDE06955F59541F73EF820DC7F4BFD4DE54C99F16A798266472540D8819F43ED29390271A2A57785AAD3B8BC142D7F3C5A179D6E4DE94C37DC0D278807119989836DA3A8DB918A2786D41753F774F5760095306B15AF307D86E6A9681950F2510C3FB3FC39820F216EA08689D085A89434CF3D98EB5ABFFCEDCBD0E6AAFE9C9BE072814730678B9082B5B62CA113D9243C83199C940D18D748D64B929A94F68268C8D5B976A32041580B2BFFD5D5FE21A338F65FB1FC494416BA804A920AEF90353F4924D30183908D2C56ECBDC381446CB0F8F4162B3F9C050FF4B226EBFC86D7DEFFB20445255A836762B18183E9F932B8775C21CBECB9C31B64A855FF4D1B5B77E6EDBC31776FD0AD5C23E53603074C118F6936C86DDEE687
+20210510055001 2 6 100 3071 5 EAC054F0A6595901FCD8F7F8FCC4BA738ED1B3A5EBCBA6F7616CAF48A071E1407283441719C3FE1C10D43799F3BF87492ABDBF0F3B0662504AE552C6B670DB5F75553BAEE273BEFA160C918C0C1039AAB3BC058505CA05328B198C797296B70B2F5F73BAB292EDE06955F59541F73EF820DC7F4BFD4DE54C99F16A798266472540D8819F43ED29390271A2A57785AAD3B8BC142D7F3C5A179D6E4DE94C37DC0D278807119989836DA3A8DB918A2786D41753F774F5760095306B15AF307D86E6A9681950F2510C3FB3FC39820F216EA08689D085A89434CF3D98EB5ABFFCEDCBD0E6AAFE9C9BE072814730678B9082B5B62CA113D9243C83199C940D18D748D64B929A94F68268C8D5B976A32041580B2BFFD5D5FE21A338F65FB1FC494416BA804A920AEF90353F4924D30183908D2C56ECBDC381446CB0F8F4162B3F9C050FF4B226EBFC86D7DEFFB20445255A836762B18183E9F932B8775C21CBECB9C31B64A855FF4D1B5B77E6EDBC31776FD0AD5C23E53603074C118F6936C86DF020FF
+20210510055111 2 6 100 3071 5 EAC054F0A6595901FCD8F7F8FCC4BA738ED1B3A5EBCBA6F7616CAF48A071E1407283441719C3FE1C10D43799F3BF87492ABDBF0F3B0662504AE552C6B670DB5F75553BAEE273BEFA160C918C0C1039AAB3BC058505CA05328B198C797296B70B2F5F73BAB292EDE06955F59541F73EF820DC7F4BFD4DE54C99F16A798266472540D8819F43ED29390271A2A57785AAD3B8BC142D7F3C5A179D6E4DE94C37DC0D278807119989836DA3A8DB918A2786D41753F774F5760095306B15AF307D86E6A9681950F2510C3FB3FC39820F216EA08689D085A89434CF3D98EB5ABFFCEDCBD0E6AAFE9C9BE072814730678B9082B5B62CA113D9243C83199C940D18D748D64B929A94F68268C8D5B976A32041580B2BFFD5D5FE21A338F65FB1FC494416BA804A920AEF90353F4924D30183908D2C56ECBDC381446CB0F8F4162B3F9C050FF4B226EBFC86D7DEFFB20445255A836762B18183E9F932B8775C21CBECB9C31B64A855FF4D1B5B77E6EDBC31776FD0AD5C23E53603074C118F6936C86E180E17
+20210510055701 2 6 100 3071 5 EAC054F0A6595901FCD8F7F8FCC4BA738ED1B3A5EBCBA6F7616CAF48A071E1407283441719C3FE1C10D43799F3BF87492ABDBF0F3B0662504AE552C6B670DB5F75553BAEE273BEFA160C918C0C1039AAB3BC058505CA05328B198C797296B70B2F5F73BAB292EDE06955F59541F73EF820DC7F4BFD4DE54C99F16A798266472540D8819F43ED29390271A2A57785AAD3B8BC142D7F3C5A179D6E4DE94C37DC0D278807119989836DA3A8DB918A2786D41753F774F5760095306B15AF307D86E6A9681950F2510C3FB3FC39820F216EA08689D085A89434CF3D98EB5ABFFCEDCBD0E6AAFE9C9BE072814730678B9082B5B62CA113D9243C83199C940D18D748D64B929A94F68268C8D5B976A32041580B2BFFD5D5FE21A338F65FB1FC494416BA804A920AEF90353F4924D30183908D2C56ECBDC381446CB0F8F4162B3F9C050FF4B226EBFC86D7DEFFB20445255A836762B18183E9F932B8775C21CBECB9C31B64A855FF4D1B5B77E6EDBC31776FD0AD5C23E53603074C118F6936C86EF8B7BF
+20210510055743 2 6 100 3071 5 EAC054F0A6595901FCD8F7F8FCC4BA738ED1B3A5EBCBA6F7616CAF48A071E1407283441719C3FE1C10D43799F3BF87492ABDBF0F3B0662504AE552C6B670DB5F75553BAEE273BEFA160C918C0C1039AAB3BC058505CA05328B198C797296B70B2F5F73BAB292EDE06955F59541F73EF820DC7F4BFD4DE54C99F16A798266472540D8819F43ED29390271A2A57785AAD3B8BC142D7F3C5A179D6E4DE94C37DC0D278807119989836DA3A8DB918A2786D41753F774F5760095306B15AF307D86E6A9681950F2510C3FB3FC39820F216EA08689D085A89434CF3D98EB5ABFFCEDCBD0E6AAFE9C9BE072814730678B9082B5B62CA113D9243C83199C940D18D748D64B929A94F68268C8D5B976A32041580B2BFFD5D5FE21A338F65FB1FC494416BA804A920AEF90353F4924D30183908D2C56ECBDC381446CB0F8F4162B3F9C050FF4B226EBFC86D7DEFFB20445255A836762B18183E9F932B8775C21CBECB9C31B64A855FF4D1B5B77E6EDBC31776FD0AD5C23E53603074C118F6936C86F0C6C87
+20210510055803 2 6 100 3071 5 EAC054F0A6595901FCD8F7F8FCC4BA738ED1B3A5EBCBA6F7616CAF48A071E1407283441719C3FE1C10D43799F3BF87492ABDBF0F3B0662504AE552C6B670DB5F75553BAEE273BEFA160C918C0C1039AAB3BC058505CA05328B198C797296B70B2F5F73BAB292EDE06955F59541F73EF820DC7F4BFD4DE54C99F16A798266472540D8819F43ED29390271A2A57785AAD3B8BC142D7F3C5A179D6E4DE94C37DC0D278807119989836DA3A8DB918A2786D41753F774F5760095306B15AF307D86E6A9681950F2510C3FB3FC39820F216EA08689D085A89434CF3D98EB5ABFFCEDCBD0E6AAFE9C9BE072814730678B9082B5B62CA113D9243C83199C940D18D748D64B929A94F68268C8D5B976A32041580B2BFFD5D5FE21A338F65FB1FC494416BA804A920AEF90353F4924D30183908D2C56ECBDC381446CB0F8F4162B3F9C050FF4B226EBFC86D7DEFFB20445255A836762B18183E9F932B8775C21CBECB9C31B64A855FF4D1B5B77E6EDBC31776FD0AD5C23E53603074C118F6936C86F1109C7
+20210510060103 2 6 100 3071 2 EAC054F0A6595901FCD8F7F8FCC4BA738ED1B3A5EBCBA6F7616CAF48A071E1407283441719C3FE1C10D43799F3BF87492ABDBF0F3B0662504AE552C6B670DB5F75553BAEE273BEFA160C918C0C1039AAB3BC058505CA05328B198C797296B70B2F5F73BAB292EDE06955F59541F73EF820DC7F4BFD4DE54C99F16A798266472540D8819F43ED29390271A2A57785AAD3B8BC142D7F3C5A179D6E4DE94C37DC0D278807119989836DA3A8DB918A2786D41753F774F5760095306B15AF307D86E6A9681950F2510C3FB3FC39820F216EA08689D085A89434CF3D98EB5ABFFCEDCBD0E6AAFE9C9BE072814730678B9082B5B62CA113D9243C83199C940D18D748D64B929A94F68268C8D5B976A32041580B2BFFD5D5FE21A338F65FB1FC494416BA804A920AEF90353F4924D30183908D2C56ECBDC381446CB0F8F4162B3F9C050FF4B226EBFC86D7DEFFB20445255A836762B18183E9F932B8775C21CBECB9C31B64A855FF4D1B5B77E6EDBC31776FD0AD5C23E53603074C118F6936C86F7F624B
+20210510060223 2 6 100 3071 2 EAC054F0A6595901FCD8F7F8FCC4BA738ED1B3A5EBCBA6F7616CAF48A071E1407283441719C3FE1C10D43799F3BF87492ABDBF0F3B0662504AE552C6B670DB5F75553BAEE273BEFA160C918C0C1039AAB3BC058505CA05328B198C797296B70B2F5F73BAB292EDE06955F59541F73EF820DC7F4BFD4DE54C99F16A798266472540D8819F43ED29390271A2A57785AAD3B8BC142D7F3C5A179D6E4DE94C37DC0D278807119989836DA3A8DB918A2786D41753F774F5760095306B15AF307D86E6A9681950F2510C3FB3FC39820F216EA08689D085A89434CF3D98EB5ABFFCEDCBD0E6AAFE9C9BE072814730678B9082B5B62CA113D9243C83199C940D18D748D64B929A94F68268C8D5B976A32041580B2BFFD5D5FE21A338F65FB1FC494416BA804A920AEF90353F4924D30183908D2C56ECBDC381446CB0F8F4162B3F9C050FF4B226EBFC86D7DEFFB20445255A836762B18183E9F932B8775C21CBECB9C31B64A855FF4D1B5B77E6EDBC31776FD0AD5C23E53603074C118F6936C86FAC18FB
+20210510060508 2 6 100 3071 5 EAC054F0A6595901FCD8F7F8FCC4BA738ED1B3A5EBCBA6F7616CAF48A071E1407283441719C3FE1C10D43799F3BF87492ABDBF0F3B0662504AE552C6B670DB5F75553BAEE273BEFA160C918C0C1039AAB3BC058505CA05328B198C797296B70B2F5F73BAB292EDE06955F59541F73EF820DC7F4BFD4DE54C99F16A798266472540D8819F43ED29390271A2A57785AAD3B8BC142D7F3C5A179D6E4DE94C37DC0D278807119989836DA3A8DB918A2786D41753F774F5760095306B15AF307D86E6A9681950F2510C3FB3FC39820F216EA08689D085A89434CF3D98EB5ABFFCEDCBD0E6AAFE9C9BE072814730678B9082B5B62CA113D9243C83199C940D18D748D64B929A94F68268C8D5B976A32041580B2BFFD5D5FE21A338F65FB1FC494416BA804A920AEF90353F4924D30183908D2C56ECBDC381446CB0F8F4162B3F9C050FF4B226EBFC86D7DEFFB20445255A836762B18183E9F932B8775C21CBECB9C31B64A855FF4D1B5B77E6EDBC31776FD0AD5C23E53603074C118F6936C870107F57
+20210510060612 2 6 100 3071 2 EAC054F0A6595901FCD8F7F8FCC4BA738ED1B3A5EBCBA6F7616CAF48A071E1407283441719C3FE1C10D43799F3BF87492ABDBF0F3B0662504AE552C6B670DB5F75553BAEE273BEFA160C918C0C1039AAB3BC058505CA05328B198C797296B70B2F5F73BAB292EDE06955F59541F73EF820DC7F4BFD4DE54C99F16A798266472540D8819F43ED29390271A2A57785AAD3B8BC142D7F3C5A179D6E4DE94C37DC0D278807119989836DA3A8DB918A2786D41753F774F5760095306B15AF307D86E6A9681950F2510C3FB3FC39820F216EA08689D085A89434CF3D98EB5ABFFCEDCBD0E6AAFE9C9BE072814730678B9082B5B62CA113D9243C83199C940D18D748D64B929A94F68268C8D5B976A32041580B2BFFD5D5FE21A338F65FB1FC494416BA804A920AEF90353F4924D30183908D2C56ECBDC381446CB0F8F4162B3F9C050FF4B226EBFC86D7DEFFB20445255A836762B18183E9F932B8775C21CBECB9C31B64A855FF4D1B5B77E6EDBC31776FD0AD5C23E53603074C118F6936C8703506C3
+20210510060937 2 6 100 3071 2 EAC054F0A6595901FCD8F7F8FCC4BA738ED1B3A5EBCBA6F7616CAF48A071E1407283441719C3FE1C10D43799F3BF87492ABDBF0F3B0662504AE552C6B670DB5F75553BAEE273BEFA160C918C0C1039AAB3BC058505CA05328B198C797296B70B2F5F73BAB292EDE06955F59541F73EF820DC7F4BFD4DE54C99F16A798266472540D8819F43ED29390271A2A57785AAD3B8BC142D7F3C5A179D6E4DE94C37DC0D278807119989836DA3A8DB918A2786D41753F774F5760095306B15AF307D86E6A9681950F2510C3FB3FC39820F216EA08689D085A89434CF3D98EB5ABFFCEDCBD0E6AAFE9C9BE072814730678B9082B5B62CA113D9243C83199C940D18D748D64B929A94F68268C8D5B976A32041580B2BFFD5D5FE21A338F65FB1FC494416BA804A920AEF90353F4924D30183908D2C56ECBDC381446CB0F8F4162B3F9C050FF4B226EBFC86D7DEFFB20445255A836762B18183E9F932B8775C21CBECB9C31B64A855FF4D1B5B77E6EDBC31776FD0AD5C23E53603074C118F6936C870B83A93
+20210510061232 2 6 100 3071 2 EAC054F0A6595901FCD8F7F8FCC4BA738ED1B3A5EBCBA6F7616CAF48A071E1407283441719C3FE1C10D43799F3BF87492ABDBF0F3B0662504AE552C6B670DB5F75553BAEE273BEFA160C918C0C1039AAB3BC058505CA05328B198C797296B70B2F5F73BAB292EDE06955F59541F73EF820DC7F4BFD4DE54C99F16A798266472540D8819F43ED29390271A2A57785AAD3B8BC142D7F3C5A179D6E4DE94C37DC0D278807119989836DA3A8DB918A2786D41753F774F5760095306B15AF307D86E6A9681950F2510C3FB3FC39820F216EA08689D085A89434CF3D98EB5ABFFCEDCBD0E6AAFE9C9BE072814730678B9082B5B62CA113D9243C83199C940D18D748D64B929A94F68268C8D5B976A32041580B2BFFD5D5FE21A338F65FB1FC494416BA804A920AEF90353F4924D30183908D2C56ECBDC381446CB0F8F4162B3F9C050FF4B226EBFC86D7DEFFB20445255A836762B18183E9F932B8775C21CBECB9C31B64A855FF4D1B5B77E6EDBC31776FD0AD5C23E53603074C118F6936C87126000B
+20210510061957 2 6 100 3071 5 EAC054F0A6595901FCD8F7F8FCC4BA738ED1B3A5EBCBA6F7616CAF48A071E1407283441719C3FE1C10D43799F3BF87492ABDBF0F3B0662504AE552C6B670DB5F75553BAEE273BEFA160C918C0C1039AAB3BC058505CA05328B198C797296B70B2F5F73BAB292EDE06955F59541F73EF820DC7F4BFD4DE54C99F16A798266472540D8819F43ED29390271A2A57785AAD3B8BC142D7F3C5A179D6E4DE94C37DC0D278807119989836DA3A8DB918A2786D41753F774F5760095306B15AF307D86E6A9681950F2510C3FB3FC39820F216EA08689D085A89434CF3D98EB5ABFFCEDCBD0E6AAFE9C9BE072814730678B9082B5B62CA113D9243C83199C940D18D748D64B929A94F68268C8D5B976A32041580B2BFFD5D5FE21A338F65FB1FC494416BA804A920AEF90353F4924D30183908D2C56ECBDC381446CB0F8F4162B3F9C050FF4B226EBFC86D7DEFFB20445255A836762B18183E9F932B8775C21CBECB9C31B64A855FF4D1B5B77E6EDBC31776FD0AD5C23E53603074C118F6936C872490677
+20210510062551 2 6 100 3071 2 EAC054F0A6595901FCD8F7F8FCC4BA738ED1B3A5EBCBA6F7616CAF48A071E1407283441719C3FE1C10D43799F3BF87492ABDBF0F3B0662504AE552C6B670DB5F75553BAEE273BEFA160C918C0C1039AAB3BC058505CA05328B198C797296B70B2F5F73BAB292EDE06955F59541F73EF820DC7F4BFD4DE54C99F16A798266472540D8819F43ED29390271A2A57785AAD3B8BC142D7F3C5A179D6E4DE94C37DC0D278807119989836DA3A8DB918A2786D41753F774F5760095306B15AF307D86E6A9681950F2510C3FB3FC39820F216EA08689D085A89434CF3D98EB5ABFFCEDCBD0E6AAFE9C9BE072814730678B9082B5B62CA113D9243C83199C940D18D748D64B929A94F68268C8D5B976A32041580B2BFFD5D5FE21A338F65FB1FC494416BA804A920AEF90353F4924D30183908D2C56ECBDC381446CB0F8F4162B3F9C050FF4B226EBFC86D7DEFFB20445255A836762B18183E9F932B8775C21CBECB9C31B64A855FF4D1B5B77E6EDBC31776FD0AD5C23E53603074C118F6936C8732DEDB3
+20210510062658 2 6 100 3071 5 EAC054F0A6595901FCD8F7F8FCC4BA738ED1B3A5EBCBA6F7616CAF48A071E1407283441719C3FE1C10D43799F3BF87492ABDBF0F3B0662504AE552C6B670DB5F75553BAEE273BEFA160C918C0C1039AAB3BC058505CA05328B198C797296B70B2F5F73BAB292EDE06955F59541F73EF820DC7F4BFD4DE54C99F16A798266472540D8819F43ED29390271A2A57785AAD3B8BC142D7F3C5A179D6E4DE94C37DC0D278807119989836DA3A8DB918A2786D41753F774F5760095306B15AF307D86E6A9681950F2510C3FB3FC39820F216EA08689D085A89434CF3D98EB5ABFFCEDCBD0E6AAFE9C9BE072814730678B9082B5B62CA113D9243C83199C940D18D748D64B929A94F68268C8D5B976A32041580B2BFFD5D5FE21A338F65FB1FC494416BA804A920AEF90353F4924D30183908D2C56ECBDC381446CB0F8F4162B3F9C050FF4B226EBFC86D7DEFFB20445255A836762B18183E9F932B8775C21CBECB9C31B64A855FF4D1B5B77E6EDBC31776FD0AD5C23E53603074C118F6936C873531EB7
+20210510062742 2 6 100 3071 5 EAC054F0A6595901FCD8F7F8FCC4BA738ED1B3A5EBCBA6F7616CAF48A071E1407283441719C3FE1C10D43799F3BF87492ABDBF0F3B0662504AE552C6B670DB5F75553BAEE273BEFA160C918C0C1039AAB3BC058505CA05328B198C797296B70B2F5F73BAB292EDE06955F59541F73EF820DC7F4BFD4DE54C99F16A798266472540D8819F43ED29390271A2A57785AAD3B8BC142D7F3C5A179D6E4DE94C37DC0D278807119989836DA3A8DB918A2786D41753F774F5760095306B15AF307D86E6A9681950F2510C3FB3FC39820F216EA08689D085A89434CF3D98EB5ABFFCEDCBD0E6AAFE9C9BE072814730678B9082B5B62CA113D9243C83199C940D18D748D64B929A94F68268C8D5B976A32041580B2BFFD5D5FE21A338F65FB1FC494416BA804A920AEF90353F4924D30183908D2C56ECBDC381446CB0F8F4162B3F9C050FF4B226EBFC86D7DEFFB20445255A836762B18183E9F932B8775C21CBECB9C31B64A855FF4D1B5B77E6EDBC31776FD0AD5C23E53603074C118F6936C87366FEE7
+20210510063155 2 6 100 3071 2 EAC054F0A6595901FCD8F7F8FCC4BA738ED1B3A5EBCBA6F7616CAF48A071E1407283441719C3FE1C10D43799F3BF87492ABDBF0F3B0662504AE552C6B670DB5F75553BAEE273BEFA160C918C0C1039AAB3BC058505CA05328B198C797296B70B2F5F73BAB292EDE06955F59541F73EF820DC7F4BFD4DE54C99F16A798266472540D8819F43ED29390271A2A57785AAD3B8BC142D7F3C5A179D6E4DE94C37DC0D278807119989836DA3A8DB918A2786D41753F774F5760095306B15AF307D86E6A9681950F2510C3FB3FC39820F216EA08689D085A89434CF3D98EB5ABFFCEDCBD0E6AAFE9C9BE072814730678B9082B5B62CA113D9243C83199C940D18D748D64B929A94F68268C8D5B976A32041580B2BFFD5D5FE21A338F65FB1FC494416BA804A920AEF90353F4924D30183908D2C56ECBDC381446CB0F8F4162B3F9C050FF4B226EBFC86D7DEFFB20445255A836762B18183E9F932B8775C21CBECB9C31B64A855FF4D1B5B77E6EDBC31776FD0AD5C23E53603074C118F6936C874081463
+20210510063849 2 6 100 3071 2 EAC054F0A6595901FCD8F7F8FCC4BA738ED1B3A5EBCBA6F7616CAF48A071E1407283441719C3FE1C10D43799F3BF87492ABDBF0F3B0662504AE552C6B670DB5F75553BAEE273BEFA160C918C0C1039AAB3BC058505CA05328B198C797296B70B2F5F73BAB292EDE06955F59541F73EF820DC7F4BFD4DE54C99F16A798266472540D8819F43ED29390271A2A57785AAD3B8BC142D7F3C5A179D6E4DE94C37DC0D278807119989836DA3A8DB918A2786D41753F774F5760095306B15AF307D86E6A9681950F2510C3FB3FC39820F216EA08689D085A89434CF3D98EB5ABFFCEDCBD0E6AAFE9C9BE072814730678B9082B5B62CA113D9243C83199C940D18D748D64B929A94F68268C8D5B976A32041580B2BFFD5D5FE21A338F65FB1FC494416BA804A920AEF90353F4924D30183908D2C56ECBDC381446CB0F8F4162B3F9C050FF4B226EBFC86D7DEFFB20445255A836762B18183E9F932B8775C21CBECB9C31B64A855FF4D1B5B77E6EDBC31776FD0AD5C23E53603074C118F6936C875123D83
+20210510064051 2 6 100 3071 5 EAC054F0A6595901FCD8F7F8FCC4BA738ED1B3A5EBCBA6F7616CAF48A071E1407283441719C3FE1C10D43799F3BF87492ABDBF0F3B0662504AE552C6B670DB5F75553BAEE273BEFA160C918C0C1039AAB3BC058505CA05328B198C797296B70B2F5F73BAB292EDE06955F59541F73EF820DC7F4BFD4DE54C99F16A798266472540D8819F43ED29390271A2A57785AAD3B8BC142D7F3C5A179D6E4DE94C37DC0D278807119989836DA3A8DB918A2786D41753F774F5760095306B15AF307D86E6A9681950F2510C3FB3FC39820F216EA08689D085A89434CF3D98EB5ABFFCEDCBD0E6AAFE9C9BE072814730678B9082B5B62CA113D9243C83199C940D18D748D64B929A94F68268C8D5B976A32041580B2BFFD5D5FE21A338F65FB1FC494416BA804A920AEF90353F4924D30183908D2C56ECBDC381446CB0F8F4162B3F9C050FF4B226EBFC86D7DEFFB20445255A836762B18183E9F932B8775C21CBECB9C31B64A855FF4D1B5B77E6EDBC31776FD0AD5C23E53603074C118F6936C8755C16E7
+20210510064226 2 6 100 3071 5 EAC054F0A6595901FCD8F7F8FCC4BA738ED1B3A5EBCBA6F7616CAF48A071E1407283441719C3FE1C10D43799F3BF87492ABDBF0F3B0662504AE552C6B670DB5F75553BAEE273BEFA160C918C0C1039AAB3BC058505CA05328B198C797296B70B2F5F73BAB292EDE06955F59541F73EF820DC7F4BFD4DE54C99F16A798266472540D8819F43ED29390271A2A57785AAD3B8BC142D7F3C5A179D6E4DE94C37DC0D278807119989836DA3A8DB918A2786D41753F774F5760095306B15AF307D86E6A9681950F2510C3FB3FC39820F216EA08689D085A89434CF3D98EB5ABFFCEDCBD0E6AAFE9C9BE072814730678B9082B5B62CA113D9243C83199C940D18D748D64B929A94F68268C8D5B976A32041580B2BFFD5D5FE21A338F65FB1FC494416BA804A920AEF90353F4924D30183908D2C56ECBDC381446CB0F8F4162B3F9C050FF4B226EBFC86D7DEFFB20445255A836762B18183E9F932B8775C21CBECB9C31B64A855FF4D1B5B77E6EDBC31776FD0AD5C23E53603074C118F6936C87592B08F
+20210510064313 2 6 100 3071 2 EAC054F0A6595901FCD8F7F8FCC4BA738ED1B3A5EBCBA6F7616CAF48A071E1407283441719C3FE1C10D43799F3BF87492ABDBF0F3B0662504AE552C6B670DB5F75553BAEE273BEFA160C918C0C1039AAB3BC058505CA05328B198C797296B70B2F5F73BAB292EDE06955F59541F73EF820DC7F4BFD4DE54C99F16A798266472540D8819F43ED29390271A2A57785AAD3B8BC142D7F3C5A179D6E4DE94C37DC0D278807119989836DA3A8DB918A2786D41753F774F5760095306B15AF307D86E6A9681950F2510C3FB3FC39820F216EA08689D085A89434CF3D98EB5ABFFCEDCBD0E6AAFE9C9BE072814730678B9082B5B62CA113D9243C83199C940D18D748D64B929A94F68268C8D5B976A32041580B2BFFD5D5FE21A338F65FB1FC494416BA804A920AEF90353F4924D30183908D2C56ECBDC381446CB0F8F4162B3F9C050FF4B226EBFC86D7DEFFB20445255A836762B18183E9F932B8775C21CBECB9C31B64A855FF4D1B5B77E6EDBC31776FD0AD5C23E53603074C118F6936C875AB115B
+20210510064513 2 6 100 3071 2 EAC054F0A6595901FCD8F7F8FCC4BA738ED1B3A5EBCBA6F7616CAF48A071E1407283441719C3FE1C10D43799F3BF87492ABDBF0F3B0662504AE552C6B670DB5F75553BAEE273BEFA160C918C0C1039AAB3BC058505CA05328B198C797296B70B2F5F73BAB292EDE06955F59541F73EF820DC7F4BFD4DE54C99F16A798266472540D8819F43ED29390271A2A57785AAD3B8BC142D7F3C5A179D6E4DE94C37DC0D278807119989836DA3A8DB918A2786D41753F774F5760095306B15AF307D86E6A9681950F2510C3FB3FC39820F216EA08689D085A89434CF3D98EB5ABFFCEDCBD0E6AAFE9C9BE072814730678B9082B5B62CA113D9243C83199C940D18D748D64B929A94F68268C8D5B976A32041580B2BFFD5D5FE21A338F65FB1FC494416BA804A920AEF90353F4924D30183908D2C56ECBDC381446CB0F8F4162B3F9C050FF4B226EBFC86D7DEFFB20445255A836762B18183E9F932B8775C21CBECB9C31B64A855FF4D1B5B77E6EDBC31776FD0AD5C23E53603074C118F6936C875F0FD83
+20210510064532 2 6 100 3071 2 EAC054F0A6595901FCD8F7F8FCC4BA738ED1B3A5EBCBA6F7616CAF48A071E1407283441719C3FE1C10D43799F3BF87492ABDBF0F3B0662504AE552C6B670DB5F75553BAEE273BEFA160C918C0C1039AAB3BC058505CA05328B198C797296B70B2F5F73BAB292EDE06955F59541F73EF820DC7F4BFD4DE54C99F16A798266472540D8819F43ED29390271A2A57785AAD3B8BC142D7F3C5A179D6E4DE94C37DC0D278807119989836DA3A8DB918A2786D41753F774F5760095306B15AF307D86E6A9681950F2510C3FB3FC39820F216EA08689D085A89434CF3D98EB5ABFFCEDCBD0E6AAFE9C9BE072814730678B9082B5B62CA113D9243C83199C940D18D748D64B929A94F68268C8D5B976A32041580B2BFFD5D5FE21A338F65FB1FC494416BA804A920AEF90353F4924D30183908D2C56ECBDC381446CB0F8F4162B3F9C050FF4B226EBFC86D7DEFFB20445255A836762B18183E9F932B8775C21CBECB9C31B64A855FF4D1B5B77E6EDBC31776FD0AD5C23E53603074C118F6936C875F527EB
+20210510065000 2 6 100 3071 2 EAC054F0A6595901FCD8F7F8FCC4BA738ED1B3A5EBCBA6F7616CAF48A071E1407283441719C3FE1C10D43799F3BF87492ABDBF0F3B0662504AE552C6B670DB5F75553BAEE273BEFA160C918C0C1039AAB3BC058505CA05328B198C797296B70B2F5F73BAB292EDE06955F59541F73EF820DC7F4BFD4DE54C99F16A798266472540D8819F43ED29390271A2A57785AAD3B8BC142D7F3C5A179D6E4DE94C37DC0D278807119989836DA3A8DB918A2786D41753F774F5760095306B15AF307D86E6A9681950F2510C3FB3FC39820F216EA08689D085A89434CF3D98EB5ABFFCEDCBD0E6AAFE9C9BE072814730678B9082B5B62CA113D9243C83199C940D18D748D64B929A94F68268C8D5B976A32041580B2BFFD5D5FE21A338F65FB1FC494416BA804A920AEF90353F4924D30183908D2C56ECBDC381446CB0F8F4162B3F9C050FF4B226EBFC86D7DEFFB20445255A836762B18183E9F932B8775C21CBECB9C31B64A855FF4D1B5B77E6EDBC31776FD0AD5C23E53603074C118F6936C876A1697B
+20210510065226 2 6 100 3071 2 EAC054F0A6595901FCD8F7F8FCC4BA738ED1B3A5EBCBA6F7616CAF48A071E1407283441719C3FE1C10D43799F3BF87492ABDBF0F3B0662504AE552C6B670DB5F75553BAEE273BEFA160C918C0C1039AAB3BC058505CA05328B198C797296B70B2F5F73BAB292EDE06955F59541F73EF820DC7F4BFD4DE54C99F16A798266472540D8819F43ED29390271A2A57785AAD3B8BC142D7F3C5A179D6E4DE94C37DC0D278807119989836DA3A8DB918A2786D41753F774F5760095306B15AF307D86E6A9681950F2510C3FB3FC39820F216EA08689D085A89434CF3D98EB5ABFFCEDCBD0E6AAFE9C9BE072814730678B9082B5B62CA113D9243C83199C940D18D748D64B929A94F68268C8D5B976A32041580B2BFFD5D5FE21A338F65FB1FC494416BA804A920AEF90353F4924D30183908D2C56ECBDC381446CB0F8F4162B3F9C050FF4B226EBFC86D7DEFFB20445255A836762B18183E9F932B8775C21CBECB9C31B64A855FF4D1B5B77E6EDBC31776FD0AD5C23E53603074C118F6936C876F8D863
+20210510065300 2 6 100 3071 2 EAC054F0A6595901FCD8F7F8FCC4BA738ED1B3A5EBCBA6F7616CAF48A071E1407283441719C3FE1C10D43799F3BF87492ABDBF0F3B0662504AE552C6B670DB5F75553BAEE273BEFA160C918C0C1039AAB3BC058505CA05328B198C797296B70B2F5F73BAB292EDE06955F59541F73EF820DC7F4BFD4DE54C99F16A798266472540D8819F43ED29390271A2A57785AAD3B8BC142D7F3C5A179D6E4DE94C37DC0D278807119989836DA3A8DB918A2786D41753F774F5760095306B15AF307D86E6A9681950F2510C3FB3FC39820F216EA08689D085A89434CF3D98EB5ABFFCEDCBD0E6AAFE9C9BE072814730678B9082B5B62CA113D9243C83199C940D18D748D64B929A94F68268C8D5B976A32041580B2BFFD5D5FE21A338F65FB1FC494416BA804A920AEF90353F4924D30183908D2C56ECBDC381446CB0F8F4162B3F9C050FF4B226EBFC86D7DEFFB20445255A836762B18183E9F932B8775C21CBECB9C31B64A855FF4D1B5B77E6EDBC31776FD0AD5C23E53603074C118F6936C87707C4B3
+20210510065704 2 6 100 3071 5 EAC054F0A6595901FCD8F7F8FCC4BA738ED1B3A5EBCBA6F7616CAF48A071E1407283441719C3FE1C10D43799F3BF87492ABDBF0F3B0662504AE552C6B670DB5F75553BAEE273BEFA160C918C0C1039AAB3BC058505CA05328B198C797296B70B2F5F73BAB292EDE06955F59541F73EF820DC7F4BFD4DE54C99F16A798266472540D8819F43ED29390271A2A57785AAD3B8BC142D7F3C5A179D6E4DE94C37DC0D278807119989836DA3A8DB918A2786D41753F774F5760095306B15AF307D86E6A9681950F2510C3FB3FC39820F216EA08689D085A89434CF3D98EB5ABFFCEDCBD0E6AAFE9C9BE072814730678B9082B5B62CA113D9243C83199C940D18D748D64B929A94F68268C8D5B976A32041580B2BFFD5D5FE21A338F65FB1FC494416BA804A920AEF90353F4924D30183908D2C56ECBDC381446CB0F8F4162B3F9C050FF4B226EBFC86D7DEFFB20445255A836762B18183E9F932B8775C21CBECB9C31B64A855FF4D1B5B77E6EDBC31776FD0AD5C23E53603074C118F6936C877A257DF
+20210510070047 2 6 100 3071 2 EAC054F0A6595901FCD8F7F8FCC4BA738ED1B3A5EBCBA6F7616CAF48A071E1407283441719C3FE1C10D43799F3BF87492ABDBF0F3B0662504AE552C6B670DB5F75553BAEE273BEFA160C918C0C1039AAB3BC058505CA05328B198C797296B70B2F5F73BAB292EDE06955F59541F73EF820DC7F4BFD4DE54C99F16A798266472540D8819F43ED29390271A2A57785AAD3B8BC142D7F3C5A179D6E4DE94C37DC0D278807119989836DA3A8DB918A2786D41753F774F5760095306B15AF307D86E6A9681950F2510C3FB3FC39820F216EA08689D085A89434CF3D98EB5ABFFCEDCBD0E6AAFE9C9BE072814730678B9082B5B62CA113D9243C83199C940D18D748D64B929A94F68268C8D5B976A32041580B2BFFD5D5FE21A338F65FB1FC494416BA804A920AEF90353F4924D30183908D2C56ECBDC381446CB0F8F4162B3F9C050FF4B226EBFC86D7DEFFB20445255A836762B18183E9F932B8775C21CBECB9C31B64A855FF4D1B5B77E6EDBC31776FD0AD5C23E53603074C118F6936C87830DAD3
+20210510070120 2 6 100 3071 5 EAC054F0A6595901FCD8F7F8FCC4BA738ED1B3A5EBCBA6F7616CAF48A071E1407283441719C3FE1C10D43799F3BF87492ABDBF0F3B0662504AE552C6B670DB5F75553BAEE273BEFA160C918C0C1039AAB3BC058505CA05328B198C797296B70B2F5F73BAB292EDE06955F59541F73EF820DC7F4BFD4DE54C99F16A798266472540D8819F43ED29390271A2A57785AAD3B8BC142D7F3C5A179D6E4DE94C37DC0D278807119989836DA3A8DB918A2786D41753F774F5760095306B15AF307D86E6A9681950F2510C3FB3FC39820F216EA08689D085A89434CF3D98EB5ABFFCEDCBD0E6AAFE9C9BE072814730678B9082B5B62CA113D9243C83199C940D18D748D64B929A94F68268C8D5B976A32041580B2BFFD5D5FE21A338F65FB1FC494416BA804A920AEF90353F4924D30183908D2C56ECBDC381446CB0F8F4162B3F9C050FF4B226EBFC86D7DEFFB20445255A836762B18183E9F932B8775C21CBECB9C31B64A855FF4D1B5B77E6EDBC31776FD0AD5C23E53603074C118F6936C8783E739F
+20210510070516 2 6 100 3071 2 EAC054F0A6595901FCD8F7F8FCC4BA738ED1B3A5EBCBA6F7616CAF48A071E1407283441719C3FE1C10D43799F3BF87492ABDBF0F3B0662504AE552C6B670DB5F75553BAEE273BEFA160C918C0C1039AAB3BC058505CA05328B198C797296B70B2F5F73BAB292EDE06955F59541F73EF820DC7F4BFD4DE54C99F16A798266472540D8819F43ED29390271A2A57785AAD3B8BC142D7F3C5A179D6E4DE94C37DC0D278807119989836DA3A8DB918A2786D41753F774F5760095306B15AF307D86E6A9681950F2510C3FB3FC39820F216EA08689D085A89434CF3D98EB5ABFFCEDCBD0E6AAFE9C9BE072814730678B9082B5B62CA113D9243C83199C940D18D748D64B929A94F68268C8D5B976A32041580B2BFFD5D5FE21A338F65FB1FC494416BA804A920AEF90353F4924D30183908D2C56ECBDC381446CB0F8F4162B3F9C050FF4B226EBFC86D7DEFFB20445255A836762B18183E9F932B8775C21CBECB9C31B64A855FF4D1B5B77E6EDBC31776FD0AD5C23E53603074C118F6936C878D7A903
+20210510070822 2 6 100 3071 5 EAC054F0A6595901FCD8F7F8FCC4BA738ED1B3A5EBCBA6F7616CAF48A071E1407283441719C3FE1C10D43799F3BF87492ABDBF0F3B0662504AE552C6B670DB5F75553BAEE273BEFA160C918C0C1039AAB3BC058505CA05328B198C797296B70B2F5F73BAB292EDE06955F59541F73EF820DC7F4BFD4DE54C99F16A798266472540D8819F43ED29390271A2A57785AAD3B8BC142D7F3C5A179D6E4DE94C37DC0D278807119989836DA3A8DB918A2786D41753F774F5760095306B15AF307D86E6A9681950F2510C3FB3FC39820F216EA08689D085A89434CF3D98EB5ABFFCEDCBD0E6AAFE9C9BE072814730678B9082B5B62CA113D9243C83199C940D18D748D64B929A94F68268C8D5B976A32041580B2BFFD5D5FE21A338F65FB1FC494416BA804A920AEF90353F4924D30183908D2C56ECBDC381446CB0F8F4162B3F9C050FF4B226EBFC86D7DEFFB20445255A836762B18183E9F932B8775C21CBECB9C31B64A855FF4D1B5B77E6EDBC31776FD0AD5C23E53603074C118F6936C8794BBDA7
+20210510070848 2 6 100 3071 2 EAC054F0A6595901FCD8F7F8FCC4BA738ED1B3A5EBCBA6F7616CAF48A071E1407283441719C3FE1C10D43799F3BF87492ABDBF0F3B0662504AE552C6B670DB5F75553BAEE273BEFA160C918C0C1039AAB3BC058505CA05328B198C797296B70B2F5F73BAB292EDE06955F59541F73EF820DC7F4BFD4DE54C99F16A798266472540D8819F43ED29390271A2A57785AAD3B8BC142D7F3C5A179D6E4DE94C37DC0D278807119989836DA3A8DB918A2786D41753F774F5760095306B15AF307D86E6A9681950F2510C3FB3FC39820F216EA08689D085A89434CF3D98EB5ABFFCEDCBD0E6AAFE9C9BE072814730678B9082B5B62CA113D9243C83199C940D18D748D64B929A94F68268C8D5B976A32041580B2BFFD5D5FE21A338F65FB1FC494416BA804A920AEF90353F4924D30183908D2C56ECBDC381446CB0F8F4162B3F9C050FF4B226EBFC86D7DEFFB20445255A836762B18183E9F932B8775C21CBECB9C31B64A855FF4D1B5B77E6EDBC31776FD0AD5C23E53603074C118F6936C8795478CB
+20210510071106 2 6 100 3071 5 EAC054F0A6595901FCD8F7F8FCC4BA738ED1B3A5EBCBA6F7616CAF48A071E1407283441719C3FE1C10D43799F3BF87492ABDBF0F3B0662504AE552C6B670DB5F75553BAEE273BEFA160C918C0C1039AAB3BC058505CA05328B198C797296B70B2F5F73BAB292EDE06955F59541F73EF820DC7F4BFD4DE54C99F16A798266472540D8819F43ED29390271A2A57785AAD3B8BC142D7F3C5A179D6E4DE94C37DC0D278807119989836DA3A8DB918A2786D41753F774F5760095306B15AF307D86E6A9681950F2510C3FB3FC39820F216EA08689D085A89434CF3D98EB5ABFFCEDCBD0E6AAFE9C9BE072814730678B9082B5B62CA113D9243C83199C940D18D748D64B929A94F68268C8D5B976A32041580B2BFFD5D5FE21A338F65FB1FC494416BA804A920AEF90353F4924D30183908D2C56ECBDC381446CB0F8F4162B3F9C050FF4B226EBFC86D7DEFFB20445255A836762B18183E9F932B8775C21CBECB9C31B64A855FF4D1B5B77E6EDBC31776FD0AD5C23E53603074C118F6936C879A76417
+20210510071125 2 6 100 3071 5 EAC054F0A6595901FCD8F7F8FCC4BA738ED1B3A5EBCBA6F7616CAF48A071E1407283441719C3FE1C10D43799F3BF87492ABDBF0F3B0662504AE552C6B670DB5F75553BAEE273BEFA160C918C0C1039AAB3BC058505CA05328B198C797296B70B2F5F73BAB292EDE06955F59541F73EF820DC7F4BFD4DE54C99F16A798266472540D8819F43ED29390271A2A57785AAD3B8BC142D7F3C5A179D6E4DE94C37DC0D278807119989836DA3A8DB918A2786D41753F774F5760095306B15AF307D86E6A9681950F2510C3FB3FC39820F216EA08689D085A89434CF3D98EB5ABFFCEDCBD0E6AAFE9C9BE072814730678B9082B5B62CA113D9243C83199C940D18D748D64B929A94F68268C8D5B976A32041580B2BFFD5D5FE21A338F65FB1FC494416BA804A920AEF90353F4924D30183908D2C56ECBDC381446CB0F8F4162B3F9C050FF4B226EBFC86D7DEFFB20445255A836762B18183E9F932B8775C21CBECB9C31B64A855FF4D1B5B77E6EDBC31776FD0AD5C23E53603074C118F6936C879ABD2EF
+20210510071236 2 6 100 3071 2 EAC054F0A6595901FCD8F7F8FCC4BA738ED1B3A5EBCBA6F7616CAF48A071E1407283441719C3FE1C10D43799F3BF87492ABDBF0F3B0662504AE552C6B670DB5F75553BAEE273BEFA160C918C0C1039AAB3BC058505CA05328B198C797296B70B2F5F73BAB292EDE06955F59541F73EF820DC7F4BFD4DE54C99F16A798266472540D8819F43ED29390271A2A57785AAD3B8BC142D7F3C5A179D6E4DE94C37DC0D278807119989836DA3A8DB918A2786D41753F774F5760095306B15AF307D86E6A9681950F2510C3FB3FC39820F216EA08689D085A89434CF3D98EB5ABFFCEDCBD0E6AAFE9C9BE072814730678B9082B5B62CA113D9243C83199C940D18D748D64B929A94F68268C8D5B976A32041580B2BFFD5D5FE21A338F65FB1FC494416BA804A920AEF90353F4924D30183908D2C56ECBDC381446CB0F8F4162B3F9C050FF4B226EBFC86D7DEFFB20445255A836762B18183E9F932B8775C21CBECB9C31B64A855FF4D1B5B77E6EDBC31776FD0AD5C23E53603074C118F6936C879D1F7B3
+20210510071324 2 6 100 3071 2 EAC054F0A6595901FCD8F7F8FCC4BA738ED1B3A5EBCBA6F7616CAF48A071E1407283441719C3FE1C10D43799F3BF87492ABDBF0F3B0662504AE552C6B670DB5F75553BAEE273BEFA160C918C0C1039AAB3BC058505CA05328B198C797296B70B2F5F73BAB292EDE06955F59541F73EF820DC7F4BFD4DE54C99F16A798266472540D8819F43ED29390271A2A57785AAD3B8BC142D7F3C5A179D6E4DE94C37DC0D278807119989836DA3A8DB918A2786D41753F774F5760095306B15AF307D86E6A9681950F2510C3FB3FC39820F216EA08689D085A89434CF3D98EB5ABFFCEDCBD0E6AAFE9C9BE072814730678B9082B5B62CA113D9243C83199C940D18D748D64B929A94F68268C8D5B976A32041580B2BFFD5D5FE21A338F65FB1FC494416BA804A920AEF90353F4924D30183908D2C56ECBDC381446CB0F8F4162B3F9C050FF4B226EBFC86D7DEFFB20445255A836762B18183E9F932B8775C21CBECB9C31B64A855FF4D1B5B77E6EDBC31776FD0AD5C23E53603074C118F6936C879EA4373
+20210510071838 2 6 100 3071 2 EAC054F0A6595901FCD8F7F8FCC4BA738ED1B3A5EBCBA6F7616CAF48A071E1407283441719C3FE1C10D43799F3BF87492ABDBF0F3B0662504AE552C6B670DB5F75553BAEE273BEFA160C918C0C1039AAB3BC058505CA05328B198C797296B70B2F5F73BAB292EDE06955F59541F73EF820DC7F4BFD4DE54C99F16A798266472540D8819F43ED29390271A2A57785AAD3B8BC142D7F3C5A179D6E4DE94C37DC0D278807119989836DA3A8DB918A2786D41753F774F5760095306B15AF307D86E6A9681950F2510C3FB3FC39820F216EA08689D085A89434CF3D98EB5ABFFCEDCBD0E6AAFE9C9BE072814730678B9082B5B62CA113D9243C83199C940D18D748D64B929A94F68268C8D5B976A32041580B2BFFD5D5FE21A338F65FB1FC494416BA804A920AEF90353F4924D30183908D2C56ECBDC381446CB0F8F4162B3F9C050FF4B226EBFC86D7DEFFB20445255A836762B18183E9F932B8775C21CBECB9C31B64A855FF4D1B5B77E6EDBC31776FD0AD5C23E53603074C118F6936C87AB188F3
+20210510072228 2 6 100 3071 5 EAC054F0A6595901FCD8F7F8FCC4BA738ED1B3A5EBCBA6F7616CAF48A071E1407283441719C3FE1C10D43799F3BF87492ABDBF0F3B0662504AE552C6B670DB5F75553BAEE273BEFA160C918C0C1039AAB3BC058505CA05328B198C797296B70B2F5F73BAB292EDE06955F59541F73EF820DC7F4BFD4DE54C99F16A798266472540D8819F43ED29390271A2A57785AAD3B8BC142D7F3C5A179D6E4DE94C37DC0D278807119989836DA3A8DB918A2786D41753F774F5760095306B15AF307D86E6A9681950F2510C3FB3FC39820F216EA08689D085A89434CF3D98EB5ABFFCEDCBD0E6AAFE9C9BE072814730678B9082B5B62CA113D9243C83199C940D18D748D64B929A94F68268C8D5B976A32041580B2BFFD5D5FE21A338F65FB1FC494416BA804A920AEF90353F4924D30183908D2C56ECBDC381446CB0F8F4162B3F9C050FF4B226EBFC86D7DEFFB20445255A836762B18183E9F932B8775C21CBECB9C31B64A855FF4D1B5B77E6EDBC31776FD0AD5C23E53603074C118F6936C87B417867
+20210510072939 2 6 100 3071 5 EAC054F0A6595901FCD8F7F8FCC4BA738ED1B3A5EBCBA6F7616CAF48A071E1407283441719C3FE1C10D43799F3BF87492ABDBF0F3B0662504AE552C6B670DB5F75553BAEE273BEFA160C918C0C1039AAB3BC058505CA05328B198C797296B70B2F5F73BAB292EDE06955F59541F73EF820DC7F4BFD4DE54C99F16A798266472540D8819F43ED29390271A2A57785AAD3B8BC142D7F3C5A179D6E4DE94C37DC0D278807119989836DA3A8DB918A2786D41753F774F5760095306B15AF307D86E6A9681950F2510C3FB3FC39820F216EA08689D085A89434CF3D98EB5ABFFCEDCBD0E6AAFE9C9BE072814730678B9082B5B62CA113D9243C83199C940D18D748D64B929A94F68268C8D5B976A32041580B2BFFD5D5FE21A338F65FB1FC494416BA804A920AEF90353F4924D30183908D2C56ECBDC381446CB0F8F4162B3F9C050FF4B226EBFC86D7DEFFB20445255A836762B18183E9F932B8775C21CBECB9C31B64A855FF4D1B5B77E6EDBC31776FD0AD5C23E53603074C118F6936C87C51C617
+20210510073226 2 6 100 3071 2 EAC054F0A6595901FCD8F7F8FCC4BA738ED1B3A5EBCBA6F7616CAF48A071E1407283441719C3FE1C10D43799F3BF87492ABDBF0F3B0662504AE552C6B670DB5F75553BAEE273BEFA160C918C0C1039AAB3BC058505CA05328B198C797296B70B2F5F73BAB292EDE06955F59541F73EF820DC7F4BFD4DE54C99F16A798266472540D8819F43ED29390271A2A57785AAD3B8BC142D7F3C5A179D6E4DE94C37DC0D278807119989836DA3A8DB918A2786D41753F774F5760095306B15AF307D86E6A9681950F2510C3FB3FC39820F216EA08689D085A89434CF3D98EB5ABFFCEDCBD0E6AAFE9C9BE072814730678B9082B5B62CA113D9243C83199C940D18D748D64B929A94F68268C8D5B976A32041580B2BFFD5D5FE21A338F65FB1FC494416BA804A920AEF90353F4924D30183908D2C56ECBDC381446CB0F8F4162B3F9C050FF4B226EBFC86D7DEFFB20445255A836762B18183E9F932B8775C21CBECB9C31B64A855FF4D1B5B77E6EDBC31776FD0AD5C23E53603074C118F6936C87CB8ECB3
+20210510073413 2 6 100 3071 5 E2F748529B9B801FBAF3AE42C75013A5C4C959A756D496B01A6E1145DB55AA31F408A8DEA8B8573506C76D8AF81C9A3F4D5D4B838D34C30C54D3886448581ABD74D6D95F8B0D4DA21A8E3C6D127657A93354E028D65AC9CFFBCFBD0DEC0EA4F7CBB1018C9618612FB2A5837631AFC614AD2D5FC45EC872EC8816CCB96841A4DC14307159F83F694C90472DA3BB20E9EAC91D1F21770CDC6A037855520D80102005651A54BF12D9BAB8ADB4149ED37B5BD851825B596887DC4E47E55FC0D7B3AE7FFA43F95CCE340942FBEC7E593A16AEAC11CA1136902A2917BC096E8B16CA28D0AC2A58B46DA69B9908CFDB5DC16B391B4DD5C1A8346DB2CDB22447E44FF1567D85B90CD8016029C33D9DE2C992AC73A8155693DDE84FCBB760D88FEA847AEB13EF8058E11E81A7ED0666794272E362F60EF252BD5E3890D85EB6297F99BFA82A7FA94F33EC9804D02E50C56C7856C7B923987825C79A22BF9188AC61E936AC48A40B73EBE61C1C8724315AEA4D1E5AB2889C2251F9A771493955AC5861ADE7
+20210510074044 2 6 100 3071 2 E2F748529B9B801FBAF3AE42C75013A5C4C959A756D496B01A6E1145DB55AA31F408A8DEA8B8573506C76D8AF81C9A3F4D5D4B838D34C30C54D3886448581ABD74D6D95F8B0D4DA21A8E3C6D127657A93354E028D65AC9CFFBCFBD0DEC0EA4F7CBB1018C9618612FB2A5837631AFC614AD2D5FC45EC872EC8816CCB96841A4DC14307159F83F694C90472DA3BB20E9EAC91D1F21770CDC6A037855520D80102005651A54BF12D9BAB8ADB4149ED37B5BD851825B596887DC4E47E55FC0D7B3AE7FFA43F95CCE340942FBEC7E593A16AEAC11CA1136902A2917BC096E8B16CA28D0AC2A58B46DA69B9908CFDB5DC16B391B4DD5C1A8346DB2CDB22447E44FF1567D85B90CD8016029C33D9DE2C992AC73A8155693DDE84FCBB760D88FEA847AEB13EF8058E11E81A7ED0666794272E362F60EF252BD5E3890D85EB6297F99BFA82A7FA94F33EC9804D02E50C56C7856C7B923987825C79A22BF9188AC61E936AC48A40B73EBE61C1C8724315AEA4D1E5AB2889C2251F9A771493955AC5964B90B
+20210510074255 2 6 100 3071 2 E2F748529B9B801FBAF3AE42C75013A5C4C959A756D496B01A6E1145DB55AA31F408A8DEA8B8573506C76D8AF81C9A3F4D5D4B838D34C30C54D3886448581ABD74D6D95F8B0D4DA21A8E3C6D127657A93354E028D65AC9CFFBCFBD0DEC0EA4F7CBB1018C9618612FB2A5837631AFC614AD2D5FC45EC872EC8816CCB96841A4DC14307159F83F694C90472DA3BB20E9EAC91D1F21770CDC6A037855520D80102005651A54BF12D9BAB8ADB4149ED37B5BD851825B596887DC4E47E55FC0D7B3AE7FFA43F95CCE340942FBEC7E593A16AEAC11CA1136902A2917BC096E8B16CA28D0AC2A58B46DA69B9908CFDB5DC16B391B4DD5C1A8346DB2CDB22447E44FF1567D85B90CD8016029C33D9DE2C992AC73A8155693DDE84FCBB760D88FEA847AEB13EF8058E11E81A7ED0666794272E362F60EF252BD5E3890D85EB6297F99BFA82A7FA94F33EC9804D02E50C56C7856C7B923987825C79A22BF9188AC61E936AC48A40B73EBE61C1C8724315AEA4D1E5AB2889C2251F9A771493955AC59B421B3
+20210510074440 2 6 100 3071 5 E2F748529B9B801FBAF3AE42C75013A5C4C959A756D496B01A6E1145DB55AA31F408A8DEA8B8573506C76D8AF81C9A3F4D5D4B838D34C30C54D3886448581ABD74D6D95F8B0D4DA21A8E3C6D127657A93354E028D65AC9CFFBCFBD0DEC0EA4F7CBB1018C9618612FB2A5837631AFC614AD2D5FC45EC872EC8816CCB96841A4DC14307159F83F694C90472DA3BB20E9EAC91D1F21770CDC6A037855520D80102005651A54BF12D9BAB8ADB4149ED37B5BD851825B596887DC4E47E55FC0D7B3AE7FFA43F95CCE340942FBEC7E593A16AEAC11CA1136902A2917BC096E8B16CA28D0AC2A58B46DA69B9908CFDB5DC16B391B4DD5C1A8346DB2CDB22447E44FF1567D85B90CD8016029C33D9DE2C992AC73A8155693DDE84FCBB760D88FEA847AEB13EF8058E11E81A7ED0666794272E362F60EF252BD5E3890D85EB6297F99BFA82A7FA94F33EC9804D02E50C56C7856C7B923987825C79A22BF9188AC61E936AC48A40B73EBE61C1C8724315AEA4D1E5AB2889C2251F9A771493955AC59F2A617
+20210510074524 2 6 100 3071 2 E2F748529B9B801FBAF3AE42C75013A5C4C959A756D496B01A6E1145DB55AA31F408A8DEA8B8573506C76D8AF81C9A3F4D5D4B838D34C30C54D3886448581ABD74D6D95F8B0D4DA21A8E3C6D127657A93354E028D65AC9CFFBCFBD0DEC0EA4F7CBB1018C9618612FB2A5837631AFC614AD2D5FC45EC872EC8816CCB96841A4DC14307159F83F694C90472DA3BB20E9EAC91D1F21770CDC6A037855520D80102005651A54BF12D9BAB8ADB4149ED37B5BD851825B596887DC4E47E55FC0D7B3AE7FFA43F95CCE340942FBEC7E593A16AEAC11CA1136902A2917BC096E8B16CA28D0AC2A58B46DA69B9908CFDB5DC16B391B4DD5C1A8346DB2CDB22447E44FF1567D85B90CD8016029C33D9DE2C992AC73A8155693DDE84FCBB760D88FEA847AEB13EF8058E11E81A7ED0666794272E362F60EF252BD5E3890D85EB6297F99BFA82A7FA94F33EC9804D02E50C56C7856C7B923987825C79A22BF9188AC61E936AC48A40B73EBE61C1C8724315AEA4D1E5AB2889C2251F9A771493955AC5A07E733
+20210510074635 2 6 100 3071 2 E2F748529B9B801FBAF3AE42C75013A5C4C959A756D496B01A6E1145DB55AA31F408A8DEA8B8573506C76D8AF81C9A3F4D5D4B838D34C30C54D3886448581ABD74D6D95F8B0D4DA21A8E3C6D127657A93354E028D65AC9CFFBCFBD0DEC0EA4F7CBB1018C9618612FB2A5837631AFC614AD2D5FC45EC872EC8816CCB96841A4DC14307159F83F694C90472DA3BB20E9EAC91D1F21770CDC6A037855520D80102005651A54BF12D9BAB8ADB4149ED37B5BD851825B596887DC4E47E55FC0D7B3AE7FFA43F95CCE340942FBEC7E593A16AEAC11CA1136902A2917BC096E8B16CA28D0AC2A58B46DA69B9908CFDB5DC16B391B4DD5C1A8346DB2CDB22447E44FF1567D85B90CD8016029C33D9DE2C992AC73A8155693DDE84FCBB760D88FEA847AEB13EF8058E11E81A7ED0666794272E362F60EF252BD5E3890D85EB6297F99BFA82A7FA94F33EC9804D02E50C56C7856C7B923987825C79A22BF9188AC61E936AC48A40B73EBE61C1C8724315AEA4D1E5AB2889C2251F9A771493955AC5A2EFED3
+20210510074720 2 6 100 3071 2 E2F748529B9B801FBAF3AE42C75013A5C4C959A756D496B01A6E1145DB55AA31F408A8DEA8B8573506C76D8AF81C9A3F4D5D4B838D34C30C54D3886448581ABD74D6D95F8B0D4DA21A8E3C6D127657A93354E028D65AC9CFFBCFBD0DEC0EA4F7CBB1018C9618612FB2A5837631AFC614AD2D5FC45EC872EC8816CCB96841A4DC14307159F83F694C90472DA3BB20E9EAC91D1F21770CDC6A037855520D80102005651A54BF12D9BAB8ADB4149ED37B5BD851825B596887DC4E47E55FC0D7B3AE7FFA43F95CCE340942FBEC7E593A16AEAC11CA1136902A2917BC096E8B16CA28D0AC2A58B46DA69B9908CFDB5DC16B391B4DD5C1A8346DB2CDB22447E44FF1567D85B90CD8016029C33D9DE2C992AC73A8155693DDE84FCBB760D88FEA847AEB13EF8058E11E81A7ED0666794272E362F60EF252BD5E3890D85EB6297F99BFA82A7FA94F33EC9804D02E50C56C7856C7B923987825C79A22BF9188AC61E936AC48A40B73EBE61C1C8724315AEA4D1E5AB2889C2251F9A771493955AC5A47453B
+20210510074829 2 6 100 3071 2 E2F748529B9B801FBAF3AE42C75013A5C4C959A756D496B01A6E1145DB55AA31F408A8DEA8B8573506C76D8AF81C9A3F4D5D4B838D34C30C54D3886448581ABD74D6D95F8B0D4DA21A8E3C6D127657A93354E028D65AC9CFFBCFBD0DEC0EA4F7CBB1018C9618612FB2A5837631AFC614AD2D5FC45EC872EC8816CCB96841A4DC14307159F83F694C90472DA3BB20E9EAC91D1F21770CDC6A037855520D80102005651A54BF12D9BAB8ADB4149ED37B5BD851825B596887DC4E47E55FC0D7B3AE7FFA43F95CCE340942FBEC7E593A16AEAC11CA1136902A2917BC096E8B16CA28D0AC2A58B46DA69B9908CFDB5DC16B391B4DD5C1A8346DB2CDB22447E44FF1567D85B90CD8016029C33D9DE2C992AC73A8155693DDE84FCBB760D88FEA847AEB13EF8058E11E81A7ED0666794272E362F60EF252BD5E3890D85EB6297F99BFA82A7FA94F33EC9804D02E50C56C7856C7B923987825C79A22BF9188AC61E936AC48A40B73EBE61C1C8724315AEA4D1E5AB2889C2251F9A771493955AC5A6E33CB
+20210510075104 2 6 100 3071 2 E2F748529B9B801FBAF3AE42C75013A5C4C959A756D496B01A6E1145DB55AA31F408A8DEA8B8573506C76D8AF81C9A3F4D5D4B838D34C30C54D3886448581ABD74D6D95F8B0D4DA21A8E3C6D127657A93354E028D65AC9CFFBCFBD0DEC0EA4F7CBB1018C9618612FB2A5837631AFC614AD2D5FC45EC872EC8816CCB96841A4DC14307159F83F694C90472DA3BB20E9EAC91D1F21770CDC6A037855520D80102005651A54BF12D9BAB8ADB4149ED37B5BD851825B596887DC4E47E55FC0D7B3AE7FFA43F95CCE340942FBEC7E593A16AEAC11CA1136902A2917BC096E8B16CA28D0AC2A58B46DA69B9908CFDB5DC16B391B4DD5C1A8346DB2CDB22447E44FF1567D85B90CD8016029C33D9DE2C992AC73A8155693DDE84FCBB760D88FEA847AEB13EF8058E11E81A7ED0666794272E362F60EF252BD5E3890D85EB6297F99BFA82A7FA94F33EC9804D02E50C56C7856C7B923987825C79A22BF9188AC61E936AC48A40B73EBE61C1C8724315AEA4D1E5AB2889C2251F9A771493955AC5ACF8A13
+20210510075335 2 6 100 3071 2 E2F748529B9B801FBAF3AE42C75013A5C4C959A756D496B01A6E1145DB55AA31F408A8DEA8B8573506C76D8AF81C9A3F4D5D4B838D34C30C54D3886448581ABD74D6D95F8B0D4DA21A8E3C6D127657A93354E028D65AC9CFFBCFBD0DEC0EA4F7CBB1018C9618612FB2A5837631AFC614AD2D5FC45EC872EC8816CCB96841A4DC14307159F83F694C90472DA3BB20E9EAC91D1F21770CDC6A037855520D80102005651A54BF12D9BAB8ADB4149ED37B5BD851825B596887DC4E47E55FC0D7B3AE7FFA43F95CCE340942FBEC7E593A16AEAC11CA1136902A2917BC096E8B16CA28D0AC2A58B46DA69B9908CFDB5DC16B391B4DD5C1A8346DB2CDB22447E44FF1567D85B90CD8016029C33D9DE2C992AC73A8155693DDE84FCBB760D88FEA847AEB13EF8058E11E81A7ED0666794272E362F60EF252BD5E3890D85EB6297F99BFA82A7FA94F33EC9804D02E50C56C7856C7B923987825C79A22BF9188AC61E936AC48A40B73EBE61C1C8724315AEA4D1E5AB2889C2251F9A771493955AC5B2E9B03
+20210510075857 2 6 100 3071 2 E2F748529B9B801FBAF3AE42C75013A5C4C959A756D496B01A6E1145DB55AA31F408A8DEA8B8573506C76D8AF81C9A3F4D5D4B838D34C30C54D3886448581ABD74D6D95F8B0D4DA21A8E3C6D127657A93354E028D65AC9CFFBCFBD0DEC0EA4F7CBB1018C9618612FB2A5837631AFC614AD2D5FC45EC872EC8816CCB96841A4DC14307159F83F694C90472DA3BB20E9EAC91D1F21770CDC6A037855520D80102005651A54BF12D9BAB8ADB4149ED37B5BD851825B596887DC4E47E55FC0D7B3AE7FFA43F95CCE340942FBEC7E593A16AEAC11CA1136902A2917BC096E8B16CA28D0AC2A58B46DA69B9908CFDB5DC16B391B4DD5C1A8346DB2CDB22447E44FF1567D85B90CD8016029C33D9DE2C992AC73A8155693DDE84FCBB760D88FEA847AEB13EF8058E11E81A7ED0666794272E362F60EF252BD5E3890D85EB6297F99BFA82A7FA94F33EC9804D02E50C56C7856C7B923987825C79A22BF9188AC61E936AC48A40B73EBE61C1C8724315AEA4D1E5AB2889C2251F9A771493955AC5C027EC3
+20210510080304 2 6 100 3071 2 E2F748529B9B801FBAF3AE42C75013A5C4C959A756D496B01A6E1145DB55AA31F408A8DEA8B8573506C76D8AF81C9A3F4D5D4B838D34C30C54D3886448581ABD74D6D95F8B0D4DA21A8E3C6D127657A93354E028D65AC9CFFBCFBD0DEC0EA4F7CBB1018C9618612FB2A5837631AFC614AD2D5FC45EC872EC8816CCB96841A4DC14307159F83F694C90472DA3BB20E9EAC91D1F21770CDC6A037855520D80102005651A54BF12D9BAB8ADB4149ED37B5BD851825B596887DC4E47E55FC0D7B3AE7FFA43F95CCE340942FBEC7E593A16AEAC11CA1136902A2917BC096E8B16CA28D0AC2A58B46DA69B9908CFDB5DC16B391B4DD5C1A8346DB2CDB22447E44FF1567D85B90CD8016029C33D9DE2C992AC73A8155693DDE84FCBB760D88FEA847AEB13EF8058E11E81A7ED0666794272E362F60EF252BD5E3890D85EB6297F99BFA82A7FA94F33EC9804D02E50C56C7856C7B923987825C79A22BF9188AC61E936AC48A40B73EBE61C1C8724315AEA4D1E5AB2889C2251F9A771493955AC5CA07843
+20210510080325 2 6 100 3071 5 E2F748529B9B801FBAF3AE42C75013A5C4C959A756D496B01A6E1145DB55AA31F408A8DEA8B8573506C76D8AF81C9A3F4D5D4B838D34C30C54D3886448581ABD74D6D95F8B0D4DA21A8E3C6D127657A93354E028D65AC9CFFBCFBD0DEC0EA4F7CBB1018C9618612FB2A5837631AFC614AD2D5FC45EC872EC8816CCB96841A4DC14307159F83F694C90472DA3BB20E9EAC91D1F21770CDC6A037855520D80102005651A54BF12D9BAB8ADB4149ED37B5BD851825B596887DC4E47E55FC0D7B3AE7FFA43F95CCE340942FBEC7E593A16AEAC11CA1136902A2917BC096E8B16CA28D0AC2A58B46DA69B9908CFDB5DC16B391B4DD5C1A8346DB2CDB22447E44FF1567D85B90CD8016029C33D9DE2C992AC73A8155693DDE84FCBB760D88FEA847AEB13EF8058E11E81A7ED0666794272E362F60EF252BD5E3890D85EB6297F99BFA82A7FA94F33EC9804D02E50C56C7856C7B923987825C79A22BF9188AC61E936AC48A40B73EBE61C1C8724315AEA4D1E5AB2889C2251F9A771493955AC5CA5F02F
+20210510080534 2 6 100 3071 5 E2F748529B9B801FBAF3AE42C75013A5C4C959A756D496B01A6E1145DB55AA31F408A8DEA8B8573506C76D8AF81C9A3F4D5D4B838D34C30C54D3886448581ABD74D6D95F8B0D4DA21A8E3C6D127657A93354E028D65AC9CFFBCFBD0DEC0EA4F7CBB1018C9618612FB2A5837631AFC614AD2D5FC45EC872EC8816CCB96841A4DC14307159F83F694C90472DA3BB20E9EAC91D1F21770CDC6A037855520D80102005651A54BF12D9BAB8ADB4149ED37B5BD851825B596887DC4E47E55FC0D7B3AE7FFA43F95CCE340942FBEC7E593A16AEAC11CA1136902A2917BC096E8B16CA28D0AC2A58B46DA69B9908CFDB5DC16B391B4DD5C1A8346DB2CDB22447E44FF1567D85B90CD8016029C33D9DE2C992AC73A8155693DDE84FCBB760D88FEA847AEB13EF8058E11E81A7ED0666794272E362F60EF252BD5E3890D85EB6297F99BFA82A7FA94F33EC9804D02E50C56C7856C7B923987825C79A22BF9188AC61E936AC48A40B73EBE61C1C8724315AEA4D1E5AB2889C2251F9A771493955AC5CF54017
+20210510080630 2 6 100 3071 5 E2F748529B9B801FBAF3AE42C75013A5C4C959A756D496B01A6E1145DB55AA31F408A8DEA8B8573506C76D8AF81C9A3F4D5D4B838D34C30C54D3886448581ABD74D6D95F8B0D4DA21A8E3C6D127657A93354E028D65AC9CFFBCFBD0DEC0EA4F7CBB1018C9618612FB2A5837631AFC614AD2D5FC45EC872EC8816CCB96841A4DC14307159F83F694C90472DA3BB20E9EAC91D1F21770CDC6A037855520D80102005651A54BF12D9BAB8ADB4149ED37B5BD851825B596887DC4E47E55FC0D7B3AE7FFA43F95CCE340942FBEC7E593A16AEAC11CA1136902A2917BC096E8B16CA28D0AC2A58B46DA69B9908CFDB5DC16B391B4DD5C1A8346DB2CDB22447E44FF1567D85B90CD8016029C33D9DE2C992AC73A8155693DDE84FCBB760D88FEA847AEB13EF8058E11E81A7ED0666794272E362F60EF252BD5E3890D85EB6297F99BFA82A7FA94F33EC9804D02E50C56C7856C7B923987825C79A22BF9188AC61E936AC48A40B73EBE61C1C8724315AEA4D1E5AB2889C2251F9A771493955AC5D12D9E7
+20210510080911 2 6 100 3071 5 E2F748529B9B801FBAF3AE42C75013A5C4C959A756D496B01A6E1145DB55AA31F408A8DEA8B8573506C76D8AF81C9A3F4D5D4B838D34C30C54D3886448581ABD74D6D95F8B0D4DA21A8E3C6D127657A93354E028D65AC9CFFBCFBD0DEC0EA4F7CBB1018C9618612FB2A5837631AFC614AD2D5FC45EC872EC8816CCB96841A4DC14307159F83F694C90472DA3BB20E9EAC91D1F21770CDC6A037855520D80102005651A54BF12D9BAB8ADB4149ED37B5BD851825B596887DC4E47E55FC0D7B3AE7FFA43F95CCE340942FBEC7E593A16AEAC11CA1136902A2917BC096E8B16CA28D0AC2A58B46DA69B9908CFDB5DC16B391B4DD5C1A8346DB2CDB22447E44FF1567D85B90CD8016029C33D9DE2C992AC73A8155693DDE84FCBB760D88FEA847AEB13EF8058E11E81A7ED0666794272E362F60EF252BD5E3890D85EB6297F99BFA82A7FA94F33EC9804D02E50C56C7856C7B923987825C79A22BF9188AC61E936AC48A40B73EBE61C1C8724315AEA4D1E5AB2889C2251F9A771493955AC5D77D397
+20210510081204 2 6 100 3071 5 E2F748529B9B801FBAF3AE42C75013A5C4C959A756D496B01A6E1145DB55AA31F408A8DEA8B8573506C76D8AF81C9A3F4D5D4B838D34C30C54D3886448581ABD74D6D95F8B0D4DA21A8E3C6D127657A93354E028D65AC9CFFBCFBD0DEC0EA4F7CBB1018C9618612FB2A5837631AFC614AD2D5FC45EC872EC8816CCB96841A4DC14307159F83F694C90472DA3BB20E9EAC91D1F21770CDC6A037855520D80102005651A54BF12D9BAB8ADB4149ED37B5BD851825B596887DC4E47E55FC0D7B3AE7FFA43F95CCE340942FBEC7E593A16AEAC11CA1136902A2917BC096E8B16CA28D0AC2A58B46DA69B9908CFDB5DC16B391B4DD5C1A8346DB2CDB22447E44FF1567D85B90CD8016029C33D9DE2C992AC73A8155693DDE84FCBB760D88FEA847AEB13EF8058E11E81A7ED0666794272E362F60EF252BD5E3890D85EB6297F99BFA82A7FA94F33EC9804D02E50C56C7856C7B923987825C79A22BF9188AC61E936AC48A40B73EBE61C1C8724315AEA4D1E5AB2889C2251F9A771493955AC5DE0D19F
+20210510081331 2 6 100 3071 2 E2F748529B9B801FBAF3AE42C75013A5C4C959A756D496B01A6E1145DB55AA31F408A8DEA8B8573506C76D8AF81C9A3F4D5D4B838D34C30C54D3886448581ABD74D6D95F8B0D4DA21A8E3C6D127657A93354E028D65AC9CFFBCFBD0DEC0EA4F7CBB1018C9618612FB2A5837631AFC614AD2D5FC45EC872EC8816CCB96841A4DC14307159F83F694C90472DA3BB20E9EAC91D1F21770CDC6A037855520D80102005651A54BF12D9BAB8ADB4149ED37B5BD851825B596887DC4E47E55FC0D7B3AE7FFA43F95CCE340942FBEC7E593A16AEAC11CA1136902A2917BC096E8B16CA28D0AC2A58B46DA69B9908CFDB5DC16B391B4DD5C1A8346DB2CDB22447E44FF1567D85B90CD8016029C33D9DE2C992AC73A8155693DDE84FCBB760D88FEA847AEB13EF8058E11E81A7ED0666794272E362F60EF252BD5E3890D85EB6297F99BFA82A7FA94F33EC9804D02E50C56C7856C7B923987825C79A22BF9188AC61E936AC48A40B73EBE61C1C8724315AEA4D1E5AB2889C2251F9A771493955AC5E111063
+20210510081720 2 6 100 3071 5 E2F748529B9B801FBAF3AE42C75013A5C4C959A756D496B01A6E1145DB55AA31F408A8DEA8B8573506C76D8AF81C9A3F4D5D4B838D34C30C54D3886448581ABD74D6D95F8B0D4DA21A8E3C6D127657A93354E028D65AC9CFFBCFBD0DEC0EA4F7CBB1018C9618612FB2A5837631AFC614AD2D5FC45EC872EC8816CCB96841A4DC14307159F83F694C90472DA3BB20E9EAC91D1F21770CDC6A037855520D80102005651A54BF12D9BAB8ADB4149ED37B5BD851825B596887DC4E47E55FC0D7B3AE7FFA43F95CCE340942FBEC7E593A16AEAC11CA1136902A2917BC096E8B16CA28D0AC2A58B46DA69B9908CFDB5DC16B391B4DD5C1A8346DB2CDB22447E44FF1567D85B90CD8016029C33D9DE2C992AC73A8155693DDE84FCBB760D88FEA847AEB13EF8058E11E81A7ED0666794272E362F60EF252BD5E3890D85EB6297F99BFA82A7FA94F33EC9804D02E50C56C7856C7B923987825C79A22BF9188AC61E936AC48A40B73EBE61C1C8724315AEA4D1E5AB2889C2251F9A771493955AC5EA68ABF
+20210510081858 2 6 100 3071 2 E2F748529B9B801FBAF3AE42C75013A5C4C959A756D496B01A6E1145DB55AA31F408A8DEA8B8573506C76D8AF81C9A3F4D5D4B838D34C30C54D3886448581ABD74D6D95F8B0D4DA21A8E3C6D127657A93354E028D65AC9CFFBCFBD0DEC0EA4F7CBB1018C9618612FB2A5837631AFC614AD2D5FC45EC872EC8816CCB96841A4DC14307159F83F694C90472DA3BB20E9EAC91D1F21770CDC6A037855520D80102005651A54BF12D9BAB8ADB4149ED37B5BD851825B596887DC4E47E55FC0D7B3AE7FFA43F95CCE340942FBEC7E593A16AEAC11CA1136902A2917BC096E8B16CA28D0AC2A58B46DA69B9908CFDB5DC16B391B4DD5C1A8346DB2CDB22447E44FF1567D85B90CD8016029C33D9DE2C992AC73A8155693DDE84FCBB760D88FEA847AEB13EF8058E11E81A7ED0666794272E362F60EF252BD5E3890D85EB6297F99BFA82A7FA94F33EC9804D02E50C56C7856C7B923987825C79A22BF9188AC61E936AC48A40B73EBE61C1C8724315AEA4D1E5AB2889C2251F9A771493955AC5EE2D9A3
+20210510082830 2 6 100 3071 2 E2F748529B9B801FBAF3AE42C75013A5C4C959A756D496B01A6E1145DB55AA31F408A8DEA8B8573506C76D8AF81C9A3F4D5D4B838D34C30C54D3886448581ABD74D6D95F8B0D4DA21A8E3C6D127657A93354E028D65AC9CFFBCFBD0DEC0EA4F7CBB1018C9618612FB2A5837631AFC614AD2D5FC45EC872EC8816CCB96841A4DC14307159F83F694C90472DA3BB20E9EAC91D1F21770CDC6A037855520D80102005651A54BF12D9BAB8ADB4149ED37B5BD851825B596887DC4E47E55FC0D7B3AE7FFA43F95CCE340942FBEC7E593A16AEAC11CA1136902A2917BC096E8B16CA28D0AC2A58B46DA69B9908CFDB5DC16B391B4DD5C1A8346DB2CDB22447E44FF1567D85B90CD8016029C33D9DE2C992AC73A8155693DDE84FCBB760D88FEA847AEB13EF8058E11E81A7ED0666794272E362F60EF252BD5E3890D85EB6297F99BFA82A7FA94F33EC9804D02E50C56C7856C7B923987825C79A22BF9188AC61E936AC48A40B73EBE61C1C8724315AEA4D1E5AB2889C2251F9A771493955AC60582ADB
+20210510083201 2 6 100 3071 2 E2F748529B9B801FBAF3AE42C75013A5C4C959A756D496B01A6E1145DB55AA31F408A8DEA8B8573506C76D8AF81C9A3F4D5D4B838D34C30C54D3886448581ABD74D6D95F8B0D4DA21A8E3C6D127657A93354E028D65AC9CFFBCFBD0DEC0EA4F7CBB1018C9618612FB2A5837631AFC614AD2D5FC45EC872EC8816CCB96841A4DC14307159F83F694C90472DA3BB20E9EAC91D1F21770CDC6A037855520D80102005651A54BF12D9BAB8ADB4149ED37B5BD851825B596887DC4E47E55FC0D7B3AE7FFA43F95CCE340942FBEC7E593A16AEAC11CA1136902A2917BC096E8B16CA28D0AC2A58B46DA69B9908CFDB5DC16B391B4DD5C1A8346DB2CDB22447E44FF1567D85B90CD8016029C33D9DE2C992AC73A8155693DDE84FCBB760D88FEA847AEB13EF8058E11E81A7ED0666794272E362F60EF252BD5E3890D85EB6297F99BFA82A7FA94F33EC9804D02E50C56C7856C7B923987825C79A22BF9188AC61E936AC48A40B73EBE61C1C8724315AEA4D1E5AB2889C2251F9A771493955AC60E0CE7B
+20210510083743 2 6 100 3071 2 E2F748529B9B801FBAF3AE42C75013A5C4C959A756D496B01A6E1145DB55AA31F408A8DEA8B8573506C76D8AF81C9A3F4D5D4B838D34C30C54D3886448581ABD74D6D95F8B0D4DA21A8E3C6D127657A93354E028D65AC9CFFBCFBD0DEC0EA4F7CBB1018C9618612FB2A5837631AFC614AD2D5FC45EC872EC8816CCB96841A4DC14307159F83F694C90472DA3BB20E9EAC91D1F21770CDC6A037855520D80102005651A54BF12D9BAB8ADB4149ED37B5BD851825B596887DC4E47E55FC0D7B3AE7FFA43F95CCE340942FBEC7E593A16AEAC11CA1136902A2917BC096E8B16CA28D0AC2A58B46DA69B9908CFDB5DC16B391B4DD5C1A8346DB2CDB22447E44FF1567D85B90CD8016029C33D9DE2C992AC73A8155693DDE84FCBB760D88FEA847AEB13EF8058E11E81A7ED0666794272E362F60EF252BD5E3890D85EB6297F99BFA82A7FA94F33EC9804D02E50C56C7856C7B923987825C79A22BF9188AC61E936AC48A40B73EBE61C1C8724315AEA4D1E5AB2889C2251F9A771493955AC61BA35A3
+20210510083915 2 6 100 3071 2 E2F748529B9B801FBAF3AE42C75013A5C4C959A756D496B01A6E1145DB55AA31F408A8DEA8B8573506C76D8AF81C9A3F4D5D4B838D34C30C54D3886448581ABD74D6D95F8B0D4DA21A8E3C6D127657A93354E028D65AC9CFFBCFBD0DEC0EA4F7CBB1018C9618612FB2A5837631AFC614AD2D5FC45EC872EC8816CCB96841A4DC14307159F83F694C90472DA3BB20E9EAC91D1F21770CDC6A037855520D80102005651A54BF12D9BAB8ADB4149ED37B5BD851825B596887DC4E47E55FC0D7B3AE7FFA43F95CCE340942FBEC7E593A16AEAC11CA1136902A2917BC096E8B16CA28D0AC2A58B46DA69B9908CFDB5DC16B391B4DD5C1A8346DB2CDB22447E44FF1567D85B90CD8016029C33D9DE2C992AC73A8155693DDE84FCBB760D88FEA847AEB13EF8058E11E81A7ED0666794272E362F60EF252BD5E3890D85EB6297F99BFA82A7FA94F33EC9804D02E50C56C7856C7B923987825C79A22BF9188AC61E936AC48A40B73EBE61C1C8724315AEA4D1E5AB2889C2251F9A771493955AC61EDA4A3
+20210510083946 2 6 100 3071 2 E2F748529B9B801FBAF3AE42C75013A5C4C959A756D496B01A6E1145DB55AA31F408A8DEA8B8573506C76D8AF81C9A3F4D5D4B838D34C30C54D3886448581ABD74D6D95F8B0D4DA21A8E3C6D127657A93354E028D65AC9CFFBCFBD0DEC0EA4F7CBB1018C9618612FB2A5837631AFC614AD2D5FC45EC872EC8816CCB96841A4DC14307159F83F694C90472DA3BB20E9EAC91D1F21770CDC6A037855520D80102005651A54BF12D9BAB8ADB4149ED37B5BD851825B596887DC4E47E55FC0D7B3AE7FFA43F95CCE340942FBEC7E593A16AEAC11CA1136902A2917BC096E8B16CA28D0AC2A58B46DA69B9908CFDB5DC16B391B4DD5C1A8346DB2CDB22447E44FF1567D85B90CD8016029C33D9DE2C992AC73A8155693DDE84FCBB760D88FEA847AEB13EF8058E11E81A7ED0666794272E362F60EF252BD5E3890D85EB6297F99BFA82A7FA94F33EC9804D02E50C56C7856C7B923987825C79A22BF9188AC61E936AC48A40B73EBE61C1C8724315AEA4D1E5AB2889C2251F9A771493955AC61FA1EB3
+20210510084019 2 6 100 3071 2 E2F748529B9B801FBAF3AE42C75013A5C4C959A756D496B01A6E1145DB55AA31F408A8DEA8B8573506C76D8AF81C9A3F4D5D4B838D34C30C54D3886448581ABD74D6D95F8B0D4DA21A8E3C6D127657A93354E028D65AC9CFFBCFBD0DEC0EA4F7CBB1018C9618612FB2A5837631AFC614AD2D5FC45EC872EC8816CCB96841A4DC14307159F83F694C90472DA3BB20E9EAC91D1F21770CDC6A037855520D80102005651A54BF12D9BAB8ADB4149ED37B5BD851825B596887DC4E47E55FC0D7B3AE7FFA43F95CCE340942FBEC7E593A16AEAC11CA1136902A2917BC096E8B16CA28D0AC2A58B46DA69B9908CFDB5DC16B391B4DD5C1A8346DB2CDB22447E44FF1567D85B90CD8016029C33D9DE2C992AC73A8155693DDE84FCBB760D88FEA847AEB13EF8058E11E81A7ED0666794272E362F60EF252BD5E3890D85EB6297F99BFA82A7FA94F33EC9804D02E50C56C7856C7B923987825C79A22BF9188AC61E936AC48A40B73EBE61C1C8724315AEA4D1E5AB2889C2251F9A771493955AC6208EA33
+20210510084631 2 6 100 3071 5 E2F748529B9B801FBAF3AE42C75013A5C4C959A756D496B01A6E1145DB55AA31F408A8DEA8B8573506C76D8AF81C9A3F4D5D4B838D34C30C54D3886448581ABD74D6D95F8B0D4DA21A8E3C6D127657A93354E028D65AC9CFFBCFBD0DEC0EA4F7CBB1018C9618612FB2A5837631AFC614AD2D5FC45EC872EC8816CCB96841A4DC14307159F83F694C90472DA3BB20E9EAC91D1F21770CDC6A037855520D80102005651A54BF12D9BAB8ADB4149ED37B5BD851825B596887DC4E47E55FC0D7B3AE7FFA43F95CCE340942FBEC7E593A16AEAC11CA1136902A2917BC096E8B16CA28D0AC2A58B46DA69B9908CFDB5DC16B391B4DD5C1A8346DB2CDB22447E44FF1567D85B90CD8016029C33D9DE2C992AC73A8155693DDE84FCBB760D88FEA847AEB13EF8058E11E81A7ED0666794272E362F60EF252BD5E3890D85EB6297F99BFA82A7FA94F33EC9804D02E50C56C7856C7B923987825C79A22BF9188AC61E936AC48A40B73EBE61C1C8724315AEA4D1E5AB2889C2251F9A771493955AC62F8C84F
+20210510084729 2 6 100 3071 2 E2F748529B9B801FBAF3AE42C75013A5C4C959A756D496B01A6E1145DB55AA31F408A8DEA8B8573506C76D8AF81C9A3F4D5D4B838D34C30C54D3886448581ABD74D6D95F8B0D4DA21A8E3C6D127657A93354E028D65AC9CFFBCFBD0DEC0EA4F7CBB1018C9618612FB2A5837631AFC614AD2D5FC45EC872EC8816CCB96841A4DC14307159F83F694C90472DA3BB20E9EAC91D1F21770CDC6A037855520D80102005651A54BF12D9BAB8ADB4149ED37B5BD851825B596887DC4E47E55FC0D7B3AE7FFA43F95CCE340942FBEC7E593A16AEAC11CA1136902A2917BC096E8B16CA28D0AC2A58B46DA69B9908CFDB5DC16B391B4DD5C1A8346DB2CDB22447E44FF1567D85B90CD8016029C33D9DE2C992AC73A8155693DDE84FCBB760D88FEA847AEB13EF8058E11E81A7ED0666794272E362F60EF252BD5E3890D85EB6297F99BFA82A7FA94F33EC9804D02E50C56C7856C7B923987825C79A22BF9188AC61E936AC48A40B73EBE61C1C8724315AEA4D1E5AB2889C2251F9A771493955AC6317E0DB
+20210510085604 2 6 100 3071 5 E2F748529B9B801FBAF3AE42C75013A5C4C959A756D496B01A6E1145DB55AA31F408A8DEA8B8573506C76D8AF81C9A3F4D5D4B838D34C30C54D3886448581ABD74D6D95F8B0D4DA21A8E3C6D127657A93354E028D65AC9CFFBCFBD0DEC0EA4F7CBB1018C9618612FB2A5837631AFC614AD2D5FC45EC872EC8816CCB96841A4DC14307159F83F694C90472DA3BB20E9EAC91D1F21770CDC6A037855520D80102005651A54BF12D9BAB8ADB4149ED37B5BD851825B596887DC4E47E55FC0D7B3AE7FFA43F95CCE340942FBEC7E593A16AEAC11CA1136902A2917BC096E8B16CA28D0AC2A58B46DA69B9908CFDB5DC16B391B4DD5C1A8346DB2CDB22447E44FF1567D85B90CD8016029C33D9DE2C992AC73A8155693DDE84FCBB760D88FEA847AEB13EF8058E11E81A7ED0666794272E362F60EF252BD5E3890D85EB6297F99BFA82A7FA94F33EC9804D02E50C56C7856C7B923987825C79A22BF9188AC61E936AC48A40B73EBE61C1C8724315AEA4D1E5AB2889C2251F9A771493955AC6466EE77
+20210510085645 2 6 100 3071 2 E2F748529B9B801FBAF3AE42C75013A5C4C959A756D496B01A6E1145DB55AA31F408A8DEA8B8573506C76D8AF81C9A3F4D5D4B838D34C30C54D3886448581ABD74D6D95F8B0D4DA21A8E3C6D127657A93354E028D65AC9CFFBCFBD0DEC0EA4F7CBB1018C9618612FB2A5837631AFC614AD2D5FC45EC872EC8816CCB96841A4DC14307159F83F694C90472DA3BB20E9EAC91D1F21770CDC6A037855520D80102005651A54BF12D9BAB8ADB4149ED37B5BD851825B596887DC4E47E55FC0D7B3AE7FFA43F95CCE340942FBEC7E593A16AEAC11CA1136902A2917BC096E8B16CA28D0AC2A58B46DA69B9908CFDB5DC16B391B4DD5C1A8346DB2CDB22447E44FF1567D85B90CD8016029C33D9DE2C992AC73A8155693DDE84FCBB760D88FEA847AEB13EF8058E11E81A7ED0666794272E362F60EF252BD5E3890D85EB6297F99BFA82A7FA94F33EC9804D02E50C56C7856C7B923987825C79A22BF9188AC61E936AC48A40B73EBE61C1C8724315AEA4D1E5AB2889C2251F9A771493955AC64795C1B
+20210510085906 2 6 100 3071 2 E2F748529B9B801FBAF3AE42C75013A5C4C959A756D496B01A6E1145DB55AA31F408A8DEA8B8573506C76D8AF81C9A3F4D5D4B838D34C30C54D3886448581ABD74D6D95F8B0D4DA21A8E3C6D127657A93354E028D65AC9CFFBCFBD0DEC0EA4F7CBB1018C9618612FB2A5837631AFC614AD2D5FC45EC872EC8816CCB96841A4DC14307159F83F694C90472DA3BB20E9EAC91D1F21770CDC6A037855520D80102005651A54BF12D9BAB8ADB4149ED37B5BD851825B596887DC4E47E55FC0D7B3AE7FFA43F95CCE340942FBEC7E593A16AEAC11CA1136902A2917BC096E8B16CA28D0AC2A58B46DA69B9908CFDB5DC16B391B4DD5C1A8346DB2CDB22447E44FF1567D85B90CD8016029C33D9DE2C992AC73A8155693DDE84FCBB760D88FEA847AEB13EF8058E11E81A7ED0666794272E362F60EF252BD5E3890D85EB6297F99BFA82A7FA94F33EC9804D02E50C56C7856C7B923987825C79A22BF9188AC61E936AC48A40B73EBE61C1C8724315AEA4D1E5AB2889C2251F9A771493955AC64D0DEFB
+20210510090053 2 6 100 3071 2 E2F748529B9B801FBAF3AE42C75013A5C4C959A756D496B01A6E1145DB55AA31F408A8DEA8B8573506C76D8AF81C9A3F4D5D4B838D34C30C54D3886448581ABD74D6D95F8B0D4DA21A8E3C6D127657A93354E028D65AC9CFFBCFBD0DEC0EA4F7CBB1018C9618612FB2A5837631AFC614AD2D5FC45EC872EC8816CCB96841A4DC14307159F83F694C90472DA3BB20E9EAC91D1F21770CDC6A037855520D80102005651A54BF12D9BAB8ADB4149ED37B5BD851825B596887DC4E47E55FC0D7B3AE7FFA43F95CCE340942FBEC7E593A16AEAC11CA1136902A2917BC096E8B16CA28D0AC2A58B46DA69B9908CFDB5DC16B391B4DD5C1A8346DB2CDB22447E44FF1567D85B90CD8016029C33D9DE2C992AC73A8155693DDE84FCBB760D88FEA847AEB13EF8058E11E81A7ED0666794272E362F60EF252BD5E3890D85EB6297F99BFA82A7FA94F33EC9804D02E50C56C7856C7B923987825C79A22BF9188AC61E936AC48A40B73EBE61C1C8724315AEA4D1E5AB2889C2251F9A771493955AC650DE7D3
+20210510090401 2 6 100 3071 2 E2F748529B9B801FBAF3AE42C75013A5C4C959A756D496B01A6E1145DB55AA31F408A8DEA8B8573506C76D8AF81C9A3F4D5D4B838D34C30C54D3886448581ABD74D6D95F8B0D4DA21A8E3C6D127657A93354E028D65AC9CFFBCFBD0DEC0EA4F7CBB1018C9618612FB2A5837631AFC614AD2D5FC45EC872EC8816CCB96841A4DC14307159F83F694C90472DA3BB20E9EAC91D1F21770CDC6A037855520D80102005651A54BF12D9BAB8ADB4149ED37B5BD851825B596887DC4E47E55FC0D7B3AE7FFA43F95CCE340942FBEC7E593A16AEAC11CA1136902A2917BC096E8B16CA28D0AC2A58B46DA69B9908CFDB5DC16B391B4DD5C1A8346DB2CDB22447E44FF1567D85B90CD8016029C33D9DE2C992AC73A8155693DDE84FCBB760D88FEA847AEB13EF8058E11E81A7ED0666794272E362F60EF252BD5E3890D85EB6297F99BFA82A7FA94F33EC9804D02E50C56C7856C7B923987825C79A22BF9188AC61E936AC48A40B73EBE61C1C8724315AEA4D1E5AB2889C2251F9A771493955AC6582AF03
+20210510090527 2 6 100 3071 5 E2F748529B9B801FBAF3AE42C75013A5C4C959A756D496B01A6E1145DB55AA31F408A8DEA8B8573506C76D8AF81C9A3F4D5D4B838D34C30C54D3886448581ABD74D6D95F8B0D4DA21A8E3C6D127657A93354E028D65AC9CFFBCFBD0DEC0EA4F7CBB1018C9618612FB2A5837631AFC614AD2D5FC45EC872EC8816CCB96841A4DC14307159F83F694C90472DA3BB20E9EAC91D1F21770CDC6A037855520D80102005651A54BF12D9BAB8ADB4149ED37B5BD851825B596887DC4E47E55FC0D7B3AE7FFA43F95CCE340942FBEC7E593A16AEAC11CA1136902A2917BC096E8B16CA28D0AC2A58B46DA69B9908CFDB5DC16B391B4DD5C1A8346DB2CDB22447E44FF1567D85B90CD8016029C33D9DE2C992AC73A8155693DDE84FCBB760D88FEA847AEB13EF8058E11E81A7ED0666794272E362F60EF252BD5E3890D85EB6297F99BFA82A7FA94F33EC9804D02E50C56C7856C7B923987825C79A22BF9188AC61E936AC48A40B73EBE61C1C8724315AEA4D1E5AB2889C2251F9A771493955AC65B4635F
+20210510090743 2 6 100 3071 2 E2F748529B9B801FBAF3AE42C75013A5C4C959A756D496B01A6E1145DB55AA31F408A8DEA8B8573506C76D8AF81C9A3F4D5D4B838D34C30C54D3886448581ABD74D6D95F8B0D4DA21A8E3C6D127657A93354E028D65AC9CFFBCFBD0DEC0EA4F7CBB1018C9618612FB2A5837631AFC614AD2D5FC45EC872EC8816CCB96841A4DC14307159F83F694C90472DA3BB20E9EAC91D1F21770CDC6A037855520D80102005651A54BF12D9BAB8ADB4149ED37B5BD851825B596887DC4E47E55FC0D7B3AE7FFA43F95CCE340942FBEC7E593A16AEAC11CA1136902A2917BC096E8B16CA28D0AC2A58B46DA69B9908CFDB5DC16B391B4DD5C1A8346DB2CDB22447E44FF1567D85B90CD8016029C33D9DE2C992AC73A8155693DDE84FCBB760D88FEA847AEB13EF8058E11E81A7ED0666794272E362F60EF252BD5E3890D85EB6297F99BFA82A7FA94F33EC9804D02E50C56C7856C7B923987825C79A22BF9188AC61E936AC48A40B73EBE61C1C8724315AEA4D1E5AB2889C2251F9A771493955AC6608EE2B
+20210510090837 2 6 100 3071 2 E2F748529B9B801FBAF3AE42C75013A5C4C959A756D496B01A6E1145DB55AA31F408A8DEA8B8573506C76D8AF81C9A3F4D5D4B838D34C30C54D3886448581ABD74D6D95F8B0D4DA21A8E3C6D127657A93354E028D65AC9CFFBCFBD0DEC0EA4F7CBB1018C9618612FB2A5837631AFC614AD2D5FC45EC872EC8816CCB96841A4DC14307159F83F694C90472DA3BB20E9EAC91D1F21770CDC6A037855520D80102005651A54BF12D9BAB8ADB4149ED37B5BD851825B596887DC4E47E55FC0D7B3AE7FFA43F95CCE340942FBEC7E593A16AEAC11CA1136902A2917BC096E8B16CA28D0AC2A58B46DA69B9908CFDB5DC16B391B4DD5C1A8346DB2CDB22447E44FF1567D85B90CD8016029C33D9DE2C992AC73A8155693DDE84FCBB760D88FEA847AEB13EF8058E11E81A7ED0666794272E362F60EF252BD5E3890D85EB6297F99BFA82A7FA94F33EC9804D02E50C56C7856C7B923987825C79A22BF9188AC61E936AC48A40B73EBE61C1C8724315AEA4D1E5AB2889C2251F9A771493955AC66237853
+20210510090953 2 6 100 3071 5 E2F748529B9B801FBAF3AE42C75013A5C4C959A756D496B01A6E1145DB55AA31F408A8DEA8B8573506C76D8AF81C9A3F4D5D4B838D34C30C54D3886448581ABD74D6D95F8B0D4DA21A8E3C6D127657A93354E028D65AC9CFFBCFBD0DEC0EA4F7CBB1018C9618612FB2A5837631AFC614AD2D5FC45EC872EC8816CCB96841A4DC14307159F83F694C90472DA3BB20E9EAC91D1F21770CDC6A037855520D80102005651A54BF12D9BAB8ADB4149ED37B5BD851825B596887DC4E47E55FC0D7B3AE7FFA43F95CCE340942FBEC7E593A16AEAC11CA1136902A2917BC096E8B16CA28D0AC2A58B46DA69B9908CFDB5DC16B391B4DD5C1A8346DB2CDB22447E44FF1567D85B90CD8016029C33D9DE2C992AC73A8155693DDE84FCBB760D88FEA847AEB13EF8058E11E81A7ED0666794272E362F60EF252BD5E3890D85EB6297F99BFA82A7FA94F33EC9804D02E50C56C7856C7B923987825C79A22BF9188AC61E936AC48A40B73EBE61C1C8724315AEA4D1E5AB2889C2251F9A771493955AC66503AC7
+20210510091517 2 6 100 3071 2 E2F748529B9B801FBAF3AE42C75013A5C4C959A756D496B01A6E1145DB55AA31F408A8DEA8B8573506C76D8AF81C9A3F4D5D4B838D34C30C54D3886448581ABD74D6D95F8B0D4DA21A8E3C6D127657A93354E028D65AC9CFFBCFBD0DEC0EA4F7CBB1018C9618612FB2A5837631AFC614AD2D5FC45EC872EC8816CCB96841A4DC14307159F83F694C90472DA3BB20E9EAC91D1F21770CDC6A037855520D80102005651A54BF12D9BAB8ADB4149ED37B5BD851825B596887DC4E47E55FC0D7B3AE7FFA43F95CCE340942FBEC7E593A16AEAC11CA1136902A2917BC096E8B16CA28D0AC2A58B46DA69B9908CFDB5DC16B391B4DD5C1A8346DB2CDB22447E44FF1567D85B90CD8016029C33D9DE2C992AC73A8155693DDE84FCBB760D88FEA847AEB13EF8058E11E81A7ED0666794272E362F60EF252BD5E3890D85EB6297F99BFA82A7FA94F33EC9804D02E50C56C7856C7B923987825C79A22BF9188AC61E936AC48A40B73EBE61C1C8724315AEA4D1E5AB2889C2251F9A771493955AC671C2453
+20210510091543 2 6 100 3071 5 E2F748529B9B801FBAF3AE42C75013A5C4C959A756D496B01A6E1145DB55AA31F408A8DEA8B8573506C76D8AF81C9A3F4D5D4B838D34C30C54D3886448581ABD74D6D95F8B0D4DA21A8E3C6D127657A93354E028D65AC9CFFBCFBD0DEC0EA4F7CBB1018C9618612FB2A5837631AFC614AD2D5FC45EC872EC8816CCB96841A4DC14307159F83F694C90472DA3BB20E9EAC91D1F21770CDC6A037855520D80102005651A54BF12D9BAB8ADB4149ED37B5BD851825B596887DC4E47E55FC0D7B3AE7FFA43F95CCE340942FBEC7E593A16AEAC11CA1136902A2917BC096E8B16CA28D0AC2A58B46DA69B9908CFDB5DC16B391B4DD5C1A8346DB2CDB22447E44FF1567D85B90CD8016029C33D9DE2C992AC73A8155693DDE84FCBB760D88FEA847AEB13EF8058E11E81A7ED0666794272E362F60EF252BD5E3890D85EB6297F99BFA82A7FA94F33EC9804D02E50C56C7856C7B923987825C79A22BF9188AC61E936AC48A40B73EBE61C1C8724315AEA4D1E5AB2889C2251F9A771493955AC6724D557
+20210510091752 2 6 100 3071 5 E2F748529B9B801FBAF3AE42C75013A5C4C959A756D496B01A6E1145DB55AA31F408A8DEA8B8573506C76D8AF81C9A3F4D5D4B838D34C30C54D3886448581ABD74D6D95F8B0D4DA21A8E3C6D127657A93354E028D65AC9CFFBCFBD0DEC0EA4F7CBB1018C9618612FB2A5837631AFC614AD2D5FC45EC872EC8816CCB96841A4DC14307159F83F694C90472DA3BB20E9EAC91D1F21770CDC6A037855520D80102005651A54BF12D9BAB8ADB4149ED37B5BD851825B596887DC4E47E55FC0D7B3AE7FFA43F95CCE340942FBEC7E593A16AEAC11CA1136902A2917BC096E8B16CA28D0AC2A58B46DA69B9908CFDB5DC16B391B4DD5C1A8346DB2CDB22447E44FF1567D85B90CD8016029C33D9DE2C992AC73A8155693DDE84FCBB760D88FEA847AEB13EF8058E11E81A7ED0666794272E362F60EF252BD5E3890D85EB6297F99BFA82A7FA94F33EC9804D02E50C56C7856C7B923987825C79A22BF9188AC61E936AC48A40B73EBE61C1C8724315AEA4D1E5AB2889C2251F9A771493955AC67729FB7
+20210510091814 2 6 100 3071 5 E2F748529B9B801FBAF3AE42C75013A5C4C959A756D496B01A6E1145DB55AA31F408A8DEA8B8573506C76D8AF81C9A3F4D5D4B838D34C30C54D3886448581ABD74D6D95F8B0D4DA21A8E3C6D127657A93354E028D65AC9CFFBCFBD0DEC0EA4F7CBB1018C9618612FB2A5837631AFC614AD2D5FC45EC872EC8816CCB96841A4DC14307159F83F694C90472DA3BB20E9EAC91D1F21770CDC6A037855520D80102005651A54BF12D9BAB8ADB4149ED37B5BD851825B596887DC4E47E55FC0D7B3AE7FFA43F95CCE340942FBEC7E593A16AEAC11CA1136902A2917BC096E8B16CA28D0AC2A58B46DA69B9908CFDB5DC16B391B4DD5C1A8346DB2CDB22447E44FF1567D85B90CD8016029C33D9DE2C992AC73A8155693DDE84FCBB760D88FEA847AEB13EF8058E11E81A7ED0666794272E362F60EF252BD5E3890D85EB6297F99BFA82A7FA94F33EC9804D02E50C56C7856C7B923987825C79A22BF9188AC61E936AC48A40B73EBE61C1C8724315AEA4D1E5AB2889C2251F9A771493955AC67785967
+20210510092259 2 6 100 3071 5 E2F748529B9B801FBAF3AE42C75013A5C4C959A756D496B01A6E1145DB55AA31F408A8DEA8B8573506C76D8AF81C9A3F4D5D4B838D34C30C54D3886448581ABD74D6D95F8B0D4DA21A8E3C6D127657A93354E028D65AC9CFFBCFBD0DEC0EA4F7CBB1018C9618612FB2A5837631AFC614AD2D5FC45EC872EC8816CCB96841A4DC14307159F83F694C90472DA3BB20E9EAC91D1F21770CDC6A037855520D80102005651A54BF12D9BAB8ADB4149ED37B5BD851825B596887DC4E47E55FC0D7B3AE7FFA43F95CCE340942FBEC7E593A16AEAC11CA1136902A2917BC096E8B16CA28D0AC2A58B46DA69B9908CFDB5DC16B391B4DD5C1A8346DB2CDB22447E44FF1567D85B90CD8016029C33D9DE2C992AC73A8155693DDE84FCBB760D88FEA847AEB13EF8058E11E81A7ED0666794272E362F60EF252BD5E3890D85EB6297F99BFA82A7FA94F33EC9804D02E50C56C7856C7B923987825C79A22BF9188AC61E936AC48A40B73EBE61C1C8724315AEA4D1E5AB2889C2251F9A771493955AC683152FF
+20210510092315 2 6 100 3071 5 E2F748529B9B801FBAF3AE42C75013A5C4C959A756D496B01A6E1145DB55AA31F408A8DEA8B8573506C76D8AF81C9A3F4D5D4B838D34C30C54D3886448581ABD74D6D95F8B0D4DA21A8E3C6D127657A93354E028D65AC9CFFBCFBD0DEC0EA4F7CBB1018C9618612FB2A5837631AFC614AD2D5FC45EC872EC8816CCB96841A4DC14307159F83F694C90472DA3BB20E9EAC91D1F21770CDC6A037855520D80102005651A54BF12D9BAB8ADB4149ED37B5BD851825B596887DC4E47E55FC0D7B3AE7FFA43F95CCE340942FBEC7E593A16AEAC11CA1136902A2917BC096E8B16CA28D0AC2A58B46DA69B9908CFDB5DC16B391B4DD5C1A8346DB2CDB22447E44FF1567D85B90CD8016029C33D9DE2C992AC73A8155693DDE84FCBB760D88FEA847AEB13EF8058E11E81A7ED0666794272E362F60EF252BD5E3890D85EB6297F99BFA82A7FA94F33EC9804D02E50C56C7856C7B923987825C79A22BF9188AC61E936AC48A40B73EBE61C1C8724315AEA4D1E5AB2889C2251F9A771493955AC68333ECF
+20210510092433 2 6 100 3071 5 E2F748529B9B801FBAF3AE42C75013A5C4C959A756D496B01A6E1145DB55AA31F408A8DEA8B8573506C76D8AF81C9A3F4D5D4B838D34C30C54D3886448581ABD74D6D95F8B0D4DA21A8E3C6D127657A93354E028D65AC9CFFBCFBD0DEC0EA4F7CBB1018C9618612FB2A5837631AFC614AD2D5FC45EC872EC8816CCB96841A4DC14307159F83F694C90472DA3BB20E9EAC91D1F21770CDC6A037855520D80102005651A54BF12D9BAB8ADB4149ED37B5BD851825B596887DC4E47E55FC0D7B3AE7FFA43F95CCE340942FBEC7E593A16AEAC11CA1136902A2917BC096E8B16CA28D0AC2A58B46DA69B9908CFDB5DC16B391B4DD5C1A8346DB2CDB22447E44FF1567D85B90CD8016029C33D9DE2C992AC73A8155693DDE84FCBB760D88FEA847AEB13EF8058E11E81A7ED0666794272E362F60EF252BD5E3890D85EB6297F99BFA82A7FA94F33EC9804D02E50C56C7856C7B923987825C79A22BF9188AC61E936AC48A40B73EBE61C1C8724315AEA4D1E5AB2889C2251F9A771493955AC685EC3F7
+20210510092808 2 6 100 3071 5 E2F748529B9B801FBAF3AE42C75013A5C4C959A756D496B01A6E1145DB55AA31F408A8DEA8B8573506C76D8AF81C9A3F4D5D4B838D34C30C54D3886448581ABD74D6D95F8B0D4DA21A8E3C6D127657A93354E028D65AC9CFFBCFBD0DEC0EA4F7CBB1018C9618612FB2A5837631AFC614AD2D5FC45EC872EC8816CCB96841A4DC14307159F83F694C90472DA3BB20E9EAC91D1F21770CDC6A037855520D80102005651A54BF12D9BAB8ADB4149ED37B5BD851825B596887DC4E47E55FC0D7B3AE7FFA43F95CCE340942FBEC7E593A16AEAC11CA1136902A2917BC096E8B16CA28D0AC2A58B46DA69B9908CFDB5DC16B391B4DD5C1A8346DB2CDB22447E44FF1567D85B90CD8016029C33D9DE2C992AC73A8155693DDE84FCBB760D88FEA847AEB13EF8058E11E81A7ED0666794272E362F60EF252BD5E3890D85EB6297F99BFA82A7FA94F33EC9804D02E50C56C7856C7B923987825C79A22BF9188AC61E936AC48A40B73EBE61C1C8724315AEA4D1E5AB2889C2251F9A771493955AC68E5574F
+20210510093246 2 6 100 3071 5 E2F748529B9B801FBAF3AE42C75013A5C4C959A756D496B01A6E1145DB55AA31F408A8DEA8B8573506C76D8AF81C9A3F4D5D4B838D34C30C54D3886448581ABD74D6D95F8B0D4DA21A8E3C6D127657A93354E028D65AC9CFFBCFBD0DEC0EA4F7CBB1018C9618612FB2A5837631AFC614AD2D5FC45EC872EC8816CCB96841A4DC14307159F83F694C90472DA3BB20E9EAC91D1F21770CDC6A037855520D80102005651A54BF12D9BAB8ADB4149ED37B5BD851825B596887DC4E47E55FC0D7B3AE7FFA43F95CCE340942FBEC7E593A16AEAC11CA1136902A2917BC096E8B16CA28D0AC2A58B46DA69B9908CFDB5DC16B391B4DD5C1A8346DB2CDB22447E44FF1567D85B90CD8016029C33D9DE2C992AC73A8155693DDE84FCBB760D88FEA847AEB13EF8058E11E81A7ED0666794272E362F60EF252BD5E3890D85EB6297F99BFA82A7FA94F33EC9804D02E50C56C7856C7B923987825C79A22BF9188AC61E936AC48A40B73EBE61C1C8724315AEA4D1E5AB2889C2251F9A771493955AC6995B96F
+20210510104920 2 6 100 4095 2 E3508586273EAF882533D9104A0F6FF5818343120ECFA2DF8002402FEA175CD1C418C3CBCE3B8C3B8897FA169C9C9521399321A353ED16DE7EDFD5F28F3F8C1B5F52F368C463B3A1AB5CF5816666973A70FA756A6A2F70313D2830D490541C09F40E7ABDCA7EE76A625F19B87D4336196CBEBEB5491E4365D7DFDF56384A3DFE662628171820829B5628694A4B4915954CF89391F3C06D9A4DF618CD54406A1198F4DF74EA2DDF55244076A5BD9295DD516B9346A98EC225F16968CA804B94F2CF67B0A4CC23A679766476CD8033CA3532230AB83092D78AB138653BAC3FE96C2E6A91387E2D7263B72CC0FEB5443233BD5C137351A4EEC65954845938DE8137C0E3F70D9932E18E4C771BD0ED3D11CDAF4EA9745D3C2C8C32E2F4C7302425A96720F939C9A32BA9475EC974D57326605F5B0402FD6431096AC965246DDEA5AD8B2B0C24A86FDA4CC9397DCE101DF441AEC0FB887CB17F61A25D2C5945BA2DC45766E939CE1210C5D0E9A8BD229EA308E995B6A99164BAC0F3985010C4AC7C36F0BBB3118A17FB1963E865AF49FD77FB4E1BA3D9551C3FAEA77CCD7A7D588294DE9EA3B8DB6A8CC98DA8C567CDAB709A287F5D53453267841E6113B3A06DF01038B6A83FA6AA4A645BB43D276B71C6EA65A98A4E9C839D38CFEDCE176C5480E8BD8AEEAB20FC1C89B889672D980C5C121545CFD4BECECE53E9CEE27EC48D7683
+20210510110208 2 6 100 4095 5 E3508586273EAF882533D9104A0F6FF5818343120ECFA2DF8002402FEA175CD1C418C3CBCE3B8C3B8897FA169C9C9521399321A353ED16DE7EDFD5F28F3F8C1B5F52F368C463B3A1AB5CF5816666973A70FA756A6A2F70313D2830D490541C09F40E7ABDCA7EE76A625F19B87D4336196CBEBEB5491E4365D7DFDF56384A3DFE662628171820829B5628694A4B4915954CF89391F3C06D9A4DF618CD54406A1198F4DF74EA2DDF55244076A5BD9295DD516B9346A98EC225F16968CA804B94F2CF67B0A4CC23A679766476CD8033CA3532230AB83092D78AB138653BAC3FE96C2E6A91387E2D7263B72CC0FEB5443233BD5C137351A4EEC65954845938DE8137C0E3F70D9932E18E4C771BD0ED3D11CDAF4EA9745D3C2C8C32E2F4C7302425A96720F939C9A32BA9475EC974D57326605F5B0402FD6431096AC965246DDEA5AD8B2B0C24A86FDA4CC9397DCE101DF441AEC0FB887CB17F61A25D2C5945BA2DC45766E939CE1210C5D0E9A8BD229EA308E995B6A99164BAC0F3985010C4AC7C36F0BBB3118A17FB1963E865AF49FD77FB4E1BA3D9551C3FAEA77CCD7A7D588294DE9EA3B8DB6A8CC98DA8C567CDAB709A287F5D53453267841E6113B3A06DF01038B6A83FA6AA4A645BB43D276B71C6EA65A98A4E9C839D38CFEDCE176C5480E8BD8AEEAB20FC1C89B889672D980C5C121545CFD4BECECE53E9CEE27EC56E987F
+20210510111200 2 6 100 4095 2 E3508586273EAF882533D9104A0F6FF5818343120ECFA2DF8002402FEA175CD1C418C3CBCE3B8C3B8897FA169C9C9521399321A353ED16DE7EDFD5F28F3F8C1B5F52F368C463B3A1AB5CF5816666973A70FA756A6A2F70313D2830D490541C09F40E7ABDCA7EE76A625F19B87D4336196CBEBEB5491E4365D7DFDF56384A3DFE662628171820829B5628694A4B4915954CF89391F3C06D9A4DF618CD54406A1198F4DF74EA2DDF55244076A5BD9295DD516B9346A98EC225F16968CA804B94F2CF67B0A4CC23A679766476CD8033CA3532230AB83092D78AB138653BAC3FE96C2E6A91387E2D7263B72CC0FEB5443233BD5C137351A4EEC65954845938DE8137C0E3F70D9932E18E4C771BD0ED3D11CDAF4EA9745D3C2C8C32E2F4C7302425A96720F939C9A32BA9475EC974D57326605F5B0402FD6431096AC965246DDEA5AD8B2B0C24A86FDA4CC9397DCE101DF441AEC0FB887CB17F61A25D2C5945BA2DC45766E939CE1210C5D0E9A8BD229EA308E995B6A99164BAC0F3985010C4AC7C36F0BBB3118A17FB1963E865AF49FD77FB4E1BA3D9551C3FAEA77CCD7A7D588294DE9EA3B8DB6A8CC98DA8C567CDAB709A287F5D53453267841E6113B3A06DF01038B6A83FA6AA4A645BB43D276B71C6EA65A98A4E9C839D38CFEDCE176C5480E8BD8AEEAB20FC1C89B889672D980C5C121545CFD4BECECE53E9CEE27EC618B3B3
+20210510112429 2 6 100 4095 2 E3508586273EAF882533D9104A0F6FF5818343120ECFA2DF8002402FEA175CD1C418C3CBCE3B8C3B8897FA169C9C9521399321A353ED16DE7EDFD5F28F3F8C1B5F52F368C463B3A1AB5CF5816666973A70FA756A6A2F70313D2830D490541C09F40E7ABDCA7EE76A625F19B87D4336196CBEBEB5491E4365D7DFDF56384A3DFE662628171820829B5628694A4B4915954CF89391F3C06D9A4DF618CD54406A1198F4DF74EA2DDF55244076A5BD9295DD516B9346A98EC225F16968CA804B94F2CF67B0A4CC23A679766476CD8033CA3532230AB83092D78AB138653BAC3FE96C2E6A91387E2D7263B72CC0FEB5443233BD5C137351A4EEC65954845938DE8137C0E3F70D9932E18E4C771BD0ED3D11CDAF4EA9745D3C2C8C32E2F4C7302425A96720F939C9A32BA9475EC974D57326605F5B0402FD6431096AC965246DDEA5AD8B2B0C24A86FDA4CC9397DCE101DF441AEC0FB887CB17F61A25D2C5945BA2DC45766E939CE1210C5D0E9A8BD229EA308E995B6A99164BAC0F3985010C4AC7C36F0BBB3118A17FB1963E865AF49FD77FB4E1BA3D9551C3FAEA77CCD7A7D588294DE9EA3B8DB6A8CC98DA8C567CDAB709A287F5D53453267841E6113B3A06DF01038B6A83FA6AA4A645BB43D276B71C6EA65A98A4E9C839D38CFEDCE176C5480E8BD8AEEAB20FC1C89B889672D980C5C121545CFD4BECECE53E9CEE27EC6F9E69B
+20210510112617 2 6 100 4095 2 E3508586273EAF882533D9104A0F6FF5818343120ECFA2DF8002402FEA175CD1C418C3CBCE3B8C3B8897FA169C9C9521399321A353ED16DE7EDFD5F28F3F8C1B5F52F368C463B3A1AB5CF5816666973A70FA756A6A2F70313D2830D490541C09F40E7ABDCA7EE76A625F19B87D4336196CBEBEB5491E4365D7DFDF56384A3DFE662628171820829B5628694A4B4915954CF89391F3C06D9A4DF618CD54406A1198F4DF74EA2DDF55244076A5BD9295DD516B9346A98EC225F16968CA804B94F2CF67B0A4CC23A679766476CD8033CA3532230AB83092D78AB138653BAC3FE96C2E6A91387E2D7263B72CC0FEB5443233BD5C137351A4EEC65954845938DE8137C0E3F70D9932E18E4C771BD0ED3D11CDAF4EA9745D3C2C8C32E2F4C7302425A96720F939C9A32BA9475EC974D57326605F5B0402FD6431096AC965246DDEA5AD8B2B0C24A86FDA4CC9397DCE101DF441AEC0FB887CB17F61A25D2C5945BA2DC45766E939CE1210C5D0E9A8BD229EA308E995B6A99164BAC0F3985010C4AC7C36F0BBB3118A17FB1963E865AF49FD77FB4E1BA3D9551C3FAEA77CCD7A7D588294DE9EA3B8DB6A8CC98DA8C567CDAB709A287F5D53453267841E6113B3A06DF01038B6A83FA6AA4A645BB43D276B71C6EA65A98A4E9C839D38CFEDCE176C5480E8BD8AEEAB20FC1C89B889672D980C5C121545CFD4BECECE53E9CEE27EC7137A93
+20210510120850 2 6 100 4095 5 E3508586273EAF882533D9104A0F6FF5818343120ECFA2DF8002402FEA175CD1C418C3CBCE3B8C3B8897FA169C9C9521399321A353ED16DE7EDFD5F28F3F8C1B5F52F368C463B3A1AB5CF5816666973A70FA756A6A2F70313D2830D490541C09F40E7ABDCA7EE76A625F19B87D4336196CBEBEB5491E4365D7DFDF56384A3DFE662628171820829B5628694A4B4915954CF89391F3C06D9A4DF618CD54406A1198F4DF74EA2DDF55244076A5BD9295DD516B9346A98EC225F16968CA804B94F2CF67B0A4CC23A679766476CD8033CA3532230AB83092D78AB138653BAC3FE96C2E6A91387E2D7263B72CC0FEB5443233BD5C137351A4EEC65954845938DE8137C0E3F70D9932E18E4C771BD0ED3D11CDAF4EA9745D3C2C8C32E2F4C7302425A96720F939C9A32BA9475EC974D57326605F5B0402FD6431096AC965246DDEA5AD8B2B0C24A86FDA4CC9397DCE101DF441AEC0FB887CB17F61A25D2C5945BA2DC45766E939CE1210C5D0E9A8BD229EA308E995B6A99164BAC0F3985010C4AC7C36F0BBB3118A17FB1963E865AF49FD77FB4E1BA3D9551C3FAEA77CCD7A7D588294DE9EA3B8DB6A8CC98DA8C567CDAB709A287F5D53453267841E6113B3A06DF01038B6A83FA6AA4A645BB43D276B71C6EA65A98A4E9C839D38CFEDCE176C5480E8BD8AEEAB20FC1C89B889672D980C5C121545CFD4BECECE53E9CEE27ECA1DD60F
+20210510121344 2 6 100 4095 5 E3508586273EAF882533D9104A0F6FF5818343120ECFA2DF8002402FEA175CD1C418C3CBCE3B8C3B8897FA169C9C9521399321A353ED16DE7EDFD5F28F3F8C1B5F52F368C463B3A1AB5CF5816666973A70FA756A6A2F70313D2830D490541C09F40E7ABDCA7EE76A625F19B87D4336196CBEBEB5491E4365D7DFDF56384A3DFE662628171820829B5628694A4B4915954CF89391F3C06D9A4DF618CD54406A1198F4DF74EA2DDF55244076A5BD9295DD516B9346A98EC225F16968CA804B94F2CF67B0A4CC23A679766476CD8033CA3532230AB83092D78AB138653BAC3FE96C2E6A91387E2D7263B72CC0FEB5443233BD5C137351A4EEC65954845938DE8137C0E3F70D9932E18E4C771BD0ED3D11CDAF4EA9745D3C2C8C32E2F4C7302425A96720F939C9A32BA9475EC974D57326605F5B0402FD6431096AC965246DDEA5AD8B2B0C24A86FDA4CC9397DCE101DF441AEC0FB887CB17F61A25D2C5945BA2DC45766E939CE1210C5D0E9A8BD229EA308E995B6A99164BAC0F3985010C4AC7C36F0BBB3118A17FB1963E865AF49FD77FB4E1BA3D9551C3FAEA77CCD7A7D588294DE9EA3B8DB6A8CC98DA8C567CDAB709A287F5D53453267841E6113B3A06DF01038B6A83FA6AA4A645BB43D276B71C6EA65A98A4E9C839D38CFEDCE176C5480E8BD8AEEAB20FC1C89B889672D980C5C121545CFD4BECECE53E9CEE27ECA6D1937
+20210510123540 2 6 100 4095 2 E3508586273EAF882533D9104A0F6FF5818343120ECFA2DF8002402FEA175CD1C418C3CBCE3B8C3B8897FA169C9C9521399321A353ED16DE7EDFD5F28F3F8C1B5F52F368C463B3A1AB5CF5816666973A70FA756A6A2F70313D2830D490541C09F40E7ABDCA7EE76A625F19B87D4336196CBEBEB5491E4365D7DFDF56384A3DFE662628171820829B5628694A4B4915954CF89391F3C06D9A4DF618CD54406A1198F4DF74EA2DDF55244076A5BD9295DD516B9346A98EC225F16968CA804B94F2CF67B0A4CC23A679766476CD8033CA3532230AB83092D78AB138653BAC3FE96C2E6A91387E2D7263B72CC0FEB5443233BD5C137351A4EEC65954845938DE8137C0E3F70D9932E18E4C771BD0ED3D11CDAF4EA9745D3C2C8C32E2F4C7302425A96720F939C9A32BA9475EC974D57326605F5B0402FD6431096AC965246DDEA5AD8B2B0C24A86FDA4CC9397DCE101DF441AEC0FB887CB17F61A25D2C5945BA2DC45766E939CE1210C5D0E9A8BD229EA308E995B6A99164BAC0F3985010C4AC7C36F0BBB3118A17FB1963E865AF49FD77FB4E1BA3D9551C3FAEA77CCD7A7D588294DE9EA3B8DB6A8CC98DA8C567CDAB709A287F5D53453267841E6113B3A06DF01038B6A83FA6AA4A645BB43D276B71C6EA65A98A4E9C839D38CFEDCE176C5480E8BD8AEEAB20FC1C89B889672D980C5C121545CFD4BECECE53E9CEE27ECBF2F10B
+20210510124120 2 6 100 4095 2 E3508586273EAF882533D9104A0F6FF5818343120ECFA2DF8002402FEA175CD1C418C3CBCE3B8C3B8897FA169C9C9521399321A353ED16DE7EDFD5F28F3F8C1B5F52F368C463B3A1AB5CF5816666973A70FA756A6A2F70313D2830D490541C09F40E7ABDCA7EE76A625F19B87D4336196CBEBEB5491E4365D7DFDF56384A3DFE662628171820829B5628694A4B4915954CF89391F3C06D9A4DF618CD54406A1198F4DF74EA2DDF55244076A5BD9295DD516B9346A98EC225F16968CA804B94F2CF67B0A4CC23A679766476CD8033CA3532230AB83092D78AB138653BAC3FE96C2E6A91387E2D7263B72CC0FEB5443233BD5C137351A4EEC65954845938DE8137C0E3F70D9932E18E4C771BD0ED3D11CDAF4EA9745D3C2C8C32E2F4C7302425A96720F939C9A32BA9475EC974D57326605F5B0402FD6431096AC965246DDEA5AD8B2B0C24A86FDA4CC9397DCE101DF441AEC0FB887CB17F61A25D2C5945BA2DC45766E939CE1210C5D0E9A8BD229EA308E995B6A99164BAC0F3985010C4AC7C36F0BBB3118A17FB1963E865AF49FD77FB4E1BA3D9551C3FAEA77CCD7A7D588294DE9EA3B8DB6A8CC98DA8C567CDAB709A287F5D53453267841E6113B3A06DF01038B6A83FA6AA4A645BB43D276B71C6EA65A98A4E9C839D38CFEDCE176C5480E8BD8AEEAB20FC1C89B889672D980C5C121545CFD4BECECE53E9CEE27ECC51479B
+20210510125020 2 6 100 4095 2 E3508586273EAF882533D9104A0F6FF5818343120ECFA2DF8002402FEA175CD1C418C3CBCE3B8C3B8897FA169C9C9521399321A353ED16DE7EDFD5F28F3F8C1B5F52F368C463B3A1AB5CF5816666973A70FA756A6A2F70313D2830D490541C09F40E7ABDCA7EE76A625F19B87D4336196CBEBEB5491E4365D7DFDF56384A3DFE662628171820829B5628694A4B4915954CF89391F3C06D9A4DF618CD54406A1198F4DF74EA2DDF55244076A5BD9295DD516B9346A98EC225F16968CA804B94F2CF67B0A4CC23A679766476CD8033CA3532230AB83092D78AB138653BAC3FE96C2E6A91387E2D7263B72CC0FEB5443233BD5C137351A4EEC65954845938DE8137C0E3F70D9932E18E4C771BD0ED3D11CDAF4EA9745D3C2C8C32E2F4C7302425A96720F939C9A32BA9475EC974D57326605F5B0402FD6431096AC965246DDEA5AD8B2B0C24A86FDA4CC9397DCE101DF441AEC0FB887CB17F61A25D2C5945BA2DC45766E939CE1210C5D0E9A8BD229EA308E995B6A99164BAC0F3985010C4AC7C36F0BBB3118A17FB1963E865AF49FD77FB4E1BA3D9551C3FAEA77CCD7A7D588294DE9EA3B8DB6A8CC98DA8C567CDAB709A287F5D53453267841E6113B3A06DF01038B6A83FA6AA4A645BB43D276B71C6EA65A98A4E9C839D38CFEDCE176C5480E8BD8AEEAB20FC1C89B889672D980C5C121545CFD4BECECE53E9CEE27ECCED89CB
+20210510125127 2 6 100 4095 2 E3508586273EAF882533D9104A0F6FF5818343120ECFA2DF8002402FEA175CD1C418C3CBCE3B8C3B8897FA169C9C9521399321A353ED16DE7EDFD5F28F3F8C1B5F52F368C463B3A1AB5CF5816666973A70FA756A6A2F70313D2830D490541C09F40E7ABDCA7EE76A625F19B87D4336196CBEBEB5491E4365D7DFDF56384A3DFE662628171820829B5628694A4B4915954CF89391F3C06D9A4DF618CD54406A1198F4DF74EA2DDF55244076A5BD9295DD516B9346A98EC225F16968CA804B94F2CF67B0A4CC23A679766476CD8033CA3532230AB83092D78AB138653BAC3FE96C2E6A91387E2D7263B72CC0FEB5443233BD5C137351A4EEC65954845938DE8137C0E3F70D9932E18E4C771BD0ED3D11CDAF4EA9745D3C2C8C32E2F4C7302425A96720F939C9A32BA9475EC974D57326605F5B0402FD6431096AC965246DDEA5AD8B2B0C24A86FDA4CC9397DCE101DF441AEC0FB887CB17F61A25D2C5945BA2DC45766E939CE1210C5D0E9A8BD229EA308E995B6A99164BAC0F3985010C4AC7C36F0BBB3118A17FB1963E865AF49FD77FB4E1BA3D9551C3FAEA77CCD7A7D588294DE9EA3B8DB6A8CC98DA8C567CDAB709A287F5D53453267841E6113B3A06DF01038B6A83FA6AA4A645BB43D276B71C6EA65A98A4E9C839D38CFEDCE176C5480E8BD8AEEAB20FC1C89B889672D980C5C121545CFD4BECECE53E9CEE27ECCF8FDBB
+20210510130049 2 6 100 4095 2 E3508586273EAF882533D9104A0F6FF5818343120ECFA2DF8002402FEA175CD1C418C3CBCE3B8C3B8897FA169C9C9521399321A353ED16DE7EDFD5F28F3F8C1B5F52F368C463B3A1AB5CF5816666973A70FA756A6A2F70313D2830D490541C09F40E7ABDCA7EE76A625F19B87D4336196CBEBEB5491E4365D7DFDF56384A3DFE662628171820829B5628694A4B4915954CF89391F3C06D9A4DF618CD54406A1198F4DF74EA2DDF55244076A5BD9295DD516B9346A98EC225F16968CA804B94F2CF67B0A4CC23A679766476CD8033CA3532230AB83092D78AB138653BAC3FE96C2E6A91387E2D7263B72CC0FEB5443233BD5C137351A4EEC65954845938DE8137C0E3F70D9932E18E4C771BD0ED3D11CDAF4EA9745D3C2C8C32E2F4C7302425A96720F939C9A32BA9475EC974D57326605F5B0402FD6431096AC965246DDEA5AD8B2B0C24A86FDA4CC9397DCE101DF441AEC0FB887CB17F61A25D2C5945BA2DC45766E939CE1210C5D0E9A8BD229EA308E995B6A99164BAC0F3985010C4AC7C36F0BBB3118A17FB1963E865AF49FD77FB4E1BA3D9551C3FAEA77CCD7A7D588294DE9EA3B8DB6A8CC98DA8C567CDAB709A287F5D53453267841E6113B3A06DF01038B6A83FA6AA4A645BB43D276B71C6EA65A98A4E9C839D38CFEDCE176C5480E8BD8AEEAB20FC1C89B889672D980C5C121545CFD4BECECE53E9CEE27ECD9C8A1B
+20210510131341 2 6 100 4095 5 E3508586273EAF882533D9104A0F6FF5818343120ECFA2DF8002402FEA175CD1C418C3CBCE3B8C3B8897FA169C9C9521399321A353ED16DE7EDFD5F28F3F8C1B5F52F368C463B3A1AB5CF5816666973A70FA756A6A2F70313D2830D490541C09F40E7ABDCA7EE76A625F19B87D4336196CBEBEB5491E4365D7DFDF56384A3DFE662628171820829B5628694A4B4915954CF89391F3C06D9A4DF618CD54406A1198F4DF74EA2DDF55244076A5BD9295DD516B9346A98EC225F16968CA804B94F2CF67B0A4CC23A679766476CD8033CA3532230AB83092D78AB138653BAC3FE96C2E6A91387E2D7263B72CC0FEB5443233BD5C137351A4EEC65954845938DE8137C0E3F70D9932E18E4C771BD0ED3D11CDAF4EA9745D3C2C8C32E2F4C7302425A96720F939C9A32BA9475EC974D57326605F5B0402FD6431096AC965246DDEA5AD8B2B0C24A86FDA4CC9397DCE101DF441AEC0FB887CB17F61A25D2C5945BA2DC45766E939CE1210C5D0E9A8BD229EA308E995B6A99164BAC0F3985010C4AC7C36F0BBB3118A17FB1963E865AF49FD77FB4E1BA3D9551C3FAEA77CCD7A7D588294DE9EA3B8DB6A8CC98DA8C567CDAB709A287F5D53453267841E6113B3A06DF01038B6A83FA6AA4A645BB43D276B71C6EA65A98A4E9C839D38CFEDCE176C5480E8BD8AEEAB20FC1C89B889672D980C5C121545CFD4BECECE53E9CEE27ECE7F859F
+20210510140804 2 6 100 4095 5 E3508586273EAF882533D9104A0F6FF5818343120ECFA2DF8002402FEA175CD1C418C3CBCE3B8C3B8897FA169C9C9521399321A353ED16DE7EDFD5F28F3F8C1B5F52F368C463B3A1AB5CF5816666973A70FA756A6A2F70313D2830D490541C09F40E7ABDCA7EE76A625F19B87D4336196CBEBEB5491E4365D7DFDF56384A3DFE662628171820829B5628694A4B4915954CF89391F3C06D9A4DF618CD54406A1198F4DF74EA2DDF55244076A5BD9295DD516B9346A98EC225F16968CA804B94F2CF67B0A4CC23A679766476CD8033CA3532230AB83092D78AB138653BAC3FE96C2E6A91387E2D7263B72CC0FEB5443233BD5C137351A4EEC65954845938DE8137C0E3F70D9932E18E4C771BD0ED3D11CDAF4EA9745D3C2C8C32E2F4C7302425A96720F939C9A32BA9475EC974D57326605F5B0402FD6431096AC965246DDEA5AD8B2B0C24A86FDA4CC9397DCE101DF441AEC0FB887CB17F61A25D2C5945BA2DC45766E939CE1210C5D0E9A8BD229EA308E995B6A99164BAC0F3985010C4AC7C36F0BBB3118A17FB1963E865AF49FD77FB4E1BA3D9551C3FAEA77CCD7A7D588294DE9EA3B8DB6A8CC98DA8C567CDAB709A287F5D53453267841E6113B3A06DF01038B6A83FA6AA4A645BB43D276B71C6EA65A98A4E9C839D38CFEDCE176C5480E8BD8AEEAB20FC1C89B889672D980C5C121545CFD4BECECE53E9CEE27ED25225A7
+20210510140916 2 6 100 4095 5 E3508586273EAF882533D9104A0F6FF5818343120ECFA2DF8002402FEA175CD1C418C3CBCE3B8C3B8897FA169C9C9521399321A353ED16DE7EDFD5F28F3F8C1B5F52F368C463B3A1AB5CF5816666973A70FA756A6A2F70313D2830D490541C09F40E7ABDCA7EE76A625F19B87D4336196CBEBEB5491E4365D7DFDF56384A3DFE662628171820829B5628694A4B4915954CF89391F3C06D9A4DF618CD54406A1198F4DF74EA2DDF55244076A5BD9295DD516B9346A98EC225F16968CA804B94F2CF67B0A4CC23A679766476CD8033CA3532230AB83092D78AB138653BAC3FE96C2E6A91387E2D7263B72CC0FEB5443233BD5C137351A4EEC65954845938DE8137C0E3F70D9932E18E4C771BD0ED3D11CDAF4EA9745D3C2C8C32E2F4C7302425A96720F939C9A32BA9475EC974D57326605F5B0402FD6431096AC965246DDEA5AD8B2B0C24A86FDA4CC9397DCE101DF441AEC0FB887CB17F61A25D2C5945BA2DC45766E939CE1210C5D0E9A8BD229EA308E995B6A99164BAC0F3985010C4AC7C36F0BBB3118A17FB1963E865AF49FD77FB4E1BA3D9551C3FAEA77CCD7A7D588294DE9EA3B8DB6A8CC98DA8C567CDAB709A287F5D53453267841E6113B3A06DF01038B6A83FA6AA4A645BB43D276B71C6EA65A98A4E9C839D38CFEDCE176C5480E8BD8AEEAB20FC1C89B889672D980C5C121545CFD4BECECE53E9CEE27ED25E3747
+20210510141423 2 6 100 4095 2 E3508586273EAF882533D9104A0F6FF5818343120ECFA2DF8002402FEA175CD1C418C3CBCE3B8C3B8897FA169C9C9521399321A353ED16DE7EDFD5F28F3F8C1B5F52F368C463B3A1AB5CF5816666973A70FA756A6A2F70313D2830D490541C09F40E7ABDCA7EE76A625F19B87D4336196CBEBEB5491E4365D7DFDF56384A3DFE662628171820829B5628694A4B4915954CF89391F3C06D9A4DF618CD54406A1198F4DF74EA2DDF55244076A5BD9295DD516B9346A98EC225F16968CA804B94F2CF67B0A4CC23A679766476CD8033CA3532230AB83092D78AB138653BAC3FE96C2E6A91387E2D7263B72CC0FEB5443233BD5C137351A4EEC65954845938DE8137C0E3F70D9932E18E4C771BD0ED3D11CDAF4EA9745D3C2C8C32E2F4C7302425A96720F939C9A32BA9475EC974D57326605F5B0402FD6431096AC965246DDEA5AD8B2B0C24A86FDA4CC9397DCE101DF441AEC0FB887CB17F61A25D2C5945BA2DC45766E939CE1210C5D0E9A8BD229EA308E995B6A99164BAC0F3985010C4AC7C36F0BBB3118A17FB1963E865AF49FD77FB4E1BA3D9551C3FAEA77CCD7A7D588294DE9EA3B8DB6A8CC98DA8C567CDAB709A287F5D53453267841E6113B3A06DF01038B6A83FA6AA4A645BB43D276B71C6EA65A98A4E9C839D38CFEDCE176C5480E8BD8AEEAB20FC1C89B889672D980C5C121545CFD4BECECE53E9CEE27ED2B414E3
+20210510144848 2 6 100 4095 2 E3508586273EAF882533D9104A0F6FF5818343120ECFA2DF8002402FEA175CD1C418C3CBCE3B8C3B8897FA169C9C9521399321A353ED16DE7EDFD5F28F3F8C1B5F52F368C463B3A1AB5CF5816666973A70FA756A6A2F70313D2830D490541C09F40E7ABDCA7EE76A625F19B87D4336196CBEBEB5491E4365D7DFDF56384A3DFE662628171820829B5628694A4B4915954CF89391F3C06D9A4DF618CD54406A1198F4DF74EA2DDF55244076A5BD9295DD516B9346A98EC225F16968CA804B94F2CF67B0A4CC23A679766476CD8033CA3532230AB83092D78AB138653BAC3FE96C2E6A91387E2D7263B72CC0FEB5443233BD5C137351A4EEC65954845938DE8137C0E3F70D9932E18E4C771BD0ED3D11CDAF4EA9745D3C2C8C32E2F4C7302425A96720F939C9A32BA9475EC974D57326605F5B0402FD6431096AC965246DDEA5AD8B2B0C24A86FDA4CC9397DCE101DF441AEC0FB887CB17F61A25D2C5945BA2DC45766E939CE1210C5D0E9A8BD229EA308E995B6A99164BAC0F3985010C4AC7C36F0BBB3118A17FB1963E865AF49FD77FB4E1BA3D9551C3FAEA77CCD7A7D588294DE9EA3B8DB6A8CC98DA8C567CDAB709A287F5D53453267841E6113B3A06DF01038B6A83FA6AA4A645BB43D276B71C6EA65A98A4E9C839D38CFEDCE176C5480E8BD8AEEAB20FC1C89B889672D980C5C121545CFD4BECECE53E9CEE27ED519CD53
+20210510150859 2 6 100 4095 2 E3508586273EAF882533D9104A0F6FF5818343120ECFA2DF8002402FEA175CD1C418C3CBCE3B8C3B8897FA169C9C9521399321A353ED16DE7EDFD5F28F3F8C1B5F52F368C463B3A1AB5CF5816666973A70FA756A6A2F70313D2830D490541C09F40E7ABDCA7EE76A625F19B87D4336196CBEBEB5491E4365D7DFDF56384A3DFE662628171820829B5628694A4B4915954CF89391F3C06D9A4DF618CD54406A1198F4DF74EA2DDF55244076A5BD9295DD516B9346A98EC225F16968CA804B94F2CF67B0A4CC23A679766476CD8033CA3532230AB83092D78AB138653BAC3FE96C2E6A91387E2D7263B72CC0FEB5443233BD5C137351A4EEC65954845938DE8137C0E3F70D9932E18E4C771BD0ED3D11CDAF4EA9745D3C2C8C32E2F4C7302425A96720F939C9A32BA9475EC974D57326605F5B0402FD6431096AC965246DDEA5AD8B2B0C24A86FDA4CC9397DCE101DF441AEC0FB887CB17F61A25D2C5945BA2DC45766E939CE1210C5D0E9A8BD229EA308E995B6A99164BAC0F3985010C4AC7C36F0BBB3118A17FB1963E865AF49FD77FB4E1BA3D9551C3FAEA77CCD7A7D588294DE9EA3B8DB6A8CC98DA8C567CDAB709A287F5D53453267841E6113B3A06DF01038B6A83FA6AA4A645BB43D276B71C6EA65A98A4E9C839D38CFEDCE176C5480E8BD8AEEAB20FC1C89B889672D980C5C121545CFD4BECECE53E9CEE27ED68073DB
+20210510151356 2 6 100 4095 2 E3508586273EAF882533D9104A0F6FF5818343120ECFA2DF8002402FEA175CD1C418C3CBCE3B8C3B8897FA169C9C9521399321A353ED16DE7EDFD5F28F3F8C1B5F52F368C463B3A1AB5CF5816666973A70FA756A6A2F70313D2830D490541C09F40E7ABDCA7EE76A625F19B87D4336196CBEBEB5491E4365D7DFDF56384A3DFE662628171820829B5628694A4B4915954CF89391F3C06D9A4DF618CD54406A1198F4DF74EA2DDF55244076A5BD9295DD516B9346A98EC225F16968CA804B94F2CF67B0A4CC23A679766476CD8033CA3532230AB83092D78AB138653BAC3FE96C2E6A91387E2D7263B72CC0FEB5443233BD5C137351A4EEC65954845938DE8137C0E3F70D9932E18E4C771BD0ED3D11CDAF4EA9745D3C2C8C32E2F4C7302425A96720F939C9A32BA9475EC974D57326605F5B0402FD6431096AC965246DDEA5AD8B2B0C24A86FDA4CC9397DCE101DF441AEC0FB887CB17F61A25D2C5945BA2DC45766E939CE1210C5D0E9A8BD229EA308E995B6A99164BAC0F3985010C4AC7C36F0BBB3118A17FB1963E865AF49FD77FB4E1BA3D9551C3FAEA77CCD7A7D588294DE9EA3B8DB6A8CC98DA8C567CDAB709A287F5D53453267841E6113B3A06DF01038B6A83FA6AA4A645BB43D276B71C6EA65A98A4E9C839D38CFEDCE176C5480E8BD8AEEAB20FC1C89B889672D980C5C121545CFD4BECECE53E9CEE27ED6D0558B
+20210510151823 2 6 100 4095 2 E3508586273EAF882533D9104A0F6FF5818343120ECFA2DF8002402FEA175CD1C418C3CBCE3B8C3B8897FA169C9C9521399321A353ED16DE7EDFD5F28F3F8C1B5F52F368C463B3A1AB5CF5816666973A70FA756A6A2F70313D2830D490541C09F40E7ABDCA7EE76A625F19B87D4336196CBEBEB5491E4365D7DFDF56384A3DFE662628171820829B5628694A4B4915954CF89391F3C06D9A4DF618CD54406A1198F4DF74EA2DDF55244076A5BD9295DD516B9346A98EC225F16968CA804B94F2CF67B0A4CC23A679766476CD8033CA3532230AB83092D78AB138653BAC3FE96C2E6A91387E2D7263B72CC0FEB5443233BD5C137351A4EEC65954845938DE8137C0E3F70D9932E18E4C771BD0ED3D11CDAF4EA9745D3C2C8C32E2F4C7302425A96720F939C9A32BA9475EC974D57326605F5B0402FD6431096AC965246DDEA5AD8B2B0C24A86FDA4CC9397DCE101DF441AEC0FB887CB17F61A25D2C5945BA2DC45766E939CE1210C5D0E9A8BD229EA308E995B6A99164BAC0F3985010C4AC7C36F0BBB3118A17FB1963E865AF49FD77FB4E1BA3D9551C3FAEA77CCD7A7D588294DE9EA3B8DB6A8CC98DA8C567CDAB709A287F5D53453267841E6113B3A06DF01038B6A83FA6AA4A645BB43D276B71C6EA65A98A4E9C839D38CFEDCE176C5480E8BD8AEEAB20FC1C89B889672D980C5C121545CFD4BECECE53E9CEE27ED71A5973
+20210510153129 2 6 100 4095 2 E3508586273EAF882533D9104A0F6FF5818343120ECFA2DF8002402FEA175CD1C418C3CBCE3B8C3B8897FA169C9C9521399321A353ED16DE7EDFD5F28F3F8C1B5F52F368C463B3A1AB5CF5816666973A70FA756A6A2F70313D2830D490541C09F40E7ABDCA7EE76A625F19B87D4336196CBEBEB5491E4365D7DFDF56384A3DFE662628171820829B5628694A4B4915954CF89391F3C06D9A4DF618CD54406A1198F4DF74EA2DDF55244076A5BD9295DD516B9346A98EC225F16968CA804B94F2CF67B0A4CC23A679766476CD8033CA3532230AB83092D78AB138653BAC3FE96C2E6A91387E2D7263B72CC0FEB5443233BD5C137351A4EEC65954845938DE8137C0E3F70D9932E18E4C771BD0ED3D11CDAF4EA9745D3C2C8C32E2F4C7302425A96720F939C9A32BA9475EC974D57326605F5B0402FD6431096AC965246DDEA5AD8B2B0C24A86FDA4CC9397DCE101DF441AEC0FB887CB17F61A25D2C5945BA2DC45766E939CE1210C5D0E9A8BD229EA308E995B6A99164BAC0F3985010C4AC7C36F0BBB3118A17FB1963E865AF49FD77FB4E1BA3D9551C3FAEA77CCD7A7D588294DE9EA3B8DB6A8CC98DA8C567CDAB709A287F5D53453267841E6113B3A06DF01038B6A83FA6AA4A645BB43D276B71C6EA65A98A4E9C839D38CFEDCE176C5480E8BD8AEEAB20FC1C89B889672D980C5C121545CFD4BECECE53E9CEE27ED7F992C3
+20210510155953 2 6 100 4095 2 E3508586273EAF882533D9104A0F6FF5818343120ECFA2DF8002402FEA175CD1C418C3CBCE3B8C3B8897FA169C9C9521399321A353ED16DE7EDFD5F28F3F8C1B5F52F368C463B3A1AB5CF5816666973A70FA756A6A2F70313D2830D490541C09F40E7ABDCA7EE76A625F19B87D4336196CBEBEB5491E4365D7DFDF56384A3DFE662628171820829B5628694A4B4915954CF89391F3C06D9A4DF618CD54406A1198F4DF74EA2DDF55244076A5BD9295DD516B9346A98EC225F16968CA804B94F2CF67B0A4CC23A679766476CD8033CA3532230AB83092D78AB138653BAC3FE96C2E6A91387E2D7263B72CC0FEB5443233BD5C137351A4EEC65954845938DE8137C0E3F70D9932E18E4C771BD0ED3D11CDAF4EA9745D3C2C8C32E2F4C7302425A96720F939C9A32BA9475EC974D57326605F5B0402FD6431096AC965246DDEA5AD8B2B0C24A86FDA4CC9397DCE101DF441AEC0FB887CB17F61A25D2C5945BA2DC45766E939CE1210C5D0E9A8BD229EA308E995B6A99164BAC0F3985010C4AC7C36F0BBB3118A17FB1963E865AF49FD77FB4E1BA3D9551C3FAEA77CCD7A7D588294DE9EA3B8DB6A8CC98DA8C567CDAB709A287F5D53453267841E6113B3A06DF01038B6A83FA6AA4A645BB43D276B71C6EA65A98A4E9C839D38CFEDCE176C5480E8BD8AEEAB20FC1C89B889672D980C5C121545CFD4BECECE53E9CEE27ED9EDF273
+20210510160542 2 6 100 4095 2 E3508586273EAF882533D9104A0F6FF5818343120ECFA2DF8002402FEA175CD1C418C3CBCE3B8C3B8897FA169C9C9521399321A353ED16DE7EDFD5F28F3F8C1B5F52F368C463B3A1AB5CF5816666973A70FA756A6A2F70313D2830D490541C09F40E7ABDCA7EE76A625F19B87D4336196CBEBEB5491E4365D7DFDF56384A3DFE662628171820829B5628694A4B4915954CF89391F3C06D9A4DF618CD54406A1198F4DF74EA2DDF55244076A5BD9295DD516B9346A98EC225F16968CA804B94F2CF67B0A4CC23A679766476CD8033CA3532230AB83092D78AB138653BAC3FE96C2E6A91387E2D7263B72CC0FEB5443233BD5C137351A4EEC65954845938DE8137C0E3F70D9932E18E4C771BD0ED3D11CDAF4EA9745D3C2C8C32E2F4C7302425A96720F939C9A32BA9475EC974D57326605F5B0402FD6431096AC965246DDEA5AD8B2B0C24A86FDA4CC9397DCE101DF441AEC0FB887CB17F61A25D2C5945BA2DC45766E939CE1210C5D0E9A8BD229EA308E995B6A99164BAC0F3985010C4AC7C36F0BBB3118A17FB1963E865AF49FD77FB4E1BA3D9551C3FAEA77CCD7A7D588294DE9EA3B8DB6A8CC98DA8C567CDAB709A287F5D53453267841E6113B3A06DF01038B6A83FA6AA4A645BB43D276B71C6EA65A98A4E9C839D38CFEDCE176C5480E8BD8AEEAB20FC1C89B889672D980C5C121545CFD4BECECE53E9CEE27EDA4F6463
+20210510161006 2 6 100 4095 5 E3508586273EAF882533D9104A0F6FF5818343120ECFA2DF8002402FEA175CD1C418C3CBCE3B8C3B8897FA169C9C9521399321A353ED16DE7EDFD5F28F3F8C1B5F52F368C463B3A1AB5CF5816666973A70FA756A6A2F70313D2830D490541C09F40E7ABDCA7EE76A625F19B87D4336196CBEBEB5491E4365D7DFDF56384A3DFE662628171820829B5628694A4B4915954CF89391F3C06D9A4DF618CD54406A1198F4DF74EA2DDF55244076A5BD9295DD516B9346A98EC225F16968CA804B94F2CF67B0A4CC23A679766476CD8033CA3532230AB83092D78AB138653BAC3FE96C2E6A91387E2D7263B72CC0FEB5443233BD5C137351A4EEC65954845938DE8137C0E3F70D9932E18E4C771BD0ED3D11CDAF4EA9745D3C2C8C32E2F4C7302425A96720F939C9A32BA9475EC974D57326605F5B0402FD6431096AC965246DDEA5AD8B2B0C24A86FDA4CC9397DCE101DF441AEC0FB887CB17F61A25D2C5945BA2DC45766E939CE1210C5D0E9A8BD229EA308E995B6A99164BAC0F3985010C4AC7C36F0BBB3118A17FB1963E865AF49FD77FB4E1BA3D9551C3FAEA77CCD7A7D588294DE9EA3B8DB6A8CC98DA8C567CDAB709A287F5D53453267841E6113B3A06DF01038B6A83FA6AA4A645BB43D276B71C6EA65A98A4E9C839D38CFEDCE176C5480E8BD8AEEAB20FC1C89B889672D980C5C121545CFD4BECECE53E9CEE27EDA97EB6F
+20210510161446 2 6 100 4095 2 E3508586273EAF882533D9104A0F6FF5818343120ECFA2DF8002402FEA175CD1C418C3CBCE3B8C3B8897FA169C9C9521399321A353ED16DE7EDFD5F28F3F8C1B5F52F368C463B3A1AB5CF5816666973A70FA756A6A2F70313D2830D490541C09F40E7ABDCA7EE76A625F19B87D4336196CBEBEB5491E4365D7DFDF56384A3DFE662628171820829B5628694A4B4915954CF89391F3C06D9A4DF618CD54406A1198F4DF74EA2DDF55244076A5BD9295DD516B9346A98EC225F16968CA804B94F2CF67B0A4CC23A679766476CD8033CA3532230AB83092D78AB138653BAC3FE96C2E6A91387E2D7263B72CC0FEB5443233BD5C137351A4EEC65954845938DE8137C0E3F70D9932E18E4C771BD0ED3D11CDAF4EA9745D3C2C8C32E2F4C7302425A96720F939C9A32BA9475EC974D57326605F5B0402FD6431096AC965246DDEA5AD8B2B0C24A86FDA4CC9397DCE101DF441AEC0FB887CB17F61A25D2C5945BA2DC45766E939CE1210C5D0E9A8BD229EA308E995B6A99164BAC0F3985010C4AC7C36F0BBB3118A17FB1963E865AF49FD77FB4E1BA3D9551C3FAEA77CCD7A7D588294DE9EA3B8DB6A8CC98DA8C567CDAB709A287F5D53453267841E6113B3A06DF01038B6A83FA6AA4A645BB43D276B71C6EA65A98A4E9C839D38CFEDCE176C5480E8BD8AEEAB20FC1C89B889672D980C5C121545CFD4BECECE53E9CEE27EDAE44433
+20210510164007 2 6 100 4095 2 E3508586273EAF882533D9104A0F6FF5818343120ECFA2DF8002402FEA175CD1C418C3CBCE3B8C3B8897FA169C9C9521399321A353ED16DE7EDFD5F28F3F8C1B5F52F368C463B3A1AB5CF5816666973A70FA756A6A2F70313D2830D490541C09F40E7ABDCA7EE76A625F19B87D4336196CBEBEB5491E4365D7DFDF56384A3DFE662628171820829B5628694A4B4915954CF89391F3C06D9A4DF618CD54406A1198F4DF74EA2DDF55244076A5BD9295DD516B9346A98EC225F16968CA804B94F2CF67B0A4CC23A679766476CD8033CA3532230AB83092D78AB138653BAC3FE96C2E6A91387E2D7263B72CC0FEB5443233BD5C137351A4EEC65954845938DE8137C0E3F70D9932E18E4C771BD0ED3D11CDAF4EA9745D3C2C8C32E2F4C7302425A96720F939C9A32BA9475EC974D57326605F5B0402FD6431096AC965246DDEA5AD8B2B0C24A86FDA4CC9397DCE101DF441AEC0FB887CB17F61A25D2C5945BA2DC45766E939CE1210C5D0E9A8BD229EA308E995B6A99164BAC0F3985010C4AC7C36F0BBB3118A17FB1963E865AF49FD77FB4E1BA3D9551C3FAEA77CCD7A7D588294DE9EA3B8DB6A8CC98DA8C567CDAB709A287F5D53453267841E6113B3A06DF01038B6A83FA6AA4A645BB43D276B71C6EA65A98A4E9C839D38CFEDCE176C5480E8BD8AEEAB20FC1C89B889672D980C5C121545CFD4BECECE53E9CEE27EDCA3DB53
+20210510164752 2 6 100 4095 2 E3508586273EAF882533D9104A0F6FF5818343120ECFA2DF8002402FEA175CD1C418C3CBCE3B8C3B8897FA169C9C9521399321A353ED16DE7EDFD5F28F3F8C1B5F52F368C463B3A1AB5CF5816666973A70FA756A6A2F70313D2830D490541C09F40E7ABDCA7EE76A625F19B87D4336196CBEBEB5491E4365D7DFDF56384A3DFE662628171820829B5628694A4B4915954CF89391F3C06D9A4DF618CD54406A1198F4DF74EA2DDF55244076A5BD9295DD516B9346A98EC225F16968CA804B94F2CF67B0A4CC23A679766476CD8033CA3532230AB83092D78AB138653BAC3FE96C2E6A91387E2D7263B72CC0FEB5443233BD5C137351A4EEC65954845938DE8137C0E3F70D9932E18E4C771BD0ED3D11CDAF4EA9745D3C2C8C32E2F4C7302425A96720F939C9A32BA9475EC974D57326605F5B0402FD6431096AC965246DDEA5AD8B2B0C24A86FDA4CC9397DCE101DF441AEC0FB887CB17F61A25D2C5945BA2DC45766E939CE1210C5D0E9A8BD229EA308E995B6A99164BAC0F3985010C4AC7C36F0BBB3118A17FB1963E865AF49FD77FB4E1BA3D9551C3FAEA77CCD7A7D588294DE9EA3B8DB6A8CC98DA8C567CDAB709A287F5D53453267841E6113B3A06DF01038B6A83FA6AA4A645BB43D276B71C6EA65A98A4E9C839D38CFEDCE176C5480E8BD8AEEAB20FC1C89B889672D980C5C121545CFD4BECECE53E9CEE27EDD296153
+20210510170111 2 6 100 4095 5 E3508586273EAF882533D9104A0F6FF5818343120ECFA2DF8002402FEA175CD1C418C3CBCE3B8C3B8897FA169C9C9521399321A353ED16DE7EDFD5F28F3F8C1B5F52F368C463B3A1AB5CF5816666973A70FA756A6A2F70313D2830D490541C09F40E7ABDCA7EE76A625F19B87D4336196CBEBEB5491E4365D7DFDF56384A3DFE662628171820829B5628694A4B4915954CF89391F3C06D9A4DF618CD54406A1198F4DF74EA2DDF55244076A5BD9295DD516B9346A98EC225F16968CA804B94F2CF67B0A4CC23A679766476CD8033CA3532230AB83092D78AB138653BAC3FE96C2E6A91387E2D7263B72CC0FEB5443233BD5C137351A4EEC65954845938DE8137C0E3F70D9932E18E4C771BD0ED3D11CDAF4EA9745D3C2C8C32E2F4C7302425A96720F939C9A32BA9475EC974D57326605F5B0402FD6431096AC965246DDEA5AD8B2B0C24A86FDA4CC9397DCE101DF441AEC0FB887CB17F61A25D2C5945BA2DC45766E939CE1210C5D0E9A8BD229EA308E995B6A99164BAC0F3985010C4AC7C36F0BBB3118A17FB1963E865AF49FD77FB4E1BA3D9551C3FAEA77CCD7A7D588294DE9EA3B8DB6A8CC98DA8C567CDAB709A287F5D53453267841E6113B3A06DF01038B6A83FA6AA4A645BB43D276B71C6EA65A98A4E9C839D38CFEDCE176C5480E8BD8AEEAB20FC1C89B889672D980C5C121545CFD4BECECE53E9CEE27EDE0FAFB7
+20210510171053 2 6 100 4095 5 E3508586273EAF882533D9104A0F6FF5818343120ECFA2DF8002402FEA175CD1C418C3CBCE3B8C3B8897FA169C9C9521399321A353ED16DE7EDFD5F28F3F8C1B5F52F368C463B3A1AB5CF5816666973A70FA756A6A2F70313D2830D490541C09F40E7ABDCA7EE76A625F19B87D4336196CBEBEB5491E4365D7DFDF56384A3DFE662628171820829B5628694A4B4915954CF89391F3C06D9A4DF618CD54406A1198F4DF74EA2DDF55244076A5BD9295DD516B9346A98EC225F16968CA804B94F2CF67B0A4CC23A679766476CD8033CA3532230AB83092D78AB138653BAC3FE96C2E6A91387E2D7263B72CC0FEB5443233BD5C137351A4EEC65954845938DE8137C0E3F70D9932E18E4C771BD0ED3D11CDAF4EA9745D3C2C8C32E2F4C7302425A96720F939C9A32BA9475EC974D57326605F5B0402FD6431096AC965246DDEA5AD8B2B0C24A86FDA4CC9397DCE101DF441AEC0FB887CB17F61A25D2C5945BA2DC45766E939CE1210C5D0E9A8BD229EA308E995B6A99164BAC0F3985010C4AC7C36F0BBB3118A17FB1963E865AF49FD77FB4E1BA3D9551C3FAEA77CCD7A7D588294DE9EA3B8DB6A8CC98DA8C567CDAB709A287F5D53453267841E6113B3A06DF01038B6A83FA6AA4A645BB43D276B71C6EA65A98A4E9C839D38CFEDCE176C5480E8BD8AEEAB20FC1C89B889672D980C5C121545CFD4BECECE53E9CEE27EDEB6FD4F
+20210510172049 2 6 100 4095 2 E3508586273EAF882533D9104A0F6FF5818343120ECFA2DF8002402FEA175CD1C418C3CBCE3B8C3B8897FA169C9C9521399321A353ED16DE7EDFD5F28F3F8C1B5F52F368C463B3A1AB5CF5816666973A70FA756A6A2F70313D2830D490541C09F40E7ABDCA7EE76A625F19B87D4336196CBEBEB5491E4365D7DFDF56384A3DFE662628171820829B5628694A4B4915954CF89391F3C06D9A4DF618CD54406A1198F4DF74EA2DDF55244076A5BD9295DD516B9346A98EC225F16968CA804B94F2CF67B0A4CC23A679766476CD8033CA3532230AB83092D78AB138653BAC3FE96C2E6A91387E2D7263B72CC0FEB5443233BD5C137351A4EEC65954845938DE8137C0E3F70D9932E18E4C771BD0ED3D11CDAF4EA9745D3C2C8C32E2F4C7302425A96720F939C9A32BA9475EC974D57326605F5B0402FD6431096AC965246DDEA5AD8B2B0C24A86FDA4CC9397DCE101DF441AEC0FB887CB17F61A25D2C5945BA2DC45766E939CE1210C5D0E9A8BD229EA308E995B6A99164BAC0F3985010C4AC7C36F0BBB3118A17FB1963E865AF49FD77FB4E1BA3D9551C3FAEA77CCD7A7D588294DE9EA3B8DB6A8CC98DA8C567CDAB709A287F5D53453267841E6113B3A06DF01038B6A83FA6AA4A645BB43D276B71C6EA65A98A4E9C839D38CFEDCE176C5480E8BD8AEEAB20FC1C89B889672D980C5C121545CFD4BECECE53E9CEE27EDF621333
+20210510174942 2 6 100 4095 5 E3508586273EAF882533D9104A0F6FF5818343120ECFA2DF8002402FEA175CD1C418C3CBCE3B8C3B8897FA169C9C9521399321A353ED16DE7EDFD5F28F3F8C1B5F52F368C463B3A1AB5CF5816666973A70FA756A6A2F70313D2830D490541C09F40E7ABDCA7EE76A625F19B87D4336196CBEBEB5491E4365D7DFDF56384A3DFE662628171820829B5628694A4B4915954CF89391F3C06D9A4DF618CD54406A1198F4DF74EA2DDF55244076A5BD9295DD516B9346A98EC225F16968CA804B94F2CF67B0A4CC23A679766476CD8033CA3532230AB83092D78AB138653BAC3FE96C2E6A91387E2D7263B72CC0FEB5443233BD5C137351A4EEC65954845938DE8137C0E3F70D9932E18E4C771BD0ED3D11CDAF4EA9745D3C2C8C32E2F4C7302425A96720F939C9A32BA9475EC974D57326605F5B0402FD6431096AC965246DDEA5AD8B2B0C24A86FDA4CC9397DCE101DF441AEC0FB887CB17F61A25D2C5945BA2DC45766E939CE1210C5D0E9A8BD229EA308E995B6A99164BAC0F3985010C4AC7C36F0BBB3118A17FB1963E865AF49FD77FB4E1BA3D9551C3FAEA77CCD7A7D588294DE9EA3B8DB6A8CC98DA8C567CDAB709A287F5D53453267841E6113B3A06DF01038B6A83FA6AA4A645BB43D276B71C6EA65A98A4E9C839D38CFEDCE176C5480E8BD8AEEAB20FC1C89B889672D980C5C121545CFD4BECECE53E9CEE27EE15B9E07
+20210510175641 2 6 100 4095 5 E3508586273EAF882533D9104A0F6FF5818343120ECFA2DF8002402FEA175CD1C418C3CBCE3B8C3B8897FA169C9C9521399321A353ED16DE7EDFD5F28F3F8C1B5F52F368C463B3A1AB5CF5816666973A70FA756A6A2F70313D2830D490541C09F40E7ABDCA7EE76A625F19B87D4336196CBEBEB5491E4365D7DFDF56384A3DFE662628171820829B5628694A4B4915954CF89391F3C06D9A4DF618CD54406A1198F4DF74EA2DDF55244076A5BD9295DD516B9346A98EC225F16968CA804B94F2CF67B0A4CC23A679766476CD8033CA3532230AB83092D78AB138653BAC3FE96C2E6A91387E2D7263B72CC0FEB5443233BD5C137351A4EEC65954845938DE8137C0E3F70D9932E18E4C771BD0ED3D11CDAF4EA9745D3C2C8C32E2F4C7302425A96720F939C9A32BA9475EC974D57326605F5B0402FD6431096AC965246DDEA5AD8B2B0C24A86FDA4CC9397DCE101DF441AEC0FB887CB17F61A25D2C5945BA2DC45766E939CE1210C5D0E9A8BD229EA308E995B6A99164BAC0F3985010C4AC7C36F0BBB3118A17FB1963E865AF49FD77FB4E1BA3D9551C3FAEA77CCD7A7D588294DE9EA3B8DB6A8CC98DA8C567CDAB709A287F5D53453267841E6113B3A06DF01038B6A83FA6AA4A645BB43D276B71C6EA65A98A4E9C839D38CFEDCE176C5480E8BD8AEEAB20FC1C89B889672D980C5C121545CFD4BECECE53E9CEE27EE1CEFE0F
+20210510180112 2 6 100 4095 2 E3508586273EAF882533D9104A0F6FF5818343120ECFA2DF8002402FEA175CD1C418C3CBCE3B8C3B8897FA169C9C9521399321A353ED16DE7EDFD5F28F3F8C1B5F52F368C463B3A1AB5CF5816666973A70FA756A6A2F70313D2830D490541C09F40E7ABDCA7EE76A625F19B87D4336196CBEBEB5491E4365D7DFDF56384A3DFE662628171820829B5628694A4B4915954CF89391F3C06D9A4DF618CD54406A1198F4DF74EA2DDF55244076A5BD9295DD516B9346A98EC225F16968CA804B94F2CF67B0A4CC23A679766476CD8033CA3532230AB83092D78AB138653BAC3FE96C2E6A91387E2D7263B72CC0FEB5443233BD5C137351A4EEC65954845938DE8137C0E3F70D9932E18E4C771BD0ED3D11CDAF4EA9745D3C2C8C32E2F4C7302425A96720F939C9A32BA9475EC974D57326605F5B0402FD6431096AC965246DDEA5AD8B2B0C24A86FDA4CC9397DCE101DF441AEC0FB887CB17F61A25D2C5945BA2DC45766E939CE1210C5D0E9A8BD229EA308E995B6A99164BAC0F3985010C4AC7C36F0BBB3118A17FB1963E865AF49FD77FB4E1BA3D9551C3FAEA77CCD7A7D588294DE9EA3B8DB6A8CC98DA8C567CDAB709A287F5D53453267841E6113B3A06DF01038B6A83FA6AA4A645BB43D276B71C6EA65A98A4E9C839D38CFEDCE176C5480E8BD8AEEAB20FC1C89B889672D980C5C121545CFD4BECECE53E9CEE27EE2138F1B
+20210510180610 2 6 100 4095 5 E3508586273EAF882533D9104A0F6FF5818343120ECFA2DF8002402FEA175CD1C418C3CBCE3B8C3B8897FA169C9C9521399321A353ED16DE7EDFD5F28F3F8C1B5F52F368C463B3A1AB5CF5816666973A70FA756A6A2F70313D2830D490541C09F40E7ABDCA7EE76A625F19B87D4336196CBEBEB5491E4365D7DFDF56384A3DFE662628171820829B5628694A4B4915954CF89391F3C06D9A4DF618CD54406A1198F4DF74EA2DDF55244076A5BD9295DD516B9346A98EC225F16968CA804B94F2CF67B0A4CC23A679766476CD8033CA3532230AB83092D78AB138653BAC3FE96C2E6A91387E2D7263B72CC0FEB5443233BD5C137351A4EEC65954845938DE8137C0E3F70D9932E18E4C771BD0ED3D11CDAF4EA9745D3C2C8C32E2F4C7302425A96720F939C9A32BA9475EC974D57326605F5B0402FD6431096AC965246DDEA5AD8B2B0C24A86FDA4CC9397DCE101DF441AEC0FB887CB17F61A25D2C5945BA2DC45766E939CE1210C5D0E9A8BD229EA308E995B6A99164BAC0F3985010C4AC7C36F0BBB3118A17FB1963E865AF49FD77FB4E1BA3D9551C3FAEA77CCD7A7D588294DE9EA3B8DB6A8CC98DA8C567CDAB709A287F5D53453267841E6113B3A06DF01038B6A83FA6AA4A645BB43D276B71C6EA65A98A4E9C839D38CFEDCE176C5480E8BD8AEEAB20FC1C89B889672D980C5C121545CFD4BECECE53E9CEE27EE2635EA7
+20210510182139 2 6 100 4095 5 C0CF9D192A5E67E12DB4EBB35F3DD5A93041B217DDC24746828F760867A58487DCC1318CEB5929A76AB776A38F78415D03207716AFB66462B964A8B64E26D54306DFC888AF824BD68D46FD93EB19835F5CA576CDF7D57281B5A2D443CA10B94C9D091680FAE8AFDC9E862E7B8AA8EB9C5964A7A6DCF33D07735325CDC0AC2E0CB1AD72398FD23D9F375C766E55060C7E9556F16933363BD73288755FCFBE99FBEF5FEF5CDBE525AC7C1AB26CE56316568FA790082931F4015CE0BB432797A80617BEF82B448D8CF568A2EEF1CC594A4CAB3FAE7CB97866833D9BD646BB4A6850AAC1D6C8011C486C9FAB4AF5FB7C1591734B3D9FB3F46E6A07F61D1AA78B19B4C96AAE67ABCDC1218D205277054711CD88C39D93913AAFED002C96950852971C044779E8C44452321A72B50802658F1E62759B5155AE21FDC3F0CBFA1BF06E35147ED4E328E1D6FFF1BC67CE4EC4D7872797759891D74E53BD496BD7E54C6F28E8E2D60E0CC5381E136465C551BA03B91D112F50F4F84208C2AE35C7CE712F230539E5CE5211D87C56074EC6E53A0A1FFB811B9580F7045D14B89C0E6CEC5B12834317944BB2D743926BD2EFF4D8CD19E7A85C58E0CD4BAF7D7915F4A8EC46CB20FF3B82ED5C8D30F5A4CAA07E0C8CCEE173FC59C3444CEB672220B98F8065A9DD5244BAAA6D44347100D2D4FABC8FB7E6746848E0E9CFD2C6AD701D4CADABDF
+20210510182246 2 6 100 4095 5 C0CF9D192A5E67E12DB4EBB35F3DD5A93041B217DDC24746828F760867A58487DCC1318CEB5929A76AB776A38F78415D03207716AFB66462B964A8B64E26D54306DFC888AF824BD68D46FD93EB19835F5CA576CDF7D57281B5A2D443CA10B94C9D091680FAE8AFDC9E862E7B8AA8EB9C5964A7A6DCF33D07735325CDC0AC2E0CB1AD72398FD23D9F375C766E55060C7E9556F16933363BD73288755FCFBE99FBEF5FEF5CDBE525AC7C1AB26CE56316568FA790082931F4015CE0BB432797A80617BEF82B448D8CF568A2EEF1CC594A4CAB3FAE7CB97866833D9BD646BB4A6850AAC1D6C8011C486C9FAB4AF5FB7C1591734B3D9FB3F46E6A07F61D1AA78B19B4C96AAE67ABCDC1218D205277054711CD88C39D93913AAFED002C96950852971C044779E8C44452321A72B50802658F1E62759B5155AE21FDC3F0CBFA1BF06E35147ED4E328E1D6FFF1BC67CE4EC4D7872797759891D74E53BD496BD7E54C6F28E8E2D60E0CC5381E136465C551BA03B91D112F50F4F84208C2AE35C7CE712F230539E5CE5211D87C56074EC6E53A0A1FFB811B9580F7045D14B89C0E6CEC5B12834317944BB2D743926BD2EFF4D8CD19E7A85C58E0CD4BAF7D7915F4A8EC46CB20FF3B82ED5C8D30F5A4CAA07E0C8CCEE173FC59C3444CEB672220B98F8065A9DD5244BAAA6D44347100D2D4FABC8FB7E6746848E0E9CFD2C6AD701D4CBA2FDF
+20210510183239 2 6 100 4095 5 C0CF9D192A5E67E12DB4EBB35F3DD5A93041B217DDC24746828F760867A58487DCC1318CEB5929A76AB776A38F78415D03207716AFB66462B964A8B64E26D54306DFC888AF824BD68D46FD93EB19835F5CA576CDF7D57281B5A2D443CA10B94C9D091680FAE8AFDC9E862E7B8AA8EB9C5964A7A6DCF33D07735325CDC0AC2E0CB1AD72398FD23D9F375C766E55060C7E9556F16933363BD73288755FCFBE99FBEF5FEF5CDBE525AC7C1AB26CE56316568FA790082931F4015CE0BB432797A80617BEF82B448D8CF568A2EEF1CC594A4CAB3FAE7CB97866833D9BD646BB4A6850AAC1D6C8011C486C9FAB4AF5FB7C1591734B3D9FB3F46E6A07F61D1AA78B19B4C96AAE67ABCDC1218D205277054711CD88C39D93913AAFED002C96950852971C044779E8C44452321A72B50802658F1E62759B5155AE21FDC3F0CBFA1BF06E35147ED4E328E1D6FFF1BC67CE4EC4D7872797759891D74E53BD496BD7E54C6F28E8E2D60E0CC5381E136465C551BA03B91D112F50F4F84208C2AE35C7CE712F230539E5CE5211D87C56074EC6E53A0A1FFB811B9580F7045D14B89C0E6CEC5B12834317944BB2D743926BD2EFF4D8CD19E7A85C58E0CD4BAF7D7915F4A8EC46CB20FF3B82ED5C8D30F5A4CAA07E0C8CCEE173FC59C3444CEB672220B98F8065A9DD5244BAAA6D44347100D2D4FABC8FB7E6746848E0E9CFD2C6AD701D4D6A3817
+20210510185138 2 6 100 4095 2 C0CF9D192A5E67E12DB4EBB35F3DD5A93041B217DDC24746828F760867A58487DCC1318CEB5929A76AB776A38F78415D03207716AFB66462B964A8B64E26D54306DFC888AF824BD68D46FD93EB19835F5CA576CDF7D57281B5A2D443CA10B94C9D091680FAE8AFDC9E862E7B8AA8EB9C5964A7A6DCF33D07735325CDC0AC2E0CB1AD72398FD23D9F375C766E55060C7E9556F16933363BD73288755FCFBE99FBEF5FEF5CDBE525AC7C1AB26CE56316568FA790082931F4015CE0BB432797A80617BEF82B448D8CF568A2EEF1CC594A4CAB3FAE7CB97866833D9BD646BB4A6850AAC1D6C8011C486C9FAB4AF5FB7C1591734B3D9FB3F46E6A07F61D1AA78B19B4C96AAE67ABCDC1218D205277054711CD88C39D93913AAFED002C96950852971C044779E8C44452321A72B50802658F1E62759B5155AE21FDC3F0CBFA1BF06E35147ED4E328E1D6FFF1BC67CE4EC4D7872797759891D74E53BD496BD7E54C6F28E8E2D60E0CC5381E136465C551BA03B91D112F50F4F84208C2AE35C7CE712F230539E5CE5211D87C56074EC6E53A0A1FFB811B9580F7045D14B89C0E6CEC5B12834317944BB2D743926BD2EFF4D8CD19E7A85C58E0CD4BAF7D7915F4A8EC46CB20FF3B82ED5C8D30F5A4CAA07E0C8CCEE173FC59C3444CEB672220B98F8065A9DD5244BAAA6D44347100D2D4FABC8FB7E6746848E0E9CFD2C6AD701D4EBD743B
+20210510190703 2 6 100 4095 2 C0CF9D192A5E67E12DB4EBB35F3DD5A93041B217DDC24746828F760867A58487DCC1318CEB5929A76AB776A38F78415D03207716AFB66462B964A8B64E26D54306DFC888AF824BD68D46FD93EB19835F5CA576CDF7D57281B5A2D443CA10B94C9D091680FAE8AFDC9E862E7B8AA8EB9C5964A7A6DCF33D07735325CDC0AC2E0CB1AD72398FD23D9F375C766E55060C7E9556F16933363BD73288755FCFBE99FBEF5FEF5CDBE525AC7C1AB26CE56316568FA790082931F4015CE0BB432797A80617BEF82B448D8CF568A2EEF1CC594A4CAB3FAE7CB97866833D9BD646BB4A6850AAC1D6C8011C486C9FAB4AF5FB7C1591734B3D9FB3F46E6A07F61D1AA78B19B4C96AAE67ABCDC1218D205277054711CD88C39D93913AAFED002C96950852971C044779E8C44452321A72B50802658F1E62759B5155AE21FDC3F0CBFA1BF06E35147ED4E328E1D6FFF1BC67CE4EC4D7872797759891D74E53BD496BD7E54C6F28E8E2D60E0CC5381E136465C551BA03B91D112F50F4F84208C2AE35C7CE712F230539E5CE5211D87C56074EC6E53A0A1FFB811B9580F7045D14B89C0E6CEC5B12834317944BB2D743926BD2EFF4D8CD19E7A85C58E0CD4BAF7D7915F4A8EC46CB20FF3B82ED5C8D30F5A4CAA07E0C8CCEE173FC59C3444CEB672220B98F8065A9DD5244BAAA6D44347100D2D4FABC8FB7E6746848E0E9CFD2C6AD701D4FD39563
+20210510191012 2 6 100 4095 2 C0CF9D192A5E67E12DB4EBB35F3DD5A93041B217DDC24746828F760867A58487DCC1318CEB5929A76AB776A38F78415D03207716AFB66462B964A8B64E26D54306DFC888AF824BD68D46FD93EB19835F5CA576CDF7D57281B5A2D443CA10B94C9D091680FAE8AFDC9E862E7B8AA8EB9C5964A7A6DCF33D07735325CDC0AC2E0CB1AD72398FD23D9F375C766E55060C7E9556F16933363BD73288755FCFBE99FBEF5FEF5CDBE525AC7C1AB26CE56316568FA790082931F4015CE0BB432797A80617BEF82B448D8CF568A2EEF1CC594A4CAB3FAE7CB97866833D9BD646BB4A6850AAC1D6C8011C486C9FAB4AF5FB7C1591734B3D9FB3F46E6A07F61D1AA78B19B4C96AAE67ABCDC1218D205277054711CD88C39D93913AAFED002C96950852971C044779E8C44452321A72B50802658F1E62759B5155AE21FDC3F0CBFA1BF06E35147ED4E328E1D6FFF1BC67CE4EC4D7872797759891D74E53BD496BD7E54C6F28E8E2D60E0CC5381E136465C551BA03B91D112F50F4F84208C2AE35C7CE712F230539E5CE5211D87C56074EC6E53A0A1FFB811B9580F7045D14B89C0E6CEC5B12834317944BB2D743926BD2EFF4D8CD19E7A85C58E0CD4BAF7D7915F4A8EC46CB20FF3B82ED5C8D30F5A4CAA07E0C8CCEE173FC59C3444CEB672220B98F8065A9DD5244BAAA6D44347100D2D4FABC8FB7E6746848E0E9CFD2C6AD701D50038993
+20210510193403 2 6 100 4095 5 C0CF9D192A5E67E12DB4EBB35F3DD5A93041B217DDC24746828F760867A58487DCC1318CEB5929A76AB776A38F78415D03207716AFB66462B964A8B64E26D54306DFC888AF824BD68D46FD93EB19835F5CA576CDF7D57281B5A2D443CA10B94C9D091680FAE8AFDC9E862E7B8AA8EB9C5964A7A6DCF33D07735325CDC0AC2E0CB1AD72398FD23D9F375C766E55060C7E9556F16933363BD73288755FCFBE99FBEF5FEF5CDBE525AC7C1AB26CE56316568FA790082931F4015CE0BB432797A80617BEF82B448D8CF568A2EEF1CC594A4CAB3FAE7CB97866833D9BD646BB4A6850AAC1D6C8011C486C9FAB4AF5FB7C1591734B3D9FB3F46E6A07F61D1AA78B19B4C96AAE67ABCDC1218D205277054711CD88C39D93913AAFED002C96950852971C044779E8C44452321A72B50802658F1E62759B5155AE21FDC3F0CBFA1BF06E35147ED4E328E1D6FFF1BC67CE4EC4D7872797759891D74E53BD496BD7E54C6F28E8E2D60E0CC5381E136465C551BA03B91D112F50F4F84208C2AE35C7CE712F230539E5CE5211D87C56074EC6E53A0A1FFB811B9580F7045D14B89C0E6CEC5B12834317944BB2D743926BD2EFF4D8CD19E7A85C58E0CD4BAF7D7915F4A8EC46CB20FF3B82ED5C8D30F5A4CAA07E0C8CCEE173FC59C3444CEB672220B98F8065A9DD5244BAAA6D44347100D2D4FABC8FB7E6746848E0E9CFD2C6AD701D51B59F6F
+20210510193504 2 6 100 4095 2 C0CF9D192A5E67E12DB4EBB35F3DD5A93041B217DDC24746828F760867A58487DCC1318CEB5929A76AB776A38F78415D03207716AFB66462B964A8B64E26D54306DFC888AF824BD68D46FD93EB19835F5CA576CDF7D57281B5A2D443CA10B94C9D091680FAE8AFDC9E862E7B8AA8EB9C5964A7A6DCF33D07735325CDC0AC2E0CB1AD72398FD23D9F375C766E55060C7E9556F16933363BD73288755FCFBE99FBEF5FEF5CDBE525AC7C1AB26CE56316568FA790082931F4015CE0BB432797A80617BEF82B448D8CF568A2EEF1CC594A4CAB3FAE7CB97866833D9BD646BB4A6850AAC1D6C8011C486C9FAB4AF5FB7C1591734B3D9FB3F46E6A07F61D1AA78B19B4C96AAE67ABCDC1218D205277054711CD88C39D93913AAFED002C96950852971C044779E8C44452321A72B50802658F1E62759B5155AE21FDC3F0CBFA1BF06E35147ED4E328E1D6FFF1BC67CE4EC4D7872797759891D74E53BD496BD7E54C6F28E8E2D60E0CC5381E136465C551BA03B91D112F50F4F84208C2AE35C7CE712F230539E5CE5211D87C56074EC6E53A0A1FFB811B9580F7045D14B89C0E6CEC5B12834317944BB2D743926BD2EFF4D8CD19E7A85C58E0CD4BAF7D7915F4A8EC46CB20FF3B82ED5C8D30F5A4CAA07E0C8CCEE173FC59C3444CEB672220B98F8065A9DD5244BAAA6D44347100D2D4FABC8FB7E6746848E0E9CFD2C6AD701D51BFEACB
+20210510193712 2 6 100 4095 5 C0CF9D192A5E67E12DB4EBB35F3DD5A93041B217DDC24746828F760867A58487DCC1318CEB5929A76AB776A38F78415D03207716AFB66462B964A8B64E26D54306DFC888AF824BD68D46FD93EB19835F5CA576CDF7D57281B5A2D443CA10B94C9D091680FAE8AFDC9E862E7B8AA8EB9C5964A7A6DCF33D07735325CDC0AC2E0CB1AD72398FD23D9F375C766E55060C7E9556F16933363BD73288755FCFBE99FBEF5FEF5CDBE525AC7C1AB26CE56316568FA790082931F4015CE0BB432797A80617BEF82B448D8CF568A2EEF1CC594A4CAB3FAE7CB97866833D9BD646BB4A6850AAC1D6C8011C486C9FAB4AF5FB7C1591734B3D9FB3F46E6A07F61D1AA78B19B4C96AAE67ABCDC1218D205277054711CD88C39D93913AAFED002C96950852971C044779E8C44452321A72B50802658F1E62759B5155AE21FDC3F0CBFA1BF06E35147ED4E328E1D6FFF1BC67CE4EC4D7872797759891D74E53BD496BD7E54C6F28E8E2D60E0CC5381E136465C551BA03B91D112F50F4F84208C2AE35C7CE712F230539E5CE5211D87C56074EC6E53A0A1FFB811B9580F7045D14B89C0E6CEC5B12834317944BB2D743926BD2EFF4D8CD19E7A85C58E0CD4BAF7D7915F4A8EC46CB20FF3B82ED5C8D30F5A4CAA07E0C8CCEE173FC59C3444CEB672220B98F8065A9DD5244BAAA6D44347100D2D4FABC8FB7E6746848E0E9CFD2C6AD701D51DE6847
+20210510200016 2 6 100 4095 2 C0CF9D192A5E67E12DB4EBB35F3DD5A93041B217DDC24746828F760867A58487DCC1318CEB5929A76AB776A38F78415D03207716AFB66462B964A8B64E26D54306DFC888AF824BD68D46FD93EB19835F5CA576CDF7D57281B5A2D443CA10B94C9D091680FAE8AFDC9E862E7B8AA8EB9C5964A7A6DCF33D07735325CDC0AC2E0CB1AD72398FD23D9F375C766E55060C7E9556F16933363BD73288755FCFBE99FBEF5FEF5CDBE525AC7C1AB26CE56316568FA790082931F4015CE0BB432797A80617BEF82B448D8CF568A2EEF1CC594A4CAB3FAE7CB97866833D9BD646BB4A6850AAC1D6C8011C486C9FAB4AF5FB7C1591734B3D9FB3F46E6A07F61D1AA78B19B4C96AAE67ABCDC1218D205277054711CD88C39D93913AAFED002C96950852971C044779E8C44452321A72B50802658F1E62759B5155AE21FDC3F0CBFA1BF06E35147ED4E328E1D6FFF1BC67CE4EC4D7872797759891D74E53BD496BD7E54C6F28E8E2D60E0CC5381E136465C551BA03B91D112F50F4F84208C2AE35C7CE712F230539E5CE5211D87C56074EC6E53A0A1FFB811B9580F7045D14B89C0E6CEC5B12834317944BB2D743926BD2EFF4D8CD19E7A85C58E0CD4BAF7D7915F4A8EC46CB20FF3B82ED5C8D30F5A4CAA07E0C8CCEE173FC59C3444CEB672220B98F8065A9DD5244BAAA6D44347100D2D4FABC8FB7E6746848E0E9CFD2C6AD701D538092BB
+20210510202408 2 6 100 4095 2 C0CF9D192A5E67E12DB4EBB35F3DD5A93041B217DDC24746828F760867A58487DCC1318CEB5929A76AB776A38F78415D03207716AFB66462B964A8B64E26D54306DFC888AF824BD68D46FD93EB19835F5CA576CDF7D57281B5A2D443CA10B94C9D091680FAE8AFDC9E862E7B8AA8EB9C5964A7A6DCF33D07735325CDC0AC2E0CB1AD72398FD23D9F375C766E55060C7E9556F16933363BD73288755FCFBE99FBEF5FEF5CDBE525AC7C1AB26CE56316568FA790082931F4015CE0BB432797A80617BEF82B448D8CF568A2EEF1CC594A4CAB3FAE7CB97866833D9BD646BB4A6850AAC1D6C8011C486C9FAB4AF5FB7C1591734B3D9FB3F46E6A07F61D1AA78B19B4C96AAE67ABCDC1218D205277054711CD88C39D93913AAFED002C96950852971C044779E8C44452321A72B50802658F1E62759B5155AE21FDC3F0CBFA1BF06E35147ED4E328E1D6FFF1BC67CE4EC4D7872797759891D74E53BD496BD7E54C6F28E8E2D60E0CC5381E136465C551BA03B91D112F50F4F84208C2AE35C7CE712F230539E5CE5211D87C56074EC6E53A0A1FFB811B9580F7045D14B89C0E6CEC5B12834317944BB2D743926BD2EFF4D8CD19E7A85C58E0CD4BAF7D7915F4A8EC46CB20FF3B82ED5C8D30F5A4CAA07E0C8CCEE173FC59C3444CEB672220B98F8065A9DD5244BAAA6D44347100D2D4FABC8FB7E6746848E0E9CFD2C6AD701D552B8EA3
+20210510204717 2 6 100 4095 5 C0CF9D192A5E67E12DB4EBB35F3DD5A93041B217DDC24746828F760867A58487DCC1318CEB5929A76AB776A38F78415D03207716AFB66462B964A8B64E26D54306DFC888AF824BD68D46FD93EB19835F5CA576CDF7D57281B5A2D443CA10B94C9D091680FAE8AFDC9E862E7B8AA8EB9C5964A7A6DCF33D07735325CDC0AC2E0CB1AD72398FD23D9F375C766E55060C7E9556F16933363BD73288755FCFBE99FBEF5FEF5CDBE525AC7C1AB26CE56316568FA790082931F4015CE0BB432797A80617BEF82B448D8CF568A2EEF1CC594A4CAB3FAE7CB97866833D9BD646BB4A6850AAC1D6C8011C486C9FAB4AF5FB7C1591734B3D9FB3F46E6A07F61D1AA78B19B4C96AAE67ABCDC1218D205277054711CD88C39D93913AAFED002C96950852971C044779E8C44452321A72B50802658F1E62759B5155AE21FDC3F0CBFA1BF06E35147ED4E328E1D6FFF1BC67CE4EC4D7872797759891D74E53BD496BD7E54C6F28E8E2D60E0CC5381E136465C551BA03B91D112F50F4F84208C2AE35C7CE712F230539E5CE5211D87C56074EC6E53A0A1FFB811B9580F7045D14B89C0E6CEC5B12834317944BB2D743926BD2EFF4D8CD19E7A85C58E0CD4BAF7D7915F4A8EC46CB20FF3B82ED5C8D30F5A4CAA07E0C8CCEE173FC59C3444CEB672220B98F8065A9DD5244BAAA6D44347100D2D4FABC8FB7E6746848E0E9CFD2C6AD701D56C3E03F
+20210510210552 2 6 100 4095 5 C0CF9D192A5E67E12DB4EBB35F3DD5A93041B217DDC24746828F760867A58487DCC1318CEB5929A76AB776A38F78415D03207716AFB66462B964A8B64E26D54306DFC888AF824BD68D46FD93EB19835F5CA576CDF7D57281B5A2D443CA10B94C9D091680FAE8AFDC9E862E7B8AA8EB9C5964A7A6DCF33D07735325CDC0AC2E0CB1AD72398FD23D9F375C766E55060C7E9556F16933363BD73288755FCFBE99FBEF5FEF5CDBE525AC7C1AB26CE56316568FA790082931F4015CE0BB432797A80617BEF82B448D8CF568A2EEF1CC594A4CAB3FAE7CB97866833D9BD646BB4A6850AAC1D6C8011C486C9FAB4AF5FB7C1591734B3D9FB3F46E6A07F61D1AA78B19B4C96AAE67ABCDC1218D205277054711CD88C39D93913AAFED002C96950852971C044779E8C44452321A72B50802658F1E62759B5155AE21FDC3F0CBFA1BF06E35147ED4E328E1D6FFF1BC67CE4EC4D7872797759891D74E53BD496BD7E54C6F28E8E2D60E0CC5381E136465C551BA03B91D112F50F4F84208C2AE35C7CE712F230539E5CE5211D87C56074EC6E53A0A1FFB811B9580F7045D14B89C0E6CEC5B12834317944BB2D743926BD2EFF4D8CD19E7A85C58E0CD4BAF7D7915F4A8EC46CB20FF3B82ED5C8D30F5A4CAA07E0C8CCEE173FC59C3444CEB672220B98F8065A9DD5244BAAA6D44347100D2D4FABC8FB7E6746848E0E9CFD2C6AD701D580CD59F
+20210510211223 2 6 100 4095 5 C0CF9D192A5E67E12DB4EBB35F3DD5A93041B217DDC24746828F760867A58487DCC1318CEB5929A76AB776A38F78415D03207716AFB66462B964A8B64E26D54306DFC888AF824BD68D46FD93EB19835F5CA576CDF7D57281B5A2D443CA10B94C9D091680FAE8AFDC9E862E7B8AA8EB9C5964A7A6DCF33D07735325CDC0AC2E0CB1AD72398FD23D9F375C766E55060C7E9556F16933363BD73288755FCFBE99FBEF5FEF5CDBE525AC7C1AB26CE56316568FA790082931F4015CE0BB432797A80617BEF82B448D8CF568A2EEF1CC594A4CAB3FAE7CB97866833D9BD646BB4A6850AAC1D6C8011C486C9FAB4AF5FB7C1591734B3D9FB3F46E6A07F61D1AA78B19B4C96AAE67ABCDC1218D205277054711CD88C39D93913AAFED002C96950852971C044779E8C44452321A72B50802658F1E62759B5155AE21FDC3F0CBFA1BF06E35147ED4E328E1D6FFF1BC67CE4EC4D7872797759891D74E53BD496BD7E54C6F28E8E2D60E0CC5381E136465C551BA03B91D112F50F4F84208C2AE35C7CE712F230539E5CE5211D87C56074EC6E53A0A1FFB811B9580F7045D14B89C0E6CEC5B12834317944BB2D743926BD2EFF4D8CD19E7A85C58E0CD4BAF7D7915F4A8EC46CB20FF3B82ED5C8D30F5A4CAA07E0C8CCEE173FC59C3444CEB672220B98F8065A9DD5244BAAA6D44347100D2D4FABC8FB7E6746848E0E9CFD2C6AD701D587C16C7
+20210510211607 2 6 100 4095 2 C0CF9D192A5E67E12DB4EBB35F3DD5A93041B217DDC24746828F760867A58487DCC1318CEB5929A76AB776A38F78415D03207716AFB66462B964A8B64E26D54306DFC888AF824BD68D46FD93EB19835F5CA576CDF7D57281B5A2D443CA10B94C9D091680FAE8AFDC9E862E7B8AA8EB9C5964A7A6DCF33D07735325CDC0AC2E0CB1AD72398FD23D9F375C766E55060C7E9556F16933363BD73288755FCFBE99FBEF5FEF5CDBE525AC7C1AB26CE56316568FA790082931F4015CE0BB432797A80617BEF82B448D8CF568A2EEF1CC594A4CAB3FAE7CB97866833D9BD646BB4A6850AAC1D6C8011C486C9FAB4AF5FB7C1591734B3D9FB3F46E6A07F61D1AA78B19B4C96AAE67ABCDC1218D205277054711CD88C39D93913AAFED002C96950852971C044779E8C44452321A72B50802658F1E62759B5155AE21FDC3F0CBFA1BF06E35147ED4E328E1D6FFF1BC67CE4EC4D7872797759891D74E53BD496BD7E54C6F28E8E2D60E0CC5381E136465C551BA03B91D112F50F4F84208C2AE35C7CE712F230539E5CE5211D87C56074EC6E53A0A1FFB811B9580F7045D14B89C0E6CEC5B12834317944BB2D743926BD2EFF4D8CD19E7A85C58E0CD4BAF7D7915F4A8EC46CB20FF3B82ED5C8D30F5A4CAA07E0C8CCEE173FC59C3444CEB672220B98F8065A9DD5244BAAA6D44347100D2D4FABC8FB7E6746848E0E9CFD2C6AD701D58B825A3
+20210510212131 2 6 100 4095 2 C0CF9D192A5E67E12DB4EBB35F3DD5A93041B217DDC24746828F760867A58487DCC1318CEB5929A76AB776A38F78415D03207716AFB66462B964A8B64E26D54306DFC888AF824BD68D46FD93EB19835F5CA576CDF7D57281B5A2D443CA10B94C9D091680FAE8AFDC9E862E7B8AA8EB9C5964A7A6DCF33D07735325CDC0AC2E0CB1AD72398FD23D9F375C766E55060C7E9556F16933363BD73288755FCFBE99FBEF5FEF5CDBE525AC7C1AB26CE56316568FA790082931F4015CE0BB432797A80617BEF82B448D8CF568A2EEF1CC594A4CAB3FAE7CB97866833D9BD646BB4A6850AAC1D6C8011C486C9FAB4AF5FB7C1591734B3D9FB3F46E6A07F61D1AA78B19B4C96AAE67ABCDC1218D205277054711CD88C39D93913AAFED002C96950852971C044779E8C44452321A72B50802658F1E62759B5155AE21FDC3F0CBFA1BF06E35147ED4E328E1D6FFF1BC67CE4EC4D7872797759891D74E53BD496BD7E54C6F28E8E2D60E0CC5381E136465C551BA03B91D112F50F4F84208C2AE35C7CE712F230539E5CE5211D87C56074EC6E53A0A1FFB811B9580F7045D14B89C0E6CEC5B12834317944BB2D743926BD2EFF4D8CD19E7A85C58E0CD4BAF7D7915F4A8EC46CB20FF3B82ED5C8D30F5A4CAA07E0C8CCEE173FC59C3444CEB672220B98F8065A9DD5244BAAA6D44347100D2D4FABC8FB7E6746848E0E9CFD2C6AD701D5914A563
+20210510212930 2 6 100 4095 2 C0CF9D192A5E67E12DB4EBB35F3DD5A93041B217DDC24746828F760867A58487DCC1318CEB5929A76AB776A38F78415D03207716AFB66462B964A8B64E26D54306DFC888AF824BD68D46FD93EB19835F5CA576CDF7D57281B5A2D443CA10B94C9D091680FAE8AFDC9E862E7B8AA8EB9C5964A7A6DCF33D07735325CDC0AC2E0CB1AD72398FD23D9F375C766E55060C7E9556F16933363BD73288755FCFBE99FBEF5FEF5CDBE525AC7C1AB26CE56316568FA790082931F4015CE0BB432797A80617BEF82B448D8CF568A2EEF1CC594A4CAB3FAE7CB97866833D9BD646BB4A6850AAC1D6C8011C486C9FAB4AF5FB7C1591734B3D9FB3F46E6A07F61D1AA78B19B4C96AAE67ABCDC1218D205277054711CD88C39D93913AAFED002C96950852971C044779E8C44452321A72B50802658F1E62759B5155AE21FDC3F0CBFA1BF06E35147ED4E328E1D6FFF1BC67CE4EC4D7872797759891D74E53BD496BD7E54C6F28E8E2D60E0CC5381E136465C551BA03B91D112F50F4F84208C2AE35C7CE712F230539E5CE5211D87C56074EC6E53A0A1FFB811B9580F7045D14B89C0E6CEC5B12834317944BB2D743926BD2EFF4D8CD19E7A85C58E0CD4BAF7D7915F4A8EC46CB20FF3B82ED5C8D30F5A4CAA07E0C8CCEE173FC59C3444CEB672220B98F8065A9DD5244BAAA6D44347100D2D4FABC8FB7E6746848E0E9CFD2C6AD701D599D3C2B
+20210510214640 2 6 100 4095 2 C0CF9D192A5E67E12DB4EBB35F3DD5A93041B217DDC24746828F760867A58487DCC1318CEB5929A76AB776A38F78415D03207716AFB66462B964A8B64E26D54306DFC888AF824BD68D46FD93EB19835F5CA576CDF7D57281B5A2D443CA10B94C9D091680FAE8AFDC9E862E7B8AA8EB9C5964A7A6DCF33D07735325CDC0AC2E0CB1AD72398FD23D9F375C766E55060C7E9556F16933363BD73288755FCFBE99FBEF5FEF5CDBE525AC7C1AB26CE56316568FA790082931F4015CE0BB432797A80617BEF82B448D8CF568A2EEF1CC594A4CAB3FAE7CB97866833D9BD646BB4A6850AAC1D6C8011C486C9FAB4AF5FB7C1591734B3D9FB3F46E6A07F61D1AA78B19B4C96AAE67ABCDC1218D205277054711CD88C39D93913AAFED002C96950852971C044779E8C44452321A72B50802658F1E62759B5155AE21FDC3F0CBFA1BF06E35147ED4E328E1D6FFF1BC67CE4EC4D7872797759891D74E53BD496BD7E54C6F28E8E2D60E0CC5381E136465C551BA03B91D112F50F4F84208C2AE35C7CE712F230539E5CE5211D87C56074EC6E53A0A1FFB811B9580F7045D14B89C0E6CEC5B12834317944BB2D743926BD2EFF4D8CD19E7A85C58E0CD4BAF7D7915F4A8EC46CB20FF3B82ED5C8D30F5A4CAA07E0C8CCEE173FC59C3444CEB672220B98F8065A9DD5244BAAA6D44347100D2D4FABC8FB7E6746848E0E9CFD2C6AD701D5AD02FBB
+20210510221404 2 6 100 4095 2 C0CF9D192A5E67E12DB4EBB35F3DD5A93041B217DDC24746828F760867A58487DCC1318CEB5929A76AB776A38F78415D03207716AFB66462B964A8B64E26D54306DFC888AF824BD68D46FD93EB19835F5CA576CDF7D57281B5A2D443CA10B94C9D091680FAE8AFDC9E862E7B8AA8EB9C5964A7A6DCF33D07735325CDC0AC2E0CB1AD72398FD23D9F375C766E55060C7E9556F16933363BD73288755FCFBE99FBEF5FEF5CDBE525AC7C1AB26CE56316568FA790082931F4015CE0BB432797A80617BEF82B448D8CF568A2EEF1CC594A4CAB3FAE7CB97866833D9BD646BB4A6850AAC1D6C8011C486C9FAB4AF5FB7C1591734B3D9FB3F46E6A07F61D1AA78B19B4C96AAE67ABCDC1218D205277054711CD88C39D93913AAFED002C96950852971C044779E8C44452321A72B50802658F1E62759B5155AE21FDC3F0CBFA1BF06E35147ED4E328E1D6FFF1BC67CE4EC4D7872797759891D74E53BD496BD7E54C6F28E8E2D60E0CC5381E136465C551BA03B91D112F50F4F84208C2AE35C7CE712F230539E5CE5211D87C56074EC6E53A0A1FFB811B9580F7045D14B89C0E6CEC5B12834317944BB2D743926BD2EFF4D8CD19E7A85C58E0CD4BAF7D7915F4A8EC46CB20FF3B82ED5C8D30F5A4CAA07E0C8CCEE173FC59C3444CEB672220B98F8065A9DD5244BAAA6D44347100D2D4FABC8FB7E6746848E0E9CFD2C6AD701D5CBD7BCB
+20210510224430 2 6 100 4095 5 C0CF9D192A5E67E12DB4EBB35F3DD5A93041B217DDC24746828F760867A58487DCC1318CEB5929A76AB776A38F78415D03207716AFB66462B964A8B64E26D54306DFC888AF824BD68D46FD93EB19835F5CA576CDF7D57281B5A2D443CA10B94C9D091680FAE8AFDC9E862E7B8AA8EB9C5964A7A6DCF33D07735325CDC0AC2E0CB1AD72398FD23D9F375C766E55060C7E9556F16933363BD73288755FCFBE99FBEF5FEF5CDBE525AC7C1AB26CE56316568FA790082931F4015CE0BB432797A80617BEF82B448D8CF568A2EEF1CC594A4CAB3FAE7CB97866833D9BD646BB4A6850AAC1D6C8011C486C9FAB4AF5FB7C1591734B3D9FB3F46E6A07F61D1AA78B19B4C96AAE67ABCDC1218D205277054711CD88C39D93913AAFED002C96950852971C044779E8C44452321A72B50802658F1E62759B5155AE21FDC3F0CBFA1BF06E35147ED4E328E1D6FFF1BC67CE4EC4D7872797759891D74E53BD496BD7E54C6F28E8E2D60E0CC5381E136465C551BA03B91D112F50F4F84208C2AE35C7CE712F230539E5CE5211D87C56074EC6E53A0A1FFB811B9580F7045D14B89C0E6CEC5B12834317944BB2D743926BD2EFF4D8CD19E7A85C58E0CD4BAF7D7915F4A8EC46CB20FF3B82ED5C8D30F5A4CAA07E0C8CCEE173FC59C3444CEB672220B98F8065A9DD5244BAAA6D44347100D2D4FABC8FB7E6746848E0E9CFD2C6AD701D5EDD3847
+20210510224732 2 6 100 4095 2 C0CF9D192A5E67E12DB4EBB35F3DD5A93041B217DDC24746828F760867A58487DCC1318CEB5929A76AB776A38F78415D03207716AFB66462B964A8B64E26D54306DFC888AF824BD68D46FD93EB19835F5CA576CDF7D57281B5A2D443CA10B94C9D091680FAE8AFDC9E862E7B8AA8EB9C5964A7A6DCF33D07735325CDC0AC2E0CB1AD72398FD23D9F375C766E55060C7E9556F16933363BD73288755FCFBE99FBEF5FEF5CDBE525AC7C1AB26CE56316568FA790082931F4015CE0BB432797A80617BEF82B448D8CF568A2EEF1CC594A4CAB3FAE7CB97866833D9BD646BB4A6850AAC1D6C8011C486C9FAB4AF5FB7C1591734B3D9FB3F46E6A07F61D1AA78B19B4C96AAE67ABCDC1218D205277054711CD88C39D93913AAFED002C96950852971C044779E8C44452321A72B50802658F1E62759B5155AE21FDC3F0CBFA1BF06E35147ED4E328E1D6FFF1BC67CE4EC4D7872797759891D74E53BD496BD7E54C6F28E8E2D60E0CC5381E136465C551BA03B91D112F50F4F84208C2AE35C7CE712F230539E5CE5211D87C56074EC6E53A0A1FFB811B9580F7045D14B89C0E6CEC5B12834317944BB2D743926BD2EFF4D8CD19E7A85C58E0CD4BAF7D7915F4A8EC46CB20FF3B82ED5C8D30F5A4CAA07E0C8CCEE173FC59C3444CEB672220B98F8065A9DD5244BAAA6D44347100D2D4FABC8FB7E6746848E0E9CFD2C6AD701D5F0BA233
+20210510230510 2 6 100 4095 2 C0CF9D192A5E67E12DB4EBB35F3DD5A93041B217DDC24746828F760867A58487DCC1318CEB5929A76AB776A38F78415D03207716AFB66462B964A8B64E26D54306DFC888AF824BD68D46FD93EB19835F5CA576CDF7D57281B5A2D443CA10B94C9D091680FAE8AFDC9E862E7B8AA8EB9C5964A7A6DCF33D07735325CDC0AC2E0CB1AD72398FD23D9F375C766E55060C7E9556F16933363BD73288755FCFBE99FBEF5FEF5CDBE525AC7C1AB26CE56316568FA790082931F4015CE0BB432797A80617BEF82B448D8CF568A2EEF1CC594A4CAB3FAE7CB97866833D9BD646BB4A6850AAC1D6C8011C486C9FAB4AF5FB7C1591734B3D9FB3F46E6A07F61D1AA78B19B4C96AAE67ABCDC1218D205277054711CD88C39D93913AAFED002C96950852971C044779E8C44452321A72B50802658F1E62759B5155AE21FDC3F0CBFA1BF06E35147ED4E328E1D6FFF1BC67CE4EC4D7872797759891D74E53BD496BD7E54C6F28E8E2D60E0CC5381E136465C551BA03B91D112F50F4F84208C2AE35C7CE712F230539E5CE5211D87C56074EC6E53A0A1FFB811B9580F7045D14B89C0E6CEC5B12834317944BB2D743926BD2EFF4D8CD19E7A85C58E0CD4BAF7D7915F4A8EC46CB20FF3B82ED5C8D30F5A4CAA07E0C8CCEE173FC59C3444CEB672220B98F8065A9DD5244BAAA6D44347100D2D4FABC8FB7E6746848E0E9CFD2C6AD701D604292FB
+20210510231041 2 6 100 4095 2 C0CF9D192A5E67E12DB4EBB35F3DD5A93041B217DDC24746828F760867A58487DCC1318CEB5929A76AB776A38F78415D03207716AFB66462B964A8B64E26D54306DFC888AF824BD68D46FD93EB19835F5CA576CDF7D57281B5A2D443CA10B94C9D091680FAE8AFDC9E862E7B8AA8EB9C5964A7A6DCF33D07735325CDC0AC2E0CB1AD72398FD23D9F375C766E55060C7E9556F16933363BD73288755FCFBE99FBEF5FEF5CDBE525AC7C1AB26CE56316568FA790082931F4015CE0BB432797A80617BEF82B448D8CF568A2EEF1CC594A4CAB3FAE7CB97866833D9BD646BB4A6850AAC1D6C8011C486C9FAB4AF5FB7C1591734B3D9FB3F46E6A07F61D1AA78B19B4C96AAE67ABCDC1218D205277054711CD88C39D93913AAFED002C96950852971C044779E8C44452321A72B50802658F1E62759B5155AE21FDC3F0CBFA1BF06E35147ED4E328E1D6FFF1BC67CE4EC4D7872797759891D74E53BD496BD7E54C6F28E8E2D60E0CC5381E136465C551BA03B91D112F50F4F84208C2AE35C7CE712F230539E5CE5211D87C56074EC6E53A0A1FFB811B9580F7045D14B89C0E6CEC5B12834317944BB2D743926BD2EFF4D8CD19E7A85C58E0CD4BAF7D7915F4A8EC46CB20FF3B82ED5C8D30F5A4CAA07E0C8CCEE173FC59C3444CEB672220B98F8065A9DD5244BAAA6D44347100D2D4FABC8FB7E6746848E0E9CFD2C6AD701D609E882B
+20210510232117 2 6 100 4095 2 C0CF9D192A5E67E12DB4EBB35F3DD5A93041B217DDC24746828F760867A58487DCC1318CEB5929A76AB776A38F78415D03207716AFB66462B964A8B64E26D54306DFC888AF824BD68D46FD93EB19835F5CA576CDF7D57281B5A2D443CA10B94C9D091680FAE8AFDC9E862E7B8AA8EB9C5964A7A6DCF33D07735325CDC0AC2E0CB1AD72398FD23D9F375C766E55060C7E9556F16933363BD73288755FCFBE99FBEF5FEF5CDBE525AC7C1AB26CE56316568FA790082931F4015CE0BB432797A80617BEF82B448D8CF568A2EEF1CC594A4CAB3FAE7CB97866833D9BD646BB4A6850AAC1D6C8011C486C9FAB4AF5FB7C1591734B3D9FB3F46E6A07F61D1AA78B19B4C96AAE67ABCDC1218D205277054711CD88C39D93913AAFED002C96950852971C044779E8C44452321A72B50802658F1E62759B5155AE21FDC3F0CBFA1BF06E35147ED4E328E1D6FFF1BC67CE4EC4D7872797759891D74E53BD496BD7E54C6F28E8E2D60E0CC5381E136465C551BA03B91D112F50F4F84208C2AE35C7CE712F230539E5CE5211D87C56074EC6E53A0A1FFB811B9580F7045D14B89C0E6CEC5B12834317944BB2D743926BD2EFF4D8CD19E7A85C58E0CD4BAF7D7915F4A8EC46CB20FF3B82ED5C8D30F5A4CAA07E0C8CCEE173FC59C3444CEB672220B98F8065A9DD5244BAAA6D44347100D2D4FABC8FB7E6746848E0E9CFD2C6AD701D61508923
+20210510232533 2 6 100 4095 5 C0CF9D192A5E67E12DB4EBB35F3DD5A93041B217DDC24746828F760867A58487DCC1318CEB5929A76AB776A38F78415D03207716AFB66462B964A8B64E26D54306DFC888AF824BD68D46FD93EB19835F5CA576CDF7D57281B5A2D443CA10B94C9D091680FAE8AFDC9E862E7B8AA8EB9C5964A7A6DCF33D07735325CDC0AC2E0CB1AD72398FD23D9F375C766E55060C7E9556F16933363BD73288755FCFBE99FBEF5FEF5CDBE525AC7C1AB26CE56316568FA790082931F4015CE0BB432797A80617BEF82B448D8CF568A2EEF1CC594A4CAB3FAE7CB97866833D9BD646BB4A6850AAC1D6C8011C486C9FAB4AF5FB7C1591734B3D9FB3F46E6A07F61D1AA78B19B4C96AAE67ABCDC1218D205277054711CD88C39D93913AAFED002C96950852971C044779E8C44452321A72B50802658F1E62759B5155AE21FDC3F0CBFA1BF06E35147ED4E328E1D6FFF1BC67CE4EC4D7872797759891D74E53BD496BD7E54C6F28E8E2D60E0CC5381E136465C551BA03B91D112F50F4F84208C2AE35C7CE712F230539E5CE5211D87C56074EC6E53A0A1FFB811B9580F7045D14B89C0E6CEC5B12834317944BB2D743926BD2EFF4D8CD19E7A85C58E0CD4BAF7D7915F4A8EC46CB20FF3B82ED5C8D30F5A4CAA07E0C8CCEE173FC59C3444CEB672220B98F8065A9DD5244BAAA6D44347100D2D4FABC8FB7E6746848E0E9CFD2C6AD701D619565D7
+20210510232612 2 6 100 4095 5 C0CF9D192A5E67E12DB4EBB35F3DD5A93041B217DDC24746828F760867A58487DCC1318CEB5929A76AB776A38F78415D03207716AFB66462B964A8B64E26D54306DFC888AF824BD68D46FD93EB19835F5CA576CDF7D57281B5A2D443CA10B94C9D091680FAE8AFDC9E862E7B8AA8EB9C5964A7A6DCF33D07735325CDC0AC2E0CB1AD72398FD23D9F375C766E55060C7E9556F16933363BD73288755FCFBE99FBEF5FEF5CDBE525AC7C1AB26CE56316568FA790082931F4015CE0BB432797A80617BEF82B448D8CF568A2EEF1CC594A4CAB3FAE7CB97866833D9BD646BB4A6850AAC1D6C8011C486C9FAB4AF5FB7C1591734B3D9FB3F46E6A07F61D1AA78B19B4C96AAE67ABCDC1218D205277054711CD88C39D93913AAFED002C96950852971C044779E8C44452321A72B50802658F1E62759B5155AE21FDC3F0CBFA1BF06E35147ED4E328E1D6FFF1BC67CE4EC4D7872797759891D74E53BD496BD7E54C6F28E8E2D60E0CC5381E136465C551BA03B91D112F50F4F84208C2AE35C7CE712F230539E5CE5211D87C56074EC6E53A0A1FFB811B9580F7045D14B89C0E6CEC5B12834317944BB2D743926BD2EFF4D8CD19E7A85C58E0CD4BAF7D7915F4A8EC46CB20FF3B82ED5C8D30F5A4CAA07E0C8CCEE173FC59C3444CEB672220B98F8065A9DD5244BAAA6D44347100D2D4FABC8FB7E6746848E0E9CFD2C6AD701D6198BB57
+20210510235513 2 6 100 4095 2 C0CF9D192A5E67E12DB4EBB35F3DD5A93041B217DDC24746828F760867A58487DCC1318CEB5929A76AB776A38F78415D03207716AFB66462B964A8B64E26D54306DFC888AF824BD68D46FD93EB19835F5CA576CDF7D57281B5A2D443CA10B94C9D091680FAE8AFDC9E862E7B8AA8EB9C5964A7A6DCF33D07735325CDC0AC2E0CB1AD72398FD23D9F375C766E55060C7E9556F16933363BD73288755FCFBE99FBEF5FEF5CDBE525AC7C1AB26CE56316568FA790082931F4015CE0BB432797A80617BEF82B448D8CF568A2EEF1CC594A4CAB3FAE7CB97866833D9BD646BB4A6850AAC1D6C8011C486C9FAB4AF5FB7C1591734B3D9FB3F46E6A07F61D1AA78B19B4C96AAE67ABCDC1218D205277054711CD88C39D93913AAFED002C96950852971C044779E8C44452321A72B50802658F1E62759B5155AE21FDC3F0CBFA1BF06E35147ED4E328E1D6FFF1BC67CE4EC4D7872797759891D74E53BD496BD7E54C6F28E8E2D60E0CC5381E136465C551BA03B91D112F50F4F84208C2AE35C7CE712F230539E5CE5211D87C56074EC6E53A0A1FFB811B9580F7045D14B89C0E6CEC5B12834317944BB2D743926BD2EFF4D8CD19E7A85C58E0CD4BAF7D7915F4A8EC46CB20FF3B82ED5C8D30F5A4CAA07E0C8CCEE173FC59C3444CEB672220B98F8065A9DD5244BAAA6D44347100D2D4FABC8FB7E6746848E0E9CFD2C6AD701D63970EA3
+20210511001630 2 6 100 4095 5 C0CF9D192A5E67E12DB4EBB35F3DD5A93041B217DDC24746828F760867A58487DCC1318CEB5929A76AB776A38F78415D03207716AFB66462B964A8B64E26D54306DFC888AF824BD68D46FD93EB19835F5CA576CDF7D57281B5A2D443CA10B94C9D091680FAE8AFDC9E862E7B8AA8EB9C5964A7A6DCF33D07735325CDC0AC2E0CB1AD72398FD23D9F375C766E55060C7E9556F16933363BD73288755FCFBE99FBEF5FEF5CDBE525AC7C1AB26CE56316568FA790082931F4015CE0BB432797A80617BEF82B448D8CF568A2EEF1CC594A4CAB3FAE7CB97866833D9BD646BB4A6850AAC1D6C8011C486C9FAB4AF5FB7C1591734B3D9FB3F46E6A07F61D1AA78B19B4C96AAE67ABCDC1218D205277054711CD88C39D93913AAFED002C96950852971C044779E8C44452321A72B50802658F1E62759B5155AE21FDC3F0CBFA1BF06E35147ED4E328E1D6FFF1BC67CE4EC4D7872797759891D74E53BD496BD7E54C6F28E8E2D60E0CC5381E136465C551BA03B91D112F50F4F84208C2AE35C7CE712F230539E5CE5211D87C56074EC6E53A0A1FFB811B9580F7045D14B89C0E6CEC5B12834317944BB2D743926BD2EFF4D8CD19E7A85C58E0CD4BAF7D7915F4A8EC46CB20FF3B82ED5C8D30F5A4CAA07E0C8CCEE173FC59C3444CEB672220B98F8065A9DD5244BAAA6D44347100D2D4FABC8FB7E6746848E0E9CFD2C6AD701D650D625F
+20210511002532 2 6 100 4095 2 C0CF9D192A5E67E12DB4EBB35F3DD5A93041B217DDC24746828F760867A58487DCC1318CEB5929A76AB776A38F78415D03207716AFB66462B964A8B64E26D54306DFC888AF824BD68D46FD93EB19835F5CA576CDF7D57281B5A2D443CA10B94C9D091680FAE8AFDC9E862E7B8AA8EB9C5964A7A6DCF33D07735325CDC0AC2E0CB1AD72398FD23D9F375C766E55060C7E9556F16933363BD73288755FCFBE99FBEF5FEF5CDBE525AC7C1AB26CE56316568FA790082931F4015CE0BB432797A80617BEF82B448D8CF568A2EEF1CC594A4CAB3FAE7CB97866833D9BD646BB4A6850AAC1D6C8011C486C9FAB4AF5FB7C1591734B3D9FB3F46E6A07F61D1AA78B19B4C96AAE67ABCDC1218D205277054711CD88C39D93913AAFED002C96950852971C044779E8C44452321A72B50802658F1E62759B5155AE21FDC3F0CBFA1BF06E35147ED4E328E1D6FFF1BC67CE4EC4D7872797759891D74E53BD496BD7E54C6F28E8E2D60E0CC5381E136465C551BA03B91D112F50F4F84208C2AE35C7CE712F230539E5CE5211D87C56074EC6E53A0A1FFB811B9580F7045D14B89C0E6CEC5B12834317944BB2D743926BD2EFF4D8CD19E7A85C58E0CD4BAF7D7915F4A8EC46CB20FF3B82ED5C8D30F5A4CAA07E0C8CCEE173FC59C3444CEB672220B98F8065A9DD5244BAAA6D44347100D2D4FABC8FB7E6746848E0E9CFD2C6AD701D65AD01CB
+20210511002655 2 6 100 4095 5 C0CF9D192A5E67E12DB4EBB35F3DD5A93041B217DDC24746828F760867A58487DCC1318CEB5929A76AB776A38F78415D03207716AFB66462B964A8B64E26D54306DFC888AF824BD68D46FD93EB19835F5CA576CDF7D57281B5A2D443CA10B94C9D091680FAE8AFDC9E862E7B8AA8EB9C5964A7A6DCF33D07735325CDC0AC2E0CB1AD72398FD23D9F375C766E55060C7E9556F16933363BD73288755FCFBE99FBEF5FEF5CDBE525AC7C1AB26CE56316568FA790082931F4015CE0BB432797A80617BEF82B448D8CF568A2EEF1CC594A4CAB3FAE7CB97866833D9BD646BB4A6850AAC1D6C8011C486C9FAB4AF5FB7C1591734B3D9FB3F46E6A07F61D1AA78B19B4C96AAE67ABCDC1218D205277054711CD88C39D93913AAFED002C96950852971C044779E8C44452321A72B50802658F1E62759B5155AE21FDC3F0CBFA1BF06E35147ED4E328E1D6FFF1BC67CE4EC4D7872797759891D74E53BD496BD7E54C6F28E8E2D60E0CC5381E136465C551BA03B91D112F50F4F84208C2AE35C7CE712F230539E5CE5211D87C56074EC6E53A0A1FFB811B9580F7045D14B89C0E6CEC5B12834317944BB2D743926BD2EFF4D8CD19E7A85C58E0CD4BAF7D7915F4A8EC46CB20FF3B82ED5C8D30F5A4CAA07E0C8CCEE173FC59C3444CEB672220B98F8065A9DD5244BAAA6D44347100D2D4FABC8FB7E6746848E0E9CFD2C6AD701D65BD0E3F
+20210511004533 2 6 100 4095 5 C0CF9D192A5E67E12DB4EBB35F3DD5A93041B217DDC24746828F760867A58487DCC1318CEB5929A76AB776A38F78415D03207716AFB66462B964A8B64E26D54306DFC888AF824BD68D46FD93EB19835F5CA576CDF7D57281B5A2D443CA10B94C9D091680FAE8AFDC9E862E7B8AA8EB9C5964A7A6DCF33D07735325CDC0AC2E0CB1AD72398FD23D9F375C766E55060C7E9556F16933363BD73288755FCFBE99FBEF5FEF5CDBE525AC7C1AB26CE56316568FA790082931F4015CE0BB432797A80617BEF82B448D8CF568A2EEF1CC594A4CAB3FAE7CB97866833D9BD646BB4A6850AAC1D6C8011C486C9FAB4AF5FB7C1591734B3D9FB3F46E6A07F61D1AA78B19B4C96AAE67ABCDC1218D205277054711CD88C39D93913AAFED002C96950852971C044779E8C44452321A72B50802658F1E62759B5155AE21FDC3F0CBFA1BF06E35147ED4E328E1D6FFF1BC67CE4EC4D7872797759891D74E53BD496BD7E54C6F28E8E2D60E0CC5381E136465C551BA03B91D112F50F4F84208C2AE35C7CE712F230539E5CE5211D87C56074EC6E53A0A1FFB811B9580F7045D14B89C0E6CEC5B12834317944BB2D743926BD2EFF4D8CD19E7A85C58E0CD4BAF7D7915F4A8EC46CB20FF3B82ED5C8D30F5A4CAA07E0C8CCEE173FC59C3444CEB672220B98F8065A9DD5244BAAA6D44347100D2D4FABC8FB7E6746848E0E9CFD2C6AD701D6707A94F
+20210511005704 2 6 100 4095 5 C0CF9D192A5E67E12DB4EBB35F3DD5A93041B217DDC24746828F760867A58487DCC1318CEB5929A76AB776A38F78415D03207716AFB66462B964A8B64E26D54306DFC888AF824BD68D46FD93EB19835F5CA576CDF7D57281B5A2D443CA10B94C9D091680FAE8AFDC9E862E7B8AA8EB9C5964A7A6DCF33D07735325CDC0AC2E0CB1AD72398FD23D9F375C766E55060C7E9556F16933363BD73288755FCFBE99FBEF5FEF5CDBE525AC7C1AB26CE56316568FA790082931F4015CE0BB432797A80617BEF82B448D8CF568A2EEF1CC594A4CAB3FAE7CB97866833D9BD646BB4A6850AAC1D6C8011C486C9FAB4AF5FB7C1591734B3D9FB3F46E6A07F61D1AA78B19B4C96AAE67ABCDC1218D205277054711CD88C39D93913AAFED002C96950852971C044779E8C44452321A72B50802658F1E62759B5155AE21FDC3F0CBFA1BF06E35147ED4E328E1D6FFF1BC67CE4EC4D7872797759891D74E53BD496BD7E54C6F28E8E2D60E0CC5381E136465C551BA03B91D112F50F4F84208C2AE35C7CE712F230539E5CE5211D87C56074EC6E53A0A1FFB811B9580F7045D14B89C0E6CEC5B12834317944BB2D743926BD2EFF4D8CD19E7A85C58E0CD4BAF7D7915F4A8EC46CB20FF3B82ED5C8D30F5A4CAA07E0C8CCEE173FC59C3444CEB672220B98F8065A9DD5244BAAA6D44347100D2D4FABC8FB7E6746848E0E9CFD2C6AD701D67CFB01F
+20210511011635 2 6 100 4095 5 C0CF9D192A5E67E12DB4EBB35F3DD5A93041B217DDC24746828F760867A58487DCC1318CEB5929A76AB776A38F78415D03207716AFB66462B964A8B64E26D54306DFC888AF824BD68D46FD93EB19835F5CA576CDF7D57281B5A2D443CA10B94C9D091680FAE8AFDC9E862E7B8AA8EB9C5964A7A6DCF33D07735325CDC0AC2E0CB1AD72398FD23D9F375C766E55060C7E9556F16933363BD73288755FCFBE99FBEF5FEF5CDBE525AC7C1AB26CE56316568FA790082931F4015CE0BB432797A80617BEF82B448D8CF568A2EEF1CC594A4CAB3FAE7CB97866833D9BD646BB4A6850AAC1D6C8011C486C9FAB4AF5FB7C1591734B3D9FB3F46E6A07F61D1AA78B19B4C96AAE67ABCDC1218D205277054711CD88C39D93913AAFED002C96950852971C044779E8C44452321A72B50802658F1E62759B5155AE21FDC3F0CBFA1BF06E35147ED4E328E1D6FFF1BC67CE4EC4D7872797759891D74E53BD496BD7E54C6F28E8E2D60E0CC5381E136465C551BA03B91D112F50F4F84208C2AE35C7CE712F230539E5CE5211D87C56074EC6E53A0A1FFB811B9580F7045D14B89C0E6CEC5B12834317944BB2D743926BD2EFF4D8CD19E7A85C58E0CD4BAF7D7915F4A8EC46CB20FF3B82ED5C8D30F5A4CAA07E0C8CCEE173FC59C3444CEB672220B98F8065A9DD5244BAAA6D44347100D2D4FABC8FB7E6746848E0E9CFD2C6AD701D6922CFE7
+20210511012416 2 6 100 4095 5 C0CF9D192A5E67E12DB4EBB35F3DD5A93041B217DDC24746828F760867A58487DCC1318CEB5929A76AB776A38F78415D03207716AFB66462B964A8B64E26D54306DFC888AF824BD68D46FD93EB19835F5CA576CDF7D57281B5A2D443CA10B94C9D091680FAE8AFDC9E862E7B8AA8EB9C5964A7A6DCF33D07735325CDC0AC2E0CB1AD72398FD23D9F375C766E55060C7E9556F16933363BD73288755FCFBE99FBEF5FEF5CDBE525AC7C1AB26CE56316568FA790082931F4015CE0BB432797A80617BEF82B448D8CF568A2EEF1CC594A4CAB3FAE7CB97866833D9BD646BB4A6850AAC1D6C8011C486C9FAB4AF5FB7C1591734B3D9FB3F46E6A07F61D1AA78B19B4C96AAE67ABCDC1218D205277054711CD88C39D93913AAFED002C96950852971C044779E8C44452321A72B50802658F1E62759B5155AE21FDC3F0CBFA1BF06E35147ED4E328E1D6FFF1BC67CE4EC4D7872797759891D74E53BD496BD7E54C6F28E8E2D60E0CC5381E136465C551BA03B91D112F50F4F84208C2AE35C7CE712F230539E5CE5211D87C56074EC6E53A0A1FFB811B9580F7045D14B89C0E6CEC5B12834317944BB2D743926BD2EFF4D8CD19E7A85C58E0CD4BAF7D7915F4A8EC46CB20FF3B82ED5C8D30F5A4CAA07E0C8CCEE173FC59C3444CEB672220B98F8065A9DD5244BAAA6D44347100D2D4FABC8FB7E6746848E0E9CFD2C6AD701D69A4C92F
+20210511012915 2 6 100 4095 2 C0CF9D192A5E67E12DB4EBB35F3DD5A93041B217DDC24746828F760867A58487DCC1318CEB5929A76AB776A38F78415D03207716AFB66462B964A8B64E26D54306DFC888AF824BD68D46FD93EB19835F5CA576CDF7D57281B5A2D443CA10B94C9D091680FAE8AFDC9E862E7B8AA8EB9C5964A7A6DCF33D07735325CDC0AC2E0CB1AD72398FD23D9F375C766E55060C7E9556F16933363BD73288755FCFBE99FBEF5FEF5CDBE525AC7C1AB26CE56316568FA790082931F4015CE0BB432797A80617BEF82B448D8CF568A2EEF1CC594A4CAB3FAE7CB97866833D9BD646BB4A6850AAC1D6C8011C486C9FAB4AF5FB7C1591734B3D9FB3F46E6A07F61D1AA78B19B4C96AAE67ABCDC1218D205277054711CD88C39D93913AAFED002C96950852971C044779E8C44452321A72B50802658F1E62759B5155AE21FDC3F0CBFA1BF06E35147ED4E328E1D6FFF1BC67CE4EC4D7872797759891D74E53BD496BD7E54C6F28E8E2D60E0CC5381E136465C551BA03B91D112F50F4F84208C2AE35C7CE712F230539E5CE5211D87C56074EC6E53A0A1FFB811B9580F7045D14B89C0E6CEC5B12834317944BB2D743926BD2EFF4D8CD19E7A85C58E0CD4BAF7D7915F4A8EC46CB20FF3B82ED5C8D30F5A4CAA07E0C8CCEE173FC59C3444CEB672220B98F8065A9DD5244BAAA6D44347100D2D4FABC8FB7E6746848E0E9CFD2C6AD701D69F74C0B
+20210511102814 2 6 100 6143 5 EE2D1C3A0CC149C6675914AEFB8A3B27C939CB721B7D7D2AECDF4464406D6B59DF4C01ABE292F37396B097215BCF049F98D5B7CBA342EF5DFE31668084E83E783AC5C21CB152C08EE0BBAB4CC8F261AFD378F97D5044BC6BD3E555ADCF508ABC26E4CAF8D0B84EDDA7E78B56B89A497BC4D5A1D5C14D1A535777D4BBA17540B64F3E2695C5B134275A2F94D1388C0F666573454ED38B3E0CAA04BF5551662A429B54153795935493FE7E3C8130EE4568A278C2FF362D070FA4D10462B347E382EE340DF1EBBDBFEFAD66AB4B2296E982EC7F0947F6BF7845E8C40F9A7B4934727781E2D129C2E055227C3CD063BBFF14DE2958D6B4D3D3EF54ECA8757C3D102B98B6C97BE8087FE6B8ABC4B7D61AB491842E37A53890081C73359B4B878570BE3B30E557B819DBEC06F1291965419B7EAD74F1ADF900E771781024B44E5669DDA88FD9C62496764EA5CE3E791EB4CCDA3E4B665355C9EC92EF18046331332886B79DC3710C36F02D2EB260246AE83459514EF00FC5857CAC8562D4DD522FA4575ECD1BACA7313A1C91F72863DFC8AF0732C9025862525CF33E5EC545D356C620C70F16D2BDD22A9BD9A25469D21C70D437FA08ED36550A2EEEF3545EFDC5A0C0FCC1070A99B2D5EFC1A32D764AEE21DC38FD6086813C01F09298B41B3EFC7F34DB201EC538901C8E05A3B3295519042CF631226BBAF9A9F8A3C4BD6B00E24CD048A14ACA7C8B9EC1C1931853909EFF8B1FBCA46C9CB9E42BE7253E7F25A97C6D50E970EF8CEFE1C70C8A3254F5402F3DCC62A5A34B477A8B452352B6CB2BFC1F372130DBC4960DCD20088DB50B39998ECCB0CD2F797F7267529DB9A63B7BE8691F9B6155EFFAEEBDB8EE7FCA2EDD9DCC92B5DDCF536E87DA064010A15CA505885DEC6499E4B1408580A3F854E1C50BEA96D4B47D9022B004F426F1F69C7580573F60BA80045BA799FB486C1AB3E363D75DA7C2BE5E256001E728B4850BA99184068CFF7A87B25C95F43E17B35BEBFA4711A1307EA545B1BA97D13F752EB7CD6F42BA4776098D71C02E4961480D18AE898D2EBCD61E897041CB1A7056C4ADADD7
+20210511104622 2 6 100 6143 2 EE2D1C3A0CC149C6675914AEFB8A3B27C939CB721B7D7D2AECDF4464406D6B59DF4C01ABE292F37396B097215BCF049F98D5B7CBA342EF5DFE31668084E83E783AC5C21CB152C08EE0BBAB4CC8F261AFD378F97D5044BC6BD3E555ADCF508ABC26E4CAF8D0B84EDDA7E78B56B89A497BC4D5A1D5C14D1A535777D4BBA17540B64F3E2695C5B134275A2F94D1388C0F666573454ED38B3E0CAA04BF5551662A429B54153795935493FE7E3C8130EE4568A278C2FF362D070FA4D10462B347E382EE340DF1EBBDBFEFAD66AB4B2296E982EC7F0947F6BF7845E8C40F9A7B4934727781E2D129C2E055227C3CD063BBFF14DE2958D6B4D3D3EF54ECA8757C3D102B98B6C97BE8087FE6B8ABC4B7D61AB491842E37A53890081C73359B4B878570BE3B30E557B819DBEC06F1291965419B7EAD74F1ADF900E771781024B44E5669DDA88FD9C62496764EA5CE3E791EB4CCDA3E4B665355C9EC92EF18046331332886B79DC3710C36F02D2EB260246AE83459514EF00FC5857CAC8562D4DD522FA4575ECD1BACA7313A1C91F72863DFC8AF0732C9025862525CF33E5EC545D356C620C70F16D2BDD22A9BD9A25469D21C70D437FA08ED36550A2EEEF3545EFDC5A0C0FCC1070A99B2D5EFC1A32D764AEE21DC38FD6086813C01F09298B41B3EFC7F34DB201EC538901C8E05A3B3295519042CF631226BBAF9A9F8A3C4BD6B00E24CD048A14ACA7C8B9EC1C1931853909EFF8B1FBCA46C9CB9E42BE7253E7F25A97C6D50E970EF8CEFE1C70C8A3254F5402F3DCC62A5A34B477A8B452352B6CB2BFC1F372130DBC4960DCD20088DB50B39998ECCB0CD2F797F7267529DB9A63B7BE8691F9B6155EFFAEEBDB8EE7FCA2EDD9DCC92B5DDCF536E87DA064010A15CA505885DEC6499E4B1408580A3F854E1C50BEA96D4B47D9022B004F426F1F69C7580573F60BA80045BA799FB486C1AB3E363D75DA7C2BE5E256001E728B4850BA99184068CFF7A87B25C95F43E17B35BEBFA4711A1307EA545B1BA97D13F752EB7CD6F42BA4776098D71C02E4961480D18AE898D2EBCD61E897041CB1A7056C75C31DB
+20210511105027 2 6 100 6143 2 EE2D1C3A0CC149C6675914AEFB8A3B27C939CB721B7D7D2AECDF4464406D6B59DF4C01ABE292F37396B097215BCF049F98D5B7CBA342EF5DFE31668084E83E783AC5C21CB152C08EE0BBAB4CC8F261AFD378F97D5044BC6BD3E555ADCF508ABC26E4CAF8D0B84EDDA7E78B56B89A497BC4D5A1D5C14D1A535777D4BBA17540B64F3E2695C5B134275A2F94D1388C0F666573454ED38B3E0CAA04BF5551662A429B54153795935493FE7E3C8130EE4568A278C2FF362D070FA4D10462B347E382EE340DF1EBBDBFEFAD66AB4B2296E982EC7F0947F6BF7845E8C40F9A7B4934727781E2D129C2E055227C3CD063BBFF14DE2958D6B4D3D3EF54ECA8757C3D102B98B6C97BE8087FE6B8ABC4B7D61AB491842E37A53890081C73359B4B878570BE3B30E557B819DBEC06F1291965419B7EAD74F1ADF900E771781024B44E5669DDA88FD9C62496764EA5CE3E791EB4CCDA3E4B665355C9EC92EF18046331332886B79DC3710C36F02D2EB260246AE83459514EF00FC5857CAC8562D4DD522FA4575ECD1BACA7313A1C91F72863DFC8AF0732C9025862525CF33E5EC545D356C620C70F16D2BDD22A9BD9A25469D21C70D437FA08ED36550A2EEEF3545EFDC5A0C0FCC1070A99B2D5EFC1A32D764AEE21DC38FD6086813C01F09298B41B3EFC7F34DB201EC538901C8E05A3B3295519042CF631226BBAF9A9F8A3C4BD6B00E24CD048A14ACA7C8B9EC1C1931853909EFF8B1FBCA46C9CB9E42BE7253E7F25A97C6D50E970EF8CEFE1C70C8A3254F5402F3DCC62A5A34B477A8B452352B6CB2BFC1F372130DBC4960DCD20088DB50B39998ECCB0CD2F797F7267529DB9A63B7BE8691F9B6155EFFAEEBDB8EE7FCA2EDD9DCC92B5DDCF536E87DA064010A15CA505885DEC6499E4B1408580A3F854E1C50BEA96D4B47D9022B004F426F1F69C7580573F60BA80045BA799FB486C1AB3E363D75DA7C2BE5E256001E728B4850BA99184068CFF7A87B25C95F43E17B35BEBFA4711A1307EA545B1BA97D13F752EB7CD6F42BA4776098D71C02E4961480D18AE898D2EBCD61E897041CB1A7056C7F679E3
+20210511110103 2 6 100 6143 5 EE2D1C3A0CC149C6675914AEFB8A3B27C939CB721B7D7D2AECDF4464406D6B59DF4C01ABE292F37396B097215BCF049F98D5B7CBA342EF5DFE31668084E83E783AC5C21CB152C08EE0BBAB4CC8F261AFD378F97D5044BC6BD3E555ADCF508ABC26E4CAF8D0B84EDDA7E78B56B89A497BC4D5A1D5C14D1A535777D4BBA17540B64F3E2695C5B134275A2F94D1388C0F666573454ED38B3E0CAA04BF5551662A429B54153795935493FE7E3C8130EE4568A278C2FF362D070FA4D10462B347E382EE340DF1EBBDBFEFAD66AB4B2296E982EC7F0947F6BF7845E8C40F9A7B4934727781E2D129C2E055227C3CD063BBFF14DE2958D6B4D3D3EF54ECA8757C3D102B98B6C97BE8087FE6B8ABC4B7D61AB491842E37A53890081C73359B4B878570BE3B30E557B819DBEC06F1291965419B7EAD74F1ADF900E771781024B44E5669DDA88FD9C62496764EA5CE3E791EB4CCDA3E4B665355C9EC92EF18046331332886B79DC3710C36F02D2EB260246AE83459514EF00FC5857CAC8562D4DD522FA4575ECD1BACA7313A1C91F72863DFC8AF0732C9025862525CF33E5EC545D356C620C70F16D2BDD22A9BD9A25469D21C70D437FA08ED36550A2EEEF3545EFDC5A0C0FCC1070A99B2D5EFC1A32D764AEE21DC38FD6086813C01F09298B41B3EFC7F34DB201EC538901C8E05A3B3295519042CF631226BBAF9A9F8A3C4BD6B00E24CD048A14ACA7C8B9EC1C1931853909EFF8B1FBCA46C9CB9E42BE7253E7F25A97C6D50E970EF8CEFE1C70C8A3254F5402F3DCC62A5A34B477A8B452352B6CB2BFC1F372130DBC4960DCD20088DB50B39998ECCB0CD2F797F7267529DB9A63B7BE8691F9B6155EFFAEEBDB8EE7FCA2EDD9DCC92B5DDCF536E87DA064010A15CA505885DEC6499E4B1408580A3F854E1C50BEA96D4B47D9022B004F426F1F69C7580573F60BA80045BA799FB486C1AB3E363D75DA7C2BE5E256001E728B4850BA99184068CFF7A87B25C95F43E17B35BEBFA4711A1307EA545B1BA97D13F752EB7CD6F42BA4776098D71C02E4961480D18AE898D2EBCD61E897041CB1A7056C98961DF
+20210511113326 2 6 100 6143 2 EE2D1C3A0CC149C6675914AEFB8A3B27C939CB721B7D7D2AECDF4464406D6B59DF4C01ABE292F37396B097215BCF049F98D5B7CBA342EF5DFE31668084E83E783AC5C21CB152C08EE0BBAB4CC8F261AFD378F97D5044BC6BD3E555ADCF508ABC26E4CAF8D0B84EDDA7E78B56B89A497BC4D5A1D5C14D1A535777D4BBA17540B64F3E2695C5B134275A2F94D1388C0F666573454ED38B3E0CAA04BF5551662A429B54153795935493FE7E3C8130EE4568A278C2FF362D070FA4D10462B347E382EE340DF1EBBDBFEFAD66AB4B2296E982EC7F0947F6BF7845E8C40F9A7B4934727781E2D129C2E055227C3CD063BBFF14DE2958D6B4D3D3EF54ECA8757C3D102B98B6C97BE8087FE6B8ABC4B7D61AB491842E37A53890081C73359B4B878570BE3B30E557B819DBEC06F1291965419B7EAD74F1ADF900E771781024B44E5669DDA88FD9C62496764EA5CE3E791EB4CCDA3E4B665355C9EC92EF18046331332886B79DC3710C36F02D2EB260246AE83459514EF00FC5857CAC8562D4DD522FA4575ECD1BACA7313A1C91F72863DFC8AF0732C9025862525CF33E5EC545D356C620C70F16D2BDD22A9BD9A25469D21C70D437FA08ED36550A2EEEF3545EFDC5A0C0FCC1070A99B2D5EFC1A32D764AEE21DC38FD6086813C01F09298B41B3EFC7F34DB201EC538901C8E05A3B3295519042CF631226BBAF9A9F8A3C4BD6B00E24CD048A14ACA7C8B9EC1C1931853909EFF8B1FBCA46C9CB9E42BE7253E7F25A97C6D50E970EF8CEFE1C70C8A3254F5402F3DCC62A5A34B477A8B452352B6CB2BFC1F372130DBC4960DCD20088DB50B39998ECCB0CD2F797F7267529DB9A63B7BE8691F9B6155EFFAEEBDB8EE7FCA2EDD9DCC92B5DDCF536E87DA064010A15CA505885DEC6499E4B1408580A3F854E1C50BEA96D4B47D9022B004F426F1F69C7580573F60BA80045BA799FB486C1AB3E363D75DA7C2BE5E256001E728B4850BA99184068CFF7A87B25C95F43E17B35BEBFA4711A1307EA545B1BA97D13F752EB7CD6F42BA4776098D71C02E4961480D18AE898D2EBCD61E897041CB1A7056CE694ADB
+20210511113553 2 6 100 6143 2 EE2D1C3A0CC149C6675914AEFB8A3B27C939CB721B7D7D2AECDF4464406D6B59DF4C01ABE292F37396B097215BCF049F98D5B7CBA342EF5DFE31668084E83E783AC5C21CB152C08EE0BBAB4CC8F261AFD378F97D5044BC6BD3E555ADCF508ABC26E4CAF8D0B84EDDA7E78B56B89A497BC4D5A1D5C14D1A535777D4BBA17540B64F3E2695C5B134275A2F94D1388C0F666573454ED38B3E0CAA04BF5551662A429B54153795935493FE7E3C8130EE4568A278C2FF362D070FA4D10462B347E382EE340DF1EBBDBFEFAD66AB4B2296E982EC7F0947F6BF7845E8C40F9A7B4934727781E2D129C2E055227C3CD063BBFF14DE2958D6B4D3D3EF54ECA8757C3D102B98B6C97BE8087FE6B8ABC4B7D61AB491842E37A53890081C73359B4B878570BE3B30E557B819DBEC06F1291965419B7EAD74F1ADF900E771781024B44E5669DDA88FD9C62496764EA5CE3E791EB4CCDA3E4B665355C9EC92EF18046331332886B79DC3710C36F02D2EB260246AE83459514EF00FC5857CAC8562D4DD522FA4575ECD1BACA7313A1C91F72863DFC8AF0732C9025862525CF33E5EC545D356C620C70F16D2BDD22A9BD9A25469D21C70D437FA08ED36550A2EEEF3545EFDC5A0C0FCC1070A99B2D5EFC1A32D764AEE21DC38FD6086813C01F09298B41B3EFC7F34DB201EC538901C8E05A3B3295519042CF631226BBAF9A9F8A3C4BD6B00E24CD048A14ACA7C8B9EC1C1931853909EFF8B1FBCA46C9CB9E42BE7253E7F25A97C6D50E970EF8CEFE1C70C8A3254F5402F3DCC62A5A34B477A8B452352B6CB2BFC1F372130DBC4960DCD20088DB50B39998ECCB0CD2F797F7267529DB9A63B7BE8691F9B6155EFFAEEBDB8EE7FCA2EDD9DCC92B5DDCF536E87DA064010A15CA505885DEC6499E4B1408580A3F854E1C50BEA96D4B47D9022B004F426F1F69C7580573F60BA80045BA799FB486C1AB3E363D75DA7C2BE5E256001E728B4850BA99184068CFF7A87B25C95F43E17B35BEBFA4711A1307EA545B1BA97D13F752EB7CD6F42BA4776098D71C02E4961480D18AE898D2EBCD61E897041CB1A7056CEBCB733
+20210511120155 2 6 100 6143 2 EE2D1C3A0CC149C6675914AEFB8A3B27C939CB721B7D7D2AECDF4464406D6B59DF4C01ABE292F37396B097215BCF049F98D5B7CBA342EF5DFE31668084E83E783AC5C21CB152C08EE0BBAB4CC8F261AFD378F97D5044BC6BD3E555ADCF508ABC26E4CAF8D0B84EDDA7E78B56B89A497BC4D5A1D5C14D1A535777D4BBA17540B64F3E2695C5B134275A2F94D1388C0F666573454ED38B3E0CAA04BF5551662A429B54153795935493FE7E3C8130EE4568A278C2FF362D070FA4D10462B347E382EE340DF1EBBDBFEFAD66AB4B2296E982EC7F0947F6BF7845E8C40F9A7B4934727781E2D129C2E055227C3CD063BBFF14DE2958D6B4D3D3EF54ECA8757C3D102B98B6C97BE8087FE6B8ABC4B7D61AB491842E37A53890081C73359B4B878570BE3B30E557B819DBEC06F1291965419B7EAD74F1ADF900E771781024B44E5669DDA88FD9C62496764EA5CE3E791EB4CCDA3E4B665355C9EC92EF18046331332886B79DC3710C36F02D2EB260246AE83459514EF00FC5857CAC8562D4DD522FA4575ECD1BACA7313A1C91F72863DFC8AF0732C9025862525CF33E5EC545D356C620C70F16D2BDD22A9BD9A25469D21C70D437FA08ED36550A2EEEF3545EFDC5A0C0FCC1070A99B2D5EFC1A32D764AEE21DC38FD6086813C01F09298B41B3EFC7F34DB201EC538901C8E05A3B3295519042CF631226BBAF9A9F8A3C4BD6B00E24CD048A14ACA7C8B9EC1C1931853909EFF8B1FBCA46C9CB9E42BE7253E7F25A97C6D50E970EF8CEFE1C70C8A3254F5402F3DCC62A5A34B477A8B452352B6CB2BFC1F372130DBC4960DCD20088DB50B39998ECCB0CD2F797F7267529DB9A63B7BE8691F9B6155EFFAEEBDB8EE7FCA2EDD9DCC92B5DDCF536E87DA064010A15CA505885DEC6499E4B1408580A3F854E1C50BEA96D4B47D9022B004F426F1F69C7580573F60BA80045BA799FB486C1AB3E363D75DA7C2BE5E256001E728B4850BA99184068CFF7A87B25C95F43E17B35BEBFA4711A1307EA545B1BA97D13F752EB7CD6F42BA4776098D71C02E4961480D18AE898D2EBCD61E897041CB1A7056D29CD07B
+20210511121150 2 6 100 6143 2 EE2D1C3A0CC149C6675914AEFB8A3B27C939CB721B7D7D2AECDF4464406D6B59DF4C01ABE292F37396B097215BCF049F98D5B7CBA342EF5DFE31668084E83E783AC5C21CB152C08EE0BBAB4CC8F261AFD378F97D5044BC6BD3E555ADCF508ABC26E4CAF8D0B84EDDA7E78B56B89A497BC4D5A1D5C14D1A535777D4BBA17540B64F3E2695C5B134275A2F94D1388C0F666573454ED38B3E0CAA04BF5551662A429B54153795935493FE7E3C8130EE4568A278C2FF362D070FA4D10462B347E382EE340DF1EBBDBFEFAD66AB4B2296E982EC7F0947F6BF7845E8C40F9A7B4934727781E2D129C2E055227C3CD063BBFF14DE2958D6B4D3D3EF54ECA8757C3D102B98B6C97BE8087FE6B8ABC4B7D61AB491842E37A53890081C73359B4B878570BE3B30E557B819DBEC06F1291965419B7EAD74F1ADF900E771781024B44E5669DDA88FD9C62496764EA5CE3E791EB4CCDA3E4B665355C9EC92EF18046331332886B79DC3710C36F02D2EB260246AE83459514EF00FC5857CAC8562D4DD522FA4575ECD1BACA7313A1C91F72863DFC8AF0732C9025862525CF33E5EC545D356C620C70F16D2BDD22A9BD9A25469D21C70D437FA08ED36550A2EEEF3545EFDC5A0C0FCC1070A99B2D5EFC1A32D764AEE21DC38FD6086813C01F09298B41B3EFC7F34DB201EC538901C8E05A3B3295519042CF631226BBAF9A9F8A3C4BD6B00E24CD048A14ACA7C8B9EC1C1931853909EFF8B1FBCA46C9CB9E42BE7253E7F25A97C6D50E970EF8CEFE1C70C8A3254F5402F3DCC62A5A34B477A8B452352B6CB2BFC1F372130DBC4960DCD20088DB50B39998ECCB0CD2F797F7267529DB9A63B7BE8691F9B6155EFFAEEBDB8EE7FCA2EDD9DCC92B5DDCF536E87DA064010A15CA505885DEC6499E4B1408580A3F854E1C50BEA96D4B47D9022B004F426F1F69C7580573F60BA80045BA799FB486C1AB3E363D75DA7C2BE5E256001E728B4850BA99184068CFF7A87B25C95F43E17B35BEBFA4711A1307EA545B1BA97D13F752EB7CD6F42BA4776098D71C02E4961480D18AE898D2EBCD61E897041CB1A7056D40F2B2B
+20210511125715 2 6 100 6143 2 EE2D1C3A0CC149C6675914AEFB8A3B27C939CB721B7D7D2AECDF4464406D6B59DF4C01ABE292F37396B097215BCF049F98D5B7CBA342EF5DFE31668084E83E783AC5C21CB152C08EE0BBAB4CC8F261AFD378F97D5044BC6BD3E555ADCF508ABC26E4CAF8D0B84EDDA7E78B56B89A497BC4D5A1D5C14D1A535777D4BBA17540B64F3E2695C5B134275A2F94D1388C0F666573454ED38B3E0CAA04BF5551662A429B54153795935493FE7E3C8130EE4568A278C2FF362D070FA4D10462B347E382EE340DF1EBBDBFEFAD66AB4B2296E982EC7F0947F6BF7845E8C40F9A7B4934727781E2D129C2E055227C3CD063BBFF14DE2958D6B4D3D3EF54ECA8757C3D102B98B6C97BE8087FE6B8ABC4B7D61AB491842E37A53890081C73359B4B878570BE3B30E557B819DBEC06F1291965419B7EAD74F1ADF900E771781024B44E5669DDA88FD9C62496764EA5CE3E791EB4CCDA3E4B665355C9EC92EF18046331332886B79DC3710C36F02D2EB260246AE83459514EF00FC5857CAC8562D4DD522FA4575ECD1BACA7313A1C91F72863DFC8AF0732C9025862525CF33E5EC545D356C620C70F16D2BDD22A9BD9A25469D21C70D437FA08ED36550A2EEEF3545EFDC5A0C0FCC1070A99B2D5EFC1A32D764AEE21DC38FD6086813C01F09298B41B3EFC7F34DB201EC538901C8E05A3B3295519042CF631226BBAF9A9F8A3C4BD6B00E24CD048A14ACA7C8B9EC1C1931853909EFF8B1FBCA46C9CB9E42BE7253E7F25A97C6D50E970EF8CEFE1C70C8A3254F5402F3DCC62A5A34B477A8B452352B6CB2BFC1F372130DBC4960DCD20088DB50B39998ECCB0CD2F797F7267529DB9A63B7BE8691F9B6155EFFAEEBDB8EE7FCA2EDD9DCC92B5DDCF536E87DA064010A15CA505885DEC6499E4B1408580A3F854E1C50BEA96D4B47D9022B004F426F1F69C7580573F60BA80045BA799FB486C1AB3E363D75DA7C2BE5E256001E728B4850BA99184068CFF7A87B25C95F43E17B35BEBFA4711A1307EA545B1BA97D13F752EB7CD6F42BA4776098D71C02E4961480D18AE898D2EBCD61E897041CB1A7056DADDC183
+20210511133230 2 6 100 6143 2 EE2D1C3A0CC149C6675914AEFB8A3B27C939CB721B7D7D2AECDF4464406D6B59DF4C01ABE292F37396B097215BCF049F98D5B7CBA342EF5DFE31668084E83E783AC5C21CB152C08EE0BBAB4CC8F261AFD378F97D5044BC6BD3E555ADCF508ABC26E4CAF8D0B84EDDA7E78B56B89A497BC4D5A1D5C14D1A535777D4BBA17540B64F3E2695C5B134275A2F94D1388C0F666573454ED38B3E0CAA04BF5551662A429B54153795935493FE7E3C8130EE4568A278C2FF362D070FA4D10462B347E382EE340DF1EBBDBFEFAD66AB4B2296E982EC7F0947F6BF7845E8C40F9A7B4934727781E2D129C2E055227C3CD063BBFF14DE2958D6B4D3D3EF54ECA8757C3D102B98B6C97BE8087FE6B8ABC4B7D61AB491842E37A53890081C73359B4B878570BE3B30E557B819DBEC06F1291965419B7EAD74F1ADF900E771781024B44E5669DDA88FD9C62496764EA5CE3E791EB4CCDA3E4B665355C9EC92EF18046331332886B79DC3710C36F02D2EB260246AE83459514EF00FC5857CAC8562D4DD522FA4575ECD1BACA7313A1C91F72863DFC8AF0732C9025862525CF33E5EC545D356C620C70F16D2BDD22A9BD9A25469D21C70D437FA08ED36550A2EEEF3545EFDC5A0C0FCC1070A99B2D5EFC1A32D764AEE21DC38FD6086813C01F09298B41B3EFC7F34DB201EC538901C8E05A3B3295519042CF631226BBAF9A9F8A3C4BD6B00E24CD048A14ACA7C8B9EC1C1931853909EFF8B1FBCA46C9CB9E42BE7253E7F25A97C6D50E970EF8CEFE1C70C8A3254F5402F3DCC62A5A34B477A8B452352B6CB2BFC1F372130DBC4960DCD20088DB50B39998ECCB0CD2F797F7267529DB9A63B7BE8691F9B6155EFFAEEBDB8EE7FCA2EDD9DCC92B5DDCF536E87DA064010A15CA505885DEC6499E4B1408580A3F854E1C50BEA96D4B47D9022B004F426F1F69C7580573F60BA80045BA799FB486C1AB3E363D75DA7C2BE5E256001E728B4850BA99184068CFF7A87B25C95F43E17B35BEBFA4711A1307EA545B1BA97D13F752EB7CD6F42BA4776098D71C02E4961480D18AE898D2EBCD61E897041CB1A7056E00C0173
+20210511134118 2 6 100 6143 2 EE2D1C3A0CC149C6675914AEFB8A3B27C939CB721B7D7D2AECDF4464406D6B59DF4C01ABE292F37396B097215BCF049F98D5B7CBA342EF5DFE31668084E83E783AC5C21CB152C08EE0BBAB4CC8F261AFD378F97D5044BC6BD3E555ADCF508ABC26E4CAF8D0B84EDDA7E78B56B89A497BC4D5A1D5C14D1A535777D4BBA17540B64F3E2695C5B134275A2F94D1388C0F666573454ED38B3E0CAA04BF5551662A429B54153795935493FE7E3C8130EE4568A278C2FF362D070FA4D10462B347E382EE340DF1EBBDBFEFAD66AB4B2296E982EC7F0947F6BF7845E8C40F9A7B4934727781E2D129C2E055227C3CD063BBFF14DE2958D6B4D3D3EF54ECA8757C3D102B98B6C97BE8087FE6B8ABC4B7D61AB491842E37A53890081C73359B4B878570BE3B30E557B819DBEC06F1291965419B7EAD74F1ADF900E771781024B44E5669DDA88FD9C62496764EA5CE3E791EB4CCDA3E4B665355C9EC92EF18046331332886B79DC3710C36F02D2EB260246AE83459514EF00FC5857CAC8562D4DD522FA4575ECD1BACA7313A1C91F72863DFC8AF0732C9025862525CF33E5EC545D356C620C70F16D2BDD22A9BD9A25469D21C70D437FA08ED36550A2EEEF3545EFDC5A0C0FCC1070A99B2D5EFC1A32D764AEE21DC38FD6086813C01F09298B41B3EFC7F34DB201EC538901C8E05A3B3295519042CF631226BBAF9A9F8A3C4BD6B00E24CD048A14ACA7C8B9EC1C1931853909EFF8B1FBCA46C9CB9E42BE7253E7F25A97C6D50E970EF8CEFE1C70C8A3254F5402F3DCC62A5A34B477A8B452352B6CB2BFC1F372130DBC4960DCD20088DB50B39998ECCB0CD2F797F7267529DB9A63B7BE8691F9B6155EFFAEEBDB8EE7FCA2EDD9DCC92B5DDCF536E87DA064010A15CA505885DEC6499E4B1408580A3F854E1C50BEA96D4B47D9022B004F426F1F69C7580573F60BA80045BA799FB486C1AB3E363D75DA7C2BE5E256001E728B4850BA99184068CFF7A87B25C95F43E17B35BEBFA4711A1307EA545B1BA97D13F752EB7CD6F42BA4776098D71C02E4961480D18AE898D2EBCD61E897041CB1A7056E14EC08B
+20210511135454 2 6 100 6143 2 EE2D1C3A0CC149C6675914AEFB8A3B27C939CB721B7D7D2AECDF4464406D6B59DF4C01ABE292F37396B097215BCF049F98D5B7CBA342EF5DFE31668084E83E783AC5C21CB152C08EE0BBAB4CC8F261AFD378F97D5044BC6BD3E555ADCF508ABC26E4CAF8D0B84EDDA7E78B56B89A497BC4D5A1D5C14D1A535777D4BBA17540B64F3E2695C5B134275A2F94D1388C0F666573454ED38B3E0CAA04BF5551662A429B54153795935493FE7E3C8130EE4568A278C2FF362D070FA4D10462B347E382EE340DF1EBBDBFEFAD66AB4B2296E982EC7F0947F6BF7845E8C40F9A7B4934727781E2D129C2E055227C3CD063BBFF14DE2958D6B4D3D3EF54ECA8757C3D102B98B6C97BE8087FE6B8ABC4B7D61AB491842E37A53890081C73359B4B878570BE3B30E557B819DBEC06F1291965419B7EAD74F1ADF900E771781024B44E5669DDA88FD9C62496764EA5CE3E791EB4CCDA3E4B665355C9EC92EF18046331332886B79DC3710C36F02D2EB260246AE83459514EF00FC5857CAC8562D4DD522FA4575ECD1BACA7313A1C91F72863DFC8AF0732C9025862525CF33E5EC545D356C620C70F16D2BDD22A9BD9A25469D21C70D437FA08ED36550A2EEEF3545EFDC5A0C0FCC1070A99B2D5EFC1A32D764AEE21DC38FD6086813C01F09298B41B3EFC7F34DB201EC538901C8E05A3B3295519042CF631226BBAF9A9F8A3C4BD6B00E24CD048A14ACA7C8B9EC1C1931853909EFF8B1FBCA46C9CB9E42BE7253E7F25A97C6D50E970EF8CEFE1C70C8A3254F5402F3DCC62A5A34B477A8B452352B6CB2BFC1F372130DBC4960DCD20088DB50B39998ECCB0CD2F797F7267529DB9A63B7BE8691F9B6155EFFAEEBDB8EE7FCA2EDD9DCC92B5DDCF536E87DA064010A15CA505885DEC6499E4B1408580A3F854E1C50BEA96D4B47D9022B004F426F1F69C7580573F60BA80045BA799FB486C1AB3E363D75DA7C2BE5E256001E728B4850BA99184068CFF7A87B25C95F43E17B35BEBFA4711A1307EA545B1BA97D13F752EB7CD6F42BA4776098D71C02E4961480D18AE898D2EBCD61E897041CB1A7056E34379F3
+20210511140822 2 6 100 6143 5 EE2D1C3A0CC149C6675914AEFB8A3B27C939CB721B7D7D2AECDF4464406D6B59DF4C01ABE292F37396B097215BCF049F98D5B7CBA342EF5DFE31668084E83E783AC5C21CB152C08EE0BBAB4CC8F261AFD378F97D5044BC6BD3E555ADCF508ABC26E4CAF8D0B84EDDA7E78B56B89A497BC4D5A1D5C14D1A535777D4BBA17540B64F3E2695C5B134275A2F94D1388C0F666573454ED38B3E0CAA04BF5551662A429B54153795935493FE7E3C8130EE4568A278C2FF362D070FA4D10462B347E382EE340DF1EBBDBFEFAD66AB4B2296E982EC7F0947F6BF7845E8C40F9A7B4934727781E2D129C2E055227C3CD063BBFF14DE2958D6B4D3D3EF54ECA8757C3D102B98B6C97BE8087FE6B8ABC4B7D61AB491842E37A53890081C73359B4B878570BE3B30E557B819DBEC06F1291965419B7EAD74F1ADF900E771781024B44E5669DDA88FD9C62496764EA5CE3E791EB4CCDA3E4B665355C9EC92EF18046331332886B79DC3710C36F02D2EB260246AE83459514EF00FC5857CAC8562D4DD522FA4575ECD1BACA7313A1C91F72863DFC8AF0732C9025862525CF33E5EC545D356C620C70F16D2BDD22A9BD9A25469D21C70D437FA08ED36550A2EEEF3545EFDC5A0C0FCC1070A99B2D5EFC1A32D764AEE21DC38FD6086813C01F09298B41B3EFC7F34DB201EC538901C8E05A3B3295519042CF631226BBAF9A9F8A3C4BD6B00E24CD048A14ACA7C8B9EC1C1931853909EFF8B1FBCA46C9CB9E42BE7253E7F25A97C6D50E970EF8CEFE1C70C8A3254F5402F3DCC62A5A34B477A8B452352B6CB2BFC1F372130DBC4960DCD20088DB50B39998ECCB0CD2F797F7267529DB9A63B7BE8691F9B6155EFFAEEBDB8EE7FCA2EDD9DCC92B5DDCF536E87DA064010A15CA505885DEC6499E4B1408580A3F854E1C50BEA96D4B47D9022B004F426F1F69C7580573F60BA80045BA799FB486C1AB3E363D75DA7C2BE5E256001E728B4850BA99184068CFF7A87B25C95F43E17B35BEBFA4711A1307EA545B1BA97D13F752EB7CD6F42BA4776098D71C02E4961480D18AE898D2EBCD61E897041CB1A7056E531D6AF
+20210511142133 2 6 100 6143 5 EE2D1C3A0CC149C6675914AEFB8A3B27C939CB721B7D7D2AECDF4464406D6B59DF4C01ABE292F37396B097215BCF049F98D5B7CBA342EF5DFE31668084E83E783AC5C21CB152C08EE0BBAB4CC8F261AFD378F97D5044BC6BD3E555ADCF508ABC26E4CAF8D0B84EDDA7E78B56B89A497BC4D5A1D5C14D1A535777D4BBA17540B64F3E2695C5B134275A2F94D1388C0F666573454ED38B3E0CAA04BF5551662A429B54153795935493FE7E3C8130EE4568A278C2FF362D070FA4D10462B347E382EE340DF1EBBDBFEFAD66AB4B2296E982EC7F0947F6BF7845E8C40F9A7B4934727781E2D129C2E055227C3CD063BBFF14DE2958D6B4D3D3EF54ECA8757C3D102B98B6C97BE8087FE6B8ABC4B7D61AB491842E37A53890081C73359B4B878570BE3B30E557B819DBEC06F1291965419B7EAD74F1ADF900E771781024B44E5669DDA88FD9C62496764EA5CE3E791EB4CCDA3E4B665355C9EC92EF18046331332886B79DC3710C36F02D2EB260246AE83459514EF00FC5857CAC8562D4DD522FA4575ECD1BACA7313A1C91F72863DFC8AF0732C9025862525CF33E5EC545D356C620C70F16D2BDD22A9BD9A25469D21C70D437FA08ED36550A2EEEF3545EFDC5A0C0FCC1070A99B2D5EFC1A32D764AEE21DC38FD6086813C01F09298B41B3EFC7F34DB201EC538901C8E05A3B3295519042CF631226BBAF9A9F8A3C4BD6B00E24CD048A14ACA7C8B9EC1C1931853909EFF8B1FBCA46C9CB9E42BE7253E7F25A97C6D50E970EF8CEFE1C70C8A3254F5402F3DCC62A5A34B477A8B452352B6CB2BFC1F372130DBC4960DCD20088DB50B39998ECCB0CD2F797F7267529DB9A63B7BE8691F9B6155EFFAEEBDB8EE7FCA2EDD9DCC92B5DDCF536E87DA064010A15CA505885DEC6499E4B1408580A3F854E1C50BEA96D4B47D9022B004F426F1F69C7580573F60BA80045BA799FB486C1AB3E363D75DA7C2BE5E256001E728B4850BA99184068CFF7A87B25C95F43E17B35BEBFA4711A1307EA545B1BA97D13F752EB7CD6F42BA4776098D71C02E4961480D18AE898D2EBCD61E897041CB1A7056E71D2267
+20210511144054 2 6 100 6143 5 EE2D1C3A0CC149C6675914AEFB8A3B27C939CB721B7D7D2AECDF4464406D6B59DF4C01ABE292F37396B097215BCF049F98D5B7CBA342EF5DFE31668084E83E783AC5C21CB152C08EE0BBAB4CC8F261AFD378F97D5044BC6BD3E555ADCF508ABC26E4CAF8D0B84EDDA7E78B56B89A497BC4D5A1D5C14D1A535777D4BBA17540B64F3E2695C5B134275A2F94D1388C0F666573454ED38B3E0CAA04BF5551662A429B54153795935493FE7E3C8130EE4568A278C2FF362D070FA4D10462B347E382EE340DF1EBBDBFEFAD66AB4B2296E982EC7F0947F6BF7845E8C40F9A7B4934727781E2D129C2E055227C3CD063BBFF14DE2958D6B4D3D3EF54ECA8757C3D102B98B6C97BE8087FE6B8ABC4B7D61AB491842E37A53890081C73359B4B878570BE3B30E557B819DBEC06F1291965419B7EAD74F1ADF900E771781024B44E5669DDA88FD9C62496764EA5CE3E791EB4CCDA3E4B665355C9EC92EF18046331332886B79DC3710C36F02D2EB260246AE83459514EF00FC5857CAC8562D4DD522FA4575ECD1BACA7313A1C91F72863DFC8AF0732C9025862525CF33E5EC545D356C620C70F16D2BDD22A9BD9A25469D21C70D437FA08ED36550A2EEEF3545EFDC5A0C0FCC1070A99B2D5EFC1A32D764AEE21DC38FD6086813C01F09298B41B3EFC7F34DB201EC538901C8E05A3B3295519042CF631226BBAF9A9F8A3C4BD6B00E24CD048A14ACA7C8B9EC1C1931853909EFF8B1FBCA46C9CB9E42BE7253E7F25A97C6D50E970EF8CEFE1C70C8A3254F5402F3DCC62A5A34B477A8B452352B6CB2BFC1F372130DBC4960DCD20088DB50B39998ECCB0CD2F797F7267529DB9A63B7BE8691F9B6155EFFAEEBDB8EE7FCA2EDD9DCC92B5DDCF536E87DA064010A15CA505885DEC6499E4B1408580A3F854E1C50BEA96D4B47D9022B004F426F1F69C7580573F60BA80045BA799FB486C1AB3E363D75DA7C2BE5E256001E728B4850BA99184068CFF7A87B25C95F43E17B35BEBFA4711A1307EA545B1BA97D13F752EB7CD6F42BA4776098D71C02E4961480D18AE898D2EBCD61E897041CB1A7056E9EE160F
+20210511144259 2 6 100 6143 2 EE2D1C3A0CC149C6675914AEFB8A3B27C939CB721B7D7D2AECDF4464406D6B59DF4C01ABE292F37396B097215BCF049F98D5B7CBA342EF5DFE31668084E83E783AC5C21CB152C08EE0BBAB4CC8F261AFD378F97D5044BC6BD3E555ADCF508ABC26E4CAF8D0B84EDDA7E78B56B89A497BC4D5A1D5C14D1A535777D4BBA17540B64F3E2695C5B134275A2F94D1388C0F666573454ED38B3E0CAA04BF5551662A429B54153795935493FE7E3C8130EE4568A278C2FF362D070FA4D10462B347E382EE340DF1EBBDBFEFAD66AB4B2296E982EC7F0947F6BF7845E8C40F9A7B4934727781E2D129C2E055227C3CD063BBFF14DE2958D6B4D3D3EF54ECA8757C3D102B98B6C97BE8087FE6B8ABC4B7D61AB491842E37A53890081C73359B4B878570BE3B30E557B819DBEC06F1291965419B7EAD74F1ADF900E771781024B44E5669DDA88FD9C62496764EA5CE3E791EB4CCDA3E4B665355C9EC92EF18046331332886B79DC3710C36F02D2EB260246AE83459514EF00FC5857CAC8562D4DD522FA4575ECD1BACA7313A1C91F72863DFC8AF0732C9025862525CF33E5EC545D356C620C70F16D2BDD22A9BD9A25469D21C70D437FA08ED36550A2EEEF3545EFDC5A0C0FCC1070A99B2D5EFC1A32D764AEE21DC38FD6086813C01F09298B41B3EFC7F34DB201EC538901C8E05A3B3295519042CF631226BBAF9A9F8A3C4BD6B00E24CD048A14ACA7C8B9EC1C1931853909EFF8B1FBCA46C9CB9E42BE7253E7F25A97C6D50E970EF8CEFE1C70C8A3254F5402F3DCC62A5A34B477A8B452352B6CB2BFC1F372130DBC4960DCD20088DB50B39998ECCB0CD2F797F7267529DB9A63B7BE8691F9B6155EFFAEEBDB8EE7FCA2EDD9DCC92B5DDCF536E87DA064010A15CA505885DEC6499E4B1408580A3F854E1C50BEA96D4B47D9022B004F426F1F69C7580573F60BA80045BA799FB486C1AB3E363D75DA7C2BE5E256001E728B4850BA99184068CFF7A87B25C95F43E17B35BEBFA4711A1307EA545B1BA97D13F752EB7CD6F42BA4776098D71C02E4961480D18AE898D2EBCD61E897041CB1A7056EA31E3A3
+20210511144958 2 6 100 6143 2 EE2D1C3A0CC149C6675914AEFB8A3B27C939CB721B7D7D2AECDF4464406D6B59DF4C01ABE292F37396B097215BCF049F98D5B7CBA342EF5DFE31668084E83E783AC5C21CB152C08EE0BBAB4CC8F261AFD378F97D5044BC6BD3E555ADCF508ABC26E4CAF8D0B84EDDA7E78B56B89A497BC4D5A1D5C14D1A535777D4BBA17540B64F3E2695C5B134275A2F94D1388C0F666573454ED38B3E0CAA04BF5551662A429B54153795935493FE7E3C8130EE4568A278C2FF362D070FA4D10462B347E382EE340DF1EBBDBFEFAD66AB4B2296E982EC7F0947F6BF7845E8C40F9A7B4934727781E2D129C2E055227C3CD063BBFF14DE2958D6B4D3D3EF54ECA8757C3D102B98B6C97BE8087FE6B8ABC4B7D61AB491842E37A53890081C73359B4B878570BE3B30E557B819DBEC06F1291965419B7EAD74F1ADF900E771781024B44E5669DDA88FD9C62496764EA5CE3E791EB4CCDA3E4B665355C9EC92EF18046331332886B79DC3710C36F02D2EB260246AE83459514EF00FC5857CAC8562D4DD522FA4575ECD1BACA7313A1C91F72863DFC8AF0732C9025862525CF33E5EC545D356C620C70F16D2BDD22A9BD9A25469D21C70D437FA08ED36550A2EEEF3545EFDC5A0C0FCC1070A99B2D5EFC1A32D764AEE21DC38FD6086813C01F09298B41B3EFC7F34DB201EC538901C8E05A3B3295519042CF631226BBAF9A9F8A3C4BD6B00E24CD048A14ACA7C8B9EC1C1931853909EFF8B1FBCA46C9CB9E42BE7253E7F25A97C6D50E970EF8CEFE1C70C8A3254F5402F3DCC62A5A34B477A8B452352B6CB2BFC1F372130DBC4960DCD20088DB50B39998ECCB0CD2F797F7267529DB9A63B7BE8691F9B6155EFFAEEBDB8EE7FCA2EDD9DCC92B5DDCF536E87DA064010A15CA505885DEC6499E4B1408580A3F854E1C50BEA96D4B47D9022B004F426F1F69C7580573F60BA80045BA799FB486C1AB3E363D75DA7C2BE5E256001E728B4850BA99184068CFF7A87B25C95F43E17B35BEBFA4711A1307EA545B1BA97D13F752EB7CD6F42BA4776098D71C02E4961480D18AE898D2EBCD61E897041CB1A7056EB339A53
+20210511145731 2 6 100 6143 2 EE2D1C3A0CC149C6675914AEFB8A3B27C939CB721B7D7D2AECDF4464406D6B59DF4C01ABE292F37396B097215BCF049F98D5B7CBA342EF5DFE31668084E83E783AC5C21CB152C08EE0BBAB4CC8F261AFD378F97D5044BC6BD3E555ADCF508ABC26E4CAF8D0B84EDDA7E78B56B89A497BC4D5A1D5C14D1A535777D4BBA17540B64F3E2695C5B134275A2F94D1388C0F666573454ED38B3E0CAA04BF5551662A429B54153795935493FE7E3C8130EE4568A278C2FF362D070FA4D10462B347E382EE340DF1EBBDBFEFAD66AB4B2296E982EC7F0947F6BF7845E8C40F9A7B4934727781E2D129C2E055227C3CD063BBFF14DE2958D6B4D3D3EF54ECA8757C3D102B98B6C97BE8087FE6B8ABC4B7D61AB491842E37A53890081C73359B4B878570BE3B30E557B819DBEC06F1291965419B7EAD74F1ADF900E771781024B44E5669DDA88FD9C62496764EA5CE3E791EB4CCDA3E4B665355C9EC92EF18046331332886B79DC3710C36F02D2EB260246AE83459514EF00FC5857CAC8562D4DD522FA4575ECD1BACA7313A1C91F72863DFC8AF0732C9025862525CF33E5EC545D356C620C70F16D2BDD22A9BD9A25469D21C70D437FA08ED36550A2EEEF3545EFDC5A0C0FCC1070A99B2D5EFC1A32D764AEE21DC38FD6086813C01F09298B41B3EFC7F34DB201EC538901C8E05A3B3295519042CF631226BBAF9A9F8A3C4BD6B00E24CD048A14ACA7C8B9EC1C1931853909EFF8B1FBCA46C9CB9E42BE7253E7F25A97C6D50E970EF8CEFE1C70C8A3254F5402F3DCC62A5A34B477A8B452352B6CB2BFC1F372130DBC4960DCD20088DB50B39998ECCB0CD2F797F7267529DB9A63B7BE8691F9B6155EFFAEEBDB8EE7FCA2EDD9DCC92B5DDCF536E87DA064010A15CA505885DEC6499E4B1408580A3F854E1C50BEA96D4B47D9022B004F426F1F69C7580573F60BA80045BA799FB486C1AB3E363D75DA7C2BE5E256001E728B4850BA99184068CFF7A87B25C95F43E17B35BEBFA4711A1307EA545B1BA97D13F752EB7CD6F42BA4776098D71C02E4961480D18AE898D2EBCD61E897041CB1A7056EC45903B
+20210511150937 2 6 100 6143 5 EE2D1C3A0CC149C6675914AEFB8A3B27C939CB721B7D7D2AECDF4464406D6B59DF4C01ABE292F37396B097215BCF049F98D5B7CBA342EF5DFE31668084E83E783AC5C21CB152C08EE0BBAB4CC8F261AFD378F97D5044BC6BD3E555ADCF508ABC26E4CAF8D0B84EDDA7E78B56B89A497BC4D5A1D5C14D1A535777D4BBA17540B64F3E2695C5B134275A2F94D1388C0F666573454ED38B3E0CAA04BF5551662A429B54153795935493FE7E3C8130EE4568A278C2FF362D070FA4D10462B347E382EE340DF1EBBDBFEFAD66AB4B2296E982EC7F0947F6BF7845E8C40F9A7B4934727781E2D129C2E055227C3CD063BBFF14DE2958D6B4D3D3EF54ECA8757C3D102B98B6C97BE8087FE6B8ABC4B7D61AB491842E37A53890081C73359B4B878570BE3B30E557B819DBEC06F1291965419B7EAD74F1ADF900E771781024B44E5669DDA88FD9C62496764EA5CE3E791EB4CCDA3E4B665355C9EC92EF18046331332886B79DC3710C36F02D2EB260246AE83459514EF00FC5857CAC8562D4DD522FA4575ECD1BACA7313A1C91F72863DFC8AF0732C9025862525CF33E5EC545D356C620C70F16D2BDD22A9BD9A25469D21C70D437FA08ED36550A2EEEF3545EFDC5A0C0FCC1070A99B2D5EFC1A32D764AEE21DC38FD6086813C01F09298B41B3EFC7F34DB201EC538901C8E05A3B3295519042CF631226BBAF9A9F8A3C4BD6B00E24CD048A14ACA7C8B9EC1C1931853909EFF8B1FBCA46C9CB9E42BE7253E7F25A97C6D50E970EF8CEFE1C70C8A3254F5402F3DCC62A5A34B477A8B452352B6CB2BFC1F372130DBC4960DCD20088DB50B39998ECCB0CD2F797F7267529DB9A63B7BE8691F9B6155EFFAEEBDB8EE7FCA2EDD9DCC92B5DDCF536E87DA064010A15CA505885DEC6499E4B1408580A3F854E1C50BEA96D4B47D9022B004F426F1F69C7580573F60BA80045BA799FB486C1AB3E363D75DA7C2BE5E256001E728B4850BA99184068CFF7A87B25C95F43E17B35BEBFA4711A1307EA545B1BA97D13F752EB7CD6F42BA4776098D71C02E4961480D18AE898D2EBCD61E897041CB1A7056EDFF14D7
+20210511151422 2 6 100 6143 5 EE2D1C3A0CC149C6675914AEFB8A3B27C939CB721B7D7D2AECDF4464406D6B59DF4C01ABE292F37396B097215BCF049F98D5B7CBA342EF5DFE31668084E83E783AC5C21CB152C08EE0BBAB4CC8F261AFD378F97D5044BC6BD3E555ADCF508ABC26E4CAF8D0B84EDDA7E78B56B89A497BC4D5A1D5C14D1A535777D4BBA17540B64F3E2695C5B134275A2F94D1388C0F666573454ED38B3E0CAA04BF5551662A429B54153795935493FE7E3C8130EE4568A278C2FF362D070FA4D10462B347E382EE340DF1EBBDBFEFAD66AB4B2296E982EC7F0947F6BF7845E8C40F9A7B4934727781E2D129C2E055227C3CD063BBFF14DE2958D6B4D3D3EF54ECA8757C3D102B98B6C97BE8087FE6B8ABC4B7D61AB491842E37A53890081C73359B4B878570BE3B30E557B819DBEC06F1291965419B7EAD74F1ADF900E771781024B44E5669DDA88FD9C62496764EA5CE3E791EB4CCDA3E4B665355C9EC92EF18046331332886B79DC3710C36F02D2EB260246AE83459514EF00FC5857CAC8562D4DD522FA4575ECD1BACA7313A1C91F72863DFC8AF0732C9025862525CF33E5EC545D356C620C70F16D2BDD22A9BD9A25469D21C70D437FA08ED36550A2EEEF3545EFDC5A0C0FCC1070A99B2D5EFC1A32D764AEE21DC38FD6086813C01F09298B41B3EFC7F34DB201EC538901C8E05A3B3295519042CF631226BBAF9A9F8A3C4BD6B00E24CD048A14ACA7C8B9EC1C1931853909EFF8B1FBCA46C9CB9E42BE7253E7F25A97C6D50E970EF8CEFE1C70C8A3254F5402F3DCC62A5A34B477A8B452352B6CB2BFC1F372130DBC4960DCD20088DB50B39998ECCB0CD2F797F7267529DB9A63B7BE8691F9B6155EFFAEEBDB8EE7FCA2EDD9DCC92B5DDCF536E87DA064010A15CA505885DEC6499E4B1408580A3F854E1C50BEA96D4B47D9022B004F426F1F69C7580573F60BA80045BA799FB486C1AB3E363D75DA7C2BE5E256001E728B4850BA99184068CFF7A87B25C95F43E17B35BEBFA4711A1307EA545B1BA97D13F752EB7CD6F42BA4776098D71C02E4961480D18AE898D2EBCD61E897041CB1A7056EEA51A4F
+20210511154856 2 6 100 6143 2 EE2D1C3A0CC149C6675914AEFB8A3B27C939CB721B7D7D2AECDF4464406D6B59DF4C01ABE292F37396B097215BCF049F98D5B7CBA342EF5DFE31668084E83E783AC5C21CB152C08EE0BBAB4CC8F261AFD378F97D5044BC6BD3E555ADCF508ABC26E4CAF8D0B84EDDA7E78B56B89A497BC4D5A1D5C14D1A535777D4BBA17540B64F3E2695C5B134275A2F94D1388C0F666573454ED38B3E0CAA04BF5551662A429B54153795935493FE7E3C8130EE4568A278C2FF362D070FA4D10462B347E382EE340DF1EBBDBFEFAD66AB4B2296E982EC7F0947F6BF7845E8C40F9A7B4934727781E2D129C2E055227C3CD063BBFF14DE2958D6B4D3D3EF54ECA8757C3D102B98B6C97BE8087FE6B8ABC4B7D61AB491842E37A53890081C73359B4B878570BE3B30E557B819DBEC06F1291965419B7EAD74F1ADF900E771781024B44E5669DDA88FD9C62496764EA5CE3E791EB4CCDA3E4B665355C9EC92EF18046331332886B79DC3710C36F02D2EB260246AE83459514EF00FC5857CAC8562D4DD522FA4575ECD1BACA7313A1C91F72863DFC8AF0732C9025862525CF33E5EC545D356C620C70F16D2BDD22A9BD9A25469D21C70D437FA08ED36550A2EEEF3545EFDC5A0C0FCC1070A99B2D5EFC1A32D764AEE21DC38FD6086813C01F09298B41B3EFC7F34DB201EC538901C8E05A3B3295519042CF631226BBAF9A9F8A3C4BD6B00E24CD048A14ACA7C8B9EC1C1931853909EFF8B1FBCA46C9CB9E42BE7253E7F25A97C6D50E970EF8CEFE1C70C8A3254F5402F3DCC62A5A34B477A8B452352B6CB2BFC1F372130DBC4960DCD20088DB50B39998ECCB0CD2F797F7267529DB9A63B7BE8691F9B6155EFFAEEBDB8EE7FCA2EDD9DCC92B5DDCF536E87DA064010A15CA505885DEC6499E4B1408580A3F854E1C50BEA96D4B47D9022B004F426F1F69C7580573F60BA80045BA799FB486C1AB3E363D75DA7C2BE5E256001E728B4850BA99184068CFF7A87B25C95F43E17B35BEBFA4711A1307EA545B1BA97D13F752EB7CD6F42BA4776098D71C02E4961480D18AE898D2EBCD61E897041CB1A7056F391E0D3
+20210511160239 2 6 100 6143 5 EE2D1C3A0CC149C6675914AEFB8A3B27C939CB721B7D7D2AECDF4464406D6B59DF4C01ABE292F37396B097215BCF049F98D5B7CBA342EF5DFE31668084E83E783AC5C21CB152C08EE0BBAB4CC8F261AFD378F97D5044BC6BD3E555ADCF508ABC26E4CAF8D0B84EDDA7E78B56B89A497BC4D5A1D5C14D1A535777D4BBA17540B64F3E2695C5B134275A2F94D1388C0F666573454ED38B3E0CAA04BF5551662A429B54153795935493FE7E3C8130EE4568A278C2FF362D070FA4D10462B347E382EE340DF1EBBDBFEFAD66AB4B2296E982EC7F0947F6BF7845E8C40F9A7B4934727781E2D129C2E055227C3CD063BBFF14DE2958D6B4D3D3EF54ECA8757C3D102B98B6C97BE8087FE6B8ABC4B7D61AB491842E37A53890081C73359B4B878570BE3B30E557B819DBEC06F1291965419B7EAD74F1ADF900E771781024B44E5669DDA88FD9C62496764EA5CE3E791EB4CCDA3E4B665355C9EC92EF18046331332886B79DC3710C36F02D2EB260246AE83459514EF00FC5857CAC8562D4DD522FA4575ECD1BACA7313A1C91F72863DFC8AF0732C9025862525CF33E5EC545D356C620C70F16D2BDD22A9BD9A25469D21C70D437FA08ED36550A2EEEF3545EFDC5A0C0FCC1070A99B2D5EFC1A32D764AEE21DC38FD6086813C01F09298B41B3EFC7F34DB201EC538901C8E05A3B3295519042CF631226BBAF9A9F8A3C4BD6B00E24CD048A14ACA7C8B9EC1C1931853909EFF8B1FBCA46C9CB9E42BE7253E7F25A97C6D50E970EF8CEFE1C70C8A3254F5402F3DCC62A5A34B477A8B452352B6CB2BFC1F372130DBC4960DCD20088DB50B39998ECCB0CD2F797F7267529DB9A63B7BE8691F9B6155EFFAEEBDB8EE7FCA2EDD9DCC92B5DDCF536E87DA064010A15CA505885DEC6499E4B1408580A3F854E1C50BEA96D4B47D9022B004F426F1F69C7580573F60BA80045BA799FB486C1AB3E363D75DA7C2BE5E256001E728B4850BA99184068CFF7A87B25C95F43E17B35BEBFA4711A1307EA545B1BA97D13F752EB7CD6F42BA4776098D71C02E4961480D18AE898D2EBCD61E897041CB1A7056F5802B47
+20210511161337 2 6 100 6143 2 EE2D1C3A0CC149C6675914AEFB8A3B27C939CB721B7D7D2AECDF4464406D6B59DF4C01ABE292F37396B097215BCF049F98D5B7CBA342EF5DFE31668084E83E783AC5C21CB152C08EE0BBAB4CC8F261AFD378F97D5044BC6BD3E555ADCF508ABC26E4CAF8D0B84EDDA7E78B56B89A497BC4D5A1D5C14D1A535777D4BBA17540B64F3E2695C5B134275A2F94D1388C0F666573454ED38B3E0CAA04BF5551662A429B54153795935493FE7E3C8130EE4568A278C2FF362D070FA4D10462B347E382EE340DF1EBBDBFEFAD66AB4B2296E982EC7F0947F6BF7845E8C40F9A7B4934727781E2D129C2E055227C3CD063BBFF14DE2958D6B4D3D3EF54ECA8757C3D102B98B6C97BE8087FE6B8ABC4B7D61AB491842E37A53890081C73359B4B878570BE3B30E557B819DBEC06F1291965419B7EAD74F1ADF900E771781024B44E5669DDA88FD9C62496764EA5CE3E791EB4CCDA3E4B665355C9EC92EF18046331332886B79DC3710C36F02D2EB260246AE83459514EF00FC5857CAC8562D4DD522FA4575ECD1BACA7313A1C91F72863DFC8AF0732C9025862525CF33E5EC545D356C620C70F16D2BDD22A9BD9A25469D21C70D437FA08ED36550A2EEEF3545EFDC5A0C0FCC1070A99B2D5EFC1A32D764AEE21DC38FD6086813C01F09298B41B3EFC7F34DB201EC538901C8E05A3B3295519042CF631226BBAF9A9F8A3C4BD6B00E24CD048A14ACA7C8B9EC1C1931853909EFF8B1FBCA46C9CB9E42BE7253E7F25A97C6D50E970EF8CEFE1C70C8A3254F5402F3DCC62A5A34B477A8B452352B6CB2BFC1F372130DBC4960DCD20088DB50B39998ECCB0CD2F797F7267529DB9A63B7BE8691F9B6155EFFAEEBDB8EE7FCA2EDD9DCC92B5DDCF536E87DA064010A15CA505885DEC6499E4B1408580A3F854E1C50BEA96D4B47D9022B004F426F1F69C7580573F60BA80045BA799FB486C1AB3E363D75DA7C2BE5E256001E728B4850BA99184068CFF7A87B25C95F43E17B35BEBFA4711A1307EA545B1BA97D13F752EB7CD6F42BA4776098D71C02E4961480D18AE898D2EBCD61E897041CB1A7056F704FF83
+20210511163831 2 6 100 6143 5 EE2D1C3A0CC149C6675914AEFB8A3B27C939CB721B7D7D2AECDF4464406D6B59DF4C01ABE292F37396B097215BCF049F98D5B7CBA342EF5DFE31668084E83E783AC5C21CB152C08EE0BBAB4CC8F261AFD378F97D5044BC6BD3E555ADCF508ABC26E4CAF8D0B84EDDA7E78B56B89A497BC4D5A1D5C14D1A535777D4BBA17540B64F3E2695C5B134275A2F94D1388C0F666573454ED38B3E0CAA04BF5551662A429B54153795935493FE7E3C8130EE4568A278C2FF362D070FA4D10462B347E382EE340DF1EBBDBFEFAD66AB4B2296E982EC7F0947F6BF7845E8C40F9A7B4934727781E2D129C2E055227C3CD063BBFF14DE2958D6B4D3D3EF54ECA8757C3D102B98B6C97BE8087FE6B8ABC4B7D61AB491842E37A53890081C73359B4B878570BE3B30E557B819DBEC06F1291965419B7EAD74F1ADF900E771781024B44E5669DDA88FD9C62496764EA5CE3E791EB4CCDA3E4B665355C9EC92EF18046331332886B79DC3710C36F02D2EB260246AE83459514EF00FC5857CAC8562D4DD522FA4575ECD1BACA7313A1C91F72863DFC8AF0732C9025862525CF33E5EC545D356C620C70F16D2BDD22A9BD9A25469D21C70D437FA08ED36550A2EEEF3545EFDC5A0C0FCC1070A99B2D5EFC1A32D764AEE21DC38FD6086813C01F09298B41B3EFC7F34DB201EC538901C8E05A3B3295519042CF631226BBAF9A9F8A3C4BD6B00E24CD048A14ACA7C8B9EC1C1931853909EFF8B1FBCA46C9CB9E42BE7253E7F25A97C6D50E970EF8CEFE1C70C8A3254F5402F3DCC62A5A34B477A8B452352B6CB2BFC1F372130DBC4960DCD20088DB50B39998ECCB0CD2F797F7267529DB9A63B7BE8691F9B6155EFFAEEBDB8EE7FCA2EDD9DCC92B5DDCF536E87DA064010A15CA505885DEC6499E4B1408580A3F854E1C50BEA96D4B47D9022B004F426F1F69C7580573F60BA80045BA799FB486C1AB3E363D75DA7C2BE5E256001E728B4850BA99184068CFF7A87B25C95F43E17B35BEBFA4711A1307EA545B1BA97D13F752EB7CD6F42BA4776098D71C02E4961480D18AE898D2EBCD61E897041CB1A7056FA993EF7
+20210511164110 2 6 100 6143 5 EE2D1C3A0CC149C6675914AEFB8A3B27C939CB721B7D7D2AECDF4464406D6B59DF4C01ABE292F37396B097215BCF049F98D5B7CBA342EF5DFE31668084E83E783AC5C21CB152C08EE0BBAB4CC8F261AFD378F97D5044BC6BD3E555ADCF508ABC26E4CAF8D0B84EDDA7E78B56B89A497BC4D5A1D5C14D1A535777D4BBA17540B64F3E2695C5B134275A2F94D1388C0F666573454ED38B3E0CAA04BF5551662A429B54153795935493FE7E3C8130EE4568A278C2FF362D070FA4D10462B347E382EE340DF1EBBDBFEFAD66AB4B2296E982EC7F0947F6BF7845E8C40F9A7B4934727781E2D129C2E055227C3CD063BBFF14DE2958D6B4D3D3EF54ECA8757C3D102B98B6C97BE8087FE6B8ABC4B7D61AB491842E37A53890081C73359B4B878570BE3B30E557B819DBEC06F1291965419B7EAD74F1ADF900E771781024B44E5669DDA88FD9C62496764EA5CE3E791EB4CCDA3E4B665355C9EC92EF18046331332886B79DC3710C36F02D2EB260246AE83459514EF00FC5857CAC8562D4DD522FA4575ECD1BACA7313A1C91F72863DFC8AF0732C9025862525CF33E5EC545D356C620C70F16D2BDD22A9BD9A25469D21C70D437FA08ED36550A2EEEF3545EFDC5A0C0FCC1070A99B2D5EFC1A32D764AEE21DC38FD6086813C01F09298B41B3EFC7F34DB201EC538901C8E05A3B3295519042CF631226BBAF9A9F8A3C4BD6B00E24CD048A14ACA7C8B9EC1C1931853909EFF8B1FBCA46C9CB9E42BE7253E7F25A97C6D50E970EF8CEFE1C70C8A3254F5402F3DCC62A5A34B477A8B452352B6CB2BFC1F372130DBC4960DCD20088DB50B39998ECCB0CD2F797F7267529DB9A63B7BE8691F9B6155EFFAEEBDB8EE7FCA2EDD9DCC92B5DDCF536E87DA064010A15CA505885DEC6499E4B1408580A3F854E1C50BEA96D4B47D9022B004F426F1F69C7580573F60BA80045BA799FB486C1AB3E363D75DA7C2BE5E256001E728B4850BA99184068CFF7A87B25C95F43E17B35BEBFA4711A1307EA545B1BA97D13F752EB7CD6F42BA4776098D71C02E4961480D18AE898D2EBCD61E897041CB1A7056FAF3096F
+20210511164534 2 6 100 6143 2 EE2D1C3A0CC149C6675914AEFB8A3B27C939CB721B7D7D2AECDF4464406D6B59DF4C01ABE292F37396B097215BCF049F98D5B7CBA342EF5DFE31668084E83E783AC5C21CB152C08EE0BBAB4CC8F261AFD378F97D5044BC6BD3E555ADCF508ABC26E4CAF8D0B84EDDA7E78B56B89A497BC4D5A1D5C14D1A535777D4BBA17540B64F3E2695C5B134275A2F94D1388C0F666573454ED38B3E0CAA04BF5551662A429B54153795935493FE7E3C8130EE4568A278C2FF362D070FA4D10462B347E382EE340DF1EBBDBFEFAD66AB4B2296E982EC7F0947F6BF7845E8C40F9A7B4934727781E2D129C2E055227C3CD063BBFF14DE2958D6B4D3D3EF54ECA8757C3D102B98B6C97BE8087FE6B8ABC4B7D61AB491842E37A53890081C73359B4B878570BE3B30E557B819DBEC06F1291965419B7EAD74F1ADF900E771781024B44E5669DDA88FD9C62496764EA5CE3E791EB4CCDA3E4B665355C9EC92EF18046331332886B79DC3710C36F02D2EB260246AE83459514EF00FC5857CAC8562D4DD522FA4575ECD1BACA7313A1C91F72863DFC8AF0732C9025862525CF33E5EC545D356C620C70F16D2BDD22A9BD9A25469D21C70D437FA08ED36550A2EEEF3545EFDC5A0C0FCC1070A99B2D5EFC1A32D764AEE21DC38FD6086813C01F09298B41B3EFC7F34DB201EC538901C8E05A3B3295519042CF631226BBAF9A9F8A3C4BD6B00E24CD048A14ACA7C8B9EC1C1931853909EFF8B1FBCA46C9CB9E42BE7253E7F25A97C6D50E970EF8CEFE1C70C8A3254F5402F3DCC62A5A34B477A8B452352B6CB2BFC1F372130DBC4960DCD20088DB50B39998ECCB0CD2F797F7267529DB9A63B7BE8691F9B6155EFFAEEBDB8EE7FCA2EDD9DCC92B5DDCF536E87DA064010A15CA505885DEC6499E4B1408580A3F854E1C50BEA96D4B47D9022B004F426F1F69C7580573F60BA80045BA799FB486C1AB3E363D75DA7C2BE5E256001E728B4850BA99184068CFF7A87B25C95F43E17B35BEBFA4711A1307EA545B1BA97D13F752EB7CD6F42BA4776098D71C02E4961480D18AE898D2EBCD61E897041CB1A7056FB84285B
+20210511170505 2 6 100 6143 2 EE2D1C3A0CC149C6675914AEFB8A3B27C939CB721B7D7D2AECDF4464406D6B59DF4C01ABE292F37396B097215BCF049F98D5B7CBA342EF5DFE31668084E83E783AC5C21CB152C08EE0BBAB4CC8F261AFD378F97D5044BC6BD3E555ADCF508ABC26E4CAF8D0B84EDDA7E78B56B89A497BC4D5A1D5C14D1A535777D4BBA17540B64F3E2695C5B134275A2F94D1388C0F666573454ED38B3E0CAA04BF5551662A429B54153795935493FE7E3C8130EE4568A278C2FF362D070FA4D10462B347E382EE340DF1EBBDBFEFAD66AB4B2296E982EC7F0947F6BF7845E8C40F9A7B4934727781E2D129C2E055227C3CD063BBFF14DE2958D6B4D3D3EF54ECA8757C3D102B98B6C97BE8087FE6B8ABC4B7D61AB491842E37A53890081C73359B4B878570BE3B30E557B819DBEC06F1291965419B7EAD74F1ADF900E771781024B44E5669DDA88FD9C62496764EA5CE3E791EB4CCDA3E4B665355C9EC92EF18046331332886B79DC3710C36F02D2EB260246AE83459514EF00FC5857CAC8562D4DD522FA4575ECD1BACA7313A1C91F72863DFC8AF0732C9025862525CF33E5EC545D356C620C70F16D2BDD22A9BD9A25469D21C70D437FA08ED36550A2EEEF3545EFDC5A0C0FCC1070A99B2D5EFC1A32D764AEE21DC38FD6086813C01F09298B41B3EFC7F34DB201EC538901C8E05A3B3295519042CF631226BBAF9A9F8A3C4BD6B00E24CD048A14ACA7C8B9EC1C1931853909EFF8B1FBCA46C9CB9E42BE7253E7F25A97C6D50E970EF8CEFE1C70C8A3254F5402F3DCC62A5A34B477A8B452352B6CB2BFC1F372130DBC4960DCD20088DB50B39998ECCB0CD2F797F7267529DB9A63B7BE8691F9B6155EFFAEEBDB8EE7FCA2EDD9DCC92B5DDCF536E87DA064010A15CA505885DEC6499E4B1408580A3F854E1C50BEA96D4B47D9022B004F426F1F69C7580573F60BA80045BA799FB486C1AB3E363D75DA7C2BE5E256001E728B4850BA99184068CFF7A87B25C95F43E17B35BEBFA4711A1307EA545B1BA97D13F752EB7CD6F42BA4776098D71C02E4961480D18AE898D2EBCD61E897041CB1A7056FE524F93
+20210511172712 2 6 100 6143 2 EE2D1C3A0CC149C6675914AEFB8A3B27C939CB721B7D7D2AECDF4464406D6B59DF4C01ABE292F37396B097215BCF049F98D5B7CBA342EF5DFE31668084E83E783AC5C21CB152C08EE0BBAB4CC8F261AFD378F97D5044BC6BD3E555ADCF508ABC26E4CAF8D0B84EDDA7E78B56B89A497BC4D5A1D5C14D1A535777D4BBA17540B64F3E2695C5B134275A2F94D1388C0F666573454ED38B3E0CAA04BF5551662A429B54153795935493FE7E3C8130EE4568A278C2FF362D070FA4D10462B347E382EE340DF1EBBDBFEFAD66AB4B2296E982EC7F0947F6BF7845E8C40F9A7B4934727781E2D129C2E055227C3CD063BBFF14DE2958D6B4D3D3EF54ECA8757C3D102B98B6C97BE8087FE6B8ABC4B7D61AB491842E37A53890081C73359B4B878570BE3B30E557B819DBEC06F1291965419B7EAD74F1ADF900E771781024B44E5669DDA88FD9C62496764EA5CE3E791EB4CCDA3E4B665355C9EC92EF18046331332886B79DC3710C36F02D2EB260246AE83459514EF00FC5857CAC8562D4DD522FA4575ECD1BACA7313A1C91F72863DFC8AF0732C9025862525CF33E5EC545D356C620C70F16D2BDD22A9BD9A25469D21C70D437FA08ED36550A2EEEF3545EFDC5A0C0FCC1070A99B2D5EFC1A32D764AEE21DC38FD6086813C01F09298B41B3EFC7F34DB201EC538901C8E05A3B3295519042CF631226BBAF9A9F8A3C4BD6B00E24CD048A14ACA7C8B9EC1C1931853909EFF8B1FBCA46C9CB9E42BE7253E7F25A97C6D50E970EF8CEFE1C70C8A3254F5402F3DCC62A5A34B477A8B452352B6CB2BFC1F372130DBC4960DCD20088DB50B39998ECCB0CD2F797F7267529DB9A63B7BE8691F9B6155EFFAEEBDB8EE7FCA2EDD9DCC92B5DDCF536E87DA064010A15CA505885DEC6499E4B1408580A3F854E1C50BEA96D4B47D9022B004F426F1F69C7580573F60BA80045BA799FB486C1AB3E363D75DA7C2BE5E256001E728B4850BA99184068CFF7A87B25C95F43E17B35BEBFA4711A1307EA545B1BA97D13F752EB7CD6F42BA4776098D71C02E4961480D18AE898D2EBCD61E897041CB1A70570166A98B
+20210511174145 2 6 100 6143 5 EE2D1C3A0CC149C6675914AEFB8A3B27C939CB721B7D7D2AECDF4464406D6B59DF4C01ABE292F37396B097215BCF049F98D5B7CBA342EF5DFE31668084E83E783AC5C21CB152C08EE0BBAB4CC8F261AFD378F97D5044BC6BD3E555ADCF508ABC26E4CAF8D0B84EDDA7E78B56B89A497BC4D5A1D5C14D1A535777D4BBA17540B64F3E2695C5B134275A2F94D1388C0F666573454ED38B3E0CAA04BF5551662A429B54153795935493FE7E3C8130EE4568A278C2FF362D070FA4D10462B347E382EE340DF1EBBDBFEFAD66AB4B2296E982EC7F0947F6BF7845E8C40F9A7B4934727781E2D129C2E055227C3CD063BBFF14DE2958D6B4D3D3EF54ECA8757C3D102B98B6C97BE8087FE6B8ABC4B7D61AB491842E37A53890081C73359B4B878570BE3B30E557B819DBEC06F1291965419B7EAD74F1ADF900E771781024B44E5669DDA88FD9C62496764EA5CE3E791EB4CCDA3E4B665355C9EC92EF18046331332886B79DC3710C36F02D2EB260246AE83459514EF00FC5857CAC8562D4DD522FA4575ECD1BACA7313A1C91F72863DFC8AF0732C9025862525CF33E5EC545D356C620C70F16D2BDD22A9BD9A25469D21C70D437FA08ED36550A2EEEF3545EFDC5A0C0FCC1070A99B2D5EFC1A32D764AEE21DC38FD6086813C01F09298B41B3EFC7F34DB201EC538901C8E05A3B3295519042CF631226BBAF9A9F8A3C4BD6B00E24CD048A14ACA7C8B9EC1C1931853909EFF8B1FBCA46C9CB9E42BE7253E7F25A97C6D50E970EF8CEFE1C70C8A3254F5402F3DCC62A5A34B477A8B452352B6CB2BFC1F372130DBC4960DCD20088DB50B39998ECCB0CD2F797F7267529DB9A63B7BE8691F9B6155EFFAEEBDB8EE7FCA2EDD9DCC92B5DDCF536E87DA064010A15CA505885DEC6499E4B1408580A3F854E1C50BEA96D4B47D9022B004F426F1F69C7580573F60BA80045BA799FB486C1AB3E363D75DA7C2BE5E256001E728B4850BA99184068CFF7A87B25C95F43E17B35BEBFA4711A1307EA545B1BA97D13F752EB7CD6F42BA4776098D71C02E4961480D18AE898D2EBCD61E897041CB1A7057036F804F
+20210511180342 2 6 100 6143 5 EE2D1C3A0CC149C6675914AEFB8A3B27C939CB721B7D7D2AECDF4464406D6B59DF4C01ABE292F37396B097215BCF049F98D5B7CBA342EF5DFE31668084E83E783AC5C21CB152C08EE0BBAB4CC8F261AFD378F97D5044BC6BD3E555ADCF508ABC26E4CAF8D0B84EDDA7E78B56B89A497BC4D5A1D5C14D1A535777D4BBA17540B64F3E2695C5B134275A2F94D1388C0F666573454ED38B3E0CAA04BF5551662A429B54153795935493FE7E3C8130EE4568A278C2FF362D070FA4D10462B347E382EE340DF1EBBDBFEFAD66AB4B2296E982EC7F0947F6BF7845E8C40F9A7B4934727781E2D129C2E055227C3CD063BBFF14DE2958D6B4D3D3EF54ECA8757C3D102B98B6C97BE8087FE6B8ABC4B7D61AB491842E37A53890081C73359B4B878570BE3B30E557B819DBEC06F1291965419B7EAD74F1ADF900E771781024B44E5669DDA88FD9C62496764EA5CE3E791EB4CCDA3E4B665355C9EC92EF18046331332886B79DC3710C36F02D2EB260246AE83459514EF00FC5857CAC8562D4DD522FA4575ECD1BACA7313A1C91F72863DFC8AF0732C9025862525CF33E5EC545D356C620C70F16D2BDD22A9BD9A25469D21C70D437FA08ED36550A2EEEF3545EFDC5A0C0FCC1070A99B2D5EFC1A32D764AEE21DC38FD6086813C01F09298B41B3EFC7F34DB201EC538901C8E05A3B3295519042CF631226BBAF9A9F8A3C4BD6B00E24CD048A14ACA7C8B9EC1C1931853909EFF8B1FBCA46C9CB9E42BE7253E7F25A97C6D50E970EF8CEFE1C70C8A3254F5402F3DCC62A5A34B477A8B452352B6CB2BFC1F372130DBC4960DCD20088DB50B39998ECCB0CD2F797F7267529DB9A63B7BE8691F9B6155EFFAEEBDB8EE7FCA2EDD9DCC92B5DDCF536E87DA064010A15CA505885DEC6499E4B1408580A3F854E1C50BEA96D4B47D9022B004F426F1F69C7580573F60BA80045BA799FB486C1AB3E363D75DA7C2BE5E256001E728B4850BA99184068CFF7A87B25C95F43E17B35BEBFA4711A1307EA545B1BA97D13F752EB7CD6F42BA4776098D71C02E4961480D18AE898D2EBCD61E897041CB1A7057068862E7
+20210511183715 2 6 100 6143 5 EE2D1C3A0CC149C6675914AEFB8A3B27C939CB721B7D7D2AECDF4464406D6B59DF4C01ABE292F37396B097215BCF049F98D5B7CBA342EF5DFE31668084E83E783AC5C21CB152C08EE0BBAB4CC8F261AFD378F97D5044BC6BD3E555ADCF508ABC26E4CAF8D0B84EDDA7E78B56B89A497BC4D5A1D5C14D1A535777D4BBA17540B64F3E2695C5B134275A2F94D1388C0F666573454ED38B3E0CAA04BF5551662A429B54153795935493FE7E3C8130EE4568A278C2FF362D070FA4D10462B347E382EE340DF1EBBDBFEFAD66AB4B2296E982EC7F0947F6BF7845E8C40F9A7B4934727781E2D129C2E055227C3CD063BBFF14DE2958D6B4D3D3EF54ECA8757C3D102B98B6C97BE8087FE6B8ABC4B7D61AB491842E37A53890081C73359B4B878570BE3B30E557B819DBEC06F1291965419B7EAD74F1ADF900E771781024B44E5669DDA88FD9C62496764EA5CE3E791EB4CCDA3E4B665355C9EC92EF18046331332886B79DC3710C36F02D2EB260246AE83459514EF00FC5857CAC8562D4DD522FA4575ECD1BACA7313A1C91F72863DFC8AF0732C9025862525CF33E5EC545D356C620C70F16D2BDD22A9BD9A25469D21C70D437FA08ED36550A2EEEF3545EFDC5A0C0FCC1070A99B2D5EFC1A32D764AEE21DC38FD6086813C01F09298B41B3EFC7F34DB201EC538901C8E05A3B3295519042CF631226BBAF9A9F8A3C4BD6B00E24CD048A14ACA7C8B9EC1C1931853909EFF8B1FBCA46C9CB9E42BE7253E7F25A97C6D50E970EF8CEFE1C70C8A3254F5402F3DCC62A5A34B477A8B452352B6CB2BFC1F372130DBC4960DCD20088DB50B39998ECCB0CD2F797F7267529DB9A63B7BE8691F9B6155EFFAEEBDB8EE7FCA2EDD9DCC92B5DDCF536E87DA064010A15CA505885DEC6499E4B1408580A3F854E1C50BEA96D4B47D9022B004F426F1F69C7580573F60BA80045BA799FB486C1AB3E363D75DA7C2BE5E256001E728B4850BA99184068CFF7A87B25C95F43E17B35BEBFA4711A1307EA545B1BA97D13F752EB7CD6F42BA4776098D71C02E4961480D18AE898D2EBCD61E897041CB1A70570B38F77F
+20210511193129 2 6 100 6143 2 F58340194C3306C216EBA34FD995EAF9AF7B4471283E848F4B029734B8BCEBCD8E52D560FFF982CE43FF8B4743C8048BC6D4338C8B93AC9F00C5A9564A840146DE9539AD56551E9187BFC36282EE41C27355F3620B33561B868295222A693A11F5817C1A4306DAD1071FB2D38DE9462DBC4778784F4BD5B27F2FD173C360611E6A21FB82A494BEC22F4ABF1F5AA692B784E15FB737684C0ECC5B8D55FD023C52DE35464CA1AAA8F3F949F1BE6C194CB7C0DD0E5BA261A216CFC40D7DEA492929D777F6B8636A4C05D58652836E70E5956173BFD976CF08406210630C4489534639053F069285A6E55B851423BB3714647681FB05D545F941E69FE5756C500328991387212418E4C54146FBEF4A6D2481DE817DCAE3E1EEDE8E617357630B734FEFD566BB0338D8EE564F35518E59AF81F67AD190E45906A0832515515D6CCD73DE76FE730694CEED007F333DB1F6F9A026655F950751EF85AC1E571A3DA7203D1E53D4D93F521AE1AD75360DE1AD187EFE3A396F40AFED9C7797681A857003A7EA20C2203D2E40419253C6706FD30EAABC972CAA9C5C97B48DC734472D310E0DEE896862407E24A243EEE1E02309A6C7E1E53CD953B93FF54283ACE51B298BB1C92FF0A172948EF0CF8D239A5849D8E3D7AAC4486FB746501F3318145B042E62CA6EB70544E31581687DD67D8AD73FFB39DD71DA00E7F3738890D65610CAA049A5CD99AD928F98D3CFBD9A706E8908A2F51712B03562CB057F99431E0746B98DEE0D367DFC93CA546E26A44A72F47122FABCA47900D76A42B29C9160C46B40F811A1B8BA8651C7CEB1200DED520709D9CC0B21A20C9519084DA66A91158CE7A82674374580134EEA025BB0185807DF2A5B1EDEFEFA8D247A84B787E2597F8BF72ED6F570F32AACA50D10E94DB679FF68CE35AF77537EA4CB7928F7EDD5CABB65E32C0D88FACCFC51C2146BF3FDA433B76F09234552FC069312C38677AD95D501AF829B0A1484FEF9A2F804F0ECD4990079B66568956C34212CE0E483CF7C78D1E638893082826C15E7CA78004D04AC95EE36ED5200EBB74FA39E297FD7E2FF33
+20210511195502 2 6 100 6143 2 F58340194C3306C216EBA34FD995EAF9AF7B4471283E848F4B029734B8BCEBCD8E52D560FFF982CE43FF8B4743C8048BC6D4338C8B93AC9F00C5A9564A840146DE9539AD56551E9187BFC36282EE41C27355F3620B33561B868295222A693A11F5817C1A4306DAD1071FB2D38DE9462DBC4778784F4BD5B27F2FD173C360611E6A21FB82A494BEC22F4ABF1F5AA692B784E15FB737684C0ECC5B8D55FD023C52DE35464CA1AAA8F3F949F1BE6C194CB7C0DD0E5BA261A216CFC40D7DEA492929D777F6B8636A4C05D58652836E70E5956173BFD976CF08406210630C4489534639053F069285A6E55B851423BB3714647681FB05D545F941E69FE5756C500328991387212418E4C54146FBEF4A6D2481DE817DCAE3E1EEDE8E617357630B734FEFD566BB0338D8EE564F35518E59AF81F67AD190E45906A0832515515D6CCD73DE76FE730694CEED007F333DB1F6F9A026655F950751EF85AC1E571A3DA7203D1E53D4D93F521AE1AD75360DE1AD187EFE3A396F40AFED9C7797681A857003A7EA20C2203D2E40419253C6706FD30EAABC972CAA9C5C97B48DC734472D310E0DEE896862407E24A243EEE1E02309A6C7E1E53CD953B93FF54283ACE51B298BB1C92FF0A172948EF0CF8D239A5849D8E3D7AAC4486FB746501F3318145B042E62CA6EB70544E31581687DD67D8AD73FFB39DD71DA00E7F3738890D65610CAA049A5CD99AD928F98D3CFBD9A706E8908A2F51712B03562CB057F99431E0746B98DEE0D367DFC93CA546E26A44A72F47122FABCA47900D76A42B29C9160C46B40F811A1B8BA8651C7CEB1200DED520709D9CC0B21A20C9519084DA66A91158CE7A82674374580134EEA025BB0185807DF2A5B1EDEFEFA8D247A84B787E2597F8BF72ED6F570F32AACA50D10E94DB679FF68CE35AF77537EA4CB7928F7EDD5CABB65E32C0D88FACCFC51C2146BF3FDA433B76F09234552FC069312C38677AD95D501AF829B0A1484FEF9A2F804F0ECD4990079B66568956C34212CE0E483CF7C78D1E638893082826C15E7CA78004D04AC95EE36ED5200EBB74FA39E297FDB6A44F3
+20210511195827 2 6 100 6143 5 F58340194C3306C216EBA34FD995EAF9AF7B4471283E848F4B029734B8BCEBCD8E52D560FFF982CE43FF8B4743C8048BC6D4338C8B93AC9F00C5A9564A840146DE9539AD56551E9187BFC36282EE41C27355F3620B33561B868295222A693A11F5817C1A4306DAD1071FB2D38DE9462DBC4778784F4BD5B27F2FD173C360611E6A21FB82A494BEC22F4ABF1F5AA692B784E15FB737684C0ECC5B8D55FD023C52DE35464CA1AAA8F3F949F1BE6C194CB7C0DD0E5BA261A216CFC40D7DEA492929D777F6B8636A4C05D58652836E70E5956173BFD976CF08406210630C4489534639053F069285A6E55B851423BB3714647681FB05D545F941E69FE5756C500328991387212418E4C54146FBEF4A6D2481DE817DCAE3E1EEDE8E617357630B734FEFD566BB0338D8EE564F35518E59AF81F67AD190E45906A0832515515D6CCD73DE76FE730694CEED007F333DB1F6F9A026655F950751EF85AC1E571A3DA7203D1E53D4D93F521AE1AD75360DE1AD187EFE3A396F40AFED9C7797681A857003A7EA20C2203D2E40419253C6706FD30EAABC972CAA9C5C97B48DC734472D310E0DEE896862407E24A243EEE1E02309A6C7E1E53CD953B93FF54283ACE51B298BB1C92FF0A172948EF0CF8D239A5849D8E3D7AAC4486FB746501F3318145B042E62CA6EB70544E31581687DD67D8AD73FFB39DD71DA00E7F3738890D65610CAA049A5CD99AD928F98D3CFBD9A706E8908A2F51712B03562CB057F99431E0746B98DEE0D367DFC93CA546E26A44A72F47122FABCA47900D76A42B29C9160C46B40F811A1B8BA8651C7CEB1200DED520709D9CC0B21A20C9519084DA66A91158CE7A82674374580134EEA025BB0185807DF2A5B1EDEFEFA8D247A84B787E2597F8BF72ED6F570F32AACA50D10E94DB679FF68CE35AF77537EA4CB7928F7EDD5CABB65E32C0D88FACCFC51C2146BF3FDA433B76F09234552FC069312C38677AD95D501AF829B0A1484FEF9A2F804F0ECD4990079B66568956C34212CE0E483CF7C78D1E638893082826C15E7CA78004D04AC95EE36ED5200EBB74FA39E297FDBE676FF
+20210511204743 2 6 100 6143 2 F58340194C3306C216EBA34FD995EAF9AF7B4471283E848F4B029734B8BCEBCD8E52D560FFF982CE43FF8B4743C8048BC6D4338C8B93AC9F00C5A9564A840146DE9539AD56551E9187BFC36282EE41C27355F3620B33561B868295222A693A11F5817C1A4306DAD1071FB2D38DE9462DBC4778784F4BD5B27F2FD173C360611E6A21FB82A494BEC22F4ABF1F5AA692B784E15FB737684C0ECC5B8D55FD023C52DE35464CA1AAA8F3F949F1BE6C194CB7C0DD0E5BA261A216CFC40D7DEA492929D777F6B8636A4C05D58652836E70E5956173BFD976CF08406210630C4489534639053F069285A6E55B851423BB3714647681FB05D545F941E69FE5756C500328991387212418E4C54146FBEF4A6D2481DE817DCAE3E1EEDE8E617357630B734FEFD566BB0338D8EE564F35518E59AF81F67AD190E45906A0832515515D6CCD73DE76FE730694CEED007F333DB1F6F9A026655F950751EF85AC1E571A3DA7203D1E53D4D93F521AE1AD75360DE1AD187EFE3A396F40AFED9C7797681A857003A7EA20C2203D2E40419253C6706FD30EAABC972CAA9C5C97B48DC734472D310E0DEE896862407E24A243EEE1E02309A6C7E1E53CD953B93FF54283ACE51B298BB1C92FF0A172948EF0CF8D239A5849D8E3D7AAC4486FB746501F3318145B042E62CA6EB70544E31581687DD67D8AD73FFB39DD71DA00E7F3738890D65610CAA049A5CD99AD928F98D3CFBD9A706E8908A2F51712B03562CB057F99431E0746B98DEE0D367DFC93CA546E26A44A72F47122FABCA47900D76A42B29C9160C46B40F811A1B8BA8651C7CEB1200DED520709D9CC0B21A20C9519084DA66A91158CE7A82674374580134EEA025BB0185807DF2A5B1EDEFEFA8D247A84B787E2597F8BF72ED6F570F32AACA50D10E94DB679FF68CE35AF77537EA4CB7928F7EDD5CABB65E32C0D88FACCFC51C2146BF3FDA433B76F09234552FC069312C38677AD95D501AF829B0A1484FEF9A2F804F0ECD4990079B66568956C34212CE0E483CF7C78D1E638893082826C15E7CA78004D04AC95EE36ED5200EBB74FA39E297FE346C16B
+20210511205051 2 6 100 6143 5 F58340194C3306C216EBA34FD995EAF9AF7B4471283E848F4B029734B8BCEBCD8E52D560FFF982CE43FF8B4743C8048BC6D4338C8B93AC9F00C5A9564A840146DE9539AD56551E9187BFC36282EE41C27355F3620B33561B868295222A693A11F5817C1A4306DAD1071FB2D38DE9462DBC4778784F4BD5B27F2FD173C360611E6A21FB82A494BEC22F4ABF1F5AA692B784E15FB737684C0ECC5B8D55FD023C52DE35464CA1AAA8F3F949F1BE6C194CB7C0DD0E5BA261A216CFC40D7DEA492929D777F6B8636A4C05D58652836E70E5956173BFD976CF08406210630C4489534639053F069285A6E55B851423BB3714647681FB05D545F941E69FE5756C500328991387212418E4C54146FBEF4A6D2481DE817DCAE3E1EEDE8E617357630B734FEFD566BB0338D8EE564F35518E59AF81F67AD190E45906A0832515515D6CCD73DE76FE730694CEED007F333DB1F6F9A026655F950751EF85AC1E571A3DA7203D1E53D4D93F521AE1AD75360DE1AD187EFE3A396F40AFED9C7797681A857003A7EA20C2203D2E40419253C6706FD30EAABC972CAA9C5C97B48DC734472D310E0DEE896862407E24A243EEE1E02309A6C7E1E53CD953B93FF54283ACE51B298BB1C92FF0A172948EF0CF8D239A5849D8E3D7AAC4486FB746501F3318145B042E62CA6EB70544E31581687DD67D8AD73FFB39DD71DA00E7F3738890D65610CAA049A5CD99AD928F98D3CFBD9A706E8908A2F51712B03562CB057F99431E0746B98DEE0D367DFC93CA546E26A44A72F47122FABCA47900D76A42B29C9160C46B40F811A1B8BA8651C7CEB1200DED520709D9CC0B21A20C9519084DA66A91158CE7A82674374580134EEA025BB0185807DF2A5B1EDEFEFA8D247A84B787E2597F8BF72ED6F570F32AACA50D10E94DB679FF68CE35AF77537EA4CB7928F7EDD5CABB65E32C0D88FACCFC51C2146BF3FDA433B76F09234552FC069312C38677AD95D501AF829B0A1484FEF9A2F804F0ECD4990079B66568956C34212CE0E483CF7C78D1E638893082826C15E7CA78004D04AC95EE36ED5200EBB74FA39E297FE3B37BA7
+20210511210241 2 6 100 6143 5 F58340194C3306C216EBA34FD995EAF9AF7B4471283E848F4B029734B8BCEBCD8E52D560FFF982CE43FF8B4743C8048BC6D4338C8B93AC9F00C5A9564A840146DE9539AD56551E9187BFC36282EE41C27355F3620B33561B868295222A693A11F5817C1A4306DAD1071FB2D38DE9462DBC4778784F4BD5B27F2FD173C360611E6A21FB82A494BEC22F4ABF1F5AA692B784E15FB737684C0ECC5B8D55FD023C52DE35464CA1AAA8F3F949F1BE6C194CB7C0DD0E5BA261A216CFC40D7DEA492929D777F6B8636A4C05D58652836E70E5956173BFD976CF08406210630C4489534639053F069285A6E55B851423BB3714647681FB05D545F941E69FE5756C500328991387212418E4C54146FBEF4A6D2481DE817DCAE3E1EEDE8E617357630B734FEFD566BB0338D8EE564F35518E59AF81F67AD190E45906A0832515515D6CCD73DE76FE730694CEED007F333DB1F6F9A026655F950751EF85AC1E571A3DA7203D1E53D4D93F521AE1AD75360DE1AD187EFE3A396F40AFED9C7797681A857003A7EA20C2203D2E40419253C6706FD30EAABC972CAA9C5C97B48DC734472D310E0DEE896862407E24A243EEE1E02309A6C7E1E53CD953B93FF54283ACE51B298BB1C92FF0A172948EF0CF8D239A5849D8E3D7AAC4486FB746501F3318145B042E62CA6EB70544E31581687DD67D8AD73FFB39DD71DA00E7F3738890D65610CAA049A5CD99AD928F98D3CFBD9A706E8908A2F51712B03562CB057F99431E0746B98DEE0D367DFC93CA546E26A44A72F47122FABCA47900D76A42B29C9160C46B40F811A1B8BA8651C7CEB1200DED520709D9CC0B21A20C9519084DA66A91158CE7A82674374580134EEA025BB0185807DF2A5B1EDEFEFA8D247A84B787E2597F8BF72ED6F570F32AACA50D10E94DB679FF68CE35AF77537EA4CB7928F7EDD5CABB65E32C0D88FACCFC51C2146BF3FDA433B76F09234552FC069312C38677AD95D501AF829B0A1484FEF9A2F804F0ECD4990079B66568956C34212CE0E483CF7C78D1E638893082826C15E7CA78004D04AC95EE36ED5200EBB74FA39E297FE56FF4F7
+20210511211006 2 6 100 6143 2 F58340194C3306C216EBA34FD995EAF9AF7B4471283E848F4B029734B8BCEBCD8E52D560FFF982CE43FF8B4743C8048BC6D4338C8B93AC9F00C5A9564A840146DE9539AD56551E9187BFC36282EE41C27355F3620B33561B868295222A693A11F5817C1A4306DAD1071FB2D38DE9462DBC4778784F4BD5B27F2FD173C360611E6A21FB82A494BEC22F4ABF1F5AA692B784E15FB737684C0ECC5B8D55FD023C52DE35464CA1AAA8F3F949F1BE6C194CB7C0DD0E5BA261A216CFC40D7DEA492929D777F6B8636A4C05D58652836E70E5956173BFD976CF08406210630C4489534639053F069285A6E55B851423BB3714647681FB05D545F941E69FE5756C500328991387212418E4C54146FBEF4A6D2481DE817DCAE3E1EEDE8E617357630B734FEFD566BB0338D8EE564F35518E59AF81F67AD190E45906A0832515515D6CCD73DE76FE730694CEED007F333DB1F6F9A026655F950751EF85AC1E571A3DA7203D1E53D4D93F521AE1AD75360DE1AD187EFE3A396F40AFED9C7797681A857003A7EA20C2203D2E40419253C6706FD30EAABC972CAA9C5C97B48DC734472D310E0DEE896862407E24A243EEE1E02309A6C7E1E53CD953B93FF54283ACE51B298BB1C92FF0A172948EF0CF8D239A5849D8E3D7AAC4486FB746501F3318145B042E62CA6EB70544E31581687DD67D8AD73FFB39DD71DA00E7F3738890D65610CAA049A5CD99AD928F98D3CFBD9A706E8908A2F51712B03562CB057F99431E0746B98DEE0D367DFC93CA546E26A44A72F47122FABCA47900D76A42B29C9160C46B40F811A1B8BA8651C7CEB1200DED520709D9CC0B21A20C9519084DA66A91158CE7A82674374580134EEA025BB0185807DF2A5B1EDEFEFA8D247A84B787E2597F8BF72ED6F570F32AACA50D10E94DB679FF68CE35AF77537EA4CB7928F7EDD5CABB65E32C0D88FACCFC51C2146BF3FDA433B76F09234552FC069312C38677AD95D501AF829B0A1484FEF9A2F804F0ECD4990079B66568956C34212CE0E483CF7C78D1E638893082826C15E7CA78004D04AC95EE36ED5200EBB74FA39E297FE685FDFB
+20210511211804 2 6 100 6143 2 F58340194C3306C216EBA34FD995EAF9AF7B4471283E848F4B029734B8BCEBCD8E52D560FFF982CE43FF8B4743C8048BC6D4338C8B93AC9F00C5A9564A840146DE9539AD56551E9187BFC36282EE41C27355F3620B33561B868295222A693A11F5817C1A4306DAD1071FB2D38DE9462DBC4778784F4BD5B27F2FD173C360611E6A21FB82A494BEC22F4ABF1F5AA692B784E15FB737684C0ECC5B8D55FD023C52DE35464CA1AAA8F3F949F1BE6C194CB7C0DD0E5BA261A216CFC40D7DEA492929D777F6B8636A4C05D58652836E70E5956173BFD976CF08406210630C4489534639053F069285A6E55B851423BB3714647681FB05D545F941E69FE5756C500328991387212418E4C54146FBEF4A6D2481DE817DCAE3E1EEDE8E617357630B734FEFD566BB0338D8EE564F35518E59AF81F67AD190E45906A0832515515D6CCD73DE76FE730694CEED007F333DB1F6F9A026655F950751EF85AC1E571A3DA7203D1E53D4D93F521AE1AD75360DE1AD187EFE3A396F40AFED9C7797681A857003A7EA20C2203D2E40419253C6706FD30EAABC972CAA9C5C97B48DC734472D310E0DEE896862407E24A243EEE1E02309A6C7E1E53CD953B93FF54283ACE51B298BB1C92FF0A172948EF0CF8D239A5849D8E3D7AAC4486FB746501F3318145B042E62CA6EB70544E31581687DD67D8AD73FFB39DD71DA00E7F3738890D65610CAA049A5CD99AD928F98D3CFBD9A706E8908A2F51712B03562CB057F99431E0746B98DEE0D367DFC93CA546E26A44A72F47122FABCA47900D76A42B29C9160C46B40F811A1B8BA8651C7CEB1200DED520709D9CC0B21A20C9519084DA66A91158CE7A82674374580134EEA025BB0185807DF2A5B1EDEFEFA8D247A84B787E2597F8BF72ED6F570F32AACA50D10E94DB679FF68CE35AF77537EA4CB7928F7EDD5CABB65E32C0D88FACCFC51C2146BF3FDA433B76F09234552FC069312C38677AD95D501AF829B0A1484FEF9A2F804F0ECD4990079B66568956C34212CE0E483CF7C78D1E638893082826C15E7CA78004D04AC95EE36ED5200EBB74FA39E297FE7B482E3
+20210511213559 2 6 100 6143 2 F58340194C3306C216EBA34FD995EAF9AF7B4471283E848F4B029734B8BCEBCD8E52D560FFF982CE43FF8B4743C8048BC6D4338C8B93AC9F00C5A9564A840146DE9539AD56551E9187BFC36282EE41C27355F3620B33561B868295222A693A11F5817C1A4306DAD1071FB2D38DE9462DBC4778784F4BD5B27F2FD173C360611E6A21FB82A494BEC22F4ABF1F5AA692B784E15FB737684C0ECC5B8D55FD023C52DE35464CA1AAA8F3F949F1BE6C194CB7C0DD0E5BA261A216CFC40D7DEA492929D777F6B8636A4C05D58652836E70E5956173BFD976CF08406210630C4489534639053F069285A6E55B851423BB3714647681FB05D545F941E69FE5756C500328991387212418E4C54146FBEF4A6D2481DE817DCAE3E1EEDE8E617357630B734FEFD566BB0338D8EE564F35518E59AF81F67AD190E45906A0832515515D6CCD73DE76FE730694CEED007F333DB1F6F9A026655F950751EF85AC1E571A3DA7203D1E53D4D93F521AE1AD75360DE1AD187EFE3A396F40AFED9C7797681A857003A7EA20C2203D2E40419253C6706FD30EAABC972CAA9C5C97B48DC734472D310E0DEE896862407E24A243EEE1E02309A6C7E1E53CD953B93FF54283ACE51B298BB1C92FF0A172948EF0CF8D239A5849D8E3D7AAC4486FB746501F3318145B042E62CA6EB70544E31581687DD67D8AD73FFB39DD71DA00E7F3738890D65610CAA049A5CD99AD928F98D3CFBD9A706E8908A2F51712B03562CB057F99431E0746B98DEE0D367DFC93CA546E26A44A72F47122FABCA47900D76A42B29C9160C46B40F811A1B8BA8651C7CEB1200DED520709D9CC0B21A20C9519084DA66A91158CE7A82674374580134EEA025BB0185807DF2A5B1EDEFEFA8D247A84B787E2597F8BF72ED6F570F32AACA50D10E94DB679FF68CE35AF77537EA4CB7928F7EDD5CABB65E32C0D88FACCFC51C2146BF3FDA433B76F09234552FC069312C38677AD95D501AF829B0A1484FEF9A2F804F0ECD4990079B66568956C34212CE0E483CF7C78D1E638893082826C15E7CA78004D04AC95EE36ED5200EBB74FA39E297FEA624573
+20210511214955 2 6 100 6143 2 F58340194C3306C216EBA34FD995EAF9AF7B4471283E848F4B029734B8BCEBCD8E52D560FFF982CE43FF8B4743C8048BC6D4338C8B93AC9F00C5A9564A840146DE9539AD56551E9187BFC36282EE41C27355F3620B33561B868295222A693A11F5817C1A4306DAD1071FB2D38DE9462DBC4778784F4BD5B27F2FD173C360611E6A21FB82A494BEC22F4ABF1F5AA692B784E15FB737684C0ECC5B8D55FD023C52DE35464CA1AAA8F3F949F1BE6C194CB7C0DD0E5BA261A216CFC40D7DEA492929D777F6B8636A4C05D58652836E70E5956173BFD976CF08406210630C4489534639053F069285A6E55B851423BB3714647681FB05D545F941E69FE5756C500328991387212418E4C54146FBEF4A6D2481DE817DCAE3E1EEDE8E617357630B734FEFD566BB0338D8EE564F35518E59AF81F67AD190E45906A0832515515D6CCD73DE76FE730694CEED007F333DB1F6F9A026655F950751EF85AC1E571A3DA7203D1E53D4D93F521AE1AD75360DE1AD187EFE3A396F40AFED9C7797681A857003A7EA20C2203D2E40419253C6706FD30EAABC972CAA9C5C97B48DC734472D310E0DEE896862407E24A243EEE1E02309A6C7E1E53CD953B93FF54283ACE51B298BB1C92FF0A172948EF0CF8D239A5849D8E3D7AAC4486FB746501F3318145B042E62CA6EB70544E31581687DD67D8AD73FFB39DD71DA00E7F3738890D65610CAA049A5CD99AD928F98D3CFBD9A706E8908A2F51712B03562CB057F99431E0746B98DEE0D367DFC93CA546E26A44A72F47122FABCA47900D76A42B29C9160C46B40F811A1B8BA8651C7CEB1200DED520709D9CC0B21A20C9519084DA66A91158CE7A82674374580134EEA025BB0185807DF2A5B1EDEFEFA8D247A84B787E2597F8BF72ED6F570F32AACA50D10E94DB679FF68CE35AF77537EA4CB7928F7EDD5CABB65E32C0D88FACCFC51C2146BF3FDA433B76F09234552FC069312C38677AD95D501AF829B0A1484FEF9A2F804F0ECD4990079B66568956C34212CE0E483CF7C78D1E638893082826C15E7CA78004D04AC95EE36ED5200EBB74FA39E297FEC6A1563
+20210511220820 2 6 100 6143 2 F58340194C3306C216EBA34FD995EAF9AF7B4471283E848F4B029734B8BCEBCD8E52D560FFF982CE43FF8B4743C8048BC6D4338C8B93AC9F00C5A9564A840146DE9539AD56551E9187BFC36282EE41C27355F3620B33561B868295222A693A11F5817C1A4306DAD1071FB2D38DE9462DBC4778784F4BD5B27F2FD173C360611E6A21FB82A494BEC22F4ABF1F5AA692B784E15FB737684C0ECC5B8D55FD023C52DE35464CA1AAA8F3F949F1BE6C194CB7C0DD0E5BA261A216CFC40D7DEA492929D777F6B8636A4C05D58652836E70E5956173BFD976CF08406210630C4489534639053F069285A6E55B851423BB3714647681FB05D545F941E69FE5756C500328991387212418E4C54146FBEF4A6D2481DE817DCAE3E1EEDE8E617357630B734FEFD566BB0338D8EE564F35518E59AF81F67AD190E45906A0832515515D6CCD73DE76FE730694CEED007F333DB1F6F9A026655F950751EF85AC1E571A3DA7203D1E53D4D93F521AE1AD75360DE1AD187EFE3A396F40AFED9C7797681A857003A7EA20C2203D2E40419253C6706FD30EAABC972CAA9C5C97B48DC734472D310E0DEE896862407E24A243EEE1E02309A6C7E1E53CD953B93FF54283ACE51B298BB1C92FF0A172948EF0CF8D239A5849D8E3D7AAC4486FB746501F3318145B042E62CA6EB70544E31581687DD67D8AD73FFB39DD71DA00E7F3738890D65610CAA049A5CD99AD928F98D3CFBD9A706E8908A2F51712B03562CB057F99431E0746B98DEE0D367DFC93CA546E26A44A72F47122FABCA47900D76A42B29C9160C46B40F811A1B8BA8651C7CEB1200DED520709D9CC0B21A20C9519084DA66A91158CE7A82674374580134EEA025BB0185807DF2A5B1EDEFEFA8D247A84B787E2597F8BF72ED6F570F32AACA50D10E94DB679FF68CE35AF77537EA4CB7928F7EDD5CABB65E32C0D88FACCFC51C2146BF3FDA433B76F09234552FC069312C38677AD95D501AF829B0A1484FEF9A2F804F0ECD4990079B66568956C34212CE0E483CF7C78D1E638893082826C15E7CA78004D04AC95EE36ED5200EBB74FA39E297FEF28F693
+20210511221550 2 6 100 6143 5 F58340194C3306C216EBA34FD995EAF9AF7B4471283E848F4B029734B8BCEBCD8E52D560FFF982CE43FF8B4743C8048BC6D4338C8B93AC9F00C5A9564A840146DE9539AD56551E9187BFC36282EE41C27355F3620B33561B868295222A693A11F5817C1A4306DAD1071FB2D38DE9462DBC4778784F4BD5B27F2FD173C360611E6A21FB82A494BEC22F4ABF1F5AA692B784E15FB737684C0ECC5B8D55FD023C52DE35464CA1AAA8F3F949F1BE6C194CB7C0DD0E5BA261A216CFC40D7DEA492929D777F6B8636A4C05D58652836E70E5956173BFD976CF08406210630C4489534639053F069285A6E55B851423BB3714647681FB05D545F941E69FE5756C500328991387212418E4C54146FBEF4A6D2481DE817DCAE3E1EEDE8E617357630B734FEFD566BB0338D8EE564F35518E59AF81F67AD190E45906A0832515515D6CCD73DE76FE730694CEED007F333DB1F6F9A026655F950751EF85AC1E571A3DA7203D1E53D4D93F521AE1AD75360DE1AD187EFE3A396F40AFED9C7797681A857003A7EA20C2203D2E40419253C6706FD30EAABC972CAA9C5C97B48DC734472D310E0DEE896862407E24A243EEE1E02309A6C7E1E53CD953B93FF54283ACE51B298BB1C92FF0A172948EF0CF8D239A5849D8E3D7AAC4486FB746501F3318145B042E62CA6EB70544E31581687DD67D8AD73FFB39DD71DA00E7F3738890D65610CAA049A5CD99AD928F98D3CFBD9A706E8908A2F51712B03562CB057F99431E0746B98DEE0D367DFC93CA546E26A44A72F47122FABCA47900D76A42B29C9160C46B40F811A1B8BA8651C7CEB1200DED520709D9CC0B21A20C9519084DA66A91158CE7A82674374580134EEA025BB0185807DF2A5B1EDEFEFA8D247A84B787E2597F8BF72ED6F570F32AACA50D10E94DB679FF68CE35AF77537EA4CB7928F7EDD5CABB65E32C0D88FACCFC51C2146BF3FDA433B76F09234552FC069312C38677AD95D501AF829B0A1484FEF9A2F804F0ECD4990079B66568956C34212CE0E483CF7C78D1E638893082826C15E7CA78004D04AC95EE36ED5200EBB74FA39E297FF0410367
+20210511222301 2 6 100 6143 5 F58340194C3306C216EBA34FD995EAF9AF7B4471283E848F4B029734B8BCEBCD8E52D560FFF982CE43FF8B4743C8048BC6D4338C8B93AC9F00C5A9564A840146DE9539AD56551E9187BFC36282EE41C27355F3620B33561B868295222A693A11F5817C1A4306DAD1071FB2D38DE9462DBC4778784F4BD5B27F2FD173C360611E6A21FB82A494BEC22F4ABF1F5AA692B784E15FB737684C0ECC5B8D55FD023C52DE35464CA1AAA8F3F949F1BE6C194CB7C0DD0E5BA261A216CFC40D7DEA492929D777F6B8636A4C05D58652836E70E5956173BFD976CF08406210630C4489534639053F069285A6E55B851423BB3714647681FB05D545F941E69FE5756C500328991387212418E4C54146FBEF4A6D2481DE817DCAE3E1EEDE8E617357630B734FEFD566BB0338D8EE564F35518E59AF81F67AD190E45906A0832515515D6CCD73DE76FE730694CEED007F333DB1F6F9A026655F950751EF85AC1E571A3DA7203D1E53D4D93F521AE1AD75360DE1AD187EFE3A396F40AFED9C7797681A857003A7EA20C2203D2E40419253C6706FD30EAABC972CAA9C5C97B48DC734472D310E0DEE896862407E24A243EEE1E02309A6C7E1E53CD953B93FF54283ACE51B298BB1C92FF0A172948EF0CF8D239A5849D8E3D7AAC4486FB746501F3318145B042E62CA6EB70544E31581687DD67D8AD73FFB39DD71DA00E7F3738890D65610CAA049A5CD99AD928F98D3CFBD9A706E8908A2F51712B03562CB057F99431E0746B98DEE0D367DFC93CA546E26A44A72F47122FABCA47900D76A42B29C9160C46B40F811A1B8BA8651C7CEB1200DED520709D9CC0B21A20C9519084DA66A91158CE7A82674374580134EEA025BB0185807DF2A5B1EDEFEFA8D247A84B787E2597F8BF72ED6F570F32AACA50D10E94DB679FF68CE35AF77537EA4CB7928F7EDD5CABB65E32C0D88FACCFC51C2146BF3FDA433B76F09234552FC069312C38677AD95D501AF829B0A1484FEF9A2F804F0ECD4990079B66568956C34212CE0E483CF7C78D1E638893082826C15E7CA78004D04AC95EE36ED5200EBB74FA39E297FF14E2BAF
+20210511223017 2 6 100 6143 2 F58340194C3306C216EBA34FD995EAF9AF7B4471283E848F4B029734B8BCEBCD8E52D560FFF982CE43FF8B4743C8048BC6D4338C8B93AC9F00C5A9564A840146DE9539AD56551E9187BFC36282EE41C27355F3620B33561B868295222A693A11F5817C1A4306DAD1071FB2D38DE9462DBC4778784F4BD5B27F2FD173C360611E6A21FB82A494BEC22F4ABF1F5AA692B784E15FB737684C0ECC5B8D55FD023C52DE35464CA1AAA8F3F949F1BE6C194CB7C0DD0E5BA261A216CFC40D7DEA492929D777F6B8636A4C05D58652836E70E5956173BFD976CF08406210630C4489534639053F069285A6E55B851423BB3714647681FB05D545F941E69FE5756C500328991387212418E4C54146FBEF4A6D2481DE817DCAE3E1EEDE8E617357630B734FEFD566BB0338D8EE564F35518E59AF81F67AD190E45906A0832515515D6CCD73DE76FE730694CEED007F333DB1F6F9A026655F950751EF85AC1E571A3DA7203D1E53D4D93F521AE1AD75360DE1AD187EFE3A396F40AFED9C7797681A857003A7EA20C2203D2E40419253C6706FD30EAABC972CAA9C5C97B48DC734472D310E0DEE896862407E24A243EEE1E02309A6C7E1E53CD953B93FF54283ACE51B298BB1C92FF0A172948EF0CF8D239A5849D8E3D7AAC4486FB746501F3318145B042E62CA6EB70544E31581687DD67D8AD73FFB39DD71DA00E7F3738890D65610CAA049A5CD99AD928F98D3CFBD9A706E8908A2F51712B03562CB057F99431E0746B98DEE0D367DFC93CA546E26A44A72F47122FABCA47900D76A42B29C9160C46B40F811A1B8BA8651C7CEB1200DED520709D9CC0B21A20C9519084DA66A91158CE7A82674374580134EEA025BB0185807DF2A5B1EDEFEFA8D247A84B787E2597F8BF72ED6F570F32AACA50D10E94DB679FF68CE35AF77537EA4CB7928F7EDD5CABB65E32C0D88FACCFC51C2146BF3FDA433B76F09234552FC069312C38677AD95D501AF829B0A1484FEF9A2F804F0ECD4990079B66568956C34212CE0E483CF7C78D1E638893082826C15E7CA78004D04AC95EE36ED5200EBB74FA39E297FF25C4F8B
+20210511223717 2 6 100 6143 5 F58340194C3306C216EBA34FD995EAF9AF7B4471283E848F4B029734B8BCEBCD8E52D560FFF982CE43FF8B4743C8048BC6D4338C8B93AC9F00C5A9564A840146DE9539AD56551E9187BFC36282EE41C27355F3620B33561B868295222A693A11F5817C1A4306DAD1071FB2D38DE9462DBC4778784F4BD5B27F2FD173C360611E6A21FB82A494BEC22F4ABF1F5AA692B784E15FB737684C0ECC5B8D55FD023C52DE35464CA1AAA8F3F949F1BE6C194CB7C0DD0E5BA261A216CFC40D7DEA492929D777F6B8636A4C05D58652836E70E5956173BFD976CF08406210630C4489534639053F069285A6E55B851423BB3714647681FB05D545F941E69FE5756C500328991387212418E4C54146FBEF4A6D2481DE817DCAE3E1EEDE8E617357630B734FEFD566BB0338D8EE564F35518E59AF81F67AD190E45906A0832515515D6CCD73DE76FE730694CEED007F333DB1F6F9A026655F950751EF85AC1E571A3DA7203D1E53D4D93F521AE1AD75360DE1AD187EFE3A396F40AFED9C7797681A857003A7EA20C2203D2E40419253C6706FD30EAABC972CAA9C5C97B48DC734472D310E0DEE896862407E24A243EEE1E02309A6C7E1E53CD953B93FF54283ACE51B298BB1C92FF0A172948EF0CF8D239A5849D8E3D7AAC4486FB746501F3318145B042E62CA6EB70544E31581687DD67D8AD73FFB39DD71DA00E7F3738890D65610CAA049A5CD99AD928F98D3CFBD9A706E8908A2F51712B03562CB057F99431E0746B98DEE0D367DFC93CA546E26A44A72F47122FABCA47900D76A42B29C9160C46B40F811A1B8BA8651C7CEB1200DED520709D9CC0B21A20C9519084DA66A91158CE7A82674374580134EEA025BB0185807DF2A5B1EDEFEFA8D247A84B787E2597F8BF72ED6F570F32AACA50D10E94DB679FF68CE35AF77537EA4CB7928F7EDD5CABB65E32C0D88FACCFC51C2146BF3FDA433B76F09234552FC069312C38677AD95D501AF829B0A1484FEF9A2F804F0ECD4990079B66568956C34212CE0E483CF7C78D1E638893082826C15E7CA78004D04AC95EE36ED5200EBB74FA39E297FF358C9EF
+20210511224022 2 6 100 6143 5 F58340194C3306C216EBA34FD995EAF9AF7B4471283E848F4B029734B8BCEBCD8E52D560FFF982CE43FF8B4743C8048BC6D4338C8B93AC9F00C5A9564A840146DE9539AD56551E9187BFC36282EE41C27355F3620B33561B868295222A693A11F5817C1A4306DAD1071FB2D38DE9462DBC4778784F4BD5B27F2FD173C360611E6A21FB82A494BEC22F4ABF1F5AA692B784E15FB737684C0ECC5B8D55FD023C52DE35464CA1AAA8F3F949F1BE6C194CB7C0DD0E5BA261A216CFC40D7DEA492929D777F6B8636A4C05D58652836E70E5956173BFD976CF08406210630C4489534639053F069285A6E55B851423BB3714647681FB05D545F941E69FE5756C500328991387212418E4C54146FBEF4A6D2481DE817DCAE3E1EEDE8E617357630B734FEFD566BB0338D8EE564F35518E59AF81F67AD190E45906A0832515515D6CCD73DE76FE730694CEED007F333DB1F6F9A026655F950751EF85AC1E571A3DA7203D1E53D4D93F521AE1AD75360DE1AD187EFE3A396F40AFED9C7797681A857003A7EA20C2203D2E40419253C6706FD30EAABC972CAA9C5C97B48DC734472D310E0DEE896862407E24A243EEE1E02309A6C7E1E53CD953B93FF54283ACE51B298BB1C92FF0A172948EF0CF8D239A5849D8E3D7AAC4486FB746501F3318145B042E62CA6EB70544E31581687DD67D8AD73FFB39DD71DA00E7F3738890D65610CAA049A5CD99AD928F98D3CFBD9A706E8908A2F51712B03562CB057F99431E0746B98DEE0D367DFC93CA546E26A44A72F47122FABCA47900D76A42B29C9160C46B40F811A1B8BA8651C7CEB1200DED520709D9CC0B21A20C9519084DA66A91158CE7A82674374580134EEA025BB0185807DF2A5B1EDEFEFA8D247A84B787E2597F8BF72ED6F570F32AACA50D10E94DB679FF68CE35AF77537EA4CB7928F7EDD5CABB65E32C0D88FACCFC51C2146BF3FDA433B76F09234552FC069312C38677AD95D501AF829B0A1484FEF9A2F804F0ECD4990079B66568956C34212CE0E483CF7C78D1E638893082826C15E7CA78004D04AC95EE36ED5200EBB74FA39E297FF3C5C0C7
+20210511224934 2 6 100 6143 5 F58340194C3306C216EBA34FD995EAF9AF7B4471283E848F4B029734B8BCEBCD8E52D560FFF982CE43FF8B4743C8048BC6D4338C8B93AC9F00C5A9564A840146DE9539AD56551E9187BFC36282EE41C27355F3620B33561B868295222A693A11F5817C1A4306DAD1071FB2D38DE9462DBC4778784F4BD5B27F2FD173C360611E6A21FB82A494BEC22F4ABF1F5AA692B784E15FB737684C0ECC5B8D55FD023C52DE35464CA1AAA8F3F949F1BE6C194CB7C0DD0E5BA261A216CFC40D7DEA492929D777F6B8636A4C05D58652836E70E5956173BFD976CF08406210630C4489534639053F069285A6E55B851423BB3714647681FB05D545F941E69FE5756C500328991387212418E4C54146FBEF4A6D2481DE817DCAE3E1EEDE8E617357630B734FEFD566BB0338D8EE564F35518E59AF81F67AD190E45906A0832515515D6CCD73DE76FE730694CEED007F333DB1F6F9A026655F950751EF85AC1E571A3DA7203D1E53D4D93F521AE1AD75360DE1AD187EFE3A396F40AFED9C7797681A857003A7EA20C2203D2E40419253C6706FD30EAABC972CAA9C5C97B48DC734472D310E0DEE896862407E24A243EEE1E02309A6C7E1E53CD953B93FF54283ACE51B298BB1C92FF0A172948EF0CF8D239A5849D8E3D7AAC4486FB746501F3318145B042E62CA6EB70544E31581687DD67D8AD73FFB39DD71DA00E7F3738890D65610CAA049A5CD99AD928F98D3CFBD9A706E8908A2F51712B03562CB057F99431E0746B98DEE0D367DFC93CA546E26A44A72F47122FABCA47900D76A42B29C9160C46B40F811A1B8BA8651C7CEB1200DED520709D9CC0B21A20C9519084DA66A91158CE7A82674374580134EEA025BB0185807DF2A5B1EDEFEFA8D247A84B787E2597F8BF72ED6F570F32AACA50D10E94DB679FF68CE35AF77537EA4CB7928F7EDD5CABB65E32C0D88FACCFC51C2146BF3FDA433B76F09234552FC069312C38677AD95D501AF829B0A1484FEF9A2F804F0ECD4990079B66568956C34212CE0E483CF7C78D1E638893082826C15E7CA78004D04AC95EE36ED5200EBB74FA39E297FF5128EE7
+20210511225354 2 6 100 6143 2 F58340194C3306C216EBA34FD995EAF9AF7B4471283E848F4B029734B8BCEBCD8E52D560FFF982CE43FF8B4743C8048BC6D4338C8B93AC9F00C5A9564A840146DE9539AD56551E9187BFC36282EE41C27355F3620B33561B868295222A693A11F5817C1A4306DAD1071FB2D38DE9462DBC4778784F4BD5B27F2FD173C360611E6A21FB82A494BEC22F4ABF1F5AA692B784E15FB737684C0ECC5B8D55FD023C52DE35464CA1AAA8F3F949F1BE6C194CB7C0DD0E5BA261A216CFC40D7DEA492929D777F6B8636A4C05D58652836E70E5956173BFD976CF08406210630C4489534639053F069285A6E55B851423BB3714647681FB05D545F941E69FE5756C500328991387212418E4C54146FBEF4A6D2481DE817DCAE3E1EEDE8E617357630B734FEFD566BB0338D8EE564F35518E59AF81F67AD190E45906A0832515515D6CCD73DE76FE730694CEED007F333DB1F6F9A026655F950751EF85AC1E571A3DA7203D1E53D4D93F521AE1AD75360DE1AD187EFE3A396F40AFED9C7797681A857003A7EA20C2203D2E40419253C6706FD30EAABC972CAA9C5C97B48DC734472D310E0DEE896862407E24A243EEE1E02309A6C7E1E53CD953B93FF54283ACE51B298BB1C92FF0A172948EF0CF8D239A5849D8E3D7AAC4486FB746501F3318145B042E62CA6EB70544E31581687DD67D8AD73FFB39DD71DA00E7F3738890D65610CAA049A5CD99AD928F98D3CFBD9A706E8908A2F51712B03562CB057F99431E0746B98DEE0D367DFC93CA546E26A44A72F47122FABCA47900D76A42B29C9160C46B40F811A1B8BA8651C7CEB1200DED520709D9CC0B21A20C9519084DA66A91158CE7A82674374580134EEA025BB0185807DF2A5B1EDEFEFA8D247A84B787E2597F8BF72ED6F570F32AACA50D10E94DB679FF68CE35AF77537EA4CB7928F7EDD5CABB65E32C0D88FACCFC51C2146BF3FDA433B76F09234552FC069312C38677AD95D501AF829B0A1484FEF9A2F804F0ECD4990079B66568956C34212CE0E483CF7C78D1E638893082826C15E7CA78004D04AC95EE36ED5200EBB74FA39E297FF5AC9E43
+20210511225504 2 6 100 6143 5 F58340194C3306C216EBA34FD995EAF9AF7B4471283E848F4B029734B8BCEBCD8E52D560FFF982CE43FF8B4743C8048BC6D4338C8B93AC9F00C5A9564A840146DE9539AD56551E9187BFC36282EE41C27355F3620B33561B868295222A693A11F5817C1A4306DAD1071FB2D38DE9462DBC4778784F4BD5B27F2FD173C360611E6A21FB82A494BEC22F4ABF1F5AA692B784E15FB737684C0ECC5B8D55FD023C52DE35464CA1AAA8F3F949F1BE6C194CB7C0DD0E5BA261A216CFC40D7DEA492929D777F6B8636A4C05D58652836E70E5956173BFD976CF08406210630C4489534639053F069285A6E55B851423BB3714647681FB05D545F941E69FE5756C500328991387212418E4C54146FBEF4A6D2481DE817DCAE3E1EEDE8E617357630B734FEFD566BB0338D8EE564F35518E59AF81F67AD190E45906A0832515515D6CCD73DE76FE730694CEED007F333DB1F6F9A026655F950751EF85AC1E571A3DA7203D1E53D4D93F521AE1AD75360DE1AD187EFE3A396F40AFED9C7797681A857003A7EA20C2203D2E40419253C6706FD30EAABC972CAA9C5C97B48DC734472D310E0DEE896862407E24A243EEE1E02309A6C7E1E53CD953B93FF54283ACE51B298BB1C92FF0A172948EF0CF8D239A5849D8E3D7AAC4486FB746501F3318145B042E62CA6EB70544E31581687DD67D8AD73FFB39DD71DA00E7F3738890D65610CAA049A5CD99AD928F98D3CFBD9A706E8908A2F51712B03562CB057F99431E0746B98DEE0D367DFC93CA546E26A44A72F47122FABCA47900D76A42B29C9160C46B40F811A1B8BA8651C7CEB1200DED520709D9CC0B21A20C9519084DA66A91158CE7A82674374580134EEA025BB0185807DF2A5B1EDEFEFA8D247A84B787E2597F8BF72ED6F570F32AACA50D10E94DB679FF68CE35AF77537EA4CB7928F7EDD5CABB65E32C0D88FACCFC51C2146BF3FDA433B76F09234552FC069312C38677AD95D501AF829B0A1484FEF9A2F804F0ECD4990079B66568956C34212CE0E483CF7C78D1E638893082826C15E7CA78004D04AC95EE36ED5200EBB74FA39E297FF5CE8FCF
+20210511230424 2 6 100 6143 2 F58340194C3306C216EBA34FD995EAF9AF7B4471283E848F4B029734B8BCEBCD8E52D560FFF982CE43FF8B4743C8048BC6D4338C8B93AC9F00C5A9564A840146DE9539AD56551E9187BFC36282EE41C27355F3620B33561B868295222A693A11F5817C1A4306DAD1071FB2D38DE9462DBC4778784F4BD5B27F2FD173C360611E6A21FB82A494BEC22F4ABF1F5AA692B784E15FB737684C0ECC5B8D55FD023C52DE35464CA1AAA8F3F949F1BE6C194CB7C0DD0E5BA261A216CFC40D7DEA492929D777F6B8636A4C05D58652836E70E5956173BFD976CF08406210630C4489534639053F069285A6E55B851423BB3714647681FB05D545F941E69FE5756C500328991387212418E4C54146FBEF4A6D2481DE817DCAE3E1EEDE8E617357630B734FEFD566BB0338D8EE564F35518E59AF81F67AD190E45906A0832515515D6CCD73DE76FE730694CEED007F333DB1F6F9A026655F950751EF85AC1E571A3DA7203D1E53D4D93F521AE1AD75360DE1AD187EFE3A396F40AFED9C7797681A857003A7EA20C2203D2E40419253C6706FD30EAABC972CAA9C5C97B48DC734472D310E0DEE896862407E24A243EEE1E02309A6C7E1E53CD953B93FF54283ACE51B298BB1C92FF0A172948EF0CF8D239A5849D8E3D7AAC4486FB746501F3318145B042E62CA6EB70544E31581687DD67D8AD73FFB39DD71DA00E7F3738890D65610CAA049A5CD99AD928F98D3CFBD9A706E8908A2F51712B03562CB057F99431E0746B98DEE0D367DFC93CA546E26A44A72F47122FABCA47900D76A42B29C9160C46B40F811A1B8BA8651C7CEB1200DED520709D9CC0B21A20C9519084DA66A91158CE7A82674374580134EEA025BB0185807DF2A5B1EDEFEFA8D247A84B787E2597F8BF72ED6F570F32AACA50D10E94DB679FF68CE35AF77537EA4CB7928F7EDD5CABB65E32C0D88FACCFC51C2146BF3FDA433B76F09234552FC069312C38677AD95D501AF829B0A1484FEF9A2F804F0ECD4990079B66568956C34212CE0E483CF7C78D1E638893082826C15E7CA78004D04AC95EE36ED5200EBB74FA39E297FF71E9D43
+20210511233003 2 6 100 6143 5 F58340194C3306C216EBA34FD995EAF9AF7B4471283E848F4B029734B8BCEBCD8E52D560FFF982CE43FF8B4743C8048BC6D4338C8B93AC9F00C5A9564A840146DE9539AD56551E9187BFC36282EE41C27355F3620B33561B868295222A693A11F5817C1A4306DAD1071FB2D38DE9462DBC4778784F4BD5B27F2FD173C360611E6A21FB82A494BEC22F4ABF1F5AA692B784E15FB737684C0ECC5B8D55FD023C52DE35464CA1AAA8F3F949F1BE6C194CB7C0DD0E5BA261A216CFC40D7DEA492929D777F6B8636A4C05D58652836E70E5956173BFD976CF08406210630C4489534639053F069285A6E55B851423BB3714647681FB05D545F941E69FE5756C500328991387212418E4C54146FBEF4A6D2481DE817DCAE3E1EEDE8E617357630B734FEFD566BB0338D8EE564F35518E59AF81F67AD190E45906A0832515515D6CCD73DE76FE730694CEED007F333DB1F6F9A026655F950751EF85AC1E571A3DA7203D1E53D4D93F521AE1AD75360DE1AD187EFE3A396F40AFED9C7797681A857003A7EA20C2203D2E40419253C6706FD30EAABC972CAA9C5C97B48DC734472D310E0DEE896862407E24A243EEE1E02309A6C7E1E53CD953B93FF54283ACE51B298BB1C92FF0A172948EF0CF8D239A5849D8E3D7AAC4486FB746501F3318145B042E62CA6EB70544E31581687DD67D8AD73FFB39DD71DA00E7F3738890D65610CAA049A5CD99AD928F98D3CFBD9A706E8908A2F51712B03562CB057F99431E0746B98DEE0D367DFC93CA546E26A44A72F47122FABCA47900D76A42B29C9160C46B40F811A1B8BA8651C7CEB1200DED520709D9CC0B21A20C9519084DA66A91158CE7A82674374580134EEA025BB0185807DF2A5B1EDEFEFA8D247A84B787E2597F8BF72ED6F570F32AACA50D10E94DB679FF68CE35AF77537EA4CB7928F7EDD5CABB65E32C0D88FACCFC51C2146BF3FDA433B76F09234552FC069312C38677AD95D501AF829B0A1484FEF9A2F804F0ECD4990079B66568956C34212CE0E483CF7C78D1E638893082826C15E7CA78004D04AC95EE36ED5200EBB74FA39E297FFAD91657
+20210511233554 2 6 100 6143 2 F58340194C3306C216EBA34FD995EAF9AF7B4471283E848F4B029734B8BCEBCD8E52D560FFF982CE43FF8B4743C8048BC6D4338C8B93AC9F00C5A9564A840146DE9539AD56551E9187BFC36282EE41C27355F3620B33561B868295222A693A11F5817C1A4306DAD1071FB2D38DE9462DBC4778784F4BD5B27F2FD173C360611E6A21FB82A494BEC22F4ABF1F5AA692B784E15FB737684C0ECC5B8D55FD023C52DE35464CA1AAA8F3F949F1BE6C194CB7C0DD0E5BA261A216CFC40D7DEA492929D777F6B8636A4C05D58652836E70E5956173BFD976CF08406210630C4489534639053F069285A6E55B851423BB3714647681FB05D545F941E69FE5756C500328991387212418E4C54146FBEF4A6D2481DE817DCAE3E1EEDE8E617357630B734FEFD566BB0338D8EE564F35518E59AF81F67AD190E45906A0832515515D6CCD73DE76FE730694CEED007F333DB1F6F9A026655F950751EF85AC1E571A3DA7203D1E53D4D93F521AE1AD75360DE1AD187EFE3A396F40AFED9C7797681A857003A7EA20C2203D2E40419253C6706FD30EAABC972CAA9C5C97B48DC734472D310E0DEE896862407E24A243EEE1E02309A6C7E1E53CD953B93FF54283ACE51B298BB1C92FF0A172948EF0CF8D239A5849D8E3D7AAC4486FB746501F3318145B042E62CA6EB70544E31581687DD67D8AD73FFB39DD71DA00E7F3738890D65610CAA049A5CD99AD928F98D3CFBD9A706E8908A2F51712B03562CB057F99431E0746B98DEE0D367DFC93CA546E26A44A72F47122FABCA47900D76A42B29C9160C46B40F811A1B8BA8651C7CEB1200DED520709D9CC0B21A20C9519084DA66A91158CE7A82674374580134EEA025BB0185807DF2A5B1EDEFEFA8D247A84B787E2597F8BF72ED6F570F32AACA50D10E94DB679FF68CE35AF77537EA4CB7928F7EDD5CABB65E32C0D88FACCFC51C2146BF3FDA433B76F09234552FC069312C38677AD95D501AF829B0A1484FEF9A2F804F0ECD4990079B66568956C34212CE0E483CF7C78D1E638893082826C15E7CA78004D04AC95EE36ED5200EBB74FA39E297FFBAD309B
+20210511233732 2 6 100 6143 2 F58340194C3306C216EBA34FD995EAF9AF7B4471283E848F4B029734B8BCEBCD8E52D560FFF982CE43FF8B4743C8048BC6D4338C8B93AC9F00C5A9564A840146DE9539AD56551E9187BFC36282EE41C27355F3620B33561B868295222A693A11F5817C1A4306DAD1071FB2D38DE9462DBC4778784F4BD5B27F2FD173C360611E6A21FB82A494BEC22F4ABF1F5AA692B784E15FB737684C0ECC5B8D55FD023C52DE35464CA1AAA8F3F949F1BE6C194CB7C0DD0E5BA261A216CFC40D7DEA492929D777F6B8636A4C05D58652836E70E5956173BFD976CF08406210630C4489534639053F069285A6E55B851423BB3714647681FB05D545F941E69FE5756C500328991387212418E4C54146FBEF4A6D2481DE817DCAE3E1EEDE8E617357630B734FEFD566BB0338D8EE564F35518E59AF81F67AD190E45906A0832515515D6CCD73DE76FE730694CEED007F333DB1F6F9A026655F950751EF85AC1E571A3DA7203D1E53D4D93F521AE1AD75360DE1AD187EFE3A396F40AFED9C7797681A857003A7EA20C2203D2E40419253C6706FD30EAABC972CAA9C5C97B48DC734472D310E0DEE896862407E24A243EEE1E02309A6C7E1E53CD953B93FF54283ACE51B298BB1C92FF0A172948EF0CF8D239A5849D8E3D7AAC4486FB746501F3318145B042E62CA6EB70544E31581687DD67D8AD73FFB39DD71DA00E7F3738890D65610CAA049A5CD99AD928F98D3CFBD9A706E8908A2F51712B03562CB057F99431E0746B98DEE0D367DFC93CA546E26A44A72F47122FABCA47900D76A42B29C9160C46B40F811A1B8BA8651C7CEB1200DED520709D9CC0B21A20C9519084DA66A91158CE7A82674374580134EEA025BB0185807DF2A5B1EDEFEFA8D247A84B787E2597F8BF72ED6F570F32AACA50D10E94DB679FF68CE35AF77537EA4CB7928F7EDD5CABB65E32C0D88FACCFC51C2146BF3FDA433B76F09234552FC069312C38677AD95D501AF829B0A1484FEF9A2F804F0ECD4990079B66568956C34212CE0E483CF7C78D1E638893082826C15E7CA78004D04AC95EE36ED5200EBB74FA39E297FFBE1CC5B
+20210511235930 2 6 100 6143 2 F58340194C3306C216EBA34FD995EAF9AF7B4471283E848F4B029734B8BCEBCD8E52D560FFF982CE43FF8B4743C8048BC6D4338C8B93AC9F00C5A9564A840146DE9539AD56551E9187BFC36282EE41C27355F3620B33561B868295222A693A11F5817C1A4306DAD1071FB2D38DE9462DBC4778784F4BD5B27F2FD173C360611E6A21FB82A494BEC22F4ABF1F5AA692B784E15FB737684C0ECC5B8D55FD023C52DE35464CA1AAA8F3F949F1BE6C194CB7C0DD0E5BA261A216CFC40D7DEA492929D777F6B8636A4C05D58652836E70E5956173BFD976CF08406210630C4489534639053F069285A6E55B851423BB3714647681FB05D545F941E69FE5756C500328991387212418E4C54146FBEF4A6D2481DE817DCAE3E1EEDE8E617357630B734FEFD566BB0338D8EE564F35518E59AF81F67AD190E45906A0832515515D6CCD73DE76FE730694CEED007F333DB1F6F9A026655F950751EF85AC1E571A3DA7203D1E53D4D93F521AE1AD75360DE1AD187EFE3A396F40AFED9C7797681A857003A7EA20C2203D2E40419253C6706FD30EAABC972CAA9C5C97B48DC734472D310E0DEE896862407E24A243EEE1E02309A6C7E1E53CD953B93FF54283ACE51B298BB1C92FF0A172948EF0CF8D239A5849D8E3D7AAC4486FB746501F3318145B042E62CA6EB70544E31581687DD67D8AD73FFB39DD71DA00E7F3738890D65610CAA049A5CD99AD928F98D3CFBD9A706E8908A2F51712B03562CB057F99431E0746B98DEE0D367DFC93CA546E26A44A72F47122FABCA47900D76A42B29C9160C46B40F811A1B8BA8651C7CEB1200DED520709D9CC0B21A20C9519084DA66A91158CE7A82674374580134EEA025BB0185807DF2A5B1EDEFEFA8D247A84B787E2597F8BF72ED6F570F32AACA50D10E94DB679FF68CE35AF77537EA4CB7928F7EDD5CABB65E32C0D88FACCFC51C2146BF3FDA433B76F09234552FC069312C38677AD95D501AF829B0A1484FEF9A2F804F0ECD4990079B66568956C34212CE0E483CF7C78D1E638893082826C15E7CA78004D04AC95EE36ED5200EBB74FA39E297FFF12F2D3
+20210512001430 2 6 100 6143 2 F58340194C3306C216EBA34FD995EAF9AF7B4471283E848F4B029734B8BCEBCD8E52D560FFF982CE43FF8B4743C8048BC6D4338C8B93AC9F00C5A9564A840146DE9539AD56551E9187BFC36282EE41C27355F3620B33561B868295222A693A11F5817C1A4306DAD1071FB2D38DE9462DBC4778784F4BD5B27F2FD173C360611E6A21FB82A494BEC22F4ABF1F5AA692B784E15FB737684C0ECC5B8D55FD023C52DE35464CA1AAA8F3F949F1BE6C194CB7C0DD0E5BA261A216CFC40D7DEA492929D777F6B8636A4C05D58652836E70E5956173BFD976CF08406210630C4489534639053F069285A6E55B851423BB3714647681FB05D545F941E69FE5756C500328991387212418E4C54146FBEF4A6D2481DE817DCAE3E1EEDE8E617357630B734FEFD566BB0338D8EE564F35518E59AF81F67AD190E45906A0832515515D6CCD73DE76FE730694CEED007F333DB1F6F9A026655F950751EF85AC1E571A3DA7203D1E53D4D93F521AE1AD75360DE1AD187EFE3A396F40AFED9C7797681A857003A7EA20C2203D2E40419253C6706FD30EAABC972CAA9C5C97B48DC734472D310E0DEE896862407E24A243EEE1E02309A6C7E1E53CD953B93FF54283ACE51B298BB1C92FF0A172948EF0CF8D239A5849D8E3D7AAC4486FB746501F3318145B042E62CA6EB70544E31581687DD67D8AD73FFB39DD71DA00E7F3738890D65610CAA049A5CD99AD928F98D3CFBD9A706E8908A2F51712B03562CB057F99431E0746B98DEE0D367DFC93CA546E26A44A72F47122FABCA47900D76A42B29C9160C46B40F811A1B8BA8651C7CEB1200DED520709D9CC0B21A20C9519084DA66A91158CE7A82674374580134EEA025BB0185807DF2A5B1EDEFEFA8D247A84B787E2597F8BF72ED6F570F32AACA50D10E94DB679FF68CE35AF77537EA4CB7928F7EDD5CABB65E32C0D88FACCFC51C2146BF3FDA433B76F09234552FC069312C38677AD95D501AF829B0A1484FEF9A2F804F0ECD4990079B66568956C34212CE0E483CF7C78D1E638893082826C15E7CA78004D04AC95EE36ED5200EBB74FA39E298001373093
+20210512002303 2 6 100 6143 2 F58340194C3306C216EBA34FD995EAF9AF7B4471283E848F4B029734B8BCEBCD8E52D560FFF982CE43FF8B4743C8048BC6D4338C8B93AC9F00C5A9564A840146DE9539AD56551E9187BFC36282EE41C27355F3620B33561B868295222A693A11F5817C1A4306DAD1071FB2D38DE9462DBC4778784F4BD5B27F2FD173C360611E6A21FB82A494BEC22F4ABF1F5AA692B784E15FB737684C0ECC5B8D55FD023C52DE35464CA1AAA8F3F949F1BE6C194CB7C0DD0E5BA261A216CFC40D7DEA492929D777F6B8636A4C05D58652836E70E5956173BFD976CF08406210630C4489534639053F069285A6E55B851423BB3714647681FB05D545F941E69FE5756C500328991387212418E4C54146FBEF4A6D2481DE817DCAE3E1EEDE8E617357630B734FEFD566BB0338D8EE564F35518E59AF81F67AD190E45906A0832515515D6CCD73DE76FE730694CEED007F333DB1F6F9A026655F950751EF85AC1E571A3DA7203D1E53D4D93F521AE1AD75360DE1AD187EFE3A396F40AFED9C7797681A857003A7EA20C2203D2E40419253C6706FD30EAABC972CAA9C5C97B48DC734472D310E0DEE896862407E24A243EEE1E02309A6C7E1E53CD953B93FF54283ACE51B298BB1C92FF0A172948EF0CF8D239A5849D8E3D7AAC4486FB746501F3318145B042E62CA6EB70544E31581687DD67D8AD73FFB39DD71DA00E7F3738890D65610CAA049A5CD99AD928F98D3CFBD9A706E8908A2F51712B03562CB057F99431E0746B98DEE0D367DFC93CA546E26A44A72F47122FABCA47900D76A42B29C9160C46B40F811A1B8BA8651C7CEB1200DED520709D9CC0B21A20C9519084DA66A91158CE7A82674374580134EEA025BB0185807DF2A5B1EDEFEFA8D247A84B787E2597F8BF72ED6F570F32AACA50D10E94DB679FF68CE35AF77537EA4CB7928F7EDD5CABB65E32C0D88FACCFC51C2146BF3FDA433B76F09234552FC069312C38677AD95D501AF829B0A1484FEF9A2F804F0ECD4990079B66568956C34212CE0E483CF7C78D1E638893082826C15E7CA78004D04AC95EE36ED5200EBB74FA39E2980026463FB
+20210512004700 2 6 100 6143 5 F58340194C3306C216EBA34FD995EAF9AF7B4471283E848F4B029734B8BCEBCD8E52D560FFF982CE43FF8B4743C8048BC6D4338C8B93AC9F00C5A9564A840146DE9539AD56551E9187BFC36282EE41C27355F3620B33561B868295222A693A11F5817C1A4306DAD1071FB2D38DE9462DBC4778784F4BD5B27F2FD173C360611E6A21FB82A494BEC22F4ABF1F5AA692B784E15FB737684C0ECC5B8D55FD023C52DE35464CA1AAA8F3F949F1BE6C194CB7C0DD0E5BA261A216CFC40D7DEA492929D777F6B8636A4C05D58652836E70E5956173BFD976CF08406210630C4489534639053F069285A6E55B851423BB3714647681FB05D545F941E69FE5756C500328991387212418E4C54146FBEF4A6D2481DE817DCAE3E1EEDE8E617357630B734FEFD566BB0338D8EE564F35518E59AF81F67AD190E45906A0832515515D6CCD73DE76FE730694CEED007F333DB1F6F9A026655F950751EF85AC1E571A3DA7203D1E53D4D93F521AE1AD75360DE1AD187EFE3A396F40AFED9C7797681A857003A7EA20C2203D2E40419253C6706FD30EAABC972CAA9C5C97B48DC734472D310E0DEE896862407E24A243EEE1E02309A6C7E1E53CD953B93FF54283ACE51B298BB1C92FF0A172948EF0CF8D239A5849D8E3D7AAC4486FB746501F3318145B042E62CA6EB70544E31581687DD67D8AD73FFB39DD71DA00E7F3738890D65610CAA049A5CD99AD928F98D3CFBD9A706E8908A2F51712B03562CB057F99431E0746B98DEE0D367DFC93CA546E26A44A72F47122FABCA47900D76A42B29C9160C46B40F811A1B8BA8651C7CEB1200DED520709D9CC0B21A20C9519084DA66A91158CE7A82674374580134EEA025BB0185807DF2A5B1EDEFEFA8D247A84B787E2597F8BF72ED6F570F32AACA50D10E94DB679FF68CE35AF77537EA4CB7928F7EDD5CABB65E32C0D88FACCFC51C2146BF3FDA433B76F09234552FC069312C38677AD95D501AF829B0A1484FEF9A2F804F0ECD4990079B66568956C34212CE0E483CF7C78D1E638893082826C15E7CA78004D04AC95EE36ED5200EBB74FA39E298005D412AF
+20210512011719 2 6 100 6143 5 F58340194C3306C216EBA34FD995EAF9AF7B4471283E848F4B029734B8BCEBCD8E52D560FFF982CE43FF8B4743C8048BC6D4338C8B93AC9F00C5A9564A840146DE9539AD56551E9187BFC36282EE41C27355F3620B33561B868295222A693A11F5817C1A4306DAD1071FB2D38DE9462DBC4778784F4BD5B27F2FD173C360611E6A21FB82A494BEC22F4ABF1F5AA692B784E15FB737684C0ECC5B8D55FD023C52DE35464CA1AAA8F3F949F1BE6C194CB7C0DD0E5BA261A216CFC40D7DEA492929D777F6B8636A4C05D58652836E70E5956173BFD976CF08406210630C4489534639053F069285A6E55B851423BB3714647681FB05D545F941E69FE5756C500328991387212418E4C54146FBEF4A6D2481DE817DCAE3E1EEDE8E617357630B734FEFD566BB0338D8EE564F35518E59AF81F67AD190E45906A0832515515D6CCD73DE76FE730694CEED007F333DB1F6F9A026655F950751EF85AC1E571A3DA7203D1E53D4D93F521AE1AD75360DE1AD187EFE3A396F40AFED9C7797681A857003A7EA20C2203D2E40419253C6706FD30EAABC972CAA9C5C97B48DC734472D310E0DEE896862407E24A243EEE1E02309A6C7E1E53CD953B93FF54283ACE51B298BB1C92FF0A172948EF0CF8D239A5849D8E3D7AAC4486FB746501F3318145B042E62CA6EB70544E31581687DD67D8AD73FFB39DD71DA00E7F3738890D65610CAA049A5CD99AD928F98D3CFBD9A706E8908A2F51712B03562CB057F99431E0746B98DEE0D367DFC93CA546E26A44A72F47122FABCA47900D76A42B29C9160C46B40F811A1B8BA8651C7CEB1200DED520709D9CC0B21A20C9519084DA66A91158CE7A82674374580134EEA025BB0185807DF2A5B1EDEFEFA8D247A84B787E2597F8BF72ED6F570F32AACA50D10E94DB679FF68CE35AF77537EA4CB7928F7EDD5CABB65E32C0D88FACCFC51C2146BF3FDA433B76F09234552FC069312C38677AD95D501AF829B0A1484FEF9A2F804F0ECD4990079B66568956C34212CE0E483CF7C78D1E638893082826C15E7CA78004D04AC95EE36ED5200EBB74FA39E29800A1EF6AF
+20210512012230 2 6 100 6143 2 F58340194C3306C216EBA34FD995EAF9AF7B4471283E848F4B029734B8BCEBCD8E52D560FFF982CE43FF8B4743C8048BC6D4338C8B93AC9F00C5A9564A840146DE9539AD56551E9187BFC36282EE41C27355F3620B33561B868295222A693A11F5817C1A4306DAD1071FB2D38DE9462DBC4778784F4BD5B27F2FD173C360611E6A21FB82A494BEC22F4ABF1F5AA692B784E15FB737684C0ECC5B8D55FD023C52DE35464CA1AAA8F3F949F1BE6C194CB7C0DD0E5BA261A216CFC40D7DEA492929D777F6B8636A4C05D58652836E70E5956173BFD976CF08406210630C4489534639053F069285A6E55B851423BB3714647681FB05D545F941E69FE5756C500328991387212418E4C54146FBEF4A6D2481DE817DCAE3E1EEDE8E617357630B734FEFD566BB0338D8EE564F35518E59AF81F67AD190E45906A0832515515D6CCD73DE76FE730694CEED007F333DB1F6F9A026655F950751EF85AC1E571A3DA7203D1E53D4D93F521AE1AD75360DE1AD187EFE3A396F40AFED9C7797681A857003A7EA20C2203D2E40419253C6706FD30EAABC972CAA9C5C97B48DC734472D310E0DEE896862407E24A243EEE1E02309A6C7E1E53CD953B93FF54283ACE51B298BB1C92FF0A172948EF0CF8D239A5849D8E3D7AAC4486FB746501F3318145B042E62CA6EB70544E31581687DD67D8AD73FFB39DD71DA00E7F3738890D65610CAA049A5CD99AD928F98D3CFBD9A706E8908A2F51712B03562CB057F99431E0746B98DEE0D367DFC93CA546E26A44A72F47122FABCA47900D76A42B29C9160C46B40F811A1B8BA8651C7CEB1200DED520709D9CC0B21A20C9519084DA66A91158CE7A82674374580134EEA025BB0185807DF2A5B1EDEFEFA8D247A84B787E2597F8BF72ED6F570F32AACA50D10E94DB679FF68CE35AF77537EA4CB7928F7EDD5CABB65E32C0D88FACCFC51C2146BF3FDA433B76F09234552FC069312C38677AD95D501AF829B0A1484FEF9A2F804F0ECD4990079B66568956C34212CE0E483CF7C78D1E638893082826C15E7CA78004D04AC95EE36ED5200EBB74FA39E29800AD88A43
+20210512012724 2 6 100 6143 5 F58340194C3306C216EBA34FD995EAF9AF7B4471283E848F4B029734B8BCEBCD8E52D560FFF982CE43FF8B4743C8048BC6D4338C8B93AC9F00C5A9564A840146DE9539AD56551E9187BFC36282EE41C27355F3620B33561B868295222A693A11F5817C1A4306DAD1071FB2D38DE9462DBC4778784F4BD5B27F2FD173C360611E6A21FB82A494BEC22F4ABF1F5AA692B784E15FB737684C0ECC5B8D55FD023C52DE35464CA1AAA8F3F949F1BE6C194CB7C0DD0E5BA261A216CFC40D7DEA492929D777F6B8636A4C05D58652836E70E5956173BFD976CF08406210630C4489534639053F069285A6E55B851423BB3714647681FB05D545F941E69FE5756C500328991387212418E4C54146FBEF4A6D2481DE817DCAE3E1EEDE8E617357630B734FEFD566BB0338D8EE564F35518E59AF81F67AD190E45906A0832515515D6CCD73DE76FE730694CEED007F333DB1F6F9A026655F950751EF85AC1E571A3DA7203D1E53D4D93F521AE1AD75360DE1AD187EFE3A396F40AFED9C7797681A857003A7EA20C2203D2E40419253C6706FD30EAABC972CAA9C5C97B48DC734472D310E0DEE896862407E24A243EEE1E02309A6C7E1E53CD953B93FF54283ACE51B298BB1C92FF0A172948EF0CF8D239A5849D8E3D7AAC4486FB746501F3318145B042E62CA6EB70544E31581687DD67D8AD73FFB39DD71DA00E7F3738890D65610CAA049A5CD99AD928F98D3CFBD9A706E8908A2F51712B03562CB057F99431E0746B98DEE0D367DFC93CA546E26A44A72F47122FABCA47900D76A42B29C9160C46B40F811A1B8BA8651C7CEB1200DED520709D9CC0B21A20C9519084DA66A91158CE7A82674374580134EEA025BB0185807DF2A5B1EDEFEFA8D247A84B787E2597F8BF72ED6F570F32AACA50D10E94DB679FF68CE35AF77537EA4CB7928F7EDD5CABB65E32C0D88FACCFC51C2146BF3FDA433B76F09234552FC069312C38677AD95D501AF829B0A1484FEF9A2F804F0ECD4990079B66568956C34212CE0E483CF7C78D1E638893082826C15E7CA78004D04AC95EE36ED5200EBB74FA39E29800B84DE0F
+20210512013230 2 6 100 6143 5 F58340194C3306C216EBA34FD995EAF9AF7B4471283E848F4B029734B8BCEBCD8E52D560FFF982CE43FF8B4743C8048BC6D4338C8B93AC9F00C5A9564A840146DE9539AD56551E9187BFC36282EE41C27355F3620B33561B868295222A693A11F5817C1A4306DAD1071FB2D38DE9462DBC4778784F4BD5B27F2FD173C360611E6A21FB82A494BEC22F4ABF1F5AA692B784E15FB737684C0ECC5B8D55FD023C52DE35464CA1AAA8F3F949F1BE6C194CB7C0DD0E5BA261A216CFC40D7DEA492929D777F6B8636A4C05D58652836E70E5956173BFD976CF08406210630C4489534639053F069285A6E55B851423BB3714647681FB05D545F941E69FE5756C500328991387212418E4C54146FBEF4A6D2481DE817DCAE3E1EEDE8E617357630B734FEFD566BB0338D8EE564F35518E59AF81F67AD190E45906A0832515515D6CCD73DE76FE730694CEED007F333DB1F6F9A026655F950751EF85AC1E571A3DA7203D1E53D4D93F521AE1AD75360DE1AD187EFE3A396F40AFED9C7797681A857003A7EA20C2203D2E40419253C6706FD30EAABC972CAA9C5C97B48DC734472D310E0DEE896862407E24A243EEE1E02309A6C7E1E53CD953B93FF54283ACE51B298BB1C92FF0A172948EF0CF8D239A5849D8E3D7AAC4486FB746501F3318145B042E62CA6EB70544E31581687DD67D8AD73FFB39DD71DA00E7F3738890D65610CAA049A5CD99AD928F98D3CFBD9A706E8908A2F51712B03562CB057F99431E0746B98DEE0D367DFC93CA546E26A44A72F47122FABCA47900D76A42B29C9160C46B40F811A1B8BA8651C7CEB1200DED520709D9CC0B21A20C9519084DA66A91158CE7A82674374580134EEA025BB0185807DF2A5B1EDEFEFA8D247A84B787E2597F8BF72ED6F570F32AACA50D10E94DB679FF68CE35AF77537EA4CB7928F7EDD5CABB65E32C0D88FACCFC51C2146BF3FDA433B76F09234552FC069312C38677AD95D501AF829B0A1484FEF9A2F804F0ECD4990079B66568956C34212CE0E483CF7C78D1E638893082826C15E7CA78004D04AC95EE36ED5200EBB74FA39E29800C3AA1EF
+20210512013650 2 6 100 6143 2 F58340194C3306C216EBA34FD995EAF9AF7B4471283E848F4B029734B8BCEBCD8E52D560FFF982CE43FF8B4743C8048BC6D4338C8B93AC9F00C5A9564A840146DE9539AD56551E9187BFC36282EE41C27355F3620B33561B868295222A693A11F5817C1A4306DAD1071FB2D38DE9462DBC4778784F4BD5B27F2FD173C360611E6A21FB82A494BEC22F4ABF1F5AA692B784E15FB737684C0ECC5B8D55FD023C52DE35464CA1AAA8F3F949F1BE6C194CB7C0DD0E5BA261A216CFC40D7DEA492929D777F6B8636A4C05D58652836E70E5956173BFD976CF08406210630C4489534639053F069285A6E55B851423BB3714647681FB05D545F941E69FE5756C500328991387212418E4C54146FBEF4A6D2481DE817DCAE3E1EEDE8E617357630B734FEFD566BB0338D8EE564F35518E59AF81F67AD190E45906A0832515515D6CCD73DE76FE730694CEED007F333DB1F6F9A026655F950751EF85AC1E571A3DA7203D1E53D4D93F521AE1AD75360DE1AD187EFE3A396F40AFED9C7797681A857003A7EA20C2203D2E40419253C6706FD30EAABC972CAA9C5C97B48DC734472D310E0DEE896862407E24A243EEE1E02309A6C7E1E53CD953B93FF54283ACE51B298BB1C92FF0A172948EF0CF8D239A5849D8E3D7AAC4486FB746501F3318145B042E62CA6EB70544E31581687DD67D8AD73FFB39DD71DA00E7F3738890D65610CAA049A5CD99AD928F98D3CFBD9A706E8908A2F51712B03562CB057F99431E0746B98DEE0D367DFC93CA546E26A44A72F47122FABCA47900D76A42B29C9160C46B40F811A1B8BA8651C7CEB1200DED520709D9CC0B21A20C9519084DA66A91158CE7A82674374580134EEA025BB0185807DF2A5B1EDEFEFA8D247A84B787E2597F8BF72ED6F570F32AACA50D10E94DB679FF68CE35AF77537EA4CB7928F7EDD5CABB65E32C0D88FACCFC51C2146BF3FDA433B76F09234552FC069312C38677AD95D501AF829B0A1484FEF9A2F804F0ECD4990079B66568956C34212CE0E483CF7C78D1E638893082826C15E7CA78004D04AC95EE36ED5200EBB74FA39E29800CCDD483
+20210512015950 2 6 100 6143 2 F58340194C3306C216EBA34FD995EAF9AF7B4471283E848F4B029734B8BCEBCD8E52D560FFF982CE43FF8B4743C8048BC6D4338C8B93AC9F00C5A9564A840146DE9539AD56551E9187BFC36282EE41C27355F3620B33561B868295222A693A11F5817C1A4306DAD1071FB2D38DE9462DBC4778784F4BD5B27F2FD173C360611E6A21FB82A494BEC22F4ABF1F5AA692B784E15FB737684C0ECC5B8D55FD023C52DE35464CA1AAA8F3F949F1BE6C194CB7C0DD0E5BA261A216CFC40D7DEA492929D777F6B8636A4C05D58652836E70E5956173BFD976CF08406210630C4489534639053F069285A6E55B851423BB3714647681FB05D545F941E69FE5756C500328991387212418E4C54146FBEF4A6D2481DE817DCAE3E1EEDE8E617357630B734FEFD566BB0338D8EE564F35518E59AF81F67AD190E45906A0832515515D6CCD73DE76FE730694CEED007F333DB1F6F9A026655F950751EF85AC1E571A3DA7203D1E53D4D93F521AE1AD75360DE1AD187EFE3A396F40AFED9C7797681A857003A7EA20C2203D2E40419253C6706FD30EAABC972CAA9C5C97B48DC734472D310E0DEE896862407E24A243EEE1E02309A6C7E1E53CD953B93FF54283ACE51B298BB1C92FF0A172948EF0CF8D239A5849D8E3D7AAC4486FB746501F3318145B042E62CA6EB70544E31581687DD67D8AD73FFB39DD71DA00E7F3738890D65610CAA049A5CD99AD928F98D3CFBD9A706E8908A2F51712B03562CB057F99431E0746B98DEE0D367DFC93CA546E26A44A72F47122FABCA47900D76A42B29C9160C46B40F811A1B8BA8651C7CEB1200DED520709D9CC0B21A20C9519084DA66A91158CE7A82674374580134EEA025BB0185807DF2A5B1EDEFEFA8D247A84B787E2597F8BF72ED6F570F32AACA50D10E94DB679FF68CE35AF77537EA4CB7928F7EDD5CABB65E32C0D88FACCFC51C2146BF3FDA433B76F09234552FC069312C38677AD95D501AF829B0A1484FEF9A2F804F0ECD4990079B66568956C34212CE0E483CF7C78D1E638893082826C15E7CA78004D04AC95EE36ED5200EBB74FA39E2980100A0E43
+20210512020847 2 6 100 6143 5 F58340194C3306C216EBA34FD995EAF9AF7B4471283E848F4B029734B8BCEBCD8E52D560FFF982CE43FF8B4743C8048BC6D4338C8B93AC9F00C5A9564A840146DE9539AD56551E9187BFC36282EE41C27355F3620B33561B868295222A693A11F5817C1A4306DAD1071FB2D38DE9462DBC4778784F4BD5B27F2FD173C360611E6A21FB82A494BEC22F4ABF1F5AA692B784E15FB737684C0ECC5B8D55FD023C52DE35464CA1AAA8F3F949F1BE6C194CB7C0DD0E5BA261A216CFC40D7DEA492929D777F6B8636A4C05D58652836E70E5956173BFD976CF08406210630C4489534639053F069285A6E55B851423BB3714647681FB05D545F941E69FE5756C500328991387212418E4C54146FBEF4A6D2481DE817DCAE3E1EEDE8E617357630B734FEFD566BB0338D8EE564F35518E59AF81F67AD190E45906A0832515515D6CCD73DE76FE730694CEED007F333DB1F6F9A026655F950751EF85AC1E571A3DA7203D1E53D4D93F521AE1AD75360DE1AD187EFE3A396F40AFED9C7797681A857003A7EA20C2203D2E40419253C6706FD30EAABC972CAA9C5C97B48DC734472D310E0DEE896862407E24A243EEE1E02309A6C7E1E53CD953B93FF54283ACE51B298BB1C92FF0A172948EF0CF8D239A5849D8E3D7AAC4486FB746501F3318145B042E62CA6EB70544E31581687DD67D8AD73FFB39DD71DA00E7F3738890D65610CAA049A5CD99AD928F98D3CFBD9A706E8908A2F51712B03562CB057F99431E0746B98DEE0D367DFC93CA546E26A44A72F47122FABCA47900D76A42B29C9160C46B40F811A1B8BA8651C7CEB1200DED520709D9CC0B21A20C9519084DA66A91158CE7A82674374580134EEA025BB0185807DF2A5B1EDEFEFA8D247A84B787E2597F8BF72ED6F570F32AACA50D10E94DB679FF68CE35AF77537EA4CB7928F7EDD5CABB65E32C0D88FACCFC51C2146BF3FDA433B76F09234552FC069312C38677AD95D501AF829B0A1484FEF9A2F804F0ECD4990079B66568956C34212CE0E483CF7C78D1E638893082826C15E7CA78004D04AC95EE36ED5200EBB74FA39E2980114782B7
+20210512022553 2 6 100 6143 2 F58340194C3306C216EBA34FD995EAF9AF7B4471283E848F4B029734B8BCEBCD8E52D560FFF982CE43FF8B4743C8048BC6D4338C8B93AC9F00C5A9564A840146DE9539AD56551E9187BFC36282EE41C27355F3620B33561B868295222A693A11F5817C1A4306DAD1071FB2D38DE9462DBC4778784F4BD5B27F2FD173C360611E6A21FB82A494BEC22F4ABF1F5AA692B784E15FB737684C0ECC5B8D55FD023C52DE35464CA1AAA8F3F949F1BE6C194CB7C0DD0E5BA261A216CFC40D7DEA492929D777F6B8636A4C05D58652836E70E5956173BFD976CF08406210630C4489534639053F069285A6E55B851423BB3714647681FB05D545F941E69FE5756C500328991387212418E4C54146FBEF4A6D2481DE817DCAE3E1EEDE8E617357630B734FEFD566BB0338D8EE564F35518E59AF81F67AD190E45906A0832515515D6CCD73DE76FE730694CEED007F333DB1F6F9A026655F950751EF85AC1E571A3DA7203D1E53D4D93F521AE1AD75360DE1AD187EFE3A396F40AFED9C7797681A857003A7EA20C2203D2E40419253C6706FD30EAABC972CAA9C5C97B48DC734472D310E0DEE896862407E24A243EEE1E02309A6C7E1E53CD953B93FF54283ACE51B298BB1C92FF0A172948EF0CF8D239A5849D8E3D7AAC4486FB746501F3318145B042E62CA6EB70544E31581687DD67D8AD73FFB39DD71DA00E7F3738890D65610CAA049A5CD99AD928F98D3CFBD9A706E8908A2F51712B03562CB057F99431E0746B98DEE0D367DFC93CA546E26A44A72F47122FABCA47900D76A42B29C9160C46B40F811A1B8BA8651C7CEB1200DED520709D9CC0B21A20C9519084DA66A91158CE7A82674374580134EEA025BB0185807DF2A5B1EDEFEFA8D247A84B787E2597F8BF72ED6F570F32AACA50D10E94DB679FF68CE35AF77537EA4CB7928F7EDD5CABB65E32C0D88FACCFC51C2146BF3FDA433B76F09234552FC069312C38677AD95D501AF829B0A1484FEF9A2F804F0ECD4990079B66568956C34212CE0E483CF7C78D1E638893082826C15E7CA78004D04AC95EE36ED5200EBB74FA39E298013B2C213
+20210512022729 2 6 100 6143 5 F58340194C3306C216EBA34FD995EAF9AF7B4471283E848F4B029734B8BCEBCD8E52D560FFF982CE43FF8B4743C8048BC6D4338C8B93AC9F00C5A9564A840146DE9539AD56551E9187BFC36282EE41C27355F3620B33561B868295222A693A11F5817C1A4306DAD1071FB2D38DE9462DBC4778784F4BD5B27F2FD173C360611E6A21FB82A494BEC22F4ABF1F5AA692B784E15FB737684C0ECC5B8D55FD023C52DE35464CA1AAA8F3F949F1BE6C194CB7C0DD0E5BA261A216CFC40D7DEA492929D777F6B8636A4C05D58652836E70E5956173BFD976CF08406210630C4489534639053F069285A6E55B851423BB3714647681FB05D545F941E69FE5756C500328991387212418E4C54146FBEF4A6D2481DE817DCAE3E1EEDE8E617357630B734FEFD566BB0338D8EE564F35518E59AF81F67AD190E45906A0832515515D6CCD73DE76FE730694CEED007F333DB1F6F9A026655F950751EF85AC1E571A3DA7203D1E53D4D93F521AE1AD75360DE1AD187EFE3A396F40AFED9C7797681A857003A7EA20C2203D2E40419253C6706FD30EAABC972CAA9C5C97B48DC734472D310E0DEE896862407E24A243EEE1E02309A6C7E1E53CD953B93FF54283ACE51B298BB1C92FF0A172948EF0CF8D239A5849D8E3D7AAC4486FB746501F3318145B042E62CA6EB70544E31581687DD67D8AD73FFB39DD71DA00E7F3738890D65610CAA049A5CD99AD928F98D3CFBD9A706E8908A2F51712B03562CB057F99431E0746B98DEE0D367DFC93CA546E26A44A72F47122FABCA47900D76A42B29C9160C46B40F811A1B8BA8651C7CEB1200DED520709D9CC0B21A20C9519084DA66A91158CE7A82674374580134EEA025BB0185807DF2A5B1EDEFEFA8D247A84B787E2597F8BF72ED6F570F32AACA50D10E94DB679FF68CE35AF77537EA4CB7928F7EDD5CABB65E32C0D88FACCFC51C2146BF3FDA433B76F09234552FC069312C38677AD95D501AF829B0A1484FEF9A2F804F0ECD4990079B66568956C34212CE0E483CF7C78D1E638893082826C15E7CA78004D04AC95EE36ED5200EBB74FA39E298013E47BAF
+20210512025425 2 6 100 6143 2 F58340194C3306C216EBA34FD995EAF9AF7B4471283E848F4B029734B8BCEBCD8E52D560FFF982CE43FF8B4743C8048BC6D4338C8B93AC9F00C5A9564A840146DE9539AD56551E9187BFC36282EE41C27355F3620B33561B868295222A693A11F5817C1A4306DAD1071FB2D38DE9462DBC4778784F4BD5B27F2FD173C360611E6A21FB82A494BEC22F4ABF1F5AA692B784E15FB737684C0ECC5B8D55FD023C52DE35464CA1AAA8F3F949F1BE6C194CB7C0DD0E5BA261A216CFC40D7DEA492929D777F6B8636A4C05D58652836E70E5956173BFD976CF08406210630C4489534639053F069285A6E55B851423BB3714647681FB05D545F941E69FE5756C500328991387212418E4C54146FBEF4A6D2481DE817DCAE3E1EEDE8E617357630B734FEFD566BB0338D8EE564F35518E59AF81F67AD190E45906A0832515515D6CCD73DE76FE730694CEED007F333DB1F6F9A026655F950751EF85AC1E571A3DA7203D1E53D4D93F521AE1AD75360DE1AD187EFE3A396F40AFED9C7797681A857003A7EA20C2203D2E40419253C6706FD30EAABC972CAA9C5C97B48DC734472D310E0DEE896862407E24A243EEE1E02309A6C7E1E53CD953B93FF54283ACE51B298BB1C92FF0A172948EF0CF8D239A5849D8E3D7AAC4486FB746501F3318145B042E62CA6EB70544E31581687DD67D8AD73FFB39DD71DA00E7F3738890D65610CAA049A5CD99AD928F98D3CFBD9A706E8908A2F51712B03562CB057F99431E0746B98DEE0D367DFC93CA546E26A44A72F47122FABCA47900D76A42B29C9160C46B40F811A1B8BA8651C7CEB1200DED520709D9CC0B21A20C9519084DA66A91158CE7A82674374580134EEA025BB0185807DF2A5B1EDEFEFA8D247A84B787E2597F8BF72ED6F570F32AACA50D10E94DB679FF68CE35AF77537EA4CB7928F7EDD5CABB65E32C0D88FACCFC51C2146BF3FDA433B76F09234552FC069312C38677AD95D501AF829B0A1484FEF9A2F804F0ECD4990079B66568956C34212CE0E483CF7C78D1E638893082826C15E7CA78004D04AC95EE36ED5200EBB74FA39E2980179E503B
+20210510215238 2 6 100 7679 2 C260CF005EEA851908A07073F58C88D37464F6C4353E3652C60C64BB441FAB9B7FB9F6CBB9D8073D3FE935B70EA1F508B2AF0E89899E9B6FD2B0E0583386A56CDADB39C1E362175A28F278B43A478B8506B1592C5A1DB8F33CE21C43CC5763DE1218C349755906B8D975B9DA963936BC01F7D79C5928C25E602D5B838892C62FDD61FAD8D0E189A70EC5891239BF69A75C87ACF1DC8DC50B359A9DC624FF7F92627B5D29748D84549AA6A831A35742E579A206F56DB0AD497AA834B877538C8045F3EE38A189AF9FFFBFC36FA4758EF1334DA487353514C0C406DB6B38E9327895D73DA4E92042EA6880336392E7E8342A1A7526816FEC68E95C995C9388779636AF8A45F54274EBDDD439AA16EE284FAF1E5459C99372083CF1531730F0354BF7E9C0733A3E785E82D99D270870B97D303F2A968C1469041D62277A14DFA2B279991C7E3C45DFEE93192650BF89D46218932FEB1C357EFA71A7F669F42FA4417F7053AEA70D43646CFDBCF7C05A1ABF53D1B5CA701BB6281097C600F951EDDEB258722C6EBA5A663BEB51CDA38D36584D6566BA1878558A7B2D32B28675D1FB2463C8C8AA5CC9CCBD733F3D741BDDC3F0F9532AAA1BB6E039F59B3CE4E5566440DEABF306861EAC945A4DDB2BC7E1B4096D92EB6901C7B83EB8980128935FCB70E82E855BBE41A9438BE84ACC738F818E5E3EDBA0AEE97CDB1634BABB6B1928BB43EDFB053DE5B3B4F0194A4D79D2EDB949D94B197F5D9406AAD368D5EEC0212A0BCA174F2BFFAACFAF2C51AE1F39DCDD849B04C0AE98935C80E62F63755F9B740343A28A5A7B93D8F5FA63E9C322BF46F484911A3B5581F9039F0A930E77AF641EEA0D1734D59B28B13280A9641382D3E489E069F2D659491F261B5FB7B4B7C7AE823D3C426FDEFD75734AD97DC4359E30BA7E99E073D8D6FD1C6B0F01006F33C829528E46565CE86F781228E2D22D7A5AA4C9E6B53DDACF380404CD9D2B2CDE31C6ECA679AA6A997AC53F9E9A429BFF636A008488447622ACFD6754E17048D0E7F7DF03CE0DE64F9FCAE47A46718D8212D620688A598D3B6AFEC54C762D4AE8AA0BA7B1AC97B8F9766BAF71EAE16D5E2B5614AC4FA5E20A0BCD622134AC7B08E00B8020D580F2C28CA1D15BDA1981CCE0E0AB5CDE942DFCC578EFF0C250B874E638705294A00724F9ED1329DA93179CAA869EE4BBAAD9F29993945745A5116840906BA4DCF9E303CE0947D4FD59C7964CC001882C001FB188697652B0A949624A983DA2099443191F6DD4EF89B705CCC825FC16C4AC5FD63D932901DE28AEEAB0DF883F44A6F0923B54A9477A3B521D8E12DD10453931E00E9F39D65FCF63
+20210510222355 2 6 100 7679 2 C260CF005EEA851908A07073F58C88D37464F6C4353E3652C60C64BB441FAB9B7FB9F6CBB9D8073D3FE935B70EA1F508B2AF0E89899E9B6FD2B0E0583386A56CDADB39C1E362175A28F278B43A478B8506B1592C5A1DB8F33CE21C43CC5763DE1218C349755906B8D975B9DA963936BC01F7D79C5928C25E602D5B838892C62FDD61FAD8D0E189A70EC5891239BF69A75C87ACF1DC8DC50B359A9DC624FF7F92627B5D29748D84549AA6A831A35742E579A206F56DB0AD497AA834B877538C8045F3EE38A189AF9FFFBFC36FA4758EF1334DA487353514C0C406DB6B38E9327895D73DA4E92042EA6880336392E7E8342A1A7526816FEC68E95C995C9388779636AF8A45F54274EBDDD439AA16EE284FAF1E5459C99372083CF1531730F0354BF7E9C0733A3E785E82D99D270870B97D303F2A968C1469041D62277A14DFA2B279991C7E3C45DFEE93192650BF89D46218932FEB1C357EFA71A7F669F42FA4417F7053AEA70D43646CFDBCF7C05A1ABF53D1B5CA701BB6281097C600F951EDDEB258722C6EBA5A663BEB51CDA38D36584D6566BA1878558A7B2D32B28675D1FB2463C8C8AA5CC9CCBD733F3D741BDDC3F0F9532AAA1BB6E039F59B3CE4E5566440DEABF306861EAC945A4DDB2BC7E1B4096D92EB6901C7B83EB8980128935FCB70E82E855BBE41A9438BE84ACC738F818E5E3EDBA0AEE97CDB1634BABB6B1928BB43EDFB053DE5B3B4F0194A4D79D2EDB949D94B197F5D9406AAD368D5EEC0212A0BCA174F2BFFAACFAF2C51AE1F39DCDD849B04C0AE98935C80E62F63755F9B740343A28A5A7B93D8F5FA63E9C322BF46F484911A3B5581F9039F0A930E77AF641EEA0D1734D59B28B13280A9641382D3E489E069F2D659491F261B5FB7B4B7C7AE823D3C426FDEFD75734AD97DC4359E30BA7E99E073D8D6FD1C6B0F01006F33C829528E46565CE86F781228E2D22D7A5AA4C9E6B53DDACF380404CD9D2B2CDE31C6ECA679AA6A997AC53F9E9A429BFF636A008488447622ACFD6754E17048D0E7F7DF03CE0DE64F9FCAE47A46718D8212D620688A598D3B6AFEC54C762D4AE8AA0BA7B1AC97B8F9766BAF71EAE16D5E2B5614AC4FA5E20A0BCD622134AC7B08E00B8020D580F2C28CA1D15BDA1981CCE0E0AB5CDE942DFCC578EFF0C250B874E638705294A00724F9ED1329DA93179CAA869EE4BBAAD9F29993945745A5116840906BA4DCF9E303CE0947D4FD59C7964CC001882C001FB188697652B0A949624A983DA2099443191F6DD4EF89B705CCC825FC16C4AC5FD63D932901DE28AEEAB0DF883F44A6F0923B54A9477A3B521D8E12DD10453931E00E9F39D8F2D76B
+20210510231559 2 6 100 7679 2 C260CF005EEA851908A07073F58C88D37464F6C4353E3652C60C64BB441FAB9B7FB9F6CBB9D8073D3FE935B70EA1F508B2AF0E89899E9B6FD2B0E0583386A56CDADB39C1E362175A28F278B43A478B8506B1592C5A1DB8F33CE21C43CC5763DE1218C349755906B8D975B9DA963936BC01F7D79C5928C25E602D5B838892C62FDD61FAD8D0E189A70EC5891239BF69A75C87ACF1DC8DC50B359A9DC624FF7F92627B5D29748D84549AA6A831A35742E579A206F56DB0AD497AA834B877538C8045F3EE38A189AF9FFFBFC36FA4758EF1334DA487353514C0C406DB6B38E9327895D73DA4E92042EA6880336392E7E8342A1A7526816FEC68E95C995C9388779636AF8A45F54274EBDDD439AA16EE284FAF1E5459C99372083CF1531730F0354BF7E9C0733A3E785E82D99D270870B97D303F2A968C1469041D62277A14DFA2B279991C7E3C45DFEE93192650BF89D46218932FEB1C357EFA71A7F669F42FA4417F7053AEA70D43646CFDBCF7C05A1ABF53D1B5CA701BB6281097C600F951EDDEB258722C6EBA5A663BEB51CDA38D36584D6566BA1878558A7B2D32B28675D1FB2463C8C8AA5CC9CCBD733F3D741BDDC3F0F9532AAA1BB6E039F59B3CE4E5566440DEABF306861EAC945A4DDB2BC7E1B4096D92EB6901C7B83EB8980128935FCB70E82E855BBE41A9438BE84ACC738F818E5E3EDBA0AEE97CDB1634BABB6B1928BB43EDFB053DE5B3B4F0194A4D79D2EDB949D94B197F5D9406AAD368D5EEC0212A0BCA174F2BFFAACFAF2C51AE1F39DCDD849B04C0AE98935C80E62F63755F9B740343A28A5A7B93D8F5FA63E9C322BF46F484911A3B5581F9039F0A930E77AF641EEA0D1734D59B28B13280A9641382D3E489E069F2D659491F261B5FB7B4B7C7AE823D3C426FDEFD75734AD97DC4359E30BA7E99E073D8D6FD1C6B0F01006F33C829528E46565CE86F781228E2D22D7A5AA4C9E6B53DDACF380404CD9D2B2CDE31C6ECA679AA6A997AC53F9E9A429BFF636A008488447622ACFD6754E17048D0E7F7DF03CE0DE64F9FCAE47A46718D8212D620688A598D3B6AFEC54C762D4AE8AA0BA7B1AC97B8F9766BAF71EAE16D5E2B5614AC4FA5E20A0BCD622134AC7B08E00B8020D580F2C28CA1D15BDA1981CCE0E0AB5CDE942DFCC578EFF0C250B874E638705294A00724F9ED1329DA93179CAA869EE4BBAAD9F29993945745A5116840906BA4DCF9E303CE0947D4FD59C7964CC001882C001FB188697652B0A949624A983DA2099443191F6DD4EF89B705CCC825FC16C4AC5FD63D932901DE28AEEAB0DF883F44A6F0923B54A9477A3B521D8E12DD10453931E00E9F39DD6E0D13
+20210510234158 2 6 100 7679 2 C260CF005EEA851908A07073F58C88D37464F6C4353E3652C60C64BB441FAB9B7FB9F6CBB9D8073D3FE935B70EA1F508B2AF0E89899E9B6FD2B0E0583386A56CDADB39C1E362175A28F278B43A478B8506B1592C5A1DB8F33CE21C43CC5763DE1218C349755906B8D975B9DA963936BC01F7D79C5928C25E602D5B838892C62FDD61FAD8D0E189A70EC5891239BF69A75C87ACF1DC8DC50B359A9DC624FF7F92627B5D29748D84549AA6A831A35742E579A206F56DB0AD497AA834B877538C8045F3EE38A189AF9FFFBFC36FA4758EF1334DA487353514C0C406DB6B38E9327895D73DA4E92042EA6880336392E7E8342A1A7526816FEC68E95C995C9388779636AF8A45F54274EBDDD439AA16EE284FAF1E5459C99372083CF1531730F0354BF7E9C0733A3E785E82D99D270870B97D303F2A968C1469041D62277A14DFA2B279991C7E3C45DFEE93192650BF89D46218932FEB1C357EFA71A7F669F42FA4417F7053AEA70D43646CFDBCF7C05A1ABF53D1B5CA701BB6281097C600F951EDDEB258722C6EBA5A663BEB51CDA38D36584D6566BA1878558A7B2D32B28675D1FB2463C8C8AA5CC9CCBD733F3D741BDDC3F0F9532AAA1BB6E039F59B3CE4E5566440DEABF306861EAC945A4DDB2BC7E1B4096D92EB6901C7B83EB8980128935FCB70E82E855BBE41A9438BE84ACC738F818E5E3EDBA0AEE97CDB1634BABB6B1928BB43EDFB053DE5B3B4F0194A4D79D2EDB949D94B197F5D9406AAD368D5EEC0212A0BCA174F2BFFAACFAF2C51AE1F39DCDD849B04C0AE98935C80E62F63755F9B740343A28A5A7B93D8F5FA63E9C322BF46F484911A3B5581F9039F0A930E77AF641EEA0D1734D59B28B13280A9641382D3E489E069F2D659491F261B5FB7B4B7C7AE823D3C426FDEFD75734AD97DC4359E30BA7E99E073D8D6FD1C6B0F01006F33C829528E46565CE86F781228E2D22D7A5AA4C9E6B53DDACF380404CD9D2B2CDE31C6ECA679AA6A997AC53F9E9A429BFF636A008488447622ACFD6754E17048D0E7F7DF03CE0DE64F9FCAE47A46718D8212D620688A598D3B6AFEC54C762D4AE8AA0BA7B1AC97B8F9766BAF71EAE16D5E2B5614AC4FA5E20A0BCD622134AC7B08E00B8020D580F2C28CA1D15BDA1981CCE0E0AB5CDE942DFCC578EFF0C250B874E638705294A00724F9ED1329DA93179CAA869EE4BBAAD9F29993945745A5116840906BA4DCF9E303CE0947D4FD59C7964CC001882C001FB188697652B0A949624A983DA2099443191F6DD4EF89B705CCC825FC16C4AC5FD63D932901DE28AEEAB0DF883F44A6F0923B54A9477A3B521D8E12DD10453931E00E9F39DFA06E23
+20210511000641 2 6 100 7679 5 C260CF005EEA851908A07073F58C88D37464F6C4353E3652C60C64BB441FAB9B7FB9F6CBB9D8073D3FE935B70EA1F508B2AF0E89899E9B6FD2B0E0583386A56CDADB39C1E362175A28F278B43A478B8506B1592C5A1DB8F33CE21C43CC5763DE1218C349755906B8D975B9DA963936BC01F7D79C5928C25E602D5B838892C62FDD61FAD8D0E189A70EC5891239BF69A75C87ACF1DC8DC50B359A9DC624FF7F92627B5D29748D84549AA6A831A35742E579A206F56DB0AD497AA834B877538C8045F3EE38A189AF9FFFBFC36FA4758EF1334DA487353514C0C406DB6B38E9327895D73DA4E92042EA6880336392E7E8342A1A7526816FEC68E95C995C9388779636AF8A45F54274EBDDD439AA16EE284FAF1E5459C99372083CF1531730F0354BF7E9C0733A3E785E82D99D270870B97D303F2A968C1469041D62277A14DFA2B279991C7E3C45DFEE93192650BF89D46218932FEB1C357EFA71A7F669F42FA4417F7053AEA70D43646CFDBCF7C05A1ABF53D1B5CA701BB6281097C600F951EDDEB258722C6EBA5A663BEB51CDA38D36584D6566BA1878558A7B2D32B28675D1FB2463C8C8AA5CC9CCBD733F3D741BDDC3F0F9532AAA1BB6E039F59B3CE4E5566440DEABF306861EAC945A4DDB2BC7E1B4096D92EB6901C7B83EB8980128935FCB70E82E855BBE41A9438BE84ACC738F818E5E3EDBA0AEE97CDB1634BABB6B1928BB43EDFB053DE5B3B4F0194A4D79D2EDB949D94B197F5D9406AAD368D5EEC0212A0BCA174F2BFFAACFAF2C51AE1F39DCDD849B04C0AE98935C80E62F63755F9B740343A28A5A7B93D8F5FA63E9C322BF46F484911A3B5581F9039F0A930E77AF641EEA0D1734D59B28B13280A9641382D3E489E069F2D659491F261B5FB7B4B7C7AE823D3C426FDEFD75734AD97DC4359E30BA7E99E073D8D6FD1C6B0F01006F33C829528E46565CE86F781228E2D22D7A5AA4C9E6B53DDACF380404CD9D2B2CDE31C6ECA679AA6A997AC53F9E9A429BFF636A008488447622ACFD6754E17048D0E7F7DF03CE0DE64F9FCAE47A46718D8212D620688A598D3B6AFEC54C762D4AE8AA0BA7B1AC97B8F9766BAF71EAE16D5E2B5614AC4FA5E20A0BCD622134AC7B08E00B8020D580F2C28CA1D15BDA1981CCE0E0AB5CDE942DFCC578EFF0C250B874E638705294A00724F9ED1329DA93179CAA869EE4BBAAD9F29993945745A5116840906BA4DCF9E303CE0947D4FD59C7964CC001882C001FB188697652B0A949624A983DA2099443191F6DD4EF89B705CCC825FC16C4AC5FD63D932901DE28AEEAB0DF883F44A6F0923B54A9477A3B521D8E12DD10453931E00E9F39E1BC772F
+20210511003255 2 6 100 7679 5 C260CF005EEA851908A07073F58C88D37464F6C4353E3652C60C64BB441FAB9B7FB9F6CBB9D8073D3FE935B70EA1F508B2AF0E89899E9B6FD2B0E0583386A56CDADB39C1E362175A28F278B43A478B8506B1592C5A1DB8F33CE21C43CC5763DE1218C349755906B8D975B9DA963936BC01F7D79C5928C25E602D5B838892C62FDD61FAD8D0E189A70EC5891239BF69A75C87ACF1DC8DC50B359A9DC624FF7F92627B5D29748D84549AA6A831A35742E579A206F56DB0AD497AA834B877538C8045F3EE38A189AF9FFFBFC36FA4758EF1334DA487353514C0C406DB6B38E9327895D73DA4E92042EA6880336392E7E8342A1A7526816FEC68E95C995C9388779636AF8A45F54274EBDDD439AA16EE284FAF1E5459C99372083CF1531730F0354BF7E9C0733A3E785E82D99D270870B97D303F2A968C1469041D62277A14DFA2B279991C7E3C45DFEE93192650BF89D46218932FEB1C357EFA71A7F669F42FA4417F7053AEA70D43646CFDBCF7C05A1ABF53D1B5CA701BB6281097C600F951EDDEB258722C6EBA5A663BEB51CDA38D36584D6566BA1878558A7B2D32B28675D1FB2463C8C8AA5CC9CCBD733F3D741BDDC3F0F9532AAA1BB6E039F59B3CE4E5566440DEABF306861EAC945A4DDB2BC7E1B4096D92EB6901C7B83EB8980128935FCB70E82E855BBE41A9438BE84ACC738F818E5E3EDBA0AEE97CDB1634BABB6B1928BB43EDFB053DE5B3B4F0194A4D79D2EDB949D94B197F5D9406AAD368D5EEC0212A0BCA174F2BFFAACFAF2C51AE1F39DCDD849B04C0AE98935C80E62F63755F9B740343A28A5A7B93D8F5FA63E9C322BF46F484911A3B5581F9039F0A930E77AF641EEA0D1734D59B28B13280A9641382D3E489E069F2D659491F261B5FB7B4B7C7AE823D3C426FDEFD75734AD97DC4359E30BA7E99E073D8D6FD1C6B0F01006F33C829528E46565CE86F781228E2D22D7A5AA4C9E6B53DDACF380404CD9D2B2CDE31C6ECA679AA6A997AC53F9E9A429BFF636A008488447622ACFD6754E17048D0E7F7DF03CE0DE64F9FCAE47A46718D8212D620688A598D3B6AFEC54C762D4AE8AA0BA7B1AC97B8F9766BAF71EAE16D5E2B5614AC4FA5E20A0BCD622134AC7B08E00B8020D580F2C28CA1D15BDA1981CCE0E0AB5CDE942DFCC578EFF0C250B874E638705294A00724F9ED1329DA93179CAA869EE4BBAAD9F29993945745A5116840906BA4DCF9E303CE0947D4FD59C7964CC001882C001FB188697652B0A949624A983DA2099443191F6DD4EF89B705CCC825FC16C4AC5FD63D932901DE28AEEAB0DF883F44A6F0923B54A9477A3B521D8E12DD10453931E00E9F39E3F4AA7F
+20210511015501 2 6 100 7679 2 C260CF005EEA851908A07073F58C88D37464F6C4353E3652C60C64BB441FAB9B7FB9F6CBB9D8073D3FE935B70EA1F508B2AF0E89899E9B6FD2B0E0583386A56CDADB39C1E362175A28F278B43A478B8506B1592C5A1DB8F33CE21C43CC5763DE1218C349755906B8D975B9DA963936BC01F7D79C5928C25E602D5B838892C62FDD61FAD8D0E189A70EC5891239BF69A75C87ACF1DC8DC50B359A9DC624FF7F92627B5D29748D84549AA6A831A35742E579A206F56DB0AD497AA834B877538C8045F3EE38A189AF9FFFBFC36FA4758EF1334DA487353514C0C406DB6B38E9327895D73DA4E92042EA6880336392E7E8342A1A7526816FEC68E95C995C9388779636AF8A45F54274EBDDD439AA16EE284FAF1E5459C99372083CF1531730F0354BF7E9C0733A3E785E82D99D270870B97D303F2A968C1469041D62277A14DFA2B279991C7E3C45DFEE93192650BF89D46218932FEB1C357EFA71A7F669F42FA4417F7053AEA70D43646CFDBCF7C05A1ABF53D1B5CA701BB6281097C600F951EDDEB258722C6EBA5A663BEB51CDA38D36584D6566BA1878558A7B2D32B28675D1FB2463C8C8AA5CC9CCBD733F3D741BDDC3F0F9532AAA1BB6E039F59B3CE4E5566440DEABF306861EAC945A4DDB2BC7E1B4096D92EB6901C7B83EB8980128935FCB70E82E855BBE41A9438BE84ACC738F818E5E3EDBA0AEE97CDB1634BABB6B1928BB43EDFB053DE5B3B4F0194A4D79D2EDB949D94B197F5D9406AAD368D5EEC0212A0BCA174F2BFFAACFAF2C51AE1F39DCDD849B04C0AE98935C80E62F63755F9B740343A28A5A7B93D8F5FA63E9C322BF46F484911A3B5581F9039F0A930E77AF641EEA0D1734D59B28B13280A9641382D3E489E069F2D659491F261B5FB7B4B7C7AE823D3C426FDEFD75734AD97DC4359E30BA7E99E073D8D6FD1C6B0F01006F33C829528E46565CE86F781228E2D22D7A5AA4C9E6B53DDACF380404CD9D2B2CDE31C6ECA679AA6A997AC53F9E9A429BFF636A008488447622ACFD6754E17048D0E7F7DF03CE0DE64F9FCAE47A46718D8212D620688A598D3B6AFEC54C762D4AE8AA0BA7B1AC97B8F9766BAF71EAE16D5E2B5614AC4FA5E20A0BCD622134AC7B08E00B8020D580F2C28CA1D15BDA1981CCE0E0AB5CDE942DFCC578EFF0C250B874E638705294A00724F9ED1329DA93179CAA869EE4BBAAD9F29993945745A5116840906BA4DCF9E303CE0947D4FD59C7964CC001882C001FB188697652B0A949624A983DA2099443191F6DD4EF89B705CCC825FC16C4AC5FD63D932901DE28AEEAB0DF883F44A6F0923B54A9477A3B521D8E12DD10453931E00E9F39EAF7F0CB
+20210511030805 2 6 100 7679 5 C260CF005EEA851908A07073F58C88D37464F6C4353E3652C60C64BB441FAB9B7FB9F6CBB9D8073D3FE935B70EA1F508B2AF0E89899E9B6FD2B0E0583386A56CDADB39C1E362175A28F278B43A478B8506B1592C5A1DB8F33CE21C43CC5763DE1218C349755906B8D975B9DA963936BC01F7D79C5928C25E602D5B838892C62FDD61FAD8D0E189A70EC5891239BF69A75C87ACF1DC8DC50B359A9DC624FF7F92627B5D29748D84549AA6A831A35742E579A206F56DB0AD497AA834B877538C8045F3EE38A189AF9FFFBFC36FA4758EF1334DA487353514C0C406DB6B38E9327895D73DA4E92042EA6880336392E7E8342A1A7526816FEC68E95C995C9388779636AF8A45F54274EBDDD439AA16EE284FAF1E5459C99372083CF1531730F0354BF7E9C0733A3E785E82D99D270870B97D303F2A968C1469041D62277A14DFA2B279991C7E3C45DFEE93192650BF89D46218932FEB1C357EFA71A7F669F42FA4417F7053AEA70D43646CFDBCF7C05A1ABF53D1B5CA701BB6281097C600F951EDDEB258722C6EBA5A663BEB51CDA38D36584D6566BA1878558A7B2D32B28675D1FB2463C8C8AA5CC9CCBD733F3D741BDDC3F0F9532AAA1BB6E039F59B3CE4E5566440DEABF306861EAC945A4DDB2BC7E1B4096D92EB6901C7B83EB8980128935FCB70E82E855BBE41A9438BE84ACC738F818E5E3EDBA0AEE97CDB1634BABB6B1928BB43EDFB053DE5B3B4F0194A4D79D2EDB949D94B197F5D9406AAD368D5EEC0212A0BCA174F2BFFAACFAF2C51AE1F39DCDD849B04C0AE98935C80E62F63755F9B740343A28A5A7B93D8F5FA63E9C322BF46F484911A3B5581F9039F0A930E77AF641EEA0D1734D59B28B13280A9641382D3E489E069F2D659491F261B5FB7B4B7C7AE823D3C426FDEFD75734AD97DC4359E30BA7E99E073D8D6FD1C6B0F01006F33C829528E46565CE86F781228E2D22D7A5AA4C9E6B53DDACF380404CD9D2B2CDE31C6ECA679AA6A997AC53F9E9A429BFF636A008488447622ACFD6754E17048D0E7F7DF03CE0DE64F9FCAE47A46718D8212D620688A598D3B6AFEC54C762D4AE8AA0BA7B1AC97B8F9766BAF71EAE16D5E2B5614AC4FA5E20A0BCD622134AC7B08E00B8020D580F2C28CA1D15BDA1981CCE0E0AB5CDE942DFCC578EFF0C250B874E638705294A00724F9ED1329DA93179CAA869EE4BBAAD9F29993945745A5116840906BA4DCF9E303CE0947D4FD59C7964CC001882C001FB188697652B0A949624A983DA2099443191F6DD4EF89B705CCC825FC16C4AC5FD63D932901DE28AEEAB0DF883F44A6F0923B54A9477A3B521D8E12DD10453931E00E9F39F104A8AF
+20210511031420 2 6 100 7679 2 C260CF005EEA851908A07073F58C88D37464F6C4353E3652C60C64BB441FAB9B7FB9F6CBB9D8073D3FE935B70EA1F508B2AF0E89899E9B6FD2B0E0583386A56CDADB39C1E362175A28F278B43A478B8506B1592C5A1DB8F33CE21C43CC5763DE1218C349755906B8D975B9DA963936BC01F7D79C5928C25E602D5B838892C62FDD61FAD8D0E189A70EC5891239BF69A75C87ACF1DC8DC50B359A9DC624FF7F92627B5D29748D84549AA6A831A35742E579A206F56DB0AD497AA834B877538C8045F3EE38A189AF9FFFBFC36FA4758EF1334DA487353514C0C406DB6B38E9327895D73DA4E92042EA6880336392E7E8342A1A7526816FEC68E95C995C9388779636AF8A45F54274EBDDD439AA16EE284FAF1E5459C99372083CF1531730F0354BF7E9C0733A3E785E82D99D270870B97D303F2A968C1469041D62277A14DFA2B279991C7E3C45DFEE93192650BF89D46218932FEB1C357EFA71A7F669F42FA4417F7053AEA70D43646CFDBCF7C05A1ABF53D1B5CA701BB6281097C600F951EDDEB258722C6EBA5A663BEB51CDA38D36584D6566BA1878558A7B2D32B28675D1FB2463C8C8AA5CC9CCBD733F3D741BDDC3F0F9532AAA1BB6E039F59B3CE4E5566440DEABF306861EAC945A4DDB2BC7E1B4096D92EB6901C7B83EB8980128935FCB70E82E855BBE41A9438BE84ACC738F818E5E3EDBA0AEE97CDB1634BABB6B1928BB43EDFB053DE5B3B4F0194A4D79D2EDB949D94B197F5D9406AAD368D5EEC0212A0BCA174F2BFFAACFAF2C51AE1F39DCDD849B04C0AE98935C80E62F63755F9B740343A28A5A7B93D8F5FA63E9C322BF46F484911A3B5581F9039F0A930E77AF641EEA0D1734D59B28B13280A9641382D3E489E069F2D659491F261B5FB7B4B7C7AE823D3C426FDEFD75734AD97DC4359E30BA7E99E073D8D6FD1C6B0F01006F33C829528E46565CE86F781228E2D22D7A5AA4C9E6B53DDACF380404CD9D2B2CDE31C6ECA679AA6A997AC53F9E9A429BFF636A008488447622ACFD6754E17048D0E7F7DF03CE0DE64F9FCAE47A46718D8212D620688A598D3B6AFEC54C762D4AE8AA0BA7B1AC97B8F9766BAF71EAE16D5E2B5614AC4FA5E20A0BCD622134AC7B08E00B8020D580F2C28CA1D15BDA1981CCE0E0AB5CDE942DFCC578EFF0C250B874E638705294A00724F9ED1329DA93179CAA869EE4BBAAD9F29993945745A5116840906BA4DCF9E303CE0947D4FD59C7964CC001882C001FB188697652B0A949624A983DA2099443191F6DD4EF89B705CCC825FC16C4AC5FD63D932901DE28AEEAB0DF883F44A6F0923B54A9477A3B521D8E12DD10453931E00E9F39F182BAA3
+20210511032555 2 6 100 7679 5 C260CF005EEA851908A07073F58C88D37464F6C4353E3652C60C64BB441FAB9B7FB9F6CBB9D8073D3FE935B70EA1F508B2AF0E89899E9B6FD2B0E0583386A56CDADB39C1E362175A28F278B43A478B8506B1592C5A1DB8F33CE21C43CC5763DE1218C349755906B8D975B9DA963936BC01F7D79C5928C25E602D5B838892C62FDD61FAD8D0E189A70EC5891239BF69A75C87ACF1DC8DC50B359A9DC624FF7F92627B5D29748D84549AA6A831A35742E579A206F56DB0AD497AA834B877538C8045F3EE38A189AF9FFFBFC36FA4758EF1334DA487353514C0C406DB6B38E9327895D73DA4E92042EA6880336392E7E8342A1A7526816FEC68E95C995C9388779636AF8A45F54274EBDDD439AA16EE284FAF1E5459C99372083CF1531730F0354BF7E9C0733A3E785E82D99D270870B97D303F2A968C1469041D62277A14DFA2B279991C7E3C45DFEE93192650BF89D46218932FEB1C357EFA71A7F669F42FA4417F7053AEA70D43646CFDBCF7C05A1ABF53D1B5CA701BB6281097C600F951EDDEB258722C6EBA5A663BEB51CDA38D36584D6566BA1878558A7B2D32B28675D1FB2463C8C8AA5CC9CCBD733F3D741BDDC3F0F9532AAA1BB6E039F59B3CE4E5566440DEABF306861EAC945A4DDB2BC7E1B4096D92EB6901C7B83EB8980128935FCB70E82E855BBE41A9438BE84ACC738F818E5E3EDBA0AEE97CDB1634BABB6B1928BB43EDFB053DE5B3B4F0194A4D79D2EDB949D94B197F5D9406AAD368D5EEC0212A0BCA174F2BFFAACFAF2C51AE1F39DCDD849B04C0AE98935C80E62F63755F9B740343A28A5A7B93D8F5FA63E9C322BF46F484911A3B5581F9039F0A930E77AF641EEA0D1734D59B28B13280A9641382D3E489E069F2D659491F261B5FB7B4B7C7AE823D3C426FDEFD75734AD97DC4359E30BA7E99E073D8D6FD1C6B0F01006F33C829528E46565CE86F781228E2D22D7A5AA4C9E6B53DDACF380404CD9D2B2CDE31C6ECA679AA6A997AC53F9E9A429BFF636A008488447622ACFD6754E17048D0E7F7DF03CE0DE64F9FCAE47A46718D8212D620688A598D3B6AFEC54C762D4AE8AA0BA7B1AC97B8F9766BAF71EAE16D5E2B5614AC4FA5E20A0BCD622134AC7B08E00B8020D580F2C28CA1D15BDA1981CCE0E0AB5CDE942DFCC578EFF0C250B874E638705294A00724F9ED1329DA93179CAA869EE4BBAAD9F29993945745A5116840906BA4DCF9E303CE0947D4FD59C7964CC001882C001FB188697652B0A949624A983DA2099443191F6DD4EF89B705CCC825FC16C4AC5FD63D932901DE28AEEAB0DF883F44A6F0923B54A9477A3B521D8E12DD10453931E00E9F39F276EC07
+20210511033918 2 6 100 7679 2 C260CF005EEA851908A07073F58C88D37464F6C4353E3652C60C64BB441FAB9B7FB9F6CBB9D8073D3FE935B70EA1F508B2AF0E89899E9B6FD2B0E0583386A56CDADB39C1E362175A28F278B43A478B8506B1592C5A1DB8F33CE21C43CC5763DE1218C349755906B8D975B9DA963936BC01F7D79C5928C25E602D5B838892C62FDD61FAD8D0E189A70EC5891239BF69A75C87ACF1DC8DC50B359A9DC624FF7F92627B5D29748D84549AA6A831A35742E579A206F56DB0AD497AA834B877538C8045F3EE38A189AF9FFFBFC36FA4758EF1334DA487353514C0C406DB6B38E9327895D73DA4E92042EA6880336392E7E8342A1A7526816FEC68E95C995C9388779636AF8A45F54274EBDDD439AA16EE284FAF1E5459C99372083CF1531730F0354BF7E9C0733A3E785E82D99D270870B97D303F2A968C1469041D62277A14DFA2B279991C7E3C45DFEE93192650BF89D46218932FEB1C357EFA71A7F669F42FA4417F7053AEA70D43646CFDBCF7C05A1ABF53D1B5CA701BB6281097C600F951EDDEB258722C6EBA5A663BEB51CDA38D36584D6566BA1878558A7B2D32B28675D1FB2463C8C8AA5CC9CCBD733F3D741BDDC3F0F9532AAA1BB6E039F59B3CE4E5566440DEABF306861EAC945A4DDB2BC7E1B4096D92EB6901C7B83EB8980128935FCB70E82E855BBE41A9438BE84ACC738F818E5E3EDBA0AEE97CDB1634BABB6B1928BB43EDFB053DE5B3B4F0194A4D79D2EDB949D94B197F5D9406AAD368D5EEC0212A0BCA174F2BFFAACFAF2C51AE1F39DCDD849B04C0AE98935C80E62F63755F9B740343A28A5A7B93D8F5FA63E9C322BF46F484911A3B5581F9039F0A930E77AF641EEA0D1734D59B28B13280A9641382D3E489E069F2D659491F261B5FB7B4B7C7AE823D3C426FDEFD75734AD97DC4359E30BA7E99E073D8D6FD1C6B0F01006F33C829528E46565CE86F781228E2D22D7A5AA4C9E6B53DDACF380404CD9D2B2CDE31C6ECA679AA6A997AC53F9E9A429BFF636A008488447622ACFD6754E17048D0E7F7DF03CE0DE64F9FCAE47A46718D8212D620688A598D3B6AFEC54C762D4AE8AA0BA7B1AC97B8F9766BAF71EAE16D5E2B5614AC4FA5E20A0BCD622134AC7B08E00B8020D580F2C28CA1D15BDA1981CCE0E0AB5CDE942DFCC578EFF0C250B874E638705294A00724F9ED1329DA93179CAA869EE4BBAAD9F29993945745A5116840906BA4DCF9E303CE0947D4FD59C7964CC001882C001FB188697652B0A949624A983DA2099443191F6DD4EF89B705CCC825FC16C4AC5FD63D932901DE28AEEAB0DF883F44A6F0923B54A9477A3B521D8E12DD10453931E00E9F39F38CC9EB
+20210511041948 2 6 100 7679 5 C260CF005EEA851908A07073F58C88D37464F6C4353E3652C60C64BB441FAB9B7FB9F6CBB9D8073D3FE935B70EA1F508B2AF0E89899E9B6FD2B0E0583386A56CDADB39C1E362175A28F278B43A478B8506B1592C5A1DB8F33CE21C43CC5763DE1218C349755906B8D975B9DA963936BC01F7D79C5928C25E602D5B838892C62FDD61FAD8D0E189A70EC5891239BF69A75C87ACF1DC8DC50B359A9DC624FF7F92627B5D29748D84549AA6A831A35742E579A206F56DB0AD497AA834B877538C8045F3EE38A189AF9FFFBFC36FA4758EF1334DA487353514C0C406DB6B38E9327895D73DA4E92042EA6880336392E7E8342A1A7526816FEC68E95C995C9388779636AF8A45F54274EBDDD439AA16EE284FAF1E5459C99372083CF1531730F0354BF7E9C0733A3E785E82D99D270870B97D303F2A968C1469041D62277A14DFA2B279991C7E3C45DFEE93192650BF89D46218932FEB1C357EFA71A7F669F42FA4417F7053AEA70D43646CFDBCF7C05A1ABF53D1B5CA701BB6281097C600F951EDDEB258722C6EBA5A663BEB51CDA38D36584D6566BA1878558A7B2D32B28675D1FB2463C8C8AA5CC9CCBD733F3D741BDDC3F0F9532AAA1BB6E039F59B3CE4E5566440DEABF306861EAC945A4DDB2BC7E1B4096D92EB6901C7B83EB8980128935FCB70E82E855BBE41A9438BE84ACC738F818E5E3EDBA0AEE97CDB1634BABB6B1928BB43EDFB053DE5B3B4F0194A4D79D2EDB949D94B197F5D9406AAD368D5EEC0212A0BCA174F2BFFAACFAF2C51AE1F39DCDD849B04C0AE98935C80E62F63755F9B740343A28A5A7B93D8F5FA63E9C322BF46F484911A3B5581F9039F0A930E77AF641EEA0D1734D59B28B13280A9641382D3E489E069F2D659491F261B5FB7B4B7C7AE823D3C426FDEFD75734AD97DC4359E30BA7E99E073D8D6FD1C6B0F01006F33C829528E46565CE86F781228E2D22D7A5AA4C9E6B53DDACF380404CD9D2B2CDE31C6ECA679AA6A997AC53F9E9A429BFF636A008488447622ACFD6754E17048D0E7F7DF03CE0DE64F9FCAE47A46718D8212D620688A598D3B6AFEC54C762D4AE8AA0BA7B1AC97B8F9766BAF71EAE16D5E2B5614AC4FA5E20A0BCD622134AC7B08E00B8020D580F2C28CA1D15BDA1981CCE0E0AB5CDE942DFCC578EFF0C250B874E638705294A00724F9ED1329DA93179CAA869EE4BBAAD9F29993945745A5116840906BA4DCF9E303CE0947D4FD59C7964CC001882C001FB188697652B0A949624A983DA2099443191F6DD4EF89B705CCC825FC16C4AC5FD63D932901DE28AEEAB0DF883F44A6F0923B54A9477A3B521D8E12DD10453931E00E9F39F6EA1CBF
+20210511044846 2 6 100 7679 5 C260CF005EEA851908A07073F58C88D37464F6C4353E3652C60C64BB441FAB9B7FB9F6CBB9D8073D3FE935B70EA1F508B2AF0E89899E9B6FD2B0E0583386A56CDADB39C1E362175A28F278B43A478B8506B1592C5A1DB8F33CE21C43CC5763DE1218C349755906B8D975B9DA963936BC01F7D79C5928C25E602D5B838892C62FDD61FAD8D0E189A70EC5891239BF69A75C87ACF1DC8DC50B359A9DC624FF7F92627B5D29748D84549AA6A831A35742E579A206F56DB0AD497AA834B877538C8045F3EE38A189AF9FFFBFC36FA4758EF1334DA487353514C0C406DB6B38E9327895D73DA4E92042EA6880336392E7E8342A1A7526816FEC68E95C995C9388779636AF8A45F54274EBDDD439AA16EE284FAF1E5459C99372083CF1531730F0354BF7E9C0733A3E785E82D99D270870B97D303F2A968C1469041D62277A14DFA2B279991C7E3C45DFEE93192650BF89D46218932FEB1C357EFA71A7F669F42FA4417F7053AEA70D43646CFDBCF7C05A1ABF53D1B5CA701BB6281097C600F951EDDEB258722C6EBA5A663BEB51CDA38D36584D6566BA1878558A7B2D32B28675D1FB2463C8C8AA5CC9CCBD733F3D741BDDC3F0F9532AAA1BB6E039F59B3CE4E5566440DEABF306861EAC945A4DDB2BC7E1B4096D92EB6901C7B83EB8980128935FCB70E82E855BBE41A9438BE84ACC738F818E5E3EDBA0AEE97CDB1634BABB6B1928BB43EDFB053DE5B3B4F0194A4D79D2EDB949D94B197F5D9406AAD368D5EEC0212A0BCA174F2BFFAACFAF2C51AE1F39DCDD849B04C0AE98935C80E62F63755F9B740343A28A5A7B93D8F5FA63E9C322BF46F484911A3B5581F9039F0A930E77AF641EEA0D1734D59B28B13280A9641382D3E489E069F2D659491F261B5FB7B4B7C7AE823D3C426FDEFD75734AD97DC4359E30BA7E99E073D8D6FD1C6B0F01006F33C829528E46565CE86F781228E2D22D7A5AA4C9E6B53DDACF380404CD9D2B2CDE31C6ECA679AA6A997AC53F9E9A429BFF636A008488447622ACFD6754E17048D0E7F7DF03CE0DE64F9FCAE47A46718D8212D620688A598D3B6AFEC54C762D4AE8AA0BA7B1AC97B8F9766BAF71EAE16D5E2B5614AC4FA5E20A0BCD622134AC7B08E00B8020D580F2C28CA1D15BDA1981CCE0E0AB5CDE942DFCC578EFF0C250B874E638705294A00724F9ED1329DA93179CAA869EE4BBAAD9F29993945745A5116840906BA4DCF9E303CE0947D4FD59C7964CC001882C001FB188697652B0A949624A983DA2099443191F6DD4EF89B705CCC825FC16C4AC5FD63D932901DE28AEEAB0DF883F44A6F0923B54A9477A3B521D8E12DD10453931E00E9F39F9459AA7
+20210511045936 2 6 100 7679 5 C260CF005EEA851908A07073F58C88D37464F6C4353E3652C60C64BB441FAB9B7FB9F6CBB9D8073D3FE935B70EA1F508B2AF0E89899E9B6FD2B0E0583386A56CDADB39C1E362175A28F278B43A478B8506B1592C5A1DB8F33CE21C43CC5763DE1218C349755906B8D975B9DA963936BC01F7D79C5928C25E602D5B838892C62FDD61FAD8D0E189A70EC5891239BF69A75C87ACF1DC8DC50B359A9DC624FF7F92627B5D29748D84549AA6A831A35742E579A206F56DB0AD497AA834B877538C8045F3EE38A189AF9FFFBFC36FA4758EF1334DA487353514C0C406DB6B38E9327895D73DA4E92042EA6880336392E7E8342A1A7526816FEC68E95C995C9388779636AF8A45F54274EBDDD439AA16EE284FAF1E5459C99372083CF1531730F0354BF7E9C0733A3E785E82D99D270870B97D303F2A968C1469041D62277A14DFA2B279991C7E3C45DFEE93192650BF89D46218932FEB1C357EFA71A7F669F42FA4417F7053AEA70D43646CFDBCF7C05A1ABF53D1B5CA701BB6281097C600F951EDDEB258722C6EBA5A663BEB51CDA38D36584D6566BA1878558A7B2D32B28675D1FB2463C8C8AA5CC9CCBD733F3D741BDDC3F0F9532AAA1BB6E039F59B3CE4E5566440DEABF306861EAC945A4DDB2BC7E1B4096D92EB6901C7B83EB8980128935FCB70E82E855BBE41A9438BE84ACC738F818E5E3EDBA0AEE97CDB1634BABB6B1928BB43EDFB053DE5B3B4F0194A4D79D2EDB949D94B197F5D9406AAD368D5EEC0212A0BCA174F2BFFAACFAF2C51AE1F39DCDD849B04C0AE98935C80E62F63755F9B740343A28A5A7B93D8F5FA63E9C322BF46F484911A3B5581F9039F0A930E77AF641EEA0D1734D59B28B13280A9641382D3E489E069F2D659491F261B5FB7B4B7C7AE823D3C426FDEFD75734AD97DC4359E30BA7E99E073D8D6FD1C6B0F01006F33C829528E46565CE86F781228E2D22D7A5AA4C9E6B53DDACF380404CD9D2B2CDE31C6ECA679AA6A997AC53F9E9A429BFF636A008488447622ACFD6754E17048D0E7F7DF03CE0DE64F9FCAE47A46718D8212D620688A598D3B6AFEC54C762D4AE8AA0BA7B1AC97B8F9766BAF71EAE16D5E2B5614AC4FA5E20A0BCD622134AC7B08E00B8020D580F2C28CA1D15BDA1981CCE0E0AB5CDE942DFCC578EFF0C250B874E638705294A00724F9ED1329DA93179CAA869EE4BBAAD9F29993945745A5116840906BA4DCF9E303CE0947D4FD59C7964CC001882C001FB188697652B0A949624A983DA2099443191F6DD4EF89B705CCC825FC16C4AC5FD63D932901DE28AEEAB0DF883F44A6F0923B54A9477A3B521D8E12DD10453931E00E9F39FA227747
+20210511061456 2 6 100 7679 2 C260CF005EEA851908A07073F58C88D37464F6C4353E3652C60C64BB441FAB9B7FB9F6CBB9D8073D3FE935B70EA1F508B2AF0E89899E9B6FD2B0E0583386A56CDADB39C1E362175A28F278B43A478B8506B1592C5A1DB8F33CE21C43CC5763DE1218C349755906B8D975B9DA963936BC01F7D79C5928C25E602D5B838892C62FDD61FAD8D0E189A70EC5891239BF69A75C87ACF1DC8DC50B359A9DC624FF7F92627B5D29748D84549AA6A831A35742E579A206F56DB0AD497AA834B877538C8045F3EE38A189AF9FFFBFC36FA4758EF1334DA487353514C0C406DB6B38E9327895D73DA4E92042EA6880336392E7E8342A1A7526816FEC68E95C995C9388779636AF8A45F54274EBDDD439AA16EE284FAF1E5459C99372083CF1531730F0354BF7E9C0733A3E785E82D99D270870B97D303F2A968C1469041D62277A14DFA2B279991C7E3C45DFEE93192650BF89D46218932FEB1C357EFA71A7F669F42FA4417F7053AEA70D43646CFDBCF7C05A1ABF53D1B5CA701BB6281097C600F951EDDEB258722C6EBA5A663BEB51CDA38D36584D6566BA1878558A7B2D32B28675D1FB2463C8C8AA5CC9CCBD733F3D741BDDC3F0F9532AAA1BB6E039F59B3CE4E5566440DEABF306861EAC945A4DDB2BC7E1B4096D92EB6901C7B83EB8980128935FCB70E82E855BBE41A9438BE84ACC738F818E5E3EDBA0AEE97CDB1634BABB6B1928BB43EDFB053DE5B3B4F0194A4D79D2EDB949D94B197F5D9406AAD368D5EEC0212A0BCA174F2BFFAACFAF2C51AE1F39DCDD849B04C0AE98935C80E62F63755F9B740343A28A5A7B93D8F5FA63E9C322BF46F484911A3B5581F9039F0A930E77AF641EEA0D1734D59B28B13280A9641382D3E489E069F2D659491F261B5FB7B4B7C7AE823D3C426FDEFD75734AD97DC4359E30BA7E99E073D8D6FD1C6B0F01006F33C829528E46565CE86F781228E2D22D7A5AA4C9E6B53DDACF380404CD9D2B2CDE31C6ECA679AA6A997AC53F9E9A429BFF636A008488447622ACFD6754E17048D0E7F7DF03CE0DE64F9FCAE47A46718D8212D620688A598D3B6AFEC54C762D4AE8AA0BA7B1AC97B8F9766BAF71EAE16D5E2B5614AC4FA5E20A0BCD622134AC7B08E00B8020D580F2C28CA1D15BDA1981CCE0E0AB5CDE942DFCC578EFF0C250B874E638705294A00724F9ED1329DA93179CAA869EE4BBAAD9F29993945745A5116840906BA4DCF9E303CE0947D4FD59C7964CC001882C001FB188697652B0A949624A983DA2099443191F6DD4EF89B705CCC825FC16C4AC5FD63D932901DE28AEEAB0DF883F44A6F0923B54A9477A3B521D8E12DD10453931E00E9F3A0049A573
+20210511070958 2 6 100 7679 2 C260CF005EEA851908A07073F58C88D37464F6C4353E3652C60C64BB441FAB9B7FB9F6CBB9D8073D3FE935B70EA1F508B2AF0E89899E9B6FD2B0E0583386A56CDADB39C1E362175A28F278B43A478B8506B1592C5A1DB8F33CE21C43CC5763DE1218C349755906B8D975B9DA963936BC01F7D79C5928C25E602D5B838892C62FDD61FAD8D0E189A70EC5891239BF69A75C87ACF1DC8DC50B359A9DC624FF7F92627B5D29748D84549AA6A831A35742E579A206F56DB0AD497AA834B877538C8045F3EE38A189AF9FFFBFC36FA4758EF1334DA487353514C0C406DB6B38E9327895D73DA4E92042EA6880336392E7E8342A1A7526816FEC68E95C995C9388779636AF8A45F54274EBDDD439AA16EE284FAF1E5459C99372083CF1531730F0354BF7E9C0733A3E785E82D99D270870B97D303F2A968C1469041D62277A14DFA2B279991C7E3C45DFEE93192650BF89D46218932FEB1C357EFA71A7F669F42FA4417F7053AEA70D43646CFDBCF7C05A1ABF53D1B5CA701BB6281097C600F951EDDEB258722C6EBA5A663BEB51CDA38D36584D6566BA1878558A7B2D32B28675D1FB2463C8C8AA5CC9CCBD733F3D741BDDC3F0F9532AAA1BB6E039F59B3CE4E5566440DEABF306861EAC945A4DDB2BC7E1B4096D92EB6901C7B83EB8980128935FCB70E82E855BBE41A9438BE84ACC738F818E5E3EDBA0AEE97CDB1634BABB6B1928BB43EDFB053DE5B3B4F0194A4D79D2EDB949D94B197F5D9406AAD368D5EEC0212A0BCA174F2BFFAACFAF2C51AE1F39DCDD849B04C0AE98935C80E62F63755F9B740343A28A5A7B93D8F5FA63E9C322BF46F484911A3B5581F9039F0A930E77AF641EEA0D1734D59B28B13280A9641382D3E489E069F2D659491F261B5FB7B4B7C7AE823D3C426FDEFD75734AD97DC4359E30BA7E99E073D8D6FD1C6B0F01006F33C829528E46565CE86F781228E2D22D7A5AA4C9E6B53DDACF380404CD9D2B2CDE31C6ECA679AA6A997AC53F9E9A429BFF636A008488447622ACFD6754E17048D0E7F7DF03CE0DE64F9FCAE47A46718D8212D620688A598D3B6AFEC54C762D4AE8AA0BA7B1AC97B8F9766BAF71EAE16D5E2B5614AC4FA5E20A0BCD622134AC7B08E00B8020D580F2C28CA1D15BDA1981CCE0E0AB5CDE942DFCC578EFF0C250B874E638705294A00724F9ED1329DA93179CAA869EE4BBAAD9F29993945745A5116840906BA4DCF9E303CE0947D4FD59C7964CC001882C001FB188697652B0A949624A983DA2099443191F6DD4EF89B705CCC825FC16C4AC5FD63D932901DE28AEEAB0DF883F44A6F0923B54A9477A3B521D8E12DD10453931E00E9F3A04A6FA53
+20210511071633 2 6 100 7679 2 C260CF005EEA851908A07073F58C88D37464F6C4353E3652C60C64BB441FAB9B7FB9F6CBB9D8073D3FE935B70EA1F508B2AF0E89899E9B6FD2B0E0583386A56CDADB39C1E362175A28F278B43A478B8506B1592C5A1DB8F33CE21C43CC5763DE1218C349755906B8D975B9DA963936BC01F7D79C5928C25E602D5B838892C62FDD61FAD8D0E189A70EC5891239BF69A75C87ACF1DC8DC50B359A9DC624FF7F92627B5D29748D84549AA6A831A35742E579A206F56DB0AD497AA834B877538C8045F3EE38A189AF9FFFBFC36FA4758EF1334DA487353514C0C406DB6B38E9327895D73DA4E92042EA6880336392E7E8342A1A7526816FEC68E95C995C9388779636AF8A45F54274EBDDD439AA16EE284FAF1E5459C99372083CF1531730F0354BF7E9C0733A3E785E82D99D270870B97D303F2A968C1469041D62277A14DFA2B279991C7E3C45DFEE93192650BF89D46218932FEB1C357EFA71A7F669F42FA4417F7053AEA70D43646CFDBCF7C05A1ABF53D1B5CA701BB6281097C600F951EDDEB258722C6EBA5A663BEB51CDA38D36584D6566BA1878558A7B2D32B28675D1FB2463C8C8AA5CC9CCBD733F3D741BDDC3F0F9532AAA1BB6E039F59B3CE4E5566440DEABF306861EAC945A4DDB2BC7E1B4096D92EB6901C7B83EB8980128935FCB70E82E855BBE41A9438BE84ACC738F818E5E3EDBA0AEE97CDB1634BABB6B1928BB43EDFB053DE5B3B4F0194A4D79D2EDB949D94B197F5D9406AAD368D5EEC0212A0BCA174F2BFFAACFAF2C51AE1F39DCDD849B04C0AE98935C80E62F63755F9B740343A28A5A7B93D8F5FA63E9C322BF46F484911A3B5581F9039F0A930E77AF641EEA0D1734D59B28B13280A9641382D3E489E069F2D659491F261B5FB7B4B7C7AE823D3C426FDEFD75734AD97DC4359E30BA7E99E073D8D6FD1C6B0F01006F33C829528E46565CE86F781228E2D22D7A5AA4C9E6B53DDACF380404CD9D2B2CDE31C6ECA679AA6A997AC53F9E9A429BFF636A008488447622ACFD6754E17048D0E7F7DF03CE0DE64F9FCAE47A46718D8212D620688A598D3B6AFEC54C762D4AE8AA0BA7B1AC97B8F9766BAF71EAE16D5E2B5614AC4FA5E20A0BCD622134AC7B08E00B8020D580F2C28CA1D15BDA1981CCE0E0AB5CDE942DFCC578EFF0C250B874E638705294A00724F9ED1329DA93179CAA869EE4BBAAD9F29993945745A5116840906BA4DCF9E303CE0947D4FD59C7964CC001882C001FB188697652B0A949624A983DA2099443191F6DD4EF89B705CCC825FC16C4AC5FD63D932901DE28AEEAB0DF883F44A6F0923B54A9477A3B521D8E12DD10453931E00E9F3A0529E6FB
+20210511090443 2 6 100 7679 2 C260CF005EEA851908A07073F58C88D37464F6C4353E3652C60C64BB441FAB9B7FB9F6CBB9D8073D3FE935B70EA1F508B2AF0E89899E9B6FD2B0E0583386A56CDADB39C1E362175A28F278B43A478B8506B1592C5A1DB8F33CE21C43CC5763DE1218C349755906B8D975B9DA963936BC01F7D79C5928C25E602D5B838892C62FDD61FAD8D0E189A70EC5891239BF69A75C87ACF1DC8DC50B359A9DC624FF7F92627B5D29748D84549AA6A831A35742E579A206F56DB0AD497AA834B877538C8045F3EE38A189AF9FFFBFC36FA4758EF1334DA487353514C0C406DB6B38E9327895D73DA4E92042EA6880336392E7E8342A1A7526816FEC68E95C995C9388779636AF8A45F54274EBDDD439AA16EE284FAF1E5459C99372083CF1531730F0354BF7E9C0733A3E785E82D99D270870B97D303F2A968C1469041D62277A14DFA2B279991C7E3C45DFEE93192650BF89D46218932FEB1C357EFA71A7F669F42FA4417F7053AEA70D43646CFDBCF7C05A1ABF53D1B5CA701BB6281097C600F951EDDEB258722C6EBA5A663BEB51CDA38D36584D6566BA1878558A7B2D32B28675D1FB2463C8C8AA5CC9CCBD733F3D741BDDC3F0F9532AAA1BB6E039F59B3CE4E5566440DEABF306861EAC945A4DDB2BC7E1B4096D92EB6901C7B83EB8980128935FCB70E82E855BBE41A9438BE84ACC738F818E5E3EDBA0AEE97CDB1634BABB6B1928BB43EDFB053DE5B3B4F0194A4D79D2EDB949D94B197F5D9406AAD368D5EEC0212A0BCA174F2BFFAACFAF2C51AE1F39DCDD849B04C0AE98935C80E62F63755F9B740343A28A5A7B93D8F5FA63E9C322BF46F484911A3B5581F9039F0A930E77AF641EEA0D1734D59B28B13280A9641382D3E489E069F2D659491F261B5FB7B4B7C7AE823D3C426FDEFD75734AD97DC4359E30BA7E99E073D8D6FD1C6B0F01006F33C829528E46565CE86F781228E2D22D7A5AA4C9E6B53DDACF380404CD9D2B2CDE31C6ECA679AA6A997AC53F9E9A429BFF636A008488447622ACFD6754E17048D0E7F7DF03CE0DE64F9FCAE47A46718D8212D620688A598D3B6AFEC54C762D4AE8AA0BA7B1AC97B8F9766BAF71EAE16D5E2B5614AC4FA5E20A0BCD622134AC7B08E00B8020D580F2C28CA1D15BDA1981CCE0E0AB5CDE942DFCC578EFF0C250B874E638705294A00724F9ED1329DA93179CAA869EE4BBAAD9F29993945745A5116840906BA4DCF9E303CE0947D4FD59C7964CC001882C001FB188697652B0A949624A983DA2099443191F6DD4EF89B705CCC825FC16C4AC5FD63D932901DE28AEEAB0DF883F44A6F0923B54A9477A3B521D8E12DD10453931E00E9F3A0DE2A39B
+20210511091529 2 6 100 7679 2 C260CF005EEA851908A07073F58C88D37464F6C4353E3652C60C64BB441FAB9B7FB9F6CBB9D8073D3FE935B70EA1F508B2AF0E89899E9B6FD2B0E0583386A56CDADB39C1E362175A28F278B43A478B8506B1592C5A1DB8F33CE21C43CC5763DE1218C349755906B8D975B9DA963936BC01F7D79C5928C25E602D5B838892C62FDD61FAD8D0E189A70EC5891239BF69A75C87ACF1DC8DC50B359A9DC624FF7F92627B5D29748D84549AA6A831A35742E579A206F56DB0AD497AA834B877538C8045F3EE38A189AF9FFFBFC36FA4758EF1334DA487353514C0C406DB6B38E9327895D73DA4E92042EA6880336392E7E8342A1A7526816FEC68E95C995C9388779636AF8A45F54274EBDDD439AA16EE284FAF1E5459C99372083CF1531730F0354BF7E9C0733A3E785E82D99D270870B97D303F2A968C1469041D62277A14DFA2B279991C7E3C45DFEE93192650BF89D46218932FEB1C357EFA71A7F669F42FA4417F7053AEA70D43646CFDBCF7C05A1ABF53D1B5CA701BB6281097C600F951EDDEB258722C6EBA5A663BEB51CDA38D36584D6566BA1878558A7B2D32B28675D1FB2463C8C8AA5CC9CCBD733F3D741BDDC3F0F9532AAA1BB6E039F59B3CE4E5566440DEABF306861EAC945A4DDB2BC7E1B4096D92EB6901C7B83EB8980128935FCB70E82E855BBE41A9438BE84ACC738F818E5E3EDBA0AEE97CDB1634BABB6B1928BB43EDFB053DE5B3B4F0194A4D79D2EDB949D94B197F5D9406AAD368D5EEC0212A0BCA174F2BFFAACFAF2C51AE1F39DCDD849B04C0AE98935C80E62F63755F9B740343A28A5A7B93D8F5FA63E9C322BF46F484911A3B5581F9039F0A930E77AF641EEA0D1734D59B28B13280A9641382D3E489E069F2D659491F261B5FB7B4B7C7AE823D3C426FDEFD75734AD97DC4359E30BA7E99E073D8D6FD1C6B0F01006F33C829528E46565CE86F781228E2D22D7A5AA4C9E6B53DDACF380404CD9D2B2CDE31C6ECA679AA6A997AC53F9E9A429BFF636A008488447622ACFD6754E17048D0E7F7DF03CE0DE64F9FCAE47A46718D8212D620688A598D3B6AFEC54C762D4AE8AA0BA7B1AC97B8F9766BAF71EAE16D5E2B5614AC4FA5E20A0BCD622134AC7B08E00B8020D580F2C28CA1D15BDA1981CCE0E0AB5CDE942DFCC578EFF0C250B874E638705294A00724F9ED1329DA93179CAA869EE4BBAAD9F29993945745A5116840906BA4DCF9E303CE0947D4FD59C7964CC001882C001FB188697652B0A949624A983DA2099443191F6DD4EF89B705CCC825FC16C4AC5FD63D932901DE28AEEAB0DF883F44A6F0923B54A9477A3B521D8E12DD10453931E00E9F3A0EBA9D9B
+20210511092043 2 6 100 7679 2 C260CF005EEA851908A07073F58C88D37464F6C4353E3652C60C64BB441FAB9B7FB9F6CBB9D8073D3FE935B70EA1F508B2AF0E89899E9B6FD2B0E0583386A56CDADB39C1E362175A28F278B43A478B8506B1592C5A1DB8F33CE21C43CC5763DE1218C349755906B8D975B9DA963936BC01F7D79C5928C25E602D5B838892C62FDD61FAD8D0E189A70EC5891239BF69A75C87ACF1DC8DC50B359A9DC624FF7F92627B5D29748D84549AA6A831A35742E579A206F56DB0AD497AA834B877538C8045F3EE38A189AF9FFFBFC36FA4758EF1334DA487353514C0C406DB6B38E9327895D73DA4E92042EA6880336392E7E8342A1A7526816FEC68E95C995C9388779636AF8A45F54274EBDDD439AA16EE284FAF1E5459C99372083CF1531730F0354BF7E9C0733A3E785E82D99D270870B97D303F2A968C1469041D62277A14DFA2B279991C7E3C45DFEE93192650BF89D46218932FEB1C357EFA71A7F669F42FA4417F7053AEA70D43646CFDBCF7C05A1ABF53D1B5CA701BB6281097C600F951EDDEB258722C6EBA5A663BEB51CDA38D36584D6566BA1878558A7B2D32B28675D1FB2463C8C8AA5CC9CCBD733F3D741BDDC3F0F9532AAA1BB6E039F59B3CE4E5566440DEABF306861EAC945A4DDB2BC7E1B4096D92EB6901C7B83EB8980128935FCB70E82E855BBE41A9438BE84ACC738F818E5E3EDBA0AEE97CDB1634BABB6B1928BB43EDFB053DE5B3B4F0194A4D79D2EDB949D94B197F5D9406AAD368D5EEC0212A0BCA174F2BFFAACFAF2C51AE1F39DCDD849B04C0AE98935C80E62F63755F9B740343A28A5A7B93D8F5FA63E9C322BF46F484911A3B5581F9039F0A930E77AF641EEA0D1734D59B28B13280A9641382D3E489E069F2D659491F261B5FB7B4B7C7AE823D3C426FDEFD75734AD97DC4359E30BA7E99E073D8D6FD1C6B0F01006F33C829528E46565CE86F781228E2D22D7A5AA4C9E6B53DDACF380404CD9D2B2CDE31C6ECA679AA6A997AC53F9E9A429BFF636A008488447622ACFD6754E17048D0E7F7DF03CE0DE64F9FCAE47A46718D8212D620688A598D3B6AFEC54C762D4AE8AA0BA7B1AC97B8F9766BAF71EAE16D5E2B5614AC4FA5E20A0BCD622134AC7B08E00B8020D580F2C28CA1D15BDA1981CCE0E0AB5CDE942DFCC578EFF0C250B874E638705294A00724F9ED1329DA93179CAA869EE4BBAAD9F29993945745A5116840906BA4DCF9E303CE0947D4FD59C7964CC001882C001FB188697652B0A949624A983DA2099443191F6DD4EF89B705CCC825FC16C4AC5FD63D932901DE28AEEAB0DF883F44A6F0923B54A9477A3B521D8E12DD10453931E00E9F3A0F1F1753
+20210512033258 2 6 100 7679 2 C260CF005EEA851908A07073F58C88D37464F6C4353E3652C60C64BB441FAB9B7FB9F6CBB9D8073D3FE935B70EA1F508B2AF0E89899E9B6FD2B0E0583386A56CDADB39C1E362175A28F278B43A478B8506B1592C5A1DB8F33CE21C43CC5763DE1218C349755906B8D975B9DA963936BC01F7D79C5928C25E602D5B838892C62FDD61FAD8D0E189A70EC5891239BF69A75C87ACF1DC8DC50B359A9DC624FF7F92627B5D29748D84549AA6A831A35742E579A206F56DB0AD497AA834B877538C8045F3EE38A189AF9FFFBFC36FA4758EF1334DA487353514C0C406DB6B38E9327895D73DA4E92042EA6880336392E7E8342A1A7526816FEC68E95C995C9388779636AF8A45F54274EBDDD439AA16EE284FAF1E5459C99372083CF1531730F0354BF7E9C0733A3E785E82D99D270870B97D303F2A968C1469041D62277A14DFA2B279991C7E3C45DFEE93192650BF89D46218932FEB1C357EFA71A7F669F42FA4417F7053AEA70D43646CFDBCF7C05A1ABF53D1B5CA701BB6281097C600F951EDDEB258722C6EBA5A663BEB51CDA38D36584D6566BA1878558A7B2D32B28675D1FB2463C8C8AA5CC9CCBD733F3D741BDDC3F0F9532AAA1BB6E039F59B3CE4E5566440DEABF306861EAC945A4DDB2BC7E1B4096D92EB6901C7B83EB8980128935FCB70E82E855BBE41A9438BE84ACC738F818E5E3EDBA0AEE97CDB1634BABB6B1928BB43EDFB053DE5B3B4F0194A4D79D2EDB949D94B197F5D9406AAD368D5EEC0212A0BCA174F2BFFAACFAF2C51AE1F39DCDD849B04C0AE98935C80E62F63755F9B740343A28A5A7B93D8F5FA63E9C322BF46F484911A3B5581F9039F0A930E77AF641EEA0D1734D59B28B13280A9641382D3E489E069F2D659491F261B5FB7B4B7C7AE823D3C426FDEFD75734AD97DC4359E30BA7E99E073D8D6FD1C6B0F01006F33C829528E46565CE86F781228E2D22D7A5AA4C9E6B53DDACF380404CD9D2B2CDE31C6ECA679AA6A997AC53F9E9A429BFF636A008488447622ACFD6754E17048D0E7F7DF03CE0DE64F9FCAE47A46718D8212D620688A598D3B6AFEC54C762D4AE8AA0BA7B1AC97B8F9766BAF71EAE16D5E2B5614AC4FA5E20A0BCD622134AC7B08E00B8020D580F2C28CA1D15BDA1981CCE0E0AB5CDE942DFCC578EFF0C250B874E638705294A00724F9ED1329DA93179CAA869EE4BBAAD9F29993945745A5116840906BA4DCF9E303CE0947D4FD59C7964CC001882C001FB188697652B0A949624A983DA2099443191F6DD4EF89B705CCC825FC16C4AC5FD63D932901DE28AEEAB0DF883F44A6F0923B54A9477A3B521D8E12DD10453931E00E9F3A16919EA3
+20210512055407 2 6 100 7679 2 C260CF005EEA851908A07073F58C88D37464F6C4353E3652C60C64BB441FAB9B7FB9F6CBB9D8073D3FE935B70EA1F508B2AF0E89899E9B6FD2B0E0583386A56CDADB39C1E362175A28F278B43A478B8506B1592C5A1DB8F33CE21C43CC5763DE1218C349755906B8D975B9DA963936BC01F7D79C5928C25E602D5B838892C62FDD61FAD8D0E189A70EC5891239BF69A75C87ACF1DC8DC50B359A9DC624FF7F92627B5D29748D84549AA6A831A35742E579A206F56DB0AD497AA834B877538C8045F3EE38A189AF9FFFBFC36FA4758EF1334DA487353514C0C406DB6B38E9327895D73DA4E92042EA6880336392E7E8342A1A7526816FEC68E95C995C9388779636AF8A45F54274EBDDD439AA16EE284FAF1E5459C99372083CF1531730F0354BF7E9C0733A3E785E82D99D270870B97D303F2A968C1469041D62277A14DFA2B279991C7E3C45DFEE93192650BF89D46218932FEB1C357EFA71A7F669F42FA4417F7053AEA70D43646CFDBCF7C05A1ABF53D1B5CA701BB6281097C600F951EDDEB258722C6EBA5A663BEB51CDA38D36584D6566BA1878558A7B2D32B28675D1FB2463C8C8AA5CC9CCBD733F3D741BDDC3F0F9532AAA1BB6E039F59B3CE4E5566440DEABF306861EAC945A4DDB2BC7E1B4096D92EB6901C7B83EB8980128935FCB70E82E855BBE41A9438BE84ACC738F818E5E3EDBA0AEE97CDB1634BABB6B1928BB43EDFB053DE5B3B4F0194A4D79D2EDB949D94B197F5D9406AAD368D5EEC0212A0BCA174F2BFFAACFAF2C51AE1F39DCDD849B04C0AE98935C80E62F63755F9B740343A28A5A7B93D8F5FA63E9C322BF46F484911A3B5581F9039F0A930E77AF641EEA0D1734D59B28B13280A9641382D3E489E069F2D659491F261B5FB7B4B7C7AE823D3C426FDEFD75734AD97DC4359E30BA7E99E073D8D6FD1C6B0F01006F33C829528E46565CE86F781228E2D22D7A5AA4C9E6B53DDACF380404CD9D2B2CDE31C6ECA679AA6A997AC53F9E9A429BFF636A008488447622ACFD6754E17048D0E7F7DF03CE0DE64F9FCAE47A46718D8212D620688A598D3B6AFEC54C762D4AE8AA0BA7B1AC97B8F9766BAF71EAE16D5E2B5614AC4FA5E20A0BCD622134AC7B08E00B8020D580F2C28CA1D15BDA1981CCE0E0AB5CDE942DFCC578EFF0C250B874E638705294A00724F9ED1329DA93179CAA869EE4BBAAD9F29993945745A5116840906BA4DCF9E303CE0947D4FD59C7964CC001882C001FB188697652B0A949624A983DA2099443191F6DD4EF89B705CCC825FC16C4AC5FD63D932901DE28AEEAB0DF883F44A6F0923B54A9477A3B521D8E12DD10453931E00E9F3A217F863B
+20210512065219 2 6 100 7679 2 C260CF005EEA851908A07073F58C88D37464F6C4353E3652C60C64BB441FAB9B7FB9F6CBB9D8073D3FE935B70EA1F508B2AF0E89899E9B6FD2B0E0583386A56CDADB39C1E362175A28F278B43A478B8506B1592C5A1DB8F33CE21C43CC5763DE1218C349755906B8D975B9DA963936BC01F7D79C5928C25E602D5B838892C62FDD61FAD8D0E189A70EC5891239BF69A75C87ACF1DC8DC50B359A9DC624FF7F92627B5D29748D84549AA6A831A35742E579A206F56DB0AD497AA834B877538C8045F3EE38A189AF9FFFBFC36FA4758EF1334DA487353514C0C406DB6B38E9327895D73DA4E92042EA6880336392E7E8342A1A7526816FEC68E95C995C9388779636AF8A45F54274EBDDD439AA16EE284FAF1E5459C99372083CF1531730F0354BF7E9C0733A3E785E82D99D270870B97D303F2A968C1469041D62277A14DFA2B279991C7E3C45DFEE93192650BF89D46218932FEB1C357EFA71A7F669F42FA4417F7053AEA70D43646CFDBCF7C05A1ABF53D1B5CA701BB6281097C600F951EDDEB258722C6EBA5A663BEB51CDA38D36584D6566BA1878558A7B2D32B28675D1FB2463C8C8AA5CC9CCBD733F3D741BDDC3F0F9532AAA1BB6E039F59B3CE4E5566440DEABF306861EAC945A4DDB2BC7E1B4096D92EB6901C7B83EB8980128935FCB70E82E855BBE41A9438BE84ACC738F818E5E3EDBA0AEE97CDB1634BABB6B1928BB43EDFB053DE5B3B4F0194A4D79D2EDB949D94B197F5D9406AAD368D5EEC0212A0BCA174F2BFFAACFAF2C51AE1F39DCDD849B04C0AE98935C80E62F63755F9B740343A28A5A7B93D8F5FA63E9C322BF46F484911A3B5581F9039F0A930E77AF641EEA0D1734D59B28B13280A9641382D3E489E069F2D659491F261B5FB7B4B7C7AE823D3C426FDEFD75734AD97DC4359E30BA7E99E073D8D6FD1C6B0F01006F33C829528E46565CE86F781228E2D22D7A5AA4C9E6B53DDACF380404CD9D2B2CDE31C6ECA679AA6A997AC53F9E9A429BFF636A008488447622ACFD6754E17048D0E7F7DF03CE0DE64F9FCAE47A46718D8212D620688A598D3B6AFEC54C762D4AE8AA0BA7B1AC97B8F9766BAF71EAE16D5E2B5614AC4FA5E20A0BCD622134AC7B08E00B8020D580F2C28CA1D15BDA1981CCE0E0AB5CDE942DFCC578EFF0C250B874E638705294A00724F9ED1329DA93179CAA869EE4BBAAD9F29993945745A5116840906BA4DCF9E303CE0947D4FD59C7964CC001882C001FB188697652B0A949624A983DA2099443191F6DD4EF89B705CCC825FC16C4AC5FD63D932901DE28AEEAB0DF883F44A6F0923B54A9477A3B521D8E12DD10453931E00E9F3A2603970B
+20210512071046 2 6 100 7679 5 C260CF005EEA851908A07073F58C88D37464F6C4353E3652C60C64BB441FAB9B7FB9F6CBB9D8073D3FE935B70EA1F508B2AF0E89899E9B6FD2B0E0583386A56CDADB39C1E362175A28F278B43A478B8506B1592C5A1DB8F33CE21C43CC5763DE1218C349755906B8D975B9DA963936BC01F7D79C5928C25E602D5B838892C62FDD61FAD8D0E189A70EC5891239BF69A75C87ACF1DC8DC50B359A9DC624FF7F92627B5D29748D84549AA6A831A35742E579A206F56DB0AD497AA834B877538C8045F3EE38A189AF9FFFBFC36FA4758EF1334DA487353514C0C406DB6B38E9327895D73DA4E92042EA6880336392E7E8342A1A7526816FEC68E95C995C9388779636AF8A45F54274EBDDD439AA16EE284FAF1E5459C99372083CF1531730F0354BF7E9C0733A3E785E82D99D270870B97D303F2A968C1469041D62277A14DFA2B279991C7E3C45DFEE93192650BF89D46218932FEB1C357EFA71A7F669F42FA4417F7053AEA70D43646CFDBCF7C05A1ABF53D1B5CA701BB6281097C600F951EDDEB258722C6EBA5A663BEB51CDA38D36584D6566BA1878558A7B2D32B28675D1FB2463C8C8AA5CC9CCBD733F3D741BDDC3F0F9532AAA1BB6E039F59B3CE4E5566440DEABF306861EAC945A4DDB2BC7E1B4096D92EB6901C7B83EB8980128935FCB70E82E855BBE41A9438BE84ACC738F818E5E3EDBA0AEE97CDB1634BABB6B1928BB43EDFB053DE5B3B4F0194A4D79D2EDB949D94B197F5D9406AAD368D5EEC0212A0BCA174F2BFFAACFAF2C51AE1F39DCDD849B04C0AE98935C80E62F63755F9B740343A28A5A7B93D8F5FA63E9C322BF46F484911A3B5581F9039F0A930E77AF641EEA0D1734D59B28B13280A9641382D3E489E069F2D659491F261B5FB7B4B7C7AE823D3C426FDEFD75734AD97DC4359E30BA7E99E073D8D6FD1C6B0F01006F33C829528E46565CE86F781228E2D22D7A5AA4C9E6B53DDACF380404CD9D2B2CDE31C6ECA679AA6A997AC53F9E9A429BFF636A008488447622ACFD6754E17048D0E7F7DF03CE0DE64F9FCAE47A46718D8212D620688A598D3B6AFEC54C762D4AE8AA0BA7B1AC97B8F9766BAF71EAE16D5E2B5614AC4FA5E20A0BCD622134AC7B08E00B8020D580F2C28CA1D15BDA1981CCE0E0AB5CDE942DFCC578EFF0C250B874E638705294A00724F9ED1329DA93179CAA869EE4BBAAD9F29993945745A5116840906BA4DCF9E303CE0947D4FD59C7964CC001882C001FB188697652B0A949624A983DA2099443191F6DD4EF89B705CCC825FC16C4AC5FD63D932901DE28AEEAB0DF883F44A6F0923B54A9477A3B521D8E12DD10453931E00E9F3A27671DBF
+20210512080928 2 6 100 7679 2 C260CF005EEA851908A07073F58C88D37464F6C4353E3652C60C64BB441FAB9B7FB9F6CBB9D8073D3FE935B70EA1F508B2AF0E89899E9B6FD2B0E0583386A56CDADB39C1E362175A28F278B43A478B8506B1592C5A1DB8F33CE21C43CC5763DE1218C349755906B8D975B9DA963936BC01F7D79C5928C25E602D5B838892C62FDD61FAD8D0E189A70EC5891239BF69A75C87ACF1DC8DC50B359A9DC624FF7F92627B5D29748D84549AA6A831A35742E579A206F56DB0AD497AA834B877538C8045F3EE38A189AF9FFFBFC36FA4758EF1334DA487353514C0C406DB6B38E9327895D73DA4E92042EA6880336392E7E8342A1A7526816FEC68E95C995C9388779636AF8A45F54274EBDDD439AA16EE284FAF1E5459C99372083CF1531730F0354BF7E9C0733A3E785E82D99D270870B97D303F2A968C1469041D62277A14DFA2B279991C7E3C45DFEE93192650BF89D46218932FEB1C357EFA71A7F669F42FA4417F7053AEA70D43646CFDBCF7C05A1ABF53D1B5CA701BB6281097C600F951EDDEB258722C6EBA5A663BEB51CDA38D36584D6566BA1878558A7B2D32B28675D1FB2463C8C8AA5CC9CCBD733F3D741BDDC3F0F9532AAA1BB6E039F59B3CE4E5566440DEABF306861EAC945A4DDB2BC7E1B4096D92EB6901C7B83EB8980128935FCB70E82E855BBE41A9438BE84ACC738F818E5E3EDBA0AEE97CDB1634BABB6B1928BB43EDFB053DE5B3B4F0194A4D79D2EDB949D94B197F5D9406AAD368D5EEC0212A0BCA174F2BFFAACFAF2C51AE1F39DCDD849B04C0AE98935C80E62F63755F9B740343A28A5A7B93D8F5FA63E9C322BF46F484911A3B5581F9039F0A930E77AF641EEA0D1734D59B28B13280A9641382D3E489E069F2D659491F261B5FB7B4B7C7AE823D3C426FDEFD75734AD97DC4359E30BA7E99E073D8D6FD1C6B0F01006F33C829528E46565CE86F781228E2D22D7A5AA4C9E6B53DDACF380404CD9D2B2CDE31C6ECA679AA6A997AC53F9E9A429BFF636A008488447622ACFD6754E17048D0E7F7DF03CE0DE64F9FCAE47A46718D8212D620688A598D3B6AFEC54C762D4AE8AA0BA7B1AC97B8F9766BAF71EAE16D5E2B5614AC4FA5E20A0BCD622134AC7B08E00B8020D580F2C28CA1D15BDA1981CCE0E0AB5CDE942DFCC578EFF0C250B874E638705294A00724F9ED1329DA93179CAA869EE4BBAAD9F29993945745A5116840906BA4DCF9E303CE0947D4FD59C7964CC001882C001FB188697652B0A949624A983DA2099443191F6DD4EF89B705CCC825FC16C4AC5FD63D932901DE28AEEAB0DF883F44A6F0923B54A9477A3B521D8E12DD10453931E00E9F3A2BE5B26B
+20210512082250 2 6 100 7679 5 C260CF005EEA851908A07073F58C88D37464F6C4353E3652C60C64BB441FAB9B7FB9F6CBB9D8073D3FE935B70EA1F508B2AF0E89899E9B6FD2B0E0583386A56CDADB39C1E362175A28F278B43A478B8506B1592C5A1DB8F33CE21C43CC5763DE1218C349755906B8D975B9DA963936BC01F7D79C5928C25E602D5B838892C62FDD61FAD8D0E189A70EC5891239BF69A75C87ACF1DC8DC50B359A9DC624FF7F92627B5D29748D84549AA6A831A35742E579A206F56DB0AD497AA834B877538C8045F3EE38A189AF9FFFBFC36FA4758EF1334DA487353514C0C406DB6B38E9327895D73DA4E92042EA6880336392E7E8342A1A7526816FEC68E95C995C9388779636AF8A45F54274EBDDD439AA16EE284FAF1E5459C99372083CF1531730F0354BF7E9C0733A3E785E82D99D270870B97D303F2A968C1469041D62277A14DFA2B279991C7E3C45DFEE93192650BF89D46218932FEB1C357EFA71A7F669F42FA4417F7053AEA70D43646CFDBCF7C05A1ABF53D1B5CA701BB6281097C600F951EDDEB258722C6EBA5A663BEB51CDA38D36584D6566BA1878558A7B2D32B28675D1FB2463C8C8AA5CC9CCBD733F3D741BDDC3F0F9532AAA1BB6E039F59B3CE4E5566440DEABF306861EAC945A4DDB2BC7E1B4096D92EB6901C7B83EB8980128935FCB70E82E855BBE41A9438BE84ACC738F818E5E3EDBA0AEE97CDB1634BABB6B1928BB43EDFB053DE5B3B4F0194A4D79D2EDB949D94B197F5D9406AAD368D5EEC0212A0BCA174F2BFFAACFAF2C51AE1F39DCDD849B04C0AE98935C80E62F63755F9B740343A28A5A7B93D8F5FA63E9C322BF46F484911A3B5581F9039F0A930E77AF641EEA0D1734D59B28B13280A9641382D3E489E069F2D659491F261B5FB7B4B7C7AE823D3C426FDEFD75734AD97DC4359E30BA7E99E073D8D6FD1C6B0F01006F33C829528E46565CE86F781228E2D22D7A5AA4C9E6B53DDACF380404CD9D2B2CDE31C6ECA679AA6A997AC53F9E9A429BFF636A008488447622ACFD6754E17048D0E7F7DF03CE0DE64F9FCAE47A46718D8212D620688A598D3B6AFEC54C762D4AE8AA0BA7B1AC97B8F9766BAF71EAE16D5E2B5614AC4FA5E20A0BCD622134AC7B08E00B8020D580F2C28CA1D15BDA1981CCE0E0AB5CDE942DFCC578EFF0C250B874E638705294A00724F9ED1329DA93179CAA869EE4BBAAD9F29993945745A5116840906BA4DCF9E303CE0947D4FD59C7964CC001882C001FB188697652B0A949624A983DA2099443191F6DD4EF89B705CCC825FC16C4AC5FD63D932901DE28AEEAB0DF883F44A6F0923B54A9477A3B521D8E12DD10453931E00E9F3A2CE9961F
+20210512093942 2 6 100 7679 2 C260CF005EEA851908A07073F58C88D37464F6C4353E3652C60C64BB441FAB9B7FB9F6CBB9D8073D3FE935B70EA1F508B2AF0E89899E9B6FD2B0E0583386A56CDADB39C1E362175A28F278B43A478B8506B1592C5A1DB8F33CE21C43CC5763DE1218C349755906B8D975B9DA963936BC01F7D79C5928C25E602D5B838892C62FDD61FAD8D0E189A70EC5891239BF69A75C87ACF1DC8DC50B359A9DC624FF7F92627B5D29748D84549AA6A831A35742E579A206F56DB0AD497AA834B877538C8045F3EE38A189AF9FFFBFC36FA4758EF1334DA487353514C0C406DB6B38E9327895D73DA4E92042EA6880336392E7E8342A1A7526816FEC68E95C995C9388779636AF8A45F54274EBDDD439AA16EE284FAF1E5459C99372083CF1531730F0354BF7E9C0733A3E785E82D99D270870B97D303F2A968C1469041D62277A14DFA2B279991C7E3C45DFEE93192650BF89D46218932FEB1C357EFA71A7F669F42FA4417F7053AEA70D43646CFDBCF7C05A1ABF53D1B5CA701BB6281097C600F951EDDEB258722C6EBA5A663BEB51CDA38D36584D6566BA1878558A7B2D32B28675D1FB2463C8C8AA5CC9CCBD733F3D741BDDC3F0F9532AAA1BB6E039F59B3CE4E5566440DEABF306861EAC945A4DDB2BC7E1B4096D92EB6901C7B83EB8980128935FCB70E82E855BBE41A9438BE84ACC738F818E5E3EDBA0AEE97CDB1634BABB6B1928BB43EDFB053DE5B3B4F0194A4D79D2EDB949D94B197F5D9406AAD368D5EEC0212A0BCA174F2BFFAACFAF2C51AE1F39DCDD849B04C0AE98935C80E62F63755F9B740343A28A5A7B93D8F5FA63E9C322BF46F484911A3B5581F9039F0A930E77AF641EEA0D1734D59B28B13280A9641382D3E489E069F2D659491F261B5FB7B4B7C7AE823D3C426FDEFD75734AD97DC4359E30BA7E99E073D8D6FD1C6B0F01006F33C829528E46565CE86F781228E2D22D7A5AA4C9E6B53DDACF380404CD9D2B2CDE31C6ECA679AA6A997AC53F9E9A429BFF636A008488447622ACFD6754E17048D0E7F7DF03CE0DE64F9FCAE47A46718D8212D620688A598D3B6AFEC54C762D4AE8AA0BA7B1AC97B8F9766BAF71EAE16D5E2B5614AC4FA5E20A0BCD622134AC7B08E00B8020D580F2C28CA1D15BDA1981CCE0E0AB5CDE942DFCC578EFF0C250B874E638705294A00724F9ED1329DA93179CAA869EE4BBAAD9F29993945745A5116840906BA4DCF9E303CE0947D4FD59C7964CC001882C001FB188697652B0A949624A983DA2099443191F6DD4EF89B705CCC825FC16C4AC5FD63D932901DE28AEEAB0DF883F44A6F0923B54A9477A3B521D8E12DD10453931E00E9F3A32BF8C6B
+20210512101658 2 6 100 7679 2 C260CF005EEA851908A07073F58C88D37464F6C4353E3652C60C64BB441FAB9B7FB9F6CBB9D8073D3FE935B70EA1F508B2AF0E89899E9B6FD2B0E0583386A56CDADB39C1E362175A28F278B43A478B8506B1592C5A1DB8F33CE21C43CC5763DE1218C349755906B8D975B9DA963936BC01F7D79C5928C25E602D5B838892C62FDD61FAD8D0E189A70EC5891239BF69A75C87ACF1DC8DC50B359A9DC624FF7F92627B5D29748D84549AA6A831A35742E579A206F56DB0AD497AA834B877538C8045F3EE38A189AF9FFFBFC36FA4758EF1334DA487353514C0C406DB6B38E9327895D73DA4E92042EA6880336392E7E8342A1A7526816FEC68E95C995C9388779636AF8A45F54274EBDDD439AA16EE284FAF1E5459C99372083CF1531730F0354BF7E9C0733A3E785E82D99D270870B97D303F2A968C1469041D62277A14DFA2B279991C7E3C45DFEE93192650BF89D46218932FEB1C357EFA71A7F669F42FA4417F7053AEA70D43646CFDBCF7C05A1ABF53D1B5CA701BB6281097C600F951EDDEB258722C6EBA5A663BEB51CDA38D36584D6566BA1878558A7B2D32B28675D1FB2463C8C8AA5CC9CCBD733F3D741BDDC3F0F9532AAA1BB6E039F59B3CE4E5566440DEABF306861EAC945A4DDB2BC7E1B4096D92EB6901C7B83EB8980128935FCB70E82E855BBE41A9438BE84ACC738F818E5E3EDBA0AEE97CDB1634BABB6B1928BB43EDFB053DE5B3B4F0194A4D79D2EDB949D94B197F5D9406AAD368D5EEC0212A0BCA174F2BFFAACFAF2C51AE1F39DCDD849B04C0AE98935C80E62F63755F9B740343A28A5A7B93D8F5FA63E9C322BF46F484911A3B5581F9039F0A930E77AF641EEA0D1734D59B28B13280A9641382D3E489E069F2D659491F261B5FB7B4B7C7AE823D3C426FDEFD75734AD97DC4359E30BA7E99E073D8D6FD1C6B0F01006F33C829528E46565CE86F781228E2D22D7A5AA4C9E6B53DDACF380404CD9D2B2CDE31C6ECA679AA6A997AC53F9E9A429BFF636A008488447622ACFD6754E17048D0E7F7DF03CE0DE64F9FCAE47A46718D8212D620688A598D3B6AFEC54C762D4AE8AA0BA7B1AC97B8F9766BAF71EAE16D5E2B5614AC4FA5E20A0BCD622134AC7B08E00B8020D580F2C28CA1D15BDA1981CCE0E0AB5CDE942DFCC578EFF0C250B874E638705294A00724F9ED1329DA93179CAA869EE4BBAAD9F29993945745A5116840906BA4DCF9E303CE0947D4FD59C7964CC001882C001FB188697652B0A949624A983DA2099443191F6DD4EF89B705CCC825FC16C4AC5FD63D932901DE28AEEAB0DF883F44A6F0923B54A9477A3B521D8E12DD10453931E00E9F3A358BA32B
+20210512111206 2 6 100 7679 2 C260CF005EEA851908A07073F58C88D37464F6C4353E3652C60C64BB441FAB9B7FB9F6CBB9D8073D3FE935B70EA1F508B2AF0E89899E9B6FD2B0E0583386A56CDADB39C1E362175A28F278B43A478B8506B1592C5A1DB8F33CE21C43CC5763DE1218C349755906B8D975B9DA963936BC01F7D79C5928C25E602D5B838892C62FDD61FAD8D0E189A70EC5891239BF69A75C87ACF1DC8DC50B359A9DC624FF7F92627B5D29748D84549AA6A831A35742E579A206F56DB0AD497AA834B877538C8045F3EE38A189AF9FFFBFC36FA4758EF1334DA487353514C0C406DB6B38E9327895D73DA4E92042EA6880336392E7E8342A1A7526816FEC68E95C995C9388779636AF8A45F54274EBDDD439AA16EE284FAF1E5459C99372083CF1531730F0354BF7E9C0733A3E785E82D99D270870B97D303F2A968C1469041D62277A14DFA2B279991C7E3C45DFEE93192650BF89D46218932FEB1C357EFA71A7F669F42FA4417F7053AEA70D43646CFDBCF7C05A1ABF53D1B5CA701BB6281097C600F951EDDEB258722C6EBA5A663BEB51CDA38D36584D6566BA1878558A7B2D32B28675D1FB2463C8C8AA5CC9CCBD733F3D741BDDC3F0F9532AAA1BB6E039F59B3CE4E5566440DEABF306861EAC945A4DDB2BC7E1B4096D92EB6901C7B83EB8980128935FCB70E82E855BBE41A9438BE84ACC738F818E5E3EDBA0AEE97CDB1634BABB6B1928BB43EDFB053DE5B3B4F0194A4D79D2EDB949D94B197F5D9406AAD368D5EEC0212A0BCA174F2BFFAACFAF2C51AE1F39DCDD849B04C0AE98935C80E62F63755F9B740343A28A5A7B93D8F5FA63E9C322BF46F484911A3B5581F9039F0A930E77AF641EEA0D1734D59B28B13280A9641382D3E489E069F2D659491F261B5FB7B4B7C7AE823D3C426FDEFD75734AD97DC4359E30BA7E99E073D8D6FD1C6B0F01006F33C829528E46565CE86F781228E2D22D7A5AA4C9E6B53DDACF380404CD9D2B2CDE31C6ECA679AA6A997AC53F9E9A429BFF636A008488447622ACFD6754E17048D0E7F7DF03CE0DE64F9FCAE47A46718D8212D620688A598D3B6AFEC54C762D4AE8AA0BA7B1AC97B8F9766BAF71EAE16D5E2B5614AC4FA5E20A0BCD622134AC7B08E00B8020D580F2C28CA1D15BDA1981CCE0E0AB5CDE942DFCC578EFF0C250B874E638705294A00724F9ED1329DA93179CAA869EE4BBAAD9F29993945745A5116840906BA4DCF9E303CE0947D4FD59C7964CC001882C001FB188697652B0A949624A983DA2099443191F6DD4EF89B705CCC825FC16C4AC5FD63D932901DE28AEEAB0DF883F44A6F0923B54A9477A3B521D8E12DD10453931E00E9F3A39AF5083
+20210512111445 2 6 100 7679 5 C260CF005EEA851908A07073F58C88D37464F6C4353E3652C60C64BB441FAB9B7FB9F6CBB9D8073D3FE935B70EA1F508B2AF0E89899E9B6FD2B0E0583386A56CDADB39C1E362175A28F278B43A478B8506B1592C5A1DB8F33CE21C43CC5763DE1218C349755906B8D975B9DA963936BC01F7D79C5928C25E602D5B838892C62FDD61FAD8D0E189A70EC5891239BF69A75C87ACF1DC8DC50B359A9DC624FF7F92627B5D29748D84549AA6A831A35742E579A206F56DB0AD497AA834B877538C8045F3EE38A189AF9FFFBFC36FA4758EF1334DA487353514C0C406DB6B38E9327895D73DA4E92042EA6880336392E7E8342A1A7526816FEC68E95C995C9388779636AF8A45F54274EBDDD439AA16EE284FAF1E5459C99372083CF1531730F0354BF7E9C0733A3E785E82D99D270870B97D303F2A968C1469041D62277A14DFA2B279991C7E3C45DFEE93192650BF89D46218932FEB1C357EFA71A7F669F42FA4417F7053AEA70D43646CFDBCF7C05A1ABF53D1B5CA701BB6281097C600F951EDDEB258722C6EBA5A663BEB51CDA38D36584D6566BA1878558A7B2D32B28675D1FB2463C8C8AA5CC9CCBD733F3D741BDDC3F0F9532AAA1BB6E039F59B3CE4E5566440DEABF306861EAC945A4DDB2BC7E1B4096D92EB6901C7B83EB8980128935FCB70E82E855BBE41A9438BE84ACC738F818E5E3EDBA0AEE97CDB1634BABB6B1928BB43EDFB053DE5B3B4F0194A4D79D2EDB949D94B197F5D9406AAD368D5EEC0212A0BCA174F2BFFAACFAF2C51AE1F39DCDD849B04C0AE98935C80E62F63755F9B740343A28A5A7B93D8F5FA63E9C322BF46F484911A3B5581F9039F0A930E77AF641EEA0D1734D59B28B13280A9641382D3E489E069F2D659491F261B5FB7B4B7C7AE823D3C426FDEFD75734AD97DC4359E30BA7E99E073D8D6FD1C6B0F01006F33C829528E46565CE86F781228E2D22D7A5AA4C9E6B53DDACF380404CD9D2B2CDE31C6ECA679AA6A997AC53F9E9A429BFF636A008488447622ACFD6754E17048D0E7F7DF03CE0DE64F9FCAE47A46718D8212D620688A598D3B6AFEC54C762D4AE8AA0BA7B1AC97B8F9766BAF71EAE16D5E2B5614AC4FA5E20A0BCD622134AC7B08E00B8020D580F2C28CA1D15BDA1981CCE0E0AB5CDE942DFCC578EFF0C250B874E638705294A00724F9ED1329DA93179CAA869EE4BBAAD9F29993945745A5116840906BA4DCF9E303CE0947D4FD59C7964CC001882C001FB188697652B0A949624A983DA2099443191F6DD4EF89B705CCC825FC16C4AC5FD63D932901DE28AEEAB0DF883F44A6F0923B54A9477A3B521D8E12DD10453931E00E9F3A39D9B197
+20210512111520 2 6 100 7679 2 C260CF005EEA851908A07073F58C88D37464F6C4353E3652C60C64BB441FAB9B7FB9F6CBB9D8073D3FE935B70EA1F508B2AF0E89899E9B6FD2B0E0583386A56CDADB39C1E362175A28F278B43A478B8506B1592C5A1DB8F33CE21C43CC5763DE1218C349755906B8D975B9DA963936BC01F7D79C5928C25E602D5B838892C62FDD61FAD8D0E189A70EC5891239BF69A75C87ACF1DC8DC50B359A9DC624FF7F92627B5D29748D84549AA6A831A35742E579A206F56DB0AD497AA834B877538C8045F3EE38A189AF9FFFBFC36FA4758EF1334DA487353514C0C406DB6B38E9327895D73DA4E92042EA6880336392E7E8342A1A7526816FEC68E95C995C9388779636AF8A45F54274EBDDD439AA16EE284FAF1E5459C99372083CF1531730F0354BF7E9C0733A3E785E82D99D270870B97D303F2A968C1469041D62277A14DFA2B279991C7E3C45DFEE93192650BF89D46218932FEB1C357EFA71A7F669F42FA4417F7053AEA70D43646CFDBCF7C05A1ABF53D1B5CA701BB6281097C600F951EDDEB258722C6EBA5A663BEB51CDA38D36584D6566BA1878558A7B2D32B28675D1FB2463C8C8AA5CC9CCBD733F3D741BDDC3F0F9532AAA1BB6E039F59B3CE4E5566440DEABF306861EAC945A4DDB2BC7E1B4096D92EB6901C7B83EB8980128935FCB70E82E855BBE41A9438BE84ACC738F818E5E3EDBA0AEE97CDB1634BABB6B1928BB43EDFB053DE5B3B4F0194A4D79D2EDB949D94B197F5D9406AAD368D5EEC0212A0BCA174F2BFFAACFAF2C51AE1F39DCDD849B04C0AE98935C80E62F63755F9B740343A28A5A7B93D8F5FA63E9C322BF46F484911A3B5581F9039F0A930E77AF641EEA0D1734D59B28B13280A9641382D3E489E069F2D659491F261B5FB7B4B7C7AE823D3C426FDEFD75734AD97DC4359E30BA7E99E073D8D6FD1C6B0F01006F33C829528E46565CE86F781228E2D22D7A5AA4C9E6B53DDACF380404CD9D2B2CDE31C6ECA679AA6A997AC53F9E9A429BFF636A008488447622ACFD6754E17048D0E7F7DF03CE0DE64F9FCAE47A46718D8212D620688A598D3B6AFEC54C762D4AE8AA0BA7B1AC97B8F9766BAF71EAE16D5E2B5614AC4FA5E20A0BCD622134AC7B08E00B8020D580F2C28CA1D15BDA1981CCE0E0AB5CDE942DFCC578EFF0C250B874E638705294A00724F9ED1329DA93179CAA869EE4BBAAD9F29993945745A5116840906BA4DCF9E303CE0947D4FD59C7964CC001882C001FB188697652B0A949624A983DA2099443191F6DD4EF89B705CCC825FC16C4AC5FD63D932901DE28AEEAB0DF883F44A6F0923B54A9477A3B521D8E12DD10453931E00E9F3A39DC61F3
+20210512120145 2 6 100 7679 5 C260CF005EEA851908A07073F58C88D37464F6C4353E3652C60C64BB441FAB9B7FB9F6CBB9D8073D3FE935B70EA1F508B2AF0E89899E9B6FD2B0E0583386A56CDADB39C1E362175A28F278B43A478B8506B1592C5A1DB8F33CE21C43CC5763DE1218C349755906B8D975B9DA963936BC01F7D79C5928C25E602D5B838892C62FDD61FAD8D0E189A70EC5891239BF69A75C87ACF1DC8DC50B359A9DC624FF7F92627B5D29748D84549AA6A831A35742E579A206F56DB0AD497AA834B877538C8045F3EE38A189AF9FFFBFC36FA4758EF1334DA487353514C0C406DB6B38E9327895D73DA4E92042EA6880336392E7E8342A1A7526816FEC68E95C995C9388779636AF8A45F54274EBDDD439AA16EE284FAF1E5459C99372083CF1531730F0354BF7E9C0733A3E785E82D99D270870B97D303F2A968C1469041D62277A14DFA2B279991C7E3C45DFEE93192650BF89D46218932FEB1C357EFA71A7F669F42FA4417F7053AEA70D43646CFDBCF7C05A1ABF53D1B5CA701BB6281097C600F951EDDEB258722C6EBA5A663BEB51CDA38D36584D6566BA1878558A7B2D32B28675D1FB2463C8C8AA5CC9CCBD733F3D741BDDC3F0F9532AAA1BB6E039F59B3CE4E5566440DEABF306861EAC945A4DDB2BC7E1B4096D92EB6901C7B83EB8980128935FCB70E82E855BBE41A9438BE84ACC738F818E5E3EDBA0AEE97CDB1634BABB6B1928BB43EDFB053DE5B3B4F0194A4D79D2EDB949D94B197F5D9406AAD368D5EEC0212A0BCA174F2BFFAACFAF2C51AE1F39DCDD849B04C0AE98935C80E62F63755F9B740343A28A5A7B93D8F5FA63E9C322BF46F484911A3B5581F9039F0A930E77AF641EEA0D1734D59B28B13280A9641382D3E489E069F2D659491F261B5FB7B4B7C7AE823D3C426FDEFD75734AD97DC4359E30BA7E99E073D8D6FD1C6B0F01006F33C829528E46565CE86F781228E2D22D7A5AA4C9E6B53DDACF380404CD9D2B2CDE31C6ECA679AA6A997AC53F9E9A429BFF636A008488447622ACFD6754E17048D0E7F7DF03CE0DE64F9FCAE47A46718D8212D620688A598D3B6AFEC54C762D4AE8AA0BA7B1AC97B8F9766BAF71EAE16D5E2B5614AC4FA5E20A0BCD622134AC7B08E00B8020D580F2C28CA1D15BDA1981CCE0E0AB5CDE942DFCC578EFF0C250B874E638705294A00724F9ED1329DA93179CAA869EE4BBAAD9F29993945745A5116840906BA4DCF9E303CE0947D4FD59C7964CC001882C001FB188697652B0A949624A983DA2099443191F6DD4EF89B705CCC825FC16C4AC5FD63D932901DE28AEEAB0DF883F44A6F0923B54A9477A3B521D8E12DD10453931E00E9F3A3D4F7B0F
+20210512135337 2 6 100 7679 2 C260CF005EEA851908A07073F58C88D37464F6C4353E3652C60C64BB441FAB9B7FB9F6CBB9D8073D3FE935B70EA1F508B2AF0E89899E9B6FD2B0E0583386A56CDADB39C1E362175A28F278B43A478B8506B1592C5A1DB8F33CE21C43CC5763DE1218C349755906B8D975B9DA963936BC01F7D79C5928C25E602D5B838892C62FDD61FAD8D0E189A70EC5891239BF69A75C87ACF1DC8DC50B359A9DC624FF7F92627B5D29748D84549AA6A831A35742E579A206F56DB0AD497AA834B877538C8045F3EE38A189AF9FFFBFC36FA4758EF1334DA487353514C0C406DB6B38E9327895D73DA4E92042EA6880336392E7E8342A1A7526816FEC68E95C995C9388779636AF8A45F54274EBDDD439AA16EE284FAF1E5459C99372083CF1531730F0354BF7E9C0733A3E785E82D99D270870B97D303F2A968C1469041D62277A14DFA2B279991C7E3C45DFEE93192650BF89D46218932FEB1C357EFA71A7F669F42FA4417F7053AEA70D43646CFDBCF7C05A1ABF53D1B5CA701BB6281097C600F951EDDEB258722C6EBA5A663BEB51CDA38D36584D6566BA1878558A7B2D32B28675D1FB2463C8C8AA5CC9CCBD733F3D741BDDC3F0F9532AAA1BB6E039F59B3CE4E5566440DEABF306861EAC945A4DDB2BC7E1B4096D92EB6901C7B83EB8980128935FCB70E82E855BBE41A9438BE84ACC738F818E5E3EDBA0AEE97CDB1634BABB6B1928BB43EDFB053DE5B3B4F0194A4D79D2EDB949D94B197F5D9406AAD368D5EEC0212A0BCA174F2BFFAACFAF2C51AE1F39DCDD849B04C0AE98935C80E62F63755F9B740343A28A5A7B93D8F5FA63E9C322BF46F484911A3B5581F9039F0A930E77AF641EEA0D1734D59B28B13280A9641382D3E489E069F2D659491F261B5FB7B4B7C7AE823D3C426FDEFD75734AD97DC4359E30BA7E99E073D8D6FD1C6B0F01006F33C829528E46565CE86F781228E2D22D7A5AA4C9E6B53DDACF380404CD9D2B2CDE31C6ECA679AA6A997AC53F9E9A429BFF636A008488447622ACFD6754E17048D0E7F7DF03CE0DE64F9FCAE47A46718D8212D620688A598D3B6AFEC54C762D4AE8AA0BA7B1AC97B8F9766BAF71EAE16D5E2B5614AC4FA5E20A0BCD622134AC7B08E00B8020D580F2C28CA1D15BDA1981CCE0E0AB5CDE942DFCC578EFF0C250B874E638705294A00724F9ED1329DA93179CAA869EE4BBAAD9F29993945745A5116840906BA4DCF9E303CE0947D4FD59C7964CC001882C001FB188697652B0A949624A983DA2099443191F6DD4EF89B705CCC825FC16C4AC5FD63D932901DE28AEEAB0DF883F44A6F0923B54A9477A3B521D8E12DD10453931E00E9F3A45A535C3
+20210512141816 2 6 100 7679 5 FAFDEC5D38380C2FFBEDCDA1262E4817F274B6544BB0A1904CF571375327EDF0105410A3F584F9A15982937EB5A64E30206DA90D66B89BF48EC74E7F40FB957673193875E02B88101A4FE81C47EBCB8451386AAEC6EA69F967310C79D8CC71BE07F669C3094E5F2CD314FF0FDD08256EFDFC03EF43C4704684CEEBBBFC48D48C920B2AC3CC15010D7EE49049D52B12E6E9228BF0482C174747EA40E558D88CACA9F143A496236C120DE560FDD7B2A1175407D333103C025E8EAE424AC5BADA1A354428B451F594BE605000CA3B2773B2D91FEDBBAF2E58DE2F03461A9F8D90B84209F66D7203E92774AB5B83809BAFFCC8D32ACB1B0AD4D1C2D37CED00654FB7517A56FE35CD364967D541D336C0E2CF96303B3BD1FBBC12D5DCF3D8F343BD2DD0EA3B5FA0062DC9A426A36DD27FD9C8E76DBB7FFE97BA3B27BDE53B017D7C9DFA6A4354FC95F3DAD99172290423EB507B574D6CEAF38A4AE227FD44541A29560020EA2EC10C5213E1EBC7A686AFA770A09C28E0D1EFB46AD409D2C58B8A4EF2E740957BCE903FF63D0B5E6BCF7E8C2B8F85DB93FC96E78BE2002603FF9AC2ACF368269FE034D6A5F8BFC6249FD140E85E9435C8B03D9390F1D0FD44519C21D174F7901BAB95DE7C91A1BFB9EB1079C584A71392A72768B2C2748145835AE7A5509B3C59539F46B5E0DF6955B84687C454679C9D87198605D78D1B551F502A5ACD915F55C919763C2F1206A0ADD5F651031A76EA0D102D064CBE24F919D3CF333D1EA0E89C1CA9E7D115802FC38757A50C97849D41E03C5F1EB8485CDDB55464E44172B0DE3D4F94A5AD01ECE4D70E17181225418F4205ABA526FA1D8C493749243D626C1D6A3170AD9D7DA551F3642229428803E81782D49355CB6CCEE08AB7583CA3A73354F2942BC6225E07788E542B1E2A9B46724D8A8EE0BE6F79CCDF78B10FC78FF3E15FFBC2EF1FFF4F53A328C7850BC0DAF358823712FF3609B981377D64FD274C578FFE92A6AE74F6F6A37907BD6B71FDA8C492C15BF9F820360709CFE9C5DFB03196120DF85D7D730DBA4CDFC36F2760227A5EAA27AA255935616A3833609B890B2445FC82D7A70B798DCB71E7C5B868AF06577FDDD034B63FF8A5CEEE3A1BBCD4CC61AF7A21D812E5987B35EF262FCCDFE85FF02E21E95C20C66357D8C813C672AFF03D9B4023E94E4397596BEA7F642D14DDA48D455EE0EBC7979D7AAD8994DC9A0DB84F1EE247C71E3D3A5626455CABC9C91BBAA98E2DD96EDA9EC0CDE2130236907A41D227CC515E1B139D278BC9F1DC231BDBDD76C400564D3200B2F61980B679BE9D8BF9D37BA5C0CB681E5054431A61CBF3979EBF1F48AF
+20210512151944 2 6 100 7679 5 FAFDEC5D38380C2FFBEDCDA1262E4817F274B6544BB0A1904CF571375327EDF0105410A3F584F9A15982937EB5A64E30206DA90D66B89BF48EC74E7F40FB957673193875E02B88101A4FE81C47EBCB8451386AAEC6EA69F967310C79D8CC71BE07F669C3094E5F2CD314FF0FDD08256EFDFC03EF43C4704684CEEBBBFC48D48C920B2AC3CC15010D7EE49049D52B12E6E9228BF0482C174747EA40E558D88CACA9F143A496236C120DE560FDD7B2A1175407D333103C025E8EAE424AC5BADA1A354428B451F594BE605000CA3B2773B2D91FEDBBAF2E58DE2F03461A9F8D90B84209F66D7203E92774AB5B83809BAFFCC8D32ACB1B0AD4D1C2D37CED00654FB7517A56FE35CD364967D541D336C0E2CF96303B3BD1FBBC12D5DCF3D8F343BD2DD0EA3B5FA0062DC9A426A36DD27FD9C8E76DBB7FFE97BA3B27BDE53B017D7C9DFA6A4354FC95F3DAD99172290423EB507B574D6CEAF38A4AE227FD44541A29560020EA2EC10C5213E1EBC7A686AFA770A09C28E0D1EFB46AD409D2C58B8A4EF2E740957BCE903FF63D0B5E6BCF7E8C2B8F85DB93FC96E78BE2002603FF9AC2ACF368269FE034D6A5F8BFC6249FD140E85E9435C8B03D9390F1D0FD44519C21D174F7901BAB95DE7C91A1BFB9EB1079C584A71392A72768B2C2748145835AE7A5509B3C59539F46B5E0DF6955B84687C454679C9D87198605D78D1B551F502A5ACD915F55C919763C2F1206A0ADD5F651031A76EA0D102D064CBE24F919D3CF333D1EA0E89C1CA9E7D115802FC38757A50C97849D41E03C5F1EB8485CDDB55464E44172B0DE3D4F94A5AD01ECE4D70E17181225418F4205ABA526FA1D8C493749243D626C1D6A3170AD9D7DA551F3642229428803E81782D49355CB6CCEE08AB7583CA3A73354F2942BC6225E07788E542B1E2A9B46724D8A8EE0BE6F79CCDF78B10FC78FF3E15FFBC2EF1FFF4F53A328C7850BC0DAF358823712FF3609B981377D64FD274C578FFE92A6AE74F6F6A37907BD6B71FDA8C492C15BF9F820360709CFE9C5DFB03196120DF85D7D730DBA4CDFC36F2760227A5EAA27AA255935616A3833609B890B2445FC82D7A70B798DCB71E7C5B868AF06577FDDD034B63FF8A5CEEE3A1BBCD4CC61AF7A21D812E5987B35EF262FCCDFE85FF02E21E95C20C66357D8C813C672AFF03D9B4023E94E4397596BEA7F642D14DDA48D455EE0EBC7979D7AAD8994DC9A0DB84F1EE247C71E3D3A5626455CABC9C91BBAA98E2DD96EDA9EC0CDE2130236907A41D227CC515E1B139D278BC9F1DC231BDBDD76C400564D3200B2F61980B679BE9D8BF9D37BA5C0CB681E5054431A61CBF3979EC46EAC57
+20210512152457 2 6 100 7679 5 FAFDEC5D38380C2FFBEDCDA1262E4817F274B6544BB0A1904CF571375327EDF0105410A3F584F9A15982937EB5A64E30206DA90D66B89BF48EC74E7F40FB957673193875E02B88101A4FE81C47EBCB8451386AAEC6EA69F967310C79D8CC71BE07F669C3094E5F2CD314FF0FDD08256EFDFC03EF43C4704684CEEBBBFC48D48C920B2AC3CC15010D7EE49049D52B12E6E9228BF0482C174747EA40E558D88CACA9F143A496236C120DE560FDD7B2A1175407D333103C025E8EAE424AC5BADA1A354428B451F594BE605000CA3B2773B2D91FEDBBAF2E58DE2F03461A9F8D90B84209F66D7203E92774AB5B83809BAFFCC8D32ACB1B0AD4D1C2D37CED00654FB7517A56FE35CD364967D541D336C0E2CF96303B3BD1FBBC12D5DCF3D8F343BD2DD0EA3B5FA0062DC9A426A36DD27FD9C8E76DBB7FFE97BA3B27BDE53B017D7C9DFA6A4354FC95F3DAD99172290423EB507B574D6CEAF38A4AE227FD44541A29560020EA2EC10C5213E1EBC7A686AFA770A09C28E0D1EFB46AD409D2C58B8A4EF2E740957BCE903FF63D0B5E6BCF7E8C2B8F85DB93FC96E78BE2002603FF9AC2ACF368269FE034D6A5F8BFC6249FD140E85E9435C8B03D9390F1D0FD44519C21D174F7901BAB95DE7C91A1BFB9EB1079C584A71392A72768B2C2748145835AE7A5509B3C59539F46B5E0DF6955B84687C454679C9D87198605D78D1B551F502A5ACD915F55C919763C2F1206A0ADD5F651031A76EA0D102D064CBE24F919D3CF333D1EA0E89C1CA9E7D115802FC38757A50C97849D41E03C5F1EB8485CDDB55464E44172B0DE3D4F94A5AD01ECE4D70E17181225418F4205ABA526FA1D8C493749243D626C1D6A3170AD9D7DA551F3642229428803E81782D49355CB6CCEE08AB7583CA3A73354F2942BC6225E07788E542B1E2A9B46724D8A8EE0BE6F79CCDF78B10FC78FF3E15FFBC2EF1FFF4F53A328C7850BC0DAF358823712FF3609B981377D64FD274C578FFE92A6AE74F6F6A37907BD6B71FDA8C492C15BF9F820360709CFE9C5DFB03196120DF85D7D730DBA4CDFC36F2760227A5EAA27AA255935616A3833609B890B2445FC82D7A70B798DCB71E7C5B868AF06577FDDD034B63FF8A5CEEE3A1BBCD4CC61AF7A21D812E5987B35EF262FCCDFE85FF02E21E95C20C66357D8C813C672AFF03D9B4023E94E4397596BEA7F642D14DDA48D455EE0EBC7979D7AAD8994DC9A0DB84F1EE247C71E3D3A5626455CABC9C91BBAA98E2DD96EDA9EC0CDE2130236907A41D227CC515E1B139D278BC9F1DC231BDBDD76C400564D3200B2F61980B679BE9D8BF9D37BA5C0CB681E5054431A61CBF3979EC4D2E37F
+20210512160220 2 6 100 7679 5 FAFDEC5D38380C2FFBEDCDA1262E4817F274B6544BB0A1904CF571375327EDF0105410A3F584F9A15982937EB5A64E30206DA90D66B89BF48EC74E7F40FB957673193875E02B88101A4FE81C47EBCB8451386AAEC6EA69F967310C79D8CC71BE07F669C3094E5F2CD314FF0FDD08256EFDFC03EF43C4704684CEEBBBFC48D48C920B2AC3CC15010D7EE49049D52B12E6E9228BF0482C174747EA40E558D88CACA9F143A496236C120DE560FDD7B2A1175407D333103C025E8EAE424AC5BADA1A354428B451F594BE605000CA3B2773B2D91FEDBBAF2E58DE2F03461A9F8D90B84209F66D7203E92774AB5B83809BAFFCC8D32ACB1B0AD4D1C2D37CED00654FB7517A56FE35CD364967D541D336C0E2CF96303B3BD1FBBC12D5DCF3D8F343BD2DD0EA3B5FA0062DC9A426A36DD27FD9C8E76DBB7FFE97BA3B27BDE53B017D7C9DFA6A4354FC95F3DAD99172290423EB507B574D6CEAF38A4AE227FD44541A29560020EA2EC10C5213E1EBC7A686AFA770A09C28E0D1EFB46AD409D2C58B8A4EF2E740957BCE903FF63D0B5E6BCF7E8C2B8F85DB93FC96E78BE2002603FF9AC2ACF368269FE034D6A5F8BFC6249FD140E85E9435C8B03D9390F1D0FD44519C21D174F7901BAB95DE7C91A1BFB9EB1079C584A71392A72768B2C2748145835AE7A5509B3C59539F46B5E0DF6955B84687C454679C9D87198605D78D1B551F502A5ACD915F55C919763C2F1206A0ADD5F651031A76EA0D102D064CBE24F919D3CF333D1EA0E89C1CA9E7D115802FC38757A50C97849D41E03C5F1EB8485CDDB55464E44172B0DE3D4F94A5AD01ECE4D70E17181225418F4205ABA526FA1D8C493749243D626C1D6A3170AD9D7DA551F3642229428803E81782D49355CB6CCEE08AB7583CA3A73354F2942BC6225E07788E542B1E2A9B46724D8A8EE0BE6F79CCDF78B10FC78FF3E15FFBC2EF1FFF4F53A328C7850BC0DAF358823712FF3609B981377D64FD274C578FFE92A6AE74F6F6A37907BD6B71FDA8C492C15BF9F820360709CFE9C5DFB03196120DF85D7D730DBA4CDFC36F2760227A5EAA27AA255935616A3833609B890B2445FC82D7A70B798DCB71E7C5B868AF06577FDDD034B63FF8A5CEEE3A1BBCD4CC61AF7A21D812E5987B35EF262FCCDFE85FF02E21E95C20C66357D8C813C672AFF03D9B4023E94E4397596BEA7F642D14DDA48D455EE0EBC7979D7AAD8994DC9A0DB84F1EE247C71E3D3A5626455CABC9C91BBAA98E2DD96EDA9EC0CDE2130236907A41D227CC515E1B139D278BC9F1DC231BDBDD76C400564D3200B2F61980B679BE9D8BF9D37BA5C0CB681E5054431A61CBF3979EC805627F
+20210512161859 2 6 100 7679 2 FAFDEC5D38380C2FFBEDCDA1262E4817F274B6544BB0A1904CF571375327EDF0105410A3F584F9A15982937EB5A64E30206DA90D66B89BF48EC74E7F40FB957673193875E02B88101A4FE81C47EBCB8451386AAEC6EA69F967310C79D8CC71BE07F669C3094E5F2CD314FF0FDD08256EFDFC03EF43C4704684CEEBBBFC48D48C920B2AC3CC15010D7EE49049D52B12E6E9228BF0482C174747EA40E558D88CACA9F143A496236C120DE560FDD7B2A1175407D333103C025E8EAE424AC5BADA1A354428B451F594BE605000CA3B2773B2D91FEDBBAF2E58DE2F03461A9F8D90B84209F66D7203E92774AB5B83809BAFFCC8D32ACB1B0AD4D1C2D37CED00654FB7517A56FE35CD364967D541D336C0E2CF96303B3BD1FBBC12D5DCF3D8F343BD2DD0EA3B5FA0062DC9A426A36DD27FD9C8E76DBB7FFE97BA3B27BDE53B017D7C9DFA6A4354FC95F3DAD99172290423EB507B574D6CEAF38A4AE227FD44541A29560020EA2EC10C5213E1EBC7A686AFA770A09C28E0D1EFB46AD409D2C58B8A4EF2E740957BCE903FF63D0B5E6BCF7E8C2B8F85DB93FC96E78BE2002603FF9AC2ACF368269FE034D6A5F8BFC6249FD140E85E9435C8B03D9390F1D0FD44519C21D174F7901BAB95DE7C91A1BFB9EB1079C584A71392A72768B2C2748145835AE7A5509B3C59539F46B5E0DF6955B84687C454679C9D87198605D78D1B551F502A5ACD915F55C919763C2F1206A0ADD5F651031A76EA0D102D064CBE24F919D3CF333D1EA0E89C1CA9E7D115802FC38757A50C97849D41E03C5F1EB8485CDDB55464E44172B0DE3D4F94A5AD01ECE4D70E17181225418F4205ABA526FA1D8C493749243D626C1D6A3170AD9D7DA551F3642229428803E81782D49355CB6CCEE08AB7583CA3A73354F2942BC6225E07788E542B1E2A9B46724D8A8EE0BE6F79CCDF78B10FC78FF3E15FFBC2EF1FFF4F53A328C7850BC0DAF358823712FF3609B981377D64FD274C578FFE92A6AE74F6F6A37907BD6B71FDA8C492C15BF9F820360709CFE9C5DFB03196120DF85D7D730DBA4CDFC36F2760227A5EAA27AA255935616A3833609B890B2445FC82D7A70B798DCB71E7C5B868AF06577FDDD034B63FF8A5CEEE3A1BBCD4CC61AF7A21D812E5987B35EF262FCCDFE85FF02E21E95C20C66357D8C813C672AFF03D9B4023E94E4397596BEA7F642D14DDA48D455EE0EBC7979D7AAD8994DC9A0DB84F1EE247C71E3D3A5626455CABC9C91BBAA98E2DD96EDA9EC0CDE2130236907A41D227CC515E1B139D278BC9F1DC231BDBDD76C400564D3200B2F61980B679BE9D8BF9D37BA5C0CB681E5054431A61CBF3979EC96E198B
+20210512165622 2 6 100 7679 5 FAFDEC5D38380C2FFBEDCDA1262E4817F274B6544BB0A1904CF571375327EDF0105410A3F584F9A15982937EB5A64E30206DA90D66B89BF48EC74E7F40FB957673193875E02B88101A4FE81C47EBCB8451386AAEC6EA69F967310C79D8CC71BE07F669C3094E5F2CD314FF0FDD08256EFDFC03EF43C4704684CEEBBBFC48D48C920B2AC3CC15010D7EE49049D52B12E6E9228BF0482C174747EA40E558D88CACA9F143A496236C120DE560FDD7B2A1175407D333103C025E8EAE424AC5BADA1A354428B451F594BE605000CA3B2773B2D91FEDBBAF2E58DE2F03461A9F8D90B84209F66D7203E92774AB5B83809BAFFCC8D32ACB1B0AD4D1C2D37CED00654FB7517A56FE35CD364967D541D336C0E2CF96303B3BD1FBBC12D5DCF3D8F343BD2DD0EA3B5FA0062DC9A426A36DD27FD9C8E76DBB7FFE97BA3B27BDE53B017D7C9DFA6A4354FC95F3DAD99172290423EB507B574D6CEAF38A4AE227FD44541A29560020EA2EC10C5213E1EBC7A686AFA770A09C28E0D1EFB46AD409D2C58B8A4EF2E740957BCE903FF63D0B5E6BCF7E8C2B8F85DB93FC96E78BE2002603FF9AC2ACF368269FE034D6A5F8BFC6249FD140E85E9435C8B03D9390F1D0FD44519C21D174F7901BAB95DE7C91A1BFB9EB1079C584A71392A72768B2C2748145835AE7A5509B3C59539F46B5E0DF6955B84687C454679C9D87198605D78D1B551F502A5ACD915F55C919763C2F1206A0ADD5F651031A76EA0D102D064CBE24F919D3CF333D1EA0E89C1CA9E7D115802FC38757A50C97849D41E03C5F1EB8485CDDB55464E44172B0DE3D4F94A5AD01ECE4D70E17181225418F4205ABA526FA1D8C493749243D626C1D6A3170AD9D7DA551F3642229428803E81782D49355CB6CCEE08AB7583CA3A73354F2942BC6225E07788E542B1E2A9B46724D8A8EE0BE6F79CCDF78B10FC78FF3E15FFBC2EF1FFF4F53A328C7850BC0DAF358823712FF3609B981377D64FD274C578FFE92A6AE74F6F6A37907BD6B71FDA8C492C15BF9F820360709CFE9C5DFB03196120DF85D7D730DBA4CDFC36F2760227A5EAA27AA255935616A3833609B890B2445FC82D7A70B798DCB71E7C5B868AF06577FDDD034B63FF8A5CEEE3A1BBCD4CC61AF7A21D812E5987B35EF262FCCDFE85FF02E21E95C20C66357D8C813C672AFF03D9B4023E94E4397596BEA7F642D14DDA48D455EE0EBC7979D7AAD8994DC9A0DB84F1EE247C71E3D3A5626455CABC9C91BBAA98E2DD96EDA9EC0CDE2130236907A41D227CC515E1B139D278BC9F1DC231BDBDD76C400564D3200B2F61980B679BE9D8BF9D37BA5C0CB681E5054431A61CBF3979ECC946B97
+20210512182636 2 6 100 7679 2 FAFDEC5D38380C2FFBEDCDA1262E4817F274B6544BB0A1904CF571375327EDF0105410A3F584F9A15982937EB5A64E30206DA90D66B89BF48EC74E7F40FB957673193875E02B88101A4FE81C47EBCB8451386AAEC6EA69F967310C79D8CC71BE07F669C3094E5F2CD314FF0FDD08256EFDFC03EF43C4704684CEEBBBFC48D48C920B2AC3CC15010D7EE49049D52B12E6E9228BF0482C174747EA40E558D88CACA9F143A496236C120DE560FDD7B2A1175407D333103C025E8EAE424AC5BADA1A354428B451F594BE605000CA3B2773B2D91FEDBBAF2E58DE2F03461A9F8D90B84209F66D7203E92774AB5B83809BAFFCC8D32ACB1B0AD4D1C2D37CED00654FB7517A56FE35CD364967D541D336C0E2CF96303B3BD1FBBC12D5DCF3D8F343BD2DD0EA3B5FA0062DC9A426A36DD27FD9C8E76DBB7FFE97BA3B27BDE53B017D7C9DFA6A4354FC95F3DAD99172290423EB507B574D6CEAF38A4AE227FD44541A29560020EA2EC10C5213E1EBC7A686AFA770A09C28E0D1EFB46AD409D2C58B8A4EF2E740957BCE903FF63D0B5E6BCF7E8C2B8F85DB93FC96E78BE2002603FF9AC2ACF368269FE034D6A5F8BFC6249FD140E85E9435C8B03D9390F1D0FD44519C21D174F7901BAB95DE7C91A1BFB9EB1079C584A71392A72768B2C2748145835AE7A5509B3C59539F46B5E0DF6955B84687C454679C9D87198605D78D1B551F502A5ACD915F55C919763C2F1206A0ADD5F651031A76EA0D102D064CBE24F919D3CF333D1EA0E89C1CA9E7D115802FC38757A50C97849D41E03C5F1EB8485CDDB55464E44172B0DE3D4F94A5AD01ECE4D70E17181225418F4205ABA526FA1D8C493749243D626C1D6A3170AD9D7DA551F3642229428803E81782D49355CB6CCEE08AB7583CA3A73354F2942BC6225E07788E542B1E2A9B46724D8A8EE0BE6F79CCDF78B10FC78FF3E15FFBC2EF1FFF4F53A328C7850BC0DAF358823712FF3609B981377D64FD274C578FFE92A6AE74F6F6A37907BD6B71FDA8C492C15BF9F820360709CFE9C5DFB03196120DF85D7D730DBA4CDFC36F2760227A5EAA27AA255935616A3833609B890B2445FC82D7A70B798DCB71E7C5B868AF06577FDDD034B63FF8A5CEEE3A1BBCD4CC61AF7A21D812E5987B35EF262FCCDFE85FF02E21E95C20C66357D8C813C672AFF03D9B4023E94E4397596BEA7F642D14DDA48D455EE0EBC7979D7AAD8994DC9A0DB84F1EE247C71E3D3A5626455CABC9C91BBAA98E2DD96EDA9EC0CDE2130236907A41D227CC515E1B139D278BC9F1DC231BDBDD76C400564D3200B2F61980B679BE9D8BF9D37BA5C0CB681E5054431A61CBF3979ED42A027B
+20210512183805 2 6 100 7679 2 FAFDEC5D38380C2FFBEDCDA1262E4817F274B6544BB0A1904CF571375327EDF0105410A3F584F9A15982937EB5A64E30206DA90D66B89BF48EC74E7F40FB957673193875E02B88101A4FE81C47EBCB8451386AAEC6EA69F967310C79D8CC71BE07F669C3094E5F2CD314FF0FDD08256EFDFC03EF43C4704684CEEBBBFC48D48C920B2AC3CC15010D7EE49049D52B12E6E9228BF0482C174747EA40E558D88CACA9F143A496236C120DE560FDD7B2A1175407D333103C025E8EAE424AC5BADA1A354428B451F594BE605000CA3B2773B2D91FEDBBAF2E58DE2F03461A9F8D90B84209F66D7203E92774AB5B83809BAFFCC8D32ACB1B0AD4D1C2D37CED00654FB7517A56FE35CD364967D541D336C0E2CF96303B3BD1FBBC12D5DCF3D8F343BD2DD0EA3B5FA0062DC9A426A36DD27FD9C8E76DBB7FFE97BA3B27BDE53B017D7C9DFA6A4354FC95F3DAD99172290423EB507B574D6CEAF38A4AE227FD44541A29560020EA2EC10C5213E1EBC7A686AFA770A09C28E0D1EFB46AD409D2C58B8A4EF2E740957BCE903FF63D0B5E6BCF7E8C2B8F85DB93FC96E78BE2002603FF9AC2ACF368269FE034D6A5F8BFC6249FD140E85E9435C8B03D9390F1D0FD44519C21D174F7901BAB95DE7C91A1BFB9EB1079C584A71392A72768B2C2748145835AE7A5509B3C59539F46B5E0DF6955B84687C454679C9D87198605D78D1B551F502A5ACD915F55C919763C2F1206A0ADD5F651031A76EA0D102D064CBE24F919D3CF333D1EA0E89C1CA9E7D115802FC38757A50C97849D41E03C5F1EB8485CDDB55464E44172B0DE3D4F94A5AD01ECE4D70E17181225418F4205ABA526FA1D8C493749243D626C1D6A3170AD9D7DA551F3642229428803E81782D49355CB6CCEE08AB7583CA3A73354F2942BC6225E07788E542B1E2A9B46724D8A8EE0BE6F79CCDF78B10FC78FF3E15FFBC2EF1FFF4F53A328C7850BC0DAF358823712FF3609B981377D64FD274C578FFE92A6AE74F6F6A37907BD6B71FDA8C492C15BF9F820360709CFE9C5DFB03196120DF85D7D730DBA4CDFC36F2760227A5EAA27AA255935616A3833609B890B2445FC82D7A70B798DCB71E7C5B868AF06577FDDD034B63FF8A5CEEE3A1BBCD4CC61AF7A21D812E5987B35EF262FCCDFE85FF02E21E95C20C66357D8C813C672AFF03D9B4023E94E4397596BEA7F642D14DDA48D455EE0EBC7979D7AAD8994DC9A0DB84F1EE247C71E3D3A5626455CABC9C91BBAA98E2DD96EDA9EC0CDE2130236907A41D227CC515E1B139D278BC9F1DC231BDBDD76C400564D3200B2F61980B679BE9D8BF9D37BA5C0CB681E5054431A61CBF3979ED519CAFB
+20210512184521 2 6 100 7679 5 FAFDEC5D38380C2FFBEDCDA1262E4817F274B6544BB0A1904CF571375327EDF0105410A3F584F9A15982937EB5A64E30206DA90D66B89BF48EC74E7F40FB957673193875E02B88101A4FE81C47EBCB8451386AAEC6EA69F967310C79D8CC71BE07F669C3094E5F2CD314FF0FDD08256EFDFC03EF43C4704684CEEBBBFC48D48C920B2AC3CC15010D7EE49049D52B12E6E9228BF0482C174747EA40E558D88CACA9F143A496236C120DE560FDD7B2A1175407D333103C025E8EAE424AC5BADA1A354428B451F594BE605000CA3B2773B2D91FEDBBAF2E58DE2F03461A9F8D90B84209F66D7203E92774AB5B83809BAFFCC8D32ACB1B0AD4D1C2D37CED00654FB7517A56FE35CD364967D541D336C0E2CF96303B3BD1FBBC12D5DCF3D8F343BD2DD0EA3B5FA0062DC9A426A36DD27FD9C8E76DBB7FFE97BA3B27BDE53B017D7C9DFA6A4354FC95F3DAD99172290423EB507B574D6CEAF38A4AE227FD44541A29560020EA2EC10C5213E1EBC7A686AFA770A09C28E0D1EFB46AD409D2C58B8A4EF2E740957BCE903FF63D0B5E6BCF7E8C2B8F85DB93FC96E78BE2002603FF9AC2ACF368269FE034D6A5F8BFC6249FD140E85E9435C8B03D9390F1D0FD44519C21D174F7901BAB95DE7C91A1BFB9EB1079C584A71392A72768B2C2748145835AE7A5509B3C59539F46B5E0DF6955B84687C454679C9D87198605D78D1B551F502A5ACD915F55C919763C2F1206A0ADD5F651031A76EA0D102D064CBE24F919D3CF333D1EA0E89C1CA9E7D115802FC38757A50C97849D41E03C5F1EB8485CDDB55464E44172B0DE3D4F94A5AD01ECE4D70E17181225418F4205ABA526FA1D8C493749243D626C1D6A3170AD9D7DA551F3642229428803E81782D49355CB6CCEE08AB7583CA3A73354F2942BC6225E07788E542B1E2A9B46724D8A8EE0BE6F79CCDF78B10FC78FF3E15FFBC2EF1FFF4F53A328C7850BC0DAF358823712FF3609B981377D64FD274C578FFE92A6AE74F6F6A37907BD6B71FDA8C492C15BF9F820360709CFE9C5DFB03196120DF85D7D730DBA4CDFC36F2760227A5EAA27AA255935616A3833609B890B2445FC82D7A70B798DCB71E7C5B868AF06577FDDD034B63FF8A5CEEE3A1BBCD4CC61AF7A21D812E5987B35EF262FCCDFE85FF02E21E95C20C66357D8C813C672AFF03D9B4023E94E4397596BEA7F642D14DDA48D455EE0EBC7979D7AAD8994DC9A0DB84F1EE247C71E3D3A5626455CABC9C91BBAA98E2DD96EDA9EC0CDE2130236907A41D227CC515E1B139D278BC9F1DC231BDBDD76C400564D3200B2F61980B679BE9D8BF9D37BA5C0CB681E5054431A61CBF3979ED5AD365F
+20210512185310 2 6 100 7679 2 FAFDEC5D38380C2FFBEDCDA1262E4817F274B6544BB0A1904CF571375327EDF0105410A3F584F9A15982937EB5A64E30206DA90D66B89BF48EC74E7F40FB957673193875E02B88101A4FE81C47EBCB8451386AAEC6EA69F967310C79D8CC71BE07F669C3094E5F2CD314FF0FDD08256EFDFC03EF43C4704684CEEBBBFC48D48C920B2AC3CC15010D7EE49049D52B12E6E9228BF0482C174747EA40E558D88CACA9F143A496236C120DE560FDD7B2A1175407D333103C025E8EAE424AC5BADA1A354428B451F594BE605000CA3B2773B2D91FEDBBAF2E58DE2F03461A9F8D90B84209F66D7203E92774AB5B83809BAFFCC8D32ACB1B0AD4D1C2D37CED00654FB7517A56FE35CD364967D541D336C0E2CF96303B3BD1FBBC12D5DCF3D8F343BD2DD0EA3B5FA0062DC9A426A36DD27FD9C8E76DBB7FFE97BA3B27BDE53B017D7C9DFA6A4354FC95F3DAD99172290423EB507B574D6CEAF38A4AE227FD44541A29560020EA2EC10C5213E1EBC7A686AFA770A09C28E0D1EFB46AD409D2C58B8A4EF2E740957BCE903FF63D0B5E6BCF7E8C2B8F85DB93FC96E78BE2002603FF9AC2ACF368269FE034D6A5F8BFC6249FD140E85E9435C8B03D9390F1D0FD44519C21D174F7901BAB95DE7C91A1BFB9EB1079C584A71392A72768B2C2748145835AE7A5509B3C59539F46B5E0DF6955B84687C454679C9D87198605D78D1B551F502A5ACD915F55C919763C2F1206A0ADD5F651031A76EA0D102D064CBE24F919D3CF333D1EA0E89C1CA9E7D115802FC38757A50C97849D41E03C5F1EB8485CDDB55464E44172B0DE3D4F94A5AD01ECE4D70E17181225418F4205ABA526FA1D8C493749243D626C1D6A3170AD9D7DA551F3642229428803E81782D49355CB6CCEE08AB7583CA3A73354F2942BC6225E07788E542B1E2A9B46724D8A8EE0BE6F79CCDF78B10FC78FF3E15FFBC2EF1FFF4F53A328C7850BC0DAF358823712FF3609B981377D64FD274C578FFE92A6AE74F6F6A37907BD6B71FDA8C492C15BF9F820360709CFE9C5DFB03196120DF85D7D730DBA4CDFC36F2760227A5EAA27AA255935616A3833609B890B2445FC82D7A70B798DCB71E7C5B868AF06577FDDD034B63FF8A5CEEE3A1BBCD4CC61AF7A21D812E5987B35EF262FCCDFE85FF02E21E95C20C66357D8C813C672AFF03D9B4023E94E4397596BEA7F642D14DDA48D455EE0EBC7979D7AAD8994DC9A0DB84F1EE247C71E3D3A5626455CABC9C91BBAA98E2DD96EDA9EC0CDE2130236907A41D227CC515E1B139D278BC9F1DC231BDBDD76C400564D3200B2F61980B679BE9D8BF9D37BA5C0CB681E5054431A61CBF3979ED648AE4B
+20210512204010 2 6 100 7679 5 FAFDEC5D38380C2FFBEDCDA1262E4817F274B6544BB0A1904CF571375327EDF0105410A3F584F9A15982937EB5A64E30206DA90D66B89BF48EC74E7F40FB957673193875E02B88101A4FE81C47EBCB8451386AAEC6EA69F967310C79D8CC71BE07F669C3094E5F2CD314FF0FDD08256EFDFC03EF43C4704684CEEBBBFC48D48C920B2AC3CC15010D7EE49049D52B12E6E9228BF0482C174747EA40E558D88CACA9F143A496236C120DE560FDD7B2A1175407D333103C025E8EAE424AC5BADA1A354428B451F594BE605000CA3B2773B2D91FEDBBAF2E58DE2F03461A9F8D90B84209F66D7203E92774AB5B83809BAFFCC8D32ACB1B0AD4D1C2D37CED00654FB7517A56FE35CD364967D541D336C0E2CF96303B3BD1FBBC12D5DCF3D8F343BD2DD0EA3B5FA0062DC9A426A36DD27FD9C8E76DBB7FFE97BA3B27BDE53B017D7C9DFA6A4354FC95F3DAD99172290423EB507B574D6CEAF38A4AE227FD44541A29560020EA2EC10C5213E1EBC7A686AFA770A09C28E0D1EFB46AD409D2C58B8A4EF2E740957BCE903FF63D0B5E6BCF7E8C2B8F85DB93FC96E78BE2002603FF9AC2ACF368269FE034D6A5F8BFC6249FD140E85E9435C8B03D9390F1D0FD44519C21D174F7901BAB95DE7C91A1BFB9EB1079C584A71392A72768B2C2748145835AE7A5509B3C59539F46B5E0DF6955B84687C454679C9D87198605D78D1B551F502A5ACD915F55C919763C2F1206A0ADD5F651031A76EA0D102D064CBE24F919D3CF333D1EA0E89C1CA9E7D115802FC38757A50C97849D41E03C5F1EB8485CDDB55464E44172B0DE3D4F94A5AD01ECE4D70E17181225418F4205ABA526FA1D8C493749243D626C1D6A3170AD9D7DA551F3642229428803E81782D49355CB6CCEE08AB7583CA3A73354F2942BC6225E07788E542B1E2A9B46724D8A8EE0BE6F79CCDF78B10FC78FF3E15FFBC2EF1FFF4F53A328C7850BC0DAF358823712FF3609B981377D64FD274C578FFE92A6AE74F6F6A37907BD6B71FDA8C492C15BF9F820360709CFE9C5DFB03196120DF85D7D730DBA4CDFC36F2760227A5EAA27AA255935616A3833609B890B2445FC82D7A70B798DCB71E7C5B868AF06577FDDD034B63FF8A5CEEE3A1BBCD4CC61AF7A21D812E5987B35EF262FCCDFE85FF02E21E95C20C66357D8C813C672AFF03D9B4023E94E4397596BEA7F642D14DDA48D455EE0EBC7979D7AAD8994DC9A0DB84F1EE247C71E3D3A5626455CABC9C91BBAA98E2DD96EDA9EC0CDE2130236907A41D227CC515E1B139D278BC9F1DC231BDBDD76C400564D3200B2F61980B679BE9D8BF9D37BA5C0CB681E5054431A61CBF3979EDF2ADBE7
+20210512204459 2 6 100 7679 2 FAFDEC5D38380C2FFBEDCDA1262E4817F274B6544BB0A1904CF571375327EDF0105410A3F584F9A15982937EB5A64E30206DA90D66B89BF48EC74E7F40FB957673193875E02B88101A4FE81C47EBCB8451386AAEC6EA69F967310C79D8CC71BE07F669C3094E5F2CD314FF0FDD08256EFDFC03EF43C4704684CEEBBBFC48D48C920B2AC3CC15010D7EE49049D52B12E6E9228BF0482C174747EA40E558D88CACA9F143A496236C120DE560FDD7B2A1175407D333103C025E8EAE424AC5BADA1A354428B451F594BE605000CA3B2773B2D91FEDBBAF2E58DE2F03461A9F8D90B84209F66D7203E92774AB5B83809BAFFCC8D32ACB1B0AD4D1C2D37CED00654FB7517A56FE35CD364967D541D336C0E2CF96303B3BD1FBBC12D5DCF3D8F343BD2DD0EA3B5FA0062DC9A426A36DD27FD9C8E76DBB7FFE97BA3B27BDE53B017D7C9DFA6A4354FC95F3DAD99172290423EB507B574D6CEAF38A4AE227FD44541A29560020EA2EC10C5213E1EBC7A686AFA770A09C28E0D1EFB46AD409D2C58B8A4EF2E740957BCE903FF63D0B5E6BCF7E8C2B8F85DB93FC96E78BE2002603FF9AC2ACF368269FE034D6A5F8BFC6249FD140E85E9435C8B03D9390F1D0FD44519C21D174F7901BAB95DE7C91A1BFB9EB1079C584A71392A72768B2C2748145835AE7A5509B3C59539F46B5E0DF6955B84687C454679C9D87198605D78D1B551F502A5ACD915F55C919763C2F1206A0ADD5F651031A76EA0D102D064CBE24F919D3CF333D1EA0E89C1CA9E7D115802FC38757A50C97849D41E03C5F1EB8485CDDB55464E44172B0DE3D4F94A5AD01ECE4D70E17181225418F4205ABA526FA1D8C493749243D626C1D6A3170AD9D7DA551F3642229428803E81782D49355CB6CCEE08AB7583CA3A73354F2942BC6225E07788E542B1E2A9B46724D8A8EE0BE6F79CCDF78B10FC78FF3E15FFBC2EF1FFF4F53A328C7850BC0DAF358823712FF3609B981377D64FD274C578FFE92A6AE74F6F6A37907BD6B71FDA8C492C15BF9F820360709CFE9C5DFB03196120DF85D7D730DBA4CDFC36F2760227A5EAA27AA255935616A3833609B890B2445FC82D7A70B798DCB71E7C5B868AF06577FDDD034B63FF8A5CEEE3A1BBCD4CC61AF7A21D812E5987B35EF262FCCDFE85FF02E21E95C20C66357D8C813C672AFF03D9B4023E94E4397596BEA7F642D14DDA48D455EE0EBC7979D7AAD8994DC9A0DB84F1EE247C71E3D3A5626455CABC9C91BBAA98E2DD96EDA9EC0CDE2130236907A41D227CC515E1B139D278BC9F1DC231BDBDD76C400564D3200B2F61980B679BE9D8BF9D37BA5C0CB681E5054431A61CBF3979EDF86656B
+20210512215034 2 6 100 7679 5 FAFDEC5D38380C2FFBEDCDA1262E4817F274B6544BB0A1904CF571375327EDF0105410A3F584F9A15982937EB5A64E30206DA90D66B89BF48EC74E7F40FB957673193875E02B88101A4FE81C47EBCB8451386AAEC6EA69F967310C79D8CC71BE07F669C3094E5F2CD314FF0FDD08256EFDFC03EF43C4704684CEEBBBFC48D48C920B2AC3CC15010D7EE49049D52B12E6E9228BF0482C174747EA40E558D88CACA9F143A496236C120DE560FDD7B2A1175407D333103C025E8EAE424AC5BADA1A354428B451F594BE605000CA3B2773B2D91FEDBBAF2E58DE2F03461A9F8D90B84209F66D7203E92774AB5B83809BAFFCC8D32ACB1B0AD4D1C2D37CED00654FB7517A56FE35CD364967D541D336C0E2CF96303B3BD1FBBC12D5DCF3D8F343BD2DD0EA3B5FA0062DC9A426A36DD27FD9C8E76DBB7FFE97BA3B27BDE53B017D7C9DFA6A4354FC95F3DAD99172290423EB507B574D6CEAF38A4AE227FD44541A29560020EA2EC10C5213E1EBC7A686AFA770A09C28E0D1EFB46AD409D2C58B8A4EF2E740957BCE903FF63D0B5E6BCF7E8C2B8F85DB93FC96E78BE2002603FF9AC2ACF368269FE034D6A5F8BFC6249FD140E85E9435C8B03D9390F1D0FD44519C21D174F7901BAB95DE7C91A1BFB9EB1079C584A71392A72768B2C2748145835AE7A5509B3C59539F46B5E0DF6955B84687C454679C9D87198605D78D1B551F502A5ACD915F55C919763C2F1206A0ADD5F651031A76EA0D102D064CBE24F919D3CF333D1EA0E89C1CA9E7D115802FC38757A50C97849D41E03C5F1EB8485CDDB55464E44172B0DE3D4F94A5AD01ECE4D70E17181225418F4205ABA526FA1D8C493749243D626C1D6A3170AD9D7DA551F3642229428803E81782D49355CB6CCEE08AB7583CA3A73354F2942BC6225E07788E542B1E2A9B46724D8A8EE0BE6F79CCDF78B10FC78FF3E15FFBC2EF1FFF4F53A328C7850BC0DAF358823712FF3609B981377D64FD274C578FFE92A6AE74F6F6A37907BD6B71FDA8C492C15BF9F820360709CFE9C5DFB03196120DF85D7D730DBA4CDFC36F2760227A5EAA27AA255935616A3833609B890B2445FC82D7A70B798DCB71E7C5B868AF06577FDDD034B63FF8A5CEEE3A1BBCD4CC61AF7A21D812E5987B35EF262FCCDFE85FF02E21E95C20C66357D8C813C672AFF03D9B4023E94E4397596BEA7F642D14DDA48D455EE0EBC7979D7AAD8994DC9A0DB84F1EE247C71E3D3A5626455CABC9C91BBAA98E2DD96EDA9EC0CDE2130236907A41D227CC515E1B139D278BC9F1DC231BDBDD76C400564D3200B2F61980B679BE9D8BF9D37BA5C0CB681E5054431A61CBF3979EE4F3F8BF
+20210512215957 2 6 100 7679 2 FAFDEC5D38380C2FFBEDCDA1262E4817F274B6544BB0A1904CF571375327EDF0105410A3F584F9A15982937EB5A64E30206DA90D66B89BF48EC74E7F40FB957673193875E02B88101A4FE81C47EBCB8451386AAEC6EA69F967310C79D8CC71BE07F669C3094E5F2CD314FF0FDD08256EFDFC03EF43C4704684CEEBBBFC48D48C920B2AC3CC15010D7EE49049D52B12E6E9228BF0482C174747EA40E558D88CACA9F143A496236C120DE560FDD7B2A1175407D333103C025E8EAE424AC5BADA1A354428B451F594BE605000CA3B2773B2D91FEDBBAF2E58DE2F03461A9F8D90B84209F66D7203E92774AB5B83809BAFFCC8D32ACB1B0AD4D1C2D37CED00654FB7517A56FE35CD364967D541D336C0E2CF96303B3BD1FBBC12D5DCF3D8F343BD2DD0EA3B5FA0062DC9A426A36DD27FD9C8E76DBB7FFE97BA3B27BDE53B017D7C9DFA6A4354FC95F3DAD99172290423EB507B574D6CEAF38A4AE227FD44541A29560020EA2EC10C5213E1EBC7A686AFA770A09C28E0D1EFB46AD409D2C58B8A4EF2E740957BCE903FF63D0B5E6BCF7E8C2B8F85DB93FC96E78BE2002603FF9AC2ACF368269FE034D6A5F8BFC6249FD140E85E9435C8B03D9390F1D0FD44519C21D174F7901BAB95DE7C91A1BFB9EB1079C584A71392A72768B2C2748145835AE7A5509B3C59539F46B5E0DF6955B84687C454679C9D87198605D78D1B551F502A5ACD915F55C919763C2F1206A0ADD5F651031A76EA0D102D064CBE24F919D3CF333D1EA0E89C1CA9E7D115802FC38757A50C97849D41E03C5F1EB8485CDDB55464E44172B0DE3D4F94A5AD01ECE4D70E17181225418F4205ABA526FA1D8C493749243D626C1D6A3170AD9D7DA551F3642229428803E81782D49355CB6CCEE08AB7583CA3A73354F2942BC6225E07788E542B1E2A9B46724D8A8EE0BE6F79CCDF78B10FC78FF3E15FFBC2EF1FFF4F53A328C7850BC0DAF358823712FF3609B981377D64FD274C578FFE92A6AE74F6F6A37907BD6B71FDA8C492C15BF9F820360709CFE9C5DFB03196120DF85D7D730DBA4CDFC36F2760227A5EAA27AA255935616A3833609B890B2445FC82D7A70B798DCB71E7C5B868AF06577FDDD034B63FF8A5CEEE3A1BBCD4CC61AF7A21D812E5987B35EF262FCCDFE85FF02E21E95C20C66357D8C813C672AFF03D9B4023E94E4397596BEA7F642D14DDA48D455EE0EBC7979D7AAD8994DC9A0DB84F1EE247C71E3D3A5626455CABC9C91BBAA98E2DD96EDA9EC0CDE2130236907A41D227CC515E1B139D278BC9F1DC231BDBDD76C400564D3200B2F61980B679BE9D8BF9D37BA5C0CB681E5054431A61CBF3979EE5AFAD1B
+20210512232130 2 6 100 7679 2 FAFDEC5D38380C2FFBEDCDA1262E4817F274B6544BB0A1904CF571375327EDF0105410A3F584F9A15982937EB5A64E30206DA90D66B89BF48EC74E7F40FB957673193875E02B88101A4FE81C47EBCB8451386AAEC6EA69F967310C79D8CC71BE07F669C3094E5F2CD314FF0FDD08256EFDFC03EF43C4704684CEEBBBFC48D48C920B2AC3CC15010D7EE49049D52B12E6E9228BF0482C174747EA40E558D88CACA9F143A496236C120DE560FDD7B2A1175407D333103C025E8EAE424AC5BADA1A354428B451F594BE605000CA3B2773B2D91FEDBBAF2E58DE2F03461A9F8D90B84209F66D7203E92774AB5B83809BAFFCC8D32ACB1B0AD4D1C2D37CED00654FB7517A56FE35CD364967D541D336C0E2CF96303B3BD1FBBC12D5DCF3D8F343BD2DD0EA3B5FA0062DC9A426A36DD27FD9C8E76DBB7FFE97BA3B27BDE53B017D7C9DFA6A4354FC95F3DAD99172290423EB507B574D6CEAF38A4AE227FD44541A29560020EA2EC10C5213E1EBC7A686AFA770A09C28E0D1EFB46AD409D2C58B8A4EF2E740957BCE903FF63D0B5E6BCF7E8C2B8F85DB93FC96E78BE2002603FF9AC2ACF368269FE034D6A5F8BFC6249FD140E85E9435C8B03D9390F1D0FD44519C21D174F7901BAB95DE7C91A1BFB9EB1079C584A71392A72768B2C2748145835AE7A5509B3C59539F46B5E0DF6955B84687C454679C9D87198605D78D1B551F502A5ACD915F55C919763C2F1206A0ADD5F651031A76EA0D102D064CBE24F919D3CF333D1EA0E89C1CA9E7D115802FC38757A50C97849D41E03C5F1EB8485CDDB55464E44172B0DE3D4F94A5AD01ECE4D70E17181225418F4205ABA526FA1D8C493749243D626C1D6A3170AD9D7DA551F3642229428803E81782D49355CB6CCEE08AB7583CA3A73354F2942BC6225E07788E542B1E2A9B46724D8A8EE0BE6F79CCDF78B10FC78FF3E15FFBC2EF1FFF4F53A328C7850BC0DAF358823712FF3609B981377D64FD274C578FFE92A6AE74F6F6A37907BD6B71FDA8C492C15BF9F820360709CFE9C5DFB03196120DF85D7D730DBA4CDFC36F2760227A5EAA27AA255935616A3833609B890B2445FC82D7A70B798DCB71E7C5B868AF06577FDDD034B63FF8A5CEEE3A1BBCD4CC61AF7A21D812E5987B35EF262FCCDFE85FF02E21E95C20C66357D8C813C672AFF03D9B4023E94E4397596BEA7F642D14DDA48D455EE0EBC7979D7AAD8994DC9A0DB84F1EE247C71E3D3A5626455CABC9C91BBAA98E2DD96EDA9EC0CDE2130236907A41D227CC515E1B139D278BC9F1DC231BDBDD76C400564D3200B2F61980B679BE9D8BF9D37BA5C0CB681E5054431A61CBF3979EEC537383
+20210513002903 2 6 100 7679 2 FAFDEC5D38380C2FFBEDCDA1262E4817F274B6544BB0A1904CF571375327EDF0105410A3F584F9A15982937EB5A64E30206DA90D66B89BF48EC74E7F40FB957673193875E02B88101A4FE81C47EBCB8451386AAEC6EA69F967310C79D8CC71BE07F669C3094E5F2CD314FF0FDD08256EFDFC03EF43C4704684CEEBBBFC48D48C920B2AC3CC15010D7EE49049D52B12E6E9228BF0482C174747EA40E558D88CACA9F143A496236C120DE560FDD7B2A1175407D333103C025E8EAE424AC5BADA1A354428B451F594BE605000CA3B2773B2D91FEDBBAF2E58DE2F03461A9F8D90B84209F66D7203E92774AB5B83809BAFFCC8D32ACB1B0AD4D1C2D37CED00654FB7517A56FE35CD364967D541D336C0E2CF96303B3BD1FBBC12D5DCF3D8F343BD2DD0EA3B5FA0062DC9A426A36DD27FD9C8E76DBB7FFE97BA3B27BDE53B017D7C9DFA6A4354FC95F3DAD99172290423EB507B574D6CEAF38A4AE227FD44541A29560020EA2EC10C5213E1EBC7A686AFA770A09C28E0D1EFB46AD409D2C58B8A4EF2E740957BCE903FF63D0B5E6BCF7E8C2B8F85DB93FC96E78BE2002603FF9AC2ACF368269FE034D6A5F8BFC6249FD140E85E9435C8B03D9390F1D0FD44519C21D174F7901BAB95DE7C91A1BFB9EB1079C584A71392A72768B2C2748145835AE7A5509B3C59539F46B5E0DF6955B84687C454679C9D87198605D78D1B551F502A5ACD915F55C919763C2F1206A0ADD5F651031A76EA0D102D064CBE24F919D3CF333D1EA0E89C1CA9E7D115802FC38757A50C97849D41E03C5F1EB8485CDDB55464E44172B0DE3D4F94A5AD01ECE4D70E17181225418F4205ABA526FA1D8C493749243D626C1D6A3170AD9D7DA551F3642229428803E81782D49355CB6CCEE08AB7583CA3A73354F2942BC6225E07788E542B1E2A9B46724D8A8EE0BE6F79CCDF78B10FC78FF3E15FFBC2EF1FFF4F53A328C7850BC0DAF358823712FF3609B981377D64FD274C578FFE92A6AE74F6F6A37907BD6B71FDA8C492C15BF9F820360709CFE9C5DFB03196120DF85D7D730DBA4CDFC36F2760227A5EAA27AA255935616A3833609B890B2445FC82D7A70B798DCB71E7C5B868AF06577FDDD034B63FF8A5CEEE3A1BBCD4CC61AF7A21D812E5987B35EF262FCCDFE85FF02E21E95C20C66357D8C813C672AFF03D9B4023E94E4397596BEA7F642D14DDA48D455EE0EBC7979D7AAD8994DC9A0DB84F1EE247C71E3D3A5626455CABC9C91BBAA98E2DD96EDA9EC0CDE2130236907A41D227CC515E1B139D278BC9F1DC231BDBDD76C400564D3200B2F61980B679BE9D8BF9D37BA5C0CB681E5054431A61CBF3979EF1CC9B5B
+20210513010529 2 6 100 7679 5 FAFDEC5D38380C2FFBEDCDA1262E4817F274B6544BB0A1904CF571375327EDF0105410A3F584F9A15982937EB5A64E30206DA90D66B89BF48EC74E7F40FB957673193875E02B88101A4FE81C47EBCB8451386AAEC6EA69F967310C79D8CC71BE07F669C3094E5F2CD314FF0FDD08256EFDFC03EF43C4704684CEEBBBFC48D48C920B2AC3CC15010D7EE49049D52B12E6E9228BF0482C174747EA40E558D88CACA9F143A496236C120DE560FDD7B2A1175407D333103C025E8EAE424AC5BADA1A354428B451F594BE605000CA3B2773B2D91FEDBBAF2E58DE2F03461A9F8D90B84209F66D7203E92774AB5B83809BAFFCC8D32ACB1B0AD4D1C2D37CED00654FB7517A56FE35CD364967D541D336C0E2CF96303B3BD1FBBC12D5DCF3D8F343BD2DD0EA3B5FA0062DC9A426A36DD27FD9C8E76DBB7FFE97BA3B27BDE53B017D7C9DFA6A4354FC95F3DAD99172290423EB507B574D6CEAF38A4AE227FD44541A29560020EA2EC10C5213E1EBC7A686AFA770A09C28E0D1EFB46AD409D2C58B8A4EF2E740957BCE903FF63D0B5E6BCF7E8C2B8F85DB93FC96E78BE2002603FF9AC2ACF368269FE034D6A5F8BFC6249FD140E85E9435C8B03D9390F1D0FD44519C21D174F7901BAB95DE7C91A1BFB9EB1079C584A71392A72768B2C2748145835AE7A5509B3C59539F46B5E0DF6955B84687C454679C9D87198605D78D1B551F502A5ACD915F55C919763C2F1206A0ADD5F651031A76EA0D102D064CBE24F919D3CF333D1EA0E89C1CA9E7D115802FC38757A50C97849D41E03C5F1EB8485CDDB55464E44172B0DE3D4F94A5AD01ECE4D70E17181225418F4205ABA526FA1D8C493749243D626C1D6A3170AD9D7DA551F3642229428803E81782D49355CB6CCEE08AB7583CA3A73354F2942BC6225E07788E542B1E2A9B46724D8A8EE0BE6F79CCDF78B10FC78FF3E15FFBC2EF1FFF4F53A328C7850BC0DAF358823712FF3609B981377D64FD274C578FFE92A6AE74F6F6A37907BD6B71FDA8C492C15BF9F820360709CFE9C5DFB03196120DF85D7D730DBA4CDFC36F2760227A5EAA27AA255935616A3833609B890B2445FC82D7A70B798DCB71E7C5B868AF06577FDDD034B63FF8A5CEEE3A1BBCD4CC61AF7A21D812E5987B35EF262FCCDFE85FF02E21E95C20C66357D8C813C672AFF03D9B4023E94E4397596BEA7F642D14DDA48D455EE0EBC7979D7AAD8994DC9A0DB84F1EE247C71E3D3A5626455CABC9C91BBAA98E2DD96EDA9EC0CDE2130236907A41D227CC515E1B139D278BC9F1DC231BDBDD76C400564D3200B2F61980B679BE9D8BF9D37BA5C0CB681E5054431A61CBF3979EF4AF06D7
+20210513024603 2 6 100 7679 2 FAFDEC5D38380C2FFBEDCDA1262E4817F274B6544BB0A1904CF571375327EDF0105410A3F584F9A15982937EB5A64E30206DA90D66B89BF48EC74E7F40FB957673193875E02B88101A4FE81C47EBCB8451386AAEC6EA69F967310C79D8CC71BE07F669C3094E5F2CD314FF0FDD08256EFDFC03EF43C4704684CEEBBBFC48D48C920B2AC3CC15010D7EE49049D52B12E6E9228BF0482C174747EA40E558D88CACA9F143A496236C120DE560FDD7B2A1175407D333103C025E8EAE424AC5BADA1A354428B451F594BE605000CA3B2773B2D91FEDBBAF2E58DE2F03461A9F8D90B84209F66D7203E92774AB5B83809BAFFCC8D32ACB1B0AD4D1C2D37CED00654FB7517A56FE35CD364967D541D336C0E2CF96303B3BD1FBBC12D5DCF3D8F343BD2DD0EA3B5FA0062DC9A426A36DD27FD9C8E76DBB7FFE97BA3B27BDE53B017D7C9DFA6A4354FC95F3DAD99172290423EB507B574D6CEAF38A4AE227FD44541A29560020EA2EC10C5213E1EBC7A686AFA770A09C28E0D1EFB46AD409D2C58B8A4EF2E740957BCE903FF63D0B5E6BCF7E8C2B8F85DB93FC96E78BE2002603FF9AC2ACF368269FE034D6A5F8BFC6249FD140E85E9435C8B03D9390F1D0FD44519C21D174F7901BAB95DE7C91A1BFB9EB1079C584A71392A72768B2C2748145835AE7A5509B3C59539F46B5E0DF6955B84687C454679C9D87198605D78D1B551F502A5ACD915F55C919763C2F1206A0ADD5F651031A76EA0D102D064CBE24F919D3CF333D1EA0E89C1CA9E7D115802FC38757A50C97849D41E03C5F1EB8485CDDB55464E44172B0DE3D4F94A5AD01ECE4D70E17181225418F4205ABA526FA1D8C493749243D626C1D6A3170AD9D7DA551F3642229428803E81782D49355CB6CCEE08AB7583CA3A73354F2942BC6225E07788E542B1E2A9B46724D8A8EE0BE6F79CCDF78B10FC78FF3E15FFBC2EF1FFF4F53A328C7850BC0DAF358823712FF3609B981377D64FD274C578FFE92A6AE74F6F6A37907BD6B71FDA8C492C15BF9F820360709CFE9C5DFB03196120DF85D7D730DBA4CDFC36F2760227A5EAA27AA255935616A3833609B890B2445FC82D7A70B798DCB71E7C5B868AF06577FDDD034B63FF8A5CEEE3A1BBCD4CC61AF7A21D812E5987B35EF262FCCDFE85FF02E21E95C20C66357D8C813C672AFF03D9B4023E94E4397596BEA7F642D14DDA48D455EE0EBC7979D7AAD8994DC9A0DB84F1EE247C71E3D3A5626455CABC9C91BBAA98E2DD96EDA9EC0CDE2130236907A41D227CC515E1B139D278BC9F1DC231BDBDD76C400564D3200B2F61980B679BE9D8BF9D37BA5C0CB681E5054431A61CBF3979EFC954793
+20210513024649 2 6 100 7679 2 FAFDEC5D38380C2FFBEDCDA1262E4817F274B6544BB0A1904CF571375327EDF0105410A3F584F9A15982937EB5A64E30206DA90D66B89BF48EC74E7F40FB957673193875E02B88101A4FE81C47EBCB8451386AAEC6EA69F967310C79D8CC71BE07F669C3094E5F2CD314FF0FDD08256EFDFC03EF43C4704684CEEBBBFC48D48C920B2AC3CC15010D7EE49049D52B12E6E9228BF0482C174747EA40E558D88CACA9F143A496236C120DE560FDD7B2A1175407D333103C025E8EAE424AC5BADA1A354428B451F594BE605000CA3B2773B2D91FEDBBAF2E58DE2F03461A9F8D90B84209F66D7203E92774AB5B83809BAFFCC8D32ACB1B0AD4D1C2D37CED00654FB7517A56FE35CD364967D541D336C0E2CF96303B3BD1FBBC12D5DCF3D8F343BD2DD0EA3B5FA0062DC9A426A36DD27FD9C8E76DBB7FFE97BA3B27BDE53B017D7C9DFA6A4354FC95F3DAD99172290423EB507B574D6CEAF38A4AE227FD44541A29560020EA2EC10C5213E1EBC7A686AFA770A09C28E0D1EFB46AD409D2C58B8A4EF2E740957BCE903FF63D0B5E6BCF7E8C2B8F85DB93FC96E78BE2002603FF9AC2ACF368269FE034D6A5F8BFC6249FD140E85E9435C8B03D9390F1D0FD44519C21D174F7901BAB95DE7C91A1BFB9EB1079C584A71392A72768B2C2748145835AE7A5509B3C59539F46B5E0DF6955B84687C454679C9D87198605D78D1B551F502A5ACD915F55C919763C2F1206A0ADD5F651031A76EA0D102D064CBE24F919D3CF333D1EA0E89C1CA9E7D115802FC38757A50C97849D41E03C5F1EB8485CDDB55464E44172B0DE3D4F94A5AD01ECE4D70E17181225418F4205ABA526FA1D8C493749243D626C1D6A3170AD9D7DA551F3642229428803E81782D49355CB6CCEE08AB7583CA3A73354F2942BC6225E07788E542B1E2A9B46724D8A8EE0BE6F79CCDF78B10FC78FF3E15FFBC2EF1FFF4F53A328C7850BC0DAF358823712FF3609B981377D64FD274C578FFE92A6AE74F6F6A37907BD6B71FDA8C492C15BF9F820360709CFE9C5DFB03196120DF85D7D730DBA4CDFC36F2760227A5EAA27AA255935616A3833609B890B2445FC82D7A70B798DCB71E7C5B868AF06577FDDD034B63FF8A5CEEE3A1BBCD4CC61AF7A21D812E5987B35EF262FCCDFE85FF02E21E95C20C66357D8C813C672AFF03D9B4023E94E4397596BEA7F642D14DDA48D455EE0EBC7979D7AAD8994DC9A0DB84F1EE247C71E3D3A5626455CABC9C91BBAA98E2DD96EDA9EC0CDE2130236907A41D227CC515E1B139D278BC9F1DC231BDBDD76C400564D3200B2F61980B679BE9D8BF9D37BA5C0CB681E5054431A61CBF3979EFC9C854B
+20210513034549 2 6 100 7679 2 FAFDEC5D38380C2FFBEDCDA1262E4817F274B6544BB0A1904CF571375327EDF0105410A3F584F9A15982937EB5A64E30206DA90D66B89BF48EC74E7F40FB957673193875E02B88101A4FE81C47EBCB8451386AAEC6EA69F967310C79D8CC71BE07F669C3094E5F2CD314FF0FDD08256EFDFC03EF43C4704684CEEBBBFC48D48C920B2AC3CC15010D7EE49049D52B12E6E9228BF0482C174747EA40E558D88CACA9F143A496236C120DE560FDD7B2A1175407D333103C025E8EAE424AC5BADA1A354428B451F594BE605000CA3B2773B2D91FEDBBAF2E58DE2F03461A9F8D90B84209F66D7203E92774AB5B83809BAFFCC8D32ACB1B0AD4D1C2D37CED00654FB7517A56FE35CD364967D541D336C0E2CF96303B3BD1FBBC12D5DCF3D8F343BD2DD0EA3B5FA0062DC9A426A36DD27FD9C8E76DBB7FFE97BA3B27BDE53B017D7C9DFA6A4354FC95F3DAD99172290423EB507B574D6CEAF38A4AE227FD44541A29560020EA2EC10C5213E1EBC7A686AFA770A09C28E0D1EFB46AD409D2C58B8A4EF2E740957BCE903FF63D0B5E6BCF7E8C2B8F85DB93FC96E78BE2002603FF9AC2ACF368269FE034D6A5F8BFC6249FD140E85E9435C8B03D9390F1D0FD44519C21D174F7901BAB95DE7C91A1BFB9EB1079C584A71392A72768B2C2748145835AE7A5509B3C59539F46B5E0DF6955B84687C454679C9D87198605D78D1B551F502A5ACD915F55C919763C2F1206A0ADD5F651031A76EA0D102D064CBE24F919D3CF333D1EA0E89C1CA9E7D115802FC38757A50C97849D41E03C5F1EB8485CDDB55464E44172B0DE3D4F94A5AD01ECE4D70E17181225418F4205ABA526FA1D8C493749243D626C1D6A3170AD9D7DA551F3642229428803E81782D49355CB6CCEE08AB7583CA3A73354F2942BC6225E07788E542B1E2A9B46724D8A8EE0BE6F79CCDF78B10FC78FF3E15FFBC2EF1FFF4F53A328C7850BC0DAF358823712FF3609B981377D64FD274C578FFE92A6AE74F6F6A37907BD6B71FDA8C492C15BF9F820360709CFE9C5DFB03196120DF85D7D730DBA4CDFC36F2760227A5EAA27AA255935616A3833609B890B2445FC82D7A70B798DCB71E7C5B868AF06577FDDD034B63FF8A5CEEE3A1BBCD4CC61AF7A21D812E5987B35EF262FCCDFE85FF02E21E95C20C66357D8C813C672AFF03D9B4023E94E4397596BEA7F642D14DDA48D455EE0EBC7979D7AAD8994DC9A0DB84F1EE247C71E3D3A5626455CABC9C91BBAA98E2DD96EDA9EC0CDE2130236907A41D227CC515E1B139D278BC9F1DC231BDBDD76C400564D3200B2F61980B679BE9D8BF9D37BA5C0CB681E5054431A61CBF3979F013F0FB3
+20210513035644 2 6 100 7679 2 FAFDEC5D38380C2FFBEDCDA1262E4817F274B6544BB0A1904CF571375327EDF0105410A3F584F9A15982937EB5A64E30206DA90D66B89BF48EC74E7F40FB957673193875E02B88101A4FE81C47EBCB8451386AAEC6EA69F967310C79D8CC71BE07F669C3094E5F2CD314FF0FDD08256EFDFC03EF43C4704684CEEBBBFC48D48C920B2AC3CC15010D7EE49049D52B12E6E9228BF0482C174747EA40E558D88CACA9F143A496236C120DE560FDD7B2A1175407D333103C025E8EAE424AC5BADA1A354428B451F594BE605000CA3B2773B2D91FEDBBAF2E58DE2F03461A9F8D90B84209F66D7203E92774AB5B83809BAFFCC8D32ACB1B0AD4D1C2D37CED00654FB7517A56FE35CD364967D541D336C0E2CF96303B3BD1FBBC12D5DCF3D8F343BD2DD0EA3B5FA0062DC9A426A36DD27FD9C8E76DBB7FFE97BA3B27BDE53B017D7C9DFA6A4354FC95F3DAD99172290423EB507B574D6CEAF38A4AE227FD44541A29560020EA2EC10C5213E1EBC7A686AFA770A09C28E0D1EFB46AD409D2C58B8A4EF2E740957BCE903FF63D0B5E6BCF7E8C2B8F85DB93FC96E78BE2002603FF9AC2ACF368269FE034D6A5F8BFC6249FD140E85E9435C8B03D9390F1D0FD44519C21D174F7901BAB95DE7C91A1BFB9EB1079C584A71392A72768B2C2748145835AE7A5509B3C59539F46B5E0DF6955B84687C454679C9D87198605D78D1B551F502A5ACD915F55C919763C2F1206A0ADD5F651031A76EA0D102D064CBE24F919D3CF333D1EA0E89C1CA9E7D115802FC38757A50C97849D41E03C5F1EB8485CDDB55464E44172B0DE3D4F94A5AD01ECE4D70E17181225418F4205ABA526FA1D8C493749243D626C1D6A3170AD9D7DA551F3642229428803E81782D49355CB6CCEE08AB7583CA3A73354F2942BC6225E07788E542B1E2A9B46724D8A8EE0BE6F79CCDF78B10FC78FF3E15FFBC2EF1FFF4F53A328C7850BC0DAF358823712FF3609B981377D64FD274C578FFE92A6AE74F6F6A37907BD6B71FDA8C492C15BF9F820360709CFE9C5DFB03196120DF85D7D730DBA4CDFC36F2760227A5EAA27AA255935616A3833609B890B2445FC82D7A70B798DCB71E7C5B868AF06577FDDD034B63FF8A5CEEE3A1BBCD4CC61AF7A21D812E5987B35EF262FCCDFE85FF02E21E95C20C66357D8C813C672AFF03D9B4023E94E4397596BEA7F642D14DDA48D455EE0EBC7979D7AAD8994DC9A0DB84F1EE247C71E3D3A5626455CABC9C91BBAA98E2DD96EDA9EC0CDE2130236907A41D227CC515E1B139D278BC9F1DC231BDBDD76C400564D3200B2F61980B679BE9D8BF9D37BA5C0CB681E5054431A61CBF3979F02144FBB
+20210513040521 2 6 100 7679 2 FAFDEC5D38380C2FFBEDCDA1262E4817F274B6544BB0A1904CF571375327EDF0105410A3F584F9A15982937EB5A64E30206DA90D66B89BF48EC74E7F40FB957673193875E02B88101A4FE81C47EBCB8451386AAEC6EA69F967310C79D8CC71BE07F669C3094E5F2CD314FF0FDD08256EFDFC03EF43C4704684CEEBBBFC48D48C920B2AC3CC15010D7EE49049D52B12E6E9228BF0482C174747EA40E558D88CACA9F143A496236C120DE560FDD7B2A1175407D333103C025E8EAE424AC5BADA1A354428B451F594BE605000CA3B2773B2D91FEDBBAF2E58DE2F03461A9F8D90B84209F66D7203E92774AB5B83809BAFFCC8D32ACB1B0AD4D1C2D37CED00654FB7517A56FE35CD364967D541D336C0E2CF96303B3BD1FBBC12D5DCF3D8F343BD2DD0EA3B5FA0062DC9A426A36DD27FD9C8E76DBB7FFE97BA3B27BDE53B017D7C9DFA6A4354FC95F3DAD99172290423EB507B574D6CEAF38A4AE227FD44541A29560020EA2EC10C5213E1EBC7A686AFA770A09C28E0D1EFB46AD409D2C58B8A4EF2E740957BCE903FF63D0B5E6BCF7E8C2B8F85DB93FC96E78BE2002603FF9AC2ACF368269FE034D6A5F8BFC6249FD140E85E9435C8B03D9390F1D0FD44519C21D174F7901BAB95DE7C91A1BFB9EB1079C584A71392A72768B2C2748145835AE7A5509B3C59539F46B5E0DF6955B84687C454679C9D87198605D78D1B551F502A5ACD915F55C919763C2F1206A0ADD5F651031A76EA0D102D064CBE24F919D3CF333D1EA0E89C1CA9E7D115802FC38757A50C97849D41E03C5F1EB8485CDDB55464E44172B0DE3D4F94A5AD01ECE4D70E17181225418F4205ABA526FA1D8C493749243D626C1D6A3170AD9D7DA551F3642229428803E81782D49355CB6CCEE08AB7583CA3A73354F2942BC6225E07788E542B1E2A9B46724D8A8EE0BE6F79CCDF78B10FC78FF3E15FFBC2EF1FFF4F53A328C7850BC0DAF358823712FF3609B981377D64FD274C578FFE92A6AE74F6F6A37907BD6B71FDA8C492C15BF9F820360709CFE9C5DFB03196120DF85D7D730DBA4CDFC36F2760227A5EAA27AA255935616A3833609B890B2445FC82D7A70B798DCB71E7C5B868AF06577FDDD034B63FF8A5CEEE3A1BBCD4CC61AF7A21D812E5987B35EF262FCCDFE85FF02E21E95C20C66357D8C813C672AFF03D9B4023E94E4397596BEA7F642D14DDA48D455EE0EBC7979D7AAD8994DC9A0DB84F1EE247C71E3D3A5626455CABC9C91BBAA98E2DD96EDA9EC0CDE2130236907A41D227CC515E1B139D278BC9F1DC231BDBDD76C400564D3200B2F61980B679BE9D8BF9D37BA5C0CB681E5054431A61CBF3979F02B7D0AB
+20210513041837 2 6 100 7679 2 FAFDEC5D38380C2FFBEDCDA1262E4817F274B6544BB0A1904CF571375327EDF0105410A3F584F9A15982937EB5A64E30206DA90D66B89BF48EC74E7F40FB957673193875E02B88101A4FE81C47EBCB8451386AAEC6EA69F967310C79D8CC71BE07F669C3094E5F2CD314FF0FDD08256EFDFC03EF43C4704684CEEBBBFC48D48C920B2AC3CC15010D7EE49049D52B12E6E9228BF0482C174747EA40E558D88CACA9F143A496236C120DE560FDD7B2A1175407D333103C025E8EAE424AC5BADA1A354428B451F594BE605000CA3B2773B2D91FEDBBAF2E58DE2F03461A9F8D90B84209F66D7203E92774AB5B83809BAFFCC8D32ACB1B0AD4D1C2D37CED00654FB7517A56FE35CD364967D541D336C0E2CF96303B3BD1FBBC12D5DCF3D8F343BD2DD0EA3B5FA0062DC9A426A36DD27FD9C8E76DBB7FFE97BA3B27BDE53B017D7C9DFA6A4354FC95F3DAD99172290423EB507B574D6CEAF38A4AE227FD44541A29560020EA2EC10C5213E1EBC7A686AFA770A09C28E0D1EFB46AD409D2C58B8A4EF2E740957BCE903FF63D0B5E6BCF7E8C2B8F85DB93FC96E78BE2002603FF9AC2ACF368269FE034D6A5F8BFC6249FD140E85E9435C8B03D9390F1D0FD44519C21D174F7901BAB95DE7C91A1BFB9EB1079C584A71392A72768B2C2748145835AE7A5509B3C59539F46B5E0DF6955B84687C454679C9D87198605D78D1B551F502A5ACD915F55C919763C2F1206A0ADD5F651031A76EA0D102D064CBE24F919D3CF333D1EA0E89C1CA9E7D115802FC38757A50C97849D41E03C5F1EB8485CDDB55464E44172B0DE3D4F94A5AD01ECE4D70E17181225418F4205ABA526FA1D8C493749243D626C1D6A3170AD9D7DA551F3642229428803E81782D49355CB6CCEE08AB7583CA3A73354F2942BC6225E07788E542B1E2A9B46724D8A8EE0BE6F79CCDF78B10FC78FF3E15FFBC2EF1FFF4F53A328C7850BC0DAF358823712FF3609B981377D64FD274C578FFE92A6AE74F6F6A37907BD6B71FDA8C492C15BF9F820360709CFE9C5DFB03196120DF85D7D730DBA4CDFC36F2760227A5EAA27AA255935616A3833609B890B2445FC82D7A70B798DCB71E7C5B868AF06577FDDD034B63FF8A5CEEE3A1BBCD4CC61AF7A21D812E5987B35EF262FCCDFE85FF02E21E95C20C66357D8C813C672AFF03D9B4023E94E4397596BEA7F642D14DDA48D455EE0EBC7979D7AAD8994DC9A0DB84F1EE247C71E3D3A5626455CABC9C91BBAA98E2DD96EDA9EC0CDE2130236907A41D227CC515E1B139D278BC9F1DC231BDBDD76C400564D3200B2F61980B679BE9D8BF9D37BA5C0CB681E5054431A61CBF3979F03B639A3
+20210513051930 2 6 100 7679 2 FAFDEC5D38380C2FFBEDCDA1262E4817F274B6544BB0A1904CF571375327EDF0105410A3F584F9A15982937EB5A64E30206DA90D66B89BF48EC74E7F40FB957673193875E02B88101A4FE81C47EBCB8451386AAEC6EA69F967310C79D8CC71BE07F669C3094E5F2CD314FF0FDD08256EFDFC03EF43C4704684CEEBBBFC48D48C920B2AC3CC15010D7EE49049D52B12E6E9228BF0482C174747EA40E558D88CACA9F143A496236C120DE560FDD7B2A1175407D333103C025E8EAE424AC5BADA1A354428B451F594BE605000CA3B2773B2D91FEDBBAF2E58DE2F03461A9F8D90B84209F66D7203E92774AB5B83809BAFFCC8D32ACB1B0AD4D1C2D37CED00654FB7517A56FE35CD364967D541D336C0E2CF96303B3BD1FBBC12D5DCF3D8F343BD2DD0EA3B5FA0062DC9A426A36DD27FD9C8E76DBB7FFE97BA3B27BDE53B017D7C9DFA6A4354FC95F3DAD99172290423EB507B574D6CEAF38A4AE227FD44541A29560020EA2EC10C5213E1EBC7A686AFA770A09C28E0D1EFB46AD409D2C58B8A4EF2E740957BCE903FF63D0B5E6BCF7E8C2B8F85DB93FC96E78BE2002603FF9AC2ACF368269FE034D6A5F8BFC6249FD140E85E9435C8B03D9390F1D0FD44519C21D174F7901BAB95DE7C91A1BFB9EB1079C584A71392A72768B2C2748145835AE7A5509B3C59539F46B5E0DF6955B84687C454679C9D87198605D78D1B551F502A5ACD915F55C919763C2F1206A0ADD5F651031A76EA0D102D064CBE24F919D3CF333D1EA0E89C1CA9E7D115802FC38757A50C97849D41E03C5F1EB8485CDDB55464E44172B0DE3D4F94A5AD01ECE4D70E17181225418F4205ABA526FA1D8C493749243D626C1D6A3170AD9D7DA551F3642229428803E81782D49355CB6CCEE08AB7583CA3A73354F2942BC6225E07788E542B1E2A9B46724D8A8EE0BE6F79CCDF78B10FC78FF3E15FFBC2EF1FFF4F53A328C7850BC0DAF358823712FF3609B981377D64FD274C578FFE92A6AE74F6F6A37907BD6B71FDA8C492C15BF9F820360709CFE9C5DFB03196120DF85D7D730DBA4CDFC36F2760227A5EAA27AA255935616A3833609B890B2445FC82D7A70B798DCB71E7C5B868AF06577FDDD034B63FF8A5CEEE3A1BBCD4CC61AF7A21D812E5987B35EF262FCCDFE85FF02E21E95C20C66357D8C813C672AFF03D9B4023E94E4397596BEA7F642D14DDA48D455EE0EBC7979D7AAD8994DC9A0DB84F1EE247C71E3D3A5626455CABC9C91BBAA98E2DD96EDA9EC0CDE2130236907A41D227CC515E1B139D278BC9F1DC231BDBDD76C400564D3200B2F61980B679BE9D8BF9D37BA5C0CB681E5054431A61CBF3979F08737F53
+20210513054050 2 6 100 7679 5 FAFDEC5D38380C2FFBEDCDA1262E4817F274B6544BB0A1904CF571375327EDF0105410A3F584F9A15982937EB5A64E30206DA90D66B89BF48EC74E7F40FB957673193875E02B88101A4FE81C47EBCB8451386AAEC6EA69F967310C79D8CC71BE07F669C3094E5F2CD314FF0FDD08256EFDFC03EF43C4704684CEEBBBFC48D48C920B2AC3CC15010D7EE49049D52B12E6E9228BF0482C174747EA40E558D88CACA9F143A496236C120DE560FDD7B2A1175407D333103C025E8EAE424AC5BADA1A354428B451F594BE605000CA3B2773B2D91FEDBBAF2E58DE2F03461A9F8D90B84209F66D7203E92774AB5B83809BAFFCC8D32ACB1B0AD4D1C2D37CED00654FB7517A56FE35CD364967D541D336C0E2CF96303B3BD1FBBC12D5DCF3D8F343BD2DD0EA3B5FA0062DC9A426A36DD27FD9C8E76DBB7FFE97BA3B27BDE53B017D7C9DFA6A4354FC95F3DAD99172290423EB507B574D6CEAF38A4AE227FD44541A29560020EA2EC10C5213E1EBC7A686AFA770A09C28E0D1EFB46AD409D2C58B8A4EF2E740957BCE903FF63D0B5E6BCF7E8C2B8F85DB93FC96E78BE2002603FF9AC2ACF368269FE034D6A5F8BFC6249FD140E85E9435C8B03D9390F1D0FD44519C21D174F7901BAB95DE7C91A1BFB9EB1079C584A71392A72768B2C2748145835AE7A5509B3C59539F46B5E0DF6955B84687C454679C9D87198605D78D1B551F502A5ACD915F55C919763C2F1206A0ADD5F651031A76EA0D102D064CBE24F919D3CF333D1EA0E89C1CA9E7D115802FC38757A50C97849D41E03C5F1EB8485CDDB55464E44172B0DE3D4F94A5AD01ECE4D70E17181225418F4205ABA526FA1D8C493749243D626C1D6A3170AD9D7DA551F3642229428803E81782D49355CB6CCEE08AB7583CA3A73354F2942BC6225E07788E542B1E2A9B46724D8A8EE0BE6F79CCDF78B10FC78FF3E15FFBC2EF1FFF4F53A328C7850BC0DAF358823712FF3609B981377D64FD274C578FFE92A6AE74F6F6A37907BD6B71FDA8C492C15BF9F820360709CFE9C5DFB03196120DF85D7D730DBA4CDFC36F2760227A5EAA27AA255935616A3833609B890B2445FC82D7A70B798DCB71E7C5B868AF06577FDDD034B63FF8A5CEEE3A1BBCD4CC61AF7A21D812E5987B35EF262FCCDFE85FF02E21E95C20C66357D8C813C672AFF03D9B4023E94E4397596BEA7F642D14DDA48D455EE0EBC7979D7AAD8994DC9A0DB84F1EE247C71E3D3A5626455CABC9C91BBAA98E2DD96EDA9EC0CDE2130236907A41D227CC515E1B139D278BC9F1DC231BDBDD76C400564D3200B2F61980B679BE9D8BF9D37BA5C0CB681E5054431A61CBF3979F0A117EFF
+20210513061420 2 6 100 7679 2 FAFDEC5D38380C2FFBEDCDA1262E4817F274B6544BB0A1904CF571375327EDF0105410A3F584F9A15982937EB5A64E30206DA90D66B89BF48EC74E7F40FB957673193875E02B88101A4FE81C47EBCB8451386AAEC6EA69F967310C79D8CC71BE07F669C3094E5F2CD314FF0FDD08256EFDFC03EF43C4704684CEEBBBFC48D48C920B2AC3CC15010D7EE49049D52B12E6E9228BF0482C174747EA40E558D88CACA9F143A496236C120DE560FDD7B2A1175407D333103C025E8EAE424AC5BADA1A354428B451F594BE605000CA3B2773B2D91FEDBBAF2E58DE2F03461A9F8D90B84209F66D7203E92774AB5B83809BAFFCC8D32ACB1B0AD4D1C2D37CED00654FB7517A56FE35CD364967D541D336C0E2CF96303B3BD1FBBC12D5DCF3D8F343BD2DD0EA3B5FA0062DC9A426A36DD27FD9C8E76DBB7FFE97BA3B27BDE53B017D7C9DFA6A4354FC95F3DAD99172290423EB507B574D6CEAF38A4AE227FD44541A29560020EA2EC10C5213E1EBC7A686AFA770A09C28E0D1EFB46AD409D2C58B8A4EF2E740957BCE903FF63D0B5E6BCF7E8C2B8F85DB93FC96E78BE2002603FF9AC2ACF368269FE034D6A5F8BFC6249FD140E85E9435C8B03D9390F1D0FD44519C21D174F7901BAB95DE7C91A1BFB9EB1079C584A71392A72768B2C2748145835AE7A5509B3C59539F46B5E0DF6955B84687C454679C9D87198605D78D1B551F502A5ACD915F55C919763C2F1206A0ADD5F651031A76EA0D102D064CBE24F919D3CF333D1EA0E89C1CA9E7D115802FC38757A50C97849D41E03C5F1EB8485CDDB55464E44172B0DE3D4F94A5AD01ECE4D70E17181225418F4205ABA526FA1D8C493749243D626C1D6A3170AD9D7DA551F3642229428803E81782D49355CB6CCEE08AB7583CA3A73354F2942BC6225E07788E542B1E2A9B46724D8A8EE0BE6F79CCDF78B10FC78FF3E15FFBC2EF1FFF4F53A328C7850BC0DAF358823712FF3609B981377D64FD274C578FFE92A6AE74F6F6A37907BD6B71FDA8C492C15BF9F820360709CFE9C5DFB03196120DF85D7D730DBA4CDFC36F2760227A5EAA27AA255935616A3833609B890B2445FC82D7A70B798DCB71E7C5B868AF06577FDDD034B63FF8A5CEEE3A1BBCD4CC61AF7A21D812E5987B35EF262FCCDFE85FF02E21E95C20C66357D8C813C672AFF03D9B4023E94E4397596BEA7F642D14DDA48D455EE0EBC7979D7AAD8994DC9A0DB84F1EE247C71E3D3A5626455CABC9C91BBAA98E2DD96EDA9EC0CDE2130236907A41D227CC515E1B139D278BC9F1DC231BDBDD76C400564D3200B2F61980B679BE9D8BF9D37BA5C0CB681E5054431A61CBF3979F0CA24113
+20210513062114 2 6 100 7679 5 FAFDEC5D38380C2FFBEDCDA1262E4817F274B6544BB0A1904CF571375327EDF0105410A3F584F9A15982937EB5A64E30206DA90D66B89BF48EC74E7F40FB957673193875E02B88101A4FE81C47EBCB8451386AAEC6EA69F967310C79D8CC71BE07F669C3094E5F2CD314FF0FDD08256EFDFC03EF43C4704684CEEBBBFC48D48C920B2AC3CC15010D7EE49049D52B12E6E9228BF0482C174747EA40E558D88CACA9F143A496236C120DE560FDD7B2A1175407D333103C025E8EAE424AC5BADA1A354428B451F594BE605000CA3B2773B2D91FEDBBAF2E58DE2F03461A9F8D90B84209F66D7203E92774AB5B83809BAFFCC8D32ACB1B0AD4D1C2D37CED00654FB7517A56FE35CD364967D541D336C0E2CF96303B3BD1FBBC12D5DCF3D8F343BD2DD0EA3B5FA0062DC9A426A36DD27FD9C8E76DBB7FFE97BA3B27BDE53B017D7C9DFA6A4354FC95F3DAD99172290423EB507B574D6CEAF38A4AE227FD44541A29560020EA2EC10C5213E1EBC7A686AFA770A09C28E0D1EFB46AD409D2C58B8A4EF2E740957BCE903FF63D0B5E6BCF7E8C2B8F85DB93FC96E78BE2002603FF9AC2ACF368269FE034D6A5F8BFC6249FD140E85E9435C8B03D9390F1D0FD44519C21D174F7901BAB95DE7C91A1BFB9EB1079C584A71392A72768B2C2748145835AE7A5509B3C59539F46B5E0DF6955B84687C454679C9D87198605D78D1B551F502A5ACD915F55C919763C2F1206A0ADD5F651031A76EA0D102D064CBE24F919D3CF333D1EA0E89C1CA9E7D115802FC38757A50C97849D41E03C5F1EB8485CDDB55464E44172B0DE3D4F94A5AD01ECE4D70E17181225418F4205ABA526FA1D8C493749243D626C1D6A3170AD9D7DA551F3642229428803E81782D49355CB6CCEE08AB7583CA3A73354F2942BC6225E07788E542B1E2A9B46724D8A8EE0BE6F79CCDF78B10FC78FF3E15FFBC2EF1FFF4F53A328C7850BC0DAF358823712FF3609B981377D64FD274C578FFE92A6AE74F6F6A37907BD6B71FDA8C492C15BF9F820360709CFE9C5DFB03196120DF85D7D730DBA4CDFC36F2760227A5EAA27AA255935616A3833609B890B2445FC82D7A70B798DCB71E7C5B868AF06577FDDD034B63FF8A5CEEE3A1BBCD4CC61AF7A21D812E5987B35EF262FCCDFE85FF02E21E95C20C66357D8C813C672AFF03D9B4023E94E4397596BEA7F642D14DDA48D455EE0EBC7979D7AAD8994DC9A0DB84F1EE247C71E3D3A5626455CABC9C91BBAA98E2DD96EDA9EC0CDE2130236907A41D227CC515E1B139D278BC9F1DC231BDBDD76C400564D3200B2F61980B679BE9D8BF9D37BA5C0CB681E5054431A61CBF3979F0D21BC27
+20210513063330 2 6 100 7679 5 FAFDEC5D38380C2FFBEDCDA1262E4817F274B6544BB0A1904CF571375327EDF0105410A3F584F9A15982937EB5A64E30206DA90D66B89BF48EC74E7F40FB957673193875E02B88101A4FE81C47EBCB8451386AAEC6EA69F967310C79D8CC71BE07F669C3094E5F2CD314FF0FDD08256EFDFC03EF43C4704684CEEBBBFC48D48C920B2AC3CC15010D7EE49049D52B12E6E9228BF0482C174747EA40E558D88CACA9F143A496236C120DE560FDD7B2A1175407D333103C025E8EAE424AC5BADA1A354428B451F594BE605000CA3B2773B2D91FEDBBAF2E58DE2F03461A9F8D90B84209F66D7203E92774AB5B83809BAFFCC8D32ACB1B0AD4D1C2D37CED00654FB7517A56FE35CD364967D541D336C0E2CF96303B3BD1FBBC12D5DCF3D8F343BD2DD0EA3B5FA0062DC9A426A36DD27FD9C8E76DBB7FFE97BA3B27BDE53B017D7C9DFA6A4354FC95F3DAD99172290423EB507B574D6CEAF38A4AE227FD44541A29560020EA2EC10C5213E1EBC7A686AFA770A09C28E0D1EFB46AD409D2C58B8A4EF2E740957BCE903FF63D0B5E6BCF7E8C2B8F85DB93FC96E78BE2002603FF9AC2ACF368269FE034D6A5F8BFC6249FD140E85E9435C8B03D9390F1D0FD44519C21D174F7901BAB95DE7C91A1BFB9EB1079C584A71392A72768B2C2748145835AE7A5509B3C59539F46B5E0DF6955B84687C454679C9D87198605D78D1B551F502A5ACD915F55C919763C2F1206A0ADD5F651031A76EA0D102D064CBE24F919D3CF333D1EA0E89C1CA9E7D115802FC38757A50C97849D41E03C5F1EB8485CDDB55464E44172B0DE3D4F94A5AD01ECE4D70E17181225418F4205ABA526FA1D8C493749243D626C1D6A3170AD9D7DA551F3642229428803E81782D49355CB6CCEE08AB7583CA3A73354F2942BC6225E07788E542B1E2A9B46724D8A8EE0BE6F79CCDF78B10FC78FF3E15FFBC2EF1FFF4F53A328C7850BC0DAF358823712FF3609B981377D64FD274C578FFE92A6AE74F6F6A37907BD6B71FDA8C492C15BF9F820360709CFE9C5DFB03196120DF85D7D730DBA4CDFC36F2760227A5EAA27AA255935616A3833609B890B2445FC82D7A70B798DCB71E7C5B868AF06577FDDD034B63FF8A5CEEE3A1BBCD4CC61AF7A21D812E5987B35EF262FCCDFE85FF02E21E95C20C66357D8C813C672AFF03D9B4023E94E4397596BEA7F642D14DDA48D455EE0EBC7979D7AAD8994DC9A0DB84F1EE247C71E3D3A5626455CABC9C91BBAA98E2DD96EDA9EC0CDE2130236907A41D227CC515E1B139D278BC9F1DC231BDBDD76C400564D3200B2F61980B679BE9D8BF9D37BA5C0CB681E5054431A61CBF3979F0E0CA30F
+20210513071712 2 6 100 7679 2 FAFDEC5D38380C2FFBEDCDA1262E4817F274B6544BB0A1904CF571375327EDF0105410A3F584F9A15982937EB5A64E30206DA90D66B89BF48EC74E7F40FB957673193875E02B88101A4FE81C47EBCB8451386AAEC6EA69F967310C79D8CC71BE07F669C3094E5F2CD314FF0FDD08256EFDFC03EF43C4704684CEEBBBFC48D48C920B2AC3CC15010D7EE49049D52B12E6E9228BF0482C174747EA40E558D88CACA9F143A496236C120DE560FDD7B2A1175407D333103C025E8EAE424AC5BADA1A354428B451F594BE605000CA3B2773B2D91FEDBBAF2E58DE2F03461A9F8D90B84209F66D7203E92774AB5B83809BAFFCC8D32ACB1B0AD4D1C2D37CED00654FB7517A56FE35CD364967D541D336C0E2CF96303B3BD1FBBC12D5DCF3D8F343BD2DD0EA3B5FA0062DC9A426A36DD27FD9C8E76DBB7FFE97BA3B27BDE53B017D7C9DFA6A4354FC95F3DAD99172290423EB507B574D6CEAF38A4AE227FD44541A29560020EA2EC10C5213E1EBC7A686AFA770A09C28E0D1EFB46AD409D2C58B8A4EF2E740957BCE903FF63D0B5E6BCF7E8C2B8F85DB93FC96E78BE2002603FF9AC2ACF368269FE034D6A5F8BFC6249FD140E85E9435C8B03D9390F1D0FD44519C21D174F7901BAB95DE7C91A1BFB9EB1079C584A71392A72768B2C2748145835AE7A5509B3C59539F46B5E0DF6955B84687C454679C9D87198605D78D1B551F502A5ACD915F55C919763C2F1206A0ADD5F651031A76EA0D102D064CBE24F919D3CF333D1EA0E89C1CA9E7D115802FC38757A50C97849D41E03C5F1EB8485CDDB55464E44172B0DE3D4F94A5AD01ECE4D70E17181225418F4205ABA526FA1D8C493749243D626C1D6A3170AD9D7DA551F3642229428803E81782D49355CB6CCEE08AB7583CA3A73354F2942BC6225E07788E542B1E2A9B46724D8A8EE0BE6F79CCDF78B10FC78FF3E15FFBC2EF1FFF4F53A328C7850BC0DAF358823712FF3609B981377D64FD274C578FFE92A6AE74F6F6A37907BD6B71FDA8C492C15BF9F820360709CFE9C5DFB03196120DF85D7D730DBA4CDFC36F2760227A5EAA27AA255935616A3833609B890B2445FC82D7A70B798DCB71E7C5B868AF06577FDDD034B63FF8A5CEEE3A1BBCD4CC61AF7A21D812E5987B35EF262FCCDFE85FF02E21E95C20C66357D8C813C672AFF03D9B4023E94E4397596BEA7F642D14DDA48D455EE0EBC7979D7AAD8994DC9A0DB84F1EE247C71E3D3A5626455CABC9C91BBAA98E2DD96EDA9EC0CDE2130236907A41D227CC515E1B139D278BC9F1DC231BDBDD76C400564D3200B2F61980B679BE9D8BF9D37BA5C0CB681E5054431A61CBF3979F1165FA43
+20210513072642 2 6 100 7679 5 FAFDEC5D38380C2FFBEDCDA1262E4817F274B6544BB0A1904CF571375327EDF0105410A3F584F9A15982937EB5A64E30206DA90D66B89BF48EC74E7F40FB957673193875E02B88101A4FE81C47EBCB8451386AAEC6EA69F967310C79D8CC71BE07F669C3094E5F2CD314FF0FDD08256EFDFC03EF43C4704684CEEBBBFC48D48C920B2AC3CC15010D7EE49049D52B12E6E9228BF0482C174747EA40E558D88CACA9F143A496236C120DE560FDD7B2A1175407D333103C025E8EAE424AC5BADA1A354428B451F594BE605000CA3B2773B2D91FEDBBAF2E58DE2F03461A9F8D90B84209F66D7203E92774AB5B83809BAFFCC8D32ACB1B0AD4D1C2D37CED00654FB7517A56FE35CD364967D541D336C0E2CF96303B3BD1FBBC12D5DCF3D8F343BD2DD0EA3B5FA0062DC9A426A36DD27FD9C8E76DBB7FFE97BA3B27BDE53B017D7C9DFA6A4354FC95F3DAD99172290423EB507B574D6CEAF38A4AE227FD44541A29560020EA2EC10C5213E1EBC7A686AFA770A09C28E0D1EFB46AD409D2C58B8A4EF2E740957BCE903FF63D0B5E6BCF7E8C2B8F85DB93FC96E78BE2002603FF9AC2ACF368269FE034D6A5F8BFC6249FD140E85E9435C8B03D9390F1D0FD44519C21D174F7901BAB95DE7C91A1BFB9EB1079C584A71392A72768B2C2748145835AE7A5509B3C59539F46B5E0DF6955B84687C454679C9D87198605D78D1B551F502A5ACD915F55C919763C2F1206A0ADD5F651031A76EA0D102D064CBE24F919D3CF333D1EA0E89C1CA9E7D115802FC38757A50C97849D41E03C5F1EB8485CDDB55464E44172B0DE3D4F94A5AD01ECE4D70E17181225418F4205ABA526FA1D8C493749243D626C1D6A3170AD9D7DA551F3642229428803E81782D49355CB6CCEE08AB7583CA3A73354F2942BC6225E07788E542B1E2A9B46724D8A8EE0BE6F79CCDF78B10FC78FF3E15FFBC2EF1FFF4F53A328C7850BC0DAF358823712FF3609B981377D64FD274C578FFE92A6AE74F6F6A37907BD6B71FDA8C492C15BF9F820360709CFE9C5DFB03196120DF85D7D730DBA4CDFC36F2760227A5EAA27AA255935616A3833609B890B2445FC82D7A70B798DCB71E7C5B868AF06577FDDD034B63FF8A5CEEE3A1BBCD4CC61AF7A21D812E5987B35EF262FCCDFE85FF02E21E95C20C66357D8C813C672AFF03D9B4023E94E4397596BEA7F642D14DDA48D455EE0EBC7979D7AAD8994DC9A0DB84F1EE247C71E3D3A5626455CABC9C91BBAA98E2DD96EDA9EC0CDE2130236907A41D227CC515E1B139D278BC9F1DC231BDBDD76C400564D3200B2F61980B679BE9D8BF9D37BA5C0CB681E5054431A61CBF3979F1213296F
+20210513075016 2 6 100 7679 5 FAFDEC5D38380C2FFBEDCDA1262E4817F274B6544BB0A1904CF571375327EDF0105410A3F584F9A15982937EB5A64E30206DA90D66B89BF48EC74E7F40FB957673193875E02B88101A4FE81C47EBCB8451386AAEC6EA69F967310C79D8CC71BE07F669C3094E5F2CD314FF0FDD08256EFDFC03EF43C4704684CEEBBBFC48D48C920B2AC3CC15010D7EE49049D52B12E6E9228BF0482C174747EA40E558D88CACA9F143A496236C120DE560FDD7B2A1175407D333103C025E8EAE424AC5BADA1A354428B451F594BE605000CA3B2773B2D91FEDBBAF2E58DE2F03461A9F8D90B84209F66D7203E92774AB5B83809BAFFCC8D32ACB1B0AD4D1C2D37CED00654FB7517A56FE35CD364967D541D336C0E2CF96303B3BD1FBBC12D5DCF3D8F343BD2DD0EA3B5FA0062DC9A426A36DD27FD9C8E76DBB7FFE97BA3B27BDE53B017D7C9DFA6A4354FC95F3DAD99172290423EB507B574D6CEAF38A4AE227FD44541A29560020EA2EC10C5213E1EBC7A686AFA770A09C28E0D1EFB46AD409D2C58B8A4EF2E740957BCE903FF63D0B5E6BCF7E8C2B8F85DB93FC96E78BE2002603FF9AC2ACF368269FE034D6A5F8BFC6249FD140E85E9435C8B03D9390F1D0FD44519C21D174F7901BAB95DE7C91A1BFB9EB1079C584A71392A72768B2C2748145835AE7A5509B3C59539F46B5E0DF6955B84687C454679C9D87198605D78D1B551F502A5ACD915F55C919763C2F1206A0ADD5F651031A76EA0D102D064CBE24F919D3CF333D1EA0E89C1CA9E7D115802FC38757A50C97849D41E03C5F1EB8485CDDB55464E44172B0DE3D4F94A5AD01ECE4D70E17181225418F4205ABA526FA1D8C493749243D626C1D6A3170AD9D7DA551F3642229428803E81782D49355CB6CCEE08AB7583CA3A73354F2942BC6225E07788E542B1E2A9B46724D8A8EE0BE6F79CCDF78B10FC78FF3E15FFBC2EF1FFF4F53A328C7850BC0DAF358823712FF3609B981377D64FD274C578FFE92A6AE74F6F6A37907BD6B71FDA8C492C15BF9F820360709CFE9C5DFB03196120DF85D7D730DBA4CDFC36F2760227A5EAA27AA255935616A3833609B890B2445FC82D7A70B798DCB71E7C5B868AF06577FDDD034B63FF8A5CEEE3A1BBCD4CC61AF7A21D812E5987B35EF262FCCDFE85FF02E21E95C20C66357D8C813C672AFF03D9B4023E94E4397596BEA7F642D14DDA48D455EE0EBC7979D7AAD8994DC9A0DB84F1EE247C71E3D3A5626455CABC9C91BBAA98E2DD96EDA9EC0CDE2130236907A41D227CC515E1B139D278BC9F1DC231BDBDD76C400564D3200B2F61980B679BE9D8BF9D37BA5C0CB681E5054431A61CBF3979F13D7F69F
+20210513080859 2 6 100 7679 2 FAFDEC5D38380C2FFBEDCDA1262E4817F274B6544BB0A1904CF571375327EDF0105410A3F584F9A15982937EB5A64E30206DA90D66B89BF48EC74E7F40FB957673193875E02B88101A4FE81C47EBCB8451386AAEC6EA69F967310C79D8CC71BE07F669C3094E5F2CD314FF0FDD08256EFDFC03EF43C4704684CEEBBBFC48D48C920B2AC3CC15010D7EE49049D52B12E6E9228BF0482C174747EA40E558D88CACA9F143A496236C120DE560FDD7B2A1175407D333103C025E8EAE424AC5BADA1A354428B451F594BE605000CA3B2773B2D91FEDBBAF2E58DE2F03461A9F8D90B84209F66D7203E92774AB5B83809BAFFCC8D32ACB1B0AD4D1C2D37CED00654FB7517A56FE35CD364967D541D336C0E2CF96303B3BD1FBBC12D5DCF3D8F343BD2DD0EA3B5FA0062DC9A426A36DD27FD9C8E76DBB7FFE97BA3B27BDE53B017D7C9DFA6A4354FC95F3DAD99172290423EB507B574D6CEAF38A4AE227FD44541A29560020EA2EC10C5213E1EBC7A686AFA770A09C28E0D1EFB46AD409D2C58B8A4EF2E740957BCE903FF63D0B5E6BCF7E8C2B8F85DB93FC96E78BE2002603FF9AC2ACF368269FE034D6A5F8BFC6249FD140E85E9435C8B03D9390F1D0FD44519C21D174F7901BAB95DE7C91A1BFB9EB1079C584A71392A72768B2C2748145835AE7A5509B3C59539F46B5E0DF6955B84687C454679C9D87198605D78D1B551F502A5ACD915F55C919763C2F1206A0ADD5F651031A76EA0D102D064CBE24F919D3CF333D1EA0E89C1CA9E7D115802FC38757A50C97849D41E03C5F1EB8485CDDB55464E44172B0DE3D4F94A5AD01ECE4D70E17181225418F4205ABA526FA1D8C493749243D626C1D6A3170AD9D7DA551F3642229428803E81782D49355CB6CCEE08AB7583CA3A73354F2942BC6225E07788E542B1E2A9B46724D8A8EE0BE6F79CCDF78B10FC78FF3E15FFBC2EF1FFF4F53A328C7850BC0DAF358823712FF3609B981377D64FD274C578FFE92A6AE74F6F6A37907BD6B71FDA8C492C15BF9F820360709CFE9C5DFB03196120DF85D7D730DBA4CDFC36F2760227A5EAA27AA255935616A3833609B890B2445FC82D7A70B798DCB71E7C5B868AF06577FDDD034B63FF8A5CEEE3A1BBCD4CC61AF7A21D812E5987B35EF262FCCDFE85FF02E21E95C20C66357D8C813C672AFF03D9B4023E94E4397596BEA7F642D14DDA48D455EE0EBC7979D7AAD8994DC9A0DB84F1EE247C71E3D3A5626455CABC9C91BBAA98E2DD96EDA9EC0CDE2130236907A41D227CC515E1B139D278BC9F1DC231BDBDD76C400564D3200B2F61980B679BE9D8BF9D37BA5C0CB681E5054431A61CBF3979F15405513
+20210513082937 2 6 100 7679 5 FAFDEC5D38380C2FFBEDCDA1262E4817F274B6544BB0A1904CF571375327EDF0105410A3F584F9A15982937EB5A64E30206DA90D66B89BF48EC74E7F40FB957673193875E02B88101A4FE81C47EBCB8451386AAEC6EA69F967310C79D8CC71BE07F669C3094E5F2CD314FF0FDD08256EFDFC03EF43C4704684CEEBBBFC48D48C920B2AC3CC15010D7EE49049D52B12E6E9228BF0482C174747EA40E558D88CACA9F143A496236C120DE560FDD7B2A1175407D333103C025E8EAE424AC5BADA1A354428B451F594BE605000CA3B2773B2D91FEDBBAF2E58DE2F03461A9F8D90B84209F66D7203E92774AB5B83809BAFFCC8D32ACB1B0AD4D1C2D37CED00654FB7517A56FE35CD364967D541D336C0E2CF96303B3BD1FBBC12D5DCF3D8F343BD2DD0EA3B5FA0062DC9A426A36DD27FD9C8E76DBB7FFE97BA3B27BDE53B017D7C9DFA6A4354FC95F3DAD99172290423EB507B574D6CEAF38A4AE227FD44541A29560020EA2EC10C5213E1EBC7A686AFA770A09C28E0D1EFB46AD409D2C58B8A4EF2E740957BCE903FF63D0B5E6BCF7E8C2B8F85DB93FC96E78BE2002603FF9AC2ACF368269FE034D6A5F8BFC6249FD140E85E9435C8B03D9390F1D0FD44519C21D174F7901BAB95DE7C91A1BFB9EB1079C584A71392A72768B2C2748145835AE7A5509B3C59539F46B5E0DF6955B84687C454679C9D87198605D78D1B551F502A5ACD915F55C919763C2F1206A0ADD5F651031A76EA0D102D064CBE24F919D3CF333D1EA0E89C1CA9E7D115802FC38757A50C97849D41E03C5F1EB8485CDDB55464E44172B0DE3D4F94A5AD01ECE4D70E17181225418F4205ABA526FA1D8C493749243D626C1D6A3170AD9D7DA551F3642229428803E81782D49355CB6CCEE08AB7583CA3A73354F2942BC6225E07788E542B1E2A9B46724D8A8EE0BE6F79CCDF78B10FC78FF3E15FFBC2EF1FFF4F53A328C7850BC0DAF358823712FF3609B981377D64FD274C578FFE92A6AE74F6F6A37907BD6B71FDA8C492C15BF9F820360709CFE9C5DFB03196120DF85D7D730DBA4CDFC36F2760227A5EAA27AA255935616A3833609B890B2445FC82D7A70B798DCB71E7C5B868AF06577FDDD034B63FF8A5CEEE3A1BBCD4CC61AF7A21D812E5987B35EF262FCCDFE85FF02E21E95C20C66357D8C813C672AFF03D9B4023E94E4397596BEA7F642D14DDA48D455EE0EBC7979D7AAD8994DC9A0DB84F1EE247C71E3D3A5626455CABC9C91BBAA98E2DD96EDA9EC0CDE2130236907A41D227CC515E1B139D278BC9F1DC231BDBDD76C400564D3200B2F61980B679BE9D8BF9D37BA5C0CB681E5054431A61CBF3979F16D0AEC7
+20210513084916 2 6 100 7679 2 FAFDEC5D38380C2FFBEDCDA1262E4817F274B6544BB0A1904CF571375327EDF0105410A3F584F9A15982937EB5A64E30206DA90D66B89BF48EC74E7F40FB957673193875E02B88101A4FE81C47EBCB8451386AAEC6EA69F967310C79D8CC71BE07F669C3094E5F2CD314FF0FDD08256EFDFC03EF43C4704684CEEBBBFC48D48C920B2AC3CC15010D7EE49049D52B12E6E9228BF0482C174747EA40E558D88CACA9F143A496236C120DE560FDD7B2A1175407D333103C025E8EAE424AC5BADA1A354428B451F594BE605000CA3B2773B2D91FEDBBAF2E58DE2F03461A9F8D90B84209F66D7203E92774AB5B83809BAFFCC8D32ACB1B0AD4D1C2D37CED00654FB7517A56FE35CD364967D541D336C0E2CF96303B3BD1FBBC12D5DCF3D8F343BD2DD0EA3B5FA0062DC9A426A36DD27FD9C8E76DBB7FFE97BA3B27BDE53B017D7C9DFA6A4354FC95F3DAD99172290423EB507B574D6CEAF38A4AE227FD44541A29560020EA2EC10C5213E1EBC7A686AFA770A09C28E0D1EFB46AD409D2C58B8A4EF2E740957BCE903FF63D0B5E6BCF7E8C2B8F85DB93FC96E78BE2002603FF9AC2ACF368269FE034D6A5F8BFC6249FD140E85E9435C8B03D9390F1D0FD44519C21D174F7901BAB95DE7C91A1BFB9EB1079C584A71392A72768B2C2748145835AE7A5509B3C59539F46B5E0DF6955B84687C454679C9D87198605D78D1B551F502A5ACD915F55C919763C2F1206A0ADD5F651031A76EA0D102D064CBE24F919D3CF333D1EA0E89C1CA9E7D115802FC38757A50C97849D41E03C5F1EB8485CDDB55464E44172B0DE3D4F94A5AD01ECE4D70E17181225418F4205ABA526FA1D8C493749243D626C1D6A3170AD9D7DA551F3642229428803E81782D49355CB6CCEE08AB7583CA3A73354F2942BC6225E07788E542B1E2A9B46724D8A8EE0BE6F79CCDF78B10FC78FF3E15FFBC2EF1FFF4F53A328C7850BC0DAF358823712FF3609B981377D64FD274C578FFE92A6AE74F6F6A37907BD6B71FDA8C492C15BF9F820360709CFE9C5DFB03196120DF85D7D730DBA4CDFC36F2760227A5EAA27AA255935616A3833609B890B2445FC82D7A70B798DCB71E7C5B868AF06577FDDD034B63FF8A5CEEE3A1BBCD4CC61AF7A21D812E5987B35EF262FCCDFE85FF02E21E95C20C66357D8C813C672AFF03D9B4023E94E4397596BEA7F642D14DDA48D455EE0EBC7979D7AAD8994DC9A0DB84F1EE247C71E3D3A5626455CABC9C91BBAA98E2DD96EDA9EC0CDE2130236907A41D227CC515E1B139D278BC9F1DC231BDBDD76C400564D3200B2F61980B679BE9D8BF9D37BA5C0CB681E5054431A61CBF3979F184559A3
+20210513101622 2 6 100 7679 2 FAFDEC5D38380C2FFBEDCDA1262E4817F274B6544BB0A1904CF571375327EDF0105410A3F584F9A15982937EB5A64E30206DA90D66B89BF48EC74E7F40FB957673193875E02B88101A4FE81C47EBCB8451386AAEC6EA69F967310C79D8CC71BE07F669C3094E5F2CD314FF0FDD08256EFDFC03EF43C4704684CEEBBBFC48D48C920B2AC3CC15010D7EE49049D52B12E6E9228BF0482C174747EA40E558D88CACA9F143A496236C120DE560FDD7B2A1175407D333103C025E8EAE424AC5BADA1A354428B451F594BE605000CA3B2773B2D91FEDBBAF2E58DE2F03461A9F8D90B84209F66D7203E92774AB5B83809BAFFCC8D32ACB1B0AD4D1C2D37CED00654FB7517A56FE35CD364967D541D336C0E2CF96303B3BD1FBBC12D5DCF3D8F343BD2DD0EA3B5FA0062DC9A426A36DD27FD9C8E76DBB7FFE97BA3B27BDE53B017D7C9DFA6A4354FC95F3DAD99172290423EB507B574D6CEAF38A4AE227FD44541A29560020EA2EC10C5213E1EBC7A686AFA770A09C28E0D1EFB46AD409D2C58B8A4EF2E740957BCE903FF63D0B5E6BCF7E8C2B8F85DB93FC96E78BE2002603FF9AC2ACF368269FE034D6A5F8BFC6249FD140E85E9435C8B03D9390F1D0FD44519C21D174F7901BAB95DE7C91A1BFB9EB1079C584A71392A72768B2C2748145835AE7A5509B3C59539F46B5E0DF6955B84687C454679C9D87198605D78D1B551F502A5ACD915F55C919763C2F1206A0ADD5F651031A76EA0D102D064CBE24F919D3CF333D1EA0E89C1CA9E7D115802FC38757A50C97849D41E03C5F1EB8485CDDB55464E44172B0DE3D4F94A5AD01ECE4D70E17181225418F4205ABA526FA1D8C493749243D626C1D6A3170AD9D7DA551F3642229428803E81782D49355CB6CCEE08AB7583CA3A73354F2942BC6225E07788E542B1E2A9B46724D8A8EE0BE6F79CCDF78B10FC78FF3E15FFBC2EF1FFF4F53A328C7850BC0DAF358823712FF3609B981377D64FD274C578FFE92A6AE74F6F6A37907BD6B71FDA8C492C15BF9F820360709CFE9C5DFB03196120DF85D7D730DBA4CDFC36F2760227A5EAA27AA255935616A3833609B890B2445FC82D7A70B798DCB71E7C5B868AF06577FDDD034B63FF8A5CEEE3A1BBCD4CC61AF7A21D812E5987B35EF262FCCDFE85FF02E21E95C20C66357D8C813C672AFF03D9B4023E94E4397596BEA7F642D14DDA48D455EE0EBC7979D7AAD8994DC9A0DB84F1EE247C71E3D3A5626455CABC9C91BBAA98E2DD96EDA9EC0CDE2130236907A41D227CC515E1B139D278BC9F1DC231BDBDD76C400564D3200B2F61980B679BE9D8BF9D37BA5C0CB681E5054431A61CBF3979F1ED0663B
+20210513103219 2 6 100 7679 2 FAFDEC5D38380C2FFBEDCDA1262E4817F274B6544BB0A1904CF571375327EDF0105410A3F584F9A15982937EB5A64E30206DA90D66B89BF48EC74E7F40FB957673193875E02B88101A4FE81C47EBCB8451386AAEC6EA69F967310C79D8CC71BE07F669C3094E5F2CD314FF0FDD08256EFDFC03EF43C4704684CEEBBBFC48D48C920B2AC3CC15010D7EE49049D52B12E6E9228BF0482C174747EA40E558D88CACA9F143A496236C120DE560FDD7B2A1175407D333103C025E8EAE424AC5BADA1A354428B451F594BE605000CA3B2773B2D91FEDBBAF2E58DE2F03461A9F8D90B84209F66D7203E92774AB5B83809BAFFCC8D32ACB1B0AD4D1C2D37CED00654FB7517A56FE35CD364967D541D336C0E2CF96303B3BD1FBBC12D5DCF3D8F343BD2DD0EA3B5FA0062DC9A426A36DD27FD9C8E76DBB7FFE97BA3B27BDE53B017D7C9DFA6A4354FC95F3DAD99172290423EB507B574D6CEAF38A4AE227FD44541A29560020EA2EC10C5213E1EBC7A686AFA770A09C28E0D1EFB46AD409D2C58B8A4EF2E740957BCE903FF63D0B5E6BCF7E8C2B8F85DB93FC96E78BE2002603FF9AC2ACF368269FE034D6A5F8BFC6249FD140E85E9435C8B03D9390F1D0FD44519C21D174F7901BAB95DE7C91A1BFB9EB1079C584A71392A72768B2C2748145835AE7A5509B3C59539F46B5E0DF6955B84687C454679C9D87198605D78D1B551F502A5ACD915F55C919763C2F1206A0ADD5F651031A76EA0D102D064CBE24F919D3CF333D1EA0E89C1CA9E7D115802FC38757A50C97849D41E03C5F1EB8485CDDB55464E44172B0DE3D4F94A5AD01ECE4D70E17181225418F4205ABA526FA1D8C493749243D626C1D6A3170AD9D7DA551F3642229428803E81782D49355CB6CCEE08AB7583CA3A73354F2942BC6225E07788E542B1E2A9B46724D8A8EE0BE6F79CCDF78B10FC78FF3E15FFBC2EF1FFF4F53A328C7850BC0DAF358823712FF3609B981377D64FD274C578FFE92A6AE74F6F6A37907BD6B71FDA8C492C15BF9F820360709CFE9C5DFB03196120DF85D7D730DBA4CDFC36F2760227A5EAA27AA255935616A3833609B890B2445FC82D7A70B798DCB71E7C5B868AF06577FDDD034B63FF8A5CEEE3A1BBCD4CC61AF7A21D812E5987B35EF262FCCDFE85FF02E21E95C20C66357D8C813C672AFF03D9B4023E94E4397596BEA7F642D14DDA48D455EE0EBC7979D7AAD8994DC9A0DB84F1EE247C71E3D3A5626455CABC9C91BBAA98E2DD96EDA9EC0CDE2130236907A41D227CC515E1B139D278BC9F1DC231BDBDD76C400564D3200B2F61980B679BE9D8BF9D37BA5C0CB681E5054431A61CBF3979F1FF64A7B
+20210513105336 2 6 100 7679 2 FAFDEC5D38380C2FFBEDCDA1262E4817F274B6544BB0A1904CF571375327EDF0105410A3F584F9A15982937EB5A64E30206DA90D66B89BF48EC74E7F40FB957673193875E02B88101A4FE81C47EBCB8451386AAEC6EA69F967310C79D8CC71BE07F669C3094E5F2CD314FF0FDD08256EFDFC03EF43C4704684CEEBBBFC48D48C920B2AC3CC15010D7EE49049D52B12E6E9228BF0482C174747EA40E558D88CACA9F143A496236C120DE560FDD7B2A1175407D333103C025E8EAE424AC5BADA1A354428B451F594BE605000CA3B2773B2D91FEDBBAF2E58DE2F03461A9F8D90B84209F66D7203E92774AB5B83809BAFFCC8D32ACB1B0AD4D1C2D37CED00654FB7517A56FE35CD364967D541D336C0E2CF96303B3BD1FBBC12D5DCF3D8F343BD2DD0EA3B5FA0062DC9A426A36DD27FD9C8E76DBB7FFE97BA3B27BDE53B017D7C9DFA6A4354FC95F3DAD99172290423EB507B574D6CEAF38A4AE227FD44541A29560020EA2EC10C5213E1EBC7A686AFA770A09C28E0D1EFB46AD409D2C58B8A4EF2E740957BCE903FF63D0B5E6BCF7E8C2B8F85DB93FC96E78BE2002603FF9AC2ACF368269FE034D6A5F8BFC6249FD140E85E9435C8B03D9390F1D0FD44519C21D174F7901BAB95DE7C91A1BFB9EB1079C584A71392A72768B2C2748145835AE7A5509B3C59539F46B5E0DF6955B84687C454679C9D87198605D78D1B551F502A5ACD915F55C919763C2F1206A0ADD5F651031A76EA0D102D064CBE24F919D3CF333D1EA0E89C1CA9E7D115802FC38757A50C97849D41E03C5F1EB8485CDDB55464E44172B0DE3D4F94A5AD01ECE4D70E17181225418F4205ABA526FA1D8C493749243D626C1D6A3170AD9D7DA551F3642229428803E81782D49355CB6CCEE08AB7583CA3A73354F2942BC6225E07788E542B1E2A9B46724D8A8EE0BE6F79CCDF78B10FC78FF3E15FFBC2EF1FFF4F53A328C7850BC0DAF358823712FF3609B981377D64FD274C578FFE92A6AE74F6F6A37907BD6B71FDA8C492C15BF9F820360709CFE9C5DFB03196120DF85D7D730DBA4CDFC36F2760227A5EAA27AA255935616A3833609B890B2445FC82D7A70B798DCB71E7C5B868AF06577FDDD034B63FF8A5CEEE3A1BBCD4CC61AF7A21D812E5987B35EF262FCCDFE85FF02E21E95C20C66357D8C813C672AFF03D9B4023E94E4397596BEA7F642D14DDA48D455EE0EBC7979D7AAD8994DC9A0DB84F1EE247C71E3D3A5626455CABC9C91BBAA98E2DD96EDA9EC0CDE2130236907A41D227CC515E1B139D278BC9F1DC231BDBDD76C400564D3200B2F61980B679BE9D8BF9D37BA5C0CB681E5054431A61CBF3979F217BF603
+20210513120417 2 6 100 7679 2 FAFDEC5D38380C2FFBEDCDA1262E4817F274B6544BB0A1904CF571375327EDF0105410A3F584F9A15982937EB5A64E30206DA90D66B89BF48EC74E7F40FB957673193875E02B88101A4FE81C47EBCB8451386AAEC6EA69F967310C79D8CC71BE07F669C3094E5F2CD314FF0FDD08256EFDFC03EF43C4704684CEEBBBFC48D48C920B2AC3CC15010D7EE49049D52B12E6E9228BF0482C174747EA40E558D88CACA9F143A496236C120DE560FDD7B2A1175407D333103C025E8EAE424AC5BADA1A354428B451F594BE605000CA3B2773B2D91FEDBBAF2E58DE2F03461A9F8D90B84209F66D7203E92774AB5B83809BAFFCC8D32ACB1B0AD4D1C2D37CED00654FB7517A56FE35CD364967D541D336C0E2CF96303B3BD1FBBC12D5DCF3D8F343BD2DD0EA3B5FA0062DC9A426A36DD27FD9C8E76DBB7FFE97BA3B27BDE53B017D7C9DFA6A4354FC95F3DAD99172290423EB507B574D6CEAF38A4AE227FD44541A29560020EA2EC10C5213E1EBC7A686AFA770A09C28E0D1EFB46AD409D2C58B8A4EF2E740957BCE903FF63D0B5E6BCF7E8C2B8F85DB93FC96E78BE2002603FF9AC2ACF368269FE034D6A5F8BFC6249FD140E85E9435C8B03D9390F1D0FD44519C21D174F7901BAB95DE7C91A1BFB9EB1079C584A71392A72768B2C2748145835AE7A5509B3C59539F46B5E0DF6955B84687C454679C9D87198605D78D1B551F502A5ACD915F55C919763C2F1206A0ADD5F651031A76EA0D102D064CBE24F919D3CF333D1EA0E89C1CA9E7D115802FC38757A50C97849D41E03C5F1EB8485CDDB55464E44172B0DE3D4F94A5AD01ECE4D70E17181225418F4205ABA526FA1D8C493749243D626C1D6A3170AD9D7DA551F3642229428803E81782D49355CB6CCEE08AB7583CA3A73354F2942BC6225E07788E542B1E2A9B46724D8A8EE0BE6F79CCDF78B10FC78FF3E15FFBC2EF1FFF4F53A328C7850BC0DAF358823712FF3609B981377D64FD274C578FFE92A6AE74F6F6A37907BD6B71FDA8C492C15BF9F820360709CFE9C5DFB03196120DF85D7D730DBA4CDFC36F2760227A5EAA27AA255935616A3833609B890B2445FC82D7A70B798DCB71E7C5B868AF06577FDDD034B63FF8A5CEEE3A1BBCD4CC61AF7A21D812E5987B35EF262FCCDFE85FF02E21E95C20C66357D8C813C672AFF03D9B4023E94E4397596BEA7F642D14DDA48D455EE0EBC7979D7AAD8994DC9A0DB84F1EE247C71E3D3A5626455CABC9C91BBAA98E2DD96EDA9EC0CDE2130236907A41D227CC515E1B139D278BC9F1DC231BDBDD76C400564D3200B2F61980B679BE9D8BF9D37BA5C0CB681E5054431A61CBF3979F26CCF6D3
+20210513122242 2 6 100 7679 5 FAFDEC5D38380C2FFBEDCDA1262E4817F274B6544BB0A1904CF571375327EDF0105410A3F584F9A15982937EB5A64E30206DA90D66B89BF48EC74E7F40FB957673193875E02B88101A4FE81C47EBCB8451386AAEC6EA69F967310C79D8CC71BE07F669C3094E5F2CD314FF0FDD08256EFDFC03EF43C4704684CEEBBBFC48D48C920B2AC3CC15010D7EE49049D52B12E6E9228BF0482C174747EA40E558D88CACA9F143A496236C120DE560FDD7B2A1175407D333103C025E8EAE424AC5BADA1A354428B451F594BE605000CA3B2773B2D91FEDBBAF2E58DE2F03461A9F8D90B84209F66D7203E92774AB5B83809BAFFCC8D32ACB1B0AD4D1C2D37CED00654FB7517A56FE35CD364967D541D336C0E2CF96303B3BD1FBBC12D5DCF3D8F343BD2DD0EA3B5FA0062DC9A426A36DD27FD9C8E76DBB7FFE97BA3B27BDE53B017D7C9DFA6A4354FC95F3DAD99172290423EB507B574D6CEAF38A4AE227FD44541A29560020EA2EC10C5213E1EBC7A686AFA770A09C28E0D1EFB46AD409D2C58B8A4EF2E740957BCE903FF63D0B5E6BCF7E8C2B8F85DB93FC96E78BE2002603FF9AC2ACF368269FE034D6A5F8BFC6249FD140E85E9435C8B03D9390F1D0FD44519C21D174F7901BAB95DE7C91A1BFB9EB1079C584A71392A72768B2C2748145835AE7A5509B3C59539F46B5E0DF6955B84687C454679C9D87198605D78D1B551F502A5ACD915F55C919763C2F1206A0ADD5F651031A76EA0D102D064CBE24F919D3CF333D1EA0E89C1CA9E7D115802FC38757A50C97849D41E03C5F1EB8485CDDB55464E44172B0DE3D4F94A5AD01ECE4D70E17181225418F4205ABA526FA1D8C493749243D626C1D6A3170AD9D7DA551F3642229428803E81782D49355CB6CCEE08AB7583CA3A73354F2942BC6225E07788E542B1E2A9B46724D8A8EE0BE6F79CCDF78B10FC78FF3E15FFBC2EF1FFF4F53A328C7850BC0DAF358823712FF3609B981377D64FD274C578FFE92A6AE74F6F6A37907BD6B71FDA8C492C15BF9F820360709CFE9C5DFB03196120DF85D7D730DBA4CDFC36F2760227A5EAA27AA255935616A3833609B890B2445FC82D7A70B798DCB71E7C5B868AF06577FDDD034B63FF8A5CEEE3A1BBCD4CC61AF7A21D812E5987B35EF262FCCDFE85FF02E21E95C20C66357D8C813C672AFF03D9B4023E94E4397596BEA7F642D14DDA48D455EE0EBC7979D7AAD8994DC9A0DB84F1EE247C71E3D3A5626455CABC9C91BBAA98E2DD96EDA9EC0CDE2130236907A41D227CC515E1B139D278BC9F1DC231BDBDD76C400564D3200B2F61980B679BE9D8BF9D37BA5C0CB681E5054431A61CBF3979F28222B57
+20210513122833 2 6 100 7679 2 FAFDEC5D38380C2FFBEDCDA1262E4817F274B6544BB0A1904CF571375327EDF0105410A3F584F9A15982937EB5A64E30206DA90D66B89BF48EC74E7F40FB957673193875E02B88101A4FE81C47EBCB8451386AAEC6EA69F967310C79D8CC71BE07F669C3094E5F2CD314FF0FDD08256EFDFC03EF43C4704684CEEBBBFC48D48C920B2AC3CC15010D7EE49049D52B12E6E9228BF0482C174747EA40E558D88CACA9F143A496236C120DE560FDD7B2A1175407D333103C025E8EAE424AC5BADA1A354428B451F594BE605000CA3B2773B2D91FEDBBAF2E58DE2F03461A9F8D90B84209F66D7203E92774AB5B83809BAFFCC8D32ACB1B0AD4D1C2D37CED00654FB7517A56FE35CD364967D541D336C0E2CF96303B3BD1FBBC12D5DCF3D8F343BD2DD0EA3B5FA0062DC9A426A36DD27FD9C8E76DBB7FFE97BA3B27BDE53B017D7C9DFA6A4354FC95F3DAD99172290423EB507B574D6CEAF38A4AE227FD44541A29560020EA2EC10C5213E1EBC7A686AFA770A09C28E0D1EFB46AD409D2C58B8A4EF2E740957BCE903FF63D0B5E6BCF7E8C2B8F85DB93FC96E78BE2002603FF9AC2ACF368269FE034D6A5F8BFC6249FD140E85E9435C8B03D9390F1D0FD44519C21D174F7901BAB95DE7C91A1BFB9EB1079C584A71392A72768B2C2748145835AE7A5509B3C59539F46B5E0DF6955B84687C454679C9D87198605D78D1B551F502A5ACD915F55C919763C2F1206A0ADD5F651031A76EA0D102D064CBE24F919D3CF333D1EA0E89C1CA9E7D115802FC38757A50C97849D41E03C5F1EB8485CDDB55464E44172B0DE3D4F94A5AD01ECE4D70E17181225418F4205ABA526FA1D8C493749243D626C1D6A3170AD9D7DA551F3642229428803E81782D49355CB6CCEE08AB7583CA3A73354F2942BC6225E07788E542B1E2A9B46724D8A8EE0BE6F79CCDF78B10FC78FF3E15FFBC2EF1FFF4F53A328C7850BC0DAF358823712FF3609B981377D64FD274C578FFE92A6AE74F6F6A37907BD6B71FDA8C492C15BF9F820360709CFE9C5DFB03196120DF85D7D730DBA4CDFC36F2760227A5EAA27AA255935616A3833609B890B2445FC82D7A70B798DCB71E7C5B868AF06577FDDD034B63FF8A5CEEE3A1BBCD4CC61AF7A21D812E5987B35EF262FCCDFE85FF02E21E95C20C66357D8C813C672AFF03D9B4023E94E4397596BEA7F642D14DDA48D455EE0EBC7979D7AAD8994DC9A0DB84F1EE247C71E3D3A5626455CABC9C91BBAA98E2DD96EDA9EC0CDE2130236907A41D227CC515E1B139D278BC9F1DC231BDBDD76C400564D3200B2F61980B679BE9D8BF9D37BA5C0CB681E5054431A61CBF3979F2886B733
+20210513132056 2 6 100 7679 5 FAFDEC5D38380C2FFBEDCDA1262E4817F274B6544BB0A1904CF571375327EDF0105410A3F584F9A15982937EB5A64E30206DA90D66B89BF48EC74E7F40FB957673193875E02B88101A4FE81C47EBCB8451386AAEC6EA69F967310C79D8CC71BE07F669C3094E5F2CD314FF0FDD08256EFDFC03EF43C4704684CEEBBBFC48D48C920B2AC3CC15010D7EE49049D52B12E6E9228BF0482C174747EA40E558D88CACA9F143A496236C120DE560FDD7B2A1175407D333103C025E8EAE424AC5BADA1A354428B451F594BE605000CA3B2773B2D91FEDBBAF2E58DE2F03461A9F8D90B84209F66D7203E92774AB5B83809BAFFCC8D32ACB1B0AD4D1C2D37CED00654FB7517A56FE35CD364967D541D336C0E2CF96303B3BD1FBBC12D5DCF3D8F343BD2DD0EA3B5FA0062DC9A426A36DD27FD9C8E76DBB7FFE97BA3B27BDE53B017D7C9DFA6A4354FC95F3DAD99172290423EB507B574D6CEAF38A4AE227FD44541A29560020EA2EC10C5213E1EBC7A686AFA770A09C28E0D1EFB46AD409D2C58B8A4EF2E740957BCE903FF63D0B5E6BCF7E8C2B8F85DB93FC96E78BE2002603FF9AC2ACF368269FE034D6A5F8BFC6249FD140E85E9435C8B03D9390F1D0FD44519C21D174F7901BAB95DE7C91A1BFB9EB1079C584A71392A72768B2C2748145835AE7A5509B3C59539F46B5E0DF6955B84687C454679C9D87198605D78D1B551F502A5ACD915F55C919763C2F1206A0ADD5F651031A76EA0D102D064CBE24F919D3CF333D1EA0E89C1CA9E7D115802FC38757A50C97849D41E03C5F1EB8485CDDB55464E44172B0DE3D4F94A5AD01ECE4D70E17181225418F4205ABA526FA1D8C493749243D626C1D6A3170AD9D7DA551F3642229428803E81782D49355CB6CCEE08AB7583CA3A73354F2942BC6225E07788E542B1E2A9B46724D8A8EE0BE6F79CCDF78B10FC78FF3E15FFBC2EF1FFF4F53A328C7850BC0DAF358823712FF3609B981377D64FD274C578FFE92A6AE74F6F6A37907BD6B71FDA8C492C15BF9F820360709CFE9C5DFB03196120DF85D7D730DBA4CDFC36F2760227A5EAA27AA255935616A3833609B890B2445FC82D7A70B798DCB71E7C5B868AF06577FDDD034B63FF8A5CEEE3A1BBCD4CC61AF7A21D812E5987B35EF262FCCDFE85FF02E21E95C20C66357D8C813C672AFF03D9B4023E94E4397596BEA7F642D14DDA48D455EE0EBC7979D7AAD8994DC9A0DB84F1EE247C71E3D3A5626455CABC9C91BBAA98E2DD96EDA9EC0CDE2130236907A41D227CC515E1B139D278BC9F1DC231BDBDD76C400564D3200B2F61980B679BE9D8BF9D37BA5C0CB681E5054431A61CBF3979F2C65CDC7
+20210513133945 2 6 100 7679 5 FAFDEC5D38380C2FFBEDCDA1262E4817F274B6544BB0A1904CF571375327EDF0105410A3F584F9A15982937EB5A64E30206DA90D66B89BF48EC74E7F40FB957673193875E02B88101A4FE81C47EBCB8451386AAEC6EA69F967310C79D8CC71BE07F669C3094E5F2CD314FF0FDD08256EFDFC03EF43C4704684CEEBBBFC48D48C920B2AC3CC15010D7EE49049D52B12E6E9228BF0482C174747EA40E558D88CACA9F143A496236C120DE560FDD7B2A1175407D333103C025E8EAE424AC5BADA1A354428B451F594BE605000CA3B2773B2D91FEDBBAF2E58DE2F03461A9F8D90B84209F66D7203E92774AB5B83809BAFFCC8D32ACB1B0AD4D1C2D37CED00654FB7517A56FE35CD364967D541D336C0E2CF96303B3BD1FBBC12D5DCF3D8F343BD2DD0EA3B5FA0062DC9A426A36DD27FD9C8E76DBB7FFE97BA3B27BDE53B017D7C9DFA6A4354FC95F3DAD99172290423EB507B574D6CEAF38A4AE227FD44541A29560020EA2EC10C5213E1EBC7A686AFA770A09C28E0D1EFB46AD409D2C58B8A4EF2E740957BCE903FF63D0B5E6BCF7E8C2B8F85DB93FC96E78BE2002603FF9AC2ACF368269FE034D6A5F8BFC6249FD140E85E9435C8B03D9390F1D0FD44519C21D174F7901BAB95DE7C91A1BFB9EB1079C584A71392A72768B2C2748145835AE7A5509B3C59539F46B5E0DF6955B84687C454679C9D87198605D78D1B551F502A5ACD915F55C919763C2F1206A0ADD5F651031A76EA0D102D064CBE24F919D3CF333D1EA0E89C1CA9E7D115802FC38757A50C97849D41E03C5F1EB8485CDDB55464E44172B0DE3D4F94A5AD01ECE4D70E17181225418F4205ABA526FA1D8C493749243D626C1D6A3170AD9D7DA551F3642229428803E81782D49355CB6CCEE08AB7583CA3A73354F2942BC6225E07788E542B1E2A9B46724D8A8EE0BE6F79CCDF78B10FC78FF3E15FFBC2EF1FFF4F53A328C7850BC0DAF358823712FF3609B981377D64FD274C578FFE92A6AE74F6F6A37907BD6B71FDA8C492C15BF9F820360709CFE9C5DFB03196120DF85D7D730DBA4CDFC36F2760227A5EAA27AA255935616A3833609B890B2445FC82D7A70B798DCB71E7C5B868AF06577FDDD034B63FF8A5CEEE3A1BBCD4CC61AF7A21D812E5987B35EF262FCCDFE85FF02E21E95C20C66357D8C813C672AFF03D9B4023E94E4397596BEA7F642D14DDA48D455EE0EBC7979D7AAD8994DC9A0DB84F1EE247C71E3D3A5626455CABC9C91BBAA98E2DD96EDA9EC0CDE2130236907A41D227CC515E1B139D278BC9F1DC231BDBDD76C400564D3200B2F61980B679BE9D8BF9D37BA5C0CB681E5054431A61CBF3979F2DC4BF6F
+20210513144224 2 6 100 8191 2 D352935F33D9BC205912B919A6C5F18F76C30A32F6C0390249B48383BA4F31098BF5B6B2ACE6A745344840435A6C9A0DBF8E268F0463420452610E9A624590DC2CD57490F709DFFC5A54630DE486C73DB3C377B87C919F90BA88A7B41627351E6BEADBA605C2C625833BB95E9F34892A5D15DDF216D1A549FCFA819D7567D99015B1C3944254B87680222859779EA64C26FCEF82F34FE28E765DE3DDBCB9B3664E7896B18B93B9AA3A69944E8CEB93C18F671E2A75D6C1061B23AF8B913911A73099EA5B0F527C054B8A71B335A65CE680F02DC58D27FDBBA83EE263DD9E171B190F1CDB173BF56BB93407074B1899E8D59832EF383BCF6FB145E0F8A4A7484A2F8F4178D0A8DF9B8B920FF1250BF88BE770FD43D7EF2F4B998D86628A676173384FA95CB6B8A2599F8D5BFAA9E7C025CF29A9E1A8818B90CF2568CB8F3C003BC22B873374ACEF560B114B6B3EA0ED1701CE77A34E2723FB377BD67D480E3BF6A4E71763ED85C4E5F034A8E1761B1424AC67CFD1727157A43EEAD2168622F43967A4494E3C3D92E41EF47B7425D13D746CF617F9BB0F7CF04C093261541B6BAD54E3ED418AA1044C21FCC95B3416E6648FC576AECA4A82F2E69CE017A982407FAB0B656B56933908F1FD739686102F68805B8C605CF88952AEE1257382DE39D777527416FBED01472FE9C947AD58968D7FF2847328265584C2E93F7DF92CA891122AF48B9549020D2FAC44913C2DB5DAE20434E477FC5AF527E3D16D13B5586131FA1CC6AB1D522A1EFDA51B84D82BCBC0E76F00E0C790A9C07D0CD81088A6E972BB453B0D72AACF78BE9506B25301A473C0F4E6DF46B6517C73D9809F5319DA70BD22C0C17D90A0A26080E262D9DFB50B21AABFB60D76E655B78B2C4A4EDE0D32CE1BBD3F05F49C12B30DA10A13BAA95F907A1306F4FAFA251D8F6E16B6A5EB177D7777FFAB5A875B3D27D250B496B3EDCF818020A27D1CF30EF135AA50CF05B70D1FBCFAB92C7D0CC17E3AB813D23233BEDB187FAB1406BB9397760F905658A124923E6F97F947EF88572CC3F50F16FC716DEA622F9878462113A5E43CFA165D80B531843CB024CC310FB4FD80788A67ABCADDD99BD5A26D1FDB72FA5DF44C84085D7EA30393ABA8E7CB659489DE64CAECC4E2E6779E80CAC156B5957C30B89F073E97BD013CE3E7D260917C1B3C46F6AF0B77A2109E7A81DBB20745B4FD4B33BCC08FD30F554C5EF9B6E69CBD225A498D2D51CA440B83205DF7AE9020AF2595F3CC648907EA05C2F4063C835606A4598A7E9CF67710332A938B1FF851A6697F9A38FFA2CCF2BBD6A00F8437794DA285A8E298CCF2D5497DCA6065D8E0AD829172FBF4D10F75BE58F97FB2D272DD9B57C5659910BDF70D78C45FDFE135DC75F8DBB69F78EF068CBEA5F9FC8940D45AB9928C9002EA165CBBFFB1974BC3929B
+20210513153319 2 6 100 8191 2 D352935F33D9BC205912B919A6C5F18F76C30A32F6C0390249B48383BA4F31098BF5B6B2ACE6A745344840435A6C9A0DBF8E268F0463420452610E9A624590DC2CD57490F709DFFC5A54630DE486C73DB3C377B87C919F90BA88A7B41627351E6BEADBA605C2C625833BB95E9F34892A5D15DDF216D1A549FCFA819D7567D99015B1C3944254B87680222859779EA64C26FCEF82F34FE28E765DE3DDBCB9B3664E7896B18B93B9AA3A69944E8CEB93C18F671E2A75D6C1061B23AF8B913911A73099EA5B0F527C054B8A71B335A65CE680F02DC58D27FDBBA83EE263DD9E171B190F1CDB173BF56BB93407074B1899E8D59832EF383BCF6FB145E0F8A4A7484A2F8F4178D0A8DF9B8B920FF1250BF88BE770FD43D7EF2F4B998D86628A676173384FA95CB6B8A2599F8D5BFAA9E7C025CF29A9E1A8818B90CF2568CB8F3C003BC22B873374ACEF560B114B6B3EA0ED1701CE77A34E2723FB377BD67D480E3BF6A4E71763ED85C4E5F034A8E1761B1424AC67CFD1727157A43EEAD2168622F43967A4494E3C3D92E41EF47B7425D13D746CF617F9BB0F7CF04C093261541B6BAD54E3ED418AA1044C21FCC95B3416E6648FC576AECA4A82F2E69CE017A982407FAB0B656B56933908F1FD739686102F68805B8C605CF88952AEE1257382DE39D777527416FBED01472FE9C947AD58968D7FF2847328265584C2E93F7DF92CA891122AF48B9549020D2FAC44913C2DB5DAE20434E477FC5AF527E3D16D13B5586131FA1CC6AB1D522A1EFDA51B84D82BCBC0E76F00E0C790A9C07D0CD81088A6E972BB453B0D72AACF78BE9506B25301A473C0F4E6DF46B6517C73D9809F5319DA70BD22C0C17D90A0A26080E262D9DFB50B21AABFB60D76E655B78B2C4A4EDE0D32CE1BBD3F05F49C12B30DA10A13BAA95F907A1306F4FAFA251D8F6E16B6A5EB177D7777FFAB5A875B3D27D250B496B3EDCF818020A27D1CF30EF135AA50CF05B70D1FBCFAB92C7D0CC17E3AB813D23233BEDB187FAB1406BB9397760F905658A124923E6F97F947EF88572CC3F50F16FC716DEA622F9878462113A5E43CFA165D80B531843CB024CC310FB4FD80788A67ABCADDD99BD5A26D1FDB72FA5DF44C84085D7EA30393ABA8E7CB659489DE64CAECC4E2E6779E80CAC156B5957C30B89F073E97BD013CE3E7D260917C1B3C46F6AF0B77A2109E7A81DBB20745B4FD4B33BCC08FD30F554C5EF9B6E69CBD225A498D2D51CA440B83205DF7AE9020AF2595F3CC648907EA05C2F4063C835606A4598A7E9CF67710332A938B1FF851A6697F9A38FFA2CCF2BBD6A00F8437794DA285A8E298CCF2D5497DCA6065D8E0AD829172FBF4D10F75BE58F97FB2D272DD9B57C5659910BDF70D78C45FDFE135DC75F8DBB69F78EF068CBEA5F9FC8940D45AB9928C9002EA165CBBFFB1974F77AE5B
+20210513202423 2 6 100 8191 5 D352935F33D9BC205912B919A6C5F18F76C30A32F6C0390249B48383BA4F31098BF5B6B2ACE6A745344840435A6C9A0DBF8E268F0463420452610E9A624590DC2CD57490F709DFFC5A54630DE486C73DB3C377B87C919F90BA88A7B41627351E6BEADBA605C2C625833BB95E9F34892A5D15DDF216D1A549FCFA819D7567D99015B1C3944254B87680222859779EA64C26FCEF82F34FE28E765DE3DDBCB9B3664E7896B18B93B9AA3A69944E8CEB93C18F671E2A75D6C1061B23AF8B913911A73099EA5B0F527C054B8A71B335A65CE680F02DC58D27FDBBA83EE263DD9E171B190F1CDB173BF56BB93407074B1899E8D59832EF383BCF6FB145E0F8A4A7484A2F8F4178D0A8DF9B8B920FF1250BF88BE770FD43D7EF2F4B998D86628A676173384FA95CB6B8A2599F8D5BFAA9E7C025CF29A9E1A8818B90CF2568CB8F3C003BC22B873374ACEF560B114B6B3EA0ED1701CE77A34E2723FB377BD67D480E3BF6A4E71763ED85C4E5F034A8E1761B1424AC67CFD1727157A43EEAD2168622F43967A4494E3C3D92E41EF47B7425D13D746CF617F9BB0F7CF04C093261541B6BAD54E3ED418AA1044C21FCC95B3416E6648FC576AECA4A82F2E69CE017A982407FAB0B656B56933908F1FD739686102F68805B8C605CF88952AEE1257382DE39D777527416FBED01472FE9C947AD58968D7FF2847328265584C2E93F7DF92CA891122AF48B9549020D2FAC44913C2DB5DAE20434E477FC5AF527E3D16D13B5586131FA1CC6AB1D522A1EFDA51B84D82BCBC0E76F00E0C790A9C07D0CD81088A6E972BB453B0D72AACF78BE9506B25301A473C0F4E6DF46B6517C73D9809F5319DA70BD22C0C17D90A0A26080E262D9DFB50B21AABFB60D76E655B78B2C4A4EDE0D32CE1BBD3F05F49C12B30DA10A13BAA95F907A1306F4FAFA251D8F6E16B6A5EB177D7777FFAB5A875B3D27D250B496B3EDCF818020A27D1CF30EF135AA50CF05B70D1FBCFAB92C7D0CC17E3AB813D23233BEDB187FAB1406BB9397760F905658A124923E6F97F947EF88572CC3F50F16FC716DEA622F9878462113A5E43CFA165D80B531843CB024CC310FB4FD80788A67ABCADDD99BD5A26D1FDB72FA5DF44C84085D7EA30393ABA8E7CB659489DE64CAECC4E2E6779E80CAC156B5957C30B89F073E97BD013CE3E7D260917C1B3C46F6AF0B77A2109E7A81DBB20745B4FD4B33BCC08FD30F554C5EF9B6E69CBD225A498D2D51CA440B83205DF7AE9020AF2595F3CC648907EA05C2F4063C835606A4598A7E9CF67710332A938B1FF851A6697F9A38FFA2CCF2BBD6A00F8437794DA285A8E298CCF2D5497DCA6065D8E0AD829172FBF4D10F75BE58F97FB2D272DD9B57C5659910BDF70D78C45FDFE135DC75F8DBB69F78EF068CBEA5F9FC8940D45AB9928C9002EA165CBBFFB1976458B21F
+20210513231705 2 6 100 8191 5 D352935F33D9BC205912B919A6C5F18F76C30A32F6C0390249B48383BA4F31098BF5B6B2ACE6A745344840435A6C9A0DBF8E268F0463420452610E9A624590DC2CD57490F709DFFC5A54630DE486C73DB3C377B87C919F90BA88A7B41627351E6BEADBA605C2C625833BB95E9F34892A5D15DDF216D1A549FCFA819D7567D99015B1C3944254B87680222859779EA64C26FCEF82F34FE28E765DE3DDBCB9B3664E7896B18B93B9AA3A69944E8CEB93C18F671E2A75D6C1061B23AF8B913911A73099EA5B0F527C054B8A71B335A65CE680F02DC58D27FDBBA83EE263DD9E171B190F1CDB173BF56BB93407074B1899E8D59832EF383BCF6FB145E0F8A4A7484A2F8F4178D0A8DF9B8B920FF1250BF88BE770FD43D7EF2F4B998D86628A676173384FA95CB6B8A2599F8D5BFAA9E7C025CF29A9E1A8818B90CF2568CB8F3C003BC22B873374ACEF560B114B6B3EA0ED1701CE77A34E2723FB377BD67D480E3BF6A4E71763ED85C4E5F034A8E1761B1424AC67CFD1727157A43EEAD2168622F43967A4494E3C3D92E41EF47B7425D13D746CF617F9BB0F7CF04C093261541B6BAD54E3ED418AA1044C21FCC95B3416E6648FC576AECA4A82F2E69CE017A982407FAB0B656B56933908F1FD739686102F68805B8C605CF88952AEE1257382DE39D777527416FBED01472FE9C947AD58968D7FF2847328265584C2E93F7DF92CA891122AF48B9549020D2FAC44913C2DB5DAE20434E477FC5AF527E3D16D13B5586131FA1CC6AB1D522A1EFDA51B84D82BCBC0E76F00E0C790A9C07D0CD81088A6E972BB453B0D72AACF78BE9506B25301A473C0F4E6DF46B6517C73D9809F5319DA70BD22C0C17D90A0A26080E262D9DFB50B21AABFB60D76E655B78B2C4A4EDE0D32CE1BBD3F05F49C12B30DA10A13BAA95F907A1306F4FAFA251D8F6E16B6A5EB177D7777FFAB5A875B3D27D250B496B3EDCF818020A27D1CF30EF135AA50CF05B70D1FBCFAB92C7D0CC17E3AB813D23233BEDB187FAB1406BB9397760F905658A124923E6F97F947EF88572CC3F50F16FC716DEA622F9878462113A5E43CFA165D80B531843CB024CC310FB4FD80788A67ABCADDD99BD5A26D1FDB72FA5DF44C84085D7EA30393ABA8E7CB659489DE64CAECC4E2E6779E80CAC156B5957C30B89F073E97BD013CE3E7D260917C1B3C46F6AF0B77A2109E7A81DBB20745B4FD4B33BCC08FD30F554C5EF9B6E69CBD225A498D2D51CA440B83205DF7AE9020AF2595F3CC648907EA05C2F4063C835606A4598A7E9CF67710332A938B1FF851A6697F9A38FFA2CCF2BBD6A00F8437794DA285A8E298CCF2D5497DCA6065D8E0AD829172FBF4D10F75BE58F97FB2D272DD9B57C5659910BDF70D78C45FDFE135DC75F8DBB69F78EF068CBEA5F9FC8940D45AB9928C9002EA165CBBFFB197705C37B7
+20210513233042 2 6 100 8191 2 D352935F33D9BC205912B919A6C5F18F76C30A32F6C0390249B48383BA4F31098BF5B6B2ACE6A745344840435A6C9A0DBF8E268F0463420452610E9A624590DC2CD57490F709DFFC5A54630DE486C73DB3C377B87C919F90BA88A7B41627351E6BEADBA605C2C625833BB95E9F34892A5D15DDF216D1A549FCFA819D7567D99015B1C3944254B87680222859779EA64C26FCEF82F34FE28E765DE3DDBCB9B3664E7896B18B93B9AA3A69944E8CEB93C18F671E2A75D6C1061B23AF8B913911A73099EA5B0F527C054B8A71B335A65CE680F02DC58D27FDBBA83EE263DD9E171B190F1CDB173BF56BB93407074B1899E8D59832EF383BCF6FB145E0F8A4A7484A2F8F4178D0A8DF9B8B920FF1250BF88BE770FD43D7EF2F4B998D86628A676173384FA95CB6B8A2599F8D5BFAA9E7C025CF29A9E1A8818B90CF2568CB8F3C003BC22B873374ACEF560B114B6B3EA0ED1701CE77A34E2723FB377BD67D480E3BF6A4E71763ED85C4E5F034A8E1761B1424AC67CFD1727157A43EEAD2168622F43967A4494E3C3D92E41EF47B7425D13D746CF617F9BB0F7CF04C093261541B6BAD54E3ED418AA1044C21FCC95B3416E6648FC576AECA4A82F2E69CE017A982407FAB0B656B56933908F1FD739686102F68805B8C605CF88952AEE1257382DE39D777527416FBED01472FE9C947AD58968D7FF2847328265584C2E93F7DF92CA891122AF48B9549020D2FAC44913C2DB5DAE20434E477FC5AF527E3D16D13B5586131FA1CC6AB1D522A1EFDA51B84D82BCBC0E76F00E0C790A9C07D0CD81088A6E972BB453B0D72AACF78BE9506B25301A473C0F4E6DF46B6517C73D9809F5319DA70BD22C0C17D90A0A26080E262D9DFB50B21AABFB60D76E655B78B2C4A4EDE0D32CE1BBD3F05F49C12B30DA10A13BAA95F907A1306F4FAFA251D8F6E16B6A5EB177D7777FFAB5A875B3D27D250B496B3EDCF818020A27D1CF30EF135AA50CF05B70D1FBCFAB92C7D0CC17E3AB813D23233BEDB187FAB1406BB9397760F905658A124923E6F97F947EF88572CC3F50F16FC716DEA622F9878462113A5E43CFA165D80B531843CB024CC310FB4FD80788A67ABCADDD99BD5A26D1FDB72FA5DF44C84085D7EA30393ABA8E7CB659489DE64CAECC4E2E6779E80CAC156B5957C30B89F073E97BD013CE3E7D260917C1B3C46F6AF0B77A2109E7A81DBB20745B4FD4B33BCC08FD30F554C5EF9B6E69CBD225A498D2D51CA440B83205DF7AE9020AF2595F3CC648907EA05C2F4063C835606A4598A7E9CF67710332A938B1FF851A6697F9A38FFA2CCF2BBD6A00F8437794DA285A8E298CCF2D5497DCA6065D8E0AD829172FBF4D10F75BE58F97FB2D272DD9B57C5659910BDF70D78C45FDFE135DC75F8DBB69F78EF068CBEA5F9FC8940D45AB9928C9002EA165CBBFFB1977149F50B
+20210513233427 2 6 100 8191 2 D352935F33D9BC205912B919A6C5F18F76C30A32F6C0390249B48383BA4F31098BF5B6B2ACE6A745344840435A6C9A0DBF8E268F0463420452610E9A624590DC2CD57490F709DFFC5A54630DE486C73DB3C377B87C919F90BA88A7B41627351E6BEADBA605C2C625833BB95E9F34892A5D15DDF216D1A549FCFA819D7567D99015B1C3944254B87680222859779EA64C26FCEF82F34FE28E765DE3DDBCB9B3664E7896B18B93B9AA3A69944E8CEB93C18F671E2A75D6C1061B23AF8B913911A73099EA5B0F527C054B8A71B335A65CE680F02DC58D27FDBBA83EE263DD9E171B190F1CDB173BF56BB93407074B1899E8D59832EF383BCF6FB145E0F8A4A7484A2F8F4178D0A8DF9B8B920FF1250BF88BE770FD43D7EF2F4B998D86628A676173384FA95CB6B8A2599F8D5BFAA9E7C025CF29A9E1A8818B90CF2568CB8F3C003BC22B873374ACEF560B114B6B3EA0ED1701CE77A34E2723FB377BD67D480E3BF6A4E71763ED85C4E5F034A8E1761B1424AC67CFD1727157A43EEAD2168622F43967A4494E3C3D92E41EF47B7425D13D746CF617F9BB0F7CF04C093261541B6BAD54E3ED418AA1044C21FCC95B3416E6648FC576AECA4A82F2E69CE017A982407FAB0B656B56933908F1FD739686102F68805B8C605CF88952AEE1257382DE39D777527416FBED01472FE9C947AD58968D7FF2847328265584C2E93F7DF92CA891122AF48B9549020D2FAC44913C2DB5DAE20434E477FC5AF527E3D16D13B5586131FA1CC6AB1D522A1EFDA51B84D82BCBC0E76F00E0C790A9C07D0CD81088A6E972BB453B0D72AACF78BE9506B25301A473C0F4E6DF46B6517C73D9809F5319DA70BD22C0C17D90A0A26080E262D9DFB50B21AABFB60D76E655B78B2C4A4EDE0D32CE1BBD3F05F49C12B30DA10A13BAA95F907A1306F4FAFA251D8F6E16B6A5EB177D7777FFAB5A875B3D27D250B496B3EDCF818020A27D1CF30EF135AA50CF05B70D1FBCFAB92C7D0CC17E3AB813D23233BEDB187FAB1406BB9397760F905658A124923E6F97F947EF88572CC3F50F16FC716DEA622F9878462113A5E43CFA165D80B531843CB024CC310FB4FD80788A67ABCADDD99BD5A26D1FDB72FA5DF44C84085D7EA30393ABA8E7CB659489DE64CAECC4E2E6779E80CAC156B5957C30B89F073E97BD013CE3E7D260917C1B3C46F6AF0B77A2109E7A81DBB20745B4FD4B33BCC08FD30F554C5EF9B6E69CBD225A498D2D51CA440B83205DF7AE9020AF2595F3CC648907EA05C2F4063C835606A4598A7E9CF67710332A938B1FF851A6697F9A38FFA2CCF2BBD6A00F8437794DA285A8E298CCF2D5497DCA6065D8E0AD829172FBF4D10F75BE58F97FB2D272DD9B57C5659910BDF70D78C45FDFE135DC75F8DBB69F78EF068CBEA5F9FC8940D45AB9928C9002EA165CBBFFB197718133B3
+20210514021221 2 6 100 8191 2 D352935F33D9BC205912B919A6C5F18F76C30A32F6C0390249B48383BA4F31098BF5B6B2ACE6A745344840435A6C9A0DBF8E268F0463420452610E9A624590DC2CD57490F709DFFC5A54630DE486C73DB3C377B87C919F90BA88A7B41627351E6BEADBA605C2C625833BB95E9F34892A5D15DDF216D1A549FCFA819D7567D99015B1C3944254B87680222859779EA64C26FCEF82F34FE28E765DE3DDBCB9B3664E7896B18B93B9AA3A69944E8CEB93C18F671E2A75D6C1061B23AF8B913911A73099EA5B0F527C054B8A71B335A65CE680F02DC58D27FDBBA83EE263DD9E171B190F1CDB173BF56BB93407074B1899E8D59832EF383BCF6FB145E0F8A4A7484A2F8F4178D0A8DF9B8B920FF1250BF88BE770FD43D7EF2F4B998D86628A676173384FA95CB6B8A2599F8D5BFAA9E7C025CF29A9E1A8818B90CF2568CB8F3C003BC22B873374ACEF560B114B6B3EA0ED1701CE77A34E2723FB377BD67D480E3BF6A4E71763ED85C4E5F034A8E1761B1424AC67CFD1727157A43EEAD2168622F43967A4494E3C3D92E41EF47B7425D13D746CF617F9BB0F7CF04C093261541B6BAD54E3ED418AA1044C21FCC95B3416E6648FC576AECA4A82F2E69CE017A982407FAB0B656B56933908F1FD739686102F68805B8C605CF88952AEE1257382DE39D777527416FBED01472FE9C947AD58968D7FF2847328265584C2E93F7DF92CA891122AF48B9549020D2FAC44913C2DB5DAE20434E477FC5AF527E3D16D13B5586131FA1CC6AB1D522A1EFDA51B84D82BCBC0E76F00E0C790A9C07D0CD81088A6E972BB453B0D72AACF78BE9506B25301A473C0F4E6DF46B6517C73D9809F5319DA70BD22C0C17D90A0A26080E262D9DFB50B21AABFB60D76E655B78B2C4A4EDE0D32CE1BBD3F05F49C12B30DA10A13BAA95F907A1306F4FAFA251D8F6E16B6A5EB177D7777FFAB5A875B3D27D250B496B3EDCF818020A27D1CF30EF135AA50CF05B70D1FBCFAB92C7D0CC17E3AB813D23233BEDB187FAB1406BB9397760F905658A124923E6F97F947EF88572CC3F50F16FC716DEA622F9878462113A5E43CFA165D80B531843CB024CC310FB4FD80788A67ABCADDD99BD5A26D1FDB72FA5DF44C84085D7EA30393ABA8E7CB659489DE64CAECC4E2E6779E80CAC156B5957C30B89F073E97BD013CE3E7D260917C1B3C46F6AF0B77A2109E7A81DBB20745B4FD4B33BCC08FD30F554C5EF9B6E69CBD225A498D2D51CA440B83205DF7AE9020AF2595F3CC648907EA05C2F4063C835606A4598A7E9CF67710332A938B1FF851A6697F9A38FFA2CCF2BBD6A00F8437794DA285A8E298CCF2D5497DCA6065D8E0AD829172FBF4D10F75BE58F97FB2D272DD9B57C5659910BDF70D78C45FDFE135DC75F8DBB69F78EF068CBEA5F9FC8940D45AB9928C9002EA165CBBFFB1977C49F803
+20210514033618 2 6 100 8191 2 D352935F33D9BC205912B919A6C5F18F76C30A32F6C0390249B48383BA4F31098BF5B6B2ACE6A745344840435A6C9A0DBF8E268F0463420452610E9A624590DC2CD57490F709DFFC5A54630DE486C73DB3C377B87C919F90BA88A7B41627351E6BEADBA605C2C625833BB95E9F34892A5D15DDF216D1A549FCFA819D7567D99015B1C3944254B87680222859779EA64C26FCEF82F34FE28E765DE3DDBCB9B3664E7896B18B93B9AA3A69944E8CEB93C18F671E2A75D6C1061B23AF8B913911A73099EA5B0F527C054B8A71B335A65CE680F02DC58D27FDBBA83EE263DD9E171B190F1CDB173BF56BB93407074B1899E8D59832EF383BCF6FB145E0F8A4A7484A2F8F4178D0A8DF9B8B920FF1250BF88BE770FD43D7EF2F4B998D86628A676173384FA95CB6B8A2599F8D5BFAA9E7C025CF29A9E1A8818B90CF2568CB8F3C003BC22B873374ACEF560B114B6B3EA0ED1701CE77A34E2723FB377BD67D480E3BF6A4E71763ED85C4E5F034A8E1761B1424AC67CFD1727157A43EEAD2168622F43967A4494E3C3D92E41EF47B7425D13D746CF617F9BB0F7CF04C093261541B6BAD54E3ED418AA1044C21FCC95B3416E6648FC576AECA4A82F2E69CE017A982407FAB0B656B56933908F1FD739686102F68805B8C605CF88952AEE1257382DE39D777527416FBED01472FE9C947AD58968D7FF2847328265584C2E93F7DF92CA891122AF48B9549020D2FAC44913C2DB5DAE20434E477FC5AF527E3D16D13B5586131FA1CC6AB1D522A1EFDA51B84D82BCBC0E76F00E0C790A9C07D0CD81088A6E972BB453B0D72AACF78BE9506B25301A473C0F4E6DF46B6517C73D9809F5319DA70BD22C0C17D90A0A26080E262D9DFB50B21AABFB60D76E655B78B2C4A4EDE0D32CE1BBD3F05F49C12B30DA10A13BAA95F907A1306F4FAFA251D8F6E16B6A5EB177D7777FFAB5A875B3D27D250B496B3EDCF818020A27D1CF30EF135AA50CF05B70D1FBCFAB92C7D0CC17E3AB813D23233BEDB187FAB1406BB9397760F905658A124923E6F97F947EF88572CC3F50F16FC716DEA622F9878462113A5E43CFA165D80B531843CB024CC310FB4FD80788A67ABCADDD99BD5A26D1FDB72FA5DF44C84085D7EA30393ABA8E7CB659489DE64CAECC4E2E6779E80CAC156B5957C30B89F073E97BD013CE3E7D260917C1B3C46F6AF0B77A2109E7A81DBB20745B4FD4B33BCC08FD30F554C5EF9B6E69CBD225A498D2D51CA440B83205DF7AE9020AF2595F3CC648907EA05C2F4063C835606A4598A7E9CF67710332A938B1FF851A6697F9A38FFA2CCF2BBD6A00F8437794DA285A8E298CCF2D5497DCA6065D8E0AD829172FBF4D10F75BE58F97FB2D272DD9B57C5659910BDF70D78C45FDFE135DC75F8DBB69F78EF068CBEA5F9FC8940D45AB9928C9002EA165CBBFFB19781E711FB
+20210514034136 2 6 100 8191 2 D352935F33D9BC205912B919A6C5F18F76C30A32F6C0390249B48383BA4F31098BF5B6B2ACE6A745344840435A6C9A0DBF8E268F0463420452610E9A624590DC2CD57490F709DFFC5A54630DE486C73DB3C377B87C919F90BA88A7B41627351E6BEADBA605C2C625833BB95E9F34892A5D15DDF216D1A549FCFA819D7567D99015B1C3944254B87680222859779EA64C26FCEF82F34FE28E765DE3DDBCB9B3664E7896B18B93B9AA3A69944E8CEB93C18F671E2A75D6C1061B23AF8B913911A73099EA5B0F527C054B8A71B335A65CE680F02DC58D27FDBBA83EE263DD9E171B190F1CDB173BF56BB93407074B1899E8D59832EF383BCF6FB145E0F8A4A7484A2F8F4178D0A8DF9B8B920FF1250BF88BE770FD43D7EF2F4B998D86628A676173384FA95CB6B8A2599F8D5BFAA9E7C025CF29A9E1A8818B90CF2568CB8F3C003BC22B873374ACEF560B114B6B3EA0ED1701CE77A34E2723FB377BD67D480E3BF6A4E71763ED85C4E5F034A8E1761B1424AC67CFD1727157A43EEAD2168622F43967A4494E3C3D92E41EF47B7425D13D746CF617F9BB0F7CF04C093261541B6BAD54E3ED418AA1044C21FCC95B3416E6648FC576AECA4A82F2E69CE017A982407FAB0B656B56933908F1FD739686102F68805B8C605CF88952AEE1257382DE39D777527416FBED01472FE9C947AD58968D7FF2847328265584C2E93F7DF92CA891122AF48B9549020D2FAC44913C2DB5DAE20434E477FC5AF527E3D16D13B5586131FA1CC6AB1D522A1EFDA51B84D82BCBC0E76F00E0C790A9C07D0CD81088A6E972BB453B0D72AACF78BE9506B25301A473C0F4E6DF46B6517C73D9809F5319DA70BD22C0C17D90A0A26080E262D9DFB50B21AABFB60D76E655B78B2C4A4EDE0D32CE1BBD3F05F49C12B30DA10A13BAA95F907A1306F4FAFA251D8F6E16B6A5EB177D7777FFAB5A875B3D27D250B496B3EDCF818020A27D1CF30EF135AA50CF05B70D1FBCFAB92C7D0CC17E3AB813D23233BEDB187FAB1406BB9397760F905658A124923E6F97F947EF88572CC3F50F16FC716DEA622F9878462113A5E43CFA165D80B531843CB024CC310FB4FD80788A67ABCADDD99BD5A26D1FDB72FA5DF44C84085D7EA30393ABA8E7CB659489DE64CAECC4E2E6779E80CAC156B5957C30B89F073E97BD013CE3E7D260917C1B3C46F6AF0B77A2109E7A81DBB20745B4FD4B33BCC08FD30F554C5EF9B6E69CBD225A498D2D51CA440B83205DF7AE9020AF2595F3CC648907EA05C2F4063C835606A4598A7E9CF67710332A938B1FF851A6697F9A38FFA2CCF2BBD6A00F8437794DA285A8E298CCF2D5497DCA6065D8E0AD829172FBF4D10F75BE58F97FB2D272DD9B57C5659910BDF70D78C45FDFE135DC75F8DBB69F78EF068CBEA5F9FC8940D45AB9928C9002EA165CBBFFB1978239BC2B
+20210514061321 2 6 100 8191 2 D352935F33D9BC205912B919A6C5F18F76C30A32F6C0390249B48383BA4F31098BF5B6B2ACE6A745344840435A6C9A0DBF8E268F0463420452610E9A624590DC2CD57490F709DFFC5A54630DE486C73DB3C377B87C919F90BA88A7B41627351E6BEADBA605C2C625833BB95E9F34892A5D15DDF216D1A549FCFA819D7567D99015B1C3944254B87680222859779EA64C26FCEF82F34FE28E765DE3DDBCB9B3664E7896B18B93B9AA3A69944E8CEB93C18F671E2A75D6C1061B23AF8B913911A73099EA5B0F527C054B8A71B335A65CE680F02DC58D27FDBBA83EE263DD9E171B190F1CDB173BF56BB93407074B1899E8D59832EF383BCF6FB145E0F8A4A7484A2F8F4178D0A8DF9B8B920FF1250BF88BE770FD43D7EF2F4B998D86628A676173384FA95CB6B8A2599F8D5BFAA9E7C025CF29A9E1A8818B90CF2568CB8F3C003BC22B873374ACEF560B114B6B3EA0ED1701CE77A34E2723FB377BD67D480E3BF6A4E71763ED85C4E5F034A8E1761B1424AC67CFD1727157A43EEAD2168622F43967A4494E3C3D92E41EF47B7425D13D746CF617F9BB0F7CF04C093261541B6BAD54E3ED418AA1044C21FCC95B3416E6648FC576AECA4A82F2E69CE017A982407FAB0B656B56933908F1FD739686102F68805B8C605CF88952AEE1257382DE39D777527416FBED01472FE9C947AD58968D7FF2847328265584C2E93F7DF92CA891122AF48B9549020D2FAC44913C2DB5DAE20434E477FC5AF527E3D16D13B5586131FA1CC6AB1D522A1EFDA51B84D82BCBC0E76F00E0C790A9C07D0CD81088A6E972BB453B0D72AACF78BE9506B25301A473C0F4E6DF46B6517C73D9809F5319DA70BD22C0C17D90A0A26080E262D9DFB50B21AABFB60D76E655B78B2C4A4EDE0D32CE1BBD3F05F49C12B30DA10A13BAA95F907A1306F4FAFA251D8F6E16B6A5EB177D7777FFAB5A875B3D27D250B496B3EDCF818020A27D1CF30EF135AA50CF05B70D1FBCFAB92C7D0CC17E3AB813D23233BEDB187FAB1406BB9397760F905658A124923E6F97F947EF88572CC3F50F16FC716DEA622F9878462113A5E43CFA165D80B531843CB024CC310FB4FD80788A67ABCADDD99BD5A26D1FDB72FA5DF44C84085D7EA30393ABA8E7CB659489DE64CAECC4E2E6779E80CAC156B5957C30B89F073E97BD013CE3E7D260917C1B3C46F6AF0B77A2109E7A81DBB20745B4FD4B33BCC08FD30F554C5EF9B6E69CBD225A498D2D51CA440B83205DF7AE9020AF2595F3CC648907EA05C2F4063C835606A4598A7E9CF67710332A938B1FF851A6697F9A38FFA2CCF2BBD6A00F8437794DA285A8E298CCF2D5497DCA6065D8E0AD829172FBF4D10F75BE58F97FB2D272DD9B57C5659910BDF70D78C45FDFE135DC75F8DBB69F78EF068CBEA5F9FC8940D45AB9928C9002EA165CBBFFB1978C43CECB
+20210514081550 2 6 100 8191 2 D352935F33D9BC205912B919A6C5F18F76C30A32F6C0390249B48383BA4F31098BF5B6B2ACE6A745344840435A6C9A0DBF8E268F0463420452610E9A624590DC2CD57490F709DFFC5A54630DE486C73DB3C377B87C919F90BA88A7B41627351E6BEADBA605C2C625833BB95E9F34892A5D15DDF216D1A549FCFA819D7567D99015B1C3944254B87680222859779EA64C26FCEF82F34FE28E765DE3DDBCB9B3664E7896B18B93B9AA3A69944E8CEB93C18F671E2A75D6C1061B23AF8B913911A73099EA5B0F527C054B8A71B335A65CE680F02DC58D27FDBBA83EE263DD9E171B190F1CDB173BF56BB93407074B1899E8D59832EF383BCF6FB145E0F8A4A7484A2F8F4178D0A8DF9B8B920FF1250BF88BE770FD43D7EF2F4B998D86628A676173384FA95CB6B8A2599F8D5BFAA9E7C025CF29A9E1A8818B90CF2568CB8F3C003BC22B873374ACEF560B114B6B3EA0ED1701CE77A34E2723FB377BD67D480E3BF6A4E71763ED85C4E5F034A8E1761B1424AC67CFD1727157A43EEAD2168622F43967A4494E3C3D92E41EF47B7425D13D746CF617F9BB0F7CF04C093261541B6BAD54E3ED418AA1044C21FCC95B3416E6648FC576AECA4A82F2E69CE017A982407FAB0B656B56933908F1FD739686102F68805B8C605CF88952AEE1257382DE39D777527416FBED01472FE9C947AD58968D7FF2847328265584C2E93F7DF92CA891122AF48B9549020D2FAC44913C2DB5DAE20434E477FC5AF527E3D16D13B5586131FA1CC6AB1D522A1EFDA51B84D82BCBC0E76F00E0C790A9C07D0CD81088A6E972BB453B0D72AACF78BE9506B25301A473C0F4E6DF46B6517C73D9809F5319DA70BD22C0C17D90A0A26080E262D9DFB50B21AABFB60D76E655B78B2C4A4EDE0D32CE1BBD3F05F49C12B30DA10A13BAA95F907A1306F4FAFA251D8F6E16B6A5EB177D7777FFAB5A875B3D27D250B496B3EDCF818020A27D1CF30EF135AA50CF05B70D1FBCFAB92C7D0CC17E3AB813D23233BEDB187FAB1406BB9397760F905658A124923E6F97F947EF88572CC3F50F16FC716DEA622F9878462113A5E43CFA165D80B531843CB024CC310FB4FD80788A67ABCADDD99BD5A26D1FDB72FA5DF44C84085D7EA30393ABA8E7CB659489DE64CAECC4E2E6779E80CAC156B5957C30B89F073E97BD013CE3E7D260917C1B3C46F6AF0B77A2109E7A81DBB20745B4FD4B33BCC08FD30F554C5EF9B6E69CBD225A498D2D51CA440B83205DF7AE9020AF2595F3CC648907EA05C2F4063C835606A4598A7E9CF67710332A938B1FF851A6697F9A38FFA2CCF2BBD6A00F8437794DA285A8E298CCF2D5497DCA6065D8E0AD829172FBF4D10F75BE58F97FB2D272DD9B57C5659910BDF70D78C45FDFE135DC75F8DBB69F78EF068CBEA5F9FC8940D45AB9928C9002EA165CBBFFB1979429D64B
+20210514112414 2 6 100 8191 2 D352935F33D9BC205912B919A6C5F18F76C30A32F6C0390249B48383BA4F31098BF5B6B2ACE6A745344840435A6C9A0DBF8E268F0463420452610E9A624590DC2CD57490F709DFFC5A54630DE486C73DB3C377B87C919F90BA88A7B41627351E6BEADBA605C2C625833BB95E9F34892A5D15DDF216D1A549FCFA819D7567D99015B1C3944254B87680222859779EA64C26FCEF82F34FE28E765DE3DDBCB9B3664E7896B18B93B9AA3A69944E8CEB93C18F671E2A75D6C1061B23AF8B913911A73099EA5B0F527C054B8A71B335A65CE680F02DC58D27FDBBA83EE263DD9E171B190F1CDB173BF56BB93407074B1899E8D59832EF383BCF6FB145E0F8A4A7484A2F8F4178D0A8DF9B8B920FF1250BF88BE770FD43D7EF2F4B998D86628A676173384FA95CB6B8A2599F8D5BFAA9E7C025CF29A9E1A8818B90CF2568CB8F3C003BC22B873374ACEF560B114B6B3EA0ED1701CE77A34E2723FB377BD67D480E3BF6A4E71763ED85C4E5F034A8E1761B1424AC67CFD1727157A43EEAD2168622F43967A4494E3C3D92E41EF47B7425D13D746CF617F9BB0F7CF04C093261541B6BAD54E3ED418AA1044C21FCC95B3416E6648FC576AECA4A82F2E69CE017A982407FAB0B656B56933908F1FD739686102F68805B8C605CF88952AEE1257382DE39D777527416FBED01472FE9C947AD58968D7FF2847328265584C2E93F7DF92CA891122AF48B9549020D2FAC44913C2DB5DAE20434E477FC5AF527E3D16D13B5586131FA1CC6AB1D522A1EFDA51B84D82BCBC0E76F00E0C790A9C07D0CD81088A6E972BB453B0D72AACF78BE9506B25301A473C0F4E6DF46B6517C73D9809F5319DA70BD22C0C17D90A0A26080E262D9DFB50B21AABFB60D76E655B78B2C4A4EDE0D32CE1BBD3F05F49C12B30DA10A13BAA95F907A1306F4FAFA251D8F6E16B6A5EB177D7777FFAB5A875B3D27D250B496B3EDCF818020A27D1CF30EF135AA50CF05B70D1FBCFAB92C7D0CC17E3AB813D23233BEDB187FAB1406BB9397760F905658A124923E6F97F947EF88572CC3F50F16FC716DEA622F9878462113A5E43CFA165D80B531843CB024CC310FB4FD80788A67ABCADDD99BD5A26D1FDB72FA5DF44C84085D7EA30393ABA8E7CB659489DE64CAECC4E2E6779E80CAC156B5957C30B89F073E97BD013CE3E7D260917C1B3C46F6AF0B77A2109E7A81DBB20745B4FD4B33BCC08FD30F554C5EF9B6E69CBD225A498D2D51CA440B83205DF7AE9020AF2595F3CC648907EA05C2F4063C835606A4598A7E9CF67710332A938B1FF851A6697F9A38FFA2CCF2BBD6A00F8437794DA285A8E298CCF2D5497DCA6065D8E0AD829172FBF4D10F75BE58F97FB2D272DD9B57C5659910BDF70D78C45FDFE135DC75F8DBB69F78EF068CBEA5F9FC8940D45AB9928C9002EA165CBBFFB197A0360BD3
+20210514115310 2 6 100 8191 5 D352935F33D9BC205912B919A6C5F18F76C30A32F6C0390249B48383BA4F31098BF5B6B2ACE6A745344840435A6C9A0DBF8E268F0463420452610E9A624590DC2CD57490F709DFFC5A54630DE486C73DB3C377B87C919F90BA88A7B41627351E6BEADBA605C2C625833BB95E9F34892A5D15DDF216D1A549FCFA819D7567D99015B1C3944254B87680222859779EA64C26FCEF82F34FE28E765DE3DDBCB9B3664E7896B18B93B9AA3A69944E8CEB93C18F671E2A75D6C1061B23AF8B913911A73099EA5B0F527C054B8A71B335A65CE680F02DC58D27FDBBA83EE263DD9E171B190F1CDB173BF56BB93407074B1899E8D59832EF383BCF6FB145E0F8A4A7484A2F8F4178D0A8DF9B8B920FF1250BF88BE770FD43D7EF2F4B998D86628A676173384FA95CB6B8A2599F8D5BFAA9E7C025CF29A9E1A8818B90CF2568CB8F3C003BC22B873374ACEF560B114B6B3EA0ED1701CE77A34E2723FB377BD67D480E3BF6A4E71763ED85C4E5F034A8E1761B1424AC67CFD1727157A43EEAD2168622F43967A4494E3C3D92E41EF47B7425D13D746CF617F9BB0F7CF04C093261541B6BAD54E3ED418AA1044C21FCC95B3416E6648FC576AECA4A82F2E69CE017A982407FAB0B656B56933908F1FD739686102F68805B8C605CF88952AEE1257382DE39D777527416FBED01472FE9C947AD58968D7FF2847328265584C2E93F7DF92CA891122AF48B9549020D2FAC44913C2DB5DAE20434E477FC5AF527E3D16D13B5586131FA1CC6AB1D522A1EFDA51B84D82BCBC0E76F00E0C790A9C07D0CD81088A6E972BB453B0D72AACF78BE9506B25301A473C0F4E6DF46B6517C73D9809F5319DA70BD22C0C17D90A0A26080E262D9DFB50B21AABFB60D76E655B78B2C4A4EDE0D32CE1BBD3F05F49C12B30DA10A13BAA95F907A1306F4FAFA251D8F6E16B6A5EB177D7777FFAB5A875B3D27D250B496B3EDCF818020A27D1CF30EF135AA50CF05B70D1FBCFAB92C7D0CC17E3AB813D23233BEDB187FAB1406BB9397760F905658A124923E6F97F947EF88572CC3F50F16FC716DEA622F9878462113A5E43CFA165D80B531843CB024CC310FB4FD80788A67ABCADDD99BD5A26D1FDB72FA5DF44C84085D7EA30393ABA8E7CB659489DE64CAECC4E2E6779E80CAC156B5957C30B89F073E97BD013CE3E7D260917C1B3C46F6AF0B77A2109E7A81DBB20745B4FD4B33BCC08FD30F554C5EF9B6E69CBD225A498D2D51CA440B83205DF7AE9020AF2595F3CC648907EA05C2F4063C835606A4598A7E9CF67710332A938B1FF851A6697F9A38FFA2CCF2BBD6A00F8437794DA285A8E298CCF2D5497DCA6065D8E0AD829172FBF4D10F75BE58F97FB2D272DD9B57C5659910BDF70D78C45FDFE135DC75F8DBB69F78EF068CBEA5F9FC8940D45AB9928C9002EA165CBBFFB197A2059F5F
+20210514125653 2 6 100 8191 2 D352935F33D9BC205912B919A6C5F18F76C30A32F6C0390249B48383BA4F31098BF5B6B2ACE6A745344840435A6C9A0DBF8E268F0463420452610E9A624590DC2CD57490F709DFFC5A54630DE486C73DB3C377B87C919F90BA88A7B41627351E6BEADBA605C2C625833BB95E9F34892A5D15DDF216D1A549FCFA819D7567D99015B1C3944254B87680222859779EA64C26FCEF82F34FE28E765DE3DDBCB9B3664E7896B18B93B9AA3A69944E8CEB93C18F671E2A75D6C1061B23AF8B913911A73099EA5B0F527C054B8A71B335A65CE680F02DC58D27FDBBA83EE263DD9E171B190F1CDB173BF56BB93407074B1899E8D59832EF383BCF6FB145E0F8A4A7484A2F8F4178D0A8DF9B8B920FF1250BF88BE770FD43D7EF2F4B998D86628A676173384FA95CB6B8A2599F8D5BFAA9E7C025CF29A9E1A8818B90CF2568CB8F3C003BC22B873374ACEF560B114B6B3EA0ED1701CE77A34E2723FB377BD67D480E3BF6A4E71763ED85C4E5F034A8E1761B1424AC67CFD1727157A43EEAD2168622F43967A4494E3C3D92E41EF47B7425D13D746CF617F9BB0F7CF04C093261541B6BAD54E3ED418AA1044C21FCC95B3416E6648FC576AECA4A82F2E69CE017A982407FAB0B656B56933908F1FD739686102F68805B8C605CF88952AEE1257382DE39D777527416FBED01472FE9C947AD58968D7FF2847328265584C2E93F7DF92CA891122AF48B9549020D2FAC44913C2DB5DAE20434E477FC5AF527E3D16D13B5586131FA1CC6AB1D522A1EFDA51B84D82BCBC0E76F00E0C790A9C07D0CD81088A6E972BB453B0D72AACF78BE9506B25301A473C0F4E6DF46B6517C73D9809F5319DA70BD22C0C17D90A0A26080E262D9DFB50B21AABFB60D76E655B78B2C4A4EDE0D32CE1BBD3F05F49C12B30DA10A13BAA95F907A1306F4FAFA251D8F6E16B6A5EB177D7777FFAB5A875B3D27D250B496B3EDCF818020A27D1CF30EF135AA50CF05B70D1FBCFAB92C7D0CC17E3AB813D23233BEDB187FAB1406BB9397760F905658A124923E6F97F947EF88572CC3F50F16FC716DEA622F9878462113A5E43CFA165D80B531843CB024CC310FB4FD80788A67ABCADDD99BD5A26D1FDB72FA5DF44C84085D7EA30393ABA8E7CB659489DE64CAECC4E2E6779E80CAC156B5957C30B89F073E97BD013CE3E7D260917C1B3C46F6AF0B77A2109E7A81DBB20745B4FD4B33BCC08FD30F554C5EF9B6E69CBD225A498D2D51CA440B83205DF7AE9020AF2595F3CC648907EA05C2F4063C835606A4598A7E9CF67710332A938B1FF851A6697F9A38FFA2CCF2BBD6A00F8437794DA285A8E298CCF2D5497DCA6065D8E0AD829172FBF4D10F75BE58F97FB2D272DD9B57C5659910BDF70D78C45FDFE135DC75F8DBB69F78EF068CBEA5F9FC8940D45AB9928C9002EA165CBBFFB197A6070053
+20210514135322 2 6 100 8191 5 D352935F33D9BC205912B919A6C5F18F76C30A32F6C0390249B48383BA4F31098BF5B6B2ACE6A745344840435A6C9A0DBF8E268F0463420452610E9A624590DC2CD57490F709DFFC5A54630DE486C73DB3C377B87C919F90BA88A7B41627351E6BEADBA605C2C625833BB95E9F34892A5D15DDF216D1A549FCFA819D7567D99015B1C3944254B87680222859779EA64C26FCEF82F34FE28E765DE3DDBCB9B3664E7896B18B93B9AA3A69944E8CEB93C18F671E2A75D6C1061B23AF8B913911A73099EA5B0F527C054B8A71B335A65CE680F02DC58D27FDBBA83EE263DD9E171B190F1CDB173BF56BB93407074B1899E8D59832EF383BCF6FB145E0F8A4A7484A2F8F4178D0A8DF9B8B920FF1250BF88BE770FD43D7EF2F4B998D86628A676173384FA95CB6B8A2599F8D5BFAA9E7C025CF29A9E1A8818B90CF2568CB8F3C003BC22B873374ACEF560B114B6B3EA0ED1701CE77A34E2723FB377BD67D480E3BF6A4E71763ED85C4E5F034A8E1761B1424AC67CFD1727157A43EEAD2168622F43967A4494E3C3D92E41EF47B7425D13D746CF617F9BB0F7CF04C093261541B6BAD54E3ED418AA1044C21FCC95B3416E6648FC576AECA4A82F2E69CE017A982407FAB0B656B56933908F1FD739686102F68805B8C605CF88952AEE1257382DE39D777527416FBED01472FE9C947AD58968D7FF2847328265584C2E93F7DF92CA891122AF48B9549020D2FAC44913C2DB5DAE20434E477FC5AF527E3D16D13B5586131FA1CC6AB1D522A1EFDA51B84D82BCBC0E76F00E0C790A9C07D0CD81088A6E972BB453B0D72AACF78BE9506B25301A473C0F4E6DF46B6517C73D9809F5319DA70BD22C0C17D90A0A26080E262D9DFB50B21AABFB60D76E655B78B2C4A4EDE0D32CE1BBD3F05F49C12B30DA10A13BAA95F907A1306F4FAFA251D8F6E16B6A5EB177D7777FFAB5A875B3D27D250B496B3EDCF818020A27D1CF30EF135AA50CF05B70D1FBCFAB92C7D0CC17E3AB813D23233BEDB187FAB1406BB9397760F905658A124923E6F97F947EF88572CC3F50F16FC716DEA622F9878462113A5E43CFA165D80B531843CB024CC310FB4FD80788A67ABCADDD99BD5A26D1FDB72FA5DF44C84085D7EA30393ABA8E7CB659489DE64CAECC4E2E6779E80CAC156B5957C30B89F073E97BD013CE3E7D260917C1B3C46F6AF0B77A2109E7A81DBB20745B4FD4B33BCC08FD30F554C5EF9B6E69CBD225A498D2D51CA440B83205DF7AE9020AF2595F3CC648907EA05C2F4063C835606A4598A7E9CF67710332A938B1FF851A6697F9A38FFA2CCF2BBD6A00F8437794DA285A8E298CCF2D5497DCA6065D8E0AD829172FBF4D10F75BE58F97FB2D272DD9B57C5659910BDF70D78C45FDFE135DC75F8DBB69F78EF068CBEA5F9FC8940D45AB9928C9002EA165CBBFFB197A992D4D7
+20210514152842 2 6 100 8191 5 D352935F33D9BC205912B919A6C5F18F76C30A32F6C0390249B48383BA4F31098BF5B6B2ACE6A745344840435A6C9A0DBF8E268F0463420452610E9A624590DC2CD57490F709DFFC5A54630DE486C73DB3C377B87C919F90BA88A7B41627351E6BEADBA605C2C625833BB95E9F34892A5D15DDF216D1A549FCFA819D7567D99015B1C3944254B87680222859779EA64C26FCEF82F34FE28E765DE3DDBCB9B3664E7896B18B93B9AA3A69944E8CEB93C18F671E2A75D6C1061B23AF8B913911A73099EA5B0F527C054B8A71B335A65CE680F02DC58D27FDBBA83EE263DD9E171B190F1CDB173BF56BB93407074B1899E8D59832EF383BCF6FB145E0F8A4A7484A2F8F4178D0A8DF9B8B920FF1250BF88BE770FD43D7EF2F4B998D86628A676173384FA95CB6B8A2599F8D5BFAA9E7C025CF29A9E1A8818B90CF2568CB8F3C003BC22B873374ACEF560B114B6B3EA0ED1701CE77A34E2723FB377BD67D480E3BF6A4E71763ED85C4E5F034A8E1761B1424AC67CFD1727157A43EEAD2168622F43967A4494E3C3D92E41EF47B7425D13D746CF617F9BB0F7CF04C093261541B6BAD54E3ED418AA1044C21FCC95B3416E6648FC576AECA4A82F2E69CE017A982407FAB0B656B56933908F1FD739686102F68805B8C605CF88952AEE1257382DE39D777527416FBED01472FE9C947AD58968D7FF2847328265584C2E93F7DF92CA891122AF48B9549020D2FAC44913C2DB5DAE20434E477FC5AF527E3D16D13B5586131FA1CC6AB1D522A1EFDA51B84D82BCBC0E76F00E0C790A9C07D0CD81088A6E972BB453B0D72AACF78BE9506B25301A473C0F4E6DF46B6517C73D9809F5319DA70BD22C0C17D90A0A26080E262D9DFB50B21AABFB60D76E655B78B2C4A4EDE0D32CE1BBD3F05F49C12B30DA10A13BAA95F907A1306F4FAFA251D8F6E16B6A5EB177D7777FFAB5A875B3D27D250B496B3EDCF818020A27D1CF30EF135AA50CF05B70D1FBCFAB92C7D0CC17E3AB813D23233BEDB187FAB1406BB9397760F905658A124923E6F97F947EF88572CC3F50F16FC716DEA622F9878462113A5E43CFA165D80B531843CB024CC310FB4FD80788A67ABCADDD99BD5A26D1FDB72FA5DF44C84085D7EA30393ABA8E7CB659489DE64CAECC4E2E6779E80CAC156B5957C30B89F073E97BD013CE3E7D260917C1B3C46F6AF0B77A2109E7A81DBB20745B4FD4B33BCC08FD30F554C5EF9B6E69CBD225A498D2D51CA440B83205DF7AE9020AF2595F3CC648907EA05C2F4063C835606A4598A7E9CF67710332A938B1FF851A6697F9A38FFA2CCF2BBD6A00F8437794DA285A8E298CCF2D5497DCA6065D8E0AD829172FBF4D10F75BE58F97FB2D272DD9B57C5659910BDF70D78C45FDFE135DC75F8DBB69F78EF068CBEA5F9FC8940D45AB9928C9002EA165CBBFFB197AF853A37
+20210514153107 2 6 100 8191 5 D352935F33D9BC205912B919A6C5F18F76C30A32F6C0390249B48383BA4F31098BF5B6B2ACE6A745344840435A6C9A0DBF8E268F0463420452610E9A624590DC2CD57490F709DFFC5A54630DE486C73DB3C377B87C919F90BA88A7B41627351E6BEADBA605C2C625833BB95E9F34892A5D15DDF216D1A549FCFA819D7567D99015B1C3944254B87680222859779EA64C26FCEF82F34FE28E765DE3DDBCB9B3664E7896B18B93B9AA3A69944E8CEB93C18F671E2A75D6C1061B23AF8B913911A73099EA5B0F527C054B8A71B335A65CE680F02DC58D27FDBBA83EE263DD9E171B190F1CDB173BF56BB93407074B1899E8D59832EF383BCF6FB145E0F8A4A7484A2F8F4178D0A8DF9B8B920FF1250BF88BE770FD43D7EF2F4B998D86628A676173384FA95CB6B8A2599F8D5BFAA9E7C025CF29A9E1A8818B90CF2568CB8F3C003BC22B873374ACEF560B114B6B3EA0ED1701CE77A34E2723FB377BD67D480E3BF6A4E71763ED85C4E5F034A8E1761B1424AC67CFD1727157A43EEAD2168622F43967A4494E3C3D92E41EF47B7425D13D746CF617F9BB0F7CF04C093261541B6BAD54E3ED418AA1044C21FCC95B3416E6648FC576AECA4A82F2E69CE017A982407FAB0B656B56933908F1FD739686102F68805B8C605CF88952AEE1257382DE39D777527416FBED01472FE9C947AD58968D7FF2847328265584C2E93F7DF92CA891122AF48B9549020D2FAC44913C2DB5DAE20434E477FC5AF527E3D16D13B5586131FA1CC6AB1D522A1EFDA51B84D82BCBC0E76F00E0C790A9C07D0CD81088A6E972BB453B0D72AACF78BE9506B25301A473C0F4E6DF46B6517C73D9809F5319DA70BD22C0C17D90A0A26080E262D9DFB50B21AABFB60D76E655B78B2C4A4EDE0D32CE1BBD3F05F49C12B30DA10A13BAA95F907A1306F4FAFA251D8F6E16B6A5EB177D7777FFAB5A875B3D27D250B496B3EDCF818020A27D1CF30EF135AA50CF05B70D1FBCFAB92C7D0CC17E3AB813D23233BEDB187FAB1406BB9397760F905658A124923E6F97F947EF88572CC3F50F16FC716DEA622F9878462113A5E43CFA165D80B531843CB024CC310FB4FD80788A67ABCADDD99BD5A26D1FDB72FA5DF44C84085D7EA30393ABA8E7CB659489DE64CAECC4E2E6779E80CAC156B5957C30B89F073E97BD013CE3E7D260917C1B3C46F6AF0B77A2109E7A81DBB20745B4FD4B33BCC08FD30F554C5EF9B6E69CBD225A498D2D51CA440B83205DF7AE9020AF2595F3CC648907EA05C2F4063C835606A4598A7E9CF67710332A938B1FF851A6697F9A38FFA2CCF2BBD6A00F8437794DA285A8E298CCF2D5497DCA6065D8E0AD829172FBF4D10F75BE58F97FB2D272DD9B57C5659910BDF70D78C45FDFE135DC75F8DBB69F78EF068CBEA5F9FC8940D45AB9928C9002EA165CBBFFB197AFA14327
+20210514162047 2 6 100 8191 5 D352935F33D9BC205912B919A6C5F18F76C30A32F6C0390249B48383BA4F31098BF5B6B2ACE6A745344840435A6C9A0DBF8E268F0463420452610E9A624590DC2CD57490F709DFFC5A54630DE486C73DB3C377B87C919F90BA88A7B41627351E6BEADBA605C2C625833BB95E9F34892A5D15DDF216D1A549FCFA819D7567D99015B1C3944254B87680222859779EA64C26FCEF82F34FE28E765DE3DDBCB9B3664E7896B18B93B9AA3A69944E8CEB93C18F671E2A75D6C1061B23AF8B913911A73099EA5B0F527C054B8A71B335A65CE680F02DC58D27FDBBA83EE263DD9E171B190F1CDB173BF56BB93407074B1899E8D59832EF383BCF6FB145E0F8A4A7484A2F8F4178D0A8DF9B8B920FF1250BF88BE770FD43D7EF2F4B998D86628A676173384FA95CB6B8A2599F8D5BFAA9E7C025CF29A9E1A8818B90CF2568CB8F3C003BC22B873374ACEF560B114B6B3EA0ED1701CE77A34E2723FB377BD67D480E3BF6A4E71763ED85C4E5F034A8E1761B1424AC67CFD1727157A43EEAD2168622F43967A4494E3C3D92E41EF47B7425D13D746CF617F9BB0F7CF04C093261541B6BAD54E3ED418AA1044C21FCC95B3416E6648FC576AECA4A82F2E69CE017A982407FAB0B656B56933908F1FD739686102F68805B8C605CF88952AEE1257382DE39D777527416FBED01472FE9C947AD58968D7FF2847328265584C2E93F7DF92CA891122AF48B9549020D2FAC44913C2DB5DAE20434E477FC5AF527E3D16D13B5586131FA1CC6AB1D522A1EFDA51B84D82BCBC0E76F00E0C790A9C07D0CD81088A6E972BB453B0D72AACF78BE9506B25301A473C0F4E6DF46B6517C73D9809F5319DA70BD22C0C17D90A0A26080E262D9DFB50B21AABFB60D76E655B78B2C4A4EDE0D32CE1BBD3F05F49C12B30DA10A13BAA95F907A1306F4FAFA251D8F6E16B6A5EB177D7777FFAB5A875B3D27D250B496B3EDCF818020A27D1CF30EF135AA50CF05B70D1FBCFAB92C7D0CC17E3AB813D23233BEDB187FAB1406BB9397760F905658A124923E6F97F947EF88572CC3F50F16FC716DEA622F9878462113A5E43CFA165D80B531843CB024CC310FB4FD80788A67ABCADDD99BD5A26D1FDB72FA5DF44C84085D7EA30393ABA8E7CB659489DE64CAECC4E2E6779E80CAC156B5957C30B89F073E97BD013CE3E7D260917C1B3C46F6AF0B77A2109E7A81DBB20745B4FD4B33BCC08FD30F554C5EF9B6E69CBD225A498D2D51CA440B83205DF7AE9020AF2595F3CC648907EA05C2F4063C835606A4598A7E9CF67710332A938B1FF851A6697F9A38FFA2CCF2BBD6A00F8437794DA285A8E298CCF2D5497DCA6065D8E0AD829172FBF4D10F75BE58F97FB2D272DD9B57C5659910BDF70D78C45FDFE135DC75F8DBB69F78EF068CBEA5F9FC8940D45AB9928C9002EA165CBBFFB197B2B7330F
+20210514163234 2 6 100 8191 2 D352935F33D9BC205912B919A6C5F18F76C30A32F6C0390249B48383BA4F31098BF5B6B2ACE6A745344840435A6C9A0DBF8E268F0463420452610E9A624590DC2CD57490F709DFFC5A54630DE486C73DB3C377B87C919F90BA88A7B41627351E6BEADBA605C2C625833BB95E9F34892A5D15DDF216D1A549FCFA819D7567D99015B1C3944254B87680222859779EA64C26FCEF82F34FE28E765DE3DDBCB9B3664E7896B18B93B9AA3A69944E8CEB93C18F671E2A75D6C1061B23AF8B913911A73099EA5B0F527C054B8A71B335A65CE680F02DC58D27FDBBA83EE263DD9E171B190F1CDB173BF56BB93407074B1899E8D59832EF383BCF6FB145E0F8A4A7484A2F8F4178D0A8DF9B8B920FF1250BF88BE770FD43D7EF2F4B998D86628A676173384FA95CB6B8A2599F8D5BFAA9E7C025CF29A9E1A8818B90CF2568CB8F3C003BC22B873374ACEF560B114B6B3EA0ED1701CE77A34E2723FB377BD67D480E3BF6A4E71763ED85C4E5F034A8E1761B1424AC67CFD1727157A43EEAD2168622F43967A4494E3C3D92E41EF47B7425D13D746CF617F9BB0F7CF04C093261541B6BAD54E3ED418AA1044C21FCC95B3416E6648FC576AECA4A82F2E69CE017A982407FAB0B656B56933908F1FD739686102F68805B8C605CF88952AEE1257382DE39D777527416FBED01472FE9C947AD58968D7FF2847328265584C2E93F7DF92CA891122AF48B9549020D2FAC44913C2DB5DAE20434E477FC5AF527E3D16D13B5586131FA1CC6AB1D522A1EFDA51B84D82BCBC0E76F00E0C790A9C07D0CD81088A6E972BB453B0D72AACF78BE9506B25301A473C0F4E6DF46B6517C73D9809F5319DA70BD22C0C17D90A0A26080E262D9DFB50B21AABFB60D76E655B78B2C4A4EDE0D32CE1BBD3F05F49C12B30DA10A13BAA95F907A1306F4FAFA251D8F6E16B6A5EB177D7777FFAB5A875B3D27D250B496B3EDCF818020A27D1CF30EF135AA50CF05B70D1FBCFAB92C7D0CC17E3AB813D23233BEDB187FAB1406BB9397760F905658A124923E6F97F947EF88572CC3F50F16FC716DEA622F9878462113A5E43CFA165D80B531843CB024CC310FB4FD80788A67ABCADDD99BD5A26D1FDB72FA5DF44C84085D7EA30393ABA8E7CB659489DE64CAECC4E2E6779E80CAC156B5957C30B89F073E97BD013CE3E7D260917C1B3C46F6AF0B77A2109E7A81DBB20745B4FD4B33BCC08FD30F554C5EF9B6E69CBD225A498D2D51CA440B83205DF7AE9020AF2595F3CC648907EA05C2F4063C835606A4598A7E9CF67710332A938B1FF851A6697F9A38FFA2CCF2BBD6A00F8437794DA285A8E298CCF2D5497DCA6065D8E0AD829172FBF4D10F75BE58F97FB2D272DD9B57C5659910BDF70D78C45FDFE135DC75F8DBB69F78EF068CBEA5F9FC8940D45AB9928C9002EA165CBBFFB197B36A5C3B
+20210514173058 2 6 100 8191 2 D352935F33D9BC205912B919A6C5F18F76C30A32F6C0390249B48383BA4F31098BF5B6B2ACE6A745344840435A6C9A0DBF8E268F0463420452610E9A624590DC2CD57490F709DFFC5A54630DE486C73DB3C377B87C919F90BA88A7B41627351E6BEADBA605C2C625833BB95E9F34892A5D15DDF216D1A549FCFA819D7567D99015B1C3944254B87680222859779EA64C26FCEF82F34FE28E765DE3DDBCB9B3664E7896B18B93B9AA3A69944E8CEB93C18F671E2A75D6C1061B23AF8B913911A73099EA5B0F527C054B8A71B335A65CE680F02DC58D27FDBBA83EE263DD9E171B190F1CDB173BF56BB93407074B1899E8D59832EF383BCF6FB145E0F8A4A7484A2F8F4178D0A8DF9B8B920FF1250BF88BE770FD43D7EF2F4B998D86628A676173384FA95CB6B8A2599F8D5BFAA9E7C025CF29A9E1A8818B90CF2568CB8F3C003BC22B873374ACEF560B114B6B3EA0ED1701CE77A34E2723FB377BD67D480E3BF6A4E71763ED85C4E5F034A8E1761B1424AC67CFD1727157A43EEAD2168622F43967A4494E3C3D92E41EF47B7425D13D746CF617F9BB0F7CF04C093261541B6BAD54E3ED418AA1044C21FCC95B3416E6648FC576AECA4A82F2E69CE017A982407FAB0B656B56933908F1FD739686102F68805B8C605CF88952AEE1257382DE39D777527416FBED01472FE9C947AD58968D7FF2847328265584C2E93F7DF92CA891122AF48B9549020D2FAC44913C2DB5DAE20434E477FC5AF527E3D16D13B5586131FA1CC6AB1D522A1EFDA51B84D82BCBC0E76F00E0C790A9C07D0CD81088A6E972BB453B0D72AACF78BE9506B25301A473C0F4E6DF46B6517C73D9809F5319DA70BD22C0C17D90A0A26080E262D9DFB50B21AABFB60D76E655B78B2C4A4EDE0D32CE1BBD3F05F49C12B30DA10A13BAA95F907A1306F4FAFA251D8F6E16B6A5EB177D7777FFAB5A875B3D27D250B496B3EDCF818020A27D1CF30EF135AA50CF05B70D1FBCFAB92C7D0CC17E3AB813D23233BEDB187FAB1406BB9397760F905658A124923E6F97F947EF88572CC3F50F16FC716DEA622F9878462113A5E43CFA165D80B531843CB024CC310FB4FD80788A67ABCADDD99BD5A26D1FDB72FA5DF44C84085D7EA30393ABA8E7CB659489DE64CAECC4E2E6779E80CAC156B5957C30B89F073E97BD013CE3E7D260917C1B3C46F6AF0B77A2109E7A81DBB20745B4FD4B33BCC08FD30F554C5EF9B6E69CBD225A498D2D51CA440B83205DF7AE9020AF2595F3CC648907EA05C2F4063C835606A4598A7E9CF67710332A938B1FF851A6697F9A38FFA2CCF2BBD6A00F8437794DA285A8E298CCF2D5497DCA6065D8E0AD829172FBF4D10F75BE58F97FB2D272DD9B57C5659910BDF70D78C45FDFE135DC75F8DBB69F78EF068CBEA5F9FC8940D45AB9928C9002EA165CBBFFB197B701F873
+20210514181258 2 6 100 8191 5 D352935F33D9BC205912B919A6C5F18F76C30A32F6C0390249B48383BA4F31098BF5B6B2ACE6A745344840435A6C9A0DBF8E268F0463420452610E9A624590DC2CD57490F709DFFC5A54630DE486C73DB3C377B87C919F90BA88A7B41627351E6BEADBA605C2C625833BB95E9F34892A5D15DDF216D1A549FCFA819D7567D99015B1C3944254B87680222859779EA64C26FCEF82F34FE28E765DE3DDBCB9B3664E7896B18B93B9AA3A69944E8CEB93C18F671E2A75D6C1061B23AF8B913911A73099EA5B0F527C054B8A71B335A65CE680F02DC58D27FDBBA83EE263DD9E171B190F1CDB173BF56BB93407074B1899E8D59832EF383BCF6FB145E0F8A4A7484A2F8F4178D0A8DF9B8B920FF1250BF88BE770FD43D7EF2F4B998D86628A676173384FA95CB6B8A2599F8D5BFAA9E7C025CF29A9E1A8818B90CF2568CB8F3C003BC22B873374ACEF560B114B6B3EA0ED1701CE77A34E2723FB377BD67D480E3BF6A4E71763ED85C4E5F034A8E1761B1424AC67CFD1727157A43EEAD2168622F43967A4494E3C3D92E41EF47B7425D13D746CF617F9BB0F7CF04C093261541B6BAD54E3ED418AA1044C21FCC95B3416E6648FC576AECA4A82F2E69CE017A982407FAB0B656B56933908F1FD739686102F68805B8C605CF88952AEE1257382DE39D777527416FBED01472FE9C947AD58968D7FF2847328265584C2E93F7DF92CA891122AF48B9549020D2FAC44913C2DB5DAE20434E477FC5AF527E3D16D13B5586131FA1CC6AB1D522A1EFDA51B84D82BCBC0E76F00E0C790A9C07D0CD81088A6E972BB453B0D72AACF78BE9506B25301A473C0F4E6DF46B6517C73D9809F5319DA70BD22C0C17D90A0A26080E262D9DFB50B21AABFB60D76E655B78B2C4A4EDE0D32CE1BBD3F05F49C12B30DA10A13BAA95F907A1306F4FAFA251D8F6E16B6A5EB177D7777FFAB5A875B3D27D250B496B3EDCF818020A27D1CF30EF135AA50CF05B70D1FBCFAB92C7D0CC17E3AB813D23233BEDB187FAB1406BB9397760F905658A124923E6F97F947EF88572CC3F50F16FC716DEA622F9878462113A5E43CFA165D80B531843CB024CC310FB4FD80788A67ABCADDD99BD5A26D1FDB72FA5DF44C84085D7EA30393ABA8E7CB659489DE64CAECC4E2E6779E80CAC156B5957C30B89F073E97BD013CE3E7D260917C1B3C46F6AF0B77A2109E7A81DBB20745B4FD4B33BCC08FD30F554C5EF9B6E69CBD225A498D2D51CA440B83205DF7AE9020AF2595F3CC648907EA05C2F4063C835606A4598A7E9CF67710332A938B1FF851A6697F9A38FFA2CCF2BBD6A00F8437794DA285A8E298CCF2D5497DCA6065D8E0AD829172FBF4D10F75BE58F97FB2D272DD9B57C5659910BDF70D78C45FDFE135DC75F8DBB69F78EF068CBEA5F9FC8940D45AB9928C9002EA165CBBFFB197B999E087
+20210514182942 2 6 100 8191 2 D352935F33D9BC205912B919A6C5F18F76C30A32F6C0390249B48383BA4F31098BF5B6B2ACE6A745344840435A6C9A0DBF8E268F0463420452610E9A624590DC2CD57490F709DFFC5A54630DE486C73DB3C377B87C919F90BA88A7B41627351E6BEADBA605C2C625833BB95E9F34892A5D15DDF216D1A549FCFA819D7567D99015B1C3944254B87680222859779EA64C26FCEF82F34FE28E765DE3DDBCB9B3664E7896B18B93B9AA3A69944E8CEB93C18F671E2A75D6C1061B23AF8B913911A73099EA5B0F527C054B8A71B335A65CE680F02DC58D27FDBBA83EE263DD9E171B190F1CDB173BF56BB93407074B1899E8D59832EF383BCF6FB145E0F8A4A7484A2F8F4178D0A8DF9B8B920FF1250BF88BE770FD43D7EF2F4B998D86628A676173384FA95CB6B8A2599F8D5BFAA9E7C025CF29A9E1A8818B90CF2568CB8F3C003BC22B873374ACEF560B114B6B3EA0ED1701CE77A34E2723FB377BD67D480E3BF6A4E71763ED85C4E5F034A8E1761B1424AC67CFD1727157A43EEAD2168622F43967A4494E3C3D92E41EF47B7425D13D746CF617F9BB0F7CF04C093261541B6BAD54E3ED418AA1044C21FCC95B3416E6648FC576AECA4A82F2E69CE017A982407FAB0B656B56933908F1FD739686102F68805B8C605CF88952AEE1257382DE39D777527416FBED01472FE9C947AD58968D7FF2847328265584C2E93F7DF92CA891122AF48B9549020D2FAC44913C2DB5DAE20434E477FC5AF527E3D16D13B5586131FA1CC6AB1D522A1EFDA51B84D82BCBC0E76F00E0C790A9C07D0CD81088A6E972BB453B0D72AACF78BE9506B25301A473C0F4E6DF46B6517C73D9809F5319DA70BD22C0C17D90A0A26080E262D9DFB50B21AABFB60D76E655B78B2C4A4EDE0D32CE1BBD3F05F49C12B30DA10A13BAA95F907A1306F4FAFA251D8F6E16B6A5EB177D7777FFAB5A875B3D27D250B496B3EDCF818020A27D1CF30EF135AA50CF05B70D1FBCFAB92C7D0CC17E3AB813D23233BEDB187FAB1406BB9397760F905658A124923E6F97F947EF88572CC3F50F16FC716DEA622F9878462113A5E43CFA165D80B531843CB024CC310FB4FD80788A67ABCADDD99BD5A26D1FDB72FA5DF44C84085D7EA30393ABA8E7CB659489DE64CAECC4E2E6779E80CAC156B5957C30B89F073E97BD013CE3E7D260917C1B3C46F6AF0B77A2109E7A81DBB20745B4FD4B33BCC08FD30F554C5EF9B6E69CBD225A498D2D51CA440B83205DF7AE9020AF2595F3CC648907EA05C2F4063C835606A4598A7E9CF67710332A938B1FF851A6697F9A38FFA2CCF2BBD6A00F8437794DA285A8E298CCF2D5497DCA6065D8E0AD829172FBF4D10F75BE58F97FB2D272DD9B57C5659910BDF70D78C45FDFE135DC75F8DBB69F78EF068CBEA5F9FC8940D45AB9928C9002EA165CBBFFB197BA9B3683
+20210514191337 2 6 100 8191 5 D352935F33D9BC205912B919A6C5F18F76C30A32F6C0390249B48383BA4F31098BF5B6B2ACE6A745344840435A6C9A0DBF8E268F0463420452610E9A624590DC2CD57490F709DFFC5A54630DE486C73DB3C377B87C919F90BA88A7B41627351E6BEADBA605C2C625833BB95E9F34892A5D15DDF216D1A549FCFA819D7567D99015B1C3944254B87680222859779EA64C26FCEF82F34FE28E765DE3DDBCB9B3664E7896B18B93B9AA3A69944E8CEB93C18F671E2A75D6C1061B23AF8B913911A73099EA5B0F527C054B8A71B335A65CE680F02DC58D27FDBBA83EE263DD9E171B190F1CDB173BF56BB93407074B1899E8D59832EF383BCF6FB145E0F8A4A7484A2F8F4178D0A8DF9B8B920FF1250BF88BE770FD43D7EF2F4B998D86628A676173384FA95CB6B8A2599F8D5BFAA9E7C025CF29A9E1A8818B90CF2568CB8F3C003BC22B873374ACEF560B114B6B3EA0ED1701CE77A34E2723FB377BD67D480E3BF6A4E71763ED85C4E5F034A8E1761B1424AC67CFD1727157A43EEAD2168622F43967A4494E3C3D92E41EF47B7425D13D746CF617F9BB0F7CF04C093261541B6BAD54E3ED418AA1044C21FCC95B3416E6648FC576AECA4A82F2E69CE017A982407FAB0B656B56933908F1FD739686102F68805B8C605CF88952AEE1257382DE39D777527416FBED01472FE9C947AD58968D7FF2847328265584C2E93F7DF92CA891122AF48B9549020D2FAC44913C2DB5DAE20434E477FC5AF527E3D16D13B5586131FA1CC6AB1D522A1EFDA51B84D82BCBC0E76F00E0C790A9C07D0CD81088A6E972BB453B0D72AACF78BE9506B25301A473C0F4E6DF46B6517C73D9809F5319DA70BD22C0C17D90A0A26080E262D9DFB50B21AABFB60D76E655B78B2C4A4EDE0D32CE1BBD3F05F49C12B30DA10A13BAA95F907A1306F4FAFA251D8F6E16B6A5EB177D7777FFAB5A875B3D27D250B496B3EDCF818020A27D1CF30EF135AA50CF05B70D1FBCFAB92C7D0CC17E3AB813D23233BEDB187FAB1406BB9397760F905658A124923E6F97F947EF88572CC3F50F16FC716DEA622F9878462113A5E43CFA165D80B531843CB024CC310FB4FD80788A67ABCADDD99BD5A26D1FDB72FA5DF44C84085D7EA30393ABA8E7CB659489DE64CAECC4E2E6779E80CAC156B5957C30B89F073E97BD013CE3E7D260917C1B3C46F6AF0B77A2109E7A81DBB20745B4FD4B33BCC08FD30F554C5EF9B6E69CBD225A498D2D51CA440B83205DF7AE9020AF2595F3CC648907EA05C2F4063C835606A4598A7E9CF67710332A938B1FF851A6697F9A38FFA2CCF2BBD6A00F8437794DA285A8E298CCF2D5497DCA6065D8E0AD829172FBF4D10F75BE58F97FB2D272DD9B57C5659910BDF70D78C45FDFE135DC75F8DBB69F78EF068CBEA5F9FC8940D45AB9928C9002EA165CBBFFB197BD4793EF
+20210514193708 2 6 100 8191 2 D352935F33D9BC205912B919A6C5F18F76C30A32F6C0390249B48383BA4F31098BF5B6B2ACE6A745344840435A6C9A0DBF8E268F0463420452610E9A624590DC2CD57490F709DFFC5A54630DE486C73DB3C377B87C919F90BA88A7B41627351E6BEADBA605C2C625833BB95E9F34892A5D15DDF216D1A549FCFA819D7567D99015B1C3944254B87680222859779EA64C26FCEF82F34FE28E765DE3DDBCB9B3664E7896B18B93B9AA3A69944E8CEB93C18F671E2A75D6C1061B23AF8B913911A73099EA5B0F527C054B8A71B335A65CE680F02DC58D27FDBBA83EE263DD9E171B190F1CDB173BF56BB93407074B1899E8D59832EF383BCF6FB145E0F8A4A7484A2F8F4178D0A8DF9B8B920FF1250BF88BE770FD43D7EF2F4B998D86628A676173384FA95CB6B8A2599F8D5BFAA9E7C025CF29A9E1A8818B90CF2568CB8F3C003BC22B873374ACEF560B114B6B3EA0ED1701CE77A34E2723FB377BD67D480E3BF6A4E71763ED85C4E5F034A8E1761B1424AC67CFD1727157A43EEAD2168622F43967A4494E3C3D92E41EF47B7425D13D746CF617F9BB0F7CF04C093261541B6BAD54E3ED418AA1044C21FCC95B3416E6648FC576AECA4A82F2E69CE017A982407FAB0B656B56933908F1FD739686102F68805B8C605CF88952AEE1257382DE39D777527416FBED01472FE9C947AD58968D7FF2847328265584C2E93F7DF92CA891122AF48B9549020D2FAC44913C2DB5DAE20434E477FC5AF527E3D16D13B5586131FA1CC6AB1D522A1EFDA51B84D82BCBC0E76F00E0C790A9C07D0CD81088A6E972BB453B0D72AACF78BE9506B25301A473C0F4E6DF46B6517C73D9809F5319DA70BD22C0C17D90A0A26080E262D9DFB50B21AABFB60D76E655B78B2C4A4EDE0D32CE1BBD3F05F49C12B30DA10A13BAA95F907A1306F4FAFA251D8F6E16B6A5EB177D7777FFAB5A875B3D27D250B496B3EDCF818020A27D1CF30EF135AA50CF05B70D1FBCFAB92C7D0CC17E3AB813D23233BEDB187FAB1406BB9397760F905658A124923E6F97F947EF88572CC3F50F16FC716DEA622F9878462113A5E43CFA165D80B531843CB024CC310FB4FD80788A67ABCADDD99BD5A26D1FDB72FA5DF44C84085D7EA30393ABA8E7CB659489DE64CAECC4E2E6779E80CAC156B5957C30B89F073E97BD013CE3E7D260917C1B3C46F6AF0B77A2109E7A81DBB20745B4FD4B33BCC08FD30F554C5EF9B6E69CBD225A498D2D51CA440B83205DF7AE9020AF2595F3CC648907EA05C2F4063C835606A4598A7E9CF67710332A938B1FF851A6697F9A38FFA2CCF2BBD6A00F8437794DA285A8E298CCF2D5497DCA6065D8E0AD829172FBF4D10F75BE58F97FB2D272DD9B57C5659910BDF70D78C45FDFE135DC75F8DBB69F78EF068CBEA5F9FC8940D45AB9928C9002EA165CBBFFB197BEACFC3B
+20210514205734 2 6 100 8191 2 D352935F33D9BC205912B919A6C5F18F76C30A32F6C0390249B48383BA4F31098BF5B6B2ACE6A745344840435A6C9A0DBF8E268F0463420452610E9A624590DC2CD57490F709DFFC5A54630DE486C73DB3C377B87C919F90BA88A7B41627351E6BEADBA605C2C625833BB95E9F34892A5D15DDF216D1A549FCFA819D7567D99015B1C3944254B87680222859779EA64C26FCEF82F34FE28E765DE3DDBCB9B3664E7896B18B93B9AA3A69944E8CEB93C18F671E2A75D6C1061B23AF8B913911A73099EA5B0F527C054B8A71B335A65CE680F02DC58D27FDBBA83EE263DD9E171B190F1CDB173BF56BB93407074B1899E8D59832EF383BCF6FB145E0F8A4A7484A2F8F4178D0A8DF9B8B920FF1250BF88BE770FD43D7EF2F4B998D86628A676173384FA95CB6B8A2599F8D5BFAA9E7C025CF29A9E1A8818B90CF2568CB8F3C003BC22B873374ACEF560B114B6B3EA0ED1701CE77A34E2723FB377BD67D480E3BF6A4E71763ED85C4E5F034A8E1761B1424AC67CFD1727157A43EEAD2168622F43967A4494E3C3D92E41EF47B7425D13D746CF617F9BB0F7CF04C093261541B6BAD54E3ED418AA1044C21FCC95B3416E6648FC576AECA4A82F2E69CE017A982407FAB0B656B56933908F1FD739686102F68805B8C605CF88952AEE1257382DE39D777527416FBED01472FE9C947AD58968D7FF2847328265584C2E93F7DF92CA891122AF48B9549020D2FAC44913C2DB5DAE20434E477FC5AF527E3D16D13B5586131FA1CC6AB1D522A1EFDA51B84D82BCBC0E76F00E0C790A9C07D0CD81088A6E972BB453B0D72AACF78BE9506B25301A473C0F4E6DF46B6517C73D9809F5319DA70BD22C0C17D90A0A26080E262D9DFB50B21AABFB60D76E655B78B2C4A4EDE0D32CE1BBD3F05F49C12B30DA10A13BAA95F907A1306F4FAFA251D8F6E16B6A5EB177D7777FFAB5A875B3D27D250B496B3EDCF818020A27D1CF30EF135AA50CF05B70D1FBCFAB92C7D0CC17E3AB813D23233BEDB187FAB1406BB9397760F905658A124923E6F97F947EF88572CC3F50F16FC716DEA622F9878462113A5E43CFA165D80B531843CB024CC310FB4FD80788A67ABCADDD99BD5A26D1FDB72FA5DF44C84085D7EA30393ABA8E7CB659489DE64CAECC4E2E6779E80CAC156B5957C30B89F073E97BD013CE3E7D260917C1B3C46F6AF0B77A2109E7A81DBB20745B4FD4B33BCC08FD30F554C5EF9B6E69CBD225A498D2D51CA440B83205DF7AE9020AF2595F3CC648907EA05C2F4063C835606A4598A7E9CF67710332A938B1FF851A6697F9A38FFA2CCF2BBD6A00F8437794DA285A8E298CCF2D5497DCA6065D8E0AD829172FBF4D10F75BE58F97FB2D272DD9B57C5659910BDF70D78C45FDFE135DC75F8DBB69F78EF068CBEA5F9FC8940D45AB9928C9002EA165CBBFFB197C391340B
+20210514221328 2 6 100 8191 2 D352935F33D9BC205912B919A6C5F18F76C30A32F6C0390249B48383BA4F31098BF5B6B2ACE6A745344840435A6C9A0DBF8E268F0463420452610E9A624590DC2CD57490F709DFFC5A54630DE486C73DB3C377B87C919F90BA88A7B41627351E6BEADBA605C2C625833BB95E9F34892A5D15DDF216D1A549FCFA819D7567D99015B1C3944254B87680222859779EA64C26FCEF82F34FE28E765DE3DDBCB9B3664E7896B18B93B9AA3A69944E8CEB93C18F671E2A75D6C1061B23AF8B913911A73099EA5B0F527C054B8A71B335A65CE680F02DC58D27FDBBA83EE263DD9E171B190F1CDB173BF56BB93407074B1899E8D59832EF383BCF6FB145E0F8A4A7484A2F8F4178D0A8DF9B8B920FF1250BF88BE770FD43D7EF2F4B998D86628A676173384FA95CB6B8A2599F8D5BFAA9E7C025CF29A9E1A8818B90CF2568CB8F3C003BC22B873374ACEF560B114B6B3EA0ED1701CE77A34E2723FB377BD67D480E3BF6A4E71763ED85C4E5F034A8E1761B1424AC67CFD1727157A43EEAD2168622F43967A4494E3C3D92E41EF47B7425D13D746CF617F9BB0F7CF04C093261541B6BAD54E3ED418AA1044C21FCC95B3416E6648FC576AECA4A82F2E69CE017A982407FAB0B656B56933908F1FD739686102F68805B8C605CF88952AEE1257382DE39D777527416FBED01472FE9C947AD58968D7FF2847328265584C2E93F7DF92CA891122AF48B9549020D2FAC44913C2DB5DAE20434E477FC5AF527E3D16D13B5586131FA1CC6AB1D522A1EFDA51B84D82BCBC0E76F00E0C790A9C07D0CD81088A6E972BB453B0D72AACF78BE9506B25301A473C0F4E6DF46B6517C73D9809F5319DA70BD22C0C17D90A0A26080E262D9DFB50B21AABFB60D76E655B78B2C4A4EDE0D32CE1BBD3F05F49C12B30DA10A13BAA95F907A1306F4FAFA251D8F6E16B6A5EB177D7777FFAB5A875B3D27D250B496B3EDCF818020A27D1CF30EF135AA50CF05B70D1FBCFAB92C7D0CC17E3AB813D23233BEDB187FAB1406BB9397760F905658A124923E6F97F947EF88572CC3F50F16FC716DEA622F9878462113A5E43CFA165D80B531843CB024CC310FB4FD80788A67ABCADDD99BD5A26D1FDB72FA5DF44C84085D7EA30393ABA8E7CB659489DE64CAECC4E2E6779E80CAC156B5957C30B89F073E97BD013CE3E7D260917C1B3C46F6AF0B77A2109E7A81DBB20745B4FD4B33BCC08FD30F554C5EF9B6E69CBD225A498D2D51CA440B83205DF7AE9020AF2595F3CC648907EA05C2F4063C835606A4598A7E9CF67710332A938B1FF851A6697F9A38FFA2CCF2BBD6A00F8437794DA285A8E298CCF2D5497DCA6065D8E0AD829172FBF4D10F75BE58F97FB2D272DD9B57C5659910BDF70D78C45FDFE135DC75F8DBB69F78EF068CBEA5F9FC8940D45AB9928C9002EA165CBBFFB197C828281B
+20210515004609 2 6 100 8191 2 DD4A2D5D7B10514C9CBEB91330C309D38566FF0D418584030168693F4060DE64CC996D4F9D446AEF0F5C78E4BCFD2067A117FF78EDB5E248F494F0F6AAF718220D801EE111F50E6FD20092C3C4CFF0452384E6EF948624A85ACB5A40280F32E0C1824BF0D7215F20DC356DCF39DB382083F4CAB942564DEDA2B38211789A707CA0388E27191F3238E75B8FA352A37BA743CB80351DB5DC8F4F5CFD79C920102A838B5EE973E4F95253B43B0E327F31CBBBD7932E13C2DB0F43CCE1FB609DFE4140CA3B048CFB3C929AB9685EBFFD09F08625727583AE0E4AB61DDE47807E124D84F3FCA43FC92A7AA931FBE193CC609611FC30E873F1988D92251DF49C1E2A9126C63FA3FE19C4D9066FEC94693CBCC0951624C3F410F729F9539D35C848D924C29CF512ED032AA4B5AC4A2440197C81D5EBA6A5A9CBC11F4660FFE7597F60E6AF25944E425D724606ABFCB84878D66CE017D3ED6B07CA4FCA5B5CFA57C82FCCF1172850678F63F6F2277F242C1DACB5D16D2BC5EC611C45751A8AFC3179CEFA82334172D326B3CFCB9FB43B2E981AB6BC4033CC2E7BB57E6A19A74953E1E5E7A2E4463E3C3C950ACC5128D1DC543A6BB34C3AE3F4C33818923C1911329D5BA8D6AF1ED5915E1A1E0824CC612898AF0B0EBB553D5760AD00913D60A5649C860B3FCA1049A55BC24045298537BAA1E47B9C779FF24654889FF6162DFF3DF787E53CE4D1355AAF425B9B7CACE1C9FE076D61BD6A1887155813C7C922ABF8D161B546A94D091365D7EF693532B7CB2352F73EB8E4CB75E5771E21C2691C1AB114880E0AB104869DA6425900EF55A5B95FED252DC1D70B2473B26AEFFBCD5569F895D16B50F030B7EB2846985D185880F2B4624622F28CDD73CAEBBC318187AD69432EF31B38831E67222CCBA64DFBF0937A297E3473421506E7AA1D30DABE3841E8F58D6C6B1D0596867D80ADA9A9ADD06A1FB634DBF7B1FEF67DBABFF52538C4563B90FD343F711822EA17054A9FD1D61B9FD78CD083345E7544853B5D284CC73082C2042BFF6C2614FB1F129F7B7E2C07DFF784DCC5859A8306A33807ED27958C3FFD25F13537F869248BE6E4B3ADD9F03E5DF976D1BCEE46C30B5E79AFCF5233F3E4FE05EE6E5AA17A0E44BD67B1ED69F51F5EF287E531FA51B4FA545BC0C3EFB16D8424518AE27498DFBCBF79D129CA3AF38108C86266527435FC27AFA4201609B974EC1CEF0741BC478676736135E5E2BA6297C061E585CE267A99CB411505FC26A2E54209C94D6757CA9B71127B401DEB364D0A86C4C22A5A65CDD2504C57602959D2DB6E8BAC42720A76B8910D08852AE79D91F195A046D86BC3D88660ECC6BAB9CA26B765B45C6DC2571685EE8F25EEBC7B7FEE5AE00B492CF90CFC2C2348F92D2C0D4776FC611CB1F7064E40230E74302CF83A93F177A53CE7B7D0AF33
+20210515010402 2 6 100 8191 5 DD4A2D5D7B10514C9CBEB91330C309D38566FF0D418584030168693F4060DE64CC996D4F9D446AEF0F5C78E4BCFD2067A117FF78EDB5E248F494F0F6AAF718220D801EE111F50E6FD20092C3C4CFF0452384E6EF948624A85ACB5A40280F32E0C1824BF0D7215F20DC356DCF39DB382083F4CAB942564DEDA2B38211789A707CA0388E27191F3238E75B8FA352A37BA743CB80351DB5DC8F4F5CFD79C920102A838B5EE973E4F95253B43B0E327F31CBBBD7932E13C2DB0F43CCE1FB609DFE4140CA3B048CFB3C929AB9685EBFFD09F08625727583AE0E4AB61DDE47807E124D84F3FCA43FC92A7AA931FBE193CC609611FC30E873F1988D92251DF49C1E2A9126C63FA3FE19C4D9066FEC94693CBCC0951624C3F410F729F9539D35C848D924C29CF512ED032AA4B5AC4A2440197C81D5EBA6A5A9CBC11F4660FFE7597F60E6AF25944E425D724606ABFCB84878D66CE017D3ED6B07CA4FCA5B5CFA57C82FCCF1172850678F63F6F2277F242C1DACB5D16D2BC5EC611C45751A8AFC3179CEFA82334172D326B3CFCB9FB43B2E981AB6BC4033CC2E7BB57E6A19A74953E1E5E7A2E4463E3C3C950ACC5128D1DC543A6BB34C3AE3F4C33818923C1911329D5BA8D6AF1ED5915E1A1E0824CC612898AF0B0EBB553D5760AD00913D60A5649C860B3FCA1049A55BC24045298537BAA1E47B9C779FF24654889FF6162DFF3DF787E53CE4D1355AAF425B9B7CACE1C9FE076D61BD6A1887155813C7C922ABF8D161B546A94D091365D7EF693532B7CB2352F73EB8E4CB75E5771E21C2691C1AB114880E0AB104869DA6425900EF55A5B95FED252DC1D70B2473B26AEFFBCD5569F895D16B50F030B7EB2846985D185880F2B4624622F28CDD73CAEBBC318187AD69432EF31B38831E67222CCBA64DFBF0937A297E3473421506E7AA1D30DABE3841E8F58D6C6B1D0596867D80ADA9A9ADD06A1FB634DBF7B1FEF67DBABFF52538C4563B90FD343F711822EA17054A9FD1D61B9FD78CD083345E7544853B5D284CC73082C2042BFF6C2614FB1F129F7B7E2C07DFF784DCC5859A8306A33807ED27958C3FFD25F13537F869248BE6E4B3ADD9F03E5DF976D1BCEE46C30B5E79AFCF5233F3E4FE05EE6E5AA17A0E44BD67B1ED69F51F5EF287E531FA51B4FA545BC0C3EFB16D8424518AE27498DFBCBF79D129CA3AF38108C86266527435FC27AFA4201609B974EC1CEF0741BC478676736135E5E2BA6297C061E585CE267A99CB411505FC26A2E54209C94D6757CA9B71127B401DEB364D0A86C4C22A5A65CDD2504C57602959D2DB6E8BAC42720A76B8910D08852AE79D91F195A046D86BC3D88660ECC6BAB9CA26B765B45C6DC2571685EE8F25EEBC7B7FEE5AE00B492CF90CFC2C2348F92D2C0D4776FC611CB1F7064E40230E74302CF83A93F177A53CE7B90F73BF
+20210515020359 2 6 100 8191 2 DD4A2D5D7B10514C9CBEB91330C309D38566FF0D418584030168693F4060DE64CC996D4F9D446AEF0F5C78E4BCFD2067A117FF78EDB5E248F494F0F6AAF718220D801EE111F50E6FD20092C3C4CFF0452384E6EF948624A85ACB5A40280F32E0C1824BF0D7215F20DC356DCF39DB382083F4CAB942564DEDA2B38211789A707CA0388E27191F3238E75B8FA352A37BA743CB80351DB5DC8F4F5CFD79C920102A838B5EE973E4F95253B43B0E327F31CBBBD7932E13C2DB0F43CCE1FB609DFE4140CA3B048CFB3C929AB9685EBFFD09F08625727583AE0E4AB61DDE47807E124D84F3FCA43FC92A7AA931FBE193CC609611FC30E873F1988D92251DF49C1E2A9126C63FA3FE19C4D9066FEC94693CBCC0951624C3F410F729F9539D35C848D924C29CF512ED032AA4B5AC4A2440197C81D5EBA6A5A9CBC11F4660FFE7597F60E6AF25944E425D724606ABFCB84878D66CE017D3ED6B07CA4FCA5B5CFA57C82FCCF1172850678F63F6F2277F242C1DACB5D16D2BC5EC611C45751A8AFC3179CEFA82334172D326B3CFCB9FB43B2E981AB6BC4033CC2E7BB57E6A19A74953E1E5E7A2E4463E3C3C950ACC5128D1DC543A6BB34C3AE3F4C33818923C1911329D5BA8D6AF1ED5915E1A1E0824CC612898AF0B0EBB553D5760AD00913D60A5649C860B3FCA1049A55BC24045298537BAA1E47B9C779FF24654889FF6162DFF3DF787E53CE4D1355AAF425B9B7CACE1C9FE076D61BD6A1887155813C7C922ABF8D161B546A94D091365D7EF693532B7CB2352F73EB8E4CB75E5771E21C2691C1AB114880E0AB104869DA6425900EF55A5B95FED252DC1D70B2473B26AEFFBCD5569F895D16B50F030B7EB2846985D185880F2B4624622F28CDD73CAEBBC318187AD69432EF31B38831E67222CCBA64DFBF0937A297E3473421506E7AA1D30DABE3841E8F58D6C6B1D0596867D80ADA9A9ADD06A1FB634DBF7B1FEF67DBABFF52538C4563B90FD343F711822EA17054A9FD1D61B9FD78CD083345E7544853B5D284CC73082C2042BFF6C2614FB1F129F7B7E2C07DFF784DCC5859A8306A33807ED27958C3FFD25F13537F869248BE6E4B3ADD9F03E5DF976D1BCEE46C30B5E79AFCF5233F3E4FE05EE6E5AA17A0E44BD67B1ED69F51F5EF287E531FA51B4FA545BC0C3EFB16D8424518AE27498DFBCBF79D129CA3AF38108C86266527435FC27AFA4201609B974EC1CEF0741BC478676736135E5E2BA6297C061E585CE267A99CB411505FC26A2E54209C94D6757CA9B71127B401DEB364D0A86C4C22A5A65CDD2504C57602959D2DB6E8BAC42720A76B8910D08852AE79D91F195A046D86BC3D88660ECC6BAB9CA26B765B45C6DC2571685EE8F25EEBC7B7FEE5AE00B492CF90CFC2C2348F92D2C0D4776FC611CB1F7064E40230E74302CF83A93F177A53CE7BD3DCDAB
+20210515020859 2 6 100 8191 5 DD4A2D5D7B10514C9CBEB91330C309D38566FF0D418584030168693F4060DE64CC996D4F9D446AEF0F5C78E4BCFD2067A117FF78EDB5E248F494F0F6AAF718220D801EE111F50E6FD20092C3C4CFF0452384E6EF948624A85ACB5A40280F32E0C1824BF0D7215F20DC356DCF39DB382083F4CAB942564DEDA2B38211789A707CA0388E27191F3238E75B8FA352A37BA743CB80351DB5DC8F4F5CFD79C920102A838B5EE973E4F95253B43B0E327F31CBBBD7932E13C2DB0F43CCE1FB609DFE4140CA3B048CFB3C929AB9685EBFFD09F08625727583AE0E4AB61DDE47807E124D84F3FCA43FC92A7AA931FBE193CC609611FC30E873F1988D92251DF49C1E2A9126C63FA3FE19C4D9066FEC94693CBCC0951624C3F410F729F9539D35C848D924C29CF512ED032AA4B5AC4A2440197C81D5EBA6A5A9CBC11F4660FFE7597F60E6AF25944E425D724606ABFCB84878D66CE017D3ED6B07CA4FCA5B5CFA57C82FCCF1172850678F63F6F2277F242C1DACB5D16D2BC5EC611C45751A8AFC3179CEFA82334172D326B3CFCB9FB43B2E981AB6BC4033CC2E7BB57E6A19A74953E1E5E7A2E4463E3C3C950ACC5128D1DC543A6BB34C3AE3F4C33818923C1911329D5BA8D6AF1ED5915E1A1E0824CC612898AF0B0EBB553D5760AD00913D60A5649C860B3FCA1049A55BC24045298537BAA1E47B9C779FF24654889FF6162DFF3DF787E53CE4D1355AAF425B9B7CACE1C9FE076D61BD6A1887155813C7C922ABF8D161B546A94D091365D7EF693532B7CB2352F73EB8E4CB75E5771E21C2691C1AB114880E0AB104869DA6425900EF55A5B95FED252DC1D70B2473B26AEFFBCD5569F895D16B50F030B7EB2846985D185880F2B4624622F28CDD73CAEBBC318187AD69432EF31B38831E67222CCBA64DFBF0937A297E3473421506E7AA1D30DABE3841E8F58D6C6B1D0596867D80ADA9A9ADD06A1FB634DBF7B1FEF67DBABFF52538C4563B90FD343F711822EA17054A9FD1D61B9FD78CD083345E7544853B5D284CC73082C2042BFF6C2614FB1F129F7B7E2C07DFF784DCC5859A8306A33807ED27958C3FFD25F13537F869248BE6E4B3ADD9F03E5DF976D1BCEE46C30B5E79AFCF5233F3E4FE05EE6E5AA17A0E44BD67B1ED69F51F5EF287E531FA51B4FA545BC0C3EFB16D8424518AE27498DFBCBF79D129CA3AF38108C86266527435FC27AFA4201609B974EC1CEF0741BC478676736135E5E2BA6297C061E585CE267A99CB411505FC26A2E54209C94D6757CA9B71127B401DEB364D0A86C4C22A5A65CDD2504C57602959D2DB6E8BAC42720A76B8910D08852AE79D91F195A046D86BC3D88660ECC6BAB9CA26B765B45C6DC2571685EE8F25EEBC7B7FEE5AE00B492CF90CFC2C2348F92D2C0D4776FC611CB1F7064E40230E74302CF83A93F177A53CE7BD8C099F
+20210515024607 2 6 100 8191 5 DD4A2D5D7B10514C9CBEB91330C309D38566FF0D418584030168693F4060DE64CC996D4F9D446AEF0F5C78E4BCFD2067A117FF78EDB5E248F494F0F6AAF718220D801EE111F50E6FD20092C3C4CFF0452384E6EF948624A85ACB5A40280F32E0C1824BF0D7215F20DC356DCF39DB382083F4CAB942564DEDA2B38211789A707CA0388E27191F3238E75B8FA352A37BA743CB80351DB5DC8F4F5CFD79C920102A838B5EE973E4F95253B43B0E327F31CBBBD7932E13C2DB0F43CCE1FB609DFE4140CA3B048CFB3C929AB9685EBFFD09F08625727583AE0E4AB61DDE47807E124D84F3FCA43FC92A7AA931FBE193CC609611FC30E873F1988D92251DF49C1E2A9126C63FA3FE19C4D9066FEC94693CBCC0951624C3F410F729F9539D35C848D924C29CF512ED032AA4B5AC4A2440197C81D5EBA6A5A9CBC11F4660FFE7597F60E6AF25944E425D724606ABFCB84878D66CE017D3ED6B07CA4FCA5B5CFA57C82FCCF1172850678F63F6F2277F242C1DACB5D16D2BC5EC611C45751A8AFC3179CEFA82334172D326B3CFCB9FB43B2E981AB6BC4033CC2E7BB57E6A19A74953E1E5E7A2E4463E3C3C950ACC5128D1DC543A6BB34C3AE3F4C33818923C1911329D5BA8D6AF1ED5915E1A1E0824CC612898AF0B0EBB553D5760AD00913D60A5649C860B3FCA1049A55BC24045298537BAA1E47B9C779FF24654889FF6162DFF3DF787E53CE4D1355AAF425B9B7CACE1C9FE076D61BD6A1887155813C7C922ABF8D161B546A94D091365D7EF693532B7CB2352F73EB8E4CB75E5771E21C2691C1AB114880E0AB104869DA6425900EF55A5B95FED252DC1D70B2473B26AEFFBCD5569F895D16B50F030B7EB2846985D185880F2B4624622F28CDD73CAEBBC318187AD69432EF31B38831E67222CCBA64DFBF0937A297E3473421506E7AA1D30DABE3841E8F58D6C6B1D0596867D80ADA9A9ADD06A1FB634DBF7B1FEF67DBABFF52538C4563B90FD343F711822EA17054A9FD1D61B9FD78CD083345E7544853B5D284CC73082C2042BFF6C2614FB1F129F7B7E2C07DFF784DCC5859A8306A33807ED27958C3FFD25F13537F869248BE6E4B3ADD9F03E5DF976D1BCEE46C30B5E79AFCF5233F3E4FE05EE6E5AA17A0E44BD67B1ED69F51F5EF287E531FA51B4FA545BC0C3EFB16D8424518AE27498DFBCBF79D129CA3AF38108C86266527435FC27AFA4201609B974EC1CEF0741BC478676736135E5E2BA6297C061E585CE267A99CB411505FC26A2E54209C94D6757CA9B71127B401DEB364D0A86C4C22A5A65CDD2504C57602959D2DB6E8BAC42720A76B8910D08852AE79D91F195A046D86BC3D88660ECC6BAB9CA26B765B45C6DC2571685EE8F25EEBC7B7FEE5AE00B492CF90CFC2C2348F92D2C0D4776FC611CB1F7064E40230E74302CF83A93F177A53CE7C01A4257
+20210515042745 2 6 100 8191 5 DD4A2D5D7B10514C9CBEB91330C309D38566FF0D418584030168693F4060DE64CC996D4F9D446AEF0F5C78E4BCFD2067A117FF78EDB5E248F494F0F6AAF718220D801EE111F50E6FD20092C3C4CFF0452384E6EF948624A85ACB5A40280F32E0C1824BF0D7215F20DC356DCF39DB382083F4CAB942564DEDA2B38211789A707CA0388E27191F3238E75B8FA352A37BA743CB80351DB5DC8F4F5CFD79C920102A838B5EE973E4F95253B43B0E327F31CBBBD7932E13C2DB0F43CCE1FB609DFE4140CA3B048CFB3C929AB9685EBFFD09F08625727583AE0E4AB61DDE47807E124D84F3FCA43FC92A7AA931FBE193CC609611FC30E873F1988D92251DF49C1E2A9126C63FA3FE19C4D9066FEC94693CBCC0951624C3F410F729F9539D35C848D924C29CF512ED032AA4B5AC4A2440197C81D5EBA6A5A9CBC11F4660FFE7597F60E6AF25944E425D724606ABFCB84878D66CE017D3ED6B07CA4FCA5B5CFA57C82FCCF1172850678F63F6F2277F242C1DACB5D16D2BC5EC611C45751A8AFC3179CEFA82334172D326B3CFCB9FB43B2E981AB6BC4033CC2E7BB57E6A19A74953E1E5E7A2E4463E3C3C950ACC5128D1DC543A6BB34C3AE3F4C33818923C1911329D5BA8D6AF1ED5915E1A1E0824CC612898AF0B0EBB553D5760AD00913D60A5649C860B3FCA1049A55BC24045298537BAA1E47B9C779FF24654889FF6162DFF3DF787E53CE4D1355AAF425B9B7CACE1C9FE076D61BD6A1887155813C7C922ABF8D161B546A94D091365D7EF693532B7CB2352F73EB8E4CB75E5771E21C2691C1AB114880E0AB104869DA6425900EF55A5B95FED252DC1D70B2473B26AEFFBCD5569F895D16B50F030B7EB2846985D185880F2B4624622F28CDD73CAEBBC318187AD69432EF31B38831E67222CCBA64DFBF0937A297E3473421506E7AA1D30DABE3841E8F58D6C6B1D0596867D80ADA9A9ADD06A1FB634DBF7B1FEF67DBABFF52538C4563B90FD343F711822EA17054A9FD1D61B9FD78CD083345E7544853B5D284CC73082C2042BFF6C2614FB1F129F7B7E2C07DFF784DCC5859A8306A33807ED27958C3FFD25F13537F869248BE6E4B3ADD9F03E5DF976D1BCEE46C30B5E79AFCF5233F3E4FE05EE6E5AA17A0E44BD67B1ED69F51F5EF287E531FA51B4FA545BC0C3EFB16D8424518AE27498DFBCBF79D129CA3AF38108C86266527435FC27AFA4201609B974EC1CEF0741BC478676736135E5E2BA6297C061E585CE267A99CB411505FC26A2E54209C94D6757CA9B71127B401DEB364D0A86C4C22A5A65CDD2504C57602959D2DB6E8BAC42720A76B8910D08852AE79D91F195A046D86BC3D88660ECC6BAB9CA26B765B45C6DC2571685EE8F25EEBC7B7FEE5AE00B492CF90CFC2C2348F92D2C0D4776FC611CB1F7064E40230E74302CF83A93F177A53CE7C7338DAF
+20210515064126 2 6 100 8191 2 DD4A2D5D7B10514C9CBEB91330C309D38566FF0D418584030168693F4060DE64CC996D4F9D446AEF0F5C78E4BCFD2067A117FF78EDB5E248F494F0F6AAF718220D801EE111F50E6FD20092C3C4CFF0452384E6EF948624A85ACB5A40280F32E0C1824BF0D7215F20DC356DCF39DB382083F4CAB942564DEDA2B38211789A707CA0388E27191F3238E75B8FA352A37BA743CB80351DB5DC8F4F5CFD79C920102A838B5EE973E4F95253B43B0E327F31CBBBD7932E13C2DB0F43CCE1FB609DFE4140CA3B048CFB3C929AB9685EBFFD09F08625727583AE0E4AB61DDE47807E124D84F3FCA43FC92A7AA931FBE193CC609611FC30E873F1988D92251DF49C1E2A9126C63FA3FE19C4D9066FEC94693CBCC0951624C3F410F729F9539D35C848D924C29CF512ED032AA4B5AC4A2440197C81D5EBA6A5A9CBC11F4660FFE7597F60E6AF25944E425D724606ABFCB84878D66CE017D3ED6B07CA4FCA5B5CFA57C82FCCF1172850678F63F6F2277F242C1DACB5D16D2BC5EC611C45751A8AFC3179CEFA82334172D326B3CFCB9FB43B2E981AB6BC4033CC2E7BB57E6A19A74953E1E5E7A2E4463E3C3C950ACC5128D1DC543A6BB34C3AE3F4C33818923C1911329D5BA8D6AF1ED5915E1A1E0824CC612898AF0B0EBB553D5760AD00913D60A5649C860B3FCA1049A55BC24045298537BAA1E47B9C779FF24654889FF6162DFF3DF787E53CE4D1355AAF425B9B7CACE1C9FE076D61BD6A1887155813C7C922ABF8D161B546A94D091365D7EF693532B7CB2352F73EB8E4CB75E5771E21C2691C1AB114880E0AB104869DA6425900EF55A5B95FED252DC1D70B2473B26AEFFBCD5569F895D16B50F030B7EB2846985D185880F2B4624622F28CDD73CAEBBC318187AD69432EF31B38831E67222CCBA64DFBF0937A297E3473421506E7AA1D30DABE3841E8F58D6C6B1D0596867D80ADA9A9ADD06A1FB634DBF7B1FEF67DBABFF52538C4563B90FD343F711822EA17054A9FD1D61B9FD78CD083345E7544853B5D284CC73082C2042BFF6C2614FB1F129F7B7E2C07DFF784DCC5859A8306A33807ED27958C3FFD25F13537F869248BE6E4B3ADD9F03E5DF976D1BCEE46C30B5E79AFCF5233F3E4FE05EE6E5AA17A0E44BD67B1ED69F51F5EF287E531FA51B4FA545BC0C3EFB16D8424518AE27498DFBCBF79D129CA3AF38108C86266527435FC27AFA4201609B974EC1CEF0741BC478676736135E5E2BA6297C061E585CE267A99CB411505FC26A2E54209C94D6757CA9B71127B401DEB364D0A86C4C22A5A65CDD2504C57602959D2DB6E8BAC42720A76B8910D08852AE79D91F195A046D86BC3D88660ECC6BAB9CA26B765B45C6DC2571685EE8F25EEBC7B7FEE5AE00B492CF90CFC2C2348F92D2C0D4776FC611CB1F7064E40230E74302CF83A93F177A53CE7D05D5BDB
+20210515065958 2 6 100 8191 2 DD4A2D5D7B10514C9CBEB91330C309D38566FF0D418584030168693F4060DE64CC996D4F9D446AEF0F5C78E4BCFD2067A117FF78EDB5E248F494F0F6AAF718220D801EE111F50E6FD20092C3C4CFF0452384E6EF948624A85ACB5A40280F32E0C1824BF0D7215F20DC356DCF39DB382083F4CAB942564DEDA2B38211789A707CA0388E27191F3238E75B8FA352A37BA743CB80351DB5DC8F4F5CFD79C920102A838B5EE973E4F95253B43B0E327F31CBBBD7932E13C2DB0F43CCE1FB609DFE4140CA3B048CFB3C929AB9685EBFFD09F08625727583AE0E4AB61DDE47807E124D84F3FCA43FC92A7AA931FBE193CC609611FC30E873F1988D92251DF49C1E2A9126C63FA3FE19C4D9066FEC94693CBCC0951624C3F410F729F9539D35C848D924C29CF512ED032AA4B5AC4A2440197C81D5EBA6A5A9CBC11F4660FFE7597F60E6AF25944E425D724606ABFCB84878D66CE017D3ED6B07CA4FCA5B5CFA57C82FCCF1172850678F63F6F2277F242C1DACB5D16D2BC5EC611C45751A8AFC3179CEFA82334172D326B3CFCB9FB43B2E981AB6BC4033CC2E7BB57E6A19A74953E1E5E7A2E4463E3C3C950ACC5128D1DC543A6BB34C3AE3F4C33818923C1911329D5BA8D6AF1ED5915E1A1E0824CC612898AF0B0EBB553D5760AD00913D60A5649C860B3FCA1049A55BC24045298537BAA1E47B9C779FF24654889FF6162DFF3DF787E53CE4D1355AAF425B9B7CACE1C9FE076D61BD6A1887155813C7C922ABF8D161B546A94D091365D7EF693532B7CB2352F73EB8E4CB75E5771E21C2691C1AB114880E0AB104869DA6425900EF55A5B95FED252DC1D70B2473B26AEFFBCD5569F895D16B50F030B7EB2846985D185880F2B4624622F28CDD73CAEBBC318187AD69432EF31B38831E67222CCBA64DFBF0937A297E3473421506E7AA1D30DABE3841E8F58D6C6B1D0596867D80ADA9A9ADD06A1FB634DBF7B1FEF67DBABFF52538C4563B90FD343F711822EA17054A9FD1D61B9FD78CD083345E7544853B5D284CC73082C2042BFF6C2614FB1F129F7B7E2C07DFF784DCC5859A8306A33807ED27958C3FFD25F13537F869248BE6E4B3ADD9F03E5DF976D1BCEE46C30B5E79AFCF5233F3E4FE05EE6E5AA17A0E44BD67B1ED69F51F5EF287E531FA51B4FA545BC0C3EFB16D8424518AE27498DFBCBF79D129CA3AF38108C86266527435FC27AFA4201609B974EC1CEF0741BC478676736135E5E2BA6297C061E585CE267A99CB411505FC26A2E54209C94D6757CA9B71127B401DEB364D0A86C4C22A5A65CDD2504C57602959D2DB6E8BAC42720A76B8910D08852AE79D91F195A046D86BC3D88660ECC6BAB9CA26B765B45C6DC2571685EE8F25EEBC7B7FEE5AE00B492CF90CFC2C2348F92D2C0D4776FC611CB1F7064E40230E74302CF83A93F177A53CE7D190DF9B
+20210515070456 2 6 100 8191 5 DD4A2D5D7B10514C9CBEB91330C309D38566FF0D418584030168693F4060DE64CC996D4F9D446AEF0F5C78E4BCFD2067A117FF78EDB5E248F494F0F6AAF718220D801EE111F50E6FD20092C3C4CFF0452384E6EF948624A85ACB5A40280F32E0C1824BF0D7215F20DC356DCF39DB382083F4CAB942564DEDA2B38211789A707CA0388E27191F3238E75B8FA352A37BA743CB80351DB5DC8F4F5CFD79C920102A838B5EE973E4F95253B43B0E327F31CBBBD7932E13C2DB0F43CCE1FB609DFE4140CA3B048CFB3C929AB9685EBFFD09F08625727583AE0E4AB61DDE47807E124D84F3FCA43FC92A7AA931FBE193CC609611FC30E873F1988D92251DF49C1E2A9126C63FA3FE19C4D9066FEC94693CBCC0951624C3F410F729F9539D35C848D924C29CF512ED032AA4B5AC4A2440197C81D5EBA6A5A9CBC11F4660FFE7597F60E6AF25944E425D724606ABFCB84878D66CE017D3ED6B07CA4FCA5B5CFA57C82FCCF1172850678F63F6F2277F242C1DACB5D16D2BC5EC611C45751A8AFC3179CEFA82334172D326B3CFCB9FB43B2E981AB6BC4033CC2E7BB57E6A19A74953E1E5E7A2E4463E3C3C950ACC5128D1DC543A6BB34C3AE3F4C33818923C1911329D5BA8D6AF1ED5915E1A1E0824CC612898AF0B0EBB553D5760AD00913D60A5649C860B3FCA1049A55BC24045298537BAA1E47B9C779FF24654889FF6162DFF3DF787E53CE4D1355AAF425B9B7CACE1C9FE076D61BD6A1887155813C7C922ABF8D161B546A94D091365D7EF693532B7CB2352F73EB8E4CB75E5771E21C2691C1AB114880E0AB104869DA6425900EF55A5B95FED252DC1D70B2473B26AEFFBCD5569F895D16B50F030B7EB2846985D185880F2B4624622F28CDD73CAEBBC318187AD69432EF31B38831E67222CCBA64DFBF0937A297E3473421506E7AA1D30DABE3841E8F58D6C6B1D0596867D80ADA9A9ADD06A1FB634DBF7B1FEF67DBABFF52538C4563B90FD343F711822EA17054A9FD1D61B9FD78CD083345E7544853B5D284CC73082C2042BFF6C2614FB1F129F7B7E2C07DFF784DCC5859A8306A33807ED27958C3FFD25F13537F869248BE6E4B3ADD9F03E5DF976D1BCEE46C30B5E79AFCF5233F3E4FE05EE6E5AA17A0E44BD67B1ED69F51F5EF287E531FA51B4FA545BC0C3EFB16D8424518AE27498DFBCBF79D129CA3AF38108C86266527435FC27AFA4201609B974EC1CEF0741BC478676736135E5E2BA6297C061E585CE267A99CB411505FC26A2E54209C94D6757CA9B71127B401DEB364D0A86C4C22A5A65CDD2504C57602959D2DB6E8BAC42720A76B8910D08852AE79D91F195A046D86BC3D88660ECC6BAB9CA26B765B45C6DC2571685EE8F25EEBC7B7FEE5AE00B492CF90CFC2C2348F92D2C0D4776FC611CB1F7064E40230E74302CF83A93F177A53CE7D1DF4F37
+20210515073228 2 6 100 8191 2 DD4A2D5D7B10514C9CBEB91330C309D38566FF0D418584030168693F4060DE64CC996D4F9D446AEF0F5C78E4BCFD2067A117FF78EDB5E248F494F0F6AAF718220D801EE111F50E6FD20092C3C4CFF0452384E6EF948624A85ACB5A40280F32E0C1824BF0D7215F20DC356DCF39DB382083F4CAB942564DEDA2B38211789A707CA0388E27191F3238E75B8FA352A37BA743CB80351DB5DC8F4F5CFD79C920102A838B5EE973E4F95253B43B0E327F31CBBBD7932E13C2DB0F43CCE1FB609DFE4140CA3B048CFB3C929AB9685EBFFD09F08625727583AE0E4AB61DDE47807E124D84F3FCA43FC92A7AA931FBE193CC609611FC30E873F1988D92251DF49C1E2A9126C63FA3FE19C4D9066FEC94693CBCC0951624C3F410F729F9539D35C848D924C29CF512ED032AA4B5AC4A2440197C81D5EBA6A5A9CBC11F4660FFE7597F60E6AF25944E425D724606ABFCB84878D66CE017D3ED6B07CA4FCA5B5CFA57C82FCCF1172850678F63F6F2277F242C1DACB5D16D2BC5EC611C45751A8AFC3179CEFA82334172D326B3CFCB9FB43B2E981AB6BC4033CC2E7BB57E6A19A74953E1E5E7A2E4463E3C3C950ACC5128D1DC543A6BB34C3AE3F4C33818923C1911329D5BA8D6AF1ED5915E1A1E0824CC612898AF0B0EBB553D5760AD00913D60A5649C860B3FCA1049A55BC24045298537BAA1E47B9C779FF24654889FF6162DFF3DF787E53CE4D1355AAF425B9B7CACE1C9FE076D61BD6A1887155813C7C922ABF8D161B546A94D091365D7EF693532B7CB2352F73EB8E4CB75E5771E21C2691C1AB114880E0AB104869DA6425900EF55A5B95FED252DC1D70B2473B26AEFFBCD5569F895D16B50F030B7EB2846985D185880F2B4624622F28CDD73CAEBBC318187AD69432EF31B38831E67222CCBA64DFBF0937A297E3473421506E7AA1D30DABE3841E8F58D6C6B1D0596867D80ADA9A9ADD06A1FB634DBF7B1FEF67DBABFF52538C4563B90FD343F711822EA17054A9FD1D61B9FD78CD083345E7544853B5D284CC73082C2042BFF6C2614FB1F129F7B7E2C07DFF784DCC5859A8306A33807ED27958C3FFD25F13537F869248BE6E4B3ADD9F03E5DF976D1BCEE46C30B5E79AFCF5233F3E4FE05EE6E5AA17A0E44BD67B1ED69F51F5EF287E531FA51B4FA545BC0C3EFB16D8424518AE27498DFBCBF79D129CA3AF38108C86266527435FC27AFA4201609B974EC1CEF0741BC478676736135E5E2BA6297C061E585CE267A99CB411505FC26A2E54209C94D6757CA9B71127B401DEB364D0A86C4C22A5A65CDD2504C57602959D2DB6E8BAC42720A76B8910D08852AE79D91F195A046D86BC3D88660ECC6BAB9CA26B765B45C6DC2571685EE8F25EEBC7B7FEE5AE00B492CF90CFC2C2348F92D2C0D4776FC611CB1F7064E40230E74302CF83A93F177A53CE7D3BDC2E3
+20210515082306 2 6 100 8191 5 DD4A2D5D7B10514C9CBEB91330C309D38566FF0D418584030168693F4060DE64CC996D4F9D446AEF0F5C78E4BCFD2067A117FF78EDB5E248F494F0F6AAF718220D801EE111F50E6FD20092C3C4CFF0452384E6EF948624A85ACB5A40280F32E0C1824BF0D7215F20DC356DCF39DB382083F4CAB942564DEDA2B38211789A707CA0388E27191F3238E75B8FA352A37BA743CB80351DB5DC8F4F5CFD79C920102A838B5EE973E4F95253B43B0E327F31CBBBD7932E13C2DB0F43CCE1FB609DFE4140CA3B048CFB3C929AB9685EBFFD09F08625727583AE0E4AB61DDE47807E124D84F3FCA43FC92A7AA931FBE193CC609611FC30E873F1988D92251DF49C1E2A9126C63FA3FE19C4D9066FEC94693CBCC0951624C3F410F729F9539D35C848D924C29CF512ED032AA4B5AC4A2440197C81D5EBA6A5A9CBC11F4660FFE7597F60E6AF25944E425D724606ABFCB84878D66CE017D3ED6B07CA4FCA5B5CFA57C82FCCF1172850678F63F6F2277F242C1DACB5D16D2BC5EC611C45751A8AFC3179CEFA82334172D326B3CFCB9FB43B2E981AB6BC4033CC2E7BB57E6A19A74953E1E5E7A2E4463E3C3C950ACC5128D1DC543A6BB34C3AE3F4C33818923C1911329D5BA8D6AF1ED5915E1A1E0824CC612898AF0B0EBB553D5760AD00913D60A5649C860B3FCA1049A55BC24045298537BAA1E47B9C779FF24654889FF6162DFF3DF787E53CE4D1355AAF425B9B7CACE1C9FE076D61BD6A1887155813C7C922ABF8D161B546A94D091365D7EF693532B7CB2352F73EB8E4CB75E5771E21C2691C1AB114880E0AB104869DA6425900EF55A5B95FED252DC1D70B2473B26AEFFBCD5569F895D16B50F030B7EB2846985D185880F2B4624622F28CDD73CAEBBC318187AD69432EF31B38831E67222CCBA64DFBF0937A297E3473421506E7AA1D30DABE3841E8F58D6C6B1D0596867D80ADA9A9ADD06A1FB634DBF7B1FEF67DBABFF52538C4563B90FD343F711822EA17054A9FD1D61B9FD78CD083345E7544853B5D284CC73082C2042BFF6C2614FB1F129F7B7E2C07DFF784DCC5859A8306A33807ED27958C3FFD25F13537F869248BE6E4B3ADD9F03E5DF976D1BCEE46C30B5E79AFCF5233F3E4FE05EE6E5AA17A0E44BD67B1ED69F51F5EF287E531FA51B4FA545BC0C3EFB16D8424518AE27498DFBCBF79D129CA3AF38108C86266527435FC27AFA4201609B974EC1CEF0741BC478676736135E5E2BA6297C061E585CE267A99CB411505FC26A2E54209C94D6757CA9B71127B401DEB364D0A86C4C22A5A65CDD2504C57602959D2DB6E8BAC42720A76B8910D08852AE79D91F195A046D86BC3D88660ECC6BAB9CA26B765B45C6DC2571685EE8F25EEBC7B7FEE5AE00B492CF90CFC2C2348F92D2C0D4776FC611CB1F7064E40230E74302CF83A93F177A53CE7D7180387
+20210515083006 2 6 100 8191 2 DD4A2D5D7B10514C9CBEB91330C309D38566FF0D418584030168693F4060DE64CC996D4F9D446AEF0F5C78E4BCFD2067A117FF78EDB5E248F494F0F6AAF718220D801EE111F50E6FD20092C3C4CFF0452384E6EF948624A85ACB5A40280F32E0C1824BF0D7215F20DC356DCF39DB382083F4CAB942564DEDA2B38211789A707CA0388E27191F3238E75B8FA352A37BA743CB80351DB5DC8F4F5CFD79C920102A838B5EE973E4F95253B43B0E327F31CBBBD7932E13C2DB0F43CCE1FB609DFE4140CA3B048CFB3C929AB9685EBFFD09F08625727583AE0E4AB61DDE47807E124D84F3FCA43FC92A7AA931FBE193CC609611FC30E873F1988D92251DF49C1E2A9126C63FA3FE19C4D9066FEC94693CBCC0951624C3F410F729F9539D35C848D924C29CF512ED032AA4B5AC4A2440197C81D5EBA6A5A9CBC11F4660FFE7597F60E6AF25944E425D724606ABFCB84878D66CE017D3ED6B07CA4FCA5B5CFA57C82FCCF1172850678F63F6F2277F242C1DACB5D16D2BC5EC611C45751A8AFC3179CEFA82334172D326B3CFCB9FB43B2E981AB6BC4033CC2E7BB57E6A19A74953E1E5E7A2E4463E3C3C950ACC5128D1DC543A6BB34C3AE3F4C33818923C1911329D5BA8D6AF1ED5915E1A1E0824CC612898AF0B0EBB553D5760AD00913D60A5649C860B3FCA1049A55BC24045298537BAA1E47B9C779FF24654889FF6162DFF3DF787E53CE4D1355AAF425B9B7CACE1C9FE076D61BD6A1887155813C7C922ABF8D161B546A94D091365D7EF693532B7CB2352F73EB8E4CB75E5771E21C2691C1AB114880E0AB104869DA6425900EF55A5B95FED252DC1D70B2473B26AEFFBCD5569F895D16B50F030B7EB2846985D185880F2B4624622F28CDD73CAEBBC318187AD69432EF31B38831E67222CCBA64DFBF0937A297E3473421506E7AA1D30DABE3841E8F58D6C6B1D0596867D80ADA9A9ADD06A1FB634DBF7B1FEF67DBABFF52538C4563B90FD343F711822EA17054A9FD1D61B9FD78CD083345E7544853B5D284CC73082C2042BFF6C2614FB1F129F7B7E2C07DFF784DCC5859A8306A33807ED27958C3FFD25F13537F869248BE6E4B3ADD9F03E5DF976D1BCEE46C30B5E79AFCF5233F3E4FE05EE6E5AA17A0E44BD67B1ED69F51F5EF287E531FA51B4FA545BC0C3EFB16D8424518AE27498DFBCBF79D129CA3AF38108C86266527435FC27AFA4201609B974EC1CEF0741BC478676736135E5E2BA6297C061E585CE267A99CB411505FC26A2E54209C94D6757CA9B71127B401DEB364D0A86C4C22A5A65CDD2504C57602959D2DB6E8BAC42720A76B8910D08852AE79D91F195A046D86BC3D88660ECC6BAB9CA26B765B45C6DC2571685EE8F25EEBC7B7FEE5AE00B492CF90CFC2C2348F92D2C0D4776FC611CB1F7064E40230E74302CF83A93F177A53CE7D78B18B3
+20210515090500 2 6 100 8191 5 DD4A2D5D7B10514C9CBEB91330C309D38566FF0D418584030168693F4060DE64CC996D4F9D446AEF0F5C78E4BCFD2067A117FF78EDB5E248F494F0F6AAF718220D801EE111F50E6FD20092C3C4CFF0452384E6EF948624A85ACB5A40280F32E0C1824BF0D7215F20DC356DCF39DB382083F4CAB942564DEDA2B38211789A707CA0388E27191F3238E75B8FA352A37BA743CB80351DB5DC8F4F5CFD79C920102A838B5EE973E4F95253B43B0E327F31CBBBD7932E13C2DB0F43CCE1FB609DFE4140CA3B048CFB3C929AB9685EBFFD09F08625727583AE0E4AB61DDE47807E124D84F3FCA43FC92A7AA931FBE193CC609611FC30E873F1988D92251DF49C1E2A9126C63FA3FE19C4D9066FEC94693CBCC0951624C3F410F729F9539D35C848D924C29CF512ED032AA4B5AC4A2440197C81D5EBA6A5A9CBC11F4660FFE7597F60E6AF25944E425D724606ABFCB84878D66CE017D3ED6B07CA4FCA5B5CFA57C82FCCF1172850678F63F6F2277F242C1DACB5D16D2BC5EC611C45751A8AFC3179CEFA82334172D326B3CFCB9FB43B2E981AB6BC4033CC2E7BB57E6A19A74953E1E5E7A2E4463E3C3C950ACC5128D1DC543A6BB34C3AE3F4C33818923C1911329D5BA8D6AF1ED5915E1A1E0824CC612898AF0B0EBB553D5760AD00913D60A5649C860B3FCA1049A55BC24045298537BAA1E47B9C779FF24654889FF6162DFF3DF787E53CE4D1355AAF425B9B7CACE1C9FE076D61BD6A1887155813C7C922ABF8D161B546A94D091365D7EF693532B7CB2352F73EB8E4CB75E5771E21C2691C1AB114880E0AB104869DA6425900EF55A5B95FED252DC1D70B2473B26AEFFBCD5569F895D16B50F030B7EB2846985D185880F2B4624622F28CDD73CAEBBC318187AD69432EF31B38831E67222CCBA64DFBF0937A297E3473421506E7AA1D30DABE3841E8F58D6C6B1D0596867D80ADA9A9ADD06A1FB634DBF7B1FEF67DBABFF52538C4563B90FD343F711822EA17054A9FD1D61B9FD78CD083345E7544853B5D284CC73082C2042BFF6C2614FB1F129F7B7E2C07DFF784DCC5859A8306A33807ED27958C3FFD25F13537F869248BE6E4B3ADD9F03E5DF976D1BCEE46C30B5E79AFCF5233F3E4FE05EE6E5AA17A0E44BD67B1ED69F51F5EF287E531FA51B4FA545BC0C3EFB16D8424518AE27498DFBCBF79D129CA3AF38108C86266527435FC27AFA4201609B974EC1CEF0741BC478676736135E5E2BA6297C061E585CE267A99CB411505FC26A2E54209C94D6757CA9B71127B401DEB364D0A86C4C22A5A65CDD2504C57602959D2DB6E8BAC42720A76B8910D08852AE79D91F195A046D86BC3D88660ECC6BAB9CA26B765B45C6DC2571685EE8F25EEBC7B7FEE5AE00B492CF90CFC2C2348F92D2C0D4776FC611CB1F7064E40230E74302CF83A93F177A53CE7D9CF96DF
+20210515092343 2 6 100 8191 5 DD4A2D5D7B10514C9CBEB91330C309D38566FF0D418584030168693F4060DE64CC996D4F9D446AEF0F5C78E4BCFD2067A117FF78EDB5E248F494F0F6AAF718220D801EE111F50E6FD20092C3C4CFF0452384E6EF948624A85ACB5A40280F32E0C1824BF0D7215F20DC356DCF39DB382083F4CAB942564DEDA2B38211789A707CA0388E27191F3238E75B8FA352A37BA743CB80351DB5DC8F4F5CFD79C920102A838B5EE973E4F95253B43B0E327F31CBBBD7932E13C2DB0F43CCE1FB609DFE4140CA3B048CFB3C929AB9685EBFFD09F08625727583AE0E4AB61DDE47807E124D84F3FCA43FC92A7AA931FBE193CC609611FC30E873F1988D92251DF49C1E2A9126C63FA3FE19C4D9066FEC94693CBCC0951624C3F410F729F9539D35C848D924C29CF512ED032AA4B5AC4A2440197C81D5EBA6A5A9CBC11F4660FFE7597F60E6AF25944E425D724606ABFCB84878D66CE017D3ED6B07CA4FCA5B5CFA57C82FCCF1172850678F63F6F2277F242C1DACB5D16D2BC5EC611C45751A8AFC3179CEFA82334172D326B3CFCB9FB43B2E981AB6BC4033CC2E7BB57E6A19A74953E1E5E7A2E4463E3C3C950ACC5128D1DC543A6BB34C3AE3F4C33818923C1911329D5BA8D6AF1ED5915E1A1E0824CC612898AF0B0EBB553D5760AD00913D60A5649C860B3FCA1049A55BC24045298537BAA1E47B9C779FF24654889FF6162DFF3DF787E53CE4D1355AAF425B9B7CACE1C9FE076D61BD6A1887155813C7C922ABF8D161B546A94D091365D7EF693532B7CB2352F73EB8E4CB75E5771E21C2691C1AB114880E0AB104869DA6425900EF55A5B95FED252DC1D70B2473B26AEFFBCD5569F895D16B50F030B7EB2846985D185880F2B4624622F28CDD73CAEBBC318187AD69432EF31B38831E67222CCBA64DFBF0937A297E3473421506E7AA1D30DABE3841E8F58D6C6B1D0596867D80ADA9A9ADD06A1FB634DBF7B1FEF67DBABFF52538C4563B90FD343F711822EA17054A9FD1D61B9FD78CD083345E7544853B5D284CC73082C2042BFF6C2614FB1F129F7B7E2C07DFF784DCC5859A8306A33807ED27958C3FFD25F13537F869248BE6E4B3ADD9F03E5DF976D1BCEE46C30B5E79AFCF5233F3E4FE05EE6E5AA17A0E44BD67B1ED69F51F5EF287E531FA51B4FA545BC0C3EFB16D8424518AE27498DFBCBF79D129CA3AF38108C86266527435FC27AFA4201609B974EC1CEF0741BC478676736135E5E2BA6297C061E585CE267A99CB411505FC26A2E54209C94D6757CA9B71127B401DEB364D0A86C4C22A5A65CDD2504C57602959D2DB6E8BAC42720A76B8910D08852AE79D91F195A046D86BC3D88660ECC6BAB9CA26B765B45C6DC2571685EE8F25EEBC7B7FEE5AE00B492CF90CFC2C2348F92D2C0D4776FC611CB1F7064E40230E74302CF83A93F177A53CE7DB040157
+20210515100730 2 6 100 8191 2 DD4A2D5D7B10514C9CBEB91330C309D38566FF0D418584030168693F4060DE64CC996D4F9D446AEF0F5C78E4BCFD2067A117FF78EDB5E248F494F0F6AAF718220D801EE111F50E6FD20092C3C4CFF0452384E6EF948624A85ACB5A40280F32E0C1824BF0D7215F20DC356DCF39DB382083F4CAB942564DEDA2B38211789A707CA0388E27191F3238E75B8FA352A37BA743CB80351DB5DC8F4F5CFD79C920102A838B5EE973E4F95253B43B0E327F31CBBBD7932E13C2DB0F43CCE1FB609DFE4140CA3B048CFB3C929AB9685EBFFD09F08625727583AE0E4AB61DDE47807E124D84F3FCA43FC92A7AA931FBE193CC609611FC30E873F1988D92251DF49C1E2A9126C63FA3FE19C4D9066FEC94693CBCC0951624C3F410F729F9539D35C848D924C29CF512ED032AA4B5AC4A2440197C81D5EBA6A5A9CBC11F4660FFE7597F60E6AF25944E425D724606ABFCB84878D66CE017D3ED6B07CA4FCA5B5CFA57C82FCCF1172850678F63F6F2277F242C1DACB5D16D2BC5EC611C45751A8AFC3179CEFA82334172D326B3CFCB9FB43B2E981AB6BC4033CC2E7BB57E6A19A74953E1E5E7A2E4463E3C3C950ACC5128D1DC543A6BB34C3AE3F4C33818923C1911329D5BA8D6AF1ED5915E1A1E0824CC612898AF0B0EBB553D5760AD00913D60A5649C860B3FCA1049A55BC24045298537BAA1E47B9C779FF24654889FF6162DFF3DF787E53CE4D1355AAF425B9B7CACE1C9FE076D61BD6A1887155813C7C922ABF8D161B546A94D091365D7EF693532B7CB2352F73EB8E4CB75E5771E21C2691C1AB114880E0AB104869DA6425900EF55A5B95FED252DC1D70B2473B26AEFFBCD5569F895D16B50F030B7EB2846985D185880F2B4624622F28CDD73CAEBBC318187AD69432EF31B38831E67222CCBA64DFBF0937A297E3473421506E7AA1D30DABE3841E8F58D6C6B1D0596867D80ADA9A9ADD06A1FB634DBF7B1FEF67DBABFF52538C4563B90FD343F711822EA17054A9FD1D61B9FD78CD083345E7544853B5D284CC73082C2042BFF6C2614FB1F129F7B7E2C07DFF784DCC5859A8306A33807ED27958C3FFD25F13537F869248BE6E4B3ADD9F03E5DF976D1BCEE46C30B5E79AFCF5233F3E4FE05EE6E5AA17A0E44BD67B1ED69F51F5EF287E531FA51B4FA545BC0C3EFB16D8424518AE27498DFBCBF79D129CA3AF38108C86266527435FC27AFA4201609B974EC1CEF0741BC478676736135E5E2BA6297C061E585CE267A99CB411505FC26A2E54209C94D6757CA9B71127B401DEB364D0A86C4C22A5A65CDD2504C57602959D2DB6E8BAC42720A76B8910D08852AE79D91F195A046D86BC3D88660ECC6BAB9CA26B765B45C6DC2571685EE8F25EEBC7B7FEE5AE00B492CF90CFC2C2348F92D2C0D4776FC611CB1F7064E40230E74302CF83A93F177A53CE7DDEA0AE3
+20210515102122 2 6 100 8191 2 DD4A2D5D7B10514C9CBEB91330C309D38566FF0D418584030168693F4060DE64CC996D4F9D446AEF0F5C78E4BCFD2067A117FF78EDB5E248F494F0F6AAF718220D801EE111F50E6FD20092C3C4CFF0452384E6EF948624A85ACB5A40280F32E0C1824BF0D7215F20DC356DCF39DB382083F4CAB942564DEDA2B38211789A707CA0388E27191F3238E75B8FA352A37BA743CB80351DB5DC8F4F5CFD79C920102A838B5EE973E4F95253B43B0E327F31CBBBD7932E13C2DB0F43CCE1FB609DFE4140CA3B048CFB3C929AB9685EBFFD09F08625727583AE0E4AB61DDE47807E124D84F3FCA43FC92A7AA931FBE193CC609611FC30E873F1988D92251DF49C1E2A9126C63FA3FE19C4D9066FEC94693CBCC0951624C3F410F729F9539D35C848D924C29CF512ED032AA4B5AC4A2440197C81D5EBA6A5A9CBC11F4660FFE7597F60E6AF25944E425D724606ABFCB84878D66CE017D3ED6B07CA4FCA5B5CFA57C82FCCF1172850678F63F6F2277F242C1DACB5D16D2BC5EC611C45751A8AFC3179CEFA82334172D326B3CFCB9FB43B2E981AB6BC4033CC2E7BB57E6A19A74953E1E5E7A2E4463E3C3C950ACC5128D1DC543A6BB34C3AE3F4C33818923C1911329D5BA8D6AF1ED5915E1A1E0824CC612898AF0B0EBB553D5760AD00913D60A5649C860B3FCA1049A55BC24045298537BAA1E47B9C779FF24654889FF6162DFF3DF787E53CE4D1355AAF425B9B7CACE1C9FE076D61BD6A1887155813C7C922ABF8D161B546A94D091365D7EF693532B7CB2352F73EB8E4CB75E5771E21C2691C1AB114880E0AB104869DA6425900EF55A5B95FED252DC1D70B2473B26AEFFBCD5569F895D16B50F030B7EB2846985D185880F2B4624622F28CDD73CAEBBC318187AD69432EF31B38831E67222CCBA64DFBF0937A297E3473421506E7AA1D30DABE3841E8F58D6C6B1D0596867D80ADA9A9ADD06A1FB634DBF7B1FEF67DBABFF52538C4563B90FD343F711822EA17054A9FD1D61B9FD78CD083345E7544853B5D284CC73082C2042BFF6C2614FB1F129F7B7E2C07DFF784DCC5859A8306A33807ED27958C3FFD25F13537F869248BE6E4B3ADD9F03E5DF976D1BCEE46C30B5E79AFCF5233F3E4FE05EE6E5AA17A0E44BD67B1ED69F51F5EF287E531FA51B4FA545BC0C3EFB16D8424518AE27498DFBCBF79D129CA3AF38108C86266527435FC27AFA4201609B974EC1CEF0741BC478676736135E5E2BA6297C061E585CE267A99CB411505FC26A2E54209C94D6757CA9B71127B401DEB364D0A86C4C22A5A65CDD2504C57602959D2DB6E8BAC42720A76B8910D08852AE79D91F195A046D86BC3D88660ECC6BAB9CA26B765B45C6DC2571685EE8F25EEBC7B7FEE5AE00B492CF90CFC2C2348F92D2C0D4776FC611CB1F7064E40230E74302CF83A93F177A53CE7DED3CFBB
+20210515111047 2 6 100 8191 2 DD4A2D5D7B10514C9CBEB91330C309D38566FF0D418584030168693F4060DE64CC996D4F9D446AEF0F5C78E4BCFD2067A117FF78EDB5E248F494F0F6AAF718220D801EE111F50E6FD20092C3C4CFF0452384E6EF948624A85ACB5A40280F32E0C1824BF0D7215F20DC356DCF39DB382083F4CAB942564DEDA2B38211789A707CA0388E27191F3238E75B8FA352A37BA743CB80351DB5DC8F4F5CFD79C920102A838B5EE973E4F95253B43B0E327F31CBBBD7932E13C2DB0F43CCE1FB609DFE4140CA3B048CFB3C929AB9685EBFFD09F08625727583AE0E4AB61DDE47807E124D84F3FCA43FC92A7AA931FBE193CC609611FC30E873F1988D92251DF49C1E2A9126C63FA3FE19C4D9066FEC94693CBCC0951624C3F410F729F9539D35C848D924C29CF512ED032AA4B5AC4A2440197C81D5EBA6A5A9CBC11F4660FFE7597F60E6AF25944E425D724606ABFCB84878D66CE017D3ED6B07CA4FCA5B5CFA57C82FCCF1172850678F63F6F2277F242C1DACB5D16D2BC5EC611C45751A8AFC3179CEFA82334172D326B3CFCB9FB43B2E981AB6BC4033CC2E7BB57E6A19A74953E1E5E7A2E4463E3C3C950ACC5128D1DC543A6BB34C3AE3F4C33818923C1911329D5BA8D6AF1ED5915E1A1E0824CC612898AF0B0EBB553D5760AD00913D60A5649C860B3FCA1049A55BC24045298537BAA1E47B9C779FF24654889FF6162DFF3DF787E53CE4D1355AAF425B9B7CACE1C9FE076D61BD6A1887155813C7C922ABF8D161B546A94D091365D7EF693532B7CB2352F73EB8E4CB75E5771E21C2691C1AB114880E0AB104869DA6425900EF55A5B95FED252DC1D70B2473B26AEFFBCD5569F895D16B50F030B7EB2846985D185880F2B4624622F28CDD73CAEBBC318187AD69432EF31B38831E67222CCBA64DFBF0937A297E3473421506E7AA1D30DABE3841E8F58D6C6B1D0596867D80ADA9A9ADD06A1FB634DBF7B1FEF67DBABFF52538C4563B90FD343F711822EA17054A9FD1D61B9FD78CD083345E7544853B5D284CC73082C2042BFF6C2614FB1F129F7B7E2C07DFF784DCC5859A8306A33807ED27958C3FFD25F13537F869248BE6E4B3ADD9F03E5DF976D1BCEE46C30B5E79AFCF5233F3E4FE05EE6E5AA17A0E44BD67B1ED69F51F5EF287E531FA51B4FA545BC0C3EFB16D8424518AE27498DFBCBF79D129CA3AF38108C86266527435FC27AFA4201609B974EC1CEF0741BC478676736135E5E2BA6297C061E585CE267A99CB411505FC26A2E54209C94D6757CA9B71127B401DEB364D0A86C4C22A5A65CDD2504C57602959D2DB6E8BAC42720A76B8910D08852AE79D91F195A046D86BC3D88660ECC6BAB9CA26B765B45C6DC2571685EE8F25EEBC7B7FEE5AE00B492CF90CFC2C2348F92D2C0D4776FC611CB1F7064E40230E74302CF83A93F177A53CE7E218ED8B
+20210515112711 2 6 100 8191 2 DD4A2D5D7B10514C9CBEB91330C309D38566FF0D418584030168693F4060DE64CC996D4F9D446AEF0F5C78E4BCFD2067A117FF78EDB5E248F494F0F6AAF718220D801EE111F50E6FD20092C3C4CFF0452384E6EF948624A85ACB5A40280F32E0C1824BF0D7215F20DC356DCF39DB382083F4CAB942564DEDA2B38211789A707CA0388E27191F3238E75B8FA352A37BA743CB80351DB5DC8F4F5CFD79C920102A838B5EE973E4F95253B43B0E327F31CBBBD7932E13C2DB0F43CCE1FB609DFE4140CA3B048CFB3C929AB9685EBFFD09F08625727583AE0E4AB61DDE47807E124D84F3FCA43FC92A7AA931FBE193CC609611FC30E873F1988D92251DF49C1E2A9126C63FA3FE19C4D9066FEC94693CBCC0951624C3F410F729F9539D35C848D924C29CF512ED032AA4B5AC4A2440197C81D5EBA6A5A9CBC11F4660FFE7597F60E6AF25944E425D724606ABFCB84878D66CE017D3ED6B07CA4FCA5B5CFA57C82FCCF1172850678F63F6F2277F242C1DACB5D16D2BC5EC611C45751A8AFC3179CEFA82334172D326B3CFCB9FB43B2E981AB6BC4033CC2E7BB57E6A19A74953E1E5E7A2E4463E3C3C950ACC5128D1DC543A6BB34C3AE3F4C33818923C1911329D5BA8D6AF1ED5915E1A1E0824CC612898AF0B0EBB553D5760AD00913D60A5649C860B3FCA1049A55BC24045298537BAA1E47B9C779FF24654889FF6162DFF3DF787E53CE4D1355AAF425B9B7CACE1C9FE076D61BD6A1887155813C7C922ABF8D161B546A94D091365D7EF693532B7CB2352F73EB8E4CB75E5771E21C2691C1AB114880E0AB104869DA6425900EF55A5B95FED252DC1D70B2473B26AEFFBCD5569F895D16B50F030B7EB2846985D185880F2B4624622F28CDD73CAEBBC318187AD69432EF31B38831E67222CCBA64DFBF0937A297E3473421506E7AA1D30DABE3841E8F58D6C6B1D0596867D80ADA9A9ADD06A1FB634DBF7B1FEF67DBABFF52538C4563B90FD343F711822EA17054A9FD1D61B9FD78CD083345E7544853B5D284CC73082C2042BFF6C2614FB1F129F7B7E2C07DFF784DCC5859A8306A33807ED27958C3FFD25F13537F869248BE6E4B3ADD9F03E5DF976D1BCEE46C30B5E79AFCF5233F3E4FE05EE6E5AA17A0E44BD67B1ED69F51F5EF287E531FA51B4FA545BC0C3EFB16D8424518AE27498DFBCBF79D129CA3AF38108C86266527435FC27AFA4201609B974EC1CEF0741BC478676736135E5E2BA6297C061E585CE267A99CB411505FC26A2E54209C94D6757CA9B71127B401DEB364D0A86C4C22A5A65CDD2504C57602959D2DB6E8BAC42720A76B8910D08852AE79D91F195A046D86BC3D88660ECC6BAB9CA26B765B45C6DC2571685EE8F25EEBC7B7FEE5AE00B492CF90CFC2C2348F92D2C0D4776FC611CB1F7064E40230E74302CF83A93F177A53CE7E32683E3
+20210515130646 2 6 100 8191 5 DD4A2D5D7B10514C9CBEB91330C309D38566FF0D418584030168693F4060DE64CC996D4F9D446AEF0F5C78E4BCFD2067A117FF78EDB5E248F494F0F6AAF718220D801EE111F50E6FD20092C3C4CFF0452384E6EF948624A85ACB5A40280F32E0C1824BF0D7215F20DC356DCF39DB382083F4CAB942564DEDA2B38211789A707CA0388E27191F3238E75B8FA352A37BA743CB80351DB5DC8F4F5CFD79C920102A838B5EE973E4F95253B43B0E327F31CBBBD7932E13C2DB0F43CCE1FB609DFE4140CA3B048CFB3C929AB9685EBFFD09F08625727583AE0E4AB61DDE47807E124D84F3FCA43FC92A7AA931FBE193CC609611FC30E873F1988D92251DF49C1E2A9126C63FA3FE19C4D9066FEC94693CBCC0951624C3F410F729F9539D35C848D924C29CF512ED032AA4B5AC4A2440197C81D5EBA6A5A9CBC11F4660FFE7597F60E6AF25944E425D724606ABFCB84878D66CE017D3ED6B07CA4FCA5B5CFA57C82FCCF1172850678F63F6F2277F242C1DACB5D16D2BC5EC611C45751A8AFC3179CEFA82334172D326B3CFCB9FB43B2E981AB6BC4033CC2E7BB57E6A19A74953E1E5E7A2E4463E3C3C950ACC5128D1DC543A6BB34C3AE3F4C33818923C1911329D5BA8D6AF1ED5915E1A1E0824CC612898AF0B0EBB553D5760AD00913D60A5649C860B3FCA1049A55BC24045298537BAA1E47B9C779FF24654889FF6162DFF3DF787E53CE4D1355AAF425B9B7CACE1C9FE076D61BD6A1887155813C7C922ABF8D161B546A94D091365D7EF693532B7CB2352F73EB8E4CB75E5771E21C2691C1AB114880E0AB104869DA6425900EF55A5B95FED252DC1D70B2473B26AEFFBCD5569F895D16B50F030B7EB2846985D185880F2B4624622F28CDD73CAEBBC318187AD69432EF31B38831E67222CCBA64DFBF0937A297E3473421506E7AA1D30DABE3841E8F58D6C6B1D0596867D80ADA9A9ADD06A1FB634DBF7B1FEF67DBABFF52538C4563B90FD343F711822EA17054A9FD1D61B9FD78CD083345E7544853B5D284CC73082C2042BFF6C2614FB1F129F7B7E2C07DFF784DCC5859A8306A33807ED27958C3FFD25F13537F869248BE6E4B3ADD9F03E5DF976D1BCEE46C30B5E79AFCF5233F3E4FE05EE6E5AA17A0E44BD67B1ED69F51F5EF287E531FA51B4FA545BC0C3EFB16D8424518AE27498DFBCBF79D129CA3AF38108C86266527435FC27AFA4201609B974EC1CEF0741BC478676736135E5E2BA6297C061E585CE267A99CB411505FC26A2E54209C94D6757CA9B71127B401DEB364D0A86C4C22A5A65CDD2504C57602959D2DB6E8BAC42720A76B8910D08852AE79D91F195A046D86BC3D88660ECC6BAB9CA26B765B45C6DC2571685EE8F25EEBC7B7FEE5AE00B492CF90CFC2C2348F92D2C0D4776FC611CB1F7064E40230E74302CF83A93F177A53CE7E9836B47
+20210515144634 2 6 100 8191 5 DD4A2D5D7B10514C9CBEB91330C309D38566FF0D418584030168693F4060DE64CC996D4F9D446AEF0F5C78E4BCFD2067A117FF78EDB5E248F494F0F6AAF718220D801EE111F50E6FD20092C3C4CFF0452384E6EF948624A85ACB5A40280F32E0C1824BF0D7215F20DC356DCF39DB382083F4CAB942564DEDA2B38211789A707CA0388E27191F3238E75B8FA352A37BA743CB80351DB5DC8F4F5CFD79C920102A838B5EE973E4F95253B43B0E327F31CBBBD7932E13C2DB0F43CCE1FB609DFE4140CA3B048CFB3C929AB9685EBFFD09F08625727583AE0E4AB61DDE47807E124D84F3FCA43FC92A7AA931FBE193CC609611FC30E873F1988D92251DF49C1E2A9126C63FA3FE19C4D9066FEC94693CBCC0951624C3F410F729F9539D35C848D924C29CF512ED032AA4B5AC4A2440197C81D5EBA6A5A9CBC11F4660FFE7597F60E6AF25944E425D724606ABFCB84878D66CE017D3ED6B07CA4FCA5B5CFA57C82FCCF1172850678F63F6F2277F242C1DACB5D16D2BC5EC611C45751A8AFC3179CEFA82334172D326B3CFCB9FB43B2E981AB6BC4033CC2E7BB57E6A19A74953E1E5E7A2E4463E3C3C950ACC5128D1DC543A6BB34C3AE3F4C33818923C1911329D5BA8D6AF1ED5915E1A1E0824CC612898AF0B0EBB553D5760AD00913D60A5649C860B3FCA1049A55BC24045298537BAA1E47B9C779FF24654889FF6162DFF3DF787E53CE4D1355AAF425B9B7CACE1C9FE076D61BD6A1887155813C7C922ABF8D161B546A94D091365D7EF693532B7CB2352F73EB8E4CB75E5771E21C2691C1AB114880E0AB104869DA6425900EF55A5B95FED252DC1D70B2473B26AEFFBCD5569F895D16B50F030B7EB2846985D185880F2B4624622F28CDD73CAEBBC318187AD69432EF31B38831E67222CCBA64DFBF0937A297E3473421506E7AA1D30DABE3841E8F58D6C6B1D0596867D80ADA9A9ADD06A1FB634DBF7B1FEF67DBABFF52538C4563B90FD343F711822EA17054A9FD1D61B9FD78CD083345E7544853B5D284CC73082C2042BFF6C2614FB1F129F7B7E2C07DFF784DCC5859A8306A33807ED27958C3FFD25F13537F869248BE6E4B3ADD9F03E5DF976D1BCEE46C30B5E79AFCF5233F3E4FE05EE6E5AA17A0E44BD67B1ED69F51F5EF287E531FA51B4FA545BC0C3EFB16D8424518AE27498DFBCBF79D129CA3AF38108C86266527435FC27AFA4201609B974EC1CEF0741BC478676736135E5E2BA6297C061E585CE267A99CB411505FC26A2E54209C94D6757CA9B71127B401DEB364D0A86C4C22A5A65CDD2504C57602959D2DB6E8BAC42720A76B8910D08852AE79D91F195A046D86BC3D88660ECC6BAB9CA26B765B45C6DC2571685EE8F25EEBC7B7FEE5AE00B492CF90CFC2C2348F92D2C0D4776FC611CB1F7064E40230E74302CF83A93F177A53CE7EFF3474F
+20210515145430 2 6 100 8191 5 DD4A2D5D7B10514C9CBEB91330C309D38566FF0D418584030168693F4060DE64CC996D4F9D446AEF0F5C78E4BCFD2067A117FF78EDB5E248F494F0F6AAF718220D801EE111F50E6FD20092C3C4CFF0452384E6EF948624A85ACB5A40280F32E0C1824BF0D7215F20DC356DCF39DB382083F4CAB942564DEDA2B38211789A707CA0388E27191F3238E75B8FA352A37BA743CB80351DB5DC8F4F5CFD79C920102A838B5EE973E4F95253B43B0E327F31CBBBD7932E13C2DB0F43CCE1FB609DFE4140CA3B048CFB3C929AB9685EBFFD09F08625727583AE0E4AB61DDE47807E124D84F3FCA43FC92A7AA931FBE193CC609611FC30E873F1988D92251DF49C1E2A9126C63FA3FE19C4D9066FEC94693CBCC0951624C3F410F729F9539D35C848D924C29CF512ED032AA4B5AC4A2440197C81D5EBA6A5A9CBC11F4660FFE7597F60E6AF25944E425D724606ABFCB84878D66CE017D3ED6B07CA4FCA5B5CFA57C82FCCF1172850678F63F6F2277F242C1DACB5D16D2BC5EC611C45751A8AFC3179CEFA82334172D326B3CFCB9FB43B2E981AB6BC4033CC2E7BB57E6A19A74953E1E5E7A2E4463E3C3C950ACC5128D1DC543A6BB34C3AE3F4C33818923C1911329D5BA8D6AF1ED5915E1A1E0824CC612898AF0B0EBB553D5760AD00913D60A5649C860B3FCA1049A55BC24045298537BAA1E47B9C779FF24654889FF6162DFF3DF787E53CE4D1355AAF425B9B7CACE1C9FE076D61BD6A1887155813C7C922ABF8D161B546A94D091365D7EF693532B7CB2352F73EB8E4CB75E5771E21C2691C1AB114880E0AB104869DA6425900EF55A5B95FED252DC1D70B2473B26AEFFBCD5569F895D16B50F030B7EB2846985D185880F2B4624622F28CDD73CAEBBC318187AD69432EF31B38831E67222CCBA64DFBF0937A297E3473421506E7AA1D30DABE3841E8F58D6C6B1D0596867D80ADA9A9ADD06A1FB634DBF7B1FEF67DBABFF52538C4563B90FD343F711822EA17054A9FD1D61B9FD78CD083345E7544853B5D284CC73082C2042BFF6C2614FB1F129F7B7E2C07DFF784DCC5859A8306A33807ED27958C3FFD25F13537F869248BE6E4B3ADD9F03E5DF976D1BCEE46C30B5E79AFCF5233F3E4FE05EE6E5AA17A0E44BD67B1ED69F51F5EF287E531FA51B4FA545BC0C3EFB16D8424518AE27498DFBCBF79D129CA3AF38108C86266527435FC27AFA4201609B974EC1CEF0741BC478676736135E5E2BA6297C061E585CE267A99CB411505FC26A2E54209C94D6757CA9B71127B401DEB364D0A86C4C22A5A65CDD2504C57602959D2DB6E8BAC42720A76B8910D08852AE79D91F195A046D86BC3D88660ECC6BAB9CA26B765B45C6DC2571685EE8F25EEBC7B7FEE5AE00B492CF90CFC2C2348F92D2C0D4776FC611CB1F7064E40230E74302CF83A93F177A53CE7F06C080F
+20210515151337 2 6 100 8191 5 DD4A2D5D7B10514C9CBEB91330C309D38566FF0D418584030168693F4060DE64CC996D4F9D446AEF0F5C78E4BCFD2067A117FF78EDB5E248F494F0F6AAF718220D801EE111F50E6FD20092C3C4CFF0452384E6EF948624A85ACB5A40280F32E0C1824BF0D7215F20DC356DCF39DB382083F4CAB942564DEDA2B38211789A707CA0388E27191F3238E75B8FA352A37BA743CB80351DB5DC8F4F5CFD79C920102A838B5EE973E4F95253B43B0E327F31CBBBD7932E13C2DB0F43CCE1FB609DFE4140CA3B048CFB3C929AB9685EBFFD09F08625727583AE0E4AB61DDE47807E124D84F3FCA43FC92A7AA931FBE193CC609611FC30E873F1988D92251DF49C1E2A9126C63FA3FE19C4D9066FEC94693CBCC0951624C3F410F729F9539D35C848D924C29CF512ED032AA4B5AC4A2440197C81D5EBA6A5A9CBC11F4660FFE7597F60E6AF25944E425D724606ABFCB84878D66CE017D3ED6B07CA4FCA5B5CFA57C82FCCF1172850678F63F6F2277F242C1DACB5D16D2BC5EC611C45751A8AFC3179CEFA82334172D326B3CFCB9FB43B2E981AB6BC4033CC2E7BB57E6A19A74953E1E5E7A2E4463E3C3C950ACC5128D1DC543A6BB34C3AE3F4C33818923C1911329D5BA8D6AF1ED5915E1A1E0824CC612898AF0B0EBB553D5760AD00913D60A5649C860B3FCA1049A55BC24045298537BAA1E47B9C779FF24654889FF6162DFF3DF787E53CE4D1355AAF425B9B7CACE1C9FE076D61BD6A1887155813C7C922ABF8D161B546A94D091365D7EF693532B7CB2352F73EB8E4CB75E5771E21C2691C1AB114880E0AB104869DA6425900EF55A5B95FED252DC1D70B2473B26AEFFBCD5569F895D16B50F030B7EB2846985D185880F2B4624622F28CDD73CAEBBC318187AD69432EF31B38831E67222CCBA64DFBF0937A297E3473421506E7AA1D30DABE3841E8F58D6C6B1D0596867D80ADA9A9ADD06A1FB634DBF7B1FEF67DBABFF52538C4563B90FD343F711822EA17054A9FD1D61B9FD78CD083345E7544853B5D284CC73082C2042BFF6C2614FB1F129F7B7E2C07DFF784DCC5859A8306A33807ED27958C3FFD25F13537F869248BE6E4B3ADD9F03E5DF976D1BCEE46C30B5E79AFCF5233F3E4FE05EE6E5AA17A0E44BD67B1ED69F51F5EF287E531FA51B4FA545BC0C3EFB16D8424518AE27498DFBCBF79D129CA3AF38108C86266527435FC27AFA4201609B974EC1CEF0741BC478676736135E5E2BA6297C061E585CE267A99CB411505FC26A2E54209C94D6757CA9B71127B401DEB364D0A86C4C22A5A65CDD2504C57602959D2DB6E8BAC42720A76B8910D08852AE79D91F195A046D86BC3D88660ECC6BAB9CA26B765B45C6DC2571685EE8F25EEBC7B7FEE5AE00B492CF90CFC2C2348F92D2C0D4776FC611CB1F7064E40230E74302CF83A93F177A53CE7F1A0735F
+20210515155550 2 6 100 8191 2 DD4A2D5D7B10514C9CBEB91330C309D38566FF0D418584030168693F4060DE64CC996D4F9D446AEF0F5C78E4BCFD2067A117FF78EDB5E248F494F0F6AAF718220D801EE111F50E6FD20092C3C4CFF0452384E6EF948624A85ACB5A40280F32E0C1824BF0D7215F20DC356DCF39DB382083F4CAB942564DEDA2B38211789A707CA0388E27191F3238E75B8FA352A37BA743CB80351DB5DC8F4F5CFD79C920102A838B5EE973E4F95253B43B0E327F31CBBBD7932E13C2DB0F43CCE1FB609DFE4140CA3B048CFB3C929AB9685EBFFD09F08625727583AE0E4AB61DDE47807E124D84F3FCA43FC92A7AA931FBE193CC609611FC30E873F1988D92251DF49C1E2A9126C63FA3FE19C4D9066FEC94693CBCC0951624C3F410F729F9539D35C848D924C29CF512ED032AA4B5AC4A2440197C81D5EBA6A5A9CBC11F4660FFE7597F60E6AF25944E425D724606ABFCB84878D66CE017D3ED6B07CA4FCA5B5CFA57C82FCCF1172850678F63F6F2277F242C1DACB5D16D2BC5EC611C45751A8AFC3179CEFA82334172D326B3CFCB9FB43B2E981AB6BC4033CC2E7BB57E6A19A74953E1E5E7A2E4463E3C3C950ACC5128D1DC543A6BB34C3AE3F4C33818923C1911329D5BA8D6AF1ED5915E1A1E0824CC612898AF0B0EBB553D5760AD00913D60A5649C860B3FCA1049A55BC24045298537BAA1E47B9C779FF24654889FF6162DFF3DF787E53CE4D1355AAF425B9B7CACE1C9FE076D61BD6A1887155813C7C922ABF8D161B546A94D091365D7EF693532B7CB2352F73EB8E4CB75E5771E21C2691C1AB114880E0AB104869DA6425900EF55A5B95FED252DC1D70B2473B26AEFFBCD5569F895D16B50F030B7EB2846985D185880F2B4624622F28CDD73CAEBBC318187AD69432EF31B38831E67222CCBA64DFBF0937A297E3473421506E7AA1D30DABE3841E8F58D6C6B1D0596867D80ADA9A9ADD06A1FB634DBF7B1FEF67DBABFF52538C4563B90FD343F711822EA17054A9FD1D61B9FD78CD083345E7544853B5D284CC73082C2042BFF6C2614FB1F129F7B7E2C07DFF784DCC5859A8306A33807ED27958C3FFD25F13537F869248BE6E4B3ADD9F03E5DF976D1BCEE46C30B5E79AFCF5233F3E4FE05EE6E5AA17A0E44BD67B1ED69F51F5EF287E531FA51B4FA545BC0C3EFB16D8424518AE27498DFBCBF79D129CA3AF38108C86266527435FC27AFA4201609B974EC1CEF0741BC478676736135E5E2BA6297C061E585CE267A99CB411505FC26A2E54209C94D6757CA9B71127B401DEB364D0A86C4C22A5A65CDD2504C57602959D2DB6E8BAC42720A76B8910D08852AE79D91F195A046D86BC3D88660ECC6BAB9CA26B765B45C6DC2571685EE8F25EEBC7B7FEE5AE00B492CF90CFC2C2348F92D2C0D4776FC611CB1F7064E40230E74302CF83A93F177A53CE7F4535AFB
+20210515170646 2 6 100 8191 2 DD4A2D5D7B10514C9CBEB91330C309D38566FF0D418584030168693F4060DE64CC996D4F9D446AEF0F5C78E4BCFD2067A117FF78EDB5E248F494F0F6AAF718220D801EE111F50E6FD20092C3C4CFF0452384E6EF948624A85ACB5A40280F32E0C1824BF0D7215F20DC356DCF39DB382083F4CAB942564DEDA2B38211789A707CA0388E27191F3238E75B8FA352A37BA743CB80351DB5DC8F4F5CFD79C920102A838B5EE973E4F95253B43B0E327F31CBBBD7932E13C2DB0F43CCE1FB609DFE4140CA3B048CFB3C929AB9685EBFFD09F08625727583AE0E4AB61DDE47807E124D84F3FCA43FC92A7AA931FBE193CC609611FC30E873F1988D92251DF49C1E2A9126C63FA3FE19C4D9066FEC94693CBCC0951624C3F410F729F9539D35C848D924C29CF512ED032AA4B5AC4A2440197C81D5EBA6A5A9CBC11F4660FFE7597F60E6AF25944E425D724606ABFCB84878D66CE017D3ED6B07CA4FCA5B5CFA57C82FCCF1172850678F63F6F2277F242C1DACB5D16D2BC5EC611C45751A8AFC3179CEFA82334172D326B3CFCB9FB43B2E981AB6BC4033CC2E7BB57E6A19A74953E1E5E7A2E4463E3C3C950ACC5128D1DC543A6BB34C3AE3F4C33818923C1911329D5BA8D6AF1ED5915E1A1E0824CC612898AF0B0EBB553D5760AD00913D60A5649C860B3FCA1049A55BC24045298537BAA1E47B9C779FF24654889FF6162DFF3DF787E53CE4D1355AAF425B9B7CACE1C9FE076D61BD6A1887155813C7C922ABF8D161B546A94D091365D7EF693532B7CB2352F73EB8E4CB75E5771E21C2691C1AB114880E0AB104869DA6425900EF55A5B95FED252DC1D70B2473B26AEFFBCD5569F895D16B50F030B7EB2846985D185880F2B4624622F28CDD73CAEBBC318187AD69432EF31B38831E67222CCBA64DFBF0937A297E3473421506E7AA1D30DABE3841E8F58D6C6B1D0596867D80ADA9A9ADD06A1FB634DBF7B1FEF67DBABFF52538C4563B90FD343F711822EA17054A9FD1D61B9FD78CD083345E7544853B5D284CC73082C2042BFF6C2614FB1F129F7B7E2C07DFF784DCC5859A8306A33807ED27958C3FFD25F13537F869248BE6E4B3ADD9F03E5DF976D1BCEE46C30B5E79AFCF5233F3E4FE05EE6E5AA17A0E44BD67B1ED69F51F5EF287E531FA51B4FA545BC0C3EFB16D8424518AE27498DFBCBF79D129CA3AF38108C86266527435FC27AFA4201609B974EC1CEF0741BC478676736135E5E2BA6297C061E585CE267A99CB411505FC26A2E54209C94D6757CA9B71127B401DEB364D0A86C4C22A5A65CDD2504C57602959D2DB6E8BAC42720A76B8910D08852AE79D91F195A046D86BC3D88660ECC6BAB9CA26B765B45C6DC2571685EE8F25EEBC7B7FEE5AE00B492CF90CFC2C2348F92D2C0D4776FC611CB1F7064E40230E74302CF83A93F177A53CE7F8D31C5B
+20210515182201 2 6 100 8191 2 DD4A2D5D7B10514C9CBEB91330C309D38566FF0D418584030168693F4060DE64CC996D4F9D446AEF0F5C78E4BCFD2067A117FF78EDB5E248F494F0F6AAF718220D801EE111F50E6FD20092C3C4CFF0452384E6EF948624A85ACB5A40280F32E0C1824BF0D7215F20DC356DCF39DB382083F4CAB942564DEDA2B38211789A707CA0388E27191F3238E75B8FA352A37BA743CB80351DB5DC8F4F5CFD79C920102A838B5EE973E4F95253B43B0E327F31CBBBD7932E13C2DB0F43CCE1FB609DFE4140CA3B048CFB3C929AB9685EBFFD09F08625727583AE0E4AB61DDE47807E124D84F3FCA43FC92A7AA931FBE193CC609611FC30E873F1988D92251DF49C1E2A9126C63FA3FE19C4D9066FEC94693CBCC0951624C3F410F729F9539D35C848D924C29CF512ED032AA4B5AC4A2440197C81D5EBA6A5A9CBC11F4660FFE7597F60E6AF25944E425D724606ABFCB84878D66CE017D3ED6B07CA4FCA5B5CFA57C82FCCF1172850678F63F6F2277F242C1DACB5D16D2BC5EC611C45751A8AFC3179CEFA82334172D326B3CFCB9FB43B2E981AB6BC4033CC2E7BB57E6A19A74953E1E5E7A2E4463E3C3C950ACC5128D1DC543A6BB34C3AE3F4C33818923C1911329D5BA8D6AF1ED5915E1A1E0824CC612898AF0B0EBB553D5760AD00913D60A5649C860B3FCA1049A55BC24045298537BAA1E47B9C779FF24654889FF6162DFF3DF787E53CE4D1355AAF425B9B7CACE1C9FE076D61BD6A1887155813C7C922ABF8D161B546A94D091365D7EF693532B7CB2352F73EB8E4CB75E5771E21C2691C1AB114880E0AB104869DA6425900EF55A5B95FED252DC1D70B2473B26AEFFBCD5569F895D16B50F030B7EB2846985D185880F2B4624622F28CDD73CAEBBC318187AD69432EF31B38831E67222CCBA64DFBF0937A297E3473421506E7AA1D30DABE3841E8F58D6C6B1D0596867D80ADA9A9ADD06A1FB634DBF7B1FEF67DBABFF52538C4563B90FD343F711822EA17054A9FD1D61B9FD78CD083345E7544853B5D284CC73082C2042BFF6C2614FB1F129F7B7E2C07DFF784DCC5859A8306A33807ED27958C3FFD25F13537F869248BE6E4B3ADD9F03E5DF976D1BCEE46C30B5E79AFCF5233F3E4FE05EE6E5AA17A0E44BD67B1ED69F51F5EF287E531FA51B4FA545BC0C3EFB16D8424518AE27498DFBCBF79D129CA3AF38108C86266527435FC27AFA4201609B974EC1CEF0741BC478676736135E5E2BA6297C061E585CE267A99CB411505FC26A2E54209C94D6757CA9B71127B401DEB364D0A86C4C22A5A65CDD2504C57602959D2DB6E8BAC42720A76B8910D08852AE79D91F195A046D86BC3D88660ECC6BAB9CA26B765B45C6DC2571685EE8F25EEBC7B7FEE5AE00B492CF90CFC2C2348F92D2C0D4776FC611CB1F7064E40230E74302CF83A93F177A53CE7FD9B5FC3
+20210515190839 2 6 100 8191 5 DD4A2D5D7B10514C9CBEB91330C309D38566FF0D418584030168693F4060DE64CC996D4F9D446AEF0F5C78E4BCFD2067A117FF78EDB5E248F494F0F6AAF718220D801EE111F50E6FD20092C3C4CFF0452384E6EF948624A85ACB5A40280F32E0C1824BF0D7215F20DC356DCF39DB382083F4CAB942564DEDA2B38211789A707CA0388E27191F3238E75B8FA352A37BA743CB80351DB5DC8F4F5CFD79C920102A838B5EE973E4F95253B43B0E327F31CBBBD7932E13C2DB0F43CCE1FB609DFE4140CA3B048CFB3C929AB9685EBFFD09F08625727583AE0E4AB61DDE47807E124D84F3FCA43FC92A7AA931FBE193CC609611FC30E873F1988D92251DF49C1E2A9126C63FA3FE19C4D9066FEC94693CBCC0951624C3F410F729F9539D35C848D924C29CF512ED032AA4B5AC4A2440197C81D5EBA6A5A9CBC11F4660FFE7597F60E6AF25944E425D724606ABFCB84878D66CE017D3ED6B07CA4FCA5B5CFA57C82FCCF1172850678F63F6F2277F242C1DACB5D16D2BC5EC611C45751A8AFC3179CEFA82334172D326B3CFCB9FB43B2E981AB6BC4033CC2E7BB57E6A19A74953E1E5E7A2E4463E3C3C950ACC5128D1DC543A6BB34C3AE3F4C33818923C1911329D5BA8D6AF1ED5915E1A1E0824CC612898AF0B0EBB553D5760AD00913D60A5649C860B3FCA1049A55BC24045298537BAA1E47B9C779FF24654889FF6162DFF3DF787E53CE4D1355AAF425B9B7CACE1C9FE076D61BD6A1887155813C7C922ABF8D161B546A94D091365D7EF693532B7CB2352F73EB8E4CB75E5771E21C2691C1AB114880E0AB104869DA6425900EF55A5B95FED252DC1D70B2473B26AEFFBCD5569F895D16B50F030B7EB2846985D185880F2B4624622F28CDD73CAEBBC318187AD69432EF31B38831E67222CCBA64DFBF0937A297E3473421506E7AA1D30DABE3841E8F58D6C6B1D0596867D80ADA9A9ADD06A1FB634DBF7B1FEF67DBABFF52538C4563B90FD343F711822EA17054A9FD1D61B9FD78CD083345E7544853B5D284CC73082C2042BFF6C2614FB1F129F7B7E2C07DFF784DCC5859A8306A33807ED27958C3FFD25F13537F869248BE6E4B3ADD9F03E5DF976D1BCEE46C30B5E79AFCF5233F3E4FE05EE6E5AA17A0E44BD67B1ED69F51F5EF287E531FA51B4FA545BC0C3EFB16D8424518AE27498DFBCBF79D129CA3AF38108C86266527435FC27AFA4201609B974EC1CEF0741BC478676736135E5E2BA6297C061E585CE267A99CB411505FC26A2E54209C94D6757CA9B71127B401DEB364D0A86C4C22A5A65CDD2504C57602959D2DB6E8BAC42720A76B8910D08852AE79D91F195A046D86BC3D88660ECC6BAB9CA26B765B45C6DC2571685EE8F25EEBC7B7FEE5AE00B492CF90CFC2C2348F92D2C0D4776FC611CB1F7064E40230E74302CF83A93F177A53CE80086B9E7
+20210515195013 2 6 100 8191 5 DD4A2D5D7B10514C9CBEB91330C309D38566FF0D418584030168693F4060DE64CC996D4F9D446AEF0F5C78E4BCFD2067A117FF78EDB5E248F494F0F6AAF718220D801EE111F50E6FD20092C3C4CFF0452384E6EF948624A85ACB5A40280F32E0C1824BF0D7215F20DC356DCF39DB382083F4CAB942564DEDA2B38211789A707CA0388E27191F3238E75B8FA352A37BA743CB80351DB5DC8F4F5CFD79C920102A838B5EE973E4F95253B43B0E327F31CBBBD7932E13C2DB0F43CCE1FB609DFE4140CA3B048CFB3C929AB9685EBFFD09F08625727583AE0E4AB61DDE47807E124D84F3FCA43FC92A7AA931FBE193CC609611FC30E873F1988D92251DF49C1E2A9126C63FA3FE19C4D9066FEC94693CBCC0951624C3F410F729F9539D35C848D924C29CF512ED032AA4B5AC4A2440197C81D5EBA6A5A9CBC11F4660FFE7597F60E6AF25944E425D724606ABFCB84878D66CE017D3ED6B07CA4FCA5B5CFA57C82FCCF1172850678F63F6F2277F242C1DACB5D16D2BC5EC611C45751A8AFC3179CEFA82334172D326B3CFCB9FB43B2E981AB6BC4033CC2E7BB57E6A19A74953E1E5E7A2E4463E3C3C950ACC5128D1DC543A6BB34C3AE3F4C33818923C1911329D5BA8D6AF1ED5915E1A1E0824CC612898AF0B0EBB553D5760AD00913D60A5649C860B3FCA1049A55BC24045298537BAA1E47B9C779FF24654889FF6162DFF3DF787E53CE4D1355AAF425B9B7CACE1C9FE076D61BD6A1887155813C7C922ABF8D161B546A94D091365D7EF693532B7CB2352F73EB8E4CB75E5771E21C2691C1AB114880E0AB104869DA6425900EF55A5B95FED252DC1D70B2473B26AEFFBCD5569F895D16B50F030B7EB2846985D185880F2B4624622F28CDD73CAEBBC318187AD69432EF31B38831E67222CCBA64DFBF0937A297E3473421506E7AA1D30DABE3841E8F58D6C6B1D0596867D80ADA9A9ADD06A1FB634DBF7B1FEF67DBABFF52538C4563B90FD343F711822EA17054A9FD1D61B9FD78CD083345E7544853B5D284CC73082C2042BFF6C2614FB1F129F7B7E2C07DFF784DCC5859A8306A33807ED27958C3FFD25F13537F869248BE6E4B3ADD9F03E5DF976D1BCEE46C30B5E79AFCF5233F3E4FE05EE6E5AA17A0E44BD67B1ED69F51F5EF287E531FA51B4FA545BC0C3EFB16D8424518AE27498DFBCBF79D129CA3AF38108C86266527435FC27AFA4201609B974EC1CEF0741BC478676736135E5E2BA6297C061E585CE267A99CB411505FC26A2E54209C94D6757CA9B71127B401DEB364D0A86C4C22A5A65CDD2504C57602959D2DB6E8BAC42720A76B8910D08852AE79D91F195A046D86BC3D88660ECC6BAB9CA26B765B45C6DC2571685EE8F25EEBC7B7FEE5AE00B492CF90CFC2C2348F92D2C0D4776FC611CB1F7064E40230E74302CF83A93F177A53CE80312E5FF
+20210515215158 2 6 100 8191 2 DD4A2D5D7B10514C9CBEB91330C309D38566FF0D418584030168693F4060DE64CC996D4F9D446AEF0F5C78E4BCFD2067A117FF78EDB5E248F494F0F6AAF718220D801EE111F50E6FD20092C3C4CFF0452384E6EF948624A85ACB5A40280F32E0C1824BF0D7215F20DC356DCF39DB382083F4CAB942564DEDA2B38211789A707CA0388E27191F3238E75B8FA352A37BA743CB80351DB5DC8F4F5CFD79C920102A838B5EE973E4F95253B43B0E327F31CBBBD7932E13C2DB0F43CCE1FB609DFE4140CA3B048CFB3C929AB9685EBFFD09F08625727583AE0E4AB61DDE47807E124D84F3FCA43FC92A7AA931FBE193CC609611FC30E873F1988D92251DF49C1E2A9126C63FA3FE19C4D9066FEC94693CBCC0951624C3F410F729F9539D35C848D924C29CF512ED032AA4B5AC4A2440197C81D5EBA6A5A9CBC11F4660FFE7597F60E6AF25944E425D724606ABFCB84878D66CE017D3ED6B07CA4FCA5B5CFA57C82FCCF1172850678F63F6F2277F242C1DACB5D16D2BC5EC611C45751A8AFC3179CEFA82334172D326B3CFCB9FB43B2E981AB6BC4033CC2E7BB57E6A19A74953E1E5E7A2E4463E3C3C950ACC5128D1DC543A6BB34C3AE3F4C33818923C1911329D5BA8D6AF1ED5915E1A1E0824CC612898AF0B0EBB553D5760AD00913D60A5649C860B3FCA1049A55BC24045298537BAA1E47B9C779FF24654889FF6162DFF3DF787E53CE4D1355AAF425B9B7CACE1C9FE076D61BD6A1887155813C7C922ABF8D161B546A94D091365D7EF693532B7CB2352F73EB8E4CB75E5771E21C2691C1AB114880E0AB104869DA6425900EF55A5B95FED252DC1D70B2473B26AEFFBCD5569F895D16B50F030B7EB2846985D185880F2B4624622F28CDD73CAEBBC318187AD69432EF31B38831E67222CCBA64DFBF0937A297E3473421506E7AA1D30DABE3841E8F58D6C6B1D0596867D80ADA9A9ADD06A1FB634DBF7B1FEF67DBABFF52538C4563B90FD343F711822EA17054A9FD1D61B9FD78CD083345E7544853B5D284CC73082C2042BFF6C2614FB1F129F7B7E2C07DFF784DCC5859A8306A33807ED27958C3FFD25F13537F869248BE6E4B3ADD9F03E5DF976D1BCEE46C30B5E79AFCF5233F3E4FE05EE6E5AA17A0E44BD67B1ED69F51F5EF287E531FA51B4FA545BC0C3EFB16D8424518AE27498DFBCBF79D129CA3AF38108C86266527435FC27AFA4201609B974EC1CEF0741BC478676736135E5E2BA6297C061E585CE267A99CB411505FC26A2E54209C94D6757CA9B71127B401DEB364D0A86C4C22A5A65CDD2504C57602959D2DB6E8BAC42720A76B8910D08852AE79D91F195A046D86BC3D88660ECC6BAB9CA26B765B45C6DC2571685EE8F25EEBC7B7FEE5AE00B492CF90CFC2C2348F92D2C0D4776FC611CB1F7064E40230E74302CF83A93F177A53CE80ABDE71B
+20210515222330 2 6 100 8191 2 DD4A2D5D7B10514C9CBEB91330C309D38566FF0D418584030168693F4060DE64CC996D4F9D446AEF0F5C78E4BCFD2067A117FF78EDB5E248F494F0F6AAF718220D801EE111F50E6FD20092C3C4CFF0452384E6EF948624A85ACB5A40280F32E0C1824BF0D7215F20DC356DCF39DB382083F4CAB942564DEDA2B38211789A707CA0388E27191F3238E75B8FA352A37BA743CB80351DB5DC8F4F5CFD79C920102A838B5EE973E4F95253B43B0E327F31CBBBD7932E13C2DB0F43CCE1FB609DFE4140CA3B048CFB3C929AB9685EBFFD09F08625727583AE0E4AB61DDE47807E124D84F3FCA43FC92A7AA931FBE193CC609611FC30E873F1988D92251DF49C1E2A9126C63FA3FE19C4D9066FEC94693CBCC0951624C3F410F729F9539D35C848D924C29CF512ED032AA4B5AC4A2440197C81D5EBA6A5A9CBC11F4660FFE7597F60E6AF25944E425D724606ABFCB84878D66CE017D3ED6B07CA4FCA5B5CFA57C82FCCF1172850678F63F6F2277F242C1DACB5D16D2BC5EC611C45751A8AFC3179CEFA82334172D326B3CFCB9FB43B2E981AB6BC4033CC2E7BB57E6A19A74953E1E5E7A2E4463E3C3C950ACC5128D1DC543A6BB34C3AE3F4C33818923C1911329D5BA8D6AF1ED5915E1A1E0824CC612898AF0B0EBB553D5760AD00913D60A5649C860B3FCA1049A55BC24045298537BAA1E47B9C779FF24654889FF6162DFF3DF787E53CE4D1355AAF425B9B7CACE1C9FE076D61BD6A1887155813C7C922ABF8D161B546A94D091365D7EF693532B7CB2352F73EB8E4CB75E5771E21C2691C1AB114880E0AB104869DA6425900EF55A5B95FED252DC1D70B2473B26AEFFBCD5569F895D16B50F030B7EB2846985D185880F2B4624622F28CDD73CAEBBC318187AD69432EF31B38831E67222CCBA64DFBF0937A297E3473421506E7AA1D30DABE3841E8F58D6C6B1D0596867D80ADA9A9ADD06A1FB634DBF7B1FEF67DBABFF52538C4563B90FD343F711822EA17054A9FD1D61B9FD78CD083345E7544853B5D284CC73082C2042BFF6C2614FB1F129F7B7E2C07DFF784DCC5859A8306A33807ED27958C3FFD25F13537F869248BE6E4B3ADD9F03E5DF976D1BCEE46C30B5E79AFCF5233F3E4FE05EE6E5AA17A0E44BD67B1ED69F51F5EF287E531FA51B4FA545BC0C3EFB16D8424518AE27498DFBCBF79D129CA3AF38108C86266527435FC27AFA4201609B974EC1CEF0741BC478676736135E5E2BA6297C061E585CE267A99CB411505FC26A2E54209C94D6757CA9B71127B401DEB364D0A86C4C22A5A65CDD2504C57602959D2DB6E8BAC42720A76B8910D08852AE79D91F195A046D86BC3D88660ECC6BAB9CA26B765B45C6DC2571685EE8F25EEBC7B7FEE5AE00B492CF90CFC2C2348F92D2C0D4776FC611CB1F7064E40230E74302CF83A93F177A53CE80CB1A273
+20210515223057 2 6 100 8191 5 DD4A2D5D7B10514C9CBEB91330C309D38566FF0D418584030168693F4060DE64CC996D4F9D446AEF0F5C78E4BCFD2067A117FF78EDB5E248F494F0F6AAF718220D801EE111F50E6FD20092C3C4CFF0452384E6EF948624A85ACB5A40280F32E0C1824BF0D7215F20DC356DCF39DB382083F4CAB942564DEDA2B38211789A707CA0388E27191F3238E75B8FA352A37BA743CB80351DB5DC8F4F5CFD79C920102A838B5EE973E4F95253B43B0E327F31CBBBD7932E13C2DB0F43CCE1FB609DFE4140CA3B048CFB3C929AB9685EBFFD09F08625727583AE0E4AB61DDE47807E124D84F3FCA43FC92A7AA931FBE193CC609611FC30E873F1988D92251DF49C1E2A9126C63FA3FE19C4D9066FEC94693CBCC0951624C3F410F729F9539D35C848D924C29CF512ED032AA4B5AC4A2440197C81D5EBA6A5A9CBC11F4660FFE7597F60E6AF25944E425D724606ABFCB84878D66CE017D3ED6B07CA4FCA5B5CFA57C82FCCF1172850678F63F6F2277F242C1DACB5D16D2BC5EC611C45751A8AFC3179CEFA82334172D326B3CFCB9FB43B2E981AB6BC4033CC2E7BB57E6A19A74953E1E5E7A2E4463E3C3C950ACC5128D1DC543A6BB34C3AE3F4C33818923C1911329D5BA8D6AF1ED5915E1A1E0824CC612898AF0B0EBB553D5760AD00913D60A5649C860B3FCA1049A55BC24045298537BAA1E47B9C779FF24654889FF6162DFF3DF787E53CE4D1355AAF425B9B7CACE1C9FE076D61BD6A1887155813C7C922ABF8D161B546A94D091365D7EF693532B7CB2352F73EB8E4CB75E5771E21C2691C1AB114880E0AB104869DA6425900EF55A5B95FED252DC1D70B2473B26AEFFBCD5569F895D16B50F030B7EB2846985D185880F2B4624622F28CDD73CAEBBC318187AD69432EF31B38831E67222CCBA64DFBF0937A297E3473421506E7AA1D30DABE3841E8F58D6C6B1D0596867D80ADA9A9ADD06A1FB634DBF7B1FEF67DBABFF52538C4563B90FD343F711822EA17054A9FD1D61B9FD78CD083345E7544853B5D284CC73082C2042BFF6C2614FB1F129F7B7E2C07DFF784DCC5859A8306A33807ED27958C3FFD25F13537F869248BE6E4B3ADD9F03E5DF976D1BCEE46C30B5E79AFCF5233F3E4FE05EE6E5AA17A0E44BD67B1ED69F51F5EF287E531FA51B4FA545BC0C3EFB16D8424518AE27498DFBCBF79D129CA3AF38108C86266527435FC27AFA4201609B974EC1CEF0741BC478676736135E5E2BA6297C061E585CE267A99CB411505FC26A2E54209C94D6757CA9B71127B401DEB364D0A86C4C22A5A65CDD2504C57602959D2DB6E8BAC42720A76B8910D08852AE79D91F195A046D86BC3D88660ECC6BAB9CA26B765B45C6DC2571685EE8F25EEBC7B7FEE5AE00B492CF90CFC2C2348F92D2C0D4776FC611CB1F7064E40230E74302CF83A93F177A53CE80D1F22DF
+20210516000343 2 6 100 8191 2 DD4A2D5D7B10514C9CBEB91330C309D38566FF0D418584030168693F4060DE64CC996D4F9D446AEF0F5C78E4BCFD2067A117FF78EDB5E248F494F0F6AAF718220D801EE111F50E6FD20092C3C4CFF0452384E6EF948624A85ACB5A40280F32E0C1824BF0D7215F20DC356DCF39DB382083F4CAB942564DEDA2B38211789A707CA0388E27191F3238E75B8FA352A37BA743CB80351DB5DC8F4F5CFD79C920102A838B5EE973E4F95253B43B0E327F31CBBBD7932E13C2DB0F43CCE1FB609DFE4140CA3B048CFB3C929AB9685EBFFD09F08625727583AE0E4AB61DDE47807E124D84F3FCA43FC92A7AA931FBE193CC609611FC30E873F1988D92251DF49C1E2A9126C63FA3FE19C4D9066FEC94693CBCC0951624C3F410F729F9539D35C848D924C29CF512ED032AA4B5AC4A2440197C81D5EBA6A5A9CBC11F4660FFE7597F60E6AF25944E425D724606ABFCB84878D66CE017D3ED6B07CA4FCA5B5CFA57C82FCCF1172850678F63F6F2277F242C1DACB5D16D2BC5EC611C45751A8AFC3179CEFA82334172D326B3CFCB9FB43B2E981AB6BC4033CC2E7BB57E6A19A74953E1E5E7A2E4463E3C3C950ACC5128D1DC543A6BB34C3AE3F4C33818923C1911329D5BA8D6AF1ED5915E1A1E0824CC612898AF0B0EBB553D5760AD00913D60A5649C860B3FCA1049A55BC24045298537BAA1E47B9C779FF24654889FF6162DFF3DF787E53CE4D1355AAF425B9B7CACE1C9FE076D61BD6A1887155813C7C922ABF8D161B546A94D091365D7EF693532B7CB2352F73EB8E4CB75E5771E21C2691C1AB114880E0AB104869DA6425900EF55A5B95FED252DC1D70B2473B26AEFFBCD5569F895D16B50F030B7EB2846985D185880F2B4624622F28CDD73CAEBBC318187AD69432EF31B38831E67222CCBA64DFBF0937A297E3473421506E7AA1D30DABE3841E8F58D6C6B1D0596867D80ADA9A9ADD06A1FB634DBF7B1FEF67DBABFF52538C4563B90FD343F711822EA17054A9FD1D61B9FD78CD083345E7544853B5D284CC73082C2042BFF6C2614FB1F129F7B7E2C07DFF784DCC5859A8306A33807ED27958C3FFD25F13537F869248BE6E4B3ADD9F03E5DF976D1BCEE46C30B5E79AFCF5233F3E4FE05EE6E5AA17A0E44BD67B1ED69F51F5EF287E531FA51B4FA545BC0C3EFB16D8424518AE27498DFBCBF79D129CA3AF38108C86266527435FC27AFA4201609B974EC1CEF0741BC478676736135E5E2BA6297C061E585CE267A99CB411505FC26A2E54209C94D6757CA9B71127B401DEB364D0A86C4C22A5A65CDD2504C57602959D2DB6E8BAC42720A76B8910D08852AE79D91F195A046D86BC3D88660ECC6BAB9CA26B765B45C6DC2571685EE8F25EEBC7B7FEE5AE00B492CF90CFC2C2348F92D2C0D4776FC611CB1F7064E40230E74302CF83A93F177A53CE812D0CF63
+20210516001402 2 6 100 8191 5 DD4A2D5D7B10514C9CBEB91330C309D38566FF0D418584030168693F4060DE64CC996D4F9D446AEF0F5C78E4BCFD2067A117FF78EDB5E248F494F0F6AAF718220D801EE111F50E6FD20092C3C4CFF0452384E6EF948624A85ACB5A40280F32E0C1824BF0D7215F20DC356DCF39DB382083F4CAB942564DEDA2B38211789A707CA0388E27191F3238E75B8FA352A37BA743CB80351DB5DC8F4F5CFD79C920102A838B5EE973E4F95253B43B0E327F31CBBBD7932E13C2DB0F43CCE1FB609DFE4140CA3B048CFB3C929AB9685EBFFD09F08625727583AE0E4AB61DDE47807E124D84F3FCA43FC92A7AA931FBE193CC609611FC30E873F1988D92251DF49C1E2A9126C63FA3FE19C4D9066FEC94693CBCC0951624C3F410F729F9539D35C848D924C29CF512ED032AA4B5AC4A2440197C81D5EBA6A5A9CBC11F4660FFE7597F60E6AF25944E425D724606ABFCB84878D66CE017D3ED6B07CA4FCA5B5CFA57C82FCCF1172850678F63F6F2277F242C1DACB5D16D2BC5EC611C45751A8AFC3179CEFA82334172D326B3CFCB9FB43B2E981AB6BC4033CC2E7BB57E6A19A74953E1E5E7A2E4463E3C3C950ACC5128D1DC543A6BB34C3AE3F4C33818923C1911329D5BA8D6AF1ED5915E1A1E0824CC612898AF0B0EBB553D5760AD00913D60A5649C860B3FCA1049A55BC24045298537BAA1E47B9C779FF24654889FF6162DFF3DF787E53CE4D1355AAF425B9B7CACE1C9FE076D61BD6A1887155813C7C922ABF8D161B546A94D091365D7EF693532B7CB2352F73EB8E4CB75E5771E21C2691C1AB114880E0AB104869DA6425900EF55A5B95FED252DC1D70B2473B26AEFFBCD5569F895D16B50F030B7EB2846985D185880F2B4624622F28CDD73CAEBBC318187AD69432EF31B38831E67222CCBA64DFBF0937A297E3473421506E7AA1D30DABE3841E8F58D6C6B1D0596867D80ADA9A9ADD06A1FB634DBF7B1FEF67DBABFF52538C4563B90FD343F711822EA17054A9FD1D61B9FD78CD083345E7544853B5D284CC73082C2042BFF6C2614FB1F129F7B7E2C07DFF784DCC5859A8306A33807ED27958C3FFD25F13537F869248BE6E4B3ADD9F03E5DF976D1BCEE46C30B5E79AFCF5233F3E4FE05EE6E5AA17A0E44BD67B1ED69F51F5EF287E531FA51B4FA545BC0C3EFB16D8424518AE27498DFBCBF79D129CA3AF38108C86266527435FC27AFA4201609B974EC1CEF0741BC478676736135E5E2BA6297C061E585CE267A99CB411505FC26A2E54209C94D6757CA9B71127B401DEB364D0A86C4C22A5A65CDD2504C57602959D2DB6E8BAC42720A76B8910D08852AE79D91F195A046D86BC3D88660ECC6BAB9CA26B765B45C6DC2571685EE8F25EEBC7B7FEE5AE00B492CF90CFC2C2348F92D2C0D4776FC611CB1F7064E40230E74302CF83A93F177A53CE813696F87
+20210516033418 2 6 100 8191 2 DD4A2D5D7B10514C9CBEB91330C309D38566FF0D418584030168693F4060DE64CC996D4F9D446AEF0F5C78E4BCFD2067A117FF78EDB5E248F494F0F6AAF718220D801EE111F50E6FD20092C3C4CFF0452384E6EF948624A85ACB5A40280F32E0C1824BF0D7215F20DC356DCF39DB382083F4CAB942564DEDA2B38211789A707CA0388E27191F3238E75B8FA352A37BA743CB80351DB5DC8F4F5CFD79C920102A838B5EE973E4F95253B43B0E327F31CBBBD7932E13C2DB0F43CCE1FB609DFE4140CA3B048CFB3C929AB9685EBFFD09F08625727583AE0E4AB61DDE47807E124D84F3FCA43FC92A7AA931FBE193CC609611FC30E873F1988D92251DF49C1E2A9126C63FA3FE19C4D9066FEC94693CBCC0951624C3F410F729F9539D35C848D924C29CF512ED032AA4B5AC4A2440197C81D5EBA6A5A9CBC11F4660FFE7597F60E6AF25944E425D724606ABFCB84878D66CE017D3ED6B07CA4FCA5B5CFA57C82FCCF1172850678F63F6F2277F242C1DACB5D16D2BC5EC611C45751A8AFC3179CEFA82334172D326B3CFCB9FB43B2E981AB6BC4033CC2E7BB57E6A19A74953E1E5E7A2E4463E3C3C950ACC5128D1DC543A6BB34C3AE3F4C33818923C1911329D5BA8D6AF1ED5915E1A1E0824CC612898AF0B0EBB553D5760AD00913D60A5649C860B3FCA1049A55BC24045298537BAA1E47B9C779FF24654889FF6162DFF3DF787E53CE4D1355AAF425B9B7CACE1C9FE076D61BD6A1887155813C7C922ABF8D161B546A94D091365D7EF693532B7CB2352F73EB8E4CB75E5771E21C2691C1AB114880E0AB104869DA6425900EF55A5B95FED252DC1D70B2473B26AEFFBCD5569F895D16B50F030B7EB2846985D185880F2B4624622F28CDD73CAEBBC318187AD69432EF31B38831E67222CCBA64DFBF0937A297E3473421506E7AA1D30DABE3841E8F58D6C6B1D0596867D80ADA9A9ADD06A1FB634DBF7B1FEF67DBABFF52538C4563B90FD343F711822EA17054A9FD1D61B9FD78CD083345E7544853B5D284CC73082C2042BFF6C2614FB1F129F7B7E2C07DFF784DCC5859A8306A33807ED27958C3FFD25F13537F869248BE6E4B3ADD9F03E5DF976D1BCEE46C30B5E79AFCF5233F3E4FE05EE6E5AA17A0E44BD67B1ED69F51F5EF287E531FA51B4FA545BC0C3EFB16D8424518AE27498DFBCBF79D129CA3AF38108C86266527435FC27AFA4201609B974EC1CEF0741BC478676736135E5E2BA6297C061E585CE267A99CB411505FC26A2E54209C94D6757CA9B71127B401DEB364D0A86C4C22A5A65CDD2504C57602959D2DB6E8BAC42720A76B8910D08852AE79D91F195A046D86BC3D88660ECC6BAB9CA26B765B45C6DC2571685EE8F25EEBC7B7FEE5AE00B492CF90CFC2C2348F92D2C0D4776FC611CB1F7064E40230E74302CF83A93F177A53CE81F94FB1B
+20210516034751 2 6 100 8191 2 DD4A2D5D7B10514C9CBEB91330C309D38566FF0D418584030168693F4060DE64CC996D4F9D446AEF0F5C78E4BCFD2067A117FF78EDB5E248F494F0F6AAF718220D801EE111F50E6FD20092C3C4CFF0452384E6EF948624A85ACB5A40280F32E0C1824BF0D7215F20DC356DCF39DB382083F4CAB942564DEDA2B38211789A707CA0388E27191F3238E75B8FA352A37BA743CB80351DB5DC8F4F5CFD79C920102A838B5EE973E4F95253B43B0E327F31CBBBD7932E13C2DB0F43CCE1FB609DFE4140CA3B048CFB3C929AB9685EBFFD09F08625727583AE0E4AB61DDE47807E124D84F3FCA43FC92A7AA931FBE193CC609611FC30E873F1988D92251DF49C1E2A9126C63FA3FE19C4D9066FEC94693CBCC0951624C3F410F729F9539D35C848D924C29CF512ED032AA4B5AC4A2440197C81D5EBA6A5A9CBC11F4660FFE7597F60E6AF25944E425D724606ABFCB84878D66CE017D3ED6B07CA4FCA5B5CFA57C82FCCF1172850678F63F6F2277F242C1DACB5D16D2BC5EC611C45751A8AFC3179CEFA82334172D326B3CFCB9FB43B2E981AB6BC4033CC2E7BB57E6A19A74953E1E5E7A2E4463E3C3C950ACC5128D1DC543A6BB34C3AE3F4C33818923C1911329D5BA8D6AF1ED5915E1A1E0824CC612898AF0B0EBB553D5760AD00913D60A5649C860B3FCA1049A55BC24045298537BAA1E47B9C779FF24654889FF6162DFF3DF787E53CE4D1355AAF425B9B7CACE1C9FE076D61BD6A1887155813C7C922ABF8D161B546A94D091365D7EF693532B7CB2352F73EB8E4CB75E5771E21C2691C1AB114880E0AB104869DA6425900EF55A5B95FED252DC1D70B2473B26AEFFBCD5569F895D16B50F030B7EB2846985D185880F2B4624622F28CDD73CAEBBC318187AD69432EF31B38831E67222CCBA64DFBF0937A297E3473421506E7AA1D30DABE3841E8F58D6C6B1D0596867D80ADA9A9ADD06A1FB634DBF7B1FEF67DBABFF52538C4563B90FD343F711822EA17054A9FD1D61B9FD78CD083345E7544853B5D284CC73082C2042BFF6C2614FB1F129F7B7E2C07DFF784DCC5859A8306A33807ED27958C3FFD25F13537F869248BE6E4B3ADD9F03E5DF976D1BCEE46C30B5E79AFCF5233F3E4FE05EE6E5AA17A0E44BD67B1ED69F51F5EF287E531FA51B4FA545BC0C3EFB16D8424518AE27498DFBCBF79D129CA3AF38108C86266527435FC27AFA4201609B974EC1CEF0741BC478676736135E5E2BA6297C061E585CE267A99CB411505FC26A2E54209C94D6757CA9B71127B401DEB364D0A86C4C22A5A65CDD2504C57602959D2DB6E8BAC42720A76B8910D08852AE79D91F195A046D86BC3D88660ECC6BAB9CA26B765B45C6DC2571685EE8F25EEBC7B7FEE5AE00B492CF90CFC2C2348F92D2C0D4776FC611CB1F7064E40230E74302CF83A93F177A53CE820609413
+20210516043347 2 6 100 8191 2 DD4A2D5D7B10514C9CBEB91330C309D38566FF0D418584030168693F4060DE64CC996D4F9D446AEF0F5C78E4BCFD2067A117FF78EDB5E248F494F0F6AAF718220D801EE111F50E6FD20092C3C4CFF0452384E6EF948624A85ACB5A40280F32E0C1824BF0D7215F20DC356DCF39DB382083F4CAB942564DEDA2B38211789A707CA0388E27191F3238E75B8FA352A37BA743CB80351DB5DC8F4F5CFD79C920102A838B5EE973E4F95253B43B0E327F31CBBBD7932E13C2DB0F43CCE1FB609DFE4140CA3B048CFB3C929AB9685EBFFD09F08625727583AE0E4AB61DDE47807E124D84F3FCA43FC92A7AA931FBE193CC609611FC30E873F1988D92251DF49C1E2A9126C63FA3FE19C4D9066FEC94693CBCC0951624C3F410F729F9539D35C848D924C29CF512ED032AA4B5AC4A2440197C81D5EBA6A5A9CBC11F4660FFE7597F60E6AF25944E425D724606ABFCB84878D66CE017D3ED6B07CA4FCA5B5CFA57C82FCCF1172850678F63F6F2277F242C1DACB5D16D2BC5EC611C45751A8AFC3179CEFA82334172D326B3CFCB9FB43B2E981AB6BC4033CC2E7BB57E6A19A74953E1E5E7A2E4463E3C3C950ACC5128D1DC543A6BB34C3AE3F4C33818923C1911329D5BA8D6AF1ED5915E1A1E0824CC612898AF0B0EBB553D5760AD00913D60A5649C860B3FCA1049A55BC24045298537BAA1E47B9C779FF24654889FF6162DFF3DF787E53CE4D1355AAF425B9B7CACE1C9FE076D61BD6A1887155813C7C922ABF8D161B546A94D091365D7EF693532B7CB2352F73EB8E4CB75E5771E21C2691C1AB114880E0AB104869DA6425900EF55A5B95FED252DC1D70B2473B26AEFFBCD5569F895D16B50F030B7EB2846985D185880F2B4624622F28CDD73CAEBBC318187AD69432EF31B38831E67222CCBA64DFBF0937A297E3473421506E7AA1D30DABE3841E8F58D6C6B1D0596867D80ADA9A9ADD06A1FB634DBF7B1FEF67DBABFF52538C4563B90FD343F711822EA17054A9FD1D61B9FD78CD083345E7544853B5D284CC73082C2042BFF6C2614FB1F129F7B7E2C07DFF784DCC5859A8306A33807ED27958C3FFD25F13537F869248BE6E4B3ADD9F03E5DF976D1BCEE46C30B5E79AFCF5233F3E4FE05EE6E5AA17A0E44BD67B1ED69F51F5EF287E531FA51B4FA545BC0C3EFB16D8424518AE27498DFBCBF79D129CA3AF38108C86266527435FC27AFA4201609B974EC1CEF0741BC478676736135E5E2BA6297C061E585CE267A99CB411505FC26A2E54209C94D6757CA9B71127B401DEB364D0A86C4C22A5A65CDD2504C57602959D2DB6E8BAC42720A76B8910D08852AE79D91F195A046D86BC3D88660ECC6BAB9CA26B765B45C6DC2571685EE8F25EEBC7B7FEE5AE00B492CF90CFC2C2348F92D2C0D4776FC611CB1F7064E40230E74302CF83A93F177A53CE8232145B3
+20210516043651 2 6 100 8191 5 DD4A2D5D7B10514C9CBEB91330C309D38566FF0D418584030168693F4060DE64CC996D4F9D446AEF0F5C78E4BCFD2067A117FF78EDB5E248F494F0F6AAF718220D801EE111F50E6FD20092C3C4CFF0452384E6EF948624A85ACB5A40280F32E0C1824BF0D7215F20DC356DCF39DB382083F4CAB942564DEDA2B38211789A707CA0388E27191F3238E75B8FA352A37BA743CB80351DB5DC8F4F5CFD79C920102A838B5EE973E4F95253B43B0E327F31CBBBD7932E13C2DB0F43CCE1FB609DFE4140CA3B048CFB3C929AB9685EBFFD09F08625727583AE0E4AB61DDE47807E124D84F3FCA43FC92A7AA931FBE193CC609611FC30E873F1988D92251DF49C1E2A9126C63FA3FE19C4D9066FEC94693CBCC0951624C3F410F729F9539D35C848D924C29CF512ED032AA4B5AC4A2440197C81D5EBA6A5A9CBC11F4660FFE7597F60E6AF25944E425D724606ABFCB84878D66CE017D3ED6B07CA4FCA5B5CFA57C82FCCF1172850678F63F6F2277F242C1DACB5D16D2BC5EC611C45751A8AFC3179CEFA82334172D326B3CFCB9FB43B2E981AB6BC4033CC2E7BB57E6A19A74953E1E5E7A2E4463E3C3C950ACC5128D1DC543A6BB34C3AE3F4C33818923C1911329D5BA8D6AF1ED5915E1A1E0824CC612898AF0B0EBB553D5760AD00913D60A5649C860B3FCA1049A55BC24045298537BAA1E47B9C779FF24654889FF6162DFF3DF787E53CE4D1355AAF425B9B7CACE1C9FE076D61BD6A1887155813C7C922ABF8D161B546A94D091365D7EF693532B7CB2352F73EB8E4CB75E5771E21C2691C1AB114880E0AB104869DA6425900EF55A5B95FED252DC1D70B2473B26AEFFBCD5569F895D16B50F030B7EB2846985D185880F2B4624622F28CDD73CAEBBC318187AD69432EF31B38831E67222CCBA64DFBF0937A297E3473421506E7AA1D30DABE3841E8F58D6C6B1D0596867D80ADA9A9ADD06A1FB634DBF7B1FEF67DBABFF52538C4563B90FD343F711822EA17054A9FD1D61B9FD78CD083345E7544853B5D284CC73082C2042BFF6C2614FB1F129F7B7E2C07DFF784DCC5859A8306A33807ED27958C3FFD25F13537F869248BE6E4B3ADD9F03E5DF976D1BCEE46C30B5E79AFCF5233F3E4FE05EE6E5AA17A0E44BD67B1ED69F51F5EF287E531FA51B4FA545BC0C3EFB16D8424518AE27498DFBCBF79D129CA3AF38108C86266527435FC27AFA4201609B974EC1CEF0741BC478676736135E5E2BA6297C061E585CE267A99CB411505FC26A2E54209C94D6757CA9B71127B401DEB364D0A86C4C22A5A65CDD2504C57602959D2DB6E8BAC42720A76B8910D08852AE79D91F195A046D86BC3D88660ECC6BAB9CA26B765B45C6DC2571685EE8F25EEBC7B7FEE5AE00B492CF90CFC2C2348F92D2C0D4776FC611CB1F7064E40230E74302CF83A93F177A53CE82348D01F
+20210516052501 2 6 100 8191 5 DD4A2D5D7B10514C9CBEB91330C309D38566FF0D418584030168693F4060DE64CC996D4F9D446AEF0F5C78E4BCFD2067A117FF78EDB5E248F494F0F6AAF718220D801EE111F50E6FD20092C3C4CFF0452384E6EF948624A85ACB5A40280F32E0C1824BF0D7215F20DC356DCF39DB382083F4CAB942564DEDA2B38211789A707CA0388E27191F3238E75B8FA352A37BA743CB80351DB5DC8F4F5CFD79C920102A838B5EE973E4F95253B43B0E327F31CBBBD7932E13C2DB0F43CCE1FB609DFE4140CA3B048CFB3C929AB9685EBFFD09F08625727583AE0E4AB61DDE47807E124D84F3FCA43FC92A7AA931FBE193CC609611FC30E873F1988D92251DF49C1E2A9126C63FA3FE19C4D9066FEC94693CBCC0951624C3F410F729F9539D35C848D924C29CF512ED032AA4B5AC4A2440197C81D5EBA6A5A9CBC11F4660FFE7597F60E6AF25944E425D724606ABFCB84878D66CE017D3ED6B07CA4FCA5B5CFA57C82FCCF1172850678F63F6F2277F242C1DACB5D16D2BC5EC611C45751A8AFC3179CEFA82334172D326B3CFCB9FB43B2E981AB6BC4033CC2E7BB57E6A19A74953E1E5E7A2E4463E3C3C950ACC5128D1DC543A6BB34C3AE3F4C33818923C1911329D5BA8D6AF1ED5915E1A1E0824CC612898AF0B0EBB553D5760AD00913D60A5649C860B3FCA1049A55BC24045298537BAA1E47B9C779FF24654889FF6162DFF3DF787E53CE4D1355AAF425B9B7CACE1C9FE076D61BD6A1887155813C7C922ABF8D161B546A94D091365D7EF693532B7CB2352F73EB8E4CB75E5771E21C2691C1AB114880E0AB104869DA6425900EF55A5B95FED252DC1D70B2473B26AEFFBCD5569F895D16B50F030B7EB2846985D185880F2B4624622F28CDD73CAEBBC318187AD69432EF31B38831E67222CCBA64DFBF0937A297E3473421506E7AA1D30DABE3841E8F58D6C6B1D0596867D80ADA9A9ADD06A1FB634DBF7B1FEF67DBABFF52538C4563B90FD343F711822EA17054A9FD1D61B9FD78CD083345E7544853B5D284CC73082C2042BFF6C2614FB1F129F7B7E2C07DFF784DCC5859A8306A33807ED27958C3FFD25F13537F869248BE6E4B3ADD9F03E5DF976D1BCEE46C30B5E79AFCF5233F3E4FE05EE6E5AA17A0E44BD67B1ED69F51F5EF287E531FA51B4FA545BC0C3EFB16D8424518AE27498DFBCBF79D129CA3AF38108C86266527435FC27AFA4201609B974EC1CEF0741BC478676736135E5E2BA6297C061E585CE267A99CB411505FC26A2E54209C94D6757CA9B71127B401DEB364D0A86C4C22A5A65CDD2504C57602959D2DB6E8BAC42720A76B8910D08852AE79D91F195A046D86BC3D88660ECC6BAB9CA26B765B45C6DC2571685EE8F25EEBC7B7FEE5AE00B492CF90CFC2C2348F92D2C0D4776FC611CB1F7064E40230E74302CF83A93F177A53CE8262E1FE7
+20210516061031 2 6 100 8191 2 DD4A2D5D7B10514C9CBEB91330C309D38566FF0D418584030168693F4060DE64CC996D4F9D446AEF0F5C78E4BCFD2067A117FF78EDB5E248F494F0F6AAF718220D801EE111F50E6FD20092C3C4CFF0452384E6EF948624A85ACB5A40280F32E0C1824BF0D7215F20DC356DCF39DB382083F4CAB942564DEDA2B38211789A707CA0388E27191F3238E75B8FA352A37BA743CB80351DB5DC8F4F5CFD79C920102A838B5EE973E4F95253B43B0E327F31CBBBD7932E13C2DB0F43CCE1FB609DFE4140CA3B048CFB3C929AB9685EBFFD09F08625727583AE0E4AB61DDE47807E124D84F3FCA43FC92A7AA931FBE193CC609611FC30E873F1988D92251DF49C1E2A9126C63FA3FE19C4D9066FEC94693CBCC0951624C3F410F729F9539D35C848D924C29CF512ED032AA4B5AC4A2440197C81D5EBA6A5A9CBC11F4660FFE7597F60E6AF25944E425D724606ABFCB84878D66CE017D3ED6B07CA4FCA5B5CFA57C82FCCF1172850678F63F6F2277F242C1DACB5D16D2BC5EC611C45751A8AFC3179CEFA82334172D326B3CFCB9FB43B2E981AB6BC4033CC2E7BB57E6A19A74953E1E5E7A2E4463E3C3C950ACC5128D1DC543A6BB34C3AE3F4C33818923C1911329D5BA8D6AF1ED5915E1A1E0824CC612898AF0B0EBB553D5760AD00913D60A5649C860B3FCA1049A55BC24045298537BAA1E47B9C779FF24654889FF6162DFF3DF787E53CE4D1355AAF425B9B7CACE1C9FE076D61BD6A1887155813C7C922ABF8D161B546A94D091365D7EF693532B7CB2352F73EB8E4CB75E5771E21C2691C1AB114880E0AB104869DA6425900EF55A5B95FED252DC1D70B2473B26AEFFBCD5569F895D16B50F030B7EB2846985D185880F2B4624622F28CDD73CAEBBC318187AD69432EF31B38831E67222CCBA64DFBF0937A297E3473421506E7AA1D30DABE3841E8F58D6C6B1D0596867D80ADA9A9ADD06A1FB634DBF7B1FEF67DBABFF52538C4563B90FD343F711822EA17054A9FD1D61B9FD78CD083345E7544853B5D284CC73082C2042BFF6C2614FB1F129F7B7E2C07DFF784DCC5859A8306A33807ED27958C3FFD25F13537F869248BE6E4B3ADD9F03E5DF976D1BCEE46C30B5E79AFCF5233F3E4FE05EE6E5AA17A0E44BD67B1ED69F51F5EF287E531FA51B4FA545BC0C3EFB16D8424518AE27498DFBCBF79D129CA3AF38108C86266527435FC27AFA4201609B974EC1CEF0741BC478676736135E5E2BA6297C061E585CE267A99CB411505FC26A2E54209C94D6757CA9B71127B401DEB364D0A86C4C22A5A65CDD2504C57602959D2DB6E8BAC42720A76B8910D08852AE79D91F195A046D86BC3D88660ECC6BAB9CA26B765B45C6DC2571685EE8F25EEBC7B7FEE5AE00B492CF90CFC2C2348F92D2C0D4776FC611CB1F7064E40230E74302CF83A93F177A53CE828E7F28B
+20210516070338 2 6 100 8191 2 DD4A2D5D7B10514C9CBEB91330C309D38566FF0D418584030168693F4060DE64CC996D4F9D446AEF0F5C78E4BCFD2067A117FF78EDB5E248F494F0F6AAF718220D801EE111F50E6FD20092C3C4CFF0452384E6EF948624A85ACB5A40280F32E0C1824BF0D7215F20DC356DCF39DB382083F4CAB942564DEDA2B38211789A707CA0388E27191F3238E75B8FA352A37BA743CB80351DB5DC8F4F5CFD79C920102A838B5EE973E4F95253B43B0E327F31CBBBD7932E13C2DB0F43CCE1FB609DFE4140CA3B048CFB3C929AB9685EBFFD09F08625727583AE0E4AB61DDE47807E124D84F3FCA43FC92A7AA931FBE193CC609611FC30E873F1988D92251DF49C1E2A9126C63FA3FE19C4D9066FEC94693CBCC0951624C3F410F729F9539D35C848D924C29CF512ED032AA4B5AC4A2440197C81D5EBA6A5A9CBC11F4660FFE7597F60E6AF25944E425D724606ABFCB84878D66CE017D3ED6B07CA4FCA5B5CFA57C82FCCF1172850678F63F6F2277F242C1DACB5D16D2BC5EC611C45751A8AFC3179CEFA82334172D326B3CFCB9FB43B2E981AB6BC4033CC2E7BB57E6A19A74953E1E5E7A2E4463E3C3C950ACC5128D1DC543A6BB34C3AE3F4C33818923C1911329D5BA8D6AF1ED5915E1A1E0824CC612898AF0B0EBB553D5760AD00913D60A5649C860B3FCA1049A55BC24045298537BAA1E47B9C779FF24654889FF6162DFF3DF787E53CE4D1355AAF425B9B7CACE1C9FE076D61BD6A1887155813C7C922ABF8D161B546A94D091365D7EF693532B7CB2352F73EB8E4CB75E5771E21C2691C1AB114880E0AB104869DA6425900EF55A5B95FED252DC1D70B2473B26AEFFBCD5569F895D16B50F030B7EB2846985D185880F2B4624622F28CDD73CAEBBC318187AD69432EF31B38831E67222CCBA64DFBF0937A297E3473421506E7AA1D30DABE3841E8F58D6C6B1D0596867D80ADA9A9ADD06A1FB634DBF7B1FEF67DBABFF52538C4563B90FD343F711822EA17054A9FD1D61B9FD78CD083345E7544853B5D284CC73082C2042BFF6C2614FB1F129F7B7E2C07DFF784DCC5859A8306A33807ED27958C3FFD25F13537F869248BE6E4B3ADD9F03E5DF976D1BCEE46C30B5E79AFCF5233F3E4FE05EE6E5AA17A0E44BD67B1ED69F51F5EF287E531FA51B4FA545BC0C3EFB16D8424518AE27498DFBCBF79D129CA3AF38108C86266527435FC27AFA4201609B974EC1CEF0741BC478676736135E5E2BA6297C061E585CE267A99CB411505FC26A2E54209C94D6757CA9B71127B401DEB364D0A86C4C22A5A65CDD2504C57602959D2DB6E8BAC42720A76B8910D08852AE79D91F195A046D86BC3D88660ECC6BAB9CA26B765B45C6DC2571685EE8F25EEBC7B7FEE5AE00B492CF90CFC2C2348F92D2C0D4776FC611CB1F7064E40230E74302CF83A93F177A53CE82C2463FB
diff --git a/crypto/openssh/moduli.c b/crypto/openssh/moduli.c
index 233cba8e881a..8dd36b1cf231 100644
--- a/crypto/openssh/moduli.c
+++ b/crypto/openssh/moduli.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: moduli.c,v 1.32 2017/12/08 03:45:52 deraadt Exp $ */
+/* $OpenBSD: moduli.c,v 1.37 2019/11/15 06:00:20 djm Exp $ */
/*
* Copyright 1994 Phil Karn <karn@qualcomm.com>
* Copyright 1996-1998, 2003 William Allen Simpson <wsimpson@greendragon.com>
@@ -159,6 +159,8 @@ qfileout(FILE * ofile, u_int32_t otype, u_int32_t otests, u_int32_t otries,
time(&time_now);
gtm = gmtime(&time_now);
+ if (gtm == NULL)
+ return -1;
res = fprintf(ofile, "%04d%02d%02d%02d%02d%02d %u %u %u %u %x ",
gtm->tm_year + 1900, gtm->tm_mon + 1, gtm->tm_mday,
@@ -453,7 +455,7 @@ write_checkpoint(char *cpfile, u_int32_t lineno)
int r;
r = snprintf(tmp, sizeof(tmp), "%s.XXXXXXXXXX", cpfile);
- if (r == -1 || r >= PATH_MAX) {
+ if (r < 0 || r >= PATH_MAX) {
logit("write_checkpoint: temp pathname too long");
return;
}
@@ -576,13 +578,12 @@ prime_test(FILE *in, FILE *out, u_int32_t trials, u_int32_t generator_wanted,
char *checkpoint_file, unsigned long start_lineno, unsigned long num_lines)
{
BIGNUM *q, *p, *a;
- BN_CTX *ctx;
char *cp, *lp;
u_int32_t count_in = 0, count_out = 0, count_possible = 0;
u_int32_t generator_known, in_tests, in_tries, in_type, in_size;
unsigned long last_processed = 0, end_lineno;
time_t time_start, time_stop;
- int res;
+ int res, is_prime;
if (trials < TRIAL_MINIMUM) {
error("Minimum primality trials is %d", TRIAL_MINIMUM);
@@ -600,8 +601,6 @@ prime_test(FILE *in, FILE *out, u_int32_t trials, u_int32_t generator_wanted,
fatal("BN_new failed");
if ((q = BN_new()) == NULL)
fatal("BN_new failed");
- if ((ctx = BN_CTX_new()) == NULL)
- fatal("BN_CTX_new failed");
debug2("%.24s Final %u Miller-Rabin trials (%x generator)",
ctime(&time_start), trials, generator_wanted);
@@ -716,8 +715,6 @@ prime_test(FILE *in, FILE *out, u_int32_t trials, u_int32_t generator_wanted,
if (generator_known == 0) {
if (BN_mod_word(p, 24) == 11)
generator_known = 2;
- else if (BN_mod_word(p, 12) == 5)
- generator_known = 3;
else {
u_int32_t r = BN_mod_word(p, 10);
@@ -753,7 +750,10 @@ prime_test(FILE *in, FILE *out, u_int32_t trials, u_int32_t generator_wanted,
* that p is also prime. A single pass will weed out the
* vast majority of composite q's.
*/
- if (BN_is_prime_ex(q, 1, ctx, NULL) <= 0) {
+ is_prime = BN_is_prime_ex(q, 1, NULL, NULL);
+ if (is_prime < 0)
+ fatal("BN_is_prime_ex failed");
+ if (is_prime == 0) {
debug("%10u: q failed first possible prime test",
count_in);
continue;
@@ -766,14 +766,20 @@ prime_test(FILE *in, FILE *out, u_int32_t trials, u_int32_t generator_wanted,
* will show up on the first Rabin-Miller iteration so it
* doesn't hurt to specify a high iteration count.
*/
- if (!BN_is_prime_ex(p, trials, ctx, NULL)) {
+ is_prime = BN_is_prime_ex(p, trials, NULL, NULL);
+ if (is_prime < 0)
+ fatal("BN_is_prime_ex failed");
+ if (is_prime == 0) {
debug("%10u: p is not prime", count_in);
continue;
}
debug("%10u: p is almost certainly prime", count_in);
/* recheck q more rigorously */
- if (!BN_is_prime_ex(q, trials - 1, ctx, NULL)) {
+ is_prime = BN_is_prime_ex(q, trials - 1, NULL, NULL);
+ if (is_prime < 0)
+ fatal("BN_is_prime_ex failed");
+ if (is_prime == 0) {
debug("%10u: q is not prime", count_in);
continue;
}
@@ -793,7 +799,6 @@ prime_test(FILE *in, FILE *out, u_int32_t trials, u_int32_t generator_wanted,
free(lp);
BN_free(p);
BN_free(q);
- BN_CTX_free(ctx);
if (checkpoint_file != NULL)
unlink(checkpoint_file);
diff --git a/crypto/openssh/monitor.c b/crypto/openssh/monitor.c
index 531b2993ab6b..74c803e15ad3 100644
--- a/crypto/openssh/monitor.c
+++ b/crypto/openssh/monitor.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: monitor.c,v 1.186 2018/07/20 03:46:34 djm Exp $ */
+/* $OpenBSD: monitor.c,v 1.228 2021/08/11 05:20:17 djm Exp $ */
/*
* Copyright 2002 Niels Provos <provos@citi.umich.edu>
* Copyright 2002 Markus Friedl <markus@openbsd.org>
@@ -40,7 +40,7 @@
#include <pwd.h>
#include <signal.h>
#ifdef HAVE_STDINT_H
-#include <stdint.h>
+# include <stdint.h>
#endif
#include <stdlib.h>
#include <string.h>
@@ -95,6 +95,7 @@
#include "authfd.h"
#include "match.h"
#include "ssherr.h"
+#include "sk-api.h"
#ifdef GSSAPI
static Gssctxt *gsscontext = NULL;
@@ -103,7 +104,6 @@ static Gssctxt *gsscontext = NULL;
/* Imports */
extern ServerOptions options;
extern u_int utmp_len;
-extern u_char session_id[];
extern struct sshbuf *loginmsg;
extern struct sshauthopt *auth_opts; /* XXX move to permanent ssh->authctxt? */
@@ -112,54 +112,52 @@ static struct sshbuf *child_state;
/* Functions on the monitor that answer unprivileged requests */
-int mm_answer_moduli(int, struct sshbuf *);
-int mm_answer_sign(int, struct sshbuf *);
-int mm_answer_pwnamallow(int, struct sshbuf *);
-int mm_answer_auth2_read_banner(int, struct sshbuf *);
-int mm_answer_authserv(int, struct sshbuf *);
-int mm_answer_authpassword(int, struct sshbuf *);
-int mm_answer_bsdauthquery(int, struct sshbuf *);
-int mm_answer_bsdauthrespond(int, struct sshbuf *);
-int mm_answer_keyallowed(int, struct sshbuf *);
-int mm_answer_keyverify(int, struct sshbuf *);
-int mm_answer_pty(int, struct sshbuf *);
-int mm_answer_pty_cleanup(int, struct sshbuf *);
-int mm_answer_term(int, struct sshbuf *);
-int mm_answer_rsa_keyallowed(int, struct sshbuf *);
-int mm_answer_rsa_challenge(int, struct sshbuf *);
-int mm_answer_rsa_response(int, struct sshbuf *);
-int mm_answer_sesskey(int, struct sshbuf *);
-int mm_answer_sessid(int, struct sshbuf *);
+int mm_answer_moduli(struct ssh *, int, struct sshbuf *);
+int mm_answer_sign(struct ssh *, int, struct sshbuf *);
+int mm_answer_pwnamallow(struct ssh *, int, struct sshbuf *);
+int mm_answer_auth2_read_banner(struct ssh *, int, struct sshbuf *);
+int mm_answer_authserv(struct ssh *, int, struct sshbuf *);
+int mm_answer_authpassword(struct ssh *, int, struct sshbuf *);
+int mm_answer_bsdauthquery(struct ssh *, int, struct sshbuf *);
+int mm_answer_bsdauthrespond(struct ssh *, int, struct sshbuf *);
+int mm_answer_keyallowed(struct ssh *, int, struct sshbuf *);
+int mm_answer_keyverify(struct ssh *, int, struct sshbuf *);
+int mm_answer_pty(struct ssh *, int, struct sshbuf *);
+int mm_answer_pty_cleanup(struct ssh *, int, struct sshbuf *);
+int mm_answer_term(struct ssh *, int, struct sshbuf *);
+int mm_answer_rsa_keyallowed(struct ssh *, int, struct sshbuf *);
+int mm_answer_rsa_challenge(struct ssh *, int, struct sshbuf *);
+int mm_answer_rsa_response(struct ssh *, int, struct sshbuf *);
+int mm_answer_sesskey(struct ssh *, int, struct sshbuf *);
+int mm_answer_sessid(struct ssh *, int, struct sshbuf *);
#ifdef USE_PAM
-int mm_answer_pam_start(int, struct sshbuf *);
-int mm_answer_pam_account(int, struct sshbuf *);
-int mm_answer_pam_init_ctx(int, struct sshbuf *);
-int mm_answer_pam_query(int, struct sshbuf *);
-int mm_answer_pam_respond(int, struct sshbuf *);
-int mm_answer_pam_free_ctx(int, struct sshbuf *);
+int mm_answer_pam_start(struct ssh *, int, struct sshbuf *);
+int mm_answer_pam_account(struct ssh *, int, struct sshbuf *);
+int mm_answer_pam_init_ctx(struct ssh *, int, struct sshbuf *);
+int mm_answer_pam_query(struct ssh *, int, struct sshbuf *);
+int mm_answer_pam_respond(struct ssh *, int, struct sshbuf *);
+int mm_answer_pam_free_ctx(struct ssh *, int, struct sshbuf *);
#endif
#ifdef GSSAPI
-int mm_answer_gss_setup_ctx(int, struct sshbuf *);
-int mm_answer_gss_accept_ctx(int, struct sshbuf *);
-int mm_answer_gss_userok(int, struct sshbuf *);
-int mm_answer_gss_checkmic(int, struct sshbuf *);
+int mm_answer_gss_setup_ctx(struct ssh *, int, struct sshbuf *);
+int mm_answer_gss_accept_ctx(struct ssh *, int, struct sshbuf *);
+int mm_answer_gss_userok(struct ssh *, int, struct sshbuf *);
+int mm_answer_gss_checkmic(struct ssh *, int, struct sshbuf *);
#endif
#ifdef SSH_AUDIT_EVENTS
-int mm_answer_audit_event(int, struct sshbuf *);
-int mm_answer_audit_command(int, struct sshbuf *);
+int mm_answer_audit_event(struct ssh *, int, struct sshbuf *);
+int mm_answer_audit_command(struct ssh *, int, struct sshbuf *);
#endif
-static int monitor_read_log(struct monitor *);
-
static Authctxt *authctxt;
/* local state for key verify */
static u_char *key_blob = NULL;
static size_t key_bloblen = 0;
-static int key_blobtype = MM_NOKEY;
+static u_int key_blobtype = MM_NOKEY;
static struct sshauthopt *key_opts = NULL;
static char *hostbased_cuser = NULL;
static char *hostbased_chost = NULL;
@@ -172,7 +170,7 @@ static pid_t monitor_child_pid;
struct mon_table {
enum monitor_reqtype type;
int flags;
- int (*f)(int, struct sshbuf *);
+ int (*f)(struct ssh *, int, struct sshbuf *);
};
#define MON_ISAUTH 0x0004 /* Required for Authentication */
@@ -184,6 +182,10 @@ struct mon_table {
#define MON_PERMIT 0x1000 /* Request is permitted */
+static int monitor_read(struct ssh *, struct monitor *, struct mon_table *,
+ struct mon_table **);
+static int monitor_read_log(struct monitor *);
+
struct mon_table mon_dispatch_proto20[] = {
#ifdef WITH_OPENSSL
{MONITOR_REQ_MODULI, MON_ONCE, mm_answer_moduli},
@@ -265,9 +267,8 @@ monitor_permit_authentications(int permit)
}
void
-monitor_child_preauth(Authctxt *_authctxt, struct monitor *pmonitor)
+monitor_child_preauth(struct ssh *ssh, struct monitor *pmonitor)
{
- struct ssh *ssh = active_state; /* XXX */
struct mon_table *ent;
int authenticated = 0, partial = 0;
@@ -279,7 +280,7 @@ monitor_child_preauth(Authctxt *_authctxt, struct monitor *pmonitor)
close(pmonitor->m_log_sendfd);
pmonitor->m_log_sendfd = pmonitor->m_recvfd = -1;
- authctxt = _authctxt;
+ authctxt = (Authctxt *)ssh->authctxt;
memset(authctxt, 0, sizeof(*authctxt));
ssh->authctxt = authctxt;
@@ -297,15 +298,15 @@ monitor_child_preauth(Authctxt *_authctxt, struct monitor *pmonitor)
auth_submethod = NULL;
auth2_authctxt_reset_info(authctxt);
- authenticated = (monitor_read(pmonitor, mon_dispatch, &ent) == 1);
+ authenticated = (monitor_read(ssh, pmonitor,
+ mon_dispatch, &ent) == 1);
/* Special handling for multiple required authentications */
if (options.num_auth_methods != 0) {
if (authenticated &&
!auth2_update_methods_lists(authctxt,
auth_method, auth_submethod)) {
- debug3("%s: method %s: partial", __func__,
- auth_method);
+ debug3_f("method %s: partial", auth_method);
authenticated = 0;
partial = 1;
}
@@ -313,8 +314,8 @@ monitor_child_preauth(Authctxt *_authctxt, struct monitor *pmonitor)
if (authenticated) {
if (!(ent->flags & MON_AUTHDECIDE))
- fatal("%s: unexpected authentication from %d",
- __func__, ent->type);
+ fatal_f("unexpected authentication from %d",
+ ent->type);
if (authctxt->pw->pw_uid == 0 &&
!auth_root_allowed(ssh, auth_method))
authenticated = 0;
@@ -329,13 +330,13 @@ monitor_child_preauth(Authctxt *_authctxt, struct monitor *pmonitor)
mm_request_receive_expect(pmonitor->m_sendfd,
MONITOR_REQ_PAM_ACCOUNT, m);
authenticated = mm_answer_pam_account(
- pmonitor->m_sendfd, m);
+ ssh, pmonitor->m_sendfd, m);
sshbuf_free(m);
}
#endif
}
if (ent->flags & (MON_AUTHDECIDE|MON_ALOG)) {
- auth_log(authctxt, authenticated, partial,
+ auth_log(ssh, authenticated, partial,
auth_method, auth_submethod);
if (!partial && !authenticated)
authctxt->failures++;
@@ -347,16 +348,15 @@ monitor_child_preauth(Authctxt *_authctxt, struct monitor *pmonitor)
}
if (!authctxt->valid)
- fatal("%s: authenticated invalid user", __func__);
+ fatal_f("authenticated invalid user");
if (strcmp(auth_method, "unknown") == 0)
- fatal("%s: authentication method name unknown", __func__);
+ fatal_f("authentication method name unknown");
- debug("%s: %s has been authenticated by privileged process",
- __func__, authctxt->user);
+ debug_f("user %s authenticated by privileged process", authctxt->user);
ssh->authctxt = NULL;
ssh_packet_set_log_preamble(ssh, "user %s", authctxt->user);
- mm_get_keystate(pmonitor);
+ mm_get_keystate(ssh, pmonitor);
/* Drain any buffered messages from the child */
while (pmonitor->m_log_recvfd != -1 && monitor_read_log(pmonitor) == 0)
@@ -382,17 +382,17 @@ monitor_child_handler(int sig)
}
void
-monitor_child_postauth(struct monitor *pmonitor)
+monitor_child_postauth(struct ssh *ssh, struct monitor *pmonitor)
{
close(pmonitor->m_recvfd);
pmonitor->m_recvfd = -1;
monitor_set_child_handler(pmonitor->m_pid);
- signal(SIGHUP, &monitor_child_handler);
- signal(SIGTERM, &monitor_child_handler);
- signal(SIGINT, &monitor_child_handler);
+ ssh_signal(SIGHUP, &monitor_child_handler);
+ ssh_signal(SIGTERM, &monitor_child_handler);
+ ssh_signal(SIGINT, &monitor_child_handler);
#ifdef SIGXFSZ
- signal(SIGXFSZ, SIG_IGN);
+ ssh_signal(SIGXFSZ, SIG_IGN);
#endif
mon_dispatch = mon_dispatch_postauth20;
@@ -408,54 +408,54 @@ monitor_child_postauth(struct monitor *pmonitor)
}
for (;;)
- monitor_read(pmonitor, mon_dispatch, NULL);
+ monitor_read(ssh, pmonitor, mon_dispatch, NULL);
}
static int
monitor_read_log(struct monitor *pmonitor)
{
struct sshbuf *logmsg;
- u_int len, level;
+ u_int len, level, forced;
char *msg;
u_char *p;
int r;
if ((logmsg = sshbuf_new()) == NULL)
- fatal("%s: sshbuf_new", __func__);
+ fatal_f("sshbuf_new");
/* Read length */
if ((r = sshbuf_reserve(logmsg, 4, &p)) != 0)
- fatal("%s: reserve: %s", __func__, ssh_err(r));
+ fatal_fr(r, "reserve len");
if (atomicio(read, pmonitor->m_log_recvfd, p, 4) != 4) {
if (errno == EPIPE) {
sshbuf_free(logmsg);
- debug("%s: child log fd closed", __func__);
+ debug_f("child log fd closed");
close(pmonitor->m_log_recvfd);
pmonitor->m_log_recvfd = -1;
return -1;
}
- fatal("%s: log fd read: %s", __func__, strerror(errno));
+ fatal_f("log fd read: %s", strerror(errno));
}
if ((r = sshbuf_get_u32(logmsg, &len)) != 0)
- fatal("%s: get len: %s", __func__, ssh_err(r));
+ fatal_fr(r, "parse len");
if (len <= 4 || len > 8192)
- fatal("%s: invalid log message length %u", __func__, len);
+ fatal_f("invalid log message length %u", len);
/* Read severity, message */
sshbuf_reset(logmsg);
if ((r = sshbuf_reserve(logmsg, len, &p)) != 0)
- fatal("%s: reserve: %s", __func__, ssh_err(r));
+ fatal_fr(r, "reserve msg");
if (atomicio(read, pmonitor->m_log_recvfd, p, len) != len)
- fatal("%s: log fd read: %s", __func__, strerror(errno));
+ fatal_f("log fd read: %s", strerror(errno));
if ((r = sshbuf_get_u32(logmsg, &level)) != 0 ||
+ (r = sshbuf_get_u32(logmsg, &forced)) != 0 ||
(r = sshbuf_get_cstring(logmsg, &msg, NULL)) != 0)
- fatal("%s: decode: %s", __func__, ssh_err(r));
+ fatal_fr(r, "parse");
/* Log it */
if (log_level_name(level) == NULL)
- fatal("%s: invalid log level %u (corrupted message?)",
- __func__, level);
- do_log2(level, "%s [preauth]", msg);
+ fatal_f("invalid log level %u (corrupted message?)", level);
+ sshlogdirect(level, forced, "%s [preauth]", msg);
sshbuf_free(logmsg);
free(msg);
@@ -463,8 +463,8 @@ monitor_read_log(struct monitor *pmonitor)
return 0;
}
-int
-monitor_read(struct monitor *pmonitor, struct mon_table *ent,
+static int
+monitor_read(struct ssh *ssh, struct monitor *pmonitor, struct mon_table *ent,
struct mon_table **pent)
{
struct sshbuf *m;
@@ -481,7 +481,7 @@ monitor_read(struct monitor *pmonitor, struct mon_table *ent,
if (poll(pfd, pfd[1].fd == -1 ? 1 : 2, -1) == -1) {
if (errno == EINTR || errno == EAGAIN)
continue;
- fatal("%s: poll: %s", __func__, strerror(errno));
+ fatal_f("poll: %s", strerror(errno));
}
if (pfd[1].revents) {
/*
@@ -496,13 +496,13 @@ monitor_read(struct monitor *pmonitor, struct mon_table *ent,
}
if ((m = sshbuf_new()) == NULL)
- fatal("%s: sshbuf_new", __func__);
+ fatal_f("sshbuf_new");
mm_request_receive(pmonitor->m_sendfd, m);
if ((r = sshbuf_get_u8(m, &type)) != 0)
- fatal("%s: decode: %s", __func__, ssh_err(r));
+ fatal_fr(r, "parse type");
- debug3("%s: checking request %d", __func__, type);
+ debug3_f("checking request %d", type);
while (ent->f != NULL) {
if (ent->type == type)
@@ -512,15 +512,13 @@ monitor_read(struct monitor *pmonitor, struct mon_table *ent,
if (ent->f != NULL) {
if (!(ent->flags & MON_PERMIT))
- fatal("%s: unpermitted request %d", __func__,
- type);
- ret = (*ent->f)(pmonitor->m_sendfd, m);
+ fatal_f("unpermitted request %d", type);
+ ret = (*ent->f)(ssh, pmonitor->m_sendfd, m);
sshbuf_free(m);
/* The child may use this request only once, disable it */
if (ent->flags & MON_ONCE) {
- debug2("%s: %d used once, disabling now", __func__,
- type);
+ debug2_f("%d used once, disabling now", type);
ent->flags &= ~MON_PERMIT;
}
@@ -530,7 +528,7 @@ monitor_read(struct monitor *pmonitor, struct mon_table *ent,
return ret;
}
- fatal("%s: unsupported request: %d", __func__, type);
+ fatal_f("unsupported request: %d", type);
/* NOTREACHED */
return (-1);
@@ -538,7 +536,7 @@ monitor_read(struct monitor *pmonitor, struct mon_table *ent,
/* allowed key state */
static int
-monitor_allowed_key(u_char *blob, u_int bloblen)
+monitor_allowed_key(const u_char *blob, u_int bloblen)
{
/* make sure key is allowed */
if (key_blob == NULL || key_bloblen != bloblen ||
@@ -565,7 +563,7 @@ monitor_reset_key_state(void)
#ifdef WITH_OPENSSL
int
-mm_answer_moduli(int sock, struct sshbuf *m)
+mm_answer_moduli(struct ssh *ssh, int sock, struct sshbuf *m)
{
DH *dh;
const BIGNUM *dh_p, *dh_g;
@@ -575,21 +573,19 @@ mm_answer_moduli(int sock, struct sshbuf *m)
if ((r = sshbuf_get_u32(m, &min)) != 0 ||
(r = sshbuf_get_u32(m, &want)) != 0 ||
(r = sshbuf_get_u32(m, &max)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "parse");
- debug3("%s: got parameters: %d %d %d",
- __func__, min, want, max);
+ debug3_f("got parameters: %d %d %d", min, want, max);
/* We need to check here, too, in case the child got corrupted */
if (max < min || want < min || max < want)
- fatal("%s: bad parameters: %d %d %d",
- __func__, min, want, max);
+ fatal_f("bad parameters: %d %d %d", min, want, max);
sshbuf_reset(m);
dh = choose_dh(min, want, max);
if (dh == NULL) {
if ((r = sshbuf_put_u8(m, 0)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "assemble empty");
return (0);
} else {
/* Send first bignum */
@@ -597,7 +593,7 @@ mm_answer_moduli(int sock, struct sshbuf *m)
if ((r = sshbuf_put_u8(m, 1)) != 0 ||
(r = sshbuf_put_bignum2(m, dh_p)) != 0 ||
(r = sshbuf_put_bignum2(m, dh_g)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "assemble");
DH_free(dh);
}
@@ -607,9 +603,8 @@ mm_answer_moduli(int sock, struct sshbuf *m)
#endif
int
-mm_answer_sign(int sock, struct sshbuf *m)
+mm_answer_sign(struct ssh *ssh, int sock, struct sshbuf *m)
{
- struct ssh *ssh = active_state; /* XXX */
extern int auth_sock; /* XXX move to state struct? */
struct sshkey *key;
struct sshbuf *sigbuf = NULL;
@@ -620,15 +615,15 @@ mm_answer_sign(int sock, struct sshbuf *m)
u_int keyid, compat;
const char proof_req[] = "hostkeys-prove-00@openssh.com";
- debug3("%s", __func__);
+ debug3_f("entering");
if ((r = sshbuf_get_u32(m, &keyid)) != 0 ||
(r = sshbuf_get_string(m, &p, &datlen)) != 0 ||
(r = sshbuf_get_cstring(m, &alg, &alglen)) != 0 ||
(r = sshbuf_get_u32(m, &compat)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "parse");
if (keyid > INT_MAX)
- fatal("%s: invalid key ID", __func__);
+ fatal_f("invalid key ID");
/*
* Supported KEX types use SHA1 (20 bytes), SHA256 (32 bytes),
@@ -647,21 +642,20 @@ mm_answer_sign(int sock, struct sshbuf *m)
* the client sent us.
*/
if (session_id2_len == 0) /* hostkeys is never first */
- fatal("%s: bad data length: %zu", __func__, datlen);
+ fatal_f("bad data length: %zu", datlen);
if ((key = get_hostkey_public_by_index(keyid, ssh)) == NULL)
- fatal("%s: no hostkey for index %d", __func__, keyid);
+ fatal_f("no hostkey for index %d", keyid);
if ((sigbuf = sshbuf_new()) == NULL)
- fatal("%s: sshbuf_new", __func__);
+ fatal_f("sshbuf_new");
if ((r = sshbuf_put_cstring(sigbuf, proof_req)) != 0 ||
(r = sshbuf_put_string(sigbuf, session_id2,
session_id2_len)) != 0 ||
(r = sshkey_puts(key, sigbuf)) != 0)
- fatal("%s: couldn't prepare private key "
- "proof buffer: %s", __func__, ssh_err(r));
+ fatal_fr(r, "assemble private key proof");
if (datlen != sshbuf_len(sigbuf) ||
memcmp(p, sshbuf_ptr(sigbuf), sshbuf_len(sigbuf)) != 0)
- fatal("%s: bad data length: %zu, hostkey proof len %zu",
- __func__, datlen, sshbuf_len(sigbuf));
+ fatal_f("bad data length: %zu, hostkey proof len %zu",
+ datlen, sshbuf_len(sigbuf));
sshbuf_free(sigbuf);
is_proof = 1;
}
@@ -675,25 +669,22 @@ mm_answer_sign(int sock, struct sshbuf *m)
if ((key = get_hostkey_by_index(keyid)) != NULL) {
if ((r = sshkey_sign(key, &signature, &siglen, p, datlen, alg,
- compat)) != 0)
- fatal("%s: sshkey_sign failed: %s",
- __func__, ssh_err(r));
+ options.sk_provider, NULL, compat)) != 0)
+ fatal_fr(r, "sign");
} else if ((key = get_hostkey_public_by_index(keyid, ssh)) != NULL &&
auth_sock > 0) {
if ((r = ssh_agent_sign(auth_sock, key, &signature, &siglen,
- p, datlen, alg, compat)) != 0) {
- fatal("%s: ssh_agent_sign failed: %s",
- __func__, ssh_err(r));
- }
+ p, datlen, alg, compat)) != 0)
+ fatal_fr(r, "agent sign");
} else
- fatal("%s: no hostkey from index %d", __func__, keyid);
+ fatal_f("no hostkey from index %d", keyid);
- debug3("%s: %s signature %p(%zu)", __func__,
- is_proof ? "KEX" : "hostkey proof", signature, siglen);
+ debug3_f("%s %s signature len=%zu", alg,
+ is_proof ? "hostkey proof" : "KEX", siglen);
sshbuf_reset(m);
if ((r = sshbuf_put_string(m, signature, siglen)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "assemble");
free(alg);
free(p);
@@ -707,26 +698,31 @@ mm_answer_sign(int sock, struct sshbuf *m)
return (0);
}
-/* Retrieves the password entry and also checks if the user is permitted */
+#define PUTPW(b, id) \
+ do { \
+ if ((r = sshbuf_put_string(b, \
+ &pwent->id, sizeof(pwent->id))) != 0) \
+ fatal_fr(r, "assemble %s", #id); \
+ } while (0)
+/* Retrieves the password entry and also checks if the user is permitted */
int
-mm_answer_pwnamallow(int sock, struct sshbuf *m)
+mm_answer_pwnamallow(struct ssh *ssh, int sock, struct sshbuf *m)
{
- struct ssh *ssh = active_state; /* XXX */
char *username;
struct passwd *pwent;
int r, allowed = 0;
u_int i;
- debug3("%s", __func__);
+ debug3_f("entering");
if (authctxt->attempt++ != 0)
- fatal("%s: multiple attempts for getpwnam", __func__);
+ fatal_f("multiple attempts for getpwnam");
if ((r = sshbuf_get_cstring(m, &username, NULL)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "parse");
- pwent = getpwnamallow(username);
+ pwent = getpwnamallow(ssh, username);
authctxt->user = xstrdup(username);
setproctitle("%s [priv]", pwent ? username : "unknown");
@@ -736,7 +732,7 @@ mm_answer_pwnamallow(int sock, struct sshbuf *m)
if (pwent == NULL) {
if ((r = sshbuf_put_u8(m, 0)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "assemble fakepw");
authctxt->pw = fakepw();
goto out;
}
@@ -745,10 +741,18 @@ mm_answer_pwnamallow(int sock, struct sshbuf *m)
authctxt->pw = pwent;
authctxt->valid = 1;
- /* XXX don't sent pwent to unpriv; send fake class/dir/shell too */
- if ((r = sshbuf_put_u8(m, 1)) != 0 ||
- (r = sshbuf_put_string(m, pwent, sizeof(*pwent))) != 0 ||
- (r = sshbuf_put_cstring(m, pwent->pw_name)) != 0 ||
+ /* XXX send fake class/dir/shell, etc. */
+ if ((r = sshbuf_put_u8(m, 1)) != 0)
+ fatal_fr(r, "assemble ok");
+ PUTPW(m, pw_uid);
+ PUTPW(m, pw_gid);
+#ifdef HAVE_STRUCT_PASSWD_PW_CHANGE
+ PUTPW(m, pw_change);
+#endif
+#ifdef HAVE_STRUCT_PASSWD_PW_EXPIRE
+ PUTPW(m, pw_expire);
+#endif
+ if ((r = sshbuf_put_cstring(m, pwent->pw_name)) != 0 ||
(r = sshbuf_put_cstring(m, "*")) != 0 ||
#ifdef HAVE_STRUCT_PASSWD_PW_GECOS
(r = sshbuf_put_cstring(m, pwent->pw_gecos)) != 0 ||
@@ -758,26 +762,23 @@ mm_answer_pwnamallow(int sock, struct sshbuf *m)
#endif
(r = sshbuf_put_cstring(m, pwent->pw_dir)) != 0 ||
(r = sshbuf_put_cstring(m, pwent->pw_shell)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "assemble pw");
out:
ssh_packet_set_log_preamble(ssh, "%suser %s",
authctxt->valid ? "authenticating" : "invalid ", authctxt->user);
if ((r = sshbuf_put_string(m, &options, sizeof(options))) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "assemble options");
#define M_CP_STROPT(x) do { \
- if (options.x != NULL) { \
- if ((r = sshbuf_put_cstring(m, options.x)) != 0) \
- fatal("%s: buffer error: %s", \
- __func__, ssh_err(r)); \
- } \
+ if (options.x != NULL && \
+ (r = sshbuf_put_cstring(m, options.x)) != 0) \
+ fatal_fr(r, "assemble %s", #x); \
} while (0)
#define M_CP_STRARRAYOPT(x, nx) do { \
for (i = 0; i < options.nx; i++) { \
if ((r = sshbuf_put_cstring(m, options.x[i])) != 0) \
- fatal("%s: buffer error: %s", \
- __func__, ssh_err(r)); \
+ fatal_fr(r, "assemble %s", #x); \
} \
} while (0)
/* See comment in servconf.h */
@@ -792,10 +793,10 @@ mm_answer_pwnamallow(int sock, struct sshbuf *m)
* run to it's packet_disconnect(), but it must not allow any
* authentication to succeed.
*/
- debug("%s: no valid authentication method lists", __func__);
+ debug_f("no valid authentication method lists");
}
- debug3("%s: sending MONITOR_ANS_PWNAM: %d", __func__, allowed);
+ debug3_f("sending MONITOR_ANS_PWNAM: %d", allowed);
mm_request_send(sock, MONITOR_ANS_PWNAM, m);
/* Allow service/style information on the auth context */
@@ -810,7 +811,7 @@ mm_answer_pwnamallow(int sock, struct sshbuf *m)
return (0);
}
-int mm_answer_auth2_read_banner(int sock, struct sshbuf *m)
+int mm_answer_auth2_read_banner(struct ssh *ssh, int sock, struct sshbuf *m)
{
char *banner;
int r;
@@ -818,7 +819,7 @@ int mm_answer_auth2_read_banner(int sock, struct sshbuf *m)
sshbuf_reset(m);
banner = auth2_read_banner();
if ((r = sshbuf_put_cstring(m, banner != NULL ? banner : "")) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "assemble");
mm_request_send(sock, MONITOR_ANS_AUTH2_READ_BANNER, m);
free(banner);
@@ -826,7 +827,7 @@ int mm_answer_auth2_read_banner(int sock, struct sshbuf *m)
}
int
-mm_answer_authserv(int sock, struct sshbuf *m)
+mm_answer_authserv(struct ssh *ssh, int sock, struct sshbuf *m)
{
int r;
@@ -834,9 +835,8 @@ mm_answer_authserv(int sock, struct sshbuf *m)
if ((r = sshbuf_get_cstring(m, &authctxt->service, NULL)) != 0 ||
(r = sshbuf_get_cstring(m, &authctxt->style, NULL)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
- debug3("%s: service=%s, style=%s",
- __func__, authctxt->service, authctxt->style);
+ fatal_fr(r, "parse");
+ debug3_f("service=%s, style=%s", authctxt->service, authctxt->style);
if (strlen(authctxt->style) == 0) {
free(authctxt->style);
@@ -846,34 +846,62 @@ mm_answer_authserv(int sock, struct sshbuf *m)
return (0);
}
+/*
+ * Check that the key type appears in the supplied pattern list, ignoring
+ * mismatches in the signature algorithm. (Signature algorithm checks are
+ * performed in the unprivileged authentication code).
+ * Returns 1 on success, 0 otherwise.
+ */
+static int
+key_base_type_match(const char *method, const struct sshkey *key,
+ const char *list)
+{
+ char *s, *l, *ol = xstrdup(list);
+ int found = 0;
+
+ l = ol;
+ for ((s = strsep(&l, ",")); s && *s != '\0'; (s = strsep(&l, ","))) {
+ if (sshkey_type_from_name(s) == key->type) {
+ found = 1;
+ break;
+ }
+ }
+ if (!found) {
+ error("%s key type %s is not in permitted list %s", method,
+ sshkey_ssh_name(key), list);
+ }
+
+ free(ol);
+ return found;
+}
+
int
-mm_answer_authpassword(int sock, struct sshbuf *m)
+mm_answer_authpassword(struct ssh *ssh, int sock, struct sshbuf *m)
{
- struct ssh *ssh = active_state; /* XXX */
static int call_count;
char *passwd;
int r, authenticated;
size_t plen;
if (!options.password_authentication)
- fatal("%s: password authentication not enabled", __func__);
+ fatal_f("password authentication not enabled");
if ((r = sshbuf_get_cstring(m, &passwd, &plen)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "parse");
/* Only authenticate if the context is valid */
authenticated = options.password_authentication &&
auth_password(ssh, passwd);
- explicit_bzero(passwd, plen);
- free(passwd);
+ freezero(passwd, plen);
sshbuf_reset(m);
if ((r = sshbuf_put_u32(m, authenticated)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "assemble");
#ifdef USE_PAM
if ((r = sshbuf_put_u32(m, sshpam_get_maxtries_reached())) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "assemble PAM");
#endif
debug3("%s: sending result %d", __func__, authenticated);
+ debug3_f("sending result %d", authenticated);
mm_request_send(sock, MONITOR_ANS_AUTHPASSWORD, m);
call_count++;
@@ -888,7 +916,7 @@ mm_answer_authpassword(int sock, struct sshbuf *m)
#ifdef BSD_AUTH
int
-mm_answer_bsdauthquery(int sock, struct sshbuf *m)
+mm_answer_bsdauthquery(struct ssh *ssh, int sock, struct sshbuf *m)
{
char *name, *infotxt;
u_int numprompts, *echo_on, success;
@@ -896,19 +924,19 @@ mm_answer_bsdauthquery(int sock, struct sshbuf *m)
int r;
if (!options.kbd_interactive_authentication)
- fatal("%s: kbd-int authentication not enabled", __func__);
+ fatal_f("kbd-int authentication not enabled");
success = bsdauth_query(authctxt, &name, &infotxt, &numprompts,
&prompts, &echo_on) < 0 ? 0 : 1;
sshbuf_reset(m);
if ((r = sshbuf_put_u32(m, success)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "assemble");
if (success) {
if ((r = sshbuf_put_cstring(m, prompts[0])) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "assemble prompt");
}
- debug3("%s: sending challenge success: %u", __func__, success);
+ debug3_f("sending challenge success: %u", success);
mm_request_send(sock, MONITOR_ANS_BSDAUTHQUERY, m);
if (success) {
@@ -922,29 +950,29 @@ mm_answer_bsdauthquery(int sock, struct sshbuf *m)
}
int
-mm_answer_bsdauthrespond(int sock, struct sshbuf *m)
+mm_answer_bsdauthrespond(struct ssh *ssh, int sock, struct sshbuf *m)
{
char *response;
int r, authok;
if (!options.kbd_interactive_authentication)
- fatal("%s: kbd-int authentication not enabled", __func__);
+ fatal_f("kbd-int authentication not enabled");
if (authctxt->as == NULL)
- fatal("%s: no bsd auth session", __func__);
+ fatal_f("no bsd auth session");
if ((r = sshbuf_get_cstring(m, &response, NULL)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
- authok = options.challenge_response_authentication &&
+ fatal_fr(r, "parse");
+ authok = options.kbd_interactive_authentication &&
auth_userresponse(authctxt->as, response, 0);
authctxt->as = NULL;
- debug3("%s: <%s> = <%d>", __func__, response, authok);
+ debug3_f("<%s> = <%d>", response, authok);
free(response);
sshbuf_reset(m);
if ((r = sshbuf_put_u32(m, authok)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "assemble");
- debug3("%s: sending authenticated: %d", __func__, authok);
+ debug3_f("sending authenticated: %d", authok);
mm_request_send(sock, MONITOR_ANS_BSDAUTHRESPOND, m);
auth_method = "keyboard-interactive";
@@ -956,12 +984,12 @@ mm_answer_bsdauthrespond(int sock, struct sshbuf *m)
#ifdef USE_PAM
int
-mm_answer_pam_start(int sock, struct sshbuf *m)
+mm_answer_pam_start(struct ssh *ssh, int sock, struct sshbuf *m)
{
if (!options.use_pam)
fatal("UsePAM not set, but ended up in %s anyway", __func__);
- start_pam(authctxt);
+ start_pam(ssh);
monitor_permit(mon_dispatch, MONITOR_REQ_PAM_ACCOUNT, 1);
if (options.kbd_interactive_authentication)
@@ -971,7 +999,7 @@ mm_answer_pam_start(int sock, struct sshbuf *m)
}
int
-mm_answer_pam_account(int sock, struct sshbuf *m)
+mm_answer_pam_account(struct ssh *ssh, int sock, struct sshbuf *m)
{
u_int ret;
int r;
@@ -994,7 +1022,7 @@ static void *sshpam_ctxt, *sshpam_authok;
extern KbdintDevice sshpam_device;
int
-mm_answer_pam_init_ctx(int sock, struct sshbuf *m)
+mm_answer_pam_init_ctx(struct ssh *ssh, int sock, struct sshbuf *m)
{
u_int ok = 0;
int r;
@@ -1019,7 +1047,7 @@ mm_answer_pam_init_ctx(int sock, struct sshbuf *m)
}
int
-mm_answer_pam_query(int sock, struct sshbuf *m)
+mm_answer_pam_query(struct ssh *ssh, int sock, struct sshbuf *m)
{
char *name = NULL, *info = NULL, **prompts = NULL;
u_int i, num = 0, *echo_on = 0;
@@ -1060,7 +1088,7 @@ mm_answer_pam_query(int sock, struct sshbuf *m)
}
int
-mm_answer_pam_respond(int sock, struct sshbuf *m)
+mm_answer_pam_respond(struct ssh *ssh, int sock, struct sshbuf *m)
{
char **resp;
u_int i, num;
@@ -1098,7 +1126,7 @@ mm_answer_pam_respond(int sock, struct sshbuf *m)
}
int
-mm_answer_pam_free_ctx(int sock, struct sshbuf *m)
+mm_answer_pam_free_ctx(struct ssh *ssh, int sock, struct sshbuf *m)
{
int r = sshpam_authok != NULL && sshpam_authok == sshpam_ctxt;
@@ -1118,31 +1146,28 @@ mm_answer_pam_free_ctx(int sock, struct sshbuf *m)
#endif
int
-mm_answer_keyallowed(int sock, struct sshbuf *m)
+mm_answer_keyallowed(struct ssh *ssh, int sock, struct sshbuf *m)
{
- struct ssh *ssh = active_state; /* XXX */
struct sshkey *key = NULL;
char *cuser, *chost;
u_int pubkey_auth_attempt;
- enum mm_keytype type = 0;
+ u_int type = 0;
int r, allowed = 0;
struct sshauthopt *opts = NULL;
- debug3("%s entering", __func__);
+ debug3_f("entering");
if ((r = sshbuf_get_u32(m, &type)) != 0 ||
(r = sshbuf_get_cstring(m, &cuser, NULL)) != 0 ||
(r = sshbuf_get_cstring(m, &chost, NULL)) != 0 ||
(r = sshkey_froms(m, &key)) != 0 ||
(r = sshbuf_get_u32(m, &pubkey_auth_attempt)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
-
- debug3("%s: key_from_blob: %p", __func__, key);
+ fatal_fr(r, "parse");
if (key != NULL && authctxt->valid) {
/* These should not make it past the privsep child */
if (sshkey_type_plain(key->type) == KEY_RSA &&
- (datafellows & SSH_BUG_RSASIGMD5) != 0)
- fatal("%s: passed a SSH_BUG_RSASIGMD5 key", __func__);
+ (ssh->compat & SSH_BUG_RSASIGMD5) != 0)
+ fatal_f("passed a SSH_BUG_RSASIGMD5 key");
switch (type) {
case MM_USERKEY:
@@ -1151,8 +1176,8 @@ mm_answer_keyallowed(int sock, struct sshbuf *m)
break;
if (auth2_key_already_used(authctxt, key))
break;
- if (match_pattern_list(sshkey_ssh_name(key),
- options.pubkey_key_types, 0) != 1)
+ if (!key_base_type_match(auth_method, key,
+ options.pubkey_accepted_algos))
break;
allowed = user_key_allowed(ssh, authctxt->pw, key,
pubkey_auth_attempt, &opts);
@@ -1163,23 +1188,23 @@ mm_answer_keyallowed(int sock, struct sshbuf *m)
break;
if (auth2_key_already_used(authctxt, key))
break;
- if (match_pattern_list(sshkey_ssh_name(key),
- options.hostbased_key_types, 0) != 1)
+ if (!key_base_type_match(auth_method, key,
+ options.hostbased_accepted_algos))
break;
- allowed = hostbased_key_allowed(authctxt->pw,
+ allowed = hostbased_key_allowed(ssh, authctxt->pw,
cuser, chost, key);
auth2_record_info(authctxt,
"client user \"%.100s\", client host \"%.100s\"",
cuser, chost);
break;
default:
- fatal("%s: unknown key type %d", __func__, type);
+ fatal_f("unknown key type %u", type);
break;
}
}
- debug3("%s: %s authentication%s: %s key is %s", __func__,
- auth_method, pubkey_auth_attempt ? "" : " test",
+ debug3_f("%s authentication%s: %s key is %s", auth_method,
+ pubkey_auth_attempt ? "" : " test",
(key == NULL || !authctxt->valid) ? "invalid" : sshkey_type(key),
allowed ? "allowed" : "not allowed");
@@ -1191,14 +1216,14 @@ mm_answer_keyallowed(int sock, struct sshbuf *m)
if (allowed) {
/* Save temporarily for comparison in verify */
if ((r = sshkey_to_blob(key, &key_blob, &key_bloblen)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "sshkey_to_blob");
key_blobtype = type;
key_opts = opts;
hostbased_cuser = cuser;
hostbased_chost = chost;
} else {
/* Log failed attempt */
- auth_log(authctxt, 0, 0, auth_method, NULL);
+ auth_log(ssh, 0, 0, auth_method, NULL);
free(cuser);
free(chost);
}
@@ -1206,9 +1231,9 @@ mm_answer_keyallowed(int sock, struct sshbuf *m)
sshbuf_reset(m);
if ((r = sshbuf_put_u32(m, allowed)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "assemble");
if (opts != NULL && (r = sshauthopt_serialise(opts, m, 1)) != 0)
- fatal("%s: sshauthopt_serialise: %s", __func__, ssh_err(r));
+ fatal_fr(r, "sshauthopt_serialise");
mm_request_send(sock, MONITOR_ANS_KEYALLOWED, m);
if (!allowed)
@@ -1218,7 +1243,7 @@ mm_answer_keyallowed(int sock, struct sshbuf *m)
}
static int
-monitor_valid_userblob(u_char *data, u_int datalen)
+monitor_valid_userblob(struct ssh *ssh, const u_char *data, u_int datalen)
{
struct sshbuf *b;
const u_char *p;
@@ -1227,12 +1252,10 @@ monitor_valid_userblob(u_char *data, u_int datalen)
u_char type;
int r, fail = 0;
- if ((b = sshbuf_new()) == NULL)
- fatal("%s: sshbuf_new", __func__);
- if ((r = sshbuf_put(b, data, datalen)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ if ((b = sshbuf_from(data, datalen)) == NULL)
+ fatal_f("sshbuf_from");
- if (datafellows & SSH_OLD_SESSIONID) {
+ if (ssh->compat & SSH_OLD_SESSIONID) {
p = sshbuf_ptr(b);
len = sshbuf_len(b);
if ((session_id2 == NULL) ||
@@ -1240,21 +1263,21 @@ monitor_valid_userblob(u_char *data, u_int datalen)
(timingsafe_bcmp(p, session_id2, session_id2_len) != 0))
fail++;
if ((r = sshbuf_consume(b, session_id2_len)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "consume");
} else {
if ((r = sshbuf_get_string_direct(b, &p, &len)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "parse sessionid");
if ((session_id2 == NULL) ||
(len != session_id2_len) ||
(timingsafe_bcmp(p, session_id2, session_id2_len) != 0))
fail++;
}
if ((r = sshbuf_get_u8(b, &type)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "parse type");
if (type != SSH2_MSG_USERAUTH_REQUEST)
fail++;
if ((r = sshbuf_get_cstring(b, &cp, NULL)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "parse userstyle");
xasprintf(&userstyle, "%s%s%s", authctxt->user,
authctxt->style ? ":" : "",
authctxt->style ? authctxt->style : "");
@@ -1267,17 +1290,17 @@ monitor_valid_userblob(u_char *data, u_int datalen)
free(cp);
if ((r = sshbuf_skip_string(b)) != 0 || /* service */
(r = sshbuf_get_cstring(b, &cp, NULL)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "parse method");
if (strcmp("publickey", cp) != 0)
fail++;
free(cp);
if ((r = sshbuf_get_u8(b, &type)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "parse pktype");
if (type == 0)
fail++;
if ((r = sshbuf_skip_string(b)) != 0 || /* pkalg */
(r = sshbuf_skip_string(b)) != 0) /* pkblob */
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "parse pk");
if (sshbuf_len(b) != 0)
fail++;
sshbuf_free(b);
@@ -1285,8 +1308,8 @@ monitor_valid_userblob(u_char *data, u_int datalen)
}
static int
-monitor_valid_hostbasedblob(u_char *data, u_int datalen, char *cuser,
- char *chost)
+monitor_valid_hostbasedblob(const u_char *data, u_int datalen,
+ const char *cuser, const char *chost)
{
struct sshbuf *b;
const u_char *p;
@@ -1295,11 +1318,10 @@ monitor_valid_hostbasedblob(u_char *data, u_int datalen, char *cuser,
int r, fail = 0;
u_char type;
- if ((b = sshbuf_new()) == NULL)
- fatal("%s: sshbuf_new", __func__);
- if ((r = sshbuf_put(b, data, datalen)) != 0 ||
- (r = sshbuf_get_string_direct(b, &p, &len)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ if ((b = sshbuf_from(data, datalen)) == NULL)
+ fatal_f("sshbuf_new");
+ if ((r = sshbuf_get_string_direct(b, &p, &len)) != 0)
+ fatal_fr(r, "parse sessionid");
if ((session_id2 == NULL) ||
(len != session_id2_len) ||
@@ -1307,11 +1329,11 @@ monitor_valid_hostbasedblob(u_char *data, u_int datalen, char *cuser,
fail++;
if ((r = sshbuf_get_u8(b, &type)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "parse type");
if (type != SSH2_MSG_USERAUTH_REQUEST)
fail++;
if ((r = sshbuf_get_cstring(b, &cp, NULL)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "parse userstyle");
xasprintf(&userstyle, "%s%s%s", authctxt->user,
authctxt->style ? ":" : "",
authctxt->style ? authctxt->style : "");
@@ -1324,17 +1346,17 @@ monitor_valid_hostbasedblob(u_char *data, u_int datalen, char *cuser,
free(cp);
if ((r = sshbuf_skip_string(b)) != 0 || /* service */
(r = sshbuf_get_cstring(b, &cp, NULL)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "parse method");
if (strcmp(cp, "hostbased") != 0)
fail++;
free(cp);
if ((r = sshbuf_skip_string(b)) != 0 || /* pkalg */
(r = sshbuf_skip_string(b)) != 0) /* pkblob */
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "parse pk");
/* verify client host, strip trailing dot if necessary */
if ((r = sshbuf_get_cstring(b, &cp, NULL)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "parse host");
if (((len = strlen(cp)) > 0) && cp[len - 1] == '.')
cp[len - 1] = '\0';
if (strcmp(cp, chost) != 0)
@@ -1343,7 +1365,7 @@ monitor_valid_hostbasedblob(u_char *data, u_int datalen, char *cuser,
/* verify client user */
if ((r = sshbuf_get_cstring(b, &cp, NULL)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "parse ruser");
if (strcmp(cp, cuser) != 0)
fail++;
free(cp);
@@ -1355,24 +1377,25 @@ monitor_valid_hostbasedblob(u_char *data, u_int datalen, char *cuser,
}
int
-mm_answer_keyverify(int sock, struct sshbuf *m)
+mm_answer_keyverify(struct ssh *ssh, int sock, struct sshbuf *m)
{
- struct ssh *ssh = active_state; /* XXX */
struct sshkey *key;
- u_char *signature, *data, *blob;
- char *sigalg;
+ const u_char *signature, *data, *blob;
+ char *sigalg = NULL, *fp = NULL;
size_t signaturelen, datalen, bloblen;
- int r, ret, valid_data = 0, encoded_ret;
+ int r, ret, req_presence = 0, req_verify = 0, valid_data = 0;
+ int encoded_ret;
+ struct sshkey_sig_details *sig_details = NULL;
- if ((r = sshbuf_get_string(m, &blob, &bloblen)) != 0 ||
- (r = sshbuf_get_string(m, &signature, &signaturelen)) != 0 ||
- (r = sshbuf_get_string(m, &data, &datalen)) != 0 ||
+ if ((r = sshbuf_get_string_direct(m, &blob, &bloblen)) != 0 ||
+ (r = sshbuf_get_string_direct(m, &signature, &signaturelen)) != 0 ||
+ (r = sshbuf_get_string_direct(m, &data, &datalen)) != 0 ||
(r = sshbuf_get_cstring(m, &sigalg, NULL)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "parse");
if (hostbased_cuser == NULL || hostbased_chost == NULL ||
!monitor_allowed_key(blob, bloblen))
- fatal("%s: bad key, not previously allowed", __func__);
+ fatal_f("bad key, not previously allowed");
/* Empty signature algorithm means NULL. */
if (*sigalg == '\0') {
@@ -1382,11 +1405,11 @@ mm_answer_keyverify(int sock, struct sshbuf *m)
/* XXX use sshkey_froms here; need to change key_blob, etc. */
if ((r = sshkey_from_blob(blob, bloblen, &key)) != 0)
- fatal("%s: bad public key blob: %s", __func__, ssh_err(r));
+ fatal_fr(r, "parse key");
switch (key_blobtype) {
case MM_USERKEY:
- valid_data = monitor_valid_userblob(data, datalen);
+ valid_data = monitor_valid_userblob(ssh, data, datalen);
auth_method = "publickey";
break;
case MM_HOSTKEY:
@@ -1399,39 +1422,79 @@ mm_answer_keyverify(int sock, struct sshbuf *m)
break;
}
if (!valid_data)
- fatal("%s: bad signature data blob", __func__);
+ fatal_f("bad %s signature data blob",
+ key_blobtype == MM_USERKEY ? "userkey" :
+ (key_blobtype == MM_HOSTKEY ? "hostkey" : "unknown"));
+
+ if ((fp = sshkey_fingerprint(key, options.fingerprint_hash,
+ SSH_FP_DEFAULT)) == NULL)
+ fatal_f("sshkey_fingerprint failed");
ret = sshkey_verify(key, signature, signaturelen, data, datalen,
- sigalg, active_state->compat);
- debug3("%s: %s %p signature %s", __func__, auth_method, key,
- (ret == 0) ? "verified" : "unverified");
+ sigalg, ssh->compat, &sig_details);
+ debug3_f("%s %s signature %s%s%s", auth_method, sshkey_type(key),
+ (ret == 0) ? "verified" : "unverified",
+ (ret != 0) ? ": " : "", (ret != 0) ? ssh_err(ret) : "");
+
+ if (ret == 0 && key_blobtype == MM_USERKEY && sig_details != NULL) {
+ req_presence = (options.pubkey_auth_options &
+ PUBKEYAUTH_TOUCH_REQUIRED) ||
+ !key_opts->no_require_user_presence;
+ if (req_presence &&
+ (sig_details->sk_flags & SSH_SK_USER_PRESENCE_REQD) == 0) {
+ error("public key %s %s signature for %s%s from %.128s "
+ "port %d rejected: user presence "
+ "(authenticator touch) requirement not met ",
+ sshkey_type(key), fp,
+ authctxt->valid ? "" : "invalid user ",
+ authctxt->user, ssh_remote_ipaddr(ssh),
+ ssh_remote_port(ssh));
+ ret = SSH_ERR_SIGNATURE_INVALID;
+ }
+ req_verify = (options.pubkey_auth_options &
+ PUBKEYAUTH_VERIFY_REQUIRED) || key_opts->require_verify;
+ if (req_verify &&
+ (sig_details->sk_flags & SSH_SK_USER_VERIFICATION_REQD) == 0) {
+ error("public key %s %s signature for %s%s from %.128s "
+ "port %d rejected: user verification requirement "
+ "not met ", sshkey_type(key), fp,
+ authctxt->valid ? "" : "invalid user ",
+ authctxt->user, ssh_remote_ipaddr(ssh),
+ ssh_remote_port(ssh));
+ ret = SSH_ERR_SIGNATURE_INVALID;
+ }
+ }
auth2_record_key(authctxt, ret == 0, key);
- free(blob);
- free(signature);
- free(data);
- free(sigalg);
-
if (key_blobtype == MM_USERKEY)
auth_activate_options(ssh, key_opts);
monitor_reset_key_state();
- sshkey_free(key);
sshbuf_reset(m);
/* encode ret != 0 as positive integer, since we're sending u32 */
encoded_ret = (ret != 0);
- if ((r = sshbuf_put_u32(m, encoded_ret)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ if ((r = sshbuf_put_u32(m, encoded_ret)) != 0 ||
+ (r = sshbuf_put_u8(m, sig_details != NULL)) != 0)
+ fatal_fr(r, "assemble");
+ if (sig_details != NULL) {
+ if ((r = sshbuf_put_u32(m, sig_details->sk_counter)) != 0 ||
+ (r = sshbuf_put_u8(m, sig_details->sk_flags)) != 0)
+ fatal_fr(r, "assemble sk");
+ }
+ sshkey_sig_details_free(sig_details);
mm_request_send(sock, MONITOR_ANS_KEYVERIFY, m);
+ free(sigalg);
+ free(fp);
+ sshkey_free(key);
+
return ret == 0;
}
static void
-mm_record_login(Session *s, struct passwd *pw)
+mm_record_login(struct ssh *ssh, Session *s, struct passwd *pw)
{
- struct ssh *ssh = active_state; /* XXX */
socklen_t fromlen;
struct sockaddr_storage from;
@@ -1441,9 +1504,9 @@ mm_record_login(Session *s, struct passwd *pw)
*/
memset(&from, 0, sizeof(from));
fromlen = sizeof(from);
- if (packet_connection_is_on_socket()) {
- if (getpeername(packet_get_connection_in(),
- (struct sockaddr *)&from, &fromlen) < 0) {
+ if (ssh_packet_connection_is_on_socket(ssh)) {
+ if (getpeername(ssh_packet_get_connection_in(ssh),
+ (struct sockaddr *)&from, &fromlen) == -1) {
debug("getpeername: %.100s", strerror(errno));
cleanup_exit(255);
}
@@ -1457,22 +1520,22 @@ mm_record_login(Session *s, struct passwd *pw)
static void
mm_session_close(Session *s)
{
- debug3("%s: session %d pid %ld", __func__, s->self, (long)s->pid);
+ debug3_f("session %d pid %ld", s->self, (long)s->pid);
if (s->ttyfd != -1) {
- debug3("%s: tty %s ptyfd %d", __func__, s->tty, s->ptyfd);
+ debug3_f("tty %s ptyfd %d", s->tty, s->ptyfd);
session_pty_cleanup2(s);
}
session_unused(s->self);
}
int
-mm_answer_pty(int sock, struct sshbuf *m)
+mm_answer_pty(struct ssh *ssh, int sock, struct sshbuf *m)
{
extern struct monitor *pmonitor;
Session *s;
int r, res, fd0;
- debug3("%s entering", __func__);
+ debug3_f("entering");
sshbuf_reset(m);
s = session_new();
@@ -1488,41 +1551,41 @@ mm_answer_pty(int sock, struct sshbuf *m)
if ((r = sshbuf_put_u32(m, 1)) != 0 ||
(r = sshbuf_put_cstring(m, s->tty)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "assemble");
/* We need to trick ttyslot */
if (dup2(s->ttyfd, 0) == -1)
- fatal("%s: dup2", __func__);
+ fatal_f("dup2");
- mm_record_login(s, authctxt->pw);
+ mm_record_login(ssh, s, authctxt->pw);
/* Now we can close the file descriptor again */
close(0);
/* send messages generated by record_login */
if ((r = sshbuf_put_stringb(m, loginmsg)) != 0)
- fatal("%s: put login message: %s", __func__, ssh_err(r));
+ fatal_fr(r, "assemble loginmsg");
sshbuf_reset(loginmsg);
mm_request_send(sock, MONITOR_ANS_PTY, m);
if (mm_send_fd(sock, s->ptyfd) == -1 ||
mm_send_fd(sock, s->ttyfd) == -1)
- fatal("%s: send fds failed", __func__);
+ fatal_f("send fds failed");
/* make sure nothing uses fd 0 */
- if ((fd0 = open(_PATH_DEVNULL, O_RDONLY)) < 0)
- fatal("%s: open(/dev/null): %s", __func__, strerror(errno));
+ if ((fd0 = open(_PATH_DEVNULL, O_RDONLY)) == -1)
+ fatal_f("open(/dev/null): %s", strerror(errno));
if (fd0 != 0)
- error("%s: fd0 %d != 0", __func__, fd0);
+ error_f("fd0 %d != 0", fd0);
- /* slave is not needed */
+ /* slave side of pty is not needed */
close(s->ttyfd);
s->ttyfd = s->ptyfd;
/* no need to dup() because nobody closes ptyfd */
s->ptymaster = s->ptyfd;
- debug3("%s: tty %s ptyfd %d", __func__, s->tty, s->ttyfd);
+ debug3_f("tty %s ptyfd %d", s->tty, s->ttyfd);
return (0);
@@ -1530,22 +1593,22 @@ mm_answer_pty(int sock, struct sshbuf *m)
if (s != NULL)
mm_session_close(s);
if ((r = sshbuf_put_u32(m, 0)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "assemble 0");
mm_request_send(sock, MONITOR_ANS_PTY, m);
return (0);
}
int
-mm_answer_pty_cleanup(int sock, struct sshbuf *m)
+mm_answer_pty_cleanup(struct ssh *ssh, int sock, struct sshbuf *m)
{
Session *s;
char *tty;
int r;
- debug3("%s entering", __func__);
+ debug3_f("entering");
if ((r = sshbuf_get_cstring(m, &tty, NULL)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "parse tty");
if ((s = session_by_tty(tty)) != NULL)
mm_session_close(s);
sshbuf_reset(m);
@@ -1554,13 +1617,12 @@ mm_answer_pty_cleanup(int sock, struct sshbuf *m)
}
int
-mm_answer_term(int sock, struct sshbuf *req)
+mm_answer_term(struct ssh *ssh, int sock, struct sshbuf *req)
{
- struct ssh *ssh = active_state; /* XXX */
extern struct monitor *pmonitor;
int res, status;
- debug3("%s: tearing down sessions", __func__);
+ debug3_f("tearing down sessions");
/* The child is terminating */
session_destroy_all(ssh, &mm_session_close);
@@ -1583,7 +1645,7 @@ mm_answer_term(int sock, struct sshbuf *req)
#ifdef SSH_AUDIT_EVENTS
/* Report that an audit event occurred */
int
-mm_answer_audit_event(int socket, struct sshbuf *m)
+mm_answer_audit_event(struct ssh *ssh, int socket, struct sshbuf *m)
{
u_int n;
ssh_audit_event_t event;
@@ -1602,7 +1664,7 @@ mm_answer_audit_event(int socket, struct sshbuf *m)
case SSH_LOGIN_ROOT_DENIED:
case SSH_CONNECTION_CLOSE:
case SSH_INVALID_USER:
- audit_event(event);
+ audit_event(ssh, event);
break;
default:
fatal("Audit event type %d not permitted", event);
@@ -1612,7 +1674,7 @@ mm_answer_audit_event(int socket, struct sshbuf *m)
}
int
-mm_answer_audit_command(int socket, struct sshbuf *m)
+mm_answer_audit_command(struct ssh *ssh, int socket, struct sshbuf *m)
{
char *cmd;
int r;
@@ -1628,10 +1690,8 @@ mm_answer_audit_command(int socket, struct sshbuf *m)
#endif /* SSH_AUDIT_EVENTS */
void
-monitor_clear_keystate(struct monitor *pmonitor)
+monitor_clear_keystate(struct ssh *ssh, struct monitor *pmonitor)
{
- struct ssh *ssh = active_state; /* XXX */
-
ssh_clear_newkeys(ssh, MODE_IN);
ssh_clear_newkeys(ssh, MODE_OUT);
sshbuf_free(child_state);
@@ -1639,52 +1699,58 @@ monitor_clear_keystate(struct monitor *pmonitor)
}
void
-monitor_apply_keystate(struct monitor *pmonitor)
+monitor_apply_keystate(struct ssh *ssh, struct monitor *pmonitor)
{
- struct ssh *ssh = active_state; /* XXX */
struct kex *kex;
int r;
- debug3("%s: packet_set_state", __func__);
+ debug3_f("packet_set_state");
if ((r = ssh_packet_set_state(ssh, child_state)) != 0)
- fatal("%s: packet_set_state: %s", __func__, ssh_err(r));
+ fatal_fr(r, "packet_set_state");
sshbuf_free(child_state);
child_state = NULL;
-
- if ((kex = ssh->kex) != NULL) {
- /* XXX set callbacks */
+ if ((kex = ssh->kex) == NULL)
+ fatal_f("internal error: ssh->kex == NULL");
+ if (session_id2_len != sshbuf_len(ssh->kex->session_id)) {
+ fatal_f("incorrect session id length %zu (expected %u)",
+ sshbuf_len(ssh->kex->session_id), session_id2_len);
+ }
+ if (memcmp(sshbuf_ptr(ssh->kex->session_id), session_id2,
+ session_id2_len) != 0)
+ fatal_f("session ID mismatch");
+ /* XXX set callbacks */
#ifdef WITH_OPENSSL
- kex->kex[KEX_DH_GRP1_SHA1] = kexdh_server;
- kex->kex[KEX_DH_GRP14_SHA1] = kexdh_server;
- kex->kex[KEX_DH_GRP14_SHA256] = kexdh_server;
- kex->kex[KEX_DH_GRP16_SHA512] = kexdh_server;
- kex->kex[KEX_DH_GRP18_SHA512] = kexdh_server;
- kex->kex[KEX_DH_GEX_SHA1] = kexgex_server;
- kex->kex[KEX_DH_GEX_SHA256] = kexgex_server;
+ kex->kex[KEX_DH_GRP1_SHA1] = kex_gen_server;
+ kex->kex[KEX_DH_GRP14_SHA1] = kex_gen_server;
+ kex->kex[KEX_DH_GRP14_SHA256] = kex_gen_server;
+ kex->kex[KEX_DH_GRP16_SHA512] = kex_gen_server;
+ kex->kex[KEX_DH_GRP18_SHA512] = kex_gen_server;
+ kex->kex[KEX_DH_GEX_SHA1] = kexgex_server;
+ kex->kex[KEX_DH_GEX_SHA256] = kexgex_server;
# ifdef OPENSSL_HAS_ECC
- kex->kex[KEX_ECDH_SHA2] = kexecdh_server;
+ kex->kex[KEX_ECDH_SHA2] = kex_gen_server;
# endif
#endif /* WITH_OPENSSL */
- kex->kex[KEX_C25519_SHA256] = kexc25519_server;
- kex->load_host_public_key=&get_hostkey_public_by_type;
- kex->load_host_private_key=&get_hostkey_private_by_type;
- kex->host_key_index=&get_hostkey_index;
- kex->sign = sshd_hostkey_sign;
- }
+ kex->kex[KEX_C25519_SHA256] = kex_gen_server;
+ kex->kex[KEX_KEM_SNTRUP761X25519_SHA512] = kex_gen_server;
+ kex->load_host_public_key=&get_hostkey_public_by_type;
+ kex->load_host_private_key=&get_hostkey_private_by_type;
+ kex->host_key_index=&get_hostkey_index;
+ kex->sign = sshd_hostkey_sign;
}
-/* This function requries careful sanity checking */
+/* This function requires careful sanity checking */
void
-mm_get_keystate(struct monitor *pmonitor)
+mm_get_keystate(struct ssh *ssh, struct monitor *pmonitor)
{
- debug3("%s: Waiting for new keys", __func__);
+ debug3_f("Waiting for new keys");
if ((child_state = sshbuf_new()) == NULL)
- fatal("%s: sshbuf_new failed", __func__);
+ fatal_f("sshbuf_new failed");
mm_request_receive_expect(pmonitor->m_sendfd, MONITOR_REQ_KEYEXPORT,
child_state);
- debug3("%s: GOT new keys", __func__);
+ debug3_f("GOT new keys");
}
@@ -1704,11 +1770,11 @@ monitor_openfds(struct monitor *mon, int do_logfds)
#endif
if (socketpair(AF_UNIX, SOCK_STREAM, 0, pair) == -1)
- fatal("%s: socketpair: %s", __func__, strerror(errno));
+ fatal_f("socketpair: %s", strerror(errno));
#ifdef SO_ZEROIZE
- if (setsockopt(pair[0], SOL_SOCKET, SO_ZEROIZE, &on, sizeof(on)) < 0)
+ if (setsockopt(pair[0], SOL_SOCKET, SO_ZEROIZE, &on, sizeof(on)) == -1)
error("setsockopt SO_ZEROIZE(0): %.100s", strerror(errno));
- if (setsockopt(pair[1], SOL_SOCKET, SO_ZEROIZE, &on, sizeof(on)) < 0)
+ if (setsockopt(pair[1], SOL_SOCKET, SO_ZEROIZE, &on, sizeof(on)) == -1)
error("setsockopt SO_ZEROIZE(1): %.100s", strerror(errno));
#endif
FD_CLOSEONEXEC(pair[0]);
@@ -1718,7 +1784,7 @@ monitor_openfds(struct monitor *mon, int do_logfds)
if (do_logfds) {
if (pipe(pair) == -1)
- fatal("%s: pipe: %s", __func__, strerror(errno));
+ fatal_f("pipe: %s", strerror(errno));
FD_CLOSEONEXEC(pair[0]);
FD_CLOSEONEXEC(pair[1]);
mon->m_log_recvfd = pair[0];
@@ -1748,7 +1814,7 @@ monitor_reinit(struct monitor *mon)
#ifdef GSSAPI
int
-mm_answer_gss_setup_ctx(int sock, struct sshbuf *m)
+mm_answer_gss_setup_ctx(struct ssh *ssh, int sock, struct sshbuf *m)
{
gss_OID_desc goid;
OM_uint32 major;
@@ -1757,10 +1823,10 @@ mm_answer_gss_setup_ctx(int sock, struct sshbuf *m)
int r;
if (!options.gss_authentication)
- fatal("%s: GSSAPI authentication not enabled", __func__);
+ fatal_f("GSSAPI authentication not enabled");
if ((r = sshbuf_get_string(m, &p, &len)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "parse");
goid.elements = p;
goid.length = len;
@@ -1770,7 +1836,7 @@ mm_answer_gss_setup_ctx(int sock, struct sshbuf *m)
sshbuf_reset(m);
if ((r = sshbuf_put_u32(m, major)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "assemble");
mm_request_send(sock, MONITOR_ANS_GSSSETUP, m);
@@ -1781,7 +1847,7 @@ mm_answer_gss_setup_ctx(int sock, struct sshbuf *m)
}
int
-mm_answer_gss_accept_ctx(int sock, struct sshbuf *m)
+mm_answer_gss_accept_ctx(struct ssh *ssh, int sock, struct sshbuf *m)
{
gss_buffer_desc in;
gss_buffer_desc out = GSS_C_EMPTY_BUFFER;
@@ -1790,10 +1856,10 @@ mm_answer_gss_accept_ctx(int sock, struct sshbuf *m)
int r;
if (!options.gss_authentication)
- fatal("%s: GSSAPI authentication not enabled", __func__);
+ fatal_f("GSSAPI authentication not enabled");
if ((r = ssh_gssapi_get_buffer_desc(m, &in)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "ssh_gssapi_get_buffer_desc");
major = ssh_gssapi_accept_ctx(gsscontext, &in, &out, &flags);
free(in.value);
@@ -1801,7 +1867,7 @@ mm_answer_gss_accept_ctx(int sock, struct sshbuf *m)
if ((r = sshbuf_put_u32(m, major)) != 0 ||
(r = sshbuf_put_string(m, out.value, out.length)) != 0 ||
(r = sshbuf_put_u32(m, flags)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "assemble");
mm_request_send(sock, MONITOR_ANS_GSSSTEP, m);
gss_release_buffer(&minor, &out);
@@ -1815,18 +1881,18 @@ mm_answer_gss_accept_ctx(int sock, struct sshbuf *m)
}
int
-mm_answer_gss_checkmic(int sock, struct sshbuf *m)
+mm_answer_gss_checkmic(struct ssh *ssh, int sock, struct sshbuf *m)
{
gss_buffer_desc gssbuf, mic;
OM_uint32 ret;
int r;
if (!options.gss_authentication)
- fatal("%s: GSSAPI authentication not enabled", __func__);
+ fatal_f("GSSAPI authentication not enabled");
if ((r = ssh_gssapi_get_buffer_desc(m, &gssbuf)) != 0 ||
(r = ssh_gssapi_get_buffer_desc(m, &mic)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "ssh_gssapi_get_buffer_desc");
ret = ssh_gssapi_checkmic(gsscontext, &gssbuf, &mic);
@@ -1835,7 +1901,7 @@ mm_answer_gss_checkmic(int sock, struct sshbuf *m)
sshbuf_reset(m);
if ((r = sshbuf_put_u32(m, ret)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "assemble");
mm_request_send(sock, MONITOR_ANS_GSSCHECKMIC, m);
@@ -1846,21 +1912,21 @@ mm_answer_gss_checkmic(int sock, struct sshbuf *m)
}
int
-mm_answer_gss_userok(int sock, struct sshbuf *m)
+mm_answer_gss_userok(struct ssh *ssh, int sock, struct sshbuf *m)
{
int r, authenticated;
const char *displayname;
if (!options.gss_authentication)
- fatal("%s: GSSAPI authentication not enabled", __func__);
+ fatal_f("GSSAPI authentication not enabled");
authenticated = authctxt->valid && ssh_gssapi_userok(authctxt->user);
sshbuf_reset(m);
if ((r = sshbuf_put_u32(m, authenticated)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "assemble");
- debug3("%s: sending result %d", __func__, authenticated);
+ debug3_f("sending result %d", authenticated);
mm_request_send(sock, MONITOR_ANS_GSSUSEROK, m);
auth_method = "gssapi-with-mic";
diff --git a/crypto/openssh/monitor.h b/crypto/openssh/monitor.h
index 16047299f882..683e5e07163e 100644
--- a/crypto/openssh/monitor.h
+++ b/crypto/openssh/monitor.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: monitor.h,v 1.21 2018/07/09 21:53:45 markus Exp $ */
+/* $OpenBSD: monitor.h,v 1.23 2019/01/19 21:43:56 djm Exp $ */
/*
* Copyright 2002 Niels Provos <provos@citi.umich.edu>
@@ -65,6 +65,8 @@ enum monitor_reqtype {
};
+struct ssh;
+
struct monitor {
int m_recvfd;
int m_sendfd;
@@ -78,15 +80,16 @@ struct monitor *monitor_init(void);
void monitor_reinit(struct monitor *);
struct Authctxt;
-void monitor_child_preauth(struct Authctxt *, struct monitor *);
-void monitor_child_postauth(struct monitor *);
+void monitor_child_preauth(struct ssh *, struct monitor *);
+void monitor_child_postauth(struct ssh *, struct monitor *);
-struct mon_table;
-int monitor_read(struct monitor*, struct mon_table *, struct mon_table **);
+void monitor_clear_keystate(struct ssh *, struct monitor *);
+void monitor_apply_keystate(struct ssh *, struct monitor *);
/* Prototypes for request sending and receiving */
void mm_request_send(int, enum monitor_reqtype, struct sshbuf *);
void mm_request_receive(int, struct sshbuf *);
void mm_request_receive_expect(int, enum monitor_reqtype, struct sshbuf *);
+void mm_get_keystate(struct ssh *, struct monitor *);
#endif /* _MONITOR_H_ */
diff --git a/crypto/openssh/monitor_fdpass.c b/crypto/openssh/monitor_fdpass.c
index d766edcf11ca..a07727a8e743 100644
--- a/crypto/openssh/monitor_fdpass.c
+++ b/crypto/openssh/monitor_fdpass.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: monitor_fdpass.c,v 1.21 2016/02/29 20:22:36 jca Exp $ */
+/* $OpenBSD: monitor_fdpass.c,v 1.22 2020/10/18 11:32:01 djm Exp $ */
/*
* Copyright 2001 Niels Provos <provos@citi.umich.edu>
* All rights reserved.
@@ -89,17 +89,16 @@ mm_send_fd(int sock, int fd)
pfd.events = POLLOUT;
while ((n = sendmsg(sock, &msg, 0)) == -1 &&
(errno == EAGAIN || errno == EINTR)) {
- debug3("%s: sendmsg(%d): %s", __func__, fd, strerror(errno));
+ debug3_f("sendmsg(%d): %s", fd, strerror(errno));
(void)poll(&pfd, 1, -1);
}
if (n == -1) {
- error("%s: sendmsg(%d): %s", __func__, fd,
- strerror(errno));
+ error_f("sendmsg(%d): %s", fd, strerror(errno));
return -1;
}
if (n != 1) {
- error("%s: sendmsg: expected sent 1 got %zd", __func__, n);
+ error_f("sendmsg: expected sent 1 got %zd", n);
return -1;
}
return 0;
@@ -145,35 +144,34 @@ mm_receive_fd(int sock)
pfd.events = POLLIN;
while ((n = recvmsg(sock, &msg, 0)) == -1 &&
(errno == EAGAIN || errno == EINTR)) {
- debug3("%s: recvmsg: %s", __func__, strerror(errno));
+ debug3_f("recvmsg: %s", strerror(errno));
(void)poll(&pfd, 1, -1);
}
if (n == -1) {
- error("%s: recvmsg: %s", __func__, strerror(errno));
+ error_f("recvmsg: %s", strerror(errno));
return -1;
}
if (n != 1) {
- error("%s: recvmsg: expected received 1 got %zd", __func__, n);
+ error_f("recvmsg: expected received 1 got %zd", n);
return -1;
}
#ifdef HAVE_ACCRIGHTS_IN_MSGHDR
if (msg.msg_accrightslen != sizeof(fd)) {
- error("%s: no fd", __func__);
+ error_f("no fd");
return -1;
}
#else
cmsg = CMSG_FIRSTHDR(&msg);
if (cmsg == NULL) {
- error("%s: no message header", __func__);
+ error_f("no message header");
return -1;
}
#ifndef BROKEN_CMSG_TYPE
if (cmsg->cmsg_type != SCM_RIGHTS) {
- error("%s: expected type %d got %d", __func__,
- SCM_RIGHTS, cmsg->cmsg_type);
+ error_f("expected %d got %d", SCM_RIGHTS, cmsg->cmsg_type);
return -1;
}
#endif
@@ -181,7 +179,7 @@ mm_receive_fd(int sock)
#endif
return fd;
#else
- error("%s: file descriptor passing not supported", __func__);
+ error_f("file descriptor passing not supported");
return -1;
#endif
}
diff --git a/crypto/openssh/monitor_wrap.c b/crypto/openssh/monitor_wrap.c
index 732fb3476bf0..748333c75e59 100644
--- a/crypto/openssh/monitor_wrap.c
+++ b/crypto/openssh/monitor_wrap.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: monitor_wrap.c,v 1.107 2018/07/20 03:46:34 djm Exp $ */
+/* $OpenBSD: monitor_wrap.c,v 1.123 2021/04/15 16:24:31 markus Exp $ */
/*
* Copyright 2002 Niels Provos <provos@citi.umich.edu>
* Copyright 2002 Markus Friedl <markus@openbsd.org>
@@ -82,7 +82,7 @@ extern struct sshbuf *loginmsg;
extern ServerOptions options;
void
-mm_log_handler(LogLevel level, const char *msg, void *ctx)
+mm_log_handler(LogLevel level, int forced, const char *msg, void *ctx)
{
struct sshbuf *log_msg;
struct monitor *mon = (struct monitor *)ctx;
@@ -90,21 +90,22 @@ mm_log_handler(LogLevel level, const char *msg, void *ctx)
size_t len;
if (mon->m_log_sendfd == -1)
- fatal("%s: no log channel", __func__);
+ fatal_f("no log channel");
if ((log_msg = sshbuf_new()) == NULL)
- fatal("%s: sshbuf_new failed", __func__);
+ fatal_f("sshbuf_new failed");
if ((r = sshbuf_put_u32(log_msg, 0)) != 0 || /* length; filled below */
(r = sshbuf_put_u32(log_msg, level)) != 0 ||
+ (r = sshbuf_put_u32(log_msg, forced)) != 0 ||
(r = sshbuf_put_cstring(log_msg, msg)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "assemble");
if ((len = sshbuf_len(log_msg)) < 4 || len > 0xffffffff)
- fatal("%s: bad length %zu", __func__, len);
+ fatal_f("bad length %zu", len);
POKE_U32(sshbuf_mutable_ptr(log_msg), len - 4);
if (atomicio(vwrite, mon->m_log_sendfd,
sshbuf_mutable_ptr(log_msg), len) != len)
- fatal("%s: write: %s", __func__, strerror(errno));
+ fatal_f("write: %s", strerror(errno));
sshbuf_free(log_msg);
}
@@ -124,16 +125,16 @@ mm_request_send(int sock, enum monitor_reqtype type, struct sshbuf *m)
size_t mlen = sshbuf_len(m);
u_char buf[5];
- debug3("%s entering: type %d", __func__, type);
+ debug3_f("entering, type %d", type);
if (mlen >= 0xffffffff)
- fatal("%s: bad length %zu", __func__, mlen);
+ fatal_f("bad length %zu", mlen);
POKE_U32(buf, mlen + 1);
buf[4] = (u_char) type; /* 1st byte of payload is mesg-type */
if (atomicio(vwrite, sock, buf, sizeof(buf)) != sizeof(buf))
- fatal("%s: write: %s", __func__, strerror(errno));
+ fatal_f("write: %s", strerror(errno));
if (atomicio(vwrite, sock, sshbuf_mutable_ptr(m), mlen) != mlen)
- fatal("%s: write: %s", __func__, strerror(errno));
+ fatal_f("write: %s", strerror(errno));
}
void
@@ -143,21 +144,21 @@ mm_request_receive(int sock, struct sshbuf *m)
u_int msg_len;
int r;
- debug3("%s entering", __func__);
+ debug3_f("entering");
if (atomicio(read, sock, buf, sizeof(buf)) != sizeof(buf)) {
if (errno == EPIPE)
cleanup_exit(255);
- fatal("%s: read: %s", __func__, strerror(errno));
+ fatal_f("read: %s", strerror(errno));
}
msg_len = PEEK_U32(buf);
if (msg_len > 256 * 1024)
- fatal("%s: read: bad msg_len %d", __func__, msg_len);
+ fatal_f("read: bad msg_len %d", msg_len);
sshbuf_reset(m);
if ((r = sshbuf_reserve(m, msg_len, &p)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "reserve");
if (atomicio(read, sock, p, msg_len) != msg_len)
- fatal("%s: read: %s", __func__, strerror(errno));
+ fatal_f("read: %s", strerror(errno));
}
void
@@ -166,14 +167,13 @@ mm_request_receive_expect(int sock, enum monitor_reqtype type, struct sshbuf *m)
u_char rtype;
int r;
- debug3("%s entering: type %d", __func__, type);
+ debug3_f("entering, type %d", type);
mm_request_receive(sock, m);
if ((r = sshbuf_get_u8(m, &rtype)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "parse");
if (rtype != type)
- fatal("%s: read: rtype %d != type %d", __func__,
- rtype, type);
+ fatal_f("read: rtype %d != type %d", rtype, type);
}
#ifdef WITH_OPENSSL
@@ -186,31 +186,27 @@ mm_choose_dh(int min, int nbits, int max)
struct sshbuf *m;
if ((m = sshbuf_new()) == NULL)
- fatal("%s: sshbuf_new failed", __func__);
+ fatal_f("sshbuf_new failed");
if ((r = sshbuf_put_u32(m, min)) != 0 ||
(r = sshbuf_put_u32(m, nbits)) != 0 ||
(r = sshbuf_put_u32(m, max)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "assemble");
mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_MODULI, m);
- debug3("%s: waiting for MONITOR_ANS_MODULI", __func__);
+ debug3_f("waiting for MONITOR_ANS_MODULI");
mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_MODULI, m);
if ((r = sshbuf_get_u8(m, &success)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "parse success");
if (success == 0)
- fatal("%s: MONITOR_ANS_MODULI failed", __func__);
-
- if ((p = BN_new()) == NULL)
- fatal("%s: BN_new failed", __func__);
- if ((g = BN_new()) == NULL)
- fatal("%s: BN_new failed", __func__);
- if ((r = sshbuf_get_bignum2(m, p)) != 0 ||
- (r = sshbuf_get_bignum2(m, g)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_f("MONITOR_ANS_MODULI failed");
+
+ if ((r = sshbuf_get_bignum2(m, &p)) != 0 ||
+ (r = sshbuf_get_bignum2(m, &g)) != 0)
+ fatal_fr(r, "parse group");
- debug3("%s: remaining %zu", __func__, sshbuf_len(m));
+ debug3_f("remaining %zu", sshbuf_len(m));
sshbuf_free(m);
return (dh_new_group(g, p));
@@ -218,39 +214,47 @@ mm_choose_dh(int min, int nbits, int max)
#endif
int
-mm_sshkey_sign(struct sshkey *key, u_char **sigp, size_t *lenp,
- const u_char *data, size_t datalen, const char *hostkey_alg, u_int compat)
+mm_sshkey_sign(struct ssh *ssh, struct sshkey *key, u_char **sigp, size_t *lenp,
+ const u_char *data, size_t datalen, const char *hostkey_alg,
+ const char *sk_provider, const char *sk_pin, u_int compat)
{
struct kex *kex = *pmonitor->m_pkex;
struct sshbuf *m;
- u_int ndx = kex->host_key_index(key, 0, active_state);
+ u_int ndx = kex->host_key_index(key, 0, ssh);
int r;
- debug3("%s entering", __func__);
-
+ debug3_f("entering");
if ((m = sshbuf_new()) == NULL)
- fatal("%s: sshbuf_new failed", __func__);
+ fatal_f("sshbuf_new failed");
if ((r = sshbuf_put_u32(m, ndx)) != 0 ||
(r = sshbuf_put_string(m, data, datalen)) != 0 ||
(r = sshbuf_put_cstring(m, hostkey_alg)) != 0 ||
(r = sshbuf_put_u32(m, compat)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "assemble");
mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_SIGN, m);
- debug3("%s: waiting for MONITOR_ANS_SIGN", __func__);
+ debug3_f("waiting for MONITOR_ANS_SIGN");
mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_SIGN, m);
if ((r = sshbuf_get_string(m, sigp, lenp)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "parse");
sshbuf_free(m);
return (0);
}
+#define GETPW(b, id) \
+ do { \
+ if ((r = sshbuf_get_string_direct(b, &p, &len)) != 0) \
+ fatal_fr(r, "parse pw %s", #id); \
+ if (len != sizeof(pw->id)) \
+ fatal_fr(r, "bad length for %s", #id); \
+ memcpy(&pw->id, p, len); \
+ } while (0)
+
struct passwd *
-mm_getpwnamallow(const char *username)
+mm_getpwnamallow(struct ssh *ssh, const char *username)
{
- struct ssh *ssh = active_state; /* XXX */
struct sshbuf *m;
struct passwd *pw;
size_t len;
@@ -260,20 +264,20 @@ mm_getpwnamallow(const char *username)
u_char ok;
const u_char *p;
- debug3("%s entering", __func__);
+ debug3_f("entering");
if ((m = sshbuf_new()) == NULL)
- fatal("%s: sshbuf_new failed", __func__);
+ fatal_f("sshbuf_new failed");
if ((r = sshbuf_put_cstring(m, username)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "assemble");
mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PWNAM, m);
- debug3("%s: waiting for MONITOR_ANS_PWNAM", __func__);
+ debug3_f("waiting for MONITOR_ANS_PWNAM");
mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_PWNAM, m);
if ((r = sshbuf_get_u8(m, &ok)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "parse success");
if (ok == 0) {
pw = NULL;
goto out;
@@ -281,12 +285,14 @@ mm_getpwnamallow(const char *username)
/* XXX don't like passing struct passwd like this */
pw = xcalloc(sizeof(*pw), 1);
- if ((r = sshbuf_get_string_direct(m, &p, &len)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
- if (len != sizeof(*pw))
- fatal("%s: struct passwd size mismatch", __func__);
- memcpy(pw, p, sizeof(*pw));
-
+ GETPW(m, pw_uid);
+ GETPW(m, pw_gid);
+#ifdef HAVE_STRUCT_PASSWD_PW_CHANGE
+ GETPW(m, pw_change);
+#endif
+#ifdef HAVE_STRUCT_PASSWD_PW_EXPIRE
+ GETPW(m, pw_expire);
+#endif
if ((r = sshbuf_get_cstring(m, &pw->pw_name, NULL)) != 0 ||
(r = sshbuf_get_cstring(m, &pw->pw_passwd, NULL)) != 0 ||
#ifdef HAVE_STRUCT_PASSWD_PW_GECOS
@@ -297,24 +303,21 @@ mm_getpwnamallow(const char *username)
#endif
(r = sshbuf_get_cstring(m, &pw->pw_dir, NULL)) != 0 ||
(r = sshbuf_get_cstring(m, &pw->pw_shell, NULL)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "parse pw");
out:
/* copy options block as a Match directive may have changed some */
if ((r = sshbuf_get_string_direct(m, &p, &len)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "parse opts");
if (len != sizeof(*newopts))
- fatal("%s: option block size mismatch", __func__);
+ fatal_f("option block size mismatch");
newopts = xcalloc(sizeof(*newopts), 1);
memcpy(newopts, p, sizeof(*newopts));
#define M_CP_STROPT(x) do { \
- if (newopts->x != NULL) { \
- if ((r = sshbuf_get_cstring(m, \
- &newopts->x, NULL)) != 0) \
- fatal("%s: buffer error: %s", \
- __func__, ssh_err(r)); \
- } \
+ if (newopts->x != NULL && \
+ (r = sshbuf_get_cstring(m, &newopts->x, NULL)) != 0) \
+ fatal_fr(r, "parse %s", #x); \
} while (0)
#define M_CP_STRARRAYOPT(x, nx) do { \
newopts->x = newopts->nx == 0 ? \
@@ -322,8 +325,7 @@ out:
for (i = 0; i < newopts->nx; i++) { \
if ((r = sshbuf_get_cstring(m, \
&newopts->x[i], NULL)) != 0) \
- fatal("%s: buffer error: %s", \
- __func__, ssh_err(r)); \
+ fatal_fr(r, "parse %s", #x); \
} \
} while (0)
/* See comment in servconf.h */
@@ -333,6 +335,9 @@ out:
copy_set_server_options(&options, newopts, 1);
log_change_level(options.log_level);
+ log_verbose_reset();
+ for (i = 0; i < options.num_log_verbose; i++)
+ log_verbose_add(options.log_verbose[i]);
process_permitopen(ssh, &options);
free(newopts);
@@ -348,17 +353,17 @@ mm_auth2_read_banner(void)
char *banner;
int r;
- debug3("%s entering", __func__);
+ debug3_f("entering");
if ((m = sshbuf_new()) == NULL)
- fatal("%s: sshbuf_new failed", __func__);
+ fatal_f("sshbuf_new failed");
mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUTH2_READ_BANNER, m);
sshbuf_reset(m);
mm_request_receive_expect(pmonitor->m_recvfd,
MONITOR_ANS_AUTH2_READ_BANNER, m);
if ((r = sshbuf_get_cstring(m, &banner, NULL)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "parse");
sshbuf_free(m);
/* treat empty banner as missing banner */
@@ -377,13 +382,13 @@ mm_inform_authserv(char *service, char *style)
struct sshbuf *m;
int r;
- debug3("%s entering", __func__);
+ debug3_f("entering");
if ((m = sshbuf_new()) == NULL)
- fatal("%s: sshbuf_new failed", __func__);
+ fatal_f("sshbuf_new failed");
if ((r = sshbuf_put_cstring(m, service)) != 0 ||
(r = sshbuf_put_cstring(m, style ? style : "")) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "assemble");
mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUTHSERV, m);
@@ -400,32 +405,31 @@ mm_auth_password(struct ssh *ssh, char *password)
u_int maxtries = 0;
#endif
- debug3("%s entering", __func__);
+ debug3_f("entering");
if ((m = sshbuf_new()) == NULL)
- fatal("%s: sshbuf_new failed", __func__);
+ fatal_f("sshbuf_new failed");
if ((r = sshbuf_put_cstring(m, password)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "assemble");
mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUTHPASSWORD, m);
- debug3("%s: waiting for MONITOR_ANS_AUTHPASSWORD", __func__);
+ debug3_f("waiting for MONITOR_ANS_AUTHPASSWORD");
mm_request_receive_expect(pmonitor->m_recvfd,
MONITOR_ANS_AUTHPASSWORD, m);
if ((r = sshbuf_get_u32(m, &authenticated)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "parse");
#ifdef USE_PAM
if ((r = sshbuf_get_u32(m, &maxtries)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "parse PAM");
if (maxtries > INT_MAX)
- fatal("%s: bad maxtries %u", __func__, maxtries);
+ fatal_fr(r, "bad maxtries");
sshpam_set_maxtries_reached(maxtries);
#endif
sshbuf_free(m);
- debug3("%s: user %sauthenticated",
- __func__, authenticated ? "" : "not ");
+ debug3_f("user %sauthenticated", authenticated ? "" : "not ");
return (authenticated);
}
@@ -438,8 +442,8 @@ mm_user_key_allowed(struct ssh *ssh, struct passwd *pw, struct sshkey *key,
}
int
-mm_hostbased_key_allowed(struct passwd *pw, const char *user, const char *host,
- struct sshkey *key)
+mm_hostbased_key_allowed(struct ssh *ssh, struct passwd *pw,
+ const char *user, const char *host, struct sshkey *key)
{
return (mm_key_allowed(MM_HOSTKEY, user, host, key, 0, NULL));
}
@@ -452,33 +456,31 @@ mm_key_allowed(enum mm_keytype type, const char *user, const char *host,
int r, allowed = 0;
struct sshauthopt *opts = NULL;
- debug3("%s entering", __func__);
+ debug3_f("entering");
if (authoptp != NULL)
*authoptp = NULL;
if ((m = sshbuf_new()) == NULL)
- fatal("%s: sshbuf_new failed", __func__);
+ fatal_f("sshbuf_new failed");
if ((r = sshbuf_put_u32(m, type)) != 0 ||
(r = sshbuf_put_cstring(m, user ? user : "")) != 0 ||
(r = sshbuf_put_cstring(m, host ? host : "")) != 0 ||
(r = sshkey_puts(key, m)) != 0 ||
(r = sshbuf_put_u32(m, pubkey_auth_attempt)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "assemble");
mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_KEYALLOWED, m);
- debug3("%s: waiting for MONITOR_ANS_KEYALLOWED", __func__);
+ debug3_f("waiting for MONITOR_ANS_KEYALLOWED");
mm_request_receive_expect(pmonitor->m_recvfd,
MONITOR_ANS_KEYALLOWED, m);
if ((r = sshbuf_get_u32(m, &allowed)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
- if (allowed && type == MM_USERKEY) {
- if ((r = sshauthopt_deserialise(m, &opts)) != 0)
- fatal("%s: sshauthopt_deserialise: %s",
- __func__, ssh_err(r));
- }
+ fatal_fr(r, "parse");
+ if (allowed && type == MM_USERKEY &&
+ (r = sshauthopt_deserialise(m, &opts)) != 0)
+ fatal_fr(r, "sshauthopt_deserialise");
sshbuf_free(m);
if (authoptp != NULL) {
@@ -498,31 +500,46 @@ mm_key_allowed(enum mm_keytype type, const char *user, const char *host,
int
mm_sshkey_verify(const struct sshkey *key, const u_char *sig, size_t siglen,
- const u_char *data, size_t datalen, const char *sigalg, u_int compat)
+ const u_char *data, size_t datalen, const char *sigalg, u_int compat,
+ struct sshkey_sig_details **sig_detailsp)
{
struct sshbuf *m;
u_int encoded_ret = 0;
int r;
+ u_char sig_details_present, flags;
+ u_int counter;
- debug3("%s entering", __func__);
-
+ debug3_f("entering");
+ if (sig_detailsp != NULL)
+ *sig_detailsp = NULL;
if ((m = sshbuf_new()) == NULL)
- fatal("%s: sshbuf_new failed", __func__);
+ fatal_f("sshbuf_new failed");
if ((r = sshkey_puts(key, m)) != 0 ||
(r = sshbuf_put_string(m, sig, siglen)) != 0 ||
(r = sshbuf_put_string(m, data, datalen)) != 0 ||
(r = sshbuf_put_cstring(m, sigalg == NULL ? "" : sigalg)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "assemble");
mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_KEYVERIFY, m);
- debug3("%s: waiting for MONITOR_ANS_KEYVERIFY", __func__);
+ debug3_f("waiting for MONITOR_ANS_KEYVERIFY");
mm_request_receive_expect(pmonitor->m_recvfd,
MONITOR_ANS_KEYVERIFY, m);
- if ((r = sshbuf_get_u32(m, &encoded_ret)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ if ((r = sshbuf_get_u32(m, &encoded_ret)) != 0 ||
+ (r = sshbuf_get_u8(m, &sig_details_present)) != 0)
+ fatal_fr(r, "parse");
+ if (sig_details_present && encoded_ret == 0) {
+ if ((r = sshbuf_get_u32(m, &counter)) != 0 ||
+ (r = sshbuf_get_u8(m, &flags)) != 0)
+ fatal_fr(r, "parse sig_details");
+ if (sig_detailsp != NULL) {
+ *sig_detailsp = xcalloc(1, sizeof(**sig_detailsp));
+ (*sig_detailsp)->sk_counter = counter;
+ (*sig_detailsp)->sk_flags = flags;
+ }
+ }
sshbuf_free(m);
@@ -532,19 +549,17 @@ mm_sshkey_verify(const struct sshkey *key, const u_char *sig, size_t siglen,
}
void
-mm_send_keystate(struct monitor *monitor)
+mm_send_keystate(struct ssh *ssh, struct monitor *monitor)
{
- struct ssh *ssh = active_state; /* XXX */
struct sshbuf *m;
int r;
if ((m = sshbuf_new()) == NULL)
- fatal("%s: sshbuf_new failed", __func__);
+ fatal_f("sshbuf_new failed");
if ((r = ssh_packet_get_state(ssh, m)) != 0)
- fatal("%s: get_state failed: %s",
- __func__, ssh_err(r));
+ fatal_fr(r, "ssh_packet_get_state");
mm_request_send(monitor->m_recvfd, MONITOR_REQ_KEYEXPORT, m);
- debug3("%s: Finished sending state", __func__);
+ debug3_f("Finished sending state");
sshbuf_free(m);
}
@@ -558,7 +573,7 @@ mm_pty_allocate(int *ptyfd, int *ttyfd, char *namebuf, size_t namebuflen)
/* Kludge: ensure there are fds free to receive the pty/tty */
if ((tmp1 = dup(pmonitor->m_recvfd)) == -1 ||
(tmp2 = dup(pmonitor->m_recvfd)) == -1) {
- error("%s: cannot allocate fds for pty", __func__);
+ error_f("cannot allocate fds for pty");
if (tmp1 > 0)
close(tmp1);
if (tmp2 > 0)
@@ -569,34 +584,34 @@ mm_pty_allocate(int *ptyfd, int *ttyfd, char *namebuf, size_t namebuflen)
close(tmp2);
if ((m = sshbuf_new()) == NULL)
- fatal("%s: sshbuf_new failed", __func__);
+ fatal_f("sshbuf_new failed");
mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PTY, m);
- debug3("%s: waiting for MONITOR_ANS_PTY", __func__);
+ debug3_f("waiting for MONITOR_ANS_PTY");
mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_PTY, m);
if ((r = sshbuf_get_u32(m, &success)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "parse success");
if (success == 0) {
- debug3("%s: pty alloc failed", __func__);
+ debug3_f("pty alloc failed");
sshbuf_free(m);
return (0);
}
if ((r = sshbuf_get_cstring(m, &p, NULL)) != 0 ||
(r = sshbuf_get_cstring(m, &msg, NULL)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "parse");
sshbuf_free(m);
strlcpy(namebuf, p, namebuflen); /* Possible truncation */
free(p);
if ((r = sshbuf_put(loginmsg, msg, strlen(msg))) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "put loginmsg");
free(msg);
if ((*ptyfd = mm_receive_fd(pmonitor->m_recvfd)) == -1 ||
(*ttyfd = mm_receive_fd(pmonitor->m_recvfd)) == -1)
- fatal("%s: receive fds failed", __func__);
+ fatal_f("receive fds failed");
/* Success */
return (1);
@@ -611,14 +626,14 @@ mm_session_pty_cleanup2(Session *s)
if (s->ttyfd == -1)
return;
if ((m = sshbuf_new()) == NULL)
- fatal("%s: sshbuf_new failed", __func__);
+ fatal_f("sshbuf_new failed");
if ((r = sshbuf_put_cstring(m, s->tty)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "assmble");
mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PTYCLEANUP, m);
sshbuf_free(m);
/* closed dup'ed master */
- if (s->ptymaster != -1 && close(s->ptymaster) < 0)
+ if (s->ptymaster != -1 && close(s->ptymaster) == -1)
error("close(s->ptymaster/%d): %s",
s->ptymaster, strerror(errno));
@@ -628,7 +643,7 @@ mm_session_pty_cleanup2(Session *s)
#ifdef USE_PAM
void
-mm_start_pam(Authctxt *authctxt)
+mm_start_pam(struct ssh *ssh)
{
struct sshbuf *m;
@@ -786,7 +801,7 @@ mm_terminate(void)
struct sshbuf *m;
if ((m = sshbuf_new()) == NULL)
- fatal("%s: sshbuf_new failed", __func__);
+ fatal_f("sshbuf_new failed");
mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_TERM, m);
sshbuf_free(m);
}
@@ -812,31 +827,31 @@ mm_bsdauth_query(void *ctx, char **name, char **infotxt,
char *challenge;
int r;
- debug3("%s: entering", __func__);
+ debug3_f("entering");
if ((m = sshbuf_new()) == NULL)
- fatal("%s: sshbuf_new failed", __func__);
+ fatal_f("sshbuf_new failed");
mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_BSDAUTHQUERY, m);
mm_request_receive_expect(pmonitor->m_recvfd,
MONITOR_ANS_BSDAUTHQUERY, m);
if ((r = sshbuf_get_u32(m, &success)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "parse success");
if (success == 0) {
- debug3("%s: no challenge", __func__);
+ debug3_f("no challenge");
sshbuf_free(m);
return (-1);
}
/* Get the challenge, and format the response */
if ((r = sshbuf_get_cstring(m, &challenge, NULL)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "parse challenge");
sshbuf_free(m);
mm_chall_setup(name, infotxt, numprompts, prompts, echo_on);
(*prompts)[0] = challenge;
- debug3("%s: received challenge: %s", __func__, challenge);
+ debug3_f("received challenge: %s", challenge);
return (0);
}
@@ -847,21 +862,21 @@ mm_bsdauth_respond(void *ctx, u_int numresponses, char **responses)
struct sshbuf *m;
int r, authok;
- debug3("%s: entering", __func__);
+ debug3_f("entering");
if (numresponses != 1)
return (-1);
if ((m = sshbuf_new()) == NULL)
- fatal("%s: sshbuf_new failed", __func__);
+ fatal_f("sshbuf_new failed");
if ((r = sshbuf_put_cstring(m, responses[0])) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "assemble");
mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_BSDAUTHRESPOND, m);
mm_request_receive_expect(pmonitor->m_recvfd,
MONITOR_ANS_BSDAUTHRESPOND, m);
if ((r = sshbuf_get_u32(m, &authok)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "parse");
sshbuf_free(m);
return ((authok == 0) ? -1 : 0);
@@ -869,7 +884,7 @@ mm_bsdauth_respond(void *ctx, u_int numresponses, char **responses)
#ifdef SSH_AUDIT_EVENTS
void
-mm_audit_event(ssh_audit_event_t event)
+mm_audit_event(struct ssh *ssh, ssh_audit_event_t event)
{
struct sshbuf *m;
int r;
@@ -915,15 +930,15 @@ mm_ssh_gssapi_server_ctx(Gssctxt **ctx, gss_OID goid)
*ctx = NULL;
if ((m = sshbuf_new()) == NULL)
- fatal("%s: sshbuf_new failed", __func__);
+ fatal_f("sshbuf_new failed");
if ((r = sshbuf_put_string(m, goid->elements, goid->length)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "assemble");
mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GSSSETUP, m);
mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_GSSSETUP, m);
if ((r = sshbuf_get_u32(m, &major)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "parse");
sshbuf_free(m);
return (major);
@@ -939,19 +954,19 @@ mm_ssh_gssapi_accept_ctx(Gssctxt *ctx, gss_buffer_desc *in,
int r;
if ((m = sshbuf_new()) == NULL)
- fatal("%s: sshbuf_new failed", __func__);
+ fatal_f("sshbuf_new failed");
if ((r = sshbuf_put_string(m, in->value, in->length)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "assemble");
mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GSSSTEP, m);
mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_GSSSTEP, m);
if ((r = sshbuf_get_u32(m, &major)) != 0 ||
(r = ssh_gssapi_get_buffer_desc(m, out)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "parse");
if (flagsp != NULL) {
if ((r = sshbuf_get_u32(m, &flags)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "parse flags");
*flagsp = flags;
}
@@ -968,17 +983,17 @@ mm_ssh_gssapi_checkmic(Gssctxt *ctx, gss_buffer_t gssbuf, gss_buffer_t gssmic)
int r;
if ((m = sshbuf_new()) == NULL)
- fatal("%s: sshbuf_new failed", __func__);
+ fatal_f("sshbuf_new failed");
if ((r = sshbuf_put_string(m, gssbuf->value, gssbuf->length)) != 0 ||
(r = sshbuf_put_string(m, gssmic->value, gssmic->length)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "assemble");
mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GSSCHECKMIC, m);
mm_request_receive_expect(pmonitor->m_recvfd,
MONITOR_ANS_GSSCHECKMIC, m);
if ((r = sshbuf_get_u32(m, &major)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "parse");
sshbuf_free(m);
return(major);
}
@@ -990,17 +1005,17 @@ mm_ssh_gssapi_userok(char *user)
int r, authenticated = 0;
if ((m = sshbuf_new()) == NULL)
- fatal("%s: sshbuf_new failed", __func__);
+ fatal_f("sshbuf_new failed");
mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GSSUSEROK, m);
mm_request_receive_expect(pmonitor->m_recvfd,
MONITOR_ANS_GSSUSEROK, m);
if ((r = sshbuf_get_u32(m, &authenticated)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "parse");
sshbuf_free(m);
- debug3("%s: user %sauthenticated",__func__, authenticated ? "" : "not ");
+ debug3_f("user %sauthenticated", authenticated ? "" : "not ");
return (authenticated);
}
#endif /* GSSAPI */
diff --git a/crypto/openssh/monitor_wrap.h b/crypto/openssh/monitor_wrap.h
index 644da081db8d..a163b67d2878 100644
--- a/crypto/openssh/monitor_wrap.h
+++ b/crypto/openssh/monitor_wrap.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: monitor_wrap.h,v 1.38 2018/07/11 18:53:29 markus Exp $ */
+/* $OpenBSD: monitor_wrap.h,v 1.47 2021/04/15 16:24:31 markus Exp $ */
/*
* Copyright 2002 Niels Provos <provos@citi.umich.edu>
@@ -33,28 +33,33 @@ extern int use_privsep;
enum mm_keytype { MM_NOKEY, MM_HOSTKEY, MM_USERKEY };
+struct ssh;
struct monitor;
struct Authctxt;
struct sshkey;
struct sshauthopt;
+struct sshkey_sig_details;
-void mm_log_handler(LogLevel, const char *, void *);
+void mm_log_handler(LogLevel, int, const char *, void *);
int mm_is_monitor(void);
+#ifdef WITH_OPENSSL
DH *mm_choose_dh(int, int, int);
-int mm_sshkey_sign(struct sshkey *, u_char **, size_t *, const u_char *, size_t,
+#endif
+int mm_sshkey_sign(struct ssh *, struct sshkey *, u_char **, size_t *,
+ const u_char *, size_t, const char *, const char *,
const char *, u_int compat);
void mm_inform_authserv(char *, char *);
-struct passwd *mm_getpwnamallow(const char *);
+struct passwd *mm_getpwnamallow(struct ssh *, const char *);
char *mm_auth2_read_banner(void);
int mm_auth_password(struct ssh *, char *);
int mm_key_allowed(enum mm_keytype, const char *, const char *, struct sshkey *,
int, struct sshauthopt **);
int mm_user_key_allowed(struct ssh *, struct passwd *, struct sshkey *, int,
struct sshauthopt **);
-int mm_hostbased_key_allowed(struct passwd *, const char *,
+int mm_hostbased_key_allowed(struct ssh *, struct passwd *, const char *,
const char *, struct sshkey *);
int mm_sshkey_verify(const struct sshkey *, const u_char *, size_t,
- const u_char *, size_t, const char *, u_int);
+ const u_char *, size_t, const char *, u_int, struct sshkey_sig_details **);
#ifdef GSSAPI
OM_uint32 mm_ssh_gssapi_server_ctx(Gssctxt **, gss_OID);
@@ -65,7 +70,7 @@ OM_uint32 mm_ssh_gssapi_checkmic(Gssctxt *, gss_buffer_t, gss_buffer_t);
#endif
#ifdef USE_PAM
-void mm_start_pam(struct Authctxt *);
+void mm_start_pam(struct ssh *ssh);
u_int mm_do_pam_account(void);
void *mm_sshpam_init_ctx(struct Authctxt *);
int mm_sshpam_query(void *, char **, char **, u_int *, char ***, u_int **);
@@ -75,7 +80,7 @@ void mm_sshpam_free_ctx(void *);
#ifdef SSH_AUDIT_EVENTS
#include "audit.h"
-void mm_audit_event(ssh_audit_event_t);
+void mm_audit_event(struct ssh *, ssh_audit_event_t);
void mm_audit_run_command(const char *);
#endif
@@ -88,10 +93,7 @@ void mm_session_pty_cleanup2(struct Session *);
struct newkeys *mm_newkeys_from_blob(u_char *, int);
int mm_newkeys_to_blob(int, u_char **, u_int *);
-void monitor_clear_keystate(struct monitor *);
-void monitor_apply_keystate(struct monitor *);
-void mm_get_keystate(struct monitor *);
-void mm_send_keystate(struct monitor*);
+void mm_send_keystate(struct ssh *, struct monitor*);
/* bsdauth */
int mm_bsdauth_query(void *, char **, char **, u_int *, char ***, u_int **);
diff --git a/crypto/openssh/msg.c b/crypto/openssh/msg.c
index 1bd20f3d305b..d22c4e477d1c 100644
--- a/crypto/openssh/msg.c
+++ b/crypto/openssh/msg.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: msg.c,v 1.17 2018/07/09 21:59:10 markus Exp $ */
+/* $OpenBSD: msg.c,v 1.20 2020/10/18 11:32:01 djm Exp $ */
/*
* Copyright (c) 2002 Markus Friedl. All rights reserved.
*
@@ -47,16 +47,16 @@ ssh_msg_send(int fd, u_char type, struct sshbuf *m)
u_char buf[5];
u_int mlen = sshbuf_len(m);
- debug3("ssh_msg_send: type %u", (unsigned int)type & 0xff);
+ debug3_f("type %u", (unsigned int)type & 0xff);
put_u32(buf, mlen + 1);
buf[4] = type; /* 1st byte of payload is mesg-type */
if (atomicio(vwrite, fd, buf, sizeof(buf)) != sizeof(buf)) {
- error("ssh_msg_send: write");
+ error_f("write: %s", strerror(errno));
return (-1);
}
if (atomicio(vwrite, fd, sshbuf_mutable_ptr(m), mlen) != mlen) {
- error("ssh_msg_send: write");
+ error_f("write: %s", strerror(errno));
return (-1);
}
return (0);
@@ -73,21 +73,21 @@ ssh_msg_recv(int fd, struct sshbuf *m)
if (atomicio(read, fd, buf, sizeof(buf)) != sizeof(buf)) {
if (errno != EPIPE)
- error("ssh_msg_recv: read: header");
+ error_f("read header: %s", strerror(errno));
return (-1);
}
msg_len = get_u32(buf);
- if (msg_len > 256 * 1024) {
- error("ssh_msg_recv: read: bad msg_len %u", msg_len);
+ if (msg_len > sshbuf_max_size(m)) {
+ error_f("read: bad msg_len %u", msg_len);
return (-1);
}
sshbuf_reset(m);
if ((r = sshbuf_reserve(m, msg_len, &p)) != 0) {
- error("%s: buffer error: %s", __func__, ssh_err(r));
+ error_fr(r, "reserve");
return -1;
}
if (atomicio(read, fd, p, msg_len) != msg_len) {
- error("ssh_msg_recv: read: %s", strerror(errno));
+ error_f("read: %s", strerror(errno));
return (-1);
}
return (0);
diff --git a/crypto/openssh/mux.c b/crypto/openssh/mux.c
index d035fbe75f74..ee26e880c996 100644
--- a/crypto/openssh/mux.c
+++ b/crypto/openssh/mux.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: mux.c,v 1.77 2018/09/26 07:32:44 djm Exp $ */
+/* $OpenBSD: mux.c,v 1.91 2021/07/23 04:00:59 djm Exp $ */
/*
* Copyright (c) 2002-2008 Damien Miller <djm@openbsd.org>
*
@@ -72,9 +72,7 @@ __RCSID("$FreeBSD$");
/* from ssh.c */
extern int tty_flag;
extern Options options;
-extern int stdin_null_flag;
extern char *host;
-extern int subsystem_flag;
extern struct sshbuf *command;
extern volatile sig_atomic_t quit_pending;
@@ -188,20 +186,20 @@ static const struct {
{ 0, NULL }
};
-/* Cleanup callback fired on closure of mux slave _session_ channel */
+/* Cleanup callback fired on closure of mux client _session_ channel */
/* ARGSUSED */
static void
mux_master_session_cleanup_cb(struct ssh *ssh, int cid, void *unused)
{
Channel *cc, *c = channel_by_id(ssh, cid);
- debug3("%s: entering for channel %d", __func__, cid);
+ debug3_f("entering for channel %d", cid);
if (c == NULL)
- fatal("%s: channel_by_id(%i) == NULL", __func__, cid);
+ fatal_f("channel_by_id(%i) == NULL", cid);
if (c->ctl_chan != -1) {
if ((cc = channel_by_id(ssh, c->ctl_chan)) == NULL)
- fatal("%s: channel %d missing control channel %d",
- __func__, c->self, c->ctl_chan);
+ fatal_f("channel %d missing control channel %d",
+ c->self, c->ctl_chan);
c->ctl_chan = -1;
cc->remote_id = 0;
cc->have_remote_id = 0;
@@ -210,26 +208,26 @@ mux_master_session_cleanup_cb(struct ssh *ssh, int cid, void *unused)
channel_cancel_cleanup(ssh, c->self);
}
-/* Cleanup callback fired on closure of mux slave _control_ channel */
+/* Cleanup callback fired on closure of mux client _control_ channel */
/* ARGSUSED */
static void
mux_master_control_cleanup_cb(struct ssh *ssh, int cid, void *unused)
{
Channel *sc, *c = channel_by_id(ssh, cid);
- debug3("%s: entering for channel %d", __func__, cid);
+ debug3_f("entering for channel %d", cid);
if (c == NULL)
- fatal("%s: channel_by_id(%i) == NULL", __func__, cid);
+ fatal_f("channel_by_id(%i) == NULL", cid);
if (c->have_remote_id) {
if ((sc = channel_by_id(ssh, c->remote_id)) == NULL)
- fatal("%s: channel %d missing session channel %u",
- __func__, c->self, c->remote_id);
+ fatal_f("channel %d missing session channel %u",
+ c->self, c->remote_id);
c->remote_id = 0;
c->have_remote_id = 0;
sc->ctl_chan = -1;
if (sc->type != SSH_CHANNEL_OPEN &&
sc->type != SSH_CHANNEL_OPENING) {
- debug2("%s: channel %d: not open", __func__, sc->self);
+ debug2_f("channel %d: not open", sc->self);
chan_mark_dead(ssh, sc);
} else {
if (sc->istate == CHAN_INPUT_OPEN)
@@ -252,7 +250,7 @@ env_permitted(char *env)
return 0;
ret = snprintf(name, sizeof(name), "%.*s", (int)(cp - env), env);
if (ret <= 0 || (size_t)ret >= sizeof(name)) {
- error("%s: name '%.100s...' too long", __func__, env);
+ error_f("name '%.100s...' too long", env);
return 0;
}
@@ -274,21 +272,21 @@ mux_master_process_hello(struct ssh *ssh, u_int rid,
int r;
if (state == NULL)
- fatal("%s: channel %d: c->mux_ctx == NULL", __func__, c->self);
+ fatal_f("channel %d: c->mux_ctx == NULL", c->self);
if (state->hello_rcvd) {
- error("%s: HELLO received twice", __func__);
+ error_f("HELLO received twice");
return -1;
}
if ((r = sshbuf_get_u32(m, &ver)) != 0) {
- error("%s: malformed message: %s", __func__, ssh_err(r));
+ error_fr(r, "parse");
return -1;
}
if (ver != SSHMUX_VER) {
- error("%s: unsupported multiplexing protocol version %u "
- "(expected %u)", __func__, ver, SSHMUX_VER);
+ error_f("unsupported multiplexing protocol version %u "
+ "(expected %u)", ver, SSHMUX_VER);
return -1;
}
- debug2("%s: channel %d slave version %u", __func__, c->self, ver);
+ debug2_f("channel %d client version %u", c->self, ver);
/* No extensions are presently defined */
while (sshbuf_len(m) > 0) {
@@ -297,12 +295,11 @@ mux_master_process_hello(struct ssh *ssh, u_int rid,
if ((r = sshbuf_get_cstring(m, &name, NULL)) != 0 ||
(r = sshbuf_get_string_direct(m, NULL, &value_len)) != 0) {
- error("%s: malformed extension: %s",
- __func__, ssh_err(r));
+ error_fr(r, "parse extension");
return -1;
}
- debug2("%s: Unrecognised extension \"%s\" length %zu",
- __func__, name, value_len);
+ debug2_f("Unrecognised extension \"%s\" length %zu",
+ name, value_len);
free(name);
}
state->hello_rcvd = 1;
@@ -317,7 +314,7 @@ reply_ok(struct sshbuf *reply, u_int rid)
if ((r = sshbuf_put_u32(reply, MUX_S_OK)) != 0 ||
(r = sshbuf_put_u32(reply, rid)) != 0)
- fatal("%s: reply: %s", __func__, ssh_err(r));
+ fatal_fr(r, "reply");
}
/* Enqueue an error response to the reply buffer */
@@ -329,7 +326,7 @@ reply_error(struct sshbuf *reply, u_int type, u_int rid, const char *msg)
if ((r = sshbuf_put_u32(reply, type)) != 0 ||
(r = sshbuf_put_u32(reply, rid)) != 0 ||
(r = sshbuf_put_cstring(reply, msg)) != 0)
- fatal("%s: reply: %s", __func__, ssh_err(r));
+ fatal_fr(r, "reply");
}
static int
@@ -364,7 +361,7 @@ mux_master_process_new_session(struct ssh *ssh, u_int rid,
free(cctx->env);
free(cctx->term);
free(cctx);
- error("%s: malformed message", __func__);
+ error_f("malformed message");
return -1;
}
@@ -381,29 +378,28 @@ mux_master_process_new_session(struct ssh *ssh, u_int rid,
cctx->env[env_len++] = cp;
cctx->env[env_len] = NULL;
if (env_len > MUX_MAX_ENV_VARS) {
- error("%s: >%d environment variables received, "
- "ignoring additional", __func__, MUX_MAX_ENV_VARS);
+ error_f(">%d environment variables received, "
+ "ignoring additional", MUX_MAX_ENV_VARS);
break;
}
}
- debug2("%s: channel %d: request tty %d, X %d, agent %d, subsys %d, "
- "term \"%s\", cmd \"%s\", env %u", __func__, c->self,
+ debug2_f("channel %d: request tty %d, X %d, agent %d, subsys %d, "
+ "term \"%s\", cmd \"%s\", env %u", c->self,
cctx->want_tty, cctx->want_x_fwd, cctx->want_agent_fwd,
cctx->want_subsys, cctx->term, cmd, env_len);
if ((cctx->cmd = sshbuf_new()) == NULL)
- fatal("%s: sshbuf_new", __func__);
+ fatal_f("sshbuf_new");
if ((r = sshbuf_put(cctx->cmd, cmd, strlen(cmd))) != 0)
- fatal("%s: sshbuf_put: %s", __func__, ssh_err(r));
+ fatal_fr(r, "sshbuf_put");
free(cmd);
cmd = NULL;
/* Gather fds from client */
for(i = 0; i < 3; i++) {
if ((new_fd[i] = mm_receive_fd(c->sock)) == -1) {
- error("%s: failed to receive fd %d from slave",
- __func__, i);
+ error_f("failed to receive fd %d from client", i);
for (j = 0; j < i; j++)
close(new_fd[j]);
for (j = 0; j < env_len; j++)
@@ -418,12 +414,12 @@ mux_master_process_new_session(struct ssh *ssh, u_int rid,
}
}
- debug3("%s: got fds stdin %d, stdout %d, stderr %d", __func__,
+ debug3_f("got fds stdin %d, stdout %d, stderr %d",
new_fd[0], new_fd[1], new_fd[2]);
/* XXX support multiple child sessions in future */
if (c->have_remote_id) {
- debug2("%s: session already open", __func__);
+ debug2_f("session already open");
reply_error(reply, MUX_S_FAILURE, rid,
"Multiple sessions not supported");
cleanup:
@@ -444,7 +440,7 @@ mux_master_process_new_session(struct ssh *ssh, u_int rid,
if (options.control_master == SSHCTL_MASTER_ASK ||
options.control_master == SSHCTL_MASTER_AUTO_ASK) {
if (!ask_permission("Allow shared connection to %s? ", host)) {
- debug2("%s: session refused by user", __func__);
+ debug2_f("session refused by user");
reply_error(reply, MUX_S_PERMISSION_DENIED, rid,
"Permission denied");
goto cleanup;
@@ -453,15 +449,7 @@ mux_master_process_new_session(struct ssh *ssh, u_int rid,
/* Try to pick up ttymodes from client before it goes raw */
if (cctx->want_tty && tcgetattr(new_fd[0], &cctx->tio) == -1)
- error("%s: tcgetattr: %s", __func__, strerror(errno));
-
- /* enable nonblocking unless tty */
- if (!isatty(new_fd[0]))
- set_nonblock(new_fd[0]);
- if (!isatty(new_fd[1]))
- set_nonblock(new_fd[1]);
- if (!isatty(new_fd[2]))
- set_nonblock(new_fd[2]);
+ error_f("tcgetattr: %s", strerror(errno));
window = CHAN_SES_WINDOW_DEFAULT;
packetmax = CHAN_SES_PACKET_DEFAULT;
@@ -472,10 +460,10 @@ mux_master_process_new_session(struct ssh *ssh, u_int rid,
nc = channel_new(ssh, "session", SSH_CHANNEL_OPENING,
new_fd[0], new_fd[1], new_fd[2], window, packetmax,
- CHAN_EXTENDED_WRITE, "client-session", /*nonblock*/0);
+ CHAN_EXTENDED_WRITE, "client-session", CHANNEL_NONBLOCK_STDIO);
nc->ctl_chan = c->self; /* link session -> control channel */
- c->remote_id = nc->self; /* link control -> session channel */
+ c->remote_id = nc->self; /* link control -> session channel */
c->have_remote_id = 1;
if (cctx->want_tty && escape_char != 0xffffffff) {
@@ -485,8 +473,8 @@ mux_master_process_new_session(struct ssh *ssh, u_int rid,
client_new_escape_filter_ctx((int)escape_char));
}
- debug2("%s: channel_new: %d linked to control channel %d",
- __func__, nc->self, nc->ctl_chan);
+ debug2_f("channel_new: %d linked to control channel %d",
+ nc->self, nc->ctl_chan);
channel_send_open(ssh, nc->self);
channel_register_open_confirm(ssh, nc->self, mux_session_confirm, cctx);
@@ -504,13 +492,13 @@ mux_master_process_alive_check(struct ssh *ssh, u_int rid,
{
int r;
- debug2("%s: channel %d: alive check", __func__, c->self);
+ debug2_f("channel %d: alive check", c->self);
/* prepare reply */
if ((r = sshbuf_put_u32(reply, MUX_S_ALIVE)) != 0 ||
(r = sshbuf_put_u32(reply, rid)) != 0 ||
(r = sshbuf_put_u32(reply, (u_int)getpid())) != 0)
- fatal("%s: reply: %s", __func__, ssh_err(r));
+ fatal_fr(r, "reply");
return 0;
}
@@ -519,13 +507,13 @@ static int
mux_master_process_terminate(struct ssh *ssh, u_int rid,
Channel *c, struct sshbuf *m, struct sshbuf *reply)
{
- debug2("%s: channel %d: terminate request", __func__, c->self);
+ debug2_f("channel %d: terminate request", c->self);
if (options.control_master == SSHCTL_MASTER_ASK ||
options.control_master == SSHCTL_MASTER_AUTO_ASK) {
if (!ask_permission("Terminate shared connection to %s? ",
host)) {
- debug2("%s: termination refused by user", __func__);
+ debug2_f("termination refused by user");
reply_error(reply, MUX_S_PERMISSION_DENIED, rid,
"Permission denied");
return 0;
@@ -557,7 +545,7 @@ format_forward(u_int ftype, struct Forward *fwd)
xasprintf(&ret, "dynamic forward %.200s:%d -> *",
(fwd->listen_host == NULL) ?
(options.fwd_opts.gateway_ports ? "*" : "LOCALHOST") :
- fwd->listen_host, fwd->listen_port);
+ fwd->listen_host, fwd->listen_port);
break;
case MUX_FWD_REMOTE:
xasprintf(&ret, "remote forward %.200s:%d -> %.200s:%d",
@@ -569,7 +557,7 @@ format_forward(u_int ftype, struct Forward *fwd)
fwd->connect_host, fwd->connect_port);
break;
default:
- fatal("%s: unknown forward type %u", __func__, ftype);
+ fatal_f("unknown forward type %u", ftype);
}
return ret;
}
@@ -611,15 +599,16 @@ mux_confirm_remote_forward(struct ssh *ssh, int type, u_int32_t seq, void *ctxt)
struct Forward *rfwd;
Channel *c;
struct sshbuf *out;
+ u_int port;
int r;
if ((c = channel_by_id(ssh, fctx->cid)) == NULL) {
/* no channel for reply */
- error("%s: unknown channel", __func__);
+ error_f("unknown channel");
return;
}
if ((out = sshbuf_new()) == NULL)
- fatal("%s: sshbuf_new", __func__);
+ fatal_f("sshbuf_new");
if (fctx->fid >= options.num_remote_forwards ||
(options.remote_forwards[fctx->fid].connect_path == NULL &&
options.remote_forwards[fctx->fid].connect_host == NULL)) {
@@ -627,13 +616,20 @@ mux_confirm_remote_forward(struct ssh *ssh, int type, u_int32_t seq, void *ctxt)
goto fail;
}
rfwd = &options.remote_forwards[fctx->fid];
- debug("%s: %s for: listen %d, connect %s:%d", __func__,
+ debug_f("%s for: listen %d, connect %s:%d",
type == SSH2_MSG_REQUEST_SUCCESS ? "success" : "failure",
rfwd->listen_port, rfwd->connect_path ? rfwd->connect_path :
rfwd->connect_host, rfwd->connect_port);
if (type == SSH2_MSG_REQUEST_SUCCESS) {
if (rfwd->listen_port == 0) {
- rfwd->allocated_port = packet_get_int();
+ if ((r = sshpkt_get_u32(ssh, &port)) != 0)
+ fatal_fr(r, "parse port");
+ if (port > 65535) {
+ fatal("Invalid allocated port %u for "
+ "mux remote forward to %s:%d", port,
+ rfwd->connect_host, rfwd->connect_port);
+ }
+ rfwd->allocated_port = (int)port;
debug("Allocated port %u for mux remote forward"
" to %s:%d", rfwd->allocated_port,
rfwd->connect_host, rfwd->connect_port);
@@ -642,9 +638,9 @@ mux_confirm_remote_forward(struct ssh *ssh, int type, u_int32_t seq, void *ctxt)
(r = sshbuf_put_u32(out, fctx->rid)) != 0 ||
(r = sshbuf_put_u32(out,
rfwd->allocated_port)) != 0)
- fatal("%s: reply: %s", __func__, ssh_err(r));
+ fatal_fr(r, "reply");
channel_update_permission(ssh, rfwd->handle,
- rfwd->allocated_port);
+ rfwd->allocated_port);
} else {
reply_ok(out, fctx->rid);
}
@@ -659,8 +655,8 @@ mux_confirm_remote_forward(struct ssh *ssh, int type, u_int32_t seq, void *ctxt)
xasprintf(&failmsg, "remote port forwarding failed for "
"listen port %d", rfwd->listen_port);
- debug2("%s: clearing registered forwarding for listen %d, "
- "connect %s:%d", __func__, rfwd->listen_port,
+ debug2_f("clearing registered forwarding for listen %d, "
+ "connect %s:%d", rfwd->listen_port,
rfwd->connect_path ? rfwd->connect_path :
rfwd->connect_host, rfwd->connect_port);
@@ -671,15 +667,15 @@ mux_confirm_remote_forward(struct ssh *ssh, int type, u_int32_t seq, void *ctxt)
memset(rfwd, 0, sizeof(*rfwd));
}
fail:
- error("%s: %s", __func__, failmsg);
+ error_f("%s", failmsg);
reply_error(out, MUX_S_FAILURE, fctx->rid, failmsg);
free(failmsg);
out:
if ((r = sshbuf_put_stringb(c->output, out)) != 0)
- fatal("%s: sshbuf_put_stringb: %s", __func__, ssh_err(r));
+ fatal_fr(r, "enqueue");
sshbuf_free(out);
if (c->mux_pause <= 0)
- fatal("%s: mux_pause %d", __func__, c->mux_pause);
+ fatal_f("mux_pause %d", c->mux_pause);
c->mux_pause = 0; /* start processing messages again */
}
@@ -704,7 +700,7 @@ mux_master_process_open_fwd(struct ssh *ssh, u_int rid,
(r = sshbuf_get_u32(m, &cport)) != 0 ||
(lport != (u_int)PORT_STREAMLOCAL && lport > 65535) ||
(cport != (u_int)PORT_STREAMLOCAL && cport > 65535)) {
- error("%s: malformed message", __func__);
+ error_f("malformed message");
ret = -1;
goto out;
}
@@ -729,12 +725,12 @@ mux_master_process_open_fwd(struct ssh *ssh, u_int rid,
else
fwd.connect_host = connect_addr;
- debug2("%s: channel %d: request %s", __func__, c->self,
+ debug2_f("channel %d: request %s", c->self,
(fwd_desc = format_forward(ftype, &fwd)));
if (ftype != MUX_FWD_LOCAL && ftype != MUX_FWD_REMOTE &&
ftype != MUX_FWD_DYNAMIC) {
- logit("%s: invalid forwarding type %u", __func__, ftype);
+ logit_f("invalid forwarding type %u", ftype);
invalid:
free(listen_addr);
free(connect_addr);
@@ -743,26 +739,25 @@ mux_master_process_open_fwd(struct ssh *ssh, u_int rid,
return 0;
}
if (ftype == MUX_FWD_DYNAMIC && fwd.listen_path) {
- logit("%s: streamlocal and dynamic forwards "
- "are mutually exclusive", __func__);
+ logit_f("streamlocal and dynamic forwards "
+ "are mutually exclusive");
goto invalid;
}
if (fwd.listen_port != PORT_STREAMLOCAL && fwd.listen_port >= 65536) {
- logit("%s: invalid listen port %u", __func__,
- fwd.listen_port);
+ logit_f("invalid listen port %u", fwd.listen_port);
goto invalid;
}
if ((fwd.connect_port != PORT_STREAMLOCAL &&
fwd.connect_port >= 65536) ||
(ftype != MUX_FWD_DYNAMIC && ftype != MUX_FWD_REMOTE &&
fwd.connect_port == 0)) {
- logit("%s: invalid connect port %u", __func__,
+ logit_f("invalid connect port %u",
fwd.connect_port);
goto invalid;
}
if (ftype != MUX_FWD_DYNAMIC && fwd.connect_host == NULL &&
fwd.connect_path == NULL) {
- logit("%s: missing connect host", __func__);
+ logit_f("missing connect host");
goto invalid;
}
@@ -774,8 +769,7 @@ mux_master_process_open_fwd(struct ssh *ssh, u_int rid,
if (compare_forward(&fwd,
options.local_forwards + i)) {
exists:
- debug2("%s: found existing forwarding",
- __func__);
+ debug2_f("found existing forwarding");
reply_ok(reply, rid);
goto out;
}
@@ -787,13 +781,13 @@ mux_master_process_open_fwd(struct ssh *ssh, u_int rid,
continue;
if (fwd.listen_port != 0)
goto exists;
- debug2("%s: found allocated port", __func__);
+ debug2_f("found allocated port");
if ((r = sshbuf_put_u32(reply,
MUX_S_REMOTE_PORT)) != 0 ||
(r = sshbuf_put_u32(reply, rid)) != 0 ||
(r = sshbuf_put_u32(reply,
options.remote_forwards[i].allocated_port)) != 0)
- fatal("%s: reply: %s", __func__, ssh_err(r));
+ fatal_fr(r, "reply FWD_REMOTE");
goto out;
}
break;
@@ -802,7 +796,7 @@ mux_master_process_open_fwd(struct ssh *ssh, u_int rid,
if (options.control_master == SSHCTL_MASTER_ASK ||
options.control_master == SSHCTL_MASTER_AUTO_ASK) {
if (!ask_permission("Open %s on %s?", fwd_desc, host)) {
- debug2("%s: forwarding refused by user", __func__);
+ debug2_f("forwarding refused by user");
reply_error(reply, MUX_S_PERMISSION_DENIED, rid,
"Permission denied");
goto out;
@@ -813,7 +807,7 @@ mux_master_process_open_fwd(struct ssh *ssh, u_int rid,
if (!channel_setup_local_fwd_listener(ssh, &fwd,
&options.fwd_opts)) {
fail:
- logit("%s: requested %s failed", __func__, fwd_desc);
+ logit_f("requested %s failed", fwd_desc);
reply_error(reply, MUX_S_FAILURE, rid,
"Port forwarding failed");
goto out;
@@ -871,7 +865,7 @@ mux_master_process_close_fwd(struct ssh *ssh, u_int rid,
(r = sshbuf_get_u32(m, &cport)) != 0 ||
(lport != (u_int)PORT_STREAMLOCAL && lport > 65535) ||
(cport != (u_int)PORT_STREAMLOCAL && cport > 65535)) {
- error("%s: malformed message", __func__);
+ error_f("malformed message");
ret = -1;
goto out;
}
@@ -897,7 +891,7 @@ mux_master_process_close_fwd(struct ssh *ssh, u_int rid,
else
fwd.connect_host = connect_addr;
- debug2("%s: channel %d: request cancel %s", __func__, c->self,
+ debug2_f("channel %d: request cancel %s", c->self,
(fwd_desc = format_forward(ftype, &fwd)));
/* make sure this has been requested */
@@ -976,18 +970,16 @@ mux_master_process_stdio_fwd(struct ssh *ssh, u_int rid,
(r = sshbuf_get_cstring(m, &chost, NULL)) != 0 ||
(r = sshbuf_get_u32(m, &cport)) != 0) {
free(chost);
- error("%s: malformed message", __func__);
+ error_f("malformed message");
return -1;
}
- debug2("%s: channel %d: request stdio fwd to %s:%u",
- __func__, c->self, chost, cport);
+ debug2_f("channel %d: stdio fwd to %s:%u", c->self, chost, cport);
/* Gather fds from client */
for(i = 0; i < 2; i++) {
if ((new_fd[i] = mm_receive_fd(c->sock)) == -1) {
- error("%s: failed to receive fd %d from slave",
- __func__, i);
+ error_f("failed to receive fd %d from client", i);
for (j = 0; j < i; j++)
close(new_fd[j]);
free(chost);
@@ -999,12 +991,11 @@ mux_master_process_stdio_fwd(struct ssh *ssh, u_int rid,
}
}
- debug3("%s: got fds stdin %d, stdout %d", __func__,
- new_fd[0], new_fd[1]);
+ debug3_f("got fds stdin %d, stdout %d", new_fd[0], new_fd[1]);
/* XXX support multiple child sessions in future */
if (c->have_remote_id) {
- debug2("%s: session already open", __func__);
+ debug2_f("session already open");
reply_error(reply, MUX_S_FAILURE, rid,
"Multiple sessions not supported");
cleanup:
@@ -1018,28 +1009,22 @@ mux_master_process_stdio_fwd(struct ssh *ssh, u_int rid,
options.control_master == SSHCTL_MASTER_AUTO_ASK) {
if (!ask_permission("Allow forward to %s:%u? ",
chost, cport)) {
- debug2("%s: stdio fwd refused by user", __func__);
+ debug2_f("stdio fwd refused by user");
reply_error(reply, MUX_S_PERMISSION_DENIED, rid,
"Permission denied");
goto cleanup;
}
}
- /* enable nonblocking unless tty */
- if (!isatty(new_fd[0]))
- set_nonblock(new_fd[0]);
- if (!isatty(new_fd[1]))
- set_nonblock(new_fd[1]);
-
- nc = channel_connect_stdio_fwd(ssh, chost, cport, new_fd[0], new_fd[1]);
+ nc = channel_connect_stdio_fwd(ssh, chost, cport, new_fd[0], new_fd[1],
+ CHANNEL_NONBLOCK_STDIO);
free(chost);
nc->ctl_chan = c->self; /* link session -> control channel */
- c->remote_id = nc->self; /* link control -> session channel */
+ c->remote_id = nc->self; /* link control -> session channel */
c->have_remote_id = 1;
- debug2("%s: channel_new: %d linked to control channel %d",
- __func__, nc->self, nc->ctl_chan);
+ debug2_f("channel_new: %d control %d", nc->self, nc->ctl_chan);
channel_register_cleanup(ssh, nc->self,
mux_master_session_cleanup_cb, 1);
@@ -1063,38 +1048,38 @@ mux_stdio_confirm(struct ssh *ssh, int id, int success, void *arg)
int r;
if (cctx == NULL)
- fatal("%s: cctx == NULL", __func__);
+ fatal_f("cctx == NULL");
if ((c = channel_by_id(ssh, id)) == NULL)
- fatal("%s: no channel for id %d", __func__, id);
+ fatal_f("no channel for id %d", id);
if ((cc = channel_by_id(ssh, c->ctl_chan)) == NULL)
- fatal("%s: channel %d lacks control channel %d", __func__,
+ fatal_f("channel %d lacks control channel %d",
id, c->ctl_chan);
if ((reply = sshbuf_new()) == NULL)
- fatal("%s: sshbuf_new", __func__);
+ fatal_f("sshbuf_new");
if (!success) {
- debug3("%s: sending failure reply", __func__);
+ debug3_f("sending failure reply");
reply_error(reply, MUX_S_FAILURE, cctx->rid,
"Session open refused by peer");
/* prepare reply */
goto done;
}
- debug3("%s: sending success reply", __func__);
+ debug3_f("sending success reply");
/* prepare reply */
if ((r = sshbuf_put_u32(reply, MUX_S_SESSION_OPENED)) != 0 ||
(r = sshbuf_put_u32(reply, cctx->rid)) != 0 ||
(r = sshbuf_put_u32(reply, c->self)) != 0)
- fatal("%s: reply: %s", __func__, ssh_err(r));
+ fatal_fr(r, "reply");
done:
/* Send reply */
if ((r = sshbuf_put_stringb(cc->output, reply)) != 0)
- fatal("%s: sshbuf_put_stringb: %s", __func__, ssh_err(r));
+ fatal_fr(r, "enqueue");
sshbuf_free(reply);
if (cc->mux_pause <= 0)
- fatal("%s: mux_pause %d", __func__, cc->mux_pause);
+ fatal_f("mux_pause %d", cc->mux_pause);
cc->mux_pause = 0; /* start processing messages again */
c->open_confirm_ctx = NULL;
free(cctx);
@@ -1104,13 +1089,13 @@ static int
mux_master_process_stop_listening(struct ssh *ssh, u_int rid,
Channel *c, struct sshbuf *m, struct sshbuf *reply)
{
- debug("%s: channel %d: stop listening", __func__, c->self);
+ debug_f("channel %d: stop listening", c->self);
if (options.control_master == SSHCTL_MASTER_ASK ||
options.control_master == SSHCTL_MASTER_AUTO_ASK) {
if (!ask_permission("Disable further multiplexing on shared "
"connection to %s? ", host)) {
- debug2("%s: stop listen refused by user", __func__);
+ debug2_f("stop listen refused by user");
reply_error(reply, MUX_S_PERMISSION_DENIED, rid,
"Permission denied");
return 0;
@@ -1136,17 +1121,17 @@ mux_master_process_proxy(struct ssh *ssh, u_int rid,
{
int r;
- debug("%s: channel %d: proxy request", __func__, c->self);
+ debug_f("channel %d: proxy request", c->self);
c->mux_rcb = channel_proxy_downstream;
if ((r = sshbuf_put_u32(reply, MUX_S_PROXY)) != 0 ||
(r = sshbuf_put_u32(reply, rid)) != 0)
- fatal("%s: reply: %s", __func__, ssh_err(r));
+ fatal_fr(r, "reply");
return 0;
}
-/* Channel callbacks fired on read/write from mux slave fd */
+/* Channel callbacks fired on read/write from mux client fd */
static int
mux_master_read_cb(struct ssh *ssh, Channel *c)
{
@@ -1156,7 +1141,7 @@ mux_master_read_cb(struct ssh *ssh, Channel *c)
int r, ret = -1;
if ((out = sshbuf_new()) == NULL)
- fatal("%s: sshbuf_new", __func__);
+ fatal_f("sshbuf_new");
/* Setup ctx and */
if (c->mux_ctx == NULL) {
@@ -1168,12 +1153,11 @@ mux_master_read_cb(struct ssh *ssh, Channel *c)
/* Send hello */
if ((r = sshbuf_put_u32(out, MUX_MSG_HELLO)) != 0 ||
(r = sshbuf_put_u32(out, SSHMUX_VER)) != 0)
- fatal("%s: reply: %s", __func__, ssh_err(r));
+ fatal_fr(r, "reply");
/* no extensions */
if ((r = sshbuf_put_stringb(c->output, out)) != 0)
- fatal("%s: sshbuf_put_stringb: %s",
- __func__, ssh_err(r));
- debug3("%s: channel %d: hello sent", __func__, c->self);
+ fatal_fr(r, "enqueue");
+ debug3_f("channel %d: hello sent", c->self);
ret = 0;
goto out;
}
@@ -1181,21 +1165,21 @@ mux_master_read_cb(struct ssh *ssh, Channel *c)
/* Channel code ensures that we receive whole packets */
if ((r = sshbuf_froms(c->input, &in)) != 0) {
malf:
- error("%s: malformed message", __func__);
+ error_f("malformed message");
goto out;
}
if ((r = sshbuf_get_u32(in, &type)) != 0)
goto malf;
- debug3("%s: channel %d packet type 0x%08x len %zu",
- __func__, c->self, type, sshbuf_len(in));
+ debug3_f("channel %d packet type 0x%08x len %zu", c->self,
+ type, sshbuf_len(in));
if (type == MUX_MSG_HELLO)
rid = 0;
else {
if (!state->hello_rcvd) {
- error("%s: expected MUX_MSG_HELLO(0x%08x), "
- "received 0x%08x", __func__, MUX_MSG_HELLO, type);
+ error_f("expected MUX_MSG_HELLO(0x%08x), "
+ "received 0x%08x", MUX_MSG_HELLO, type);
goto out;
}
if ((r = sshbuf_get_u32(in, &rid)) != 0)
@@ -1210,16 +1194,14 @@ mux_master_read_cb(struct ssh *ssh, Channel *c)
}
}
if (mux_master_handlers[i].handler == NULL) {
- error("%s: unsupported mux message 0x%08x", __func__, type);
+ error_f("unsupported mux message 0x%08x", type);
reply_error(out, MUX_S_FAILURE, rid, "unsupported request");
ret = 0;
}
/* Enqueue reply packet */
- if (sshbuf_len(out) != 0) {
- if ((r = sshbuf_put_stringb(c->output, out)) != 0)
- fatal("%s: sshbuf_put_stringb: %s",
- __func__, ssh_err(r));
- }
+ if (sshbuf_len(out) != 0 &&
+ (r = sshbuf_put_stringb(c->output, out)) != 0)
+ fatal_fr(r, "enqueue");
out:
sshbuf_free(in);
sshbuf_free(out);
@@ -1233,21 +1215,19 @@ mux_exit_message(struct ssh *ssh, Channel *c, int exitval)
Channel *mux_chan;
int r;
- debug3("%s: channel %d: exit message, exitval %d", __func__, c->self,
- exitval);
+ debug3_f("channel %d: exit message, exitval %d", c->self, exitval);
if ((mux_chan = channel_by_id(ssh, c->ctl_chan)) == NULL)
- fatal("%s: channel %d missing mux channel %d",
- __func__, c->self, c->ctl_chan);
+ fatal_f("channel %d missing mux %d", c->self, c->ctl_chan);
/* Append exit message packet to control socket output queue */
if ((m = sshbuf_new()) == NULL)
- fatal("%s: sshbuf_new", __func__);
+ fatal_f("sshbuf_new");
if ((r = sshbuf_put_u32(m, MUX_S_EXIT_MESSAGE)) != 0 ||
(r = sshbuf_put_u32(m, c->self)) != 0 ||
(r = sshbuf_put_u32(m, exitval)) != 0 ||
(r = sshbuf_put_stringb(mux_chan->output, m)) != 0)
- fatal("%s: reply: %s", __func__, ssh_err(r));
+ fatal_fr(r, "reply");
sshbuf_free(m);
}
@@ -1258,19 +1238,18 @@ mux_tty_alloc_failed(struct ssh *ssh, Channel *c)
Channel *mux_chan;
int r;
- debug3("%s: channel %d: TTY alloc failed", __func__, c->self);
+ debug3_f("channel %d: TTY alloc failed", c->self);
if ((mux_chan = channel_by_id(ssh, c->ctl_chan)) == NULL)
- fatal("%s: channel %d missing mux channel %d",
- __func__, c->self, c->ctl_chan);
+ fatal_f("channel %d missing mux %d", c->self, c->ctl_chan);
/* Append exit message packet to control socket output queue */
if ((m = sshbuf_new()) == NULL)
- fatal("%s: sshbuf_new", __func__);
+ fatal_f("sshbuf_new");
if ((r = sshbuf_put_u32(m, MUX_S_TTY_ALLOC_FAIL)) != 0 ||
(r = sshbuf_put_u32(m, c->self)) != 0 ||
(r = sshbuf_put_stringb(mux_chan->output, m)) != 0)
- fatal("%s: reply: %s", __func__, ssh_err(r));
+ fatal_fr(r, "reply");
sshbuf_free(m);
}
@@ -1305,7 +1284,7 @@ muxserver_listen(struct ssh *ssh)
rbuf[sizeof(rbuf) - 1] = '\0';
options.control_path = NULL;
xasprintf(&options.control_path, "%s.%s", orig_control_path, rbuf);
- debug3("%s: temporary control path %s", __func__, options.control_path);
+ debug3_f("temporary control path %s", options.control_path);
old_umask = umask(0177);
muxserver_sock = unix_listener(options.control_path, 64, 0);
@@ -1334,7 +1313,7 @@ muxserver_listen(struct ssh *ssh)
/* Now atomically "move" the mux socket into position */
if (link(options.control_path, orig_control_path) != 0) {
if (errno != EEXIST) {
- fatal("%s: link mux listener %s => %s: %s", __func__,
+ fatal_f("link mux listener %s => %s: %s",
options.control_path, orig_control_path,
strerror(errno));
}
@@ -1354,7 +1333,7 @@ muxserver_listen(struct ssh *ssh)
CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT,
0, options.control_path, 1);
mux_listener_channel->mux_rcb = mux_master_read_cb;
- debug3("%s: mux listener channel %d fd %d", __func__,
+ debug3_f("mux listener channel %d fd %d",
mux_listener_channel->self, mux_listener_channel->sock);
}
@@ -1369,17 +1348,17 @@ mux_session_confirm(struct ssh *ssh, int id, int success, void *arg)
struct sshbuf *reply;
if (cctx == NULL)
- fatal("%s: cctx == NULL", __func__);
+ fatal_f("cctx == NULL");
if ((c = channel_by_id(ssh, id)) == NULL)
- fatal("%s: no channel for id %d", __func__, id);
+ fatal_f("no channel for id %d", id);
if ((cc = channel_by_id(ssh, c->ctl_chan)) == NULL)
- fatal("%s: channel %d lacks control channel %d", __func__,
+ fatal_f("channel %d lacks control channel %d",
id, c->ctl_chan);
if ((reply = sshbuf_new()) == NULL)
- fatal("%s: sshbuf_new", __func__);
+ fatal_f("sshbuf_new");
if (!success) {
- debug3("%s: sending failure reply", __func__);
+ debug3_f("sending failure reply");
reply_error(reply, MUX_S_FAILURE, cctx->rid,
"Session open refused by peer");
goto done;
@@ -1407,27 +1386,28 @@ mux_session_confirm(struct ssh *ssh, int id, int success, void *arg)
if (cctx->want_agent_fwd && options.forward_agent) {
debug("Requesting authentication agent forwarding.");
channel_request_start(ssh, id, "auth-agent-req@openssh.com", 0);
- packet_send();
+ if ((r = sshpkt_send(ssh)) != 0)
+ fatal_fr(r, "send");
}
client_session2_setup(ssh, id, cctx->want_tty, cctx->want_subsys,
cctx->term, &cctx->tio, c->rfd, cctx->cmd, cctx->env);
- debug3("%s: sending success reply", __func__);
+ debug3_f("sending success reply");
/* prepare reply */
if ((r = sshbuf_put_u32(reply, MUX_S_SESSION_OPENED)) != 0 ||
(r = sshbuf_put_u32(reply, cctx->rid)) != 0 ||
(r = sshbuf_put_u32(reply, c->self)) != 0)
- fatal("%s: reply: %s", __func__, ssh_err(r));
+ fatal_fr(r, "reply");
done:
/* Send reply */
if ((r = sshbuf_put_stringb(cc->output, reply)) != 0)
- fatal("%s: sshbuf_put_stringb: %s", __func__, ssh_err(r));
+ fatal_fr(r, "enqueue");
sshbuf_free(reply);
if (cc->mux_pause <= 0)
- fatal("%s: mux_pause %d", __func__, cc->mux_pause);
+ fatal_f("mux_pause %d", cc->mux_pause);
cc->mux_pause = 0; /* start processing messages again */
c->open_confirm_ctx = NULL;
sshbuf_free(cctx->cmd);
@@ -1476,14 +1456,14 @@ mux_client_read(int fd, struct sshbuf *b, size_t need)
pfd.fd = fd;
pfd.events = POLLIN;
if ((r = sshbuf_reserve(b, need, &p)) != 0)
- fatal("%s: reserve: %s", __func__, ssh_err(r));
+ fatal_fr(r, "reserve");
for (have = 0; have < need; ) {
if (muxclient_terminate) {
errno = EINTR;
return -1;
}
len = read(fd, p + have, need - have);
- if (len < 0) {
+ if (len == -1) {
switch (errno) {
#if defined(EWOULDBLOCK) && (EWOULDBLOCK != EAGAIN)
case EWOULDBLOCK:
@@ -1518,9 +1498,9 @@ mux_client_write_packet(int fd, struct sshbuf *m)
pfd.fd = fd;
pfd.events = POLLOUT;
if ((queue = sshbuf_new()) == NULL)
- fatal("%s: sshbuf_new", __func__);
+ fatal_f("sshbuf_new");
if ((r = sshbuf_put_stringb(queue, m)) != 0)
- fatal("%s: sshbuf_put_stringb: %s", __func__, ssh_err(r));
+ fatal_fr(r, "enqueue");
need = sshbuf_len(queue);
ptr = sshbuf_ptr(queue);
@@ -1532,7 +1512,7 @@ mux_client_write_packet(int fd, struct sshbuf *m)
return -1;
}
len = write(fd, ptr + have, need - have);
- if (len < 0) {
+ if (len == -1) {
switch (errno) {
#if defined(EWOULDBLOCK) && (EWOULDBLOCK != EAGAIN)
case EWOULDBLOCK:
@@ -1569,10 +1549,10 @@ mux_client_read_packet(int fd, struct sshbuf *m)
int r, oerrno;
if ((queue = sshbuf_new()) == NULL)
- fatal("%s: sshbuf_new", __func__);
+ fatal_f("sshbuf_new");
if (mux_client_read(fd, queue, 4) != 0) {
if ((oerrno = errno) == EPIPE)
- debug3("%s: read header failed: %s", __func__,
+ debug3_f("read header failed: %s",
strerror(errno));
sshbuf_free(queue);
errno = oerrno;
@@ -1581,14 +1561,14 @@ mux_client_read_packet(int fd, struct sshbuf *m)
need = PEEK_U32(sshbuf_ptr(queue));
if (mux_client_read(fd, queue, need) != 0) {
oerrno = errno;
- debug3("%s: read body failed: %s", __func__, strerror(errno));
+ debug3_f("read body failed: %s", strerror(errno));
sshbuf_free(queue);
errno = oerrno;
return -1;
}
if ((r = sshbuf_get_string_direct(queue, &ptr, &have)) != 0 ||
(r = sshbuf_put(m, ptr, have)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "dequeue");
sshbuf_free(queue);
return 0;
}
@@ -1601,14 +1581,14 @@ mux_client_hello_exchange(int fd)
int r, ret = -1;
if ((m = sshbuf_new()) == NULL)
- fatal("%s: sshbuf_new", __func__);
+ fatal_f("sshbuf_new");
if ((r = sshbuf_put_u32(m, MUX_MSG_HELLO)) != 0 ||
(r = sshbuf_put_u32(m, SSHMUX_VER)) != 0)
- fatal("%s: hello: %s", __func__, ssh_err(r));
+ fatal_fr(r, "assemble hello");
/* no extensions */
if (mux_client_write_packet(fd, m) != 0) {
- debug("%s: write packet: %s", __func__, strerror(errno));
+ debug_f("write packet: %s", strerror(errno));
goto out;
}
@@ -1616,33 +1596,31 @@ mux_client_hello_exchange(int fd)
/* Read their HELLO */
if (mux_client_read_packet(fd, m) != 0) {
- debug("%s: read packet failed", __func__);
+ debug_f("read packet failed");
goto out;
}
if ((r = sshbuf_get_u32(m, &type)) != 0)
- fatal("%s: decode type: %s", __func__, ssh_err(r));
+ fatal_fr(r, "parse type");
if (type != MUX_MSG_HELLO) {
- error("%s: expected HELLO (%u) received %u",
- __func__, MUX_MSG_HELLO, type);
+ error_f("expected HELLO (%u) got %u", MUX_MSG_HELLO, type);
goto out;
}
if ((r = sshbuf_get_u32(m, &ver)) != 0)
- fatal("%s: decode version: %s", __func__, ssh_err(r));
+ fatal_fr(r, "parse version");
if (ver != SSHMUX_VER) {
error("Unsupported multiplexing protocol version %d "
"(expected %d)", ver, SSHMUX_VER);
goto out;
}
- debug2("%s: master version %u", __func__, ver);
+ debug2_f("master version %u", ver);
/* No extensions are presently defined */
while (sshbuf_len(m) > 0) {
char *name = NULL;
if ((r = sshbuf_get_cstring(m, &name, NULL)) != 0 ||
(r = sshbuf_skip_string(m)) != 0) { /* value */
- error("%s: malformed extension: %s",
- __func__, ssh_err(r));
+ error_fr(r, "parse extension");
goto out;
}
debug2("Unrecognised master extension \"%s\"", name);
@@ -1663,16 +1641,16 @@ mux_client_request_alive(int fd)
u_int pid, type, rid;
int r;
- debug3("%s: entering", __func__);
+ debug3_f("entering");
if ((m = sshbuf_new()) == NULL)
- fatal("%s: sshbuf_new", __func__);
+ fatal_f("sshbuf_new");
if ((r = sshbuf_put_u32(m, MUX_C_ALIVE_CHECK)) != 0 ||
(r = sshbuf_put_u32(m, muxclient_request_id)) != 0)
- fatal("%s: request: %s", __func__, ssh_err(r));
+ fatal_fr(r, "assemble");
if (mux_client_write_packet(fd, m) != 0)
- fatal("%s: write packet: %s", __func__, strerror(errno));
+ fatal_f("write packet: %s", strerror(errno));
sshbuf_reset(m);
@@ -1683,23 +1661,23 @@ mux_client_request_alive(int fd)
}
if ((r = sshbuf_get_u32(m, &type)) != 0)
- fatal("%s: decode type: %s", __func__, ssh_err(r));
+ fatal_fr(r, "parse type");
if (type != MUX_S_ALIVE) {
if ((r = sshbuf_get_cstring(m, &e, NULL)) != 0)
- fatal("%s: decode error: %s", __func__, ssh_err(r));
- fatal("%s: master returned error: %s", __func__, e);
+ fatal_fr(r, "parse error message");
+ fatal_f("master returned error: %s", e);
}
if ((r = sshbuf_get_u32(m, &rid)) != 0)
- fatal("%s: decode remote ID: %s", __func__, ssh_err(r));
+ fatal_fr(r, "parse remote ID");
if (rid != muxclient_request_id)
- fatal("%s: out of sequence reply: my id %u theirs %u",
- __func__, muxclient_request_id, rid);
+ fatal_f("out of sequence reply: my id %u theirs %u",
+ muxclient_request_id, rid);
if ((r = sshbuf_get_u32(m, &pid)) != 0)
- fatal("%s: decode PID: %s", __func__, ssh_err(r));
+ fatal_fr(r, "parse PID");
sshbuf_free(m);
- debug3("%s: done pid = %u", __func__, pid);
+ debug3_f("done pid = %u", pid);
muxclient_request_id++;
@@ -1714,16 +1692,16 @@ mux_client_request_terminate(int fd)
u_int type, rid;
int r;
- debug3("%s: entering", __func__);
+ debug3_f("entering");
if ((m = sshbuf_new()) == NULL)
- fatal("%s: sshbuf_new", __func__);
+ fatal_f("sshbuf_new");
if ((r = sshbuf_put_u32(m, MUX_C_TERMINATE)) != 0 ||
(r = sshbuf_put_u32(m, muxclient_request_id)) != 0)
- fatal("%s: request: %s", __func__, ssh_err(r));
+ fatal_fr(r, "request");
if (mux_client_write_packet(fd, m) != 0)
- fatal("%s: write packet: %s", __func__, strerror(errno));
+ fatal_f("write packet: %s", strerror(errno));
sshbuf_reset(m);
@@ -1734,30 +1712,28 @@ mux_client_request_terminate(int fd)
sshbuf_free(m);
return;
}
- fatal("%s: read from master failed: %s",
- __func__, strerror(errno));
+ fatal_f("read from master failed: %s", strerror(errno));
}
if ((r = sshbuf_get_u32(m, &type)) != 0 ||
(r = sshbuf_get_u32(m, &rid)) != 0)
- fatal("%s: decode: %s", __func__, ssh_err(r));
+ fatal_fr(r, "parse");
if (rid != muxclient_request_id)
- fatal("%s: out of sequence reply: my id %u theirs %u",
- __func__, muxclient_request_id, rid);
+ fatal_f("out of sequence reply: my id %u theirs %u",
+ muxclient_request_id, rid);
switch (type) {
case MUX_S_OK:
break;
case MUX_S_PERMISSION_DENIED:
if ((r = sshbuf_get_cstring(m, &e, NULL)) != 0)
- fatal("%s: decode error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "parse error message");
fatal("Master refused termination request: %s", e);
case MUX_S_FAILURE:
if ((r = sshbuf_get_cstring(m, &e, NULL)) != 0)
- fatal("%s: decode error: %s", __func__, ssh_err(r));
- fatal("%s: termination request failed: %s", __func__, e);
+ fatal_fr(r, "parse error message");
+ fatal_f("termination request failed: %s", e);
default:
- fatal("%s: unexpected response from master 0x%08x",
- __func__, type);
+ fatal_f("unexpected response from master 0x%08x", type);
}
sshbuf_free(m);
muxclient_request_id++;
@@ -1795,7 +1771,7 @@ mux_client_forward(int fd, int cancel_flag, u_int ftype, struct Forward *fwd)
chost = fwd->connect_host;
if ((m = sshbuf_new()) == NULL)
- fatal("%s: sshbuf_new", __func__);
+ fatal_f("sshbuf_new");
if ((r = sshbuf_put_u32(m, type)) != 0 ||
(r = sshbuf_put_u32(m, muxclient_request_id)) != 0 ||
(r = sshbuf_put_u32(m, ftype)) != 0 ||
@@ -1803,10 +1779,10 @@ mux_client_forward(int fd, int cancel_flag, u_int ftype, struct Forward *fwd)
(r = sshbuf_put_u32(m, fwd->listen_port)) != 0 ||
(r = sshbuf_put_cstring(m, chost)) != 0 ||
(r = sshbuf_put_u32(m, fwd->connect_port)) != 0)
- fatal("%s: request: %s", __func__, ssh_err(r));
+ fatal_fr(r, "request");
if (mux_client_write_packet(fd, m) != 0)
- fatal("%s: write packet: %s", __func__, strerror(errno));
+ fatal_f("write packet: %s", strerror(errno));
sshbuf_reset(m);
@@ -1818,19 +1794,19 @@ mux_client_forward(int fd, int cancel_flag, u_int ftype, struct Forward *fwd)
if ((r = sshbuf_get_u32(m, &type)) != 0 ||
(r = sshbuf_get_u32(m, &rid)) != 0)
- fatal("%s: decode: %s", __func__, ssh_err(r));
+ fatal_fr(r, "parse");
if (rid != muxclient_request_id)
- fatal("%s: out of sequence reply: my id %u theirs %u",
- __func__, muxclient_request_id, rid);
+ fatal_f("out of sequence reply: my id %u theirs %u",
+ muxclient_request_id, rid);
switch (type) {
case MUX_S_OK:
break;
case MUX_S_REMOTE_PORT:
if (cancel_flag)
- fatal("%s: got MUX_S_REMOTE_PORT for cancel", __func__);
+ fatal_f("got MUX_S_REMOTE_PORT for cancel");
if ((r = sshbuf_get_u32(m, &fwd->allocated_port)) != 0)
- fatal("%s: decode port: %s", __func__, ssh_err(r));
+ fatal_fr(r, "parse port");
verbose("Allocated port %u for remote forward to %s:%d",
fwd->allocated_port,
fwd->connect_host ? fwd->connect_host : "",
@@ -1840,19 +1816,18 @@ mux_client_forward(int fd, int cancel_flag, u_int ftype, struct Forward *fwd)
break;
case MUX_S_PERMISSION_DENIED:
if ((r = sshbuf_get_cstring(m, &e, NULL)) != 0)
- fatal("%s: decode error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "parse error message");
sshbuf_free(m);
error("Master refused forwarding request: %s", e);
return -1;
case MUX_S_FAILURE:
if ((r = sshbuf_get_cstring(m, &e, NULL)) != 0)
- fatal("%s: decode error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "parse error message");
sshbuf_free(m);
- error("%s: forwarding request failed: %s", __func__, e);
+ error_f("forwarding request failed: %s", e);
return -1;
default:
- fatal("%s: unexpected response from master 0x%08x",
- __func__, type);
+ fatal_f("unexpected response from master 0x%08x", type);
}
sshbuf_free(m);
@@ -1865,7 +1840,7 @@ mux_client_forwards(int fd, int cancel_flag)
{
int i, ret = 0;
- debug3("%s: %s forwardings: %d local, %d remote", __func__,
+ debug3_f("%s forwardings: %d local, %d remote",
cancel_flag ? "cancel" : "request",
options.num_local_forwards, options.num_remote_forwards);
@@ -1890,48 +1865,44 @@ mux_client_request_session(int fd)
{
struct sshbuf *m;
char *e;
- const char *term;
+ const char *term = NULL;
u_int echar, rid, sid, esid, exitval, type, exitval_seen;
extern char **environ;
- int r, i, devnull, rawmode;
+ int r, i, rawmode;
- debug3("%s: entering", __func__);
+ debug3_f("entering");
if ((muxserver_pid = mux_client_request_alive(fd)) == 0) {
- error("%s: master alive request failed", __func__);
+ error_f("master alive request failed");
return -1;
}
- signal(SIGPIPE, SIG_IGN);
+ ssh_signal(SIGPIPE, SIG_IGN);
- if (stdin_null_flag) {
- if ((devnull = open(_PATH_DEVNULL, O_RDONLY)) == -1)
- fatal("open(/dev/null): %s", strerror(errno));
- if (dup2(devnull, STDIN_FILENO) == -1)
- fatal("dup2: %s", strerror(errno));
- if (devnull > STDERR_FILENO)
- close(devnull);
- }
+ if (options.stdin_null && stdfd_devnull(1, 0, 0) == -1)
+ fatal_f("stdfd_devnull failed");
+
+ if ((term = lookup_env_in_list("TERM", options.setenv,
+ options.num_setenv)) == NULL || *term == '\0')
+ term = getenv("TERM");
- if ((term = getenv("TERM")) == NULL)
- term = "";
echar = 0xffffffff;
if (options.escape_char != SSH_ESCAPECHAR_NONE)
echar = (u_int)options.escape_char;
if ((m = sshbuf_new()) == NULL)
- fatal("%s: sshbuf_new", __func__);
+ fatal_f("sshbuf_new");
if ((r = sshbuf_put_u32(m, MUX_C_NEW_SESSION)) != 0 ||
(r = sshbuf_put_u32(m, muxclient_request_id)) != 0 ||
(r = sshbuf_put_string(m, NULL, 0)) != 0 || /* reserved */
(r = sshbuf_put_u32(m, tty_flag)) != 0 ||
(r = sshbuf_put_u32(m, options.forward_x11)) != 0 ||
(r = sshbuf_put_u32(m, options.forward_agent)) != 0 ||
- (r = sshbuf_put_u32(m, subsystem_flag)) != 0 ||
+ (r = sshbuf_put_u32(m, options.session_type == SESSION_TYPE_SUBSYSTEM)) != 0 ||
(r = sshbuf_put_u32(m, echar)) != 0 ||
- (r = sshbuf_put_cstring(m, term)) != 0 ||
+ (r = sshbuf_put_cstring(m, term == NULL ? "" : term)) != 0 ||
(r = sshbuf_put_stringb(m, command)) != 0)
- fatal("%s: request: %s", __func__, ssh_err(r));
+ fatal_fr(r, "request");
/* Pass environment */
if (options.num_send_env > 0 && environ != NULL) {
@@ -1939,74 +1910,73 @@ mux_client_request_session(int fd)
if (!env_permitted(environ[i]))
continue;
if ((r = sshbuf_put_cstring(m, environ[i])) != 0)
- fatal("%s: request: %s", __func__, ssh_err(r));
+ fatal_fr(r, "request sendenv");
}
}
for (i = 0; i < options.num_setenv; i++) {
if ((r = sshbuf_put_cstring(m, options.setenv[i])) != 0)
- fatal("%s: request: %s", __func__, ssh_err(r));
+ fatal_fr(r, "request setenv");
}
if (mux_client_write_packet(fd, m) != 0)
- fatal("%s: write packet: %s", __func__, strerror(errno));
+ fatal_f("write packet: %s", strerror(errno));
/* Send the stdio file descriptors */
if (mm_send_fd(fd, STDIN_FILENO) == -1 ||
mm_send_fd(fd, STDOUT_FILENO) == -1 ||
mm_send_fd(fd, STDERR_FILENO) == -1)
- fatal("%s: send fds failed", __func__);
+ fatal_f("send fds failed");
- debug3("%s: session request sent", __func__);
+ debug3_f("session request sent");
/* Read their reply */
sshbuf_reset(m);
if (mux_client_read_packet(fd, m) != 0) {
- error("%s: read from master failed: %s",
- __func__, strerror(errno));
+ error_f("read from master failed: %s", strerror(errno));
sshbuf_free(m);
return -1;
}
if ((r = sshbuf_get_u32(m, &type)) != 0 ||
(r = sshbuf_get_u32(m, &rid)) != 0)
- fatal("%s: decode: %s", __func__, ssh_err(r));
+ fatal_fr(r, "parse");
if (rid != muxclient_request_id)
- fatal("%s: out of sequence reply: my id %u theirs %u",
- __func__, muxclient_request_id, rid);
+ fatal_f("out of sequence reply: my id %u theirs %u",
+ muxclient_request_id, rid);
switch (type) {
case MUX_S_SESSION_OPENED:
if ((r = sshbuf_get_u32(m, &sid)) != 0)
- fatal("%s: decode ID: %s", __func__, ssh_err(r));
+ fatal_fr(r, "parse session ID");
+ debug_f("master session id: %u", sid);
break;
case MUX_S_PERMISSION_DENIED:
if ((r = sshbuf_get_cstring(m, &e, NULL)) != 0)
- fatal("%s: decode error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "parse error message");
error("Master refused session request: %s", e);
sshbuf_free(m);
return -1;
case MUX_S_FAILURE:
if ((r = sshbuf_get_cstring(m, &e, NULL)) != 0)
- fatal("%s: decode error: %s", __func__, ssh_err(r));
- error("%s: session request failed: %s", __func__, e);
+ fatal_fr(r, "parse error message");
+ error_f("session request failed: %s", e);
sshbuf_free(m);
return -1;
default:
sshbuf_free(m);
- error("%s: unexpected response from master 0x%08x",
- __func__, type);
+ error_f("unexpected response from master 0x%08x", type);
return -1;
}
muxclient_request_id++;
if (pledge("stdio proc tty", NULL) == -1)
- fatal("%s pledge(): %s", __func__, strerror(errno));
+ fatal_f("pledge(): %s", strerror(errno));
platform_pledge_mux();
- signal(SIGHUP, control_client_sighandler);
- signal(SIGINT, control_client_sighandler);
- signal(SIGTERM, control_client_sighandler);
- signal(SIGWINCH, control_client_sigrelay);
+ ssh_signal(SIGHUP, control_client_sighandler);
+ ssh_signal(SIGINT, control_client_sighandler);
+ ssh_signal(SIGTERM, control_client_sighandler);
+ ssh_signal(SIGWINCH, control_client_sigrelay);
rawmode = tty_flag;
if (tty_flag)
@@ -2024,40 +1994,34 @@ mux_client_request_session(int fd)
if (mux_client_read_packet(fd, m) != 0)
break;
if ((r = sshbuf_get_u32(m, &type)) != 0)
- fatal("%s: decode type: %s", __func__, ssh_err(r));
+ fatal_fr(r, "parse type");
switch (type) {
case MUX_S_TTY_ALLOC_FAIL:
if ((r = sshbuf_get_u32(m, &esid)) != 0)
- fatal("%s: decode ID: %s",
- __func__, ssh_err(r));
+ fatal_fr(r, "parse session ID");
if (esid != sid)
- fatal("%s: tty alloc fail on unknown session: "
- "my id %u theirs %u",
- __func__, sid, esid);
+ fatal_f("tty alloc fail on unknown session: "
+ "my id %u theirs %u", sid, esid);
leave_raw_mode(options.request_tty ==
REQUEST_TTY_FORCE);
rawmode = 0;
continue;
case MUX_S_EXIT_MESSAGE:
if ((r = sshbuf_get_u32(m, &esid)) != 0)
- fatal("%s: decode ID: %s",
- __func__, ssh_err(r));
+ fatal_fr(r, "parse session ID");
if (esid != sid)
- fatal("%s: exit on unknown session: "
- "my id %u theirs %u",
- __func__, sid, esid);
+ fatal_f("exit on unknown session: "
+ "my id %u theirs %u", sid, esid);
if (exitval_seen)
- fatal("%s: exitval sent twice", __func__);
+ fatal_f("exitval sent twice");
if ((r = sshbuf_get_u32(m, &exitval)) != 0)
- fatal("%s: decode exit value: %s",
- __func__, ssh_err(r));
+ fatal_fr(r, "parse exitval");
exitval_seen = 1;
continue;
default:
if ((r = sshbuf_get_cstring(m, &e, NULL)) != 0)
- fatal("%s: decode error: %s",
- __func__, ssh_err(r));
- fatal("%s: master returned error: %s", __func__, e);
+ fatal_fr(r, "parse error message");
+ fatal_f("master returned error: %s", e);
}
}
@@ -2089,12 +2053,12 @@ mux_client_proxy(int fd)
int r;
if ((m = sshbuf_new()) == NULL)
- fatal("%s: sshbuf_new", __func__);
+ fatal_f("sshbuf_new");
if ((r = sshbuf_put_u32(m, MUX_C_PROXY)) != 0 ||
(r = sshbuf_put_u32(m, muxclient_request_id)) != 0)
- fatal("%s: request: %s", __func__, ssh_err(r));
+ fatal_fr(r, "request");
if (mux_client_write_packet(fd, m) != 0)
- fatal("%s: write packet: %s", __func__, strerror(errno));
+ fatal_f("write packet: %s", strerror(errno));
sshbuf_reset(m);
@@ -2105,18 +2069,18 @@ mux_client_proxy(int fd)
}
if ((r = sshbuf_get_u32(m, &type)) != 0 ||
(r = sshbuf_get_u32(m, &rid)) != 0)
- fatal("%s: decode: %s", __func__, ssh_err(r));
+ fatal_fr(r, "parse");
if (rid != muxclient_request_id)
- fatal("%s: out of sequence reply: my id %u theirs %u",
- __func__, muxclient_request_id, rid);
+ fatal_f("out of sequence reply: my id %u theirs %u",
+ muxclient_request_id, rid);
if (type != MUX_S_PROXY) {
if ((r = sshbuf_get_cstring(m, &e, NULL)) != 0)
- fatal("%s: decode error: %s", __func__, ssh_err(r));
- fatal("%s: master returned error: %s", __func__, e);
+ fatal_fr(r, "parse error message");
+ fatal_f("master returned error: %s", e);
}
sshbuf_free(m);
- debug3("%s: done", __func__);
+ debug3_f("done");
muxclient_request_id++;
return 0;
}
@@ -2127,93 +2091,85 @@ mux_client_request_stdio_fwd(int fd)
struct sshbuf *m;
char *e;
u_int type, rid, sid;
- int r, devnull;
+ int r;
- debug3("%s: entering", __func__);
+ debug3_f("entering");
if ((muxserver_pid = mux_client_request_alive(fd)) == 0) {
- error("%s: master alive request failed", __func__);
+ error_f("master alive request failed");
return -1;
}
- signal(SIGPIPE, SIG_IGN);
+ ssh_signal(SIGPIPE, SIG_IGN);
- if (stdin_null_flag) {
- if ((devnull = open(_PATH_DEVNULL, O_RDONLY)) == -1)
- fatal("open(/dev/null): %s", strerror(errno));
- if (dup2(devnull, STDIN_FILENO) == -1)
- fatal("dup2: %s", strerror(errno));
- if (devnull > STDERR_FILENO)
- close(devnull);
- }
+ if (options.stdin_null && stdfd_devnull(1, 0, 0) == -1)
+ fatal_f("stdfd_devnull failed");
if ((m = sshbuf_new()) == NULL)
- fatal("%s: sshbuf_new", __func__);
+ fatal_f("sshbuf_new");
if ((r = sshbuf_put_u32(m, MUX_C_NEW_STDIO_FWD)) != 0 ||
(r = sshbuf_put_u32(m, muxclient_request_id)) != 0 ||
(r = sshbuf_put_string(m, NULL, 0)) != 0 || /* reserved */
(r = sshbuf_put_cstring(m, options.stdio_forward_host)) != 0 ||
(r = sshbuf_put_u32(m, options.stdio_forward_port)) != 0)
- fatal("%s: request: %s", __func__, ssh_err(r));
+ fatal_fr(r, "request");
if (mux_client_write_packet(fd, m) != 0)
- fatal("%s: write packet: %s", __func__, strerror(errno));
+ fatal_f("write packet: %s", strerror(errno));
/* Send the stdio file descriptors */
if (mm_send_fd(fd, STDIN_FILENO) == -1 ||
mm_send_fd(fd, STDOUT_FILENO) == -1)
- fatal("%s: send fds failed", __func__);
+ fatal_f("send fds failed");
if (pledge("stdio proc tty", NULL) == -1)
- fatal("%s pledge(): %s", __func__, strerror(errno));
+ fatal_f("pledge(): %s", strerror(errno));
platform_pledge_mux();
- debug3("%s: stdio forward request sent", __func__);
+ debug3_f("stdio forward request sent");
/* Read their reply */
sshbuf_reset(m);
if (mux_client_read_packet(fd, m) != 0) {
- error("%s: read from master failed: %s",
- __func__, strerror(errno));
+ error_f("read from master failed: %s", strerror(errno));
sshbuf_free(m);
return -1;
}
if ((r = sshbuf_get_u32(m, &type)) != 0 ||
(r = sshbuf_get_u32(m, &rid)) != 0)
- fatal("%s: decode: %s", __func__, ssh_err(r));
+ fatal_fr(r, "parse");
if (rid != muxclient_request_id)
- fatal("%s: out of sequence reply: my id %u theirs %u",
- __func__, muxclient_request_id, rid);
+ fatal_f("out of sequence reply: my id %u theirs %u",
+ muxclient_request_id, rid);
switch (type) {
case MUX_S_SESSION_OPENED:
if ((r = sshbuf_get_u32(m, &sid)) != 0)
- fatal("%s: decode ID: %s", __func__, ssh_err(r));
- debug("%s: master session id: %u", __func__, sid);
+ fatal_fr(r, "parse session ID");
+ debug_f("master session id: %u", sid);
break;
case MUX_S_PERMISSION_DENIED:
if ((r = sshbuf_get_cstring(m, &e, NULL)) != 0)
- fatal("%s: decode error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "parse error message");
sshbuf_free(m);
fatal("Master refused stdio forwarding request: %s", e);
case MUX_S_FAILURE:
if ((r = sshbuf_get_cstring(m, &e, NULL)) != 0)
- fatal("%s: decode error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "parse error message");
sshbuf_free(m);
fatal("Stdio forwarding request failed: %s", e);
default:
sshbuf_free(m);
- error("%s: unexpected response from master 0x%08x",
- __func__, type);
+ error_f("unexpected response from master 0x%08x", type);
return -1;
}
muxclient_request_id++;
- signal(SIGHUP, control_client_sighandler);
- signal(SIGINT, control_client_sighandler);
- signal(SIGTERM, control_client_sighandler);
- signal(SIGWINCH, control_client_sigrelay);
+ ssh_signal(SIGHUP, control_client_sighandler);
+ ssh_signal(SIGINT, control_client_sighandler);
+ ssh_signal(SIGTERM, control_client_sighandler);
+ ssh_signal(SIGWINCH, control_client_sigrelay);
/*
* Stick around until the controlee closes the client_fd.
@@ -2223,10 +2179,9 @@ mux_client_request_stdio_fwd(int fd)
if (errno == EPIPE ||
(errno == EINTR && muxclient_terminate != 0))
return 0;
- fatal("%s: mux_client_read_packet: %s",
- __func__, strerror(errno));
+ fatal_f("mux_client_read_packet: %s", strerror(errno));
}
- fatal("%s: master returned unexpected message %u", __func__, type);
+ fatal_f("master returned unexpected message %u", type);
}
static void
@@ -2237,45 +2192,43 @@ mux_client_request_stop_listening(int fd)
u_int type, rid;
int r;
- debug3("%s: entering", __func__);
+ debug3_f("entering");
if ((m = sshbuf_new()) == NULL)
- fatal("%s: sshbuf_new", __func__);
+ fatal_f("sshbuf_new");
if ((r = sshbuf_put_u32(m, MUX_C_STOP_LISTENING)) != 0 ||
(r = sshbuf_put_u32(m, muxclient_request_id)) != 0)
- fatal("%s: request: %s", __func__, ssh_err(r));
+ fatal_fr(r, "request");
if (mux_client_write_packet(fd, m) != 0)
- fatal("%s: write packet: %s", __func__, strerror(errno));
+ fatal_f("write packet: %s", strerror(errno));
sshbuf_reset(m);
/* Read their reply */
if (mux_client_read_packet(fd, m) != 0)
- fatal("%s: read from master failed: %s",
- __func__, strerror(errno));
+ fatal_f("read from master failed: %s", strerror(errno));
if ((r = sshbuf_get_u32(m, &type)) != 0 ||
(r = sshbuf_get_u32(m, &rid)) != 0)
- fatal("%s: decode: %s", __func__, ssh_err(r));
+ fatal_fr(r, "parse");
if (rid != muxclient_request_id)
- fatal("%s: out of sequence reply: my id %u theirs %u",
- __func__, muxclient_request_id, rid);
+ fatal_f("out of sequence reply: my id %u theirs %u",
+ muxclient_request_id, rid);
switch (type) {
case MUX_S_OK:
break;
case MUX_S_PERMISSION_DENIED:
if ((r = sshbuf_get_cstring(m, &e, NULL)) != 0)
- fatal("%s: decode error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "parse error message");
fatal("Master refused stop listening request: %s", e);
case MUX_S_FAILURE:
if ((r = sshbuf_get_cstring(m, &e, NULL)) != 0)
- fatal("%s: decode error: %s", __func__, ssh_err(r));
- fatal("%s: stop listening request failed: %s", __func__, e);
+ fatal_fr(r, "parse error message");
+ fatal_f("stop listening request failed: %s", e);
default:
- fatal("%s: unexpected response from master 0x%08x",
- __func__, type);
+ fatal_f("unexpected response from master 0x%08x", type);
}
sshbuf_free(m);
muxclient_request_id++;
@@ -2313,10 +2266,10 @@ muxclient(const char *path)
if (strlcpy(addr.sun_path, path,
sizeof(addr.sun_path)) >= sizeof(addr.sun_path))
fatal("ControlPath too long ('%s' >= %u bytes)", path,
- (unsigned int)sizeof(addr.sun_path));
+ (unsigned int)sizeof(addr.sun_path));
- if ((sock = socket(PF_UNIX, SOCK_STREAM, 0)) < 0)
- fatal("%s socket(): %s", __func__, strerror(errno));
+ if ((sock = socket(PF_UNIX, SOCK_STREAM, 0)) == -1)
+ fatal_f("socket(): %s", strerror(errno));
if (connect(sock, (struct sockaddr *)&addr, sizeof(addr)) == -1) {
switch (muxclient_command) {
@@ -2343,7 +2296,7 @@ muxclient(const char *path)
set_nonblock(sock);
if (mux_client_hello_exchange(sock) != 0) {
- error("%s: master hello exchange failed", __func__);
+ error_f("master hello exchange failed");
close(sock);
return -1;
}
@@ -2351,7 +2304,7 @@ muxclient(const char *path)
switch (muxclient_command) {
case SSHMUX_COMMAND_ALIVE_CHECK:
if ((pid = mux_client_request_alive(sock)) == 0)
- fatal("%s: master alive check failed", __func__);
+ fatal_f("master alive check failed");
fprintf(stderr, "Master running (pid=%u)\r\n", pid);
exit(0);
case SSHMUX_COMMAND_TERMINATE:
@@ -2361,11 +2314,11 @@ muxclient(const char *path)
exit(0);
case SSHMUX_COMMAND_FORWARD:
if (mux_client_forwards(sock, 0) != 0)
- fatal("%s: master forward request failed", __func__);
+ fatal_f("master forward request failed");
exit(0);
case SSHMUX_COMMAND_OPEN:
if (mux_client_forwards(sock, 0) != 0) {
- error("%s: master forward request failed", __func__);
+ error_f("master forward request failed");
return -1;
}
mux_client_request_session(sock);
@@ -2380,8 +2333,7 @@ muxclient(const char *path)
exit(0);
case SSHMUX_COMMAND_CANCEL_FWD:
if (mux_client_forwards(sock, 1) != 0)
- error("%s: master cancel forward request failed",
- __func__);
+ error_f("master cancel forward request failed");
exit(0);
case SSHMUX_COMMAND_PROXY:
mux_client_proxy(sock);
diff --git a/crypto/openssh/myproposal.h b/crypto/openssh/myproposal.h
index 27b4a15a1279..f03b7dfd0df9 100644
--- a/crypto/openssh/myproposal.h
+++ b/crypto/openssh/myproposal.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: myproposal.h,v 1.57 2018/09/12 01:34:02 djm Exp $ */
+/* $OpenBSD: myproposal.h,v 1.68 2020/10/03 04:15:06 djm Exp $ */
/*
* Copyright (c) 2000 Markus Friedl. All rights reserved.
@@ -24,108 +24,47 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#include <openssl/opensslv.h>
-
-/* conditional algorithm support */
-
-#ifdef OPENSSL_HAS_ECC
-#ifdef OPENSSL_HAS_NISTP521
-# define KEX_ECDH_METHODS \
+#define KEX_SERVER_KEX \
+ "curve25519-sha256," \
+ "curve25519-sha256@libssh.org," \
"ecdh-sha2-nistp256," \
"ecdh-sha2-nistp384," \
- "ecdh-sha2-nistp521,"
-# define HOSTKEY_ECDSA_CERT_METHODS \
- "ecdsa-sha2-nistp256-cert-v01@openssh.com," \
- "ecdsa-sha2-nistp384-cert-v01@openssh.com," \
- "ecdsa-sha2-nistp521-cert-v01@openssh.com,"
-# define HOSTKEY_ECDSA_METHODS \
- "ecdsa-sha2-nistp256," \
- "ecdsa-sha2-nistp384," \
- "ecdsa-sha2-nistp521,"
-#else
-# define KEX_ECDH_METHODS \
- "ecdh-sha2-nistp256," \
- "ecdh-sha2-nistp384,"
-# define HOSTKEY_ECDSA_CERT_METHODS \
- "ecdsa-sha2-nistp256-cert-v01@openssh.com," \
- "ecdsa-sha2-nistp384-cert-v01@openssh.com,"
-# define HOSTKEY_ECDSA_METHODS \
- "ecdsa-sha2-nistp256," \
- "ecdsa-sha2-nistp384,"
-#endif
-#else
-# define KEX_ECDH_METHODS
-# define HOSTKEY_ECDSA_CERT_METHODS
-# define HOSTKEY_ECDSA_METHODS
-#endif
-
-#ifdef OPENSSL_HAVE_EVPGCM
-# define AESGCM_CIPHER_MODES \
- ",aes128-gcm@openssh.com,aes256-gcm@openssh.com"
-#else
-# define AESGCM_CIPHER_MODES
-#endif
-
-#ifdef HAVE_EVP_SHA256
-# define KEX_SHA2_METHODS \
+ "ecdh-sha2-nistp521," \
"diffie-hellman-group-exchange-sha256," \
"diffie-hellman-group16-sha512," \
- "diffie-hellman-group18-sha512,"
-# define KEX_SHA2_GROUP14 \
- "diffie-hellman-group14-sha256,"
-#define SHA2_HMAC_MODES \
- "hmac-sha2-256," \
- "hmac-sha2-512,"
-#else
-# define KEX_SHA2_METHODS
-# define KEX_SHA2_GROUP14
-# define SHA2_HMAC_MODES
-#endif
+ "diffie-hellman-group18-sha512," \
+ "diffie-hellman-group14-sha256"
-#ifdef WITH_OPENSSL
-# ifdef HAVE_EVP_SHA256
-# define KEX_CURVE25519_METHODS \
- "curve25519-sha256," \
- "curve25519-sha256@libssh.org,"
-# else
-# define KEX_CURVE25519_METHODS ""
-# endif
-#define KEX_COMMON_KEX \
- KEX_CURVE25519_METHODS \
- KEX_ECDH_METHODS \
- KEX_SHA2_METHODS
-
-#define KEX_SERVER_KEX KEX_COMMON_KEX \
- KEX_SHA2_GROUP14 \
- "diffie-hellman-group14-sha1" \
-
-#define KEX_CLIENT_KEX KEX_COMMON_KEX \
- "diffie-hellman-group-exchange-sha1," \
- KEX_SHA2_GROUP14 \
- "diffie-hellman-group14-sha1"
+#define KEX_CLIENT_KEX KEX_SERVER_KEX
#define KEX_DEFAULT_PK_ALG \
- HOSTKEY_ECDSA_CERT_METHODS \
"ssh-ed25519-cert-v01@openssh.com," \
+ "ecdsa-sha2-nistp256-cert-v01@openssh.com," \
+ "ecdsa-sha2-nistp384-cert-v01@openssh.com," \
+ "ecdsa-sha2-nistp521-cert-v01@openssh.com," \
+ "sk-ssh-ed25519-cert-v01@openssh.com," \
+ "sk-ecdsa-sha2-nistp256-cert-v01@openssh.com," \
"rsa-sha2-512-cert-v01@openssh.com," \
"rsa-sha2-256-cert-v01@openssh.com," \
"ssh-rsa-cert-v01@openssh.com," \
- HOSTKEY_ECDSA_METHODS \
"ssh-ed25519," \
+ "ecdsa-sha2-nistp256," \
+ "ecdsa-sha2-nistp384," \
+ "ecdsa-sha2-nistp521," \
+ "sk-ssh-ed25519@openssh.com," \
+ "sk-ecdsa-sha2-nistp256@openssh.com," \
"rsa-sha2-512," \
"rsa-sha2-256," \
"ssh-rsa"
-/* the actual algorithms */
-
-#define KEX_SERVER_ENCRYPT \
+#define KEX_SERVER_ENCRYPT \
"chacha20-poly1305@openssh.com," \
- "aes128-ctr,aes192-ctr,aes256-ctr" \
- AESGCM_CIPHER_MODES
+ "aes128-ctr,aes192-ctr,aes256-ctr," \
+ "aes128-gcm@openssh.com,aes256-gcm@openssh.com"
#define KEX_CLIENT_ENCRYPT KEX_SERVER_ENCRYPT
-#define KEX_SERVER_MAC \
+#define KEX_SERVER_MAC \
"umac-64-etm@openssh.com," \
"umac-128-etm@openssh.com," \
"hmac-sha2-256-etm@openssh.com," \
@@ -141,44 +80,14 @@
/* Not a KEX value, but here so all the algorithm defaults are together */
#define SSH_ALLOWED_CA_SIGALGS \
+ "ssh-ed25519," \
"ecdsa-sha2-nistp256," \
"ecdsa-sha2-nistp384," \
"ecdsa-sha2-nistp521," \
- "ssh-ed25519," \
+ "sk-ssh-ed25519@openssh.com," \
+ "sk-ecdsa-sha2-nistp256@openssh.com," \
"rsa-sha2-512," \
- "rsa-sha2-256," \
- "ssh-rsa"
-
-#else /* WITH_OPENSSL */
-
-#define KEX_SERVER_KEX \
- "curve25519-sha256," \
- "curve25519-sha256@libssh.org"
-#define KEX_DEFAULT_PK_ALG \
- "ssh-ed25519-cert-v01@openssh.com," \
- "ssh-ed25519"
-#define KEX_SERVER_ENCRYPT \
- "chacha20-poly1305@openssh.com," \
- "aes128-ctr,aes192-ctr,aes256-ctr"
-#define KEX_SERVER_MAC \
- "umac-64-etm@openssh.com," \
- "umac-128-etm@openssh.com," \
- "hmac-sha2-256-etm@openssh.com," \
- "hmac-sha2-512-etm@openssh.com," \
- "hmac-sha1-etm@openssh.com," \
- "umac-64@openssh.com," \
- "umac-128@openssh.com," \
- "hmac-sha2-256," \
- "hmac-sha2-512," \
- "hmac-sha1"
-
-#define KEX_CLIENT_KEX KEX_SERVER_KEX
-#define KEX_CLIENT_ENCRYPT KEX_SERVER_ENCRYPT
-#define KEX_CLIENT_MAC KEX_SERVER_MAC
-
-#define SSH_ALLOWED_CA_SIGALGS "ssh-ed25519"
-
-#endif /* WITH_OPENSSL */
+ "rsa-sha2-256"
#define KEX_DEFAULT_COMP "none,zlib@openssh.com"
#define KEX_DEFAULT_LANG ""
@@ -206,4 +115,3 @@
KEX_DEFAULT_COMP, \
KEX_DEFAULT_LANG, \
KEX_DEFAULT_LANG
-
diff --git a/crypto/openssh/nchan.c b/crypto/openssh/nchan.c
index 8294d7fcad1d..7ef3a350b79a 100644
--- a/crypto/openssh/nchan.c
+++ b/crypto/openssh/nchan.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: nchan.c,v 1.69 2018/10/04 07:47:35 djm Exp $ */
+/* $OpenBSD: nchan.c,v 1.73 2021/05/19 01:24:05 djm Exp $ */
/*
* Copyright (c) 1999, 2000, 2001, 2002 Markus Friedl. All rights reserved.
*
@@ -185,12 +185,11 @@ chan_send_eof2(struct ssh *ssh, Channel *c)
switch (c->istate) {
case CHAN_INPUT_WAIT_DRAIN:
if (!c->have_remote_id)
- fatal("%s: channel %d: no remote_id",
- __func__, c->self);
+ fatal_f("channel %d: no remote_id", c->self);
if ((r = sshpkt_start(ssh, SSH2_MSG_CHANNEL_EOF)) != 0 ||
(r = sshpkt_put_u32(ssh, c->remote_id)) != 0 ||
(r = sshpkt_send(ssh)) != 0)
- fatal("%s: send CHANNEL_EOF: %s", __func__, ssh_err(r));
+ fatal_fr(r, "send CHANNEL_EOF");
c->flags |= CHAN_EOF_SENT;
break;
default:
@@ -214,12 +213,11 @@ chan_send_close2(struct ssh *ssh, Channel *c)
error("channel %d: already sent close", c->self);
} else {
if (!c->have_remote_id)
- fatal("%s: channel %d: no remote_id",
- __func__, c->self);
+ fatal_f("channel %d: no remote_id", c->self);
if ((r = sshpkt_start(ssh, SSH2_MSG_CHANNEL_CLOSE)) != 0 ||
(r = sshpkt_put_u32(ssh, c->remote_id)) != 0 ||
(r = sshpkt_send(ssh)) != 0)
- fatal("%s: send CHANNEL_EOF: %s", __func__, ssh_err(r));
+ fatal_fr(r, "send CHANNEL_EOF");
c->flags |= CHAN_CLOSE_SENT;
}
}
@@ -235,16 +233,16 @@ chan_send_eow2(struct ssh *ssh, Channel *c)
c->self);
return;
}
- if (!(datafellows & SSH_NEW_OPENSSH))
+ if (!(ssh->compat & SSH_NEW_OPENSSH))
return;
if (!c->have_remote_id)
- fatal("%s: channel %d: no remote_id", __func__, c->self);
+ fatal_f("channel %d: no remote_id", c->self);
if ((r = sshpkt_start(ssh, SSH2_MSG_CHANNEL_REQUEST)) != 0 ||
(r = sshpkt_put_u32(ssh, c->remote_id)) != 0 ||
(r = sshpkt_put_cstring(ssh, "eow@openssh.com")) != 0 ||
(r = sshpkt_put_u8(ssh, 0)) != 0 ||
(r = sshpkt_send(ssh)) != 0)
- fatal("%s: send CHANNEL_EOF: %s", __func__, ssh_err(r));
+ fatal_fr(r, "send CHANNEL_EOF");
}
/* shared */
@@ -336,7 +334,7 @@ chan_is_dead(struct ssh *ssh, Channel *c, int do_send)
}
if (c->istate != CHAN_INPUT_CLOSED || c->ostate != CHAN_OUTPUT_CLOSED)
return 0;
- if ((datafellows & SSH_BUG_EXTEOF) &&
+ if ((ssh->compat & SSH_BUG_EXTEOF) &&
c->extended_usage == CHAN_EXTENDED_WRITE &&
c->efd != -1 &&
sshbuf_len(c->extended) > 0) {
@@ -376,22 +374,20 @@ chan_shutdown_write(struct ssh *ssh, Channel *c)
if (c->type == SSH_CHANNEL_LARVAL)
return;
/* shutdown failure is allowed if write failed already */
- debug2("channel %d: %s (i%d o%d sock %d wfd %d efd %d [%s])",
- c->self, __func__, c->istate, c->ostate, c->sock, c->wfd, c->efd,
+ debug2_f("channel %d: (i%d o%d sock %d wfd %d efd %d [%s])",
+ c->self, c->istate, c->ostate, c->sock, c->wfd, c->efd,
channel_format_extended_usage(c));
if (c->sock != -1) {
- if (shutdown(c->sock, SHUT_WR) < 0) {
- debug2("channel %d: %s: shutdown() failed for "
- "fd %d [i%d o%d]: %.100s", c->self, __func__,
- c->sock, c->istate, c->ostate,
- strerror(errno));
+ if (shutdown(c->sock, SHUT_WR) == -1) {
+ debug2_f("channel %d: shutdown() failed for "
+ "fd %d [i%d o%d]: %.100s", c->self, c->sock,
+ c->istate, c->ostate, strerror(errno));
}
} else {
- if (channel_close_fd(ssh, &c->wfd) < 0) {
- logit("channel %d: %s: close() failed for "
- "fd %d [i%d o%d]: %.100s",
- c->self, __func__, c->wfd, c->istate, c->ostate,
- strerror(errno));
+ if (channel_close_fd(ssh, c, &c->wfd) < 0) {
+ logit_f("channel %d: close() failed for "
+ "fd %d [i%d o%d]: %.100s", c->self, c->wfd,
+ c->istate, c->ostate, strerror(errno));
}
}
}
@@ -401,8 +397,8 @@ chan_shutdown_read(struct ssh *ssh, Channel *c)
{
if (c->type == SSH_CHANNEL_LARVAL)
return;
- debug2("channel %d: %s (i%d o%d sock %d wfd %d efd %d [%s])",
- c->self, __func__, c->istate, c->ostate, c->sock, c->rfd, c->efd,
+ debug2_f("channel %d: (i%d o%d sock %d wfd %d efd %d [%s])",
+ c->self, c->istate, c->ostate, c->sock, c->rfd, c->efd,
channel_format_extended_usage(c));
if (c->sock != -1) {
/*
@@ -410,18 +406,16 @@ chan_shutdown_read(struct ssh *ssh, Channel *c)
* write side has been closed already. (bug on Linux)
* HP-UX may return ENOTCONN also.
*/
- if (shutdown(c->sock, SHUT_RD) < 0 && errno != ENOTCONN) {
- error("channel %d: %s: shutdown() failed for "
- "fd %d [i%d o%d]: %.100s",
- c->self, __func__, c->sock, c->istate, c->ostate,
- strerror(errno));
+ if (shutdown(c->sock, SHUT_RD) == -1 && errno != ENOTCONN) {
+ error_f("channel %d: shutdown() failed for "
+ "fd %d [i%d o%d]: %.100s", c->self, c->sock,
+ c->istate, c->ostate, strerror(errno));
}
} else {
- if (channel_close_fd(ssh, &c->rfd) < 0) {
- logit("channel %d: %s: close() failed for "
- "fd %d [i%d o%d]: %.100s",
- c->self, __func__, c->rfd, c->istate, c->ostate,
- strerror(errno));
+ if (channel_close_fd(ssh, c, &c->rfd) < 0) {
+ logit_f("channel %d: close() failed for "
+ "fd %d [i%d o%d]: %.100s", c->self, c->rfd,
+ c->istate, c->ostate, strerror(errno));
}
}
}
@@ -434,13 +428,12 @@ chan_shutdown_extended_read(struct ssh *ssh, Channel *c)
if (c->extended_usage != CHAN_EXTENDED_READ &&
c->extended_usage != CHAN_EXTENDED_IGNORE)
return;
- debug2("channel %d: %s (i%d o%d sock %d wfd %d efd %d [%s])",
- c->self, __func__, c->istate, c->ostate, c->sock, c->rfd, c->efd,
+ debug_f("channel %d: (i%d o%d sock %d wfd %d efd %d [%s])",
+ c->self, c->istate, c->ostate, c->sock, c->rfd, c->efd,
channel_format_extended_usage(c));
- if (channel_close_fd(ssh, &c->efd) < 0) {
- logit("channel %d: %s: close() failed for "
- "extended fd %d [i%d o%d]: %.100s",
- c->self, __func__, c->efd, c->istate, c->ostate,
- strerror(errno));
+ if (channel_close_fd(ssh, c, &c->efd) < 0) {
+ logit_f("channel %d: close() failed for "
+ "extended fd %d [i%d o%d]: %.100s", c->self, c->efd,
+ c->istate, c->ostate, strerror(errno));
}
}
diff --git a/crypto/openssh/opacket.c b/crypto/openssh/opacket.c
deleted file mode 100644
index e637d7a71b5b..000000000000
--- a/crypto/openssh/opacket.c
+++ /dev/null
@@ -1,320 +0,0 @@
-/* $OpenBSD: opacket.c,v 1.7 2017/10/20 01:56:39 djm Exp $ */
-/* Written by Markus Friedl. Placed in the public domain. */
-
-#include "includes.h"
-
-#include <stdarg.h>
-
-#include "ssherr.h"
-#include "packet.h"
-#include "log.h"
-
-struct ssh *active_state, *backup_state;
-
-/* Map old to new API */
-
-void
-ssh_packet_start(struct ssh *ssh, u_char type)
-{
- int r;
-
- if ((r = sshpkt_start(ssh, type)) != 0)
- fatal("%s: %s", __func__, ssh_err(r));
-}
-
-void
-ssh_packet_put_char(struct ssh *ssh, int value)
-{
- u_char ch = value;
- int r;
-
- if ((r = sshpkt_put_u8(ssh, ch)) != 0)
- fatal("%s: %s", __func__, ssh_err(r));
-}
-
-void
-ssh_packet_put_int(struct ssh *ssh, u_int value)
-{
- int r;
-
- if ((r = sshpkt_put_u32(ssh, value)) != 0)
- fatal("%s: %s", __func__, ssh_err(r));
-}
-
-void
-ssh_packet_put_int64(struct ssh *ssh, u_int64_t value)
-{
- int r;
-
- if ((r = sshpkt_put_u64(ssh, value)) != 0)
- fatal("%s: %s", __func__, ssh_err(r));
-}
-
-void
-ssh_packet_put_string(struct ssh *ssh, const void *buf, u_int len)
-{
- int r;
-
- if ((r = sshpkt_put_string(ssh, buf, len)) != 0)
- fatal("%s: %s", __func__, ssh_err(r));
-}
-
-void
-ssh_packet_put_cstring(struct ssh *ssh, const char *str)
-{
- int r;
-
- if ((r = sshpkt_put_cstring(ssh, str)) != 0)
- fatal("%s: %s", __func__, ssh_err(r));
-}
-
-void
-ssh_packet_put_raw(struct ssh *ssh, const void *buf, u_int len)
-{
- int r;
-
- if ((r = sshpkt_put(ssh, buf, len)) != 0)
- fatal("%s: %s", __func__, ssh_err(r));
-}
-
-
-#ifdef WITH_OPENSSL
-void
-ssh_packet_put_bignum2(struct ssh *ssh, BIGNUM * value)
-{
- int r;
-
- if ((r = sshpkt_put_bignum2(ssh, value)) != 0)
- fatal("%s: %s", __func__, ssh_err(r));
-}
-
-# ifdef OPENSSL_HAS_ECC
-void
-ssh_packet_put_ecpoint(struct ssh *ssh, const EC_GROUP *curve,
- const EC_POINT *point)
-{
- int r;
-
- if ((r = sshpkt_put_ec(ssh, point, curve)) != 0)
- fatal("%s: %s", __func__, ssh_err(r));
-}
-# endif
-#endif /* WITH_OPENSSL */
-
-void
-ssh_packet_send(struct ssh *ssh)
-{
- int r;
-
- if ((r = sshpkt_send(ssh)) != 0)
- fatal("%s: %s", __func__, ssh_err(r));
-}
-
-u_int
-ssh_packet_get_char(struct ssh *ssh)
-{
- u_char ch;
- int r;
-
- if ((r = sshpkt_get_u8(ssh, &ch)) != 0)
- fatal("%s: %s", __func__, ssh_err(r));
- return ch;
-}
-
-u_int
-ssh_packet_get_int(struct ssh *ssh)
-{
- u_int val;
- int r;
-
- if ((r = sshpkt_get_u32(ssh, &val)) != 0)
- fatal("%s: %s", __func__, ssh_err(r));
- return val;
-}
-
-u_int64_t
-ssh_packet_get_int64(struct ssh *ssh)
-{
- u_int64_t val;
- int r;
-
- if ((r = sshpkt_get_u64(ssh, &val)) != 0)
- fatal("%s: %s", __func__, ssh_err(r));
- return val;
-}
-
-
-#ifdef WITH_OPENSSL
-void
-ssh_packet_get_bignum2(struct ssh *ssh, BIGNUM * value)
-{
- int r;
-
- if ((r = sshpkt_get_bignum2(ssh, value)) != 0)
- fatal("%s: %s", __func__, ssh_err(r));
-}
-
-# ifdef OPENSSL_HAS_ECC
-void
-ssh_packet_get_ecpoint(struct ssh *ssh, const EC_GROUP *curve, EC_POINT *point)
-{
- int r;
-
- if ((r = sshpkt_get_ec(ssh, point, curve)) != 0)
- fatal("%s: %s", __func__, ssh_err(r));
-}
-# endif
-#endif /* WITH_OPENSSL */
-
-void *
-ssh_packet_get_string(struct ssh *ssh, u_int *length_ptr)
-{
- int r;
- size_t len;
- u_char *val;
-
- if ((r = sshpkt_get_string(ssh, &val, &len)) != 0)
- fatal("%s: %s", __func__, ssh_err(r));
- if (length_ptr != NULL)
- *length_ptr = (u_int)len;
- return val;
-}
-
-const void *
-ssh_packet_get_string_ptr(struct ssh *ssh, u_int *length_ptr)
-{
- int r;
- size_t len;
- const u_char *val;
-
- if ((r = sshpkt_get_string_direct(ssh, &val, &len)) != 0)
- fatal("%s: %s", __func__, ssh_err(r));
- if (length_ptr != NULL)
- *length_ptr = (u_int)len;
- return val;
-}
-
-char *
-ssh_packet_get_cstring(struct ssh *ssh, u_int *length_ptr)
-{
- int r;
- size_t len;
- char *val;
-
- if ((r = sshpkt_get_cstring(ssh, &val, &len)) != 0)
- fatal("%s: %s", __func__, ssh_err(r));
- if (length_ptr != NULL)
- *length_ptr = (u_int)len;
- return val;
-}
-
-/* Old API, that had to be reimplemented */
-
-void
-packet_set_connection(int fd_in, int fd_out)
-{
- active_state = ssh_packet_set_connection(active_state, fd_in, fd_out);
- if (active_state == NULL)
- fatal("%s: ssh_packet_set_connection failed", __func__);
-}
-
-u_int
-packet_get_char(void)
-{
- return (ssh_packet_get_char(active_state));
-}
-
-u_int
-packet_get_int(void)
-{
- return (ssh_packet_get_int(active_state));
-}
-
-int
-packet_read_seqnr(u_int32_t *seqnr)
-{
- u_char type;
- int r;
-
- if ((r = ssh_packet_read_seqnr(active_state, &type, seqnr)) != 0)
- sshpkt_fatal(active_state, __func__, r);
- return type;
-}
-
-int
-packet_read_poll_seqnr(u_int32_t *seqnr)
-{
- u_char type;
- int r;
-
- if ((r = ssh_packet_read_poll_seqnr(active_state, &type, seqnr)))
- sshpkt_fatal(active_state, __func__, r);
- return type;
-}
-
-void
-packet_close(void)
-{
- ssh_packet_close(active_state);
- active_state = NULL;
-}
-
-void
-packet_process_incoming(const char *buf, u_int len)
-{
- int r;
-
- if ((r = ssh_packet_process_incoming(active_state, buf, len)) != 0)
- sshpkt_fatal(active_state, __func__, r);
-}
-
-void
-packet_write_wait(void)
-{
- int r;
-
- if ((r = ssh_packet_write_wait(active_state)) != 0)
- sshpkt_fatal(active_state, __func__, r);
-}
-
-void
-packet_write_poll(void)
-{
- int r;
-
- if ((r = ssh_packet_write_poll(active_state)) != 0)
- sshpkt_fatal(active_state, __func__, r);
-}
-
-void
-packet_read_expect(int expected_type)
-{
- int r;
-
- if ((r = ssh_packet_read_expect(active_state, expected_type)) != 0)
- sshpkt_fatal(active_state, __func__, r);
-}
-
-void
-packet_disconnect(const char *fmt, ...)
-{
- char buf[1024];
- va_list args;
-
- va_start(args, fmt);
- vsnprintf(buf, sizeof(buf), fmt, args);
- va_end(args);
- ssh_packet_disconnect(active_state, "%s", buf);
-}
-
-void
-packet_send_debug(const char *fmt, ...)
-{
- char buf[1024];
- va_list args;
-
- va_start(args, fmt);
- vsnprintf(buf, sizeof(buf), fmt, args);
- va_end(args);
- ssh_packet_send_debug(active_state, "%s", buf);
-}
diff --git a/crypto/openssh/opacket.h b/crypto/openssh/opacket.h
deleted file mode 100644
index f92fe586efb5..000000000000
--- a/crypto/openssh/opacket.h
+++ /dev/null
@@ -1,154 +0,0 @@
-/* $OpenBSD: opacket.h,v 1.13 2018/07/06 09:03:02 sf Exp $ */
-#ifndef _OPACKET_H
-/* Written by Markus Friedl. Placed in the public domain. */
-
-/* Map old to new API */
-void ssh_packet_start(struct ssh *, u_char);
-void ssh_packet_put_char(struct ssh *, int ch);
-void ssh_packet_put_int(struct ssh *, u_int value);
-void ssh_packet_put_int64(struct ssh *, u_int64_t value);
-void ssh_packet_put_bignum2(struct ssh *, BIGNUM * value);
-void ssh_packet_put_ecpoint(struct ssh *, const EC_GROUP *, const EC_POINT *);
-void ssh_packet_put_string(struct ssh *, const void *buf, u_int len);
-void ssh_packet_put_cstring(struct ssh *, const char *str);
-void ssh_packet_put_raw(struct ssh *, const void *buf, u_int len);
-void ssh_packet_send(struct ssh *);
-
-u_int ssh_packet_get_char(struct ssh *);
-u_int ssh_packet_get_int(struct ssh *);
-u_int64_t ssh_packet_get_int64(struct ssh *);
-void ssh_packet_get_bignum2(struct ssh *, BIGNUM * value);
-void ssh_packet_get_ecpoint(struct ssh *, const EC_GROUP *, EC_POINT *);
-void *ssh_packet_get_string(struct ssh *, u_int *length_ptr);
-char *ssh_packet_get_cstring(struct ssh *, u_int *length_ptr);
-
-/* don't allow remaining bytes after the end of the message */
-#define ssh_packet_check_eom(ssh) \
-do { \
- int _len = ssh_packet_remaining(ssh); \
- if (_len > 0) { \
- logit("Packet integrity error (%d bytes remaining) at %s:%d", \
- _len ,__FILE__, __LINE__); \
- ssh_packet_disconnect(ssh, \
- "Packet integrity error."); \
- } \
-} while (0)
-
-/* old API */
-void packet_close(void);
-u_int packet_get_char(void);
-u_int packet_get_int(void);
-void packet_set_connection(int, int);
-int packet_read_seqnr(u_int32_t *);
-int packet_read_poll_seqnr(u_int32_t *);
-void packet_process_incoming(const char *buf, u_int len);
-void packet_write_wait(void);
-void packet_write_poll(void);
-void packet_read_expect(int expected_type);
-#define packet_set_timeout(timeout, count) \
- ssh_packet_set_timeout(active_state, (timeout), (count))
-#define packet_connection_is_on_socket() \
- ssh_packet_connection_is_on_socket(active_state)
-#define packet_set_nonblocking() \
- ssh_packet_set_nonblocking(active_state)
-#define packet_get_connection_in() \
- ssh_packet_get_connection_in(active_state)
-#define packet_get_connection_out() \
- ssh_packet_get_connection_out(active_state)
-#define packet_set_protocol_flags(protocol_flags) \
- ssh_packet_set_protocol_flags(active_state, (protocol_flags))
-#define packet_get_protocol_flags() \
- ssh_packet_get_protocol_flags(active_state)
-#define packet_start(type) \
- ssh_packet_start(active_state, (type))
-#define packet_put_char(value) \
- ssh_packet_put_char(active_state, (value))
-#define packet_put_int(value) \
- ssh_packet_put_int(active_state, (value))
-#define packet_put_int64(value) \
- ssh_packet_put_int64(active_state, (value))
-#define packet_put_string( buf, len) \
- ssh_packet_put_string(active_state, (buf), (len))
-#define packet_put_cstring(str) \
- ssh_packet_put_cstring(active_state, (str))
-#define packet_put_raw(buf, len) \
- ssh_packet_put_raw(active_state, (buf), (len))
-#define packet_put_bignum2(value) \
- ssh_packet_put_bignum2(active_state, (value))
-#define packet_send() \
- ssh_packet_send(active_state)
-#define packet_read() \
- ssh_packet_read(active_state)
-#define packet_get_int64() \
- ssh_packet_get_int64(active_state)
-#define packet_get_bignum2(value) \
- ssh_packet_get_bignum2(active_state, (value))
-#define packet_remaining() \
- ssh_packet_remaining(active_state)
-#define packet_get_string(length_ptr) \
- ssh_packet_get_string(active_state, (length_ptr))
-#define packet_get_string_ptr(length_ptr) \
- ssh_packet_get_string_ptr(active_state, (length_ptr))
-#define packet_get_cstring(length_ptr) \
- ssh_packet_get_cstring(active_state, (length_ptr))
-void packet_send_debug(const char *, ...)
- __attribute__((format(printf, 1, 2)));
-void packet_disconnect(const char *, ...)
- __attribute__((format(printf, 1, 2)))
- __attribute__((noreturn));
-#define packet_have_data_to_write() \
- ssh_packet_have_data_to_write(active_state)
-#define packet_not_very_much_data_to_write() \
- ssh_packet_not_very_much_data_to_write(active_state)
-#define packet_set_interactive(interactive, qos_interactive, qos_bulk) \
- ssh_packet_set_interactive(active_state, (interactive), (qos_interactive), (qos_bulk))
-#define packet_is_interactive() \
- ssh_packet_is_interactive(active_state)
-#define packet_set_maxsize(s) \
- ssh_packet_set_maxsize(active_state, (s))
-#define packet_inc_alive_timeouts() \
- ssh_packet_inc_alive_timeouts(active_state)
-#define packet_set_alive_timeouts(ka) \
- ssh_packet_set_alive_timeouts(active_state, (ka))
-#define packet_get_maxsize() \
- ssh_packet_get_maxsize(active_state)
-#define packet_add_padding(pad) \
- sshpkt_add_padding(active_state, (pad))
-#define packet_send_ignore(nbytes) \
- ssh_packet_send_ignore(active_state, (nbytes))
-#define packet_set_server() \
- ssh_packet_set_server(active_state)
-#define packet_set_authenticated() \
- ssh_packet_set_authenticated(active_state)
-#define packet_get_input() \
- ssh_packet_get_input(active_state)
-#define packet_get_output() \
- ssh_packet_get_output(active_state)
-#define packet_check_eom() \
- ssh_packet_check_eom(active_state)
-#define set_newkeys(mode) \
- ssh_set_newkeys(active_state, (mode))
-#define packet_get_state(m) \
- ssh_packet_get_state(active_state, m)
-#define packet_set_state(m) \
- ssh_packet_set_state(active_state, m)
-#define packet_get_raw(lenp) \
- sshpkt_ptr(active_state, lenp)
-#define packet_get_ecpoint(c,p) \
- ssh_packet_get_ecpoint(active_state, c, p)
-#define packet_put_ecpoint(c,p) \
- ssh_packet_put_ecpoint(active_state, c, p)
-#define packet_get_rekey_timeout() \
- ssh_packet_get_rekey_timeout(active_state)
-#define packet_set_rekey_limits(x,y) \
- ssh_packet_set_rekey_limits(active_state, x, y)
-#define packet_get_bytes(x,y) \
- ssh_packet_get_bytes(active_state, x, y)
-#define packet_set_mux() \
- ssh_packet_set_mux(active_state)
-#define packet_get_mux() \
- ssh_packet_get_mux(active_state)
-#define packet_clear_keys() \
- ssh_packet_clear_keys(active_state)
-
-#endif /* _OPACKET_H */
diff --git a/crypto/openssh/openbsd-compat/Makefile.in b/crypto/openssh/openbsd-compat/Makefile.in
index c1e14cbd0ed4..5d53bef5757f 100644
--- a/crypto/openssh/openbsd-compat/Makefile.in
+++ b/crypto/openssh/openbsd-compat/Makefile.in
@@ -7,12 +7,15 @@ VPATH=@srcdir@
CC=@CC@
LD=@LD@
CFLAGS=@CFLAGS@
+CFLAGS_NOPIE=@CFLAGS_NOPIE@
CPPFLAGS=-I. -I.. -I$(srcdir) -I$(srcdir)/.. @CPPFLAGS@ @DEFS@
+PICFLAG=@PICFLAG@
LIBS=@LIBS@
AR=@AR@
RANLIB=@RANLIB@
INSTALL=@INSTALL@
LDFLAGS=-L. @LDFLAGS@
+LDFLAGS_NOPIE=-L. -Lopenbsd-compat/ @LDFLAGS_NOPIE@
OPENBSD=base64.o \
basename.o \
@@ -25,6 +28,7 @@ OPENBSD=base64.o \
explicit_bzero.o \
fmt_scaled.o \
freezero.o \
+ fnmatch.o \
getcwd.o \
getgrouplist.o \
getopt_long.o \
@@ -34,13 +38,12 @@ OPENBSD=base64.o \
inet_ntoa.o \
inet_ntop.o \
md5.o \
+ memmem.o \
mktemp.o \
pwcache.o \
readpassphrase.o \
reallocarray.o \
- realpath.o \
recallocarray.o \
- rmd160.o \
rresvport.o \
setenv.o \
setproctitle.o \
@@ -76,6 +79,7 @@ COMPAT= arc4random.o \
bsd-nextstep.o \
bsd-openpty.o \
bsd-poll.o \
+ bsd-pselect.o \
bsd-setres_id.o \
bsd-signal.o \
bsd-snprintf.o \
@@ -91,12 +95,13 @@ COMPAT= arc4random.o \
PORTS= port-aix.o \
port-irix.o \
port-linux.o \
+ port-prngd.o \
port-solaris.o \
port-net.o \
port-uw.o
.c.o:
- $(CC) $(CFLAGS) $(CPPFLAGS) -c $<
+ $(CC) $(CFLAGS_NOPIE) $(PICFLAG) $(CPPFLAGS) -c $<
all: libopenbsd-compat.a
diff --git a/crypto/openssh/openbsd-compat/arc4random.c b/crypto/openssh/openbsd-compat/arc4random.c
index 578f69f4f74f..14853aba43d1 100644
--- a/crypto/openssh/openbsd-compat/arc4random.c
+++ b/crypto/openssh/openbsd-compat/arc4random.c
@@ -88,7 +88,7 @@ _rs_init(u_char *buf, size_t n)
static void
getrnd(u_char *s, size_t len)
{
- int fd;
+ int fd, save_errno;
ssize_t r;
size_t o = 0;
@@ -97,8 +97,14 @@ getrnd(u_char *s, size_t len)
return;
#endif /* HAVE_GETRANDOM */
- if ((fd = open(SSH_RANDOM_DEV, O_RDONLY)) == -1)
- fatal("Couldn't open %s: %s", SSH_RANDOM_DEV, strerror(errno));
+ if ((fd = open(SSH_RANDOM_DEV, O_RDONLY)) == -1) {
+ save_errno = errno;
+ /* Try egd/prngd before giving up. */
+ if (seed_from_prngd(s, len) == 0)
+ return;
+ fatal("Couldn't open %s: %s", SSH_RANDOM_DEV,
+ strerror(save_errno));
+ }
while (o < len) {
r = read(fd, s + o, len - o);
if (r < 0) {
diff --git a/crypto/openssh/openbsd-compat/base64.c b/crypto/openssh/openbsd-compat/base64.c
index 9e7466716425..b7dce095e4c3 100644
--- a/crypto/openssh/openbsd-compat/base64.c
+++ b/crypto/openssh/openbsd-compat/base64.c
@@ -211,7 +211,7 @@ b64_pton(char const *src, u_char *target, size_t targsize)
break;
pos = strchr(Base64, ch);
- if (pos == 0) /* A non-base64 character. */
+ if (pos == 0) /* A non-base64 character. */
return (-1);
switch (state) {
diff --git a/crypto/openssh/openbsd-compat/bcrypt_pbkdf.c b/crypto/openssh/openbsd-compat/bcrypt_pbkdf.c
index 78523456387a..62728d38f002 100644
--- a/crypto/openssh/openbsd-compat/bcrypt_pbkdf.c
+++ b/crypto/openssh/openbsd-compat/bcrypt_pbkdf.c
@@ -15,6 +15,8 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
+/* OPENBSD ORIGINAL: lib/libutil/bcrypt_pbkdf.c */
+
#include "includes.h"
#ifndef HAVE_BCRYPT_PBKDF
@@ -91,7 +93,7 @@ bcrypt_hash(u_int8_t *sha2pass, u_int8_t *sha2salt, u_int8_t *out)
cdata[i] = Blowfish_stream2word(ciphertext, sizeof(ciphertext),
&j);
for (i = 0; i < 64; i++)
- blf_enc(&state, cdata, sizeof(cdata) / sizeof(uint64_t));
+ blf_enc(&state, cdata, sizeof(cdata) / (sizeof(uint64_t)));
/* copy out */
for (i = 0; i < BCRYPT_WORDS; i++) {
diff --git a/crypto/openssh/openbsd-compat/bsd-closefrom.c b/crypto/openssh/openbsd-compat/bsd-closefrom.c
index b56476a2d858..8fadca2dad66 100644
--- a/crypto/openssh/openbsd-compat/bsd-closefrom.c
+++ b/crypto/openssh/openbsd-compat/bsd-closefrom.c
@@ -46,6 +46,9 @@
# include <ndir.h>
# endif
#endif
+#if defined(HAVE_LIBPROC_H)
+# include <libproc.h>
+#endif
#ifndef OPEN_MAX
# define OPEN_MAX 256
@@ -55,21 +58,73 @@
__unused static const char rcsid[] = "$Sudo: closefrom.c,v 1.11 2006/08/17 15:26:54 millert Exp $";
#endif /* lint */
+#ifndef HAVE_FCNTL_CLOSEM
/*
* Close all file descriptors greater than or equal to lowfd.
*/
+static void
+closefrom_fallback(int lowfd)
+{
+ long fd, maxfd;
+
+ /*
+ * 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 */
+
#ifdef HAVE_FCNTL_CLOSEM
void
closefrom(int lowfd)
{
(void) fcntl(lowfd, F_CLOSEM, 0);
}
-#else
+#elif defined(HAVE_LIBPROC_H) && defined(HAVE_PROC_PIDINFO)
void
closefrom(int lowfd)
{
- long fd, maxfd;
-#if defined(HAVE_DIRFD) && defined(HAVE_PROC_PID)
+ int i, r, sz;
+ pid_t pid = getpid();
+ struct proc_fdinfo *fdinfo_buf = NULL;
+
+ sz = proc_pidinfo(pid, PROC_PIDLISTFDS, 0, NULL, 0);
+ if (sz == 0)
+ return; /* no fds, really? */
+ else if (sz == -1)
+ goto fallback;
+ if ((fdinfo_buf = malloc(sz)) == NULL)
+ goto fallback;
+ r = proc_pidinfo(pid, PROC_PIDLISTFDS, 0, fdinfo_buf, sz);
+ if (r < 0 || r > sz)
+ goto fallback;
+ for (i = 0; i < r / (int)PROC_PIDLISTFD_SIZE; i++) {
+ if (fdinfo_buf[i].proc_fd >= lowfd)
+ close(fdinfo_buf[i].proc_fd);
+ }
+ free(fdinfo_buf);
+ return;
+ fallback:
+ free(fdinfo_buf);
+ closefrom_fallback(lowfd);
+ return;
+}
+#elif defined(HAVE_DIRFD) && defined(HAVE_PROC_PID)
+void
+closefrom(int lowfd)
+{
+ long fd;
char fdpath[PATH_MAX], *endp;
struct dirent *dent;
DIR *dirp;
@@ -85,25 +140,16 @@ closefrom(int lowfd)
(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);
+ return;
}
+ /* /proc/$$/fd strategy failed, fall back to brute force closure */
+ closefrom_fallback(lowfd);
+}
+#else
+void
+closefrom(int lowfd)
+{
+ closefrom_fallback(lowfd);
}
#endif /* !HAVE_FCNTL_CLOSEM */
#endif /* HAVE_CLOSEFROM */
diff --git a/crypto/openssh/openbsd-compat/bsd-cygwin_util.c b/crypto/openssh/openbsd-compat/bsd-cygwin_util.c
index fb49e30f5981..54628e2607b4 100644
--- a/crypto/openssh/openbsd-compat/bsd-cygwin_util.c
+++ b/crypto/openssh/openbsd-compat/bsd-cygwin_util.c
@@ -37,6 +37,9 @@
#include <string.h>
#include <unistd.h>
#include <stdarg.h>
+#include <stdlib.h>
+#include <wchar.h>
+#include <wctype.h>
#include "xmalloc.h"
@@ -117,4 +120,150 @@ free_windows_environment(char **p)
free(p);
}
+/*
+ * Returns true if the given string matches the pattern (which may contain ?
+ * and * as wildcards), and zero if it does not match.
+ *
+ * The Cygwin version of this function must be case-insensitive and take
+ * Unicode characters into account.
+ */
+
+static int
+__match_pattern (const wchar_t *s, const wchar_t *pattern)
+{
+ for (;;) {
+ /* If at end of pattern, accept if also at end of string. */
+ if (!*pattern)
+ return !*s;
+
+ if (*pattern == '*') {
+ /* Skip the asterisk. */
+ pattern++;
+
+ /* If at end of pattern, accept immediately. */
+ if (!*pattern)
+ return 1;
+
+ /* If next character in pattern is known, optimize. */
+ if (*pattern != '?' && *pattern != '*') {
+ /*
+ * Look instances of the next character in
+ * pattern, and try to match starting from
+ * those.
+ */
+ for (; *s; s++)
+ if (*s == *pattern &&
+ __match_pattern(s + 1, pattern + 1))
+ return 1;
+ /* Failed. */
+ return 0;
+ }
+ /*
+ * Move ahead one character at a time and try to
+ * match at each position.
+ */
+ for (; *s; s++)
+ if (__match_pattern(s, pattern))
+ return 1;
+ /* Failed. */
+ return 0;
+ }
+ /*
+ * There must be at least one more character in the string.
+ * If we are at the end, fail.
+ */
+ if (!*s)
+ return 0;
+
+ /* Check if the next character of the string is acceptable. */
+ if (*pattern != '?' && towlower(*pattern) != towlower(*s))
+ return 0;
+
+ /* Move to the next character, both in string and in pattern. */
+ s++;
+ pattern++;
+ }
+ /* NOTREACHED */
+}
+
+static int
+_match_pattern(const char *s, const char *pattern)
+{
+ wchar_t *ws;
+ wchar_t *wpattern;
+ size_t len;
+ int ret;
+
+ if ((len = mbstowcs(NULL, s, 0)) < 0)
+ return 0;
+ ws = (wchar_t *) xcalloc(len + 1, sizeof (wchar_t));
+ mbstowcs(ws, s, len + 1);
+ if ((len = mbstowcs(NULL, pattern, 0)) < 0)
+ return 0;
+ wpattern = (wchar_t *) xcalloc(len + 1, sizeof (wchar_t));
+ mbstowcs(wpattern, pattern, len + 1);
+ ret = __match_pattern (ws, wpattern);
+ free(ws);
+ free(wpattern);
+ return ret;
+}
+
+/*
+ * Tries to match the string against the
+ * comma-separated sequence of subpatterns (each possibly preceded by ! to
+ * indicate negation). Returns -1 if negation matches, 1 if there is
+ * a positive match, 0 if there is no match at all.
+ */
+int
+cygwin_ug_match_pattern_list(const char *string, const char *pattern)
+{
+ char sub[1024];
+ int negated;
+ int got_positive;
+ u_int i, subi, len = strlen(pattern);
+
+ got_positive = 0;
+ for (i = 0; i < len;) {
+ /* Check if the subpattern is negated. */
+ if (pattern[i] == '!') {
+ negated = 1;
+ i++;
+ } else
+ negated = 0;
+
+ /*
+ * Extract the subpattern up to a comma or end. Convert the
+ * subpattern to lowercase.
+ */
+ for (subi = 0;
+ i < len && subi < sizeof(sub) - 1 && pattern[i] != ',';
+ subi++, i++)
+ sub[subi] = pattern[i];
+ /* If subpattern too long, return failure (no match). */
+ if (subi >= sizeof(sub) - 1)
+ return 0;
+
+ /* If the subpattern was terminated by a comma, then skip it. */
+ if (i < len && pattern[i] == ',')
+ i++;
+
+ /* Null-terminate the subpattern. */
+ sub[subi] = '\0';
+
+ /* Try to match the subpattern against the string. */
+ if (_match_pattern(string, sub)) {
+ if (negated)
+ return -1; /* Negative */
+ else
+ got_positive = 1; /* Positive */
+ }
+ }
+
+ /*
+ * Return success if got a positive match. If there was a negative
+ * match, we have already returned -1 and never get here.
+ */
+ return got_positive;
+}
+
#endif /* HAVE_CYGWIN */
diff --git a/crypto/openssh/openbsd-compat/bsd-cygwin_util.h b/crypto/openssh/openbsd-compat/bsd-cygwin_util.h
index 202c055dbae7..55c5a5b81b44 100644
--- a/crypto/openssh/openbsd-compat/bsd-cygwin_util.h
+++ b/crypto/openssh/openbsd-compat/bsd-cygwin_util.h
@@ -55,6 +55,7 @@ int binary_open(const char *, int , ...);
int check_ntsec(const char *);
char **fetch_windows_environment(void);
void free_windows_environment(char **);
+int cygwin_ug_match_pattern_list(const char *, const char *);
#ifndef NO_BINARY_OPEN
#define open binary_open
diff --git a/crypto/openssh/openbsd-compat/bsd-misc.c b/crypto/openssh/openbsd-compat/bsd-misc.c
index 5d7540a70f4b..059b6d3b3ec7 100644
--- a/crypto/openssh/openbsd-compat/bsd-misc.c
+++ b/crypto/openssh/openbsd-compat/bsd-misc.c
@@ -25,6 +25,7 @@
# include <sys/time.h>
#endif
+#include <fcntl.h>
#include <string.h>
#include <signal.h>
#include <stdlib.h>
@@ -117,6 +118,108 @@ int utimes(char *filename, struct timeval *tvp)
}
#endif
+#ifndef HAVE_UTIMENSAT
+/*
+ * A limited implementation of utimensat() that only implements the
+ * functionality used by OpenSSH, currently only AT_FDCWD and
+ * AT_SYMLINK_NOFOLLOW.
+ */
+int
+utimensat(int fd, const char *path, const struct timespec times[2],
+ int flag)
+{
+ struct timeval tv[2];
+# ifdef HAVE_FUTIMES
+ int ret, oflags = O_WRONLY;
+# endif
+
+ tv[0].tv_sec = times[0].tv_sec;
+ tv[0].tv_usec = times[0].tv_nsec / 1000;
+ tv[1].tv_sec = times[1].tv_sec;
+ tv[1].tv_usec = times[1].tv_nsec / 1000;
+
+ if (fd != AT_FDCWD) {
+ errno = ENOSYS;
+ return -1;
+ }
+# ifndef HAVE_FUTIMES
+ return utimes(path, tv);
+# else
+# ifdef O_NOFOLLOW
+ if (flag & AT_SYMLINK_NOFOLLOW)
+ oflags |= O_NOFOLLOW;
+# endif /* O_NOFOLLOW */
+ if ((fd = open(path, oflags)) == -1)
+ return -1;
+ ret = futimes(fd, tv);
+ close(fd);
+ return ret;
+# endif
+}
+#endif
+
+#ifndef HAVE_FCHOWNAT
+/*
+ * A limited implementation of fchownat() that only implements the
+ * functionality used by OpenSSH, currently only AT_FDCWD and
+ * AT_SYMLINK_NOFOLLOW.
+ */
+int
+fchownat(int fd, const char *path, uid_t owner, gid_t group, int flag)
+{
+ int ret, oflags = O_WRONLY;
+
+ if (fd != AT_FDCWD) {
+ errno = ENOSYS;
+ return -1;
+ }
+# ifndef HAVE_FCHOWN
+ return chown(path, owner, group);
+# else
+# ifdef O_NOFOLLOW
+ if (flag & AT_SYMLINK_NOFOLLOW)
+ oflags |= O_NOFOLLOW;
+# endif /* O_NOFOLLOW */
+ if ((fd = open(path, oflags)) == -1)
+ return -1;
+ ret = fchown(fd, owner, group);
+ close(fd);
+ return ret;
+# endif
+}
+#endif
+
+#ifndef HAVE_FCHMODAT
+/*
+ * A limited implementation of fchmodat() that only implements the
+ * functionality used by OpenSSH, currently only AT_FDCWD and
+ * AT_SYMLINK_NOFOLLOW.
+ */
+int
+fchmodat(int fd, const char *path, mode_t mode, int flag)
+{
+ int ret, oflags = O_WRONLY;
+
+ if (fd != AT_FDCWD) {
+ errno = ENOSYS;
+ return -1;
+ }
+# ifndef HAVE_FCHMOD
+ return chmod(path, mode);
+# else
+# ifdef O_NOFOLLOW
+ if (flag & AT_SYMLINK_NOFOLLOW)
+ oflags |= O_NOFOLLOW;
+# endif /* O_NOFOLLOW */
+ if ((fd = open(path, oflags)) == -1)
+ return -1;
+ ret = fchmod(fd, mode);
+ close(fd);
+ return ret;
+# endif
+}
+#endif
+
#ifndef HAVE_TRUNCATE
int truncate(const char *path, off_t length)
{
@@ -325,3 +428,13 @@ int _ssh_compat_fflush(FILE *f)
return fflush(f);
}
#endif
+
+#ifndef HAVE_LOCALTIME_R
+struct tm *
+localtime_r(const time_t *timep, struct tm *result)
+{
+ struct tm *tm = localtime(timep);
+ *result = *tm;
+ return result;
+}
+#endif
diff --git a/crypto/openssh/openbsd-compat/bsd-misc.h b/crypto/openssh/openbsd-compat/bsd-misc.h
index 52ec528538b5..2206e1a82140 100644
--- a/crypto/openssh/openbsd-compat/bsd-misc.h
+++ b/crypto/openssh/openbsd-compat/bsd-misc.h
@@ -20,6 +20,7 @@
#include "includes.h"
char *ssh_get_progname(char *);
+int seed_from_prngd(unsigned char *, size_t);
#ifndef HAVE_SETSID
#define setsid() setpgrp(0, getpid())
@@ -64,20 +65,43 @@ struct timeval {
int utimes(char *, struct timeval *);
#endif /* HAVE_UTIMES */
+#ifndef AT_FDCWD
+# define AT_FDCWD (-2)
+#endif
+
+#ifndef HAVE_FCHMODAT
+int fchmodat(int, const char *, mode_t, int);
+#endif
+
+#ifndef HAVE_FCHOWNAT
+int fchownat(int, const char *, uid_t, gid_t, int);
+#endif
+
#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
+#endif /* !HAVE_STRUCT_TIMESPEC */
+
+#if !defined(HAVE_NANOSLEEP) && !defined(HAVE_NSLEEP)
+# include <time.h>
int nanosleep(const struct timespec *, struct timespec *);
#endif
+#ifndef HAVE_UTIMENSAT
+# include <time.h>
+/* start with the high bits and work down to minimise risk of overlap */
+# ifndef AT_SYMLINK_NOFOLLOW
+# define AT_SYMLINK_NOFOLLOW 0x80000000
+# endif
+int utimensat(int, const char *, const struct timespec[2], int);
+#endif /* !HAVE_UTIMENSAT */
+
#ifndef HAVE_USLEEP
int usleep(unsigned int useconds);
#endif
@@ -102,6 +126,11 @@ int isblank(int);
pid_t getpgid(pid_t);
#endif
+#ifndef HAVE_PSELECT
+int pselect(int, fd_set *, fd_set *, fd_set *, const struct timespec *,
+ const sigset_t *);
+#endif
+
#ifndef HAVE_ENDGRENT
# define endgrent() do { } while(0)
#endif
@@ -157,4 +186,12 @@ int flock(int, int);
# define fflush(x) (_ssh_compat_fflush(x))
#endif
+#ifndef HAVE_LOCALTIME_R
+struct tm *localtime_r(const time_t *, struct tm *);
+#endif
+
+#ifndef HAVE_REALPATH
+#define realpath(x, y) (sftp_realpath((x), (y)))
+#endif
+
#endif /* _BSD_MISC_H */
diff --git a/crypto/openssh/openbsd-compat/bsd-openpty.c b/crypto/openssh/openbsd-compat/bsd-openpty.c
index e8ad542f8d55..1ab41f42b634 100644
--- a/crypto/openssh/openbsd-compat/bsd-openpty.c
+++ b/crypto/openssh/openbsd-compat/bsd-openpty.c
@@ -65,6 +65,8 @@
#include <string.h>
#include <unistd.h>
+#include "misc.h"
+
#ifndef O_NOCTTY
#define O_NOCTTY 0
#endif
@@ -97,16 +99,16 @@ openpty(int *amaster, int *aslave, char *name, struct termios *termp,
*/
int ptm;
char *pts;
- mysig_t old_signal;
+ sshsig_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);
+ old_signal = ssh_signal(SIGCHLD, SIG_DFL);
if (grantpt(ptm) < 0)
return (-1);
- signal(SIGCHLD, old_signal);
+ ssh_signal(SIGCHLD, old_signal);
if (unlockpt(ptm) < 0)
return (-1);
@@ -121,6 +123,15 @@ openpty(int *amaster, int *aslave, char *name, struct termios *termp,
return (-1);
}
+# if defined(I_FIND) && defined(__SVR4)
+ /*
+ * If the streams modules have already been pushed then there
+ * is no more work to do here.
+ */
+ if (ioctl(*aslave, I_FIND, "ptem") != 0)
+ return 0;
+# endif
+
/*
* Try to push the appropriate streams modules, as described
* in Solaris pts(7).
diff --git a/crypto/openssh/openbsd-compat/bsd-poll.h b/crypto/openssh/openbsd-compat/bsd-poll.h
index 17945f5b46f5..8420ca1db378 100644
--- a/crypto/openssh/openbsd-compat/bsd-poll.h
+++ b/crypto/openssh/openbsd-compat/bsd-poll.h
@@ -32,7 +32,7 @@
#define _COMPAT_POLL_H_
typedef struct pollfd {
- int fd;
+ int fd;
short events;
short revents;
} pollfd_t;
diff --git a/crypto/openssh/openbsd-compat/bsd-pselect.c b/crypto/openssh/openbsd-compat/bsd-pselect.c
new file mode 100644
index 000000000000..fff1bf54f72c
--- /dev/null
+++ b/crypto/openssh/openbsd-compat/bsd-pselect.c
@@ -0,0 +1,205 @@
+/*
+ * Copyright (c) 2001 Markus Friedl. All rights reserved.
+ * Copyright (c) 2021 Darren Tucker (dtucker at dtucker net).
+ *
+ * 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_PSELECT
+
+#include <sys/types.h>
+#include <sys/time.h>
+#ifdef HAVE_SYS_SELECT_H
+# include <sys/select.h>
+#endif
+
+#include <errno.h>
+#include <fcntl.h>
+#include <signal.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "log.h"
+#include "misc.h" /* for set_nonblock */
+
+#ifndef HAVE_SIGHANDLER_T
+typedef void (*sighandler_t)(int);
+#endif
+
+static sighandler_t saved_sighandler[_NSIG];
+
+/*
+ * Set up the descriptors. Because they are close-on-exec, in the case
+ * where sshd's re-exec fails notify_pipe will still point to a descriptor
+ * that was closed by the exec attempt but if that descriptor has been
+ * reopened then we'll attempt to use that. Ensure that notify_pipe is
+ * outside of the range used by sshd re-exec but within NFDBITS (so we don't
+ * need to expand the fd_sets).
+ */
+#define REEXEC_MIN_FREE_FD (STDERR_FILENO + 4)
+static int
+pselect_notify_setup_fd(int *fd)
+{
+ int r;
+
+ if ((r = fcntl(*fd, F_DUPFD, REEXEC_MIN_FREE_FD)) < 0 ||
+ fcntl(r, F_SETFD, FD_CLOEXEC) < 0 || r >= FD_SETSIZE)
+ return -1;
+ (void)close(*fd);
+ return (*fd = r);
+}
+
+/*
+ * we write to this pipe if a SIGCHLD is caught in order to avoid
+ * the race between select() and child_terminated
+ */
+static pid_t notify_pid;
+static int notify_pipe[2];
+static void
+pselect_notify_setup(void)
+{
+ static int initialized;
+
+ if (initialized && notify_pid == getpid())
+ return;
+ if (notify_pid == 0)
+ debug3_f("initializing");
+ else {
+ debug3_f("pid changed, reinitializing");
+ if (notify_pipe[0] != -1)
+ close(notify_pipe[0]);
+ if (notify_pipe[1] != -1)
+ close(notify_pipe[1]);
+ }
+ if (pipe(notify_pipe) == -1) {
+ error("pipe(notify_pipe) failed %s", strerror(errno));
+ } else if (pselect_notify_setup_fd(&notify_pipe[0]) == -1 ||
+ pselect_notify_setup_fd(&notify_pipe[1]) == -1) {
+ error("fcntl(notify_pipe, ...) failed %s", strerror(errno));
+ close(notify_pipe[0]);
+ close(notify_pipe[1]);
+ } else {
+ set_nonblock(notify_pipe[0]);
+ set_nonblock(notify_pipe[1]);
+ notify_pid = getpid();
+ debug3_f("pid %d saved %d pipe0 %d pipe1 %d", getpid(),
+ notify_pid, notify_pipe[0], notify_pipe[1]);
+ initialized = 1;
+ return;
+ }
+ notify_pipe[0] = -1; /* read end */
+ notify_pipe[1] = -1; /* write end */
+}
+static void
+pselect_notify_parent(void)
+{
+ if (notify_pipe[1] != -1)
+ (void)write(notify_pipe[1], "", 1);
+}
+static void
+pselect_notify_prepare(fd_set *readset)
+{
+ if (notify_pipe[0] != -1)
+ FD_SET(notify_pipe[0], readset);
+}
+static void
+pselect_notify_done(fd_set *readset)
+{
+ char c;
+
+ if (notify_pipe[0] != -1 && FD_ISSET(notify_pipe[0], readset)) {
+ while (read(notify_pipe[0], &c, 1) != -1)
+ debug2_f("reading");
+ FD_CLR(notify_pipe[0], readset);
+ }
+}
+
+/*ARGSUSED*/
+static void
+pselect_sig_handler(int sig)
+{
+ int save_errno = errno;
+
+ pselect_notify_parent();
+ if (saved_sighandler[sig] != NULL)
+ (*saved_sighandler[sig])(sig); /* call original handler */
+ errno = save_errno;
+}
+
+/*
+ * A minimal implementation of pselect(2), built on top of select(2).
+ */
+
+int
+pselect(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
+ const struct timespec *timeout, const sigset_t *mask)
+{
+ int ret, sig, saved_errno, unmasked = 0;
+ sigset_t osig;
+ struct sigaction sa, osa;
+ struct timeval tv, *tvp = NULL;
+
+ if (timeout != NULL) {
+ tv.tv_sec = timeout->tv_sec;
+ tv.tv_usec = timeout->tv_nsec / 1000;
+ tvp = &tv;
+ }
+ if (mask == NULL) /* no signal mask, just call select */
+ return select(nfds, readfds, writefds, exceptfds, tvp);
+
+ /* For each signal we're unmasking, install our handler if needed. */
+ for (sig = 0; sig < _NSIG; sig++) {
+ if (sig == SIGKILL || sig == SIGSTOP || sigismember(mask, sig))
+ continue;
+ if (sigaction(sig, NULL, &sa) == 0 &&
+ sa.sa_handler != SIG_IGN && sa.sa_handler != SIG_DFL) {
+ unmasked = 1;
+ if (sa.sa_handler == pselect_sig_handler)
+ continue;
+ sa.sa_handler = pselect_sig_handler;
+ if (sigaction(sig, &sa, &osa) == 0) {
+ debug3_f("installing signal handler for %s, "
+ "previous %p", strsignal(sig),
+ osa.sa_handler);
+ saved_sighandler[sig] = osa.sa_handler;
+ }
+ }
+ }
+ if (unmasked) {
+ pselect_notify_setup();
+ pselect_notify_prepare(readfds);
+ nfds = MAX(nfds, notify_pipe[0]);
+ }
+
+ /* Unmask signals, call select then restore signal mask. */
+ sigprocmask(SIG_SETMASK, mask, &osig);
+ ret = select(nfds, readfds, writefds, exceptfds, tvp);
+ saved_errno = errno;
+ sigprocmask(SIG_SETMASK, &osig, NULL);
+
+ if (unmasked)
+ pselect_notify_done(readfds);
+ errno = saved_errno;
+ return ret;
+}
+#endif
diff --git a/crypto/openssh/openbsd-compat/bsd-setres_id.c b/crypto/openssh/openbsd-compat/bsd-setres_id.c
index 696ae7b28136..04752d5afa08 100644
--- a/crypto/openssh/openbsd-compat/bsd-setres_id.c
+++ b/crypto/openssh/openbsd-compat/bsd-setres_id.c
@@ -37,20 +37,20 @@ setresgid(gid_t rgid, gid_t egid, gid_t sgid)
#if defined(HAVE_SETREGID) && !defined(BROKEN_SETREGID)
if (setregid(rgid, egid) < 0) {
saved_errno = errno;
- error("setregid %u: %.100s", rgid, strerror(errno));
+ error("setregid %lu: %.100s", (u_long)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));
+ error("setegid %lu: %.100s", (u_long)egid, strerror(errno));
errno = saved_errno;
ret = -1;
}
if (setgid(rgid) < 0) {
saved_errno = errno;
- error("setgid %u: %.100s", rgid, strerror(errno));
+ error("setgid %lu: %.100s", (u_long)rgid, strerror(errno));
errno = saved_errno;
ret = -1;
}
@@ -72,7 +72,7 @@ setresuid(uid_t ruid, uid_t euid, uid_t suid)
#if defined(HAVE_SETREUID) && !defined(BROKEN_SETREUID)
if (setreuid(ruid, euid) < 0) {
saved_errno = errno;
- error("setreuid %u: %.100s", ruid, strerror(errno));
+ error("setreuid %lu: %.100s", (u_long)ruid, strerror(errno));
errno = saved_errno;
ret = -1;
}
@@ -81,14 +81,14 @@ setresuid(uid_t ruid, uid_t euid, uid_t suid)
# ifndef SETEUID_BREAKS_SETUID
if (seteuid(euid) < 0) {
saved_errno = errno;
- error("seteuid %u: %.100s", euid, strerror(errno));
+ error("seteuid %lu: %.100s", (u_long)euid, strerror(errno));
errno = saved_errno;
ret = -1;
}
# endif
if (setuid(ruid) < 0) {
saved_errno = errno;
- error("setuid %u: %.100s", ruid, strerror(errno));
+ error("setuid %lu: %.100s", (u_long)ruid, strerror(errno));
errno = saved_errno;
ret = -1;
}
diff --git a/crypto/openssh/openbsd-compat/bsd-signal.c b/crypto/openssh/openbsd-compat/bsd-signal.c
index 979010e84b5f..38d5e972e9e4 100644
--- a/crypto/openssh/openbsd-compat/bsd-signal.c
+++ b/crypto/openssh/openbsd-compat/bsd-signal.c
@@ -17,39 +17,12 @@
#include "includes.h"
#include <signal.h>
+#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include "openbsd-compat/bsd-signal.h"
-#undef signal
-
-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
- return (signal(sig, act));
-#endif
-}
-
#if !defined(HAVE_STRSIGNAL)
char *strsignal(int sig)
{
diff --git a/crypto/openssh/openbsd-compat/bsd-signal.h b/crypto/openssh/openbsd-compat/bsd-signal.h
index 4cb8cb7a0b92..8d8c4441968d 100644
--- a/crypto/openssh/openbsd-compat/bsd-signal.h
+++ b/crypto/openssh/openbsd-compat/bsd-signal.h
@@ -19,6 +19,8 @@
#include "includes.h"
+#include <signal.h>
+
#ifndef _NSIG
# ifdef NSIG
# define _NSIG NSIG
@@ -27,11 +29,6 @@
# endif
#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)
-
#if !defined(HAVE_STRSIGNAL)
char *strsignal(int);
#endif
diff --git a/crypto/openssh/openbsd-compat/bsd-snprintf.c b/crypto/openssh/openbsd-compat/bsd-snprintf.c
index f27b9d808a2a..b9eaee14f3c0 100644
--- a/crypto/openssh/openbsd-compat/bsd-snprintf.c
+++ b/crypto/openssh/openbsd-compat/bsd-snprintf.c
@@ -73,7 +73,7 @@
* Fix incorrect zpadlen handling in fmtfp.
* Thanks to Ollie Oldham <ollie.oldham@metro-optix.com> for spotting it.
* few mods to make it easier to compile the tests.
- * addedd the "Ollie" test to the floating point ones.
+ * added 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
@@ -135,13 +135,13 @@
#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)
+#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
@@ -592,7 +592,7 @@ fmtint(char *buffer, size_t *currlen, size_t maxlen,
#ifdef DEBUG_SNPRINTF
printf("zpad: %d, spad: %d, min: %d, max: %d, place: %d\n",
- zpadlen, spadlen, min, max, place);
+ zpadlen, spadlen, min, max, place);
#endif
/* Spaces */
diff --git a/crypto/openssh/openbsd-compat/bsd-statvfs.c b/crypto/openssh/openbsd-compat/bsd-statvfs.c
index e3bd87d985a3..10d8764392c2 100644
--- a/crypto/openssh/openbsd-compat/bsd-statvfs.c
+++ b/crypto/openssh/openbsd-compat/bsd-statvfs.c
@@ -29,6 +29,11 @@
# define MNAMELEN 32
#endif
+#ifdef HAVE_STRUCT_STATFS_F_FILES
+# define HAVE_STRUCT_STATFS
+#endif
+
+#ifdef HAVE_STRUCT_STATFS
static void
copy_statfs_to_statvfs(struct statvfs *to, struct statfs *from)
{
@@ -48,11 +53,12 @@ copy_statfs_to_statvfs(struct statvfs *to, struct statfs *from)
#endif
to->f_namemax = MNAMELEN;
}
+#endif
# ifndef HAVE_STATVFS
int statvfs(const char *path, struct statvfs *buf)
{
-# ifdef HAVE_STATFS
+# if defined(HAVE_STATFS) && defined(HAVE_STRUCT_STATFS)
struct statfs fs;
memset(&fs, 0, sizeof(fs));
@@ -70,7 +76,7 @@ int statvfs(const char *path, struct statvfs *buf)
# ifndef HAVE_FSTATVFS
int fstatvfs(int fd, struct statvfs *buf)
{
-# ifdef HAVE_FSTATFS
+# if defined(HAVE_FSTATFS) && defined(HAVE_STRUCT_STATFS)
struct statfs fs;
memset(&fs, 0, sizeof(fs));
diff --git a/crypto/openssh/openbsd-compat/bsd-waitpid.h b/crypto/openssh/openbsd-compat/bsd-waitpid.h
index b551268ab063..bd61b6909240 100644
--- a/crypto/openssh/openbsd-compat/bsd-waitpid.h
+++ b/crypto/openssh/openbsd-compat/bsd-waitpid.h
@@ -40,7 +40,7 @@
#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)
+#define WCOREDUMP(w) ((_W_INT(w)) & WCOREFLAG)
/* Prototype */
pid_t waitpid(int, int *, int);
diff --git a/crypto/openssh/openbsd-compat/explicit_bzero.c b/crypto/openssh/openbsd-compat/explicit_bzero.c
index 6ef9825a9ad3..68cd2c10b3c8 100644
--- a/crypto/openssh/openbsd-compat/explicit_bzero.c
+++ b/crypto/openssh/openbsd-compat/explicit_bzero.c
@@ -15,7 +15,15 @@
#ifndef HAVE_EXPLICIT_BZERO
-#ifdef HAVE_MEMSET_S
+#ifdef HAVE_EXPLICIT_MEMSET
+
+void
+explicit_bzero(void *p, size_t n)
+{
+ (void)explicit_memset(p, 0, n);
+}
+
+#elif defined(HAVE_MEMSET_S)
void
explicit_bzero(void *p, size_t n)
diff --git a/crypto/openssh/openbsd-compat/fnmatch.c b/crypto/openssh/openbsd-compat/fnmatch.c
new file mode 100644
index 000000000000..b5641a091632
--- /dev/null
+++ b/crypto/openssh/openbsd-compat/fnmatch.c
@@ -0,0 +1,495 @@
+/* $OpenBSD: fnmatch.c,v 1.22 2020/03/13 03:25:45 djm Exp $ */
+
+/* Copyright (c) 2011, VMware, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * 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.
+ * * Neither the name of the VMware, Inc. 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 COPYRIGHT HOLDERS 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 VMWARE, INC. 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.
+ */
+
+/*
+ * Copyright (c) 2008, 2016 Todd C. Miller <millert@openbsd.org>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* Authored by William A. Rowe Jr. <wrowe; apache.org, vmware.com>, April 2011
+ *
+ * Derived from The Open Group Base Specifications Issue 7, IEEE Std 1003.1-2008
+ * as described in;
+ * http://pubs.opengroup.org/onlinepubs/9699919799/functions/fnmatch.html
+ *
+ * Filename pattern matches defined in section 2.13, "Pattern Matching Notation"
+ * from chapter 2. "Shell Command Language"
+ * http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_13
+ * where; 1. A bracket expression starting with an unquoted <circumflex> '^'
+ * character CONTINUES to specify a non-matching list; 2. an explicit <period> '.'
+ * in a bracket expression matching list, e.g. "[.abc]" does NOT match a leading
+ * <period> in a filename; 3. a <left-square-bracket> '[' which does not introduce
+ * a valid bracket expression is treated as an ordinary character; 4. a differing
+ * number of consecutive slashes within pattern and string will NOT match;
+ * 5. a trailing '\' in FNM_ESCAPE mode is treated as an ordinary '\' character.
+ *
+ * Bracket expansion defined in section 9.3.5, "RE Bracket Expression",
+ * from chapter 9, "Regular Expressions"
+ * http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap09.html#tag_09_03_05
+ * with no support for collating symbols, equivalence class expressions or
+ * character class expressions. A partial range expression with a leading
+ * hyphen following a valid range expression will match only the ordinary
+ * <hyphen> and the ending character (e.g. "[a-m-z]" will match characters
+ * 'a' through 'm', a <hyphen> '-', or a 'z').
+ *
+ * Supports BSD extensions FNM_LEADING_DIR to match pattern to the end of one
+ * path segment of string, and FNM_CASEFOLD to ignore alpha case.
+ *
+ * NOTE: Only POSIX/C single byte locales are correctly supported at this time.
+ * Notably, non-POSIX locales with FNM_CASEFOLD produce undefined results,
+ * particularly in ranges of mixed case (e.g. "[A-z]") or spanning alpha and
+ * nonalpha characters within a range.
+ *
+ * XXX comments below indicate porting required for multi-byte character sets
+ * and non-POSIX locale collation orders; requires mbr* APIs to track shift
+ * state of pattern and string (rewinding pattern and string repeatedly).
+ *
+ * Certain parts of the code assume 0x00-0x3F are unique with any MBCS (e.g.
+ * UTF-8, SHIFT-JIS, etc). Any implementation allowing '\' as an alternate
+ * path delimiter must be aware that 0x5C is NOT unique within SHIFT-JIS.
+ */
+
+/* OPENBSD ORIGINAL: lib/libc/gen/fnmatch.c */
+
+#include "includes.h"
+#ifndef HAVE_FNMATCH
+
+#include <fnmatch.h>
+#include <string.h>
+#include <ctype.h>
+
+#include "charclass.h"
+
+#define RANGE_MATCH 1
+#define RANGE_NOMATCH 0
+#define RANGE_ERROR (-1)
+
+static int
+classmatch(const char *pattern, char test, int foldcase, const char **ep)
+{
+ const char * const mismatch = pattern;
+ const char *colon;
+ struct cclass *cc;
+ int rval = RANGE_NOMATCH;
+ size_t len;
+
+ if (pattern[0] != '[' || pattern[1] != ':') {
+ *ep = mismatch;
+ return RANGE_ERROR;
+ }
+ pattern += 2;
+
+ if ((colon = strchr(pattern, ':')) == NULL || colon[1] != ']') {
+ *ep = mismatch;
+ return RANGE_ERROR;
+ }
+ *ep = colon + 2;
+ len = (size_t)(colon - pattern);
+
+ if (foldcase && strncmp(pattern, "upper:]", 7) == 0)
+ pattern = "lower:]";
+ for (cc = cclasses; cc->name != NULL; cc++) {
+ if (!strncmp(pattern, cc->name, len) && cc->name[len] == '\0') {
+ if (cc->isctype((unsigned char)test))
+ rval = RANGE_MATCH;
+ break;
+ }
+ }
+ if (cc->name == NULL) {
+ /* invalid character class, treat as normal text */
+ *ep = mismatch;
+ rval = RANGE_ERROR;
+ }
+ return rval;
+}
+
+/* Most MBCS/collation/case issues handled here. Wildcard '*' is not handled.
+ * EOS '\0' and the FNM_PATHNAME '/' delimiters are not advanced over,
+ * however the "\/" sequence is advanced to '/'.
+ *
+ * Both pattern and string are **char to support pointer increment of arbitrary
+ * multibyte characters for the given locale, in a later iteration of this code
+ */
+static int fnmatch_ch(const char **pattern, const char **string, int flags)
+{
+ const char * const mismatch = *pattern;
+ const int nocase = !!(flags & FNM_CASEFOLD);
+ const int escape = !(flags & FNM_NOESCAPE);
+ const int slash = !!(flags & FNM_PATHNAME);
+ int result = FNM_NOMATCH;
+ const char *startch;
+ int negate;
+
+ if (**pattern == '[') {
+ ++*pattern;
+
+ /* Handle negation, either leading ! or ^ operators */
+ negate = (**pattern == '!') || (**pattern == '^');
+ if (negate)
+ ++*pattern;
+
+ /* ']' is an ordinary char at the start of the range pattern */
+ if (**pattern == ']')
+ goto leadingclosebrace;
+
+ while (**pattern) {
+ if (**pattern == ']') {
+ ++*pattern;
+ /* XXX: Fix for MBCS character width */
+ ++*string;
+ return (result ^ negate);
+ }
+
+ if (escape && (**pattern == '\\')) {
+ ++*pattern;
+
+ /* Patterns must terminate with ']', not EOS */
+ if (!**pattern)
+ break;
+ }
+
+ /* Patterns must terminate with ']' not '/' */
+ if (slash && (**pattern == '/'))
+ break;
+
+ /* Match character classes. */
+ switch (classmatch(*pattern, **string, nocase, pattern)) {
+ case RANGE_MATCH:
+ result = 0;
+ continue;
+ case RANGE_NOMATCH:
+ /* Valid character class but no match. */
+ continue;
+ default:
+ /* Not a valid character class. */
+ break;
+ }
+ if (!**pattern)
+ break;
+
+leadingclosebrace:
+ /* Look at only well-formed range patterns;
+ * "x-]" is not allowed unless escaped ("x-\]")
+ * XXX: Fix for locale/MBCS character width
+ */
+ if (((*pattern)[1] == '-') && ((*pattern)[2] != ']')) {
+ startch = *pattern;
+ *pattern += (escape && ((*pattern)[2] == '\\')) ? 3 : 2;
+
+ /*
+ * NOT a properly balanced [expr] pattern, EOS
+ * terminated or ranges containing a slash in
+ * FNM_PATHNAME mode pattern fall out to to the
+ * rewind and test '[' literal code path.
+ */
+ if (!**pattern || (slash && (**pattern == '/')))
+ break;
+
+ /* XXX: handle locale/MBCS comparison, advance by MBCS char width */
+ if ((**string >= *startch) && (**string <= **pattern))
+ result = 0;
+ else if (nocase &&
+ (isupper((unsigned char)**string) ||
+ isupper((unsigned char)*startch) ||
+ isupper((unsigned char)**pattern)) &&
+ (tolower((unsigned char)**string) >=
+ tolower((unsigned char)*startch)) &&
+ (tolower((unsigned char)**string) <=
+ tolower((unsigned char)**pattern)))
+ result = 0;
+
+ ++*pattern;
+ continue;
+ }
+
+ /* XXX: handle locale/MBCS comparison, advance by MBCS char width */
+ if ((**string == **pattern))
+ result = 0;
+ else if (nocase && (isupper((unsigned char)**string) ||
+ isupper((unsigned char)**pattern)) &&
+ (tolower((unsigned char)**string) ==
+ tolower((unsigned char)**pattern)))
+ result = 0;
+
+ ++*pattern;
+ }
+ /*
+ * NOT a properly balanced [expr] pattern;
+ * Rewind and reset result to test '[' literal
+ */
+ *pattern = mismatch;
+ result = FNM_NOMATCH;
+ } else if (**pattern == '?') {
+ /* Optimize '?' match before unescaping **pattern */
+ if (!**string || (slash && (**string == '/')))
+ return FNM_NOMATCH;
+ result = 0;
+ goto fnmatch_ch_success;
+ } else if (escape && (**pattern == '\\') && (*pattern)[1]) {
+ ++*pattern;
+ }
+
+ /* XXX: handle locale/MBCS comparison, advance by the MBCS char width */
+ if (**string == **pattern)
+ result = 0;
+ else if (nocase && (isupper((unsigned char)**string) ||
+ isupper((unsigned char)**pattern)) &&
+ (tolower((unsigned char)**string) ==
+ tolower((unsigned char)**pattern)))
+ result = 0;
+
+ /* Refuse to advance over trailing slash or NULs */
+ if (**string == '\0' || **pattern == '\0' ||
+ (slash && ((**string == '/') || (**pattern == '/'))))
+ return result;
+
+fnmatch_ch_success:
+ ++*pattern;
+ ++*string;
+ return result;
+}
+
+
+int fnmatch(const char *pattern, const char *string, int flags)
+{
+ static const char dummystring[2] = {' ', 0};
+ const int escape = !(flags & FNM_NOESCAPE);
+ const int slash = !!(flags & FNM_PATHNAME);
+ const int leading_dir = !!(flags & FNM_LEADING_DIR);
+ const char *dummyptr, *matchptr, *strendseg;
+ int wild;
+ /* For '*' wild processing only; suppress 'used before initialization'
+ * warnings with dummy initialization values;
+ */
+ const char *strstartseg = NULL;
+ const char *mismatch = NULL;
+ int matchlen = 0;
+
+ if (*pattern == '*')
+ goto firstsegment;
+
+ while (*pattern && *string) {
+ /*
+ * Pre-decode "\/" which has no special significance, and
+ * match balanced slashes, starting a new segment pattern.
+ */
+ if (slash && escape && (*pattern == '\\') && (pattern[1] == '/'))
+ ++pattern;
+ if (slash && (*pattern == '/') && (*string == '/')) {
+ ++pattern;
+ ++string;
+ }
+
+firstsegment:
+ /*
+ * At the beginning of each segment, validate leading period
+ * behavior.
+ */
+ if ((flags & FNM_PERIOD) && (*string == '.')) {
+ if (*pattern == '.')
+ ++pattern;
+ else if (escape && (*pattern == '\\') && (pattern[1] == '.'))
+ pattern += 2;
+ else
+ return FNM_NOMATCH;
+ ++string;
+ }
+
+ /*
+ * Determine the end of string segment. Presumes '/'
+ * character is unique, not composite in any MBCS encoding
+ */
+ if (slash) {
+ strendseg = strchr(string, '/');
+ if (!strendseg)
+ strendseg = strchr(string, '\0');
+ } else {
+ strendseg = strchr(string, '\0');
+ }
+
+ /*
+ * Allow pattern '*' to be consumed even with no remaining
+ * string to match.
+ */
+ while (*pattern) {
+ if ((string > strendseg) ||
+ ((string == strendseg) && (*pattern != '*')))
+ break;
+
+ if (slash && ((*pattern == '/') ||
+ (escape && (*pattern == '\\') && (pattern[1] == '/'))))
+ break;
+
+ /*
+ * Reduce groups of '*' and '?' to n '?' matches
+ * followed by one '*' test for simplicity.
+ */
+ for (wild = 0; (*pattern == '*') || (*pattern == '?'); ++pattern) {
+ if (*pattern == '*') {
+ wild = 1;
+ } else if (string < strendseg) { /* && (*pattern == '?') */
+ /* XXX: Advance 1 char for MBCS locale */
+ ++string;
+ }
+ else { /* (string >= strendseg) && (*pattern == '?') */
+ return FNM_NOMATCH;
+ }
+ }
+
+ if (wild) {
+ strstartseg = string;
+ mismatch = pattern;
+
+ /*
+ * Count fixed (non '*') char matches remaining
+ * in pattern * excluding '/' (or "\/") and '*'.
+ */
+ for (matchptr = pattern, matchlen = 0; 1; ++matchlen) {
+ if ((*matchptr == '\0') ||
+ (slash && ((*matchptr == '/') ||
+ (escape && (*matchptr == '\\') &&
+ (matchptr[1] == '/'))))) {
+ /* Compare precisely this many
+ * trailing string chars, the
+ * resulting match needs no
+ * wildcard loop.
+ */
+ /* XXX: Adjust for MBCS */
+ if (string + matchlen > strendseg)
+ return FNM_NOMATCH;
+
+ string = strendseg - matchlen;
+ wild = 0;
+ break;
+ }
+
+ if (*matchptr == '*') {
+ /*
+ * Ensure at least this many
+ * trailing string chars remain
+ * for the first comparison.
+ */
+ /* XXX: Adjust for MBCS */
+ if (string + matchlen > strendseg)
+ return FNM_NOMATCH;
+
+ /*
+ * Begin first wild comparison
+ * at the current position.
+ */
+ break;
+ }
+
+ /*
+ * Skip forward in pattern by a single
+ * character match Use a dummy
+ * fnmatch_ch() test to count one
+ * "[range]" escape.
+ */
+ /* XXX: Adjust for MBCS */
+ if (escape && (*matchptr == '\\') &&
+ matchptr[1]) {
+ matchptr += 2;
+ } else if (*matchptr == '[') {
+ dummyptr = dummystring;
+ fnmatch_ch(&matchptr, &dummyptr,
+ flags);
+ } else {
+ ++matchptr;
+ }
+ }
+ }
+
+ /* Incrementally match string against the pattern. */
+ while (*pattern && (string < strendseg)) {
+ /* Success; begin a new wild pattern search. */
+ if (*pattern == '*')
+ break;
+
+ if (slash && ((*string == '/') ||
+ (*pattern == '/') || (escape &&
+ (*pattern == '\\') && (pattern[1] == '/'))))
+ break;
+
+ /*
+ * Compare ch's (the pattern is advanced over
+ * "\/" to the '/', but slashes will mismatch,
+ * and are not consumed).
+ */
+ if (!fnmatch_ch(&pattern, &string, flags))
+ continue;
+
+ /*
+ * Failed to match, loop against next char
+ * offset of string segment until not enough
+ * string chars remain to match the fixed
+ * pattern.
+ */
+ if (wild) {
+ /* XXX: Advance 1 char for MBCS locale */
+ string = ++strstartseg;
+ if (string + matchlen > strendseg)
+ return FNM_NOMATCH;
+
+ pattern = mismatch;
+ continue;
+ } else
+ return FNM_NOMATCH;
+ }
+ }
+
+ if (*string && !((slash || leading_dir) && (*string == '/')))
+ return FNM_NOMATCH;
+
+ if (*pattern && !(slash && ((*pattern == '/') ||
+ (escape && (*pattern == '\\') && (pattern[1] == '/')))))
+ return FNM_NOMATCH;
+
+ if (leading_dir && !*pattern && *string == '/')
+ return 0;
+ }
+
+ /* Where both pattern and string are at EOS, declare success. */
+ if (!*string && !*pattern)
+ return 0;
+
+ /* Pattern didn't match to the end of string. */
+ return FNM_NOMATCH;
+}
+#endif /* HAVE_FNMATCH */
diff --git a/crypto/openssh/openbsd-compat/fnmatch.h b/crypto/openssh/openbsd-compat/fnmatch.h
new file mode 100644
index 000000000000..d3bc4a8634f1
--- /dev/null
+++ b/crypto/openssh/openbsd-compat/fnmatch.h
@@ -0,0 +1,66 @@
+/* $OpenBSD: fnmatch.h,v 1.8 2005/12/13 00:35:22 millert Exp $ */
+/* $NetBSD: fnmatch.h,v 1.5 1994/10/26 00:55:53 cgd Exp $ */
+
+/*-
+ * Copyright (c) 1992, 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.
+ *
+ * @(#)fnmatch.h 8.1 (Berkeley) 6/2/93
+ */
+
+/* OPENBSD ORIGINAL: include/fnmatch.h */
+
+#ifndef HAVE_FNMATCH_H
+/* Ensure we define FNM_CASEFOLD */
+#define __BSD_VISIBLE 1
+
+#ifndef _FNMATCH_H_
+#define _FNMATCH_H_
+
+#ifdef HAVE_SYS_CDEFS_H
+#include <sys/cdefs.h>
+#endif
+
+#define FNM_NOMATCH 1 /* Match failed. */
+#define FNM_NOSYS 2 /* Function not supported (unused). */
+
+#define FNM_NOESCAPE 0x01 /* Disable backslash escaping. */
+#define FNM_PATHNAME 0x02 /* Slash must be matched by slash. */
+#define FNM_PERIOD 0x04 /* Period must be matched by period. */
+#if __BSD_VISIBLE
+#define FNM_LEADING_DIR 0x08 /* Ignore /<tail> after Imatch. */
+#define FNM_CASEFOLD 0x10 /* Case insensitive search. */
+#define FNM_IGNORECASE FNM_CASEFOLD
+#define FNM_FILE_NAME FNM_PATHNAME
+#endif
+
+/* __BEGIN_DECLS */
+int fnmatch(const char *, const char *, int);
+/* __END_DECLS */
+
+#endif /* !_FNMATCH_H_ */
+#endif /* ! HAVE_FNMATCH_H */
diff --git a/crypto/openssh/openbsd-compat/getopt_long.c b/crypto/openssh/openbsd-compat/getopt_long.c
index e28947430578..1a5001f7d98a 100644
--- a/crypto/openssh/openbsd-compat/getopt_long.c
+++ b/crypto/openssh/openbsd-compat/getopt_long.c
@@ -87,7 +87,7 @@ char *optarg; /* argument associated with option */
/* return values */
#define BADCH (int)'?'
#define BADARG ((*options == ':') ? (int)':' : (int)'?')
-#define INORDER (int)1
+#define INORDER (int)1
#define EMSG ""
diff --git a/crypto/openssh/openbsd-compat/glob.c b/crypto/openssh/openbsd-compat/glob.c
index 7c97e67f557c..e89151789aa3 100644
--- a/crypto/openssh/openbsd-compat/glob.c
+++ b/crypto/openssh/openbsd-compat/glob.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: glob.c,v 1.38 2011/09/22 06:27:29 djm Exp $ */
+/* $OpenBSD: glob.c,v 1.49 2020/04/21 08:25:22 dtucker Exp $ */
/*
* Copyright (c) 1989, 1993
* The Regents of the University of California. All rights reserved.
@@ -70,6 +70,9 @@
#include <limits.h>
#include <pwd.h>
#include <stdlib.h>
+#ifdef HAVE_STDINT_H
+#include <stdint.h>
+#endif
#include <string.h>
#include <unistd.h>
@@ -80,6 +83,10 @@
#include "charclass.h"
+#ifdef TILDE
+# undef TILDE
+#endif
+
#define DOLLAR '$'
#define DOT '.'
#define EOS '\0'
@@ -131,12 +138,9 @@ typedef char Char;
#define ismeta(c) (((c)&M_QUOTE) != 0)
#define GLOB_LIMIT_MALLOC 65536
-#define GLOB_LIMIT_STAT 128
+#define GLOB_LIMIT_STAT 2048
#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;
@@ -150,7 +154,7 @@ struct glob_path_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_Ctoc(const Char *, char *, size_t);
static int g_lstat(Char *, struct stat *, glob_t *);
static DIR *g_opendir(Char *, glob_t *);
static Char *g_strchr(const Char *, int);
@@ -169,7 +173,7 @@ static const Char *
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);
+static int match(Char *, Char *, Char *);
#ifdef DEBUG
static void qprintf(const char *, Char *);
#endif
@@ -180,12 +184,9 @@ glob(const char *pattern, int flags, int (*errfunc)(const char *, int),
{
const u_char *patnext;
int c;
- Char *bufnext, *bufend, patbuf[MAXPATHLEN];
+ Char *bufnext, *bufend, patbuf[PATH_MAX];
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;
@@ -198,13 +199,15 @@ glob(const char *pattern, int flags, int (*errfunc)(const char *, int),
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)
+ if (strnlen(pattern, PATH_MAX) == PATH_MAX)
+ return(GLOB_NOMATCH);
+
+ if (pglob->gl_offs >= SSIZE_MAX || pglob->gl_pathc >= SSIZE_MAX ||
+ pglob->gl_pathc >= SSIZE_MAX - pglob->gl_offs - 1)
return GLOB_NOSPACE;
bufnext = patbuf;
- bufend = bufnext + MAXPATHLEN - 1;
+ bufend = bufnext + PATH_MAX - 1;
if (flags & GLOB_NOESCAPE)
while (bufnext < bufend && (c = *patnext++) != EOS)
*bufnext++ = c;
@@ -261,7 +264,7 @@ globexp2(const Char *ptr, const Char *pattern, glob_t *pglob,
int i, rv;
Char *lm, *ls;
const Char *pe, *pm, *pl;
- Char patbuf[MAXPATHLEN];
+ Char patbuf[PATH_MAX];
/* copy part up to the brace */
for (lm = patbuf, pm = pattern; pm != ptr; *lm++ = *pm++)
@@ -472,10 +475,11 @@ static int
glob0(const Char *pattern, glob_t *pglob, struct glob_lim *limitp)
{
const Char *qpatnext;
- int c, err, oldpathc;
- Char *bufnext, patbuf[MAXPATHLEN];
+ int c, err;
+ size_t oldpathc;
+ Char *bufnext, patbuf[PATH_MAX];
- qpatnext = globtilde(pattern, patbuf, MAXPATHLEN, pglob);
+ qpatnext = globtilde(pattern, patbuf, PATH_MAX, pglob);
oldpathc = pglob->gl_pathc;
bufnext = patbuf;
@@ -545,7 +549,7 @@ glob0(const Char *pattern, glob_t *pglob, struct glob_lim *limitp)
qprintf("glob0:", patbuf);
#endif
- if ((err = glob1(patbuf, patbuf+MAXPATHLEN-1, pglob, limitp)) != 0)
+ if ((err = glob1(patbuf, patbuf+PATH_MAX-1, pglob, limitp)) != 0)
return(err);
/*
@@ -566,9 +570,9 @@ glob0(const Char *pattern, glob_t *pglob, struct glob_lim *limitp)
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;
+ size_t i;
+ size_t n = pglob->gl_pathc - oldpathc;
+ size_t o = pglob->gl_offs + oldpathc;
if ((path_stat = calloc(n, sizeof(*path_stat))) == NULL)
return GLOB_NOSPACE;
@@ -609,13 +613,13 @@ compare_gps(const void *_p, const void *_q)
static int
glob1(Char *pattern, Char *pattern_last, glob_t *pglob, struct glob_lim *limitp)
{
- Char pathbuf[MAXPATHLEN];
+ Char pathbuf[PATH_MAX];
/* 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,
+ return(glob2(pathbuf, pathbuf+PATH_MAX-1,
+ pathbuf, pathbuf+PATH_MAX-1,
pattern, pattern_last, pglob, limitp));
}
@@ -639,8 +643,6 @@ glob2(Char *pathbuf, Char *pathbuf_last, Char *pathend, Char *pathend_last,
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) {
@@ -649,6 +651,8 @@ glob2(Char *pathbuf, Char *pathbuf_last, Char *pathend, Char *pathend_last,
*pathend = EOS;
return(GLOB_NOSPACE);
}
+ if (g_lstat(pathbuf, &sb, pglob))
+ return(0);
if (((pglob->gl_flags & GLOB_MARK) &&
pathend[-1] != SEP) && (S_ISDIR(sb.st_mode) ||
@@ -700,7 +704,7 @@ glob3(Char *pathbuf, Char *pathbuf_last, Char *pathend, Char *pathend_last,
struct dirent *dp;
DIR *dirp;
int err;
- char buf[MAXPATHLEN];
+ char buf[PATH_MAX];
/*
* The readdirfunc declaration can't be prototyped, because it is
@@ -760,7 +764,7 @@ glob3(Char *pathbuf, Char *pathbuf_last, Char *pathend, Char *pathend_last,
break;
}
- if (!match(pathend, pattern, restpattern, GLOB_LIMIT_RECUR)) {
+ if (!match(pathend, pattern, restpattern)) {
*pathend = EOS;
continue;
}
@@ -797,56 +801,51 @@ globextend(const Char *path, glob_t *pglob, struct glob_lim *limitp,
struct stat *sb)
{
char **pathv;
- ssize_t i;
- size_t newn, len;
+ size_t i, 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 ||
+ if (pglob->gl_offs >= SSIZE_MAX ||
+ pglob->gl_pathc >= SSIZE_MAX ||
+ newn >= SSIZE_MAX ||
SIZE_MAX / sizeof(*pathv) <= newn ||
SIZE_MAX / sizeof(*statv) <= newn) {
nospace:
- for (i = pglob->gl_offs; i < (ssize_t)(newn - 2); i++) {
+ for (i = pglob->gl_offs; i < 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;
- }
+ free(pglob->gl_pathv);
+ pglob->gl_pathv = NULL;
+ free(pglob->gl_statv);
+ pglob->gl_statv = NULL;
return(GLOB_NOSPACE);
}
- pathv = realloc(pglob->gl_pathv, newn * sizeof(*pathv));
+ pathv = reallocarray(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; )
+ for (i = pglob->gl_offs; i > 0; i--)
*--pathv = NULL;
}
pglob->gl_pathv = pathv;
if ((pglob->gl_flags & GLOB_KEEPSTAT) != 0) {
- statv = realloc(pglob->gl_statv, newn * sizeof(*statv));
+ statv = reallocarray(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; )
+ for (i = pglob->gl_offs; i > 0; i--)
*--statv = NULL;
}
pglob->gl_statv = statv;
@@ -894,17 +893,24 @@ globextend(const Char *path, glob_t *pglob, struct glob_lim *limitp,
/*
* pattern matching function for filenames. Each occurrence of the *
- * pattern causes a recursion level.
+ * pattern causes an iteration.
+ *
+ * Note, this function differs from the original as per the discussion
+ * here: https://research.swtch.com/glob
+ *
+ * Basically we removed the recursion and made it use the algorithm
+ * from Russ Cox to not go quadratic on cases like a file called
+ * ("a" x 100) . "x" matched against a pattern like "a*a*a*a*a*a*a*y".
*/
static int
-match(Char *name, Char *pat, Char *patend, int recur)
+match(Char *name, Char *pat, Char *patend)
{
int ok, negate_range;
Char c, k;
+ Char *nextp = NULL;
+ Char *nextn = NULL;
- if (recur-- == 0)
- return(GLOB_NOSPACE);
-
+loop:
while (pat < patend) {
c = *pat++;
switch (c & M_MASK) {
@@ -913,19 +919,19 @@ match(Char *name, Char *pat, Char *patend, int recur)
pat++; /* eat consecutive '*' */
if (pat == patend)
return(1);
- do {
- if (match(name, pat, patend, recur))
- return(1);
- } while (*name++ != EOS);
- return(0);
+ if (*name == EOS)
+ return(0);
+ nextn = name + 1;
+ nextp = pat - 1;
+ break;
case M_ONE:
if (*name++ == EOS)
- return(0);
+ goto fail;
break;
case M_SET:
ok = 0;
if ((k = *name++) == EOS)
- return(0);
+ goto fail;
if ((negate_range = ((*pat & M_MASK) == M_NOT)) != EOS)
++pat;
while (((c = *pat++) & M_MASK) != M_END) {
@@ -944,36 +950,43 @@ match(Char *name, Char *pat, Char *patend, int recur)
ok = 1;
}
if (ok == negate_range)
- return(0);
+ goto fail;
break;
default:
if (*name++ != c)
- return(0);
+ goto fail;
break;
}
}
- return(*name == EOS);
+ if (*name == EOS)
+ return(1);
+
+fail:
+ if (nextn) {
+ pat = nextp;
+ name = nextn;
+ goto loop;
+ }
+ return(0);
}
/* Free allocated data belonging to a glob_t structure. */
void
globfree(glob_t *pglob)
{
- int i;
+ size_t 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(*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[i]);
}
free(pglob->gl_statv);
pglob->gl_statv = NULL;
@@ -983,7 +996,7 @@ globfree(glob_t *pglob)
static DIR *
g_opendir(Char *str, glob_t *pglob)
{
- char buf[MAXPATHLEN];
+ char buf[PATH_MAX];
if (!*str)
strlcpy(buf, ".", sizeof buf);
@@ -1001,7 +1014,7 @@ g_opendir(Char *str, glob_t *pglob)
static int
g_lstat(Char *fn, struct stat *sb, glob_t *pglob)
{
- char buf[MAXPATHLEN];
+ char buf[PATH_MAX];
if (g_Ctoc(fn, buf, sizeof(buf)))
return(-1);
@@ -1013,7 +1026,7 @@ g_lstat(Char *fn, struct stat *sb, glob_t *pglob)
static int
g_stat(Char *fn, struct stat *sb, glob_t *pglob)
{
- char buf[MAXPATHLEN];
+ char buf[PATH_MAX];
if (g_Ctoc(fn, buf, sizeof(buf)))
return(-1);
@@ -1033,7 +1046,7 @@ g_strchr(const Char *str, int ch)
}
static int
-g_Ctoc(const Char *str, char *buf, u_int len)
+g_Ctoc(const Char *str, char *buf, size_t len)
{
while (len--) {
diff --git a/crypto/openssh/openbsd-compat/glob.h b/crypto/openssh/openbsd-compat/glob.h
index f069a05dc656..1692d36cc25a 100644
--- a/crypto/openssh/openbsd-compat/glob.h
+++ b/crypto/openssh/openbsd-compat/glob.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: glob.h,v 1.11 2010/09/24 13:32:55 djm Exp $ */
+/* $OpenBSD: glob.h,v 1.14 2019/02/04 16:45:40 millert Exp $ */
/* $NetBSD: glob.h,v 1.5 1994/10/26 00:55:56 cgd Exp $ */
/*
@@ -46,6 +46,7 @@
#define _COMPAT_GLOB_H_
#include <sys/stat.h>
+#include <sys/types.h>
# define glob_t _ssh_compat_glob_t
# define glob(a, b, c, d) _ssh__compat_glob(a, b, c, d)
@@ -53,9 +54,9 @@
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. */
+ size_t gl_pathc; /* Count of total paths so far. */
+ size_t gl_matchc; /* Count of paths matching pattern. */
+ size_t 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 */
diff --git a/crypto/openssh/openbsd-compat/libressl-api-compat.c b/crypto/openssh/openbsd-compat/libressl-api-compat.c
index de3e64a63f12..801a2e8dd3d9 100644
--- a/crypto/openssh/openbsd-compat/libressl-api-compat.c
+++ b/crypto/openssh/openbsd-compat/libressl-api-compat.c
@@ -152,7 +152,9 @@
#include <openssl/dsa.h>
#include <openssl/rsa.h>
#include <openssl/evp.h>
+#ifdef OPENSSL_HAS_ECC
#include <openssl/ecdsa.h>
+#endif
#include <openssl/dh.h>
#ifndef HAVE_DSA_GET0_PQG
@@ -282,7 +284,7 @@ RSA_set0_crt_params(RSA *r, BIGNUM *dmp1, BIGNUM *dmq1, BIGNUM *iqmp)
if ((r->dmp1 == NULL && dmp1 == NULL) ||
(r->dmq1 == NULL && dmq1 == NULL) ||
(r->iqmp == NULL && iqmp == NULL))
- return 0;
+ return 0;
if (dmp1 != NULL) {
BN_free(r->dmp1);
@@ -417,6 +419,7 @@ DSA_SIG_set0(DSA_SIG *sig, BIGNUM *r, BIGNUM *s)
}
#endif /* HAVE_DSA_SIG_SET0 */
+#ifdef OPENSSL_HAS_ECC
#ifndef HAVE_ECDSA_SIG_GET0
void
ECDSA_SIG_get0(const ECDSA_SIG *sig, const BIGNUM **pr, const BIGNUM **ps)
@@ -442,6 +445,7 @@ ECDSA_SIG_set0(ECDSA_SIG *sig, BIGNUM *r, BIGNUM *s)
return 1;
}
#endif /* HAVE_ECDSA_SIG_SET0 */
+#endif /* OPENSSL_HAS_ECC */
#ifndef HAVE_DH_GET0_PQG
void
diff --git a/crypto/openssh/openbsd-compat/memmem.c b/crypto/openssh/openbsd-compat/memmem.c
new file mode 100644
index 000000000000..2637401d7c6e
--- /dev/null
+++ b/crypto/openssh/openbsd-compat/memmem.c
@@ -0,0 +1,196 @@
+/* $OpenBSD: memmem.c,v 1.5 2020/04/16 12:39:28 claudio Exp $ */
+
+/*
+ * Copyright (c) 2005-2020 Rich Felker, et al.
+ *
+ * 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, 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 AUTHORS OR 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.
+ */
+
+/* OPENBSD ORIGINAL: lib/libc/string/memmem.c */
+
+#include "includes.h"
+
+#ifndef HAVE_MEMMEM
+
+#include <string.h>
+#ifdef HAVE_STDINT_H
+#include <stdint.h>
+#endif
+
+static char *
+twobyte_memmem(const unsigned char *h, size_t k, const unsigned char *n)
+{
+ uint16_t nw = n[0]<<8 | n[1], hw = h[0]<<8 | h[1];
+ for (h+=2, k-=2; k; k--, hw = hw<<8 | *h++)
+ if (hw == nw) return (char *)h-2;
+ return hw == nw ? (char *)h-2 : 0;
+}
+
+static char *
+threebyte_memmem(const unsigned char *h, size_t k, const unsigned char *n)
+{
+ uint32_t nw = n[0]<<24 | n[1]<<16 | n[2]<<8;
+ uint32_t hw = h[0]<<24 | h[1]<<16 | h[2]<<8;
+ for (h+=3, k-=3; k; k--, hw = (hw|*h++)<<8)
+ if (hw == nw) return (char *)h-3;
+ return hw == nw ? (char *)h-3 : 0;
+}
+
+static char *
+fourbyte_memmem(const unsigned char *h, size_t k, const unsigned char *n)
+{
+ uint32_t nw = n[0]<<24 | n[1]<<16 | n[2]<<8 | n[3];
+ uint32_t hw = h[0]<<24 | h[1]<<16 | h[2]<<8 | h[3];
+ for (h+=4, k-=4; k; k--, hw = hw<<8 | *h++)
+ if (hw == nw) return (char *)h-4;
+ return hw == nw ? (char *)h-4 : 0;
+}
+
+#if 0
+/* In -portable, defines.h ensures that these are already defined. */
+#define MAX(a,b) ((a)>(b)?(a):(b))
+#define MIN(a,b) ((a)<(b)?(a):(b))
+#endif
+
+#define BITOP(a,b,op) \
+ ((a)[(size_t)(b)/(8*sizeof *(a))] op (size_t)1<<((size_t)(b)%(8*sizeof *(a))))
+
+/*
+ * Maxime Crochemore and Dominique Perrin, Two-way string-matching,
+ * Journal of the ACM, 38(3):651-675, July 1991.
+ */
+static char *
+twoway_memmem(const unsigned char *h, const unsigned char *z,
+ const unsigned char *n, size_t l)
+{
+ size_t i, ip, jp, k, p, ms, p0, mem, mem0;
+ size_t byteset[32 / sizeof(size_t)] = { 0 };
+ size_t shift[256];
+
+ /* Computing length of needle and fill shift table */
+ for (i=0; i<l; i++)
+ BITOP(byteset, n[i], |=), shift[n[i]] = i+1;
+
+ /* Compute maximal suffix */
+ ip = -1; jp = 0; k = p = 1;
+ while (jp+k<l) {
+ if (n[ip+k] == n[jp+k]) {
+ if (k == p) {
+ jp += p;
+ k = 1;
+ } else k++;
+ } else if (n[ip+k] > n[jp+k]) {
+ jp += k;
+ k = 1;
+ p = jp - ip;
+ } else {
+ ip = jp++;
+ k = p = 1;
+ }
+ }
+ ms = ip;
+ p0 = p;
+
+ /* And with the opposite comparison */
+ ip = -1; jp = 0; k = p = 1;
+ while (jp+k<l) {
+ if (n[ip+k] == n[jp+k]) {
+ if (k == p) {
+ jp += p;
+ k = 1;
+ } else k++;
+ } else if (n[ip+k] < n[jp+k]) {
+ jp += k;
+ k = 1;
+ p = jp - ip;
+ } else {
+ ip = jp++;
+ k = p = 1;
+ }
+ }
+ if (ip+1 > ms+1) ms = ip;
+ else p = p0;
+
+ /* Periodic needle? */
+ if (memcmp(n, n+p, ms+1)) {
+ mem0 = 0;
+ p = MAX(ms, l-ms-1) + 1;
+ } else mem0 = l-p;
+ mem = 0;
+
+ /* Search loop */
+ for (;;) {
+ /* If remainder of haystack is shorter than needle, done */
+ if (z-h < l) return 0;
+
+ /* Check last byte first; advance by shift on mismatch */
+ if (BITOP(byteset, h[l-1], &)) {
+ k = l-shift[h[l-1]];
+ if (k) {
+ if (k < mem) k = mem;
+ h += k;
+ mem = 0;
+ continue;
+ }
+ } else {
+ h += l;
+ mem = 0;
+ continue;
+ }
+
+ /* Compare right half */
+ for (k=MAX(ms+1,mem); k<l && n[k] == h[k]; k++);
+ if (k < l) {
+ h += k-ms;
+ mem = 0;
+ continue;
+ }
+ /* Compare left half */
+ for (k=ms+1; k>mem && n[k-1] == h[k-1]; k--);
+ if (k <= mem) return (char *)h;
+ h += p;
+ mem = mem0;
+ }
+}
+
+void *
+memmem(const void *h0, size_t k, const void *n0, size_t l)
+{
+ const unsigned char *h = h0, *n = n0;
+
+ /* Return immediately on empty needle */
+ if (!l) return (void *)h;
+
+ /* Return immediately when needle is longer than haystack */
+ if (k<l) return 0;
+
+ /* Use faster algorithms for short needles */
+ h = memchr(h0, *n, k);
+ if (!h || l==1) return (void *)h;
+ k -= h - (const unsigned char *)h0;
+ if (k<l) return 0;
+ if (l==2) return twobyte_memmem(h, k, n);
+ if (l==3) return threebyte_memmem(h, k, n);
+ if (l==4) return fourbyte_memmem(h, k, n);
+
+ return twoway_memmem(h, h+k, n, l);
+}
+DEF_WEAK(memmem);
+#endif /* HAVE_MEMMEM */
diff --git a/crypto/openssh/openbsd-compat/mktemp.c b/crypto/openssh/openbsd-compat/mktemp.c
index 4eb52f421b72..ac922c1ecbe5 100644
--- a/crypto/openssh/openbsd-compat/mktemp.c
+++ b/crypto/openssh/openbsd-compat/mktemp.c
@@ -34,7 +34,7 @@
#include <ctype.h>
#include <unistd.h>
-#if !defined(HAVE_MKDTEMP) || defined(HAVE_STRICT_MKSTEMP)
+#if !defined(HAVE_MKDTEMP)
#define MKTEMP_NAME 0
#define MKTEMP_FILE 1
@@ -138,4 +138,4 @@ mkdtemp(char *path)
return(error ? NULL : path);
}
-#endif /* !defined(HAVE_MKDTEMP) || defined(HAVE_STRICT_MKSTEMP) */
+#endif /* !defined(HAVE_MKDTEMP) */
diff --git a/crypto/openssh/openbsd-compat/openbsd-compat.h b/crypto/openssh/openbsd-compat/openbsd-compat.h
index f5c833bf271f..a7209ceb26a9 100644
--- a/crypto/openssh/openbsd-compat/openbsd-compat.h
+++ b/crypto/openssh/openbsd-compat/openbsd-compat.h
@@ -44,9 +44,14 @@
#include "getrrsetbyname.h"
#include "sha1.h"
#include "sha2.h"
-#include "rmd160.h"
#include "md5.h"
#include "blf.h"
+#include "fnmatch.h"
+
+#if defined(HAVE_LOGIN_CAP) && !defined(HAVE_LOGIN_GETPWCLASS)
+# include <login_cap.h>
+# define login_getpwclass(pw) login_getclass(pw->pw_class)
+#endif
#ifndef HAVE_BASENAME
char *basename(const char *path);
@@ -61,6 +66,7 @@ void closefrom(int);
#endif
#ifndef HAVE_GETLINE
+#include <stdio.h>
ssize_t getline(char **, size_t *, FILE *);
#endif
@@ -72,6 +78,10 @@ int getpagesize(void);
char *getcwd(char *pt, size_t size);
#endif
+#if defined(HAVE_DECL_MEMMEM) && HAVE_DECL_MEMMEM == 0
+void *memmem(const void *, size_t, const void *, size_t);
+#endif
+
#ifndef HAVE_REALLOCARRAY
void *reallocarray(void *, size_t, size_t);
#endif
@@ -80,18 +90,6 @@ void *reallocarray(void *, size_t, size_t);
void *recallocarray(void *, size_t, 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
@@ -108,6 +106,14 @@ size_t strlcat(char *dst, const char *src, size_t siz);
char *strcasestr(const char *, const char *);
#endif
+#ifndef HAVE_STRNLEN
+size_t strnlen(const char *, size_t);
+#endif
+
+#ifndef HAVE_STRNDUP
+char *strndup(const char *s, size_t n);
+#endif
+
#ifndef HAVE_SETENV
int setenv(register const char *name, register const char *value, int rewrite);
#endif
@@ -121,7 +127,7 @@ void strmode(int mode, char *p);
char *strptime(const char *buf, const char *fmt, struct tm *tm);
#endif
-#if !defined(HAVE_MKDTEMP) || defined(HAVE_STRICT_MKSTEMP)
+#if !defined(HAVE_MKDTEMP)
int mkstemps(char *path, int slen);
int mkstemp(char *path);
char *mkdtemp(char *path);
@@ -189,14 +195,14 @@ int writev(int, struct iovec *, int);
#endif
/* Home grown routines */
+#include "bsd-signal.h"
#include "bsd-misc.h"
#include "bsd-setres_id.h"
-#include "bsd-signal.h"
#include "bsd-statvfs.h"
#include "bsd-waitpid.h"
#include "bsd-poll.h"
-#ifndef HAVE_GETPEEREID
+#if defined(HAVE_DECL_GETPEEREID) && HAVE_DECL_GETPEEREID == 0
int getpeereid(int , uid_t *, gid_t *);
#endif
@@ -321,6 +327,10 @@ void explicit_bzero(void *p, size_t n);
void freezero(void *, size_t);
#endif
+#ifndef HAVE_LOCALTIME_R
+struct tm *localtime_r(const time_t *, struct tm *);
+#endif
+
char *xcrypt(const char *password, const char *salt);
char *shadow_pw(struct passwd *pw);
diff --git a/crypto/openssh/openbsd-compat/openssl-compat.c b/crypto/openssh/openbsd-compat/openssl-compat.c
index 8b4a36274606..a37ca61bf2d4 100644
--- a/crypto/openssh/openbsd-compat/openssl-compat.c
+++ b/crypto/openssh/openbsd-compat/openssl-compat.c
@@ -66,23 +66,31 @@ ssh_compatible_openssl(long headerver, long libver)
return 0;
}
-#ifdef USE_OPENSSL_ENGINE
void
-ssh_OpenSSL_add_all_algorithms(void)
+ssh_libcrypto_init(void)
{
+#if defined(HAVE_OPENSSL_INIT_CRYPTO) && \
+ defined(OPENSSL_INIT_ADD_ALL_CIPHERS) && \
+ defined(OPENSSL_INIT_ADD_ALL_DIGESTS)
+ OPENSSL_init_crypto(OPENSSL_INIT_ADD_ALL_CIPHERS |
+ OPENSSL_INIT_ADD_ALL_DIGESTS, NULL);
+#elif defined(HAVE_OPENSSL_ADD_ALL_ALGORITHMS)
OpenSSL_add_all_algorithms();
+#endif
+#ifdef USE_OPENSSL_ENGINE
/* Enable use of crypto hardware */
ENGINE_load_builtin_engines();
ENGINE_register_all_complete();
-#if OPENSSL_VERSION_NUMBER < 0x10001000L
- OPENSSL_config(NULL);
-#else
+ /* Load the libcrypto config file to pick up engines defined there */
+# if defined(HAVE_OPENSSL_INIT_CRYPTO) && defined(OPENSSL_INIT_LOAD_CONFIG)
OPENSSL_init_crypto(OPENSSL_INIT_ADD_ALL_CIPHERS |
OPENSSL_INIT_ADD_ALL_DIGESTS | OPENSSL_INIT_LOAD_CONFIG, NULL);
-#endif
+# else
+ OPENSSL_config(NULL);
+# endif
+#endif /* USE_OPENSSL_ENGINE */
}
-#endif
#endif /* WITH_OPENSSL */
diff --git a/crypto/openssh/openbsd-compat/openssl-compat.h b/crypto/openssh/openbsd-compat/openssl-compat.h
index 9e0264c04167..8ca50b5ace63 100644
--- a/crypto/openssh/openbsd-compat/openssl-compat.h
+++ b/crypto/openssh/openbsd-compat/openssl-compat.h
@@ -21,16 +21,32 @@
#ifdef WITH_OPENSSL
#include <openssl/opensslv.h>
+#include <openssl/crypto.h>
#include <openssl/evp.h>
#include <openssl/rsa.h>
#include <openssl/dsa.h>
+#ifdef OPENSSL_HAS_ECC
#include <openssl/ecdsa.h>
+#endif
#include <openssl/dh.h>
int ssh_compatible_openssl(long, long);
+void ssh_libcrypto_init(void);
+
+#if (OPENSSL_VERSION_NUMBER < 0x1000100fL)
+# error OpenSSL 1.0.1 or greater is required
+#endif
-#if (OPENSSL_VERSION_NUMBER <= 0x0090805fL)
-# error OpenSSL 0.9.8f or greater is required
+#ifndef OPENSSL_VERSION
+# define OPENSSL_VERSION SSLEAY_VERSION
+#endif
+
+#ifndef HAVE_OPENSSL_VERSION
+# define OpenSSL_version(x) SSLeay_version(x)
+#endif
+
+#ifndef HAVE_OPENSSL_VERSION_NUM
+# define OpenSSL_version_num SSLeay
#endif
#if OPENSSL_VERSION_NUMBER < 0x10000001L
@@ -46,6 +62,12 @@ int ssh_compatible_openssl(long, long);
# define OPENSSL_DSA_MAX_MODULUS_BITS 10000
#endif
+#ifdef LIBRESSL_VERSION_NUMBER
+# if LIBRESSL_VERSION_NUMBER < 0x3010000fL
+# define HAVE_BROKEN_CHACHA20
+# endif
+#endif
+
#ifndef OPENSSL_HAVE_EVPCTR
# define EVP_aes_128_ctr evp_aes_128_ctr
# define EVP_aes_192_ctr evp_aes_128_ctr
@@ -71,33 +93,6 @@ void ssh_aes_ctr_iv(EVP_CIPHER_CTX *, int, u_char *, size_t);
# endif
#endif
-#if defined(HAVE_EVP_RIPEMD160)
-# if defined(OPENSSL_NO_RIPEMD) || defined(OPENSSL_NO_RMD160)
-# undef HAVE_EVP_RIPEMD160
-# 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 */
-
/* LibreSSL/OpenSSL 1.1x API compat */
#ifndef HAVE_DSA_GET0_PQG
void DSA_get0_pqg(const DSA *d, const BIGNUM **p, const BIGNUM **q,
@@ -118,8 +113,12 @@ int DSA_set0_key(DSA *d, BIGNUM *pub_key, BIGNUM *priv_key);
#endif /* HAVE_DSA_SET0_KEY */
#ifndef HAVE_EVP_CIPHER_CTX_GET_IV
+# ifdef HAVE_EVP_CIPHER_CTX_GET_UPDATED_IV
+# define EVP_CIPHER_CTX_get_iv EVP_CIPHER_CTX_get_updated_iv
+# else /* HAVE_EVP_CIPHER_CTX_GET_UPDATED_IV */
int EVP_CIPHER_CTX_get_iv(const EVP_CIPHER_CTX *ctx,
unsigned char *iv, size_t len);
+# endif /* HAVE_EVP_CIPHER_CTX_GET_UPDATED_IV */
#endif /* HAVE_EVP_CIPHER_CTX_GET_IV */
#ifndef HAVE_EVP_CIPHER_CTX_SET_IV
@@ -161,6 +160,7 @@ void DSA_SIG_get0(const DSA_SIG *sig, const BIGNUM **pr, const BIGNUM **ps);
int DSA_SIG_set0(DSA_SIG *sig, BIGNUM *r, BIGNUM *s);
#endif /* DSA_SIG_SET0 */
+#ifdef OPENSSL_HAS_ECC
#ifndef HAVE_ECDSA_SIG_GET0
void ECDSA_SIG_get0(const ECDSA_SIG *sig, const BIGNUM **pr, const BIGNUM **ps);
#endif /* HAVE_ECDSA_SIG_GET0 */
@@ -168,6 +168,7 @@ void ECDSA_SIG_get0(const ECDSA_SIG *sig, const BIGNUM **pr, const BIGNUM **ps);
#ifndef HAVE_ECDSA_SIG_SET0
int ECDSA_SIG_set0(ECDSA_SIG *sig, BIGNUM *r, BIGNUM *s);
#endif /* HAVE_ECDSA_SIG_SET0 */
+#endif /* OPENSSL_HAS_ECC */
#ifndef HAVE_DH_GET0_PQG
void DH_get0_pqg(const DH *dh, const BIGNUM **p, const BIGNUM **q,
diff --git a/crypto/openssh/openbsd-compat/port-aix.c b/crypto/openssh/openbsd-compat/port-aix.c
index 943177c708c9..2ac9bad09834 100644
--- a/crypto/openssh/openbsd-compat/port-aix.c
+++ b/crypto/openssh/openbsd-compat/port-aix.c
@@ -26,6 +26,8 @@
*/
#include "includes.h"
+#ifdef _AIX
+
#include "xmalloc.h"
#include "sshbuf.h"
#include "ssherr.h"
@@ -36,8 +38,6 @@
#include "ssh_api.h"
#include "log.h"
-#ifdef _AIX
-
#include <errno.h>
#if defined(HAVE_NETDB_H)
# include <netdb.h>
@@ -313,7 +313,8 @@ sys_auth_get_lastlogin_msg(const char *user, uid_t uid)
* record_failed_login: generic "login failed" interface function
*/
void
-record_failed_login(const char *user, const char *hostname, const char *ttyname)
+record_failed_login(struct ssh *ssh, const char *user, const char *hostname,
+ const char *ttyname)
{
if (geteuid() != 0)
return;
@@ -382,12 +383,13 @@ aix_restoreauthdb(void)
# 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.
+ * 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)
+aix_krb5_get_principal_name(const char *const_pw_name)
{
+ char *pw_name = (char *)const_pw_name;
char *authname = NULL, *authdomain = NULL, *principal = NULL;
setuserdb(S_READ);
@@ -397,7 +399,8 @@ aix_krb5_get_principal_name(char *pw_name)
debug("AIX getuserattr S_AUTHNAME: %s", strerror(errno));
if (authdomain != NULL)
- xasprintf(&principal, "%s@%s", authname ? authname : pw_name, authdomain);
+ xasprintf(&principal, "%s@%s", authname ? authname : pw_name,
+ authdomain);
else if (authname != NULL)
principal = xstrdup(authname);
enduserdb();
@@ -442,7 +445,7 @@ 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;
+ long long ll;
maxgroups = *grpcnt;
@@ -460,12 +463,12 @@ getgrouplist(const char *user, gid_t pgid, gid_t *groups, int *grpcnt)
/* 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) {
+ ll = strtoll(grp, NULL, 10);
+ if (ngroups >= maxgroups || ll < 0 || ll > UID_MAX) {
ret = -1;
goto out;
}
- gid = (gid_t)l;
+ gid = (gid_t)ll;
if (gid == pgid)
continue; /* we have already added primary gid */
groups[ngroups++] = gid;
diff --git a/crypto/openssh/openbsd-compat/port-aix.h b/crypto/openssh/openbsd-compat/port-aix.h
index 748c0e4e3109..0ee366140b5b 100644
--- a/crypto/openssh/openbsd-compat/port-aix.h
+++ b/crypto/openssh/openbsd-compat/port-aix.h
@@ -30,6 +30,7 @@
# include <sys/socket.h>
#endif
+struct ssh;
struct sshbuf;
/* These should be in the system headers but are not. */
@@ -89,14 +90,14 @@ void aix_usrinfo(struct passwd *);
# define CUSTOM_SYS_AUTH_ALLOWED_USER 1
int sys_auth_allowed_user(struct passwd *, struct sshbuf *);
# define CUSTOM_SYS_AUTH_RECORD_LOGIN 1
-int sys_auth_record_login(const char *, const char *,
- const char *, struct sshbuf *);
+int sys_auth_record_login(const char *, const char *, const char *,
+ struct sshbuf *);
# 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 *);
+char *aix_krb5_get_principal_name(const char *);
# endif
#endif
diff --git a/crypto/openssh/openbsd-compat/port-irix.c b/crypto/openssh/openbsd-compat/port-irix.c
index 525b029092fb..aebffb0143b9 100644
--- a/crypto/openssh/openbsd-compat/port-irix.c
+++ b/crypto/openssh/openbsd-compat/port-irix.c
@@ -43,6 +43,8 @@
# include <sat.h>
#endif /* WITH_IRIX_AUDIT */
+#include "log.h"
+
void
irix_setusercontext(struct passwd *pw)
{
diff --git a/crypto/openssh/openbsd-compat/port-linux.c b/crypto/openssh/openbsd-compat/port-linux.c
index 622988822adf..77cb8213a12e 100644
--- a/crypto/openssh/openbsd-compat/port-linux.c
+++ b/crypto/openssh/openbsd-compat/port-linux.c
@@ -55,11 +55,10 @@ ssh_selinux_enabled(void)
}
/* Return the default security context for the given username */
-static security_context_t
+static char *
ssh_selinux_getctxbyname(char *pwname)
{
- security_context_t sc = NULL;
- char *sename = NULL, *lvl = NULL;
+ char *sc = NULL, *sename = NULL, *lvl = NULL;
int r;
#ifdef HAVE_GETSEUSERBYNAME
@@ -105,7 +104,7 @@ ssh_selinux_getctxbyname(char *pwname)
void
ssh_selinux_setup_exec_context(char *pwname)
{
- security_context_t user_ctx = NULL;
+ char *user_ctx = NULL;
if (!ssh_selinux_enabled())
return;
@@ -136,9 +135,7 @@ ssh_selinux_setup_exec_context(char *pwname)
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;
+ char *new_tty_ctx = NULL, *user_ctx = NULL, *old_tty_ctx = NULL;
security_class_t chrclass;
if (!ssh_selinux_enabled())
@@ -182,18 +179,18 @@ ssh_selinux_change_context(const char *newname)
{
int len, newlen;
char *oldctx, *newctx, *cx;
- void (*switchlog) (const char *fmt,...) = logit;
+ LogLevel log_level = SYSLOG_LEVEL_INFO;
if (!ssh_selinux_enabled())
return;
- if (getcon((security_context_t *)&oldctx) < 0) {
+ if (getcon(&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);
+ logit("%s: unparsable context %s", __func__, oldctx);
return;
}
@@ -203,7 +200,7 @@ ssh_selinux_change_context(const char *newname)
*/
if (strncmp(cx, SSH_SELINUX_UNCONFINED_TYPE,
sizeof(SSH_SELINUX_UNCONFINED_TYPE) - 1) == 0)
- switchlog = debug3;
+ log_level = SYSLOG_LEVEL_DEBUG3;
newlen = strlen(oldctx) + strlen(newname) + 1;
newctx = xmalloc(newlen);
@@ -215,8 +212,8 @@ ssh_selinux_change_context(const char *newname)
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));
+ do_log2(log_level, "%s: setcon %s from %s failed with %s",
+ __func__, newctx, oldctx, strerror(errno));
free(oldctx);
free(newctx);
}
@@ -224,7 +221,7 @@ ssh_selinux_change_context(const char *newname)
void
ssh_selinux_setfscreatecon(const char *path)
{
- security_context_t context;
+ char *context;
if (!ssh_selinux_enabled())
return;
diff --git a/crypto/openssh/openbsd-compat/port-net.c b/crypto/openssh/openbsd-compat/port-net.c
index bb535626ffe0..198e73f0de20 100644
--- a/crypto/openssh/openbsd-compat/port-net.c
+++ b/crypto/openssh/openbsd-compat/port-net.c
@@ -26,6 +26,7 @@
#include <errno.h>
#include <fcntl.h>
#include <stdarg.h>
+#include <stdio.h>
#include <string.h>
#include <unistd.h>
@@ -67,7 +68,7 @@ sys_set_rdomain(int fd, const char *name)
if (setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE,
name, strlen(name)) == -1) {
error("%s: setsockopt(%d, SO_BINDTODEVICE, %s): %s",
- __func__, fd, name, strerror(errno));
+ __func__, fd, name, strerror(errno));
return -1;
}
return 0;
@@ -137,6 +138,7 @@ sys_set_process_rdomain(const char *name)
#if defined(SSH_TUN_LINUX)
#include <linux/if_tun.h>
+#define TUN_CTRL_DEV "/dev/net/tun"
int
sys_tun_open(int tun, int mode, char **ifname)
@@ -147,10 +149,9 @@ sys_tun_open(int tun, int mode, char **ifname)
if (ifname != NULL)
*ifname = NULL;
-
- if ((fd = open("/dev/net/tun", O_RDWR)) == -1) {
- debug("%s: failed to open tunnel control interface: %s",
- __func__, strerror(errno));
+ if ((fd = open(TUN_CTRL_DEV, O_RDWR)) == -1) {
+ debug("%s: failed to open tunnel control device \"%s\": %s",
+ __func__, TUN_CTRL_DEV, strerror(errno));
return (-1);
}
@@ -209,8 +210,11 @@ sys_tun_open(int tun, int mode, char **ifname)
{
struct ifreq ifr;
char name[100];
- int fd = -1, sock, flag;
+ int fd = -1, sock;
const char *tunbase = "tun";
+#if defined(TUNSIFHEAD) && !defined(SSH_TUN_PREPEND_AF)
+ int flag;
+#endif
if (ifname != NULL)
*ifname = NULL;
@@ -247,8 +251,8 @@ sys_tun_open(int tun, int mode, char **ifname)
}
/* Turn on tunnel headers */
- flag = 1;
#if defined(TUNSIFHEAD) && !defined(SSH_TUN_PREPEND_AF)
+ flag = 1;
if (mode != SSH_TUNMODE_ETHERNET &&
ioctl(fd, TUNSIFHEAD, &flag) == -1) {
debug("%s: ioctl(%d, TUNSIFHEAD, 1): %s", __func__, fd,
diff --git a/crypto/openssh/openbsd-compat/port-prngd.c b/crypto/openssh/openbsd-compat/port-prngd.c
new file mode 100644
index 000000000000..6afa8f913ae3
--- /dev/null
+++ b/crypto/openssh/openbsd-compat/port-prngd.c
@@ -0,0 +1,164 @@
+/*
+ * 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"
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#ifdef HAVE_SYS_UN_H
+# include <sys/un.h>
+#endif
+
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+#include <errno.h>
+#include <signal.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <stddef.h> /* for offsetof */
+
+#include "atomicio.h"
+#include "misc.h"
+#include "log.h"
+
+#if defined(PRNGD_PORT) || defined(PRNGD_SOCKET)
+/*
+ * EGD/PRNGD interface.
+ *
+ * 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
+ */
+static 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;
+ sshsig_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 = ssh_signal(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:
+ ssh_signal(SIGPIPE, old_sigpipe);
+ if (fd != -1)
+ close(fd);
+ return rval;
+}
+#endif /* PRNGD_PORT || PRNGD_SOCKET */
+
+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;
+}
diff --git a/crypto/openssh/openbsd-compat/port-solaris.c b/crypto/openssh/openbsd-compat/port-solaris.c
index 0e89dc3261d7..b84fbff5e7f5 100644
--- a/crypto/openssh/openbsd-compat/port-solaris.c
+++ b/crypto/openssh/openbsd-compat/port-solaris.c
@@ -17,8 +17,6 @@
#include "config.h"
#include "includes.h"
-#ifdef USE_SOLARIS_PROCESS_CONTRACTS
-
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/param.h>
@@ -31,12 +29,14 @@
#include <string.h>
#include <unistd.h>
+#include "log.h"
+
+#ifdef USE_SOLARIS_PROCESS_CONTRACTS
+
#include <libcontract.h>
#include <sys/contract/process.h>
#include <sys/ctfs.h>
-#include "log.h"
-
#define CT_TEMPLATE CTFS_ROOT "/process/template"
#define CT_LATEST CTFS_ROOT "/process/latest"
@@ -284,11 +284,10 @@ solaris_drop_privs_pinfo_net_fork_exec(void)
priv_addset(npset, PRIV_FILE_OWNER) != 0)
fatal("priv_addset: %s", strerror(errno));
- if (priv_delset(npset, PRIV_FILE_LINK_ANY) != 0 ||
+ if (priv_delset(npset, PRIV_PROC_EXEC) != 0 ||
#ifdef PRIV_NET_ACCESS
priv_delset(npset, PRIV_NET_ACCESS) != 0 ||
#endif
- priv_delset(npset, PRIV_PROC_EXEC) != 0 ||
priv_delset(npset, PRIV_PROC_FORK) != 0 ||
priv_delset(npset, PRIV_PROC_INFO) != 0 ||
priv_delset(npset, PRIV_PROC_SESSION) != 0)
@@ -348,8 +347,7 @@ solaris_drop_privs_root_pinfo_net_exec(void)
priv_delset(pset, PRIV_NET_ACCESS) != 0 ||
#endif
priv_delset(pset, PRIV_PROC_EXEC) != 0 ||
- priv_delset(pset, PRIV_PROC_INFO) != 0 ||
- priv_delset(pset, PRIV_PROC_SESSION) != 0)
+ priv_delset(pset, PRIV_PROC_INFO) != 0)
fatal("priv_delset: %s", strerror(errno));
if (setppriv(PRIV_SET, PRIV_PERMITTED, pset) != 0 ||
diff --git a/crypto/openssh/openbsd-compat/port-uw.c b/crypto/openssh/openbsd-compat/port-uw.c
index 132213131e8f..074f80c8d3d5 100644
--- a/crypto/openssh/openbsd-compat/port-uw.c
+++ b/crypto/openssh/openbsd-compat/port-uw.c
@@ -143,7 +143,7 @@ get_iaf_password(struct passwd *pw)
if (pw_password == NULL)
fatal("ia_get_logpwd: Unable to get the shadow passwd");
ia_closeinfo(uinfo);
- return pw_password;
+ return pw_password;
}
else
fatal("ia_openinfo: Unable to open the shadow passwd file");
diff --git a/crypto/openssh/openbsd-compat/pwcache.c b/crypto/openssh/openbsd-compat/pwcache.c
index 5a8b78801b91..826c2378ba25 100644
--- a/crypto/openssh/openbsd-compat/pwcache.c
+++ b/crypto/openssh/openbsd-compat/pwcache.c
@@ -67,7 +67,7 @@ user_from_uid(uid_t uid, int nouser)
if ((pw = getpwuid(uid)) == NULL) {
if (nouser)
return (NULL);
- (void)snprintf(nbuf, sizeof(nbuf), "%u", uid);
+ (void)snprintf(nbuf, sizeof(nbuf), "%lu", (u_long)uid);
}
cp->uid = uid;
if (cp->name != NULL)
@@ -102,7 +102,7 @@ group_from_gid(gid_t gid, int nogroup)
if ((gr = getgrgid(gid)) == NULL) {
if (nogroup)
return (NULL);
- (void)snprintf(nbuf, sizeof(nbuf), "%u", gid);
+ (void)snprintf(nbuf, sizeof(nbuf), "%lu", (u_long)gid);
}
cp->gid = gid;
if (cp->name != NULL)
diff --git a/crypto/openssh/openbsd-compat/regress/Makefile.in b/crypto/openssh/openbsd-compat/regress/Makefile.in
index 529331be5c26..dd8cdc4b7e7a 100644
--- a/crypto/openssh/openbsd-compat/regress/Makefile.in
+++ b/crypto/openssh/openbsd-compat/regress/Makefile.in
@@ -7,14 +7,14 @@ VPATH=@srcdir@
CC=@CC@
LD=@LD@
CFLAGS=@CFLAGS@
-CPPFLAGS=-I. -I.. -I$(srcdir) -I$(srcdir)/.. @CPPFLAGS@ @DEFS@
+CPPFLAGS=-I. -I.. -I../.. -I$(srcdir) -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)
+ strtonumtest$(EXEEXT) opensslvertest$(EXEEXT) utimensattest$(EXEEXT)
all: t-exec ${OTHERTESTS}
diff --git a/crypto/openssh/openbsd-compat/regress/closefromtest.c b/crypto/openssh/openbsd-compat/regress/closefromtest.c
index 82ffeb9a7613..7a69fb2b1a4e 100644
--- a/crypto/openssh/openbsd-compat/regress/closefromtest.c
+++ b/crypto/openssh/openbsd-compat/regress/closefromtest.c
@@ -14,6 +14,8 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
+#include "includes.h"
+
#include <sys/types.h>
#include <sys/stat.h>
@@ -24,8 +26,6 @@
#define NUM_OPENS 10
-int closefrom(int);
-
void
fail(char *msg)
{
diff --git a/crypto/openssh/openbsd-compat/regress/opensslvertest.c b/crypto/openssh/openbsd-compat/regress/opensslvertest.c
index 5d019b5981a2..43825b24c3eb 100644
--- a/crypto/openssh/openbsd-compat/regress/opensslvertest.c
+++ b/crypto/openssh/openbsd-compat/regress/opensslvertest.c
@@ -14,6 +14,8 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
+#include "includes.h"
+
#include <stdio.h>
#include <stdlib.h>
diff --git a/crypto/openssh/openbsd-compat/regress/snprintftest.c b/crypto/openssh/openbsd-compat/regress/snprintftest.c
index 4ca63e18048c..a3134db1ca94 100644
--- a/crypto/openssh/openbsd-compat/regress/snprintftest.c
+++ b/crypto/openssh/openbsd-compat/regress/snprintftest.c
@@ -17,6 +17,8 @@
#define BUFSZ 2048
+#include "includes.h"
+
#include <sys/types.h>
#include <stdlib.h>
#include <stdio.h>
@@ -47,7 +49,7 @@ int
main(void)
{
char b[5];
- char *src;
+ char *src = NULL;
snprintf(b,5,"123456789");
if (b[4] != '\0')
@@ -69,5 +71,6 @@ main(void)
if (x_snprintf(b, 1, "%s %d", "hello", 12345) != 11)
fail("vsnprintf does not return required length");
+ free(src);
return failed;
}
diff --git a/crypto/openssh/openbsd-compat/regress/strduptest.c b/crypto/openssh/openbsd-compat/regress/strduptest.c
index 7f6d779bedb3..8a3ccf77169f 100644
--- a/crypto/openssh/openbsd-compat/regress/strduptest.c
+++ b/crypto/openssh/openbsd-compat/regress/strduptest.c
@@ -14,6 +14,8 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
+#include "includes.h"
+
#include <stdlib.h>
#include <string.h>
diff --git a/crypto/openssh/openbsd-compat/regress/strtonumtest.c b/crypto/openssh/openbsd-compat/regress/strtonumtest.c
index 50ca5bd22d4e..46bd2b916494 100644
--- a/crypto/openssh/openbsd-compat/regress/strtonumtest.c
+++ b/crypto/openssh/openbsd-compat/regress/strtonumtest.c
@@ -17,6 +17,8 @@
/* OPENBSD ORIGINAL: regress/lib/libc/strtonum/strtonumtest.c */
+#include "includes.h"
+
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
diff --git a/crypto/openssh/openbsd-compat/regress/utimensattest.c b/crypto/openssh/openbsd-compat/regress/utimensattest.c
new file mode 100644
index 000000000000..bbc66c48523e
--- /dev/null
+++ b/crypto/openssh/openbsd-compat/regress/utimensattest.c
@@ -0,0 +1,120 @@
+/*
+ * Copyright (c) 2019 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 "includes.h"
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#define TMPFILE "utimensat.tmp"
+#define TMPFILE2 "utimensat.tmp2"
+
+#ifndef AT_SYMLINK_NOFOLLOW
+# define AT_SYMLINK_NOFOLLOW 0x80000000
+#endif
+
+int utimensat(int, const char *, const struct timespec[2], int);
+
+static void
+cleanup(void)
+{
+ (void)unlink(TMPFILE);
+ (void)unlink(TMPFILE2);
+}
+
+static void
+fail(char *msg, long expect, long got)
+{
+ int saved_errno = errno;
+
+ if (expect == got && got == 0)
+ fprintf(stderr, "utimensat: %s: %s\n", msg,
+ strerror(saved_errno));
+ else
+ fprintf(stderr, "utimensat: %s: expected %ld got %ld\n",
+ msg, expect, got);
+ cleanup();
+ exit(1);
+}
+
+int
+main(void)
+{
+ int fd;
+ struct stat sb;
+ struct timespec ts[2];
+
+ cleanup();
+ if ((fd = open(TMPFILE, O_CREAT, 0600)) == -1)
+ fail("open", 0, 0);
+ close(fd);
+
+ ts[0].tv_sec = 12345678;
+ ts[0].tv_nsec = 23456789;
+ ts[1].tv_sec = 34567890;
+ ts[1].tv_nsec = 45678901;
+ if (utimensat(AT_FDCWD, TMPFILE, ts, AT_SYMLINK_NOFOLLOW) == -1)
+ fail("utimensat", 0, 0);
+
+ if (stat(TMPFILE, &sb) == -1)
+ fail("stat", 0, 0 );
+ if (sb.st_atime != 12345678)
+ fail("st_atime", 0, 0 );
+ if (sb.st_mtime != 34567890)
+ fail("st_mtime", 0, 0 );
+#if 0
+ /*
+ * Results expected to be rounded to the nearest microsecond.
+ * Depends on timestamp precision in kernel and filesystem so
+ * disabled by default.
+ */
+ if (sb.st_atim.tv_nsec != 23456000)
+ fail("atim.tv_nsec", 23456000, sb.st_atim.tv_nsec);
+ if (sb.st_mtim.tv_nsec != 45678000)
+ fail("mtim.tv_nsec", 45678000, sb.st_mtim.tv_nsec);
+#endif
+
+ /*
+ * POSIX specifies that when given a symlink, AT_SYMLINK_NOFOLLOW
+ * should update the symlink and not the destination. The compat
+ * code doesn't have a way to do this, so where possible it fails
+ * with instead of following a symlink when explicitly asked not to.
+ * Here we just test that it does not update the destination.
+ */
+ if (rename(TMPFILE, TMPFILE2) == -1)
+ fail("rename", 0, 0);
+ if (symlink(TMPFILE2, TMPFILE) == -1)
+ fail("symlink", 0, 0);
+ ts[0].tv_sec = 11223344;
+ ts[1].tv_sec = 55667788;
+ (void)utimensat(AT_FDCWD, TMPFILE, ts, AT_SYMLINK_NOFOLLOW);
+ if (stat(TMPFILE2, &sb) == -1)
+ fail("stat", 0, 0 );
+ if (sb.st_atime == 11223344)
+ fail("utimensat symlink st_atime", 0, 0 );
+ if (sb.st_mtime == 55667788)
+ fail("utimensat symlink st_mtime", 0, 0 );
+
+ cleanup();
+ exit(0);
+}
diff --git a/crypto/openssh/openbsd-compat/rmd160.c b/crypto/openssh/openbsd-compat/rmd160.c
deleted file mode 100644
index e915141a5715..000000000000
--- a/crypto/openssh/openbsd-compat/rmd160.c
+++ /dev/null
@@ -1,378 +0,0 @@
-/*
- * 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 <sys/types.h>
-#ifdef HAVE_ENDIAN_H
-#include <endian.h>
-#endif
-#include <string.h>
-#include <rmd160.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)
-
-#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/openssh/openbsd-compat/rmd160.h b/crypto/openssh/openbsd-compat/rmd160.h
deleted file mode 100644
index 99c1dcdc060a..000000000000
--- a/crypto/openssh/openbsd-compat/rmd160.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/* $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/openssh/openbsd-compat/setenv.c b/crypto/openssh/openbsd-compat/setenv.c
index 373b701d9c6f..86954c284ee3 100644
--- a/crypto/openssh/openbsd-compat/setenv.c
+++ b/crypto/openssh/openbsd-compat/setenv.c
@@ -39,7 +39,9 @@
#include <string.h>
extern char **environ;
+#ifndef HAVE_SETENV
static char **lastenv; /* last value of environ */
+#endif
/* OpenSSH Portable: __findenv is from getenv.c rev 1.8, made static */
/*
diff --git a/crypto/openssh/openbsd-compat/setproctitle.c b/crypto/openssh/openbsd-compat/setproctitle.c
index dbd1a95a061a..e4064323a630 100644
--- a/crypto/openssh/openbsd-compat/setproctitle.c
+++ b/crypto/openssh/openbsd-compat/setproctitle.c
@@ -36,6 +36,7 @@
#ifndef HAVE_SETPROCTITLE
#include <stdarg.h>
+#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#ifdef HAVE_SYS_PSTAT_H
diff --git a/crypto/openssh/openbsd-compat/sha1.c b/crypto/openssh/openbsd-compat/sha1.c
index 4b5381f87582..73f8974853d1 100644
--- a/crypto/openssh/openbsd-compat/sha1.c
+++ b/crypto/openssh/openbsd-compat/sha1.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: sha1.c,v 1.23 2014/01/08 06:14:57 tedu Exp $ */
+/* $OpenBSD: sha1.c,v 1.27 2019/06/07 22:56:36 dtucker Exp $ */
/*
* SHA-1 in C
@@ -18,7 +18,7 @@
#ifndef WITH_OPENSSL
-#include <sys/param.h>
+#include <sys/types.h>
#include <string.h>
#define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits))))
@@ -101,6 +101,7 @@ SHA1Transform(u_int32_t state[5], const u_int8_t buffer[SHA1_BLOCK_LENGTH])
/* Wipe variables */
a = b = c = d = e = 0;
}
+DEF_WEAK(SHA1Transform);
/*
@@ -118,6 +119,7 @@ SHA1Init(SHA1_CTX *context)
context->state[3] = 0x10325476;
context->state[4] = 0xC3D2E1F0;
}
+DEF_WEAK(SHA1Init);
/*
@@ -129,7 +131,7 @@ 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);
+ context->count += ((u_int64_t)len << 3);
if ((j + len) > 63) {
(void)memcpy(&context->buffer[j], data, (i = 64-j));
SHA1Transform(context->state, context->buffer);
@@ -141,6 +143,7 @@ SHA1Update(SHA1_CTX *context, const u_int8_t *data, size_t len)
}
(void)memcpy(&context->buffer[j], &data[i], len - i);
}
+DEF_WEAK(SHA1Update);
/*
@@ -161,6 +164,7 @@ SHA1Pad(SHA1_CTX *context)
SHA1Update(context, (u_int8_t *)"\0", 1);
SHA1Update(context, finalcount, 8); /* Should cause a SHA1Transform() */
}
+DEF_WEAK(SHA1Pad);
void
SHA1Final(u_int8_t digest[SHA1_DIGEST_LENGTH], SHA1_CTX *context)
@@ -172,6 +176,7 @@ SHA1Final(u_int8_t digest[SHA1_DIGEST_LENGTH], SHA1_CTX *context)
digest[i] = (u_int8_t)
((context->state[i>>2] >> ((3-(i & 3)) * 8) ) & 255);
}
- memset(context, 0, sizeof(*context));
+ explicit_bzero(context, sizeof(*context));
}
+DEF_WEAK(SHA1Final);
#endif /* !WITH_OPENSSL */
diff --git a/crypto/openssh/openbsd-compat/sha2.c b/crypto/openssh/openbsd-compat/sha2.c
index b55ea30ac743..4f2ad8f2352a 100644
--- a/crypto/openssh/openbsd-compat/sha2.c
+++ b/crypto/openssh/openbsd-compat/sha2.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: sha2.c,v 1.11 2005/08/08 08:05:35 espie Exp */
+/* $OpenBSD: sha2.c,v 1.28 2019/07/23 12:35:22 dtucker Exp $ */
/*
* FILE: sha2.c
@@ -38,18 +38,14 @@
#include "includes.h"
-#ifdef WITH_OPENSSL
-# include <openssl/opensslv.h>
-# if !defined(HAVE_EVP_SHA256) && (OPENSSL_VERSION_NUMBER >= 0x00907000L)
-# define _NEED_SHA2 1
-# endif
-#else
-# define _NEED_SHA2 1
-#endif
+#if !defined(HAVE_SHA256UPDATE) || !defined(HAVE_SHA384UPDATE) || \
+ !defined(HAVE_SHA512UPDATE)
-#if defined(_NEED_SHA2) && !defined(HAVE_SHA256_UPDATE)
+/* no-op out, similar to DEF_WEAK but only needed here */
+#define MAKE_CLONE(x, y) void __ssh_compat_make_clone_##x_##y(void)
#include <string.h>
+#include "openbsd-compat/sha2.h"
/*
* UNROLLED TRANSFORM LOOP NOTE:
@@ -64,8 +60,13 @@
* #define SHA2_UNROLL_TRANSFORM
*
*/
+#ifndef SHA2_SMALL
+#if defined(__amd64__) || defined(__i386__)
+#define SHA2_UNROLL_TRANSFORM
+#endif
+#endif
-/*** SHA-256/384/512 Machine Architecture Definitions *****************/
+/*** SHA-224/256/384/512 Machine Architecture Definitions *****************/
/*
* BYTE_ORDER NOTE:
*
@@ -98,8 +99,9 @@
#endif
-/*** SHA-256/384/512 Various Length Definitions ***********************/
+/*** SHA-224/256/384/512 Various Length Definitions ***********************/
/* NOTE: Most of these are in sha2.h */
+#define SHA224_SHORT_BLOCK_LENGTH (SHA224_BLOCK_LENGTH - 8)
#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)
@@ -152,22 +154,22 @@
* 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
+ * S is a ROTATION) because the SHA-224/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): */
+/* Shift-right (used in SHA-224, SHA-256, SHA-384, and SHA-512): */
+#define R(b,x) ((x) >> (b))
+/* 32-bit Rotate-right (used in SHA-224 and 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: */
+/* Two of six logical functions used in SHA-224, 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: */
+/* Four of six logical functions used in SHA-224 and 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)))
@@ -181,8 +183,8 @@
/*** SHA-XYZ INITIAL HASH VALUES AND CONSTANTS ************************/
-/* Hash constant words K for SHA-256: */
-const static u_int32_t K256[64] = {
+/* Hash constant words K for SHA-224 and SHA-256: */
+static const u_int32_t K256[64] = {
0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL,
0x3956c25bUL, 0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL,
0xd807aa98UL, 0x12835b01UL, 0x243185beUL, 0x550c7dc3UL,
@@ -202,7 +204,7 @@ const static u_int32_t K256[64] = {
};
/* Initial hash value H for SHA-256: */
-const static u_int32_t sha256_initial_hash_value[8] = {
+static const u_int32_t sha256_initial_hash_value[8] = {
0x6a09e667UL,
0xbb67ae85UL,
0x3c6ef372UL,
@@ -214,7 +216,7 @@ const static u_int32_t sha256_initial_hash_value[8] = {
};
/* Hash constant words K for SHA-384 and SHA-512: */
-const static u_int64_t K512[80] = {
+static const u_int64_t K512[80] = {
0x428a2f98d728ae22ULL, 0x7137449123ef65cdULL,
0xb5c0fbcfec4d3b2fULL, 0xe9b5dba58189dbbcULL,
0x3956c25bf348b538ULL, 0x59f111f1b605d019ULL,
@@ -257,8 +259,35 @@ const static u_int64_t K512[80] = {
0x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL
};
+/* Initial hash value H for SHA-512 */
+static const u_int64_t sha512_initial_hash_value[8] = {
+ 0x6a09e667f3bcc908ULL,
+ 0xbb67ae8584caa73bULL,
+ 0x3c6ef372fe94f82bULL,
+ 0xa54ff53a5f1d36f1ULL,
+ 0x510e527fade682d1ULL,
+ 0x9b05688c2b3e6c1fULL,
+ 0x1f83d9abfb41bd6bULL,
+ 0x5be0cd19137e2179ULL
+};
+
+#if !defined(SHA2_SMALL)
+#if 0
+/* Initial hash value H for SHA-224: */
+static const u_int32_t sha224_initial_hash_value[8] = {
+ 0xc1059ed8UL,
+ 0x367cd507UL,
+ 0x3070dd17UL,
+ 0xf70e5939UL,
+ 0xffc00b31UL,
+ 0x68581511UL,
+ 0x64f98fa7UL,
+ 0xbefa4fa4UL
+};
+#endif /* 0 */
+
/* Initial hash value H for SHA-384 */
-const static u_int64_t sha384_initial_hash_value[8] = {
+static const u_int64_t sha384_initial_hash_value[8] = {
0xcbbb9d5dc1059ed8ULL,
0x629a292a367cd507ULL,
0x9159015a3070dd17ULL,
@@ -269,30 +298,67 @@ const static u_int64_t sha384_initial_hash_value[8] = {
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
+#if 0
+/* Initial hash value H for SHA-512-256 */
+static const u_int64_t sha512_256_initial_hash_value[8] = {
+ 0x22312194fc2bf72cULL,
+ 0x9f555fa3c84c64c2ULL,
+ 0x2393b86b6f53b151ULL,
+ 0x963877195940eabdULL,
+ 0x96283ee2a88effe3ULL,
+ 0xbe5e1e2553863992ULL,
+ 0x2b0199fc2c85b8aaULL,
+ 0x0eb72ddc81c52ca2ULL
};
+/*** SHA-224: *********************************************************/
+void
+SHA224Init(SHA2_CTX *context)
+{
+ memcpy(context->state.st32, sha224_initial_hash_value,
+ sizeof(sha224_initial_hash_value));
+ memset(context->buffer, 0, sizeof(context->buffer));
+ context->bitcount[0] = 0;
+}
+DEF_WEAK(SHA224Init);
+
+MAKE_CLONE(SHA224Transform, SHA256Transform);
+MAKE_CLONE(SHA224Update, SHA256Update);
+MAKE_CLONE(SHA224Pad, SHA256Pad);
+DEF_WEAK(SHA224Transform);
+DEF_WEAK(SHA224Update);
+DEF_WEAK(SHA224Pad);
+
+void
+SHA224Final(u_int8_t digest[SHA224_DIGEST_LENGTH], SHA2_CTX *context)
+{
+ SHA224Pad(context);
+
+#if BYTE_ORDER == LITTLE_ENDIAN
+ int i;
+
+ /* Convert TO host byte order */
+ for (i = 0; i < 7; i++)
+ BE_32_TO_8(digest + i * 4, context->state.st32[i]);
+#else
+ memcpy(digest, context->state.st32, SHA224_DIGEST_LENGTH);
+#endif
+ explicit_bzero(context, sizeof(*context));
+}
+DEF_WEAK(SHA224Final);
+#endif /* !defined(SHA2_SMALL) */
+#endif /* 0 */
/*** SHA-256: *********************************************************/
void
-SHA256_Init(SHA256_CTX *context)
+SHA256Init(SHA2_CTX *context)
{
- if (context == NULL)
- return;
- memcpy(context->state, sha256_initial_hash_value,
+ memcpy(context->state.st32, sha256_initial_hash_value,
sizeof(sha256_initial_hash_value));
memset(context->buffer, 0, sizeof(context->buffer));
- context->bitcount = 0;
+ context->bitcount[0] = 0;
}
+DEF_WEAK(SHA256Init);
#ifdef SHA2_UNROLL_TRANSFORM
@@ -320,7 +386,7 @@ SHA256_Init(SHA256_CTX *context)
} while(0)
void
-SHA256_Transform(u_int32_t state[8], const u_int8_t data[SHA256_BLOCK_LENGTH])
+SHA256Transform(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];
@@ -378,7 +444,7 @@ SHA256_Transform(u_int32_t state[8], const u_int8_t data[SHA256_BLOCK_LENGTH])
#else /* SHA2_UNROLL_TRANSFORM */
void
-SHA256_Transform(u_int32_t state[8], const u_int8_t data[SHA256_BLOCK_LENGTH])
+SHA256Transform(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];
@@ -451,17 +517,18 @@ SHA256_Transform(u_int32_t state[8], const u_int8_t data[SHA256_BLOCK_LENGTH])
}
#endif /* SHA2_UNROLL_TRANSFORM */
+DEF_WEAK(SHA256Transform);
void
-SHA256_Update(SHA256_CTX *context, const u_int8_t *data, size_t len)
+SHA256Update(SHA2_CTX *context, const u_int8_t *data, size_t len)
{
- size_t freespace, usedspace;
+ u_int64_t freespace, usedspace;
/* Calling with no data is valid (we do nothing) */
if (len == 0)
return;
- usedspace = (context->bitcount >> 3) % SHA256_BLOCK_LENGTH;
+ usedspace = (context->bitcount[0] >> 3) % SHA256_BLOCK_LENGTH;
if (usedspace > 0) {
/* Calculate how much free space is available in the buffer */
freespace = SHA256_BLOCK_LENGTH - usedspace;
@@ -469,14 +536,14 @@ SHA256_Update(SHA256_CTX *context, const u_int8_t *data, size_t len)
if (len >= freespace) {
/* Fill the buffer completely and process it */
memcpy(&context->buffer[usedspace], data, freespace);
- context->bitcount += freespace << 3;
+ context->bitcount[0] += freespace << 3;
len -= freespace;
data += freespace;
- SHA256_Transform(context->state, context->buffer);
+ SHA256Transform(context->state.st32, context->buffer);
} else {
/* The buffer is not yet full */
memcpy(&context->buffer[usedspace], data, len);
- context->bitcount += len << 3;
+ context->bitcount[0] += (u_int64_t)len << 3;
/* Clean up: */
usedspace = freespace = 0;
return;
@@ -484,26 +551,27 @@ SHA256_Update(SHA256_CTX *context, const u_int8_t *data, size_t len)
}
while (len >= SHA256_BLOCK_LENGTH) {
/* Process as many complete blocks as we can */
- SHA256_Transform(context->state, data);
- context->bitcount += SHA256_BLOCK_LENGTH << 3;
+ SHA256Transform(context->state.st32, data);
+ context->bitcount[0] += 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;
+ context->bitcount[0] += len << 3;
}
/* Clean up: */
usedspace = freespace = 0;
}
+DEF_WEAK(SHA256Update);
void
-SHA256_Pad(SHA256_CTX *context)
+SHA256Pad(SHA2_CTX *context)
{
unsigned int usedspace;
- usedspace = (context->bitcount >> 3) % SHA256_BLOCK_LENGTH;
+ usedspace = (context->bitcount[0] >> 3) % SHA256_BLOCK_LENGTH;
if (usedspace > 0) {
/* Begin padding with a 1 bit: */
context->buffer[usedspace++] = 0x80;
@@ -518,7 +586,7 @@ SHA256_Pad(SHA256_CTX *context)
SHA256_BLOCK_LENGTH - usedspace);
}
/* Do second-to-last transform: */
- SHA256_Transform(context->state, context->buffer);
+ SHA256Transform(context->state.st32, context->buffer);
/* Prepare for last transform: */
memset(context->buffer, 0, SHA256_SHORT_BLOCK_LENGTH);
@@ -532,47 +600,45 @@ SHA256_Pad(SHA256_CTX *context)
}
/* Store the length of input data (in bits) in big endian format: */
BE_64_TO_8(&context->buffer[SHA256_SHORT_BLOCK_LENGTH],
- context->bitcount);
+ context->bitcount[0]);
/* Final transform: */
- SHA256_Transform(context->state, context->buffer);
+ SHA256Transform(context->state.st32, context->buffer);
/* Clean up: */
usedspace = 0;
}
+DEF_WEAK(SHA256Pad);
void
-SHA256_Final(u_int8_t digest[SHA256_DIGEST_LENGTH], SHA256_CTX *context)
+SHA256Final(u_int8_t digest[SHA256_DIGEST_LENGTH], SHA2_CTX *context)
{
- SHA256_Pad(context);
+ SHA256Pad(context);
- /* If no digest buffer is passed, we don't bother doing this: */
- if (digest != NULL) {
#if BYTE_ORDER == LITTLE_ENDIAN
- int i;
+ int i;
- /* Convert TO host byte order */
- for (i = 0; i < 8; i++)
- BE_32_TO_8(digest + i * 4, context->state[i]);
+ /* Convert TO host byte order */
+ for (i = 0; i < 8; i++)
+ BE_32_TO_8(digest + i * 4, context->state.st32[i]);
#else
- memcpy(digest, context->state, SHA256_DIGEST_LENGTH);
+ memcpy(digest, context->state.st32, SHA256_DIGEST_LENGTH);
#endif
- memset(context, 0, sizeof(*context));
- }
+ explicit_bzero(context, sizeof(*context));
}
+DEF_WEAK(SHA256Final);
/*** SHA-512: *********************************************************/
void
-SHA512_Init(SHA512_CTX *context)
+SHA512Init(SHA2_CTX *context)
{
- if (context == NULL)
- return;
- memcpy(context->state, sha512_initial_hash_value,
+ memcpy(context->state.st64, sha512_initial_hash_value,
sizeof(sha512_initial_hash_value));
memset(context->buffer, 0, sizeof(context->buffer));
context->bitcount[0] = context->bitcount[1] = 0;
}
+DEF_WEAK(SHA512Init);
#ifdef SHA2_UNROLL_TRANSFORM
@@ -601,7 +667,7 @@ SHA512_Init(SHA512_CTX *context)
} while(0)
void
-SHA512_Transform(u_int64_t state[8], const u_int8_t data[SHA512_BLOCK_LENGTH])
+SHA512Transform(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];
@@ -659,7 +725,7 @@ SHA512_Transform(u_int64_t state[8], const u_int8_t data[SHA512_BLOCK_LENGTH])
#else /* SHA2_UNROLL_TRANSFORM */
void
-SHA512_Transform(u_int64_t state[8], const u_int8_t data[SHA512_BLOCK_LENGTH])
+SHA512Transform(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];
@@ -732,9 +798,10 @@ SHA512_Transform(u_int64_t state[8], const u_int8_t data[SHA512_BLOCK_LENGTH])
}
#endif /* SHA2_UNROLL_TRANSFORM */
+DEF_WEAK(SHA512Transform);
void
-SHA512_Update(SHA512_CTX *context, const u_int8_t *data, size_t len)
+SHA512Update(SHA2_CTX *context, const u_int8_t *data, size_t len)
{
size_t freespace, usedspace;
@@ -753,7 +820,7 @@ SHA512_Update(SHA512_CTX *context, const u_int8_t *data, size_t len)
ADDINC128(context->bitcount, freespace << 3);
len -= freespace;
data += freespace;
- SHA512_Transform(context->state, context->buffer);
+ SHA512Transform(context->state.st64, context->buffer);
} else {
/* The buffer is not yet full */
memcpy(&context->buffer[usedspace], data, len);
@@ -765,7 +832,7 @@ SHA512_Update(SHA512_CTX *context, const u_int8_t *data, size_t len)
}
while (len >= SHA512_BLOCK_LENGTH) {
/* Process as many complete blocks as we can */
- SHA512_Transform(context->state, data);
+ SHA512Transform(context->state.st64, data);
ADDINC128(context->bitcount, SHA512_BLOCK_LENGTH << 3);
len -= SHA512_BLOCK_LENGTH;
data += SHA512_BLOCK_LENGTH;
@@ -778,9 +845,10 @@ SHA512_Update(SHA512_CTX *context, const u_int8_t *data, size_t len)
/* Clean up: */
usedspace = freespace = 0;
}
+DEF_WEAK(SHA512Update);
void
-SHA512_Pad(SHA512_CTX *context)
+SHA512Pad(SHA2_CTX *context)
{
unsigned int usedspace;
@@ -797,7 +865,7 @@ SHA512_Pad(SHA512_CTX *context)
memset(&context->buffer[usedspace], 0, SHA512_BLOCK_LENGTH - usedspace);
}
/* Do second-to-last transform: */
- SHA512_Transform(context->state, context->buffer);
+ SHA512Transform(context->state.st64, context->buffer);
/* And set-up for the last transform: */
memset(context->buffer, 0, SHA512_BLOCK_LENGTH - 2);
@@ -816,89 +884,127 @@ SHA512_Pad(SHA512_CTX *context)
context->bitcount[0]);
/* Final transform: */
- SHA512_Transform(context->state, context->buffer);
+ SHA512Transform(context->state.st64, context->buffer);
/* Clean up: */
usedspace = 0;
}
+DEF_WEAK(SHA512Pad);
void
-SHA512_Final(u_int8_t digest[SHA512_DIGEST_LENGTH], SHA512_CTX *context)
+SHA512Final(u_int8_t digest[SHA512_DIGEST_LENGTH], SHA2_CTX *context)
{
- SHA512_Pad(context);
+ SHA512Pad(context);
- /* If no digest buffer is passed, we don't bother doing this: */
- if (digest != NULL) {
#if BYTE_ORDER == LITTLE_ENDIAN
- int i;
+ int i;
- /* Convert TO host byte order */
- for (i = 0; i < 8; i++)
- BE_64_TO_8(digest + i * 8, context->state[i]);
+ /* Convert TO host byte order */
+ for (i = 0; i < 8; i++)
+ BE_64_TO_8(digest + i * 8, context->state.st64[i]);
#else
- memcpy(digest, context->state, SHA512_DIGEST_LENGTH);
+ memcpy(digest, context->state.st64, SHA512_DIGEST_LENGTH);
#endif
- memset(context, 0, sizeof(*context));
- }
+ explicit_bzero(context, sizeof(*context));
}
+DEF_WEAK(SHA512Final);
+#if !defined(SHA2_SMALL)
/*** SHA-384: *********************************************************/
void
-SHA384_Init(SHA384_CTX *context)
+SHA384Init(SHA2_CTX *context)
{
- if (context == NULL)
- return;
- memcpy(context->state, sha384_initial_hash_value,
+ memcpy(context->state.st64, sha384_initial_hash_value,
sizeof(sha384_initial_hash_value));
memset(context->buffer, 0, sizeof(context->buffer));
context->bitcount[0] = context->bitcount[1] = 0;
}
+DEF_WEAK(SHA384Init);
-#if 0
-__weak_alias(SHA384_Transform, SHA512_Transform);
-__weak_alias(SHA384_Update, SHA512_Update);
-__weak_alias(SHA384_Pad, SHA512_Pad);
-#endif
+MAKE_CLONE(SHA384Transform, SHA512Transform);
+MAKE_CLONE(SHA384Update, SHA512Update);
+MAKE_CLONE(SHA384Pad, SHA512Pad);
+DEF_WEAK(SHA384Transform);
+DEF_WEAK(SHA384Update);
+DEF_WEAK(SHA384Pad);
+/* Equivalent of MAKE_CLONE (which is a no-op) for SHA384 funcs */
void
-SHA384_Transform(u_int64_t state[8], const u_int8_t data[SHA512_BLOCK_LENGTH])
+SHA384Transform(u_int64_t state[8], const u_int8_t data[SHA512_BLOCK_LENGTH])
{
- return SHA512_Transform(state, data);
+ SHA512Transform(state, data);
}
void
-SHA384_Update(SHA512_CTX *context, const u_int8_t *data, size_t len)
+SHA384Update(SHA2_CTX *context, const u_int8_t *data, size_t len)
{
- SHA512_Update(context, data, len);
+ SHA512Update(context, data, len);
}
void
-SHA384_Pad(SHA512_CTX *context)
+SHA384Pad(SHA2_CTX *context)
{
- SHA512_Pad(context);
+ SHA512Pad(context);
}
void
-SHA384_Final(u_int8_t digest[SHA384_DIGEST_LENGTH], SHA384_CTX *context)
+SHA384Final(u_int8_t digest[SHA384_DIGEST_LENGTH], SHA2_CTX *context)
{
- SHA384_Pad(context);
+ SHA384Pad(context);
- /* If no digest buffer is passed, we don't bother doing this: */
- if (digest != NULL) {
#if BYTE_ORDER == LITTLE_ENDIAN
- int i;
+ int i;
- /* Convert TO host byte order */
- for (i = 0; i < 6; i++)
- BE_64_TO_8(digest + i * 8, context->state[i]);
+ /* Convert TO host byte order */
+ for (i = 0; i < 6; i++)
+ BE_64_TO_8(digest + i * 8, context->state.st64[i]);
#else
- memcpy(digest, context->state, SHA384_DIGEST_LENGTH);
+ memcpy(digest, context->state.st64, SHA384_DIGEST_LENGTH);
#endif
- }
+ /* Zero out state data */
+ explicit_bzero(context, sizeof(*context));
+}
+DEF_WEAK(SHA384Final);
+
+#if 0
+/*** SHA-512/256: *********************************************************/
+void
+SHA512_256Init(SHA2_CTX *context)
+{
+ memcpy(context->state.st64, sha512_256_initial_hash_value,
+ sizeof(sha512_256_initial_hash_value));
+ memset(context->buffer, 0, sizeof(context->buffer));
+ context->bitcount[0] = context->bitcount[1] = 0;
+}
+DEF_WEAK(SHA512_256Init);
+MAKE_CLONE(SHA512_256Transform, SHA512Transform);
+MAKE_CLONE(SHA512_256Update, SHA512Update);
+MAKE_CLONE(SHA512_256Pad, SHA512Pad);
+DEF_WEAK(SHA512_256Transform);
+DEF_WEAK(SHA512_256Update);
+DEF_WEAK(SHA512_256Pad);
+
+void
+SHA512_256Final(u_int8_t digest[SHA512_256_DIGEST_LENGTH], SHA2_CTX *context)
+{
+ SHA512_256Pad(context);
+
+#if BYTE_ORDER == LITTLE_ENDIAN
+ int i;
+
+ /* Convert TO host byte order */
+ for (i = 0; i < 4; i++)
+ BE_64_TO_8(digest + i * 8, context->state.st64[i]);
+#else
+ memcpy(digest, context->state.st64, SHA512_256_DIGEST_LENGTH);
+#endif
/* Zero out state data */
- memset(context, 0, sizeof(*context));
+ explicit_bzero(context, sizeof(*context));
}
+DEF_WEAK(SHA512_256Final);
+#endif /* !defined(SHA2_SMALL) */
+#endif /* 0 */
-#endif /* defined(_NEED_SHA2) && !defined(HAVE_SHA256_UPDATE) */
+#endif /* HAVE_SHA{256,384,512}UPDATE */
diff --git a/crypto/openssh/openbsd-compat/sha2.h b/crypto/openssh/openbsd-compat/sha2.h
index c6e6c97a5397..d051e96e83c9 100644
--- a/crypto/openssh/openbsd-compat/sha2.h
+++ b/crypto/openssh/openbsd-compat/sha2.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: sha2.h,v 1.6 2004/06/22 01:57:30 jfb Exp */
+/* $OpenBSD: sha2.h,v 1.10 2016/09/03 17:00:29 tedu Exp $ */
/*
* FILE: sha2.h
@@ -41,18 +41,13 @@
#include "includes.h"
-#ifdef WITH_OPENSSL
-# include <openssl/opensslv.h>
-# 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)
+#if !defined(HAVE_SHA256UPDATE) || !defined(HAVE_SHA384UPDATE) || \
+ !defined(HAVE_SHA512UPDATE)
/*** SHA-256/384/512 Various Length Definitions ***********************/
+#define SHA224_BLOCK_LENGTH 64
+#define SHA224_DIGEST_LENGTH 28
+#define SHA224_DIGEST_STRING_LENGTH (SHA224_DIGEST_LENGTH * 2 + 1)
#define SHA256_BLOCK_LENGTH 64
#define SHA256_DIGEST_LENGTH 32
#define SHA256_DIGEST_STRING_LENGTH (SHA256_DIGEST_LENGTH * 2 + 1)
@@ -62,73 +57,118 @@
#define SHA512_BLOCK_LENGTH 128
#define SHA512_DIGEST_LENGTH 64
#define SHA512_DIGEST_STRING_LENGTH (SHA512_DIGEST_LENGTH * 2 + 1)
+#define SHA512_256_BLOCK_LENGTH 128
+#define SHA512_256_DIGEST_LENGTH 32
+#define SHA512_256_DIGEST_STRING_LENGTH (SHA512_256_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];
+/*** SHA-224/256/384/512 Context Structure *******************************/
+typedef struct _SHA2_CTX {
+ union {
+ u_int32_t st32[8];
+ u_int64_t st64[8];
+ } state;
u_int64_t bitcount[2];
u_int8_t buffer[SHA512_BLOCK_LENGTH];
-} SHA512_CTX;
+} SHA2_CTX;
-typedef SHA512_CTX SHA384_CTX;
+#if 0
+__BEGIN_DECLS
+void SHA224Init(SHA2_CTX *);
+void SHA224Transform(u_int32_t state[8], const u_int8_t [SHA224_BLOCK_LENGTH]);
+void SHA224Update(SHA2_CTX *, const u_int8_t *, size_t)
+ __attribute__((__bounded__(__string__,2,3)));
+void SHA224Pad(SHA2_CTX *);
+void SHA224Final(u_int8_t [SHA224_DIGEST_LENGTH], SHA2_CTX *)
+ __attribute__((__bounded__(__minbytes__,1,SHA224_DIGEST_LENGTH)));
+char *SHA224End(SHA2_CTX *, char *)
+ __attribute__((__bounded__(__minbytes__,2,SHA224_DIGEST_STRING_LENGTH)));
+char *SHA224File(const char *, char *)
+ __attribute__((__bounded__(__minbytes__,2,SHA224_DIGEST_STRING_LENGTH)));
+char *SHA224FileChunk(const char *, char *, off_t, off_t)
+ __attribute__((__bounded__(__minbytes__,2,SHA224_DIGEST_STRING_LENGTH)));
+char *SHA224Data(const u_int8_t *, size_t, char *)
+ __attribute__((__bounded__(__string__,1,2)))
+ __attribute__((__bounded__(__minbytes__,3,SHA224_DIGEST_STRING_LENGTH)));
+#endif /* 0 */
-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)
+#ifndef HAVE_SHA256UPDATE
+void SHA256Init(SHA2_CTX *);
+void SHA256Transform(u_int32_t state[8], const u_int8_t [SHA256_BLOCK_LENGTH]);
+void SHA256Update(SHA2_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 *)
+void SHA256Pad(SHA2_CTX *);
+void SHA256Final(u_int8_t [SHA256_DIGEST_LENGTH], SHA2_CTX *)
__attribute__((__bounded__(__minbytes__,1,SHA256_DIGEST_LENGTH)));
-char *SHA256_End(SHA256_CTX *, char *)
+char *SHA256End(SHA2_CTX *, char *)
__attribute__((__bounded__(__minbytes__,2,SHA256_DIGEST_STRING_LENGTH)));
-char *SHA256_File(const char *, char *)
+char *SHA256File(const char *, char *)
__attribute__((__bounded__(__minbytes__,2,SHA256_DIGEST_STRING_LENGTH)));
-char *SHA256_FileChunk(const char *, char *, off_t, off_t)
+char *SHA256FileChunk(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 *)
+char *SHA256Data(const u_int8_t *, size_t, char *)
__attribute__((__bounded__(__string__,1,2)))
__attribute__((__bounded__(__minbytes__,3,SHA256_DIGEST_STRING_LENGTH)));
+#endif /* HAVE_SHA256UPDATE */
-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)
+#ifndef HAVE_SHA384UPDATE
+void SHA384Init(SHA2_CTX *);
+void SHA384Transform(u_int64_t state[8], const u_int8_t [SHA384_BLOCK_LENGTH]);
+void SHA384Update(SHA2_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 *)
+void SHA384Pad(SHA2_CTX *);
+void SHA384Final(u_int8_t [SHA384_DIGEST_LENGTH], SHA2_CTX *)
__attribute__((__bounded__(__minbytes__,1,SHA384_DIGEST_LENGTH)));
-char *SHA384_End(SHA384_CTX *, char *)
+char *SHA384End(SHA2_CTX *, char *)
__attribute__((__bounded__(__minbytes__,2,SHA384_DIGEST_STRING_LENGTH)));
-char *SHA384_File(const char *, char *)
+char *SHA384File(const char *, char *)
__attribute__((__bounded__(__minbytes__,2,SHA384_DIGEST_STRING_LENGTH)));
-char *SHA384_FileChunk(const char *, char *, off_t, off_t)
+char *SHA384FileChunk(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 *)
+char *SHA384Data(const u_int8_t *, size_t, char *)
__attribute__((__bounded__(__string__,1,2)))
__attribute__((__bounded__(__minbytes__,3,SHA384_DIGEST_STRING_LENGTH)));
+#endif /* HAVE_SHA384UPDATE */
-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)
+#ifndef HAVE_SHA512UPDATE
+void SHA512Init(SHA2_CTX *);
+void SHA512Transform(u_int64_t state[8], const u_int8_t [SHA512_BLOCK_LENGTH]);
+void SHA512Update(SHA2_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 *)
+void SHA512Pad(SHA2_CTX *);
+void SHA512Final(u_int8_t [SHA512_DIGEST_LENGTH], SHA2_CTX *)
__attribute__((__bounded__(__minbytes__,1,SHA512_DIGEST_LENGTH)));
-char *SHA512_End(SHA512_CTX *, char *)
+char *SHA512End(SHA2_CTX *, char *)
__attribute__((__bounded__(__minbytes__,2,SHA512_DIGEST_STRING_LENGTH)));
-char *SHA512_File(const char *, char *)
+char *SHA512File(const char *, char *)
__attribute__((__bounded__(__minbytes__,2,SHA512_DIGEST_STRING_LENGTH)));
-char *SHA512_FileChunk(const char *, char *, off_t, off_t)
+char *SHA512FileChunk(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 *)
+char *SHA512Data(const u_int8_t *, size_t, char *)
__attribute__((__bounded__(__string__,1,2)))
__attribute__((__bounded__(__minbytes__,3,SHA512_DIGEST_STRING_LENGTH)));
+#endif /* HAVE_SHA512UPDATE */
+
+#if 0
+void SHA512_256Init(SHA2_CTX *);
+void SHA512_256Transform(u_int64_t state[8], const u_int8_t [SHA512_256_BLOCK_LENGTH]);
+void SHA512_256Update(SHA2_CTX *, const u_int8_t *, size_t)
+ __attribute__((__bounded__(__string__,2,3)));
+void SHA512_256Pad(SHA2_CTX *);
+void SHA512_256Final(u_int8_t [SHA512_256_DIGEST_LENGTH], SHA2_CTX *)
+ __attribute__((__bounded__(__minbytes__,1,SHA512_256_DIGEST_LENGTH)));
+char *SHA512_256End(SHA2_CTX *, char *)
+ __attribute__((__bounded__(__minbytes__,2,SHA512_256_DIGEST_STRING_LENGTH)));
+char *SHA512_256File(const char *, char *)
+ __attribute__((__bounded__(__minbytes__,2,SHA512_256_DIGEST_STRING_LENGTH)));
+char *SHA512_256FileChunk(const char *, char *, off_t, off_t)
+ __attribute__((__bounded__(__minbytes__,2,SHA512_256_DIGEST_STRING_LENGTH)));
+char *SHA512_256Data(const u_int8_t *, size_t, char *)
+ __attribute__((__bounded__(__string__,1,2)))
+ __attribute__((__bounded__(__minbytes__,3,SHA512_256_DIGEST_STRING_LENGTH)));
+__END_DECLS
+#endif /* 0 */
-#endif /* defined(_NEED_SHA2) && !defined(HAVE_SHA256_UPDATE) */
+#endif /* HAVE_SHA{256,384,512}UPDATE */
#endif /* _SSHSHA2_H */
diff --git a/crypto/openssh/openbsd-compat/strtonum.c b/crypto/openssh/openbsd-compat/strtonum.c
index 87f2f24b2583..130d89684e90 100644
--- a/crypto/openssh/openbsd-compat/strtonum.c
+++ b/crypto/openssh/openbsd-compat/strtonum.c
@@ -26,9 +26,9 @@
#include <limits.h>
#include <errno.h>
-#define INVALID 1
-#define TOOSMALL 2
-#define TOOLARGE 3
+#define INVALID 1
+#define TOOSMALL 2
+#define TOOLARGE 3
long long
strtonum(const char *numstr, long long minval, long long maxval,
diff --git a/crypto/openssh/openbsd-compat/sys-queue.h b/crypto/openssh/openbsd-compat/sys-queue.h
index af93d6814025..816c15cd4262 100644
--- a/crypto/openssh/openbsd-compat/sys-queue.h
+++ b/crypto/openssh/openbsd-compat/sys-queue.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: queue.h,v 1.36 2012/04/11 13:29:14 naddy Exp $ */
+/* $OpenBSD: queue.h,v 1.45 2018/07/12 14:22:54 sashan Exp $ */
/* $NetBSD: queue.h,v 1.11 1996/05/16 05:17:14 mycroft Exp $ */
/*
@@ -41,93 +41,97 @@
* Require for OS/X and other platforms that have old/broken/incomplete
* <sys/queue.h>.
*/
-#undef SLIST_HEAD
-#undef SLIST_HEAD_INITIALIZER
-#undef SLIST_ENTRY
-#undef SLIST_FOREACH_PREVPTR
-#undef SLIST_FOREACH_SAFE
-#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_AFTER
-#undef SLIST_REMOVE
-#undef SLIST_REMOVE_NEXT
-#undef LIST_HEAD
-#undef LIST_HEAD_INITIALIZER
+#undef CIRCLEQ_EMPTY
+#undef CIRCLEQ_END
+#undef CIRCLEQ_ENTRY
+#undef CIRCLEQ_FIRST
+#undef CIRCLEQ_FOREACH
+#undef CIRCLEQ_FOREACH_REVERSE
+#undef CIRCLEQ_HEAD
+#undef CIRCLEQ_HEAD_INITIALIZER
+#undef CIRCLEQ_INIT
+#undef CIRCLEQ_INSERT_AFTER
+#undef CIRCLEQ_INSERT_BEFORE
+#undef CIRCLEQ_INSERT_HEAD
+#undef CIRCLEQ_INSERT_TAIL
+#undef CIRCLEQ_LAST
+#undef CIRCLEQ_NEXT
+#undef CIRCLEQ_PREV
+#undef CIRCLEQ_REMOVE
+#undef CIRCLEQ_REPLACE
+#undef LIST_EMPTY
+#undef LIST_END
#undef LIST_ENTRY
#undef LIST_FIRST
-#undef LIST_END
-#undef LIST_EMPTY
-#undef LIST_NEXT
#undef LIST_FOREACH
#undef LIST_FOREACH_SAFE
+#undef LIST_HEAD
+#undef LIST_HEAD_INITIALIZER
#undef LIST_INIT
#undef LIST_INSERT_AFTER
#undef LIST_INSERT_BEFORE
#undef LIST_INSERT_HEAD
+#undef LIST_NEXT
#undef LIST_REMOVE
#undef LIST_REPLACE
-#undef SIMPLEQ_HEAD
-#undef SIMPLEQ_HEAD_INITIALIZER
+#undef SIMPLEQ_CONCAT
+#undef SIMPLEQ_EMPTY
+#undef SIMPLEQ_END
#undef SIMPLEQ_ENTRY
#undef SIMPLEQ_FIRST
-#undef SIMPLEQ_END
-#undef SIMPLEQ_EMPTY
-#undef SIMPLEQ_NEXT
#undef SIMPLEQ_FOREACH
+#undef SIMPLEQ_FOREACH_SAFE
+#undef SIMPLEQ_HEAD
+#undef SIMPLEQ_HEAD_INITIALIZER
#undef SIMPLEQ_INIT
+#undef SIMPLEQ_INSERT_AFTER
#undef SIMPLEQ_INSERT_HEAD
#undef SIMPLEQ_INSERT_TAIL
-#undef SIMPLEQ_INSERT_AFTER
+#undef SIMPLEQ_NEXT
+#undef SIMPLEQ_REMOVE_AFTER
#undef SIMPLEQ_REMOVE_HEAD
-#undef TAILQ_HEAD
-#undef TAILQ_HEAD_INITIALIZER
+#undef SLIST_EMPTY
+#undef SLIST_END
+#undef SLIST_ENTRY
+#undef SLIST_FIRST
+#undef SLIST_FOREACH
+#undef SLIST_FOREACH_PREVPTR
+#undef SLIST_FOREACH_SAFE
+#undef SLIST_HEAD
+#undef SLIST_HEAD_INITIALIZER
+#undef SLIST_INIT
+#undef SLIST_INSERT_AFTER
+#undef SLIST_INSERT_HEAD
+#undef SLIST_NEXT
+#undef SLIST_REMOVE
+#undef SLIST_REMOVE_AFTER
+#undef SLIST_REMOVE_HEAD
+#undef SLIST_REMOVE_NEXT
+#undef TAILQ_CONCAT
+#undef TAILQ_EMPTY
+#undef TAILQ_END
#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_FOREACH_SAFE
#undef TAILQ_FOREACH_REVERSE_SAFE
+#undef TAILQ_FOREACH_SAFE
+#undef TAILQ_HEAD
+#undef TAILQ_HEAD_INITIALIZER
#undef TAILQ_INIT
-#undef TAILQ_INSERT_HEAD
-#undef TAILQ_INSERT_TAIL
#undef TAILQ_INSERT_AFTER
#undef TAILQ_INSERT_BEFORE
+#undef TAILQ_INSERT_HEAD
+#undef TAILQ_INSERT_TAIL
+#undef TAILQ_LAST
+#undef TAILQ_NEXT
+#undef TAILQ_PREV
#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.
+ * This file defines five types of data structures: singly-linked lists,
+ * lists, simple queues, tail queues and XOR simple queues.
*
*
* A singly-linked list is headed by a single forward pointer. The elements
@@ -147,7 +151,7 @@
* 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
+ * A simple 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 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
@@ -161,19 +165,17 @@
* 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.
+ * An XOR simple queue is used in the same way as a regular simple queue.
+ * The difference is that the head structure also includes a "cookie" that
+ * is XOR'd with the queue pointer (first, last or next) to generate the
+ * real pointer value.
*
* 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)
+#define _Q_INVALID ((void *)-1)
+#define _Q_INVALIDATE(a) (a) = _Q_INVALID
#else
#define _Q_INVALIDATE(a)
#endif
@@ -185,15 +187,15 @@
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.
*/
@@ -247,8 +249,8 @@ struct { \
curelm = curelm->field.sle_next; \
curelm->field.sle_next = \
curelm->field.sle_next->field.sle_next; \
- _Q_INVALIDATE((elm)->field.sle_next); \
} \
+ _Q_INVALIDATE((elm)->field.sle_next); \
} while (0)
/*
@@ -269,7 +271,7 @@ struct { \
}
/*
- * List access methods
+ * List access methods.
*/
#define LIST_FIRST(head) ((head)->lh_first)
#define LIST_END(head) NULL
@@ -406,6 +408,94 @@ struct { \
(head)->sqh_last = &(elm)->field.sqe_next; \
} while (0)
+#define SIMPLEQ_CONCAT(head1, head2) do { \
+ if (!SIMPLEQ_EMPTY((head2))) { \
+ *(head1)->sqh_last = (head2)->sqh_first; \
+ (head1)->sqh_last = (head2)->sqh_last; \
+ SIMPLEQ_INIT((head2)); \
+ } \
+} while (0)
+
+/*
+ * XOR Simple queue definitions.
+ */
+#define XSIMPLEQ_HEAD(name, type) \
+struct name { \
+ struct type *sqx_first; /* first element */ \
+ struct type **sqx_last; /* addr of last next element */ \
+ unsigned long sqx_cookie; \
+}
+
+#define XSIMPLEQ_ENTRY(type) \
+struct { \
+ struct type *sqx_next; /* next element */ \
+}
+
+/*
+ * XOR Simple queue access methods.
+ */
+#define XSIMPLEQ_XOR(head, ptr) ((__typeof(ptr))((head)->sqx_cookie ^ \
+ (unsigned long)(ptr)))
+#define XSIMPLEQ_FIRST(head) XSIMPLEQ_XOR(head, ((head)->sqx_first))
+#define XSIMPLEQ_END(head) NULL
+#define XSIMPLEQ_EMPTY(head) (XSIMPLEQ_FIRST(head) == XSIMPLEQ_END(head))
+#define XSIMPLEQ_NEXT(head, elm, field) XSIMPLEQ_XOR(head, ((elm)->field.sqx_next))
+
+
+#define XSIMPLEQ_FOREACH(var, head, field) \
+ for ((var) = XSIMPLEQ_FIRST(head); \
+ (var) != XSIMPLEQ_END(head); \
+ (var) = XSIMPLEQ_NEXT(head, var, field))
+
+#define XSIMPLEQ_FOREACH_SAFE(var, head, field, tvar) \
+ for ((var) = XSIMPLEQ_FIRST(head); \
+ (var) && ((tvar) = XSIMPLEQ_NEXT(head, var, field), 1); \
+ (var) = (tvar))
+
+/*
+ * XOR Simple queue functions.
+ */
+#define XSIMPLEQ_INIT(head) do { \
+ arc4random_buf(&(head)->sqx_cookie, sizeof((head)->sqx_cookie)); \
+ (head)->sqx_first = XSIMPLEQ_XOR(head, NULL); \
+ (head)->sqx_last = XSIMPLEQ_XOR(head, &(head)->sqx_first); \
+} while (0)
+
+#define XSIMPLEQ_INSERT_HEAD(head, elm, field) do { \
+ if (((elm)->field.sqx_next = (head)->sqx_first) == \
+ XSIMPLEQ_XOR(head, NULL)) \
+ (head)->sqx_last = XSIMPLEQ_XOR(head, &(elm)->field.sqx_next); \
+ (head)->sqx_first = XSIMPLEQ_XOR(head, (elm)); \
+} while (0)
+
+#define XSIMPLEQ_INSERT_TAIL(head, elm, field) do { \
+ (elm)->field.sqx_next = XSIMPLEQ_XOR(head, NULL); \
+ *(XSIMPLEQ_XOR(head, (head)->sqx_last)) = XSIMPLEQ_XOR(head, (elm)); \
+ (head)->sqx_last = XSIMPLEQ_XOR(head, &(elm)->field.sqx_next); \
+} while (0)
+
+#define XSIMPLEQ_INSERT_AFTER(head, listelm, elm, field) do { \
+ if (((elm)->field.sqx_next = (listelm)->field.sqx_next) == \
+ XSIMPLEQ_XOR(head, NULL)) \
+ (head)->sqx_last = XSIMPLEQ_XOR(head, &(elm)->field.sqx_next); \
+ (listelm)->field.sqx_next = XSIMPLEQ_XOR(head, (elm)); \
+} while (0)
+
+#define XSIMPLEQ_REMOVE_HEAD(head, field) do { \
+ if (((head)->sqx_first = XSIMPLEQ_XOR(head, \
+ (head)->sqx_first)->field.sqx_next) == XSIMPLEQ_XOR(head, NULL)) \
+ (head)->sqx_last = XSIMPLEQ_XOR(head, &(head)->sqx_first); \
+} while (0)
+
+#define XSIMPLEQ_REMOVE_AFTER(head, elm, field) do { \
+ if (((elm)->field.sqx_next = XSIMPLEQ_XOR(head, \
+ (elm)->field.sqx_next)->field.sqx_next) \
+ == XSIMPLEQ_XOR(head, NULL)) \
+ (head)->sqx_last = \
+ XSIMPLEQ_XOR(head, &(elm)->field.sqx_next); \
+} while (0)
+
+
/*
* Tail queue definitions.
*/
@@ -424,8 +514,8 @@ struct { \
struct type **tqe_prev; /* address of previous next element */ \
}
-/*
- * tail queue access methods
+/*
+ * Tail queue access methods.
*/
#define TAILQ_FIRST(head) ((head)->tqh_first)
#define TAILQ_END(head) NULL
@@ -526,133 +616,13 @@ struct { \
_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); \
+#define TAILQ_CONCAT(head1, head2, field) do { \
+ if (!TAILQ_EMPTY(head2)) { \
+ *(head1)->tqh_last = (head2)->tqh_first; \
+ (head2)->tqh_first->field.tqe_prev = (head1)->tqh_last; \
+ (head1)->tqh_last = (head2)->tqh_last; \
+ TAILQ_INIT((head2)); \
+ } \
} while (0)
-#endif /* !_FAKE_QUEUE_H_ */
+#endif /* !_SYS_QUEUE_H_ */
diff --git a/crypto/openssh/packet.c b/crypto/openssh/packet.c
index 8f4077d4c27f..3379862ebc79 100644
--- a/crypto/openssh/packet.c
+++ b/crypto/openssh/packet.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: packet.c,v 1.277 2018/07/16 03:09:13 djm Exp $ */
+/* $OpenBSD: packet.c,v 1.301 2021/07/16 09:00:23 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -59,6 +59,9 @@ __RCSID("$FreeBSD$");
#include <string.h>
#include <unistd.h>
#include <limits.h>
+#ifdef HAVE_POLL_H
+#include <poll.h>
+#endif
#include <signal.h>
#include <time.h>
@@ -74,10 +77,11 @@ __RCSID("$FreeBSD$");
# endif
#endif
+#ifdef WITH_ZLIB
#include <zlib.h>
+#endif
#include "xmalloc.h"
-#include "crc32.h"
#include "compat.h"
#include "ssh2.h"
#include "cipher.h"
@@ -150,9 +154,11 @@ struct session_state {
/* Scratch buffer for packet compression/decompression. */
struct sshbuf *compression_buffer;
+#ifdef WITH_ZLIB
/* Incoming/outgoing compression dictionaries */
z_stream compression_in_stream;
z_stream compression_out_stream;
+#endif
int compression_in_started;
int compression_out_started;
int compression_in_failures;
@@ -230,6 +236,7 @@ ssh_alloc_session_state(void)
if ((ssh = calloc(1, sizeof(*ssh))) == NULL ||
(state = calloc(1, sizeof(*state))) == NULL ||
+ (ssh->kex = kex_new()) == NULL ||
(state->input = sshbuf_new()) == NULL ||
(state->output = sshbuf_new()) == NULL ||
(state->outgoing_packet = sshbuf_new()) == NULL ||
@@ -252,6 +259,10 @@ ssh_alloc_session_state(void)
ssh->state = state;
return ssh;
fail:
+ if (ssh) {
+ kex_free(ssh->kex);
+ free(ssh);
+ }
if (state) {
sshbuf_free(state->input);
sshbuf_free(state->output);
@@ -259,7 +270,6 @@ ssh_alloc_session_state(void)
sshbuf_free(state->outgoing_packet);
free(state);
}
- free(ssh);
return NULL;
}
@@ -289,13 +299,13 @@ ssh_packet_set_connection(struct ssh *ssh, int fd_in, int fd_out)
int r;
if (none == NULL) {
- error("%s: cannot load cipher 'none'", __func__);
+ error_f("cannot load cipher 'none'");
return NULL;
}
if (ssh == NULL)
ssh = ssh_alloc_session_state();
if (ssh == NULL) {
- error("%s: cound not allocate state", __func__);
+ error_f("could not allocate state");
return NULL;
}
state = ssh->state;
@@ -305,7 +315,7 @@ ssh_packet_set_connection(struct ssh *ssh, int fd_in, int fd_out)
(const u_char *)"", 0, NULL, 0, CIPHER_ENCRYPT)) != 0 ||
(r = cipher_init(&state->receive_context, none,
(const u_char *)"", 0, NULL, 0, CIPHER_DECRYPT)) != 0) {
- error("%s: cipher_init failed: %s", __func__, ssh_err(r));
+ error_fr(r, "cipher_init failed");
free(ssh); /* XXX need ssh_free_session_state? */
return NULL;
}
@@ -338,6 +348,8 @@ ssh_packet_set_mux(struct ssh *ssh)
{
ssh->state->mux = 1;
ssh->state->rekeying = 0;
+ kex_free(ssh->kex);
+ ssh->kex = NULL;
}
int
@@ -439,12 +451,12 @@ ssh_packet_connection_is_on_socket(struct ssh *ssh)
fromlen = sizeof(from);
memset(&from, 0, sizeof(from));
if (getpeername(state->connection_in, (struct sockaddr *)&from,
- &fromlen) < 0)
+ &fromlen) == -1)
return 0;
tolen = sizeof(to);
memset(&to, 0, sizeof(to));
if (getpeername(state->connection_out, (struct sockaddr *)&to,
- &tolen) < 0)
+ &tolen) == -1)
return 0;
if (fromlen != tolen || memcmp(&from, &to, fromlen) != 0)
return 0;
@@ -465,19 +477,7 @@ ssh_packet_get_bytes(struct ssh *ssh, u_int64_t *ibytes, u_int64_t *obytes)
int
ssh_packet_connection_af(struct ssh *ssh)
{
- struct sockaddr_storage to;
- socklen_t tolen = sizeof(to);
-
- memset(&to, 0, sizeof(to));
- if (getsockname(ssh->state->connection_out, (struct sockaddr *)&to,
- &tolen) < 0)
- return 0;
-#ifdef IPV4_IN_IPV6
- if (to.ss_family == AF_INET6 &&
- IN6_IS_ADDR_V4MAPPED(&((struct sockaddr_in6 *)&to)->sin6_addr))
- return AF_INET;
-#endif
- return to.ss_family;
+ return get_sock_af(ssh->state->connection_out);
}
/* Sets the connection into non-blocking mode. */
@@ -527,9 +527,9 @@ ssh_remote_ipaddr(struct ssh *ssh)
ssh->local_ipaddr = get_local_ipaddr(sock);
ssh->local_port = get_local_port(sock);
} else {
- ssh->remote_ipaddr = strdup("UNKNOWN");
+ ssh->remote_ipaddr = xstrdup("UNKNOWN");
ssh->remote_port = 65535;
- ssh->local_ipaddr = strdup("UNKNOWN");
+ ssh->local_ipaddr = xstrdup("UNKNOWN");
ssh->local_port = 65535;
}
}
@@ -606,6 +606,7 @@ ssh_packet_close_internal(struct ssh *ssh, int do_close)
state->newkeys[mode] = NULL;
ssh_clear_newkeys(ssh, mode); /* next keys */
}
+#ifdef WITH_ZLIB
/* compression state is in shared mem, so we can only release it once */
if (do_close && state->compression_buffer) {
sshbuf_free(state->compression_buffer);
@@ -632,6 +633,7 @@ ssh_packet_close_internal(struct ssh *ssh, int do_close)
inflateEnd(stream);
}
}
+#endif /* WITH_ZLIB */
cipher_free(state->send_context);
cipher_free(state->receive_context);
state->send_context = state->receive_context = NULL;
@@ -642,6 +644,8 @@ ssh_packet_close_internal(struct ssh *ssh, int do_close)
ssh->remote_ipaddr = NULL;
free(ssh->state);
ssh->state = NULL;
+ kex_free(ssh->kex);
+ ssh->kex = NULL;
}
}
@@ -682,11 +686,12 @@ static int
ssh_packet_init_compression(struct ssh *ssh)
{
if (!ssh->state->compression_buffer &&
- ((ssh->state->compression_buffer = sshbuf_new()) == NULL))
+ ((ssh->state->compression_buffer = sshbuf_new()) == NULL))
return SSH_ERR_ALLOC_FAIL;
return 0;
}
+#ifdef WITH_ZLIB
static int
start_compression_out(struct ssh *ssh, int level)
{
@@ -818,6 +823,33 @@ uncompress_buffer(struct ssh *ssh, struct sshbuf *in, struct sshbuf *out)
/* NOTREACHED */
}
+#else /* WITH_ZLIB */
+
+static int
+start_compression_out(struct ssh *ssh, int level)
+{
+ return SSH_ERR_INTERNAL_ERROR;
+}
+
+static int
+start_compression_in(struct ssh *ssh)
+{
+ return SSH_ERR_INTERNAL_ERROR;
+}
+
+static int
+compress_buffer(struct ssh *ssh, struct sshbuf *in, struct sshbuf *out)
+{
+ return SSH_ERR_INTERNAL_ERROR;
+}
+
+static int
+uncompress_buffer(struct ssh *ssh, struct sshbuf *in, struct sshbuf *out)
+{
+ return SSH_ERR_INTERNAL_ERROR;
+}
+#endif /* WITH_ZLIB */
+
void
ssh_clear_newkeys(struct ssh *ssh, int mode)
{
@@ -839,6 +871,7 @@ ssh_set_newkeys(struct ssh *ssh, int mode)
u_int64_t *max_blocks;
const char *wmsg;
int r, crypt_type;
+ const char *dir = mode == MODE_OUT ? "out" : "in";
debug2("set_newkeys: mode %d", mode);
@@ -854,14 +887,12 @@ ssh_set_newkeys(struct ssh *ssh, int mode)
max_blocks = &state->max_blocks_in;
}
if (state->newkeys[mode] != NULL) {
- debug("set_newkeys: rekeying, input %llu bytes %llu blocks, "
- "output %llu bytes %llu blocks",
- (unsigned long long)state->p_read.bytes,
- (unsigned long long)state->p_read.blocks,
- (unsigned long long)state->p_send.bytes,
- (unsigned long long)state->p_send.blocks);
- cipher_free(*ccp);
- *ccp = NULL;
+ debug_f("rekeying %s, input %llu bytes %llu blocks, "
+ "output %llu bytes %llu blocks", dir,
+ (unsigned long long)state->p_read.bytes,
+ (unsigned long long)state->p_read.blocks,
+ (unsigned long long)state->p_send.bytes,
+ (unsigned long long)state->p_send.blocks);
kex_free_newkeys(state->newkeys[mode]);
state->newkeys[mode] = NULL;
}
@@ -879,7 +910,9 @@ ssh_set_newkeys(struct ssh *ssh, int mode)
return r;
}
mac->enabled = 1;
- DBG(debug("cipher_init_context: %d", mode));
+ DBG(debug_f("cipher_init_context: %s", dir));
+ cipher_free(*ccp);
+ *ccp = NULL;
if ((r = cipher_init(ccp, enc->cipher, enc->key, enc->key_len,
enc->iv, enc->iv_len, crypt_type)) != 0)
return r;
@@ -894,7 +927,7 @@ ssh_set_newkeys(struct ssh *ssh, int mode)
explicit_bzero(mac->key, mac->key_len); */
if ((comp->type == COMP_ZLIB ||
(comp->type == COMP_DELAYED &&
- state->after_authentication)) && comp->enabled == 0) {
+ state->after_authentication)) && comp->enabled == 0) {
if ((r = ssh_packet_init_compression(ssh)) < 0)
return r;
if (mode == MODE_OUT) {
@@ -918,7 +951,8 @@ ssh_set_newkeys(struct ssh *ssh, int mode)
if (state->rekey_limit)
*max_blocks = MINIMUM(*max_blocks,
state->rekey_limit / enc->block_size);
- debug("rekey after %llu blocks", (unsigned long long)*max_blocks);
+ debug("rekey %s after %llu blocks", dir,
+ (unsigned long long)*max_blocks);
return 0;
}
@@ -934,7 +968,7 @@ ssh_packet_need_rekeying(struct ssh *ssh, u_int outbound_packet_len)
return 0;
/* Haven't keyed yet or KEX in progress. */
- if (ssh->kex == NULL || ssh_packet_is_rekeying(ssh))
+ if (ssh_packet_is_rekeying(ssh))
return 0;
/* Peer can't rekey */
@@ -970,6 +1004,15 @@ ssh_packet_need_rekeying(struct ssh *ssh, u_int outbound_packet_len)
(state->p_read.blocks > state->max_blocks_in));
}
+int
+ssh_packet_check_rekey(struct ssh *ssh)
+{
+ if (!ssh_packet_need_rekeying(ssh, 0))
+ return 0;
+ debug3_f("rekex triggered");
+ return kex_start_rekex(ssh);
+}
+
/*
* Delayed compression for SSH2 is enabled after authentication:
* This happens on the server side after a SSH2_MSG_USERAUTH_SUCCESS is sent,
@@ -1099,8 +1142,8 @@ ssh_packet_send2_wrapped(struct ssh *ssh)
if (tmp > state->extra_pad)
return SSH_ERR_INVALID_ARGUMENT;
pad = state->extra_pad - tmp;
- DBG(debug3("%s: adding %d (len %d padlen %d extra_pad %d)",
- __func__, pad, len, padlen, state->extra_pad));
+ DBG(debug3_f("adding %d (len %d padlen %d extra_pad %d)",
+ pad, len, padlen, state->extra_pad));
tmp = padlen;
padlen += pad;
/* Check whether padlen calculation overflowed */
@@ -1215,7 +1258,7 @@ ssh_packet_send2(struct ssh *ssh)
*/
if ((need_rekey || state->rekeying) && !ssh_packet_type_is_kex(type)) {
if (need_rekey)
- debug3("%s: rekex triggered", __func__);
+ debug3_f("rekex triggered");
debug("enqueue packet: %u", type);
p = calloc(1, sizeof(*p));
if (p == NULL)
@@ -1257,8 +1300,7 @@ ssh_packet_send2(struct ssh *ssh)
*/
if (ssh_packet_need_rekeying(ssh,
sshbuf_len(p->payload))) {
- debug3("%s: queued packet triggered rekex",
- __func__);
+ debug3_f("queued packet triggered rekex");
return kex_start_rekex(ssh);
}
debug("dequeue packet: %u", type);
@@ -1326,7 +1368,7 @@ ssh_packet_read_seqnr(struct ssh *ssh, u_char *typep, u_int32_t *seqnr_p)
}
/* Wait for some data to arrive. */
for (;;) {
- if (state->packet_timeout_ms != -1) {
+ if (state->packet_timeout_ms > 0) {
ms_to_timeval(&timeout, ms_remain);
monotime_tv(&start);
}
@@ -1338,7 +1380,7 @@ ssh_packet_read_seqnr(struct ssh *ssh, u_char *typep, u_int32_t *seqnr_p)
r = SSH_ERR_SYSTEM_ERROR;
goto out;
}
- if (state->packet_timeout_ms == -1)
+ if (state->packet_timeout_ms <= 0)
continue;
ms_subtract_diff(&start, &ms_remain);
if (ms_remain <= 0) {
@@ -1356,7 +1398,7 @@ ssh_packet_read_seqnr(struct ssh *ssh, u_char *typep, u_int32_t *seqnr_p)
r = SSH_ERR_CONN_CLOSED;
goto out;
}
- if (len < 0) {
+ if (len == -1) {
r = SSH_ERR_SYSTEM_ERROR;
goto out;
}
@@ -1377,7 +1419,7 @@ ssh_packet_read(struct ssh *ssh)
int r;
if ((r = ssh_packet_read_seqnr(ssh, &type, NULL)) != 0)
- fatal("%s: %s", __func__, ssh_err(r));
+ fatal_fr(r, "read");
return type;
}
@@ -1435,7 +1477,7 @@ ssh_packet_read_poll2_mux(struct ssh *ssh, u_char *typep, u_int32_t *seqnr_p)
(r = sshbuf_get_u8(state->incoming_packet, typep)) != 0)
return r;
if (ssh_packet_log_type(*typep))
- debug3("%s: type %u", __func__, *typep);
+ debug3_f("type %u", *typep);
/* sshbuf_dump(state->incoming_packet, stderr); */
/* reset for next packet */
state->packlen = 0;
@@ -1664,12 +1706,8 @@ ssh_packet_read_poll2(struct ssh *ssh, u_char *typep, u_int32_t *seqnr_p)
/* reset for next packet */
state->packlen = 0;
- /* do we need to rekey? */
- if (ssh_packet_need_rekeying(ssh, 0)) {
- debug3("%s: rekex triggered", __func__);
- if ((r = kex_start_rekex(ssh)) != 0)
- return r;
- }
+ if ((r = ssh_packet_check_rekey(ssh)) != 0)
+ return r;
out:
return r;
}
@@ -1792,7 +1830,7 @@ ssh_packet_send_debug(struct ssh *ssh, const char *fmt,...)
(r = sshpkt_put_cstring(ssh, "")) != 0 ||
(r = sshpkt_send(ssh)) != 0 ||
(r = ssh_packet_write_wait(ssh)) != 0)
- fatal("%s: %s", __func__, ssh_err(r));
+ fatal_fr(r, "send DEBUG");
}
void
@@ -1807,10 +1845,11 @@ sshpkt_fmt_connection_id(struct ssh *ssh, char *s, size_t l)
/*
* Pretty-print connection-terminating errors and exit.
*/
-void
-sshpkt_fatal(struct ssh *ssh, const char *tag, int r)
+static void
+sshpkt_vfatal(struct ssh *ssh, int r, const char *fmt, va_list ap)
{
- char remote_id[512];
+ char *tag = NULL, remote_id[512];
+ int oerrno = errno;
sshpkt_fmt_connection_id(ssh, remote_id, sizeof(remote_id));
@@ -1839,20 +1878,37 @@ sshpkt_fatal(struct ssh *ssh, const char *tag, int r)
if (ssh && ssh->kex && ssh->kex->failed_choice) {
BLACKLIST_NOTIFY(BLACKLIST_AUTH_FAIL, "ssh");
ssh_packet_clear_keys(ssh);
+ errno = oerrno;
logdie("Unable to negotiate with %s: %s. "
"Their offer: %s", remote_id, ssh_err(r),
ssh->kex->failed_choice);
}
/* FALLTHROUGH */
default:
+ if (vasprintf(&tag, fmt, ap) == -1) {
+ ssh_packet_clear_keys(ssh);
+ logdie_f("could not allocate failure message");
+ }
ssh_packet_clear_keys(ssh);
- logdie("%s%sConnection %s %s: %s",
+ errno = oerrno;
+ logdie_r(r, "%s%sConnection %s %s",
tag != NULL ? tag : "", tag != NULL ? ": " : "",
- ssh->state->server_side ? "from" : "to",
- remote_id, ssh_err(r));
+ ssh->state->server_side ? "from" : "to", remote_id);
}
}
+void
+sshpkt_fatal(struct ssh *ssh, int r, const char *fmt, ...)
+{
+ va_list ap;
+
+ va_start(ap, fmt);
+ sshpkt_vfatal(ssh, r, fmt, ap);
+ /* NOTREACHED */
+ va_end(ap);
+ logdie_f("should have exited");
+}
+
/*
* Logs the error plus constructs and sends a disconnect packet, closes the
* connection, and exits. This function never returns. The error message
@@ -1888,10 +1944,10 @@ ssh_packet_disconnect(struct ssh *ssh, const char *fmt,...)
* for it to get sent.
*/
if ((r = sshpkt_disconnect(ssh, "%s", buf)) != 0)
- sshpkt_fatal(ssh, __func__, r);
+ sshpkt_fatal(ssh, r, "%s", __func__);
if ((r = ssh_packet_write_wait(ssh)) != 0)
- sshpkt_fatal(ssh, __func__, r);
+ sshpkt_fatal(ssh, r, "%s", __func__);
/* Close the connection. */
ssh_packet_close(ssh);
@@ -1956,7 +2012,7 @@ ssh_packet_write_wait(struct ssh *ssh)
timeoutp = &timeout;
}
for (;;) {
- if (state->packet_timeout_ms != -1) {
+ if (state->packet_timeout_ms > 0) {
ms_to_timeval(&timeout, ms_remain);
monotime_tv(&start);
}
@@ -1966,7 +2022,7 @@ ssh_packet_write_wait(struct ssh *ssh)
if (errno != EAGAIN && errno != EINTR &&
errno != EWOULDBLOCK)
break;
- if (state->packet_timeout_ms == -1)
+ if (state->packet_timeout_ms <= 0)
continue;
ms_subtract_diff(&start, &ms_remain);
if (ms_remain <= 0) {
@@ -2009,30 +2065,9 @@ ssh_packet_not_very_much_data_to_write(struct ssh *ssh)
void
ssh_packet_set_tos(struct ssh *ssh, int tos)
{
-#ifndef IP_TOS_IS_BROKEN
if (!ssh_packet_connection_is_on_socket(ssh) || tos == INT_MAX)
return;
- switch (ssh_packet_connection_af(ssh)) {
-# ifdef IP_TOS
- case AF_INET:
- debug3("%s: set IP_TOS 0x%02x", __func__, tos);
- if (setsockopt(ssh->state->connection_in,
- IPPROTO_IP, IP_TOS, &tos, sizeof(tos)) < 0)
- error("setsockopt IP_TOS %d: %.100s:",
- tos, strerror(errno));
- break;
-# endif /* IP_TOS */
-# ifdef IPV6_TCLASS
- case AF_INET6:
- debug3("%s: set IPV6_TCLASS 0x%02x", __func__, tos);
- if (setsockopt(ssh->state->connection_in,
- IPPROTO_IPV6, IPV6_TCLASS, &tos, sizeof(tos)) < 0)
- error("setsockopt IPV6_TCLASS %d: %.100s:",
- tos, strerror(errno));
- break;
-# endif /* IPV6_TCLASS */
- }
-#endif /* IP_TOS_IS_BROKEN */
+ set_sock_tos(ssh->state->connection_in, tos);
}
/* Informs that the current session is interactive. Sets IP flags for that. */
@@ -2053,8 +2088,7 @@ ssh_packet_set_interactive(struct ssh *ssh, int interactive, int qos_interactive
if (!ssh_packet_connection_is_on_socket(ssh))
return;
set_nodelay(state->connection_in);
- ssh_packet_set_tos(ssh, interactive ? qos_interactive :
- qos_bulk);
+ ssh_packet_set_tos(ssh, interactive ? qos_interactive : qos_bulk);
}
/* Returns true if the current connection is interactive. */
@@ -2126,6 +2160,7 @@ void
ssh_packet_set_server(struct ssh *ssh)
{
ssh->state->server_side = 1;
+ ssh->kex->server = 1; /* XXX unify? */
}
void
@@ -2152,7 +2187,7 @@ ssh_packet_set_postauth(struct ssh *ssh)
{
int r;
- debug("%s: called", __func__);
+ debug_f("called");
/* This was set in net child, but is not visible in user child */
ssh->state->after_authentication = 1;
ssh->state->rekeying = 0;
@@ -2169,18 +2204,17 @@ kex_to_blob(struct sshbuf *m, struct kex *kex)
{
int r;
- if ((r = sshbuf_put_string(m, kex->session_id,
- kex->session_id_len)) != 0 ||
- (r = sshbuf_put_u32(m, kex->we_need)) != 0 ||
+ if ((r = sshbuf_put_u32(m, kex->we_need)) != 0 ||
(r = sshbuf_put_cstring(m, kex->hostkey_alg)) != 0 ||
(r = sshbuf_put_u32(m, kex->hostkey_type)) != 0 ||
(r = sshbuf_put_u32(m, kex->hostkey_nid)) != 0 ||
(r = sshbuf_put_u32(m, kex->kex_type)) != 0 ||
(r = sshbuf_put_stringb(m, kex->my)) != 0 ||
(r = sshbuf_put_stringb(m, kex->peer)) != 0 ||
- (r = sshbuf_put_u32(m, kex->flags)) != 0 ||
- (r = sshbuf_put_cstring(m, kex->client_version_string)) != 0 ||
- (r = sshbuf_put_cstring(m, kex->server_version_string)) != 0)
+ (r = sshbuf_put_stringb(m, kex->client_version)) != 0 ||
+ (r = sshbuf_put_stringb(m, kex->server_version)) != 0 ||
+ (r = sshbuf_put_stringb(m, kex->session_id)) != 0 ||
+ (r = sshbuf_put_u32(m, kex->flags)) != 0)
return r;
return 0;
}
@@ -2330,37 +2364,30 @@ kex_from_blob(struct sshbuf *m, struct kex **kexp)
struct kex *kex;
int r;
- if ((kex = calloc(1, sizeof(struct kex))) == NULL ||
- (kex->my = sshbuf_new()) == NULL ||
- (kex->peer = sshbuf_new()) == NULL) {
- r = SSH_ERR_ALLOC_FAIL;
- goto out;
- }
- if ((r = sshbuf_get_string(m, &kex->session_id, &kex->session_id_len)) != 0 ||
- (r = sshbuf_get_u32(m, &kex->we_need)) != 0 ||
+ if ((kex = kex_new()) == NULL)
+ return SSH_ERR_ALLOC_FAIL;
+ if ((r = sshbuf_get_u32(m, &kex->we_need)) != 0 ||
(r = sshbuf_get_cstring(m, &kex->hostkey_alg, NULL)) != 0 ||
(r = sshbuf_get_u32(m, (u_int *)&kex->hostkey_type)) != 0 ||
(r = sshbuf_get_u32(m, (u_int *)&kex->hostkey_nid)) != 0 ||
(r = sshbuf_get_u32(m, &kex->kex_type)) != 0 ||
(r = sshbuf_get_stringb(m, kex->my)) != 0 ||
(r = sshbuf_get_stringb(m, kex->peer)) != 0 ||
- (r = sshbuf_get_u32(m, &kex->flags)) != 0 ||
- (r = sshbuf_get_cstring(m, &kex->client_version_string, NULL)) != 0 ||
- (r = sshbuf_get_cstring(m, &kex->server_version_string, NULL)) != 0)
+ (r = sshbuf_get_stringb(m, kex->client_version)) != 0 ||
+ (r = sshbuf_get_stringb(m, kex->server_version)) != 0 ||
+ (r = sshbuf_get_stringb(m, kex->session_id)) != 0 ||
+ (r = sshbuf_get_u32(m, &kex->flags)) != 0)
goto out;
kex->server = 1;
kex->done = 1;
r = 0;
out:
if (r != 0 || kexp == NULL) {
- if (kex != NULL) {
- sshbuf_free(kex->my);
- sshbuf_free(kex->peer);
- free(kex);
- }
+ kex_free(kex);
if (kexp != NULL)
*kexp = NULL;
} else {
+ kex_free(*kexp);
*kexp = kex;
}
return r;
@@ -2393,7 +2420,7 @@ ssh_packet_set_state(struct ssh *ssh, struct sshbuf *m)
(r = sshbuf_get_u64(m, &state->p_read.bytes)) != 0)
return r;
/*
- * We set the time here so that in post-auth privsep slave we
+ * We set the time here so that in post-auth privsep child we
* count from the completion of the authentication.
*/
state->rekey_time = monotime();
@@ -2415,7 +2442,7 @@ ssh_packet_set_state(struct ssh *ssh, struct sshbuf *m)
if (sshbuf_len(m))
return SSH_ERR_INVALID_FORMAT;
- debug3("%s: done", __func__);
+ debug3_f("done");
return 0;
}
@@ -2471,6 +2498,12 @@ sshpkt_put_stringb(struct ssh *ssh, const struct sshbuf *v)
return sshbuf_put_stringb(ssh->state->outgoing_packet, v);
}
+int
+sshpkt_getb_froms(struct ssh *ssh, struct sshbuf **valp)
+{
+ return sshbuf_froms(ssh->state->incoming_packet, valp);
+}
+
#ifdef WITH_OPENSSL
#ifdef OPENSSL_HAS_ECC
int
@@ -2547,11 +2580,10 @@ sshpkt_get_ec(struct ssh *ssh, EC_POINT *v, const EC_GROUP *g)
}
#endif /* OPENSSL_HAS_ECC */
-
int
-sshpkt_get_bignum2(struct ssh *ssh, BIGNUM *v)
+sshpkt_get_bignum2(struct ssh *ssh, BIGNUM **valp)
{
- return sshbuf_get_bignum2(ssh->state->incoming_packet, v);
+ return sshbuf_get_bignum2(ssh->state->incoming_packet, valp);
}
#endif /* WITH_OPENSSL */
@@ -2601,7 +2633,7 @@ ssh_packet_send_mux(struct ssh *ssh)
cp = sshbuf_mutable_ptr(state->outgoing_packet);
type = cp[5];
if (ssh_packet_log_type(type))
- debug3("%s: type %u", __func__, type);
+ debug3_f("type %u", type);
/* drop everything, but the connection protocol */
if (type >= SSH2_MSG_CONNECTION_MIN &&
type <= SSH2_MSG_CONNECTION_MAX) {
diff --git a/crypto/openssh/packet.h b/crypto/openssh/packet.h
index 170203cabeb2..2ad0e70cfd79 100644
--- a/crypto/openssh/packet.h
+++ b/crypto/openssh/packet.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: packet.h,v 1.86 2018/07/09 21:20:26 markus Exp $ */
+/* $OpenBSD: packet.h,v 1.93 2021/07/16 09:00:23 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -105,6 +105,7 @@ void ssh_packet_clear_keys(struct ssh *);
void ssh_clear_newkeys(struct ssh *, int);
int ssh_packet_is_rekeying(struct ssh *);
+int ssh_packet_check_rekey(struct ssh *);
void ssh_packet_set_protocol_flags(struct ssh *, u_int);
u_int ssh_packet_get_protocol_flags(struct ssh *);
void ssh_packet_set_tos(struct ssh *, int);
@@ -176,7 +177,9 @@ int sshpkt_send(struct ssh *ssh);
int sshpkt_disconnect(struct ssh *, const char *fmt, ...)
__attribute__((format(printf, 2, 3)));
int sshpkt_add_padding(struct ssh *, u_char);
-void sshpkt_fatal(struct ssh *ssh, const char *tag, int r);
+void sshpkt_fatal(struct ssh *ssh, int r, const char *fmt, ...)
+ __attribute__((format(printf, 3, 4)))
+ __attribute__((noreturn));
int sshpkt_msg_ignore(struct ssh *, u_int);
int sshpkt_put(struct ssh *ssh, const void *v, size_t len);
@@ -198,16 +201,13 @@ int sshpkt_get_string(struct ssh *ssh, u_char **valp, size_t *lenp);
int sshpkt_get_string_direct(struct ssh *ssh, const u_char **valp, size_t *lenp);
int sshpkt_peek_string_direct(struct ssh *ssh, const u_char **valp, size_t *lenp);
int sshpkt_get_cstring(struct ssh *ssh, char **valp, size_t *lenp);
+int sshpkt_getb_froms(struct ssh *ssh, struct sshbuf **valp);
int sshpkt_get_ec(struct ssh *ssh, EC_POINT *v, const EC_GROUP *g);
-int sshpkt_get_bignum2(struct ssh *ssh, BIGNUM *v);
+int sshpkt_get_bignum2(struct ssh *ssh, BIGNUM **valp);
int sshpkt_get_end(struct ssh *ssh);
void sshpkt_fmt_connection_id(struct ssh *ssh, char *s, size_t l);
const u_char *sshpkt_ptr(struct ssh *, size_t *lenp);
-/* OLD API */
-extern struct ssh *active_state;
-#include "opacket.h"
-
#if !defined(WITH_OPENSSL)
# undef BIGNUM
# undef EC_KEY
diff --git a/crypto/openssh/pathnames.h b/crypto/openssh/pathnames.h
index 78c25ae0888c..eafa7d4efa41 100644
--- a/crypto/openssh/pathnames.h
+++ b/crypto/openssh/pathnames.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: pathnames.h,v 1.28 2018/02/23 15:58:37 markus Exp $ */
+/* $OpenBSD: pathnames.h,v 1.31 2019/11/12 19:33:08 markus Exp $ */
/* $FreeBSD$ */
/*
@@ -78,6 +78,8 @@
#define _PATH_SSH_CLIENT_ID_RSA _PATH_SSH_USER_DIR "/id_rsa"
#define _PATH_SSH_CLIENT_ID_ED25519 _PATH_SSH_USER_DIR "/id_ed25519"
#define _PATH_SSH_CLIENT_ID_XMSS _PATH_SSH_USER_DIR "/id_xmss"
+#define _PATH_SSH_CLIENT_ID_ECDSA_SK _PATH_SSH_USER_DIR "/id_ecdsa_sk"
+#define _PATH_SSH_CLIENT_ID_ED25519_SK _PATH_SSH_USER_DIR "/id_ed25519_sk"
/*
* Configuration file in user's home directory. This file need not be
@@ -133,6 +135,11 @@
#define _PATH_SSH_PKCS11_HELPER "/usr/libexec/ssh-pkcs11-helper"
#endif
+/* Location of ssh-sk-helper to support keys in security keys */
+#ifndef _PATH_SSH_SK_HELPER
+#define _PATH_SSH_SK_HELPER "/usr/libexec/ssh-sk-helper"
+#endif
+
/* xauth for X11 forwarding */
#ifndef _PATH_XAUTH
#define _PATH_XAUTH "/usr/local/bin/xauth"
diff --git a/crypto/openssh/platform.c b/crypto/openssh/platform.c
index 41acc9370d5e..44ba71dc5fcb 100644
--- a/crypto/openssh/platform.c
+++ b/crypto/openssh/platform.c
@@ -17,6 +17,7 @@
#include "includes.h"
#include <stdarg.h>
+#include <stdio.h>
#include <unistd.h>
#include "log.h"
diff --git a/crypto/openssh/progressmeter.c b/crypto/openssh/progressmeter.c
index fe9bf52e4c90..8baf798f1813 100644
--- a/crypto/openssh/progressmeter.c
+++ b/crypto/openssh/progressmeter.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: progressmeter.c,v 1.45 2016/06/30 05:17:05 dtucker Exp $ */
+/* $OpenBSD: progressmeter.c,v 1.50 2020/01/23 07:10:22 dtucker Exp $ */
/*
* Copyright (c) 2003 Nils Nordman. All rights reserved.
*
@@ -31,6 +31,7 @@
#include <errno.h>
#include <signal.h>
+#include <stdarg.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
@@ -39,6 +40,7 @@
#include "progressmeter.h"
#include "atomicio.h"
#include "misc.h"
+#include "utf8.h"
#define DEFAULT_WINSIZE 80
#define MAX_WINSIZE 512
@@ -57,11 +59,8 @@ static void format_rate(char *, int, off_t);
static void sig_winch(int);
static void setscreensize(void);
-/* updates the progressmeter to reflect the current state of the transfer */
-void refresh_progress_meter(void);
-
/* signal handler for updating the progress meter */
-static void update_progress_meter(int);
+static void sig_alarm(int);
static double start; /* start progress */
static double last_update; /* last progress update */
@@ -74,6 +73,7 @@ static long stalled; /* how long we have been stalled */
static int bytes_per_second; /* current speed in bytes per second */
static int win_size; /* terminal window size */
static volatile sig_atomic_t win_resized; /* for window resizing */
+static volatile sig_atomic_t alarm_fired;
/* units for format_size */
static const char unit[] = " KMGT";
@@ -117,7 +117,7 @@ format_size(char *buf, int size, off_t bytes)
}
void
-refresh_progress_meter(void)
+refresh_progress_meter(int force_update)
{
char buf[MAX_WINSIZE + 1];
off_t transferred;
@@ -126,9 +126,17 @@ refresh_progress_meter(void)
off_t bytes_left;
int cur_speed;
int hours, minutes, seconds;
- int i, len;
int file_len;
+ if ((!force_update && !alarm_fired && !win_resized) || !can_output())
+ return;
+ alarm_fired = 0;
+
+ if (win_resized) {
+ setscreensize();
+ win_resized = 0;
+ }
+
transferred = *counter - (cur_pos ? cur_pos : start_pos);
cur_pos = *counter;
now = monotime_double();
@@ -158,16 +166,11 @@ refresh_progress_meter(void)
/* filename */
buf[0] = '\0';
- file_len = win_size - 35;
+ file_len = win_size - 36;
if (file_len > 0) {
- len = snprintf(buf, file_len + 1, "\r%s", file);
- if (len < 0)
- len = 0;
- if (len >= file_len + 1)
- len = file_len;
- for (i = len; i < file_len; i++)
- buf[i] = ' ';
- buf[file_len] = '\0';
+ buf[0] = '\r';
+ snmprintf(buf+1, sizeof(buf)-1, &file_len, "%-*s",
+ file_len, file);
}
/* percent of transfer done */
@@ -228,22 +231,10 @@ refresh_progress_meter(void)
/*ARGSUSED*/
static void
-update_progress_meter(int ignore)
+sig_alarm(int ignore)
{
- int save_errno;
-
- save_errno = errno;
-
- if (win_resized) {
- setscreensize();
- win_resized = 0;
- }
- if (can_output())
- refresh_progress_meter();
-
- signal(SIGALRM, update_progress_meter);
+ alarm_fired = 1;
alarm(UPDATE_INTERVAL);
- errno = save_errno;
}
void
@@ -259,11 +250,10 @@ start_progress_meter(const char *f, off_t filesize, off_t *ctr)
bytes_per_second = 0;
setscreensize();
- if (can_output())
- refresh_progress_meter();
+ refresh_progress_meter(1);
- signal(SIGALRM, update_progress_meter);
- signal(SIGWINCH, sig_winch);
+ ssh_signal(SIGALRM, sig_alarm);
+ ssh_signal(SIGWINCH, sig_winch);
alarm(UPDATE_INTERVAL);
}
@@ -277,7 +267,7 @@ stop_progress_meter(void)
/* Ensure we complete the progress */
if (cur_pos != end_pos)
- refresh_progress_meter();
+ refresh_progress_meter(1);
atomicio(vwrite, STDOUT_FILENO, "\n", 1);
}
diff --git a/crypto/openssh/progressmeter.h b/crypto/openssh/progressmeter.h
index bf179dca6518..1703ea75babc 100644
--- a/crypto/openssh/progressmeter.h
+++ b/crypto/openssh/progressmeter.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: progressmeter.h,v 1.3 2015/01/14 13:54:13 djm Exp $ */
+/* $OpenBSD: progressmeter.h,v 1.5 2019/01/24 16:52:17 dtucker Exp $ */
/*
* Copyright (c) 2002 Nils Nordman. All rights reserved.
*
@@ -24,4 +24,5 @@
*/
void start_progress_meter(const char *, off_t, off_t *);
+void refresh_progress_meter(int);
void stop_progress_meter(void);
diff --git a/crypto/openssh/readconf.c b/crypto/openssh/readconf.c
index c1147a9e2e5f..7abefb6f5627 100644
--- a/crypto/openssh/readconf.c
+++ b/crypto/openssh/readconf.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: readconf.c,v 1.300 2018/10/05 14:26:09 naddy Exp $ */
+/* $OpenBSD: readconf.c,v 1.361 2021/07/23 04:04:52 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -36,9 +36,9 @@ __RCSID("$FreeBSD$");
#endif
#include <pwd.h>
#include <signal.h>
-#include <stdarg.h>
#include <stdio.h>
#include <string.h>
+#include <stdarg.h>
#include <unistd.h>
#ifdef USE_SYSTEM_GLOB
# include <glob.h>
@@ -88,7 +88,7 @@ __RCSID("$FreeBSD$");
User foo
Host fake.com
- HostName another.host.name.real.org
+ Hostname another.host.name.real.org
User blaah
Port 34289
ForwardX11 no
@@ -123,8 +123,6 @@ __RCSID("$FreeBSD$");
ForwardAgent no
ForwardX11 no
PasswordAuthentication yes
- RSAAuthentication yes
- RhostsRSAAuthentication yes
StrictHostKeyChecking yes
TcpKeepAlive no
IdentityFile ~/.ssh/identity
@@ -135,10 +133,11 @@ __RCSID("$FreeBSD$");
static int read_config_file_depth(const char *filename, struct passwd *pw,
const char *host, const char *original_host, Options *options,
- int flags, int *activep, int depth);
+ int flags, int *activep, int *want_final_pass, int depth);
static int process_config_line_depth(Options *options, struct passwd *pw,
const char *host, const char *original_host, char *line,
- const char *filename, int linenum, int *activep, int flags, int depth);
+ const char *filename, int linenum, int *activep, int flags,
+ int *want_final_pass, int depth);
/* Keyword tokens. */
@@ -148,15 +147,16 @@ typedef enum {
oHost, oMatch, oInclude,
oForwardAgent, oForwardX11, oForwardX11Trusted, oForwardX11Timeout,
oGatewayPorts, oExitOnForwardFailure,
- oPasswordAuthentication, oRSAAuthentication,
- oChallengeResponseAuthentication, oXAuthLocation,
- oIdentityFile, oHostName, oPort, oCipher, oRemoteForward, oLocalForward,
+ oPasswordAuthentication,
+ oXAuthLocation,
+ oIdentityFile, oHostname, oPort, oRemoteForward, oLocalForward,
+ oPermitRemoteOpen,
oCertificateFile, oAddKeysToAgent, oIdentityAgent,
- oUser, oEscapeChar, oRhostsRSAAuthentication, oProxyCommand,
+ oUser, oEscapeChar, oProxyCommand,
oGlobalKnownHostsFile, oUserKnownHostsFile, oConnectionAttempts,
oBatchMode, oCheckHostIP, oStrictHostKeyChecking, oCompression,
- oCompressionLevel, oTCPKeepAlive, oNumberOfPasswordPrompts,
- oUsePrivilegedPort, oLogFacility, oLogLevel, oCiphers, oMacs,
+ oTCPKeepAlive, oNumberOfPasswordPrompts,
+ oLogFacility, oLogLevel, oLogVerbose, oCiphers, oMacs,
oPubkeyAuthentication,
oKbdInteractiveAuthentication, oKbdInteractiveDevices, oHostKeyAlias,
oDynamicForward, oPreferredAuthentications, oHostbasedAuthentication,
@@ -170,12 +170,14 @@ typedef enum {
oTunnel, oTunnelDevice,
oLocalCommand, oPermitLocalCommand, oRemoteCommand,
oVisualHostKey,
- oKexAlgorithms, oIPQoS, oRequestTTY, oIgnoreUnknown, oProxyUseFdpass,
+ oKexAlgorithms, oIPQoS, oRequestTTY, oSessionType, oStdinNull,
+ oForkAfterAuthentication, oIgnoreUnknown, oProxyUseFdpass,
oCanonicalDomains, oCanonicalizeHostname, oCanonicalizeMaxDots,
oCanonicalizeFallbackLocal, oCanonicalizePermittedCNAMEs,
oStreamLocalBindMask, oStreamLocalBindUnlink, oRevokedHostKeys,
- oFingerprintHash, oUpdateHostkeys, oHostbasedKeyTypes,
- oPubkeyAcceptedKeyTypes, oCASignatureAlgorithms, oProxyJump,
+ oFingerprintHash, oUpdateHostkeys, oHostbasedAcceptedAlgorithms,
+ oPubkeyAcceptedAlgorithms, oCASignatureAlgorithms, oProxyJump,
+ oSecurityKeyProvider, oKnownHostsCommand,
oIgnore, oIgnoredUnknownOption, oDeprecated, oUnsupported
} OpCodes;
@@ -200,6 +202,9 @@ static struct {
{ "afstokenpassing", oUnsupported },
{ "kerberosauthentication", oUnsupported },
{ "kerberostgtpassing", oUnsupported },
+ { "rsaauthentication", oUnsupported },
+ { "rhostsrsaauthentication", oUnsupported },
+ { "compressionlevel", oUnsupported },
/* Sometimes-unsupported options */
#if defined(GSSAPI)
@@ -210,15 +215,12 @@ static struct {
{ "gssapidelegatecredentials", oUnsupported },
#endif
#ifdef ENABLE_PKCS11
- { "smartcarddevice", oPKCS11Provider },
{ "pkcs11provider", oPKCS11Provider },
+ { "smartcarddevice", oPKCS11Provider },
# else
{ "smartcarddevice", oUnsupported },
{ "pkcs11provider", oUnsupported },
#endif
- { "rsaauthentication", oUnsupported },
- { "rhostsrsaauthentication", oUnsupported },
- { "compressionlevel", oUnsupported },
{ "forwardagent", oForwardAgent },
{ "forwardx11", oForwardX11 },
@@ -230,19 +232,19 @@ static struct {
{ "passwordauthentication", oPasswordAuthentication },
{ "kbdinteractiveauthentication", oKbdInteractiveAuthentication },
{ "kbdinteractivedevices", oKbdInteractiveDevices },
+ { "challengeresponseauthentication", oKbdInteractiveAuthentication }, /* alias */
+ { "skeyauthentication", oKbdInteractiveAuthentication }, /* alias */
+ { "tisauthentication", oKbdInteractiveAuthentication }, /* alias */
{ "pubkeyauthentication", oPubkeyAuthentication },
{ "dsaauthentication", oPubkeyAuthentication }, /* alias */
{ "hostbasedauthentication", oHostbasedAuthentication },
- { "challengeresponseauthentication", oChallengeResponseAuthentication },
- { "skeyauthentication", oUnsupported },
- { "tisauthentication", oChallengeResponseAuthentication }, /* alias */
{ "identityfile", oIdentityFile },
{ "identityfile2", oIdentityFile }, /* obsolete */
{ "identitiesonly", oIdentitiesOnly },
{ "certificatefile", oCertificateFile },
{ "addkeystoagent", oAddKeysToAgent },
{ "identityagent", oIdentityAgent },
- { "hostname", oHostName },
+ { "hostname", oHostname },
{ "hostkeyalias", oHostKeyAlias },
{ "proxycommand", oProxyCommand },
{ "port", oPort },
@@ -250,6 +252,7 @@ static struct {
{ "macs", oMacs },
{ "remoteforward", oRemoteForward },
{ "localforward", oLocalForward },
+ { "permitremoteopen", oPermitRemoteOpen },
{ "user", oUser },
{ "host", oHost },
{ "match", oMatch },
@@ -266,6 +269,7 @@ static struct {
{ "numberofpasswordprompts", oNumberOfPasswordPrompts },
{ "syslogfacility", oLogFacility },
{ "loglevel", oLogLevel },
+ { "logverbose", oLogVerbose },
{ "dynamicforward", oDynamicForward },
{ "preferredauthentications", oPreferredAuthentications },
{ "hostkeyalgorithms", oHostKeyAlgorithms },
@@ -297,6 +301,9 @@ static struct {
{ "kexalgorithms", oKexAlgorithms },
{ "ipqos", oIPQoS },
{ "requesttty", oRequestTTY },
+ { "sessiontype", oSessionType },
+ { "stdinnull", oStdinNull },
+ { "forkafterauthentication", oForkAfterAuthentication },
{ "proxyusefdpass", oProxyUseFdpass },
{ "canonicaldomains", oCanonicalDomains },
{ "canonicalizefallbacklocal", oCanonicalizeFallbackLocal },
@@ -308,10 +315,14 @@ static struct {
{ "revokedhostkeys", oRevokedHostKeys },
{ "fingerprinthash", oFingerprintHash },
{ "updatehostkeys", oUpdateHostkeys },
- { "hostbasedkeytypes", oHostbasedKeyTypes },
- { "pubkeyacceptedkeytypes", oPubkeyAcceptedKeyTypes },
+ { "hostbasedacceptedalgorithms", oHostbasedAcceptedAlgorithms },
+ { "hostbasedkeytypes", oHostbasedAcceptedAlgorithms }, /* obsolete */
+ { "pubkeyacceptedalgorithms", oPubkeyAcceptedAlgorithms },
+ { "pubkeyacceptedkeytypes", oPubkeyAcceptedAlgorithms }, /* obsolete */
{ "ignoreunknown", oIgnoreUnknown },
{ "proxyjump", oProxyJump },
+ { "securitykeyprovider", oSecurityKeyProvider },
+ { "knownhostscommand", oKnownHostsCommand },
{ "hpndisabled", oDeprecated },
{ "hpnbuffersize", oDeprecated },
@@ -324,6 +335,41 @@ static struct {
{ NULL, oBadOption }
};
+static const char *lookup_opcode_name(OpCodes code);
+
+const char *
+kex_default_pk_alg(void)
+{
+ static char *pkalgs;
+
+ if (pkalgs == NULL) {
+ char *all_key;
+
+ all_key = sshkey_alg_list(0, 0, 1, ',');
+ pkalgs = match_filter_allowlist(KEX_DEFAULT_PK_ALG, all_key);
+ free(all_key);
+ }
+ return pkalgs;
+}
+
+char *
+ssh_connection_hash(const char *thishost, const char *host, const char *portstr,
+ const char *user)
+{
+ struct ssh_digest_ctx *md;
+ u_char conn_hash[SSH_DIGEST_MAX_LENGTH];
+
+ if ((md = ssh_digest_start(SSH_DIGEST_SHA1)) == NULL ||
+ ssh_digest_update(md, thishost, strlen(thishost)) < 0 ||
+ ssh_digest_update(md, host, strlen(host)) < 0 ||
+ ssh_digest_update(md, portstr, strlen(portstr)) < 0 ||
+ ssh_digest_update(md, user, strlen(user)) < 0 ||
+ ssh_digest_final(md, conn_hash, sizeof(conn_hash)) < 0)
+ fatal_f("mux digest failed");
+ ssh_digest_free(md);
+ return tohex(conn_hash, ssh_digest_bytes(SSH_DIGEST_SHA1));
+}
+
/*
* Adds a local TCP/IP port forward to options. Never returns if there is an
* error.
@@ -427,7 +473,7 @@ add_certificate_file(Options *options, const char *path, int userprovided)
for (i = 0; i < options->num_certificate_files; i++) {
if (options->certificate_file_userprovided[i] == userprovided &&
strcmp(options->certificate_files[i], path) == 0) {
- debug2("%s: ignoring duplicate key %s", __func__, path);
+ debug2_f("ignoring duplicate key %s", path);
return;
}
}
@@ -458,7 +504,7 @@ add_identity_file(Options *options, const char *dir, const char *filename,
for (i = 0; i < options->num_identity_files; i++) {
if (options->identity_file_userprovided[i] == userprovided &&
strcmp(options->identity_files[i], path) == 0) {
- debug2("%s: ignoring duplicate key %s", __func__, path);
+ debug2_f("ignoring duplicate key %s", path);
free(path);
return;
}
@@ -491,14 +537,15 @@ execute_in_shell(const char *cmd)
{
char *shell;
pid_t pid;
- int devnull, status;
+ int status;
if ((shell = getenv("SHELL")) == NULL)
shell = _PATH_BSHELL;
- /* Need this to redirect subprocess stdin/out */
- if ((devnull = open(_PATH_DEVNULL, O_RDWR)) == -1)
- fatal("open(/dev/null): %s", strerror(errno));
+ if (access(shell, X_OK) == -1) {
+ fatal("Shell \"%s\" is not executable: %s",
+ shell, strerror(errno));
+ }
debug("Executing command: '%.500s'", cmd);
@@ -506,13 +553,8 @@ execute_in_shell(const char *cmd)
if ((pid = fork()) == 0) {
char *argv[4];
- /* Redirect child stdin and stdout. Leave stderr */
- if (dup2(devnull, STDIN_FILENO) == -1)
- fatal("dup2: %s", strerror(errno));
- if (dup2(devnull, STDOUT_FILENO) == -1)
- fatal("dup2: %s", strerror(errno));
- if (devnull > STDERR_FILENO)
- close(devnull);
+ if (stdfd_devnull(1, 1, 0) == -1)
+ fatal_f("stdfd_devnull failed");
closefrom(STDERR_FILENO + 1);
argv[0] = shell;
@@ -523,19 +565,17 @@ execute_in_shell(const char *cmd)
execv(argv[0], argv);
error("Unable to execute '%.100s': %s", cmd, strerror(errno));
/* Die with signal to make this error apparent to parent. */
- signal(SIGTERM, SIG_DFL);
+ ssh_signal(SIGTERM, SIG_DFL);
kill(getpid(), SIGTERM);
_exit(1);
}
/* Parent. */
- if (pid < 0)
- fatal("%s: fork: %.100s", __func__, strerror(errno));
-
- close(devnull);
+ if (pid == -1)
+ fatal_f("fork: %.100s", strerror(errno));
while (waitpid(pid, &status, 0) == -1) {
if (errno != EINTR && errno != EAGAIN)
- fatal("%s: waitpid: %s", __func__, strerror(errno));
+ fatal_f("waitpid: %s", strerror(errno));
}
if (!WIFEXITED(status)) {
error("command '%.100s' exited abnormally", cmd);
@@ -550,8 +590,8 @@ execute_in_shell(const char *cmd)
*/
static int
match_cfg_line(Options *options, char **condition, struct passwd *pw,
- const char *host_arg, const char *original_host, int post_canon,
- const char *filename, int linenum)
+ const char *host_arg, const char *original_host, int final_pass,
+ int *want_final_pass, const char *filename, int linenum)
{
char *arg, *oattrib, *attrib, *cmd, *cp = *condition, *host, *criteria;
const char *ruser;
@@ -565,7 +605,7 @@ match_cfg_line(Options *options, char **condition, struct passwd *pw,
*/
port = options->port <= 0 ? default_ssh_port() : options->port;
ruser = options->user == NULL ? pw->pw_name : options->user;
- if (post_canon) {
+ if (final_pass) {
host = xstrdup(options->hostname);
} else if (options->hostname != NULL) {
/* NB. Please keep in sync with ssh.c:main() */
@@ -578,27 +618,43 @@ match_cfg_line(Options *options, char **condition, struct passwd *pw,
debug2("checking match for '%s' host %s originally %s",
cp, host, original_host);
while ((oattrib = attrib = strdelim(&cp)) && *attrib != '\0') {
- criteria = NULL;
+ /* Terminate on comment */
+ if (*attrib == '#') {
+ cp = NULL; /* mark all arguments consumed */
+ break;
+ }
+ arg = criteria = NULL;
this_result = 1;
if ((negate = attrib[0] == '!'))
attrib++;
- /* criteria "all" and "canonical" have no argument */
+ /* Criterion "all" has no argument and must appear alone */
if (strcasecmp(attrib, "all") == 0) {
- if (attributes > 1 ||
- ((arg = strdelim(&cp)) != NULL && *arg != '\0')) {
+ if (attributes > 1 || ((arg = strdelim(&cp)) != NULL &&
+ *arg != '\0' && *arg != '#')) {
error("%.200s line %d: '%s' cannot be combined "
"with other Match attributes",
filename, linenum, oattrib);
result = -1;
goto out;
}
+ if (arg != NULL && *arg == '#')
+ cp = NULL; /* mark all arguments consumed */
if (result)
result = negate ? 0 : 1;
goto out;
}
attributes++;
- if (strcasecmp(attrib, "canonical") == 0) {
- r = !!post_canon; /* force bitmask member to boolean */
+ /* criteria "final" and "canonical" have no argument */
+ if (strcasecmp(attrib, "canonical") == 0 ||
+ strcasecmp(attrib, "final") == 0) {
+ /*
+ * If the config requests "Match final" then remember
+ * this so we can perform a second pass later.
+ */
+ if (strcasecmp(attrib, "final") == 0 &&
+ want_final_pass != NULL)
+ *want_final_pass = 1;
+ r = !!final_pass; /* force bitmask member to boolean */
if (r == (negate ? 1 : 0))
this_result = result = 0;
debug3("%.200s line %d: %smatched '%s'",
@@ -607,7 +663,8 @@ match_cfg_line(Options *options, char **condition, struct passwd *pw,
continue;
}
/* All other criteria require an argument */
- if ((arg = strdelim(&cp)) == NULL || *arg == '\0') {
+ if ((arg = strdelim(&cp)) == NULL ||
+ *arg == '\0' || *arg == '#') {
error("Missing Match criteria for %s", attrib);
result = -1;
goto out;
@@ -633,6 +690,8 @@ match_cfg_line(Options *options, char **condition, struct passwd *pw,
if (r == (negate ? 1 : 0))
this_result = result = 0;
} else if (strcasecmp(attrib, "exec") == 0) {
+ char *conn_hash_hex, *keyalias;
+
if (gethostname(thishost, sizeof(thishost)) == -1)
fatal("gethostname: %s", strerror(errno));
strlcpy(shorthost, thishost, sizeof(shorthost));
@@ -640,11 +699,17 @@ match_cfg_line(Options *options, char **condition, struct passwd *pw,
snprintf(portstr, sizeof(portstr), "%d", port);
snprintf(uidstr, sizeof(uidstr), "%llu",
(unsigned long long)pw->pw_uid);
+ conn_hash_hex = ssh_connection_hash(thishost, host,
+ portstr, ruser);
+ keyalias = options->host_key_alias ?
+ options->host_key_alias : host;
cmd = percent_expand(arg,
+ "C", conn_hash_hex,
"L", shorthost,
"d", pw->pw_dir,
"h", host,
+ "k", keyalias,
"l", thishost,
"n", original_host,
"p", portstr,
@@ -652,6 +717,7 @@ match_cfg_line(Options *options, char **condition, struct passwd *pw,
"u", pw->pw_name,
"i", uidstr,
(char *)NULL);
+ free(conn_hash_hex);
if (result != 1) {
/* skip execution if prior predicate failed */
debug3("%.200s line %d: skipped exec "
@@ -698,7 +764,7 @@ match_cfg_line(Options *options, char **condition, struct passwd *pw,
static void
rm_env(Options *options, const char *arg, const char *filename, int linenum)
{
- int i, j;
+ int i, j, onum_send_env = options->num_send_env;
char *cp;
/* Remove an environment variable */
@@ -721,6 +787,11 @@ rm_env(Options *options, const char *arg, const char *filename, int linenum)
options->num_send_env--;
/* NB. don't increment i */
}
+ if (onum_send_env != options->num_send_env) {
+ options->send_env = xrecallocarray(options->send_env,
+ onum_send_env, options->num_send_env,
+ sizeof(*options->send_env));
+ }
}
/*
@@ -816,6 +887,12 @@ static const struct multistate multistate_requesttty[] = {
{ "auto", REQUEST_TTY_AUTO },
{ NULL, -1 }
};
+static const struct multistate multistate_sessiontype[] = {
+ { "none", SESSION_TYPE_NONE },
+ { "subsystem", SESSION_TYPE_SUBSYSTEM },
+ { "default", SESSION_TYPE_DEFAULT },
+ { NULL, -1 }
+};
static const struct multistate multistate_canonicalizehostname[] = {
{ "true", SSH_CANONICALISE_YES },
{ "false", SSH_CANONICALISE_NO },
@@ -824,6 +901,30 @@ static const struct multistate multistate_canonicalizehostname[] = {
{ "always", SSH_CANONICALISE_ALWAYS },
{ NULL, -1 }
};
+static const struct multistate multistate_compression[] = {
+#ifdef WITH_ZLIB
+ { "yes", COMP_ZLIB },
+#endif
+ { "no", COMP_NONE },
+ { NULL, -1 }
+};
+
+static int
+parse_multistate_value(const char *arg, const char *filename, int linenum,
+ const struct multistate *multistate_ptr)
+{
+ int i;
+
+ if (!arg || *arg == '\0') {
+ error("%s line %d: missing argument.", filename, linenum);
+ return -1;
+ }
+ for (i = 0; multistate_ptr[i].key != NULL; i++) {
+ if (strcasecmp(arg, multistate_ptr[i].key) == 0)
+ return multistate_ptr[i].value;
+ }
+ return -1;
+}
/*
* Processes a single option line as used in the configuration files. This
@@ -835,18 +936,18 @@ process_config_line(Options *options, struct passwd *pw, const char *host,
int linenum, int *activep, int flags)
{
return process_config_line_depth(options, pw, host, original_host,
- line, filename, linenum, activep, flags, 0);
+ line, filename, linenum, activep, flags, NULL, 0);
}
#define WHITESPACE " \t\r\n"
static int
process_config_line_depth(Options *options, struct passwd *pw, const char *host,
const char *original_host, char *line, const char *filename,
- int linenum, int *activep, int flags, int depth)
+ int linenum, int *activep, int flags, int *want_final_pass, int depth)
{
- char *s, **charptr, *endofnumber, *keyword, *arg, *arg2;
- char **cpptr, fwdarg[256];
- u_int i, *uintptr, max_entries = 0;
+ char *str, **charptr, *endofnumber, *keyword, *arg, *arg2, *p, ch;
+ char **cpptr, ***cppptr, fwdarg[256];
+ u_int i, *uintptr, uvalue, max_entries = 0;
int r, oactive, negated, opcode, *intptr, value, value2, cmdline = 0;
int remotefwd, dynamicfwd;
LogLevel *log_level_ptr;
@@ -858,6 +959,9 @@ process_config_line_depth(Options *options, struct passwd *pw, const char *host,
struct allowed_cname *cname;
glob_t gl;
const char *errstr;
+ char **oav = NULL, **av;
+ int oac = 0, ac;
+ int ret = -1;
if (activep == NULL) { /* We are processing a command line directive */
cmdline = 1;
@@ -873,73 +977,112 @@ process_config_line_depth(Options *options, struct passwd *pw, const char *host,
line[len] = '\0';
}
- s = line;
+ str = line;
/* Get the keyword. (Each line is supposed to begin with a keyword). */
- if ((keyword = strdelim(&s)) == NULL)
+ if ((keyword = strdelim(&str)) == NULL)
return 0;
/* Ignore leading whitespace. */
if (*keyword == '\0')
- keyword = strdelim(&s);
+ keyword = strdelim(&str);
if (keyword == NULL || !*keyword || *keyword == '\n' || *keyword == '#')
return 0;
/* Match lowercase keyword */
lowercase(keyword);
+ /* Prepare to parse remainder of line */
+ if (str != NULL)
+ str += strspn(str, WHITESPACE);
+ if (str == NULL || *str == '\0') {
+ error("%s line %d: no argument after keyword \"%s\"",
+ filename, linenum, keyword);
+ return -1;
+ }
opcode = parse_token(keyword, filename, linenum,
options->ignored_unknown);
+ if (argv_split(str, &oac, &oav, 1) != 0) {
+ error("%s line %d: invalid quotes", filename, linenum);
+ return -1;
+ }
+ ac = oac;
+ av = oav;
switch (opcode) {
case oBadOption:
/* don't panic, but count bad options */
- return -1;
+ goto out;
case oIgnore:
- return 0;
+ argv_consume(&ac);
+ break;
case oIgnoredUnknownOption:
debug("%s line %d: Ignored unknown option \"%s\"",
filename, linenum, keyword);
- return 0;
+ argv_consume(&ac);
+ break;
case oConnectTimeout:
intptr = &options->connection_timeout;
parse_time:
- arg = strdelim(&s);
- if (!arg || *arg == '\0')
- fatal("%s line %d: missing time value.",
+ arg = argv_next(&ac, &av);
+ if (!arg || *arg == '\0') {
+ error("%s line %d: missing time value.",
filename, linenum);
+ goto out;
+ }
if (strcmp(arg, "none") == 0)
value = -1;
- else if ((value = convtime(arg)) == -1)
- fatal("%s line %d: invalid time value.",
+ else if ((value = convtime(arg)) == -1) {
+ error("%s line %d: invalid time value.",
filename, linenum);
+ goto out;
+ }
if (*activep && *intptr == -1)
*intptr = value;
break;
case oForwardAgent:
intptr = &options->forward_agent;
- parse_flag:
- multistate_ptr = multistate_flag;
- parse_multistate:
- arg = strdelim(&s);
- if (!arg || *arg == '\0')
- fatal("%s line %d: missing argument.",
+
+ arg = argv_next(&ac, &av);
+ if (!arg || *arg == '\0') {
+ error("%s line %d: missing argument.",
filename, linenum);
+ goto out;
+ }
+
value = -1;
+ multistate_ptr = multistate_flag;
for (i = 0; multistate_ptr[i].key != NULL; i++) {
if (strcasecmp(arg, multistate_ptr[i].key) == 0) {
value = multistate_ptr[i].value;
break;
}
}
- if (value == -1)
- fatal("%s line %d: unsupported option \"%s\".",
- filename, linenum, arg);
+ if (value != -1) {
+ if (*activep && *intptr == -1)
+ *intptr = value;
+ break;
+ }
+ /* ForwardAgent wasn't 'yes' or 'no', assume a path */
if (*activep && *intptr == -1)
- *intptr = value;
- break;
+ *intptr = 1;
+
+ charptr = &options->forward_agent_sock_path;
+ goto parse_agent_path;
case oForwardX11:
intptr = &options->forward_x11;
- goto parse_flag;
+ parse_flag:
+ multistate_ptr = multistate_flag;
+ parse_multistate:
+ arg = argv_next(&ac, &av);
+ if ((value = parse_multistate_value(arg, filename, linenum,
+ multistate_ptr)) == -1) {
+ error("%s line %d: unsupported option \"%s\".",
+ filename, linenum, arg);
+ goto out;
+ }
+ if (*activep && *intptr == -1)
+ *intptr = value;
+ break;
case oForwardX11Trusted:
intptr = &options->forward_x11_trusted;
@@ -977,10 +1120,6 @@ parse_time:
intptr = &options->hostbased_authentication;
goto parse_flag;
- case oChallengeResponseAuthentication:
- intptr = &options->challenge_response_authentication;
- goto parse_flag;
-
case oGssAuthentication:
intptr = &options->gss_authentication;
goto parse_flag;
@@ -1009,7 +1148,8 @@ parse_time:
case oCompression:
intptr = &options->compression;
- goto parse_flag;
+ multistate_ptr = multistate_compression;
+ goto parse_multistate;
case oTCPKeepAlive:
intptr = &options->tcp_keep_alive;
@@ -1024,25 +1164,31 @@ parse_time:
goto parse_int;
case oRekeyLimit:
- arg = strdelim(&s);
- if (!arg || *arg == '\0')
- fatal("%.200s line %d: Missing argument.", filename,
+ arg = argv_next(&ac, &av);
+ if (!arg || *arg == '\0') {
+ error("%.200s line %d: Missing argument.", filename,
linenum);
+ goto out;
+ }
if (strcmp(arg, "default") == 0) {
val64 = 0;
} else {
- if (scan_scaled(arg, &val64) == -1)
- fatal("%.200s line %d: Bad number '%s': %s",
+ if (scan_scaled(arg, &val64) == -1) {
+ error("%.200s line %d: Bad number '%s': %s",
filename, linenum, arg, strerror(errno));
- if (val64 != 0 && val64 < 16)
- fatal("%.200s line %d: RekeyLimit too small",
+ goto out;
+ }
+ if (val64 != 0 && val64 < 16) {
+ error("%.200s line %d: RekeyLimit too small",
filename, linenum);
+ goto out;
+ }
}
if (*activep && options->rekey_limit == -1)
options->rekey_limit = val64;
- if (s != NULL) { /* optional rekey interval present */
- if (strcmp(s, "none") == 0) {
- (void)strdelim(&s); /* discard */
+ if (ac != 0) { /* optional rekey interval present */
+ if (strcmp(av[0], "none") == 0) {
+ (void)argv_next(&ac, &av); /* discard */
break;
}
intptr = &options->rekey_interval;
@@ -1051,31 +1197,40 @@ parse_time:
break;
case oIdentityFile:
- arg = strdelim(&s);
- if (!arg || *arg == '\0')
- fatal("%.200s line %d: Missing argument.", filename, linenum);
+ arg = argv_next(&ac, &av);
+ if (!arg || *arg == '\0') {
+ error("%.200s line %d: Missing argument.",
+ filename, linenum);
+ goto out;
+ }
if (*activep) {
intptr = &options->num_identity_files;
- if (*intptr >= SSH_MAX_IDENTITY_FILES)
- fatal("%.200s line %d: Too many identity files specified (max %d).",
- filename, linenum, SSH_MAX_IDENTITY_FILES);
+ if (*intptr >= SSH_MAX_IDENTITY_FILES) {
+ error("%.200s line %d: Too many identity files "
+ "specified (max %d).", filename, linenum,
+ SSH_MAX_IDENTITY_FILES);
+ goto out;
+ }
add_identity_file(options, NULL,
arg, flags & SSHCONF_USERCONF);
}
break;
case oCertificateFile:
- arg = strdelim(&s);
- if (!arg || *arg == '\0')
- fatal("%.200s line %d: Missing argument.",
+ arg = argv_next(&ac, &av);
+ if (!arg || *arg == '\0') {
+ error("%.200s line %d: Missing argument.",
filename, linenum);
+ goto out;
+ }
if (*activep) {
intptr = &options->num_certificate_files;
if (*intptr >= SSH_MAX_CERTIFICATE_FILES) {
- fatal("%.200s line %d: Too many certificate "
+ error("%.200s line %d: Too many certificate "
"files specified (max %d).",
filename, linenum,
SSH_MAX_CERTIFICATE_FILES);
+ goto out;
}
add_certificate_file(options, arg,
flags & SSHCONF_USERCONF);
@@ -1089,10 +1244,12 @@ parse_time:
case oUser:
charptr = &options->user;
parse_string:
- arg = strdelim(&s);
- if (!arg || *arg == '\0')
- fatal("%.200s line %d: Missing argument.",
+ arg = argv_next(&ac, &av);
+ if (!arg || *arg == '\0') {
+ error("%.200s line %d: Missing argument.",
filename, linenum);
+ goto out;
+ }
if (*activep && *charptr == NULL)
*charptr = xstrdup(arg);
break;
@@ -1102,16 +1259,35 @@ parse_string:
uintptr = &options->num_system_hostfiles;
max_entries = SSH_MAX_HOSTS_FILES;
parse_char_array:
- if (*activep && *uintptr == 0) {
- while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
- if ((*uintptr) >= max_entries)
- fatal("%s line %d: "
- "too many authorized keys files.",
- filename, linenum);
+ i = 0;
+ value = *uintptr == 0; /* was array empty when we started? */
+ while ((arg = argv_next(&ac, &av)) != NULL) {
+ if (*arg == '\0') {
+ error("%s line %d: keyword %s empty argument",
+ filename, linenum, keyword);
+ goto out;
+ }
+ /* Allow "none" only in first position */
+ if (strcasecmp(arg, "none") == 0) {
+ if (i > 0 || ac > 0) {
+ error("%s line %d: keyword %s \"none\" "
+ "argument must appear alone.",
+ filename, linenum, keyword);
+ goto out;
+ }
+ }
+ i++;
+ if (*activep && value) {
+ if ((*uintptr) >= max_entries) {
+ error("%s line %d: too many %s "
+ "entries.", filename, linenum,
+ keyword);
+ goto out;
+ }
cpptr[(*uintptr)++] = xstrdup(arg);
}
}
- return 0;
+ break;
case oUserKnownHostsFile:
cpptr = (char **)&options->user_hostfiles;
@@ -1119,7 +1295,7 @@ parse_char_array:
max_entries = SSH_MAX_HOSTS_FILES;
goto parse_char_array;
- case oHostName:
+ case oHostname:
charptr = &options->hostname;
goto parse_string;
@@ -1143,40 +1319,60 @@ parse_char_array:
charptr = &options->pkcs11_provider;
goto parse_string;
+ case oSecurityKeyProvider:
+ charptr = &options->sk_provider;
+ goto parse_string;
+
+ case oKnownHostsCommand:
+ charptr = &options->known_hosts_command;
+ goto parse_command;
+
case oProxyCommand:
charptr = &options->proxy_command;
/* Ignore ProxyCommand if ProxyJump already specified */
if (options->jump_host != NULL)
charptr = &options->jump_host; /* Skip below */
parse_command:
- if (s == NULL)
- fatal("%.200s line %d: Missing argument.", filename, linenum);
- len = strspn(s, WHITESPACE "=");
+ if (str == NULL) {
+ error("%.200s line %d: Missing argument.",
+ filename, linenum);
+ goto out;
+ }
+ len = strspn(str, WHITESPACE "=");
if (*activep && *charptr == NULL)
- *charptr = xstrdup(s + len);
- return 0;
+ *charptr = xstrdup(str + len);
+ argv_consume(&ac);
+ break;
case oProxyJump:
- if (s == NULL) {
- fatal("%.200s line %d: Missing argument.",
+ if (str == NULL) {
+ error("%.200s line %d: Missing argument.",
filename, linenum);
+ goto out;
}
- len = strspn(s, WHITESPACE "=");
- if (parse_jump(s + len, options, *activep) == -1) {
- fatal("%.200s line %d: Invalid ProxyJump \"%s\"",
- filename, linenum, s + len);
+ len = strspn(str, WHITESPACE "=");
+ /* XXX use argv? */
+ if (parse_jump(str + len, options, *activep) == -1) {
+ error("%.200s line %d: Invalid ProxyJump \"%s\"",
+ filename, linenum, str + len);
+ goto out;
}
- return 0;
+ argv_consume(&ac);
+ break;
case oPort:
- arg = strdelim(&s);
- if (!arg || *arg == '\0')
- fatal("%.200s line %d: Missing argument.",
+ arg = argv_next(&ac, &av);
+ if (!arg || *arg == '\0') {
+ error("%.200s line %d: Missing argument.",
filename, linenum);
+ goto out;
+ }
value = a2port(arg);
- if (value <= 0)
- fatal("%.200s line %d: Bad port '%s'.",
+ if (value <= 0) {
+ error("%.200s line %d: Bad port '%s'.",
filename, linenum, arg);
+ goto out;
+ }
if (*activep && options->port == -1)
options->port = value;
break;
@@ -1184,109 +1380,169 @@ parse_command:
case oConnectionAttempts:
intptr = &options->connection_attempts;
parse_int:
- arg = strdelim(&s);
- if ((errstr = atoi_err(arg, &value)) != NULL)
- fatal("%s line %d: integer value %s.",
+ arg = argv_next(&ac, &av);
+ if ((errstr = atoi_err(arg, &value)) != NULL) {
+ error("%s line %d: integer value %s.",
filename, linenum, errstr);
+ goto out;
+ }
if (*activep && *intptr == -1)
*intptr = value;
break;
case oCiphers:
- arg = strdelim(&s);
- if (!arg || *arg == '\0')
- fatal("%.200s line %d: Missing argument.", filename, linenum);
- if (*arg != '-' && !ciphers_valid(*arg == '+' ? arg + 1 : arg))
- fatal("%.200s line %d: Bad SSH2 cipher spec '%s'.",
+ arg = argv_next(&ac, &av);
+ if (!arg || *arg == '\0') {
+ error("%.200s line %d: Missing argument.",
+ filename, linenum);
+ goto out;
+ }
+ if (*arg != '-' &&
+ !ciphers_valid(*arg == '+' || *arg == '^' ? arg + 1 : arg)){
+ error("%.200s line %d: Bad SSH2 cipher spec '%s'.",
filename, linenum, arg ? arg : "<NONE>");
+ goto out;
+ }
if (*activep && options->ciphers == NULL)
options->ciphers = xstrdup(arg);
break;
case oMacs:
- arg = strdelim(&s);
- if (!arg || *arg == '\0')
- fatal("%.200s line %d: Missing argument.", filename, linenum);
- if (*arg != '-' && !mac_valid(*arg == '+' ? arg + 1 : arg))
- fatal("%.200s line %d: Bad SSH2 Mac spec '%s'.",
+ arg = argv_next(&ac, &av);
+ if (!arg || *arg == '\0') {
+ error("%.200s line %d: Missing argument.",
+ filename, linenum);
+ goto out;
+ }
+ if (*arg != '-' &&
+ !mac_valid(*arg == '+' || *arg == '^' ? arg + 1 : arg)) {
+ error("%.200s line %d: Bad SSH2 MAC spec '%s'.",
filename, linenum, arg ? arg : "<NONE>");
+ goto out;
+ }
if (*activep && options->macs == NULL)
options->macs = xstrdup(arg);
break;
case oKexAlgorithms:
- arg = strdelim(&s);
- if (!arg || *arg == '\0')
- fatal("%.200s line %d: Missing argument.",
+ arg = argv_next(&ac, &av);
+ if (!arg || *arg == '\0') {
+ error("%.200s line %d: Missing argument.",
filename, linenum);
+ goto out;
+ }
if (*arg != '-' &&
- !kex_names_valid(*arg == '+' ? arg + 1 : arg))
- fatal("%.200s line %d: Bad SSH2 KexAlgorithms '%s'.",
+ !kex_names_valid(*arg == '+' || *arg == '^' ?
+ arg + 1 : arg)) {
+ error("%.200s line %d: Bad SSH2 KexAlgorithms '%s'.",
filename, linenum, arg ? arg : "<NONE>");
+ goto out;
+ }
if (*activep && options->kex_algorithms == NULL)
options->kex_algorithms = xstrdup(arg);
break;
case oHostKeyAlgorithms:
charptr = &options->hostkeyalgorithms;
-parse_keytypes:
- arg = strdelim(&s);
- if (!arg || *arg == '\0')
- fatal("%.200s line %d: Missing argument.",
+parse_pubkey_algos:
+ arg = argv_next(&ac, &av);
+ if (!arg || *arg == '\0') {
+ error("%.200s line %d: Missing argument.",
filename, linenum);
+ goto out;
+ }
if (*arg != '-' &&
- !sshkey_names_valid2(*arg == '+' ? arg + 1 : arg, 1))
- fatal("%s line %d: Bad key types '%s'.",
- filename, linenum, arg ? arg : "<NONE>");
+ !sshkey_names_valid2(*arg == '+' || *arg == '^' ?
+ arg + 1 : arg, 1)) {
+ error("%s line %d: Bad key types '%s'.",
+ filename, linenum, arg ? arg : "<NONE>");
+ goto out;
+ }
if (*activep && *charptr == NULL)
*charptr = xstrdup(arg);
break;
case oCASignatureAlgorithms:
charptr = &options->ca_sign_algorithms;
- goto parse_keytypes;
+ goto parse_pubkey_algos;
case oLogLevel:
log_level_ptr = &options->log_level;
- arg = strdelim(&s);
+ arg = argv_next(&ac, &av);
value = log_level_number(arg);
- if (value == SYSLOG_LEVEL_NOT_SET)
- fatal("%.200s line %d: unsupported log level '%s'",
+ if (value == SYSLOG_LEVEL_NOT_SET) {
+ error("%.200s line %d: unsupported log level '%s'",
filename, linenum, arg ? arg : "<NONE>");
+ goto out;
+ }
if (*activep && *log_level_ptr == SYSLOG_LEVEL_NOT_SET)
*log_level_ptr = (LogLevel) value;
break;
case oLogFacility:
log_facility_ptr = &options->log_facility;
- arg = strdelim(&s);
+ arg = argv_next(&ac, &av);
value = log_facility_number(arg);
- if (value == SYSLOG_FACILITY_NOT_SET)
- fatal("%.200s line %d: unsupported log facility '%s'",
+ if (value == SYSLOG_FACILITY_NOT_SET) {
+ error("%.200s line %d: unsupported log facility '%s'",
filename, linenum, arg ? arg : "<NONE>");
+ goto out;
+ }
if (*log_facility_ptr == -1)
*log_facility_ptr = (SyslogFacility) value;
break;
+ case oLogVerbose:
+ cppptr = &options->log_verbose;
+ uintptr = &options->num_log_verbose;
+ i = 0;
+ while ((arg = argv_next(&ac, &av)) != NULL) {
+ if (*arg == '\0') {
+ error("%s line %d: keyword %s empty argument",
+ filename, linenum, keyword);
+ goto out;
+ }
+ /* Allow "none" only in first position */
+ if (strcasecmp(arg, "none") == 0) {
+ if (i > 0 || ac > 0) {
+ error("%s line %d: keyword %s \"none\" "
+ "argument must appear alone.",
+ filename, linenum, keyword);
+ goto out;
+ }
+ }
+ i++;
+ if (*activep && *uintptr == 0) {
+ *cppptr = xrecallocarray(*cppptr, *uintptr,
+ *uintptr + 1, sizeof(**cppptr));
+ (*cppptr)[(*uintptr)++] = xstrdup(arg);
+ }
+ }
+ break;
+
case oLocalForward:
case oRemoteForward:
case oDynamicForward:
- arg = strdelim(&s);
- if (arg == NULL || *arg == '\0')
- fatal("%.200s line %d: Missing port argument.",
+ arg = argv_next(&ac, &av);
+ if (!arg || *arg == '\0') {
+ error("%.200s line %d: Missing argument.",
filename, linenum);
+ goto out;
+ }
remotefwd = (opcode == oRemoteForward);
dynamicfwd = (opcode == oDynamicForward);
if (!dynamicfwd) {
- arg2 = strdelim(&s);
+ arg2 = argv_next(&ac, &av);
if (arg2 == NULL || *arg2 == '\0') {
if (remotefwd)
dynamicfwd = 1;
- else
- fatal("%.200s line %d: Missing target "
+ else {
+ error("%.200s line %d: Missing target "
"argument.", filename, linenum);
+ goto out;
+ }
} else {
/* construct a string for parse_forward */
snprintf(fwdarg, sizeof(fwdarg), "%s:%s", arg,
@@ -1296,9 +1552,11 @@ parse_keytypes:
if (dynamicfwd)
strlcpy(fwdarg, arg, sizeof(fwdarg));
- if (parse_forward(&fwd, fwdarg, dynamicfwd, remotefwd) == 0)
- fatal("%.200s line %d: Bad forwarding specification.",
+ if (parse_forward(&fwd, fwdarg, dynamicfwd, remotefwd) == 0) {
+ error("%.200s line %d: Bad forwarding specification.",
filename, linenum);
+ goto out;
+ }
if (*activep) {
if (remotefwd) {
@@ -1309,19 +1567,73 @@ parse_keytypes:
}
break;
+ case oPermitRemoteOpen:
+ uintptr = &options->num_permitted_remote_opens;
+ cppptr = &options->permitted_remote_opens;
+ arg = argv_next(&ac, &av);
+ if (!arg || *arg == '\0')
+ fatal("%s line %d: missing %s specification",
+ filename, linenum, lookup_opcode_name(opcode));
+ uvalue = *uintptr; /* modified later */
+ if (strcmp(arg, "any") == 0 || strcmp(arg, "none") == 0) {
+ if (*activep && uvalue == 0) {
+ *uintptr = 1;
+ *cppptr = xcalloc(1, sizeof(**cppptr));
+ (*cppptr)[0] = xstrdup(arg);
+ }
+ break;
+ }
+ while ((arg = argv_next(&ac, &av)) != NULL) {
+ arg2 = xstrdup(arg);
+ ch = '\0';
+ p = hpdelim2(&arg, &ch);
+ if (p == NULL || ch == '/') {
+ fatal("%s line %d: missing host in %s",
+ filename, linenum,
+ lookup_opcode_name(opcode));
+ }
+ p = cleanhostname(p);
+ /*
+ * don't want to use permitopen_port to avoid
+ * dependency on channels.[ch] here.
+ */
+ if (arg == NULL ||
+ (strcmp(arg, "*") != 0 && a2port(arg) <= 0)) {
+ fatal("%s line %d: bad port number in %s",
+ filename, linenum,
+ lookup_opcode_name(opcode));
+ }
+ if (*activep && uvalue == 0) {
+ opt_array_append(filename, linenum,
+ lookup_opcode_name(opcode),
+ cppptr, uintptr, arg2);
+ }
+ free(arg2);
+ }
+ break;
+
case oClearAllForwardings:
intptr = &options->clear_forwardings;
goto parse_flag;
case oHost:
- if (cmdline)
- fatal("Host directive not supported as a command-line "
+ if (cmdline) {
+ error("Host directive not supported as a command-line "
"option");
+ goto out;
+ }
*activep = 0;
arg2 = NULL;
- while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
- if ((flags & SSHCONF_NEVERMATCH) != 0)
+ while ((arg = argv_next(&ac, &av)) != NULL) {
+ if (*arg == '\0') {
+ error("%s line %d: keyword %s empty argument",
+ filename, linenum, keyword);
+ goto out;
+ }
+ if ((flags & SSHCONF_NEVERMATCH) != 0) {
+ argv_consume(&ac);
break;
+ }
negated = *arg == '!';
if (negated)
arg++;
@@ -1332,6 +1644,7 @@ parse_keytypes:
"for %.100s", filename, linenum,
arg);
*activep = 0;
+ argv_consume(&ac);
break;
}
if (!*activep)
@@ -1342,26 +1655,40 @@ parse_keytypes:
if (*activep)
debug("%.200s line %d: Applying options for %.100s",
filename, linenum, arg2);
- /* Avoid garbage check below, as strdelim is done. */
- return 0;
+ break;
case oMatch:
- if (cmdline)
- fatal("Host directive not supported as a command-line "
+ if (cmdline) {
+ error("Host directive not supported as a command-line "
"option");
- value = match_cfg_line(options, &s, pw, host, original_host,
- flags & SSHCONF_POSTCANON, filename, linenum);
- if (value < 0)
- fatal("%.200s line %d: Bad Match condition", filename,
+ goto out;
+ }
+ value = match_cfg_line(options, &str, pw, host, original_host,
+ flags & SSHCONF_FINAL, want_final_pass,
+ filename, linenum);
+ if (value < 0) {
+ error("%.200s line %d: Bad Match condition", filename,
linenum);
+ goto out;
+ }
*activep = (flags & SSHCONF_NEVERMATCH) ? 0 : value;
+ /*
+ * If match_cfg_line() didn't consume all its arguments then
+ * arrange for the extra arguments check below to fail.
+ */
+
+ if (str == NULL || *str == '\0')
+ argv_consume(&ac);
break;
case oEscapeChar:
intptr = &options->escape_char;
- arg = strdelim(&s);
- if (!arg || *arg == '\0')
- fatal("%.200s line %d: Missing argument.", filename, linenum);
+ arg = argv_next(&ac, &av);
+ if (!arg || *arg == '\0') {
+ error("%.200s line %d: Missing argument.",
+ filename, linenum);
+ goto out;
+ }
if (strcmp(arg, "none") == 0)
value = SSH_ESCAPECHAR_NONE;
else if (arg[1] == '\0')
@@ -1370,10 +1697,9 @@ parse_keytypes:
(u_char) arg[1] >= 64 && (u_char) arg[1] < 128)
value = (u_char) arg[1] & 31;
else {
- fatal("%.200s line %d: Bad escape character.",
+ error("%.200s line %d: Bad escape character.",
filename, linenum);
- /* NOTREACHED */
- value = 0; /* Avoid compiler warning. */
+ goto out;
}
if (*activep && *intptr == -1)
*intptr = value;
@@ -1401,10 +1727,12 @@ parse_keytypes:
goto parse_int;
case oSendEnv:
- while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
- if (strchr(arg, '=') != NULL)
- fatal("%s line %d: Invalid environment name.",
+ while ((arg = argv_next(&ac, &av)) != NULL) {
+ if (*arg == '\0' || strchr(arg, '=') != NULL) {
+ error("%s line %d: Invalid environment name.",
filename, linenum);
+ goto out;
+ }
if (!*activep)
continue;
if (*arg == '-') {
@@ -1413,9 +1741,11 @@ parse_keytypes:
continue;
} else {
/* Adding an env var */
- if (options->num_send_env >= INT_MAX)
- fatal("%s line %d: too many send env.",
+ if (options->num_send_env >= INT_MAX) {
+ error("%s line %d: too many send env.",
filename, linenum);
+ goto out;
+ }
options->send_env = xrecallocarray(
options->send_env, options->num_send_env,
options->num_send_env + 1,
@@ -1428,16 +1758,20 @@ parse_keytypes:
case oSetEnv:
value = options->num_setenv;
- while ((arg = strdelimw(&s)) != NULL && *arg != '\0') {
- if (strchr(arg, '=') == NULL)
- fatal("%s line %d: Invalid SetEnv.",
+ while ((arg = argv_next(&ac, &av)) != NULL) {
+ if (strchr(arg, '=') == NULL) {
+ error("%s line %d: Invalid SetEnv.",
filename, linenum);
+ goto out;
+ }
if (!*activep || value != 0)
continue;
/* Adding a setenv var */
- if (options->num_setenv >= INT_MAX)
- fatal("%s line %d: too many SetEnv.",
+ if (options->num_setenv >= INT_MAX) {
+ error("%s line %d: too many SetEnv.",
filename, linenum);
+ goto out;
+ }
options->setenv = xrecallocarray(
options->setenv, options->num_setenv,
options->num_setenv + 1, sizeof(*options->setenv));
@@ -1457,10 +1791,12 @@ parse_keytypes:
case oControlPersist:
/* no/false/yes/true, or a time spec */
intptr = &options->control_persist;
- arg = strdelim(&s);
- if (!arg || *arg == '\0')
- fatal("%.200s line %d: Missing ControlPersist"
+ arg = argv_next(&ac, &av);
+ if (!arg || *arg == '\0') {
+ error("%.200s line %d: Missing ControlPersist"
" argument.", filename, linenum);
+ goto out;
+ }
value = 0;
value2 = 0; /* timeout */
if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0)
@@ -1469,9 +1805,11 @@ parse_keytypes:
value = 1;
else if ((value2 = convtime(arg)) >= 0)
value = 1;
- else
- fatal("%.200s line %d: Bad ControlPersist argument.",
+ else {
+ error("%.200s line %d: Bad ControlPersist argument.",
filename, linenum);
+ goto out;
+ }
if (*activep && *intptr == -1) {
*intptr = value;
options->control_persist_timeout = value2;
@@ -1488,13 +1826,19 @@ parse_keytypes:
goto parse_multistate;
case oTunnelDevice:
- arg = strdelim(&s);
- if (!arg || *arg == '\0')
- fatal("%.200s line %d: Missing argument.", filename, linenum);
+ arg = argv_next(&ac, &av);
+ if (!arg || *arg == '\0') {
+ error("%.200s line %d: Missing argument.",
+ filename, linenum);
+ goto out;
+ }
value = a2tun(arg, &value2);
- if (value == SSH_TUNID_ERR)
- fatal("%.200s line %d: Bad tun device.", filename, linenum);
- if (*activep) {
+ if (value == SSH_TUNID_ERR) {
+ error("%.200s line %d: Bad tun device.",
+ filename, linenum);
+ goto out;
+ }
+ if (*activep && options->tun_local == -1) {
options->tun_local = value;
options->tun_remote = value2;
}
@@ -1517,11 +1861,18 @@ parse_keytypes:
goto parse_flag;
case oInclude:
- if (cmdline)
- fatal("Include directive not supported as a "
+ if (cmdline) {
+ error("Include directive not supported as a "
"command-line option");
+ goto out;
+ }
value = 0;
- while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
+ while ((arg = argv_next(&ac, &av)) != NULL) {
+ if (*arg == '\0') {
+ error("%s line %d: keyword %s empty argument",
+ filename, linenum, keyword);
+ goto out;
+ }
/*
* Ensure all paths are anchored. User configuration
* files may begin with '~/' but system configurations
@@ -1529,10 +1880,12 @@ parse_keytypes:
* as living in ~/.ssh for user configurations or
* /etc/ssh for system ones.
*/
- if (*arg == '~' && (flags & SSHCONF_USERCONF) == 0)
- fatal("%.200s line %d: bad include path %s.",
+ if (*arg == '~' && (flags & SSHCONF_USERCONF) == 0) {
+ error("%.200s line %d: bad include path %s.",
filename, linenum, arg);
- if (*arg != '/' && *arg != '~') {
+ goto out;
+ }
+ if (!path_absolute(arg) && *arg != '~') {
xasprintf(&arg2, "%s/%s",
(flags & SSHCONF_USERCONF) ?
"~/" _PATH_SSH_USER_DIR : SSHDIR, arg);
@@ -1545,12 +1898,14 @@ parse_keytypes:
"files",filename, linenum, arg2);
free(arg2);
continue;
- } else if (r != 0 || gl.gl_pathc < 0)
- fatal("%.200s line %d: glob failed for %s.",
+ } else if (r != 0) {
+ error("%.200s line %d: glob failed for %s.",
filename, linenum, arg2);
+ goto out;
+ }
free(arg2);
oactive = *activep;
- for (i = 0; i < (u_int)gl.gl_pathc; i++) {
+ for (i = 0; i < gl.gl_pathc; i++) {
debug3("%.200s line %d: Including file %s "
"depth %d%s", filename, linenum,
gl.gl_pathv[i], depth,
@@ -1559,11 +1914,13 @@ parse_keytypes:
pw, host, original_host, options,
flags | SSHCONF_CHECKPERM |
(oactive ? 0 : SSHCONF_NEVERMATCH),
- activep, depth + 1);
+ activep, want_final_pass, depth + 1);
if (r != 1 && errno != ENOENT) {
- fatal("Can't open user config file "
+ error("Can't open user config file "
"%.100s: %.100s", gl.gl_pathv[i],
strerror(errno));
+ globfree(&gl);
+ goto out;
}
/*
* don't let Match in includes clobber the
@@ -1576,21 +1933,25 @@ parse_keytypes:
globfree(&gl);
}
if (value != 0)
- return value;
+ ret = value;
break;
case oIPQoS:
- arg = strdelim(&s);
- if ((value = parse_ipqos(arg)) == -1)
- fatal("%s line %d: Bad IPQoS value: %s",
+ arg = argv_next(&ac, &av);
+ if ((value = parse_ipqos(arg)) == -1) {
+ error("%s line %d: Bad IPQoS value: %s",
filename, linenum, arg);
- arg = strdelim(&s);
+ goto out;
+ }
+ arg = argv_next(&ac, &av);
if (arg == NULL)
value2 = value;
- else if ((value2 = parse_ipqos(arg)) == -1)
- fatal("%s line %d: Bad IPQoS value: %s",
+ else if ((value2 = parse_ipqos(arg)) == -1) {
+ error("%s line %d: Bad IPQoS value: %s",
filename, linenum, arg);
- if (*activep) {
+ goto out;
+ }
+ if (*activep && options->ip_qos_interactive == -1) {
options->ip_qos_interactive = value;
options->ip_qos_bulk = value2;
}
@@ -1601,19 +1962,32 @@ parse_keytypes:
multistate_ptr = multistate_requesttty;
goto parse_multistate;
+ case oSessionType:
+ intptr = &options->session_type;
+ multistate_ptr = multistate_sessiontype;
+ goto parse_multistate;
+
+ case oStdinNull:
+ intptr = &options->stdin_null;
+ goto parse_flag;
+
+ case oForkAfterAuthentication:
+ intptr = &options->fork_after_authentication;
+ goto parse_flag;
+
case oVersionAddendum:
- if (s == NULL)
+ if (str == NULL)
fatal("%.200s line %d: Missing argument.", filename,
linenum);
- len = strspn(s, WHITESPACE);
+ len = strspn(str, WHITESPACE);
if (*activep && options->version_addendum == NULL) {
- if (strcasecmp(s + len, "none") == 0)
+ if (strcasecmp(str + len, "none") == 0)
options->version_addendum = xstrdup("");
- else if (strchr(s + len, '\r') != NULL)
+ else if (strchr(str + len, '\r') != NULL)
fatal("%.200s line %d: Invalid argument",
filename, linenum);
else
- options->version_addendum = xstrdup(s + len);
+ options->version_addendum = xstrdup(str + len);
}
return 0;
@@ -1627,16 +2001,36 @@ parse_keytypes:
case oCanonicalDomains:
value = options->num_canonical_domains != 0;
- while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
+ i = 0;
+ while ((arg = argv_next(&ac, &av)) != NULL) {
+ if (*arg == '\0') {
+ error("%s line %d: keyword %s empty argument",
+ filename, linenum, keyword);
+ goto out;
+ }
+ /* Allow "none" only in first position */
+ if (strcasecmp(arg, "none") == 0) {
+ if (i > 0 || ac > 0) {
+ error("%s line %d: keyword %s \"none\" "
+ "argument must appear alone.",
+ filename, linenum, keyword);
+ goto out;
+ }
+ }
+ i++;
if (!valid_domain(arg, 1, &errstr)) {
- fatal("%s line %d: %s", filename, linenum,
+ error("%s line %d: %s", filename, linenum,
errstr);
+ goto out;
}
if (!*activep || value)
continue;
- if (options->num_canonical_domains >= MAX_CANON_DOMAINS)
- fatal("%s line %d: too many hostname suffixes.",
+ if (options->num_canonical_domains >=
+ MAX_CANON_DOMAINS) {
+ error("%s line %d: too many hostname suffixes.",
filename, linenum);
+ goto out;
+ }
options->canonical_domains[
options->num_canonical_domains++] = xstrdup(arg);
}
@@ -1644,7 +2038,7 @@ parse_keytypes:
case oCanonicalizePermittedCNAMEs:
value = options->num_permitted_cnames != 0;
- while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
+ while ((arg = argv_next(&ac, &av)) != NULL) {
/* Either '*' for everything or 'list:list' */
if (strcmp(arg, "*") == 0)
arg2 = arg;
@@ -1652,18 +2046,22 @@ parse_keytypes:
lowercase(arg);
if ((arg2 = strchr(arg, ':')) == NULL ||
arg2[1] == '\0') {
- fatal("%s line %d: "
+ error("%s line %d: "
"Invalid permitted CNAME \"%s\"",
filename, linenum, arg);
+ goto out;
}
*arg2 = '\0';
arg2++;
}
if (!*activep || value)
continue;
- if (options->num_permitted_cnames >= MAX_CANON_DOMAINS)
- fatal("%s line %d: too many permitted CNAMEs.",
+ if (options->num_permitted_cnames >=
+ MAX_CANON_DOMAINS) {
+ error("%s line %d: too many permitted CNAMEs.",
filename, linenum);
+ goto out;
+ }
cname = options->permitted_cnames +
options->num_permitted_cnames++;
cname->source_list = xstrdup(arg);
@@ -1685,13 +2083,18 @@ parse_keytypes:
goto parse_flag;
case oStreamLocalBindMask:
- arg = strdelim(&s);
- if (!arg || *arg == '\0')
- fatal("%.200s line %d: Missing StreamLocalBindMask argument.", filename, linenum);
+ arg = argv_next(&ac, &av);
+ if (!arg || *arg == '\0') {
+ error("%.200s line %d: Missing StreamLocalBindMask "
+ "argument.", filename, linenum);
+ goto out;
+ }
/* Parse mode in octal format */
value = strtol(arg, &endofnumber, 8);
- if (arg == endofnumber || value < 0 || value > 0777)
- fatal("%.200s line %d: Bad mask.", filename, linenum);
+ if (arg == endofnumber || value < 0 || value > 0777) {
+ error("%.200s line %d: Bad mask.", filename, linenum);
+ goto out;
+ }
options->fwd_opts.streamlocal_bind_mask = (mode_t)value;
break;
@@ -1705,13 +2108,17 @@ parse_keytypes:
case oFingerprintHash:
intptr = &options->fingerprint_hash;
- arg = strdelim(&s);
- if (!arg || *arg == '\0')
- fatal("%.200s line %d: Missing argument.",
+ arg = argv_next(&ac, &av);
+ if (!arg || *arg == '\0') {
+ error("%.200s line %d: Missing argument.",
filename, linenum);
- if ((value = ssh_digest_alg_by_name(arg)) == -1)
- fatal("%.200s line %d: Invalid hash algorithm \"%s\".",
+ goto out;
+ }
+ if ((value = ssh_digest_alg_by_name(arg)) == -1) {
+ error("%.200s line %d: Invalid hash algorithm \"%s\".",
filename, linenum, arg);
+ goto out;
+ }
if (*activep && *intptr == -1)
*intptr = value;
break;
@@ -1721,29 +2128,69 @@ parse_keytypes:
multistate_ptr = multistate_yesnoask;
goto parse_multistate;
- case oHostbasedKeyTypes:
- charptr = &options->hostbased_key_types;
- goto parse_keytypes;
+ case oHostbasedAcceptedAlgorithms:
+ charptr = &options->hostbased_accepted_algos;
+ goto parse_pubkey_algos;
- case oPubkeyAcceptedKeyTypes:
- charptr = &options->pubkey_key_types;
- goto parse_keytypes;
+ case oPubkeyAcceptedAlgorithms:
+ charptr = &options->pubkey_accepted_algos;
+ goto parse_pubkey_algos;
case oAddKeysToAgent:
- intptr = &options->add_keys_to_agent;
- multistate_ptr = multistate_yesnoaskconfirm;
- goto parse_multistate;
+ arg = argv_next(&ac, &av);
+ arg2 = argv_next(&ac, &av);
+ value = parse_multistate_value(arg, filename, linenum,
+ multistate_yesnoaskconfirm);
+ value2 = 0; /* unlimited lifespan by default */
+ if (value == 3 && arg2 != NULL) {
+ /* allow "AddKeysToAgent confirm 5m" */
+ if ((value2 = convtime(arg2)) == -1 ||
+ value2 > INT_MAX) {
+ error("%s line %d: invalid time value.",
+ filename, linenum);
+ goto out;
+ }
+ } else if (value == -1 && arg2 == NULL) {
+ if ((value2 = convtime(arg)) == -1 ||
+ value2 > INT_MAX) {
+ error("%s line %d: unsupported option",
+ filename, linenum);
+ goto out;
+ }
+ value = 1; /* yes */
+ } else if (value == -1 || arg2 != NULL) {
+ error("%s line %d: unsupported option",
+ filename, linenum);
+ goto out;
+ }
+ if (*activep && options->add_keys_to_agent == -1) {
+ options->add_keys_to_agent = value;
+ options->add_keys_to_agent_lifespan = value2;
+ }
+ break;
case oIdentityAgent:
charptr = &options->identity_agent;
- arg = strdelim(&s);
- if (!arg || *arg == '\0')
- fatal("%.200s line %d: Missing argument.",
+ arg = argv_next(&ac, &av);
+ if (!arg || *arg == '\0') {
+ error("%.200s line %d: Missing argument.",
filename, linenum);
+ goto out;
+ }
+ parse_agent_path:
/* Extra validation if the string represents an env var. */
- if (arg[0] == '$' && !valid_env_name(arg + 1)) {
- fatal("%.200s line %d: Invalid environment name %s.",
+ if ((arg2 = dollar_expand(&r, arg)) == NULL || r) {
+ error("%.200s line %d: Invalid environment expansion "
+ "%s.", filename, linenum, arg);
+ goto out;
+ }
+ free(arg2);
+ /* check for legacy environment format */
+ if (arg[0] == '$' && arg[1] != '{' &&
+ !valid_env_name(arg + 1)) {
+ error("%.200s line %d: Invalid environment name %s.",
filename, linenum, arg);
+ goto out;
}
if (*activep && *charptr == NULL)
*charptr = xstrdup(arg);
@@ -1752,23 +2199,33 @@ parse_keytypes:
case oDeprecated:
debug("%s line %d: Deprecated option \"%s\"",
filename, linenum, keyword);
- return 0;
+ argv_consume(&ac);
+ break;
case oUnsupported:
error("%s line %d: Unsupported option \"%s\"",
filename, linenum, keyword);
- return 0;
+ argv_consume(&ac);
+ break;
default:
- fatal("%s: Unimplemented opcode %d", __func__, opcode);
+ error("%s line %d: Unimplemented opcode %d",
+ filename, linenum, opcode);
+ goto out;
}
/* Check that there is no garbage at end of line. */
- if ((arg = strdelim(&s)) != NULL && *arg != '\0') {
- fatal("%.200s line %d: garbage at end of line; \"%.200s\".",
- filename, linenum, arg);
+ if (ac > 0) {
+ error("%.200s line %d: keyword %s extra arguments "
+ "at end of line", filename, linenum, keyword);
+ goto out;
}
- return 0;
+
+ /* success */
+ ret = 0;
+ out:
+ argv_free(oav, oac);
+ return ret;
}
/*
@@ -1778,19 +2235,20 @@ parse_keytypes:
*/
int
read_config_file(const char *filename, struct passwd *pw, const char *host,
- const char *original_host, Options *options, int flags)
+ const char *original_host, Options *options, int flags,
+ int *want_final_pass)
{
int active = 1;
return read_config_file_depth(filename, pw, host, original_host,
- options, flags, &active, 0);
+ options, flags, &active, want_final_pass, 0);
}
#define READCONF_MAX_DEPTH 16
static int
read_config_file_depth(const char *filename, struct passwd *pw,
const char *host, const char *original_host, Options *options,
- int flags, int *activep, int depth)
+ int flags, int *activep, int *want_final_pass, int depth)
{
FILE *f;
char *line = NULL;
@@ -1824,8 +2282,14 @@ read_config_file_depth(const char *filename, struct passwd *pw,
while (getline(&line, &linesize, f) != -1) {
/* Update line number counter. */
linenum++;
+ /*
+ * Trim out comments and strip whitespace.
+ * NB - preserve newlines, they are needed to reproduce
+ * line numbers later for error messages.
+ */
if (process_config_line_depth(options, pw, host, original_host,
- line, filename, linenum, activep, flags, depth) != 0)
+ line, filename, linenum, activep, flags, want_final_pass,
+ depth) != 0)
bad_options++;
}
free(line);
@@ -1856,6 +2320,7 @@ initialize_options(Options * options)
memset(options, 'X', sizeof(*options));
options->version_addendum = NULL;
options->forward_agent = -1;
+ options->forward_agent_sock_path = NULL;
options->forward_x11 = -1;
options->forward_x11_trusted = -1;
options->forward_x11_timeout = -1;
@@ -1868,7 +2333,6 @@ initialize_options(Options * options)
options->fwd_opts.streamlocal_bind_mask = (mode_t)-1;
options->fwd_opts.streamlocal_bind_unlink = -1;
options->pubkey_authentication = -1;
- options->challenge_response_authentication = -1;
options->gss_authentication = -1;
options->gss_deleg_creds = -1;
options->password_authentication = -1;
@@ -1891,7 +2355,9 @@ initialize_options(Options * options)
options->hostkeyalgorithms = NULL;
options->ca_sign_algorithms = NULL;
options->num_identity_files = 0;
+ memset(options->identity_keys, 0, sizeof(options->identity_keys));
options->num_certificate_files = 0;
+ memset(options->certificates, 0, sizeof(options->certificates));
options->hostname = NULL;
options->host_key_alias = NULL;
options->proxy_command = NULL;
@@ -1907,12 +2373,17 @@ initialize_options(Options * options)
options->num_local_forwards = 0;
options->remote_forwards = NULL;
options->num_remote_forwards = 0;
+ options->permitted_remote_opens = NULL;
+ options->num_permitted_remote_opens = 0;
options->log_facility = SYSLOG_FACILITY_NOT_SET;
options->log_level = SYSLOG_LEVEL_NOT_SET;
+ options->num_log_verbose = 0;
+ options->log_verbose = NULL;
options->preferred_authentications = NULL;
options->bind_address = NULL;
options->bind_interface = NULL;
options->pkcs11_provider = NULL;
+ options->sk_provider = NULL;
options->enable_ssh_keysign = - 1;
options->no_host_authentication_for_localhost = - 1;
options->identities_only = - 1;
@@ -1937,11 +2408,15 @@ initialize_options(Options * options)
options->permit_local_command = -1;
options->remote_command = NULL;
options->add_keys_to_agent = -1;
+ options->add_keys_to_agent_lifespan = -1;
options->identity_agent = NULL;
options->visual_host_key = -1;
options->ip_qos_interactive = -1;
options->ip_qos_bulk = -1;
options->request_tty = -1;
+ options->session_type = -1;
+ options->stdin_null = -1;
+ options->fork_after_authentication = -1;
options->proxy_use_fdpass = -1;
options->ignored_unknown = NULL;
options->num_canonical_domains = 0;
@@ -1952,8 +2427,9 @@ initialize_options(Options * options)
options->revoked_host_keys = NULL;
options->fingerprint_hash = -1;
options->update_hostkeys = -1;
- options->hostbased_key_types = NULL;
- options->pubkey_key_types = NULL;
+ options->hostbased_accepted_algos = NULL;
+ options->pubkey_accepted_algos = NULL;
+ options->known_hosts_command = NULL;
}
/*
@@ -1975,11 +2451,12 @@ fill_default_options_for_canonicalization(Options *options)
* Called after processing other sources of option data, this fills those
* options for which no value has been specified with their default values.
*/
-void
+int
fill_default_options(Options * options)
{
char *all_cipher, *all_mac, *all_kex, *all_key, *all_sig;
- int r;
+ char *def_cipher, *def_mac, *def_kex, *def_key, *def_sig;
+ int ret = 0, r;
if (options->forward_agent == -1)
options->forward_agent = 0;
@@ -2003,7 +2480,7 @@ fill_default_options(Options * options)
clear_forwardings(options);
if (options->xauth_location == NULL)
- options->xauth_location = _PATH_XAUTH;
+ options->xauth_location = xstrdup(_PATH_XAUTH);
if (options->fwd_opts.gateway_ports == -1)
options->fwd_opts.gateway_ports = 0;
if (options->fwd_opts.streamlocal_bind_mask == (mode_t)-1)
@@ -2012,8 +2489,6 @@ fill_default_options(Options * options)
options->fwd_opts.streamlocal_bind_unlink = 0;
if (options->pubkey_authentication == -1)
options->pubkey_authentication = 1;
- if (options->challenge_response_authentication == -1)
- options->challenge_response_authentication = 1;
if (options->gss_authentication == -1)
options->gss_authentication = 0;
if (options->gss_deleg_creds == -1)
@@ -2043,16 +2518,22 @@ fill_default_options(Options * options)
if (options->number_of_password_prompts == -1)
options->number_of_password_prompts = 3;
/* options->hostkeyalgorithms, default set in myproposals.h */
- if (options->add_keys_to_agent == -1)
+ if (options->add_keys_to_agent == -1) {
options->add_keys_to_agent = 0;
+ options->add_keys_to_agent_lifespan = 0;
+ }
if (options->num_identity_files == 0) {
add_identity_file(options, "~/", _PATH_SSH_CLIENT_ID_RSA, 0);
add_identity_file(options, "~/", _PATH_SSH_CLIENT_ID_DSA, 0);
#ifdef OPENSSL_HAS_ECC
add_identity_file(options, "~/", _PATH_SSH_CLIENT_ID_ECDSA, 0);
+ add_identity_file(options, "~/",
+ _PATH_SSH_CLIENT_ID_ECDSA_SK, 0);
#endif
add_identity_file(options, "~/",
_PATH_SSH_CLIENT_ID_ED25519, 0);
+ add_identity_file(options, "~/",
+ _PATH_SSH_CLIENT_ID_ED25519_SK, 0);
add_identity_file(options, "~/", _PATH_SSH_CLIENT_ID_XMSS, 0);
}
if (options->escape_char == -1)
@@ -2063,6 +2544,15 @@ fill_default_options(Options * options)
options->system_hostfiles[options->num_system_hostfiles++] =
xstrdup(_PATH_SSH_SYSTEM_HOSTFILE2);
}
+ if (options->update_hostkeys == -1) {
+ if (options->verify_host_key_dns <= 0 &&
+ (options->num_user_hostfiles == 0 ||
+ (options->num_user_hostfiles == 1 && strcmp(options->
+ user_hostfiles[0], _PATH_SSH_USER_HOSTFILE) == 0)))
+ options->update_hostkeys = SSH_UPDATE_HOSTKEYS_YES;
+ else
+ options->update_hostkeys = SSH_UPDATE_HOSTKEYS_NO;
+ }
if (options->num_user_hostfiles == 0) {
options->user_hostfiles[options->num_user_hostfiles++] =
xstrdup(_PATH_SSH_USER_HOSTFILE);
@@ -2119,6 +2609,12 @@ fill_default_options(Options * options)
options->ip_qos_bulk = IPTOS_DSCP_CS1;
if (options->request_tty == -1)
options->request_tty = REQUEST_TTY_AUTO;
+ if (options->session_type == -1)
+ options->session_type = SESSION_TYPE_DEFAULT;
+ if (options->stdin_null == -1)
+ options->stdin_null = 0;
+ if (options->fork_after_authentication == -1)
+ options->fork_after_authentication = 0;
if (options->proxy_use_fdpass == -1)
options->proxy_use_fdpass = 0;
if (options->canonicalize_max_dots == -1)
@@ -2129,8 +2625,13 @@ fill_default_options(Options * options)
options->canonicalize_hostname = SSH_CANONICALISE_NO;
if (options->fingerprint_hash == -1)
options->fingerprint_hash = SSH_FP_HASH_DEFAULT;
- if (options->update_hostkeys == -1)
- options->update_hostkeys = 0;
+#ifdef ENABLE_SK_INTERNAL
+ if (options->sk_provider == NULL)
+ options->sk_provider = xstrdup("internal");
+#else
+ if (options->sk_provider == NULL)
+ options->sk_provider = xstrdup("$SSH_SK_PROVIDER");
+#endif
/* Expand KEX name lists */
all_cipher = cipher_alg_list(',', 0);
@@ -2138,24 +2639,27 @@ fill_default_options(Options * options)
all_kex = kex_alg_list(',');
all_key = sshkey_alg_list(0, 0, 1, ',');
all_sig = sshkey_alg_list(0, 1, 1, ',');
+ /* remove unsupported algos from default lists */
+ def_cipher = match_filter_allowlist(KEX_CLIENT_ENCRYPT, all_cipher);
+ def_mac = match_filter_allowlist(KEX_CLIENT_MAC, all_mac);
+ def_kex = match_filter_allowlist(KEX_CLIENT_KEX, all_kex);
+ def_key = match_filter_allowlist(KEX_DEFAULT_PK_ALG, all_key);
+ def_sig = match_filter_allowlist(SSH_ALLOWED_CA_SIGALGS, all_sig);
#define ASSEMBLE(what, defaults, all) \
do { \
if ((r = kex_assemble_names(&options->what, \
- defaults, all)) != 0) \
- fatal("%s: %s: %s", __func__, #what, ssh_err(r)); \
+ defaults, all)) != 0) { \
+ error_fr(r, "%s", #what); \
+ goto fail; \
+ } \
} while (0)
- ASSEMBLE(ciphers, KEX_SERVER_ENCRYPT, all_cipher);
- ASSEMBLE(macs, KEX_SERVER_MAC, all_mac);
- ASSEMBLE(kex_algorithms, KEX_SERVER_KEX, all_kex);
- ASSEMBLE(hostbased_key_types, KEX_DEFAULT_PK_ALG, all_key);
- ASSEMBLE(pubkey_key_types, KEX_DEFAULT_PK_ALG, all_key);
- ASSEMBLE(ca_sign_algorithms, SSH_ALLOWED_CA_SIGALGS, all_sig);
+ ASSEMBLE(ciphers, def_cipher, all_cipher);
+ ASSEMBLE(macs, def_mac, all_mac);
+ ASSEMBLE(kex_algorithms, def_kex, all_kex);
+ ASSEMBLE(hostbased_accepted_algos, def_key, all_key);
+ ASSEMBLE(pubkey_accepted_algos, def_key, all_key);
+ ASSEMBLE(ca_sign_algorithms, def_sig, all_sig);
#undef ASSEMBLE
- free(all_cipher);
- free(all_mac);
- free(all_kex);
- free(all_key);
- free(all_sig);
#define CLEAR_ON_NONE(v) \
do { \
@@ -2169,6 +2673,9 @@ fill_default_options(Options * options)
CLEAR_ON_NONE(options->proxy_command);
CLEAR_ON_NONE(options->control_path);
CLEAR_ON_NONE(options->revoked_host_keys);
+ CLEAR_ON_NONE(options->pkcs11_provider);
+ CLEAR_ON_NONE(options->sk_provider);
+ CLEAR_ON_NONE(options->known_hosts_command);
if (options->jump_host != NULL &&
strcmp(options->jump_host, "none") == 0 &&
options->jump_port == 0 && options->jump_user == NULL) {
@@ -2182,6 +2689,103 @@ fill_default_options(Options * options)
/* options->preferred_authentications will be set in ssh */
if (options->version_addendum == NULL)
options->version_addendum = xstrdup(SSH_VERSION_FREEBSD);
+
+ /* success */
+ ret = 0;
+ fail:
+ free(all_cipher);
+ free(all_mac);
+ free(all_kex);
+ free(all_key);
+ free(all_sig);
+ free(def_cipher);
+ free(def_mac);
+ free(def_kex);
+ free(def_key);
+ free(def_sig);
+ return ret;
+}
+
+void
+free_options(Options *o)
+{
+ int i;
+
+ if (o == NULL)
+ return;
+
+#define FREE_ARRAY(type, n, a) \
+ do { \
+ type _i; \
+ for (_i = 0; _i < (n); _i++) \
+ free((a)[_i]); \
+ } while (0)
+
+ free(o->forward_agent_sock_path);
+ free(o->xauth_location);
+ FREE_ARRAY(u_int, o->num_log_verbose, o->log_verbose);
+ free(o->log_verbose);
+ free(o->ciphers);
+ free(o->macs);
+ free(o->hostkeyalgorithms);
+ free(o->kex_algorithms);
+ free(o->ca_sign_algorithms);
+ free(o->hostname);
+ free(o->host_key_alias);
+ free(o->proxy_command);
+ free(o->user);
+ FREE_ARRAY(u_int, o->num_system_hostfiles, o->system_hostfiles);
+ FREE_ARRAY(u_int, o->num_user_hostfiles, o->user_hostfiles);
+ free(o->preferred_authentications);
+ free(o->bind_address);
+ free(o->bind_interface);
+ free(o->pkcs11_provider);
+ free(o->sk_provider);
+ for (i = 0; i < o->num_identity_files; i++) {
+ free(o->identity_files[i]);
+ sshkey_free(o->identity_keys[i]);
+ }
+ for (i = 0; i < o->num_certificate_files; i++) {
+ free(o->certificate_files[i]);
+ sshkey_free(o->certificates[i]);
+ }
+ free(o->identity_agent);
+ for (i = 0; i < o->num_local_forwards; i++) {
+ free(o->local_forwards[i].listen_host);
+ free(o->local_forwards[i].listen_path);
+ free(o->local_forwards[i].connect_host);
+ free(o->local_forwards[i].connect_path);
+ }
+ free(o->local_forwards);
+ for (i = 0; i < o->num_remote_forwards; i++) {
+ free(o->remote_forwards[i].listen_host);
+ free(o->remote_forwards[i].listen_path);
+ free(o->remote_forwards[i].connect_host);
+ free(o->remote_forwards[i].connect_path);
+ }
+ free(o->remote_forwards);
+ free(o->stdio_forward_host);
+ FREE_ARRAY(int, o->num_send_env, o->send_env);
+ free(o->send_env);
+ FREE_ARRAY(int, o->num_setenv, o->setenv);
+ free(o->setenv);
+ free(o->control_path);
+ free(o->local_command);
+ free(o->remote_command);
+ FREE_ARRAY(int, o->num_canonical_domains, o->canonical_domains);
+ for (i = 0; i < o->num_permitted_cnames; i++) {
+ free(o->permitted_cnames[i].source_list);
+ free(o->permitted_cnames[i].target_list);
+ }
+ free(o->revoked_host_keys);
+ free(o->hostbased_accepted_algos);
+ free(o->pubkey_accepted_algos);
+ free(o->jump_user);
+ free(o->jump_host);
+ free(o->jump_extra);
+ free(o->ignored_unknown);
+ explicit_bzero(o, sizeof(*o));
+#undef FREE_ARRAY
}
struct fwdarg {
@@ -2267,12 +2871,19 @@ parse_forward(struct Forward *fwd, const char *fwdspec, int dynamicfwd, int remo
{
struct fwdarg fwdargs[4];
char *p, *cp;
- int i;
+ int i, err;
memset(fwd, 0, sizeof(*fwd));
memset(fwdargs, 0, sizeof(fwdargs));
- cp = p = xstrdup(fwdspec);
+ /*
+ * We expand environment variables before checking if we think they're
+ * paths so that if ${VAR} expands to a fully qualified path it is
+ * treated as a path.
+ */
+ cp = p = dollar_expand(&err, fwdspec);
+ if (p == NULL || err)
+ return 0;
/* skip leading spaces */
while (isspace((u_char)*cp))
@@ -2368,7 +2979,10 @@ parse_forward(struct Forward *fwd, const char *fwdspec, int dynamicfwd, int remo
if (fwd->connect_host != NULL &&
strlen(fwd->connect_host) >= NI_MAXHOST)
goto fail_free;
- /* XXX - if connecting to a remote socket, max sun len may not match this host */
+ /*
+ * XXX - if connecting to a remote socket, max sun len may not
+ * match this host
+ */
if (fwd->connect_path != NULL &&
strlen(fwd->connect_path) >= PATH_MAX_SUN)
goto fail_free;
@@ -2398,11 +3012,17 @@ parse_jump(const char *s, Options *o, int active)
{
char *orig, *sdup, *cp;
char *host = NULL, *user = NULL;
- int ret = -1, port = -1, first;
+ int r, ret = -1, port = -1, first;
active &= o->proxy_command == NULL && o->jump_host == NULL;
orig = sdup = xstrdup(s);
+
+ /* Remove comment and trailing whitespace */
+ if ((cp = strchr(orig, '#')) != NULL)
+ *cp = '\0';
+ rtrim(orig);
+
first = active;
do {
if (strcasecmp(s, "none") == 0)
@@ -2414,13 +3034,15 @@ parse_jump(const char *s, Options *o, int active)
if (first) {
/* First argument and configuration is active */
- if (parse_ssh_uri(cp, &user, &host, &port) == -1 ||
- parse_user_host_port(cp, &user, &host, &port) != 0)
+ r = parse_ssh_uri(cp, &user, &host, &port);
+ if (r == -1 || (r == 1 &&
+ parse_user_host_port(cp, &user, &host, &port) != 0))
goto out;
} else {
/* Subsequent argument or inactive configuration */
- if (parse_ssh_uri(cp, NULL, NULL, NULL) == -1 ||
- parse_user_host_port(cp, NULL, NULL, NULL) != 0)
+ r = parse_ssh_uri(cp, NULL, NULL, NULL);
+ if (r == -1 || (r == 1 &&
+ parse_user_host_port(cp, NULL, NULL, NULL) != 0))
goto out;
}
first = 0; /* only check syntax for subsequent hosts */
@@ -2453,12 +3075,27 @@ parse_jump(const char *s, Options *o, int active)
int
parse_ssh_uri(const char *uri, char **userp, char **hostp, int *portp)
{
- char *path;
- int r;
+ char *user = NULL, *host = NULL, *path = NULL;
+ int r, port;
- r = parse_uri("ssh", uri, userp, hostp, portp, &path);
+ r = parse_uri("ssh", uri, &user, &host, &port, &path);
if (r == 0 && path != NULL)
r = -1; /* path not allowed */
+ if (r == 0) {
+ if (userp != NULL) {
+ *userp = user;
+ user = NULL;
+ }
+ if (hostp != NULL) {
+ *hostp = host;
+ host = NULL;
+ }
+ if (portp != NULL)
+ *portp = port;
+ }
+ free(user);
+ free(host);
+ free(path);
return r;
}
@@ -2494,6 +3131,8 @@ fmt_intarg(OpCodes code, int val)
return fmt_multistate_int(val, multistate_tunnel);
case oRequestTTY:
return fmt_multistate_int(val, multistate_requesttty);
+ case oSessionType:
+ return fmt_multistate_int(val, multistate_sessiontype);
case oCanonicalizeHostname:
return fmt_multistate_int(val, multistate_canonicalizehostname);
case oAddKeysToAgent:
@@ -2558,6 +3197,8 @@ dump_cfg_strarray_oneline(OpCodes code, u_int count, char **vals)
u_int i;
printf("%s", lookup_opcode_name(code));
+ if (count == 0)
+ printf(" none");
for (i = 0; i < count; i++)
printf(" %s", vals[i]);
printf("\n");
@@ -2604,28 +3245,31 @@ dump_cfg_forwards(OpCodes code, u_int count, const struct Forward *fwds)
void
dump_client_config(Options *o, const char *host)
{
- int i;
+ int i, r;
char buf[8], *all_key;
- /* This is normally prepared in ssh_kex2 */
+ /*
+ * Expand HostKeyAlgorithms name lists. This isn't handled in
+ * fill_default_options() like the other algorithm lists because
+ * the host key algorithms are by default dynamically chosen based
+ * on the host's keys found in known_hosts.
+ */
all_key = sshkey_alg_list(0, 0, 1, ',');
- if (kex_assemble_names( &o->hostkeyalgorithms,
- KEX_DEFAULT_PK_ALG, all_key) != 0)
- fatal("%s: kex_assemble_names failed", __func__);
+ if ((r = kex_assemble_names(&o->hostkeyalgorithms, kex_default_pk_alg(),
+ all_key)) != 0)
+ fatal_fr(r, "expand HostKeyAlgorithms");
free(all_key);
/* Most interesting options first: user, host, port */
dump_cfg_string(oUser, o->user);
- dump_cfg_string(oHostName, host);
+ dump_cfg_string(oHostname, host);
dump_cfg_int(oPort, o->port);
/* Flag options */
- dump_cfg_fmtint(oAddKeysToAgent, o->add_keys_to_agent);
dump_cfg_fmtint(oAddressFamily, o->address_family);
dump_cfg_fmtint(oBatchMode, o->batch_mode);
dump_cfg_fmtint(oCanonicalizeFallbackLocal, o->canonicalize_fallback_local);
dump_cfg_fmtint(oCanonicalizeHostname, o->canonicalize_hostname);
- dump_cfg_fmtint(oChallengeResponseAuthentication, o->challenge_response_authentication);
dump_cfg_fmtint(oCheckHostIP, o->check_host_ip);
dump_cfg_fmtint(oCompression, o->compression);
dump_cfg_fmtint(oControlMaster, o->control_master);
@@ -2633,7 +3277,6 @@ dump_client_config(Options *o, const char *host)
dump_cfg_fmtint(oClearAllForwardings, o->clear_forwardings);
dump_cfg_fmtint(oExitOnForwardFailure, o->exit_on_forward_failure);
dump_cfg_fmtint(oFingerprintHash, o->fingerprint_hash);
- dump_cfg_fmtint(oForwardAgent, o->forward_agent);
dump_cfg_fmtint(oForwardX11, o->forward_x11);
dump_cfg_fmtint(oForwardX11Trusted, o->forward_x11_trusted);
dump_cfg_fmtint(oGatewayPorts, o->fwd_opts.gateway_ports);
@@ -2651,6 +3294,9 @@ dump_client_config(Options *o, const char *host)
dump_cfg_fmtint(oProxyUseFdpass, o->proxy_use_fdpass);
dump_cfg_fmtint(oPubkeyAuthentication, o->pubkey_authentication);
dump_cfg_fmtint(oRequestTTY, o->request_tty);
+ dump_cfg_fmtint(oSessionType, o->session_type);
+ dump_cfg_fmtint(oStdinNull, o->stdin_null);
+ dump_cfg_fmtint(oForkAfterAuthentication, o->fork_after_authentication);
dump_cfg_fmtint(oStreamLocalBindUnlink, o->fwd_opts.streamlocal_bind_unlink);
dump_cfg_fmtint(oStrictHostKeyChecking, o->strict_host_key_checking);
dump_cfg_fmtint(oTCPKeepAlive, o->tcp_keep_alive);
@@ -2670,27 +3316,29 @@ dump_client_config(Options *o, const char *host)
/* String options */
dump_cfg_string(oBindAddress, o->bind_address);
dump_cfg_string(oBindInterface, o->bind_interface);
- dump_cfg_string(oCiphers, o->ciphers ? o->ciphers : KEX_CLIENT_ENCRYPT);
+ dump_cfg_string(oCiphers, o->ciphers);
dump_cfg_string(oControlPath, o->control_path);
dump_cfg_string(oHostKeyAlgorithms, o->hostkeyalgorithms);
dump_cfg_string(oHostKeyAlias, o->host_key_alias);
- dump_cfg_string(oHostbasedKeyTypes, o->hostbased_key_types);
+ dump_cfg_string(oHostbasedAcceptedAlgorithms, o->hostbased_accepted_algos);
dump_cfg_string(oIdentityAgent, o->identity_agent);
dump_cfg_string(oIgnoreUnknown, o->ignored_unknown);
dump_cfg_string(oKbdInteractiveDevices, o->kbd_interactive_devices);
- dump_cfg_string(oKexAlgorithms, o->kex_algorithms ? o->kex_algorithms : KEX_CLIENT_KEX);
- dump_cfg_string(oCASignatureAlgorithms, o->ca_sign_algorithms ? o->ca_sign_algorithms : SSH_ALLOWED_CA_SIGALGS);
+ dump_cfg_string(oKexAlgorithms, o->kex_algorithms);
+ dump_cfg_string(oCASignatureAlgorithms, o->ca_sign_algorithms);
dump_cfg_string(oLocalCommand, o->local_command);
dump_cfg_string(oRemoteCommand, o->remote_command);
dump_cfg_string(oLogLevel, log_level_name(o->log_level));
- dump_cfg_string(oMacs, o->macs ? o->macs : KEX_CLIENT_MAC);
+ dump_cfg_string(oMacs, o->macs);
#ifdef ENABLE_PKCS11
dump_cfg_string(oPKCS11Provider, o->pkcs11_provider);
#endif
+ dump_cfg_string(oSecurityKeyProvider, o->sk_provider);
dump_cfg_string(oPreferredAuthentications, o->preferred_authentications);
- dump_cfg_string(oPubkeyAcceptedKeyTypes, o->pubkey_key_types);
+ dump_cfg_string(oPubkeyAcceptedAlgorithms, o->pubkey_accepted_algos);
dump_cfg_string(oRevokedHostKeys, o->revoked_host_keys);
dump_cfg_string(oXAuthLocation, o->xauth_location);
+ dump_cfg_string(oKnownHostsCommand, o->known_hosts_command);
/* Forwards */
dump_cfg_forwards(oDynamicForward, o->num_local_forwards, o->local_forwards);
@@ -2705,9 +3353,33 @@ dump_client_config(Options *o, const char *host)
dump_cfg_strarray_oneline(oUserKnownHostsFile, o->num_user_hostfiles, o->user_hostfiles);
dump_cfg_strarray(oSendEnv, o->num_send_env, o->send_env);
dump_cfg_strarray(oSetEnv, o->num_setenv, o->setenv);
+ dump_cfg_strarray_oneline(oLogVerbose,
+ o->num_log_verbose, o->log_verbose);
/* Special cases */
+ /* PermitRemoteOpen */
+ if (o->num_permitted_remote_opens == 0)
+ printf("%s any\n", lookup_opcode_name(oPermitRemoteOpen));
+ else
+ dump_cfg_strarray_oneline(oPermitRemoteOpen,
+ o->num_permitted_remote_opens, o->permitted_remote_opens);
+
+ /* AddKeysToAgent */
+ if (o->add_keys_to_agent_lifespan <= 0)
+ dump_cfg_fmtint(oAddKeysToAgent, o->add_keys_to_agent);
+ else {
+ printf("addkeystoagent%s %d\n",
+ o->add_keys_to_agent == 3 ? " confirm" : "",
+ o->add_keys_to_agent_lifespan);
+ }
+
+ /* oForwardAgent */
+ if (o->forward_agent_sock_path == NULL)
+ dump_cfg_fmtint(oForwardAgent, o->forward_agent);
+ else
+ dump_cfg_string(oForwardAgent, o->forward_agent_sock_path);
+
/* oConnectTimeout */
if (o->connection_timeout == -1)
printf("connecttimeout none\n");
diff --git a/crypto/openssh/readconf.h b/crypto/openssh/readconf.h
index ed92bb182d31..f3ac60bd71ee 100644
--- a/crypto/openssh/readconf.h
+++ b/crypto/openssh/readconf.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: readconf.h,v 1.128 2018/09/20 03:30:44 djm Exp $ */
+/* $OpenBSD: readconf.h,v 1.144 2021/07/23 04:04:52 djm Exp $ */
/* $FreeBSD$ */
/*
@@ -30,6 +30,7 @@ struct allowed_cname {
typedef struct {
int forward_agent; /* Forward authentication agent. */
+ char *forward_agent_sock_path; /* Optional path of the agent. */
int forward_x11; /* Forward X11 display. */
int forward_x11_timeout; /* Expiration for Cookies */
int forward_x11_trusted; /* Trust Forward X11 display. */
@@ -38,8 +39,6 @@ typedef struct {
struct ForwardOptions fwd_opts; /* forwarding options */
int pubkey_authentication; /* Try ssh2 pubkey authentication. */
int hostbased_authentication; /* ssh2's rhosts_rsa */
- int challenge_response_authentication;
- /* Try S/Key or TIS, authentication. */
int gss_authentication; /* Try GSS authentication */
int gss_deleg_creds; /* Delegate GSS credentials */
int password_authentication; /* Try password
@@ -55,7 +54,8 @@ typedef struct {
int ip_qos_bulk; /* IP ToS/DSCP/class for bulk traffic */
SyslogFacility log_facility; /* Facility for system logging. */
LogLevel log_level; /* Level for logging. */
-
+ u_int num_log_verbose; /* Verbose log overrides */
+ char **log_verbose;
int port; /* Port to connect. */
int address_family;
int connection_attempts; /* Max attempts (seconds) before
@@ -83,6 +83,7 @@ typedef struct {
char *bind_address; /* local socket address for connection to sshd */
char *bind_interface; /* local interface for bind address */
char *pkcs11_provider; /* PKCS#11 provider */
+ char *sk_provider; /* Security key provider */
int verify_host_key_dns; /* Verify host key using DNS */
int num_identity_files; /* Number of files for RSA/DSA identities. */
@@ -96,6 +97,7 @@ typedef struct {
struct sshkey *certificates[SSH_MAX_CERTIFICATE_FILES];
int add_keys_to_agent;
+ int add_keys_to_agent_lifespan;
char *identity_agent; /* Optional path to ssh-agent socket */
/* Local TCP/IP forward requests. */
@@ -107,6 +109,10 @@ typedef struct {
struct Forward *remote_forwards;
int clear_forwardings;
+ /* Restrict remote dynamic forwarding */
+ char **permitted_remote_opens;
+ u_int num_permitted_remote_opens;
+
/* stdio forwarding (-W) host and port */
char *stdio_forward_host;
int stdio_forward_port;
@@ -141,6 +147,9 @@ typedef struct {
int visual_host_key;
int request_tty;
+ int session_type;
+ int stdin_null;
+ int fork_after_authentication;
int proxy_use_fdpass;
@@ -158,8 +167,8 @@ typedef struct {
int update_hostkeys; /* one of SSH_UPDATE_HOSTKEYS_* */
- char *hostbased_key_types;
- char *pubkey_key_types;
+ char *hostbased_accepted_algos;
+ char *pubkey_accepted_algos;
char *version_addendum; /* Appended to SSH banner */
@@ -168,6 +177,8 @@ typedef struct {
int jump_port;
char *jump_extra;
+ char *known_hosts_command;
+
char *ignored_unknown; /* Pattern list of unknown tokens to ignore */
} Options;
@@ -186,9 +197,13 @@ typedef struct {
#define REQUEST_TTY_YES 2
#define REQUEST_TTY_FORCE 3
+#define SESSION_TYPE_NONE 0
+#define SESSION_TYPE_SUBSYSTEM 1
+#define SESSION_TYPE_DEFAULT 2
+
#define SSHCONF_CHECKPERM 1 /* check permissions on config file */
#define SSHCONF_USERCONF 2 /* user provided config file not system */
-#define SSHCONF_POSTCANON 4 /* After hostname canonicalisation */
+#define SSHCONF_FINAL 4 /* Final pass over config, after canon. */
#define SSHCONF_NEVERMATCH 8 /* Match/Host never matches; internal only */
#define SSH_UPDATE_HOSTKEYS_NO 0
@@ -200,13 +215,17 @@ typedef struct {
#define SSH_STRICT_HOSTKEY_YES 2
#define SSH_STRICT_HOSTKEY_ASK 3
+const char *kex_default_pk_alg(void);
+char *ssh_connection_hash(const char *thishost, const char *host,
+ const char *portstr, const char *user);
void initialize_options(Options *);
-void fill_default_options(Options *);
+int fill_default_options(Options *);
void fill_default_options_for_canonicalization(Options *);
+void free_options(Options *o);
int process_config_line(Options *, struct passwd *, const char *,
const char *, char *, const char *, int, int *, int);
int read_config_file(const char *, struct passwd *, const char *,
- const char *, Options *, int);
+ const char *, Options *, int, int *);
int parse_forward(struct Forward *, const char *, int, int);
int parse_jump(const char *, Options *, int);
int parse_ssh_uri(const char *, char **, char **, int *);
diff --git a/crypto/openssh/readpass.c b/crypto/openssh/readpass.c
index f160f866b885..39af25c88729 100644
--- a/crypto/openssh/readpass.c
+++ b/crypto/openssh/readpass.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: readpass.c,v 1.52 2018/07/18 11:34:04 dtucker Exp $ */
+/* $OpenBSD: readpass.c,v 1.69 2021/07/23 05:56:47 djm Exp $ */
/*
* Copyright (c) 2001 Markus Friedl. All rights reserved.
*
@@ -48,7 +48,7 @@
#include "uidswap.h"
static char *
-ssh_askpass(char *askpass, const char *msg)
+ssh_askpass(char *askpass, const char *msg, const char *env_hint)
{
pid_t pid, ret;
size_t len;
@@ -58,25 +58,27 @@ ssh_askpass(char *askpass, const char *msg)
void (*osigchld)(int);
if (fflush(stdout) != 0)
- error("ssh_askpass: fflush: %s", strerror(errno));
+ error_f("fflush: %s", strerror(errno));
if (askpass == NULL)
fatal("internal error: askpass undefined");
- if (pipe(p) < 0) {
- error("ssh_askpass: pipe: %s", strerror(errno));
+ if (pipe(p) == -1) {
+ error_f("pipe: %s", strerror(errno));
return NULL;
}
- osigchld = signal(SIGCHLD, SIG_DFL);
- if ((pid = fork()) < 0) {
- error("ssh_askpass: fork: %s", strerror(errno));
- signal(SIGCHLD, osigchld);
+ osigchld = ssh_signal(SIGCHLD, SIG_DFL);
+ if ((pid = fork()) == -1) {
+ error_f("fork: %s", strerror(errno));
+ ssh_signal(SIGCHLD, osigchld);
return NULL;
}
if (pid == 0) {
close(p[0]);
- if (dup2(p[1], STDOUT_FILENO) < 0)
- fatal("ssh_askpass: dup2: %s", strerror(errno));
+ if (dup2(p[1], STDOUT_FILENO) == -1)
+ fatal_f("dup2: %s", strerror(errno));
+ if (env_hint != NULL)
+ setenv("SSH_ASKPASS_PROMPT", env_hint, 1);
execlp(askpass, askpass, msg, (char *)NULL);
- fatal("ssh_askpass: exec(%s): %s", askpass, strerror(errno));
+ fatal_f("exec(%s): %s", askpass, strerror(errno));
}
close(p[1]);
@@ -93,10 +95,10 @@ ssh_askpass(char *askpass, const char *msg)
buf[len] = '\0';
close(p[0]);
- while ((ret = waitpid(pid, &status, 0)) < 0)
+ while ((ret = waitpid(pid, &status, 0)) == -1)
if (errno != EINTR)
break;
- signal(SIGCHLD, osigchld);
+ ssh_signal(SIGCHLD, osigchld);
if (ret == -1 || !WIFEXITED(status) || WEXITSTATUS(status) != 0) {
explicit_bzero(buf, sizeof(buf));
return NULL;
@@ -108,47 +110,75 @@ ssh_askpass(char *askpass, const char *msg)
return pass;
}
+/* private/internal read_passphrase flags */
+#define RP_ASK_PERMISSION 0x8000 /* pass hint to askpass for confirm UI */
+
/*
* Reads a passphrase from /dev/tty with echo turned off/on. Returns the
* passphrase (allocated with xmalloc). Exits if EOF is encountered. If
* RP_ALLOW_STDIN is set, the passphrase will be read from stdin if no
- * tty is available
+ * tty is or askpass program is available
*/
char *
read_passphrase(const char *prompt, int flags)
{
- char *askpass = NULL, *ret, buf[1024];
- int rppflags, use_askpass = 0, ttyfd;
+ char cr = '\r', *askpass = NULL, *ret, buf[1024];
+ int rppflags, ttyfd, use_askpass = 0, allow_askpass = 0;
+ const char *askpass_hint = NULL;
+ const char *s;
+
+ if ((s = getenv("DISPLAY")) != NULL)
+ allow_askpass = *s != '\0';
+ if ((s = getenv(SSH_ASKPASS_REQUIRE_ENV)) != NULL) {
+ if (strcasecmp(s, "force") == 0) {
+ use_askpass = 1;
+ allow_askpass = 1;
+ } else if (strcasecmp(s, "prefer") == 0)
+ use_askpass = allow_askpass;
+ else if (strcasecmp(s, "never") == 0)
+ allow_askpass = 0;
+ }
rppflags = (flags & RP_ECHO) ? RPP_ECHO_ON : RPP_ECHO_OFF;
- if (flags & RP_USE_ASKPASS)
+ if (use_askpass)
+ debug_f("requested to askpass");
+ else if (flags & RP_USE_ASKPASS)
use_askpass = 1;
else if (flags & RP_ALLOW_STDIN) {
if (!isatty(STDIN_FILENO)) {
- debug("read_passphrase: stdin is not a tty");
+ debug_f("stdin is not a tty");
use_askpass = 1;
}
} else {
rppflags |= RPP_REQUIRE_TTY;
ttyfd = open(_PATH_TTY, O_RDWR);
- if (ttyfd >= 0)
+ if (ttyfd >= 0) {
+ /*
+ * If we're on a tty, ensure that show the prompt at
+ * the beginning of the line. This will hopefully
+ * clobber any password characters the user has
+ * optimistically typed before echo is disabled.
+ */
+ (void)write(ttyfd, &cr, 1);
close(ttyfd);
- else {
- debug("read_passphrase: can't open %s: %s", _PATH_TTY,
+ } else {
+ debug_f("can't open %s: %s", _PATH_TTY,
strerror(errno));
use_askpass = 1;
}
}
- if ((flags & RP_USE_ASKPASS) && getenv("DISPLAY") == NULL)
+ if ((flags & RP_USE_ASKPASS) && !allow_askpass)
return (flags & RP_ALLOW_EOF) ? NULL : xstrdup("");
- if (use_askpass && getenv("DISPLAY")) {
+ if (use_askpass && allow_askpass) {
if (getenv(SSH_ASKPASS_ENV))
askpass = getenv(SSH_ASKPASS_ENV);
else
askpass = _PATH_SSH_ASKPASS_DEFAULT;
- if ((ret = ssh_askpass(askpass, prompt)) == NULL)
+ if ((flags & RP_ASK_PERMISSION) != 0)
+ askpass_hint = "confirm";
+ if ((ret = ssh_askpass(askpass, prompt, askpass_hint)) == NULL)
if (!(flags & RP_ALLOW_EOF))
return xstrdup("");
return ret;
@@ -176,7 +206,8 @@ ask_permission(const char *fmt, ...)
vsnprintf(prompt, sizeof(prompt), fmt, args);
va_end(args);
- p = read_passphrase(prompt, RP_USE_ASKPASS|RP_ALLOW_EOF);
+ p = read_passphrase(prompt,
+ RP_USE_ASKPASS|RP_ALLOW_EOF|RP_ASK_PERMISSION);
if (p != NULL) {
/*
* Accept empty responses and responses consisting
@@ -190,3 +221,111 @@ ask_permission(const char *fmt, ...)
return (allowed);
}
+
+static void
+writemsg(const char *msg)
+{
+ (void)write(STDERR_FILENO, "\r", 1);
+ (void)write(STDERR_FILENO, msg, strlen(msg));
+ (void)write(STDERR_FILENO, "\r\n", 2);
+}
+
+struct notifier_ctx {
+ pid_t pid;
+ void (*osigchld)(int);
+};
+
+struct notifier_ctx *
+notify_start(int force_askpass, const char *fmt, ...)
+{
+ va_list args;
+ char *prompt = NULL;
+ pid_t pid = -1;
+ void (*osigchld)(int) = NULL;
+ const char *askpass, *s;
+ struct notifier_ctx *ret = NULL;
+
+ va_start(args, fmt);
+ xvasprintf(&prompt, fmt, args);
+ va_end(args);
+
+ if (fflush(NULL) != 0)
+ error_f("fflush: %s", strerror(errno));
+ if (!force_askpass && isatty(STDERR_FILENO)) {
+ writemsg(prompt);
+ goto out_ctx;
+ }
+ if ((askpass = getenv("SSH_ASKPASS")) == NULL)
+ askpass = _PATH_SSH_ASKPASS_DEFAULT;
+ if (*askpass == '\0') {
+ debug3_f("cannot notify: no askpass");
+ goto out;
+ }
+ if (getenv("DISPLAY") == NULL &&
+ ((s = getenv(SSH_ASKPASS_REQUIRE_ENV)) == NULL ||
+ strcmp(s, "force") != 0)) {
+ debug3_f("cannot notify: no display");
+ goto out;
+ }
+ osigchld = ssh_signal(SIGCHLD, SIG_DFL);
+ if ((pid = fork()) == -1) {
+ error_f("fork: %s", strerror(errno));
+ ssh_signal(SIGCHLD, osigchld);
+ free(prompt);
+ return NULL;
+ }
+ if (pid == 0) {
+ if (stdfd_devnull(1, 1, 0) == -1)
+ fatal_f("stdfd_devnull failed");
+ closefrom(STDERR_FILENO + 1);
+ setenv("SSH_ASKPASS_PROMPT", "none", 1); /* hint to UI */
+ execlp(askpass, askpass, prompt, (char *)NULL);
+ error_f("exec(%s): %s", askpass, strerror(errno));
+ _exit(1);
+ /* NOTREACHED */
+ }
+ out_ctx:
+ if ((ret = calloc(1, sizeof(*ret))) == NULL) {
+ kill(pid, SIGTERM);
+ fatal_f("calloc failed");
+ }
+ ret->pid = pid;
+ ret->osigchld = osigchld;
+ out:
+ free(prompt);
+ return ret;
+}
+
+void
+notify_complete(struct notifier_ctx *ctx, const char *fmt, ...)
+{
+ int ret;
+ char *msg = NULL;
+ va_list args;
+
+ if (ctx != NULL && fmt != NULL && ctx->pid == -1) {
+ /*
+ * notify_start wrote to stderr, so send conclusion message
+ * there too
+ */
+ va_start(args, fmt);
+ xvasprintf(&msg, fmt, args);
+ va_end(args);
+ writemsg(msg);
+ free(msg);
+ }
+
+ if (ctx == NULL || ctx->pid <= 0) {
+ free(ctx);
+ return;
+ }
+ kill(ctx->pid, SIGTERM);
+ while ((ret = waitpid(ctx->pid, NULL, 0)) == -1) {
+ if (errno != EINTR)
+ break;
+ }
+ if (ret == -1)
+ fatal_f("waitpid: %s", strerror(errno));
+ ssh_signal(SIGCHLD, ctx->osigchld);
+ free(ctx);
+}
diff --git a/crypto/openssh/regress/Makefile b/crypto/openssh/regress/Makefile
index 647b4a049be3..810d74ce599d 100644
--- a/crypto/openssh/regress/Makefile
+++ b/crypto/openssh/regress/Makefile
@@ -1,7 +1,11 @@
-# $OpenBSD: Makefile,v 1.97 2018/06/07 04:46:34 djm Exp $
+# $OpenBSD: Makefile,v 1.116 2021/08/04 21:28:00 djm Exp $
-REGRESS_TARGETS= unit t1 t2 t3 t4 t5 t6 t7 t8 t9 t10 t11 t12 t-exec
-tests: prep $(REGRESS_TARGETS)
+tests: prep file-tests t-exec unit
+
+REGRESS_TARGETS= t1 t2 t3 t4 t5 t6 t7 t8 t9 t10 t11 t12
+
+# File based tests
+file-tests: $(REGRESS_TARGETS)
# Interop tests are not run by default
interop interop-tests: t-exec-interop
@@ -11,13 +15,13 @@ prep:
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 \
+ sshfp-connect \
connect-privsep \
connect-uri \
proto-version \
@@ -27,6 +31,7 @@ LTESTS= connect \
transfer \
banner \
rekey \
+ dhgex \
stderr-data \
stderr-after-eof \
broken-pipe \
@@ -37,12 +42,17 @@ LTESTS= connect \
agent-getpeereid \
agent-timeout \
agent-ptrace \
+ agent-subprocess \
keyscan \
keygen-change \
+ keygen-comment \
keygen-convert \
+ keygen-knownhosts \
keygen-moduli \
+ keygen-sshfp \
key-options \
scp \
+ scp3 \
scp-uri \
sftp \
sftp-chroot \
@@ -62,6 +72,7 @@ LTESTS= connect \
cfgparse \
cfgmatch \
cfgmatchlisten \
+ percent \
addrmatch \
localcommand \
forcecommand \
@@ -78,21 +89,22 @@ LTESTS= connect \
multipubkey \
limit-keytype \
hostkey-agent \
- keygen-knownhosts \
hostkey-rotate \
principals-command \
cert-file \
cfginclude \
+ servcfginclude \
allow-deny-users \
- authinfo
-
+ authinfo \
+ sshsig \
+ knownhosts-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
+EXTRA_TESTS= agent-pkcs11
+#EXTRA_TESTS+= cipher-speed
USERNAME= ${LOGNAME}
CLEANFILES= *.core actual agent-key.* authorized_keys_${USERNAME} \
@@ -102,28 +114,27 @@ CLEANFILES= *.core actual agent-key.* authorized_keys_${USERNAME} \
copy.1 copy.2 data ed25519-agent ed25519-agent* \
ed25519-agent.pub ed25519 ed25519.pub empty.in \
expect failed-regress.log failed-ssh.log failed-sshd.log \
- hkr.* host.ed25519 host.rsa host.rsa1 host_* \
- host_ca_key* host_krl_* host_revoked_* key.* \
+ hkr.* host.ecdsa-sha2-nistp256 host.ecdsa-sha2-nistp384 \
+ host.ecdsa-sha2-nistp521 host.ssh-dss host.ssh-ed25519 \
+ host.ssh-rsa host_ca_key* host_krl_* host_revoked_* key.* \
key.dsa-* key.ecdsa-* key.ed25519-512 \
- key.ed25519-512.pub key.rsa-* keys-command-args kh.* \
+ key.ed25519-512.pub key.rsa-* keys-command-args kh.* askpass \
known_hosts known_hosts-cert known_hosts.* krl-* ls.copy \
modpipe netcat no_identity_config \
- pidfile putty.rsa2 ready regress.log \
- remote_pid revoked-* rsa rsa-agent rsa-agent.pub rsa.pub \
- rsa1 rsa1-agent rsa1-agent.pub rsa1.pub rsa_ssh2_cr.prv \
+ pidfile putty.rsa2 ready regress.log remote_pid \
+ revoked-* rsa rsa-agent rsa-agent.pub rsa.pub rsa_ssh2_cr.prv \
rsa_ssh2_crnl.prv scp-ssh-wrapper.exe \
scp-ssh-wrapper.scp setuid-allowed sftp-server.log \
sftp-server.sh sftp.log ssh-log-wrapper.sh ssh.log \
+ ssh-rsa_oldfmt knownhosts_command \
ssh_config ssh_config.* ssh_proxy ssh_proxy_bak \
- ssh_proxy_envpass sshd.log sshd_config sshd_config_minimal \
- sshd_config.orig sshd_proxy sshd_proxy.* sshd_proxy_bak \
+ ssh_proxy_* sshd.log sshd_config sshd_config.* \
+ sshd_config.* sshd_proxy sshd_proxy.* sshd_proxy_bak \
sshd_proxy_orig t10.out t10.out.pub t12.out t12.out.pub \
t2.out t3.out t6.out1 t6.out2 t7.out t7.out.pub \
t8.out t8.out.pub t9.out t9.out.pub testdata \
user_*key* user_ca* user_key*
-SUDO_CLEAN+= /var/run/testdata_${USERNAME} /var/run/keycommand_${USERNAME}
-
# Enable all malloc(3) randomisations and checks
TEST_ENV= "MALLOC_OPTIONS=CFGJRSUX"
@@ -206,11 +217,26 @@ t12: $(OBJ)/t12.out
t-exec: ${LTESTS:=.sh}
@if [ "x$?" = "x" ]; then exit 0; fi; \
for TEST in ""$?; do \
+ skip=no; \
+ for t in ""$${SKIP_LTESTS}; do \
+ if [ "x$${t}.sh" = "x$${TEST}" ]; then skip=yes; fi; \
+ done; \
+ if [ "x$${skip}" = "xno" ]; then \
+ echo "run test $${TEST}" ... 1>&2; \
+ (env SUDO="${SUDO}" TEST_ENV=${TEST_ENV} ${TEST_SHELL} ${.CURDIR}/test-exec.sh ${.OBJDIR} ${.CURDIR}/$${TEST}) || exit $$?; \
+ else \
+ echo skip test $${TEST} 1>&2; \
+ fi; \
+ 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
-t-exec-interop: ${INTEROP_TESTS:=.sh}
+t-extra: ${EXTRA_TESTS:=.sh}
@if [ "x$?" = "x" ]; then exit 0; fi; \
for TEST in ""$?; do \
echo "run test $${TEST}" ... 1>&2; \
@@ -226,15 +252,20 @@ unit:
V="" ; \
test "x${USE_VALGRIND}" = "x" || \
V=${.CURDIR}/valgrind-unit.sh ; \
- $$V ${.OBJDIR}/unittests/sshbuf/test_sshbuf ; \
- $$V ${.OBJDIR}/unittests/sshkey/test_sshkey \
+ $$V ${.OBJDIR}/unittests/sshbuf/test_sshbuf ; \
+ $$V ${.OBJDIR}/unittests/sshkey/test_sshkey \
-d ${.CURDIR}/unittests/sshkey/testdata ; \
+ $$V ${.OBJDIR}/unittests/sshsig/test_sshsig \
+ -d ${.CURDIR}/unittests/sshsig/testdata ; \
+ $$V ${.OBJDIR}/unittests/authopt/test_authopt \
+ -d ${.CURDIR}/unittests/authopt/testdata ; \
$$V ${.OBJDIR}/unittests/bitmap/test_bitmap ; \
$$V ${.OBJDIR}/unittests/conversion/test_conversion ; \
$$V ${.OBJDIR}/unittests/kex/test_kex ; \
$$V ${.OBJDIR}/unittests/hostkeys/test_hostkeys \
-d ${.CURDIR}/unittests/hostkeys/testdata ; \
$$V ${.OBJDIR}/unittests/match/test_match ; \
+ $$V ${.OBJDIR}/unittests/misc/test_misc ; \
if test "x${TEST_SSH_UTF8}" = "xyes" ; then \
$$V ${.OBJDIR}/unittests/utf8/test_utf8 ; \
fi \
diff --git a/crypto/openssh/regress/README.regress b/crypto/openssh/regress/README.regress
index 315fe149a0f5..ac2e8487e78e 100644
--- a/crypto/openssh/regress/README.regress
+++ b/crypto/openssh/regress/README.regress
@@ -25,6 +25,7 @@ SUDO: path to sudo/doas command, if desired. Note that some systems
(notably systems using PAM) require sudo to execute some tests.
LTESTS: Whitespace separated list of tests (filenames without the .sh
extension) to run.
+SKIP_LTESTS: Whitespace separated list of tests to skip.
OBJ: used by test scripts to access build dir.
TEST_SHELL: shell used for running the test scripts.
TEST_SSH_FAIL_FATAL: set to "yes" to make any failure abort the test
@@ -63,28 +64,79 @@ 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
+proxy-connect.sh: proxy connect
+connect-privsep.sh: proxy connect with privsep
+connect-uri.sh: uri connect
+proto-version.sh: sshd version with different protocol combinations
+proto-mismatch.sh: protocol version mismatch
exit-status.sh: remote exit status
-forwarding.sh: local and remote forwarding
-keygen-change.sh: change passphrase for key
+envpass.sh: environment passing
+transfer.sh: transfer data
+banner.sh: banner
+rekey.sh: rekey
+stderr-data.sh: stderr data transfer
+stderr-after-eof.sh: stderr data after eof
+broken-pipe.sh: broken pipe test
+try-ciphers.sh: try ciphers
+yes-head.sh: yes pipe head
+login-timeout.sh: connect after login grace timeout
+agent.sh: simple connect via agent
+agent-getpeereid.sh: disallow agent attach from other uid
+agent-timeout.sh: agent timeout test
+agent-ptrace.sh: disallow agent ptrace attach
keyscan.sh: keyscan
-proto-mismatch.sh: protocol version mismatch
-proto-version.sh: sshd version with different protocol combinations
-proxy-connect.sh: proxy connect
+keygen-change.sh: change passphrase for key
+keygen-convert.sh: convert keys
+keygen-moduli.sh: keygen moduli
+key-options.sh: key options
+scp.sh: scp
+scp-uri.sh: scp-uri
sftp.sh: basic sftp put/get
+sftp-chroot.sh: sftp in chroot
+sftp-cmds.sh: sftp command
+sftp-badcmds.sh: sftp invalid commands
+sftp-batch.sh: sftp batchfile
+sftp-glob.sh: sftp glob
+sftp-perm.sh: sftp permissions
+sftp-uri.sh: sftp-uri
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
+reconfigure.sh: simple connect after reconfigure
+dynamic-forward.sh: dynamic forwarding
+forwarding.sh: local and remote forwarding
+multiplex.sh: connection multiplexing
+reexec.sh: reexec tests
+brokenkeys.sh: broken keys
+sshcfgparse.sh: ssh config parse
+cfgparse.sh: sshd config parse
+cfgmatch.sh: sshd_config match
+cfgmatchlisten.sh: sshd_config matchlisten
+addrmatch.sh: address match
+localcommand.sh: localcommand
+forcecommand.sh: forced command
+portnum.sh: port number parsing
+keytype.sh: login with different key types
+kextype.sh: login with different key exchange algorithms
+cert-hostkey.sh certified host keys
+cert-userkey.sh: certified user keys
+host-expand.sh: expand %h and %n
+keys-command.sh: authorized keys from command
+forward-control.sh: sshd control of local and remote forwarding
+integrity.sh: integrity
+krl.sh: key revocation lists
+multipubkey.sh: multiple pubkey
+limit-keytype.sh: restrict pubkey type
+hostkey-agent.sh: hostkey agent
+keygen-knownhosts.sh: ssh-keygen known_hosts
+hostkey-rotate.sh: hostkey rotate
+principals-command.sh: authorized principals command
+cert-file.sh: ssh with certificates
+cfginclude.sh: config include
+allow-deny-users.sh: AllowUsers/DenyUsers
+authinfo.sh: authinfo
Problems?
diff --git a/crypto/openssh/regress/addrmatch.sh b/crypto/openssh/regress/addrmatch.sh
index 1584bd4053d6..26e0c9910c47 100755..100644
--- a/crypto/openssh/regress/addrmatch.sh
+++ b/crypto/openssh/regress/addrmatch.sh
@@ -1,4 +1,4 @@
-# $OpenBSD: addrmatch.sh,v 1.4 2012/05/13 01:42:32 dtucker Exp $
+# $OpenBSD: addrmatch.sh,v 1.6 2020/08/28 03:17:13 dtucker Exp $
# Placed in the Public Domain.
tid="address match"
@@ -43,7 +43,7 @@ run_trial user 19.0.0.1 somehost 1.2.3.4 5678 match4 "localport"
if test "$TEST_SSH_IPV6" != "no"; then
run_trial user ::1 somehost.example.com ::2 1234 match2 "bare IP6 address"
-run_trial user ::2 somehost.exaple.com ::2 1234 nomatch "deny IPv6"
+run_trial user ::2 somehost.example.com ::2 1234 nomatch "deny IPv6"
run_trial user ::3 somehost ::2 1234 nomatch "IP6 negated"
run_trial user ::4 somehost ::2 1234 nomatch "IP6 no match"
run_trial user 2000::1 somehost ::2 1234 match2 "IP6 network"
@@ -52,5 +52,17 @@ run_trial user ::5 somehost ::1 1234 match3 "IP6 localaddress"
run_trial user ::5 somehost ::2 5678 match4 "IP6 localport"
fi
+#
+# Check that we catch invalid address/mask in Match Address/Localaddress
+#
+for i in 10.0.1.0/8 10.0.0.1/24 2000:aa:bb:01::/56; do
+ for a in address localaddress; do
+ verbose "test invalid Match $a $i"
+ echo "Match $a $i" > $OBJ/sshd_proxy
+ ${SUDO} ${SSHD} -f $OBJ/sshd_proxy -t >/dev/null 2>&1 && \
+ fail "accepted invalid match $a $i"
+ done
+done
+
cp $OBJ/sshd_proxy_bak $OBJ/sshd_proxy
rm $OBJ/sshd_proxy_bak
diff --git a/crypto/openssh/regress/agent-getpeereid.sh b/crypto/openssh/regress/agent-getpeereid.sh
index 769c29e8da47..ddeef01f1b73 100644
--- a/crypto/openssh/regress/agent-getpeereid.sh
+++ b/crypto/openssh/regress/agent-getpeereid.sh
@@ -1,4 +1,4 @@
-# $OpenBSD: agent-getpeereid.sh,v 1.10 2018/02/09 03:40:22 dtucker Exp $
+# $OpenBSD: agent-getpeereid.sh,v 1.11 2019/11/26 23:43:10 djm Exp $
# Placed in the Public Domain.
tid="disallow agent attach from other uid"
@@ -15,7 +15,7 @@ else
fi
case "x$SUDO" in
xsudo) sudo=1;;
- xdoas) ;;
+ xdoas|xdoas\ *) ;;
x)
echo "need SUDO to switch to uid $UNPRIV"
echo SKIPPED
@@ -26,7 +26,7 @@ case "x$SUDO" in
esac
trace "start agent"
-eval `${SSHAGENT} -s -a ${ASOCK}` > /dev/null
+eval `${SSHAGENT} ${EXTRA_AGENT_ARGS} -s -a ${ASOCK}` > /dev/null
r=$?
if [ $r -ne 0 ]; then
fail "could not start ssh-agent: exit code $r"
diff --git a/crypto/openssh/regress/agent-pkcs11.sh b/crypto/openssh/regress/agent-pkcs11.sh
index db3018b885fe..268a70de8885 100755..100644
--- a/crypto/openssh/regress/agent-pkcs11.sh
+++ b/crypto/openssh/regress/agent-pkcs11.sh
@@ -1,16 +1,53 @@
-# $OpenBSD: agent-pkcs11.sh,v 1.3 2017/04/30 23:34:55 djm Exp $
+# $OpenBSD: agent-pkcs11.sh,v 1.9 2021/07/25 12:13:03 dtucker Exp $
# Placed in the Public Domain.
tid="pkcs11 agent test"
-TEST_SSH_PIN=""
-TEST_SSH_PKCS11=/usr/local/lib/soft-pkcs11.so.0.0
+try_token_libs() {
+ for _lib in "$@" ; do
+ if test -f "$_lib" ; then
+ verbose "Using token library $_lib"
+ TEST_SSH_PKCS11="$_lib"
+ return
+ fi
+ done
+ echo "skipped: Unable to find PKCS#11 token library"
+ exit 0
+}
+
+try_token_libs \
+ /usr/local/lib/softhsm/libsofthsm2.so \
+ /usr/lib64/pkcs11/libsofthsm2.so \
+ /usr/lib/x86_64-linux-gnu/softhsm/libsofthsm2.so
+
+TEST_SSH_PIN=1234
+TEST_SSH_SOPIN=12345678
+if [ "x$TEST_SSH_SSHPKCS11HELPER" != "x" ]; then
+ SSH_PKCS11_HELPER="${TEST_SSH_SSHPKCS11HELPER}"
+ export SSH_PKCS11_HELPER
+fi
test -f "$TEST_SSH_PKCS11" || fatal "$TEST_SSH_PKCS11 does not exist"
-# setup environment for soft-pkcs11 token
-SOFTPKCS11RC=$OBJ/pkcs11.info
-export SOFTPKCS11RC
+# setup environment for softhsm2 token
+DIR=$OBJ/SOFTHSM
+rm -rf $DIR
+TOKEN=$DIR/tokendir
+mkdir -p $TOKEN
+SOFTHSM2_CONF=$DIR/softhsm2.conf
+export SOFTHSM2_CONF
+cat > $SOFTHSM2_CONF << EOF
+# SoftHSM v2 configuration file
+directories.tokendir = ${TOKEN}
+objectstore.backend = file
+# ERROR, WARNING, INFO, DEBUG
+log.level = DEBUG
+# If CKF_REMOVABLE_DEVICE flag should be set
+slots.removable = false
+EOF
+out=$(softhsm2-util --init-token --free --label token-slot-0 --pin "$TEST_SSH_PIN" --so-pin "$TEST_SSH_SOPIN")
+slot=$(echo -- $out | sed 's/.* //')
+
# prevent ssh-agent from calling ssh-askpass
SSH_ASKPASS=/usr/bin/true
export SSH_ASKPASS
@@ -22,22 +59,27 @@ notty() {
if (fork) { wait; exit($? >> 8); } else { exec(@ARGV) }' "$@"
}
+trace "generating keys"
+RSA=${DIR}/RSA
+EC=${DIR}/EC
+$OPENSSL_BIN genpkey -algorithm rsa > $RSA
+$OPENSSL_BIN pkcs8 -nocrypt -in $RSA |\
+ softhsm2-util --slot "$slot" --label 01 --id 01 --pin "$TEST_SSH_PIN" --import /dev/stdin
+$OPENSSL_BIN genpkey \
+ -genparam \
+ -algorithm ec \
+ -pkeyopt ec_paramgen_curve:prime256v1 |\
+ $OPENSSL_BIN genpkey \
+ -paramfile /dev/stdin > $EC
+$OPENSSL_BIN pkcs8 -nocrypt -in $EC |\
+ softhsm2-util --slot "$slot" --label 02 --id 02 --pin "$TEST_SSH_PIN" --import /dev/stdin
+
trace "start agent"
-eval `${SSHAGENT} -s` > /dev/null
+eval `${SSHAGENT} ${EXTRA_AGENT_ARGS} -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=$?
@@ -52,12 +94,23 @@ else
fail "ssh-add -l failed: exit code $r"
fi
- trace "pkcs11 connect via agent"
- ${SSH} -F $OBJ/ssh_proxy somehost exit 5
- r=$?
- if [ $r -ne 5 ]; then
- fail "ssh connect failed (exit code $r)"
- fi
+ for k in $RSA $EC; do
+ trace "testing $k"
+ chmod 600 $k
+ ssh-keygen -y -f $k > $k.pub
+ pub=$(cat $k.pub)
+ ${SSHADD} -L | grep -q "$pub" || fail "key $k missing in ssh-add -L"
+ ${SSHADD} -T $k.pub || fail "ssh-add -T with $k failed"
+
+ # add to authorized keys
+ cat $k.pub > $OBJ/authorized_keys_$USER
+ trace "pkcs11 connect via agent ($k)"
+ ${SSH} -F $OBJ/ssh_proxy somehost exit 5
+ r=$?
+ if [ $r -ne 5 ]; then
+ fail "ssh connect failed (exit code $r)"
+ fi
+ done
trace "remove pkcs11 keys"
echo ${TEST_SSH_PIN} | notty ${SSHADD} -e ${TEST_SSH_PKCS11} > /dev/null 2>&1
diff --git a/crypto/openssh/regress/agent-ptrace.sh b/crypto/openssh/regress/agent-ptrace.sh
index 2d795ee32043..9cd68d7ec84e 100644
--- a/crypto/openssh/regress/agent-ptrace.sh
+++ b/crypto/openssh/regress/agent-ptrace.sh
@@ -41,7 +41,7 @@ else
fi
trace "start agent"
-eval `${SSHAGENT} -s` > /dev/null
+eval `${SSHAGENT} ${EXTRA_AGENT_ARGS} -s` > /dev/null
r=$?
if [ $r -ne 0 ]; then
fail "could not start ssh-agent: exit code $r"
diff --git a/crypto/openssh/regress/agent-subprocess.sh b/crypto/openssh/regress/agent-subprocess.sh
new file mode 100644
index 000000000000..2f36d70cccae
--- /dev/null
+++ b/crypto/openssh/regress/agent-subprocess.sh
@@ -0,0 +1,22 @@
+# $OpenBSD: agent-subprocess.sh,v 1.1 2020/06/19 05:07:09 dtucker Exp $
+# Placed in the Public Domain.
+
+tid="agent subprocess"
+
+trace "ensure agent exits when run as subprocess"
+${SSHAGENT} sh -c "echo \$SSH_AGENT_PID >$OBJ/pidfile; sleep 1"
+
+pid=`cat $OBJ/pidfile`
+
+# Currently ssh-agent polls every 10s so we need to wait at least that long.
+n=12
+while kill -0 $pid >/dev/null 2>&1 && test "$n" -gt "0"; do
+ n=$(($n - 1))
+ sleep 1
+done
+
+if test "$n" -eq "0"; then
+ fail "agent still running"
+fi
+
+rm -f $OBJ/pidfile
diff --git a/crypto/openssh/regress/agent-timeout.sh b/crypto/openssh/regress/agent-timeout.sh
index 9598c2032d26..6dec09285908 100644
--- a/crypto/openssh/regress/agent-timeout.sh
+++ b/crypto/openssh/regress/agent-timeout.sh
@@ -1,4 +1,4 @@
-# $OpenBSD: agent-timeout.sh,v 1.3 2015/03/03 22:35:19 markus Exp $
+# $OpenBSD: agent-timeout.sh,v 1.6 2019/11/26 23:43:10 djm Exp $
# Placed in the Public Domain.
tid="agent timeout test"
@@ -6,22 +6,24 @@ tid="agent timeout test"
SSHAGENT_TIMEOUT=10
trace "start agent"
-eval `${SSHAGENT} -s` > /dev/null
+eval `${SSHAGENT} -s ${EXTRA_AGENT_ARGS}` > /dev/null
r=$?
if [ $r -ne 0 ]; then
fail "could not start ssh-agent: exit code $r"
else
trace "add keys with timeout"
+ keys=0
for t in ${SSH_KEYTYPES}; do
- ${SSHADD} -t ${SSHAGENT_TIMEOUT} $OBJ/$t > /dev/null 2>&1
+ ${SSHADD} -kt ${SSHAGENT_TIMEOUT} $OBJ/$t > /dev/null 2>&1
if [ $? -ne 0 ]; then
fail "ssh-add did succeed exit code 0"
fi
+ keys=$((${keys} + 1))
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"
+ if [ $n -ne $keys ]; then
+ fail "ssh-add -l did not return $keys keys: $n"
fi
trace "sleeping 2*${SSHAGENT_TIMEOUT} seconds"
sleep ${SSHAGENT_TIMEOUT}
diff --git a/crypto/openssh/regress/agent.sh b/crypto/openssh/regress/agent.sh
index 7111056c9be4..f187b6757201 100644
--- a/crypto/openssh/regress/agent.sh
+++ b/crypto/openssh/regress/agent.sh
@@ -1,4 +1,4 @@
-# $OpenBSD: agent.sh,v 1.13 2017/12/19 00:49:30 djm Exp $
+# $OpenBSD: agent.sh,v 1.20 2021/02/25 03:27:34 djm Exp $
# Placed in the Public Domain.
tid="simple agent test"
@@ -8,13 +8,19 @@ if [ $? -ne 2 ]; then
fail "ssh-add -l did not fail with exit code 2"
fi
-trace "start agent"
-eval `${SSHAGENT} -s` > /dev/null
+trace "start agent, args ${EXTRA_AGENT_ARGS} -s"
+eval `${SSHAGENT} ${EXTRA_AGENT_ARGS} -s` > /dev/null
r=$?
if [ $r -ne 0 ]; then
fatal "could not start ssh-agent: exit code $r"
fi
+eval `${SSHAGENT} ${EXTRA_AGENT_ARGS} -s | sed 's/SSH_/FW_SSH_/g'` > /dev/null
+r=$?
+if [ $r -ne 0 ]; then
+ fatal "could not start second ssh-agent: exit code $r"
+fi
+
${SSHADD} -l > /dev/null 2>&1
if [ $? -ne 1 ]; then
fail "ssh-add -l did not fail with exit code 1"
@@ -38,13 +44,21 @@ for t in ${SSH_KEYTYPES}; do
# add to authorized keys
cat $OBJ/$t-agent.pub >> $OBJ/authorized_keys_$USER
- # add privat key to agent
+ # add private key to agent
${SSHADD} $OBJ/$t-agent > /dev/null 2>&1
if [ $? -ne 0 ]; then
- fail "ssh-add did succeed exit code 0"
+ fail "ssh-add failed exit code $?"
+ fi
+ # add private key to second agent
+ SSH_AUTH_SOCK=$FW_SSH_AUTH_SOCK ${SSHADD} $OBJ/$t-agent > /dev/null 2>&1
+ if [ $? -ne 0 ]; then
+ fail "ssh-add failed exit code $?"
fi
- # Remove private key to ensure that we aren't accidentally using it.
- rm -f $OBJ/$t-agent
+ # Move private key to ensure that we aren't accidentally using it.
+ # Keep the corresponding public keys/certs around for later use.
+ mv -f $OBJ/$t-agent $OBJ/$t-agent-private
+ cp -f $OBJ/$t-agent.pub $OBJ/$t-agent-private.pub
+ cp -f $OBJ/$t-agent-cert.pub $OBJ/$t-agent-private-cert.pub
done
# Remove explicit identity directives from ssh_proxy
@@ -72,6 +86,10 @@ fi
for t in ${SSH_KEYTYPES}; do
trace "connect via agent using $t key"
+ if [ "$t" = "ssh-dss" ]; then
+ echo "PubkeyAcceptedAlgorithms +ssh-dss" >> $OBJ/ssh_proxy
+ echo "PubkeyAcceptedAlgorithms +ssh-dss" >> $OBJ/sshd_proxy
+ fi
${SSH} -F $OBJ/ssh_proxy -i $OBJ/$t-agent.pub -oIdentitiesOnly=yes \
somehost exit 52
r=$?
@@ -86,6 +104,11 @@ r=$?
if [ $r -ne 0 ]; then
fail "ssh-add -l via agent fwd failed (exit code $r)"
fi
+${SSH} "-oForwardAgent=$SSH_AUTH_SOCK" -F $OBJ/ssh_proxy somehost ${SSHADD} -l > /dev/null 2>&1
+r=$?
+if [ $r -ne 0 ]; then
+ fail "ssh-add -l via agent path fwd failed (exit code $r)"
+fi
${SSH} -A -F $OBJ/ssh_proxy somehost \
"${SSH} -F $OBJ/ssh_proxy somehost exit 52"
r=$?
@@ -93,9 +116,34 @@ if [ $r -ne 52 ]; then
fail "agent fwd failed (exit code $r)"
fi
+trace "agent forwarding different agent"
+${SSH} "-oForwardAgent=$FW_SSH_AUTH_SOCK" -F $OBJ/ssh_proxy somehost ${SSHADD} -l > /dev/null 2>&1
+r=$?
+if [ $r -ne 0 ]; then
+ fail "ssh-add -l via agent path fwd of different agent failed (exit code $r)"
+fi
+${SSH} '-oForwardAgent=$FW_SSH_AUTH_SOCK' -F $OBJ/ssh_proxy somehost ${SSHADD} -l > /dev/null 2>&1
+r=$?
+if [ $r -ne 0 ]; then
+ fail "ssh-add -l via agent path env fwd of different agent failed (exit code $r)"
+fi
+
+# Remove keys from forwarded agent, ssh-add on remote machine should now fail.
+SSH_AUTH_SOCK=$FW_SSH_AUTH_SOCK ${SSHADD} -D > /dev/null 2>&1
+r=$?
+if [ $r -ne 0 ]; then
+ fail "ssh-add -D failed: exit code $r"
+fi
+${SSH} '-oForwardAgent=$FW_SSH_AUTH_SOCK' -F $OBJ/ssh_proxy somehost ${SSHADD} -l > /dev/null 2>&1
+r=$?
+if [ $r -ne 1 ]; then
+ fail "ssh-add -l with different agent did not fail with exit code 1 (exit code $r)"
+fi
+
(printf 'cert-authority,principals="estragon" '; cat $OBJ/user_ca_key.pub) \
> $OBJ/authorized_keys_$USER
for t in ${SSH_KEYTYPES}; do
+ if [ "$t" != "ssh-dss" ]; then
trace "connect via agent using $t key"
${SSH} -F $OBJ/ssh_proxy -i $OBJ/$t-agent.pub \
-oCertificateFile=$OBJ/$t-agent-cert.pub \
@@ -104,14 +152,76 @@ for t in ${SSH_KEYTYPES}; do
if [ $r -ne 52 ]; then
fail "ssh connect with failed (exit code $r)"
fi
+ fi
done
+## Deletion tests.
+
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
+# make sure they're gone
+${SSHADD} -l > /dev/null 2>&1
+r=$?
+if [ $r -ne 1 ]; then
+ fail "ssh-add -l returned unexpected exit code: $r"
+fi
+trace "readd keys"
+# re-add keys/certs to agent
+for t in ${SSH_KEYTYPES}; do
+ ${SSHADD} $OBJ/$t-agent-private >/dev/null 2>&1 || \
+ fail "ssh-add failed exit code $?"
+done
+# make sure they are there
+${SSHADD} -l > /dev/null 2>&1
+r=$?
+if [ $r -ne 0 ]; then
+ fail "ssh-add -l failed: exit code $r"
+fi
+
+check_key_absent() {
+ ${SSHADD} -L | grep "^$1 " >/dev/null
+ if [ $? -eq 0 ]; then
+ fail "$1 key unexpectedly present"
+ fi
+}
+check_key_present() {
+ ${SSHADD} -L | grep "^$1 " >/dev/null
+ if [ $? -ne 0 ]; then
+ fail "$1 key missing from agent"
+ fi
+}
+
+# delete the ed25519 key
+trace "delete single key by file"
+${SSHADD} -qdk $OBJ/ssh-ed25519-agent || fail "ssh-add -d ed25519 failed"
+check_key_absent ssh-ed25519
+check_key_present ssh-ed25519-cert-v01@openssh.com
+# Put key/cert back.
+${SSHADD} $OBJ/ssh-ed25519-agent-private >/dev/null 2>&1 || \
+ fail "ssh-add failed exit code $?"
+check_key_present ssh-ed25519
+# Delete both key and certificate.
+trace "delete key/cert by file"
+${SSHADD} -qd $OBJ/ssh-ed25519-agent || fail "ssh-add -d ed25519 failed"
+check_key_absent ssh-ed25519
+check_key_absent ssh-ed25519-cert-v01@openssh.com
+# Put key/cert back.
+${SSHADD} $OBJ/ssh-ed25519-agent-private >/dev/null 2>&1 || \
+ fail "ssh-add failed exit code $?"
+check_key_present ssh-ed25519
+# Delete certificate via stdin
+${SSHADD} -qd - < $OBJ/ssh-ed25519-agent-cert.pub || fail "ssh-add -d - failed"
+check_key_present ssh-ed25519
+check_key_absent ssh-ed25519-cert-v01@openssh.com
+# Delete key via stdin
+${SSHADD} -qd - < $OBJ/ssh-ed25519-agent.pub || fail "ssh-add -d - failed"
+check_key_absent ssh-ed25519
+check_key_absent ssh-ed25519-cert-v01@openssh.com
trace "kill agent"
${SSHAGENT} -k > /dev/null
+SSH_AGENT_PID=$FW_SSH_AGENT_PID ${SSHAGENT} -k > /dev/null
diff --git a/crypto/openssh/regress/allow-deny-users.sh b/crypto/openssh/regress/allow-deny-users.sh
index 5c389512247c..6c053eef0882 100644
--- a/crypto/openssh/regress/allow-deny-users.sh
+++ b/crypto/openssh/regress/allow-deny-users.sh
@@ -1,6 +1,6 @@
# Public Domain
# Zev Weiss, 2016
-# $OpenBSD: allow-deny-users.sh,v 1.5 2018/07/13 02:13:50 djm Exp $
+# $OpenBSD: allow-deny-users.sh,v 1.6 2021/06/07 00:00:50 djm Exp $
tid="AllowUsers/DenyUsers"
@@ -20,10 +20,8 @@ test_auth()
failmsg="$4"
cp $OBJ/sshd_proxy.orig $OBJ/sshd_proxy
- echo DenyUsers="$deny" >> $OBJ/sshd_proxy
- echo AllowUsers="$allow" >> $OBJ/sshd_proxy
-
- start_sshd -oDenyUsers="$deny" -oAllowUsers="$allow"
+ test -z "$deny" || echo DenyUsers="$deny" >> $OBJ/sshd_proxy
+ test -z "$allow" || echo AllowUsers="$allow" >> $OBJ/sshd_proxy
${SSH} -F $OBJ/ssh_proxy "$me@somehost" true
status=$?
diff --git a/crypto/openssh/regress/banner.sh b/crypto/openssh/regress/banner.sh
index 0d9654fe247a..a84feb5ad7c1 100644
--- a/crypto/openssh/regress/banner.sh
+++ b/crypto/openssh/regress/banner.sh
@@ -1,4 +1,4 @@
-# $OpenBSD: banner.sh,v 1.3 2017/04/30 23:34:55 djm Exp $
+# $OpenBSD: banner.sh,v 1.4 2021/08/08 06:38:33 dtucker Exp $
# Placed in the Public Domain.
tid="banner"
@@ -37,7 +37,9 @@ done
trace "test suppress banner (-q)"
verbose "test $tid: suppress banner (-q)"
-( ${SSH} -q -F $OBJ/ssh_proxy otherhost true 2>$OBJ/banner.out && \
+# ssh-log-wrapper drops "-q" to preserve debug output so use ssh directly
+# for just this test.
+( ${REAL_SSH} -q -F $OBJ/ssh_proxy otherhost true 2>$OBJ/banner.out && \
cmp $OBJ/empty.in $OBJ/banner.out ) || \
fail "suppress banner (-q)"
diff --git a/crypto/openssh/regress/cert-file.sh b/crypto/openssh/regress/cert-file.sh
index 1157a3582e5f..94e672a99b6c 100755..100644
--- a/crypto/openssh/regress/cert-file.sh
+++ b/crypto/openssh/regress/cert-file.sh
@@ -1,4 +1,4 @@
-# $OpenBSD: cert-file.sh,v 1.7 2018/04/10 00:14:10 djm Exp $
+# $OpenBSD: cert-file.sh,v 1.8 2019/11/26 23:43:10 djm Exp $
# Placed in the Public Domain.
tid="ssh with certificates"
@@ -120,7 +120,7 @@ if [ $? -ne 2 ]; then
fi
trace "start agent"
-eval `${SSHAGENT} -s` > /dev/null
+eval `${SSHAGENT} ${EXTRA_AGENT_ARGS} -s` > /dev/null
r=$?
if [ $r -ne 0 ]; then
fatal "could not start ssh-agent: exit code $r"
diff --git a/crypto/openssh/regress/cert-hostkey.sh b/crypto/openssh/regress/cert-hostkey.sh
index d2ecd318beae..de8652b0e5e2 100755..100644
--- a/crypto/openssh/regress/cert-hostkey.sh
+++ b/crypto/openssh/regress/cert-hostkey.sh
@@ -1,4 +1,4 @@
-# $OpenBSD: cert-hostkey.sh,v 1.16 2018/07/03 11:43:49 djm Exp $
+# $OpenBSD: cert-hostkey.sh,v 1.25 2021/06/08 22:30:27 djm Exp $
# Placed in the Public Domain.
tid="certified host keys"
@@ -7,8 +7,9 @@ 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
+rsa=0
types=""
-for i in `$SSH -Q key`; do
+for i in `$SSH -Q key | maybe_filter_sk`; do
if [ -z "$types" ]; then
types="$i"
continue
@@ -19,6 +20,7 @@ for i in `$SSH -Q key`; do
types="rsa-sha2-256-cert-v01@openssh.com,$i,$types"
types="rsa-sha2-512-cert-v01@openssh.com,$types";;
*rsa*)
+ rsa=1
types="$types,rsa-sha2-512,rsa-sha2-256,$i";;
# Prefer certificate to plain keys.
*cert*) types="$i,$types";;
@@ -27,12 +29,12 @@ for i in `$SSH -Q key`; do
done
(
echo "HostKeyAlgorithms ${types}"
- echo "PubkeyAcceptedKeyTypes *"
+ echo "PubkeyAcceptedAlgorithms *"
) >> $OBJ/ssh_proxy
cp $OBJ/sshd_proxy $OBJ/sshd_proxy_bak
(
echo "HostKeyAlgorithms *"
- echo "PubkeyAcceptedKeyTypes *"
+ echo "PubkeyAcceptedAlgorithms *"
) >> $OBJ/sshd_proxy_bak
HOSTS='localhost-with-alias,127.0.0.1,::1'
@@ -51,10 +53,12 @@ kh_revoke() {
}
# Create a CA key and add it to known hosts. Ed25519 chosen for speed.
-# RSA for testing RSA/SHA2 signatures.
+# RSA for testing RSA/SHA2 signatures if supported.
+ktype2=ed25519
+[ "x$rsa" = "x1" ] && ktype2=rsa
${SSHKEYGEN} -q -N '' -t ed25519 -f $OBJ/host_ca_key ||\
fail "ssh-keygen of host_ca_key failed"
-${SSHKEYGEN} -q -N '' -t rsa -f $OBJ/host_ca_key2 ||\
+${SSHKEYGEN} -q -N '' -t $ktype2 -f $OBJ/host_ca_key2 ||\
fail "ssh-keygen of host_ca_key failed"
kh_ca host_ca_key.pub host_ca_key2.pub > $OBJ/known_hosts-cert.orig
@@ -66,7 +70,7 @@ touch $OBJ/host_revoked_plain
touch $OBJ/host_revoked_cert
cat $OBJ/host_ca_key.pub $OBJ/host_ca_key2.pub > $OBJ/host_revoked_ca
-PLAIN_TYPES=`$SSH -Q key-plain | sed 's/^ssh-dss/ssh-dsa/g;s/^ssh-//'`
+PLAIN_TYPES=`echo "$SSH_KEYTYPES" | sed 's/^ssh-dss/ssh-dsa/g;s/^ssh-//'`
if echo "$PLAIN_TYPES" | grep '^rsa$' >/dev/null 2>&1 ; then
PLAIN_TYPES="$PLAIN_TYPES rsa-sha2-256 rsa-sha2-512"
@@ -127,7 +131,7 @@ attempt_connect() {
}
# Basic connect and revocation tests.
-for privsep in yes no ; do
+for privsep in yes ; do
for ktype in $PLAIN_TYPES ; do
verbose "$tid: host ${ktype} cert connect privsep $privsep"
(
@@ -165,7 +169,7 @@ for ktype in $PLAIN_TYPES ; do
kh_revoke cert_host_key_${ktype}.pub >> $OBJ/known_hosts-cert.orig
done
cp $OBJ/known_hosts-cert.orig $OBJ/known_hosts-cert
-for privsep in yes no ; do
+for privsep in yes ; do
for ktype in $PLAIN_TYPES ; do
verbose "$tid: host ${ktype} revoked cert privsep $privsep"
(
@@ -214,7 +218,7 @@ test_one() {
result=$2
sign_opts=$3
- for kt in rsa ed25519 ; do
+ for kt in $PLAIN_TYPES; do
case $ktype in
rsa-sha2-*) tflag="-t $ktype"; ca="$OBJ/host_ca_key2" ;;
*) tflag=""; ca="$OBJ/host_ca_key" ;;
@@ -248,7 +252,7 @@ test_one() {
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 not yet valid" failure "-h -V20300101:20320101"
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"
@@ -279,11 +283,17 @@ for ktype in $PLAIN_TYPES ; do
) > $OBJ/sshd_proxy
${SSH} -oUserKnownHostsFile=$OBJ/known_hosts-cert \
- -oGlobalKnownHostsFile=$OBJ/known_hosts-cert \
- -F $OBJ/ssh_proxy somehost true
+ -oGlobalKnownHostsFile=none -F $OBJ/ssh_proxy somehost true
if [ $? -ne 0 ]; then
fail "ssh cert connect failed"
fi
+ # Also check that it works when the known_hosts file is not in the
+ # first array position.
+ ${SSH} -oUserKnownHostsFile="/dev/null $OBJ/known_hosts-cert" \
+ -oGlobalKnownHostsFile=none -F $OBJ/ssh_proxy somehost true
+ if [ $? -ne 0 ]; then
+ fail "ssh cert connect failed known_hosts 2nd"
+ fi
done
# Wrong certificate
diff --git a/crypto/openssh/regress/cert-userkey.sh b/crypto/openssh/regress/cert-userkey.sh
index 30c2c156d2f1..baa6903ea268 100755..100644
--- a/crypto/openssh/regress/cert-userkey.sh
+++ b/crypto/openssh/regress/cert-userkey.sh
@@ -1,4 +1,4 @@
-# $OpenBSD: cert-userkey.sh,v 1.19 2018/03/12 00:54:04 djm Exp $
+# $OpenBSD: cert-userkey.sh,v 1.26 2021/02/25 03:27:34 djm Exp $
# Placed in the Public Domain.
tid="certified user keys"
@@ -7,24 +7,37 @@ 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-//'`
+PLAIN_TYPES=`$SSH -Q key-plain | maybe_filter_sk | sed 's/^ssh-dss/ssh-dsa/;s/^ssh-//'`
EXTRA_TYPES=""
+rsa=""
if echo "$PLAIN_TYPES" | grep '^rsa$' >/dev/null 2>&1 ; then
+ rsa=rsa
PLAIN_TYPES="$PLAIN_TYPES rsa-sha2-256 rsa-sha2-512"
fi
kname() {
- case $ktype in
- rsa-sha2-*) n="$ktype" ;;
+ case $1 in
+ rsa-sha2-*) n="$1" ;;
+ sk-ecdsa-*) n="sk-ecdsa" ;;
+ sk-ssh-ed25519*) n="sk-ssh-ed25519" ;;
# subshell because some seds will add a newline
*) n=$(echo $1 | sed 's/^dsa/ssh-dss/;s/^rsa/ssh-rsa/;s/^ed/ssh-ed/') ;;
esac
- echo "$n*,ssh-rsa*,ssh-ed25519*"
+ if [ -z "$rsa" ]; then
+ echo "$n*,ssh-ed25519*"
+ else
+ echo "$n*,ssh-rsa*,ssh-ed25519*"
+ fi
}
# Create a CA key
-${SSHKEYGEN} -q -N '' -t rsa -f $OBJ/user_ca_key ||\
+if [ ! -z "$rsa" ]; then
+ catype=rsa
+else
+ catype=ed25519
+fi
+${SSHKEYGEN} -q -N '' -t $catype -f $OBJ/user_ca_key ||\
fail "ssh-keygen of user_ca_key failed"
# Generate and sign user keys
@@ -47,7 +60,7 @@ done
# Test explicitly-specified principals
for ktype in $EXTRA_TYPES $PLAIN_TYPES ; do
t=$(kname $ktype)
- for privsep in yes no ; do
+ for privsep in yes ; do
_prefix="${ktype} privsep $privsep"
# Setup for AuthorizedPrincipalsFile
@@ -58,11 +71,11 @@ for ktype in $EXTRA_TYPES $PLAIN_TYPES ; do
echo "AuthorizedPrincipalsFile " \
"$OBJ/authorized_principals_%u"
echo "TrustedUserCAKeys $OBJ/user_ca_key.pub"
- echo "PubkeyAcceptedKeyTypes ${t}"
+ echo "PubkeyAcceptedAlgorithms ${t}"
) > $OBJ/sshd_proxy
(
cat $OBJ/ssh_proxy_bak
- echo "PubkeyAcceptedKeyTypes ${t}"
+ echo "PubkeyAcceptedAlgorithms ${t}"
) > $OBJ/ssh_proxy
# Missing authorized_principals
@@ -136,11 +149,11 @@ for ktype in $EXTRA_TYPES $PLAIN_TYPES ; do
(
cat $OBJ/sshd_proxy_bak
echo "UsePrivilegeSeparation $privsep"
- echo "PubkeyAcceptedKeyTypes ${t}"
+ echo "PubkeyAcceptedAlgorithms ${t}"
) > $OBJ/sshd_proxy
(
cat $OBJ/ssh_proxy_bak
- echo "PubkeyAcceptedKeyTypes ${t}"
+ echo "PubkeyAcceptedAlgorithms ${t}"
) > $OBJ/ssh_proxy
# Wrong principals list
@@ -184,19 +197,19 @@ basic_tests() {
for ktype in $PLAIN_TYPES ; do
t=$(kname $ktype)
- for privsep in yes no ; do
+ for privsep in yes ; do
_prefix="${ktype} privsep $privsep $auth"
# Simple connect
verbose "$tid: ${_prefix} connect"
(
cat $OBJ/sshd_proxy_bak
echo "UsePrivilegeSeparation $privsep"
- echo "PubkeyAcceptedKeyTypes ${t}"
+ echo "PubkeyAcceptedAlgorithms ${t}"
echo "$extra_sshd"
) > $OBJ/sshd_proxy
(
cat $OBJ/ssh_proxy_bak
- echo "PubkeyAcceptedKeyTypes ${t}"
+ echo "PubkeyAcceptedAlgorithms ${t}"
) > $OBJ/ssh_proxy
${SSH} -i $OBJ/cert_user_key_${ktype} \
@@ -211,7 +224,7 @@ basic_tests() {
cat $OBJ/sshd_proxy_bak
echo "UsePrivilegeSeparation $privsep"
echo "RevokedKeys $OBJ/cert_user_key_revoked"
- echo "PubkeyAcceptedKeyTypes ${t}"
+ echo "PubkeyAcceptedAlgorithms ${t}"
echo "$extra_sshd"
) > $OBJ/sshd_proxy
cp $OBJ/cert_user_key_${ktype}.pub \
@@ -244,7 +257,7 @@ basic_tests() {
(
cat $OBJ/sshd_proxy_bak
echo "RevokedKeys $OBJ/user_ca_key.pub"
- echo "PubkeyAcceptedKeyTypes ${t}"
+ echo "PubkeyAcceptedAlgorithms ${t}"
echo "$extra_sshd"
) > $OBJ/sshd_proxy
${SSH} -i $OBJ/cert_user_key_${ktype} -F $OBJ/ssh_proxy \
@@ -257,7 +270,7 @@ basic_tests() {
verbose "$tid: $auth CA does not authenticate"
(
cat $OBJ/sshd_proxy_bak
- echo "PubkeyAcceptedKeyTypes ${t}"
+ echo "PubkeyAcceptedAlgorithms ${t}"
echo "$extra_sshd"
) > $OBJ/sshd_proxy
verbose "$tid: ensure CA key does not authenticate user"
@@ -283,7 +296,7 @@ test_one() {
fi
for auth in $auth_choice ; do
- for ktype in rsa ed25519 ; 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
@@ -295,7 +308,7 @@ test_one() {
echo > $OBJ/authorized_keys_$USER
echo "TrustedUserCAKeys $OBJ/user_ca_key.pub" \
>> $OBJ/sshd_proxy
- echo "PubkeyAcceptedKeyTypes ${t}*" \
+ echo "PubkeyAcceptedAlgorithms ${t}*" \
>> $OBJ/sshd_proxy
if test "x$auth_opt" != "x" ; then
echo $auth_opt >> $OBJ/sshd_proxy
@@ -327,7 +340,7 @@ test_one() {
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 not yet valid" failure "-n ${USER} -V20300101:20320101"
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"
diff --git a/crypto/openssh/regress/cfginclude.sh b/crypto/openssh/regress/cfginclude.sh
index 2fc39ce45b8a..f5b492f17867 100644
--- a/crypto/openssh/regress/cfginclude.sh
+++ b/crypto/openssh/regress/cfginclude.sh
@@ -1,4 +1,4 @@
-# $OpenBSD: cfginclude.sh,v 1.2 2016/05/03 15:30:46 dtucker Exp $
+# $OpenBSD: cfginclude.sh,v 1.3 2021/06/08 06:52:43 djm Exp $
# Placed in the Public Domain.
tid="config include"
@@ -10,7 +10,7 @@ cat > $OBJ/ssh_config.i << _EOF
Match host a
Hostname aa
-Match host b
+Match host b # comment
Hostname bb
Include $OBJ/ssh_config.i.*
@@ -19,10 +19,10 @@ Match host c
Hostname cc
Match host m
- Include $OBJ/ssh_config.i.*
+ Include $OBJ/ssh_config.i.* # comment
Host d
- Hostname dd
+ Hostname dd # comment
Host e
Hostname ee
@@ -47,17 +47,17 @@ Match host a
Match host b
Hostname bbb
-Match host c
+Match host c # comment
Hostname ccc
-Host d
+Host d # comment
Hostname ddd
Host e
Hostname eee
Host f
- Hostname fff
+ Hostname fff # comment
_EOF
cat > $OBJ/ssh_config.i.2 << _EOF
@@ -142,7 +142,7 @@ trial a aa
# cleanup
rm -f $OBJ/ssh_config.i $OBJ/ssh_config.i.* $OBJ/ssh_config.out
-# $OpenBSD: cfginclude.sh,v 1.2 2016/05/03 15:30:46 dtucker Exp $
+# $OpenBSD: cfginclude.sh,v 1.3 2021/06/08 06:52:43 djm Exp $
# Placed in the Public Domain.
tid="config include"
@@ -185,11 +185,11 @@ cat > $OBJ/ssh_config.i.1 << _EOF
Match host a
Hostname aaa
-Match host b
+Match host b # comment
Hostname bbb
Match host c
- Hostname ccc
+ Hostname ccc # comment
Host d
Hostname ddd
@@ -220,8 +220,8 @@ Host e
Host f
Hostname ffff
-Match all
- Hostname xxxx
+Match all # comment
+ Hostname xxxx # comment
_EOF
trial() {
diff --git a/crypto/openssh/regress/cfgmatch.sh b/crypto/openssh/regress/cfgmatch.sh
index dd11e404dc4f..05a6668551a9 100644
--- a/crypto/openssh/regress/cfgmatch.sh
+++ b/crypto/openssh/regress/cfgmatch.sh
@@ -1,4 +1,4 @@
-# $OpenBSD: cfgmatch.sh,v 1.11 2017/10/04 18:50:23 djm Exp $
+# $OpenBSD: cfgmatch.sh,v 1.13 2021/06/08 06:52:43 djm Exp $
# Placed in the Public Domain.
tid="sshd_config match"
@@ -39,21 +39,22 @@ stop_client()
}
cp $OBJ/sshd_proxy $OBJ/sshd_proxy_bak
-echo "PermitOpen 127.0.0.1:1" >>$OBJ/sshd_config
+echo "PermitOpen 127.0.0.1:1 # comment" >>$OBJ/sshd_config
echo "Match Address 127.0.0.1" >>$OBJ/sshd_config
echo "PermitOpen 127.0.0.1:2 127.0.0.1:3 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 "AuthorizedKeysFile /dev/null # comment" >>$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 "Match Address 127.0.0.1 # comment" >>$OBJ/sshd_proxy
echo "PermitOpen 127.0.0.1:2 127.0.0.1:3 127.0.0.1:$PORT" >>$OBJ/sshd_proxy
-start_sshd
+${SUDO} ${SSHD} -f $OBJ/sshd_config -T >/dev/null || \
+ fail "config w/match fails config test"
-#set -x
+start_sshd
# Test Match + PermitOpen in sshd_config. This should be permitted
trace "match permitopen localhost"
@@ -113,3 +114,45 @@ start_client -F $OBJ/ssh_proxy
${SSH} -q -p $fwdport -F $OBJ/ssh_config somehost true || \
fail "nomatch override permitopen"
stop_client
+
+# Test parsing of available Match criteria (with the exception of Group which
+# requires knowledge of actual group memberships user running the test).
+params="user:user:u1 host:host:h1 address:addr:1.2.3.4 \
+ localaddress:laddr:5.6.7.8 rdomain:rdomain:rdom1"
+cp $OBJ/sshd_proxy_bak $OBJ/sshd_config
+echo 'Banner /nomatch' >>$OBJ/sshd_config
+for i in $params; do
+ config=`echo $i | cut -f1 -d:`
+ criteria=`echo $i | cut -f2 -d:`
+ value=`echo $i | cut -f3 -d:`
+ cat >>$OBJ/sshd_config <<EOD
+ Match $config $value
+ Banner /$value
+EOD
+done
+
+${SUDO} ${SSHD} -f $OBJ/sshd_config -T >/dev/null || \
+ fail "validate config for w/out spec"
+
+# Test matching each criteria.
+for i in $params; do
+ testcriteria=`echo $i | cut -f2 -d:`
+ expected=/`echo $i | cut -f3 -d:`
+ spec=""
+ for j in $params; do
+ config=`echo $j | cut -f1 -d:`
+ criteria=`echo $j | cut -f2 -d:`
+ value=`echo $j | cut -f3 -d:`
+ if [ "$criteria" = "$testcriteria" ]; then
+ spec="$criteria=$value,$spec"
+ else
+ spec="$criteria=1$value,$spec"
+ fi
+ done
+ trace "test spec $spec"
+ result=`${SUDO} ${SSHD} -f $OBJ/sshd_config -T -C "$spec" | \
+ awk '$1=="banner"{print $2}'`
+ if [ "$result" != "$expected" ]; then
+ fail "match $config expected $expected got $result"
+ fi
+done
diff --git a/crypto/openssh/regress/cfgparse.sh b/crypto/openssh/regress/cfgparse.sh
index a9e5c6b09ee2..a9e5c6b09ee2 100755..100644
--- a/crypto/openssh/regress/cfgparse.sh
+++ b/crypto/openssh/regress/cfgparse.sh
diff --git a/crypto/openssh/regress/conch-ciphers.sh b/crypto/openssh/regress/conch-ciphers.sh
index 199d863a0dcd..6678813a2bdb 100755..100644
--- a/crypto/openssh/regress/conch-ciphers.sh
+++ b/crypto/openssh/regress/conch-ciphers.sh
@@ -1,4 +1,4 @@
-# $OpenBSD: conch-ciphers.sh,v 1.3 2013/05/17 04:29:14 dtucker Exp $
+# $OpenBSD: conch-ciphers.sh,v 1.4 2019/07/05 04:12:46 dtucker Exp $
# Placed in the Public Domain.
tid="conch ciphers"
@@ -16,7 +16,7 @@ for c in aes256-ctr aes256-cbc aes192-ctr aes192-cbc aes128-ctr aes128-cbc \
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 \
+ ${CONCH} --identity $OBJ/ssh-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
diff --git a/crypto/openssh/regress/connect-privsep.sh b/crypto/openssh/regress/connect-privsep.sh
index b6abb65e3566..8970340a29c4 100644
--- a/crypto/openssh/regress/connect-privsep.sh
+++ b/crypto/openssh/regress/connect-privsep.sh
@@ -16,13 +16,12 @@ echo 'UsePrivilegeSeparation sandbox' >> $OBJ/sshd_proxy
${SSH} -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 failed"
+ fail "ssh privsep/sandbox+proxyconnect failed"
fi
# Because sandbox is sensitive to changes in libc, especially malloc, retest
# with every malloc.conf option (and none).
-if [ -z "TEST_MALLOC_OPTIONS" ]; then
+if [ -z "$TEST_MALLOC_OPTIONS" ]; then
mopts="C F G J R S U X < >"
else
mopts=`echo $TEST_MALLOC_OPTIONS | sed 's/./& /g'`
diff --git a/crypto/openssh/regress/connect.sh b/crypto/openssh/regress/connect.sh
index 1b344b6034e9..46f12b7b3c92 100644
--- a/crypto/openssh/regress/connect.sh
+++ b/crypto/openssh/regress/connect.sh
@@ -1,11 +1,18 @@
-# $OpenBSD: connect.sh,v 1.6 2017/04/30 23:34:55 djm Exp $
+# $OpenBSD: connect.sh,v 1.8 2020/01/25 02:57:53 dtucker Exp $
# Placed in the Public Domain.
tid="simple connect"
start_sshd
+trace "direct connect"
${SSH} -F $OBJ/ssh_config somehost true
if [ $? -ne 0 ]; then
- fail "ssh connect with failed"
+ fail "ssh direct connect failed"
+fi
+
+trace "proxy connect"
+${SSH} -F $OBJ/ssh_config -o "proxycommand $NC %h %p" somehost true
+if [ $? -ne 0 ]; then
+ fail "ssh proxycommand connect failed"
fi
diff --git a/crypto/openssh/regress/dhgex.sh b/crypto/openssh/regress/dhgex.sh
index 61fc178e890c..6dd4cfe3f94a 100755..100644
--- a/crypto/openssh/regress/dhgex.sh
+++ b/crypto/openssh/regress/dhgex.sh
@@ -1,4 +1,4 @@
-# $OpenBSD: dhgex.sh,v 1.4 2017/05/08 01:52:49 djm Exp $
+# $OpenBSD: dhgex.sh,v 1.7 2020/12/21 22:48:41 dtucker Exp $
# Placed in the Public Domain.
tid="dhgex"
@@ -34,9 +34,11 @@ ssh_test_dhgex()
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
+ # check what we got.
+ gotbits="`awk 'BEGIN{FS="/"}/bits set:/{print $2}' ${LOG} |
+ head -1 | tr -d '\r\n'`"
+ trace "expected '$bits' got '$gotbits'"
+ if [ -z "$gotbits" ] || [ "$gotbits" -lt "$bits" ]; then
fatal "$tid expected $bits bit group, got $gotbits"
fi
}
@@ -52,8 +54,8 @@ check()
done
}
-#check 2048 3des-cbc
+check 3072 3des-cbc # 112 bits.
check 3072 `${SSH} -Q cipher | grep 128`
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
+check 8192 chacha20-poly1305@openssh.com
diff --git a/crypto/openssh/regress/ed25519_openssh.prv b/crypto/openssh/regress/ed25519_openssh.prv
new file mode 100644
index 000000000000..9f191b778962
--- /dev/null
+++ b/crypto/openssh/regress/ed25519_openssh.prv
@@ -0,0 +1,7 @@
+-----BEGIN OPENSSH PRIVATE KEY-----
+b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW
+QyNTUxOQAAACDE8/0FM7Yw6xc53QpiZUQAh/LK2mEAwNDNYdSR6GIGIwAAAKC+Cfdzvgn3
+cwAAAAtzc2gtZWQyNTUxOQAAACDE8/0FM7Yw6xc53QpiZUQAh/LK2mEAwNDNYdSR6GIGIw
+AAAEBm+60DgH0WMW7Z5oyvu1dxo7MaXe5RRMWTMJCfLkHexMTz/QUztjDrFzndCmJlRACH
+8sraYQDA0M1h1JHoYgYjAAAAGWR0dWNrZXJAcXVvbGwuZHR1Y2tlci5uZXQBAgME
+-----END OPENSSH PRIVATE KEY-----
diff --git a/crypto/openssh/regress/ed25519_openssh.pub b/crypto/openssh/regress/ed25519_openssh.pub
new file mode 100644
index 000000000000..910363138658
--- /dev/null
+++ b/crypto/openssh/regress/ed25519_openssh.pub
@@ -0,0 +1 @@
+ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMTz/QUztjDrFzndCmJlRACH8sraYQDA0M1h1JHoYgYj
diff --git a/crypto/openssh/regress/forward-control.sh b/crypto/openssh/regress/forward-control.sh
index 3b1f69a71e56..02f7667a665b 100755..100644
--- a/crypto/openssh/regress/forward-control.sh
+++ b/crypto/openssh/regress/forward-control.sh
@@ -1,4 +1,4 @@
-# $OpenBSD: forward-control.sh,v 1.7 2018/06/07 14:29:43 djm Exp $
+# $OpenBSD: forward-control.sh,v 1.8 2021/05/07 09:23:40 dtucker Exp $
# Placed in the Public Domain.
tid="sshd control of local and remote forwarding"
@@ -46,7 +46,7 @@ check_lfwd() {
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
+ -oConnectionAttempts=10 host true >/dev/null 2>&1
_result=$?
kill $_sshpid `cat $READY` 2>/dev/null
wait_for_process_to_exit $_sshpid
@@ -76,7 +76,7 @@ check_rfwd() {
_result=$?
if test $_result -eq 0 ; then
${SSH} -F $OBJ/ssh_config -p $RFWD_PORT \
- -oConnectionAttempts=4 host true >/dev/null 2>&1
+ -oConnectionAttempts=10 host true >/dev/null 2>&1
_result=$?
kill $_sshpid `cat $READY` 2>/dev/null
wait_for_process_to_exit $_sshpid
diff --git a/crypto/openssh/regress/forwarding.sh b/crypto/openssh/regress/forwarding.sh
index 7d0fae114697..a72bd3a05cfa 100644
--- a/crypto/openssh/regress/forwarding.sh
+++ b/crypto/openssh/regress/forwarding.sh
@@ -1,4 +1,4 @@
-# $OpenBSD: forwarding.sh,v 1.20 2017/04/30 23:34:55 djm Exp $
+# $OpenBSD: forwarding.sh,v 1.24 2021/05/07 09:23:40 dtucker Exp $
# Placed in the Public Domain.
tid="local and remote forwarding"
@@ -26,15 +26,15 @@ done
trace "start forwarding, fork to background"
rm -f $CTL
-${SSH} -S $CTL -M -F $OBJ/ssh_config -f $fwd somehost sleep 10
+${SSH} -S $CTL -N -M -F $OBJ/ssh_config -f $fwd somehost
trace "transfer over forwarded channels and check result"
-${SSH} -F $OBJ/ssh_config -p$last -o 'ConnectionAttempts=4' \
+${SSH} -F $OBJ/ssh_config -p$last -o 'ConnectionAttempts=10' \
somehost cat ${DATA} > ${COPY}
test -s ${COPY} || fail "failed copy of ${DATA}"
cmp ${DATA} ${COPY} || fail "corrupted copy of ${DATA}"
-${SSH} -F $OBJ/ssh_config -S $CTL -O exit somehost
+${SSH} -F $OBJ/ssh_config -S $CTL -O exit somehost 2>/dev/null
for d in L R; do
trace "exit on -$d forward failure"
@@ -69,8 +69,8 @@ ${SSH} -F $OBJ/ssh_config -oClearAllForwardings=yes somehost true
trace "clear local forward"
rm -f $CTL
-${SSH} -S $CTL -M -f -F $OBJ/ssh_config -L ${base}01:127.0.0.1:$PORT \
- -oClearAllForwardings=yes somehost sleep 10
+${SSH} -S $CTL -N -M -f -F $OBJ/ssh_config -L ${base}01:127.0.0.1:$PORT \
+ -oClearAllForwardings=yes somehost
if [ $? != 0 ]; then
fail "connection failed with cleared local forwarding"
else
@@ -79,12 +79,12 @@ else
>>$TEST_REGRESS_LOGFILE 2>&1 && \
fail "local forwarding not cleared"
fi
-${SSH} -F $OBJ/ssh_config -S $CTL -O exit somehost
+${SSH} -F $OBJ/ssh_config -S $CTL -O exit somehost 2>/dev/null
trace "clear remote forward"
rm -f $CTL
-${SSH} -S $CTL -M -f -F $OBJ/ssh_config -R ${base}01:127.0.0.1:$PORT \
- -oClearAllForwardings=yes somehost sleep 10
+${SSH} -S $CTL -N -M -f -F $OBJ/ssh_config -R ${base}01:127.0.0.1:$PORT \
+ -oClearAllForwardings=yes somehost
if [ $? != 0 ]; then
fail "connection failed with cleared remote forwarding"
else
@@ -93,7 +93,7 @@ else
>>$TEST_REGRESS_LOGFILE 2>&1 && \
fail "remote forwarding not cleared"
fi
-${SSH} -F $OBJ/ssh_config -S $CTL -O exit somehost
+${SSH} -F $OBJ/ssh_config -S $CTL -O exit somehost 2>/dev/null
trace "stdio forwarding"
cmd="${SSH} -F $OBJ/ssh_config"
@@ -107,30 +107,30 @@ echo "RemoteForward ${base}02 127.0.0.1:${base}01" >> $OBJ/ssh_config
trace "config file: start forwarding, fork to background"
rm -f $CTL
-${SSH} -S $CTL -M -F $OBJ/ssh_config -f somehost sleep 10
+${SSH} -S $CTL -N -M -F $OBJ/ssh_config -f somehost
trace "config file: transfer over forwarded channels and check result"
-${SSH} -F $OBJ/ssh_config -p${base}02 -o 'ConnectionAttempts=4' \
+${SSH} -F $OBJ/ssh_config -p${base}02 -o 'ConnectionAttempts=10' \
somehost cat ${DATA} > ${COPY}
test -s ${COPY} || fail "failed copy of ${DATA}"
cmp ${DATA} ${COPY} || fail "corrupted copy of ${DATA}"
-${SSH} -F $OBJ/ssh_config -S $CTL -O exit somehost
+${SSH} -F $OBJ/ssh_config -S $CTL -O exit somehost 2>/dev/null
trace "transfer over chained unix domain socket forwards and check result"
rm -f $OBJ/unix-[123].fwd
rm -f $CTL $CTL.[123]
-${SSH} -S $CTL -M -f -F $OBJ/ssh_config -R${base}01:[$OBJ/unix-1.fwd] somehost sleep 10
-${SSH} -S $CTL.1 -M -f -F $OBJ/ssh_config -L[$OBJ/unix-1.fwd]:[$OBJ/unix-2.fwd] somehost sleep 10
-${SSH} -S $CTL.2 -M -f -F $OBJ/ssh_config -R[$OBJ/unix-2.fwd]:[$OBJ/unix-3.fwd] somehost sleep 10
-${SSH} -S $CTL.3 -M -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' \
+${SSH} -S $CTL -N -M -f -F $OBJ/ssh_config -R${base}01:[$OBJ/unix-1.fwd] somehost
+${SSH} -S $CTL.1 -N -M -f -F $OBJ/ssh_config -L[$OBJ/unix-1.fwd]:[$OBJ/unix-2.fwd] somehost
+${SSH} -S $CTL.2 -N -M -f -F $OBJ/ssh_config -R[$OBJ/unix-2.fwd]:[$OBJ/unix-3.fwd] somehost
+${SSH} -S $CTL.3 -N -M -f -F $OBJ/ssh_config -L[$OBJ/unix-3.fwd]:127.0.0.1:$PORT somehost
+${SSH} -F $OBJ/ssh_config -p${base}01 -o 'ConnectionAttempts=10' \
somehost cat ${DATA} > ${COPY}
test -s ${COPY} || fail "failed copy ${DATA}"
cmp ${DATA} ${COPY} || fail "corrupted copy of ${DATA}"
-${SSH} -F $OBJ/ssh_config -S $CTL -O exit somehost
-${SSH} -F $OBJ/ssh_config -S $CTL.1 -O exit somehost
-${SSH} -F $OBJ/ssh_config -S $CTL.2 -O exit somehost
-${SSH} -F $OBJ/ssh_config -S $CTL.3 -O exit somehost
+${SSH} -F $OBJ/ssh_config -S $CTL -O exit somehost 2>/dev/null
+${SSH} -F $OBJ/ssh_config -S $CTL.1 -O exit somehost 2>/dev/null
+${SSH} -F $OBJ/ssh_config -S $CTL.2 -O exit somehost 2>/dev/null
+${SSH} -F $OBJ/ssh_config -S $CTL.3 -O exit somehost 2>/dev/null
diff --git a/crypto/openssh/regress/host-expand.sh b/crypto/openssh/regress/host-expand.sh
index 9444f7fb619e..9444f7fb619e 100755..100644
--- a/crypto/openssh/regress/host-expand.sh
+++ b/crypto/openssh/regress/host-expand.sh
diff --git a/crypto/openssh/regress/hostkey-agent.sh b/crypto/openssh/regress/hostkey-agent.sh
index 811b6b9ab25a..d6736e246501 100755..100644
--- a/crypto/openssh/regress/hostkey-agent.sh
+++ b/crypto/openssh/regress/hostkey-agent.sh
@@ -1,4 +1,4 @@
-# $OpenBSD: hostkey-agent.sh,v 1.7 2017/04/30 23:34:55 djm Exp $
+# $OpenBSD: hostkey-agent.sh,v 1.11 2019/12/16 02:39:05 djm Exp $
# Placed in the Public Domain.
tid="hostkey agent"
@@ -6,7 +6,7 @@ tid="hostkey agent"
rm -f $OBJ/agent-key.* $OBJ/ssh_proxy.orig $OBJ/known_hosts.orig
trace "start agent"
-eval `${SSHAGENT} -s` > /dev/null
+eval `${SSHAGENT} ${EXTRA_AGENT_ARGS} -s` > /dev/null
r=$?
[ $r -ne 0 ] && fatal "could not start ssh-agent: exit code $r"
@@ -14,7 +14,7 @@ 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
+for k in $SSH_KEYTYPES ; do
${SSHKEYGEN} -qt $k -f $OBJ/agent-key.$k -N '' || fatal "ssh-keygen $k"
(
printf 'localhost-with-alias,127.0.0.1,::1 '
@@ -30,8 +30,8 @@ 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
+for ps in yes; do
+ for k in $SSH_KEYTYPES ; do
verbose "key type $k privsep=$ps"
cp $OBJ/sshd_proxy.orig $OBJ/sshd_proxy
echo "UsePrivilegeSeparation $ps" >> $OBJ/sshd_proxy
diff --git a/crypto/openssh/regress/hostkey-rotate.sh b/crypto/openssh/regress/hostkey-rotate.sh
index d69de32557a6..2852c457c259 100755..100644
--- a/crypto/openssh/regress/hostkey-rotate.sh
+++ b/crypto/openssh/regress/hostkey-rotate.sh
@@ -1,26 +1,34 @@
-# $OpenBSD: hostkey-rotate.sh,v 1.5 2015/09/04 04:23:10 djm Exp $
+# $OpenBSD: hostkey-rotate.sh,v 1.9 2020/10/07 06:38:16 djm 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
+rm -f $OBJ/hkr.* $OBJ/ssh_proxy.orig $OBJ/ssh_proxy.orig
grep -vi 'hostkey' $OBJ/sshd_proxy > $OBJ/sshd_proxy.orig
+mv $OBJ/ssh_proxy $OBJ/ssh_proxy.orig
+grep -vi 'globalknownhostsfile' $OBJ/ssh_proxy.orig > $OBJ/ssh_proxy
echo "UpdateHostkeys=yes" >> $OBJ/ssh_proxy
+echo "GlobalKnownHostsFile=none" >> $OBJ/ssh_proxy
rm $OBJ/known_hosts
+# The "primary" key type is ed25519 since it's supported even when built
+# without OpenSSL. The secondary is RSA if it's supported.
+primary="ssh-ed25519"
+secondary="$primary"
+
trace "prepare hostkeys"
nkeys=0
all_algs=""
-for k in `${SSH} -Q key-plain` ; do
+for k in $SSH_HOSTKEY_TYPES; 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"
+ case "$k" in
+ ssh-rsa) secondary="ssh-rsa" ;;
+ esac
done
dossh() {
@@ -49,62 +57,68 @@ 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
+dossh -oHostKeyAlgorithms=$primary -oStrictHostKeyChecking=no
# Verify no additional keys learned
expect_nkeys 1 "unstrict connect keys"
-check_key_present ssh-ed25519 || fail "unstrict didn't learn key"
+check_key_present $primary || 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"
+for k in $SSH_HOSTKEY_TYPES; do
+ check_key_present $k || fail "didn't learn keytype $k"
+done
# Check each key type
-for k in `${SSH} -Q key-plain` ; do
+for k in $SSH_HOSTKEY_TYPES; 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"
+ check_key_present $k || fail "didn't learn $k correctly"
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"
+if [ "$primary" != "$secondary" ]; then
+ verbose "learn changed non-primary hostkey type=${secondary}"
+ mv $OBJ/hkr.${secondary}.pub $OBJ/hkr.${secondary}.pub.old
+ rm -f $OBJ/hkr.${secondary}
+ ${SSHKEYGEN} -qt ${secondary} -f $OBJ/hkr.${secondary} -N '' || \
+ fatal "ssh-keygen $secondary"
+ dossh -oStrictHostKeyChecking=yes -oHostKeyAlgorithms=$all_algs
+ # Check that the key was replaced
+ expect_nkeys $nkeys "learn hostkeys"
+ check_key_present ${secondary} $OBJ/hkr.${secondary}.pub.old && \
+ fail "old key present"
+ check_key_present ${secondary} || fail "didn't learn changed key"
+fi
# 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 ) \
+${SSHKEYGEN} -qt ${primary} -f $OBJ/hkr.${primary}-new -N '' || fatal "ssh-keygen ed25519"
+( cat $OBJ/sshd_proxy.orig ; echo HostKey $OBJ/hkr.${primary}-new ) \
> $OBJ/sshd_proxy
# Check new hostkey added
-dossh -oStrictHostKeyChecking=yes -oHostKeyAlgorithms=ssh-rsa,$all_algs
+dossh -oStrictHostKeyChecking=yes -oHostKeyAlgorithms=${primary},$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"
+check_key_present ${primary} || fail "current key missing"
+check_key_present ${primary} $OBJ/hkr.${primary}-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
+mv $OBJ/hkr.${primary}.pub $OBJ/hkr.${primary}.pub.old
+mv $OBJ/hkr.${primary}-new.pub $OBJ/hkr.${primary}.pub
+mv $OBJ/hkr.${primary}-new $OBJ/hkr.${primary}
# Check old hostkey removed
-dossh -oStrictHostKeyChecking=yes -oHostKeyAlgorithms=ssh-rsa,$all_algs
+dossh -oStrictHostKeyChecking=yes -oHostKeyAlgorithms=${primary},$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"
+check_key_present ${primary} $OBJ/hkr.${primary}.pub.old && fail "old key present"
+check_key_present ${primary} || fail "didn't learn changed key"
# Connect again, forcing rotated key
verbose "check rotate primary hostkey"
-dossh -oStrictHostKeyChecking=yes -oHostKeyAlgorithms=ssh-rsa
+dossh -oStrictHostKeyChecking=yes -oHostKeyAlgorithms=${primary}
expect_nkeys 1 "learn hostkeys"
-check_key_present ssh-rsa || fail "didn't learn changed key"
+check_key_present ${primary} || fail "didn't learn changed key"
diff --git a/crypto/openssh/regress/integrity.sh b/crypto/openssh/regress/integrity.sh
index 3eda40f0a3d3..bc030cb74f35 100755..100644
--- a/crypto/openssh/regress/integrity.sh
+++ b/crypto/openssh/regress/integrity.sh
@@ -1,4 +1,4 @@
-# $OpenBSD: integrity.sh,v 1.23 2017/04/30 23:34:55 djm Exp $
+# $OpenBSD: integrity.sh,v 1.24 2020/01/21 08:06:27 djm Exp $
# Placed in the Public Domain.
tid="integrity"
@@ -14,11 +14,11 @@ 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
+#echo "KexAlgorithms -diffie-hellman-group*" \
+# >> $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"
+cmd="$SUDO env SSH_SK_HELPER="$SSH_SK_HELPER" 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"
diff --git a/crypto/openssh/regress/kextype.sh b/crypto/openssh/regress/kextype.sh
index e27189904bbb..e27189904bbb 100755..100644
--- a/crypto/openssh/regress/kextype.sh
+++ b/crypto/openssh/regress/kextype.sh
diff --git a/crypto/openssh/regress/key-options.sh b/crypto/openssh/regress/key-options.sh
index 112c9bd8ec5c..2f3d66e2e9ea 100755..100644
--- a/crypto/openssh/regress/key-options.sh
+++ b/crypto/openssh/regress/key-options.sh
@@ -7,6 +7,12 @@ origkeys="$OBJ/authkeys_orig"
authkeys="$OBJ/authorized_keys_${USER}"
cp $authkeys $origkeys
+# Allocating ptys can require privileges on some platforms.
+skip_pty=""
+if ! config_defined HAVE_OPENPTY && [ "x$SUDO" = "x" ]; then
+ skip_pty="no openpty(3) and SUDO not set"
+fi
+
# Test command= forced command
for c in 'command="echo bar"' 'no-pty,command="echo bar"'; do
sed "s/.*/$c &/" $origkeys >$authkeys
@@ -27,7 +33,7 @@ expect_pty_succeed() {
rm -f $OBJ/data
sed "s/.*/$opts &/" $origkeys >$authkeys
verbose "key option pty $which"
- config_defined HAVE_OPENPTY || verbose "skipped for no openpty(3)"
+ [ "x$skip_pty" != "x" ] && verbose "skipped because $skip_pty" && return
${SSH} -ttq -F $OBJ/ssh_proxy somehost "tty > $OBJ/data; exit 0"
if [ $? -ne 0 ] ; then
fail "key option failed $which"
@@ -45,7 +51,7 @@ expect_pty_fail() {
rm -f $OBJ/data
sed "s/.*/$opts &/" $origkeys >$authkeys
verbose "key option pty $which"
- config_defined HAVE_OPENPTY || verbose "skipped for no openpty(3)"
+ [ "x$skip_pty" != "x" ] && verbose "skipped because $skip_pty" && return
${SSH} -ttq -F $OBJ/ssh_proxy somehost "tty > $OBJ/data; exit 0"
if [ $? -eq 0 ]; then
r=`cat $OBJ/data`
diff --git a/crypto/openssh/regress/keygen-change.sh b/crypto/openssh/regress/keygen-change.sh
index 8b8acd52fb9f..3863e33b5287 100644
--- a/crypto/openssh/regress/keygen-change.sh
+++ b/crypto/openssh/regress/keygen-change.sh
@@ -1,4 +1,4 @@
-# $OpenBSD: keygen-change.sh,v 1.6 2017/04/30 23:34:55 djm Exp $
+# $OpenBSD: keygen-change.sh,v 1.9 2019/12/16 02:39:05 djm Exp $
# Placed in the Public Domain.
tid="change passphrase for key"
@@ -6,10 +6,7 @@ tid="change passphrase for key"
S1="secret1"
S2="2secret"
-KEYTYPES=`${SSH} -Q key-plain`
-
-for t in $KEYTYPES; do
- # generate user key for agent
+for t in $SSH_KEYTYPES; do
trace "generating $t key"
rm -f $OBJ/$t-key
${SSHKEYGEN} -q -N ${S1} -t $t -f $OBJ/$t-key
diff --git a/crypto/openssh/regress/keygen-comment.sh b/crypto/openssh/regress/keygen-comment.sh
new file mode 100644
index 000000000000..af571d39035f
--- /dev/null
+++ b/crypto/openssh/regress/keygen-comment.sh
@@ -0,0 +1,52 @@
+#    Placed in the Public Domain.
+
+tid="Comment extraction from private key"
+
+S1="secret1"
+
+check_fingerprint () {
+ file="$1"
+ comment="$2"
+ trace "fingerprinting $file"
+ if ! ${SSHKEYGEN} -l -E sha256 -f $file > $OBJ/$t-fgp ; then
+ fail "ssh-keygen -l failed for $t-key"
+ fi
+ if ! egrep "^([0-9]+) SHA256:(.){43} ${comment} \(.*\)\$" \
+ $OBJ/$t-fgp >/dev/null 2>&1 ; then
+ fail "comment is not correctly recovered for $t-key"
+ fi
+ rm -f $OBJ/$t-fgp
+}
+
+for fmt in '' RFC4716 PKCS8 PEM; do
+ for t in $SSH_KEYTYPES; do
+ trace "generating $t key in '$fmt' format"
+ rm -f $OBJ/$t-key*
+ oldfmt=""
+ case "$fmt" in
+ PKCS8|PEM) oldfmt=1 ;;
+ esac
+ # Some key types like ssh-ed25519 and *@openssh.com are never
+ # stored in old formats.
+ case "$t" in
+ ssh-ed25519|*openssh.com) test -z "$oldfmt" || continue ;;
+ esac
+ comment="foo bar"
+ fmtarg=""
+ test -z "$fmt" || fmtarg="-m $fmt"
+ ${SSHKEYGEN} $fmtarg -N '' -C "${comment}" \
+ -t $t -f $OBJ/$t-key >/dev/null 2>&1 || \
+ fatal "keygen of $t in format $fmt failed"
+ check_fingerprint $OBJ/$t-key "${comment}"
+ check_fingerprint $OBJ/$t-key.pub "${comment}"
+ # Output fingerprint using only private file
+ trace "fingerprinting $t key using private key file"
+ rm -f $OBJ/$t-key.pub
+ if [ ! -z "$oldfmt" ] ; then
+ # Comment cannot be recovered from old format keys.
+ comment="no comment"
+ fi
+ check_fingerprint $OBJ/$t-key "${comment}"
+ rm -f $OBJ/$t-key*
+ done
+done
diff --git a/crypto/openssh/regress/keygen-convert.sh b/crypto/openssh/regress/keygen-convert.sh
index ad0e9c637d0f..95656581c5b1 100755..100644
--- a/crypto/openssh/regress/keygen-convert.sh
+++ b/crypto/openssh/regress/keygen-convert.sh
@@ -1,32 +1,54 @@
-# $OpenBSD: keygen-convert.sh,v 1.1 2009/11/09 04:20:04 dtucker Exp $
+# $OpenBSD: keygen-convert.sh,v 1.6 2021/07/24 02:57:28 dtucker Exp $
# Placed in the Public Domain.
tid="convert keys"
-for t in rsa dsa; do
+cat > $OBJ/askpass <<EOD
+#!/bin/sh
+echo hunter2
+EOD
+chmod u+x $OBJ/askpass
+
+if ${SSHKEYGEN} -? 2>&1 | grep "ssh-keygen -e" >/dev/null; then
+ test_import_export=1
+fi
+
+for t in ${SSH_KEYTYPES}; 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"
+ if test "x$test_import_export" = "x1"; then
+ 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 "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"
+ trace "import $t rfc4716 public"
+ ${SSHKEYGEN} -q -i -f $OBJ/$t-key-rfc >$OBJ/$t-rfc-imported || \
+ fail "$t import rfc4716 public"
- cmp $OBJ/$t-key-rfc $OBJ/$t-key-rfc.pub || \
- fail "$t rfc4716 exports differ between public and private"
+ 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"
+ fi
- trace "import $t rfc4716 public"
- ${SSHKEYGEN} -q -i -f $OBJ/$t-key-rfc >$OBJ/$t-rfc-imported || \
- fail "$t import rfc4716 public"
+ trace "set passphrase $t"
+ ${SSHKEYGEN} -q -p -P '' -N 'hunter2' -f $OBJ/$t-key >/dev/null || \
+ fail "$t set passphrase failed"
- 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"
+ trace "export $t to public with passphrase"
+ SSH_ASKPASS=$OBJ/askpass SSH_ASKPASS_REQUIRE=force \
+ ${SSHKEYGEN} -y -f $OBJ/$t-key >$OBJ/$t-key-nocomment.pub
+ cmp $OBJ/$t-key.pub $OBJ/$t-key-nocomment.pub || \
+ fail "$t exported pubkey differs from generated"
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
diff --git a/crypto/openssh/regress/keygen-knownhosts.sh b/crypto/openssh/regress/keygen-knownhosts.sh
index 37af34769ecb..37af34769ecb 100755..100644
--- a/crypto/openssh/regress/keygen-knownhosts.sh
+++ b/crypto/openssh/regress/keygen-knownhosts.sh
diff --git a/crypto/openssh/regress/keygen-moduli.sh b/crypto/openssh/regress/keygen-moduli.sh
index d4e771383fea..8be53f92f852 100644
--- a/crypto/openssh/regress/keygen-moduli.sh
+++ b/crypto/openssh/regress/keygen-moduli.sh
@@ -1,18 +1,27 @@
-# $OpenBSD: keygen-moduli.sh,v 1.2 2016/09/14 00:45:31 dtucker Exp $
+# $OpenBSD: keygen-moduli.sh,v 1.4 2020/01/02 13:25:38 dtucker Exp $
# Placed in the Public Domain.
tid="keygen moduli"
+dhgex=0
+for kex in `${SSH} -Q kex`; do
+ case $kex in
+ diffie-hellman-group*) dhgex=1 ;;
+ esac
+done
+
# Try "start at the beginning and stop after 1", "skip 1 then stop after 1"
# and "skip 2 and run to the end with checkpointing". Since our test data
# file has 3 lines, these should always result in 1 line of output.
-for i in "-J1" "-j1 -J1" "-j2 -K $OBJ/moduli.ckpt"; do
+if [ "x$dhgex" = "x1" ]; then
+ for i in "-O lines=1" "-O start-line=1 -O lines=1" "-O start-line=2 -O checkpoint=$OBJ/moduli.ckpt"; do
trace "keygen $i"
rm -f $OBJ/moduli.out $OBJ/moduli.ckpt
- ${SSHKEYGEN} -T $OBJ/moduli.out -f ${SRC}/moduli.in $i 2>/dev/null || \
+ ${SSHKEYGEN} -M screen -f ${SRC}/moduli.in $i $OBJ/moduli.out 2>/dev/null || \
fail "keygen screen failed $i"
lines=`wc -l <$OBJ/moduli.out`
test "$lines" -eq "1" || fail "expected 1 line, got $lines"
-done
+ done
+fi
rm -f $OBJ/moduli.out $OBJ/moduli.ckpt
diff --git a/crypto/openssh/regress/keygen-sshfp.sh b/crypto/openssh/regress/keygen-sshfp.sh
new file mode 100644
index 000000000000..2abf9adecac7
--- /dev/null
+++ b/crypto/openssh/regress/keygen-sshfp.sh
@@ -0,0 +1,29 @@
+# $OpenBSD: keygen-sshfp.sh,v 1.2 2021/07/19 02:29:28 dtucker Exp $
+# Placed in the Public Domain.
+
+tid="keygen-sshfp"
+
+trace "keygen fingerprints"
+fp=`${SSHKEYGEN} -r test -f ${SRC}/ed25519_openssh.pub | \
+ awk '$5=="1"{print $6}'`
+if [ "$fp" != "8a8647a7567e202ce317e62606c799c53d4c121f" ]; then
+ fail "keygen fingerprint sha1"
+fi
+fp=`${SSHKEYGEN} -r test -f ${SRC}/ed25519_openssh.pub | \
+ awk '$5=="2"{print $6}'`
+if [ "$fp" != \
+ "54a506fb849aafb9f229cf78a94436c281efcb4ae67c8a430e8c06afcb5ee18f" ]; then
+ fail "keygen fingerprint sha256"
+fi
+
+if ${SSH} -Q key-plain | grep ssh-rsa >/dev/null; then
+ fp=`${SSHKEYGEN} -r test -f ${SRC}/rsa_openssh.pub | awk '$5=="1"{print $6}'`
+ if [ "$fp" != "99c79cc09f5f81069cc017cdf9552cfc94b3b929" ]; then
+ fail "keygen fingerprint sha1"
+ fi
+ fp=`${SSHKEYGEN} -r test -f ${SRC}/rsa_openssh.pub | awk '$5=="2"{print $6}'`
+ if [ "$fp" != \
+ "e30d6b9eb7a4de495324e4d5870b8220577993ea6af417e8e4a4f1c5bf01a9b6" ]; then
+ fail "keygen fingerprint sha256"
+ fi
+fi
diff --git a/crypto/openssh/regress/keys-command.sh b/crypto/openssh/regress/keys-command.sh
index 4029e2c78637..33b6e7b423df 100755..100644
--- a/crypto/openssh/regress/keys-command.sh
+++ b/crypto/openssh/regress/keys-command.sh
@@ -1,4 +1,4 @@
-# $OpenBSD: keys-command.sh,v 1.4 2016/09/26 21:34:38 bluhm Exp $
+# $OpenBSD: keys-command.sh,v 1.6 2019/07/25 08:48:11 dtucker Exp $
# Placed in the Public Domain.
tid="authorized keys from command"
@@ -14,12 +14,13 @@ 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 }'`
+expected_key_text=`awk '{ print $2 }' < $OBJ/ssh-ed25519.pub`
+expected_key_fp=`$SSHKEYGEN -lf $OBJ/ssh-ed25519.pub | awk '{ print $2 }'`
# Establish a AuthorizedKeysCommand in /var/run where it will have
# acceptable directory permissions.
-KEY_COMMAND="/var/run/keycommand_${LOGNAME}"
+KEY_COMMAND="/var/run/keycommand_${LOGNAME}.$$"
+trap "${SUDO} rm -f ${KEY_COMMAND}" 0
cat << _EOF | $SUDO sh -c "rm -f '$KEY_COMMAND' ; cat > '$KEY_COMMAND'"
#!/bin/sh
echo args: "\$@" >> $OBJ/keys-command-args
@@ -78,5 +79,3 @@ if [ -x $KEY_COMMAND ]; then
else
echo "SKIPPED: $KEY_COMMAND not executable (/var/run mounted noexec?)"
fi
-
-$SUDO rm -f $KEY_COMMAND
diff --git a/crypto/openssh/regress/keyscan.sh b/crypto/openssh/regress/keyscan.sh
index 3bde1219a605..75a14ee0eecb 100644
--- a/crypto/openssh/regress/keyscan.sh
+++ b/crypto/openssh/regress/keyscan.sh
@@ -1,17 +1,22 @@
-# $OpenBSD: keyscan.sh,v 1.6 2017/04/30 23:34:55 djm Exp $
+# $OpenBSD: keyscan.sh,v 1.13 2020/01/22 07:31:27 dtucker Exp $
# Placed in the Public Domain.
tid="keyscan"
-# remove DSA hostkey
-rm -f ${OBJ}/host.dsa
+for i in $SSH_KEYTYPES; do
+ if [ -z "$algs" ]; then
+ algs="$i"
+ else
+ algs="$algs,$i"
+ fi
+done
+echo "HostKeyAlgorithms $algs" >> $OBJ/sshd_config
start_sshd
-KEYTYPES=`${SSH} -Q key-plain`
-for t in $KEYTYPES; do
+for t in $SSH_KEYTYPES; do
trace "keyscan type $t"
- ${SSHKEYSCAN} -t $t -p $PORT 127.0.0.1 127.0.0.1 127.0.0.1 \
+ ${SSHKEYSCAN} -t $t -T 15 -p $PORT 127.0.0.1 127.0.0.1 127.0.0.1 \
> /dev/null 2>&1
r=$?
if [ $r -ne 0 ]; then
diff --git a/crypto/openssh/regress/keytype.sh b/crypto/openssh/regress/keytype.sh
index f78a2c171fa5..f1c045183bd3 100755..100644
--- a/crypto/openssh/regress/keytype.sh
+++ b/crypto/openssh/regress/keytype.sh
@@ -1,4 +1,4 @@
-# $OpenBSD: keytype.sh,v 1.7 2018/03/12 00:54:04 djm Exp $
+# $OpenBSD: keytype.sh,v 1.11 2021/02/25 03:27:34 djm Exp $
# Placed in the Public Domain.
tid="login with different key types"
@@ -6,51 +6,66 @@ tid="login with different key types"
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
+# Construct list of key types based on what the built binaries support.
+ktypes=""
+for i in ${SSH_KEYTYPES}; do
case "$i" in
+ ssh-dss) ktypes="$ktypes dsa-1024" ;;
+ ssh-rsa) ktypes="$ktypes rsa-2048 rsa-3072" ;;
+ ssh-ed25519) ktypes="$ktypes ed25519-512" ;;
ecdsa-sha2-nistp256) ktypes="$ktypes ecdsa-256" ;;
ecdsa-sha2-nistp384) ktypes="$ktypes ecdsa-384" ;;
ecdsa-sha2-nistp521) ktypes="$ktypes ecdsa-521" ;;
+ sk-ssh-ed25519*) ktypes="$ktypes ed25519-sk" ;;
+ sk-ecdsa-sha2-nistp256*) ktypes="$ktypes ecdsa-sk" ;;
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}'`
+ xbits=`echo ${kt} | awk -F- '{print $2}'`
+ xtype=`echo ${kt} | awk -F- '{print $1}'`
+ case "$kt" in
+ *sk) type="$kt"; bits="n/a"; bits_arg="";;
+ *) type=$xtype; bits=$xbits; bits_arg="-b $bits";;
+ esac
verbose "keygen $type, $bits bits"
- ${SSHKEYGEN} -b $bits -q -N '' -t $type -f $OBJ/key.$kt ||\
+ ${SSHKEYGEN} $bits_arg -q -N '' -t $type -f $OBJ/key.$kt || \
fail "ssh-keygen for type $type, $bits bits failed"
done
+kname_to_ktype() {
+ case $1 in
+ dsa-1024) echo ssh-dss;;
+ ecdsa-256) echo ecdsa-sha2-nistp256;;
+ ecdsa-384) echo ecdsa-sha2-nistp384;;
+ ecdsa-521) echo ecdsa-sha2-nistp521;;
+ ed25519-512) echo ssh-ed25519;;
+ rsa-*) echo rsa-sha2-512,rsa-sha2-256,ssh-rsa;;
+ ed25519-sk) echo sk-ssh-ed25519@openssh.com;;
+ ecdsa-sk) echo sk-ecdsa-sha2-nistp256@openssh.com;;
+ esac
+}
+
tries="1 2 3"
for ut in $ktypes; do
- htypes=$ut
+ user_type=`kname_to_ktype "$ut"`
+ 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=rsa-sha2-512,rsa-sha2-256,ssh-rsa;;
- esac
+ host_type=`kname_to_ktype "$ht"`
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
+ echo PubkeyAcceptedAlgorithms $user_type
+ echo HostKeyAlgorithms $host_type
) > $OBJ/sshd_proxy
(
grep -v IdentityFile $OBJ/ssh_proxy_bak
echo IdentityFile $OBJ/key.$ut
- echo PubkeyAcceptedKeyTypes $t
- echo HostKeyAlgorithms $t
+ echo PubkeyAcceptedAlgorithms $user_type
+ echo HostKeyAlgorithms $host_type
) > $OBJ/ssh_proxy
(
printf 'localhost-with-alias,127.0.0.1,::1 '
diff --git a/crypto/openssh/regress/knownhosts-command.sh b/crypto/openssh/regress/knownhosts-command.sh
new file mode 100644
index 000000000000..f15df670b0c8
--- /dev/null
+++ b/crypto/openssh/regress/knownhosts-command.sh
@@ -0,0 +1,53 @@
+# $OpenBSD: knownhosts-command.sh,v 1.2 2020/12/22 06:47:24 djm Exp $
+# Placed in the Public Domain.
+
+tid="known hosts command "
+
+rm -f $OBJ/knownhosts_command $OBJ/ssh_proxy_khc
+cp $OBJ/ssh_proxy $OBJ/ssh_proxy_orig
+
+( grep -vi GlobalKnownHostsFile $OBJ/ssh_proxy_orig | \
+ grep -vi UserKnownHostsFile;
+ echo "GlobalKnownHostsFile none" ;
+ echo "UserKnownHostsFile none" ;
+ echo "KnownHostsCommand $OBJ/knownhosts_command '%t' '%K' '%u'" ;
+) > $OBJ/ssh_proxy
+
+verbose "simple connection"
+cat > $OBJ/knownhosts_command << _EOF
+#!/bin/sh
+cat $OBJ/known_hosts
+_EOF
+chmod a+x $OBJ/knownhosts_command
+${SSH} -F $OBJ/ssh_proxy x true || fail "ssh connect failed"
+
+verbose "no keys"
+cat > $OBJ/knownhosts_command << _EOF
+#!/bin/sh
+exit 0
+_EOF
+chmod a+x $OBJ/knownhosts_command
+${SSH} -F $OBJ/ssh_proxy x true && fail "ssh connect succeeded with no keys"
+
+verbose "bad exit status"
+cat > $OBJ/knownhosts_command << _EOF
+#!/bin/sh
+cat $OBJ/known_hosts
+exit 1
+_EOF
+chmod a+x $OBJ/knownhosts_command
+${SSH} -F $OBJ/ssh_proxy x true && fail "ssh connect succeeded with bad exit"
+
+for keytype in ${SSH_HOSTKEY_TYPES} ; do
+ test "x$keytype" = "xssh-dss" && continue
+ verbose "keytype $keytype"
+ cat > $OBJ/knownhosts_command << _EOF
+#!/bin/sh
+die() { echo "\$@" 1>&2 ; exit 1; }
+test "x\$1" = "x$keytype" || die "wrong keytype \$1 (expected $keytype)"
+test "x\$3" = "x$LOGNAME" || die "wrong username \$3 (expected $LOGNAME)"
+grep -- "\$1.*\$2" $OBJ/known_hosts
+_EOF
+ ${SSH} -F $OBJ/ssh_proxy -oHostKeyAlgorithms=$keytype x true ||
+ fail "ssh connect failed for keytype $x"
+done
diff --git a/crypto/openssh/regress/krl.sh b/crypto/openssh/regress/krl.sh
index a70c79c66fd4..c381225ed7cd 100755..100644
--- a/crypto/openssh/regress/krl.sh
+++ b/crypto/openssh/regress/krl.sh
@@ -1,13 +1,21 @@
-# $OpenBSD: krl.sh,v 1.7 2018/09/12 01:23:48 djm Exp $
+# $OpenBSD: krl.sh,v 1.11 2019/12/16 02:39:05 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
+# Use ed25519 by default since it's fast and it's supported when building
+# w/out OpenSSL. Populate ktype[2-4] with the other types if supported.
+ktype1=ed25519; ktype2=ed25519; ktype3=ed25519;
+ktype4=ed25519; ktype5=ed25519; ktype6=ed25519;
+for t in $SSH_KEYTYPES; do
+ case "$t" in
+ ecdsa*) ktype2=ecdsa ;;
+ ssh-rsa) ktype3=rsa ;;
+ ssh-dss) ktype4=dsa ;;
+ sk-ssh-ed25519@openssh.com) ktype5=ed25519-sk ;;
+ sk-ecdsa-sha2-nistp256@openssh.com) ktype6=ecdsa-sk ;;
+ esac
+done
# Do most testing with ssh-keygen; it uses the same verification code as sshd.
@@ -15,9 +23,9 @@ fi
rm -f $OBJ/revoked-* $OBJ/krl-*
# Generate a CA key
-$SSHKEYGEN -t $ECDSA -f $OBJ/revoked-ca -C "" -N "" > /dev/null ||
+$SSHKEYGEN -t $ktype1 -f $OBJ/revoked-ca -C "" -N "" > /dev/null ||
fatal "$SSHKEYGEN CA failed"
-$SSHKEYGEN -t ed25519 -f $OBJ/revoked-ca2 -C "" -N "" > /dev/null ||
+$SSHKEYGEN -t $ktype2 -f $OBJ/revoked-ca2 -C "" -N "" > /dev/null ||
fatal "$SSHKEYGEN CA2 failed"
# A specification that revokes some certificates by serial numbers
@@ -29,6 +37,7 @@ serial: 10
serial: 15
serial: 30
serial: 50
+serial: 90
serial: 999
# The following sum to 500-799
serial: 500
@@ -46,7 +55,7 @@ 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
+for n in 1 2 3 4 10 15 30 50 90 `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
@@ -55,11 +64,15 @@ 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
+ # Vary the keytype. We use mostly ed25519 since this is fast and well
+ # supported.
+ keytype=$ktype1
case $N in
- 2 | 10 | 510 | 1001) keytype=rsa;;
- 4 | 30 | 520 | 1002) keytype=ed25519;;
+ 2 | 10 | 510 | 1001) keytype=$ktype2 ;;
+ 4 | 30 | 520 | 1002) keytype=$ktype3 ;;
+ 8 | 50 | 530 | 1003) keytype=$ktype4 ;;
+ 16 | 70 | 540 | 1004) keytype=$ktype5 ;;
+ 32 | 90 | 550 | 1005) keytype=$ktype6 ;;
esac
$SSHKEYGEN -t $keytype -f $f -C "" -N "" > /dev/null \
|| fatal "$SSHKEYGEN failed"
@@ -71,7 +84,7 @@ keygen() {
# Generate some keys.
verbose "$tid: generating test keys"
-REVOKED_SERIALS="1 4 10 50 500 510 520 799 999"
+REVOKED_SERIALS="1 4 10 50 90 500 510 520 550 799 999"
for n in $REVOKED_SERIALS ; do
f=`keygen $n`
RKEYS="$RKEYS ${f}.pub"
diff --git a/crypto/openssh/regress/limit-keytype.sh b/crypto/openssh/regress/limit-keytype.sh
index 04f11977e140..7127de007cc6 100755..100644
--- a/crypto/openssh/regress/limit-keytype.sh
+++ b/crypto/openssh/regress/limit-keytype.sh
@@ -1,26 +1,44 @@
-# $OpenBSD: limit-keytype.sh,v 1.5 2018/03/12 00:52:57 djm Exp $
+# $OpenBSD: limit-keytype.sh,v 1.10 2021/02/25 03:27:34 djm Exp $
# Placed in the Public Domain.
tid="restrict pubkey type"
+# XXX sk-* keys aren't actually tested ATM.
+
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
+ktype1=ed25519; ktype2=ed25519; ktype3=ed25519;
+ktype4=ed25519; ktype5=ed25519; ktype6=ed25519;
+for t in $SSH_KEYTYPES ; do
+ case "$t" in
+ ssh-rsa) ktype2=rsa ;;
+ ecdsa*) ktype3=ecdsa ;; # unused
+ ssh-dss) ktype4=dsa ;;
+ sk-ssh-ed25519@openssh.com) ktype5=ed25519-sk ;;
+ sk-ecdsa-sha2-nistp256@openssh.com) ktype6=ecdsa-sk ;;
+ esac
+done
+
# Create a CA key
-${SSHKEYGEN} -q -N '' -t ed25519 -f $OBJ/user_ca_key ||\
+${SSHKEYGEN} -q -N '' -t $ktype1 -f $OBJ/user_ca_key ||\
fatal "ssh-keygen failed"
# Make some keys and a certificate.
-${SSHKEYGEN} -q -N '' -t ed25519 -f $OBJ/user_key1 || \
+${SSHKEYGEN} -q -N '' -t $ktype1 -f $OBJ/user_key1 || \
+ fatal "ssh-keygen failed"
+${SSHKEYGEN} -q -N '' -t $ktype2 -f $OBJ/user_key2 || \
+ fatal "ssh-keygen failed"
+${SSHKEYGEN} -q -N '' -t $ktype2 -f $OBJ/user_key3 || \
fatal "ssh-keygen failed"
-${SSHKEYGEN} -q -N '' -t rsa -f $OBJ/user_key2 || \
+${SSHKEYGEN} -q -N '' -t $ktype4 -f $OBJ/user_key4 || \
fatal "ssh-keygen failed"
-${SSHKEYGEN} -q -N '' -t rsa -f $OBJ/user_key3 || \
+${SSHKEYGEN} -q -N '' -t $ktype5 -f $OBJ/user_key5 || \
fatal "ssh-keygen failed"
-${SSHKEYGEN} -q -N '' -t dsa -f $OBJ/user_key4 || \
+${SSHKEYGEN} -q -N '' -t $ktype6 -f $OBJ/user_key6 || \
fatal "ssh-keygen failed"
${SSHKEYGEN} -q -s $OBJ/user_ca_key -I "regress user key for $USER" \
-z $$ -n ${USER},mekmitasdigoat $OBJ/user_key3 ||
@@ -51,6 +69,19 @@ prepare_config() {
) > $OBJ/sshd_proxy
}
+# Return the required parameter for PubkeyAcceptedAlgorithms corresponding to
+# the supplied key type.
+keytype() {
+ case "$1" in
+ ecdsa) printf "ecdsa-sha2-*" ;;
+ ed25519) printf "ssh-ed25519" ;;
+ dsa) printf "ssh-dss" ;;
+ rsa) printf "rsa-sha2-256,rsa-sha2-512,ssh-rsa" ;;
+ sk-ecdsa) printf "sk-ecdsa-*" ;;
+ sk-ssh-ed25519) printf "sk-ssh-ed25519-*" ;;
+ esac
+}
+
prepare_config
# Check we can log in with all key types.
@@ -59,39 +90,43 @@ ${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 "allow rsa,ed25519"
+verbose "allow $ktype2,$ktype1"
prepare_config \
- "PubkeyAcceptedKeyTypes rsa-sha2-256,rsa-sha2-512,ssh-rsa,ssh-ed25519"
+ "PubkeyAcceptedAlgorithms `keytype $ktype2`,`keytype $ktype1`"
${SSH} $certopts 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 "allow ed25519"
-prepare_config "PubkeyAcceptedKeyTypes ssh-ed25519"
+verbose "allow $ktype1"
+prepare_config "PubkeyAcceptedAlgorithms `keytype $ktype1`"
${SSH} $certopts 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"
+if [ "$ktype1" != "$ktype2" ]; then
+ ${SSH} $opts -i $OBJ/user_key2 proxy true && fatal "key2 succeeded"
+fi
# Allow all certs. Plain keys should fail.
verbose "allow cert only"
-prepare_config "PubkeyAcceptedKeyTypes *-cert-v01@openssh.com"
+prepare_config "PubkeyAcceptedAlgorithms *-cert-v01@openssh.com"
${SSH} $certopts 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"
# Allow RSA in main config, Ed25519 for non-existent user.
verbose "match w/ no match"
-prepare_config "PubkeyAcceptedKeyTypes rsa-sha2-256,rsa-sha2-512,ssh-rsa" \
- "Match user x$USER" "PubkeyAcceptedKeyTypes +ssh-ed25519"
+prepare_config "PubkeyAcceptedAlgorithms `keytype $ktype2`" \
+ "Match user x$USER" "PubkeyAcceptedAlgorithms +`keytype $ktype1`"
${SSH} $certopts proxy true && fatal "cert succeeded"
-${SSH} $opts -i $OBJ/user_key1 proxy true && fatal "key1 succeeded"
+if [ "$ktype1" != "$ktype2" ]; then
+ ${SSH} $opts -i $OBJ/user_key1 proxy true && fatal "key1 succeeded"
+fi
${SSH} $opts -i $OBJ/user_key2 proxy true || fatal "key2 failed"
# Allow only DSA in main config, Ed25519 for user.
verbose "match w/ matching"
-prepare_config "PubkeyAcceptedKeyTypes ssh-dss" \
- "Match user $USER" "PubkeyAcceptedKeyTypes +ssh-ed25519"
+prepare_config "PubkeyAcceptedAlgorithms `keytype $ktype4`" \
+ "Match user $USER" "PubkeyAcceptedAlgorithms +`keytype $ktype1`"
${SSH} $certopts proxy true || fatal "cert failed"
${SSH} $opts -i $OBJ/user_key1 proxy true || fatal "key1 failed"
${SSH} $opts -i $OBJ/user_key4 proxy true && fatal "key4 succeeded"
diff --git a/crypto/openssh/regress/localcommand.sh b/crypto/openssh/regress/localcommand.sh
index 5224a16b24d7..5224a16b24d7 100755..100644
--- a/crypto/openssh/regress/localcommand.sh
+++ b/crypto/openssh/regress/localcommand.sh
diff --git a/crypto/openssh/regress/misc/Makefile b/crypto/openssh/regress/misc/Makefile
index 14c0c279f7ac..b9149f2879eb 100644
--- a/crypto/openssh/regress/misc/Makefile
+++ b/crypto/openssh/regress/misc/Makefile
@@ -1,3 +1,3 @@
-SUBDIR= kexfuzz
+SUBDIR= sk-dummy
.include <bsd.subdir.mk>
diff --git a/crypto/openssh/regress/misc/fuzz-harness/Makefile b/crypto/openssh/regress/misc/fuzz-harness/Makefile
index a2aa4441f97e..e879fcdae297 100644
--- a/crypto/openssh/regress/misc/fuzz-harness/Makefile
+++ b/crypto/openssh/regress/misc/fuzz-harness/Makefile
@@ -1,25 +1,52 @@
# NB. libssh and libopenbsd-compat should be built with the same sanitizer opts.
-CXX=clang++-3.9
-FUZZ_FLAGS=-fsanitize=address,undefined -fsanitize-coverage=edge
+CC=clang-11
+CXX=clang++-11
+FUZZ_FLAGS=-fsanitize=address,fuzzer -fno-omit-frame-pointer
FUZZ_LIBS=-lFuzzer
-CXXFLAGS=-O2 -g -Wall -Wextra -I ../../.. $(FUZZ_FLAGS)
+CXXFLAGS=-O2 -g -Wall -Wextra -Wno-unused-parameter -I ../../.. $(FUZZ_FLAGS)
+CFLAGS=$(CXXFLAGS)
LDFLAGS=-L ../../.. -L ../../../openbsd-compat -g $(FUZZ_FLAGS)
-LIBS=-lssh -lopenbsd-compat -lcrypto $(FUZZ_LIBS)
+LIBS=-lssh -lopenbsd-compat -lcrypto -lfido2 -lcbor $(FUZZ_LIBS)
+SK_NULL_OBJS=ssh-sk-null.o
+COMMON_DEPS=../../../libssh.a
-all: pubkey_fuzz sig_fuzz authopt_fuzz
+TARGETS=pubkey_fuzz sig_fuzz authopt_fuzz sshsig_fuzz \
+ sshsigopt_fuzz privkey_fuzz kex_fuzz agent_fuzz
+
+all: $(TARGETS)
.cc.o:
$(CXX) $(CXXFLAGS) -c $< -o $@
-pubkey_fuzz: pubkey_fuzz.o
- $(CXX) -o $@ pubkey_fuzz.o $(LDFLAGS) $(LIBS)
+pubkey_fuzz: pubkey_fuzz.o $(SK_NULL_OBJS) $(COMMON_DEPS)
+ $(CXX) -o $@ pubkey_fuzz.o $(SK_NULL_OBJS) $(LDFLAGS) $(LIBS)
+
+sig_fuzz: sig_fuzz.o $(SK_NULL_OBJS) $(COMMON_DEPS)
+ $(CXX) -o $@ sig_fuzz.o $(SK_NULL_OBJS) $(LDFLAGS) $(LIBS)
+
+authopt_fuzz: authopt_fuzz.o $(SK_NULL_OBJS) $(COMMON_DEPS)
+ $(CXX) -o $@ authopt_fuzz.o $(SK_NULL_OBJS) ../../../auth-options.o $(LDFLAGS) $(LIBS)
+
+sshsig_fuzz: sshsig_fuzz.o $(SK_NULL_OBJS) $(COMMON_DEPS)
+ $(CXX) -o $@ sshsig_fuzz.o $(SK_NULL_OBJS) ../../../sshsig.o $(LDFLAGS) $(LIBS)
+
+sshsigopt_fuzz: sshsigopt_fuzz.o $(SK_NULL_OBJS) $(COMMON_DEPS)
+ $(CXX) -o $@ sshsigopt_fuzz.o $(SK_NULL_OBJS) ../../../sshsig.o $(LDFLAGS) $(LIBS)
+
+privkey_fuzz: privkey_fuzz.o $(SK_NULL_OBJS) $(COMMON_DEPS)
+ $(CXX) -o $@ privkey_fuzz.o $(SK_NULL_OBJS) $(LDFLAGS) $(LIBS)
+
+kex_fuzz: kex_fuzz.o $(SK_NULL_OBJS) $(COMMON_DEPS)
+ $(CXX) -o $@ kex_fuzz.o $(SK_NULL_OBJS) $(LDFLAGS) $(LIBS) -lz
+
+agent_fuzz: agent_fuzz.o agent_fuzz_helper.o sk-dummy.o ../../../ssh-sk.o $(COMMON_DEPS)
+ $(CXX) -o $@ agent_fuzz.o agent_fuzz_helper.o sk-dummy.o ../../../ssh-sk.o $(LDFLAGS) $(LIBS) -lz
-sig_fuzz: sig_fuzz.o
- $(CXX) -o $@ sig_fuzz.o $(LDFLAGS) $(LIBS)
+agent_fuzz_helper.o: agent_fuzz_helper.c ../../../ssh-agent.c
-authopt_fuzz: authopt_fuzz.o
- $(CXX) -o $@ authopt_fuzz.o ../../../auth-options.o $(LDFLAGS) $(LIBS)
+sk-dummy.o: ../sk-dummy/sk-dummy.c
+ $(CC) $(CFLAGS) -c -o $@ ../sk-dummy/sk-dummy.c -DSK_DUMMY_INTEGRATE=1 $(LDFLAGS)
clean:
- -rm -f *.o pubkey_fuzz sig_fuzz authopt_fuzz
+ -rm -f *.o $(TARGETS)
diff --git a/crypto/openssh/regress/misc/fuzz-harness/agent_fuzz.cc b/crypto/openssh/regress/misc/fuzz-harness/agent_fuzz.cc
new file mode 100644
index 000000000000..ad85b2f9a297
--- /dev/null
+++ b/crypto/openssh/regress/misc/fuzz-harness/agent_fuzz.cc
@@ -0,0 +1,15 @@
+// cc_fuzz_target test for ssh-agent.
+extern "C" {
+
+#include <stdint.h>
+#include <sys/types.h>
+
+extern void test_one(const uint8_t* s, size_t slen);
+
+int LLVMFuzzerTestOneInput(const uint8_t* s, size_t slen)
+{
+ test_one(s, slen);
+ return 0;
+}
+
+} // extern
diff --git a/crypto/openssh/regress/misc/fuzz-harness/agent_fuzz_helper.c b/crypto/openssh/regress/misc/fuzz-harness/agent_fuzz_helper.c
new file mode 100644
index 000000000000..1d419820cc5d
--- /dev/null
+++ b/crypto/openssh/regress/misc/fuzz-harness/agent_fuzz_helper.c
@@ -0,0 +1,177 @@
+#include "fixed-keys.h"
+#include <assert.h>
+
+#define main(ac, av) xxxmain(ac, av)
+#include "../../../ssh-agent.c"
+
+void test_one(const uint8_t* s, size_t slen);
+
+static int
+devnull_or_die(void)
+{
+ int fd;
+
+ if ((fd = open("/dev/null", O_RDWR)) == -1) {
+ error_f("open /dev/null: %s", strerror(errno));
+ abort();
+ }
+ return fd;
+}
+
+static struct sshkey *
+pubkey_or_die(const char *s)
+{
+ char *tmp, *cp;
+ struct sshkey *pubkey;
+ int r;
+
+ tmp = cp = xstrdup(s);
+ if ((pubkey = sshkey_new(KEY_UNSPEC)) == NULL)
+ abort();
+ if ((r = sshkey_read(pubkey, &cp)) != 0) {
+ error_fr(r, "parse");
+ abort();
+ }
+ free(tmp);
+ return pubkey;
+}
+
+static struct sshkey *
+privkey_or_die(const char *s)
+{
+ int r;
+ struct sshbuf *b;
+ struct sshkey *privkey;
+
+ if ((b = sshbuf_from(s, strlen(s))) == NULL) {
+ error_f("sshbuf_from failed");
+ abort();
+ }
+ if ((r = sshkey_parse_private_fileblob(b, "", &privkey, NULL)) != 0) {
+ error_fr(r, "parse");
+ abort();
+ }
+ sshbuf_free(b);
+ return privkey;
+}
+
+static void
+add_key(const char *privkey, const char *certpath)
+{
+ Identity *id;
+ int r;
+ struct sshkey *cert;
+
+ id = xcalloc(1, sizeof(Identity));
+ TAILQ_INSERT_TAIL(&idtab->idlist, id, next);
+ idtab->nentries++;
+ id->key = privkey_or_die(privkey);
+ id->comment = xstrdup("rhododaktulos Eos");
+ if (sshkey_is_sk(id->key))
+ id->sk_provider = xstrdup("internal");
+
+ /* Now the cert too */
+ id = xcalloc(1, sizeof(Identity));
+ TAILQ_INSERT_TAIL(&idtab->idlist, id, next);
+ idtab->nentries++;
+ id->key = privkey_or_die(privkey);
+ cert = pubkey_or_die(certpath);
+ if ((r = sshkey_to_certified(id->key)) != 0) {
+ error_fr(r, "sshkey_to_certified");
+ abort();
+ }
+ if ((r = sshkey_cert_copy(cert, id->key)) != 0) {
+ error_fr(r, "sshkey_cert_copy");
+ abort();
+ }
+ sshkey_free(cert);
+ id->comment = xstrdup("outis");
+ if (sshkey_is_sk(id->key))
+ id->sk_provider = xstrdup("internal");
+}
+
+static void
+cleanup_idtab(void)
+{
+ Identity *id;
+
+ if (idtab == NULL) return;
+ for (id = TAILQ_FIRST(&idtab->idlist); id;
+ id = TAILQ_FIRST(&idtab->idlist)) {
+ TAILQ_REMOVE(&idtab->idlist, id, next);
+ free_identity(id);
+ }
+ free(idtab);
+ idtab = NULL;
+}
+
+static void
+reset_idtab(void)
+{
+ cleanup_idtab();
+ idtab_init();
+ // Load keys.
+ add_key(PRIV_RSA, CERT_RSA);
+ add_key(PRIV_DSA, CERT_DSA);
+ add_key(PRIV_ECDSA, CERT_ECDSA);
+ add_key(PRIV_ED25519, CERT_ED25519);
+ add_key(PRIV_ECDSA_SK, CERT_ECDSA_SK);
+ add_key(PRIV_ED25519_SK, CERT_ED25519_SK);
+}
+
+static void
+cleanup_sockettab(void)
+{
+ u_int i;
+ for (i = 0; i < sockets_alloc; i++) {
+ if (sockets[i].type != AUTH_UNUSED)
+ close_socket(sockets + i);
+ }
+ free(sockets);
+ sockets = NULL;
+ sockets_alloc = 0;
+}
+
+static void
+reset_sockettab(int devnull)
+{
+ int fd;
+
+ cleanup_sockettab();
+ if ((fd = dup(devnull)) == -1) {
+ error_f("dup: %s", strerror(errno));
+ abort();
+ }
+ new_socket(AUTH_CONNECTION, fd);
+ assert(sockets[0].type == AUTH_CONNECTION);
+ assert(sockets[0].fd == fd);
+}
+
+#define MAX_MESSAGES 256
+void
+test_one(const uint8_t* s, size_t slen)
+{
+ static int devnull = -1;
+ size_t i, olen, nlen;
+
+ if (devnull == -1) {
+ log_init(__progname, SYSLOG_LEVEL_DEBUG3,
+ SYSLOG_FACILITY_AUTH, 1);
+ devnull = devnull_or_die();
+ allowed_providers = xstrdup("");
+ setenv("DISPLAY", "", 1); /* ban askpass */
+ }
+
+ reset_idtab();
+ reset_sockettab(devnull);
+ (void)sshbuf_put(sockets[0].input, s, slen);
+ for (i = 0; i < MAX_MESSAGES; i++) {
+ olen = sshbuf_len(sockets[0].input);
+ process_message(0);
+ nlen = sshbuf_len(sockets[0].input);
+ if (nlen == 0 || nlen == olen)
+ break;
+ }
+ cleanup_idtab();
+ cleanup_sockettab();
+}
diff --git a/crypto/openssh/regress/misc/fuzz-harness/fixed-keys.h b/crypto/openssh/regress/misc/fuzz-harness/fixed-keys.h
new file mode 100644
index 000000000000..c6e7c6cc1828
--- /dev/null
+++ b/crypto/openssh/regress/misc/fuzz-harness/fixed-keys.h
@@ -0,0 +1,119 @@
+/*
+ * Some keys used by fuzzers
+ */
+
+#define PRIV_RSA \
+"-----BEGIN OPENSSH PRIVATE KEY-----\n"\
+"b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAABFwAAAAdzc2gtcn\n"\
+"NhAAAAAwEAAQAAAQEA3+epf+VGKoGPaAZXrf6S0cyumQnddkGBnVFX0A5eh37RtLug0qY5\n"\
+"thxsBUbGGVr9mTd2QXwLujBwYg5l1MP/Fmg+5312Zgx9pHmS+qKULbar0hlNgptNEb+aNU\n"\
+"d3o9qg3aXqXm7+ZnjAV05ef/mxNRN2ZvuEkw7cRppTJcbBI+vF3lXuCXnX2klDI95Gl2AW\n"\
+"3WHRtanqLHZXuBkjjRBDKc7MUq/GP1hmLiAd95dvU7fZjRlIEsP84zGEI1Fb0L/kmPHcOt\n"\
+"iVfHft8CtmC9v6+94JrOiPBBNScV+dyrgAGPsdKdr/1vIpQmCNiI8s3PCiD8J7ZiBaYm0I\n"\
+"8fq5G/qnUwAAA7ggw2dXIMNnVwAAAAdzc2gtcnNhAAABAQDf56l/5UYqgY9oBlet/pLRzK\n"\
+"6ZCd12QYGdUVfQDl6HftG0u6DSpjm2HGwFRsYZWv2ZN3ZBfAu6MHBiDmXUw/8WaD7nfXZm\n"\
+"DH2keZL6opQttqvSGU2Cm00Rv5o1R3ej2qDdpepebv5meMBXTl5/+bE1E3Zm+4STDtxGml\n"\
+"MlxsEj68XeVe4JedfaSUMj3kaXYBbdYdG1qeosdle4GSONEEMpzsxSr8Y/WGYuIB33l29T\n"\
+"t9mNGUgSw/zjMYQjUVvQv+SY8dw62JV8d+3wK2YL2/r73gms6I8EE1JxX53KuAAY+x0p2v\n"\
+"/W8ilCYI2Ijyzc8KIPwntmIFpibQjx+rkb+qdTAAAAAwEAAQAAAQEArWm5B4tFasppjUHM\n"\
+"SsAuajtCxtizI1Hc10EW59cZM4vvUzE2f6+qZvdgWj3UU/L7Et23w0QVuSCnCerox379ZB\n"\
+"ddEOFFAAiQjwBx65hbd4RRUymxtIQfjq18++LcMJW1nbVQ7c69ThQbtALIggmbS+ZE/8Gx\n"\
+"jkwmIrCH0Ww8TlpsPe+mNHuyNk7UEZoXLm22lNLqq5qkIL5JgT6M2iNJpMOJy9/CKi6kO4\n"\
+"JPuVwjdG4C5pBPaMN3KJ1IvAlSlLGNaXnfXcn85gWfsCjsZmH3liey2NJamqp/w83BrKUg\n"\
+"YZvMR2qeWZaKkFTahpzN5KRK1BFeB37O0P84Dzh1biDX8QAAAIEAiWXW8ePYFwLpa2mFIh\n"\
+"VvRTdcrN70rVK5eWVaL3pyS4vGA56Jixq86dHveOnbSY+iNb1jQidtXc8SWUt2wtHqZ32h\n"\
+"Lji9/hMSKqe9SEP3xvDRDmUJqsVw0ySyrFrzm4160QY6RKU3CIQCVFslMZ9fxmrfZ/hxoU\n"\
+"0X3FVsxmC4+kwAAACBAPOc1YERpV6PjANBrGR+1o1RCdACbm5myc42QzSNIaOZmgrYs+Gt\n"\
+"7+EcoqSdbJzHJNCNQfF+A+vjbIkFiuZqq/5wwr59qXx5OAlijLB/ywwKmTWq6lp//Zxny+\n"\
+"ka3sIGNO14eQvmxNDnlLL+RIZleCTEKBXSW6CZhr+uHMZFKKMtAAAAgQDrSkm+LbILB7H9\n"\
+"jxEBZLhv53aAn4u81kFKQOJ7PzzpBGSoD12i7oIJu5siSD5EKDNVEr+SvCf0ISU3BuMpzl\n"\
+"t3YrPrHRheOFhn5e3j0e//zB8rBC0DGB4CtTDdeh7rOXUL4K0pz+8wEpNkV62SWxhC6NRW\n"\
+"I79JhtGkh+GtcnkEfwAAAAAB\n"\
+"-----END OPENSSH PRIVATE KEY-----\n"
+#define PUB_RSA \
+"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDf56l/5UYqgY9oBlet/pLRzK6ZCd12QYGdUVfQDl6HftG0u6DSpjm2HGwFRsYZWv2ZN3ZBfAu6MHBiDmXUw/8WaD7nfXZmDH2keZL6opQttqvSGU2Cm00Rv5o1R3ej2qDdpepebv5meMBXTl5/+bE1E3Zm+4STDtxGmlMlxsEj68XeVe4JedfaSUMj3kaXYBbdYdG1qeosdle4GSONEEMpzsxSr8Y/WGYuIB33l29Tt9mNGUgSw/zjMYQjUVvQv+SY8dw62JV8d+3wK2YL2/r73gms6I8EE1JxX53KuAAY+x0p2v/W8ilCYI2Ijyzc8KIPwntmIFpibQjx+rkb+qdT"
+#define CERT_RSA \
+"ssh-rsa-cert-v01@openssh.com AAAAHHNzaC1yc2EtY2VydC12MDFAb3BlbnNzaC5jb20AAAAg89JX6OBMYDSxER8fnU5y8xxeMCHR/hI0uVqdEhNyCpcAAAADAQABAAABAQDf56l/5UYqgY9oBlet/pLRzK6ZCd12QYGdUVfQDl6HftG0u6DSpjm2HGwFRsYZWv2ZN3ZBfAu6MHBiDmXUw/8WaD7nfXZmDH2keZL6opQttqvSGU2Cm00Rv5o1R3ej2qDdpepebv5meMBXTl5/+bE1E3Zm+4STDtxGmlMlxsEj68XeVe4JedfaSUMj3kaXYBbdYdG1qeosdle4GSONEEMpzsxSr8Y/WGYuIB33l29Tt9mNGUgSw/zjMYQjUVvQv+SY8dw62JV8d+3wK2YL2/r73gms6I8EE1JxX53KuAAY+x0p2v/W8ilCYI2Ijyzc8KIPwntmIFpibQjx+rkb+qdTAAAAAAAAA+0AAAABAAAAB3VseXNzZXMAAAAXAAAAB3VseXNzZXMAAAAIb2R5c3NldXMAAAAAAAAAAP//////////AAAAAAAAAIIAAAAVcGVybWl0LVgxMS1mb3J3YXJkaW5nAAAAAAAAABdwZXJtaXQtYWdlbnQtZm9yd2FyZGluZwAAAAAAAAAWcGVybWl0LXBvcnQtZm9yd2FyZGluZwAAAAAAAAAKcGVybWl0LXB0eQAAAAAAAAAOcGVybWl0LXVzZXItcmMAAAAAAAAAAAAAADMAAAALc3NoLWVkMjU1MTkAAAAgM9BeYRUxUuZ4VHJp8oxVaA8OS/z+5EFPCZwQNq1nMwMAAABTAAAAC3NzaC1lZDI1NTE5AAAAQGCDA6PWw4x9bHQl0w7NqifHepumqD3dmyMx+hZGuPRon+TsyCjfytu7hWmV7l9XUF0fPQNFQ7FGat5e+7YUNgE= id_rsa.pub"
+#define PRIV_DSA \
+"-----BEGIN OPENSSH PRIVATE KEY-----\n"\
+"b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAABsgAAAAdzc2gtZH\n"\
+"NzAAAAgQCsGTfjpQ465EOkfQXJM9BOvfRQE0fqlykAls+ncz+T7hrbeScRu8xpwzsznJNm\n"\
+"xlW8o6cUDiHmBJ5OHgamUC9N7YJeU/6fnOAZifgN8mqK6k8pKHuje8ANOiYgHLl0yiASQA\n"\
+"3//qMyzZ+W/hemoLSmLAbEqlfWVeyYx+wta1Vm+QAAABUAvWyehvUvdHvQxavYgS5p0t5Q\n"\
+"d7UAAACBAIRA9Yy+f4Kzqpv/qICPO3zk42UuP7WAhSW2nCbQdLlCiSTxcjKgcvXNRckwJP\n"\
+"44JjSHOtJy/AMtJrPIbLYG6KuWTdBlEHFiG6DafvLG+qPMSL2bPjXTOhuOMbCHIZ+5WBkW\n"\
+"THeG/Nv11iI01Of9V6tXkig23K370flkRkXFi9MdAAAAgCt6YUcQkNwG7B/e5M1FZsLP9O\n"\
+"kVB3BwLAOjmWdHpyhu3HpwSJa3XLEvhXN0i6IVI2KgPo/2GtYA6rHt14L+6u1pmhh8sAvQ\n"\
+"ksp3qZB+xh/NP+hBqf0sbHX0yYbzKOvI5SCc/kKK6yagcBZOsubM/KC8TxyVgmD5c6WzYs\n"\
+"h5TEpvAAAB2PHjRbbx40W2AAAAB3NzaC1kc3MAAACBAKwZN+OlDjrkQ6R9Bckz0E699FAT\n"\
+"R+qXKQCWz6dzP5PuGtt5JxG7zGnDOzOck2bGVbyjpxQOIeYEnk4eBqZQL03tgl5T/p+c4B\n"\
+"mJ+A3yaorqTykoe6N7wA06JiAcuXTKIBJADf/+ozLNn5b+F6agtKYsBsSqV9ZV7JjH7C1r\n"\
+"VWb5AAAAFQC9bJ6G9S90e9DFq9iBLmnS3lB3tQAAAIEAhED1jL5/grOqm/+ogI87fOTjZS\n"\
+"4/tYCFJbacJtB0uUKJJPFyMqBy9c1FyTAk/jgmNIc60nL8Ay0ms8hstgboq5ZN0GUQcWIb\n"\
+"oNp+8sb6o8xIvZs+NdM6G44xsIchn7lYGRZMd4b82/XWIjTU5/1Xq1eSKDbcrfvR+WRGRc\n"\
+"WL0x0AAACAK3phRxCQ3AbsH97kzUVmws/06RUHcHAsA6OZZ0enKG7cenBIlrdcsS+Fc3SL\n"\
+"ohUjYqA+j/Ya1gDqse3Xgv7q7WmaGHywC9CSynepkH7GH80/6EGp/SxsdfTJhvMo68jlIJ\n"\
+"z+QorrJqBwFk6y5sz8oLxPHJWCYPlzpbNiyHlMSm8AAAAUUA+OGldMi76ClO/sstpdbBUE\n"\
+"lq8AAAAAAQI=\n"\
+"-----END OPENSSH PRIVATE KEY-----\n"
+#define PUB_DSA \
+"ssh-dss AAAAB3NzaC1kc3MAAACBAKwZN+OlDjrkQ6R9Bckz0E699FATR+qXKQCWz6dzP5PuGtt5JxG7zGnDOzOck2bGVbyjpxQOIeYEnk4eBqZQL03tgl5T/p+c4BmJ+A3yaorqTykoe6N7wA06JiAcuXTKIBJADf/+ozLNn5b+F6agtKYsBsSqV9ZV7JjH7C1rVWb5AAAAFQC9bJ6G9S90e9DFq9iBLmnS3lB3tQAAAIEAhED1jL5/grOqm/+ogI87fOTjZS4/tYCFJbacJtB0uUKJJPFyMqBy9c1FyTAk/jgmNIc60nL8Ay0ms8hstgboq5ZN0GUQcWIboNp+8sb6o8xIvZs+NdM6G44xsIchn7lYGRZMd4b82/XWIjTU5/1Xq1eSKDbcrfvR+WRGRcWL0x0AAACAK3phRxCQ3AbsH97kzUVmws/06RUHcHAsA6OZZ0enKG7cenBIlrdcsS+Fc3SLohUjYqA+j/Ya1gDqse3Xgv7q7WmaGHywC9CSynepkH7GH80/6EGp/SxsdfTJhvMo68jlIJz+QorrJqBwFk6y5sz8oLxPHJWCYPlzpbNiyHlMSm8="
+#define CERT_DSA \
+"ssh-dss-cert-v01@openssh.com AAAAHHNzaC1kc3MtY2VydC12MDFAb3BlbnNzaC5jb20AAAAguF716Yub+vVKNlONKLsfxGYWkRe/PyjfYdGRTsFaDvAAAACBAKwZN+OlDjrkQ6R9Bckz0E699FATR+qXKQCWz6dzP5PuGtt5JxG7zGnDOzOck2bGVbyjpxQOIeYEnk4eBqZQL03tgl5T/p+c4BmJ+A3yaorqTykoe6N7wA06JiAcuXTKIBJADf/+ozLNn5b+F6agtKYsBsSqV9ZV7JjH7C1rVWb5AAAAFQC9bJ6G9S90e9DFq9iBLmnS3lB3tQAAAIEAhED1jL5/grOqm/+ogI87fOTjZS4/tYCFJbacJtB0uUKJJPFyMqBy9c1FyTAk/jgmNIc60nL8Ay0ms8hstgboq5ZN0GUQcWIboNp+8sb6o8xIvZs+NdM6G44xsIchn7lYGRZMd4b82/XWIjTU5/1Xq1eSKDbcrfvR+WRGRcWL0x0AAACAK3phRxCQ3AbsH97kzUVmws/06RUHcHAsA6OZZ0enKG7cenBIlrdcsS+Fc3SLohUjYqA+j/Ya1gDqse3Xgv7q7WmaGHywC9CSynepkH7GH80/6EGp/SxsdfTJhvMo68jlIJz+QorrJqBwFk6y5sz8oLxPHJWCYPlzpbNiyHlMSm8AAAAAAAAD6AAAAAEAAAAHdWx5c3NlcwAAABcAAAAHdWx5c3NlcwAAAAhvZHlzc2V1cwAAAAAAAAAA//////////8AAAAAAAAAggAAABVwZXJtaXQtWDExLWZvcndhcmRpbmcAAAAAAAAAF3Blcm1pdC1hZ2VudC1mb3J3YXJkaW5nAAAAAAAAABZwZXJtaXQtcG9ydC1mb3J3YXJkaW5nAAAAAAAAAApwZXJtaXQtcHR5AAAAAAAAAA5wZXJtaXQtdXNlci1yYwAAAAAAAAAAAAAAMwAAAAtzc2gtZWQyNTUxOQAAACAz0F5hFTFS5nhUcmnyjFVoDw5L/P7kQU8JnBA2rWczAwAAAFMAAAALc3NoLWVkMjU1MTkAAABAjMQEZcbdUYJBjIC4GxByFDOb8tv71vDZdx7irHwaqIjx5rzpJUuOV1r8ZO4kY+Yaiun1yrWj2QYkfJrHBvD1DA== id_dsa.pub"
+#define PRIV_ECDSA \
+"-----BEGIN OPENSSH PRIVATE KEY-----\n"\
+"b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAaAAAABNlY2RzYS\n"\
+"1zaGEyLW5pc3RwMjU2AAAACG5pc3RwMjU2AAAAQQTDJ0VlMv+0rguNzaJ1DF2KueHaxRSQ\n"\
+"6LpIxGbulrg1a8RPbnMXwag5GcDiDllD2lDUJUuBEWyjXA0rZoZX35ELAAAAoE/Bbr5PwW\n"\
+"6+AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBMMnRWUy/7SuC43N\n"\
+"onUMXYq54drFFJDoukjEZu6WuDVrxE9ucxfBqDkZwOIOWUPaUNQlS4ERbKNcDStmhlffkQ\n"\
+"sAAAAhAIhE6hCID5oOm1TDktc++KFKyScjLifcZ6Cgv5xSSyLOAAAAAAECAwQFBgc=\n"\
+"-----END OPENSSH PRIVATE KEY-----\n"
+#define PUB_ECDSA \
+"ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBMMnRWUy/7SuC43NonUMXYq54drFFJDoukjEZu6WuDVrxE9ucxfBqDkZwOIOWUPaUNQlS4ERbKNcDStmhlffkQs="
+#define CERT_ECDSA \
+"ecdsa-sha2-nistp256-cert-v01@openssh.com AAAAKGVjZHNhLXNoYTItbmlzdHAyNTYtY2VydC12MDFAb3BlbnNzaC5jb20AAAAgVJZuM/1AOe6n++qRWMyUuAThYqLvvQxj5CGflLODp60AAAAIbmlzdHAyNTYAAABBBMMnRWUy/7SuC43NonUMXYq54drFFJDoukjEZu6WuDVrxE9ucxfBqDkZwOIOWUPaUNQlS4ERbKNcDStmhlffkQsAAAAAAAAD6QAAAAEAAAAHdWx5c3NlcwAAABcAAAAHdWx5c3NlcwAAAAhvZHlzc2V1cwAAAAAAAAAA//////////8AAAAAAAAAggAAABVwZXJtaXQtWDExLWZvcndhcmRpbmcAAAAAAAAAF3Blcm1pdC1hZ2VudC1mb3J3YXJkaW5nAAAAAAAAABZwZXJtaXQtcG9ydC1mb3J3YXJkaW5nAAAAAAAAAApwZXJtaXQtcHR5AAAAAAAAAA5wZXJtaXQtdXNlci1yYwAAAAAAAAAAAAAAMwAAAAtzc2gtZWQyNTUxOQAAACAz0F5hFTFS5nhUcmnyjFVoDw5L/P7kQU8JnBA2rWczAwAAAFMAAAALc3NoLWVkMjU1MTkAAABAtdJpcF6ZmQL+ueices4QZeL7AK8Xuo08jyLgiolhjKy2jj4LSUki4aX/ZeZeJuby1ovGrfaeFAgx3itPLR7IAQ== id_ecdsa.pub"
+#define PRIV_ED25519 \
+"-----BEGIN OPENSSH PRIVATE KEY-----\n"\
+"b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW\n"\
+"QyNTUxOQAAACAz0F5hFTFS5nhUcmnyjFVoDw5L/P7kQU8JnBA2rWczAwAAAIhWlP99VpT/\n"\
+"fQAAAAtzc2gtZWQyNTUxOQAAACAz0F5hFTFS5nhUcmnyjFVoDw5L/P7kQU8JnBA2rWczAw\n"\
+"AAAEDE1rlcMC0s0X3TKVZAOVavZOywwkXw8tO5dLObxaCMEDPQXmEVMVLmeFRyafKMVWgP\n"\
+"Dkv8/uRBTwmcEDatZzMDAAAAAAECAwQF\n"\
+"-----END OPENSSH PRIVATE KEY-----\n"
+#define PUB_ED25519 \
+"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIDPQXmEVMVLmeFRyafKMVWgPDkv8/uRBTwmcEDatZzMD"
+#define CERT_ED25519 \
+"ssh-ed25519-cert-v01@openssh.com AAAAIHNzaC1lZDI1NTE5LWNlcnQtdjAxQG9wZW5zc2guY29tAAAAIMDQjYH6XRzH3j3MW1DdjCoAfvrHfgjnVGF+sLK0pBfqAAAAIDPQXmEVMVLmeFRyafKMVWgPDkv8/uRBTwmcEDatZzMDAAAAAAAAA+sAAAABAAAAB3VseXNzZXMAAAAXAAAAB3VseXNzZXMAAAAIb2R5c3NldXMAAAAAAAAAAP//////////AAAAAAAAAIIAAAAVcGVybWl0LVgxMS1mb3J3YXJkaW5nAAAAAAAAABdwZXJtaXQtYWdlbnQtZm9yd2FyZGluZwAAAAAAAAAWcGVybWl0LXBvcnQtZm9yd2FyZGluZwAAAAAAAAAKcGVybWl0LXB0eQAAAAAAAAAOcGVybWl0LXVzZXItcmMAAAAAAAAAAAAAADMAAAALc3NoLWVkMjU1MTkAAAAgM9BeYRUxUuZ4VHJp8oxVaA8OS/z+5EFPCZwQNq1nMwMAAABTAAAAC3NzaC1lZDI1NTE5AAAAQBj0og+s09/HpwdHZbzN0twooKPDWWrxGfnP1Joy6cDnY2BCSQ7zg9vbq11kLF8H/sKOTZWAQrUZ7LlChOu9Ogw= id_ed25519.pub"
+#define PRIV_ECDSA_SK \
+"-----BEGIN OPENSSH PRIVATE KEY-----\n"\
+"b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAfwAAACJzay1lY2\n"\
+"RzYS1zaGEyLW5pc3RwMjU2QG9wZW5zc2guY29tAAAACG5pc3RwMjU2AAAAQQTYyU76zop1\n"\
+"VOb4DfKWYnR5b0TOC3zw8DzObAfHWB5o6xls+tOYiEleXvIEi00Da2iCK47habZTOhLyeB\n"\
+"X2Avu5AAAABHNzaDoAAAGYqUAQSKlAEEgAAAAic2stZWNkc2Etc2hhMi1uaXN0cDI1NkBv\n"\
+"cGVuc3NoLmNvbQAAAAhuaXN0cDI1NgAAAEEE2MlO+s6KdVTm+A3ylmJ0eW9Ezgt88PA8zm\n"\
+"wHx1geaOsZbPrTmIhJXl7yBItNA2togiuO4Wm2UzoS8ngV9gL7uQAAAARzc2g6AQAAAOMt\n"\
+"LS0tLUJFR0lOIEVDIFBSSVZBVEUgS0VZLS0tLS0KTUhjQ0FRRUVJSHFsZjNsWTkxZFhwUn\n"\
+"dYZDBrS0lYWmNpeDRRcDBNSU15Ny9JMUxXSTFuWG9Bb0dDQ3FHU000OQpBd0VIb1VRRFFn\n"\
+"QUUyTWxPK3M2S2RWVG0rQTN5bG1KMGVXOUV6Z3Q4OFBBOHptd0h4MWdlYU9zWmJQclRtSW\n"\
+"hKClhsN3lCSXROQTJ0b2dpdU80V20yVXpvUzhuZ1Y5Z0w3dVE9PQotLS0tLUVORCBFQyBQ\n"\
+"UklWQVRFIEtFWS0tLS0tCgAAAAAAAAAbZGptQGRqbS5zeWQuY29ycC5nb29nbGUuY29tAQ\n"\
+"IDBAUG\n"\
+"-----END OPENSSH PRIVATE KEY-----\n"
+#define PUB_ECDSA_SK \
+"sk-ecdsa-sha2-nistp256@openssh.com AAAAInNrLWVjZHNhLXNoYTItbmlzdHAyNTZAb3BlbnNzaC5jb20AAAAIbmlzdHAyNTYAAABBBNjJTvrOinVU5vgN8pZidHlvRM4LfPDwPM5sB8dYHmjrGWz605iISV5e8gSLTQNraIIrjuFptlM6EvJ4FfYC+7kAAAAEc3NoOg=="
+#define CERT_ECDSA_SK \
+"sk-ecdsa-sha2-nistp256-cert-v01@openssh.com AAAAK3NrLWVjZHNhLXNoYTItbmlzdHAyNTYtY2VydC12MDFAb3BlbnNzaC5jb20AAAAgKLHtIca++5VoDrUAXU/KqGJZ7jZEnuJSTvt7VrYY9foAAAAIbmlzdHAyNTYAAABBBNjJTvrOinVU5vgN8pZidHlvRM4LfPDwPM5sB8dYHmjrGWz605iISV5e8gSLTQNraIIrjuFptlM6EvJ4FfYC+7kAAAAEc3NoOgAAAAAAAAPqAAAAAQAAAAd1bHlzc2VzAAAAFwAAAAd1bHlzc2VzAAAACG9keXNzZXVzAAAAAAAAAAD//////////wAAAAAAAACCAAAAFXBlcm1pdC1YMTEtZm9yd2FyZGluZwAAAAAAAAAXcGVybWl0LWFnZW50LWZvcndhcmRpbmcAAAAAAAAAFnBlcm1pdC1wb3J0LWZvcndhcmRpbmcAAAAAAAAACnBlcm1pdC1wdHkAAAAAAAAADnBlcm1pdC11c2VyLXJjAAAAAAAAAAAAAAAzAAAAC3NzaC1lZDI1NTE5AAAAIDPQXmEVMVLmeFRyafKMVWgPDkv8/uRBTwmcEDatZzMDAAAAUwAAAAtzc2gtZWQyNTUxOQAAAEB1naZOQDLaDr+fwn6E9x8/8HeiaUubDzPexfNQMz+m/7RD0gd5uJhHYUfDb5+/sIx1I7bUEeRIDkBbmZ2foo0E"
+#define PRIV_ED25519_SK \
+"-----BEGIN OPENSSH PRIVATE KEY-----\n"\
+"b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAASgAAABpzay1zc2\n"\
+"gtZWQyNTUxOUBvcGVuc3NoLmNvbQAAACCTJtH10vWhIDxd62edvMLg9u2cwYKyqa7332je\n"\
+"RArHjAAAAARzc2g6AAAAwN7vvE3e77xNAAAAGnNrLXNzaC1lZDI1NTE5QG9wZW5zc2guY2\n"\
+"9tAAAAIJMm0fXS9aEgPF3rZ528wuD27ZzBgrKprvffaN5ECseMAAAABHNzaDoBAAAAQEsS\n"\
+"xLFiVzfpH2mt9xh8i/zmHV646Hud4QruNBAGNl8gkybR9dL1oSA8XetnnbzC4PbtnMGCsq\n"\
+"mu999o3kQKx4wAAAAAAAAAG2RqbUBkam0uc3lkLmNvcnAuZ29vZ2xlLmNvbQECAwQFBg==\n"\
+"-----END OPENSSH PRIVATE KEY-----\n"
+#define PUB_ED25519_SK \
+"sk-ssh-ed25519@openssh.com AAAAGnNrLXNzaC1lZDI1NTE5QG9wZW5zc2guY29tAAAAIJMm0fXS9aEgPF3rZ528wuD27ZzBgrKprvffaN5ECseMAAAABHNzaDo="
+#define CERT_ED25519_SK \
+"sk-ssh-ed25519-cert-v01@openssh.com AAAAI3NrLXNzaC1lZDI1NTE5LWNlcnQtdjAxQG9wZW5zc2guY29tAAAAIJiT+C/VLMWholFZ4xhOyJr0nSLZSFRIM3I07wUNTRPaAAAAIJMm0fXS9aEgPF3rZ528wuD27ZzBgrKprvffaN5ECseMAAAABHNzaDoAAAAAAAAD7AAAAAEAAAAHdWx5c3NlcwAAABcAAAAHdWx5c3NlcwAAAAhvZHlzc2V1cwAAAAAAAAAA//////////8AAAAAAAAAggAAABVwZXJtaXQtWDExLWZvcndhcmRpbmcAAAAAAAAAF3Blcm1pdC1hZ2VudC1mb3J3YXJkaW5nAAAAAAAAABZwZXJtaXQtcG9ydC1mb3J3YXJkaW5nAAAAAAAAAApwZXJtaXQtcHR5AAAAAAAAAA5wZXJtaXQtdXNlci1yYwAAAAAAAAAAAAAAMwAAAAtzc2gtZWQyNTUxOQAAACAz0F5hFTFS5nhUcmnyjFVoDw5L/P7kQU8JnBA2rWczAwAAAFMAAAALc3NoLWVkMjU1MTkAAABAX0Pu13B94pVR3qq8MJQGkOS1Cd7AAM1k6O2VSwyDPM/LfsWIQ4ywgxDmk3hjXWOY7BqljuMxo5VO4JymEIhQBA=="
diff --git a/crypto/openssh/regress/misc/fuzz-harness/kex_fuzz.cc b/crypto/openssh/regress/misc/fuzz-harness/kex_fuzz.cc
new file mode 100644
index 000000000000..4740a7cb04c1
--- /dev/null
+++ b/crypto/openssh/regress/misc/fuzz-harness/kex_fuzz.cc
@@ -0,0 +1,461 @@
+// libfuzzer driver for key exchange fuzzing.
+
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+
+extern "C" {
+
+#include "includes.h"
+#include "ssherr.h"
+#include "ssh_api.h"
+#include "sshbuf.h"
+#include "packet.h"
+#include "myproposal.h"
+#include "xmalloc.h"
+#include "authfile.h"
+#include "log.h"
+
+#include "fixed-keys.h"
+
+// Define if you want to generate traces.
+/* #define STANDALONE 1 */
+
+static int prepare_key(struct shared_state *st, int keytype, int bits);
+
+struct shared_state {
+ size_t nkeys;
+ struct sshkey **privkeys, **pubkeys;
+};
+
+struct test_state {
+ struct sshbuf *smsgs, *cmsgs; /* output, for standalone mode */
+ struct sshbuf *sin, *cin; /* input; setup per-test in do_kex_with_key */
+ struct sshbuf *s_template, *c_template; /* main copy of input */
+};
+
+static int
+do_send_and_receive(struct ssh *from, struct ssh *to,
+ struct sshbuf *store, int clobber, size_t *n)
+{
+ u_char type;
+ size_t len;
+ const u_char *buf;
+ int r;
+
+ for (*n = 0;; (*n)++) {
+ if ((r = ssh_packet_next(from, &type)) != 0) {
+ debug_fr(r, "ssh_packet_next");
+ return r;
+ }
+ if (type != 0)
+ return 0;
+ buf = ssh_output_ptr(from, &len);
+ debug_f("%zu%s", len, clobber ? " ignore" : "");
+ if (len == 0)
+ return 0;
+ if ((r = ssh_output_consume(from, len)) != 0) {
+ debug_fr(r, "ssh_output_consume");
+ return r;
+ }
+ if (store != NULL && (r = sshbuf_put(store, buf, len)) != 0) {
+ debug_fr(r, "sshbuf_put");
+ return r;
+ }
+ if (!clobber && (r = ssh_input_append(to, buf, len)) != 0) {
+ debug_fr(r, "ssh_input_append");
+ return r;
+ }
+ }
+}
+
+static int
+run_kex(struct test_state *ts, struct ssh *client, struct ssh *server)
+{
+ int r = 0;
+ size_t cn, sn;
+
+ /* If fuzzing, replace server/client input */
+ if (ts->sin != NULL) {
+ if ((r = ssh_input_append(server, sshbuf_ptr(ts->sin),
+ sshbuf_len(ts->sin))) != 0) {
+ error_fr(r, "ssh_input_append");
+ return r;
+ }
+ sshbuf_reset(ts->sin);
+ }
+ if (ts->cin != NULL) {
+ if ((r = ssh_input_append(client, sshbuf_ptr(ts->cin),
+ sshbuf_len(ts->cin))) != 0) {
+ error_fr(r, "ssh_input_append");
+ return r;
+ }
+ sshbuf_reset(ts->cin);
+ }
+ while (!server->kex->done || !client->kex->done) {
+ cn = sn = 0;
+ debug_f("S:");
+ if ((r = do_send_and_receive(server, client,
+ ts->smsgs, ts->cin != NULL, &sn)) != 0) {
+ debug_fr(r, "S->C");
+ break;
+ }
+ debug_f("C:");
+ if ((r = do_send_and_receive(client, server,
+ ts->cmsgs, ts->sin != NULL, &cn)) != 0) {
+ debug_fr(r, "C->S");
+ break;
+ }
+ if (cn == 0 && sn == 0) {
+ debug_f("kex stalled");
+ r = SSH_ERR_PROTOCOL_ERROR;
+ break;
+ }
+ }
+ debug_fr(r, "done");
+ return r;
+}
+
+static void
+store_key(struct shared_state *st, struct sshkey *pubkey,
+ struct sshkey *privkey)
+{
+ if (st == NULL || pubkey->type < 0 || pubkey->type > INT_MAX ||
+ privkey->type != pubkey->type ||
+ ((size_t)pubkey->type < st->nkeys &&
+ st->pubkeys[pubkey->type] != NULL))
+ abort();
+ if ((size_t)pubkey->type >= st->nkeys) {
+ st->pubkeys = (struct sshkey **)xrecallocarray(st->pubkeys,
+ st->nkeys, pubkey->type + 1, sizeof(*st->pubkeys));
+ st->privkeys = (struct sshkey **)xrecallocarray(st->privkeys,
+ st->nkeys, privkey->type + 1, sizeof(*st->privkeys));
+ st->nkeys = privkey->type + 1;
+ }
+ debug_f("store %s at %d", sshkey_ssh_name(pubkey), pubkey->type);
+ st->pubkeys[pubkey->type] = pubkey;
+ st->privkeys[privkey->type] = privkey;
+}
+
+static int
+prepare_keys(struct shared_state *st)
+{
+ if (prepare_key(st, KEY_RSA, 2048) != 0 ||
+ prepare_key(st, KEY_DSA, 1024) != 0 ||
+ prepare_key(st, KEY_ECDSA, 256) != 0 ||
+ prepare_key(st, KEY_ED25519, 256) != 0) {
+ error_f("key prepare failed");
+ return -1;
+ }
+ return 0;
+}
+
+static struct sshkey *
+get_pubkey(struct shared_state *st, int keytype)
+{
+ if (st == NULL || keytype < 0 || (size_t)keytype >= st->nkeys ||
+ st->pubkeys == NULL || st->pubkeys[keytype] == NULL)
+ abort();
+ return st->pubkeys[keytype];
+}
+
+static struct sshkey *
+get_privkey(struct shared_state *st, int keytype)
+{
+ if (st == NULL || keytype < 0 || (size_t)keytype >= st->nkeys ||
+ st->privkeys == NULL || st->privkeys[keytype] == NULL)
+ abort();
+ return st->privkeys[keytype];
+}
+
+static int
+do_kex_with_key(struct shared_state *st, struct test_state *ts,
+ const char *kex, int keytype)
+{
+ struct ssh *client = NULL, *server = NULL;
+ struct sshkey *privkey = NULL, *pubkey = NULL;
+ struct sshbuf *state = NULL;
+ struct kex_params kex_params;
+ const char *ccp, *proposal[PROPOSAL_MAX] = { KEX_CLIENT };
+ char *myproposal[PROPOSAL_MAX] = {0}, *keyname = NULL;
+ int i, r;
+
+ ts->cin = ts->sin = NULL;
+ if (ts->c_template != NULL &&
+ (ts->cin = sshbuf_fromb(ts->c_template)) == NULL)
+ abort();
+ if (ts->s_template != NULL &&
+ (ts->sin = sshbuf_fromb(ts->s_template)) == NULL)
+ abort();
+
+ pubkey = get_pubkey(st, keytype);
+ privkey = get_privkey(st, keytype);
+ keyname = xstrdup(sshkey_ssh_name(privkey));
+ if (ts->cin != NULL) {
+ debug_f("%s %s clobber client %zu", kex, keyname,
+ sshbuf_len(ts->cin));
+ } else if (ts->sin != NULL) {
+ debug_f("%s %s clobber server %zu", kex, keyname,
+ sshbuf_len(ts->sin));
+ } else
+ debug_f("%s %s noclobber", kex, keyname);
+
+ for (i = 0; i < PROPOSAL_MAX; i++) {
+ ccp = proposal[i];
+#ifdef CIPHER_NONE_AVAIL
+ if (i == PROPOSAL_ENC_ALGS_CTOS || i == PROPOSAL_ENC_ALGS_STOC)
+ ccp = "none";
+#endif
+ if (i == PROPOSAL_SERVER_HOST_KEY_ALGS)
+ ccp = keyname;
+ else if (i == PROPOSAL_KEX_ALGS && kex != NULL)
+ ccp = kex;
+ if ((myproposal[i] = strdup(ccp)) == NULL) {
+ error_f("strdup prop %d", i);
+ goto fail;
+ }
+ }
+ memcpy(kex_params.proposal, myproposal, sizeof(myproposal));
+ if ((r = ssh_init(&client, 0, &kex_params)) != 0) {
+ error_fr(r, "init client");
+ goto fail;
+ }
+ if ((r = ssh_init(&server, 1, &kex_params)) != 0) {
+ error_fr(r, "init server");
+ goto fail;
+ }
+ if ((r = ssh_add_hostkey(server, privkey)) != 0 ||
+ (r = ssh_add_hostkey(client, pubkey)) != 0) {
+ error_fr(r, "add hostkeys");
+ goto fail;
+ }
+ if ((r = run_kex(ts, client, server)) != 0) {
+ error_fr(r, "kex");
+ goto fail;
+ }
+ /* XXX rekex, set_state, etc */
+ fail:
+ for (i = 0; i < PROPOSAL_MAX; i++)
+ free(myproposal[i]);
+ sshbuf_free(ts->sin);
+ sshbuf_free(ts->cin);
+ sshbuf_free(state);
+ ssh_free(client);
+ ssh_free(server);
+ free(keyname);
+ return r;
+}
+
+static int
+prepare_key(struct shared_state *st, int kt, int bits)
+{
+ const char *pubstr = NULL;
+ const char *privstr = NULL;
+ char *tmp, *cp;
+ struct sshkey *privkey = NULL, *pubkey = NULL;
+ struct sshbuf *b = NULL;
+ int r;
+
+ switch (kt) {
+ case KEY_RSA:
+ pubstr = PUB_RSA;
+ privstr = PRIV_RSA;
+ break;
+ case KEY_DSA:
+ pubstr = PUB_DSA;
+ privstr = PRIV_DSA;
+ break;
+ case KEY_ECDSA:
+ pubstr = PUB_ECDSA;
+ privstr = PRIV_ECDSA;
+ break;
+ case KEY_ED25519:
+ pubstr = PUB_ED25519;
+ privstr = PRIV_ED25519;
+ break;
+ default:
+ abort();
+ }
+ if ((b = sshbuf_from(privstr, strlen(privstr))) == NULL)
+ abort();
+ if ((r = sshkey_parse_private_fileblob(b, "", &privkey, NULL)) != 0) {
+ error_fr(r, "priv %d", kt);
+ abort();
+ }
+ sshbuf_free(b);
+ tmp = cp = xstrdup(pubstr);
+ if ((pubkey = sshkey_new(KEY_UNSPEC)) == NULL)
+ abort();
+ if ((r = sshkey_read(pubkey, &cp)) != 0) {
+ error_fr(r, "pub %d", kt);
+ abort();
+ }
+ free(tmp);
+
+ store_key(st, pubkey, privkey);
+ return 0;
+}
+
+#if defined(STANDALONE)
+
+#if 0 /* use this if generating new keys to embed above */
+static int
+prepare_key(struct shared_state *st, int keytype, int bits)
+{
+ struct sshkey *privkey = NULL, *pubkey = NULL;
+ int r;
+
+ if ((r = sshkey_generate(keytype, bits, &privkey)) != 0) {
+ error_fr(r, "generate");
+ abort();
+ }
+ if ((r = sshkey_from_private(privkey, &pubkey)) != 0) {
+ error_fr(r, "make pubkey");
+ abort();
+ }
+ store_key(st, pubkey, privkey);
+ return 0;
+}
+#endif
+
+int main(void)
+{
+ static struct shared_state *st;
+ struct test_state *ts;
+ const int keytypes[] = { KEY_RSA, KEY_DSA, KEY_ECDSA, KEY_ED25519, -1 };
+ const char *kextypes[] = {
+ "sntrup761x25519-sha512@openssh.com",
+ "curve25519-sha256@libssh.org",
+ "ecdh-sha2-nistp256",
+ "diffie-hellman-group1-sha1",
+ "diffie-hellman-group-exchange-sha1",
+ NULL,
+ };
+ int i, j;
+ char *path;
+ FILE *f;
+
+ log_init("kex_fuzz", SYSLOG_LEVEL_DEBUG3, SYSLOG_FACILITY_AUTH, 1);
+
+ if (st == NULL) {
+ st = (struct shared_state *)xcalloc(1, sizeof(*st));
+ prepare_keys(st);
+ }
+ /* Run each kex method for each key and save client/server packets */
+ for (i = 0; keytypes[i] != -1; i++) {
+ for (j = 0; kextypes[j] != NULL; j++) {
+ ts = (struct test_state *)xcalloc(1, sizeof(*ts));
+ ts->smsgs = sshbuf_new();
+ ts->cmsgs = sshbuf_new();
+ do_kex_with_key(st, ts, kextypes[j], keytypes[i]);
+ xasprintf(&path, "S2C-%s-%s",
+ kextypes[j], sshkey_type(st->pubkeys[keytypes[i]]));
+ debug_f("%s", path);
+ if ((f = fopen(path, "wb+")) == NULL)
+ abort();
+ if (fwrite(sshbuf_ptr(ts->smsgs), 1,
+ sshbuf_len(ts->smsgs), f) != sshbuf_len(ts->smsgs))
+ abort();
+ fclose(f);
+ free(path);
+ //sshbuf_dump(ts->smsgs, stderr);
+ xasprintf(&path, "C2S-%s-%s",
+ kextypes[j], sshkey_type(st->pubkeys[keytypes[i]]));
+ debug_f("%s", path);
+ if ((f = fopen(path, "wb+")) == NULL)
+ abort();
+ if (fwrite(sshbuf_ptr(ts->cmsgs), 1,
+ sshbuf_len(ts->cmsgs), f) != sshbuf_len(ts->cmsgs))
+ abort();
+ fclose(f);
+ free(path);
+ //sshbuf_dump(ts->cmsgs, stderr);
+ sshbuf_free(ts->smsgs);
+ sshbuf_free(ts->cmsgs);
+ free(ts);
+ }
+ }
+ for (i = 0; keytypes[i] != -1; i++) {
+ xasprintf(&path, "%s.priv",
+ sshkey_type(st->privkeys[keytypes[i]]));
+ debug_f("%s", path);
+ if (sshkey_save_private(st->privkeys[keytypes[i]], path,
+ "", "", SSHKEY_PRIVATE_OPENSSH, NULL, 0) != 0)
+ abort();
+ free(path);
+ xasprintf(&path, "%s.pub",
+ sshkey_type(st->pubkeys[keytypes[i]]));
+ debug_f("%s", path);
+ if (sshkey_save_public(st->pubkeys[keytypes[i]], path, "") != 0)
+ abort();
+ free(path);
+ }
+}
+#else /* !STANDALONE */
+static void
+do_kex(struct shared_state *st, struct test_state *ts, const char *kex)
+{
+ do_kex_with_key(st, ts, kex, KEY_RSA);
+ do_kex_with_key(st, ts, kex, KEY_DSA);
+ do_kex_with_key(st, ts, kex, KEY_ECDSA);
+ do_kex_with_key(st, ts, kex, KEY_ED25519);
+}
+
+static void
+kex_tests(struct shared_state *st, struct test_state *ts)
+{
+ do_kex(st, ts, "sntrup761x25519-sha512@openssh.com");
+ do_kex(st, ts, "curve25519-sha256@libssh.org");
+ do_kex(st, ts, "ecdh-sha2-nistp256");
+ do_kex(st, ts, "diffie-hellman-group1-sha1");
+ do_kex(st, ts, "diffie-hellman-group-exchange-sha1");
+}
+
+int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size)
+{
+ static struct shared_state *st;
+ struct test_state *ts;
+ u_char crbuf[SSH_MAX_PRE_BANNER_LINES * 4];
+ u_char zbuf[4096] = {0};
+ static LogLevel loglevel = SYSLOG_LEVEL_INFO;
+
+ if (st == NULL) {
+ if (getenv("DEBUG") != NULL || getenv("KEX_FUZZ_DEBUG") != NULL)
+ loglevel = SYSLOG_LEVEL_DEBUG3;
+ log_init("kex_fuzz",
+ loglevel, SYSLOG_FACILITY_AUTH, 1);
+ st = (struct shared_state *)xcalloc(1, sizeof(*st));
+ prepare_keys(st);
+ }
+
+ /* Ensure that we can complete (fail) banner exchange at least */
+ memset(crbuf, '\n', sizeof(crbuf));
+
+ ts = (struct test_state *)xcalloc(1, sizeof(*ts));
+ if ((ts->s_template = sshbuf_new()) == NULL ||
+ sshbuf_put(ts->s_template, data, size) != 0 ||
+ sshbuf_put(ts->s_template, crbuf, sizeof(crbuf)) != 0 ||
+ sshbuf_put(ts->s_template, zbuf, sizeof(zbuf)) != 0)
+ abort();
+ kex_tests(st, ts);
+ sshbuf_free(ts->s_template);
+ free(ts);
+
+ ts = (struct test_state *)xcalloc(1, sizeof(*ts));
+ if ((ts->c_template = sshbuf_new()) == NULL ||
+ sshbuf_put(ts->c_template, data, size) != 0 ||
+ sshbuf_put(ts->c_template, crbuf, sizeof(crbuf)) != 0 ||
+ sshbuf_put(ts->c_template, zbuf, sizeof(zbuf)) != 0)
+ abort();
+ kex_tests(st, ts);
+ sshbuf_free(ts->c_template);
+ free(ts);
+
+ return 0;
+}
+#endif /* STANDALONE */
+} /* extern "C" */
diff --git a/crypto/openssh/regress/misc/fuzz-harness/privkey_fuzz.cc b/crypto/openssh/regress/misc/fuzz-harness/privkey_fuzz.cc
new file mode 100644
index 000000000000..ff0b0f7769dc
--- /dev/null
+++ b/crypto/openssh/regress/misc/fuzz-harness/privkey_fuzz.cc
@@ -0,0 +1,21 @@
+#include <stddef.h>
+#include <stdio.h>
+#include <stdint.h>
+
+extern "C" {
+
+#include "sshkey.h"
+#include "sshbuf.h"
+
+int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size)
+{
+ struct sshkey *k = NULL;
+ struct sshbuf *b = sshbuf_from(data, size);
+ int r = sshkey_private_deserialize(b, &k);
+ if (r == 0) sshkey_free(k);
+ sshbuf_free(b);
+ return 0;
+}
+
+} // extern
+
diff --git a/crypto/openssh/regress/misc/fuzz-harness/sig_fuzz.cc b/crypto/openssh/regress/misc/fuzz-harness/sig_fuzz.cc
index dd1fda091f49..b32502ba023f 100644
--- a/crypto/openssh/regress/misc/fuzz-harness/sig_fuzz.cc
+++ b/crypto/openssh/regress/misc/fuzz-harness/sig_fuzz.cc
@@ -31,19 +31,31 @@ int LLVMFuzzerTestOneInput(const uint8_t* sig, size_t slen)
static struct sshkey *ecdsa384 = generate_or_die(KEY_ECDSA, 384);
static struct sshkey *ecdsa521 = generate_or_die(KEY_ECDSA, 521);
#endif
+ struct sshkey_sig_details *details = NULL;
static struct sshkey *ed25519 = generate_or_die(KEY_ED25519, 0);
static const char *data = "If everyone started announcing his nose had "
"run away, I don’t know how it would all end";
static const size_t dlen = strlen(data);
#ifdef WITH_OPENSSL
- sshkey_verify(rsa, sig, slen, (const u_char *)data, dlen, NULL, 0);
- sshkey_verify(dsa, sig, slen, (const u_char *)data, dlen, NULL, 0);
- sshkey_verify(ecdsa256, sig, slen, (const u_char *)data, dlen, NULL, 0);
- sshkey_verify(ecdsa384, sig, slen, (const u_char *)data, dlen, NULL, 0);
- sshkey_verify(ecdsa521, sig, slen, (const u_char *)data, dlen, NULL, 0);
+ sshkey_verify(rsa, sig, slen, (const u_char *)data, dlen, NULL, 0, &details);
+ sshkey_sig_details_free(details);
+ details = NULL;
+ sshkey_verify(dsa, sig, slen, (const u_char *)data, dlen, NULL, 0, &details);
+ sshkey_sig_details_free(details);
+ details = NULL;
+ sshkey_verify(ecdsa256, sig, slen, (const u_char *)data, dlen, NULL, 0, &details);
+ sshkey_sig_details_free(details);
+ details = NULL;
+ sshkey_verify(ecdsa384, sig, slen, (const u_char *)data, dlen, NULL, 0, &details);
+ sshkey_sig_details_free(details);
+ details = NULL;
+ sshkey_verify(ecdsa521, sig, slen, (const u_char *)data, dlen, NULL, 0, &details);
+ sshkey_sig_details_free(details);
+ details = NULL;
#endif
- sshkey_verify(ed25519, sig, slen, (const u_char *)data, dlen, NULL, 0);
+ sshkey_verify(ed25519, sig, slen, (const u_char *)data, dlen, NULL, 0, &details);
+ sshkey_sig_details_free(details);
return 0;
}
diff --git a/crypto/openssh/regress/misc/fuzz-harness/ssh-sk-null.cc b/crypto/openssh/regress/misc/fuzz-harness/ssh-sk-null.cc
new file mode 100644
index 000000000000..199af11217e8
--- /dev/null
+++ b/crypto/openssh/regress/misc/fuzz-harness/ssh-sk-null.cc
@@ -0,0 +1,51 @@
+/* $OpenBSD$ */
+/*
+ * Copyright (c) 2019 Google LLC
+ *
+ * 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.
+ */
+
+extern "C" {
+
+#include "includes.h"
+
+#include <sys/types.h>
+
+#include "ssherr.h"
+#include "ssh-sk.h"
+
+int
+sshsk_enroll(int type, const char *provider_path, const char *device,
+ const char *application, const char *userid, uint8_t flags,
+ const char *pin, struct sshbuf *challenge_buf,
+ struct sshkey **keyp, struct sshbuf *attest)
+{
+ return SSH_ERR_FEATURE_UNSUPPORTED;
+}
+
+int
+sshsk_sign(const char *provider_path, struct sshkey *key,
+ u_char **sigp, size_t *lenp, const u_char *data, size_t datalen,
+ u_int compat, const char *pin)
+{
+ return SSH_ERR_FEATURE_UNSUPPORTED;
+}
+
+int
+sshsk_load_resident(const char *provider_path, const char *device,
+ const char *pin, struct sshkey ***keysp, size_t *nkeysp)
+{
+ return SSH_ERR_FEATURE_UNSUPPORTED;
+}
+
+};
diff --git a/crypto/openssh/regress/misc/fuzz-harness/sshsig_fuzz.cc b/crypto/openssh/regress/misc/fuzz-harness/sshsig_fuzz.cc
new file mode 100644
index 000000000000..02211a096b24
--- /dev/null
+++ b/crypto/openssh/regress/misc/fuzz-harness/sshsig_fuzz.cc
@@ -0,0 +1,37 @@
+// cc_fuzz_target test for sshsig verification.
+
+#include <stddef.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+
+extern "C" {
+
+#include "includes.h"
+#include "sshkey.h"
+#include "ssherr.h"
+#include "sshbuf.h"
+#include "sshsig.h"
+#include "log.h"
+
+int LLVMFuzzerTestOneInput(const uint8_t* sig, size_t slen)
+{
+ static const char *data = "If everyone started announcing his nose had "
+ "run away, I don’t know how it would all end";
+ struct sshbuf *signature = sshbuf_from(sig, slen);
+ struct sshbuf *message = sshbuf_from(data, strlen(data));
+ struct sshkey *k = NULL;
+ struct sshkey_sig_details *details = NULL;
+ extern char *__progname;
+
+ log_init(__progname, SYSLOG_LEVEL_QUIET, SYSLOG_FACILITY_USER, 1);
+ sshsig_verifyb(signature, message, "castle", &k, &details);
+ sshkey_sig_details_free(details);
+ sshkey_free(k);
+ sshbuf_free(signature);
+ sshbuf_free(message);
+ return 0;
+}
+
+} // extern
diff --git a/crypto/openssh/regress/misc/fuzz-harness/sshsigopt_fuzz.cc b/crypto/openssh/regress/misc/fuzz-harness/sshsigopt_fuzz.cc
new file mode 100644
index 000000000000..7424fcbe358e
--- /dev/null
+++ b/crypto/openssh/regress/misc/fuzz-harness/sshsigopt_fuzz.cc
@@ -0,0 +1,29 @@
+#include <stddef.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <string.h>
+#include <stdlib.h>
+
+extern "C" {
+
+#include "sshsig.h"
+
+int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size)
+{
+ char *cp = (char *)malloc(size + 1);
+ struct sshsigopt *opts = NULL;
+
+ if (cp == NULL)
+ goto out;
+ memcpy(cp, data, size);
+ cp[size] = '\0';
+ if ((opts = sshsigopt_parse(cp, "libfuzzer", 0, NULL)) == NULL)
+ goto out;
+
+ out:
+ free(cp);
+ sshsigopt_free(opts);
+ return 0;
+}
+
+} // extern "C"
diff --git a/crypto/openssh/regress/misc/fuzz-harness/testdata/README b/crypto/openssh/regress/misc/fuzz-harness/testdata/README
new file mode 100644
index 000000000000..752053001ac4
--- /dev/null
+++ b/crypto/openssh/regress/misc/fuzz-harness/testdata/README
@@ -0,0 +1,4 @@
+This is preparatory data for fuzzing testing including scripts and test keys,
+corresponding to ../fixed-keys that are used in the fuzz tests and consequent
+fuzzing seed corpora. They should not be changed unless the affected seed
+corpora are also regenerated.
diff --git a/crypto/openssh/regress/misc/fuzz-harness/testdata/create-agent-corpus.sh b/crypto/openssh/regress/misc/fuzz-harness/testdata/create-agent-corpus.sh
new file mode 100755
index 000000000000..1043b9ff47d7
--- /dev/null
+++ b/crypto/openssh/regress/misc/fuzz-harness/testdata/create-agent-corpus.sh
@@ -0,0 +1,44 @@
+#!/bin/sh
+
+# Exercise ssh-agent to generate fuzzing corpus
+
+# XXX assumes agent hacked up with sk-dummy.o and ssh-sk.o linked directly
+# and dumping of e->request for each message.
+
+set -xe
+SSH_AUTH_SOCK=$PWD/sock
+rm -f agent-[0-9]* $SSH_AUTH_SOCK
+export SSH_AUTH_SOCK
+../../../../ssh-agent -D -a $SSH_AUTH_SOCK &
+sleep 1
+AGENT_PID=$!
+trap "kill $AGENT_PID" EXIT
+
+PRIV="id_dsa id_ecdsa id_ecdsa_sk id_ed25519 id_ed25519_sk id_rsa"
+
+# add keys
+ssh-add $PRIV
+
+# sign
+ssh-add -T *.pub
+
+# list
+ssh-add -l
+
+# remove individually
+ssh-add -d $PRIV
+
+# re-add with constraints
+ssh-add -c -t 3h $PRIV
+
+# delete all
+ssh-add -D
+
+# attempt to add a PKCS#11 token
+ssh-add -s /fake || :
+
+# attempt to delete PKCS#11
+ssh-add -e /fake || :
+
+ssh-add -L
+
diff --git a/crypto/openssh/regress/misc/fuzz-harness/testdata/id_dsa b/crypto/openssh/regress/misc/fuzz-harness/testdata/id_dsa
new file mode 100644
index 000000000000..88bf5566c93b
--- /dev/null
+++ b/crypto/openssh/regress/misc/fuzz-harness/testdata/id_dsa
@@ -0,0 +1,21 @@
+-----BEGIN OPENSSH PRIVATE KEY-----
+b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAABsgAAAAdzc2gtZH
+NzAAAAgQCsGTfjpQ465EOkfQXJM9BOvfRQE0fqlykAls+ncz+T7hrbeScRu8xpwzsznJNm
+xlW8o6cUDiHmBJ5OHgamUC9N7YJeU/6fnOAZifgN8mqK6k8pKHuje8ANOiYgHLl0yiASQA
+3//qMyzZ+W/hemoLSmLAbEqlfWVeyYx+wta1Vm+QAAABUAvWyehvUvdHvQxavYgS5p0t5Q
+d7UAAACBAIRA9Yy+f4Kzqpv/qICPO3zk42UuP7WAhSW2nCbQdLlCiSTxcjKgcvXNRckwJP
+44JjSHOtJy/AMtJrPIbLYG6KuWTdBlEHFiG6DafvLG+qPMSL2bPjXTOhuOMbCHIZ+5WBkW
+THeG/Nv11iI01Of9V6tXkig23K370flkRkXFi9MdAAAAgCt6YUcQkNwG7B/e5M1FZsLP9O
+kVB3BwLAOjmWdHpyhu3HpwSJa3XLEvhXN0i6IVI2KgPo/2GtYA6rHt14L+6u1pmhh8sAvQ
+ksp3qZB+xh/NP+hBqf0sbHX0yYbzKOvI5SCc/kKK6yagcBZOsubM/KC8TxyVgmD5c6WzYs
+h5TEpvAAAB2PHjRbbx40W2AAAAB3NzaC1kc3MAAACBAKwZN+OlDjrkQ6R9Bckz0E699FAT
+R+qXKQCWz6dzP5PuGtt5JxG7zGnDOzOck2bGVbyjpxQOIeYEnk4eBqZQL03tgl5T/p+c4B
+mJ+A3yaorqTykoe6N7wA06JiAcuXTKIBJADf/+ozLNn5b+F6agtKYsBsSqV9ZV7JjH7C1r
+VWb5AAAAFQC9bJ6G9S90e9DFq9iBLmnS3lB3tQAAAIEAhED1jL5/grOqm/+ogI87fOTjZS
+4/tYCFJbacJtB0uUKJJPFyMqBy9c1FyTAk/jgmNIc60nL8Ay0ms8hstgboq5ZN0GUQcWIb
+oNp+8sb6o8xIvZs+NdM6G44xsIchn7lYGRZMd4b82/XWIjTU5/1Xq1eSKDbcrfvR+WRGRc
+WL0x0AAACAK3phRxCQ3AbsH97kzUVmws/06RUHcHAsA6OZZ0enKG7cenBIlrdcsS+Fc3SL
+ohUjYqA+j/Ya1gDqse3Xgv7q7WmaGHywC9CSynepkH7GH80/6EGp/SxsdfTJhvMo68jlIJ
+z+QorrJqBwFk6y5sz8oLxPHJWCYPlzpbNiyHlMSm8AAAAUUA+OGldMi76ClO/sstpdbBUE
+lq8AAAAAAQI=
+-----END OPENSSH PRIVATE KEY-----
diff --git a/crypto/openssh/regress/misc/fuzz-harness/testdata/id_dsa-cert.pub b/crypto/openssh/regress/misc/fuzz-harness/testdata/id_dsa-cert.pub
new file mode 100644
index 000000000000..3afb87fe62f7
--- /dev/null
+++ b/crypto/openssh/regress/misc/fuzz-harness/testdata/id_dsa-cert.pub
@@ -0,0 +1 @@
+ssh-dss-cert-v01@openssh.com AAAAHHNzaC1kc3MtY2VydC12MDFAb3BlbnNzaC5jb20AAAAguF716Yub+vVKNlONKLsfxGYWkRe/PyjfYdGRTsFaDvAAAACBAKwZN+OlDjrkQ6R9Bckz0E699FATR+qXKQCWz6dzP5PuGtt5JxG7zGnDOzOck2bGVbyjpxQOIeYEnk4eBqZQL03tgl5T/p+c4BmJ+A3yaorqTykoe6N7wA06JiAcuXTKIBJADf/+ozLNn5b+F6agtKYsBsSqV9ZV7JjH7C1rVWb5AAAAFQC9bJ6G9S90e9DFq9iBLmnS3lB3tQAAAIEAhED1jL5/grOqm/+ogI87fOTjZS4/tYCFJbacJtB0uUKJJPFyMqBy9c1FyTAk/jgmNIc60nL8Ay0ms8hstgboq5ZN0GUQcWIboNp+8sb6o8xIvZs+NdM6G44xsIchn7lYGRZMd4b82/XWIjTU5/1Xq1eSKDbcrfvR+WRGRcWL0x0AAACAK3phRxCQ3AbsH97kzUVmws/06RUHcHAsA6OZZ0enKG7cenBIlrdcsS+Fc3SLohUjYqA+j/Ya1gDqse3Xgv7q7WmaGHywC9CSynepkH7GH80/6EGp/SxsdfTJhvMo68jlIJz+QorrJqBwFk6y5sz8oLxPHJWCYPlzpbNiyHlMSm8AAAAAAAAD6AAAAAEAAAAHdWx5c3NlcwAAABcAAAAHdWx5c3NlcwAAAAhvZHlzc2V1cwAAAAAAAAAA//////////8AAAAAAAAAggAAABVwZXJtaXQtWDExLWZvcndhcmRpbmcAAAAAAAAAF3Blcm1pdC1hZ2VudC1mb3J3YXJkaW5nAAAAAAAAABZwZXJtaXQtcG9ydC1mb3J3YXJkaW5nAAAAAAAAAApwZXJtaXQtcHR5AAAAAAAAAA5wZXJtaXQtdXNlci1yYwAAAAAAAAAAAAAAMwAAAAtzc2gtZWQyNTUxOQAAACAz0F5hFTFS5nhUcmnyjFVoDw5L/P7kQU8JnBA2rWczAwAAAFMAAAALc3NoLWVkMjU1MTkAAABAjMQEZcbdUYJBjIC4GxByFDOb8tv71vDZdx7irHwaqIjx5rzpJUuOV1r8ZO4kY+Yaiun1yrWj2QYkfJrHBvD1DA== id_dsa.pub
diff --git a/crypto/openssh/regress/misc/fuzz-harness/testdata/id_dsa.pub b/crypto/openssh/regress/misc/fuzz-harness/testdata/id_dsa.pub
new file mode 100644
index 000000000000..6f91c4e07336
--- /dev/null
+++ b/crypto/openssh/regress/misc/fuzz-harness/testdata/id_dsa.pub
@@ -0,0 +1 @@
+ssh-dss AAAAB3NzaC1kc3MAAACBAKwZN+OlDjrkQ6R9Bckz0E699FATR+qXKQCWz6dzP5PuGtt5JxG7zGnDOzOck2bGVbyjpxQOIeYEnk4eBqZQL03tgl5T/p+c4BmJ+A3yaorqTykoe6N7wA06JiAcuXTKIBJADf/+ozLNn5b+F6agtKYsBsSqV9ZV7JjH7C1rVWb5AAAAFQC9bJ6G9S90e9DFq9iBLmnS3lB3tQAAAIEAhED1jL5/grOqm/+ogI87fOTjZS4/tYCFJbacJtB0uUKJJPFyMqBy9c1FyTAk/jgmNIc60nL8Ay0ms8hstgboq5ZN0GUQcWIboNp+8sb6o8xIvZs+NdM6G44xsIchn7lYGRZMd4b82/XWIjTU5/1Xq1eSKDbcrfvR+WRGRcWL0x0AAACAK3phRxCQ3AbsH97kzUVmws/06RUHcHAsA6OZZ0enKG7cenBIlrdcsS+Fc3SLohUjYqA+j/Ya1gDqse3Xgv7q7WmaGHywC9CSynepkH7GH80/6EGp/SxsdfTJhvMo68jlIJz+QorrJqBwFk6y5sz8oLxPHJWCYPlzpbNiyHlMSm8=
diff --git a/crypto/openssh/regress/misc/fuzz-harness/testdata/id_ecdsa b/crypto/openssh/regress/misc/fuzz-harness/testdata/id_ecdsa
new file mode 100644
index 000000000000..c1a96c6f9eaf
--- /dev/null
+++ b/crypto/openssh/regress/misc/fuzz-harness/testdata/id_ecdsa
@@ -0,0 +1,8 @@
+-----BEGIN OPENSSH PRIVATE KEY-----
+b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAaAAAABNlY2RzYS
+1zaGEyLW5pc3RwMjU2AAAACG5pc3RwMjU2AAAAQQTDJ0VlMv+0rguNzaJ1DF2KueHaxRSQ
+6LpIxGbulrg1a8RPbnMXwag5GcDiDllD2lDUJUuBEWyjXA0rZoZX35ELAAAAoE/Bbr5PwW
+6+AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBMMnRWUy/7SuC43N
+onUMXYq54drFFJDoukjEZu6WuDVrxE9ucxfBqDkZwOIOWUPaUNQlS4ERbKNcDStmhlffkQ
+sAAAAhAIhE6hCID5oOm1TDktc++KFKyScjLifcZ6Cgv5xSSyLOAAAAAAECAwQFBgc=
+-----END OPENSSH PRIVATE KEY-----
diff --git a/crypto/openssh/regress/misc/fuzz-harness/testdata/id_ecdsa-cert.pub b/crypto/openssh/regress/misc/fuzz-harness/testdata/id_ecdsa-cert.pub
new file mode 100644
index 000000000000..9de599917de6
--- /dev/null
+++ b/crypto/openssh/regress/misc/fuzz-harness/testdata/id_ecdsa-cert.pub
@@ -0,0 +1 @@
+ecdsa-sha2-nistp256-cert-v01@openssh.com AAAAKGVjZHNhLXNoYTItbmlzdHAyNTYtY2VydC12MDFAb3BlbnNzaC5jb20AAAAgVJZuM/1AOe6n++qRWMyUuAThYqLvvQxj5CGflLODp60AAAAIbmlzdHAyNTYAAABBBMMnRWUy/7SuC43NonUMXYq54drFFJDoukjEZu6WuDVrxE9ucxfBqDkZwOIOWUPaUNQlS4ERbKNcDStmhlffkQsAAAAAAAAD6QAAAAEAAAAHdWx5c3NlcwAAABcAAAAHdWx5c3NlcwAAAAhvZHlzc2V1cwAAAAAAAAAA//////////8AAAAAAAAAggAAABVwZXJtaXQtWDExLWZvcndhcmRpbmcAAAAAAAAAF3Blcm1pdC1hZ2VudC1mb3J3YXJkaW5nAAAAAAAAABZwZXJtaXQtcG9ydC1mb3J3YXJkaW5nAAAAAAAAAApwZXJtaXQtcHR5AAAAAAAAAA5wZXJtaXQtdXNlci1yYwAAAAAAAAAAAAAAMwAAAAtzc2gtZWQyNTUxOQAAACAz0F5hFTFS5nhUcmnyjFVoDw5L/P7kQU8JnBA2rWczAwAAAFMAAAALc3NoLWVkMjU1MTkAAABAtdJpcF6ZmQL+ueices4QZeL7AK8Xuo08jyLgiolhjKy2jj4LSUki4aX/ZeZeJuby1ovGrfaeFAgx3itPLR7IAQ== id_ecdsa.pub
diff --git a/crypto/openssh/regress/misc/fuzz-harness/testdata/id_ecdsa.pub b/crypto/openssh/regress/misc/fuzz-harness/testdata/id_ecdsa.pub
new file mode 100644
index 000000000000..30a7cc23b228
--- /dev/null
+++ b/crypto/openssh/regress/misc/fuzz-harness/testdata/id_ecdsa.pub
@@ -0,0 +1 @@
+ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBMMnRWUy/7SuC43NonUMXYq54drFFJDoukjEZu6WuDVrxE9ucxfBqDkZwOIOWUPaUNQlS4ERbKNcDStmhlffkQs=
diff --git a/crypto/openssh/regress/misc/fuzz-harness/testdata/id_ecdsa_sk b/crypto/openssh/regress/misc/fuzz-harness/testdata/id_ecdsa_sk
new file mode 100644
index 000000000000..5a364ed39f1e
--- /dev/null
+++ b/crypto/openssh/regress/misc/fuzz-harness/testdata/id_ecdsa_sk
@@ -0,0 +1,14 @@
+-----BEGIN OPENSSH PRIVATE KEY-----
+b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAfwAAACJzay1lY2
+RzYS1zaGEyLW5pc3RwMjU2QG9wZW5zc2guY29tAAAACG5pc3RwMjU2AAAAQQTYyU76zop1
+VOb4DfKWYnR5b0TOC3zw8DzObAfHWB5o6xls+tOYiEleXvIEi00Da2iCK47habZTOhLyeB
+X2Avu5AAAABHNzaDoAAAGYqUAQSKlAEEgAAAAic2stZWNkc2Etc2hhMi1uaXN0cDI1NkBv
+cGVuc3NoLmNvbQAAAAhuaXN0cDI1NgAAAEEE2MlO+s6KdVTm+A3ylmJ0eW9Ezgt88PA8zm
+wHx1geaOsZbPrTmIhJXl7yBItNA2togiuO4Wm2UzoS8ngV9gL7uQAAAARzc2g6AQAAAOMt
+LS0tLUJFR0lOIEVDIFBSSVZBVEUgS0VZLS0tLS0KTUhjQ0FRRUVJSHFsZjNsWTkxZFhwUn
+dYZDBrS0lYWmNpeDRRcDBNSU15Ny9JMUxXSTFuWG9Bb0dDQ3FHU000OQpBd0VIb1VRRFFn
+QUUyTWxPK3M2S2RWVG0rQTN5bG1KMGVXOUV6Z3Q4OFBBOHptd0h4MWdlYU9zWmJQclRtSW
+hKClhsN3lCSXROQTJ0b2dpdU80V20yVXpvUzhuZ1Y5Z0w3dVE9PQotLS0tLUVORCBFQyBQ
+UklWQVRFIEtFWS0tLS0tCgAAAAAAAAAbZGptQGRqbS5zeWQuY29ycC5nb29nbGUuY29tAQ
+IDBAUG
+-----END OPENSSH PRIVATE KEY-----
diff --git a/crypto/openssh/regress/misc/fuzz-harness/testdata/id_ecdsa_sk-cert.pub b/crypto/openssh/regress/misc/fuzz-harness/testdata/id_ecdsa_sk-cert.pub
new file mode 100644
index 000000000000..14040fad7aa6
--- /dev/null
+++ b/crypto/openssh/regress/misc/fuzz-harness/testdata/id_ecdsa_sk-cert.pub
@@ -0,0 +1 @@
+sk-ecdsa-sha2-nistp256-cert-v01@openssh.com AAAAK3NrLWVjZHNhLXNoYTItbmlzdHAyNTYtY2VydC12MDFAb3BlbnNzaC5jb20AAAAgKLHtIca++5VoDrUAXU/KqGJZ7jZEnuJSTvt7VrYY9foAAAAIbmlzdHAyNTYAAABBBNjJTvrOinVU5vgN8pZidHlvRM4LfPDwPM5sB8dYHmjrGWz605iISV5e8gSLTQNraIIrjuFptlM6EvJ4FfYC+7kAAAAEc3NoOgAAAAAAAAPqAAAAAQAAAAd1bHlzc2VzAAAAFwAAAAd1bHlzc2VzAAAACG9keXNzZXVzAAAAAAAAAAD//////////wAAAAAAAACCAAAAFXBlcm1pdC1YMTEtZm9yd2FyZGluZwAAAAAAAAAXcGVybWl0LWFnZW50LWZvcndhcmRpbmcAAAAAAAAAFnBlcm1pdC1wb3J0LWZvcndhcmRpbmcAAAAAAAAACnBlcm1pdC1wdHkAAAAAAAAADnBlcm1pdC11c2VyLXJjAAAAAAAAAAAAAAAzAAAAC3NzaC1lZDI1NTE5AAAAIDPQXmEVMVLmeFRyafKMVWgPDkv8/uRBTwmcEDatZzMDAAAAUwAAAAtzc2gtZWQyNTUxOQAAAEB1naZOQDLaDr+fwn6E9x8/8HeiaUubDzPexfNQMz+m/7RD0gd5uJhHYUfDb5+/sIx1I7bUEeRIDkBbmZ2foo0E djm@djm.syd.corp.google.com
diff --git a/crypto/openssh/regress/misc/fuzz-harness/testdata/id_ecdsa_sk.pub b/crypto/openssh/regress/misc/fuzz-harness/testdata/id_ecdsa_sk.pub
new file mode 100644
index 000000000000..1b5e829b7418
--- /dev/null
+++ b/crypto/openssh/regress/misc/fuzz-harness/testdata/id_ecdsa_sk.pub
@@ -0,0 +1 @@
+sk-ecdsa-sha2-nistp256@openssh.com AAAAInNrLWVjZHNhLXNoYTItbmlzdHAyNTZAb3BlbnNzaC5jb20AAAAIbmlzdHAyNTYAAABBBNjJTvrOinVU5vgN8pZidHlvRM4LfPDwPM5sB8dYHmjrGWz605iISV5e8gSLTQNraIIrjuFptlM6EvJ4FfYC+7kAAAAEc3NoOg== djm@djm.syd.corp.google.com
diff --git a/crypto/openssh/regress/misc/fuzz-harness/testdata/id_ed25519 b/crypto/openssh/regress/misc/fuzz-harness/testdata/id_ed25519
new file mode 100644
index 000000000000..6a7fbac929d1
--- /dev/null
+++ b/crypto/openssh/regress/misc/fuzz-harness/testdata/id_ed25519
@@ -0,0 +1,7 @@
+-----BEGIN OPENSSH PRIVATE KEY-----
+b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW
+QyNTUxOQAAACAz0F5hFTFS5nhUcmnyjFVoDw5L/P7kQU8JnBA2rWczAwAAAIhWlP99VpT/
+fQAAAAtzc2gtZWQyNTUxOQAAACAz0F5hFTFS5nhUcmnyjFVoDw5L/P7kQU8JnBA2rWczAw
+AAAEDE1rlcMC0s0X3TKVZAOVavZOywwkXw8tO5dLObxaCMEDPQXmEVMVLmeFRyafKMVWgP
+Dkv8/uRBTwmcEDatZzMDAAAAAAECAwQF
+-----END OPENSSH PRIVATE KEY-----
diff --git a/crypto/openssh/regress/misc/fuzz-harness/testdata/id_ed25519-cert.pub b/crypto/openssh/regress/misc/fuzz-harness/testdata/id_ed25519-cert.pub
new file mode 100644
index 000000000000..6a95fed2ac80
--- /dev/null
+++ b/crypto/openssh/regress/misc/fuzz-harness/testdata/id_ed25519-cert.pub
@@ -0,0 +1 @@
+ssh-ed25519-cert-v01@openssh.com AAAAIHNzaC1lZDI1NTE5LWNlcnQtdjAxQG9wZW5zc2guY29tAAAAIMDQjYH6XRzH3j3MW1DdjCoAfvrHfgjnVGF+sLK0pBfqAAAAIDPQXmEVMVLmeFRyafKMVWgPDkv8/uRBTwmcEDatZzMDAAAAAAAAA+sAAAABAAAAB3VseXNzZXMAAAAXAAAAB3VseXNzZXMAAAAIb2R5c3NldXMAAAAAAAAAAP//////////AAAAAAAAAIIAAAAVcGVybWl0LVgxMS1mb3J3YXJkaW5nAAAAAAAAABdwZXJtaXQtYWdlbnQtZm9yd2FyZGluZwAAAAAAAAAWcGVybWl0LXBvcnQtZm9yd2FyZGluZwAAAAAAAAAKcGVybWl0LXB0eQAAAAAAAAAOcGVybWl0LXVzZXItcmMAAAAAAAAAAAAAADMAAAALc3NoLWVkMjU1MTkAAAAgM9BeYRUxUuZ4VHJp8oxVaA8OS/z+5EFPCZwQNq1nMwMAAABTAAAAC3NzaC1lZDI1NTE5AAAAQBj0og+s09/HpwdHZbzN0twooKPDWWrxGfnP1Joy6cDnY2BCSQ7zg9vbq11kLF8H/sKOTZWAQrUZ7LlChOu9Ogw= id_ed25519.pub
diff --git a/crypto/openssh/regress/misc/fuzz-harness/testdata/id_ed25519.pub b/crypto/openssh/regress/misc/fuzz-harness/testdata/id_ed25519.pub
new file mode 100644
index 000000000000..87b61744701f
--- /dev/null
+++ b/crypto/openssh/regress/misc/fuzz-harness/testdata/id_ed25519.pub
@@ -0,0 +1,2 @@
+ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIDPQXmEVMVLmeFRyafKMVWgPDkv8/uRBTwmcEDatZzMD
+
diff --git a/crypto/openssh/regress/misc/fuzz-harness/testdata/id_ed25519_sk b/crypto/openssh/regress/misc/fuzz-harness/testdata/id_ed25519_sk
new file mode 100644
index 000000000000..9dcda6c4626f
--- /dev/null
+++ b/crypto/openssh/regress/misc/fuzz-harness/testdata/id_ed25519_sk
@@ -0,0 +1,8 @@
+-----BEGIN OPENSSH PRIVATE KEY-----
+b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAASgAAABpzay1zc2
+gtZWQyNTUxOUBvcGVuc3NoLmNvbQAAACCTJtH10vWhIDxd62edvMLg9u2cwYKyqa7332je
+RArHjAAAAARzc2g6AAAAwN7vvE3e77xNAAAAGnNrLXNzaC1lZDI1NTE5QG9wZW5zc2guY2
+9tAAAAIJMm0fXS9aEgPF3rZ528wuD27ZzBgrKprvffaN5ECseMAAAABHNzaDoBAAAAQEsS
+xLFiVzfpH2mt9xh8i/zmHV646Hud4QruNBAGNl8gkybR9dL1oSA8XetnnbzC4PbtnMGCsq
+mu999o3kQKx4wAAAAAAAAAG2RqbUBkam0uc3lkLmNvcnAuZ29vZ2xlLmNvbQECAwQFBg==
+-----END OPENSSH PRIVATE KEY-----
diff --git a/crypto/openssh/regress/misc/fuzz-harness/testdata/id_ed25519_sk-cert.pub b/crypto/openssh/regress/misc/fuzz-harness/testdata/id_ed25519_sk-cert.pub
new file mode 100644
index 000000000000..9e41eec00df4
--- /dev/null
+++ b/crypto/openssh/regress/misc/fuzz-harness/testdata/id_ed25519_sk-cert.pub
@@ -0,0 +1 @@
+sk-ssh-ed25519-cert-v01@openssh.com AAAAI3NrLXNzaC1lZDI1NTE5LWNlcnQtdjAxQG9wZW5zc2guY29tAAAAIJiT+C/VLMWholFZ4xhOyJr0nSLZSFRIM3I07wUNTRPaAAAAIJMm0fXS9aEgPF3rZ528wuD27ZzBgrKprvffaN5ECseMAAAABHNzaDoAAAAAAAAD7AAAAAEAAAAHdWx5c3NlcwAAABcAAAAHdWx5c3NlcwAAAAhvZHlzc2V1cwAAAAAAAAAA//////////8AAAAAAAAAggAAABVwZXJtaXQtWDExLWZvcndhcmRpbmcAAAAAAAAAF3Blcm1pdC1hZ2VudC1mb3J3YXJkaW5nAAAAAAAAABZwZXJtaXQtcG9ydC1mb3J3YXJkaW5nAAAAAAAAAApwZXJtaXQtcHR5AAAAAAAAAA5wZXJtaXQtdXNlci1yYwAAAAAAAAAAAAAAMwAAAAtzc2gtZWQyNTUxOQAAACAz0F5hFTFS5nhUcmnyjFVoDw5L/P7kQU8JnBA2rWczAwAAAFMAAAALc3NoLWVkMjU1MTkAAABAX0Pu13B94pVR3qq8MJQGkOS1Cd7AAM1k6O2VSwyDPM/LfsWIQ4ywgxDmk3hjXWOY7BqljuMxo5VO4JymEIhQBA== djm@djm.syd.corp.google.com
diff --git a/crypto/openssh/regress/misc/fuzz-harness/testdata/id_ed25519_sk.pub b/crypto/openssh/regress/misc/fuzz-harness/testdata/id_ed25519_sk.pub
new file mode 100644
index 000000000000..38d198444b79
--- /dev/null
+++ b/crypto/openssh/regress/misc/fuzz-harness/testdata/id_ed25519_sk.pub
@@ -0,0 +1 @@
+sk-ssh-ed25519@openssh.com AAAAGnNrLXNzaC1lZDI1NTE5QG9wZW5zc2guY29tAAAAIJMm0fXS9aEgPF3rZ528wuD27ZzBgrKprvffaN5ECseMAAAABHNzaDo= djm@djm.syd.corp.google.com
diff --git a/crypto/openssh/regress/misc/fuzz-harness/testdata/id_rsa b/crypto/openssh/regress/misc/fuzz-harness/testdata/id_rsa
new file mode 100644
index 000000000000..574fecf47008
--- /dev/null
+++ b/crypto/openssh/regress/misc/fuzz-harness/testdata/id_rsa
@@ -0,0 +1,27 @@
+-----BEGIN OPENSSH PRIVATE KEY-----
+b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAABFwAAAAdzc2gtcn
+NhAAAAAwEAAQAAAQEA3+epf+VGKoGPaAZXrf6S0cyumQnddkGBnVFX0A5eh37RtLug0qY5
+thxsBUbGGVr9mTd2QXwLujBwYg5l1MP/Fmg+5312Zgx9pHmS+qKULbar0hlNgptNEb+aNU
+d3o9qg3aXqXm7+ZnjAV05ef/mxNRN2ZvuEkw7cRppTJcbBI+vF3lXuCXnX2klDI95Gl2AW
+3WHRtanqLHZXuBkjjRBDKc7MUq/GP1hmLiAd95dvU7fZjRlIEsP84zGEI1Fb0L/kmPHcOt
+iVfHft8CtmC9v6+94JrOiPBBNScV+dyrgAGPsdKdr/1vIpQmCNiI8s3PCiD8J7ZiBaYm0I
+8fq5G/qnUwAAA7ggw2dXIMNnVwAAAAdzc2gtcnNhAAABAQDf56l/5UYqgY9oBlet/pLRzK
+6ZCd12QYGdUVfQDl6HftG0u6DSpjm2HGwFRsYZWv2ZN3ZBfAu6MHBiDmXUw/8WaD7nfXZm
+DH2keZL6opQttqvSGU2Cm00Rv5o1R3ej2qDdpepebv5meMBXTl5/+bE1E3Zm+4STDtxGml
+MlxsEj68XeVe4JedfaSUMj3kaXYBbdYdG1qeosdle4GSONEEMpzsxSr8Y/WGYuIB33l29T
+t9mNGUgSw/zjMYQjUVvQv+SY8dw62JV8d+3wK2YL2/r73gms6I8EE1JxX53KuAAY+x0p2v
+/W8ilCYI2Ijyzc8KIPwntmIFpibQjx+rkb+qdTAAAAAwEAAQAAAQEArWm5B4tFasppjUHM
+SsAuajtCxtizI1Hc10EW59cZM4vvUzE2f6+qZvdgWj3UU/L7Et23w0QVuSCnCerox379ZB
+ddEOFFAAiQjwBx65hbd4RRUymxtIQfjq18++LcMJW1nbVQ7c69ThQbtALIggmbS+ZE/8Gx
+jkwmIrCH0Ww8TlpsPe+mNHuyNk7UEZoXLm22lNLqq5qkIL5JgT6M2iNJpMOJy9/CKi6kO4
+JPuVwjdG4C5pBPaMN3KJ1IvAlSlLGNaXnfXcn85gWfsCjsZmH3liey2NJamqp/w83BrKUg
+YZvMR2qeWZaKkFTahpzN5KRK1BFeB37O0P84Dzh1biDX8QAAAIEAiWXW8ePYFwLpa2mFIh
+VvRTdcrN70rVK5eWVaL3pyS4vGA56Jixq86dHveOnbSY+iNb1jQidtXc8SWUt2wtHqZ32h
+Lji9/hMSKqe9SEP3xvDRDmUJqsVw0ySyrFrzm4160QY6RKU3CIQCVFslMZ9fxmrfZ/hxoU
+0X3FVsxmC4+kwAAACBAPOc1YERpV6PjANBrGR+1o1RCdACbm5myc42QzSNIaOZmgrYs+Gt
+7+EcoqSdbJzHJNCNQfF+A+vjbIkFiuZqq/5wwr59qXx5OAlijLB/ywwKmTWq6lp//Zxny+
+ka3sIGNO14eQvmxNDnlLL+RIZleCTEKBXSW6CZhr+uHMZFKKMtAAAAgQDrSkm+LbILB7H9
+jxEBZLhv53aAn4u81kFKQOJ7PzzpBGSoD12i7oIJu5siSD5EKDNVEr+SvCf0ISU3BuMpzl
+t3YrPrHRheOFhn5e3j0e//zB8rBC0DGB4CtTDdeh7rOXUL4K0pz+8wEpNkV62SWxhC6NRW
+I79JhtGkh+GtcnkEfwAAAAAB
+-----END OPENSSH PRIVATE KEY-----
diff --git a/crypto/openssh/regress/misc/fuzz-harness/testdata/id_rsa-cert.pub b/crypto/openssh/regress/misc/fuzz-harness/testdata/id_rsa-cert.pub
new file mode 100644
index 000000000000..01761a38fa0f
--- /dev/null
+++ b/crypto/openssh/regress/misc/fuzz-harness/testdata/id_rsa-cert.pub
@@ -0,0 +1 @@
+ssh-rsa-cert-v01@openssh.com AAAAHHNzaC1yc2EtY2VydC12MDFAb3BlbnNzaC5jb20AAAAg89JX6OBMYDSxER8fnU5y8xxeMCHR/hI0uVqdEhNyCpcAAAADAQABAAABAQDf56l/5UYqgY9oBlet/pLRzK6ZCd12QYGdUVfQDl6HftG0u6DSpjm2HGwFRsYZWv2ZN3ZBfAu6MHBiDmXUw/8WaD7nfXZmDH2keZL6opQttqvSGU2Cm00Rv5o1R3ej2qDdpepebv5meMBXTl5/+bE1E3Zm+4STDtxGmlMlxsEj68XeVe4JedfaSUMj3kaXYBbdYdG1qeosdle4GSONEEMpzsxSr8Y/WGYuIB33l29Tt9mNGUgSw/zjMYQjUVvQv+SY8dw62JV8d+3wK2YL2/r73gms6I8EE1JxX53KuAAY+x0p2v/W8ilCYI2Ijyzc8KIPwntmIFpibQjx+rkb+qdTAAAAAAAAA+0AAAABAAAAB3VseXNzZXMAAAAXAAAAB3VseXNzZXMAAAAIb2R5c3NldXMAAAAAAAAAAP//////////AAAAAAAAAIIAAAAVcGVybWl0LVgxMS1mb3J3YXJkaW5nAAAAAAAAABdwZXJtaXQtYWdlbnQtZm9yd2FyZGluZwAAAAAAAAAWcGVybWl0LXBvcnQtZm9yd2FyZGluZwAAAAAAAAAKcGVybWl0LXB0eQAAAAAAAAAOcGVybWl0LXVzZXItcmMAAAAAAAAAAAAAADMAAAALc3NoLWVkMjU1MTkAAAAgM9BeYRUxUuZ4VHJp8oxVaA8OS/z+5EFPCZwQNq1nMwMAAABTAAAAC3NzaC1lZDI1NTE5AAAAQGCDA6PWw4x9bHQl0w7NqifHepumqD3dmyMx+hZGuPRon+TsyCjfytu7hWmV7l9XUF0fPQNFQ7FGat5e+7YUNgE= id_rsa.pub
diff --git a/crypto/openssh/regress/misc/fuzz-harness/testdata/id_rsa.pub b/crypto/openssh/regress/misc/fuzz-harness/testdata/id_rsa.pub
new file mode 100644
index 000000000000..05015e12bfaa
--- /dev/null
+++ b/crypto/openssh/regress/misc/fuzz-harness/testdata/id_rsa.pub
@@ -0,0 +1 @@
+ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDf56l/5UYqgY9oBlet/pLRzK6ZCd12QYGdUVfQDl6HftG0u6DSpjm2HGwFRsYZWv2ZN3ZBfAu6MHBiDmXUw/8WaD7nfXZmDH2keZL6opQttqvSGU2Cm00Rv5o1R3ej2qDdpepebv5meMBXTl5/+bE1E3Zm+4STDtxGmlMlxsEj68XeVe4JedfaSUMj3kaXYBbdYdG1qeosdle4GSONEEMpzsxSr8Y/WGYuIB33l29Tt9mNGUgSw/zjMYQjUVvQv+SY8dw62JV8d+3wK2YL2/r73gms6I8EE1JxX53KuAAY+x0p2v/W8ilCYI2Ijyzc8KIPwntmIFpibQjx+rkb+qdT
diff --git a/crypto/openssh/regress/misc/kexfuzz/Makefile b/crypto/openssh/regress/misc/kexfuzz/Makefile
deleted file mode 100644
index a7bb6b70d211..000000000000
--- a/crypto/openssh/regress/misc/kexfuzz/Makefile
+++ /dev/null
@@ -1,88 +0,0 @@
-# $OpenBSD: Makefile,v 1.3 2017/12/21 05:46:35 djm Exp $
-
-.include <bsd.own.mk>
-.include <bsd.obj.mk>
-
-# XXX detect from ssh binary?
-SSH1?= no
-OPENSSL?= yes
-
-PROG= kexfuzz
-SRCS= kexfuzz.c
-
-SSHREL=../../../../../usr.bin/ssh
-.PATH: ${.CURDIR}/${SSHREL}
-# From usr.bin/ssh
-SRCS+=sshbuf-getput-basic.c sshbuf-getput-crypto.c sshbuf-misc.c sshbuf.c
-SRCS+=atomicio.c sshkey.c authfile.c cipher.c log.c ssh-rsa.c ssh-dss.c
-SRCS+=ssh-ecdsa.c ssh-ed25519.c mac.c umac.c umac128.c hmac.c misc.c
-SRCS+=ssherr.c uidswap.c cleanup.c xmalloc.c match.c krl.c fatal.c
-SRCS+=addrmatch.c bitmap.c packet.c dispatch.c canohost.c ssh_api.c
-SRCS+=kex.c kexc25519.c kexc25519c.c kexc25519s.c kexdh.c kexdhc.c kexdhs.c
-SRCS+=kexecdh.c kexecdhc.c kexecdhs.c kexgex.c kexgexc.c kexgexs.c
-SRCS+=dh.c compat.c
-SRCS+=ed25519.c hash.c ge25519.c fe25519.c sc25519.c verify.c
-SRCS+=cipher-chachapoly.c chacha.c poly1305.c
-SRCS+=smult_curve25519_ref.c
-
-SRCS+=digest-openssl.c
-#SRCS+=digest-libc.c
-
-NOMAN= 1
-
-.if (${OPENSSL:L} == "yes")
-CFLAGS+= -DWITH_OPENSSL
-.else
-# SSH v.1 requires OpenSSL.
-SSH1= no
-.endif
-
-.if (${SSH1:L} == "yes")
-CFLAGS+= -DWITH_SSH1
-.endif
-
-# 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
-CDIAGFLAGS+= -Wno-unused-parameter
-.if ${COMPILER_VERSION:L} != "gcc3"
-CDIAGFLAGS+= -Wold-style-definition
-.endif
-
-
-CFLAGS+=-I${.CURDIR}/${SSHREL}
-
-LDADD+= -lutil -lz
-DPADD+= ${LIBUTIL} ${LIBZ}
-
-.if (${OPENSSL:L} == "yes")
-LDADD+= -lcrypto
-DPADD+= ${LIBCRYPTO}
-.endif
-
-.include <bsd.prog.mk>
-
diff --git a/crypto/openssh/regress/misc/kexfuzz/README b/crypto/openssh/regress/misc/kexfuzz/README
deleted file mode 100644
index 504c26f3bed3..000000000000
--- a/crypto/openssh/regress/misc/kexfuzz/README
+++ /dev/null
@@ -1,34 +0,0 @@
-This is a harness to help with fuzzing KEX.
-
-To use it, you first set it to count packets in each direction:
-
-./kexfuzz -K diffie-hellman-group1-sha1 -k host_ed25519_key -c
-S2C: 29
-C2S: 31
-
-Then get it to record a particular packet (in this case the 4th
-packet from client->server):
-
-./kexfuzz -K diffie-hellman-group1-sha1 -k host_ed25519_key \
- -d -D C2S -i 3 -f packet_3
-
-Fuzz the packet somehow:
-
-dd if=/dev/urandom of=packet_3 bs=32 count=1 # Just for example
-
-Then re-run the key exchange substituting the modified packet in
-its original sequence:
-
-./kexfuzz -K diffie-hellman-group1-sha1 -k host_ed25519_key \
- -r -D C2S -i 3 -f packet_3
-
-A comprehensive KEX fuzz run would fuzz every packet in both
-directions for each key exchange type and every hostkey type.
-This will take some time.
-
-Limitations: kexfuzz can't change the ordering of packets at
-present. It is limited to replacing individual packets with
-fuzzed variants with the same type. It really should allow
-insertion, deletion on replacement of packets too.
-
-$OpenBSD: README,v 1.3 2017/10/20 02:13:41 djm Exp $
diff --git a/crypto/openssh/regress/misc/kexfuzz/kexfuzz.c b/crypto/openssh/regress/misc/kexfuzz/kexfuzz.c
deleted file mode 100644
index 3e2c481606c0..000000000000
--- a/crypto/openssh/regress/misc/kexfuzz/kexfuzz.c
+++ /dev/null
@@ -1,459 +0,0 @@
-/* $OpenBSD: kexfuzz.c,v 1.4 2017/04/30 23:34:55 djm Exp $ */
-/*
- * Fuzz harness for KEX code
- *
- * Placed in the public domain
- */
-
-#include "includes.h"
-
-#include <sys/types.h>
-#include <sys/param.h>
-#include <stdio.h>
-#ifdef HAVE_STDINT_H
-# include <stdint.h>
-#endif
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <fcntl.h>
-#ifdef HAVE_ERR_H
-# include <err.h>
-#endif
-
-#include "ssherr.h"
-#include "ssh_api.h"
-#include "sshbuf.h"
-#include "packet.h"
-#include "myproposal.h"
-#include "authfile.h"
-#include "log.h"
-
-struct ssh *active_state = NULL; /* XXX - needed for linking */
-
-void kex_tests(void);
-static int do_debug = 0;
-
-enum direction { S2C, C2S };
-
-struct hook_ctx {
- struct ssh *client, *server, *server2;
- int *c2s, *s2c;
- int trigger_direction, packet_index;
- const char *dump_path;
- struct sshbuf *replace_data;
-};
-
-static int
-packet_hook(struct ssh *ssh, struct sshbuf *packet, u_char *typep, void *_ctx)
-{
- struct hook_ctx *ctx = (struct hook_ctx *)_ctx;
- int mydirection = ssh == ctx->client ? S2C : C2S;
- int *packet_count = mydirection == S2C ? ctx->s2c : ctx->c2s;
- FILE *dumpfile;
- int r;
-
- if (do_debug) {
- printf("%s packet %d type %u:\n",
- mydirection == S2C ? "s2c" : "c2s",
- *packet_count, *typep);
- sshbuf_dump(packet, stdout);
- }
- if (mydirection == ctx->trigger_direction &&
- ctx->packet_index == *packet_count) {
- if (ctx->replace_data != NULL) {
- sshbuf_reset(packet);
- /* Type is first byte of packet */
- if ((r = sshbuf_get_u8(ctx->replace_data,
- typep)) != 0 ||
- (r = sshbuf_putb(packet, ctx->replace_data)) != 0)
- return r;
- if (do_debug) {
- printf("***** replaced packet type %u\n",
- *typep);
- sshbuf_dump(packet, stdout);
- }
- } else if (ctx->dump_path != NULL) {
- if ((dumpfile = fopen(ctx->dump_path, "w+")) == NULL)
- err(1, "fopen %s", ctx->dump_path);
- /* Write { type, packet } */
- if (fwrite(typep, 1, 1, dumpfile) != 1)
- err(1, "fwrite type %s", ctx->dump_path);
- if (sshbuf_len(packet) != 0 &&
- fwrite(sshbuf_ptr(packet), sshbuf_len(packet),
- 1, dumpfile) != 1)
- err(1, "fwrite body %s", ctx->dump_path);
- if (do_debug) {
- printf("***** dumped packet type %u len %zu\n",
- *typep, sshbuf_len(packet));
- }
- fclose(dumpfile);
- /* No point in continuing */
- exit(0);
- }
- }
- (*packet_count)++;
- return 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 (len == 0)
- return 0;
- if ((r = ssh_input_append(to, buf, len)) != 0) {
- debug("ssh_input_append: %s", ssh_err(r));
- return r;
- }
- if ((r = ssh_output_consume(from, len)) != 0) {
- debug("ssh_output_consume: %s", ssh_err(r));
- return r;
- }
- }
-}
-
-/* Minimal test_helper.c scaffholding to make this standalone */
-const char *in_test = NULL;
-#define TEST_START(a) \
- do { \
- in_test = (a); \
- if (do_debug) \
- fprintf(stderr, "test %s starting\n", in_test); \
- } while (0)
-#define TEST_DONE() \
- do { \
- if (do_debug) \
- fprintf(stderr, "test %s done\n", \
- in_test ? in_test : "???"); \
- in_test = NULL; \
- } while(0)
-#define ASSERT_INT_EQ(a, b) \
- do { \
- if ((int)(a) != (int)(b)) { \
- fprintf(stderr, "%s %s:%d " \
- "%s (%d) != expected %s (%d)\n", \
- in_test ? in_test : "(none)", \
- __func__, __LINE__, #a, (int)(a), #b, (int)(b)); \
- exit(2); \
- } \
- } while (0)
-#define ASSERT_INT_GE(a, b) \
- do { \
- if ((int)(a) < (int)(b)) { \
- fprintf(stderr, "%s %s:%d " \
- "%s (%d) < expected %s (%d)\n", \
- in_test ? in_test : "(none)", \
- __func__, __LINE__, #a, (int)(a), #b, (int)(b)); \
- exit(2); \
- } \
- } while (0)
-#define ASSERT_PTR_NE(a, b) \
- do { \
- if ((a) == (b)) { \
- fprintf(stderr, "%s %s:%d " \
- "%s (%p) != expected %s (%p)\n", \
- in_test ? in_test : "(none)", \
- __func__, __LINE__, #a, (a), #b, (b)); \
- exit(2); \
- } \
- } while (0)
-
-
-static void
-run_kex(struct ssh *client, struct ssh *server)
-{
- int r = 0;
-
- while (!server->kex->done || !client->kex->done) {
- if ((r = do_send_and_receive(server, client)) != 0) {
- debug("do_send_and_receive S2C: %s", ssh_err(r));
- break;
- }
- if ((r = do_send_and_receive(client, server)) != 0) {
- debug("do_send_and_receive C2S: %s", ssh_err(r));
- 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(const char *kex, struct sshkey *prvkey, int *c2s, int *s2c,
- int direction, int packet_index,
- const char *dump_path, struct sshbuf *replace_data)
-{
- struct ssh *client = NULL, *server = NULL, *server2 = NULL;
- struct sshkey *pubkey = NULL;
- struct sshbuf *state;
- struct kex_params kex_params;
- char *myproposal[PROPOSAL_MAX] = { KEX_CLIENT };
- char *keyname = NULL;
- struct hook_ctx hook_ctx;
-
- TEST_START("sshkey_from_private");
- ASSERT_INT_EQ(sshkey_from_private(prvkey, &pubkey), 0);
- TEST_DONE();
-
- TEST_START("ssh_init");
- memcpy(kex_params.proposal, myproposal, sizeof(myproposal));
- if (kex != NULL)
- kex_params.proposal[PROPOSAL_KEX_ALGS] = strdup(kex);
- keyname = strdup(sshkey_ssh_name(prvkey));
- 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_INT_EQ(ssh_init(&server2, 1, NULL), 0);
- ASSERT_PTR_NE(client, NULL);
- ASSERT_PTR_NE(server, NULL);
- ASSERT_PTR_NE(server2, NULL);
- TEST_DONE();
-
- hook_ctx.c2s = c2s;
- hook_ctx.s2c = s2c;
- hook_ctx.trigger_direction = direction;
- hook_ctx.packet_index = packet_index;
- hook_ctx.dump_path = dump_path;
- hook_ctx.replace_data = replace_data;
- hook_ctx.client = client;
- hook_ctx.server = server;
- hook_ctx.server2 = server2;
- ssh_packet_set_input_hook(client, packet_hook, &hook_ctx);
- ssh_packet_set_input_hook(server, packet_hook, &hook_ctx);
- ssh_packet_set_input_hook(server2, packet_hook, &hook_ctx);
-
- TEST_START("ssh_add_hostkey");
- ASSERT_INT_EQ(ssh_add_hostkey(server, prvkey), 0);
- ASSERT_INT_EQ(ssh_add_hostkey(client, pubkey), 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");
- ASSERT_INT_EQ(ssh_add_hostkey(server2, prvkey), 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 */
-#ifdef WITH_OPENSSL
- server2->kex->kex[KEX_DH_GRP1_SHA1] = kexdh_server;
- server2->kex->kex[KEX_DH_GRP14_SHA1] = kexdh_server;
- server2->kex->kex[KEX_DH_GRP14_SHA256] = kexdh_server;
- server2->kex->kex[KEX_DH_GRP16_SHA512] = kexdh_server;
- server2->kex->kex[KEX_DH_GRP18_SHA512] = 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
-#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(pubkey);
- ssh_free(client);
- ssh_free(server);
- ssh_free(server2);
- free(keyname);
- TEST_DONE();
-}
-
-static void
-usage(void)
-{
- fprintf(stderr,
- "Usage: kexfuzz [-hcdrv] [-D direction] [-f data_file]\n"
- " [-K kex_alg] [-k private_key] [-i packet_index]\n"
- "\n"
- "Options:\n"
- " -h Display this help\n"
- " -c Count packets sent during KEX\n"
- " -d Dump mode: record KEX packet to data file\n"
- " -r Replace mode: replace packet with data file\n"
- " -v Turn on verbose logging\n"
- " -D S2C|C2S Packet direction for replacement or dump\n"
- " -f data_file Path to data file for replacement or dump\n"
- " -K kex_alg Name of KEX algorithm to test (see below)\n"
- " -k private_key Path to private key file\n"
- " -i packet_index Index of packet to replace or dump (from 0)\n"
- "\n"
- "Available KEX algorithms: %s\n", kex_alg_list(' '));
-}
-
-static void
-badusage(const char *bad)
-{
- fprintf(stderr, "Invalid options\n");
- fprintf(stderr, "%s\n", bad);
- usage();
- exit(1);
-}
-
-int
-main(int argc, char **argv)
-{
- int ch, fd, r;
- int count_flag = 0, dump_flag = 0, replace_flag = 0;
- int packet_index = -1, direction = -1;
- int s2c = 0, c2s = 0; /* packet counts */
- const char *kex = NULL, *kpath = NULL, *data_path = NULL;
- struct sshkey *key = NULL;
- struct sshbuf *replace_data = NULL;
-
- setvbuf(stdout, NULL, _IONBF, 0);
- while ((ch = getopt(argc, argv, "hcdrvD:f:K:k:i:")) != -1) {
- switch (ch) {
- case 'h':
- usage();
- return 0;
- case 'c':
- count_flag = 1;
- break;
- case 'd':
- dump_flag = 1;
- break;
- case 'r':
- replace_flag = 1;
- break;
- case 'v':
- do_debug = 1;
- break;
-
- case 'D':
- if (strcasecmp(optarg, "s2c") == 0)
- direction = S2C;
- else if (strcasecmp(optarg, "c2s") == 0)
- direction = C2S;
- else
- badusage("Invalid direction (-D)");
- break;
- case 'f':
- data_path = optarg;
- break;
- case 'K':
- kex = optarg;
- break;
- case 'k':
- kpath = optarg;
- break;
- case 'i':
- packet_index = atoi(optarg);
- if (packet_index < 0)
- badusage("Invalid packet index");
- break;
- default:
- badusage("unsupported flag");
- }
- }
- argc -= optind;
- argv += optind;
-
- log_init(argv[0], do_debug ? SYSLOG_LEVEL_DEBUG3 : SYSLOG_LEVEL_INFO,
- SYSLOG_FACILITY_USER, 1);
-
- /* Must select a single mode */
- if ((count_flag + dump_flag + replace_flag) != 1)
- badusage("Must select one mode: -c, -d or -r");
- /* KEX type is mandatory */
- if (kex == NULL || !kex_names_valid(kex) || strchr(kex, ',') != NULL)
- badusage("Missing or invalid kex type (-K flag)");
- /* Valid key is mandatory */
- if (kpath == NULL)
- badusage("Missing private key (-k flag)");
- if ((fd = open(kpath, O_RDONLY)) == -1)
- err(1, "open %s", kpath);
- if ((r = sshkey_load_private_type_fd(fd, KEY_UNSPEC, NULL,
- &key, NULL)) != 0)
- errx(1, "Unable to load key %s: %s", kpath, ssh_err(r));
- close(fd);
- /* XXX check that it is a private key */
- /* XXX support certificates */
- if (key == NULL || key->type == KEY_UNSPEC)
- badusage("Invalid key file (-k flag)");
-
- /* Replace (fuzz) mode */
- if (replace_flag) {
- if (packet_index == -1 || direction == -1 || data_path == NULL)
- badusage("Replace (-r) mode must specify direction "
- "(-D) packet index (-i) and data path (-f)");
- if ((fd = open(data_path, O_RDONLY)) == -1)
- err(1, "open %s", data_path);
- replace_data = sshbuf_new();
- if ((r = sshkey_load_file(fd, replace_data)) != 0)
- errx(1, "read %s: %s", data_path, ssh_err(r));
- close(fd);
- }
-
- /* Dump mode */
- if (dump_flag) {
- if (packet_index == -1 || direction == -1 || data_path == NULL)
- badusage("Dump (-d) mode must specify direction "
- "(-D), packet index (-i) and data path (-f)");
- }
-
- /* Count mode needs no further flags */
-
- do_kex_with_key(kex, key, &c2s, &s2c,
- direction, packet_index,
- dump_flag ? data_path : NULL,
- replace_flag ? replace_data : NULL);
- sshkey_free(key);
- sshbuf_free(replace_data);
-
- if (count_flag) {
- printf("S2C: %d\n", s2c);
- printf("C2S: %d\n", c2s);
- }
-
- return 0;
-}
diff --git a/crypto/openssh/regress/misc/sk-dummy/fatal.c b/crypto/openssh/regress/misc/sk-dummy/fatal.c
new file mode 100644
index 000000000000..c6e4b5d6fa71
--- /dev/null
+++ b/crypto/openssh/regress/misc/sk-dummy/fatal.c
@@ -0,0 +1,27 @@
+/* public domain */
+
+#include "includes.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <unistd.h>
+
+#include "log.h"
+
+void
+sshfatal(const char *file, const char *func, int line, int showfunc,
+ LogLevel level, const char *suffix, const char *fmt, ...)
+{
+ va_list ap;
+
+ if (showfunc)
+ fprintf(stderr, "%s: ", func);
+ va_start(ap, fmt);
+ vfprintf(stderr, fmt, ap);
+ va_end(ap);
+ if (suffix != NULL)
+ fprintf(stderr, ": %s", suffix);
+ fputc('\n', stderr);
+ _exit(1);
+}
diff --git a/crypto/openssh/regress/misc/sk-dummy/sk-dummy.c b/crypto/openssh/regress/misc/sk-dummy/sk-dummy.c
new file mode 100644
index 000000000000..4003362d7960
--- /dev/null
+++ b/crypto/openssh/regress/misc/sk-dummy/sk-dummy.c
@@ -0,0 +1,539 @@
+/*
+ * Copyright (c) 2019 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"
+
+#ifdef HAVE_STDINT_H
+#include <stdint.h>
+#endif
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <stddef.h>
+#include <stdarg.h>
+
+#include "crypto_api.h"
+#include "sk-api.h"
+
+#include <openssl/opensslv.h>
+#include <openssl/crypto.h>
+#include <openssl/evp.h>
+#include <openssl/bn.h>
+#include <openssl/ec.h>
+#include <openssl/ecdsa.h>
+#include <openssl/pem.h>
+
+/* #define SK_DEBUG 1 */
+
+/* Compatibility with OpenSSH 1.0.x */
+#if (OPENSSL_VERSION_NUMBER < 0x10100000L)
+#define ECDSA_SIG_get0(sig, pr, ps) \
+ do { \
+ (*pr) = sig->r; \
+ (*ps) = sig->s; \
+ } while (0)
+#endif
+
+#if SSH_SK_VERSION_MAJOR != 0x00070000
+# error SK API has changed, sk-dummy.c needs an update
+#endif
+
+#ifdef SK_DUMMY_INTEGRATE
+# define sk_api_version ssh_sk_api_version
+# define sk_enroll ssh_sk_enroll
+# define sk_sign ssh_sk_sign
+# define sk_load_resident_keys ssh_sk_load_resident_keys
+#endif /* !SK_STANDALONE */
+
+static void skdebug(const char *func, const char *fmt, ...)
+ __attribute__((__format__ (printf, 2, 3)));
+
+static void
+skdebug(const char *func, const char *fmt, ...)
+{
+#if defined(SK_DEBUG)
+ va_list ap;
+
+ va_start(ap, fmt);
+ fprintf(stderr, "sk-dummy %s: ", func);
+ vfprintf(stderr, fmt, ap);
+ fputc('\n', stderr);
+ va_end(ap);
+#else
+ (void)func; /* XXX */
+ (void)fmt; /* XXX */
+#endif
+}
+
+uint32_t
+sk_api_version(void)
+{
+ return SSH_SK_VERSION_MAJOR;
+}
+
+static int
+pack_key_ecdsa(struct sk_enroll_response *response)
+{
+#ifdef OPENSSL_HAS_ECC
+ EC_KEY *key = NULL;
+ const EC_GROUP *g;
+ const EC_POINT *q;
+ int ret = -1;
+ long privlen;
+ BIO *bio = NULL;
+ char *privptr;
+
+ response->public_key = NULL;
+ response->public_key_len = 0;
+ response->key_handle = NULL;
+ response->key_handle_len = 0;
+
+ if ((key = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1)) == NULL) {
+ skdebug(__func__, "EC_KEY_new_by_curve_name");
+ goto out;
+ }
+ if (EC_KEY_generate_key(key) != 1) {
+ skdebug(__func__, "EC_KEY_generate_key");
+ goto out;
+ }
+ EC_KEY_set_asn1_flag(key, OPENSSL_EC_NAMED_CURVE);
+ if ((bio = BIO_new(BIO_s_mem())) == NULL ||
+ (g = EC_KEY_get0_group(key)) == NULL ||
+ (q = EC_KEY_get0_public_key(key)) == NULL) {
+ skdebug(__func__, "couldn't get key parameters");
+ goto out;
+ }
+ response->public_key_len = EC_POINT_point2oct(g, q,
+ POINT_CONVERSION_UNCOMPRESSED, NULL, 0, NULL);
+ if (response->public_key_len == 0 || response->public_key_len > 2048) {
+ skdebug(__func__, "bad pubkey length %zu",
+ response->public_key_len);
+ goto out;
+ }
+ if ((response->public_key = malloc(response->public_key_len)) == NULL) {
+ skdebug(__func__, "malloc pubkey failed");
+ goto out;
+ }
+ if (EC_POINT_point2oct(g, q, POINT_CONVERSION_UNCOMPRESSED,
+ response->public_key, response->public_key_len, NULL) == 0) {
+ skdebug(__func__, "EC_POINT_point2oct failed");
+ goto out;
+ }
+ /* Key handle contains PEM encoded private key */
+ if (!PEM_write_bio_ECPrivateKey(bio, key, NULL, NULL, 0, NULL, NULL)) {
+ skdebug(__func__, "PEM_write_bio_ECPrivateKey failed");
+ goto out;
+ }
+ if ((privlen = BIO_get_mem_data(bio, &privptr)) <= 0) {
+ skdebug(__func__, "BIO_get_mem_data failed");
+ goto out;
+ }
+ if ((response->key_handle = malloc(privlen)) == NULL) {
+ skdebug(__func__, "malloc key_handle failed");
+ goto out;
+ }
+ response->key_handle_len = (size_t)privlen;
+ memcpy(response->key_handle, privptr, response->key_handle_len);
+ /* success */
+ ret = 0;
+ out:
+ if (ret != 0) {
+ if (response->public_key != NULL) {
+ memset(response->public_key, 0,
+ response->public_key_len);
+ free(response->public_key);
+ response->public_key = NULL;
+ }
+ if (response->key_handle != NULL) {
+ memset(response->key_handle, 0,
+ response->key_handle_len);
+ free(response->key_handle);
+ response->key_handle = NULL;
+ }
+ }
+ BIO_free(bio);
+ EC_KEY_free(key);
+ return ret;
+#else
+ return -1;
+#endif
+}
+
+static int
+pack_key_ed25519(struct sk_enroll_response *response)
+{
+ int ret = -1;
+ u_char pk[crypto_sign_ed25519_PUBLICKEYBYTES];
+ u_char sk[crypto_sign_ed25519_SECRETKEYBYTES];
+
+ response->public_key = NULL;
+ response->public_key_len = 0;
+ response->key_handle = NULL;
+ response->key_handle_len = 0;
+
+ memset(pk, 0, sizeof(pk));
+ memset(sk, 0, sizeof(sk));
+ crypto_sign_ed25519_keypair(pk, sk);
+
+ response->public_key_len = sizeof(pk);
+ if ((response->public_key = malloc(response->public_key_len)) == NULL) {
+ skdebug(__func__, "malloc pubkey failed");
+ goto out;
+ }
+ memcpy(response->public_key, pk, sizeof(pk));
+ /* Key handle contains sk */
+ response->key_handle_len = sizeof(sk);
+ if ((response->key_handle = malloc(response->key_handle_len)) == NULL) {
+ skdebug(__func__, "malloc key_handle failed");
+ goto out;
+ }
+ memcpy(response->key_handle, sk, sizeof(sk));
+ /* success */
+ ret = 0;
+ out:
+ if (ret != 0)
+ free(response->public_key);
+ return ret;
+}
+
+static int
+check_options(struct sk_option **options)
+{
+ size_t i;
+
+ if (options == NULL)
+ return 0;
+ for (i = 0; options[i] != NULL; i++) {
+ skdebug(__func__, "requested unsupported option %s",
+ options[i]->name);
+ if (options[i]->required) {
+ skdebug(__func__, "unknown required option");
+ return -1;
+ }
+ }
+ return 0;
+}
+
+int
+sk_enroll(uint32_t alg, const uint8_t *challenge, size_t challenge_len,
+ const char *application, uint8_t flags, const char *pin,
+ struct sk_option **options, struct sk_enroll_response **enroll_response)
+{
+ struct sk_enroll_response *response = NULL;
+ int ret = SSH_SK_ERR_GENERAL;
+
+ (void)flags; /* XXX; unused */
+
+ if (enroll_response == NULL) {
+ skdebug(__func__, "enroll_response == NULL");
+ goto out;
+ }
+ *enroll_response = NULL;
+ if (check_options(options) != 0)
+ goto out; /* error already logged */
+ if ((response = calloc(1, sizeof(*response))) == NULL) {
+ skdebug(__func__, "calloc response failed");
+ goto out;
+ }
+ switch(alg) {
+ case SSH_SK_ECDSA:
+ if (pack_key_ecdsa(response) != 0)
+ goto out;
+ break;
+ case SSH_SK_ED25519:
+ if (pack_key_ed25519(response) != 0)
+ goto out;
+ break;
+ default:
+ skdebug(__func__, "unsupported key type %d", alg);
+ return -1;
+ }
+ /* Have to return something here */
+ if ((response->signature = calloc(1, 1)) == NULL) {
+ skdebug(__func__, "calloc signature failed");
+ goto out;
+ }
+ response->signature_len = 0;
+
+ *enroll_response = response;
+ response = NULL;
+ ret = 0;
+ out:
+ if (response != NULL) {
+ free(response->public_key);
+ free(response->key_handle);
+ free(response->signature);
+ free(response->attestation_cert);
+ free(response);
+ }
+ return ret;
+}
+
+static void
+dump(const char *preamble, const void *sv, size_t l)
+{
+#ifdef SK_DEBUG
+ const u_char *s = (const u_char *)sv;
+ size_t i;
+
+ fprintf(stderr, "%s (len %zu):\n", preamble, l);
+ for (i = 0; i < l; i++) {
+ if (i % 16 == 0)
+ fprintf(stderr, "%04zu: ", i);
+ fprintf(stderr, "%02x", s[i]);
+ if (i % 16 == 15 || i == l - 1)
+ fprintf(stderr, "\n");
+ }
+#endif
+}
+
+static int
+sig_ecdsa(const uint8_t *message, size_t message_len,
+ const char *application, uint32_t counter, uint8_t flags,
+ const uint8_t *key_handle, size_t key_handle_len,
+ struct sk_sign_response *response)
+{
+#ifdef OPENSSL_HAS_ECC
+ ECDSA_SIG *sig = NULL;
+ const BIGNUM *sig_r, *sig_s;
+ int ret = -1;
+ BIO *bio = NULL;
+ EVP_PKEY *pk = NULL;
+ EC_KEY *ec = NULL;
+ SHA256_CTX ctx;
+ uint8_t apphash[SHA256_DIGEST_LENGTH];
+ uint8_t sighash[SHA256_DIGEST_LENGTH];
+ uint8_t countbuf[4];
+
+ /* Decode EC_KEY from key handle */
+ if ((bio = BIO_new(BIO_s_mem())) == NULL ||
+ BIO_write(bio, key_handle, key_handle_len) != (int)key_handle_len) {
+ skdebug(__func__, "BIO setup failed");
+ goto out;
+ }
+ if ((pk = PEM_read_bio_PrivateKey(bio, NULL, NULL, "")) == NULL) {
+ skdebug(__func__, "PEM_read_bio_PrivateKey failed");
+ goto out;
+ }
+ if (EVP_PKEY_base_id(pk) != EVP_PKEY_EC) {
+ skdebug(__func__, "Not an EC key: %d", EVP_PKEY_base_id(pk));
+ goto out;
+ }
+ if ((ec = EVP_PKEY_get1_EC_KEY(pk)) == NULL) {
+ skdebug(__func__, "EVP_PKEY_get1_EC_KEY failed");
+ goto out;
+ }
+ /* Expect message to be pre-hashed */
+ if (message_len != SHA256_DIGEST_LENGTH) {
+ skdebug(__func__, "bad message len %zu", message_len);
+ goto out;
+ }
+ /* Prepare data to be signed */
+ dump("message", message, message_len);
+ SHA256_Init(&ctx);
+ SHA256_Update(&ctx, application, strlen(application));
+ SHA256_Final(apphash, &ctx);
+ dump("apphash", apphash, sizeof(apphash));
+ countbuf[0] = (counter >> 24) & 0xff;
+ countbuf[1] = (counter >> 16) & 0xff;
+ countbuf[2] = (counter >> 8) & 0xff;
+ countbuf[3] = counter & 0xff;
+ dump("countbuf", countbuf, sizeof(countbuf));
+ dump("flags", &flags, sizeof(flags));
+ SHA256_Init(&ctx);
+ SHA256_Update(&ctx, apphash, sizeof(apphash));
+ SHA256_Update(&ctx, &flags, sizeof(flags));
+ SHA256_Update(&ctx, countbuf, sizeof(countbuf));
+ SHA256_Update(&ctx, message, message_len);
+ SHA256_Final(sighash, &ctx);
+ dump("sighash", sighash, sizeof(sighash));
+ /* create and encode signature */
+ if ((sig = ECDSA_do_sign(sighash, sizeof(sighash), ec)) == NULL) {
+ skdebug(__func__, "ECDSA_do_sign failed");
+ goto out;
+ }
+ ECDSA_SIG_get0(sig, &sig_r, &sig_s);
+ response->sig_r_len = BN_num_bytes(sig_r);
+ response->sig_s_len = BN_num_bytes(sig_s);
+ if ((response->sig_r = calloc(1, response->sig_r_len)) == NULL ||
+ (response->sig_s = calloc(1, response->sig_s_len)) == NULL) {
+ skdebug(__func__, "calloc signature failed");
+ goto out;
+ }
+ BN_bn2bin(sig_r, response->sig_r);
+ BN_bn2bin(sig_s, response->sig_s);
+ ret = 0;
+ out:
+ explicit_bzero(&ctx, sizeof(ctx));
+ explicit_bzero(&apphash, sizeof(apphash));
+ explicit_bzero(&sighash, sizeof(sighash));
+ ECDSA_SIG_free(sig);
+ if (ret != 0) {
+ free(response->sig_r);
+ free(response->sig_s);
+ response->sig_r = NULL;
+ response->sig_s = NULL;
+ }
+ BIO_free(bio);
+ EC_KEY_free(ec);
+ EVP_PKEY_free(pk);
+ return ret;
+#else
+ return -1;
+#endif
+}
+
+static int
+sig_ed25519(const uint8_t *message, size_t message_len,
+ const char *application, uint32_t counter, uint8_t flags,
+ const uint8_t *key_handle, size_t key_handle_len,
+ struct sk_sign_response *response)
+{
+ size_t o;
+ int ret = -1;
+ SHA256_CTX ctx;
+ uint8_t apphash[SHA256_DIGEST_LENGTH];
+ uint8_t signbuf[sizeof(apphash) + sizeof(flags) +
+ sizeof(counter) + SHA256_DIGEST_LENGTH];
+ uint8_t sig[crypto_sign_ed25519_BYTES + sizeof(signbuf)];
+ unsigned long long smlen;
+
+ if (key_handle_len != crypto_sign_ed25519_SECRETKEYBYTES) {
+ skdebug(__func__, "bad key handle length %zu", key_handle_len);
+ goto out;
+ }
+ /* Expect message to be pre-hashed */
+ if (message_len != SHA256_DIGEST_LENGTH) {
+ skdebug(__func__, "bad message len %zu", message_len);
+ goto out;
+ }
+ /* Prepare data to be signed */
+ dump("message", message, message_len);
+ SHA256_Init(&ctx);
+ SHA256_Update(&ctx, application, strlen(application));
+ SHA256_Final(apphash, &ctx);
+ dump("apphash", apphash, sizeof(apphash));
+
+ memcpy(signbuf, apphash, sizeof(apphash));
+ o = sizeof(apphash);
+ signbuf[o++] = flags;
+ signbuf[o++] = (counter >> 24) & 0xff;
+ signbuf[o++] = (counter >> 16) & 0xff;
+ signbuf[o++] = (counter >> 8) & 0xff;
+ signbuf[o++] = counter & 0xff;
+ memcpy(signbuf + o, message, message_len);
+ o += message_len;
+ if (o != sizeof(signbuf)) {
+ skdebug(__func__, "bad sign buf len %zu, expected %zu",
+ o, sizeof(signbuf));
+ goto out;
+ }
+ dump("signbuf", signbuf, sizeof(signbuf));
+ /* create and encode signature */
+ smlen = sizeof(signbuf);
+ if (crypto_sign_ed25519(sig, &smlen, signbuf, sizeof(signbuf),
+ key_handle) != 0) {
+ skdebug(__func__, "crypto_sign_ed25519 failed");
+ goto out;
+ }
+ if (smlen <= sizeof(signbuf)) {
+ skdebug(__func__, "bad sign smlen %llu, expected min %zu",
+ smlen, sizeof(signbuf) + 1);
+ goto out;
+ }
+ response->sig_r_len = (size_t)(smlen - sizeof(signbuf));
+ if ((response->sig_r = calloc(1, response->sig_r_len)) == NULL) {
+ skdebug(__func__, "calloc signature failed");
+ goto out;
+ }
+ memcpy(response->sig_r, sig, response->sig_r_len);
+ dump("sig_r", response->sig_r, response->sig_r_len);
+ ret = 0;
+ out:
+ explicit_bzero(&ctx, sizeof(ctx));
+ explicit_bzero(&apphash, sizeof(apphash));
+ explicit_bzero(&signbuf, sizeof(signbuf));
+ explicit_bzero(&sig, sizeof(sig));
+ if (ret != 0) {
+ free(response->sig_r);
+ response->sig_r = NULL;
+ }
+ return ret;
+}
+
+int
+sk_sign(uint32_t alg, const uint8_t *data, size_t datalen,
+ const char *application, const uint8_t *key_handle, size_t key_handle_len,
+ uint8_t flags, const char *pin, struct sk_option **options,
+ struct sk_sign_response **sign_response)
+{
+ struct sk_sign_response *response = NULL;
+ int ret = SSH_SK_ERR_GENERAL;
+ SHA256_CTX ctx;
+ uint8_t message[32];
+
+ if (sign_response == NULL) {
+ skdebug(__func__, "sign_response == NULL");
+ goto out;
+ }
+ *sign_response = NULL;
+ if (check_options(options) != 0)
+ goto out; /* error already logged */
+ if ((response = calloc(1, sizeof(*response))) == NULL) {
+ skdebug(__func__, "calloc response failed");
+ goto out;
+ }
+ SHA256_Init(&ctx);
+ SHA256_Update(&ctx, data, datalen);
+ SHA256_Final(message, &ctx);
+ response->flags = flags;
+ response->counter = 0x12345678;
+ switch(alg) {
+ case SSH_SK_ECDSA:
+ if (sig_ecdsa(message, sizeof(message), application,
+ response->counter, flags, key_handle, key_handle_len,
+ response) != 0)
+ goto out;
+ break;
+ case SSH_SK_ED25519:
+ if (sig_ed25519(message, sizeof(message), application,
+ response->counter, flags, key_handle, key_handle_len,
+ response) != 0)
+ goto out;
+ break;
+ default:
+ skdebug(__func__, "unsupported key type %d", alg);
+ return -1;
+ }
+ *sign_response = response;
+ response = NULL;
+ ret = 0;
+ out:
+ explicit_bzero(message, sizeof(message));
+ if (response != NULL) {
+ free(response->sig_r);
+ free(response->sig_s);
+ free(response);
+ }
+ return ret;
+}
+
+int
+sk_load_resident_keys(const char *pin, struct sk_option **options,
+ struct sk_resident_key ***rks, size_t *nrks)
+{
+ return SSH_SK_ERR_UNSUPPORTED;
+}
diff --git a/crypto/openssh/regress/modpipe.c b/crypto/openssh/regress/modpipe.c
index 5f4824b51d02..5f4824b51d02 100755..100644
--- a/crypto/openssh/regress/modpipe.c
+++ b/crypto/openssh/regress/modpipe.c
diff --git a/crypto/openssh/regress/multiplex.sh b/crypto/openssh/regress/multiplex.sh
index a6fad8eb820c..4744fa3d97d6 100644
--- a/crypto/openssh/regress/multiplex.sh
+++ b/crypto/openssh/regress/multiplex.sh
@@ -1,4 +1,4 @@
-# $OpenBSD: multiplex.sh,v 1.28 2017/04/30 23:34:55 djm Exp $
+# $OpenBSD: multiplex.sh,v 1.33 2020/06/24 15:16:23 markus Exp $
# Placed in the Public Domain.
make_tmpdir
@@ -6,8 +6,6 @@ CTL=${SSH_REGRESS_TMP}/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)"
@@ -18,7 +16,7 @@ P=3301 # test port
wait_for_mux_master_ready()
{
- for i in 1 2 3 4 5; do
+ for i in 1 2 3 4 5 6 7 8 9; do
${SSH} -F $OBJ/ssh_config -S $CTL -Ocheck otherhost \
>/dev/null 2>&1 && return 0
sleep $i
@@ -81,6 +79,7 @@ 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
+sleep 1 # XXX remove once race fixed
$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
@@ -91,28 +90,31 @@ $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
+sleep 1 # XXX remove once race fixed
+$NC -U $OBJ/unix-3.fwd < /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
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
+ for mode in "" "-Oproxy"; do
+ trace "exit status $s over multiplexed connection ($mode)"
+ verbose "test $tid: status $s ($mode)"
+ ${SSH} -F $OBJ/ssh_config -S $CTL $mode otherhost exit $s
r=$?
if [ $r -ne $s ]; then
fail "exit code mismatch: $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 \
+ trace "exit status $s with early close over multiplexed connection ($mode)"
+ ${SSH} -F $OBJ/ssh_config -S $CTL -n $mode 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: $r != $s"
fi
+ done
done
verbose "test $tid: cmd check"
@@ -122,6 +124,7 @@ ${SSH} -F $OBJ/ssh_config -S $CTL -Ocheck otherhost >>$TEST_REGRESS_LOGFILE 2>&1
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"
+sleep 1 # XXX remove once race fixed
${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 \
@@ -132,6 +135,7 @@ ${SSH} -F $OBJ/ssh_config -p$P otherhost true \
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"
+sleep 1 # XXX remove once race fixed
${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 \
@@ -142,7 +146,9 @@ ${SSH} -F $OBJ/ssh_config -p$P otherhost true \
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 \
+sleep 1 # XXX remove once race fixed
+echo "" | $NC -U $OBJ/unix-1.fwd | \
+ grep "Invalid SSH identification string" >/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"
@@ -153,7 +159,9 @@ 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 \
+sleep 1 # XXX remove once race fixed
+echo "" | $NC -U $OBJ/unix-1.fwd | \
+ grep "Invalid SSH identification string" >/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"
diff --git a/crypto/openssh/regress/multipubkey.sh b/crypto/openssh/regress/multipubkey.sh
index e9d15306ff2f..8cdda1a9ae0d 100755..100644
--- a/crypto/openssh/regress/multipubkey.sh
+++ b/crypto/openssh/regress/multipubkey.sh
@@ -1,4 +1,4 @@
-# $OpenBSD: multipubkey.sh,v 1.1 2014/12/22 08:06:03 djm Exp $
+# $OpenBSD: multipubkey.sh,v 1.4 2021/06/07 01:16:34 djm Exp $
# Placed in the Public Domain.
tid="multiple pubkey"
@@ -31,27 +31,35 @@ 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
+for match in no yes ; do
(
- grep -v "Protocol" $OBJ/sshd_proxy.orig
+ cat $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
+ if test "$match" = "yes" ; then
+ echo "AuthenticationMethods none" >> $OBJ/sshd_proxy
+ echo "PubkeyAuthentication no" >> $OBJ/sshd_proxy
+ echo "Match all" >> $OBJ/sshd_proxy
+ echo "PubkeyAuthentication yes" >> $OBJ/sshd_proxy
+ fi
+ echo "AuthenticationMethods publickey,publickey" >> $OBJ/sshd_proxy
# Single key should fail.
+ trace "match $match single key"
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.
+ trace "match $match pubkey + identical cert"
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.
+ trace "match $match multiple public"
rm -f $OBJ/authorized_principals_$USER
cat $OBJ/user_key1.pub $OBJ/user_key2.pub > \
$OBJ/authorized_keys_$USER
@@ -59,6 +67,7 @@ for privsep in no yes; do
# Cert and different key should succeed
# Key and different-public cert should succeed.
+ trace "match $match pubkey + different cert"
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"
diff --git a/crypto/openssh/regress/netcat.c b/crypto/openssh/regress/netcat.c
index 56bd09de5485..20ec3f5954fa 100644
--- a/crypto/openssh/regress/netcat.c
+++ b/crypto/openssh/regress/netcat.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: netcat.c,v 1.126 2014/10/30 16:08:31 tedu Exp $ */
+/* $OpenBSD: netcat.c,v 1.131 2015/09/03 23:06:28 sobrado Exp $ */
/*
* Copyright (c) 2001 Eric Jackson <ericj@monkey.org>
*
@@ -44,14 +44,15 @@
#include <netinet/ip.h>
#include <errno.h>
+#include <fcntl.h>
+#include <limits.h>
#include <netdb.h>
+#include <signal.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
-#include <fcntl.h>
-#include <limits.h>
#include "atomicio.h"
#ifdef HAVE_POLL_H
@@ -64,6 +65,12 @@
#ifdef HAVE_ERR_H
# include <err.h>
#endif
+#ifdef HAVE_SYS_BYTEORDER_H
+# include <sys/byteorder.h>
+#endif
+
+/* rename to avoid collision in libssh */
+#define timeout_connect netcat_timeout_connect
/* Telnet options from arpa/telnet.h */
#define IAC 255
@@ -130,7 +137,7 @@ int udptest(int);
int unix_bind(char *);
int unix_connect(char *);
int unix_listen(char *);
-void set_common_sockopts(int);
+void set_common_sockopts(int, int);
int map_tos(char *, int *);
void report_connect(const struct sockaddr *, socklen_t);
void usage(int);
@@ -159,6 +166,8 @@ main(int argc, char *argv[])
uport = NULL;
sv = NULL;
+ signal(SIGPIPE, SIG_IGN);
+
while ((ch = getopt(argc, argv,
"46DdFhI:i:klNnO:P:p:rSs:tT:UuV:vw:X:x:z")) != -1) {
switch (ch) {
@@ -645,7 +654,7 @@ remote_connect(const char *host, const char *port, struct addrinfo hints)
freeaddrinfo(ares);
}
- set_common_sockopts(s);
+ set_common_sockopts(s, res0->ai_family);
if (timeout_connect(s, res0->ai_addr, res0->ai_addrlen) == 0)
break;
@@ -745,7 +754,7 @@ local_listen(char *host, char *port, struct addrinfo hints)
if (ret == -1)
err(1, "setsockopt SO_REUSEADDR");
#endif
- set_common_sockopts(s);
+ set_common_sockopts(s, res0->ai_family);
if (bind(s, (struct sockaddr *)res0->ai_addr,
res0->ai_addrlen) == 0)
@@ -1031,17 +1040,17 @@ fdpass(int nfd)
bzero(&pfd, sizeof(pfd));
pfd.fd = STDOUT_FILENO;
+ pfd.events = POLLOUT;
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)
+ } else if (r != 1)
errx(1, "sendmsg: unexpected return value %zd", r);
else
break;
@@ -1165,7 +1174,7 @@ udptest(int s)
}
void
-set_common_sockopts(int s)
+set_common_sockopts(int s, int af)
{
int x = 1;
@@ -1181,11 +1190,22 @@ set_common_sockopts(int s)
&x, sizeof(x)) == -1)
err(1, "setsockopt");
}
+#if defined(IP_TOS) && defined(IPV6_TCLASS)
if (Tflag != -1) {
- if (setsockopt(s, IPPROTO_IP, IP_TOS,
- &Tflag, sizeof(Tflag)) == -1)
+ int proto, option;
+
+ if (af == AF_INET6) {
+ proto = IPPROTO_IPV6;
+ option = IPV6_TCLASS;
+ } else {
+ proto = IPPROTO_IP;
+ option = IP_TOS;
+ }
+
+ if (setsockopt(s, proto, option, &Tflag, sizeof(Tflag)) == -1)
err(1, "set IP ToS");
}
+#endif
if (Iflag) {
if (setsockopt(s, SOL_SOCKET, SO_RCVBUF,
&Iflag, sizeof(Iflag)) == -1)
@@ -1201,6 +1221,7 @@ set_common_sockopts(int s)
int
map_tos(char *s, int *val)
{
+#ifdef IP_TOS
/* DiffServ Codepoints and other TOS mappings */
const struct toskeywords {
const char *keyword;
@@ -1242,6 +1263,7 @@ map_tos(char *s, int *val)
return (1);
}
}
+#endif
return (0);
}
@@ -1314,7 +1336,7 @@ 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 [-P proxy_username] [-p source_port] [-s source] [-T toskeyword]\n"
"\t [-V rtable] [-w timeout] [-X proxy_protocol]\n"
"\t [-x proxy_address[:port]] [destination] [port]\n");
if (ret)
diff --git a/crypto/openssh/regress/percent.sh b/crypto/openssh/regress/percent.sh
new file mode 100644
index 000000000000..7ed41845b5cf
--- /dev/null
+++ b/crypto/openssh/regress/percent.sh
@@ -0,0 +1,119 @@
+# $OpenBSD: percent.sh,v 1.13 2021/07/25 12:13:03 dtucker Exp $
+# Placed in the Public Domain.
+
+tid="percent expansions"
+
+if [ -x "/usr/xpg4/bin/id" ]; then
+ PATH=/usr/xpg4/bin:$PATH
+ export PATH
+fi
+
+USER=`id -u -n`
+USERID=`id -u`
+HOST=`hostname | cut -f1 -d.`
+HOSTNAME=`hostname`
+
+# Localcommand is evaluated after connection because %T is not available
+# until then. Because of this we use a different method of exercising it,
+# and we can't override the remote user otherwise authentication will fail.
+# We also have to explicitly enable it.
+echo "permitlocalcommand yes" >> $OBJ/ssh_proxy
+
+trial()
+{
+ opt="$1"; arg="$2"; expect="$3"
+
+ trace "test $opt=$arg $expect"
+ rm -f $OBJ/actual
+ got=""
+ case "$opt" in
+ localcommand)
+ ${SSH} -F $OBJ/ssh_proxy -o $opt="echo '$arg' >$OBJ/actual" \
+ somehost true
+ got=`cat $OBJ/actual`
+ ;;
+ userknownhostsfile)
+ # Move the userknownhosts file to what the expansion says,
+ # make sure ssh works then put it back.
+ mv "$OBJ/known_hosts" "$OBJ/$expect"
+ ${SSH} -F $OBJ/ssh_proxy -o $opt="$OBJ/$arg" somehost true && \
+ got="$expect"
+ mv "$OBJ/$expect" "$OBJ/known_hosts"
+ ;;
+ matchexec)
+ (cat $OBJ/ssh_proxy && \
+ echo "Match Exec \"echo '$arg' >$OBJ/actual\"") \
+ >$OBJ/ssh_proxy_match
+ ${SSH} -F $OBJ/ssh_proxy_match remuser@somehost true || true
+ got=`cat $OBJ/actual`
+ ;;
+ *forward)
+ # LocalForward and RemoteForward take two args and only
+ # operate on Unix domain socket paths
+ got=`${SSH} -F $OBJ/ssh_proxy -o $opt="/$arg /$arg" -G \
+ remuser@somehost | awk '$1=="'$opt'"{print $2" "$3}'`
+ expect="/$expect /$expect"
+ ;;
+ *)
+ got=`${SSH} -F $OBJ/ssh_proxy -o $opt="$arg" -G \
+ remuser@somehost | awk '$1=="'$opt'"{print $2}'`
+ esac
+ if [ "$got" != "$expect" ]; then
+ fail "$opt=$arg expect $expect got $got"
+ fi
+}
+
+for i in matchexec localcommand remotecommand controlpath identityagent \
+ forwardagent localforward remoteforward userknownhostsfile; do
+ verbose $tid $i percent
+ case "$i" in
+ localcommand|userknownhostsfile)
+ # Any test that's going to actually make a connection needs
+ # to use the real username.
+ REMUSER=$USER ;;
+ *)
+ REMUSER=remuser ;;
+ esac
+ if [ "$i" = "$localcommand" ]; then
+ trial $i '%T' NONE
+ fi
+ # Matches implementation in readconf.c:ssh_connection_hash()
+ HASH=`printf "${HOSTNAME}127.0.0.1${PORT}$REMUSER" |
+ $OPENSSL_BIN sha1 | cut -f2 -d' '`
+ trial $i '%%' '%'
+ trial $i '%C' $HASH
+ trial $i '%i' $USERID
+ trial $i '%h' 127.0.0.1
+ trial $i '%L' $HOST
+ trial $i '%l' $HOSTNAME
+ trial $i '%n' somehost
+ trial $i '%k' localhost-with-alias
+ trial $i '%p' $PORT
+ trial $i '%r' $REMUSER
+ trial $i '%u' $USER
+ # We can't specify a full path outside the regress dir, so skip tests
+ # containing %d for UserKnownHostsFile
+ if [ "$i" != "userknownhostsfile" ]; then
+ trial $i '%d' $HOME
+ trial $i '%%/%C/%i/%h/%d/%L/%l/%n/%p/%r/%u' \
+ "%/$HASH/$USERID/127.0.0.1/$HOME/$HOST/$HOSTNAME/somehost/$PORT/$REMUSER/$USER"
+ fi
+done
+
+# Subset of above since we don't expand shell-style variables on anything that
+# runs a command because the shell will expand those.
+for i in controlpath identityagent forwardagent localforward remoteforward \
+ userknownhostsfile; do
+ verbose $tid $i dollar
+ FOO=bar
+ export FOO
+ trial $i '${FOO}' $FOO
+done
+
+
+# A subset of options support tilde expansion
+for i in controlpath identityagent forwardagent; do
+ verbose $tid $i tilde
+ trial $i '~' $HOME/
+ trial $i '~/.ssh' $HOME/.ssh
+done
diff --git a/crypto/openssh/regress/portnum.sh b/crypto/openssh/regress/portnum.sh
index c56b869a31bd..c56b869a31bd 100755..100644
--- a/crypto/openssh/regress/portnum.sh
+++ b/crypto/openssh/regress/portnum.sh
diff --git a/crypto/openssh/regress/principals-command.sh b/crypto/openssh/regress/principals-command.sh
index bcc68e80bca6..5e535c133464 100755..100644
--- a/crypto/openssh/regress/principals-command.sh
+++ b/crypto/openssh/regress/principals-command.sh
@@ -1,4 +1,4 @@
-# $OpenBSD: principals-command.sh,v 1.4 2017/04/30 23:34:55 djm Exp $
+# $OpenBSD: principals-command.sh,v 1.11 2019/12/16 02:39:05 djm Exp $
# Placed in the Public Domain.
tid="authorized principals command"
@@ -12,12 +12,17 @@ if [ -z "$SUDO" -a ! -w /var/run ]; then
exit 0
fi
+case "$SSH_KEYTYPES" in
+ *ssh-rsa*) userkeytype=rsa ;;
+ *) userkeytype=ed25519 ;;
+esac
+
SERIAL=$$
# 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 rsa -f $OBJ/cert_user_key || \
+${SSHKEYGEN} -q -N '' -t ${userkeytype} -f $OBJ/cert_user_key || \
fatal "ssh-keygen of cert_user_key failed"
${SSHKEYGEN} -q -s $OBJ/user_ca_key -I "Joanne User" \
-z $$ -n ${USER},mekmitasdigoat $OBJ/cert_user_key || \
@@ -30,11 +35,12 @@ CA_FP=`${SSHKEYGEN} -lf $OBJ/user_ca_key.pub | awk '{ print $2 }'`
# Establish a AuthorizedPrincipalsCommand in /var/run where it will have
# acceptable directory permissions.
-PRINCIPALS_COMMAND="/var/run/principals_command_${LOGNAME}"
+PRINCIPALS_COMMAND="/var/run/principals_command_${LOGNAME}.$$"
+trap "$SUDO rm -f ${PRINCIPALS_COMMAND}" 0
cat << _EOF | $SUDO sh -c "cat > '$PRINCIPALS_COMMAND'"
#!/bin/sh
test "x\$1" != "x${LOGNAME}" && exit 1
-test "x\$2" != "xssh-rsa-cert-v01@openssh.com" && exit 1
+test "x\$2" != "xssh-${userkeytype}-cert-v01@openssh.com" && exit 1
test "x\$3" != "xssh-ed25519" && exit 1
test "x\$4" != "xJoanne User" && exit 1
test "x\$5" != "x${SERIAL}" && exit 1
@@ -57,7 +63,7 @@ fi
if [ -x $PRINCIPALS_COMMAND ]; then
# Test explicitly-specified principals
- for privsep in yes no ; do
+ for privsep in yes ; do
_prefix="privsep $privsep"
# Setup for AuthorizedPrincipalsCommand
diff --git a/crypto/openssh/regress/proxy-connect.sh b/crypto/openssh/regress/proxy-connect.sh
index 39bbd3c96e76..8847fe0c664b 100644
--- a/crypto/openssh/regress/proxy-connect.sh
+++ b/crypto/openssh/regress/proxy-connect.sh
@@ -1,9 +1,15 @@
-# $OpenBSD: proxy-connect.sh,v 1.11 2017/09/26 22:39:25 dtucker Exp $
+# $OpenBSD: proxy-connect.sh,v 1.12 2020/01/23 11:19:12 dtucker Exp $
# Placed in the Public Domain.
tid="proxy connect"
-for c in no yes; do
+if [ "`${SSH} -Q compression`" = "none" ]; then
+ comp="no"
+else
+ comp="no yes"
+fi
+
+for c in $comp; do
verbose "plain username comp=$c"
opts="-oCompression=$c -F $OBJ/ssh_proxy"
SSH_CONNECTION=`${SSH} $opts 999.999.999.999 'echo $SSH_CONNECTION'`
diff --git a/crypto/openssh/regress/putty-ciphers.sh b/crypto/openssh/regress/putty-ciphers.sh
index 191a2bda8d35..708c288d73ae 100755..100644
--- a/crypto/openssh/regress/putty-ciphers.sh
+++ b/crypto/openssh/regress/putty-ciphers.sh
@@ -1,4 +1,4 @@
-# $OpenBSD: putty-ciphers.sh,v 1.6 2017/05/08 01:52:49 djm Exp $
+# $OpenBSD: putty-ciphers.sh,v 1.7 2020/01/23 03:35:07 dtucker Exp $
# Placed in the Public Domain.
tid="putty ciphers"
@@ -8,7 +8,7 @@ if test "x$REGRESS_INTEROP_PUTTY" != "xyes" ; then
exit 0
fi
-for c in aes 3des aes128-ctr aes192-ctr aes256-ctr ; do
+for c in aes 3des aes128-ctr aes192-ctr aes256-ctr chacha20 ; do
verbose "$tid: cipher $c"
cp ${OBJ}/.putty/sessions/localhost_proxy \
${OBJ}/.putty/sessions/cipher_$c
diff --git a/crypto/openssh/regress/putty-kex.sh b/crypto/openssh/regress/putty-kex.sh
index 71c09701b2c8..686d0e1af2e5 100755..100644
--- a/crypto/openssh/regress/putty-kex.sh
+++ b/crypto/openssh/regress/putty-kex.sh
@@ -1,4 +1,4 @@
-# $OpenBSD: putty-kex.sh,v 1.4 2016/11/25 03:02:01 dtucker Exp $
+# $OpenBSD: putty-kex.sh,v 1.5 2020/01/23 03:24:38 dtucker Exp $
# Placed in the Public Domain.
tid="putty KEX"
@@ -8,7 +8,7 @@ if test "x$REGRESS_INTEROP_PUTTY" != "xyes" ; then
exit 0
fi
-for k in dh-gex-sha1 dh-group1-sha1 dh-group14-sha1 ; do
+for k in dh-gex-sha1 dh-group1-sha1 dh-group14-sha1 ecdh ; do
verbose "$tid: kex $k"
cp ${OBJ}/.putty/sessions/localhost_proxy \
${OBJ}/.putty/sessions/kex_$k
diff --git a/crypto/openssh/regress/putty-transfer.sh b/crypto/openssh/regress/putty-transfer.sh
index 4928d4533f6b..14b41022f8a6 100755..100644
--- a/crypto/openssh/regress/putty-transfer.sh
+++ b/crypto/openssh/regress/putty-transfer.sh
@@ -1,4 +1,4 @@
-# $OpenBSD: putty-transfer.sh,v 1.6 2018/02/23 03:03:00 djm Exp $
+# $OpenBSD: putty-transfer.sh,v 1.7 2020/01/23 11:19:12 dtucker Exp $
# Placed in the Public Domain.
tid="putty transfer data"
@@ -8,7 +8,13 @@ if test "x$REGRESS_INTEROP_PUTTY" != "xyes" ; then
exit 0
fi
-for c in 0 1 ; do
+if [ "`${SSH} -Q compression`" = "none" ]; then
+ comp="0"
+else
+ comp="0 1"
+fi
+
+for c in $comp; do
verbose "$tid: compression $c"
rm -f ${COPY}
cp ${OBJ}/.putty/sessions/localhost_proxy \
diff --git a/crypto/openssh/regress/reconfigure.sh b/crypto/openssh/regress/reconfigure.sh
index dd15eddb2a24..d5b4e9808fcc 100644
--- a/crypto/openssh/regress/reconfigure.sh
+++ b/crypto/openssh/regress/reconfigure.sh
@@ -1,4 +1,4 @@
-# $OpenBSD: reconfigure.sh,v 1.6 2017/04/30 23:34:55 djm Exp $
+# $OpenBSD: reconfigure.sh,v 1.9 2021/06/10 09:46:28 dtucker Exp $
# Placed in the Public Domain.
tid="simple connect after reconfigure"
@@ -41,3 +41,25 @@ ${SSH} -F $OBJ/ssh_config somehost true
if [ $? -ne 0 ]; then
fail "ssh connect with failed after reconfigure"
fi
+
+trace "reconfigure with active clients"
+${SSH} -F $OBJ/ssh_config somehost sleep 10 # authenticated client
+${NC} -d 127.0.0.1 $PORT >/dev/null & # unauthenticated client
+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 with active clients"
+${SSH} -F $OBJ/ssh_config somehost true
+if [ $? -ne 0 ]; then
+ fail "ssh connect with failed after reconfigure"
+fi
diff --git a/crypto/openssh/regress/reexec.sh b/crypto/openssh/regress/reexec.sh
index 2192456cd85e..8966ba524e60 100644
--- a/crypto/openssh/regress/reexec.sh
+++ b/crypto/openssh/regress/reexec.sh
@@ -9,7 +9,10 @@ SSHD_COPY=$OBJ/sshd
# Start a sshd and then delete it
start_sshd_copy ()
{
- cp $SSHD_ORIG $SSHD_COPY
+ # NB. prefer ln to cp here. On some OSX 19.4 configurations,
+ # djm has seen failure after fork() when the executable image
+ # has been removed from the filesystem.
+ ln $SSHD_ORIG $SSHD_COPY || cp $SSHD_ORIG $SSHD_COPY
SSHD=$SSHD_COPY
start_sshd
SSHD=$SSHD_ORIG
diff --git a/crypto/openssh/regress/rekey.sh b/crypto/openssh/regress/rekey.sh
index fd6a02cc7a62..61723cd86608 100644
--- a/crypto/openssh/regress/rekey.sh
+++ b/crypto/openssh/regress/rekey.sh
@@ -1,4 +1,4 @@
-# $OpenBSD: rekey.sh,v 1.18 2018/04/10 00:14:10 djm Exp $
+# $OpenBSD: rekey.sh,v 1.19 2021/07/19 05:08:54 dtucker Exp $
# Placed in the Public Domain.
tid="rekey"
@@ -71,7 +71,7 @@ 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"
+ $OBJ/ssh_proxy somehost "cat >${COPY};sleep $s;sleep 10"
if [ $? -ne 0 ]; then
fail "ssh failed"
fi
@@ -88,7 +88,7 @@ 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"
+ $OBJ/ssh_proxy somehost "sleep $s;sleep 10"
if [ $? -ne 0 ]; then
fail "ssh failed"
fi
@@ -124,7 +124,7 @@ for s in 5 10; do
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"
+ ${SSH} -oCompression=no -F $OBJ/ssh_proxy somehost "sleep $s;sleep 10"
if [ $? -ne 0 ]; then
fail "ssh failed"
fi
diff --git a/crypto/openssh/regress/scp-ssh-wrapper.sh b/crypto/openssh/regress/scp-ssh-wrapper.sh
index 59f1ff63e6da..7fb21f424ebd 100644
--- a/crypto/openssh/regress/scp-ssh-wrapper.sh
+++ b/crypto/openssh/regress/scp-ssh-wrapper.sh
@@ -1,5 +1,5 @@
#!/bin/sh
-# $OpenBSD: scp-ssh-wrapper.sh,v 1.3 2014/01/26 10:49:17 djm Exp $
+# $OpenBSD: scp-ssh-wrapper.sh,v 1.4 2019/07/19 03:45:44 djm Exp $
# Placed in the Public Domain.
printname () {
@@ -51,6 +51,18 @@ badserver_4)
echo "C755 2 file"
echo "X"
;;
+badserver_5)
+ echo "D0555 0 "
+ echo "X"
+ ;;
+badserver_6)
+ echo "D0555 0 ."
+ echo "X"
+ ;;
+badserver_7)
+ echo "C0755 2 extrafile"
+ echo "X"
+ ;;
*)
set -- $arg
shift
diff --git a/crypto/openssh/regress/scp-uri.sh b/crypto/openssh/regress/scp-uri.sh
index c03d8bbe0761..20ac3c89ec26 100644
--- a/crypto/openssh/regress/scp-uri.sh
+++ b/crypto/openssh/regress/scp-uri.sh
@@ -1,4 +1,4 @@
-# $OpenBSD: scp-uri.sh,v 1.2 2017/12/11 11:41:56 dtucker Exp $
+# $OpenBSD: scp-uri.sh,v 1.4 2021/08/10 03:35:45 djm Exp $
# Placed in the Public Domain.
tid="scp-uri"
@@ -12,7 +12,6 @@ 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() {
@@ -24,47 +23,55 @@ scpclean() {
cp $OBJ/ssh_config $OBJ/ssh_config.orig
egrep -v '^ +(Port|User) +.*$' $OBJ/ssh_config.orig > $OBJ/ssh_config
-verbose "$tid: simple copy local file to remote file"
-scpclean
-$SCP $scpopts ${DATA} "scp://${USER}@somehost:${PORT}/${COPY}" || fail "copy failed"
-cmp ${DATA} ${COPY} || fail "corrupted copy"
+for mode in scp sftp ; do
+ tag="$tid: $mode mode"
+ if test $mode = scp ; then
+ scpopts="-O -q -S ${OBJ}/scp-ssh-wrapper.scp"
+ else
+ scpopts="-s -D ${SFTPSERVER}"
+ fi
+ verbose "$tag: simple copy local file to remote file"
+ scpclean
+ $SCP $scpopts ${DATA} "scp://${USER}@somehost:${PORT}/${COPY}" || fail "copy failed"
+ cmp ${DATA} ${COPY} || fail "corrupted copy"
-verbose "$tid: simple copy remote file to local file"
-scpclean
-$SCP $scpopts "scp://${USER}@somehost:${PORT}/${DATA}" ${COPY} || fail "copy failed"
-cmp ${DATA} ${COPY} || fail "corrupted copy"
+ verbose "$tag: simple copy remote file to local file"
+ scpclean
+ $SCP $scpopts "scp://${USER}@somehost:${PORT}/${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} "scp://${USER}@somehost:${PORT}/${DIR}" || fail "copy failed"
-cmp ${COPY} ${DIR}/copy || fail "corrupted copy"
+ verbose "$tag: simple copy local file to remote dir"
+ scpclean
+ cp ${DATA} ${COPY}
+ $SCP $scpopts ${COPY} "scp://${USER}@somehost:${PORT}/${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 "scp://${USER}@somehost:${PORT}/${COPY}" ${DIR} || fail "copy failed"
-cmp ${COPY} ${DIR}/copy || fail "corrupted copy"
+ verbose "$tag: simple copy remote file to local dir"
+ scpclean
+ cp ${DATA} ${COPY}
+ $SCP $scpopts "scp://${USER}@somehost:${PORT}/${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} "scp://${USER}@somehost:${PORT}/${DIR2}" || fail "copy failed"
-for i in $(cd ${DIR} && echo *); do
- cmp ${DIR}/$i ${DIR2}/$i || fail "corrupted copy"
-done
+ verbose "$tag: recursive local dir to remote dir"
+ scpclean
+ rm -rf ${DIR2}
+ cp ${DATA} ${DIR}/copy
+ $SCP $scpopts -r ${DIR} "scp://${USER}@somehost:${PORT}/${DIR2}" || fail "copy failed"
+ for i in $(cd ${DIR} && echo *); do
+ cmp ${DIR}/$i ${DIR2}/$i || fail "corrupted copy"
+ done
-verbose "$tid: recursive remote dir to local dir"
-scpclean
-rm -rf ${DIR2}
-cp ${DATA} ${DIR}/copy
-$SCP $scpopts -r "scp://${USER}@somehost:${PORT}/${DIR}" ${DIR2} || fail "copy failed"
-for i in $(cd ${DIR} && echo *); do
- cmp ${DIR}/$i ${DIR2}/$i || fail "corrupted copy"
-done
+ verbose "$tag: recursive remote dir to local dir"
+ scpclean
+ rm -rf ${DIR2}
+ cp ${DATA} ${DIR}/copy
+ $SCP $scpopts -r "scp://${USER}@somehost:${PORT}/${DIR}" ${DIR2} || fail "copy failed"
+ for i in $(cd ${DIR} && echo *); do
+ cmp ${DIR}/$i ${DIR2}/$i || fail "corrupted copy"
+ done
-# TODO: scp -3
+ # TODO: scp -3
+done
scpclean
rm -f ${OBJ}/scp-ssh-wrapper.exe
diff --git a/crypto/openssh/regress/scp.sh b/crypto/openssh/regress/scp.sh
index 57cc77066064..358a8df66b1c 100644
--- a/crypto/openssh/regress/scp.sh
+++ b/crypto/openssh/regress/scp.sh
@@ -1,4 +1,4 @@
-# $OpenBSD: scp.sh,v 1.10 2014/01/26 10:49:17 djm Exp $
+# $OpenBSD: scp.sh,v 1.13 2021/08/10 03:35:45 djm Exp $
# Placed in the Public Domain.
tid="scp"
@@ -19,108 +19,125 @@ 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}
+ chmod 755 ${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"
+for mode in scp sftp ; do
+ tag="$tid: $mode mode"
+ if test $mode = scp ; then
+ scpopts="-O -q -S ${OBJ}/scp-ssh-wrapper.scp"
+ else
+ scpopts="-s -D ${SFTPSERVER}"
+ fi
+ 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 local dir"
-scpclean
-cp ${DATA} ${COPY}
-$SCP $scpopts ${COPY} ${DIR} || fail "copy failed"
-cmp ${COPY} ${DIR}/copy || fail "corrupted copy"
+ verbose "$tag: 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 dir"
-scpclean
-cp ${DATA} ${COPY}
-$SCP $scpopts somehost:${COPY} ${DIR} || fail "copy failed"
-cmp ${COPY} ${DIR}/copy || fail "corrupted copy"
+ verbose "$tag: simple copy remote file to local file"
+ scpclean
+ $SCP $scpopts somehost:${DATA} ${COPY} || fail "copy failed"
+ cmp ${DATA} ${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 "$tag: 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: 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 "$tag: 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: 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 "$tag: 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: shell metacharacters"
-scpclean
-(cd ${DIR} && \
-touch '`touch metachartest`' && \
-$SCP $scpopts *metachar* ${DIR2} 2>/dev/null; \
-[ ! -f metachartest ] ) || fail "shell metacharacters"
+ verbose "$tag: 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"
-if [ ! -z "$SUDO" ]; then
- verbose "$tid: skipped file after scp -p with failed chown+utimes"
+ verbose "$tag: recursive local dir to local dir"
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
+ rm -rf ${DIR2}
+ cp ${DATA} ${DIR}/copy
+ $SCP $scpopts -r ${DIR} ${DIR2} || fail "copy failed"
+ diff ${DIFFOPT} ${DIR} ${DIR2} || fail "corrupted copy"
-for i in 0 1 2 3 4; do
- verbose "$tid: disallow bad server #$i"
- SCPTESTMODE=badserver_$i
- export DIR SCPTESTMODE
+ verbose "$tag: recursive remote dir to local dir"
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"
+ rm -rf ${DIR2}
+ cp ${DATA} ${DIR}/copy
+ $SCP $scpopts -r somehost:${DIR} ${DIR2} || fail "copy failed"
+ diff ${DIFFOPT} ${DIR} ${DIR2} || fail "corrupted copy"
+ verbose "$tag: shell metacharacters"
scpclean
- $SCP -r $scpopts somehost:${DATA} ${DIR2} >/dev/null 2>/dev/null
- [ -d ${DIR}/dotpathdir ] && fail "allows dir creation outside of subdir"
+ (cd ${DIR} && \
+ touch '`touch metachartest`' && \
+ $SCP $scpopts *metachar* ${DIR2} 2>/dev/null; \
+ [ ! -f metachartest ] ) || fail "shell metacharacters"
+
+ if [ ! -z "$SUDO" ]; then
+ verbose "$tag: 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 5 6 7; do
+ verbose "$tag: 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"
+
+ scpclean
+ $SCP -pr $scpopts somehost:${DATA} ${DIR2} >/dev/null 2>/dev/null
+ [ ! -w ${DIR2} ] && fail "allows target root attribute change"
+
+ scpclean
+ $SCP $scpopts somehost:${DATA} ${DIR2} >/dev/null 2>/dev/null
+ [ -e ${DIR2}/extrafile ] && fail "allows unauth object creation"
+ rm -f ${DIR2}/extrafile
+ done
+
+ verbose "$tag: detect non-directory target"
+ scpclean
+ echo a > ${COPY}
+ echo b > ${COPY2}
+ $SCP $scpopts ${DATA} ${COPY} ${COPY2}
+ cmp ${COPY} ${COPY2} >/dev/null && fail "corrupt target"
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/openssh/regress/scp3.sh b/crypto/openssh/regress/scp3.sh
new file mode 100644
index 000000000000..f71b1567755b
--- /dev/null
+++ b/crypto/openssh/regress/scp3.sh
@@ -0,0 +1,60 @@
+# $OpenBSD: scp3.sh,v 1.3 2021/08/10 03:35:45 djm Exp $
+# Placed in the Public Domain.
+
+tid="scp3"
+
+#set -x
+
+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
+export SCP # used in scp-ssh-wrapper.scp
+
+scpclean() {
+ rm -rf ${COPY} ${COPY2} ${DIR} ${DIR2}
+ mkdir ${DIR} ${DIR2}
+ chmod 755 ${DIR} ${DIR2}
+}
+
+for mode in scp sftp ; do
+ scpopts="-F${OBJ}/ssh_proxy -S ${SSH} -q"
+ tag="$tid: $mode mode"
+ if test $mode = scp ; then
+ scpopts="$scpopts -O"
+ else
+ scpopts="-s -D ${SFTPSERVER}"
+ fi
+
+ verbose "$tag: simple copy remote file to remote file"
+ scpclean
+ $SCP $scpopts -3 hostA:${DATA} hostB:${COPY} || fail "copy failed"
+ cmp ${DATA} ${COPY} || fail "corrupted copy"
+
+ verbose "$tag: simple copy remote file to remote dir"
+ scpclean
+ cp ${DATA} ${COPY}
+ $SCP $scpopts -3 hostA:${COPY} hostB:${DIR} || fail "copy failed"
+ cmp ${COPY} ${DIR}/copy || fail "corrupted copy"
+
+ verbose "$tag: recursive remote dir to remote dir"
+ scpclean
+ rm -rf ${DIR2}
+ cp ${DATA} ${DIR}/copy
+ $SCP $scpopts -3r hostA:${DIR} hostB:${DIR2} || fail "copy failed"
+ diff -r ${DIR} ${DIR2} || fail "corrupted copy"
+ diff -r ${DIR2} ${DIR} || fail "corrupted copy"
+
+ verbose "$tag: detect non-directory target"
+ scpclean
+ echo a > ${COPY}
+ echo b > ${COPY2}
+ $SCP $scpopts -3 hostA:${DATA} hostA:${COPY} hostB:${COPY2}
+ cmp ${COPY} ${COPY2} >/dev/null && fail "corrupt target"
+done
+
+scpclean
+rm -f ${OBJ}/scp-ssh-wrapper.exe
diff --git a/crypto/openssh/regress/servcfginclude.sh b/crypto/openssh/regress/servcfginclude.sh
new file mode 100644
index 000000000000..518a703d100e
--- /dev/null
+++ b/crypto/openssh/regress/servcfginclude.sh
@@ -0,0 +1,188 @@
+# Placed in the Public Domain.
+
+tid="server config include"
+
+cat > $OBJ/sshd_config.i << _EOF
+HostKey $OBJ/host.ssh-ed25519
+Match host a
+ Banner /aa
+
+Match host b
+ Banner /bb
+ Include $OBJ/sshd_config.i.* # comment
+
+Match host c
+ Include $OBJ/sshd_config.i.* # comment
+ Banner /cc
+
+Match host m
+ Include $OBJ/sshd_config.i.*
+
+Match Host d
+ Banner /dd # comment
+
+Match Host e
+ Banner /ee
+ Include $OBJ/sshd_config.i.*
+
+Match Host f
+ Include $OBJ/sshd_config.i.*
+ Banner /ff
+
+Match Host n
+ Include $OBJ/sshd_config.i.*
+_EOF
+
+cat > $OBJ/sshd_config.i.0 << _EOF
+Match host xxxxxx
+_EOF
+
+cat > $OBJ/sshd_config.i.1 << _EOF
+Match host a
+ Banner /aaa
+
+Match host b
+ Banner /bbb
+
+Match host c
+ Banner /ccc
+
+Match Host d
+ Banner /ddd
+
+Match Host e
+ Banner /eee
+
+Match Host f
+ Banner /fff
+_EOF
+
+cat > $OBJ/sshd_config.i.2 << _EOF
+Match host a
+ Banner /aaaa
+
+Match host b
+ Banner /bbbb
+
+Match host c # comment
+ Banner /cccc
+
+Match Host d
+ Banner /dddd
+
+Match Host e
+ Banner /eeee
+
+Match Host f
+ Banner /ffff
+
+Match all
+ Banner /xxxx
+_EOF
+
+trial() {
+ _host="$1"
+ _exp="$2"
+ _desc="$3"
+ test -z "$_desc" && _desc="test match"
+ trace "$_desc host=$_host expect=$_exp"
+ ${SUDO} ${REAL_SSHD} -f $OBJ/sshd_config.i -T \
+ -C "host=$_host,user=test,addr=127.0.0.1" > $OBJ/sshd_config.out ||
+ fatal "ssh config parse failed: $_desc host=$_host expect=$_exp"
+ _got=`grep -i '^banner ' $OBJ/sshd_config.out | awk '{print $2}'`
+ if test "x$_exp" != "x$_got" ; then
+ fail "$desc_ host $_host include fail: expected $_exp got $_got"
+ fi
+}
+
+trial a /aa
+trial b /bb
+trial c /ccc
+trial d /dd
+trial e /ee
+trial f /fff
+trial m /xxxx
+trial n /xxxx
+trial x none
+
+# Prepare an included config with an error.
+
+cat > $OBJ/sshd_config.i.3 << _EOF
+Banner xxxx
+ Junk
+_EOF
+
+trace "disallow invalid config host=a"
+${SUDO} ${REAL_SSHD} -f $OBJ/sshd_config.i \
+ -C "host=a,user=test,addr=127.0.0.1" 2>/dev/null && \
+ fail "sshd include allowed invalid config"
+
+trace "disallow invalid config host=x"
+${SUDO} ${REAL_SSHD} -f $OBJ/sshd_config.i \
+ -C "host=x,user=test,addr=127.0.0.1" 2>/dev/null && \
+ fail "sshd include allowed invalid config"
+
+rm -f $OBJ/sshd_config.i.*
+
+# Ensure that a missing include is not fatal.
+cat > $OBJ/sshd_config.i << _EOF
+HostKey $OBJ/host.ssh-ed25519
+Include $OBJ/sshd_config.i.*
+Banner /aa
+_EOF
+
+trial a /aa "missing include non-fatal"
+
+# Ensure that Match/Host in an included config does not affect parent.
+cat > $OBJ/sshd_config.i.x << _EOF
+Match host x
+_EOF
+
+trial a /aa "included file does not affect match state"
+
+# Ensure the empty include directive is not accepted
+cat > $OBJ/sshd_config.i.x << _EOF
+Include
+_EOF
+
+trace "disallow invalid with no argument"
+${SUDO} ${REAL_SSHD} -f $OBJ/sshd_config.i.x -T \
+ -C "host=x,user=test,addr=127.0.0.1" 2>/dev/null && \
+ fail "sshd allowed Include with no argument"
+
+# Ensure the Include before any Match block works as expected (bug #3122)
+cat > $OBJ/sshd_config.i << _EOF
+Banner /xx
+HostKey $OBJ/host.ssh-ed25519
+Include $OBJ/sshd_config.i.2
+Match host a
+ Banner /aaaa
+_EOF
+cat > $OBJ/sshd_config.i.2 << _EOF
+Match host a
+ Banner /aa
+_EOF
+
+trace "Include before match blocks"
+trial a /aa "included file before match blocks is properly evaluated"
+
+# Port in included file is correctly interpretted (bug #3169)
+cat > $OBJ/sshd_config.i << _EOF
+Include $OBJ/sshd_config.i.2
+Port 7722
+_EOF
+cat > $OBJ/sshd_config.i.2 << _EOF
+HostKey $OBJ/host.ssh-ed25519
+_EOF
+
+trace "Port after included files"
+${SUDO} ${REAL_SSHD} -f $OBJ/sshd_config.i -T \
+ -C "host=x,user=test,addr=127.0.0.1" > $OBJ/sshd_config.out || \
+ fail "failed to parse Port after included files"
+_port=`grep -i '^port ' $OBJ/sshd_config.out | awk '{print $2}'`
+if test "x7722" != "x$_port" ; then
+ fail "The Port in included file was intertepretted wrongly. Expected 7722, got $_port"
+fi
+
+# cleanup
+rm -f $OBJ/sshd_config.i $OBJ/sshd_config.i.* $OBJ/sshd_config.out
diff --git a/crypto/openssh/regress/sftp-badcmds.sh b/crypto/openssh/regress/sftp-badcmds.sh
index 7f85c4f229ca..5b016d558b3f 100644
--- a/crypto/openssh/regress/sftp-badcmds.sh
+++ b/crypto/openssh/regress/sftp-badcmds.sh
@@ -1,4 +1,4 @@
-# $OpenBSD: sftp-badcmds.sh,v 1.6 2013/05/17 10:26:26 dtucker Exp $
+# $OpenBSD: sftp-badcmds.sh,v 1.7 2020/03/13 03:18:45 djm Exp $
# Placed in the Public Domain.
tid="sftp invalid commands"
@@ -58,7 +58,7 @@ 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"
+cmp ${DATA2} ${COPY} || fail "put succeeded when it should have failed"
rm -rf ${COPY} ${COPY}.1 ${COPY}.2 ${COPY}.dd
diff --git a/crypto/openssh/regress/sftp-chroot.sh b/crypto/openssh/regress/sftp-chroot.sh
index ba5bd1efb30e..5acc4d2de4a6 100755..100644
--- a/crypto/openssh/regress/sftp-chroot.sh
+++ b/crypto/openssh/regress/sftp-chroot.sh
@@ -1,11 +1,12 @@
-# $OpenBSD: sftp-chroot.sh,v 1.6 2018/02/09 03:42:57 dtucker Exp $
+# $OpenBSD: sftp-chroot.sh,v 1.7 2018/11/22 08:48:32 dtucker Exp $
# Placed in the Public Domain.
tid="sftp in chroot"
CHROOT=/var/run
-FILENAME=testdata_${USER}
+FILENAME=testdata_${USER}.$$
PRIVDATA=${CHROOT}/${FILENAME}
+trap "${SUDO} rm -f ${PRIVDATA}" 0
if [ -z "$SUDO" -a ! -w /var/run ]; then
echo "need SUDO to create file in /var/run, test won't work without"
@@ -28,5 +29,3 @@ ${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/openssh/regress/sftp-cmds.sh b/crypto/openssh/regress/sftp-cmds.sh
index aad7fcac2325..1289c4089c6c 100644
--- a/crypto/openssh/regress/sftp-cmds.sh
+++ b/crypto/openssh/regress/sftp-cmds.sh
@@ -77,7 +77,6 @@ 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"
@@ -85,7 +84,6 @@ 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"
@@ -136,13 +134,11 @@ 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"
diff --git a/crypto/openssh/regress/sftp-perm.sh b/crypto/openssh/regress/sftp-perm.sh
index 304ca0ac5877..de96a14da8e8 100644
--- a/crypto/openssh/regress/sftp-perm.sh
+++ b/crypto/openssh/regress/sftp-perm.sh
@@ -1,4 +1,4 @@
-# $OpenBSD: sftp-perm.sh,v 1.2 2013/10/17 22:00:18 djm Exp $
+# $OpenBSD: sftp-perm.sh,v 1.3 2021/03/31 21:59:26 djm Exp $
# Placed in the Public Domain.
tid="sftp permissions"
@@ -220,13 +220,15 @@ perm_test \
"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"
+# Can't readily test this because the client falls back to traditional rename.
+# XXX maybe there is a behaviorial difference we can test for?
+#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" \
diff --git a/crypto/openssh/regress/ssh2putty.sh b/crypto/openssh/regress/ssh2putty.sh
index bcf83afe9e9e..9b08310391ca 100755
--- a/crypto/openssh/regress/ssh2putty.sh
+++ b/crypto/openssh/regress/ssh2putty.sh
@@ -1,5 +1,5 @@
#!/bin/sh
-# $OpenBSD: ssh2putty.sh,v 1.3 2015/05/08 07:26:13 djm Exp $
+# $OpenBSD: ssh2putty.sh,v 1.9 2021/07/25 12:13:03 dtucker Exp $
if test "x$1" = "x" -o "x$2" = "x" -o "x$3" = "x" ; then
echo "Usage: ssh2putty hostname port ssh-private-key"
@@ -10,6 +10,8 @@ HOST=$1
PORT=$2
KEYFILE=$3
+OPENSSL_BIN="${OPENSSL_BIN:-openssl}"
+
# XXX - support DSA keys too
if grep "BEGIN RSA PRIVATE KEY" $KEYFILE >/dev/null 2>&1 ; then
:
@@ -19,13 +21,13 @@ else
fi
public_exponent=`
- openssl rsa -noout -text -in $KEYFILE | grep ^publicExponent |
+ $OPENSSL_BIN rsa -noout -text -in $KEYFILE | grep ^publicExponent |
sed 's/.*(//;s/).*//'
`
test $? -ne 0 && exit 1
modulus=`
- openssl rsa -noout -modulus -in $KEYFILE | grep ^Modulus= |
+ $OPENSSL_BIN rsa -noout -modulus -in $KEYFILE | grep ^Modulus= |
sed 's/^Modulus=/0x/' | tr A-Z a-z
`
test $? -ne 0 && exit 1
diff --git a/crypto/openssh/regress/sshcfgparse.sh b/crypto/openssh/regress/sshcfgparse.sh
index e0ce568d71c4..504853d32db5 100644
--- a/crypto/openssh/regress/sshcfgparse.sh
+++ b/crypto/openssh/regress/sshcfgparse.sh
@@ -1,8 +1,15 @@
-# $OpenBSD: sshcfgparse.sh,v 1.4 2018/07/04 13:51:12 djm Exp $
+# $OpenBSD: sshcfgparse.sh,v 1.9 2021/06/08 07:05:27 dtucker Exp $
# Placed in the Public Domain.
tid="ssh config parse"
+dsa=0
+for t in $SSH_KEYTYPES; do
+ case "$t" in
+ ssh-dss) dsa=1 ;;
+ esac
+done
+
expect_result_present() {
_str="$1" ; shift
for _expect in "$@" ; do
@@ -25,7 +32,7 @@ expect_result_absent() {
verbose "reparse minimal config"
(${SSH} -G -F $OBJ/ssh_config somehost >$OBJ/ssh_config.1 &&
${SSH} -G -F $OBJ/ssh_config.1 somehost >$OBJ/ssh_config.2 &&
- diff $OBJ/ssh_config.1 $OBJ/ssh_config.2) || fail "reparse minimal config"
+ diff $OBJ/ssh_config.1 $OBJ/ssh_config.2) || fail "failed to reparse minimal"
verbose "ssh -W opts"
f=`${SSH} -GF $OBJ/ssh_config host | awk '/exitonforwardfailure/{print $2}'`
@@ -55,35 +62,58 @@ test "$f" = "bar" || fail "user first match -l, expected 'bar' got '$f'"
f=`${SSH} -GF $OBJ/ssh_config baz@host -o user=foo -l bar baz@host | awk '/^user /{print $2}'`
test "$f" = "baz" || fail "user first match user@host, expected 'baz' got '$f'"
-verbose "pubkeyacceptedkeytypes"
+verbose "pubkeyacceptedalgorithms"
# Default set
-f=`${SSH} -GF none host | awk '/^pubkeyacceptedkeytypes /{print $2}'`
+f=`${SSH} -GF none host | awk '/^pubkeyacceptedalgorithms /{print $2}'`
expect_result_present "$f" "ssh-ed25519" "ssh-ed25519-cert-v01.*"
expect_result_absent "$f" "ssh-dss"
# Explicit override
-f=`${SSH} -GF none -opubkeyacceptedkeytypes=ssh-ed25519 host | \
- awk '/^pubkeyacceptedkeytypes /{print $2}'`
+f=`${SSH} -GF none -opubkeyacceptedalgorithms=ssh-ed25519 host | \
+ awk '/^pubkeyacceptedalgorithms /{print $2}'`
expect_result_present "$f" "ssh-ed25519"
expect_result_absent "$f" "ssh-ed25519-cert-v01.*" "ssh-dss"
# Removal from default set
-f=`${SSH} -GF none -opubkeyacceptedkeytypes=-ssh-ed25519-cert* host | \
- awk '/^pubkeyacceptedkeytypes /{print $2}'`
+f=`${SSH} -GF none -opubkeyacceptedalgorithms=-ssh-ed25519-cert* host | \
+ awk '/^pubkeyacceptedalgorithms /{print $2}'`
expect_result_present "$f" "ssh-ed25519"
expect_result_absent "$f" "ssh-ed25519-cert-v01.*" "ssh-dss"
-f=`${SSH} -GF none -opubkeyacceptedkeytypes=-ssh-ed25519 host | \
- awk '/^pubkeyacceptedkeytypes /{print $2}'`
+f=`${SSH} -GF none -opubkeyacceptedalgorithms=-ssh-ed25519 host | \
+ awk '/^pubkeyacceptedalgorithms /{print $2}'`
expect_result_present "$f" "ssh-ed25519-cert-v01.*"
expect_result_absent "$f" "ssh-ed25519" "ssh-dss"
# Append to default set.
-# XXX this will break for !WITH_OPENSSL
-f=`${SSH} -GF none -opubkeyacceptedkeytypes=+ssh-dss-cert* host | \
- awk '/^pubkeyacceptedkeytypes /{print $2}'`
-expect_result_present "$f" "ssh-ed25519" "ssh-dss-cert-v01.*"
-expect_result_absent "$f" "ssh-dss"
-f=`${SSH} -GF none -opubkeyacceptedkeytypes=+ssh-dss host | \
- awk '/^pubkeyacceptedkeytypes /{print $2}'`
-expect_result_present "$f" "ssh-ed25519" "ssh-ed25519-cert-v01.*" "ssh-dss"
-expect_result_absent "$f" "ssh-dss-cert-v01.*"
+# This is not tested when built !WITH_OPENSSL
+if [ "$dsa" = "1" ]; then
+ f=`${SSH} -GF none -opubkeyacceptedalgorithms=+ssh-dss-cert* host | \
+ awk '/^pubkeyacceptedalgorithms /{print $2}'`
+ expect_result_present "$f" "ssh-ed25519" "ssh-dss-cert-v01.*"
+ expect_result_absent "$f" "ssh-dss"
+ f=`${SSH} -GF none -opubkeyacceptedalgorithms=+ssh-dss host | \
+ awk '/^pubkeyacceptedalgorithms /{print $2}'`
+ expect_result_present "$f" "ssh-ed25519" "ssh-ed25519-cert-v01.*" "ssh-dss"
+ expect_result_absent "$f" "ssh-dss-cert-v01.*"
+fi
+
+verbose "agentforwarding"
+f=`${SSH} -GF none host | awk '/^forwardagent /{print$2}'`
+expect_result_present "$f" "no"
+f=`${SSH} -GF none -oforwardagent=no host | awk '/^forwardagent /{print$2}'`
+expect_result_present "$f" "no"
+f=`${SSH} -GF none -oforwardagent=yes host | awk '/^forwardagent /{print$2}'`
+expect_result_present "$f" "yes"
+f=`${SSH} -GF none '-oforwardagent=SSH_AUTH_SOCK.forward' host | awk '/^forwardagent /{print$2}'`
+expect_result_present "$f" "SSH_AUTH_SOCK.forward"
+
+verbose "command line override"
+cat >$OBJ/ssh_config.0 <<EOD
+Host *
+ IPQoS af21 cs1
+ TunnelDevice 1:2
+EOD
+f=`${SSH} -GF $OBJ/ssh_config.0 -oipqos=cs1 host | awk '/^ipqos /{print$2}'`
+expect_result_present "$f" "cs1"
+f=`${SSH} -GF $OBJ/ssh_config.0 -otunneldevice=3:4 host | awk '/^tunneldevice /{print$2}'`
+expect_result_present "$f" "3:4"
# cleanup
rm -f $OBJ/ssh_config.[012]
diff --git a/crypto/openssh/regress/sshfp-connect.sh b/crypto/openssh/regress/sshfp-connect.sh
new file mode 100644
index 000000000000..06e91cdbb851
--- /dev/null
+++ b/crypto/openssh/regress/sshfp-connect.sh
@@ -0,0 +1,66 @@
+# $OpenBSD: sshfp-connect.sh,v 1.2 2021/07/19 08:48:33 dtucker Exp $
+# Placed in the Public Domain.
+
+# This test requires external setup and thus is skipped unless
+# TEST_SSH_SSHFP_DOMAIN is set. It requires:
+# 1) A DNSSEC-enabled domain, which TEST_SSH_SSHFP_DOMAIN points to.
+# 2) A DNSSEC-validating resolver such as unwind(8).
+# 3) The following SSHFP records with fingerprints from rsa_openssh.pub
+# in that domain that are expected to succeed:
+# sshtest: valid sha1 and sha256 fingerprints.
+# sshtest-sha{1,256}, : valid fingerprints for that type only.
+# and the following records that are expected to fail:
+# sshtest-bad: invalid sha1 fingerprint and good sha256 fingerprint
+# sshtest-sha{1,256}-bad: invalid fingerprints for that type only.
+#
+# sshtest IN SSHFP 1 1 99C79CC09F5F81069CC017CDF9552CFC94B3B929
+# sshtest IN SSHFP 1 2 E30D6B9EB7A4DE495324E4D5870B8220577993EA6AF417E8E4A4F1C5 BF01A9B6
+# sshtest-sha1 IN SSHFP 1 1 99C79CC09F5F81069CC017CDF9552CFC94B3B929
+# sshtest-sha256 IN SSHFP 1 2 E30D6B9EB7A4DE495324E4D5870B8220577993EA6AF417E8E4A4F1C5 BF01A9B6
+# sshtest-bad IN SSHFP 1 2 E30D6B9EB7A4DE495324E4D5870B8220577993EA6AF417E8E4A4F1C5 BF01A9B6
+# sshtest-bad IN SSHFP 1 1 99C79CC09F5F81069CC017CDF9552CFC94B3B928
+# sshtest-sha1-bad IN SSHFP 1 1 99D79CC09F5F81069CC017CDF9552CFC94B3B929
+# sshtest-sha256-bad IN SSHFP 1 2 E30D6B9EB7A4DE495324E4D5870B8220577993EA6AF417E8E4A4F1C5 BF01A9B5
+
+tid="sshfp connect"
+
+if [ ! -z "${TEST_SSH_SSHFP_DOMAIN}" ] && \
+ $SSH -Q key-plain | grep ssh-rsa >/dev/null; then
+
+ # Set RSA host key to match fingerprints above.
+ mv $OBJ/sshd_proxy $OBJ/sshd_proxy.orig
+ $SUDO cp $SRC/rsa_openssh.prv $OBJ/host.ssh-rsa
+ $SUDO chmod 600 $OBJ/host.ssh-rsa
+ sed -e "s|$OBJ/ssh-rsa|$OBJ/host.ssh-rsa|" \
+ $OBJ/sshd_proxy.orig > $OBJ/sshd_proxy
+
+ # Zero out known hosts and key aliases to force use of SSHFP records.
+ > $OBJ/known_hosts
+ mv $OBJ/ssh_proxy $OBJ/ssh_proxy.orig
+ sed -e "/HostKeyAlias.*localhost-with-alias/d" \
+ -e "/Hostname.*127.0.0.1/d" \
+ $OBJ/ssh_proxy.orig > $OBJ/ssh_proxy
+
+ for n in sshtest sshtest-sha1 sshtest-sha256; do
+ trace "sshfp connect $n good fingerprint"
+ host="${n}.dtucker.net"
+ opts="-F $OBJ/ssh_proxy -o VerifyHostKeyDNS=yes "
+ opts="$opts -o HostKeyAlgorithms=ssh-rsa"
+ host="${n}.${TEST_SSH_SSHFP_DOMAIN}"
+ SSH_CONNECTION=`${SSH} $opts $host 'echo $SSH_CONNECTION'`
+ if [ $? -ne 0 ]; then
+ fail "ssh sshfp connect failed"
+ fi
+ if [ "$SSH_CONNECTION" != "UNKNOWN 65535 UNKNOWN 65535" ]; then
+ fail "bad SSH_CONNECTION: $SSH_CONNECTION"
+ fi
+
+ trace "sshfp connect $n bad fingerprint"
+ host="${n}-bad.${TEST_SSH_SSHFP_DOMAIN}"
+ if ${SSH} $opts ${host} true; then
+ fail "sshfp-connect succeeded with bad SSHFP record"
+ fi
+ done
+else
+ echo SKIPPED: TEST_SSH_SSHFP_DOMAIN not set.
+fi
diff --git a/crypto/openssh/regress/sshsig.sh b/crypto/openssh/regress/sshsig.sh
new file mode 100644
index 000000000000..fc300a8dc3ed
--- /dev/null
+++ b/crypto/openssh/regress/sshsig.sh
@@ -0,0 +1,236 @@
+# $OpenBSD: sshsig.sh,v 1.7 2021/08/11 08:55:04 djm Exp $
+# Placed in the Public Domain.
+
+tid="sshsig"
+
+DATA2=$OBJ/${DATANAME}.2
+cat ${DATA} ${DATA} > ${DATA2}
+
+rm -f $OBJ/sshsig-*.sig $OBJ/wrong-key* $OBJ/sigca-key*
+
+sig_namespace="test-$$"
+sig_principal="user-$$@example.com"
+
+# Make a "wrong key"
+${SSHKEYGEN} -q -t ed25519 -f $OBJ/wrong-key \
+ -C "wrong trousers, Grommit" -N '' \
+ || fatal "couldn't generate key"
+WRONG=$OBJ/wrong-key.pub
+
+# Make a CA key.
+${SSHKEYGEN} -q -t ed25519 -f $OBJ/sigca-key -C "CA" -N '' \
+ || fatal "couldn't generate key"
+CA_PRIV=$OBJ/sigca-key
+CA_PUB=$OBJ/sigca-key.pub
+
+trace "start agent"
+eval `${SSHAGENT} ${EXTRA_AGENT_ARGS} -s` > /dev/null
+r=$?
+if [ $r -ne 0 ]; then
+ fatal "could not start ssh-agent: exit code $r"
+fi
+
+SIGNKEYS="$SSH_KEYTYPES"
+verbose "$tid: make certificates"
+for t in $SSH_KEYTYPES ; do
+ ${SSHKEYGEN} -q -s $CA_PRIV -z $$ \
+ -I "regress signature key for $USER" \
+ -n $sig_principal $OBJ/${t} || \
+ fatal "couldn't sign ${t}"
+ SIGNKEYS="$SIGNKEYS ${t}-cert.pub"
+done
+
+for t in $SIGNKEYS; do
+ verbose "$tid: check signature for $t"
+ keybase=`basename $t .pub`
+ privkey=${OBJ}/`basename $t -cert.pub`
+ sigfile=${OBJ}/sshsig-${keybase}.sig
+ sigfile_agent=${OBJ}/sshsig-agent-${keybase}.sig
+ pubkey=${OBJ}/${keybase}.pub
+
+ ${SSHKEYGEN} -vvv -Y sign -f ${OBJ}/$t -n $sig_namespace \
+ < $DATA > $sigfile 2>/dev/null || fail "sign using $t failed"
+
+ (printf "$sig_principal " ; cat $pubkey) > $OBJ/allowed_signers
+ ${SSHKEYGEN} -vvv -Y verify -s $sigfile -n $sig_namespace \
+ -I $sig_principal -f $OBJ/allowed_signers \
+ < $DATA >/dev/null 2>&1 || \
+ fail "failed signature for $t key"
+
+ (printf "$sig_principal namespaces=\"$sig_namespace,whatever\" ";
+ cat $pubkey) > $OBJ/allowed_signers
+ ${SSHKEYGEN} -vvv -Y verify -s $sigfile -n $sig_namespace \
+ -I $sig_principal -f $OBJ/allowed_signers \
+ < $DATA >/dev/null 2>&1 || \
+ fail "failed signature for $t key w/ limited namespace"
+
+ (printf "$sig_principal namespaces=\"$sig_namespace,whatever\" ";
+ cat $pubkey) > $OBJ/allowed_signers
+ ${SSHKEYGEN} -q -Y verify -s $sigfile -n $sig_namespace \
+ -I $sig_principal -f $OBJ/allowed_signers \
+ -O print-pubkey \
+ < $DATA | cut -d' ' -f1-2 > ${OBJ}/${keybase}-fromsig.pub || \
+ fail "failed signature for $t key w/ print-pubkey"
+ cut -d' ' -f1-2 ${OBJ}/${keybase}.pub > ${OBJ}/${keybase}-strip.pub
+ diff -r ${OBJ}/${keybase}-strip.pub ${OBJ}/${keybase}-fromsig.pub || \
+ fail "print-pubkey differs from signature key"
+
+ # Invalid option
+ (printf "$sig_principal octopus " ; cat $pubkey) > $OBJ/allowed_signers
+ ${SSHKEYGEN} -vvv -Y verify -s $sigfile -n $sig_namespace \
+ -I $sig_principal -f $OBJ/allowed_signers \
+ < $DATA >/dev/null 2>&1 && \
+ fail "accepted signature for $t key with bad signers option"
+
+ # Wrong key trusted.
+ (printf "$sig_principal " ; cat $WRONG) > $OBJ/allowed_signers
+ ${SSHKEYGEN} -vvv -Y verify -s $sigfile -n $sig_namespace \
+ -I $sig_principal -f $OBJ/allowed_signers \
+ < $DATA >/dev/null 2>&1 && \
+ fail "accepted signature for $t key with wrong key trusted"
+
+ # incorrect data
+ (printf "$sig_principal " ; cat $pubkey) > $OBJ/allowed_signers
+ ${SSHKEYGEN} -vvv -Y verify -s $sigfile -n $sig_namespace \
+ -I $sig_principal -f $OBJ/allowed_signers \
+ < $DATA2 >/dev/null 2>&1 && \
+ fail "passed signature for wrong data with $t key"
+
+ # wrong principal in signers
+ (printf "josef.k@example.com " ; cat $pubkey) > $OBJ/allowed_signers
+ ${SSHKEYGEN} -vvv -Y verify -s $sigfile -n $sig_namespace \
+ -I $sig_principal -f $OBJ/allowed_signers \
+ < $DATA >/dev/null 2>&1 && \
+ fail "accepted signature for $t key with wrong principal"
+
+ # wrong namespace
+ (printf "$sig_principal " ; cat $pubkey) > $OBJ/allowed_signers
+ ${SSHKEYGEN} -vvv -Y verify -s $sigfile -n COWS_COWS_COWS \
+ -I $sig_principal -f $OBJ/allowed_signers \
+ < $DATA >/dev/null 2>&1 && \
+ fail "accepted signature for $t key with wrong namespace"
+
+ # namespace excluded by option
+ (printf "$sig_principal namespaces=\"whatever\" " ;
+ cat $pubkey) > $OBJ/allowed_signers
+ ${SSHKEYGEN} -vvv -Y verify -s $sigfile -n $sig_namespace \
+ -I $sig_principal -f $OBJ/allowed_signers \
+ < $DATA >/dev/null 2>&1 && \
+ fail "accepted signature for $t key with excluded namespace"
+
+ ( printf "$sig_principal " ;
+ printf "valid-after=\"19800101\",valid-before=\"19900101\" " ;
+ cat $pubkey) > $OBJ/allowed_signers
+
+ # key lifespan valid
+ ${SSHKEYGEN} -vvv -Y verify -s $sigfile -n $sig_namespace \
+ -I $sig_principal -f $OBJ/allowed_signers \
+ -Overify-time=19850101 \
+ < $DATA >/dev/null 2>&1 || \
+ fail "failed signature for $t key with valid expiry interval"
+ # key not yet valid
+ ${SSHKEYGEN} -vvv -Y verify -s $sigfile -n $sig_namespace \
+ -I $sig_principal -f $OBJ/allowed_signers \
+ -Overify-time=19790101 \
+ < $DATA >/dev/null 2>&1 && \
+ fail "failed signature for $t not-yet-valid key"
+ # key expired
+ ${SSHKEYGEN} -vvv -Y verify -s $sigfile -n $sig_namespace \
+ -I $sig_principal -f $OBJ/allowed_signers \
+ -Overify-time=19910101 \
+ < $DATA >/dev/null 2>&1 && \
+ fail "failed signature for $t with expired key"
+ # NB. assumes we're not running this test in the 1980s
+ ${SSHKEYGEN} -vvv -Y verify -s $sigfile -n $sig_namespace \
+ -I $sig_principal -f $OBJ/allowed_signers \
+ < $DATA >/dev/null 2>&1 && \
+ fail "failed signature for $t with expired key"
+
+ # public key in revoked keys file
+ cat $pubkey > $OBJ/revoked_keys
+ (printf "$sig_principal namespaces=\"whatever\" " ;
+ cat $pubkey) > $OBJ/allowed_signers
+ ${SSHKEYGEN} -vvv -Y verify -s $sigfile -n $sig_namespace \
+ -I $sig_principal -f $OBJ/allowed_signers \
+ -r $OBJ/revoked_keys \
+ < $DATA >/dev/null 2>&1 && \
+ fail "accepted signature for $t key, but key is in revoked_keys"
+
+ # public key not revoked, but others are present in revoked_keysfile
+ cat $WRONG > $OBJ/revoked_keys
+ (printf "$sig_principal " ; cat $pubkey) > $OBJ/allowed_signers
+ ${SSHKEYGEN} -vvv -Y verify -s $sigfile -n $sig_namespace \
+ -I $sig_principal -f $OBJ/allowed_signers \
+ -r $OBJ/revoked_keys \
+ < $DATA >/dev/null 2>&1 || \
+ fail "couldn't verify signature for $t key, but key not in revoked_keys"
+
+ # check-novalidate with valid data
+ ${SSHKEYGEN} -vvv -Y check-novalidate -s $sigfile -n $sig_namespace \
+ < $DATA >/dev/null 2>&1 || \
+ fail "failed to check valid signature for $t key"
+
+ # check-novalidate with invalid data
+ ${SSHKEYGEN} -vvv -Y check-novalidate -s $sigfile -n $sig_namespace \
+ < $DATA2 >/dev/null 2>&1 && \
+ fail "succeeded checking signature for $t key with invalid data"
+
+ # Check signing keys using ssh-agent.
+ ${SSHADD} -D >/dev/null 2>&1 # Remove all previously-loaded keys.
+ ${SSHADD} ${privkey} > /dev/null 2>&1 || fail "ssh-add failed"
+
+ # Move private key to ensure agent key is used
+ mv ${privkey} ${privkey}.tmp
+
+ ${SSHKEYGEN} -vvv -Y sign -f $pubkey -n $sig_namespace \
+ < $DATA > $sigfile_agent 2>/dev/null || \
+ fail "ssh-agent based sign using $pubkey failed"
+ ${SSHKEYGEN} -vvv -Y check-novalidate -s $sigfile_agent \
+ -n $sig_namespace < $DATA >/dev/null 2>&1 || \
+ fail "failed to check valid signature for $t key"
+
+ # Move private key back
+ mv ${privkey}.tmp ${privkey}
+
+ # Remaining tests are for certificates only.
+ case "$keybase" in
+ *-cert) ;;
+ *) continue ;;
+ esac
+
+
+ # correct CA key
+ (printf "$sig_principal cert-authority " ;
+ cat $CA_PUB) > $OBJ/allowed_signers
+ ${SSHKEYGEN} -vvv -Y verify -s $sigfile -n $sig_namespace \
+ -I $sig_principal -f $OBJ/allowed_signers \
+ < $DATA >/dev/null 2>&1 || \
+ fail "failed signature for $t cert"
+
+ # signing key listed as cert-authority
+ (printf "$sig_principal cert-authority " ;
+ cat $pubkey) > $OBJ/allowed_signers
+ ${SSHKEYGEN} -vvv -Y verify -s $sigfile -n $sig_namespace \
+ -I $sig_principal -f $OBJ/allowed_signers \
+ < $DATA >/dev/null 2>&1 && \
+ fail "accepted signature with $t key listed as CA"
+
+ # CA key not flagged cert-authority
+ (printf "$sig_principal " ; cat $CA_PUB) > $OBJ/allowed_signers
+ ${SSHKEYGEN} -vvv -Y verify -s $sigfile -n $sig_namespace \
+ -I $sig_principal -f $OBJ/allowed_signers \
+ < $DATA >/dev/null 2>&1 && \
+ fail "accepted signature for $t cert with CA not marked"
+
+ # mismatch between cert principal and file
+ (printf "josef.k@example.com cert-authority " ;
+ cat $CA_PUB) > $OBJ/allowed_signers
+ ${SSHKEYGEN} -vvv -Y verify -s $sigfile -n $sig_namespace \
+ -I $sig_principal -f $OBJ/allowed_signers \
+ < $DATA >/dev/null 2>&1 && \
+ fail "accepted signature for $t cert with wrong principal"
+done
+
+trace "kill agent"
+${SSHAGENT} -k > /dev/null
+
diff --git a/crypto/openssh/regress/test-exec.sh b/crypto/openssh/regress/test-exec.sh
index 40d46e3cd4ca..db6d6161aa2b 100644
--- a/crypto/openssh/regress/test-exec.sh
+++ b/crypto/openssh/regress/test-exec.sh
@@ -1,25 +1,11 @@
-# $OpenBSD: test-exec.sh,v 1.64 2018/08/10 01:35:49 dtucker Exp $
+# $OpenBSD: test-exec.sh,v 1.86 2021/08/08 08:27:28 dtucker 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 [ ! -x "$TEST_SSH_ELAPSED_TIMES" ]; then
+ STARTTIME=`date '+%s'`
+fi
if [ ! -z "$TEST_SSH_PORT" ]; then
PORT="$TEST_SSH_PORT"
@@ -27,16 +13,6 @@ 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'
@@ -63,6 +39,46 @@ else
fi
unset SSH_AUTH_SOCK
+# Portable-specific settings.
+
+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
+if test -z "$LOGNAME"; then
+ LOGNAME="${USER}"
+ export LOGNAME
+fi
+
+# 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*)
+ os=cygwin
+ ;;
+esac
+
+# If configure tells us to use a different egrep, create a wrapper function
+# to call it. This means we don't need to change all the tests that depend
+# on a good implementation.
+if test "x${EGREP}" != "x"; then
+ egrep ()
+{
+ ${EGREP} "$@"
+}
+fi
+
SRC=`dirname ${SCRIPT}`
# defaults
@@ -84,6 +100,10 @@ PLINK=plink
PUTTYGEN=puttygen
CONCH=conch
+# Tools used by multiple tests
+NC=$OBJ/netcat
+OPENSSL_BIN="${OPENSSL_BIN:-openssl}"
+
if [ "x$TEST_SSH_SSH" != "x" ]; then
SSH="${TEST_SSH_SSH}"
fi
@@ -132,6 +152,15 @@ if [ "x$TEST_SSH_CONCH" != "x" ]; then
*) CONCH=`which ${TEST_SSH_CONCH} 2>/dev/null` ;;
esac
fi
+if [ "x$TEST_SSH_PKCS11_HELPER" != "x" ]; then
+ SSH_PKCS11_HELPER="${TEST_SSH_PKCS11_HELPER}"
+fi
+if [ "x$TEST_SSH_SK_HELPER" != "x" ]; then
+ SSH_SK_HELPER="${TEST_SSH_SK_HELPER}"
+fi
+if [ "x$TEST_SSH_OPENSSL" != "x" ]; then
+ OPENSSL_BIN="${TEST_SSH_OPENSSL}"
+fi
# Path to sshd must be absolute for rexec
case "$SSHD" in
@@ -156,13 +185,22 @@ SFTPSERVER_BIN=${SFTPSERVER}
SCP_BIN=${SCP}
if [ "x$USE_VALGRIND" != "x" ]; then
- mkdir -p $OBJ/valgrind-out
+ rm -rf $OBJ/valgrind-out $OBJ/valgrind-vgdb
+ mkdir -p $OBJ/valgrind-out $OBJ/valgrind-vgdb
+ # When using sudo ensure low-priv tests can write pipes and logs.
+ if [ "x$SUDO" != "x" ]; then
+ chmod 777 $OBJ/valgrind-out $OBJ/valgrind-vgdb
+ fi
VG_TEST=`basename $SCRIPT .sh`
# Some tests are difficult to fix.
case "$VG_TEST" in
- connect-privsep|reexec)
+ reexec)
VG_SKIP=1 ;;
+ sftp-chroot)
+ if [ "x${SUDO}" != "x" ]; then
+ VG_SKIP=1
+ fi ;;
esac
if [ x"$VG_SKIP" = "x" ]; then
@@ -175,6 +213,7 @@ if [ "x$USE_VALGRIND" != "x" ]; then
VG_OPTS="--track-origins=yes $VG_LEAK"
VG_OPTS="$VG_OPTS --trace-children=yes"
VG_OPTS="$VG_OPTS --trace-children-skip=${VG_IGNORE}"
+ VG_OPTS="$VG_OPTS --vgdb-prefix=$OBJ/valgrind-vgdb/"
VG_PATH="valgrind"
if [ "x$VALGRIND_PATH" != "x" ]; then
VG_PATH="$VALGRIND_PATH"
@@ -217,13 +256,19 @@ fi
>$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.
+# because sftp and scp don't handle spaces in arguments. scp and sftp like
+# to use -q so we remove those to preserve our debug logging. In the rare
+# instance where -q is desirable -qq is equivalent and is not removed.
SSHLOGWRAP=$OBJ/ssh-log-wrapper.sh
-echo "#!/bin/sh" > $SSHLOGWRAP
-echo "exec ${SSH} -E${TEST_SSH_LOGFILE} "'"$@"' >>$SSHLOGWRAP
+cat >$SSHLOGWRAP <<EOD
+#!/bin/sh
+for i in "\$@";do shift;case "\$i" in -q):;; *) set -- "\$@" "\$i";;esac;done
+exec ${SSH} -E${TEST_SSH_LOGFILE} "\$@"
+EOD
chmod a+rx $OBJ/ssh-log-wrapper.sh
REAL_SSH="$SSH"
+REAL_SSHD="$SSHD"
SSH="$SSHLOGWRAP"
# Some test data. We make a copy because some tests will overwrite it.
@@ -246,6 +291,7 @@ increase_datafile_size()
# these should be used in tests
export SSH SSHD SSHAGENT SSHADD SSHKEYGEN SSHKEYSCAN SFTP SFTPSERVER SCP
+export SSH_PKCS11_HELPER SSH_SK_HELPER
#echo $SSH $SSHD $SSHAGENT $SSHADD $SSHKEYGEN $SSHKEYSCAN $SFTP $SFTPSERVER $SCP
# Portable specific functions
@@ -288,10 +334,27 @@ md5 () {
cksum
elif have_prog sum; then
sum
+ elif [ -x ${OPENSSL_BIN} ]; then
+ ${OPENSSL_BIN} md5
else
wc -c
fi
}
+
+# Some platforms don't have hostname at all, but on others uname -n doesn't
+# provide the fully qualified name we need, so in the former case we create
+# our own hostname function.
+if ! have_prog hostname; then
+ hostname() {
+ uname -n
+ }
+fi
+
+make_tmpdir ()
+{
+ SSH_REGRESS_TMP="$($OBJ/mkdtemp openssh-XXXXXXXX)" || \
+ fatal "failed to create temporary directory"
+}
# End of portable specific functions
stop_sshd ()
@@ -325,12 +388,6 @@ stop_sshd ()
fi
}
-make_tmpdir ()
-{
- SSH_REGRESS_TMP="$($OBJ/mkdtemp openssh-XXXXXXXX)" || \
- fatal "failed to create temporary directory"
-}
-
# helper
cleanup ()
{
@@ -345,6 +402,11 @@ cleanup ()
rm -rf "$SSH_REGRESS_TMP"
fi
stop_sshd
+ if [ ! -z "$TEST_SSH_ELAPSED_TIMES" ]; then
+ now=`date '+%s'`
+ elapsed=$(($now - $STARTTIME))
+ echo elapsed $elapsed `basename $SCRIPT .sh`
+ fi
}
start_debug_log ()
@@ -380,12 +442,6 @@ verbose ()
fi
}
-warn ()
-{
- echo "WARNING: $@" >>$TEST_SSH_LOGFILE
- echo "WARNING: $@"
-}
-
fail ()
{
save_debug_log "FAIL: $@"
@@ -430,7 +486,37 @@ EOF
# but if you aren't careful with permissions then the unit tests could
# be abused to locally escalate privileges.
if [ ! -z "$TEST_SSH_UNSAFE_PERMISSIONS" ]; then
- echo "StrictModes no" >> $OBJ/sshd_config
+ echo " StrictModes no" >> $OBJ/sshd_config
+else
+ # check and warn if excessive permissions are likely to cause failures.
+ unsafe=""
+ dir="${OBJ}"
+ while test ${dir} != "/"; do
+ if test -d "${dir}" && ! test -h "${dir}"; then
+ perms=`ls -ld ${dir}`
+ case "${perms}" in
+ ?????w????*|????????w?*) unsafe="${unsafe} ${dir}" ;;
+ esac
+ fi
+ dir=`dirname ${dir}`
+ done
+ if ! test -z "${unsafe}"; then
+ cat <<EOD
+
+WARNING: Unsafe (group or world writable) directory permissions found:
+${unsafe}
+
+These could be abused to locally escalate privileges. If you are
+sure that this is not a risk (eg there are no other users), you can
+bypass this check by setting TEST_SSH_UNSAFE_PERMISSIONS=1
+
+EOD
+ fi
+fi
+
+if [ ! -z "$TEST_SSH_MODULI_FILE" ]; then
+ trace "adding modulifile='$TEST_SSH_MODULI_FILE' to sshd_config"
+ echo " ModuliFile '$TEST_SSH_MODULI_FILE'" >> $OBJ/sshd_config
fi
if [ ! -z "$TEST_SSH_SSHD_CONFOPTS" ]; then
@@ -469,29 +555,60 @@ fi
rm -f $OBJ/known_hosts $OBJ/authorized_keys_$USER
-SSH_KEYTYPES="rsa ed25519"
+SSH_SK_PROVIDER=
+if ! config_defined ENABLE_SK; then
+ trace skipping sk-dummy
+elif [ -f "${SRC}/misc/sk-dummy/obj/sk-dummy.so" ] ; then
+ SSH_SK_PROVIDER="${SRC}/misc/sk-dummy/obj/sk-dummy.so"
+elif [ -f "${SRC}/misc/sk-dummy/sk-dummy.so" ] ; then
+ SSH_SK_PROVIDER="${SRC}/misc/sk-dummy/sk-dummy.so"
+fi
+export SSH_SK_PROVIDER
+
+if ! test -z "$SSH_SK_PROVIDER"; then
+ EXTRA_AGENT_ARGS='-P/*' # XXX want realpath(1)...
+ echo "SecurityKeyProvider $SSH_SK_PROVIDER" >> $OBJ/ssh_config
+ echo "SecurityKeyProvider $SSH_SK_PROVIDER" >> $OBJ/sshd_config
+ echo "SecurityKeyProvider $SSH_SK_PROVIDER" >> $OBJ/sshd_proxy
+fi
+export EXTRA_AGENT_ARGS
+
+maybe_filter_sk() {
+ if test -z "$SSH_SK_PROVIDER" ; then
+ grep -v ^sk
+ else
+ cat
+ fi
+}
+
+SSH_KEYTYPES=`$SSH -Q key-plain | maybe_filter_sk`
+SSH_HOSTKEY_TYPES=`$SSH -Q key-plain | maybe_filter_sk`
-trace "generate keys"
for t in ${SSH_KEYTYPES}; do
# generate user key
if [ ! -f $OBJ/$t ] || [ ${SSHKEYGEN_BIN} -nt $OBJ/$t ]; then
+ trace "generating key type $t"
rm -f $OBJ/$t
${SSHKEYGEN} -q -N '' -t $t -f $OBJ/$t ||\
fail "ssh-keygen for $t failed"
+ else
+ trace "using cached key type $t"
fi
+ # setup authorized keys
+ cat $OBJ/$t.pub >> $OBJ/authorized_keys_$USER
+ echo IdentityFile $OBJ/$t >> $OBJ/ssh_config
+done
+
+for t in ${SSH_HOSTKEY_TYPES}; do
# 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
+ (umask 077; $SUDO cp $OBJ/$t $OBJ/host.$t)
echo HostKey $OBJ/host.$t >> $OBJ/sshd_config
# don't use SUDO for proxy connect
@@ -505,10 +622,11 @@ 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
+# If PuTTY is present, new enough and we are running a PuTTY test, prepare
+# keys and configuration.
REGRESS_INTEROP_PUTTY=no
-if test -x "$PUTTYGEN" -a -x "$PLINK" ; then
+if test -x "$PUTTYGEN" -a -x "$PLINK" &&
+ "$PUTTYGEN" --help 2>&1 | grep -- --new-passphrase >/dev/null; then
REGRESS_INTEROP_PUTTY=yes
fi
case "$SCRIPT" in
@@ -521,23 +639,23 @@ if test "$REGRESS_INTEROP_PUTTY" = "yes" ; then
# Add a PuTTY key to authorized_keys
rm -f ${OBJ}/putty.rsa2
- if ! puttygen -t rsa -o ${OBJ}/putty.rsa2 \
+ if ! "$PUTTYGEN" -t rsa -o ${OBJ}/putty.rsa2 \
--random-device=/dev/urandom \
--new-passphrase /dev/null < /dev/null > /dev/null; then
- echo "Your installed version of PuTTY is too old to support --new-passphrase; trying without (may require manual interaction) ..." >&2
- puttygen -t rsa -o ${OBJ}/putty.rsa2 < /dev/null > /dev/null
+ echo "Your installed version of PuTTY is too old to support --new-passphrase, skipping test" >&2
+ exit 1
fi
- puttygen -O public-openssh ${OBJ}/putty.rsa2 \
+ "$PUTTYGEN" -O public-openssh ${OBJ}/putty.rsa2 \
>> $OBJ/authorized_keys_$USER
# Convert rsa2 host key to PuTTY format
- cp $OBJ/rsa $OBJ/rsa_oldfmt
- ${SSHKEYGEN} -p -N '' -m PEM -f $OBJ/rsa_oldfmt >/dev/null
- ${SRC}/ssh2putty.sh 127.0.0.1 $PORT $OBJ/rsa_oldfmt > \
+ cp $OBJ/ssh-rsa $OBJ/ssh-rsa_oldfmt
+ ${SSHKEYGEN} -p -N '' -m PEM -f $OBJ/ssh-rsa_oldfmt >/dev/null
+ ${SRC}/ssh2putty.sh 127.0.0.1 $PORT $OBJ/ssh-rsa_oldfmt > \
${OBJ}/.putty/sshhostkeys
- ${SRC}/ssh2putty.sh 127.0.0.1 22 $OBJ/rsa_oldfmt >> \
+ ${SRC}/ssh2putty.sh 127.0.0.1 22 $OBJ/ssh-rsa_oldfmt >> \
${OBJ}/.putty/sshhostkeys
- rm -f $OBJ/rsa_oldfmt
+ rm -f $OBJ/ssh-rsa_oldfmt
# Setup proxied session
mkdir -p ${OBJ}/.putty/sessions
@@ -551,14 +669,12 @@ if test "$REGRESS_INTEROP_PUTTY" = "yes" ; then
PUTTYDIR=${OBJ}/.putty
export PUTTYDIR
-
- 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
+ echo proxycommand ${SUDO} env SSH_SK_HELPER=\"$SSH_SK_HELPER\" sh ${SRC}/sshd-log-wrapper.sh ${TEST_SSHD_LOGFILE} ${SSHD} -i -f $OBJ/sshd_proxy
) > $OBJ/ssh_proxy
# check proxy config
@@ -568,7 +684,8 @@ 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
+ $SUDO env SSH_SK_HELPER="$SSH_SK_HELPER" \
+ ${SSHD} -f $OBJ/sshd_config "$@" -E$TEST_SSHD_LOGFILE
trace "wait for sshd"
i=0;
@@ -585,6 +702,31 @@ start_sshd ()
# kill sshd
cleanup
+
+if [ "x$USE_VALGRIND" != "x" ]; then
+ # wait for any running process to complete
+ wait; sleep 1
+ VG_RESULTS=$(find $OBJ/valgrind-out -type f -print)
+ VG_RESULT_COUNT=0
+ VG_FAIL_COUNT=0
+ for i in $VG_RESULTS; do
+ if grep "ERROR SUMMARY" $i >/dev/null; then
+ VG_RESULT_COUNT=$(($VG_RESULT_COUNT + 1))
+ if ! grep "ERROR SUMMARY: 0 errors" $i >/dev/null; then
+ VG_FAIL_COUNT=$(($VG_FAIL_COUNT + 1))
+ RESULT=1
+ verbose valgrind failure $i
+ cat $i
+ fi
+ fi
+ done
+ if [ x"$VG_SKIP" != "x" ]; then
+ verbose valgrind skipped
+ else
+ verbose valgrind results $VG_RESULT_COUNT failures $VG_FAIL_COUNT
+ fi
+fi
+
if [ $RESULT -eq 0 ]; then
verbose ok $tid
else
diff --git a/crypto/openssh/regress/unittests/Makefile b/crypto/openssh/regress/unittests/Makefile
index e464b085adc8..4d26b74770e2 100644
--- a/crypto/openssh/regress/unittests/Makefile
+++ b/crypto/openssh/regress/unittests/Makefile
@@ -1,7 +1,7 @@
-# $OpenBSD: Makefile,v 1.10 2018/03/03 03:16:17 djm Exp $
+# $OpenBSD: Makefile,v 1.12 2020/06/19 04:34:21 djm Exp $
REGRESS_FAIL_EARLY?= yes
SUBDIR= test_helper sshbuf sshkey bitmap kex hostkeys utf8 match conversion
-SUBDIR+=authopt
+SUBDIR+=authopt misc sshsig
.include <bsd.subdir.mk>
diff --git a/crypto/openssh/regress/unittests/Makefile.inc b/crypto/openssh/regress/unittests/Makefile.inc
index b509f4452500..370224aa5e36 100644
--- a/crypto/openssh/regress/unittests/Makefile.inc
+++ b/crypto/openssh/regress/unittests/Makefile.inc
@@ -1,8 +1,25 @@
-# $OpenBSD: Makefile.inc,v 1.12 2017/12/21 00:41:22 djm Exp $
+# $OpenBSD: Makefile.inc,v 1.14 2019/11/25 10:32:35 djm Exp $
+
+REGRESS_FAIL_EARLY?= yes
.include <bsd.own.mk>
.include <bsd.obj.mk>
+# User-settable options
+UNITTEST_FAST?= no # Skip slow tests (e.g. less intensive fuzzing).
+UNITTEST_SLOW?= no # Include slower tests (e.g. more intensive fuzzing).
+UNITTEST_VERBOSE?= no # Verbose test output (inc. per-test names).
+
+MALLOC_OPTIONS?= CFGJRSUX
+TEST_ENV?= MALLOC_OPTIONS=${MALLOC_OPTIONS}
+
+# XXX detect from ssh binary?
+OPENSSL?= yes
+
+.if (${OPENSSL:L} == "yes")
+CFLAGS+= -DWITH_OPENSSL
+.endif
+
# enable warnings
WARNINGS=Yes
@@ -49,5 +66,24 @@ DPADD+=${.CURDIR}/../test_helper/libtest_helper.a
.PATH: ${.CURDIR}/${SSHREL}
+LDADD+= -lutil
+DPADD+= ${LIBUTIL}
+
+.if (${OPENSSL:L} == "yes")
LDADD+= -lcrypto
DPADD+= ${LIBCRYPTO}
+.endif
+
+LDADD+= -lfido2 -lcbor -lusbhid
+DPADD+= ${LIBFIDO2} ${LIBCBOR} ${LIBUSBHID}
+
+UNITTEST_ARGS?=
+
+.if (${UNITTEST_VERBOSE:L} != "no")
+UNITTEST_ARGS+= -v
+.endif
+.if (${UNITTEST_FAST:L} != "no")
+UNITTEST_ARGS+= -f
+.elif (${UNITTEST_SLOW:L} != "no")
+UNITTEST_ARGS+= -F
+.endif
diff --git a/crypto/openssh/regress/unittests/authopt/tests.c b/crypto/openssh/regress/unittests/authopt/tests.c
index 0e8aacb91699..9873c09c6545 100644
--- a/crypto/openssh/regress/unittests/authopt/tests.c
+++ b/crypto/openssh/regress/unittests/authopt/tests.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: tests.c,v 1.1 2018/03/03 03:16:17 djm Exp $ */
+/* $OpenBSD: tests.c,v 1.2 2021/07/24 01:54:23 djm Exp $ */
/*
* Regress test for keys options functions.
@@ -6,14 +6,18 @@
* Placed in the public domain
*/
+#include "includes.h"
+
#include <sys/types.h>
#include <sys/param.h>
#include <stdio.h>
+#ifdef HAVE_STDINT_H
#include <stdint.h>
+#endif
#include <stdlib.h>
#include <string.h>
-#include "test_helper.h"
+#include "../test_helper/test_helper.h"
#include "sshkey.h"
#include "authfile.h"
@@ -268,6 +272,8 @@ test_authkeys_parse(void)
} while (0)
ARRAY_TEST("environment", "environment=\"foo=1\",environment=\"bar=2\"",
env, nenv, "foo=1,bar=2");
+ ARRAY_TEST("environment", "environment=\"foo=1\",environment=\"foo=2\"",
+ env, nenv, "foo=1");
ARRAY_TEST("permitopen", "permitopen=\"foo:123\",permitopen=\"bar:*\"",
permitopen, npermitopen, "foo:123,bar:*");
#undef ARRAY_TEST
diff --git a/crypto/openssh/regress/unittests/bitmap/tests.c b/crypto/openssh/regress/unittests/bitmap/tests.c
index 23025f90af82..f66a4ce46a56 100644
--- a/crypto/openssh/regress/unittests/bitmap/tests.c
+++ b/crypto/openssh/regress/unittests/bitmap/tests.c
@@ -16,7 +16,9 @@
#include <stdlib.h>
#include <string.h>
+#ifdef WITH_OPENSSL
#include <openssl/bn.h>
+#endif
#include "../test_helper/test_helper.h"
@@ -27,6 +29,7 @@
void
tests(void)
{
+#ifdef WITH_OPENSSL
struct bitmap *b;
BIGNUM *bn;
size_t len;
@@ -131,5 +134,6 @@ tests(void)
bitmap_free(b);
BN_free(bn);
TEST_DONE();
+#endif
}
diff --git a/crypto/openssh/regress/unittests/conversion/Makefile b/crypto/openssh/regress/unittests/conversion/Makefile
index 8b2a09cc39fe..5793c4934845 100644
--- a/crypto/openssh/regress/unittests/conversion/Makefile
+++ b/crypto/openssh/regress/unittests/conversion/Makefile
@@ -1,4 +1,4 @@
-# $OpenBSD: Makefile,v 1.2 2017/12/21 00:41:22 djm Exp $
+# $OpenBSD: Makefile,v 1.4 2021/01/09 12:24:30 dtucker Exp $
PROG=test_conversion
SRCS=tests.c
@@ -6,6 +6,7 @@ SRCS=tests.c
# From usr.bin/ssh
SRCS+=sshbuf-getput-basic.c sshbuf-getput-crypto.c sshbuf-misc.c sshbuf.c
SRCS+=atomicio.c misc.c xmalloc.c log.c uidswap.c cleanup.c fatal.c ssherr.c
+SRCS+=match.c addr.c addrmatch.c
REGRESS_TARGETS=run-regress-${PROG}
diff --git a/crypto/openssh/regress/unittests/conversion/tests.c b/crypto/openssh/regress/unittests/conversion/tests.c
index 6dd77ef42548..bbdc5f5a7cb1 100644
--- a/crypto/openssh/regress/unittests/conversion/tests.c
+++ b/crypto/openssh/regress/unittests/conversion/tests.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: tests.c,v 1.1 2017/03/14 01:20:29 dtucker Exp $ */
+/* $OpenBSD: tests.c,v 1.3 2021/01/18 11:43:34 dtucker Exp $ */
/*
* Regress test for conversions
*
@@ -26,26 +26,28 @@ tests(void)
char buf[1024];
TEST_START("conversion_convtime");
- ASSERT_LONG_EQ(convtime("0"), 0);
- ASSERT_LONG_EQ(convtime("1"), 1);
- ASSERT_LONG_EQ(convtime("1S"), 1);
+ ASSERT_INT_EQ(convtime("0"), 0);
+ ASSERT_INT_EQ(convtime("1"), 1);
+ ASSERT_INT_EQ(convtime("1S"), 1);
/* from the examples in the comment above the function */
- ASSERT_LONG_EQ(convtime("90m"), 5400);
- ASSERT_LONG_EQ(convtime("1h30m"), 5400);
- ASSERT_LONG_EQ(convtime("2d"), 172800);
- ASSERT_LONG_EQ(convtime("1w"), 604800);
+ ASSERT_INT_EQ(convtime("90m"), 5400);
+ ASSERT_INT_EQ(convtime("1h30m"), 5400);
+ ASSERT_INT_EQ(convtime("2d"), 172800);
+ ASSERT_INT_EQ(convtime("1w"), 604800);
/* negative time is not allowed */
- ASSERT_LONG_EQ(convtime("-7"), -1);
- ASSERT_LONG_EQ(convtime("-9d"), -1);
+ ASSERT_INT_EQ(convtime("-7"), -1);
+ ASSERT_INT_EQ(convtime("-9d"), -1);
/* overflow */
- snprintf(buf, sizeof buf, "%llu", (unsigned long long)LONG_MAX + 1);
- ASSERT_LONG_EQ(convtime(buf), -1);
+ snprintf(buf, sizeof buf, "%llu", (unsigned long long)INT_MAX);
+ ASSERT_INT_EQ(convtime(buf), INT_MAX);
+ snprintf(buf, sizeof buf, "%llu", (unsigned long long)INT_MAX + 1);
+ ASSERT_INT_EQ(convtime(buf), -1);
/* overflow with multiplier */
- snprintf(buf, sizeof buf, "%lluM", (unsigned long long)LONG_MAX/60 + 1);
- ASSERT_LONG_EQ(convtime(buf), -1);
- ASSERT_LONG_EQ(convtime("1000000000000000000000w"), -1);
+ snprintf(buf, sizeof buf, "%lluM", (unsigned long long)INT_MAX/60 + 1);
+ ASSERT_INT_EQ(convtime(buf), -1);
+ ASSERT_INT_EQ(convtime("1000000000000000000000w"), -1);
TEST_DONE();
}
diff --git a/crypto/openssh/regress/unittests/hostkeys/Makefile b/crypto/openssh/regress/unittests/hostkeys/Makefile
index 3368851225c5..9a53423eeac0 100644
--- a/crypto/openssh/regress/unittests/hostkeys/Makefile
+++ b/crypto/openssh/regress/unittests/hostkeys/Makefile
@@ -1,19 +1,21 @@
-# $OpenBSD: Makefile,v 1.4 2017/12/21 00:41:22 djm Exp $
+# $OpenBSD: Makefile,v 1.9 2021/01/09 12:24:30 dtucker Exp $
PROG=test_hostkeys
SRCS=tests.c test_iterate.c
# From usr.bin/ssh
SRCS+=sshbuf-getput-basic.c sshbuf-getput-crypto.c sshbuf-misc.c sshbuf.c
-SRCS+=atomicio.c sshkey.c authfile.c cipher.c log.c ssh-rsa.c ssh-dss.c
-SRCS+=ssh-ecdsa.c ssh-ed25519.c mac.c umac.c umac128.c hmac.c misc.c
+SRCS+=sshbuf-io.c atomicio.c sshkey.c authfile.c cipher.c log.c ssh-rsa.c
+SRCS+=ssh-dss.c ssh-ecdsa.c ssh-ed25519.c mac.c umac.c umac128.c hmac.c misc.c
SRCS+=ssherr.c uidswap.c cleanup.c xmalloc.c match.c krl.c fatal.c
-SRCS+=addrmatch.c bitmap.c hostfile.c
+SRCS+=addr.c addrmatch.c bitmap.c hostfile.c
SRCS+=ed25519.c hash.c ge25519.c fe25519.c sc25519.c verify.c
-SRCS+=cipher-chachapoly.c chacha.c poly1305.c
+SRCS+=cipher-chachapoly.c chacha.c poly1305.c ssh-ecdsa-sk.c ssh-sk.c
+SRCS+=ssh-ed25519-sk.c sk-usbhid.c
SRCS+=digest-openssl.c
#SRCS+=digest-libc.c
+SRCS+=utf8.c
REGRESS_TARGETS=run-regress-${PROG}
diff --git a/crypto/openssh/regress/unittests/hostkeys/mktestdata.sh b/crypto/openssh/regress/unittests/hostkeys/mktestdata.sh
index 5a46de990dca..5a46de990dca 100755..100644
--- a/crypto/openssh/regress/unittests/hostkeys/mktestdata.sh
+++ b/crypto/openssh/regress/unittests/hostkeys/mktestdata.sh
diff --git a/crypto/openssh/regress/unittests/hostkeys/test_iterate.c b/crypto/openssh/regress/unittests/hostkeys/test_iterate.c
index d6963bd2a30f..a5b17d7e4056 100644
--- a/crypto/openssh/regress/unittests/hostkeys/test_iterate.c
+++ b/crypto/openssh/regress/unittests/hostkeys/test_iterate.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: test_iterate.c,v 1.6 2018/07/16 03:09:59 djm Exp $ */
+/* $OpenBSD: test_iterate.c,v 1.7 2020/12/21 01:31:06 djm Exp $ */
/*
* Regress test for hostfile.h hostkeys_foreach()
*
@@ -57,7 +57,7 @@ check(struct hostkey_foreach_line *l, void *_ctx)
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;
+ int expected_keytype, skip = 0;
test_subtest_info("entry %zu/%zu, file line %ld",
ctx->i + 1, ctx->nexpected, l->linenum);
@@ -92,13 +92,23 @@ check(struct hostkey_foreach_line *l, void *_ctx)
#ifndef OPENSSL_HAS_ECC
if (expected->l.keytype == KEY_ECDSA ||
- expected->no_parse_keytype == KEY_ECDSA) {
+ expected->no_parse_keytype == KEY_ECDSA)
+ skip = 1;
+#endif /* OPENSSL_HAS_ECC */
+#ifndef WITH_OPENSSL
+ if (expected->l.keytype == KEY_DSA ||
+ expected->no_parse_keytype == KEY_DSA ||
+ expected->l.keytype == KEY_RSA ||
+ expected->no_parse_keytype == KEY_RSA ||
+ expected->l.keytype == KEY_ECDSA ||
+ expected->no_parse_keytype == KEY_ECDSA)
+ skip = 1;
+#endif /* WITH_OPENSSL */
+ if (skip) {
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);
@@ -145,7 +155,15 @@ prepare_expected(struct expected *expected, size_t n)
#ifndef OPENSSL_HAS_ECC
if (expected[i].l.keytype == KEY_ECDSA)
continue;
-#endif
+#endif /* OPENSSL_HAS_ECC */
+#ifndef WITH_OPENSSL
+ switch (expected[i].l.keytype) {
+ case KEY_RSA:
+ case KEY_DSA:
+ case KEY_ECDSA:
+ continue;
+ }
+#endif /* WITH_OPENSSL */
ASSERT_INT_EQ(sshkey_load_public(
test_data_file(expected[i].key_file), &expected[i].l.key,
NULL), 0);
@@ -176,6 +194,7 @@ struct expected expected_full[] = {
KEY_UNSPEC, /* key type */
NULL, /* deserialised key */
NULL, /* comment */
+ 0, /* note */
} },
{ "dsa_1.pub" , -1, -1, 0, HKF_MATCH_HOST, 0, 0, -1, {
NULL,
@@ -189,6 +208,7 @@ struct expected expected_full[] = {
KEY_DSA,
NULL, /* filled at runtime */
"DSA #1",
+ 0,
} },
{ "ecdsa_1.pub" , -1, -1, 0, HKF_MATCH_HOST, 0, 0, -1, {
NULL,
@@ -202,6 +222,7 @@ struct expected expected_full[] = {
KEY_ECDSA,
NULL, /* filled at runtime */
"ECDSA #1",
+ 0,
} },
{ "ed25519_1.pub" , -1, -1, 0, HKF_MATCH_HOST, 0, 0, -1, {
NULL,
@@ -215,6 +236,7 @@ struct expected expected_full[] = {
KEY_ED25519,
NULL, /* filled at runtime */
"ED25519 #1",
+ 0,
} },
{ "rsa_1.pub" , -1, -1, 0, HKF_MATCH_HOST, 0, 0, -1, {
NULL,
@@ -228,6 +250,7 @@ struct expected expected_full[] = {
KEY_RSA,
NULL, /* filled at runtime */
"RSA #1",
+ 0,
} },
{ NULL, -1, -1, 0, 0, 0, 0, -1, {
NULL,
@@ -241,6 +264,7 @@ struct expected expected_full[] = {
KEY_UNSPEC,
NULL,
NULL,
+ 0,
} },
{ NULL, -1, -1, 0, 0, 0, 0, -1, {
NULL,
@@ -254,6 +278,7 @@ struct expected expected_full[] = {
KEY_UNSPEC,
NULL,
NULL,
+ 0,
} },
{ "dsa_2.pub" , -1, -1, HKF_MATCH_HOST, 0, HKF_MATCH_IP, HKF_MATCH_IP, -1, {
NULL,
@@ -267,6 +292,7 @@ struct expected expected_full[] = {
KEY_DSA,
NULL, /* filled at runtime */
"DSA #2",
+ 0,
} },
{ "ecdsa_2.pub" , -1, -1, HKF_MATCH_HOST, 0, HKF_MATCH_IP, HKF_MATCH_IP, -1, {
NULL,
@@ -280,6 +306,7 @@ struct expected expected_full[] = {
KEY_ECDSA,
NULL, /* filled at runtime */
"ECDSA #2",
+ 0,
} },
{ "ed25519_2.pub" , -1, -1, HKF_MATCH_HOST, 0, HKF_MATCH_IP, HKF_MATCH_IP, -1, {
NULL,
@@ -293,6 +320,7 @@ struct expected expected_full[] = {
KEY_ED25519,
NULL, /* filled at runtime */
"ED25519 #2",
+ 0,
} },
{ "rsa_2.pub" , -1, -1, HKF_MATCH_HOST, 0, HKF_MATCH_IP, HKF_MATCH_IP, -1, {
NULL,
@@ -306,6 +334,7 @@ struct expected expected_full[] = {
KEY_RSA,
NULL, /* filled at runtime */
"RSA #2",
+ 0,
} },
{ NULL, -1, -1, 0, 0, 0, 0, -1, {
NULL,
@@ -319,6 +348,7 @@ struct expected expected_full[] = {
KEY_UNSPEC,
NULL,
NULL,
+ 0,
} },
{ NULL, -1, -1, 0, 0, 0, 0, -1, {
NULL,
@@ -332,6 +362,7 @@ struct expected expected_full[] = {
KEY_UNSPEC,
NULL,
NULL,
+ 0,
} },
{ "dsa_3.pub" , -1, -1, HKF_MATCH_HOST, HKF_MATCH_HOST, HKF_MATCH_IP, HKF_MATCH_IP, -1, {
NULL,
@@ -345,6 +376,7 @@ struct expected expected_full[] = {
KEY_DSA,
NULL, /* filled at runtime */
"DSA #3",
+ 0,
} },
{ "ecdsa_3.pub" , -1, -1, HKF_MATCH_HOST, HKF_MATCH_HOST, HKF_MATCH_IP, HKF_MATCH_IP, -1, {
NULL,
@@ -358,6 +390,7 @@ struct expected expected_full[] = {
KEY_ECDSA,
NULL, /* filled at runtime */
"ECDSA #3",
+ 0,
} },
{ "ed25519_3.pub" , -1, -1, HKF_MATCH_HOST, HKF_MATCH_HOST, HKF_MATCH_IP, HKF_MATCH_IP, -1, {
NULL,
@@ -371,6 +404,7 @@ struct expected expected_full[] = {
KEY_ED25519,
NULL, /* filled at runtime */
"ED25519 #3",
+ 0,
} },
{ "rsa_3.pub" , -1, -1, HKF_MATCH_HOST, HKF_MATCH_HOST, HKF_MATCH_IP, HKF_MATCH_IP, -1, {
NULL,
@@ -384,6 +418,7 @@ struct expected expected_full[] = {
KEY_RSA,
NULL, /* filled at runtime */
"RSA #3",
+ 0,
} },
{ NULL, -1, -1, 0, 0, 0, 0, -1, {
NULL,
@@ -397,6 +432,7 @@ struct expected expected_full[] = {
KEY_UNSPEC,
NULL,
NULL,
+ 0,
} },
{ NULL, -1, -1, 0, 0, 0, 0, -1, {
NULL,
@@ -410,6 +446,7 @@ struct expected expected_full[] = {
KEY_UNSPEC,
NULL,
NULL,
+ 0,
} },
{ "dsa_5.pub" , -1, -1, 0, HKF_MATCH_HOST|HKF_MATCH_HOST_HASHED, 0, 0, -1, {
NULL,
@@ -423,6 +460,7 @@ struct expected expected_full[] = {
KEY_DSA,
NULL, /* filled at runtime */
"DSA #5",
+ 0,
} },
{ "ecdsa_5.pub" , -1, -1, 0, HKF_MATCH_HOST|HKF_MATCH_HOST_HASHED, 0, 0, -1, {
NULL,
@@ -436,6 +474,7 @@ struct expected expected_full[] = {
KEY_ECDSA,
NULL, /* filled at runtime */
"ECDSA #5",
+ 0,
} },
{ "ed25519_5.pub" , -1, -1, 0, HKF_MATCH_HOST|HKF_MATCH_HOST_HASHED, 0, 0, -1, {
NULL,
@@ -449,6 +488,7 @@ struct expected expected_full[] = {
KEY_ED25519,
NULL, /* filled at runtime */
"ED25519 #5",
+ 0,
} },
{ "rsa_5.pub" , -1, -1, 0, HKF_MATCH_HOST|HKF_MATCH_HOST_HASHED, 0, 0, -1, {
NULL,
@@ -462,6 +502,7 @@ struct expected expected_full[] = {
KEY_RSA,
NULL, /* filled at runtime */
"RSA #5",
+ 0,
} },
{ NULL, -1, -1, 0, 0, 0, 0, -1, {
NULL,
@@ -475,6 +516,7 @@ struct expected expected_full[] = {
KEY_UNSPEC,
NULL,
NULL,
+ 0,
} },
/*
* The next series have each key listed multiple times, as the
@@ -493,6 +535,7 @@ struct expected expected_full[] = {
KEY_DSA,
NULL, /* filled at runtime */
"DSA #6",
+ 0,
} },
{ "dsa_6.pub" , -1, -1, 0, 0, HKF_MATCH_IP|HKF_MATCH_IP_HASHED, 0, -1, {
NULL,
@@ -506,6 +549,7 @@ struct expected expected_full[] = {
KEY_DSA,
NULL, /* filled at runtime */
"DSA #6",
+ 0,
} },
{ "dsa_6.pub" , -1, -1, 0, 0, 0, HKF_MATCH_IP|HKF_MATCH_IP_HASHED, -1, {
NULL,
@@ -519,6 +563,7 @@ struct expected expected_full[] = {
KEY_DSA,
NULL, /* filled at runtime */
"DSA #6",
+ 0,
} },
{ "ecdsa_6.pub" , -1, -1, HKF_MATCH_HOST|HKF_MATCH_HOST_HASHED, 0, 0, 0, -1, {
NULL,
@@ -532,6 +577,7 @@ struct expected expected_full[] = {
KEY_ECDSA,
NULL, /* filled at runtime */
"ECDSA #6",
+ 0,
} },
{ "ecdsa_6.pub" , -1, -1, 0, 0, HKF_MATCH_IP|HKF_MATCH_IP_HASHED, 0, -1, {
NULL,
@@ -545,6 +591,7 @@ struct expected expected_full[] = {
KEY_ECDSA,
NULL, /* filled at runtime */
"ECDSA #6",
+ 0,
} },
{ "ecdsa_6.pub" , -1, -1, 0, 0, 0, HKF_MATCH_IP|HKF_MATCH_IP_HASHED, -1, {
NULL,
@@ -558,6 +605,7 @@ struct expected expected_full[] = {
KEY_ECDSA,
NULL, /* filled at runtime */
"ECDSA #6",
+ 0,
} },
{ "ed25519_6.pub" , -1, -1, HKF_MATCH_HOST|HKF_MATCH_HOST_HASHED, 0, 0, 0, -1, {
NULL,
@@ -571,6 +619,7 @@ struct expected expected_full[] = {
KEY_ED25519,
NULL, /* filled at runtime */
"ED25519 #6",
+ 0,
} },
{ "ed25519_6.pub" , -1, -1, 0, 0, HKF_MATCH_IP|HKF_MATCH_IP_HASHED, 0, -1, {
NULL,
@@ -584,6 +633,7 @@ struct expected expected_full[] = {
KEY_ED25519,
NULL, /* filled at runtime */
"ED25519 #6",
+ 0,
} },
{ "ed25519_6.pub" , -1, -1, 0, 0, 0, HKF_MATCH_IP|HKF_MATCH_IP_HASHED, -1, {
NULL,
@@ -597,6 +647,7 @@ struct expected expected_full[] = {
KEY_ED25519,
NULL, /* filled at runtime */
"ED25519 #6",
+ 0,
} },
{ "rsa_6.pub" , -1, -1, HKF_MATCH_HOST|HKF_MATCH_HOST_HASHED, 0, 0, 0, -1, {
NULL,
@@ -610,6 +661,7 @@ struct expected expected_full[] = {
KEY_RSA,
NULL, /* filled at runtime */
"RSA #6",
+ 0,
} },
{ "rsa_6.pub" , -1, -1, 0, 0, HKF_MATCH_IP|HKF_MATCH_IP_HASHED, 0, -1, {
NULL,
@@ -623,6 +675,7 @@ struct expected expected_full[] = {
KEY_RSA,
NULL, /* filled at runtime */
"RSA #6",
+ 0,
} },
{ "rsa_6.pub" , -1, -1, 0, 0, 0, HKF_MATCH_IP|HKF_MATCH_IP_HASHED, -1, {
NULL,
@@ -636,6 +689,7 @@ struct expected expected_full[] = {
KEY_RSA,
NULL, /* filled at runtime */
"RSA #6",
+ 0,
} },
{ NULL, -1, -1, 0, 0, 0, 0, -1, {
NULL,
@@ -649,6 +703,7 @@ struct expected expected_full[] = {
KEY_UNSPEC,
NULL,
NULL,
+ 0,
} },
{ NULL, -1, -1, 0, 0, 0, 0, -1, {
NULL,
@@ -662,6 +717,7 @@ struct expected expected_full[] = {
KEY_UNSPEC,
NULL,
NULL,
+ 0,
} },
{ NULL, -1, -1, 0, 0, 0, 0, -1, {
NULL,
@@ -675,6 +731,7 @@ struct expected expected_full[] = {
KEY_UNSPEC,
NULL,
NULL,
+ 0,
} },
{ "ed25519_4.pub" , -1, -1, 0, HKF_MATCH_HOST, 0, 0, -1, {
NULL,
@@ -688,6 +745,7 @@ struct expected expected_full[] = {
KEY_ED25519,
NULL, /* filled at runtime */
"ED25519 #4",
+ 0,
} },
{ "ecdsa_4.pub" , -1, -1, HKF_MATCH_HOST, 0, 0, 0, -1, {
NULL,
@@ -701,6 +759,7 @@ struct expected expected_full[] = {
KEY_ECDSA,
NULL, /* filled at runtime */
"ECDSA #4",
+ 0,
} },
{ "dsa_4.pub" , -1, -1, HKF_MATCH_HOST, HKF_MATCH_HOST, 0, 0, -1, {
NULL,
@@ -714,6 +773,7 @@ struct expected expected_full[] = {
KEY_DSA,
NULL, /* filled at runtime */
"DSA #4",
+ 0,
} },
{ NULL, -1, -1, 0, 0, 0, 0, -1, {
NULL,
@@ -727,6 +787,7 @@ struct expected expected_full[] = {
KEY_UNSPEC,
NULL,
NULL,
+ 0,
} },
{ NULL, -1, -1, 0, 0, 0, 0, -1, {
NULL,
@@ -740,6 +801,7 @@ struct expected expected_full[] = {
KEY_UNSPEC,
NULL,
NULL,
+ 0,
} },
{ NULL, -1, -1, 0, 0, 0, 0, -1, {
NULL,
@@ -753,6 +815,7 @@ struct expected expected_full[] = {
KEY_UNSPEC,
NULL,
NULL,
+ 0,
} },
{ NULL, -1, -1, 0, HKF_MATCH_HOST, 0, 0, -1, {
NULL,
@@ -766,6 +829,7 @@ struct expected expected_full[] = {
KEY_UNSPEC,
NULL,
NULL,
+ 0,
} },
{ NULL, -1, -1, HKF_MATCH_HOST, 0, 0, 0, -1, {
NULL,
@@ -779,6 +843,7 @@ struct expected expected_full[] = {
KEY_UNSPEC,
NULL,
NULL,
+ 0,
} },
{ NULL, -1, -1, 0, HKF_MATCH_HOST, 0, 0, -1, {
NULL,
@@ -792,6 +857,7 @@ struct expected expected_full[] = {
KEY_UNSPEC,
NULL,
NULL,
+ 0,
} },
{ NULL, -1, -1, 0, HKF_MATCH_HOST, 0, 0, -1, {
NULL,
@@ -805,6 +871,7 @@ struct expected expected_full[] = {
KEY_UNSPEC,
NULL, /* filled at runtime */
NULL,
+ 0,
} },
{ NULL, HKF_STATUS_OK, KEY_RSA, HKF_MATCH_HOST, 0, 0, 0, -1, {
NULL,
@@ -818,6 +885,7 @@ struct expected expected_full[] = {
KEY_UNSPEC,
NULL, /* filled at runtime */
NULL,
+ 0,
} },
};
@@ -835,7 +903,7 @@ test_iterate(void)
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);
+ check, &ctx, NULL, NULL, ctx.flags, 0), 0);
cleanup_expected(expected_full, ctx.nexpected);
TEST_DONE();
@@ -846,7 +914,7 @@ test_iterate(void)
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);
+ check, &ctx, NULL, NULL, ctx.flags, 0), 0);
cleanup_expected(expected_full, ctx.nexpected);
TEST_DONE();
@@ -858,7 +926,7 @@ test_iterate(void)
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);
+ check, &ctx, "prometheus.example.com", NULL, ctx.flags, 0), 0);
cleanup_expected(expected_full, ctx.nexpected);
TEST_DONE();
@@ -870,7 +938,7 @@ test_iterate(void)
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);
+ check, &ctx, "sisyphus.example.com", NULL, ctx.flags, 0), 0);
cleanup_expected(expected_full, ctx.nexpected);
TEST_DONE();
@@ -882,7 +950,7 @@ test_iterate(void)
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);
+ check, &ctx, "prometheus.example.com", NULL, ctx.flags, 0), 0);
cleanup_expected(expected_full, ctx.nexpected);
TEST_DONE();
@@ -894,7 +962,7 @@ test_iterate(void)
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);
+ check, &ctx, "sisyphus.example.com", NULL, ctx.flags, 0), 0);
cleanup_expected(expected_full, ctx.nexpected);
TEST_DONE();
@@ -905,7 +973,7 @@ test_iterate(void)
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);
+ check, &ctx, "actaeon.example.org", NULL, ctx.flags, 0), 0);
cleanup_expected(expected_full, ctx.nexpected);
TEST_DONE();
@@ -916,7 +984,7 @@ test_iterate(void)
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);
+ check, &ctx, "actaeon.example.org", NULL, ctx.flags, 0), 0);
cleanup_expected(expected_full, ctx.nexpected);
TEST_DONE();
@@ -928,7 +996,7 @@ test_iterate(void)
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);
+ check, &ctx, "tiresias.example.org", "192.0.2.1", ctx.flags, 0), 0);
cleanup_expected(expected_full, ctx.nexpected);
TEST_DONE();
@@ -940,7 +1008,8 @@ test_iterate(void)
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);
+ check, &ctx, "tiresias.example.org", "2001:db8::1",
+ ctx.flags, 0), 0);
cleanup_expected(expected_full, ctx.nexpected);
TEST_DONE();
@@ -952,7 +1021,7 @@ test_iterate(void)
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);
+ check, &ctx, "tiresias.example.org", "192.0.2.1", ctx.flags, 0), 0);
cleanup_expected(expected_full, ctx.nexpected);
TEST_DONE();
@@ -964,7 +1033,8 @@ test_iterate(void)
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);
+ check, &ctx, "tiresias.example.org", "2001:db8::1",
+ ctx.flags, 0), 0);
cleanup_expected(expected_full, ctx.nexpected);
TEST_DONE();
@@ -975,7 +1045,8 @@ test_iterate(void)
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);
+ check, &ctx, "tiresias.example.org", "192.168.0.1",
+ ctx.flags, 0), 0);
cleanup_expected(expected_full, ctx.nexpected);
TEST_DONE();
@@ -986,7 +1057,7 @@ test_iterate(void)
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);
+ check, &ctx, "tiresias.example.org", "::1", ctx.flags, 0), 0);
cleanup_expected(expected_full, ctx.nexpected);
TEST_DONE();
@@ -999,7 +1070,7 @@ test_iterate(void)
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);
+ check, &ctx, "sisyphus.example.com", "192.0.2.1", ctx.flags, 0), 0);
cleanup_expected(expected_full, ctx.nexpected);
TEST_DONE();
@@ -1013,7 +1084,7 @@ test_iterate(void)
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);
+ "2001:db8::1", ctx.flags, 0), 0);
cleanup_expected(expected_full, ctx.nexpected);
TEST_DONE();
@@ -1026,7 +1097,7 @@ test_iterate(void)
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);
+ check, &ctx, "sisyphus.example.com", "192.0.2.1", ctx.flags, 0), 0);
cleanup_expected(expected_full, ctx.nexpected);
TEST_DONE();
@@ -1040,7 +1111,7 @@ test_iterate(void)
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);
+ "2001:db8::1", ctx.flags, 0), 0);
cleanup_expected(expected_full, ctx.nexpected);
TEST_DONE();
}
diff --git a/crypto/openssh/regress/unittests/kex/Makefile b/crypto/openssh/regress/unittests/kex/Makefile
index 5c61307a325a..50b117c07851 100644
--- a/crypto/openssh/regress/unittests/kex/Makefile
+++ b/crypto/openssh/regress/unittests/kex/Makefile
@@ -1,20 +1,31 @@
-# $OpenBSD: Makefile,v 1.5 2017/12/21 00:41:22 djm Exp $
+# $OpenBSD: Makefile,v 1.12 2021/01/09 12:24:30 dtucker Exp $
PROG=test_kex
SRCS=tests.c test_kex.c
# From usr.bin/ssh
SRCS+=sshbuf-getput-basic.c sshbuf-getput-crypto.c sshbuf-misc.c sshbuf.c
-SRCS+=atomicio.c sshkey.c authfile.c cipher.c log.c ssh-rsa.c ssh-dss.c
-SRCS+=ssh-ecdsa.c ssh-ed25519.c mac.c umac.c umac128.c hmac.c misc.c
+SRCS+=sshbuf-io.c atomicio.c sshkey.c authfile.c cipher.c log.c ssh-rsa.c
+SRCS+=ssh-dss.c ssh-ecdsa.c ssh-ed25519.c mac.c umac.c umac128.c hmac.c misc.c
SRCS+=ssherr.c uidswap.c cleanup.c xmalloc.c match.c krl.c fatal.c
-SRCS+=addrmatch.c bitmap.c packet.c dispatch.c canohost.c ssh_api.c
-SRCS+=kex.c kexc25519.c kexc25519c.c kexc25519s.c kexdh.c kexdhc.c kexdhs.c
-SRCS+=kexecdh.c kexecdhc.c kexecdhs.c kexgex.c kexgexc.c kexgexs.c
-SRCS+=dh.c compat.c
-SRCS+=ed25519.c hash.c ge25519.c fe25519.c sc25519.c verify.c
-SRCS+=cipher-chachapoly.c chacha.c poly1305.c
-SRCS+=smult_curve25519_ref.c
+SRCS+=addr.c addrmatch.c bitmap.c packet.c dispatch.c canohost.c ssh_api.c
+SRCS+=compat.c ed25519.c hash.c ge25519.c fe25519.c sc25519.c verify.c
+SRCS+=cipher-chachapoly.c chacha.c poly1305.c ssh-ecdsa-sk.c ssh-sk.c
+SRCS+=ssh-ed25519-sk.c sk-usbhid.c
+
+SRCS+= kex.c
+SRCS+= dh.c
+SRCS+= kexdh.c
+SRCS+= kexecdh.c
+SRCS+= kexgex.c
+SRCS+= kexgexc.c
+SRCS+= kexgexs.c
+SRCS+= kexc25519.c
+SRCS+= smult_curve25519_ref.c
+SRCS+= kexgen.c
+SRCS+= kexsntrup761x25519.c
+SRCS+= sntrup761.c
+SRCS+= utf8.c
SRCS+=digest-openssl.c
#SRCS+=digest-libc.c
diff --git a/crypto/openssh/regress/unittests/kex/test_kex.c b/crypto/openssh/regress/unittests/kex/test_kex.c
index 6e5999bb9edd..3bd71a9f4d56 100644
--- a/crypto/openssh/regress/unittests/kex/test_kex.c
+++ b/crypto/openssh/regress/unittests/kex/test_kex.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: test_kex.c,v 1.2 2015/07/10 06:23:25 markus Exp $ */
+/* $OpenBSD: test_kex.c,v 1.5 2020/12/29 01:02:15 djm Exp $ */
/*
* Regress test KEX
*
@@ -24,8 +24,6 @@
#include "packet.h"
#include "myproposal.h"
-struct ssh *active_state = NULL; /* XXX - needed for linking */
-
void kex_tests(void);
static int do_debug = 0;
@@ -139,20 +137,22 @@ do_kex_with_key(char *kex, int keytype, int bits)
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;
+#ifdef WITH_OPENSSL
+ server2->kex->kex[KEX_DH_GRP1_SHA1] = kex_gen_server;
+ server2->kex->kex[KEX_DH_GRP14_SHA1] = kex_gen_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->kex[KEX_ECDH_SHA2] = kex_gen_server;
+#endif /* OPENSSL_HAS_ECC */
+#endif /* WITH_OPENSSL */
+ server2->kex->kex[KEX_C25519_SHA256] = kex_gen_server;
+ server2->kex->kex[KEX_KEM_SNTRUP761X25519_SHA512] = kex_gen_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;
@@ -178,11 +178,13 @@ do_kex_with_key(char *kex, int keytype, int bits)
static void
do_kex(char *kex)
{
+#ifdef WITH_OPENSSL
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
+#endif /* OPENSSL_HAS_ECC */
+#endif /* WITH_OPENSSL */
do_kex_with_key(kex, KEY_ED25519, 256);
}
@@ -190,13 +192,18 @@ void
kex_tests(void)
{
do_kex("curve25519-sha256@libssh.org");
+#ifdef WITH_OPENSSL
#ifdef OPENSSL_HAS_ECC
do_kex("ecdh-sha2-nistp256");
do_kex("ecdh-sha2-nistp384");
do_kex("ecdh-sha2-nistp521");
-#endif
+#endif /* OPENSSL_HAS_ECC */
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");
+# ifdef USE_SNTRUP761X25519
+ do_kex("sntrup761x25519-sha512@openssh.com");
+# endif /* USE_SNTRUP761X25519 */
+#endif /* WITH_OPENSSL */
}
diff --git a/crypto/openssh/regress/unittests/match/Makefile b/crypto/openssh/regress/unittests/match/Makefile
index 87e75826ac27..939163d30ef5 100644
--- a/crypto/openssh/regress/unittests/match/Makefile
+++ b/crypto/openssh/regress/unittests/match/Makefile
@@ -1,4 +1,4 @@
-# $OpenBSD: Makefile,v 1.4 2017/12/21 03:01:49 djm Exp $
+# $OpenBSD: Makefile,v 1.5 2021/01/09 12:24:31 dtucker Exp $
PROG=test_match
SRCS=tests.c
@@ -6,7 +6,7 @@ SRCS=tests.c
# From usr.bin/ssh
SRCS+=sshbuf-getput-basic.c sshbuf-getput-crypto.c sshbuf-misc.c sshbuf.c
SRCS+=match.c misc.c log.c uidswap.c fatal.c ssherr.c addrmatch.c xmalloc.c
-SRCS+=cleanup.c atomicio.c
+SRCS+=cleanup.c atomicio.c addr.c
REGRESS_TARGETS=run-regress-${PROG}
diff --git a/crypto/openssh/regress/unittests/match/tests.c b/crypto/openssh/regress/unittests/match/tests.c
index 3d9af55f2849..4fefaf4f3756 100644
--- a/crypto/openssh/regress/unittests/match/tests.c
+++ b/crypto/openssh/regress/unittests/match/tests.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: tests.c,v 1.5 2018/07/04 13:51:45 djm Exp $ */
+/* $OpenBSD: tests.c,v 1.7 2020/07/15 06:43:16 dtucker Exp $ */
/*
* Regress test for matching functions
*
@@ -105,7 +105,7 @@ tests(void)
#define CHECK_FILTER(string,filter,expected) \
do { \
- char *result = match_filter_blacklist((string), (filter)); \
+ char *result = match_filter_denylist((string), (filter)); \
ASSERT_STRING_EQ(result, expected); \
free(result); \
} while (0)
diff --git a/crypto/openssh/regress/unittests/misc/test_argv.c b/crypto/openssh/regress/unittests/misc/test_argv.c
new file mode 100644
index 000000000000..2cfebf2d9588
--- /dev/null
+++ b/crypto/openssh/regress/unittests/misc/test_argv.c
@@ -0,0 +1,187 @@
+/* $OpenBSD: test_argv.c,v 1.3 2021/06/08 07:40:12 djm Exp $ */
+/*
+ * Regress test for misc argv handling functions.
+ *
+ * Placed in the public domain.
+ */
+
+#include "includes.h"
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <stdio.h>
+#ifdef HAVE_STDINT_H
+#include <stdint.h>
+#endif
+#include <stdlib.h>
+#include <string.h>
+
+#include "../test_helper/test_helper.h"
+
+#include "log.h"
+#include "misc.h"
+
+void test_argv(void);
+
+void
+test_argv(void)
+{
+ char **av = NULL;
+ int ac = 0;
+
+#define RESET_ARGV() \
+ do { \
+ argv_free(av, ac); \
+ av = NULL; \
+ ac = -1; \
+ } while (0)
+
+ TEST_START("empty args");
+ ASSERT_INT_EQ(argv_split("", &ac, &av, 0), 0);
+ ASSERT_INT_EQ(ac, 0);
+ ASSERT_PTR_NE(av, NULL);
+ ASSERT_PTR_EQ(av[0], NULL);
+ RESET_ARGV();
+ ASSERT_INT_EQ(argv_split(" ", &ac, &av, 0), 0);
+ ASSERT_INT_EQ(ac, 0);
+ ASSERT_PTR_NE(av, NULL);
+ ASSERT_PTR_EQ(av[0], NULL);
+ RESET_ARGV();
+ TEST_DONE();
+
+ TEST_START("trivial args");
+ ASSERT_INT_EQ(argv_split("leamas", &ac, &av, 0), 0);
+ ASSERT_INT_EQ(ac, 1);
+ ASSERT_PTR_NE(av, NULL);
+ ASSERT_STRING_EQ(av[0], "leamas");
+ ASSERT_PTR_EQ(av[1], NULL);
+ RESET_ARGV();
+ ASSERT_INT_EQ(argv_split("smiley leamas", &ac, &av, 0), 0);
+ ASSERT_INT_EQ(ac, 2);
+ ASSERT_PTR_NE(av, NULL);
+ ASSERT_STRING_EQ(av[0], "smiley");
+ ASSERT_STRING_EQ(av[1], "leamas");
+ ASSERT_PTR_EQ(av[2], NULL);
+ RESET_ARGV();
+ TEST_DONE();
+
+ TEST_START("quoted");
+ ASSERT_INT_EQ(argv_split("\"smiley\"", &ac, &av, 0), 0);
+ ASSERT_INT_EQ(ac, 1);
+ ASSERT_PTR_NE(av, NULL);
+ ASSERT_STRING_EQ(av[0], "smiley");
+ ASSERT_PTR_EQ(av[1], NULL);
+ RESET_ARGV();
+ ASSERT_INT_EQ(argv_split("leamas \" smiley \"", &ac, &av, 0), 0);
+ ASSERT_INT_EQ(ac, 2);
+ ASSERT_PTR_NE(av, NULL);
+ ASSERT_STRING_EQ(av[0], "leamas");
+ ASSERT_STRING_EQ(av[1], " smiley ");
+ ASSERT_PTR_EQ(av[2], NULL);
+ RESET_ARGV();
+ ASSERT_INT_EQ(argv_split("\"smiley leamas\"", &ac, &av, 0), 0);
+ ASSERT_INT_EQ(ac, 1);
+ ASSERT_PTR_NE(av, NULL);
+ ASSERT_STRING_EQ(av[0], "smiley leamas");
+ ASSERT_PTR_EQ(av[1], NULL);
+ RESET_ARGV();
+ ASSERT_INT_EQ(argv_split("smiley\" leamas\" liz", &ac, &av, 0), 0);
+ ASSERT_INT_EQ(ac, 2);
+ ASSERT_PTR_NE(av, NULL);
+ ASSERT_STRING_EQ(av[0], "smiley leamas");
+ ASSERT_STRING_EQ(av[1], "liz");
+ ASSERT_PTR_EQ(av[2], NULL);
+ RESET_ARGV();
+ TEST_DONE();
+
+ TEST_START("escaped");
+ ASSERT_INT_EQ(argv_split("\\\"smiley\\'", &ac, &av, 0), 0);
+ ASSERT_INT_EQ(ac, 1);
+ ASSERT_PTR_NE(av, NULL);
+ ASSERT_STRING_EQ(av[0], "\"smiley'");
+ ASSERT_PTR_EQ(av[1], NULL);
+ RESET_ARGV();
+ ASSERT_INT_EQ(argv_split("'\\'smiley\\\"'", &ac, &av, 0), 0);
+ ASSERT_INT_EQ(ac, 1);
+ ASSERT_PTR_NE(av, NULL);
+ ASSERT_STRING_EQ(av[0], "'smiley\"");
+ ASSERT_PTR_EQ(av[1], NULL);
+ RESET_ARGV();
+ ASSERT_INT_EQ(argv_split("smiley\\'s leamas\\'", &ac, &av, 0), 0);
+ ASSERT_INT_EQ(ac, 2);
+ ASSERT_PTR_NE(av, NULL);
+ ASSERT_STRING_EQ(av[0], "smiley's");
+ ASSERT_STRING_EQ(av[1], "leamas'");
+ ASSERT_PTR_EQ(av[2], NULL);
+ RESET_ARGV();
+ ASSERT_INT_EQ(argv_split("leamas\\\\smiley", &ac, &av, 0), 0);
+ ASSERT_INT_EQ(ac, 1);
+ ASSERT_PTR_NE(av, NULL);
+ ASSERT_STRING_EQ(av[0], "leamas\\smiley");
+ ASSERT_PTR_EQ(av[1], NULL);
+ RESET_ARGV();
+ ASSERT_INT_EQ(argv_split("leamas\\\\ \\\\smiley", &ac, &av, 0), 0);
+ ASSERT_INT_EQ(ac, 2);
+ ASSERT_PTR_NE(av, NULL);
+ ASSERT_STRING_EQ(av[0], "leamas\\");
+ ASSERT_STRING_EQ(av[1], "\\smiley");
+ ASSERT_PTR_EQ(av[2], NULL);
+ RESET_ARGV();
+ ASSERT_INT_EQ(argv_split("smiley\\ leamas", &ac, &av, 0), 0);
+ ASSERT_INT_EQ(ac, 1);
+ ASSERT_PTR_NE(av, NULL);
+ ASSERT_STRING_EQ(av[0], "smiley leamas");
+ ASSERT_PTR_EQ(av[1], NULL);
+ RESET_ARGV();
+ TEST_DONE();
+
+ TEST_START("quoted escaped");
+ ASSERT_INT_EQ(argv_split("'smiley\\ leamas'", &ac, &av, 0), 0);
+ ASSERT_INT_EQ(ac, 1);
+ ASSERT_PTR_NE(av, NULL);
+ ASSERT_STRING_EQ(av[0], "smiley\\ leamas");
+ ASSERT_PTR_EQ(av[1], NULL);
+ RESET_ARGV();
+ ASSERT_INT_EQ(argv_split("\"smiley\\ leamas\"", &ac, &av, 0), 0);
+ ASSERT_INT_EQ(ac, 1);
+ ASSERT_PTR_NE(av, NULL);
+ ASSERT_STRING_EQ(av[0], "smiley\\ leamas");
+ ASSERT_PTR_EQ(av[1], NULL);
+ RESET_ARGV();
+ TEST_DONE();
+
+ TEST_START("comments");
+ ASSERT_INT_EQ(argv_split("# gold", &ac, &av, 0), 0);
+ ASSERT_INT_EQ(ac, 2);
+ ASSERT_PTR_NE(av, NULL);
+ ASSERT_STRING_EQ(av[0], "#");
+ ASSERT_STRING_EQ(av[1], "gold");
+ ASSERT_PTR_EQ(av[2], NULL);
+ RESET_ARGV();
+ ASSERT_INT_EQ(argv_split("# gold", &ac, &av, 1), 0);
+ ASSERT_INT_EQ(ac, 0);
+ ASSERT_PTR_NE(av, NULL);
+ ASSERT_PTR_EQ(av[0], NULL);
+ RESET_ARGV();
+ ASSERT_INT_EQ(argv_split("leamas#gold", &ac, &av, 1), 0);
+ ASSERT_INT_EQ(ac, 1);
+ ASSERT_PTR_NE(av, NULL);
+ ASSERT_STRING_EQ(av[0], "leamas#gold");
+ ASSERT_PTR_EQ(av[1], NULL);
+ RESET_ARGV();
+ ASSERT_INT_EQ(argv_split("\"leamas # gold\"", &ac, &av, 1), 0);
+ ASSERT_INT_EQ(ac, 1);
+ ASSERT_PTR_NE(av, NULL);
+ ASSERT_STRING_EQ(av[0], "leamas # gold");
+ ASSERT_PTR_EQ(av[1], NULL);
+ RESET_ARGV();
+ ASSERT_INT_EQ(argv_split("\"leamas\"#gold", &ac, &av, 1), 0);
+ ASSERT_INT_EQ(ac, 1);
+ ASSERT_PTR_NE(av, NULL);
+ ASSERT_STRING_EQ(av[0], "leamas#gold");
+ ASSERT_PTR_EQ(av[1], NULL);
+ RESET_ARGV();
+ TEST_DONE();
+
+ /* XXX test char *argv_assemble(int argc, char **argv) */
+}
diff --git a/crypto/openssh/regress/unittests/misc/test_convtime.c b/crypto/openssh/regress/unittests/misc/test_convtime.c
new file mode 100644
index 000000000000..8f9be89ff900
--- /dev/null
+++ b/crypto/openssh/regress/unittests/misc/test_convtime.c
@@ -0,0 +1,59 @@
+/* $OpenBSD: test_convtime.c,v 1.1 2021/03/19 03:25:01 djm Exp $ */
+/*
+ * Regress test for misc time conversion functions.
+ *
+ * Placed in the public domain.
+ */
+
+#include "includes.h"
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <stdio.h>
+#ifdef HAVE_STDINT_H
+#include <stdint.h>
+#endif
+#include <stdlib.h>
+#include <string.h>
+
+#include "../test_helper/test_helper.h"
+
+#include "log.h"
+#include "misc.h"
+
+void test_convtime(void);
+
+void
+test_convtime(void)
+{
+ char buf[1024];
+
+ TEST_START("misc_convtime");
+ ASSERT_INT_EQ(convtime("0"), 0);
+ ASSERT_INT_EQ(convtime("1"), 1);
+ ASSERT_INT_EQ(convtime("2s"), 2);
+ ASSERT_INT_EQ(convtime("3m"), 180);
+ ASSERT_INT_EQ(convtime("1m30"), 90);
+ ASSERT_INT_EQ(convtime("1m30s"), 90);
+ ASSERT_INT_EQ(convtime("1h1s"), 3601);
+ ASSERT_INT_EQ(convtime("1h30m"), 90 * 60);
+ ASSERT_INT_EQ(convtime("1d"), 24 * 60 * 60);
+ ASSERT_INT_EQ(convtime("1w"), 7 * 24 * 60 * 60);
+ ASSERT_INT_EQ(convtime("1w2d3h4m5"), 788645);
+ ASSERT_INT_EQ(convtime("1w2d3h4m5s"), 788645);
+ /* any negative number or error returns -1 */
+ ASSERT_INT_EQ(convtime("-1"), -1);
+ ASSERT_INT_EQ(convtime(""), -1);
+ ASSERT_INT_EQ(convtime("trout"), -1);
+ ASSERT_INT_EQ(convtime("-77"), -1);
+ /* boundary conditions */
+ snprintf(buf, sizeof buf, "%llu", (long long unsigned)INT_MAX);
+ ASSERT_INT_EQ(convtime(buf), INT_MAX);
+ snprintf(buf, sizeof buf, "%llu", (long long unsigned)INT_MAX + 1);
+ ASSERT_INT_EQ(convtime(buf), -1);
+ ASSERT_INT_EQ(convtime("3550w5d3h14m7s"), 2147483647);
+#if INT_MAX == 2147483647
+ ASSERT_INT_EQ(convtime("3550w5d3h14m8s"), -1);
+#endif
+ TEST_DONE();
+}
diff --git a/crypto/openssh/regress/unittests/misc/test_expand.c b/crypto/openssh/regress/unittests/misc/test_expand.c
new file mode 100644
index 000000000000..513c69bce4e2
--- /dev/null
+++ b/crypto/openssh/regress/unittests/misc/test_expand.c
@@ -0,0 +1,90 @@
+/* $OpenBSD: test_expand.c,v 1.2 2021/04/06 09:07:33 dtucker Exp $ */
+/*
+ * Regress test for misc string expansion functions.
+ *
+ * Placed in the public domain.
+ */
+
+#include "includes.h"
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <stdio.h>
+#ifdef HAVE_STDINT_H
+#include <stdint.h>
+#endif
+#include <stdlib.h>
+#include <string.h>
+
+#include "../test_helper/test_helper.h"
+
+#include "log.h"
+#include "misc.h"
+
+void test_expand(void);
+
+void
+test_expand(void)
+{
+ int parseerr;
+ char *ret;
+
+ TEST_START("dollar_expand");
+ ASSERT_INT_EQ(setenv("FOO", "bar", 1), 0);
+ ASSERT_INT_EQ(setenv("BAR", "baz", 1), 0);
+ (void)unsetenv("BAZ");
+#define ASSERT_DOLLAR_EQ(x, y) do { \
+ char *str = dollar_expand(NULL, (x)); \
+ ASSERT_STRING_EQ(str, (y)); \
+ free(str); \
+} while(0)
+ ASSERT_DOLLAR_EQ("${FOO}", "bar");
+ ASSERT_DOLLAR_EQ(" ${FOO}", " bar");
+ ASSERT_DOLLAR_EQ("${FOO} ", "bar ");
+ ASSERT_DOLLAR_EQ(" ${FOO} ", " bar ");
+ ASSERT_DOLLAR_EQ("${FOO}${BAR}", "barbaz");
+ ASSERT_DOLLAR_EQ(" ${FOO} ${BAR}", " bar baz");
+ ASSERT_DOLLAR_EQ("${FOO}${BAR} ", "barbaz ");
+ ASSERT_DOLLAR_EQ(" ${FOO} ${BAR} ", " bar baz ");
+ ASSERT_DOLLAR_EQ("$", "$");
+ ASSERT_DOLLAR_EQ(" $", " $");
+ ASSERT_DOLLAR_EQ("$ ", "$ ");
+
+ /* suppress error messages for error handing tests */
+ log_init("test_misc", SYSLOG_LEVEL_QUIET, SYSLOG_FACILITY_AUTH, 1);
+ /* error checking, non existent variable */
+ ret = dollar_expand(&parseerr, "a${BAZ}");
+ ASSERT_PTR_EQ(ret, NULL); ASSERT_INT_EQ(parseerr, 0);
+ ret = dollar_expand(&parseerr, "${BAZ}b");
+ ASSERT_PTR_EQ(ret, NULL); ASSERT_INT_EQ(parseerr, 0);
+ ret = dollar_expand(&parseerr, "a${BAZ}b");
+ ASSERT_PTR_EQ(ret, NULL); ASSERT_INT_EQ(parseerr, 0);
+ /* invalid format */
+ ret = dollar_expand(&parseerr, "${");
+ ASSERT_PTR_EQ(ret, NULL); ASSERT_INT_EQ(parseerr, 1);
+ ret = dollar_expand(&parseerr, "${F");
+ ASSERT_PTR_EQ(ret, NULL); ASSERT_INT_EQ(parseerr, 1);
+ ret = dollar_expand(&parseerr, "${FO");
+ ASSERT_PTR_EQ(ret, NULL); ASSERT_INT_EQ(parseerr, 1);
+ /* empty variable name */
+ ret = dollar_expand(&parseerr, "${}");
+ ASSERT_PTR_EQ(ret, NULL); ASSERT_INT_EQ(parseerr, 1);
+ /* restore loglevel to default */
+ log_init("test_misc", SYSLOG_LEVEL_INFO, SYSLOG_FACILITY_AUTH, 1);
+ TEST_DONE();
+
+ TEST_START("percent_expand");
+ ASSERT_STRING_EQ(percent_expand("%%", "%h", "foo", NULL), "%");
+ ASSERT_STRING_EQ(percent_expand("%h", "h", "foo", NULL), "foo");
+ ASSERT_STRING_EQ(percent_expand("%h ", "h", "foo", NULL), "foo ");
+ ASSERT_STRING_EQ(percent_expand(" %h", "h", "foo", NULL), " foo");
+ ASSERT_STRING_EQ(percent_expand(" %h ", "h", "foo", NULL), " foo ");
+ ASSERT_STRING_EQ(percent_expand(" %a%b ", "a", "foo", "b", "bar", NULL),
+ " foobar ");
+ TEST_DONE();
+
+ TEST_START("percent_dollar_expand");
+ ASSERT_STRING_EQ(percent_dollar_expand("%h${FOO}", "h", "foo", NULL),
+ "foobar");
+ TEST_DONE();
+}
diff --git a/crypto/openssh/regress/unittests/misc/test_parse.c b/crypto/openssh/regress/unittests/misc/test_parse.c
new file mode 100644
index 000000000000..727ff3dea9d7
--- /dev/null
+++ b/crypto/openssh/regress/unittests/misc/test_parse.c
@@ -0,0 +1,86 @@
+/* $OpenBSD: test_parse.c,v 1.1 2021/03/19 03:25:01 djm Exp $ */
+/*
+ * Regress test for misc user/host/URI parsing functions.
+ *
+ * Placed in the public domain.
+ */
+
+#include "includes.h"
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <stdio.h>
+#ifdef HAVE_STDINT_H
+#include <stdint.h>
+#endif
+#include <stdlib.h>
+#include <string.h>
+
+#include "../test_helper/test_helper.h"
+
+#include "log.h"
+#include "misc.h"
+
+void test_parse(void);
+
+void
+test_parse(void)
+{
+ int port;
+ char *user, *host, *path;
+
+ TEST_START("misc_parse_user_host_path");
+ ASSERT_INT_EQ(parse_user_host_path("someuser@some.host:some/path",
+ &user, &host, &path), 0);
+ ASSERT_STRING_EQ(user, "someuser");
+ ASSERT_STRING_EQ(host, "some.host");
+ ASSERT_STRING_EQ(path, "some/path");
+ free(user); free(host); free(path);
+ TEST_DONE();
+
+ TEST_START("misc_parse_user_ipv4_path");
+ ASSERT_INT_EQ(parse_user_host_path("someuser@1.22.33.144:some/path",
+ &user, &host, &path), 0);
+ ASSERT_STRING_EQ(user, "someuser");
+ ASSERT_STRING_EQ(host, "1.22.33.144");
+ ASSERT_STRING_EQ(path, "some/path");
+ free(user); free(host); free(path);
+ TEST_DONE();
+
+ TEST_START("misc_parse_user_[ipv4]_path");
+ ASSERT_INT_EQ(parse_user_host_path("someuser@[1.22.33.144]:some/path",
+ &user, &host, &path), 0);
+ ASSERT_STRING_EQ(user, "someuser");
+ ASSERT_STRING_EQ(host, "1.22.33.144");
+ ASSERT_STRING_EQ(path, "some/path");
+ free(user); free(host); free(path);
+ TEST_DONE();
+
+ TEST_START("misc_parse_user_[ipv4]_nopath");
+ ASSERT_INT_EQ(parse_user_host_path("someuser@[1.22.33.144]:",
+ &user, &host, &path), 0);
+ ASSERT_STRING_EQ(user, "someuser");
+ ASSERT_STRING_EQ(host, "1.22.33.144");
+ ASSERT_STRING_EQ(path, ".");
+ free(user); free(host); free(path);
+ TEST_DONE();
+
+ TEST_START("misc_parse_user_ipv6_path");
+ ASSERT_INT_EQ(parse_user_host_path("someuser@[::1]:some/path",
+ &user, &host, &path), 0);
+ ASSERT_STRING_EQ(user, "someuser");
+ ASSERT_STRING_EQ(host, "::1");
+ ASSERT_STRING_EQ(path, "some/path");
+ free(user); free(host); free(path);
+ TEST_DONE();
+
+ TEST_START("misc_parse_uri");
+ ASSERT_INT_EQ(parse_uri("ssh", "ssh://someuser@some.host:22/some/path",
+ &user, &host, &port, &path), 0);
+ ASSERT_STRING_EQ(user, "someuser");
+ ASSERT_STRING_EQ(host, "some.host");
+ ASSERT_INT_EQ(port, 22);
+ ASSERT_STRING_EQ(path, "some/path");
+ free(user); free(host); free(path);
+ TEST_DONE();
+}
diff --git a/crypto/openssh/regress/unittests/misc/test_strdelim.c b/crypto/openssh/regress/unittests/misc/test_strdelim.c
new file mode 100644
index 000000000000..1d9133d4b31b
--- /dev/null
+++ b/crypto/openssh/regress/unittests/misc/test_strdelim.c
@@ -0,0 +1,202 @@
+/* $OpenBSD: test_strdelim.c,v 1.2 2021/05/21 03:59:01 djm Exp $ */
+/*
+ * Regress test for misc strdelim() and co
+ *
+ * Placed in the public domain.
+ */
+
+#include "includes.h"
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <stdio.h>
+#ifdef HAVE_STDINT_H
+#include <stdint.h>
+#endif
+#include <stdlib.h>
+#include <string.h>
+
+#include "../test_helper/test_helper.h"
+
+#include "log.h"
+#include "misc.h"
+#include "xmalloc.h"
+
+void test_strdelim(void);
+
+void
+test_strdelim(void)
+{
+ char *orig, *str, *cp;
+
+#define START_STRING(x) orig = str = xstrdup(x)
+#define DONE_STRING() free(orig)
+
+ TEST_START("empty");
+ START_STRING("");
+ cp = strdelim(&str);
+ ASSERT_STRING_EQ(cp, ""); /* XXX arguable */
+ cp = strdelim(&str);
+ ASSERT_PTR_EQ(cp, NULL);
+ DONE_STRING();
+ TEST_DONE();
+
+ TEST_START("whitespace");
+ START_STRING(" ");
+ cp = strdelim(&str);
+ ASSERT_STRING_EQ(cp, ""); /* XXX better as NULL */
+ ASSERT_STRING_EQ(str, "");
+ DONE_STRING();
+ TEST_DONE();
+
+ TEST_START("trivial");
+ START_STRING("blob");
+ cp = strdelim(&str);
+ ASSERT_STRING_EQ(cp, "blob");
+ cp = strdelim(&str);
+ ASSERT_PTR_EQ(cp, NULL);
+ ASSERT_PTR_EQ(str, NULL);
+ DONE_STRING();
+ TEST_DONE();
+
+ TEST_START("trivial whitespace");
+ START_STRING("blob ");
+ cp = strdelim(&str);
+ ASSERT_STRING_EQ(cp, "blob");
+ ASSERT_STRING_EQ(str, "");
+ cp = strdelim(&str);
+ ASSERT_STRING_EQ(cp, ""); /* XXX better as NULL */
+ ASSERT_PTR_EQ(str, NULL);
+ DONE_STRING();
+ TEST_DONE();
+
+ TEST_START("multi");
+ START_STRING("blob1 blob2");
+ cp = strdelim(&str);
+ ASSERT_STRING_EQ(cp, "blob1");
+ ASSERT_STRING_EQ(str, "blob2");
+ cp = strdelim(&str);
+ ASSERT_STRING_EQ(cp, "blob2");
+ ASSERT_PTR_EQ(str, NULL);
+ cp = strdelim(&str);
+ ASSERT_PTR_EQ(cp, NULL);
+ DONE_STRING();
+ TEST_DONE();
+
+ TEST_START("multi whitespace");
+ START_STRING("blob1 blob2 ");
+ cp = strdelim(&str);
+ ASSERT_STRING_EQ(cp, "blob1");
+ ASSERT_STRING_EQ(str, "blob2 ");
+ cp = strdelim(&str);
+ ASSERT_STRING_EQ(cp, "blob2");
+ cp = strdelim(&str);
+ ASSERT_STRING_EQ(cp, ""); /* XXX better as NULL */
+ ASSERT_PTR_EQ(str, NULL);
+ DONE_STRING();
+ TEST_DONE();
+
+ TEST_START("multi equals");
+ START_STRING("blob1=blob2");
+ cp = strdelim(&str);
+ ASSERT_STRING_EQ(cp, "blob1");
+ ASSERT_STRING_EQ(str, "blob2");
+ cp = strdelim(&str);
+ ASSERT_STRING_EQ(cp, "blob2");
+ ASSERT_PTR_EQ(str, NULL);
+ cp = strdelim(&str);
+ ASSERT_PTR_EQ(cp, NULL);
+ DONE_STRING();
+ TEST_DONE();
+
+ TEST_START("multi too many equals");
+ START_STRING("blob1==blob2");
+ cp = strdelim(&str);
+ ASSERT_STRING_EQ(cp, "blob1"); /* XXX better returning NULL early */
+ ASSERT_STRING_EQ(str, "=blob2");
+ cp = strdelim(&str);
+ ASSERT_STRING_EQ(cp, "");
+ ASSERT_STRING_EQ(str, "blob2");
+ cp = strdelim(&str);
+ ASSERT_STRING_EQ(cp, "blob2"); /* XXX should (but can't) reject */
+ ASSERT_PTR_EQ(str, NULL);
+ DONE_STRING();
+ TEST_DONE();
+
+ TEST_START("multi equals strdelimw");
+ START_STRING("blob1=blob2");
+ cp = strdelimw(&str);
+ ASSERT_STRING_EQ(cp, "blob1=blob2");
+ ASSERT_PTR_EQ(str, NULL);
+ cp = strdelimw(&str);
+ ASSERT_PTR_EQ(cp, NULL);
+ DONE_STRING();
+ TEST_DONE();
+
+ TEST_START("quoted");
+ START_STRING("\"blob\"");
+ cp = strdelim(&str);
+ ASSERT_STRING_EQ(cp, "blob");
+ cp = strdelim(&str);
+ ASSERT_STRING_EQ(cp, ""); /* XXX better as NULL */
+ ASSERT_PTR_EQ(str, NULL);
+ DONE_STRING();
+ TEST_DONE();
+
+ TEST_START("quoted multi");
+ START_STRING("\"blob1\" blob2");
+ cp = strdelim(&str);
+ ASSERT_STRING_EQ(cp, "blob1");
+ ASSERT_STRING_EQ(str, "blob2");
+ cp = strdelim(&str);
+ ASSERT_STRING_EQ(cp, "blob2");
+ ASSERT_PTR_EQ(str, NULL);
+ cp = strdelim(&str);
+ ASSERT_PTR_EQ(cp, NULL);
+ DONE_STRING();
+ TEST_DONE();
+
+ TEST_START("quoted multi reverse");
+ START_STRING("blob1 \"blob2\"");
+ cp = strdelim(&str);
+ ASSERT_STRING_EQ(cp, "blob1");
+ ASSERT_STRING_EQ(str, "\"blob2\"");
+ cp = strdelim(&str);
+ ASSERT_STRING_EQ(cp, "blob2");
+ ASSERT_STRING_EQ(str, "");
+ cp = strdelim(&str);
+ ASSERT_STRING_EQ(cp, ""); /* XXX better as NULL */
+ ASSERT_PTR_EQ(str, NULL);
+ DONE_STRING();
+ TEST_DONE();
+
+ TEST_START("quoted multi middle");
+ START_STRING("blob1 \"blob2\" blob3");
+ cp = strdelim(&str);
+ ASSERT_STRING_EQ(cp, "blob1");
+ cp = strdelim(&str);
+ ASSERT_STRING_EQ(cp, "blob2");
+ cp = strdelim(&str);
+ ASSERT_STRING_EQ(cp, "blob3");
+ cp = strdelim(&str);
+ ASSERT_PTR_EQ(cp, NULL);
+ DONE_STRING();
+ TEST_DONE();
+
+ TEST_START("badquote");
+ START_STRING("\"blob");
+ cp = strdelim(&str);
+ ASSERT_PTR_EQ(cp, NULL);
+ DONE_STRING();
+ TEST_DONE();
+
+ TEST_START("oops quote");
+ START_STRING("\"blob\\\"");
+ cp = strdelim(&str);
+ ASSERT_STRING_EQ(cp, "blob\\"); /* XXX wrong */
+ cp = strdelim(&str);
+ ASSERT_STRING_EQ(cp, "");
+ DONE_STRING();
+ TEST_DONE();
+
+}
diff --git a/crypto/openssh/regress/unittests/misc/tests.c b/crypto/openssh/regress/unittests/misc/tests.c
new file mode 100644
index 000000000000..b0b7cd4332e3
--- /dev/null
+++ b/crypto/openssh/regress/unittests/misc/tests.c
@@ -0,0 +1,38 @@
+/* $OpenBSD: tests.c,v 1.7 2021/05/21 03:48:07 djm Exp $ */
+/*
+ * Regress test for misc helper functions.
+ *
+ * Placed in the public domain.
+ */
+
+#include "includes.h"
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <stdio.h>
+#ifdef HAVE_STDINT_H
+#include <stdint.h>
+#endif
+#include <stdlib.h>
+#include <string.h>
+
+#include "../test_helper/test_helper.h"
+
+#include "log.h"
+#include "misc.h"
+
+void test_parse(void);
+void test_convtime(void);
+void test_expand(void);
+void test_argv(void);
+void test_strdelim(void);
+
+void
+tests(void)
+{
+ test_parse();
+ test_convtime();
+ test_expand();
+ test_argv();
+ test_strdelim();
+}
diff --git a/crypto/openssh/regress/unittests/sshbuf/Makefile b/crypto/openssh/regress/unittests/sshbuf/Makefile
index 81d4f27a6132..a8ddfaf7ed24 100644
--- a/crypto/openssh/regress/unittests/sshbuf/Makefile
+++ b/crypto/openssh/regress/unittests/sshbuf/Makefile
@@ -1,6 +1,6 @@
-# $OpenBSD: Makefile,v 1.6 2017/12/21 00:41:22 djm Exp $
+# $OpenBSD: Makefile,v 1.10 2021/01/09 12:24:31 dtucker Exp $
-.include <bsd.regress.mk>
+# $OpenBSD: Makefile,v 1.8 2020/01/26 00:09:50 djm Exp $
PROG=test_sshbuf
SRCS=tests.c
@@ -14,9 +14,9 @@ SRCS+=test_sshbuf_fixed.c
# From usr.bin/ssh
SRCS+=sshbuf-getput-basic.c sshbuf-getput-crypto.c sshbuf-misc.c sshbuf.c
-SRCS+=atomicio.c
+SRCS+=sshbuf-io.c atomicio.c misc.c xmalloc.c log.c fatal.c ssherr.c cleanup.c
+SRCS+=match.c addr.c addrmatch.c
run-regress-${PROG}: ${PROG}
- env ${TEST_ENV} ./${PROG}
-
+ env ${TEST_ENV} ./${PROG} ${UNITTEST_ARGS}
diff --git a/crypto/openssh/regress/unittests/sshbuf/test_sshbuf_fuzz.c b/crypto/openssh/regress/unittests/sshbuf/test_sshbuf_fuzz.c
index c52376b531a3..e236c82f96fc 100644
--- a/crypto/openssh/regress/unittests/sshbuf/test_sshbuf_fuzz.c
+++ b/crypto/openssh/regress/unittests/sshbuf/test_sshbuf_fuzz.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: test_sshbuf_fuzz.c,v 1.1 2014/04/30 05:32:00 djm Exp $ */
+/* $OpenBSD: test_sshbuf_fuzz.c,v 1.2 2018/10/17 23:28:05 djm Exp $ */
/*
* Regress test for sshbuf.h buffer API
*
@@ -30,10 +30,15 @@ sshbuf_fuzz_tests(void)
{
struct sshbuf *p1;
u_char *dp;
- size_t sz, sz2, i;
+ size_t sz, sz2, i, ntests = NUM_FUZZ_TESTS;
u_int32_t r;
int ret;
+ if (test_is_fast())
+ ntests >>= 2;
+ if (test_is_slow())
+ ntests <<= 2;
+
/* NB. uses sshbuf internals */
TEST_START("fuzz alloc/dealloc");
p1 = sshbuf_new();
diff --git a/crypto/openssh/regress/unittests/sshbuf/test_sshbuf_getput_basic.c b/crypto/openssh/regress/unittests/sshbuf/test_sshbuf_getput_basic.c
index 966e8432b2d6..bea89881a463 100644
--- a/crypto/openssh/regress/unittests/sshbuf/test_sshbuf_getput_basic.c
+++ b/crypto/openssh/regress/unittests/sshbuf/test_sshbuf_getput_basic.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: test_sshbuf_getput_basic.c,v 1.1 2014/04/30 05:32:00 djm Exp $ */
+/* $OpenBSD: test_sshbuf_getput_basic.c,v 1.2 2019/07/14 23:33:19 djm Exp $ */
/*
* Regress test for sshbuf.h buffer API
*
@@ -481,4 +481,233 @@ sshbuf_getput_basic_tests(void)
ASSERT_MEM_EQ(sshbuf_ptr(p1), bn_exp3, sizeof(bn_exp3));
sshbuf_free(p1);
TEST_DONE();
+
+ TEST_START("sshbuf_peek_u64");
+ p1 = sshbuf_new();
+ ASSERT_PTR_NE(p1, NULL);
+ ASSERT_INT_EQ(sshbuf_put(p1, x, sizeof(x)), 0);
+ ASSERT_INT_EQ(sshbuf_peek_u64(p1, 0, &v64), 0);
+ ASSERT_U64_EQ(v64, 0x1122334455667788ULL);
+ ASSERT_INT_EQ(sshbuf_peek_u64(p1, 2, &v64), 0);
+ ASSERT_U64_EQ(v64, 0x3344556677880099ULL);
+ ASSERT_INT_EQ(sshbuf_peek_u64(p1, 3, &v64), SSH_ERR_MESSAGE_INCOMPLETE);
+ ASSERT_INT_EQ(sshbuf_peek_u64(p1, sizeof(x), &v64),
+ SSH_ERR_MESSAGE_INCOMPLETE);
+ ASSERT_INT_EQ(sshbuf_peek_u64(p1, 1000, &v64),
+ SSH_ERR_MESSAGE_INCOMPLETE);
+ sshbuf_free(p1);
+ TEST_DONE();
+
+ TEST_START("sshbuf_peek_u32");
+ p1 = sshbuf_new();
+ ASSERT_PTR_NE(p1, NULL);
+ ASSERT_INT_EQ(sshbuf_put(p1, x, sizeof(x)), 0);
+ ASSERT_INT_EQ(sshbuf_peek_u32(p1, 0, &v32), 0);
+ ASSERT_U32_EQ(v32, 0x11223344);
+ ASSERT_INT_EQ(sshbuf_peek_u32(p1, 6, &v32), 0);
+ ASSERT_U32_EQ(v32, 0x77880099);
+ ASSERT_INT_EQ(sshbuf_peek_u32(p1, 7, &v32), SSH_ERR_MESSAGE_INCOMPLETE);
+ ASSERT_INT_EQ(sshbuf_peek_u32(p1, sizeof(x), &v32),
+ SSH_ERR_MESSAGE_INCOMPLETE);
+ ASSERT_INT_EQ(sshbuf_peek_u32(p1, 1000, &v32),
+ SSH_ERR_MESSAGE_INCOMPLETE);
+ sshbuf_free(p1);
+ TEST_DONE();
+
+ TEST_START("sshbuf_peek_u16");
+ p1 = sshbuf_new();
+ ASSERT_PTR_NE(p1, NULL);
+ ASSERT_INT_EQ(sshbuf_put(p1, x, sizeof(x)), 0);
+ ASSERT_INT_EQ(sshbuf_peek_u16(p1, 0, &v16), 0);
+ ASSERT_U16_EQ(v16, 0x1122);
+ ASSERT_INT_EQ(sshbuf_peek_u16(p1, 8, &v16), 0);
+ ASSERT_U16_EQ(v16, 0x99);
+ ASSERT_INT_EQ(sshbuf_peek_u16(p1, 9, &v16), SSH_ERR_MESSAGE_INCOMPLETE);
+ ASSERT_INT_EQ(sshbuf_peek_u16(p1, sizeof(x), &v16),
+ SSH_ERR_MESSAGE_INCOMPLETE);
+ ASSERT_INT_EQ(sshbuf_peek_u16(p1, 1000, &v16),
+ SSH_ERR_MESSAGE_INCOMPLETE);
+ sshbuf_free(p1);
+ TEST_DONE();
+
+ TEST_START("sshbuf_peek_u8");
+ p1 = sshbuf_new();
+ ASSERT_PTR_NE(p1, NULL);
+ ASSERT_INT_EQ(sshbuf_put(p1, x, sizeof(x)), 0);
+ ASSERT_INT_EQ(sshbuf_peek_u8(p1, 0, &v8), 0);
+ ASSERT_U8_EQ(v8, 0x11);
+ ASSERT_INT_EQ(sshbuf_peek_u8(p1, 9, &v8), 0);
+ ASSERT_U8_EQ(v8, 0x99);
+ ASSERT_INT_EQ(sshbuf_peek_u8(p1, sizeof(x), &v8),
+ SSH_ERR_MESSAGE_INCOMPLETE);
+ ASSERT_INT_EQ(sshbuf_peek_u8(p1, 1000, &v8),
+ SSH_ERR_MESSAGE_INCOMPLETE);
+ sshbuf_free(p1);
+ TEST_DONE();
+
+ TEST_START("sshbuf_poke_u64");
+ p1 = sshbuf_new();
+ ASSERT_PTR_NE(p1, NULL);
+ ASSERT_INT_EQ(sshbuf_reserve(p1, 10, NULL), 0);
+ /* poke at start of buffer */
+ ASSERT_INT_EQ(sshbuf_poke_u64(p1, 0, 0xa1b2c3d4e5f60718ULL), 0);
+ s2 = sshbuf_dtob16(p1);
+ ASSERT_PTR_NE(s2, NULL);
+ ASSERT_STRING_EQ(s2, "a1b2c3d4e5f607180000");
+ free(s2);
+ sshbuf_reset(p1);
+ ASSERT_INT_EQ(sshbuf_reserve(p1, 10, NULL), 0);
+ /* poke aligned with end of buffer */
+ ASSERT_INT_EQ(sshbuf_poke_u64(p1, 2, 0xa1b2c3d4e5f60718ULL), 0);
+ s2 = sshbuf_dtob16(p1);
+ ASSERT_PTR_NE(s2, NULL);
+ ASSERT_STRING_EQ(s2, "0000a1b2c3d4e5f60718");
+ free(s2);
+ sshbuf_reset(p1);
+ ASSERT_INT_EQ(sshbuf_reserve(p1, 10, NULL), 0);
+ /* poke past end of buffer */
+ ASSERT_INT_EQ(sshbuf_poke_u64(p1, 3, 0xa1b2c3d4e5f60718ULL),
+ SSH_ERR_NO_BUFFER_SPACE);
+ ASSERT_INT_EQ(sshbuf_poke_u64(p1, 10, 0xa1b2c3d4e5f60718ULL),
+ SSH_ERR_NO_BUFFER_SPACE);
+ ASSERT_INT_EQ(sshbuf_poke_u64(p1, 1000, 0xa1b2c3d4e5f60718ULL),
+ SSH_ERR_NO_BUFFER_SPACE);
+ /* ensure failed pokes do not modify buffer */
+ s2 = sshbuf_dtob16(p1);
+ ASSERT_PTR_NE(s2, NULL);
+ ASSERT_STRING_EQ(s2, "00000000000000000000");
+ sshbuf_free(p1);
+ TEST_DONE();
+
+ TEST_START("sshbuf_poke_u32");
+ p1 = sshbuf_new();
+ ASSERT_PTR_NE(p1, NULL);
+ ASSERT_INT_EQ(sshbuf_reserve(p1, 10, NULL), 0);
+ /* poke at start of buffer */
+ ASSERT_INT_EQ(sshbuf_poke_u32(p1, 0, 0xa1b2c3d4), 0);
+ s2 = sshbuf_dtob16(p1);
+ ASSERT_PTR_NE(s2, NULL);
+ ASSERT_STRING_EQ(s2, "a1b2c3d4000000000000");
+ free(s2);
+ sshbuf_reset(p1);
+ ASSERT_INT_EQ(sshbuf_reserve(p1, 10, NULL), 0);
+ /* poke aligned with end of buffer */
+ ASSERT_INT_EQ(sshbuf_poke_u32(p1, 6, 0xa1b2c3d4), 0);
+ s2 = sshbuf_dtob16(p1);
+ ASSERT_PTR_NE(s2, NULL);
+ ASSERT_STRING_EQ(s2, "000000000000a1b2c3d4");
+ free(s2);
+ sshbuf_reset(p1);
+ ASSERT_INT_EQ(sshbuf_reserve(p1, 10, NULL), 0);
+ /* poke past end of buffer */
+ ASSERT_INT_EQ(sshbuf_poke_u32(p1, 7, 0xa1b2c3d4),
+ SSH_ERR_NO_BUFFER_SPACE);
+ ASSERT_INT_EQ(sshbuf_poke_u32(p1, 10, 0xa1b2c3d4),
+ SSH_ERR_NO_BUFFER_SPACE);
+ ASSERT_INT_EQ(sshbuf_poke_u32(p1, 1000, 0xa1b2c3d4),
+ SSH_ERR_NO_BUFFER_SPACE);
+ /* ensure failed pokes do not modify buffer */
+ s2 = sshbuf_dtob16(p1);
+ ASSERT_PTR_NE(s2, NULL);
+ ASSERT_STRING_EQ(s2, "00000000000000000000");
+ sshbuf_free(p1);
+ TEST_DONE();
+
+ TEST_START("sshbuf_poke_u16");
+ p1 = sshbuf_new();
+ ASSERT_PTR_NE(p1, NULL);
+ ASSERT_INT_EQ(sshbuf_reserve(p1, 10, NULL), 0);
+ /* poke at start of buffer */
+ ASSERT_INT_EQ(sshbuf_poke_u16(p1, 0, 0xa1b2), 0);
+ s2 = sshbuf_dtob16(p1);
+ ASSERT_PTR_NE(s2, NULL);
+ ASSERT_STRING_EQ(s2, "a1b20000000000000000");
+ free(s2);
+ sshbuf_reset(p1);
+ ASSERT_INT_EQ(sshbuf_reserve(p1, 10, NULL), 0);
+ /* poke aligned with end of buffer */
+ ASSERT_INT_EQ(sshbuf_poke_u16(p1, 8, 0xa1b2), 0);
+ s2 = sshbuf_dtob16(p1);
+ ASSERT_PTR_NE(s2, NULL);
+ ASSERT_STRING_EQ(s2, "0000000000000000a1b2");
+ free(s2);
+ sshbuf_reset(p1);
+ ASSERT_INT_EQ(sshbuf_reserve(p1, 10, NULL), 0);
+ /* poke past end of buffer */
+ ASSERT_INT_EQ(sshbuf_poke_u16(p1, 9, 0xa1b2),
+ SSH_ERR_NO_BUFFER_SPACE);
+ ASSERT_INT_EQ(sshbuf_poke_u16(p1, 10, 0xa1b2),
+ SSH_ERR_NO_BUFFER_SPACE);
+ ASSERT_INT_EQ(sshbuf_poke_u16(p1, 1000, 0xa1b2),
+ SSH_ERR_NO_BUFFER_SPACE);
+ /* ensure failed pokes do not modify buffer */
+ s2 = sshbuf_dtob16(p1);
+ ASSERT_PTR_NE(s2, NULL);
+ ASSERT_STRING_EQ(s2, "00000000000000000000");
+ sshbuf_free(p1);
+ TEST_DONE();
+
+ TEST_START("sshbuf_poke_u8");
+ p1 = sshbuf_new();
+ ASSERT_PTR_NE(p1, NULL);
+ ASSERT_INT_EQ(sshbuf_reserve(p1, 10, NULL), 0);
+ /* poke at start of buffer */
+ ASSERT_INT_EQ(sshbuf_poke_u8(p1, 0, 0xa1), 0);
+ s2 = sshbuf_dtob16(p1);
+ ASSERT_PTR_NE(s2, NULL);
+ ASSERT_STRING_EQ(s2, "a1000000000000000000");
+ free(s2);
+ sshbuf_reset(p1);
+ ASSERT_INT_EQ(sshbuf_reserve(p1, 10, NULL), 0);
+ /* poke aligned with end of buffer */
+ ASSERT_INT_EQ(sshbuf_poke_u8(p1, 9, 0xa1), 0);
+ s2 = sshbuf_dtob16(p1);
+ ASSERT_PTR_NE(s2, NULL);
+ ASSERT_STRING_EQ(s2, "000000000000000000a1");
+ free(s2);
+ sshbuf_reset(p1);
+ ASSERT_INT_EQ(sshbuf_reserve(p1, 10, NULL), 0);
+ /* poke past end of buffer */
+ ASSERT_INT_EQ(sshbuf_poke_u8(p1, 10, 0xa1), SSH_ERR_NO_BUFFER_SPACE);
+ ASSERT_INT_EQ(sshbuf_poke_u8(p1, 1000, 0xa1), SSH_ERR_NO_BUFFER_SPACE);
+ /* ensure failed pokes do not modify buffer */
+ s2 = sshbuf_dtob16(p1);
+ ASSERT_PTR_NE(s2, NULL);
+ ASSERT_STRING_EQ(s2, "00000000000000000000");
+ sshbuf_free(p1);
+ TEST_DONE();
+
+ TEST_START("sshbuf_poke");
+ p1 = sshbuf_new();
+ ASSERT_PTR_NE(p1, NULL);
+ ASSERT_INT_EQ(sshbuf_reserve(p1, 10, NULL), 0);
+ /* poke at start of buffer */
+ ASSERT_INT_EQ(sshbuf_poke(p1, 0, "hello!", 6), 0);
+ s2 = sshbuf_dtob16(p1);
+ ASSERT_PTR_NE(s2, NULL);
+ ASSERT_STRING_EQ(s2, "68656c6c6f2100000000");
+ free(s2);
+ sshbuf_reset(p1);
+ ASSERT_INT_EQ(sshbuf_reserve(p1, 10, NULL), 0);
+ /* poke aligned with end of buffer */
+ ASSERT_INT_EQ(sshbuf_poke(p1, 4, "hello!", 6), 0);
+ s2 = sshbuf_dtob16(p1);
+ ASSERT_PTR_NE(s2, NULL);
+ ASSERT_STRING_EQ(s2, "0000000068656c6c6f21");
+ free(s2);
+ sshbuf_reset(p1);
+ ASSERT_INT_EQ(sshbuf_reserve(p1, 10, NULL), 0);
+ /* poke past end of buffer */
+ ASSERT_INT_EQ(sshbuf_poke(p1, 7, "hello!", 6),
+ SSH_ERR_NO_BUFFER_SPACE);
+ ASSERT_INT_EQ(sshbuf_poke(p1, 10, "hello!", 6),
+ SSH_ERR_NO_BUFFER_SPACE);
+ ASSERT_INT_EQ(sshbuf_poke(p1, 1000, "hello!", 6),
+ SSH_ERR_NO_BUFFER_SPACE);
+ /* ensure failed pokes do not modify buffer */
+ s2 = sshbuf_dtob16(p1);
+ ASSERT_PTR_NE(s2, NULL);
+ ASSERT_STRING_EQ(s2, "00000000000000000000");
+ sshbuf_free(p1);
+ TEST_DONE();
}
diff --git a/crypto/openssh/regress/unittests/sshbuf/test_sshbuf_getput_crypto.c b/crypto/openssh/regress/unittests/sshbuf/test_sshbuf_getput_crypto.c
index a68e1329e40b..492b3bdf0627 100644
--- a/crypto/openssh/regress/unittests/sshbuf/test_sshbuf_getput_crypto.c
+++ b/crypto/openssh/regress/unittests/sshbuf/test_sshbuf_getput_crypto.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: test_sshbuf_getput_crypto.c,v 1.1 2014/04/30 05:32:00 djm Exp $ */
+/* $OpenBSD: test_sshbuf_getput_crypto.c,v 1.2 2019/01/21 12:29:35 djm Exp $ */
/*
* Regress test for sshbuf.h buffer API
*
@@ -7,6 +7,8 @@
#include "includes.h"
+#ifdef WITH_OPENSSL
+
#include <sys/types.h>
#include <sys/param.h>
#include <stdio.h>
@@ -33,7 +35,6 @@ 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";
@@ -77,54 +78,6 @@ sshbuf_getput_crypto_tests(void)
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();
@@ -174,88 +127,6 @@ sshbuf_getput_crypto_tests(void)
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();
@@ -264,8 +135,8 @@ sshbuf_getput_crypto_tests(void)
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);
+ bn2 = NULL;
+ 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);
@@ -279,8 +150,8 @@ sshbuf_getput_crypto_tests(void)
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);
+ bn2 = NULL;
+ 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);
@@ -294,8 +165,8 @@ sshbuf_getput_crypto_tests(void)
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);
+ bn2 = NULL;
+ 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);
@@ -312,8 +183,8 @@ sshbuf_getput_crypto_tests(void)
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);
+ bn2 = NULL;
+ 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);
@@ -328,8 +199,8 @@ sshbuf_getput_crypto_tests(void)
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);
+ bn2 = NULL;
+ 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);
@@ -343,8 +214,8 @@ sshbuf_getput_crypto_tests(void)
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);
+ bn2 = NULL;
+ 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);
@@ -407,3 +278,4 @@ sshbuf_getput_crypto_tests(void)
#endif
}
+#endif /* WITH_OPENSSL */
diff --git a/crypto/openssh/regress/unittests/sshbuf/test_sshbuf_getput_fuzz.c b/crypto/openssh/regress/unittests/sshbuf/test_sshbuf_getput_fuzz.c
index c6b5c29d176b..1ca30be973ce 100644
--- a/crypto/openssh/regress/unittests/sshbuf/test_sshbuf_getput_fuzz.c
+++ b/crypto/openssh/regress/unittests/sshbuf/test_sshbuf_getput_fuzz.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: test_sshbuf_getput_fuzz.c,v 1.2 2014/05/02 02:54:00 djm Exp $ */
+/* $OpenBSD: test_sshbuf_getput_fuzz.c,v 1.4 2019/01/21 12:29:35 djm Exp $ */
/*
* Regress test for sshbuf.h buffer API
*
@@ -32,10 +32,12 @@ static void
attempt_parse_blob(u_char *blob, size_t len)
{
struct sshbuf *p1;
+#ifdef WITH_OPENSSL
BIGNUM *bn;
#if defined(OPENSSL_HAS_ECC) && defined(OPENSSL_HAS_NISTP256)
EC_KEY *eck;
-#endif
+#endif /* defined(OPENSSL_HAS_ECC) && defined(OPENSSL_HAS_NISTP256) */
+#endif /* WITH_OPENSSL */
u_char *s;
size_t l;
u_int8_t u8;
@@ -54,18 +56,17 @@ attempt_parse_blob(u_char *blob, size_t len)
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);
+#ifdef WITH_OPENSSL
+ bn = NULL;
+ 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
+#endif /* defined(OPENSSL_HAS_ECC) && defined(OPENSSL_HAS_NISTP256) */
+#endif /* WITH_OPENSSL */
sshbuf_free(p1);
}
@@ -92,10 +93,6 @@ sshbuf_getput_fuzz_tests(void)
/* 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,
@@ -115,11 +112,15 @@ sshbuf_getput_fuzz_tests(void)
0x55, 0x0f, 0x69, 0xd8, 0x0e, 0xc2, 0x3c, 0xd4,
};
struct fuzz *fuzz;
+ u_int fuzzers = FUZZ_1_BIT_FLIP | FUZZ_2_BIT_FLIP |
+ FUZZ_1_BYTE_FLIP | FUZZ_2_BYTE_FLIP |
+ FUZZ_TRUNCATE_START | FUZZ_TRUNCATE_END;
+
+ if (test_is_fast())
+ fuzzers &= ~(FUZZ_2_BYTE_FLIP|FUZZ_2_BIT_FLIP);
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));
+ fuzz = fuzz_begin(fuzzers, blob, sizeof(blob));
TEST_ONERROR(onerror, fuzz);
for(; !fuzz_done(fuzz); fuzz_next(fuzz))
attempt_parse_blob(blob, sizeof(blob));
diff --git a/crypto/openssh/regress/unittests/sshbuf/test_sshbuf_misc.c b/crypto/openssh/regress/unittests/sshbuf/test_sshbuf_misc.c
index 762a6c31c037..c53db937f2f1 100644
--- a/crypto/openssh/regress/unittests/sshbuf/test_sshbuf_misc.c
+++ b/crypto/openssh/regress/unittests/sshbuf/test_sshbuf_misc.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: test_sshbuf_misc.c,v 1.2 2016/05/03 13:48:33 djm Exp $ */
+/* $OpenBSD: test_sshbuf_misc.c,v 1.4 2019/07/16 22:16:49 djm Exp $ */
/*
* Regress test for sshbuf.h buffer API
*
@@ -19,6 +19,7 @@
#include "../test_helper/test_helper.h"
#include "sshbuf.h"
+#include "ssherr.h"
void sshbuf_misc_tests(void);
@@ -26,7 +27,7 @@ void
sshbuf_misc_tests(void)
{
struct sshbuf *p1;
- char tmp[512], *p;
+ char tmp[512], msg[] = "imploring ping silence ping over", *p;
FILE *out;
size_t sz;
@@ -60,48 +61,48 @@ sshbuf_misc_tests(void)
sshbuf_free(p1);
TEST_DONE();
- TEST_START("sshbuf_dtob64 len 1");
+ TEST_START("sshbuf_dtob64_string len 1");
p1 = sshbuf_new();
ASSERT_PTR_NE(p1, NULL);
ASSERT_INT_EQ(sshbuf_put_u8(p1, 0x11), 0);
- p = sshbuf_dtob64(p1);
+ p = sshbuf_dtob64_string(p1, 0);
ASSERT_PTR_NE(p, NULL);
ASSERT_STRING_EQ(p, "EQ==");
free(p);
sshbuf_free(p1);
TEST_DONE();
- TEST_START("sshbuf_dtob64 len 2");
+ TEST_START("sshbuf_dtob64_string 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);
+ p = sshbuf_dtob64_string(p1, 0);
ASSERT_PTR_NE(p, NULL);
ASSERT_STRING_EQ(p, "ESI=");
free(p);
sshbuf_free(p1);
TEST_DONE();
- TEST_START("sshbuf_dtob64 len 3");
+ TEST_START("sshbuf_dtob64_string 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);
+ p = sshbuf_dtob64_string(p1, 0);
ASSERT_PTR_NE(p, NULL);
ASSERT_STRING_EQ(p, "ESIz");
free(p);
sshbuf_free(p1);
TEST_DONE();
- TEST_START("sshbuf_dtob64 len 8191");
+ TEST_START("sshbuf_dtob64_string 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);
+ p = sshbuf_dtob64_string(p1, 0);
ASSERT_PTR_NE(p, NULL);
ASSERT_SIZE_T_EQ(strlen(p), ((8191 + 2) / 3) * 4);
free(p);
@@ -163,5 +164,55 @@ sshbuf_misc_tests(void)
ASSERT_PTR_EQ(p, NULL);
sshbuf_free(p1);
TEST_DONE();
+
+ TEST_START("sshbuf_cmp");
+ p1 = sshbuf_from(msg, sizeof(msg) - 1);
+ ASSERT_PTR_NE(p1, NULL);
+ ASSERT_INT_EQ(sshbuf_cmp(p1, 0, "i", 1), 0);
+ ASSERT_INT_EQ(sshbuf_cmp(p1, 0, "j", 1), SSH_ERR_INVALID_FORMAT);
+ ASSERT_INT_EQ(sshbuf_cmp(p1, 0, "imploring", 9), 0);
+ ASSERT_INT_EQ(sshbuf_cmp(p1, 0, "implored", 9), SSH_ERR_INVALID_FORMAT);
+ ASSERT_INT_EQ(sshbuf_cmp(p1, 10, "ping", 4), 0);
+ ASSERT_INT_EQ(sshbuf_cmp(p1, 10, "ring", 4), SSH_ERR_INVALID_FORMAT);
+ ASSERT_INT_EQ(sshbuf_cmp(p1, 28, "over", 4), 0);
+ ASSERT_INT_EQ(sshbuf_cmp(p1, 28, "rove", 4), SSH_ERR_INVALID_FORMAT);
+ ASSERT_INT_EQ(sshbuf_cmp(p1, 28, "overt", 5),
+ SSH_ERR_MESSAGE_INCOMPLETE);
+ ASSERT_INT_EQ(sshbuf_cmp(p1, 32, "ping", 4),
+ SSH_ERR_MESSAGE_INCOMPLETE);
+ ASSERT_INT_EQ(sshbuf_cmp(p1, 1000, "silence", 7),
+ SSH_ERR_MESSAGE_INCOMPLETE);
+ ASSERT_INT_EQ(sshbuf_cmp(p1, 0, msg, sizeof(msg) - 1), 0);
+ TEST_DONE();
+
+ TEST_START("sshbuf_find");
+ p1 = sshbuf_from(msg, sizeof(msg) - 1);
+ ASSERT_PTR_NE(p1, NULL);
+ ASSERT_INT_EQ(sshbuf_find(p1, 0, "i", 1, &sz), 0);
+ ASSERT_SIZE_T_EQ(sz, 0);
+ ASSERT_INT_EQ(sshbuf_find(p1, 0, "j", 1, &sz), SSH_ERR_INVALID_FORMAT);
+ ASSERT_INT_EQ(sshbuf_find(p1, 0, "imploring", 9, &sz), 0);
+ ASSERT_SIZE_T_EQ(sz, 0);
+ ASSERT_INT_EQ(sshbuf_find(p1, 0, "implored", 9, &sz),
+ SSH_ERR_INVALID_FORMAT);
+ ASSERT_INT_EQ(sshbuf_find(p1, 3, "ping", 4, &sz), 0);
+ ASSERT_SIZE_T_EQ(sz, 10);
+ ASSERT_INT_EQ(sshbuf_find(p1, 11, "ping", 4, &sz), 0);
+ ASSERT_SIZE_T_EQ(sz, 23);
+ ASSERT_INT_EQ(sshbuf_find(p1, 20, "over", 4, &sz), 0);
+ ASSERT_SIZE_T_EQ(sz, 28);
+ ASSERT_INT_EQ(sshbuf_find(p1, 28, "over", 4, &sz), 0);
+ ASSERT_SIZE_T_EQ(sz, 28);
+ ASSERT_INT_EQ(sshbuf_find(p1, 28, "rove", 4, &sz),
+ SSH_ERR_INVALID_FORMAT);
+ ASSERT_INT_EQ(sshbuf_find(p1, 28, "overt", 5, &sz),
+ SSH_ERR_MESSAGE_INCOMPLETE);
+ ASSERT_INT_EQ(sshbuf_find(p1, 32, "ping", 4, &sz),
+ SSH_ERR_MESSAGE_INCOMPLETE);
+ ASSERT_INT_EQ(sshbuf_find(p1, 1000, "silence", 7, &sz),
+ SSH_ERR_MESSAGE_INCOMPLETE);
+ ASSERT_INT_EQ(sshbuf_find(p1, 0, msg + 1, sizeof(msg) - 2, &sz), 0);
+ ASSERT_SIZE_T_EQ(sz, 1);
+ TEST_DONE();
}
diff --git a/crypto/openssh/regress/unittests/sshbuf/tests.c b/crypto/openssh/regress/unittests/sshbuf/tests.c
index 1557e43421ac..29916a10bc5b 100644
--- a/crypto/openssh/regress/unittests/sshbuf/tests.c
+++ b/crypto/openssh/regress/unittests/sshbuf/tests.c
@@ -20,7 +20,9 @@ tests(void)
{
sshbuf_tests();
sshbuf_getput_basic_tests();
+#ifdef WITH_OPENSSL
sshbuf_getput_crypto_tests();
+#endif
sshbuf_misc_tests();
sshbuf_fuzz_tests();
sshbuf_getput_fuzz_tests();
diff --git a/crypto/openssh/regress/unittests/sshkey/Makefile b/crypto/openssh/regress/unittests/sshkey/Makefile
index 1c940bec640b..d4a892375bd7 100644
--- a/crypto/openssh/regress/unittests/sshkey/Makefile
+++ b/crypto/openssh/regress/unittests/sshkey/Makefile
@@ -1,24 +1,26 @@
-# $OpenBSD: Makefile,v 1.5 2017/12/21 00:41:22 djm Exp $
+# $OpenBSD: Makefile,v 1.11 2021/01/09 12:24:31 dtucker Exp $
PROG=test_sshkey
SRCS=tests.c test_sshkey.c test_file.c test_fuzz.c common.c
# From usr.bin/ssh
SRCS+=sshbuf-getput-basic.c sshbuf-getput-crypto.c sshbuf-misc.c sshbuf.c
-SRCS+=atomicio.c sshkey.c authfile.c cipher.c log.c ssh-rsa.c ssh-dss.c
-SRCS+=ssh-ecdsa.c ssh-ed25519.c mac.c umac.c umac128.c hmac.c misc.c
+SRCS+=sshbuf-io.c atomicio.c sshkey.c authfile.c cipher.c log.c ssh-rsa.c
+SRCS+=ssh-dss.c ssh-ecdsa.c ssh-ed25519.c mac.c umac.c umac128.c hmac.c misc.c
SRCS+=ssherr.c uidswap.c cleanup.c xmalloc.c match.c krl.c fatal.c
-SRCS+=addrmatch.c bitmap.c
+SRCS+=addr.c addrmatch.c bitmap.c
SRCS+=ed25519.c hash.c ge25519.c fe25519.c sc25519.c verify.c
-SRCS+=cipher-chachapoly.c chacha.c poly1305.c
+SRCS+=cipher-chachapoly.c chacha.c poly1305.c ssh-ecdsa-sk.c ssh-sk.c
+SRCS+=ssh-ed25519-sk.c sk-usbhid.c
SRCS+=digest-openssl.c
#SRCS+=digest-libc.c
+SRCS+=utf8.c
REGRESS_TARGETS=run-regress-${PROG}
run-regress-${PROG}: ${PROG}
- env ${TEST_ENV} ./${PROG} -d ${.CURDIR}/testdata
+ env ${TEST_ENV} ./${PROG} ${UNITTEST_ARGS} -d ${.CURDIR}/testdata
.include <bsd.regress.mk>
diff --git a/crypto/openssh/regress/unittests/sshkey/common.c b/crypto/openssh/regress/unittests/sshkey/common.c
index e63465c47f7b..effea578c094 100644
--- a/crypto/openssh/regress/unittests/sshkey/common.c
+++ b/crypto/openssh/regress/unittests/sshkey/common.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: common.c,v 1.3 2018/09/13 09:03:20 djm Exp $ */
+/* $OpenBSD: common.c,v 1.4 2020/01/26 00:09:50 djm Exp $ */
/*
* Helpers for key API tests
*
@@ -19,13 +19,15 @@
#include <string.h>
#include <unistd.h>
+#ifdef WITH_OPENSSL
#include <openssl/bn.h>
#include <openssl/rsa.h>
#include <openssl/dsa.h>
#include <openssl/objects.h>
#ifdef OPENSSL_HAS_NISTP256
# include <openssl/ec.h>
-#endif
+#endif /* OPENSSL_HAS_NISTP256 */
+#endif /* WITH_OPENSSL */
#include "openbsd-compat/openssl-compat.h"
@@ -41,13 +43,10 @@
struct sshbuf *
load_file(const char *name)
{
- int fd;
- struct sshbuf *ret;
+ struct sshbuf *ret = NULL;
- 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);
+ ASSERT_INT_EQ(sshbuf_load_file(test_data_file(name), &ret), 0);
+ ASSERT_PTR_NE(ret, NULL);
return ret;
}
@@ -72,6 +71,7 @@ load_text_file(const char *name)
return ret;
}
+#ifdef WITH_OPENSSL
BIGNUM *
load_bignum(const char *name)
{
@@ -160,4 +160,5 @@ dsa_priv_key(struct sshkey *k)
DSA_get0_key(k->dsa, NULL, &priv_key);
return priv_key;
}
+#endif /* WITH_OPENSSL */
diff --git a/crypto/openssh/regress/unittests/sshkey/mktestdata.sh b/crypto/openssh/regress/unittests/sshkey/mktestdata.sh
index 93da34c64671..fcd78e990e8b 100755
--- a/crypto/openssh/regress/unittests/sshkey/mktestdata.sh
+++ b/crypto/openssh/regress/unittests/sshkey/mktestdata.sh
@@ -1,5 +1,5 @@
#!/bin/sh
-# $OpenBSD: mktestdata.sh,v 1.7 2018/09/12 01:36:45 djm Exp $
+# $OpenBSD: mktestdata.sh,v 1.11 2020/06/19 03:48:49 djm Exp $
PW=mekmitasdigoat
@@ -56,8 +56,8 @@ ecdsa_params() {
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
+ grep "ASN1 OID:" | \
+ sed 's/.*: //;s/ *$//' | tr -d '\n' > ${_outbase}.curve
for x in priv pub curve ; do
echo "" >> ${_outbase}.$x
echo ============ ${_outbase}.$x
@@ -70,6 +70,15 @@ set -ex
cd testdata
+if [ -f ../../../misc/sk-dummy/sk-dummy.so ] ; then
+ SK_DUMMY=../../../misc/sk-dummy/sk-dummy.so
+elif [ -f ../../../misc/sk-dummy/obj/sk-dummy.so ] ; then
+ SK_DUMMY=../../../misc/sk-dummy/obj/sk-dummy.so
+else
+ echo "Can't find sk-dummy.so" 1>&2
+ exit 1
+fi
+
rm -f rsa_1 dsa_1 ecdsa_1 ed25519_1
rm -f rsa_2 dsa_2 ecdsa_2 ed25519_2
rm -f rsa_n dsa_n ecdsa_n # new-format keys
@@ -77,35 +86,52 @@ rm -f 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 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 rsa -b 1024 -C "RSA test key #1" -N "" -f rsa_1 -m PEM
+ssh-keygen -t dsa -b 1024 -C "DSA test key #1" -N "" -f dsa_1 -m PEM
+ssh-keygen -t ecdsa -b 256 -C "ECDSA test key #1" -N "" -f ecdsa_1 -m PEM
ssh-keygen -t ed25519 -C "ED25519 test key #1" -N "" -f ed25519_1
+ssh-keygen -w "$SK_DUMMY" -t ecdsa-sk -C "ECDSA-SK test key #1" \
+ -N "" -f ecdsa_sk1
+ssh-keygen -w "$SK_DUMMY" -t ed25519-sk -C "ED25519-SK test key #1" \
+ -N "" -f ed25519_sk1
+
-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
+ssh-keygen -t rsa -b 2048 -C "RSA test key #2" -N "" -f rsa_2 -m PEM
+ssh-keygen -t dsa -b 1024 -C "DSA test key #2" -N "" -f dsa_2 -m PEM
+ssh-keygen -t ecdsa -b 521 -C "ECDSA test key #2" -N "" -f ecdsa_2 -m PEM
+ssh-keygen -t ed25519 -C "ED25519 test key #2" -N "" -f ed25519_2
+ssh-keygen -w "$SK_DUMMY" -t ecdsa-sk -C "ECDSA-SK test key #2" \
+ -N "" -f ecdsa_sk2
+ssh-keygen -w "$SK_DUMMY" -t ed25519-sk -C "ED25519-SK test key #2" \
+ -N "" -f ed25519_sk2
cp rsa_1 rsa_n
cp dsa_1 dsa_n
cp ecdsa_1 ecdsa_n
+ssh-keygen -pf rsa_n -N ""
+ssh-keygen -pf dsa_n -N ""
+ssh-keygen -pf ecdsa_n -N ""
+
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 ecdsa_sk1 ecdsa_sk1_pw
+cp ed25519_sk1 ed25519_sk1_pw
cp rsa_1 rsa_n_pw
cp dsa_1 dsa_n_pw
cp ecdsa_1 ecdsa_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 rsa_1_pw -m PEM -N "$PW"
+ssh-keygen -pf dsa_1_pw -m PEM -N "$PW"
+ssh-keygen -pf ecdsa_1_pw -m PEM -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"
+ssh-keygen -pf ecdsa_sk1_pw -m PEM -N "$PW"
+ssh-keygen -pf ed25519_sk1_pw -N "$PW"
+ssh-keygen -pf rsa_n_pw -N "$PW"
+ssh-keygen -pf dsa_n_pw -N "$PW"
+ssh-keygen -pf ecdsa_n_pw -N "$PW"
rsa_params rsa_1 rsa_1.param
rsa_params rsa_2 rsa_2.param
@@ -113,7 +139,7 @@ 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
+# XXX ed25519, *sk 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 \
@@ -127,6 +153,13 @@ ssh-keygen -s rsa_2 -I hugo -n user1,user2 \
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 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 ecdsa_sk1.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_sk1.pub
+
# Make a few RSA variant signature too.
cp rsa_1 rsa_1_sha1
@@ -148,30 +181,42 @@ 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 -s ecdsa_1 -I julius -n host1,host2 -h \
+ -V 19990101:20110101 -z 7 ecdsa_sk1.pub
+ssh-keygen -s ed25519_1 -I julius -n host1,host2 -h \
+ -V 19990101:20110101 -z 8 ed25519_sk1.pub
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 ecdsa_sk1 | awk '{print $2}' > ecdsa_sk1.fp
+ssh-keygen -lf ed25519_sk1 | awk '{print $2}' > ed25519_sk1.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 ecdsa_sk2 | awk '{print $2}' > ecdsa_sk2.fp
+ssh-keygen -lf ed25519_sk2 | awk '{print $2}' > ed25519_sk2.fp
+ssh-keygen -lf rsa_1-cert.pub | awk '{print $2}' > rsa_1-cert.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 -lf ecdsa_sk1-cert.pub | awk '{print $2}' > ecdsa_sk1-cert.fp
+ssh-keygen -lf ed25519_sk1-cert.pub | awk '{print $2}' > ed25519_sk1-cert.fp
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 ecdsa_sk1 | awk '{print $2}' > ecdsa_sk1.fp.bb
+ssh-keygen -Bf ed25519_sk1 | awk '{print $2}' > ed25519_sk1.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)
+ssh-keygen -Bf ecdsa_sk2 | awk '{print $2}' > ecdsa_sk2.fp.bb
+ssh-keygen -Bf ed25519_sk2 | awk '{print $2}' > ed25519_sk2.fp.bb
echo "$PW" > pw
diff --git a/crypto/openssh/regress/unittests/sshkey/test_file.c b/crypto/openssh/regress/unittests/sshkey/test_file.c
index 65610dacc7f6..7d767336ef47 100644
--- a/crypto/openssh/regress/unittests/sshkey/test_file.c
+++ b/crypto/openssh/regress/unittests/sshkey/test_file.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: test_file.c,v 1.8 2018/09/13 09:03:20 djm Exp $ */
+/* $OpenBSD: test_file.c,v 1.9 2020/06/19 03:48:49 djm Exp $ */
/*
* Regress test for sshkey.h key management API
*
@@ -19,13 +19,15 @@
#include <string.h>
#include <unistd.h>
+#ifdef WITH_OPENSSL
#include <openssl/bn.h>
#include <openssl/rsa.h>
#include <openssl/dsa.h>
#include <openssl/objects.h>
#ifdef OPENSSL_HAS_NISTP256
# include <openssl/ec.h>
-#endif
+#endif /* OPENSSL_HAS_NISTP256 */
+#endif /* WITH_OPENSSL */
#include "../test_helper/test_helper.h"
@@ -44,7 +46,9 @@ sshkey_file_tests(void)
{
struct sshkey *k1, *k2;
struct sshbuf *buf, *pw;
+#ifdef WITH_OPENSSL
BIGNUM *a, *b, *c;
+#endif
char *cp;
TEST_START("load passphrase");
@@ -52,6 +56,7 @@ sshkey_file_tests(void)
TEST_DONE();
+#ifdef WITH_OPENSSL
TEST_START("parse RSA from private");
buf = load_file("rsa_1");
ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", &k1, NULL), 0);
@@ -350,6 +355,7 @@ sshkey_file_tests(void)
sshkey_free(k1);
#endif /* OPENSSL_HAS_ECC */
+#endif /* WITH_OPENSSL */
TEST_START("parse Ed25519 from private");
buf = load_file("ed25519_1");
@@ -416,6 +422,137 @@ sshkey_file_tests(void)
sshkey_free(k1);
+#if defined(WITH_OPENSSL) && defined(OPENSSL_HAS_ECC)
+ TEST_START("parse ECDSA-SK from private");
+ buf = load_file("ecdsa_sk1");
+ ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", &k1, NULL), 0);
+ sshbuf_free(buf);
+ ASSERT_PTR_NE(k1, NULL);
+ ASSERT_INT_EQ(k1->type, KEY_ECDSA_SK);
+ TEST_DONE();
+
+ TEST_START("parse ECDSA-SK from private w/ passphrase");
+ buf = load_file("ecdsa_sk1_pw");
+ ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf,
+ (const char *)sshbuf_ptr(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-SK from public");
+ ASSERT_INT_EQ(sshkey_load_public(test_data_file("ecdsa_sk1.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-SK cert");
+ ASSERT_INT_EQ(sshkey_load_cert(test_data_file("ecdsa_sk1"), &k2), 0);
+ ASSERT_PTR_NE(k2, NULL);
+ ASSERT_INT_EQ(k2->type, KEY_ECDSA_SK_CERT);
+ ASSERT_INT_EQ(sshkey_equal(k1, k2), 0);
+ ASSERT_INT_EQ(sshkey_equal_public(k1, k2), 1);
+ TEST_DONE();
+
+ TEST_START("ECDSA-SK key hex fingerprint");
+ buf = load_text_file("ecdsa_sk1.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-SK cert hex fingerprint");
+ buf = load_text_file("ecdsa_sk1-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-SK key bubblebabble fingerprint");
+ buf = load_text_file("ecdsa_sk1.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 Ed25519-SK from private");
+ buf = load_file("ed25519_sk1");
+ ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", &k1, NULL), 0);
+ sshbuf_free(buf);
+ ASSERT_PTR_NE(k1, NULL);
+ ASSERT_INT_EQ(k1->type, KEY_ED25519_SK);
+ /* XXX check key contents */
+ TEST_DONE();
+
+ TEST_START("parse Ed25519-SK from private w/ passphrase");
+ buf = load_file("ed25519_sk1_pw");
+ ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf,
+ (const char *)sshbuf_ptr(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-SK from public");
+ ASSERT_INT_EQ(sshkey_load_public(test_data_file("ed25519_sk1.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-SK cert");
+ ASSERT_INT_EQ(sshkey_load_cert(test_data_file("ed25519_sk1"), &k2), 0);
+ ASSERT_PTR_NE(k2, NULL);
+ ASSERT_INT_EQ(k2->type, KEY_ED25519_SK_CERT);
+ ASSERT_INT_EQ(sshkey_equal(k1, k2), 0);
+ ASSERT_INT_EQ(sshkey_equal_public(k1, k2), 1);
+ TEST_DONE();
+
+ TEST_START("Ed25519-SK key hex fingerprint");
+ buf = load_text_file("ed25519_sk1.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-SK cert hex fingerprint");
+ buf = load_text_file("ed25519_sk1-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-SK key bubblebabble fingerprint");
+ buf = load_text_file("ed25519_sk1.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/openssh/regress/unittests/sshkey/test_fuzz.c b/crypto/openssh/regress/unittests/sshkey/test_fuzz.c
index d3b0c92b47a0..f111446a9398 100644
--- a/crypto/openssh/regress/unittests/sshkey/test_fuzz.c
+++ b/crypto/openssh/regress/unittests/sshkey/test_fuzz.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: test_fuzz.c,v 1.8 2017/12/21 00:41:22 djm Exp $ */
+/* $OpenBSD: test_fuzz.c,v 1.12 2020/08/27 03:55:22 djm Exp $ */
/*
* Fuzz tests for key parsing
*
@@ -51,14 +51,16 @@ public_fuzz(struct sshkey *k)
struct sshkey *k1;
struct sshbuf *buf;
struct fuzz *fuzz;
+ u_int fuzzers = FUZZ_1_BIT_FLIP | FUZZ_1_BYTE_FLIP |
+ FUZZ_TRUNCATE_START | FUZZ_TRUNCATE_END;
+ if (test_is_fast())
+ fuzzers &= ~FUZZ_1_BIT_FLIP;
+ if (test_is_slow())
+ fuzzers |= FUZZ_2_BIT_FLIP | FUZZ_2_BYTE_FLIP;
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));
+ fuzz = fuzz_begin(fuzzers, sshbuf_mutable_ptr(buf), sshbuf_len(buf));
ASSERT_INT_EQ(sshkey_from_blob(sshbuf_ptr(buf), sshbuf_len(buf),
&k1), 0);
sshkey_free(k1);
@@ -77,13 +79,19 @@ sig_fuzz(struct sshkey *k, const char *sig_alg)
struct fuzz *fuzz;
u_char *sig, c[] = "some junk to be signed";
size_t l;
+ u_int fuzzers = FUZZ_1_BIT_FLIP | FUZZ_1_BYTE_FLIP | FUZZ_2_BYTE_FLIP |
+ FUZZ_TRUNCATE_START | FUZZ_TRUNCATE_END;
- ASSERT_INT_EQ(sshkey_sign(k, &sig, &l, c, sizeof(c), sig_alg, 0), 0);
+ if (test_is_fast())
+ fuzzers &= ~FUZZ_2_BYTE_FLIP;
+ if (test_is_slow())
+ fuzzers |= FUZZ_2_BIT_FLIP;
+
+ ASSERT_INT_EQ(sshkey_sign(k, &sig, &l, c, sizeof(c),
+ sig_alg, NULL, NULL, 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), NULL, 0), 0);
+ fuzz = fuzz_begin(fuzzers, sig, l);
+ ASSERT_INT_EQ(sshkey_verify(k, sig, l, c, sizeof(c), NULL, 0, NULL), 0);
free(sig);
TEST_ONERROR(onerror, fuzz);
for(; !fuzz_done(fuzz); fuzz_next(fuzz)) {
@@ -91,20 +99,22 @@ sig_fuzz(struct sshkey *k, const char *sig_alg)
if (fuzz_matches_original(fuzz))
continue;
ASSERT_INT_NE(sshkey_verify(k, fuzz_ptr(fuzz), fuzz_len(fuzz),
- c, sizeof(c), NULL, 0), 0);
+ c, sizeof(c), NULL, 0, NULL), 0);
}
fuzz_cleanup(fuzz);
}
+#define NUM_FAST_BASE64_TESTS 1024
+
void
sshkey_fuzz_tests(void)
{
struct sshkey *k1;
struct sshbuf *buf, *fuzzed;
struct fuzz *fuzz;
- int r;
-
+ int r, i;
+#ifdef WITH_OPENSSL
TEST_START("fuzz RSA private");
buf = load_file("rsa_1");
fuzz = fuzz_begin(FUZZ_BASE64, sshbuf_mutable_ptr(buf),
@@ -114,12 +124,14 @@ sshkey_fuzz_tests(void)
sshbuf_free(buf);
ASSERT_PTR_NE(fuzzed = sshbuf_new(), NULL);
TEST_ONERROR(onerror, fuzz);
- for(; !fuzz_done(fuzz); fuzz_next(fuzz)) {
+ for(i = 0; !fuzz_done(fuzz); i++, fuzz_next(fuzz)) {
r = sshbuf_put(fuzzed, fuzz_ptr(fuzz), fuzz_len(fuzz));
ASSERT_INT_EQ(r, 0);
if (sshkey_parse_private_fileblob(fuzzed, "", &k1, NULL) == 0)
sshkey_free(k1);
sshbuf_reset(fuzzed);
+ if (test_is_fast() && i >= NUM_FAST_BASE64_TESTS)
+ break;
}
sshbuf_free(fuzzed);
fuzz_cleanup(fuzz);
@@ -134,12 +146,14 @@ sshkey_fuzz_tests(void)
sshbuf_free(buf);
ASSERT_PTR_NE(fuzzed = sshbuf_new(), NULL);
TEST_ONERROR(onerror, fuzz);
- for(; !fuzz_done(fuzz); fuzz_next(fuzz)) {
+ for(i = 0; !fuzz_done(fuzz); i++, fuzz_next(fuzz)) {
r = sshbuf_put(fuzzed, fuzz_ptr(fuzz), fuzz_len(fuzz));
ASSERT_INT_EQ(r, 0);
if (sshkey_parse_private_fileblob(fuzzed, "", &k1, NULL) == 0)
sshkey_free(k1);
sshbuf_reset(fuzzed);
+ if (test_is_fast() && i >= NUM_FAST_BASE64_TESTS)
+ break;
}
sshbuf_free(fuzzed);
fuzz_cleanup(fuzz);
@@ -154,12 +168,14 @@ sshkey_fuzz_tests(void)
sshbuf_free(buf);
ASSERT_PTR_NE(fuzzed = sshbuf_new(), NULL);
TEST_ONERROR(onerror, fuzz);
- for(; !fuzz_done(fuzz); fuzz_next(fuzz)) {
+ for(i = 0; !fuzz_done(fuzz); i++, fuzz_next(fuzz)) {
r = sshbuf_put(fuzzed, fuzz_ptr(fuzz), fuzz_len(fuzz));
ASSERT_INT_EQ(r, 0);
if (sshkey_parse_private_fileblob(fuzzed, "", &k1, NULL) == 0)
sshkey_free(k1);
sshbuf_reset(fuzzed);
+ if (test_is_fast() && i >= NUM_FAST_BASE64_TESTS)
+ break;
}
sshbuf_free(fuzzed);
fuzz_cleanup(fuzz);
@@ -174,12 +190,14 @@ sshkey_fuzz_tests(void)
sshbuf_free(buf);
ASSERT_PTR_NE(fuzzed = sshbuf_new(), NULL);
TEST_ONERROR(onerror, fuzz);
- for(; !fuzz_done(fuzz); fuzz_next(fuzz)) {
+ for(i = 0; !fuzz_done(fuzz); i++, fuzz_next(fuzz)) {
r = sshbuf_put(fuzzed, fuzz_ptr(fuzz), fuzz_len(fuzz));
ASSERT_INT_EQ(r, 0);
if (sshkey_parse_private_fileblob(fuzzed, "", &k1, NULL) == 0)
sshkey_free(k1);
sshbuf_reset(fuzzed);
+ if (test_is_fast() && i >= NUM_FAST_BASE64_TESTS)
+ break;
}
sshbuf_free(fuzzed);
fuzz_cleanup(fuzz);
@@ -195,12 +213,14 @@ sshkey_fuzz_tests(void)
sshbuf_free(buf);
ASSERT_PTR_NE(fuzzed = sshbuf_new(), NULL);
TEST_ONERROR(onerror, fuzz);
- for(; !fuzz_done(fuzz); fuzz_next(fuzz)) {
+ for(i = 0; !fuzz_done(fuzz); i++, fuzz_next(fuzz)) {
r = sshbuf_put(fuzzed, fuzz_ptr(fuzz), fuzz_len(fuzz));
ASSERT_INT_EQ(r, 0);
if (sshkey_parse_private_fileblob(fuzzed, "", &k1, NULL) == 0)
sshkey_free(k1);
sshbuf_reset(fuzzed);
+ if (test_is_fast() && i >= NUM_FAST_BASE64_TESTS)
+ break;
}
sshbuf_free(fuzzed);
fuzz_cleanup(fuzz);
@@ -215,17 +235,20 @@ sshkey_fuzz_tests(void)
sshbuf_free(buf);
ASSERT_PTR_NE(fuzzed = sshbuf_new(), NULL);
TEST_ONERROR(onerror, fuzz);
- for(; !fuzz_done(fuzz); fuzz_next(fuzz)) {
+ for(i = 0; !fuzz_done(fuzz); i++, fuzz_next(fuzz)) {
r = sshbuf_put(fuzzed, fuzz_ptr(fuzz), fuzz_len(fuzz));
ASSERT_INT_EQ(r, 0);
if (sshkey_parse_private_fileblob(fuzzed, "", &k1, NULL) == 0)
sshkey_free(k1);
sshbuf_reset(fuzzed);
+ if (test_is_fast() && i >= NUM_FAST_BASE64_TESTS)
+ break;
}
sshbuf_free(fuzzed);
fuzz_cleanup(fuzz);
TEST_DONE();
-#endif
+#endif /* OPENSSL_HAS_ECC */
+#endif /* WITH_OPENSSL */
TEST_START("fuzz Ed25519 private");
buf = load_file("ed25519_1");
@@ -236,17 +259,20 @@ sshkey_fuzz_tests(void)
sshbuf_free(buf);
ASSERT_PTR_NE(fuzzed = sshbuf_new(), NULL);
TEST_ONERROR(onerror, fuzz);
- for(; !fuzz_done(fuzz); fuzz_next(fuzz)) {
+ for(i = 0; !fuzz_done(fuzz); i++, fuzz_next(fuzz)) {
r = sshbuf_put(fuzzed, fuzz_ptr(fuzz), fuzz_len(fuzz));
ASSERT_INT_EQ(r, 0);
if (sshkey_parse_private_fileblob(fuzzed, "", &k1, NULL) == 0)
sshkey_free(k1);
sshbuf_reset(fuzzed);
+ if (test_is_fast() && i >= NUM_FAST_BASE64_TESTS)
+ break;
}
sshbuf_free(fuzzed);
fuzz_cleanup(fuzz);
TEST_DONE();
+#ifdef WITH_OPENSSL
TEST_START("fuzz RSA public");
buf = load_file("rsa_1");
ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", &k1, NULL), 0);
@@ -289,7 +315,8 @@ sshkey_fuzz_tests(void)
public_fuzz(k1);
sshkey_free(k1);
TEST_DONE();
-#endif
+#endif /* OPENSSL_HAS_ECC */
+#endif /* WITH_OPENSSL */
TEST_START("fuzz Ed25519 public");
buf = load_file("ed25519_1");
@@ -305,6 +332,7 @@ sshkey_fuzz_tests(void)
sshkey_free(k1);
TEST_DONE();
+#ifdef WITH_OPENSSL
TEST_START("fuzz RSA sig");
buf = load_file("rsa_1");
ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", &k1, NULL), 0);
@@ -345,7 +373,8 @@ sshkey_fuzz_tests(void)
sig_fuzz(k1, NULL);
sshkey_free(k1);
TEST_DONE();
-#endif
+#endif /* OPENSSL_HAS_ECC */
+#endif /* WITH_OPENSSL */
TEST_START("fuzz Ed25519 sig");
buf = load_file("ed25519_1");
@@ -356,5 +385,6 @@ sshkey_fuzz_tests(void)
TEST_DONE();
/* XXX fuzz decoded new-format blobs too */
+/* XXX fuzz XMSS too */
}
diff --git a/crypto/openssh/regress/unittests/sshkey/test_sshkey.c b/crypto/openssh/regress/unittests/sshkey/test_sshkey.c
index 3415ed68196a..5872d7406ffc 100644
--- a/crypto/openssh/regress/unittests/sshkey/test_sshkey.c
+++ b/crypto/openssh/regress/unittests/sshkey/test_sshkey.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: test_sshkey.c,v 1.17 2018/09/13 09:03:20 djm Exp $ */
+/* $OpenBSD: test_sshkey.c,v 1.21 2020/08/27 03:55:22 djm Exp $ */
/*
* Regress test for sshkey.h key management API
*
@@ -51,9 +51,10 @@ put_opt(struct sshbuf *b, const char *name, const char *value)
sshbuf_free(sect);
}
+#ifdef WITH_OPENSSL
static void
-build_cert(struct sshbuf *b, const struct sshkey *k, const char *type,
- const struct sshkey *sign_key, const struct sshkey *ca_key,
+build_cert(struct sshbuf *b, struct sshkey *k, const char *type,
+ struct sshkey *sign_key, struct sshkey *ca_key,
const char *sig_alg)
{
struct sshbuf *ca_buf, *pk, *principals, *critopts, *exts;
@@ -101,7 +102,7 @@ build_cert(struct sshbuf *b, const struct sshkey *k, const char *type,
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), sig_alg, 0), 0);
+ sshbuf_ptr(b), sshbuf_len(b), sig_alg, NULL, NULL, 0), 0);
ASSERT_INT_EQ(sshbuf_put_string(b, sigblob, siglen), 0); /* signature */
free(sigblob);
@@ -111,6 +112,7 @@ build_cert(struct sshbuf *b, const struct sshkey *k, const char *type,
sshbuf_free(principals);
sshbuf_free(pk);
}
+#endif /* WITH_OPENSSL */
static void
signature_test(struct sshkey *k, struct sshkey *bad, const char *sig_alg,
@@ -119,14 +121,15 @@ signature_test(struct sshkey *k, struct sshkey *bad, const char *sig_alg,
size_t len;
u_char *sig;
- ASSERT_INT_EQ(sshkey_sign(k, &sig, &len, d, l, sig_alg, 0), 0);
+ ASSERT_INT_EQ(sshkey_sign(k, &sig, &len, d, l, sig_alg,
+ NULL, NULL, 0), 0);
ASSERT_SIZE_T_GT(len, 8);
ASSERT_PTR_NE(sig, NULL);
- ASSERT_INT_EQ(sshkey_verify(k, sig, len, d, l, NULL, 0), 0);
- ASSERT_INT_NE(sshkey_verify(bad, sig, len, d, l, NULL, 0), 0);
+ ASSERT_INT_EQ(sshkey_verify(k, sig, len, d, l, NULL, 0, NULL), 0);
+ ASSERT_INT_NE(sshkey_verify(bad, sig, len, d, l, NULL, 0, NULL), 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, NULL, 0), 0);
+ ASSERT_INT_NE(sshkey_verify(k, sig, len, d, l, NULL, 0, NULL), 0);
free(sig);
}
@@ -177,10 +180,13 @@ get_private(const char *n)
void
sshkey_tests(void)
{
- struct sshkey *k1, *k2, *k3, *k4, *kr, *kd, *kf;
+ struct sshkey *k1, *k2, *k3, *kf;
+#ifdef WITH_OPENSSL
+ struct sshkey *k4, *kr, *kd;
#ifdef OPENSSL_HAS_ECC
struct sshkey *ke;
-#endif
+#endif /* OPENSSL_HAS_ECC */
+#endif /* WITH_OPENSSL */
struct sshbuf *b;
TEST_START("new invalid");
@@ -194,6 +200,7 @@ sshkey_tests(void)
sshkey_free(k1);
TEST_DONE();
+#ifdef WITH_OPENSSL
TEST_START("new/free KEY_RSA");
k1 = sshkey_new(KEY_RSA);
ASSERT_PTR_NE(k1, NULL);
@@ -282,7 +289,8 @@ sshkey_tests(void)
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
+#endif /* OPENSSL_HAS_ECC */
+#endif /* WITH_OPENSSL */
TEST_START("generate KEY_ED25519");
ASSERT_INT_EQ(sshkey_generate(KEY_ED25519, 256, &kf), 0);
@@ -292,6 +300,7 @@ sshkey_tests(void)
ASSERT_PTR_NE(kf->ed25519_sk, NULL);
TEST_DONE();
+#ifdef WITH_OPENSSL
TEST_START("demote KEY_RSA");
ASSERT_INT_EQ(sshkey_from_private(kr, &k1), 0);
ASSERT_PTR_NE(k1, NULL);
@@ -339,7 +348,8 @@ sshkey_tests(void)
ASSERT_INT_EQ(sshkey_equal(ke, k1), 1);
sshkey_free(k1);
TEST_DONE();
-#endif
+#endif /* OPENSSL_HAS_ECC */
+#endif /* WITH_OPENSSL */
TEST_START("demote KEY_ED25519");
ASSERT_INT_EQ(sshkey_from_private(kf, &k1), 0);
@@ -355,17 +365,20 @@ sshkey_tests(void)
sshkey_free(k1);
TEST_DONE();
+#ifdef WITH_OPENSSL
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
+#endif /* OPENSSL_HAS_ECC */
ASSERT_INT_EQ(sshkey_equal(kd, kf), 0);
TEST_DONE();
+#endif /* WITH_OPENSSL */
TEST_START("equal different keys");
+#ifdef WITH_OPENSSL
ASSERT_INT_EQ(sshkey_generate(KEY_RSA, 1024, &k1), 0);
ASSERT_INT_EQ(sshkey_equal(kr, k1), 0);
sshkey_free(k1);
@@ -376,17 +389,20 @@ sshkey_tests(void)
ASSERT_INT_EQ(sshkey_generate(KEY_ECDSA, 256, &k1), 0);
ASSERT_INT_EQ(sshkey_equal(ke, k1), 0);
sshkey_free(k1);
-#endif
+#endif /* OPENSSL_HAS_ECC */
+#endif /* WITH_OPENSSL */
ASSERT_INT_EQ(sshkey_generate(KEY_ED25519, 256, &k1), 0);
ASSERT_INT_EQ(sshkey_equal(kf, k1), 0);
sshkey_free(k1);
TEST_DONE();
+#ifdef WITH_OPENSSL
sshkey_free(kr);
sshkey_free(kd);
#ifdef OPENSSL_HAS_ECC
sshkey_free(ke);
-#endif
+#endif /* OPENSSL_HAS_ECC */
+#endif /* WITH_OPENSSL */
sshkey_free(kf);
TEST_START("certify key");
@@ -423,7 +439,7 @@ sshkey_tests(void)
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, NULL), 0);
+ ASSERT_INT_EQ(sshkey_certify(k1, k2, NULL, NULL, NULL), 0);
b = sshbuf_new();
ASSERT_PTR_NE(b, NULL);
ASSERT_INT_EQ(sshkey_putb(k1, b), 0);
@@ -435,6 +451,7 @@ sshkey_tests(void)
sshbuf_reset(b);
TEST_DONE();
+#ifdef WITH_OPENSSL
TEST_START("sign and verify RSA");
k1 = get_private("rsa_1");
ASSERT_INT_EQ(sshkey_load_public(test_data_file("rsa_2.pub"), &k2,
@@ -480,7 +497,8 @@ sshkey_tests(void)
sshkey_free(k1);
sshkey_free(k2);
TEST_DONE();
-#endif
+#endif /* OPENSSL_HAS_ECC */
+#endif /* WITH_OPENSSL */
TEST_START("sign and verify ED25519");
k1 = get_private("ed25519_1");
@@ -491,6 +509,7 @@ sshkey_tests(void)
sshkey_free(k2);
TEST_DONE();
+#ifdef WITH_OPENSSL
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,
@@ -505,5 +524,5 @@ sshkey_tests(void)
sshkey_free(k3);
sshbuf_free(b);
TEST_DONE();
-
+#endif /* WITH_OPENSSL */
}
diff --git a/crypto/openssh/regress/unittests/sshkey/testdata/dsa_n b/crypto/openssh/regress/unittests/sshkey/testdata/dsa_n
index d3f24824f8d5..657624e0e72f 100644
--- a/crypto/openssh/regress/unittests/sshkey/testdata/dsa_n
+++ b/crypto/openssh/regress/unittests/sshkey/testdata/dsa_n
@@ -1,12 +1,21 @@
------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-----
+-----BEGIN OPENSSH PRIVATE KEY-----
+b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAABswAAAAdzc2gtZH
+NzAAAAgQD6kutNFRsHTwEAv6d39Lhsqy1apdHBZ9c2HfyRr7WmypyGIy2mKa43vzXI8CNw
+mRSYs+A6d0vJC7Pl+f9QzJ/04NWOA+MiwfurwrR3CRe61QRYb8PymcHOxueHs95IcjrbIP
+Nn86cjnPP5qvv/guUzCjuww4zBdJOXpligrGt2XwAAABUAowP/nSpDLuPwloyT7X5e2DWk
+rTUAAACBAO7l9QVVbSSoy5lq6cOtvpf8UlwOa6+zBwblo4gmFd1RwX1yWkA8kQ7RrhCSg8
+Hc6mIGnKRgKRli/3LgbSfZ0obFJehkRtEWtN4Ph8fVUeS74iQbIwFQeKlYHIlNTRoGtAbd
+i3nHdV+BBkEQc1V3rjqYqhjOoz/yNsgzLND26HrdAAAAgQDnV6cn5qGxAWjqmQLr4I9T9L
+oYxtj99VH7q79thVjwVNwPaq5MWzl8BNC8L4wr67EFf5a2ISc/7YsrONFXmobpVmROUgBz
+FxiH/eS4i0oGlzI5KO46KLfiyvOJbS8psGeEDJ2I52UknJX9VLskDHFLW9+PiNLvWHJ8oa
+dpkhbELQAAAdhWTOFbVkzhWwAAAAdzc2gtZHNzAAAAgQD6kutNFRsHTwEAv6d39Lhsqy1a
+pdHBZ9c2HfyRr7WmypyGIy2mKa43vzXI8CNwmRSYs+A6d0vJC7Pl+f9QzJ/04NWOA+Miwf
+urwrR3CRe61QRYb8PymcHOxueHs95IcjrbIPNn86cjnPP5qvv/guUzCjuww4zBdJOXplig
+rGt2XwAAABUAowP/nSpDLuPwloyT7X5e2DWkrTUAAACBAO7l9QVVbSSoy5lq6cOtvpf8Ul
+wOa6+zBwblo4gmFd1RwX1yWkA8kQ7RrhCSg8Hc6mIGnKRgKRli/3LgbSfZ0obFJehkRtEW
+tN4Ph8fVUeS74iQbIwFQeKlYHIlNTRoGtAbdi3nHdV+BBkEQc1V3rjqYqhjOoz/yNsgzLN
+D26HrdAAAAgQDnV6cn5qGxAWjqmQLr4I9T9LoYxtj99VH7q79thVjwVNwPaq5MWzl8BNC8
+L4wr67EFf5a2ISc/7YsrONFXmobpVmROUgBzFxiH/eS4i0oGlzI5KO46KLfiyvOJbS8psG
+eEDJ2I52UknJX9VLskDHFLW9+PiNLvWHJ8oadpkhbELQAAABRYIbQ5KfXsZuBPuWe5FJz3
+ldaEgwAAAAAB
+-----END OPENSSH PRIVATE KEY-----
diff --git a/crypto/openssh/regress/unittests/sshkey/testdata/ecdsa_n b/crypto/openssh/regress/unittests/sshkey/testdata/ecdsa_n
index 80382b62d2db..9694f32e4407 100644
--- a/crypto/openssh/regress/unittests/sshkey/testdata/ecdsa_n
+++ b/crypto/openssh/regress/unittests/sshkey/testdata/ecdsa_n
@@ -1,5 +1,8 @@
------BEGIN EC PRIVATE KEY-----
-MHcCAQEEIPPNyUAnjvFr+eT/7t/IyjuQQd/aLFiTY92LB9gIjyrMoAoGCCqGSM49
-AwEHoUQDQgAEDFlblkOrW9ydKVhtM+9AY3c9saBE7SG3lFx38nBavkADDaI9jh3/
-kvG/Jt9vpm22qwoklTCGDfzCkXkIKaWlBw==
------END EC PRIVATE KEY-----
+-----BEGIN OPENSSH PRIVATE KEY-----
+b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAaAAAABNlY2RzYS
+1zaGEyLW5pc3RwMjU2AAAACG5pc3RwMjU2AAAAQQQMWVuWQ6tb3J0pWG0z70Bjdz2xoETt
+IbeUXHfycFq+QAMNoj2OHf+S8b8m32+mbbarCiSVMIYN/MKReQgppaUHAAAAoFrmmZBa5p
+mQAAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBAxZW5ZDq1vcnSlY
+bTPvQGN3PbGgRO0ht5Rcd/JwWr5AAw2iPY4d/5Lxvybfb6ZttqsKJJUwhg38wpF5CCmlpQ
+cAAAAhAPPNyUAnjvFr+eT/7t/IyjuQQd/aLFiTY92LB9gIjyrMAAAAAAECAwQFBgc=
+-----END OPENSSH PRIVATE KEY-----
diff --git a/crypto/openssh/regress/unittests/sshkey/testdata/ecdsa_sk1 b/crypto/openssh/regress/unittests/sshkey/testdata/ecdsa_sk1
new file mode 100644
index 000000000000..b51fb73d6386
--- /dev/null
+++ b/crypto/openssh/regress/unittests/sshkey/testdata/ecdsa_sk1
@@ -0,0 +1,13 @@
+-----BEGIN OPENSSH PRIVATE KEY-----
+b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAfwAAACJzay1lY2
+RzYS1zaGEyLW5pc3RwMjU2QG9wZW5zc2guY29tAAAACG5pc3RwMjU2AAAAQQRnVT5Cji1D
+Ge2+q2X0vATh6LYnODV+DJrshJorr5GnipW29RfuaDXs0WB6XBej9dOLazVRDjQrtV19Qg
+O6cfkFAAAABHNzaDoAAAGQuPdnP7j3Zz8AAAAic2stZWNkc2Etc2hhMi1uaXN0cDI1NkBv
+cGVuc3NoLmNvbQAAAAhuaXN0cDI1NgAAAEEEZ1U+Qo4tQxntvqtl9LwE4ei2Jzg1fgya7I
+SaK6+Rp4qVtvUX7mg17NFgelwXo/XTi2s1UQ40K7VdfUIDunH5BQAAAARzc2g6AQAAAOMt
+LS0tLUJFR0lOIEVDIFBSSVZBVEUgS0VZLS0tLS0KTUhjQ0FRRUVJRURmVFB4YzA0alN5Zk
+Z5NlhoV1pTVlpzcnU5ZFlaSVpTOWhjeVFhcDlVT29Bb0dDQ3FHU000OQpBd0VIb1VRRFFn
+QUVaMVUrUW80dFF4bnR2cXRsOUx3RTRlaTJKemcxZmd5YTdJU2FLNitScDRxVnR2VVg3bW
+cxCjdORmdlbHdYby9YVGkyczFVUTQwSzdWZGZVSUR1bkg1QlE9PQotLS0tLUVORCBFQyBQ
+UklWQVRFIEtFWS0tLS0tCgAAAAAAAAAURUNEU0EtU0sgdGVzdCBrZXkgIzEBAgMEBQ==
+-----END OPENSSH PRIVATE KEY-----
diff --git a/crypto/openssh/regress/unittests/sshkey/testdata/ecdsa_sk1-cert.fp b/crypto/openssh/regress/unittests/sshkey/testdata/ecdsa_sk1-cert.fp
new file mode 100644
index 000000000000..d1921451d740
--- /dev/null
+++ b/crypto/openssh/regress/unittests/sshkey/testdata/ecdsa_sk1-cert.fp
@@ -0,0 +1 @@
+SHA256:Go7HO0CVPYG+BSDSk9ZUJBKGSrtBExp6obTa9iqzIUo
diff --git a/crypto/openssh/regress/unittests/sshkey/testdata/ecdsa_sk1-cert.pub b/crypto/openssh/regress/unittests/sshkey/testdata/ecdsa_sk1-cert.pub
new file mode 100644
index 000000000000..9586c61a7d69
--- /dev/null
+++ b/crypto/openssh/regress/unittests/sshkey/testdata/ecdsa_sk1-cert.pub
@@ -0,0 +1 @@
+sk-ecdsa-sha2-nistp256-cert-v01@openssh.com AAAAK3NrLWVjZHNhLXNoYTItbmlzdHAyNTYtY2VydC12MDFAb3BlbnNzaC5jb20AAAAgE012YoSBE9hEC2FRzblcSx784JNo2A4g611A7I75YMMAAAAIbmlzdHAyNTYAAABBBGdVPkKOLUMZ7b6rZfS8BOHotic4NX4MmuyEmiuvkaeKlbb1F+5oNezRYHpcF6P104trNVEONCu1XX1CA7px+QUAAAAEc3NoOgAAAAAAAAAHAAAAAgAAAAZqdWxpdXMAAAASAAAABWhvc3QxAAAABWhvc3QyAAAAADaLg2AAAAAATR3h4AAAAAAAAAAAAAAAAAAAAGgAAAATZWNkc2Etc2hhMi1uaXN0cDI1NgAAAAhuaXN0cDI1NgAAAEEEAlTtPiWUHubBeCys4Xp0QF91dYARpkyqtCnzg10HRS+ZDgkMrSUvPPG+Ge8iqtnB951MBxDq9FqDFIkhQBYXDAAAAGQAAAATZWNkc2Etc2hhMi1uaXN0cDI1NgAAAEkAAAAhALY+eXRJjVGnMk38Sm5S+H5CloNq757ypsoxt+WYoadtAAAAIA42/mAhUfLij1GY7wl+OFrI+icB/t4tGiEUZmhx6Foo ECDSA-SK test key #1
diff --git a/crypto/openssh/regress/unittests/sshkey/testdata/ecdsa_sk1.fp b/crypto/openssh/regress/unittests/sshkey/testdata/ecdsa_sk1.fp
new file mode 100644
index 000000000000..d1921451d740
--- /dev/null
+++ b/crypto/openssh/regress/unittests/sshkey/testdata/ecdsa_sk1.fp
@@ -0,0 +1 @@
+SHA256:Go7HO0CVPYG+BSDSk9ZUJBKGSrtBExp6obTa9iqzIUo
diff --git a/crypto/openssh/regress/unittests/sshkey/testdata/ecdsa_sk1.fp.bb b/crypto/openssh/regress/unittests/sshkey/testdata/ecdsa_sk1.fp.bb
new file mode 100644
index 000000000000..cb9f4dd0dc8d
--- /dev/null
+++ b/crypto/openssh/regress/unittests/sshkey/testdata/ecdsa_sk1.fp.bb
@@ -0,0 +1 @@
+xovem-sacac-dageg-vovoc-symyz-bozal-cibiv-cyvat-vylyn-romib-hoxax
diff --git a/crypto/openssh/regress/unittests/sshkey/testdata/ecdsa_sk1.pub b/crypto/openssh/regress/unittests/sshkey/testdata/ecdsa_sk1.pub
new file mode 100644
index 000000000000..c3b21e02b1f3
--- /dev/null
+++ b/crypto/openssh/regress/unittests/sshkey/testdata/ecdsa_sk1.pub
@@ -0,0 +1 @@
+sk-ecdsa-sha2-nistp256@openssh.com AAAAInNrLWVjZHNhLXNoYTItbmlzdHAyNTZAb3BlbnNzaC5jb20AAAAIbmlzdHAyNTYAAABBBGdVPkKOLUMZ7b6rZfS8BOHotic4NX4MmuyEmiuvkaeKlbb1F+5oNezRYHpcF6P104trNVEONCu1XX1CA7px+QUAAAAEc3NoOg== ECDSA-SK test key #1
diff --git a/crypto/openssh/regress/unittests/sshkey/testdata/ecdsa_sk1_pw b/crypto/openssh/regress/unittests/sshkey/testdata/ecdsa_sk1_pw
new file mode 100644
index 000000000000..4fa23a7383e3
--- /dev/null
+++ b/crypto/openssh/regress/unittests/sshkey/testdata/ecdsa_sk1_pw
@@ -0,0 +1,14 @@
+-----BEGIN OPENSSH PRIVATE KEY-----
+b3BlbnNzaC1rZXktdjEAAAAACmFlczI1Ni1jdHIAAAAGYmNyeXB0AAAAGAAAABB6vcJVx2
+cPc7yYRROup8VnAAAAEAAAAAEAAAB/AAAAInNrLWVjZHNhLXNoYTItbmlzdHAyNTZAb3Bl
+bnNzaC5jb20AAAAIbmlzdHAyNTYAAABBBGdVPkKOLUMZ7b6rZfS8BOHotic4NX4MmuyEmi
+uvkaeKlbb1F+5oNezRYHpcF6P104trNVEONCu1XX1CA7px+QUAAAAEc3NoOgAAAZBrvCxe
+xFz0bvzXwaPhrUHBeNCoZy/wNKDx0kxlxUPuA+lgOvy5l3lT3yxxd0qj5PQB+NTcuz8AAE
+1f7aSWQNZSifox3COsBGoHV9C8i+glcxiBKheAZD+EBnRGjG8kbcaLhuYDW/I39qNe8lHW
+YSDjmvsT55Hy0IAtVRAXizDoXKNdFPTZisC67WyOSJ3ED7Fy4bfT4ApbvhoFTwjikZBEhy
+LOad1sbJa4eT19TsskYfQdnJf8sjAmCMOZY4ZV0FiNW5XZOp8nIal1oyULPfzTAm6oaeFN
+0ImCSU3U8h4wUQ8q/3XvBWtTKycZaoou0AwPoP0QN95Ywte7FHezNPb/n8KD7k0S6h9XAX
+UcBeCe5NHyov/0ZzA2p737hzm3w+MXGOboTQMu8WFXeGh4m7QH2o8ZJdgBhM5JF17uii+Q
+ppGoPWHf33MXwB3wxWmKZ0ua0f9AVLkQ2DfFszUoBJE/kcHRd4kj4Q4FWXeMBN0GoH8gdE
+gRWIlxn2/FAOce/BFPzzdP87H0jwz7SdcuVO1L
+-----END OPENSSH PRIVATE KEY-----
diff --git a/crypto/openssh/regress/unittests/sshkey/testdata/ecdsa_sk2 b/crypto/openssh/regress/unittests/sshkey/testdata/ecdsa_sk2
new file mode 100644
index 000000000000..19db5a3f5690
--- /dev/null
+++ b/crypto/openssh/regress/unittests/sshkey/testdata/ecdsa_sk2
@@ -0,0 +1,13 @@
+-----BEGIN OPENSSH PRIVATE KEY-----
+b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAfwAAACJzay1lY2
+RzYS1zaGEyLW5pc3RwMjU2QG9wZW5zc2guY29tAAAACG5pc3RwMjU2AAAAQQSTl+SR6rTg
+lOZmcQkCtJ3Pd+lWinezo/gHk4oZdZcTQsmEYs766BlWGuB2Bz3qQRLa6cXsP+4K9kAjAJ
+7zdoFUAAAABHNzaDoAAAGQ1qllJtapZSYAAAAic2stZWNkc2Etc2hhMi1uaXN0cDI1NkBv
+cGVuc3NoLmNvbQAAAAhuaXN0cDI1NgAAAEEEk5fkkeq04JTmZnEJArSdz3fpVop3s6P4B5
+OKGXWXE0LJhGLO+ugZVhrgdgc96kES2unF7D/uCvZAIwCe83aBVAAAAARzc2g6AQAAAOMt
+LS0tLUJFR0lOIEVDIFBSSVZBVEUgS0VZLS0tLS0KTUhjQ0FRRUVJSkxwVkxnSTVvdkRlOW
+VMWmZodCs5WWlMaitnam0rTXhHTXg5NndiRWw0Wm9Bb0dDQ3FHU000OQpBd0VIb1VRRFFn
+QUVrNWZra2VxMDRKVG1abkVKQXJTZHozZnBWb3AzczZQNEI1T0tHWFdYRTBMSmhHTE8rdW
+daClZocmdkZ2M5NmtFUzJ1bkY3RC91Q3ZaQUl3Q2U4M2FCVkE9PQotLS0tLUVORCBFQyBQ
+UklWQVRFIEtFWS0tLS0tCgAAAAAAAAAURUNEU0EtU0sgdGVzdCBrZXkgIzIBAgMEBQ==
+-----END OPENSSH PRIVATE KEY-----
diff --git a/crypto/openssh/regress/unittests/sshkey/testdata/ecdsa_sk2.fp b/crypto/openssh/regress/unittests/sshkey/testdata/ecdsa_sk2.fp
new file mode 100644
index 000000000000..1bc99ea0d7a4
--- /dev/null
+++ b/crypto/openssh/regress/unittests/sshkey/testdata/ecdsa_sk2.fp
@@ -0,0 +1 @@
+SHA256:pz8VkgtRY3r50F4zSuzRlmq9c6vPTpJXLKKOgkyUcKE
diff --git a/crypto/openssh/regress/unittests/sshkey/testdata/ecdsa_sk2.fp.bb b/crypto/openssh/regress/unittests/sshkey/testdata/ecdsa_sk2.fp.bb
new file mode 100644
index 000000000000..bfee7658a606
--- /dev/null
+++ b/crypto/openssh/regress/unittests/sshkey/testdata/ecdsa_sk2.fp.bb
@@ -0,0 +1 @@
+xobel-gavur-gorym-pedop-rarob-bunek-gucer-lofeg-syhaf-fylur-zoxix
diff --git a/crypto/openssh/regress/unittests/sshkey/testdata/ecdsa_sk2.pub b/crypto/openssh/regress/unittests/sshkey/testdata/ecdsa_sk2.pub
new file mode 100644
index 000000000000..2629d9509ed2
--- /dev/null
+++ b/crypto/openssh/regress/unittests/sshkey/testdata/ecdsa_sk2.pub
@@ -0,0 +1 @@
+sk-ecdsa-sha2-nistp256@openssh.com AAAAInNrLWVjZHNhLXNoYTItbmlzdHAyNTZAb3BlbnNzaC5jb20AAAAIbmlzdHAyNTYAAABBBJOX5JHqtOCU5mZxCQK0nc936VaKd7Oj+AeTihl1lxNCyYRizvroGVYa4HYHPepBEtrpxew/7gr2QCMAnvN2gVQAAAAEc3NoOg== ECDSA-SK test key #2
diff --git a/crypto/openssh/regress/unittests/sshkey/testdata/ed25519_1_pw b/crypto/openssh/regress/unittests/sshkey/testdata/ed25519_1_pw
index c3b7ae7f811b..da94d2b8e2e4 100644
--- a/crypto/openssh/regress/unittests/sshkey/testdata/ed25519_1_pw
+++ b/crypto/openssh/regress/unittests/sshkey/testdata/ed25519_1_pw
@@ -1,8 +1,8 @@
-----BEGIN OPENSSH PRIVATE KEY-----
-b3BlbnNzaC1rZXktdjEAAAAACmFlczI1Ni1jYmMAAAAGYmNyeXB0AAAAGAAAABCus+kaow
-AUjHphacvRp98dAAAAEAAAAAEAAAAzAAAAC3NzaC1lZDI1NTE5AAAAIFOG6kY7Rf4UtCFv
-PwKgo/BztXck2xC4a2WyA34XtIwZAAAAoJaqqgiYQuElraJAmYOm7Tb4nJ3eI4oj9mQ52M
-/Yd+ION2Ur1v8BDewpDX+LHEYgKHo3Mlmcn2UyF+QJ+7xUCW7QCtk/4szrJzw74DlEl6mH
-T8PT/f/av7PpECBD/YD3NoDlB9OWm/Q4sHcxfBEKfTGD7s2Onn71HgrdEOPqd4Sj/IQigR
-drfjtXEMlD32k9n3dd2eS9x7AHWYaGFEMkOcY=
+b3BlbnNzaC1rZXktdjEAAAAACmFlczI1Ni1jdHIAAAAGYmNyeXB0AAAAGAAAABDKT56mBA
+tXIMsWqmuuA2gdAAAAEAAAAAEAAAAzAAAAC3NzaC1lZDI1NTE5AAAAIFOG6kY7Rf4UtCFv
+PwKgo/BztXck2xC4a2WyA34XtIwZAAAAoC13U47yfUOSZJePNUAwWXuFOk3aOKwPM5PMvK
+0zwRnMZZjgn+tsMAYPwhsT3Mx3h5QzvVGFyFEqsiK7j4vAotD+LVQeBN5TwWbUBx4lnoGs
+3iAfYVDakO/gNvVBDDGOqv5kdCc4cgn5HacjHQLKOAx6KzHe7JFn7uCywMdVVQjlpI6LHb
+mHkaKiVX/C2oiRnsoe17HZ8Fxyt3vd1qNM8BE=
-----END OPENSSH PRIVATE KEY-----
diff --git a/crypto/openssh/regress/unittests/sshkey/testdata/ed25519_sk1 b/crypto/openssh/regress/unittests/sshkey/testdata/ed25519_sk1
new file mode 100644
index 000000000000..4196d9c6a2de
--- /dev/null
+++ b/crypto/openssh/regress/unittests/sshkey/testdata/ed25519_sk1
@@ -0,0 +1,8 @@
+-----BEGIN OPENSSH PRIVATE KEY-----
+b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAASgAAABpzay1zc2
+gtZWQyNTUxOUBvcGVuc3NoLmNvbQAAACAhaP5OS1PPOt7uumAvXlDtte9EHbqIT1EZEJ2y
+2v3XMwAAAARzc2g6AAAAuBocY6UaHGOlAAAAGnNrLXNzaC1lZDI1NTE5QG9wZW5zc2guY2
+9tAAAAICFo/k5LU8863u66YC9eUO2170QduohPURkQnbLa/dczAAAABHNzaDoBAAAAQJYq
+lGHhFoA25/q8X/rdTqDAb7dhqs4ehhd/w8x99CwiIWj+TktTzzre7rpgL15Q7bXvRB26iE
+9RGRCdstr91zMAAAAAAAAAFkVEMjU1MTktU0sgdGVzdCBrZXkgIzEBAgM=
+-----END OPENSSH PRIVATE KEY-----
diff --git a/crypto/openssh/regress/unittests/sshkey/testdata/ed25519_sk1-cert.fp b/crypto/openssh/regress/unittests/sshkey/testdata/ed25519_sk1-cert.fp
new file mode 100644
index 000000000000..a6bb1a99cb32
--- /dev/null
+++ b/crypto/openssh/regress/unittests/sshkey/testdata/ed25519_sk1-cert.fp
@@ -0,0 +1 @@
+SHA256:6WZVJ44bqhAWLVP4Ns0TDkoSQSsZo/h2K+mEvOaNFbw
diff --git a/crypto/openssh/regress/unittests/sshkey/testdata/ed25519_sk1-cert.pub b/crypto/openssh/regress/unittests/sshkey/testdata/ed25519_sk1-cert.pub
new file mode 100644
index 000000000000..3c72c268df94
--- /dev/null
+++ b/crypto/openssh/regress/unittests/sshkey/testdata/ed25519_sk1-cert.pub
@@ -0,0 +1 @@
+sk-ssh-ed25519-cert-v01@openssh.com AAAAI3NrLXNzaC1lZDI1NTE5LWNlcnQtdjAxQG9wZW5zc2guY29tAAAAIJr7CuMntQKvHoUshx374fJLFEkyxKsEOBA1H6hk5scoAAAAICFo/k5LU8863u66YC9eUO2170QduohPURkQnbLa/dczAAAABHNzaDoAAAAAAAAACAAAAAIAAAAGanVsaXVzAAAAEgAAAAVob3N0MQAAAAVob3N0MgAAAAA2i4NgAAAAAE0d4eAAAAAAAAAAAAAAAAAAAAAzAAAAC3NzaC1lZDI1NTE5AAAAIOo/0xneV3iM2qWEo5RUwvUYa2bjff292T5vvuXRomGQAAAAUwAAAAtzc2gtZWQyNTUxOQAAAECgsRGLDh1SI3m66MRp9D2iLP4wabQ0OrDgGidk7LsVn2XZHV5jBZN1RtNfe6PBMeVzfRtGUzOg18sO7H7uU+EC ED25519-SK test key #1
diff --git a/crypto/openssh/regress/unittests/sshkey/testdata/ed25519_sk1.fp b/crypto/openssh/regress/unittests/sshkey/testdata/ed25519_sk1.fp
new file mode 100644
index 000000000000..a6bb1a99cb32
--- /dev/null
+++ b/crypto/openssh/regress/unittests/sshkey/testdata/ed25519_sk1.fp
@@ -0,0 +1 @@
+SHA256:6WZVJ44bqhAWLVP4Ns0TDkoSQSsZo/h2K+mEvOaNFbw
diff --git a/crypto/openssh/regress/unittests/sshkey/testdata/ed25519_sk1.fp.bb b/crypto/openssh/regress/unittests/sshkey/testdata/ed25519_sk1.fp.bb
new file mode 100644
index 000000000000..1bfe20a4803a
--- /dev/null
+++ b/crypto/openssh/regress/unittests/sshkey/testdata/ed25519_sk1.fp.bb
@@ -0,0 +1 @@
+xucac-vusip-tydoz-dudad-nerif-raran-tezun-cogyd-pamoh-bahef-ruxix
diff --git a/crypto/openssh/regress/unittests/sshkey/testdata/ed25519_sk1.pub b/crypto/openssh/regress/unittests/sshkey/testdata/ed25519_sk1.pub
new file mode 100644
index 000000000000..60fe00c3949b
--- /dev/null
+++ b/crypto/openssh/regress/unittests/sshkey/testdata/ed25519_sk1.pub
@@ -0,0 +1 @@
+sk-ssh-ed25519@openssh.com AAAAGnNrLXNzaC1lZDI1NTE5QG9wZW5zc2guY29tAAAAICFo/k5LU8863u66YC9eUO2170QduohPURkQnbLa/dczAAAABHNzaDo= ED25519-SK test key #1
diff --git a/crypto/openssh/regress/unittests/sshkey/testdata/ed25519_sk1_pw b/crypto/openssh/regress/unittests/sshkey/testdata/ed25519_sk1_pw
new file mode 100644
index 000000000000..1c29ff07fe5c
--- /dev/null
+++ b/crypto/openssh/regress/unittests/sshkey/testdata/ed25519_sk1_pw
@@ -0,0 +1,9 @@
+-----BEGIN OPENSSH PRIVATE KEY-----
+b3BlbnNzaC1rZXktdjEAAAAACmFlczI1Ni1jdHIAAAAGYmNyeXB0AAAAGAAAABDr5R9Yf/
+ucEh0Ns6c34tcIAAAAEAAAAAEAAABKAAAAGnNrLXNzaC1lZDI1NTE5QG9wZW5zc2guY29t
+AAAAICFo/k5LU8863u66YC9eUO2170QduohPURkQnbLa/dczAAAABHNzaDoAAADA2T6owx
+OSgKz4DvLnS3UJ/renbuew5mbkIWB1/y8xd3y5Usm08iUCAlKxep9dVRQvmyoTrc/7rHOM
+DkokNw+WgKambnlYT/9QfqViZ9iCBtbdmhLM6ksUCgQefvquRyXoJxlWstjXUll6Ru+ZbT
+H//Ss8C1bYtAiXR68OQ+rhDrvQxA9P8J1sGIlkuV3h8YXddSpyBW2Sn0LTHHBXYZo86cXZ
+G4Lnc8aGYm65eqdHgkfRmht3eS8DTdzEBfBNH5Ml
+-----END OPENSSH PRIVATE KEY-----
diff --git a/crypto/openssh/regress/unittests/sshkey/testdata/ed25519_sk2 b/crypto/openssh/regress/unittests/sshkey/testdata/ed25519_sk2
new file mode 100644
index 000000000000..b9b748966bca
--- /dev/null
+++ b/crypto/openssh/regress/unittests/sshkey/testdata/ed25519_sk2
@@ -0,0 +1,8 @@
+-----BEGIN OPENSSH PRIVATE KEY-----
+b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAASgAAABpzay1zc2
+gtZWQyNTUxOUBvcGVuc3NoLmNvbQAAACAV8fu1Sc31QLK2R/zGPdN3ve5xuFvDc7mEAWxb
+aI+YcwAAAARzc2g6AAAAuJCMX5uQjF+bAAAAGnNrLXNzaC1lZDI1NTE5QG9wZW5zc2guY2
+9tAAAAIBXx+7VJzfVAsrZH/MY903e97nG4W8NzuYQBbFtoj5hzAAAABHNzaDoBAAAAQObE
+PajcKI1W30EKOhBb6u+Fgx464kf7EjnqDSg4l7gAFfH7tUnN9UCytkf8xj3Td73ucbhbw3
+O5hAFsW2iPmHMAAAAAAAAAFkVEMjU1MTktU0sgdGVzdCBrZXkgIzIBAgM=
+-----END OPENSSH PRIVATE KEY-----
diff --git a/crypto/openssh/regress/unittests/sshkey/testdata/ed25519_sk2.fp b/crypto/openssh/regress/unittests/sshkey/testdata/ed25519_sk2.fp
new file mode 100644
index 000000000000..1c4369a00768
--- /dev/null
+++ b/crypto/openssh/regress/unittests/sshkey/testdata/ed25519_sk2.fp
@@ -0,0 +1 @@
+SHA256:b9BVPS5vuU4yu/FgweojLLg6zbfmBBoWLUgibdxxsoo
diff --git a/crypto/openssh/regress/unittests/sshkey/testdata/ed25519_sk2.fp.bb b/crypto/openssh/regress/unittests/sshkey/testdata/ed25519_sk2.fp.bb
new file mode 100644
index 000000000000..f5fd9efd8f9f
--- /dev/null
+++ b/crypto/openssh/regress/unittests/sshkey/testdata/ed25519_sk2.fp.bb
@@ -0,0 +1 @@
+xemac-tizim-dihep-supar-zupib-cukak-pasis-febeg-dyguv-hutec-dyxox
diff --git a/crypto/openssh/regress/unittests/sshkey/testdata/ed25519_sk2.pub b/crypto/openssh/regress/unittests/sshkey/testdata/ed25519_sk2.pub
new file mode 100644
index 000000000000..c7ed9f524a49
--- /dev/null
+++ b/crypto/openssh/regress/unittests/sshkey/testdata/ed25519_sk2.pub
@@ -0,0 +1 @@
+sk-ssh-ed25519@openssh.com AAAAGnNrLXNzaC1lZDI1NTE5QG9wZW5zc2guY29tAAAAIBXx+7VJzfVAsrZH/MY903e97nG4W8NzuYQBbFtoj5hzAAAABHNzaDo= ED25519-SK test key #2
diff --git a/crypto/openssh/regress/unittests/sshkey/testdata/rsa1_1 b/crypto/openssh/regress/unittests/sshkey/testdata/rsa1_1
deleted file mode 100644
index 161cc04dc700..000000000000
--- a/crypto/openssh/regress/unittests/sshkey/testdata/rsa1_1
+++ /dev/null
Binary files differ
diff --git a/crypto/openssh/regress/unittests/sshkey/testdata/rsa1_1.fp b/crypto/openssh/regress/unittests/sshkey/testdata/rsa1_1.fp
deleted file mode 100644
index 21b3d1a9a128..000000000000
--- a/crypto/openssh/regress/unittests/sshkey/testdata/rsa1_1.fp
+++ /dev/null
@@ -1 +0,0 @@
-SHA256:/kk7K9S9kwYFiFilnZYFwCsQJweI/SGQVR2nIa8VBhE
diff --git a/crypto/openssh/regress/unittests/sshkey/testdata/rsa1_1.fp.bb b/crypto/openssh/regress/unittests/sshkey/testdata/rsa1_1.fp.bb
deleted file mode 100644
index 62991b3e0bbe..000000000000
--- a/crypto/openssh/regress/unittests/sshkey/testdata/rsa1_1.fp.bb
+++ /dev/null
@@ -1 +0,0 @@
-xilil-nabyf-gynih-duheb-gokyp-bofet-nekac-bosod-lozin-kuvyh-poxix
diff --git a/crypto/openssh/regress/unittests/sshkey/testdata/rsa1_1.param.n b/crypto/openssh/regress/unittests/sshkey/testdata/rsa1_1.param.n
deleted file mode 100644
index 9a2549bbbd15..000000000000
--- a/crypto/openssh/regress/unittests/sshkey/testdata/rsa1_1.param.n
+++ /dev/null
@@ -1 +0,0 @@
-00ce8ca77a556eba887f9a866c084a6402785354a81c10854d343181fa09351223a65f99915f8433d11a9c41677d307c03c3a39865b83e7172d2c1d878333c980438d6e4462106a0065cd75cfea7ca7f21538bf2f43f2af49cacee51b22e3bdcc5e87b59cc691f7c6942a77ef13bfdfb24300777b727348d0ba7900ba06b886729
diff --git a/crypto/openssh/regress/unittests/sshkey/testdata/rsa1_1.pub b/crypto/openssh/regress/unittests/sshkey/testdata/rsa1_1.pub
deleted file mode 100644
index f665b0d64d1e..000000000000
--- a/crypto/openssh/regress/unittests/sshkey/testdata/rsa1_1.pub
+++ /dev/null
@@ -1 +0,0 @@
-1024 65537 145043942670517902781741650890610683756045780348507433188994725700923246927874581962206512480287863636935077725837494808988986557337885675565086448774391442851909709751605441036910145362277967349042489937363543710406342212883803780768870873303921572812138116796733586484633244057911618360651775855949808953129 RSA1 test key #1
diff --git a/crypto/openssh/regress/unittests/sshkey/testdata/rsa1_1_pw b/crypto/openssh/regress/unittests/sshkey/testdata/rsa1_1_pw
deleted file mode 100644
index e73c6794ade5..000000000000
--- a/crypto/openssh/regress/unittests/sshkey/testdata/rsa1_1_pw
+++ /dev/null
Binary files differ
diff --git a/crypto/openssh/regress/unittests/sshkey/testdata/rsa1_2 b/crypto/openssh/regress/unittests/sshkey/testdata/rsa1_2
deleted file mode 100644
index 1d672ddea393..000000000000
--- a/crypto/openssh/regress/unittests/sshkey/testdata/rsa1_2
+++ /dev/null
Binary files differ
diff --git a/crypto/openssh/regress/unittests/sshkey/testdata/rsa1_2.fp b/crypto/openssh/regress/unittests/sshkey/testdata/rsa1_2.fp
deleted file mode 100644
index 00516d521fba..000000000000
--- a/crypto/openssh/regress/unittests/sshkey/testdata/rsa1_2.fp
+++ /dev/null
@@ -1 +0,0 @@
-SHA256:JaOeRCnLl/TLe7vn1+aQ4ONyKZCUhK5x3k4VHilmbpE
diff --git a/crypto/openssh/regress/unittests/sshkey/testdata/rsa1_2.fp.bb b/crypto/openssh/regress/unittests/sshkey/testdata/rsa1_2.fp.bb
deleted file mode 100644
index b4989a588d88..000000000000
--- a/crypto/openssh/regress/unittests/sshkey/testdata/rsa1_2.fp.bb
+++ /dev/null
@@ -1 +0,0 @@
-xipag-zohut-zepuk-pisyv-kamog-pupus-netud-tudis-melup-cynov-gaxox
diff --git a/crypto/openssh/regress/unittests/sshkey/testdata/rsa1_2.param.n b/crypto/openssh/regress/unittests/sshkey/testdata/rsa1_2.param.n
deleted file mode 100644
index 25d438d06207..000000000000
--- a/crypto/openssh/regress/unittests/sshkey/testdata/rsa1_2.param.n
+++ /dev/null
@@ -1 +0,0 @@
-00cab091b57a154740c1bb7020f46a21a19dc40f647db2aab1babd30cabe241f0437391e68376ba35e48c624b8eaf6b59424d4c1a848c9fd1ef5cdc7c1b7f5e5df23b7ad513b79021286d38c52fdfae35656659e8649b2bf8bedf7c99664e45534007bd1c5dc3de1dafdf2d34ad087155951aa0f3d500b36d0d804bbccdef15ab31ca3dd40bdf5196065a97f397ef576caffb606be8232f6e0614aea0e979b9584296673fabb1dbd9f3212495c428842a2ab1f1768dd424fb6fdceeeab9126cacdfc834f0a0d09ba73ad8360d183ba85bb1565555cc6a536eb8d06df1a1e841107c021ae28a2d8b3465f9d8b58ef4045aea1c4ad7f8bf639574d6b142af67b4eb3
diff --git a/crypto/openssh/regress/unittests/sshkey/testdata/rsa1_2.pub b/crypto/openssh/regress/unittests/sshkey/testdata/rsa1_2.pub
deleted file mode 100644
index acab6dda6e62..000000000000
--- a/crypto/openssh/regress/unittests/sshkey/testdata/rsa1_2.pub
+++ /dev/null
@@ -1 +0,0 @@
-2048 65537 25587207108642486834576012232250034427766229965612147538722032399009467293691448851087324679403117563681753304072089087252850866332601294130674473984011813227791089686736237645788471744456489819306046398653719249100878753563464696688916667605969658659855996383142110932332560049231682024775766802333675397528993897914717996946881193454997890776063024953924432026083898531677702536941151535135950834711001926404724453460085864892836473957600610133803037286539329764689125111700732309717375455919436557475211197800228646235077584780367991159670572954337165006813357814232200750568307753718414790655085790471723847208627 RSA1 test key #2
diff --git a/crypto/openssh/regress/unittests/sshkey/testdata/rsa_n b/crypto/openssh/regress/unittests/sshkey/testdata/rsa_n
index 5de3f8422e89..b8e585e5188a 100644
--- a/crypto/openssh/regress/unittests/sshkey/testdata/rsa_n
+++ b/crypto/openssh/regress/unittests/sshkey/testdata/rsa_n
@@ -1,15 +1,16 @@
------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-----
+-----BEGIN OPENSSH PRIVATE KEY-----
+b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAlwAAAAdzc2gtcn
+NhAAAAAwEAAQAAAIEAy1eZVE7exawA7HgfwhoRGc6aKI4xFucvPnj7y6aZitzJjCNfLner
+8c6St28GS2JFUsnyWCNB5iLhoXbu8jK1usG/OIG6vAt9V6HvRDkXCFLhkrwynTUjNUo5YQ
+6rkW5QxQfJE6Kl8sdZaq13nF8pcSFDi9IxPrtK1Nfeu6QycfsAAAH4to4I7raOCO4AAAAH
+c3NoLXJzYQAAAIEAy1eZVE7exawA7HgfwhoRGc6aKI4xFucvPnj7y6aZitzJjCNfLner8c
+6St28GS2JFUsnyWCNB5iLhoXbu8jK1usG/OIG6vAt9V6HvRDkXCFLhkrwynTUjNUo5YQ6r
+kW5QxQfJE6Kl8sdZaq13nF8pcSFDi9IxPrtK1Nfeu6QycfsAAAADAQABAAAAgF8o+ZqY5m
+w/mJcRiFs/86zOIRrFoHeFbXihCcU+jDCOLswkaZDHdHJPKB4sGRgCP0sFMyLILTjULh9w
+F1bFIIIVuGJ5/vJLBL9CGfdfFgzA8Kr6pMq1c7DrGc6mIz3/A1AygqcBY55ZJydOMr1gWb
+1YVrWODomfBldE7bLt5PhhAAAAQAndVkxvO8hwyEFGGwF3faHIAe/OxVb+MjaU25//Pe1/
+h/e6tlCk4w9CODpyV685gV394eYwMcGDcIkipTNUDZsAAABBAPVgd+8FvkV0kG9SF17YiX
+6NoWJrybBVU01qIPYQLFfHoLMbPnhksQH009V8NRkryUnhQkOp6VY2HeI8XdF59YMAAABB
+ANQlQcwBS+JjcKZXlT8638uvcT94FjmtujMTPxhOs8fYwux4ENyj2linRvxbh7NPOWk0Q2
+gy5hnGfCLzLruzYCkAAAAAAQID
+-----END OPENSSH PRIVATE KEY-----
diff --git a/crypto/openssh/regress/unittests/sshkey/tests.c b/crypto/openssh/regress/unittests/sshkey/tests.c
index 13f265cdb91b..78aa9223d42b 100644
--- a/crypto/openssh/regress/unittests/sshkey/tests.c
+++ b/crypto/openssh/regress/unittests/sshkey/tests.c
@@ -7,8 +7,6 @@
#include "includes.h"
-#include <openssl/evp.h>
-
#include "../test_helper/test_helper.h"
void sshkey_tests(void);
@@ -18,9 +16,6 @@ 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/openssh/regress/unittests/sshsig/Makefile b/crypto/openssh/regress/unittests/sshsig/Makefile
new file mode 100644
index 000000000000..65564d1b278b
--- /dev/null
+++ b/crypto/openssh/regress/unittests/sshsig/Makefile
@@ -0,0 +1,25 @@
+# $OpenBSD: Makefile,v 1.2 2021/01/09 12:24:31 dtucker Exp $
+
+PROG=test_sshsig
+SRCS=tests.c
+
+# From usr.bin/ssh
+SRCS+=sshbuf-getput-basic.c sshbuf-getput-crypto.c sshbuf-misc.c sshbuf.c
+SRCS+=sshbuf-io.c atomicio.c sshkey.c authfile.c cipher.c log.c ssh-rsa.c
+SRCS+=ssh-dss.c ssh-ecdsa.c ssh-ed25519.c mac.c umac.c umac128.c hmac.c misc.c
+SRCS+=ssherr.c uidswap.c cleanup.c xmalloc.c match.c krl.c fatal.c
+SRCS+=addr.c addrmatch.c bitmap.c sshsig.c
+SRCS+=ed25519.c hash.c ge25519.c fe25519.c sc25519.c verify.c
+SRCS+=cipher-chachapoly.c chacha.c poly1305.c ssh-ecdsa-sk.c ssh-sk.c
+SRCS+=ssh-ed25519-sk.c sk-usbhid.c
+
+SRCS+=digest-openssl.c
+#SRCS+=digest-libc.c
+SRCS+=utf8.c
+
+REGRESS_TARGETS=run-regress-${PROG}
+
+run-regress-${PROG}: ${PROG}
+ env ${TEST_ENV} ./${PROG} ${UNITTEST_ARGS} -d ${.CURDIR}/testdata
+
+.include <bsd.regress.mk>
diff --git a/crypto/openssh/regress/unittests/sshsig/mktestdata.sh b/crypto/openssh/regress/unittests/sshsig/mktestdata.sh
new file mode 100755
index 000000000000..d2300f9c6ee1
--- /dev/null
+++ b/crypto/openssh/regress/unittests/sshsig/mktestdata.sh
@@ -0,0 +1,42 @@
+#!/bin/sh
+# $OpenBSD: mktestdata.sh,v 1.1 2020/06/19 04:32:09 djm Exp $
+
+NAMESPACE=unittest
+
+set -ex
+
+cd testdata
+
+if [ -f ../../../misc/sk-dummy/sk-dummy.so ] ; then
+ SK_DUMMY=../../../misc/sk-dummy/sk-dummy.so
+elif [ -f ../../../misc/sk-dummy/obj/sk-dummy.so ] ; then
+ SK_DUMMY=../../../misc/sk-dummy/obj/sk-dummy.so
+else
+ echo "Can't find sk-dummy.so" 1>&2
+ exit 1
+fi
+
+rm -f signed-data namespace
+rm -f rsa dsa ecdsa ed25519 ecdsa_sk ed25519_sk
+rm -f rsa.sig dsa.sig ecdsa.sig ed25519.sig ecdsa_sk.sig ed25519_sk.sig
+
+printf "This is a test, this is only a test" > signed-data
+printf "$NAMESPACE" > namespace
+
+ssh-keygen -t rsa -C "RSA test" -N "" -f rsa -m PEM
+ssh-keygen -t dsa -C "DSA test" -N "" -f dsa -m PEM
+ssh-keygen -t ecdsa -C "ECDSA test" -N "" -f ecdsa -m PEM
+ssh-keygen -t ed25519 -C "ED25519 test key" -N "" -f ed25519
+ssh-keygen -w "$SK_DUMMY" -t ecdsa-sk -C "ECDSA-SK test key" \
+ -N "" -f ecdsa_sk
+ssh-keygen -w "$SK_DUMMY" -t ed25519-sk -C "ED25519-SK test key" \
+ -N "" -f ed25519_sk
+
+ssh-keygen -Y sign -f rsa -n $NAMESPACE - < signed-data > rsa.sig
+ssh-keygen -Y sign -f dsa -n $NAMESPACE - < signed-data > dsa.sig
+ssh-keygen -Y sign -f ecdsa -n $NAMESPACE - < signed-data > ecdsa.sig
+ssh-keygen -Y sign -f ed25519 -n $NAMESPACE - < signed-data > ed25519.sig
+ssh-keygen -w "$SK_DUMMY" \
+ -Y sign -f ecdsa_sk -n $NAMESPACE - < signed-data > ecdsa_sk.sig
+ssh-keygen -w "$SK_DUMMY" \
+ -Y sign -f ed25519_sk -n $NAMESPACE - < signed-data > ed25519_sk.sig
diff --git a/crypto/openssh/regress/unittests/sshsig/testdata/dsa b/crypto/openssh/regress/unittests/sshsig/testdata/dsa
new file mode 100644
index 000000000000..7c0063efcdf5
--- /dev/null
+++ b/crypto/openssh/regress/unittests/sshsig/testdata/dsa
@@ -0,0 +1,12 @@
+-----BEGIN DSA PRIVATE KEY-----
+MIIBuwIBAAKBgQCXpndQdz2mQVnk+lYOF3nxDT+h6SiJmUvBFhnFWBv8tG4pTOkb
+EwGufLEzGpzjTj+3bjVau7LFt37AFrqs4Num272BWNsYNIjOlGPgq7Xjv32FN00x
+JYh1DoRs1cGGnvohlsWEamGGhTHD1a9ipctPEBV+NrxtZMrl+pO/ZZg8vQIVAKJB
+P3iNYSpSuW74+q4WxLCuK8O3AoGAQldE+BIuxlvoG1IFiWesx0CU+H2KO0SEZc9A
+SX/qjOabh0Fb78ofTlEf9gWHFfat8SvSJQIOPMVlb76Lio8AAMT8Eaa/qQKKYmQL
+dNq4MLhhjxx5KLGt6J2JyFPExCv+qnHYHD59ngtLwKyqGjpSC8LPLktdXn8W/Aad
+Ly1K7+MCgYBsMHBczhSeUh8w7i20CVg4OlNTmfJRVU2tO6OpMxZ/quitRm3hLKSN
+u4xRkvHJwi4LhQtv1SXvLI5gs5P3gCG8tsIAiyCqLinHha63iBdJpqhnV/x/j7dB
+yJr3xJbnmLdWLkkCtNk1Ir1/CuEz+ufAyLGdKWksEAu1UUlb501BkwIVAILIa3Rg
+0h7J9lQpHJphvF3K0M1T
+-----END DSA PRIVATE KEY-----
diff --git a/crypto/openssh/regress/unittests/sshsig/testdata/dsa.pub b/crypto/openssh/regress/unittests/sshsig/testdata/dsa.pub
new file mode 100644
index 000000000000..e77aa7ef41a0
--- /dev/null
+++ b/crypto/openssh/regress/unittests/sshsig/testdata/dsa.pub
@@ -0,0 +1 @@
+ssh-dss AAAAB3NzaC1kc3MAAACBAJemd1B3PaZBWeT6Vg4XefENP6HpKImZS8EWGcVYG/y0bilM6RsTAa58sTManONOP7duNVq7ssW3fsAWuqzg26bbvYFY2xg0iM6UY+CrteO/fYU3TTEliHUOhGzVwYae+iGWxYRqYYaFMcPVr2Kly08QFX42vG1kyuX6k79lmDy9AAAAFQCiQT94jWEqUrlu+PquFsSwrivDtwAAAIBCV0T4Ei7GW+gbUgWJZ6zHQJT4fYo7RIRlz0BJf+qM5puHQVvvyh9OUR/2BYcV9q3xK9IlAg48xWVvvouKjwAAxPwRpr+pAopiZAt02rgwuGGPHHkosa3onYnIU8TEK/6qcdgcPn2eC0vArKoaOlILws8uS11efxb8Bp0vLUrv4wAAAIBsMHBczhSeUh8w7i20CVg4OlNTmfJRVU2tO6OpMxZ/quitRm3hLKSNu4xRkvHJwi4LhQtv1SXvLI5gs5P3gCG8tsIAiyCqLinHha63iBdJpqhnV/x/j7dByJr3xJbnmLdWLkkCtNk1Ir1/CuEz+ufAyLGdKWksEAu1UUlb501Bkw== DSA test
diff --git a/crypto/openssh/regress/unittests/sshsig/testdata/dsa.sig b/crypto/openssh/regress/unittests/sshsig/testdata/dsa.sig
new file mode 100644
index 000000000000..0b14ad6b8a7b
--- /dev/null
+++ b/crypto/openssh/regress/unittests/sshsig/testdata/dsa.sig
@@ -0,0 +1,13 @@
+-----BEGIN SSH SIGNATURE-----
+U1NIU0lHAAAAAQAAAbEAAAAHc3NoLWRzcwAAAIEAl6Z3UHc9pkFZ5PpWDhd58Q0/oekoiZ
+lLwRYZxVgb/LRuKUzpGxMBrnyxMxqc404/t241Wruyxbd+wBa6rODbptu9gVjbGDSIzpRj
+4Ku14799hTdNMSWIdQ6EbNXBhp76IZbFhGphhoUxw9WvYqXLTxAVfja8bWTK5fqTv2WYPL
+0AAAAVAKJBP3iNYSpSuW74+q4WxLCuK8O3AAAAgEJXRPgSLsZb6BtSBYlnrMdAlPh9ijtE
+hGXPQEl/6ozmm4dBW+/KH05RH/YFhxX2rfEr0iUCDjzFZW++i4qPAADE/BGmv6kCimJkC3
+TauDC4YY8ceSixreidichTxMQr/qpx2Bw+fZ4LS8Csqho6UgvCzy5LXV5/FvwGnS8tSu/j
+AAAAgGwwcFzOFJ5SHzDuLbQJWDg6U1OZ8lFVTa07o6kzFn+q6K1GbeEspI27jFGS8cnCLg
+uFC2/VJe8sjmCzk/eAIby2wgCLIKouKceFrreIF0mmqGdX/H+Pt0HImvfElueYt1YuSQK0
+2TUivX8K4TP658DIsZ0paSwQC7VRSVvnTUGTAAAACHVuaXR0ZXN0AAAAAAAAAAZzaGE1MT
+IAAAA3AAAAB3NzaC1kc3MAAAAodi5lr0pqBpO76OY4N1CtfR85BCgZ95qfVjP/e9lToj0q
+lwjSJJXUjw==
+-----END SSH SIGNATURE-----
diff --git a/crypto/openssh/regress/unittests/sshsig/testdata/ecdsa b/crypto/openssh/regress/unittests/sshsig/testdata/ecdsa
new file mode 100644
index 000000000000..55fb440e01d4
--- /dev/null
+++ b/crypto/openssh/regress/unittests/sshsig/testdata/ecdsa
@@ -0,0 +1,5 @@
+-----BEGIN EC PRIVATE KEY-----
+MHcCAQEEIFg0ZCSEB5LNeLsXYL25g3kqEWsqh52DR+yNOjyQJqyZoAoGCCqGSM49
+AwEHoUQDQgAE3sud88FV0N8FPspZSV7LWqj6uPPLRZiSsenNuEYAteWPyDgrZsWb
+LzXBuUJucepaCNuW/QWgHBRbrjWj3ERm3A==
+-----END EC PRIVATE KEY-----
diff --git a/crypto/openssh/regress/unittests/sshsig/testdata/ecdsa.pub b/crypto/openssh/regress/unittests/sshsig/testdata/ecdsa.pub
new file mode 100644
index 000000000000..14ec6cf1230c
--- /dev/null
+++ b/crypto/openssh/regress/unittests/sshsig/testdata/ecdsa.pub
@@ -0,0 +1 @@
+ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBN7LnfPBVdDfBT7KWUley1qo+rjzy0WYkrHpzbhGALXlj8g4K2bFmy81wblCbnHqWgjblv0FoBwUW641o9xEZtw= ECDSA test
diff --git a/crypto/openssh/regress/unittests/sshsig/testdata/ecdsa.sig b/crypto/openssh/regress/unittests/sshsig/testdata/ecdsa.sig
new file mode 100644
index 000000000000..79781570cda1
--- /dev/null
+++ b/crypto/openssh/regress/unittests/sshsig/testdata/ecdsa.sig
@@ -0,0 +1,7 @@
+-----BEGIN SSH SIGNATURE-----
+U1NIU0lHAAAAAQAAAGgAAAATZWNkc2Etc2hhMi1uaXN0cDI1NgAAAAhuaXN0cDI1NgAAAE
+EE3sud88FV0N8FPspZSV7LWqj6uPPLRZiSsenNuEYAteWPyDgrZsWbLzXBuUJucepaCNuW
+/QWgHBRbrjWj3ERm3AAAAAh1bml0dGVzdAAAAAAAAAAGc2hhNTEyAAAAZQAAABNlY2RzYS
+1zaGEyLW5pc3RwMjU2AAAASgAAACEAycVNsTlE+XEZYyYiDxWZlliruf/pPMhEEMR/XLdQ
+a4MAAAAhALQt+5gES7L3uKGptHB6UZQMuZ2WyI0C6FJs4v6AtMIU
+-----END SSH SIGNATURE-----
diff --git a/crypto/openssh/regress/unittests/sshsig/testdata/ecdsa_sk b/crypto/openssh/regress/unittests/sshsig/testdata/ecdsa_sk
new file mode 100644
index 000000000000..62ae44cb09ee
--- /dev/null
+++ b/crypto/openssh/regress/unittests/sshsig/testdata/ecdsa_sk
@@ -0,0 +1,13 @@
+-----BEGIN OPENSSH PRIVATE KEY-----
+b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAfwAAACJzay1lY2
+RzYS1zaGEyLW5pc3RwMjU2QG9wZW5zc2guY29tAAAACG5pc3RwMjU2AAAAQQSg1WuY0XE+
+VexOsrJsFYuxyVoe6eQ/oXmyz2pEHKZw9moyWehv+Fs7oZWFp3JVmOtybKQ6dvfUZYauQE
+/Ov4PAAAAABHNzaDoAAAGI6iV41+oleNcAAAAic2stZWNkc2Etc2hhMi1uaXN0cDI1NkBv
+cGVuc3NoLmNvbQAAAAhuaXN0cDI1NgAAAEEEoNVrmNFxPlXsTrKybBWLsclaHunkP6F5ss
+9qRBymcPZqMlnob/hbO6GVhadyVZjrcmykOnb31GWGrkBPzr+DwAAAAARzc2g6AQAAAOMt
+LS0tLUJFR0lOIEVDIFBSSVZBVEUgS0VZLS0tLS0KTUhjQ0FRRUVJQm9oeW54M2tpTFVEeS
+t5UjU3WXBXSU5KektnU1p6WnV2VTljYXFla3JGcW9Bb0dDQ3FHU000OQpBd0VIb1VRRFFn
+QUVvTlZybU5GeFBsWHNUckt5YkJXTHNjbGFIdW5rUDZGNXNzOXFSQnltY1BacU1sbm9iL2
+hiCk82R1ZoYWR5VlpqcmNteWtPbmIzMUdXR3JrQlB6citEd0E9PQotLS0tLUVORCBFQyBQ
+UklWQVRFIEtFWS0tLS0tCgAAAAAAAAARRUNEU0EtU0sgdGVzdCBrZXk=
+-----END OPENSSH PRIVATE KEY-----
diff --git a/crypto/openssh/regress/unittests/sshsig/testdata/ecdsa_sk.pub b/crypto/openssh/regress/unittests/sshsig/testdata/ecdsa_sk.pub
new file mode 100644
index 000000000000..385ebf15b142
--- /dev/null
+++ b/crypto/openssh/regress/unittests/sshsig/testdata/ecdsa_sk.pub
@@ -0,0 +1 @@
+sk-ecdsa-sha2-nistp256@openssh.com AAAAInNrLWVjZHNhLXNoYTItbmlzdHAyNTZAb3BlbnNzaC5jb20AAAAIbmlzdHAyNTYAAABBBKDVa5jRcT5V7E6ysmwVi7HJWh7p5D+hebLPakQcpnD2ajJZ6G/4WzuhlYWnclWY63JspDp299Rlhq5AT86/g8AAAAAEc3NoOg== ECDSA-SK test key
diff --git a/crypto/openssh/regress/unittests/sshsig/testdata/ecdsa_sk.sig b/crypto/openssh/regress/unittests/sshsig/testdata/ecdsa_sk.sig
new file mode 100644
index 000000000000..86de36063174
--- /dev/null
+++ b/crypto/openssh/regress/unittests/sshsig/testdata/ecdsa_sk.sig
@@ -0,0 +1,8 @@
+-----BEGIN SSH SIGNATURE-----
+U1NIU0lHAAAAAQAAAH8AAAAic2stZWNkc2Etc2hhMi1uaXN0cDI1NkBvcGVuc3NoLmNvbQ
+AAAAhuaXN0cDI1NgAAAEEEoNVrmNFxPlXsTrKybBWLsclaHunkP6F5ss9qRBymcPZqMlno
+b/hbO6GVhadyVZjrcmykOnb31GWGrkBPzr+DwAAAAARzc2g6AAAACHVuaXR0ZXN0AAAAAA
+AAAAZzaGE1MTIAAAB3AAAAInNrLWVjZHNhLXNoYTItbmlzdHAyNTZAb3BlbnNzaC5jb20A
+AABIAAAAIHohGwyy8iKT3zwd1TYA9V/Ioo7h/3zCJUtyq/Qigt/HAAAAIGzidTwq7D/kFa
+7Xjcp/KkdbIs4MfQpfAW/0OciajlpzARI0Vng=
+-----END SSH SIGNATURE-----
diff --git a/crypto/openssh/regress/unittests/sshsig/testdata/ecdsa_sk_webauthn.pub b/crypto/openssh/regress/unittests/sshsig/testdata/ecdsa_sk_webauthn.pub
new file mode 100644
index 000000000000..1597302ce70d
--- /dev/null
+++ b/crypto/openssh/regress/unittests/sshsig/testdata/ecdsa_sk_webauthn.pub
@@ -0,0 +1 @@
+sk-ecdsa-sha2-nistp256@openssh.com AAAAInNrLWVjZHNhLXNoYTItbmlzdHAyNTZAb3BlbnNzaC5jb20AAAAIbmlzdHAyNTYAAABBBBRGwDjs4HhJFcn4tJ5Gr72KcmRmCS1OirETxaXvnsNApgoOLF1a/7rxldfSMHm73eT1nhHe97W8qicPPEAKDJQAAAALbWluZHJvdC5vcmc=
diff --git a/crypto/openssh/regress/unittests/sshsig/testdata/ecdsa_sk_webauthn.sig b/crypto/openssh/regress/unittests/sshsig/testdata/ecdsa_sk_webauthn.sig
new file mode 100644
index 000000000000..4bdd8edc681a
--- /dev/null
+++ b/crypto/openssh/regress/unittests/sshsig/testdata/ecdsa_sk_webauthn.sig
@@ -0,0 +1,13 @@
+-----BEGIN SSH SIGNATURE-----
+U1NIU0lHAAAAAQAAAIYAAAAic2stZWNkc2Etc2hhMi1uaXN0cDI1NkBvcGVuc3NoLmNvbQ
+AAAAhuaXN0cDI1NgAAAEEEFEbAOOzgeEkVyfi0nkavvYpyZGYJLU6KsRPFpe+ew0CmCg4s
+XVr/uvGV19Iwebvd5PWeEd73tbyqJw88QAoMlAAAAAttaW5kcm90Lm9yZwAAAAh1bml0dG
+VzdAAAAAAAAAAGc2hhNTEyAAABhwAAACt3ZWJhdXRobi1zay1lY2RzYS1zaGEyLW5pc3Rw
+MjU2QG9wZW5zc2guY29tAAAASQAAACBj2oMT9tb5wRXe6mdmf4/lgAO8wrgr95ouozwNg4
+itnQAAACEAtU9g5wz3HchUiLfLD6plr9T4TiJ32lVCrATSjpiy0SMBAAADHwAAABdodHRw
+czovL3d3dy5taW5kcm90Lm9yZwAAAON7InR5cGUiOiJ3ZWJhdXRobi5nZXQiLCJjaGFsbG
+VuZ2UiOiJVMU5JVTBsSEFBQUFDSFZ1YVhSMFpYTjBBQUFBQUFBQUFBWnphR0UxTVRJQUFB
+QkFMTHU4WmdjU3h0Nk1zRlV6dWlaZ0c2R3dNZEo5ZDd4ZUU3WW9SSXcwZzlpSEpfd3NGRD
+cxbzRXbHllenZGV0VqYnFRMHFDN0Z3R3Bqa2pVUVAtTmQ2dyIsIm9yaWdpbiI6Imh0dHBz
+Oi8vd3d3Lm1pbmRyb3Qub3JnIiwiY3Jvc3NPcmlnaW4iOmZhbHNlfQAAAAA=
+-----END SSH SIGNATURE-----
diff --git a/crypto/openssh/regress/unittests/sshsig/testdata/ed25519 b/crypto/openssh/regress/unittests/sshsig/testdata/ed25519
new file mode 100644
index 000000000000..b44a63d3ea60
--- /dev/null
+++ b/crypto/openssh/regress/unittests/sshsig/testdata/ed25519
@@ -0,0 +1,7 @@
+-----BEGIN OPENSSH PRIVATE KEY-----
+b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW
+QyNTUxOQAAACCJYs0iDdw0Fe/FTzY1b78I4H/j+R6mz2AmLtwTjHYwBAAAAJjpGas/6Rmr
+PwAAAAtzc2gtZWQyNTUxOQAAACCJYs0iDdw0Fe/FTzY1b78I4H/j+R6mz2AmLtwTjHYwBA
+AAAEDpSKRA1QKW6kYiQftGRWh+H0fNekzYLG6c3bzseoCpEolizSIN3DQV78VPNjVvvwjg
+f+P5HqbPYCYu3BOMdjAEAAAAEEVEMjU1MTkgdGVzdCBrZXkBAgMEBQ==
+-----END OPENSSH PRIVATE KEY-----
diff --git a/crypto/openssh/regress/unittests/sshsig/testdata/ed25519.pub b/crypto/openssh/regress/unittests/sshsig/testdata/ed25519.pub
new file mode 100644
index 000000000000..b078e4516fbe
--- /dev/null
+++ b/crypto/openssh/regress/unittests/sshsig/testdata/ed25519.pub
@@ -0,0 +1 @@
+ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIlizSIN3DQV78VPNjVvvwjgf+P5HqbPYCYu3BOMdjAE ED25519 test key
diff --git a/crypto/openssh/regress/unittests/sshsig/testdata/ed25519.sig b/crypto/openssh/regress/unittests/sshsig/testdata/ed25519.sig
new file mode 100644
index 000000000000..8e8ff2a8ac19
--- /dev/null
+++ b/crypto/openssh/regress/unittests/sshsig/testdata/ed25519.sig
@@ -0,0 +1,6 @@
+-----BEGIN SSH SIGNATURE-----
+U1NIU0lHAAAAAQAAADMAAAALc3NoLWVkMjU1MTkAAAAgiWLNIg3cNBXvxU82NW+/COB/4/
+keps9gJi7cE4x2MAQAAAAIdW5pdHRlc3QAAAAAAAAABnNoYTUxMgAAAFMAAAALc3NoLWVk
+MjU1MTkAAABAihQsbUzuNEFflk5Tw1+H9aLS7tZQk0RG8KW1DtOmDYYnWe3D3UKiG3fcJa
+DNg4vBWp1j1gLRiBMOF+gwYNegDg==
+-----END SSH SIGNATURE-----
diff --git a/crypto/openssh/regress/unittests/sshsig/testdata/ed25519_sk b/crypto/openssh/regress/unittests/sshsig/testdata/ed25519_sk
new file mode 100644
index 000000000000..3a434ecb9417
--- /dev/null
+++ b/crypto/openssh/regress/unittests/sshsig/testdata/ed25519_sk
@@ -0,0 +1,8 @@
+-----BEGIN OPENSSH PRIVATE KEY-----
+b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAASgAAABpzay1zc2
+gtZWQyNTUxOUBvcGVuc3NoLmNvbQAAACCbGg2F0GK7nOm4pQmAyCuGEjnhvs5q0TtjPbdN
+//+yxwAAAARzc2g6AAAAuBw56jAcOeowAAAAGnNrLXNzaC1lZDI1NTE5QG9wZW5zc2guY2
+9tAAAAIJsaDYXQYruc6bilCYDIK4YSOeG+zmrRO2M9t03//7LHAAAABHNzaDoBAAAAQFXc
+6dCwWewIk1EBofAouGZApW8+s0XekXenxtb78+x0mxoNhdBiu5zpuKUJgMgrhhI54b7Oat
+E7Yz23Tf//sscAAAAAAAAAE0VEMjU1MTktU0sgdGVzdCBrZXkBAgMEBQY=
+-----END OPENSSH PRIVATE KEY-----
diff --git a/crypto/openssh/regress/unittests/sshsig/testdata/ed25519_sk.pub b/crypto/openssh/regress/unittests/sshsig/testdata/ed25519_sk.pub
new file mode 100644
index 000000000000..71051ec3b217
--- /dev/null
+++ b/crypto/openssh/regress/unittests/sshsig/testdata/ed25519_sk.pub
@@ -0,0 +1 @@
+sk-ssh-ed25519@openssh.com AAAAGnNrLXNzaC1lZDI1NTE5QG9wZW5zc2guY29tAAAAIJsaDYXQYruc6bilCYDIK4YSOeG+zmrRO2M9t03//7LHAAAABHNzaDo= ED25519-SK test key
diff --git a/crypto/openssh/regress/unittests/sshsig/testdata/ed25519_sk.sig b/crypto/openssh/regress/unittests/sshsig/testdata/ed25519_sk.sig
new file mode 100644
index 000000000000..49b6818da59f
--- /dev/null
+++ b/crypto/openssh/regress/unittests/sshsig/testdata/ed25519_sk.sig
@@ -0,0 +1,7 @@
+-----BEGIN SSH SIGNATURE-----
+U1NIU0lHAAAAAQAAAEoAAAAac2stc3NoLWVkMjU1MTlAb3BlbnNzaC5jb20AAAAgmxoNhd
+Biu5zpuKUJgMgrhhI54b7OatE7Yz23Tf//sscAAAAEc3NoOgAAAAh1bml0dGVzdAAAAAAA
+AAAGc2hhNTEyAAAAZwAAABpzay1zc2gtZWQyNTUxOUBvcGVuc3NoLmNvbQAAAEAi+7eTjW
+/+LQ2M+sCD+KFtH1n7VFFJon/SZFsxODyV8cWTlFKj617Ys1Ur5TV6uaEXQhck8rBA2oQI
+HTPANLIPARI0Vng=
+-----END SSH SIGNATURE-----
diff --git a/crypto/openssh/regress/unittests/sshsig/testdata/namespace b/crypto/openssh/regress/unittests/sshsig/testdata/namespace
new file mode 100644
index 000000000000..1570cd548baa
--- /dev/null
+++ b/crypto/openssh/regress/unittests/sshsig/testdata/namespace
@@ -0,0 +1 @@
+unittest \ No newline at end of file
diff --git a/crypto/openssh/regress/unittests/sshsig/testdata/rsa b/crypto/openssh/regress/unittests/sshsig/testdata/rsa
new file mode 100644
index 000000000000..228fad7978e9
--- /dev/null
+++ b/crypto/openssh/regress/unittests/sshsig/testdata/rsa
@@ -0,0 +1,39 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIG4wIBAAKCAYEA386lmjRHtJpyj87BrS+ssMmtvc/1SPN0gXTPs9jZ1hYAq98P
+ca3/RYVM4HaSu6COztQJ2ZnZD3Te/XeBnIU2mfuvQEl+DiwisGeNglVyRCi7787f
+PFFfcxzZfDa7EB2qY8S3oaSGZK8QqzuGwmGAImjlQXz6J+HCd/eD/58GoCSSirIE
+CFWCAt+uNrOC/EmgAzsbfcfaIbbVzA40tlgU3hO2J42kddz8CisDTtDKQABFcOaQ
+ZycSfn7HDP+WgXLXXBUI9wVM1Tif1f+9MX08xIsvCvGzo7yLgbbTFLSGr5SkA+tO
+rYuoA7V8fge0id/3pnVtG1Ui3I7vejeAwf0HZqtFeBEnOwkIJFmZeMtFeOVf+4ki
+4h1rDqAvSscNvMtLp6OXpbAATATAuEWEkIQBl1rngnEe0iC9iU9itKMW6qJ4FtIb
+4ACH1EoU1x8vqrFecg2hvqfk5CZBJIbV28JFuGjac3OxBZ17Fqb8ljomUir1GrET
+2z66NMgb5TjDD7BVAgMBAAECggGACfjDGCPMLhfTkuS7bGP7ZcUWoKZrX1y5jCsQ
+NgsraYaBcSb3ITGHdimCS139G68DreN0rOVV7oJejRyOAdNNo367SDn+C9ObmBCF
+FZGJDdBiz0SAXceiYRaf+hDWNNmdheR16hXShxnlvDtivbZqZx4VWN2gp7Y/W+kD
+UJhdSzVV8igMVfK5YDdnI7jL1UHSh1JS3z/QUEA9NmJLpvQ1uc9XBlwhP78g27Me
+6pwS5tccQPOE65OqF0i+xa19nzbmnC940Y34yZeI/UE+PYaO2+asapvOfu/sboBH
+Yb5BuWXVEkSeRWI23SpuZbmfNTtVgiRoRqOvqM4G88LkhYjZ6xpDggxQwJiShiiD
+oWCucs0v3pX8H8/LbGs8l50SGI5nzUqAdZ7/QQucU/GuDiQtampntkLEDgf9KIw/
+SDrtCw1E9fnCWj4Z71IYfepY9bVY6QUEcfTdnDcYSY1Z5tVpzeMHVLeo0lbNVZv9
+2qmPnjjP/IvWbjjwu/PHpUWkUs0BAoHBAPx4YwPXWYgWnesMKXkjAHyO5KA4EyBr
++rcEmOZkZDibC8PKYzIK2ztptuthahVovW20R/QJhJkO5teGZMeGPFq+floCeC5P
+la9CEYGYcTrzgSe1QM9IGMr1vGI1KIWck7VkJ0bkKoY40uIJSVZxnyG9pEpcwYSp
+tnOqA/f5YZUFctWvXUz46OfiLKstXLrcrGIU7YRmLv2rW9twnpJYTzE98g3KpVJ2
+TI1pyvrDTdGeAQUTGCAjpviY6XR5d020vQKBwQDi76wsGLQ3XLI+OAE95Ljo0Mcl
++KdJPVVQPq/VcjKgZQndFloflMRrmgNHme9gmsHOrf8DLZvEDbtT+gbmWslMFZQ9
+om1kR404gfuGmfIYdBdOwWjuBLsZs3pfqDB4Xa3NkxljwOMYTp035n0r2UMFaSy3
+gvpW7fsdPOGAJsqNhSw/JNHcokHeBm7VbV0aD7tSyIghmARb5c98fmrSPbiEo8mP
+ITIZlgbfZCq2KuXY4q16R3QvlpuSwitVobLR/3kCgcEAueH5JM7dQHFGe9RMhL/c
+j9i1Q7GFg4183lsoKBkqIPMmylSsjB+qIihHYS4r6O9g6PCfOXH4iqiKFY0BjlWr
+AjTW2naO/aniz1KZiQ0v8PNv2Eh/Gx4+AtDCjpwM5bLOnfLLaEp9dK1JttqXgGnP
+fAwgdg+s+3votWgr29tkmU+VqPagfxeUg4Xm1XFkoL/wu5Yk+iIx3trXms1kMuOK
+CvtMyBK3fetTmZqWs+Iv3XGz1oSkcqVNPiN3XyY/TJsRAoG/Q17jvjOXTNg4EkCO
+HdHJE1Tnyl4HS7bpnOj/Sl6cqQFV7Ey2dKm1pjwSvS714bgP0UvWaRshIxLwif2w
+DrLlD7FYUPPnhd24Dw6HnW4WcSwFv1uryv2cjgS6T6ueuB0Xe/AvmW2p/Y1ZHz9N
+6baWLwUKQXCg4S3FXui0CVd6yoi+mgBUTSveYguG29WbziDde7YMs+xtXtravhrJ
+m6C3Jql5LQSt2uqvH6KdC3ewxLKGzcZot7f+d5MtSj6216ECgcEA9PGmWeUkhVuW
+Xz2c9iBeHwCtmDso7gVwxNnHqdqirB4f1nDCGbrJS7hz5Ss7/wfzekP2W5if2P6U
+JPUdfykAQgALNn1twAtj1a+UAp31ZWu8JK/Qzt4hLJPBxzMo7MenJq189JmYmDnm
+6D5d9vDLCW15gCZua89GZa8K8V50lYyeHBOHAyzNTfNlnMBkHyP645+nqpuEWzIT
+3mCe2OAbl60o8VvvVUlAQyQ/ObLq37HHEoDu0U/YAnP157cxpa84
+-----END RSA PRIVATE KEY-----
diff --git a/crypto/openssh/regress/unittests/sshsig/testdata/rsa.pub b/crypto/openssh/regress/unittests/sshsig/testdata/rsa.pub
new file mode 100644
index 000000000000..30142ac0aee3
--- /dev/null
+++ b/crypto/openssh/regress/unittests/sshsig/testdata/rsa.pub
@@ -0,0 +1 @@
+ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDfzqWaNEe0mnKPzsGtL6ywya29z/VI83SBdM+z2NnWFgCr3w9xrf9FhUzgdpK7oI7O1AnZmdkPdN79d4GchTaZ+69ASX4OLCKwZ42CVXJEKLvvzt88UV9zHNl8NrsQHapjxLehpIZkrxCrO4bCYYAiaOVBfPon4cJ394P/nwagJJKKsgQIVYIC3642s4L8SaADOxt9x9ohttXMDjS2WBTeE7YnjaR13PwKKwNO0MpAAEVw5pBnJxJ+fscM/5aBctdcFQj3BUzVOJ/V/70xfTzEiy8K8bOjvIuBttMUtIavlKQD606ti6gDtXx+B7SJ3/emdW0bVSLcju96N4DB/Qdmq0V4ESc7CQgkWZl4y0V45V/7iSLiHWsOoC9Kxw28y0uno5elsABMBMC4RYSQhAGXWueCcR7SIL2JT2K0oxbqongW0hvgAIfUShTXHy+qsV5yDaG+p+TkJkEkhtXbwkW4aNpzc7EFnXsWpvyWOiZSKvUasRPbPro0yBvlOMMPsFU= RSA test
diff --git a/crypto/openssh/regress/unittests/sshsig/testdata/rsa.sig b/crypto/openssh/regress/unittests/sshsig/testdata/rsa.sig
new file mode 100644
index 000000000000..15a032e0100b
--- /dev/null
+++ b/crypto/openssh/regress/unittests/sshsig/testdata/rsa.sig
@@ -0,0 +1,19 @@
+-----BEGIN SSH SIGNATURE-----
+U1NIU0lHAAAAAQAAAZcAAAAHc3NoLXJzYQAAAAMBAAEAAAGBAN/OpZo0R7Saco/Owa0vrL
+DJrb3P9UjzdIF0z7PY2dYWAKvfD3Gt/0WFTOB2krugjs7UCdmZ2Q903v13gZyFNpn7r0BJ
+fg4sIrBnjYJVckQou+/O3zxRX3Mc2Xw2uxAdqmPEt6GkhmSvEKs7hsJhgCJo5UF8+ifhwn
+f3g/+fBqAkkoqyBAhVggLfrjazgvxJoAM7G33H2iG21cwONLZYFN4TtieNpHXc/AorA07Q
+ykAARXDmkGcnEn5+xwz/loFy11wVCPcFTNU4n9X/vTF9PMSLLwrxs6O8i4G20xS0hq+UpA
+PrTq2LqAO1fH4HtInf96Z1bRtVItyO73o3gMH9B2arRXgRJzsJCCRZmXjLRXjlX/uJIuId
+aw6gL0rHDbzLS6ejl6WwAEwEwLhFhJCEAZda54JxHtIgvYlPYrSjFuqieBbSG+AAh9RKFN
+cfL6qxXnINob6n5OQmQSSG1dvCRbho2nNzsQWdexam/JY6JlIq9RqxE9s+ujTIG+U4ww+w
+VQAAAAh1bml0dGVzdAAAAAAAAAAGc2hhNTEyAAABlAAAAAxyc2Etc2hhMi01MTIAAAGACi
+nEpBrQxZi0yOrrT6h98JFfZh0XXioih4fzmvtoV0yOReWClS+otGgXoJyZHcbaKNOjDwSM
+rIkUoX6OUJmtHYP0HRELnKw35m33LdBPXpFGS4tRS7NeSpvc04KtjT6jYXY9FjWy5hcn17
+Sxc/3DnJqLgJBur8acY7FeIzpWmKixPd/dGkEjdWoD9gO6szLczGuQgrOdYmSRL4yKadTJ
+lVjz5OSeKSYYGQy33US2XQassRRNYf4e9byTA3DKvHa/OcTt7lFerea0kZdDpAboqffz7T
+Yaw/hFskAYLIEdTW3aoXBGHSOvu8AkDOtb7qwuxGSQ27pjkDLDNsp1ceCFaCaQ6X83RZuK
+ACv9JUBI5KaSf81e0bs0KezJKkhB9czeZ6dk96qISbgayEBnvhYgXvUDKtHn7HzNlCJKfK
+5ABhNxfGG2CD+NKqcrndwFgS1sQO3hbA84zPQb26ShBovT8ytHBmW1F8ZK4O9Bz61Q6EZK
+vs/u6xP6LUean/so5daa
+-----END SSH SIGNATURE-----
diff --git a/crypto/openssh/regress/unittests/sshsig/testdata/signed-data b/crypto/openssh/regress/unittests/sshsig/testdata/signed-data
new file mode 100644
index 000000000000..7df4bedd135c
--- /dev/null
+++ b/crypto/openssh/regress/unittests/sshsig/testdata/signed-data
@@ -0,0 +1 @@
+This is a test, this is only a test \ No newline at end of file
diff --git a/crypto/openssh/regress/unittests/sshsig/tests.c b/crypto/openssh/regress/unittests/sshsig/tests.c
new file mode 100644
index 000000000000..bf59d58d157e
--- /dev/null
+++ b/crypto/openssh/regress/unittests/sshsig/tests.c
@@ -0,0 +1,139 @@
+/* $OpenBSD: tests.c,v 1.2 2020/06/22 06:00:06 djm Exp $ */
+/*
+ * Regress test for sshbuf.h buffer API
+ *
+ * Placed in the public domain
+ */
+
+#include "includes.h"
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <stdio.h>
+#ifdef HAVE_STDINT_H
+#include <stdint.h>
+#endif
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <openssl/evp.h>
+#include <openssl/crypto.h>
+
+#include "ssherr.h"
+#include "authfile.h"
+#include "sshkey.h"
+#include "sshbuf.h"
+#include "sshsig.h"
+#include "log.h"
+
+#include "../test_helper/test_helper.h"
+
+static struct sshbuf *
+load_file(const char *name)
+{
+ struct sshbuf *ret = NULL;
+
+ ASSERT_INT_EQ(sshbuf_load_file(test_data_file(name), &ret), 0);
+ ASSERT_PTR_NE(ret, NULL);
+ return ret;
+}
+
+static struct sshkey *
+load_key(const char *name)
+{
+ struct sshkey *ret = NULL;
+ ASSERT_INT_EQ(sshkey_load_public(test_data_file(name), &ret, NULL), 0);
+ ASSERT_PTR_NE(ret, NULL);
+ return ret;
+}
+
+static void
+check_sig(const char *keyname, const char *signame, const struct sshbuf *msg,
+ const char *namespace)
+{
+ struct sshkey *k, *sign_key;
+ struct sshbuf *sig, *rawsig;
+ struct sshkey_sig_details *sig_details;
+
+ k = load_key(keyname);
+ sig = load_file(signame);
+ sign_key = NULL;
+ sig_details = NULL;
+ rawsig = NULL;
+ ASSERT_INT_EQ(sshsig_dearmor(sig, &rawsig), 0);
+ ASSERT_INT_EQ(sshsig_verifyb(rawsig, msg, namespace,
+ &sign_key, &sig_details), 0);
+ ASSERT_INT_EQ(sshkey_equal(k, sign_key), 1);
+ sshkey_free(k);
+ sshkey_free(sign_key);
+ sshkey_sig_details_free(sig_details);
+ sshbuf_free(sig);
+ sshbuf_free(rawsig);
+}
+
+void
+tests(void)
+{
+ struct sshbuf *msg;
+ char *namespace;
+
+#if 0
+ log_init("test_sshsig", SYSLOG_LEVEL_DEBUG3, SYSLOG_FACILITY_AUTH, 1);
+#endif
+
+#ifdef WITH_OPENSSL
+ OpenSSL_add_all_algorithms();
+ ERR_load_CRYPTO_strings();
+#endif
+
+ TEST_START("load data");
+ msg = load_file("namespace");
+ namespace = sshbuf_dup_string(msg);
+ ASSERT_PTR_NE(namespace, NULL);
+ sshbuf_free(msg);
+ msg = load_file("signed-data");
+ TEST_DONE();
+
+#ifdef WITH_OPENSSL
+ TEST_START("check RSA signature");
+ check_sig("rsa.pub", "rsa.sig", msg, namespace);
+ TEST_DONE();
+
+ TEST_START("check DSA signature");
+ check_sig("dsa.pub", "dsa.sig", msg, namespace);
+ TEST_DONE();
+
+#ifdef OPENSSL_HAS_ECC
+ TEST_START("check ECDSA signature");
+ check_sig("ecdsa.pub", "ecdsa.sig", msg, namespace);
+ TEST_DONE();
+#endif
+#endif
+
+ TEST_START("check ED25519 signature");
+ check_sig("ed25519.pub", "ed25519.sig", msg, namespace);
+ TEST_DONE();
+
+#if defined(WITH_OPENSSL) && defined(OPENSSL_HAS_ECC)
+ TEST_START("check ECDSA-SK signature");
+ check_sig("ecdsa_sk.pub", "ecdsa_sk.sig", msg, namespace);
+ TEST_DONE();
+#endif
+
+ TEST_START("check ED25519-SK signature");
+ check_sig("ed25519_sk.pub", "ed25519_sk.sig", msg, namespace);
+ TEST_DONE();
+
+#if defined(WITH_OPENSSL) && defined(OPENSSL_HAS_ECC)
+ TEST_START("check ECDSA-SK webauthn signature");
+ check_sig("ecdsa_sk_webauthn.pub", "ecdsa_sk_webauthn.sig",
+ msg, namespace);
+ TEST_DONE();
+#endif
+
+ sshbuf_free(msg);
+ free(namespace);
+}
diff --git a/crypto/openssh/regress/unittests/sshsig/webauthn.html b/crypto/openssh/regress/unittests/sshsig/webauthn.html
new file mode 100644
index 000000000000..1869c8b373cf
--- /dev/null
+++ b/crypto/openssh/regress/unittests/sshsig/webauthn.html
@@ -0,0 +1,766 @@
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
+<title>webauthn test</title>
+</head>
+<body onload="init()">
+<h1>webauthn test</h1>
+<p>
+This is a demo/test page for generating FIDO keys and signatures in SSH
+formats. The page initially displays a form to generate a FIDO key and
+convert it to a SSH public key.
+</p>
+<p>
+Once a key has been generated, an additional form will be displayed to
+allow signing of data using the just-generated key. The data may be signed
+as either a raw SSH signature or wrapped in a sshsig message (the latter is
+easier to test using command-line tools.
+</p>
+<p>
+Lots of debugging is printed along the way.
+</p>
+<h2>Enroll</h2>
+<span id="error" style="color: #800; font-weight: bold; font-size: 150%;"></span>
+<form id="enrollform">
+<table>
+<tr>
+<td><b>Username:</b></td>
+<td><input id="username" type="text" size="20" name="user" value="test" /></td>
+</tr>
+<tr><td></td><td><input id="assertsubmit" type="submit" value="submit" /></td></tr>
+</table>
+</form>
+<span id="enrollresult" style="visibility: hidden;">
+<h2>clientData</h2>
+<pre id="enrollresultjson" style="color: #008; font-family: monospace;"></pre>
+<h2>attestationObject raw</h2>
+<pre id="enrollresultraw" style="color: #008; font-family: monospace;"></pre>
+<h2>attestationObject</h2>
+<pre id="enrollresultattestobj" style="color: #008; font-family: monospace;"></pre>
+<h2>key handle</h2>
+<pre id="keyhandle" style="color: #008; font-family: monospace;"></pre>
+<h2>authData raw</h2>
+<pre id="enrollresultauthdataraw" style="color: #008; font-family: monospace;"></pre>
+<h2>authData</h2>
+<pre id="enrollresultauthdata" style="color: #008; font-family: monospace;"></pre>
+<h2>SSH pubkey blob</h2>
+<pre id="enrollresultpkblob" style="color: #008; font-family: monospace;"></pre>
+<h2>SSH pubkey string</h2>
+<pre id="enrollresultpk" style="color: #008; font-family: monospace;"></pre>
+<h2>SSH private key string</h2>
+<pre id="enrollresultprivkey" style="color: #008; font-family: monospace;"></pre>
+</span>
+<span id="assertsection" style="visibility: hidden;">
+<h2>Assert</h2>
+<form id="assertform">
+<span id="asserterror" style="color: #800; font-weight: bold;"></span>
+<table>
+<tr>
+<td><b>Data to sign:</b></td>
+<td><input id="message" type="text" size="20" name="message" value="test" /></td>
+</tr>
+<tr>
+<td><input id="message_sshsig" type="checkbox" checked /> use sshsig format</td>
+</tr>
+<tr>
+<td><b>Signature namespace:</b></td>
+<td><input id="message_namespace" type="text" size="20" name="namespace" value="test" /></td>
+</tr>
+<tr><td></td><td><input type="submit" value="submit" /></td></tr>
+</table>
+</form>
+</span>
+<span id="assertresult" style="visibility: hidden;">
+<h2>clientData</h2>
+<pre id="assertresultjson" style="color: #008; font-family: monospace;"></pre>
+<h2>signature raw</h2>
+<pre id="assertresultsigraw" style="color: #008; font-family: monospace;"></pre>
+<h2>authenticatorData raw</h2>
+<pre id="assertresultauthdataraw" style="color: #008; font-family: monospace;"></pre>
+<h2>authenticatorData</h2>
+<pre id="assertresultauthdata" style="color: #008; font-family: monospace;"></pre>
+<h2>signature in SSH format</h2>
+<pre id="assertresultsshsigraw" style="color: #008; font-family: monospace;"></pre>
+<h2>signature in SSH format (base64 encoded)</h2>
+<pre id="assertresultsshsigb64" style="color: #008; font-family: monospace;"></pre>
+</span>
+</body>
+<script>
+// ------------------------------------------------------------------
+// a crappy CBOR decoder - 20200401 djm@openbsd.org
+
+var CBORDecode = function(buffer) {
+ this.buf = buffer
+ this.v = new DataView(buffer)
+ this.offset = 0
+}
+
+CBORDecode.prototype.empty = function() {
+ return this.offset >= this.buf.byteLength
+}
+
+CBORDecode.prototype.getU8 = function() {
+ let r = this.v.getUint8(this.offset)
+ this.offset += 1
+ return r
+}
+
+CBORDecode.prototype.getU16 = function() {
+ let r = this.v.getUint16(this.offset)
+ this.offset += 2
+ return r
+}
+
+CBORDecode.prototype.getU32 = function() {
+ let r = this.v.getUint32(this.offset)
+ this.offset += 4
+ return r
+}
+
+CBORDecode.prototype.getU64 = function() {
+ let r = this.v.getUint64(this.offset)
+ this.offset += 8
+ return r
+}
+
+CBORDecode.prototype.getCBORTypeLen = function() {
+ let tl, t, l
+ tl = this.getU8()
+ t = (tl & 0xe0) >> 5
+ l = tl & 0x1f
+ return [t, this.decodeInteger(l)]
+}
+
+CBORDecode.prototype.decodeInteger = function(len) {
+ switch (len) {
+ case 0x18: return this.getU8()
+ case 0x19: return this.getU16()
+ case 0x20: return this.getU32()
+ case 0x21: return this.getU64()
+ default:
+ if (len <= 23) {
+ return len
+ }
+ throw new Error("Unsupported int type 0x" + len.toString(16))
+ }
+}
+
+CBORDecode.prototype.decodeNegint = function(len) {
+ let r = -(this.decodeInteger(len) + 1)
+ return r
+}
+
+CBORDecode.prototype.decodeByteString = function(len) {
+ let r = this.buf.slice(this.offset, this.offset + len)
+ this.offset += len
+ return r
+}
+
+CBORDecode.prototype.decodeTextString = function(len) {
+ let u8dec = new TextDecoder('utf-8')
+ r = u8dec.decode(this.decodeByteString(len))
+ return r
+}
+
+CBORDecode.prototype.decodeArray = function(len, level) {
+ let r = []
+ for (let i = 0; i < len; i++) {
+ let v = this.decodeInternal(level)
+ r.push(v)
+ // console.log("decodeArray level " + level.toString() + " index " + i.toString() + " value " + JSON.stringify(v))
+ }
+ return r
+}
+
+CBORDecode.prototype.decodeMap = function(len, level) {
+ let r = {}
+ for (let i = 0; i < len; i++) {
+ let k = this.decodeInternal(level)
+ let v = this.decodeInternal(level)
+ r[k] = v
+ // console.log("decodeMap level " + level.toString() + " key " + k.toString() + " value " + JSON.stringify(v))
+ // XXX check string keys, duplicates
+ }
+ return r
+}
+
+CBORDecode.prototype.decodePrimitive = function(t) {
+ switch (t) {
+ case 20: return false
+ case 21: return true
+ case 22: return null
+ case 23: return undefined
+ default:
+ throw new Error("Unsupported primitive 0x" + t.toString(2))
+ }
+}
+
+CBORDecode.prototype.decodeInternal = function(level) {
+ if (level > 256) {
+ throw new Error("CBOR nesting too deep")
+ }
+ let t, l, r
+ [t, l] = this.getCBORTypeLen()
+ // console.log("decode level " + level.toString() + " type " + t.toString() + " len " + l.toString())
+ switch (t) {
+ case 0:
+ r = this.decodeInteger(l)
+ break
+ case 1:
+ r = this.decodeNegint(l)
+ break
+ case 2:
+ r = this.decodeByteString(l)
+ break
+ case 3:
+ r = this.decodeTextString(l)
+ break
+ case 4:
+ r = this.decodeArray(l, level + 1)
+ break
+ case 5:
+ r = this.decodeMap(l, level + 1)
+ break
+ case 6:
+ console.log("XXX ignored semantic tag " + this.decodeInteger(l).toString())
+ break;
+ case 7:
+ r = this.decodePrimitive(l)
+ break
+ default:
+ throw new Error("Unsupported type 0x" + t.toString(2) + " len " + l.toString())
+ }
+ // console.log("decode level " + level.toString() + " value " + JSON.stringify(r))
+ return r
+}
+
+CBORDecode.prototype.decode = function() {
+ return this.decodeInternal(0)
+}
+
+// ------------------------------------------------------------------
+// a crappy SSH message packer - 20200401 djm@openbsd.org
+
+var SSHMSG = function() {
+ this.r = []
+}
+
+SSHMSG.prototype.length = function() {
+ let len = 0
+ for (buf of this.r) {
+ len += buf.length
+ }
+ return len
+}
+
+SSHMSG.prototype.serialise = function() {
+ let r = new ArrayBuffer(this.length())
+ let v = new Uint8Array(r)
+ let offset = 0
+ for (buf of this.r) {
+ v.set(buf, offset)
+ offset += buf.length
+ }
+ if (offset != r.byteLength) {
+ throw new Error("djm can't count")
+ }
+ return r
+}
+
+SSHMSG.prototype.serialiseBase64 = function(v) {
+ let b = this.serialise()
+ return btoa(String.fromCharCode(...new Uint8Array(b)));
+}
+
+SSHMSG.prototype.putU8 = function(v) {
+ this.r.push(new Uint8Array([v]))
+}
+
+SSHMSG.prototype.putU32 = function(v) {
+ this.r.push(new Uint8Array([
+ (v >> 24) & 0xff,
+ (v >> 16) & 0xff,
+ (v >> 8) & 0xff,
+ (v & 0xff)
+ ]))
+}
+
+SSHMSG.prototype.put = function(v) {
+ this.r.push(new Uint8Array(v))
+}
+
+SSHMSG.prototype.putStringRaw = function(v) {
+ let enc = new TextEncoder();
+ let venc = enc.encode(v)
+ this.put(venc)
+}
+
+SSHMSG.prototype.putString = function(v) {
+ let enc = new TextEncoder();
+ let venc = enc.encode(v)
+ this.putU32(venc.length)
+ this.put(venc)
+}
+
+SSHMSG.prototype.putSSHMSG = function(v) {
+ let msg = v.serialise()
+ this.putU32(msg.byteLength)
+ this.put(msg)
+}
+
+SSHMSG.prototype.putBytes = function(v) {
+ this.putU32(v.byteLength)
+ this.put(v)
+}
+
+SSHMSG.prototype.putECPoint = function(x, y) {
+ let x8 = new Uint8Array(x)
+ let y8 = new Uint8Array(y)
+ this.putU32(1 + x8.length + y8.length)
+ this.putU8(0x04) // Uncompressed point format.
+ this.put(x8)
+ this.put(y8)
+}
+
+// ------------------------------------------------------------------
+// webauthn to SSH glue - djm@openbsd.org 20200408
+
+function error(msg, ...args) {
+ document.getElementById("error").innerText = msg
+ console.log(msg)
+ for (const arg of args) {
+ console.dir(arg)
+ }
+}
+function hexdump(buf) {
+ const hex = Array.from(new Uint8Array(buf)).map(
+ b => b.toString(16).padStart(2, "0"))
+ const fmt = new Array()
+ for (let i = 0; i < hex.length; i++) {
+ if ((i % 16) == 0) {
+ // Prepend length every 16 bytes.
+ fmt.push(i.toString(16).padStart(4, "0"))
+ fmt.push(" ")
+ }
+ fmt.push(hex[i])
+ fmt.push(" ")
+ if ((i % 16) == 15) {
+ fmt.push("\n")
+ }
+ }
+ return fmt.join("")
+}
+function enrollform_submit(event) {
+ event.preventDefault();
+ console.log("submitted")
+ username = event.target.elements.username.value
+ if (username === "") {
+ error("no username specified")
+ return false
+ }
+ enrollStart(username)
+}
+function enrollStart(username) {
+ let challenge = new Uint8Array(32)
+ window.crypto.getRandomValues(challenge)
+ let userid = new Uint8Array(8)
+ window.crypto.getRandomValues(userid)
+
+ console.log("challenge:" + btoa(challenge))
+ console.log("userid:" + btoa(userid))
+
+ let pkopts = {
+ challenge: challenge,
+ rp: {
+ name: "mindrot.org",
+ id: "mindrot.org",
+ },
+ user: {
+ id: userid,
+ name: username,
+ displayName: username,
+ },
+ authenticatorSelection: {
+ authenticatorAttachment: "cross-platform",
+ userVerification: "discouraged",
+ },
+ pubKeyCredParams: [{alg: -7, type: "public-key"}], // ES256
+ timeout: 30 * 1000,
+ };
+ console.dir(pkopts)
+ window.enrollOpts = pkopts
+ let credpromise = navigator.credentials.create({ publicKey: pkopts });
+ credpromise.then(enrollSuccess, enrollFailure)
+}
+function enrollFailure(result) {
+ error("Enroll failed", result)
+}
+function enrollSuccess(result) {
+ console.log("Enroll succeeded")
+ console.dir(result)
+ window.enrollResult = result
+ document.getElementById("enrollresult").style.visibility = "visible"
+
+ // Show the clientData
+ let u8dec = new TextDecoder('utf-8')
+ clientData = u8dec.decode(result.response.clientDataJSON)
+ document.getElementById("enrollresultjson").innerText = clientData
+
+ // Show the raw key handle.
+ document.getElementById("keyhandle").innerText = hexdump(result.rawId)
+
+ // Decode and show the attestationObject
+ document.getElementById("enrollresultraw").innerText = hexdump(result.response.attestationObject)
+ let aod = new CBORDecode(result.response.attestationObject)
+ let attestationObject = aod.decode()
+ console.log("attestationObject")
+ console.dir(attestationObject)
+ document.getElementById("enrollresultattestobj").innerText = JSON.stringify(attestationObject)
+
+ // Decode and show the authData
+ document.getElementById("enrollresultauthdataraw").innerText = hexdump(attestationObject.authData)
+ let authData = decodeAuthenticatorData(attestationObject.authData, true)
+ console.log("authData")
+ console.dir(authData)
+ window.enrollAuthData = authData
+ document.getElementById("enrollresultauthdata").innerText = JSON.stringify(authData)
+
+ // Reformat the pubkey as a SSH key for easy verification
+ window.rawKey = reformatPubkey(authData.attestedCredentialData.credentialPublicKey, window.enrollOpts.rp.id)
+ console.log("SSH pubkey blob")
+ console.dir(window.rawKey)
+ document.getElementById("enrollresultpkblob").innerText = hexdump(window.rawKey)
+ let pk64 = btoa(String.fromCharCode(...new Uint8Array(window.rawKey)));
+ let pk = "sk-ecdsa-sha2-nistp256@openssh.com " + pk64
+ document.getElementById("enrollresultpk").innerText = pk
+
+ // Format a private key too.
+ flags = 0x01 // SSH_SK_USER_PRESENCE_REQD
+ window.rawPrivkey = reformatPrivkey(authData.attestedCredentialData.credentialPublicKey, window.enrollOpts.rp.id, result.rawId, flags)
+ let privkeyFileBlob = privkeyFile(window.rawKey, window.rawPrivkey, window.enrollOpts.user.name, window.enrollOpts.rp.id)
+ let privk64 = btoa(String.fromCharCode(...new Uint8Array(privkeyFileBlob)));
+ let privkey = "-----BEGIN OPENSSH PRIVATE KEY-----\n" + wrapString(privk64, 70) + "-----END OPENSSH PRIVATE KEY-----\n"
+ document.getElementById("enrollresultprivkey").innerText = privkey
+
+ // Success: show the assertion form.
+ document.getElementById("assertsection").style.visibility = "visible"
+}
+
+function decodeAuthenticatorData(authData, expectCred) {
+ let r = new Object()
+ let v = new DataView(authData)
+
+ r.rpIdHash = authData.slice(0, 32)
+ r.flags = v.getUint8(32)
+ r.signCount = v.getUint32(33)
+
+ // Decode attestedCredentialData if present.
+ let offset = 37
+ let acd = new Object()
+ if (expectCred) {
+ acd.aaguid = authData.slice(offset, offset+16)
+ offset += 16
+ let credentialIdLength = v.getUint16(offset)
+ offset += 2
+ acd.credentialIdLength = credentialIdLength
+ acd.credentialId = authData.slice(offset, offset+credentialIdLength)
+ offset += credentialIdLength
+ r.attestedCredentialData = acd
+ }
+ console.log("XXXXX " + offset.toString())
+ let pubkeyrest = authData.slice(offset, authData.byteLength)
+ let pkdecode = new CBORDecode(pubkeyrest)
+ if (expectCred) {
+ // XXX unsafe: doesn't mandate COSE canonical format.
+ acd.credentialPublicKey = pkdecode.decode()
+ }
+ if (!pkdecode.empty()) {
+ // Decode extensions if present.
+ r.extensions = pkdecode.decode()
+ }
+ return r
+}
+
+function wrapString(s, l) {
+ ret = ""
+ for (i = 0; i < s.length; i += l) {
+ ret += s.slice(i, i + l) + "\n"
+ }
+ return ret
+}
+
+function checkPubkey(pk) {
+ // pk is in COSE format. We only care about a tiny subset.
+ if (pk[1] != 2) {
+ console.dir(pk)
+ throw new Error("pubkey is not EC")
+ }
+ if (pk[-1] != 1) {
+ throw new Error("pubkey is not in P256")
+ }
+ if (pk[3] != -7) {
+ throw new Error("pubkey is not ES256")
+ }
+ if (pk[-2].byteLength != 32 || pk[-3].byteLength != 32) {
+ throw new Error("pubkey EC coords have bad length")
+ }
+}
+
+function reformatPubkey(pk, rpid) {
+ checkPubkey(pk)
+ let msg = new SSHMSG()
+ msg.putString("sk-ecdsa-sha2-nistp256@openssh.com") // Key type
+ msg.putString("nistp256") // Key curve
+ msg.putECPoint(pk[-2], pk[-3]) // EC key
+ msg.putString(rpid) // RP ID
+ return msg.serialise()
+}
+
+function reformatPrivkey(pk, rpid, kh, flags) {
+ checkPubkey(pk)
+ let msg = new SSHMSG()
+ msg.putString("sk-ecdsa-sha2-nistp256@openssh.com") // Key type
+ msg.putString("nistp256") // Key curve
+ msg.putECPoint(pk[-2], pk[-3]) // EC key
+ msg.putString(rpid) // RP ID
+ msg.putU8(flags) // flags
+ msg.putBytes(kh) // handle
+ msg.putString("") // reserved
+ return msg.serialise()
+}
+
+function privkeyFile(pub, priv, user, rp) {
+ let innerMsg = new SSHMSG()
+ innerMsg.putU32(0xdeadbeef) // check byte
+ innerMsg.putU32(0xdeadbeef) // check byte
+ innerMsg.put(priv) // privkey
+ innerMsg.putString("webauthn.html " + user + "@" + rp) // comment
+ // Pad to cipher blocksize (8).
+ p = 1
+ while (innerMsg.length() % 8 != 0) {
+ innerMsg.putU8(p++)
+ }
+ let msg = new SSHMSG()
+ msg.putStringRaw("openssh-key-v1") // Magic
+ msg.putU8(0) // \0 terminate
+ msg.putString("none") // cipher
+ msg.putString("none") // KDF
+ msg.putString("") // KDF options
+ msg.putU32(1) // nkeys
+ msg.putBytes(pub) // pubkey
+ msg.putSSHMSG(innerMsg) // inner
+ //msg.put(innerMsg.serialise()) // inner
+ return msg.serialise()
+}
+
+async function assertform_submit(event) {
+ event.preventDefault();
+ console.log("submitted")
+ message = event.target.elements.message.value
+ if (message === "") {
+ error("no message specified")
+ return false
+ }
+ let enc = new TextEncoder()
+ let encmsg = enc.encode(message)
+ window.assertSignRaw = !event.target.elements.message_sshsig.checked
+ console.log("using sshsig ", !window.assertSignRaw)
+ if (window.assertSignRaw) {
+ assertStart(encmsg)
+ return
+ }
+ // Format a sshsig-style message.
+ window.sigHashAlg = "sha512"
+ let msghash = await crypto.subtle.digest("SHA-512", encmsg);
+ console.log("raw message hash")
+ console.dir(msghash)
+ window.sigNamespace = event.target.elements.message_namespace.value
+ let sigbuf = new SSHMSG()
+ sigbuf.put(enc.encode("SSHSIG"))
+ sigbuf.putString(window.sigNamespace)
+ sigbuf.putU32(0) // Reserved string
+ sigbuf.putString(window.sigHashAlg)
+ sigbuf.putBytes(msghash)
+ let msg = sigbuf.serialise()
+ console.log("sigbuf")
+ console.dir(msg)
+ assertStart(msg)
+}
+
+function assertStart(message) {
+ let assertReqOpts = {
+ challenge: message,
+ rpId: "mindrot.org",
+ allowCredentials: [{
+ type: 'public-key',
+ id: window.enrollResult.rawId,
+ }],
+ userVerification: "discouraged",
+ timeout: (30 * 1000),
+ }
+ console.log("assertReqOpts")
+ console.dir(assertReqOpts)
+ window.assertReqOpts = assertReqOpts
+ let assertpromise = navigator.credentials.get({
+ publicKey: assertReqOpts
+ });
+ assertpromise.then(assertSuccess, assertFailure)
+}
+function assertFailure(result) {
+ error("Assertion failed", result)
+}
+function linewrap(s) {
+ const linelen = 70
+ let ret = ""
+ for (let i = 0; i < s.length; i += linelen) {
+ end = i + linelen
+ if (end > s.length) {
+ end = s.length
+ }
+ if (i > 0) {
+ ret += "\n"
+ }
+ ret += s.slice(i, end)
+ }
+ return ret + "\n"
+}
+function assertSuccess(result) {
+ console.log("Assertion succeeded")
+ console.dir(result)
+ window.assertResult = result
+ document.getElementById("assertresult").style.visibility = "visible"
+
+ // show the clientData.
+ let u8dec = new TextDecoder('utf-8')
+ clientData = u8dec.decode(result.response.clientDataJSON)
+ document.getElementById("assertresultjson").innerText = clientData
+
+ // show the signature.
+ document.getElementById("assertresultsigraw").innerText = hexdump(result.response.signature)
+
+ // decode and show the authData.
+ document.getElementById("assertresultauthdataraw").innerText = hexdump(result.response.authenticatorData)
+ authData = decodeAuthenticatorData(result.response.authenticatorData, false)
+ document.getElementById("assertresultauthdata").innerText = JSON.stringify(authData)
+
+ // Parse and reformat the signature to an SSH style signature.
+ let sshsig = reformatSignature(result.response.signature, clientData, authData)
+ document.getElementById("assertresultsshsigraw").innerText = hexdump(sshsig)
+ let sig64 = btoa(String.fromCharCode(...new Uint8Array(sshsig)));
+ if (window.assertSignRaw) {
+ document.getElementById("assertresultsshsigb64").innerText = sig64
+ } else {
+ document.getElementById("assertresultsshsigb64").innerText =
+ "-----BEGIN SSH SIGNATURE-----\n" + linewrap(sig64) +
+ "-----END SSH SIGNATURE-----\n";
+ }
+}
+
+function reformatSignature(sig, clientData, authData) {
+ if (sig.byteLength < 2) {
+ throw new Error("signature is too short")
+ }
+ let offset = 0
+ let v = new DataView(sig)
+ // Expect an ASN.1 SEQUENCE that exactly spans the signature.
+ if (v.getUint8(offset) != 0x30) {
+ throw new Error("signature not an ASN.1 sequence")
+ }
+ offset++
+ let seqlen = v.getUint8(offset)
+ offset++
+ if ((seqlen & 0x80) != 0 || seqlen != sig.byteLength - offset) {
+ throw new Error("signature has unexpected length " + seqlen.toString() + " vs expected " + (sig.byteLength - offset).toString())
+ }
+
+ // Parse 'r' INTEGER value.
+ if (v.getUint8(offset) != 0x02) {
+ throw new Error("signature r not an ASN.1 integer")
+ }
+ offset++
+ let rlen = v.getUint8(offset)
+ offset++
+ if ((rlen & 0x80) != 0 || rlen > sig.byteLength - offset) {
+ throw new Error("signature r has unexpected length " + rlen.toString() + " vs buffer " + (sig.byteLength - offset).toString())
+ }
+ let r = sig.slice(offset, offset + rlen)
+ offset += rlen
+ console.log("sig_r")
+ console.dir(r)
+
+ // Parse 's' INTEGER value.
+ if (v.getUint8(offset) != 0x02) {
+ throw new Error("signature r not an ASN.1 integer")
+ }
+ offset++
+ let slen = v.getUint8(offset)
+ offset++
+ if ((slen & 0x80) != 0 || slen > sig.byteLength - offset) {
+ throw new Error("signature s has unexpected length " + slen.toString() + " vs buffer " + (sig.byteLength - offset).toString())
+ }
+ let s = sig.slice(offset, offset + slen)
+ console.log("sig_s")
+ console.dir(s)
+ offset += slen
+
+ if (offset != sig.byteLength) {
+ throw new Error("unexpected final offset during signature parsing " + offset.toString() + " expected " + sig.byteLength.toString())
+ }
+
+ // Reformat as an SSH signature.
+ let clientDataParsed = JSON.parse(clientData)
+ let innersig = new SSHMSG()
+ innersig.putBytes(r)
+ innersig.putBytes(s)
+
+ let rawsshsig = new SSHMSG()
+ rawsshsig.putString("webauthn-sk-ecdsa-sha2-nistp256@openssh.com")
+ rawsshsig.putSSHMSG(innersig)
+ rawsshsig.putU8(authData.flags)
+ rawsshsig.putU32(authData.signCount)
+ rawsshsig.putString(clientDataParsed.origin)
+ rawsshsig.putString(clientData)
+ if (authData.extensions == undefined) {
+ rawsshsig.putU32(0)
+ } else {
+ rawsshsig.putBytes(authData.extensions)
+ }
+
+ if (window.assertSignRaw) {
+ return rawsshsig.serialise()
+ }
+ // Format as SSHSIG.
+ let enc = new TextEncoder()
+ let sshsig = new SSHMSG()
+ sshsig.put(enc.encode("SSHSIG"))
+ sshsig.putU32(0x01) // Signature version.
+ sshsig.putBytes(window.rawKey)
+ sshsig.putString(window.sigNamespace)
+ sshsig.putU32(0) // Reserved string
+ sshsig.putString(window.sigHashAlg)
+ sshsig.putBytes(rawsshsig.serialise())
+ return sshsig.serialise()
+}
+
+function toggleNamespaceVisibility() {
+ const assertsigtype = document.getElementById('message_sshsig');
+ const assertsignamespace = document.getElementById('message_namespace');
+ assertsignamespace.disabled = !assertsigtype.checked;
+}
+
+function init() {
+ if (document.location.protocol != "https:") {
+ error("This page must be loaded via https")
+ const assertsubmit = document.getElementById('assertsubmit')
+ assertsubmit.disabled = true
+ }
+ const enrollform = document.getElementById('enrollform');
+ enrollform.addEventListener('submit', enrollform_submit);
+ const assertform = document.getElementById('assertform');
+ assertform.addEventListener('submit', assertform_submit);
+ const assertsigtype = document.getElementById('message_sshsig');
+ assertsigtype.onclick = toggleNamespaceVisibility;
+}
+</script>
+
+</html>
diff --git a/crypto/openssh/regress/unittests/test_helper/test_helper.c b/crypto/openssh/regress/unittests/test_helper/test_helper.c
index 4cc70852c044..9014ce8e4d02 100644
--- a/crypto/openssh/regress/unittests/test_helper/test_helper.c
+++ b/crypto/openssh/regress/unittests/test_helper/test_helper.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: test_helper.c,v 1.8 2018/02/08 08:46:20 djm Exp $ */
+/* $OpenBSD: test_helper.c,v 1.12 2019/08/02 01:41:24 djm Exp $ */
/*
* Copyright (c) 2011 Damien Miller <djm@mindrot.org>
*
@@ -23,6 +23,7 @@
#include <sys/param.h>
#include <sys/uio.h>
+#include <stdarg.h>
#include <fcntl.h>
#include <stdio.h>
#ifdef HAVE_STDINT_H
@@ -34,12 +35,16 @@
#include <unistd.h>
#include <signal.h>
+#ifdef WITH_OPENSSL
#include <openssl/bn.h>
+#include <openssl/err.h>
+#endif
#if defined(HAVE_STRNVIS) && defined(HAVE_VIS_H) && !defined(BROKEN_STRNVIS)
# include <vis.h>
#endif
+#include "entropy.h"
#include "test_helper.h"
#include "atomicio.h"
@@ -115,12 +120,19 @@ static test_onerror_func_t *test_onerror = NULL;
static void *onerror_ctx = NULL;
static const char *data_dir = NULL;
static char subtest_info[512];
+static int fast = 0;
+static int slow = 0;
int
main(int argc, char **argv)
{
int ch;
+ seed_rng();
+#ifdef WITH_OPENSSL
+ ERR_load_CRYPTO_strings();
+#endif
+
/* Handle systems without __progname */
if (__progname == NULL) {
__progname = strrchr(argv[0], '/');
@@ -134,8 +146,14 @@ main(int argc, char **argv)
}
}
- while ((ch = getopt(argc, argv, "vqd:")) != -1) {
+ while ((ch = getopt(argc, argv, "Ffvqd:")) != -1) {
switch (ch) {
+ case 'F':
+ slow = 1;
+ break;
+ case 'f':
+ fast = 1;
+ break;
case 'd':
data_dir = optarg;
break;
@@ -167,17 +185,29 @@ main(int argc, char **argv)
}
int
-test_is_verbose()
+test_is_verbose(void)
{
return verbose_mode;
}
int
-test_is_quiet()
+test_is_quiet(void)
{
return quiet_mode;
}
+int
+test_is_fast(void)
+{
+ return fast;
+}
+
+int
+test_is_slow(void)
+{
+ return slow;
+}
+
const char *
test_data_file(const char *name)
{
@@ -262,6 +292,7 @@ test_subtest_info(const char *fmt, ...)
void
ssl_err_check(const char *file, int line)
{
+#ifdef WITH_OPENSSL
long openssl_error = ERR_get_error();
if (openssl_error == 0)
@@ -269,6 +300,10 @@ ssl_err_check(const char *file, int line)
fprintf(stderr, "\n%s:%d: uncaught OpenSSL error: %s",
file, line, ERR_error_string(openssl_error, NULL));
+#else /* WITH_OPENSSL */
+ fprintf(stderr, "\n%s:%d: uncaught OpenSSL error ",
+ file, line);
+#endif /* WITH_OPENSSL */
abort();
}
@@ -313,6 +348,7 @@ test_header(const char *file, int line, const char *a1, const char *a2,
a2 != NULL ? ", " : "", a2 != NULL ? a2 : "");
}
+#ifdef WITH_OPENSSL
void
assert_bignum(const char *file, int line, const char *a1, const char *a2,
const BIGNUM *aa1, const BIGNUM *aa2, enum test_predicate pred)
@@ -325,6 +361,7 @@ assert_bignum(const char *file, int line, const char *a1, const char *a2,
fprintf(stderr, "%12s = 0x%s\n", a2, BN_bn2hex(aa2));
test_die();
}
+#endif
void
assert_string(const char *file, int line, const char *a1, const char *a2,
@@ -366,6 +403,8 @@ 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;
+ char *aa1_tohex = NULL;
+ char *aa2_tohex = NULL;
if (l == 0)
return;
@@ -376,8 +415,12 @@ assert_mem(const char *file, int line, const char *a1, const char *a2,
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);
+ aa1_tohex = tohex(aa1, MIN(l, 256));
+ aa2_tohex = tohex(aa2, MIN(l, 256));
+ fprintf(stderr, "%12s = %s (len %zu)\n", a1, aa1_tohex, l);
+ fprintf(stderr, "%12s = %s (len %zu)\n", a2, aa2_tohex, l);
+ free(aa1_tohex);
+ free(aa2_tohex);
test_die();
}
@@ -402,6 +445,7 @@ assert_mem_filled(const char *file, int line, const char *a1,
size_t where = -1;
int r;
char tmp[64];
+ char *aa1_tohex = NULL;
if (l == 0)
return;
@@ -411,8 +455,10 @@ assert_mem_filled(const char *file, int line, const char *a1,
r = memvalcmp(aa1, v, l, &where);
TEST_CHECK_INT(r, pred);
test_header(file, line, a1, NULL, "MEM_ZERO", pred);
+ aa1_tohex = tohex(aa1, MIN(l, 20));
fprintf(stderr, "%20s = %s%s (len %zu)\n", a1,
- tohex(aa1, MIN(l, 20)), l > 20 ? "..." : "", l);
+ aa1_tohex, l > 20 ? "..." : "", l);
+ free(aa1_tohex);
snprintf(tmp, sizeof(tmp), "(%s)[%zu]", a1, where);
fprintf(stderr, "%20s = 0x%02x (expected 0x%02x)\n", tmp,
((u_char *)aa1)[where], v);
diff --git a/crypto/openssh/regress/unittests/test_helper/test_helper.h b/crypto/openssh/regress/unittests/test_helper/test_helper.h
index 6da0066e907a..66302201cec3 100644
--- a/crypto/openssh/regress/unittests/test_helper/test_helper.h
+++ b/crypto/openssh/regress/unittests/test_helper/test_helper.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: test_helper.h,v 1.8 2018/02/08 08:46:20 djm Exp $ */
+/* $OpenBSD: test_helper.h,v 1.9 2018/10/17 23:28:05 djm Exp $ */
/*
* Copyright (c) 2011 Damien Miller <djm@mindrot.org>
*
@@ -27,8 +27,10 @@
# include <stdint.h>
#endif
+#ifdef WITH_OPENSSL
#include <openssl/bn.h>
#include <openssl/err.h>
+#endif
enum test_predicate {
TEST_EQ, TEST_NE, TEST_LT, TEST_LE, TEST_GT, TEST_GE
@@ -45,12 +47,16 @@ void set_onerror_func(test_onerror_func_t *f, void *ctx);
void test_done(void);
int test_is_verbose(void);
int test_is_quiet(void);
+int test_is_fast(void);
+int test_is_slow(void);
void test_subtest_info(const char *fmt, ...)
__attribute__((format(printf, 1, 2)));
void ssl_err_check(const char *file, int line);
+#ifdef WITH_OPENSSL
void assert_bignum(const char *file, int line,
const char *a1, const char *a2,
const BIGNUM *aa1, const BIGNUM *aa2, enum test_predicate pred);
+#endif
void assert_string(const char *file, int line,
const char *a1, const char *a2,
const char *aa1, const char *aa2, enum test_predicate pred);
diff --git a/crypto/openssh/regress/unittests/utf8/tests.c b/crypto/openssh/regress/unittests/utf8/tests.c
index f0bbca5096f0..8cf524ddb210 100644
--- a/crypto/openssh/regress/unittests/utf8/tests.c
+++ b/crypto/openssh/regress/unittests/utf8/tests.c
@@ -9,7 +9,9 @@
#include "includes.h"
#include <locale.h>
+#include <stdarg.h>
#include <string.h>
+#include <stdio.h>
#include "../test_helper/test_helper.h"
diff --git a/crypto/openssh/regress/valgrind-unit.sh b/crypto/openssh/regress/valgrind-unit.sh
index 4143ead4b62e..193289e6b78e 100755
--- a/crypto/openssh/regress/valgrind-unit.sh
+++ b/crypto/openssh/regress/valgrind-unit.sh
@@ -19,4 +19,6 @@ if [ "x$VALGRIND_PATH" != "x" ]; then
VG_PATH="$VALGRIND_PATH"
fi
+mkdir -p "$OBJ/valgrind-out"
+
exec $VG_PATH $VG_OPTS $UNIT_BINARY $UNIT_ARGS
diff --git a/crypto/openssh/sandbox-darwin.c b/crypto/openssh/sandbox-darwin.c
index a61de74951a0..59b4d286eea5 100644
--- a/crypto/openssh/sandbox-darwin.c
+++ b/crypto/openssh/sandbox-darwin.c
@@ -30,7 +30,7 @@
#include <unistd.h>
#include "log.h"
-#include "sandbox.h"
+#include "ssh-sandbox.h"
#include "monitor.h"
#include "xmalloc.h"
diff --git a/crypto/openssh/sandbox-pledge.c b/crypto/openssh/sandbox-pledge.c
index d28fc27274e2..302f1cfedd3d 100644
--- a/crypto/openssh/sandbox-pledge.c
+++ b/crypto/openssh/sandbox-pledge.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: sandbox-pledge.c,v 1.1 2015/10/09 01:37:08 deraadt Exp $ */
+/* $OpenBSD: sandbox-pledge.c,v 1.2 2020/10/18 11:32:01 djm Exp $ */
/*
* Copyright (c) 2015 Theo de Raadt <deraadt@openbsd.org>
*
@@ -46,7 +46,7 @@ ssh_sandbox_init(struct monitor *m)
{
struct ssh_sandbox *box;
- debug3("%s: preparing pledge sandbox", __func__);
+ debug3_f("preparing pledge sandbox");
box = xcalloc(1, sizeof(*box));
box->child_pid = 0;
@@ -57,14 +57,14 @@ void
ssh_sandbox_child(struct ssh_sandbox *box)
{
if (pledge("stdio", NULL) == -1)
- fatal("%s: pledge()", __func__);
+ fatal_f("pledge()");
}
void
ssh_sandbox_parent_finish(struct ssh_sandbox *box)
{
free(box);
- debug3("%s: finished", __func__);
+ debug3_f("finished");
}
void
diff --git a/crypto/openssh/sandbox-rlimit.c b/crypto/openssh/sandbox-rlimit.c
index 0bff3dfba496..26c61d264817 100644
--- a/crypto/openssh/sandbox-rlimit.c
+++ b/crypto/openssh/sandbox-rlimit.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: sandbox-rlimit.c,v 1.4 2016/09/12 01:22:38 deraadt Exp $ */
+/* $OpenBSD: sandbox-rlimit.c,v 1.5 2020/10/18 11:32:01 djm Exp $ */
/*
* Copyright (c) 2011 Damien Miller <djm@mindrot.org>
*
@@ -49,7 +49,7 @@ ssh_sandbox_init(struct monitor *monitor)
* Strictly, we don't need to maintain any state here but we need
* to return non-NULL to satisfy the API.
*/
- debug3("%s: preparing rlimit sandbox", __func__);
+ debug3_f("preparing rlimit sandbox");
box = xcalloc(1, sizeof(*box));
box->child_pid = 0;
@@ -65,18 +65,18 @@ ssh_sandbox_child(struct ssh_sandbox *box)
#ifndef SANDBOX_SKIP_RLIMIT_FSIZE
if (setrlimit(RLIMIT_FSIZE, &rl_zero) == -1)
- fatal("%s: setrlimit(RLIMIT_FSIZE, { 0, 0 }): %s",
- __func__, strerror(errno));
+ fatal_f("setrlimit(RLIMIT_FSIZE, { 0, 0 }): %s",
+ strerror(errno));
#endif
#ifndef SANDBOX_SKIP_RLIMIT_NOFILE
if (setrlimit(RLIMIT_NOFILE, &rl_zero) == -1)
- fatal("%s: setrlimit(RLIMIT_NOFILE, { 0, 0 }): %s",
- __func__, strerror(errno));
+ fatal_f("setrlimit(RLIMIT_NOFILE, { 0, 0 }): %s",
+ strerror(errno));
#endif
#ifdef HAVE_RLIMIT_NPROC
if (setrlimit(RLIMIT_NPROC, &rl_zero) == -1)
- fatal("%s: setrlimit(RLIMIT_NPROC, { 0, 0 }): %s",
- __func__, strerror(errno));
+ fatal_f("setrlimit(RLIMIT_NPROC, { 0, 0 }): %s",
+ strerror(errno));
#endif
}
@@ -84,7 +84,7 @@ void
ssh_sandbox_parent_finish(struct ssh_sandbox *box)
{
free(box);
- debug3("%s: finished", __func__);
+ debug3_f("finished");
}
void
diff --git a/crypto/openssh/sandbox-seccomp-filter.c b/crypto/openssh/sandbox-seccomp-filter.c
index 5edbc6946b07..798b24bd878f 100644
--- a/crypto/openssh/sandbox-seccomp-filter.c
+++ b/crypto/openssh/sandbox-seccomp-filter.c
@@ -42,6 +42,8 @@
#include <sys/types.h>
#include <sys/resource.h>
#include <sys/prctl.h>
+#include <sys/mman.h>
+#include <sys/syscall.h>
#include <linux/net.h>
#include <linux/audit.h>
@@ -95,12 +97,12 @@
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), 0, 6), \
- /* load and test first syscall argument, low word */ \
+ /* load and test syscall argument, low word */ \
BPF_STMT(BPF_LD+BPF_W+BPF_ABS, \
offsetof(struct seccomp_data, args[(_arg_nr)]) + ARG_LO_OFFSET), \
BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, \
((_arg_val) & 0xFFFFFFFF), 0, 3), \
- /* load and test first syscall argument, high word */ \
+ /* load and test syscall argument, high word */ \
BPF_STMT(BPF_LD+BPF_W+BPF_ABS, \
offsetof(struct seccomp_data, args[(_arg_nr)]) + ARG_HI_OFFSET), \
BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, \
@@ -109,6 +111,24 @@
/* reload syscall number; all rules expect it in accumulator */ \
BPF_STMT(BPF_LD+BPF_W+BPF_ABS, \
offsetof(struct seccomp_data, nr))
+/* Allow if syscall argument contains only values in mask */
+#define SC_ALLOW_ARG_MASK(_nr, _arg_nr, _arg_mask) \
+ BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, (_nr), 0, 8), \
+ /* load, mask and test syscall argument, low word */ \
+ BPF_STMT(BPF_LD+BPF_W+BPF_ABS, \
+ offsetof(struct seccomp_data, args[(_arg_nr)]) + ARG_LO_OFFSET), \
+ BPF_STMT(BPF_ALU+BPF_AND+BPF_K, ~((_arg_mask) & 0xFFFFFFFF)), \
+ BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0, 0, 4), \
+ /* load, mask and test syscall argument, high word */ \
+ BPF_STMT(BPF_LD+BPF_W+BPF_ABS, \
+ offsetof(struct seccomp_data, args[(_arg_nr)]) + ARG_HI_OFFSET), \
+ BPF_STMT(BPF_ALU+BPF_AND+BPF_K, \
+ ~(((uint32_t)((uint64_t)(_arg_mask) >> 32)) & 0xFFFFFFFF)), \
+ BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0, 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[] = {
@@ -134,6 +154,9 @@ static const struct sock_filter preauth_insns[] = {
#ifdef __NR_fstat64
SC_DENY(__NR_fstat64, EACCES),
#endif
+#ifdef __NR_fstatat64
+ SC_DENY(__NR_fstatat64, EACCES),
+#endif
#ifdef __NR_open
SC_DENY(__NR_open, EACCES),
#endif
@@ -149,6 +172,21 @@ static const struct sock_filter preauth_insns[] = {
#ifdef __NR_stat64
SC_DENY(__NR_stat64, EACCES),
#endif
+#ifdef __NR_shmget
+ SC_DENY(__NR_shmget, EACCES),
+#endif
+#ifdef __NR_shmat
+ SC_DENY(__NR_shmat, EACCES),
+#endif
+#ifdef __NR_shmdt
+ SC_DENY(__NR_shmdt, EACCES),
+#endif
+#ifdef __NR_ipc
+ SC_DENY(__NR_ipc, EACCES),
+#endif
+#ifdef __NR_statx
+ SC_DENY(__NR_statx, EACCES),
+#endif
/* Syscalls to permit */
#ifdef __NR_brk
@@ -157,6 +195,9 @@ static const struct sock_filter preauth_insns[] = {
#ifdef __NR_clock_gettime
SC_ALLOW(__NR_clock_gettime),
#endif
+#ifdef __NR_clock_gettime64
+ SC_ALLOW(__NR_clock_gettime64),
+#endif
#ifdef __NR_close
SC_ALLOW(__NR_close),
#endif
@@ -169,6 +210,9 @@ static const struct sock_filter preauth_insns[] = {
#ifdef __NR_futex
SC_ALLOW(__NR_futex),
#endif
+#ifdef __NR_futex_time64
+ SC_ALLOW(__NR_futex_time64),
+#endif
#ifdef __NR_geteuid
SC_ALLOW(__NR_geteuid),
#endif
@@ -197,10 +241,13 @@ static const struct sock_filter preauth_insns[] = {
SC_ALLOW(__NR_madvise),
#endif
#ifdef __NR_mmap
- SC_ALLOW(__NR_mmap),
+ SC_ALLOW_ARG_MASK(__NR_mmap, 2, PROT_READ|PROT_WRITE|PROT_NONE),
#endif
#ifdef __NR_mmap2
- SC_ALLOW(__NR_mmap2),
+ SC_ALLOW_ARG_MASK(__NR_mmap2, 2, PROT_READ|PROT_WRITE|PROT_NONE),
+#endif
+#ifdef __NR_mprotect
+ SC_ALLOW_ARG_MASK(__NR_mprotect, 2, PROT_READ|PROT_WRITE|PROT_NONE),
#endif
#ifdef __NR_mremap
SC_ALLOW(__NR_mremap),
@@ -211,6 +258,15 @@ static const struct sock_filter preauth_insns[] = {
#ifdef __NR_nanosleep
SC_ALLOW(__NR_nanosleep),
#endif
+#ifdef __NR_clock_nanosleep
+ SC_ALLOW(__NR_clock_nanosleep),
+#endif
+#ifdef __NR_clock_nanosleep_time64
+ SC_ALLOW(__NR_clock_nanosleep_time64),
+#endif
+#ifdef __NR_clock_gettime64
+ SC_ALLOW(__NR_clock_gettime64),
+#endif
#ifdef __NR__newselect
SC_ALLOW(__NR__newselect),
#endif
@@ -220,6 +276,9 @@ static const struct sock_filter preauth_insns[] = {
#ifdef __NR_pselect6
SC_ALLOW(__NR_pselect6),
#endif
+#ifdef __NR_pselect6_time64
+ SC_ALLOW(__NR_pselect6_time64),
+#endif
#ifdef __NR_read
SC_ALLOW(__NR_read),
#endif
@@ -250,6 +309,9 @@ static const struct sock_filter preauth_insns[] = {
SC_ALLOW_ARG(__NR_ioctl, 1, Z90STAT_STATUS_MASK),
SC_ALLOW_ARG(__NR_ioctl, 1, ICARSAMODEXPO),
SC_ALLOW_ARG(__NR_ioctl, 1, ICARSACRT),
+ SC_ALLOW_ARG(__NR_ioctl, 1, ZSECSENDCPRB),
+ /* Allow ioctls for EP11 crypto card on s390 */
+ SC_ALLOW_ARG(__NR_ioctl, 1, ZSENDEP11CPRB),
#endif
#if defined(__x86_64__) && defined(__ILP32__) && defined(__X32_SYSCALL_BIT)
/*
@@ -322,7 +384,7 @@ ssh_sandbox_child_debugging(void)
fatal("%s: sigaction(SIGSYS): %s", __func__, strerror(errno));
if (sigprocmask(SIG_UNBLOCK, &mask, NULL) == -1)
fatal("%s: sigprocmask(SIGSYS): %s",
- __func__, strerror(errno));
+ __func__, strerror(errno));
}
#endif /* SANDBOX_SECCOMP_FILTER_DEBUG */
@@ -351,13 +413,13 @@ ssh_sandbox_child(struct ssh_sandbox *box)
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));
+ __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));
+ __func__, strerror(errno));
else if (nnp_failed)
fatal("%s: SECCOMP_MODE_FILTER activated but "
"PR_SET_NO_NEW_PRIVS failed", __func__);
diff --git a/crypto/openssh/sandbox-systrace.c b/crypto/openssh/sandbox-systrace.c
index add4c46d071e..e61d581aedba 100644
--- a/crypto/openssh/sandbox-systrace.c
+++ b/crypto/openssh/sandbox-systrace.c
@@ -36,7 +36,6 @@
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
-#include <limits.h>
#include "atomicio.h"
#include "log.h"
@@ -106,7 +105,7 @@ ssh_sandbox_init(struct monitor *monitor)
box = xcalloc(1, sizeof(*box));
box->systrace_fd = -1;
box->child_pid = 0;
- box->osigchld = signal(SIGCHLD, SIG_IGN);
+ box->osigchld = ssh_signal(SIGCHLD, SIG_IGN);
return box;
}
@@ -115,7 +114,7 @@ void
ssh_sandbox_child(struct ssh_sandbox *box)
{
debug3("%s: ready", __func__);
- signal(SIGCHLD, box->osigchld);
+ ssh_signal(SIGCHLD, box->osigchld);
if (kill(getpid(), SIGSTOP) != 0)
fatal("%s: kill(%d, SIGSTOP)", __func__, getpid());
debug3("%s: started", __func__);
@@ -134,7 +133,7 @@ ssh_sandbox_parent(struct ssh_sandbox *box, pid_t child_pid,
do {
pid = waitpid(child_pid, &status, WUNTRACED);
} while (pid == -1 && errno == EINTR);
- signal(SIGCHLD, box->osigchld);
+ ssh_signal(SIGCHLD, box->osigchld);
if (!WIFSTOPPED(status)) {
if (WIFSIGNALED(status))
fatal("%s: child terminated with signal %d",
diff --git a/crypto/openssh/scp.1 b/crypto/openssh/scp.1
index 397e7709195a..68aac04b205c 100644
--- a/crypto/openssh/scp.1
+++ b/crypto/openssh/scp.1
@@ -8,20 +8,22 @@
.\"
.\" Created: Sun May 7 00:14:37 1995 ylo
.\"
-.\" $OpenBSD: scp.1,v 1.81 2018/09/20 06:58:48 jmc Exp $
+.\" $OpenBSD: scp.1,v 1.100 2021/08/11 14:07:54 naddy Exp $
.\"
-.Dd $Mdocdate: September 20 2018 $
+.Dd $Mdocdate: August 11 2021 $
.Dt SCP 1
.Os
.Sh NAME
.Nm scp
-.Nd secure copy (remote file copy program)
+.Nd OpenSSH secure file copy
.Sh SYNOPSIS
.Nm scp
-.Op Fl 346BCpqrTv
+.Op Fl 346ABCOpqRrsTv
.Op Fl c Ar cipher
+.Op Fl D Ar sftp_server_path
.Op Fl F Ar ssh_config
.Op Fl i Ar identity_file
+.Op Fl J Ar destination
.Op Fl l Ar limit
.Op Fl o Ar ssh_option
.Op Fl P Ar port
@@ -30,11 +32,15 @@
.Sh DESCRIPTION
.Nm
copies files between hosts on a network.
+.Pp
It uses
.Xr ssh 1
for data transfer, and uses the same authentication and provides the
-same security as
-.Xr ssh 1 .
+same security as a login session.
+The scp protocol requires execution of the remote user's shell to perform
+.Xr glob 3
+pattern matching.
+.Pp
.Nm
will ask for passwords or passphrases if they are needed for
authentication.
@@ -61,10 +67,10 @@ as host specifiers.
.Pp
When copying between two remote hosts, if the URI format is used, a
.Ar port
-may only be specified on the
+cannot be specified on the
.Ar target
if the
-.Fl 3
+.Fl R
option is used.
.Pp
The options are as follows:
@@ -73,7 +79,11 @@ The options are as follows:
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.
+Note that, when using the legacy SCP protocol (the default), this option
+selects batch mode for the second host as
+.Nm
+cannot ask for passwords or passphrases for both hosts.
+This mode is the default.
.It Fl 4
Forces
.Nm
@@ -82,6 +92,11 @@ to use IPv4 addresses only.
Forces
.Nm
to use IPv6 addresses only.
+.It Fl A
+Allows forwarding of
+.Xr ssh-agent 1
+to the remote system.
+The default is not to forward an authentication agent.
.It Fl B
Selects batch mode (prevents asking for passwords or passphrases).
.It Fl C
@@ -95,6 +110,13 @@ to enable compression.
Selects the cipher to use for encrypting the data transfer.
This option is directly passed to
.Xr ssh 1 .
+.It Fl D Ar sftp_server_path
+When using the SFTP protocol support via
+.Fl M ,
+connect directly to a local SFTP server program rather than a
+remote one via
+.Xr ssh 1 .
+This option may be useful in debugging the client and server.
.It Fl F Ar ssh_config
Specifies an alternative
per-user configuration file for
@@ -106,8 +128,27 @@ Selects the file from which the identity (private key) for public key
authentication is read.
This option is directly passed to
.Xr ssh 1 .
+.It Fl J Ar destination
+Connect to the target host by first making an
+.Nm
+connection to the jump host described by
+.Ar destination
+and then establishing a TCP forwarding to the ultimate destination from
+there.
+Multiple jump hops may be specified separated by comma characters.
+This is a shortcut to specify a
+.Cm ProxyJump
+configuration directive.
+This option is directly passed to
+.Xr ssh 1 .
.It Fl l Ar limit
Limits the used bandwidth, specified in Kbit/s.
+.It Fl O
+Use the legacy SCP protocol for file transfers instead of the SFTP protocol.
+Forcing the use of the SCP protocol may be necessary for servers that do
+not implement SFTP or for backwards-compatibility for particular filename
+wildcard patterns.
+This mode is the default.
.It Fl o Ar ssh_option
Can be used to pass options to
.Nm ssh
@@ -132,7 +173,6 @@ For full details of the options listed below, and their possible values, see
.It CanonicalizePermittedCNAMEs
.It CASignatureAlgorithms
.It CertificateFile
-.It ChallengeResponseAuthentication
.It CheckHostIP
.It Ciphers
.It Compression
@@ -146,11 +186,11 @@ For full details of the options listed below, and their possible values, see
.It GSSAPIDelegateCredentials
.It HashKnownHosts
.It Host
+.It HostbasedAcceptedAlgorithms
.It HostbasedAuthentication
-.It HostbasedKeyTypes
.It HostKeyAlgorithms
.It HostKeyAlias
-.It HostName
+.It Hostname
.It IdentitiesOnly
.It IdentityAgent
.It IdentityFile
@@ -158,6 +198,7 @@ For full details of the options listed below, and their possible values, see
.It KbdInteractiveAuthentication
.It KbdInteractiveDevices
.It KexAlgorithms
+.It KnownHostsCommand
.It LogLevel
.It MACs
.It NoHostAuthenticationForLocalhost
@@ -168,7 +209,7 @@ For full details of the options listed below, and their possible values, see
.It PreferredAuthentications
.It ProxyCommand
.It ProxyJump
-.It PubkeyAcceptedKeyTypes
+.It PubkeyAcceptedAlgorithms
.It PubkeyAuthentication
.It RekeyLimit
.It SendEnv
@@ -196,6 +237,15 @@ original file.
Quiet mode: disables the progress meter as well as warning and diagnostic
messages from
.Xr ssh 1 .
+.It Fl R
+Copies between two remote hosts are performed by connecting to the origin
+host and executing
+.Nm
+there.
+This requires that
+.Nm
+running on the origin host can authenticate to the destination host without
+requiring a password.
.It Fl r
Recursively copy entire directories.
Note that
@@ -208,6 +258,16 @@ to use for the encrypted connection.
The program must understand
.Xr ssh 1
options.
+.It Fl s
+Use the SFTP protocol for file transfers instead of the legacy SCP protocol.
+Using SFTP avoids invoking a shell on the remote side and provides
+more predictable filename handling, as the SCP protocol
+relied on the remote shell for expanding
+.Xr glob 3
+wildcards.
+.Pp
+A near-future release of OpenSSH will make the SFTP protocol the default.
+This option will be deleted before the end of 2022.
.It Fl T
Disable strict filename checking.
By default when copying files from a remote host to a local directory
@@ -237,6 +297,7 @@ debugging connection, authentication, and configuration problems.
.Xr ssh-agent 1 ,
.Xr ssh-keygen 1 ,
.Xr ssh_config 5 ,
+.Xr sftp-server 8 ,
.Xr sshd 8
.Sh HISTORY
.Nm
diff --git a/crypto/openssh/scp.c b/crypto/openssh/scp.c
index cbf67b69de5e..e039350c6093 100644
--- a/crypto/openssh/scp.c
+++ b/crypto/openssh/scp.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: scp.c,v 1.204 2019/02/10 11:15:52 djm Exp $ */
+/* $OpenBSD: scp.c,v 1.232 2021/08/11 14:07:54 naddy Exp $ */
/*
* scp - secure remote copy. This is basically patched BSD rcp which
* uses ssh to do the data transfer (instead of using rcmd).
@@ -94,14 +94,24 @@
#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
+#ifdef HAVE_FNMATCH_H
#include <fnmatch.h>
+#endif
+#ifdef USE_SYSTEM_GLOB
+# include <glob.h>
+#else
+# include "openbsd-compat/glob.h"
+#endif
+#ifdef HAVE_LIBGEN_H
+#include <libgen.h>
+#endif
#include <limits.h>
#include <locale.h>
#include <pwd.h>
#include <signal.h>
#include <stdarg.h>
#ifdef HAVE_STDINT_H
-#include <stdint.h>
+# include <stdint.h>
#endif
#include <stdio.h>
#include <stdlib.h>
@@ -121,12 +131,15 @@
#include "progressmeter.h"
#include "utf8.h"
+#include "sftp-common.h"
+#include "sftp-client.h"
+
extern char *__progname;
#define COPY_BUFLEN 16384
-int do_cmd(char *host, char *remuser, int port, char *cmd, int *fdin, int *fdout);
-int do_cmd2(char *host, char *remuser, int port, char *cmd, int fdin, int fdout);
+int do_cmd(char *, char *, char *, int, int, char *, int *, int *, pid_t *);
+int do_cmd2(char *, char *, int, char *, int, int);
/* Struct for addargs */
arglist args;
@@ -141,6 +154,7 @@ char *curfile;
/* This is set to non-zero to enable verbose mode. */
int verbose_mode = 0;
+LogLevel log_level = SYSLOG_LEVEL_INFO;
/* This is set to zero if the progressmeter is not desired. */
int showprogress = 1;
@@ -149,7 +163,7 @@ int showprogress = 1;
* This is set to non-zero if remote-remote copy should be piped
* through this process.
*/
-int throughlocal = 0;
+int throughlocal = 1;
/* Non-standard port to use for the ssh connection or -1. */
int sshport = -1;
@@ -159,6 +173,13 @@ char *ssh_program = _PATH_SSH_PROGRAM;
/* This is used to store the pid of ssh_program */
pid_t do_cmd_pid = -1;
+pid_t do_cmd_pid2 = -1;
+
+/* Needed for sftp */
+volatile sig_atomic_t interrupted = 0;
+
+int remote_glob(struct sftp_conn *, const char *, int,
+ int (*)(const char *, int), glob_t *); /* proto for sftp-glob.c */
static void
killchild(int signo)
@@ -167,6 +188,10 @@ killchild(int signo)
kill(do_cmd_pid, signo ? signo : SIGTERM);
waitpid(do_cmd_pid, NULL, 0);
}
+ if (do_cmd_pid2 > 1) {
+ kill(do_cmd_pid2, signo ? signo : SIGTERM);
+ waitpid(do_cmd_pid2, NULL, 0);
+ }
if (signo)
_exit(1);
@@ -174,19 +199,26 @@ killchild(int signo)
}
static void
-suspchild(int signo)
+suspone(int pid, int signo)
{
int status;
- if (do_cmd_pid > 1) {
- kill(do_cmd_pid, signo);
- while (waitpid(do_cmd_pid, &status, WUNTRACED) == -1 &&
+ if (pid > 1) {
+ kill(pid, signo);
+ while (waitpid(pid, &status, WUNTRACED) == -1 &&
errno == EINTR)
;
- kill(getpid(), SIGSTOP);
}
}
+static void
+suspchild(int signo)
+{
+ suspone(do_cmd_pid, signo);
+ suspone(do_cmd_pid2, signo);
+ kill(getpid(), SIGSTOP);
+}
+
static int
do_local_cmd(arglist *a)
{
@@ -213,9 +245,9 @@ do_local_cmd(arglist *a)
}
do_cmd_pid = pid;
- signal(SIGTERM, killchild);
- signal(SIGINT, killchild);
- signal(SIGHUP, killchild);
+ ssh_signal(SIGTERM, killchild);
+ ssh_signal(SIGINT, killchild);
+ ssh_signal(SIGHUP, killchild);
while (waitpid(pid, &status, 0) == -1)
if (errno != EINTR)
@@ -236,14 +268,15 @@ do_local_cmd(arglist *a)
*/
int
-do_cmd(char *host, char *remuser, int port, char *cmd, int *fdin, int *fdout)
+do_cmd(char *program, char *host, char *remuser, int port, int subsystem,
+ char *cmd, int *fdin, int *fdout, pid_t *pid)
{
int pin[2], pout[2], reserved[2];
if (verbose_mode)
fmprintf(stderr,
"Executing: program %s host %s, user %s, command %s\n",
- ssh_program, host,
+ program, host,
remuser ? remuser : "(unspecified)", cmd);
if (port == -1)
@@ -253,26 +286,26 @@ do_cmd(char *host, char *remuser, int port, char *cmd, int *fdin, int *fdout)
* Reserve two descriptors so that the real pipes won't get
* descriptors 0 and 1 because that will screw up dup2 below.
*/
- if (pipe(reserved) < 0)
+ if (pipe(reserved) == -1)
fatal("pipe: %s", strerror(errno));
/* Create a socket pair for communicating with ssh. */
- if (pipe(pin) < 0)
+ if (pipe(pin) == -1)
fatal("pipe: %s", strerror(errno));
- if (pipe(pout) < 0)
+ if (pipe(pout) == -1)
fatal("pipe: %s", strerror(errno));
/* Free the reserved descriptors. */
close(reserved[0]);
close(reserved[1]);
- signal(SIGTSTP, suspchild);
- signal(SIGTTIN, suspchild);
- signal(SIGTTOU, suspchild);
+ ssh_signal(SIGTSTP, suspchild);
+ ssh_signal(SIGTTIN, suspchild);
+ ssh_signal(SIGTTOU, suspchild);
/* Fork a child to execute the command on the remote host using ssh. */
- do_cmd_pid = fork();
- if (do_cmd_pid == 0) {
+ *pid = fork();
+ if (*pid == 0) {
/* Child. */
close(pin[1]);
close(pout[0]);
@@ -281,7 +314,7 @@ do_cmd(char *host, char *remuser, int port, char *cmd, int *fdin, int *fdout)
close(pin[0]);
close(pout[1]);
- replacearg(&args, 0, "%s", ssh_program);
+ replacearg(&args, 0, "%s", program);
if (port != -1) {
addargs(&args, "-p");
addargs(&args, "%d", port);
@@ -290,14 +323,16 @@ do_cmd(char *host, char *remuser, int port, char *cmd, int *fdin, int *fdout)
addargs(&args, "-l");
addargs(&args, "%s", remuser);
}
+ if (subsystem)
+ addargs(&args, "-s");
addargs(&args, "--");
addargs(&args, "%s", host);
addargs(&args, "%s", cmd);
- execvp(ssh_program, args.list);
- perror(ssh_program);
+ execvp(program, args.list);
+ perror(program);
exit(1);
- } else if (do_cmd_pid == -1) {
+ } else if (*pid == -1) {
fatal("fork: %s", strerror(errno));
}
/* Parent. Close the other side, and return the local side. */
@@ -305,9 +340,9 @@ do_cmd(char *host, char *remuser, int port, char *cmd, int *fdin, int *fdout)
*fdout = pin[1];
close(pout[1]);
*fdin = pout[0];
- signal(SIGTERM, killchild);
- signal(SIGINT, killchild);
- signal(SIGHUP, killchild);
+ ssh_signal(SIGTERM, killchild);
+ ssh_signal(SIGINT, killchild);
+ ssh_signal(SIGHUP, killchild);
return 0;
}
@@ -317,10 +352,11 @@ do_cmd(char *host, char *remuser, int port, char *cmd, int *fdin, int *fdout)
* This way the input and output of two commands can be connected.
*/
int
-do_cmd2(char *host, char *remuser, int port, char *cmd, int fdin, int fdout)
+do_cmd2(char *host, char *remuser, int port, char *cmd,
+ int fdin, int fdout)
{
- pid_t pid;
int status;
+ pid_t pid;
if (verbose_mode)
fmprintf(stderr,
@@ -346,6 +382,7 @@ do_cmd2(char *host, char *remuser, int port, char *cmd, int fdin, int fdout)
addargs(&args, "-l");
addargs(&args, "%s", remuser);
}
+ addargs(&args, "-oBatchMode=yes");
addargs(&args, "--");
addargs(&args, "%s", host);
addargs(&args, "%s", cmd);
@@ -370,40 +407,59 @@ typedef struct {
BUF *allocbuf(BUF *, int, int);
void lostconn(int);
int okname(char *);
-void run_err(const char *,...);
+void run_err(const char *,...)
+ __attribute__((__format__ (printf, 1, 2)))
+ __attribute__((__nonnull__ (1)));
+int note_err(const char *,...)
+ __attribute__((__format__ (printf, 1, 2)));
void verifydir(char *);
struct passwd *pwd;
uid_t userid;
-int errs, remin, remout;
+int errs, remin, remout, remin2, remout2;
int Tflag, pflag, iamremote, iamrecursive, targetshouldbedirectory;
#define CMDNEEDS 64
char cmd[CMDNEEDS]; /* must hold "rcp -r -p -d\0" */
+enum scp_mode_e {
+ MODE_SCP,
+ MODE_SFTP
+};
+
int response(void);
void rsource(char *, struct stat *);
void sink(int, char *[], const char *);
void source(int, char *[]);
-void tolocal(int, char *[]);
-void toremote(int, char *[]);
+void tolocal(int, char *[], enum scp_mode_e, char *sftp_direct);
+void toremote(int, char *[], enum scp_mode_e, char *sftp_direct);
void usage(void);
+void source_sftp(int, char *, char *, struct sftp_conn *);
+void sink_sftp(int, char *, const char *, struct sftp_conn *);
+void throughlocal_sftp(struct sftp_conn *, struct sftp_conn *,
+ char *, char *);
+
int
main(int argc, char **argv)
{
int ch, fflag, tflag, status, n;
- char **newargv;
+ char **newargv, *argv0;
const char *errstr;
extern char *optarg;
extern int optind;
+ enum scp_mode_e mode = MODE_SCP;
+ char *sftp_direct = NULL;
/* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */
sanitise_stdfd();
+ seed_rng();
+
msetlocale();
/* Copy argv, because we modify it */
+ argv0 = argv[0];
newargv = xcalloc(MAXIMUM(argc + 1, 1), sizeof(*newargv));
for (n = 0; n < argc; n++)
newargv[n] = xstrdup(argv[n]);
@@ -411,12 +467,13 @@ main(int argc, char **argv)
__progname = ssh_get_progname(argv[0]);
+ log_init(argv0, log_level, SYSLOG_FACILITY_USER, 1);
+
memset(&args, '\0', sizeof(args));
memset(&remote_remote_args, '\0', sizeof(remote_remote_args));
args.list = remote_remote_args.list = NULL;
addargs(&args, "%s", ssh_program);
addargs(&args, "-x");
- addargs(&args, "-oForwardAgent=no");
addargs(&args, "-oPermitLocalCommand=no");
addargs(&args, "-oClearAllForwardings=yes");
addargs(&args, "-oRemoteCommand=none");
@@ -424,7 +481,7 @@ main(int argc, char **argv)
fflag = Tflag = tflag = 0;
while ((ch = getopt(argc, argv,
- "dfl:prtTvBCc:i:P:q12346S:o:F:")) != -1) {
+ "12346ABCTdfOpqRrstvD:F:J:M:P:S:c:i:l:o:")) != -1) {
switch (ch) {
/* User-visible flags. */
case '1':
@@ -433,24 +490,38 @@ main(int argc, char **argv)
case '2':
/* Ignored */
break;
+ case 'A':
case '4':
case '6':
case 'C':
addargs(&args, "-%c", ch);
addargs(&remote_remote_args, "-%c", ch);
break;
+ case 'D':
+ sftp_direct = optarg;
+ break;
case '3':
throughlocal = 1;
break;
+ case 'R':
+ throughlocal = 0;
+ break;
case 'o':
case 'c':
case 'i':
case 'F':
+ case 'J':
addargs(&remote_remote_args, "-%c", ch);
addargs(&remote_remote_args, "%s", optarg);
addargs(&args, "-%c", ch);
addargs(&args, "%s", optarg);
break;
+ case 'O':
+ mode = MODE_SCP;
+ break;
+ case 's':
+ mode = MODE_SFTP;
+ break;
case 'P':
sshport = a2port(optarg);
if (sshport <= 0)
@@ -480,6 +551,10 @@ main(int argc, char **argv)
case 'v':
addargs(&args, "-v");
addargs(&remote_remote_args, "-v");
+ if (verbose_mode == 0)
+ log_level = SYSLOG_LEVEL_DEBUG1;
+ else if (log_level < SYSLOG_LEVEL_DEBUG3)
+ log_level++;
verbose_mode = 1;
break;
case 'q':
@@ -513,6 +588,14 @@ main(int argc, char **argv)
argc -= optind;
argv += optind;
+ log_init(argv0, log_level, SYSLOG_FACILITY_USER, 1);
+
+ /* Do this last because we want the user to be able to override it */
+ addargs(&args, "-oForwardAgent=no");
+
+ if (iamremote)
+ mode = MODE_SCP;
+
if ((pwd = getpwuid(userid = getuid())) == NULL)
fatal("unknown user %u", (u_int) userid);
@@ -556,14 +639,14 @@ main(int argc, char **argv)
iamrecursive ? " -r" : "", pflag ? " -p" : "",
targetshouldbedirectory ? " -d" : "");
- (void) signal(SIGPIPE, lostconn);
+ (void) ssh_signal(SIGPIPE, lostconn);
if (colon(argv[argc - 1])) /* Dest is remote host. */
- toremote(argc, argv);
+ toremote(argc, argv, mode, sftp_direct);
else {
if (targetshouldbedirectory)
verifydir(argv[argc - 1]);
- tolocal(argc, argv); /* Dest is local host. */
+ tolocal(argc, argv, mode, sftp_direct); /* Dest is local host. */
}
/*
* Finally check the exit status of the ssh process, if one was forked
@@ -591,6 +674,7 @@ scpio(void *_cnt, size_t s)
off_t *cnt = (off_t *)_cnt;
*cnt += s;
+ refresh_progress_meter(0);
if (limit_kbps > 0)
bandwidth_limit(&bwlimit, s);
return 0;
@@ -616,7 +700,7 @@ do_times(int fd, int verb, const struct stat *sb)
static int
parse_scp_uri(const char *uri, char **userp, char **hostp, int *portp,
- char **pathp)
+ char **pathp)
{
int r;
@@ -834,7 +918,7 @@ brace_expand(const char *pattern, char ***patternsp, size_t *npatternsp)
goto fail;
}
if (invalid)
- fatal("%s: invalid brace pattern \"%s\"", __func__, cp);
+ fatal_f("invalid brace pattern \"%s\"", cp);
if (expanded) {
/*
* Current entry expanded to new entries on the
@@ -873,14 +957,34 @@ brace_expand(const char *pattern, char ***patternsp, size_t *npatternsp)
return ret;
}
+static struct sftp_conn *
+do_sftp_connect(char *host, char *user, int port, char *sftp_direct,
+ int *reminp, int *remoutp, int *pidp)
+{
+ if (sftp_direct == NULL) {
+ if (do_cmd(ssh_program, host, user, port, 1, "sftp",
+ reminp, remoutp, pidp) < 0)
+ return NULL;
+
+ } else {
+ args.list = NULL;
+ addargs(&args, "sftp-server");
+ if (do_cmd(sftp_direct, host, NULL, -1, 0, "sftp",
+ reminp, remoutp, pidp) < 0)
+ return NULL;
+ }
+ return do_init(*reminp, *remoutp, 32768, 64, limit_kbps);
+}
+
void
-toremote(int argc, char **argv)
+toremote(int argc, char **argv, enum scp_mode_e mode, char *sftp_direct)
{
char *suser = NULL, *host = NULL, *src = NULL;
char *bp, *tuser, *thost, *targ;
int sport = -1, tport = -1;
+ struct sftp_conn *conn = NULL, *conn2 = NULL;
arglist alist;
- int i, r;
+ int i, r, status;
u_int j;
memset(&alist, '\0', sizeof(alist));
@@ -901,10 +1005,6 @@ toremote(int argc, char **argv)
goto out;
}
}
- if (tuser != NULL && !okname(tuser)) {
- ++errs;
- goto out;
- }
/* Parse source files */
for (i = 0; i < argc - 1; i++) {
@@ -925,24 +1025,77 @@ toremote(int argc, char **argv)
continue;
}
if (host && throughlocal) { /* extended remote to remote */
- xasprintf(&bp, "%s -f %s%s", cmd,
- *src == '-' ? "-- " : "", src);
- if (do_cmd(host, suser, sport, bp, &remin, &remout) < 0)
- exit(1);
- free(bp);
- xasprintf(&bp, "%s -t %s%s", cmd,
- *targ == '-' ? "-- " : "", targ);
- if (do_cmd2(thost, tuser, tport, bp, remin, remout) < 0)
- exit(1);
- free(bp);
- (void) close(remin);
- (void) close(remout);
- remin = remout = -1;
+ if (mode == MODE_SFTP) {
+ if (remin == -1) {
+ /* Connect to dest now */
+ conn = do_sftp_connect(thost, tuser,
+ tport, sftp_direct,
+ &remin, &remout, &do_cmd_pid);
+ if (conn == NULL) {
+ fatal("Unable to open "
+ "destination connection");
+ }
+ debug3_f("origin in %d out %d pid %ld",
+ remin, remout, (long)do_cmd_pid);
+ }
+ /*
+ * XXX remember suser/host/sport and only
+ * reconnect if they change between arguments.
+ * would save reconnections for cases like
+ * scp -3 hosta:/foo hosta:/bar hostb:
+ */
+ /* Connect to origin now */
+ conn2 = do_sftp_connect(host, suser,
+ sport, sftp_direct,
+ &remin2, &remout2, &do_cmd_pid2);
+ if (conn2 == NULL) {
+ fatal("Unable to open "
+ "source connection");
+ }
+ debug3_f("destination in %d out %d pid %ld",
+ remin2, remout2, (long)do_cmd_pid2);
+ throughlocal_sftp(conn2, conn, src, targ);
+ (void) close(remin2);
+ (void) close(remout2);
+ remin2 = remout2 = -1;
+ if (waitpid(do_cmd_pid2, &status, 0) == -1)
+ ++errs;
+ else if (!WIFEXITED(status) ||
+ WEXITSTATUS(status) != 0)
+ ++errs;
+ do_cmd_pid2 = -1;
+ continue;
+ } else {
+ xasprintf(&bp, "%s -f %s%s", cmd,
+ *src == '-' ? "-- " : "", src);
+ if (do_cmd(ssh_program, host, suser, sport, 0,
+ bp, &remin, &remout, &do_cmd_pid) < 0)
+ exit(1);
+ free(bp);
+ xasprintf(&bp, "%s -t %s%s", cmd,
+ *targ == '-' ? "-- " : "", targ);
+ if (do_cmd2(thost, tuser, tport, bp,
+ remin, remout) < 0)
+ exit(1);
+ free(bp);
+ (void) close(remin);
+ (void) close(remout);
+ remin = remout = -1;
+ }
} else if (host) { /* standard remote to remote */
+ /*
+ * Second remote user is passed to first remote side
+ * via scp command-line. Ensure it contains no obvious
+ * shell characters.
+ */
+ if (tuser != NULL && !okname(tuser)) {
+ ++errs;
+ continue;
+ }
if (tport != -1 && tport != SSH_DEFAULT_PORT) {
/* This would require the remote support URIs */
fatal("target port not supported with two "
- "remote hosts without the -3 option");
+ "remote hosts and the -R option");
}
freeargs(&alist);
@@ -973,11 +1126,28 @@ toremote(int argc, char **argv)
if (do_local_cmd(&alist) != 0)
errs = 1;
} else { /* local to remote */
+ if (mode == MODE_SFTP) {
+ if (remin == -1) {
+ /* Connect to remote now */
+ conn = do_sftp_connect(thost, tuser,
+ tport, sftp_direct,
+ &remin, &remout, &do_cmd_pid);
+ if (conn == NULL) {
+ fatal("Unable to open sftp "
+ "connection");
+ }
+ }
+
+ /* The protocol */
+ source_sftp(1, argv[i], targ, conn);
+ continue;
+ }
+ /* SCP */
if (remin == -1) {
xasprintf(&bp, "%s -t %s%s", cmd,
*targ == '-' ? "-- " : "", targ);
- if (do_cmd(thost, tuser, tport, bp, &remin,
- &remout) < 0)
+ if (do_cmd(ssh_program, thost, tuser, tport, 0,
+ bp, &remin, &remout, &do_cmd_pid) < 0)
exit(1);
if (response() < 0)
exit(1);
@@ -987,6 +1157,8 @@ toremote(int argc, char **argv)
}
}
out:
+ if (mode == MODE_SFTP)
+ free(conn);
free(tuser);
free(thost);
free(targ);
@@ -996,10 +1168,11 @@ out:
}
void
-tolocal(int argc, char **argv)
+tolocal(int argc, char **argv, enum scp_mode_e mode, char *sftp_direct)
{
char *bp, *host = NULL, *src = NULL, *suser = NULL;
arglist alist;
+ struct sftp_conn *conn = NULL;
int i, r, sport = -1;
memset(&alist, '\0', sizeof(alist));
@@ -1036,9 +1209,30 @@ tolocal(int argc, char **argv)
continue;
}
/* Remote to local. */
+ if (mode == MODE_SFTP) {
+ conn = do_sftp_connect(host, suser, sport,
+ sftp_direct, &remin, &remout, &do_cmd_pid);
+ if (conn == NULL) {
+ error("Couldn't make sftp connection "
+ "to server");
+ ++errs;
+ continue;
+ }
+
+ /* The protocol */
+ sink_sftp(1, argv[argc - 1], src, conn);
+
+ free(conn);
+ (void) close(remin);
+ (void) close(remout);
+ remin = remout = -1;
+ continue;
+ }
+ /* SCP */
xasprintf(&bp, "%s -f %s%s",
cmd, *src == '-' ? "-- " : "", src);
- if (do_cmd(host, suser, sport, bp, &remin, &remout) < 0) {
+ if (do_cmd(ssh_program, host, suser, sport, 0, bp,
+ &remin, &remout, &do_cmd_pid) < 0) {
free(bp);
++errs;
continue;
@@ -1053,6 +1247,65 @@ tolocal(int argc, char **argv)
free(src);
}
+/* Prepare remote path, handling ~ by assuming cwd is the homedir */
+static char *
+prepare_remote_path(struct sftp_conn *conn, const char *path)
+{
+ /* Handle ~ prefixed paths */
+ if (*path != '~')
+ return xstrdup(path);
+ if (*path == '\0' || strcmp(path, "~") == 0)
+ return xstrdup(".");
+ if (strncmp(path, "~/", 2) == 0)
+ return xstrdup(path + 2);
+ if (can_expand_path(conn))
+ return do_expand_path(conn, path);
+ /* No protocol extension */
+ error("~user paths are not currently supported");
+ return NULL;
+}
+
+void
+source_sftp(int argc, char *src, char *targ, struct sftp_conn *conn)
+{
+ char *target = NULL, *filename = NULL, *abs_dst = NULL;
+ int target_is_dir;
+
+ if ((filename = basename(src)) == NULL)
+ fatal("basename %s: %s", src, strerror(errno));
+
+ /*
+ * No need to glob here - the local shell already took care of
+ * the expansions
+ */
+ if ((target = prepare_remote_path(conn, targ)) == NULL)
+ cleanup_exit(255);
+ target_is_dir = remote_is_dir(conn, target);
+ if (targetshouldbedirectory && !target_is_dir) {
+ fatal("Target is not a directory, but more files selected "
+ "for upload");
+ }
+ if (target_is_dir)
+ abs_dst = path_append(target, filename);
+ else {
+ abs_dst = target;
+ target = NULL;
+ }
+ debug3_f("copying local %s to remote %s", src, abs_dst);
+
+ if (local_is_dir(src) && iamrecursive) {
+ if (upload_dir(conn, src, abs_dst, pflag,
+ SFTP_PROGRESS_ONLY, 0, 0, 1) != 0) {
+ fatal("failed to upload directory %s to %s",
+ src, abs_dst);
+ }
+ } else if (do_upload(conn, src, abs_dst, pflag, 0, 0) != 0)
+ fatal("failed to upload file %s to %s", src, abs_dst);
+
+ free(abs_dst);
+ free(target);
+}
+
void
source(int argc, char **argv)
{
@@ -1062,7 +1315,7 @@ source(int argc, char **argv)
off_t i, statbytes;
size_t amt, nr;
int fd = -1, haderr, indx;
- char *last, *name, buf[2048], encname[PATH_MAX];
+ char *last, *name, buf[PATH_MAX + 128], encname[PATH_MAX];
int len;
for (indx = 0; indx < argc; ++indx) {
@@ -1071,13 +1324,13 @@ source(int argc, char **argv)
len = strlen(name);
while (len > 1 && name[len-1] == '/')
name[--len] = '\0';
- if ((fd = open(name, O_RDONLY|O_NONBLOCK, 0)) < 0)
+ if ((fd = open(name, O_RDONLY|O_NONBLOCK, 0)) == -1)
goto syserr;
if (strchr(name, '\n') != NULL) {
strnvis(encname, name, sizeof(encname), VIS_NL);
name = encname;
}
- if (fstat(fd, &stb) < 0) {
+ if (fstat(fd, &stb) == -1) {
syserr: run_err("%s: %s", name, strerror(errno));
goto next;
}
@@ -1151,7 +1404,7 @@ next: if (fd != -1) {
unset_nonblock(remout);
if (fd != -1) {
- if (close(fd) < 0 && !haderr)
+ if (close(fd) == -1 && !haderr)
haderr = errno;
fd = -1;
}
@@ -1214,6 +1467,82 @@ rsource(char *name, struct stat *statp)
(void) response();
}
+void
+sink_sftp(int argc, char *dst, const char *src, struct sftp_conn *conn)
+{
+ char *abs_src = NULL;
+ char *abs_dst = NULL;
+ glob_t g;
+ char *filename, *tmp = NULL;
+ int i, r, err = 0;
+
+ memset(&g, 0, sizeof(g));
+ /*
+ * Here, we need remote glob as SFTP can not depend on remote shell
+ * expansions
+ */
+
+ if ((abs_src = prepare_remote_path(conn, src)) == NULL) {
+ err = -1;
+ goto out;
+ }
+
+ debug3_f("copying remote %s to local %s", abs_src, dst);
+ if ((r = remote_glob(conn, abs_src, GLOB_MARK, NULL, &g)) != 0) {
+ if (r == GLOB_NOSPACE)
+ error("Too many glob matches for \"%s\".", abs_src);
+ else
+ error("File \"%s\" not found.", abs_src);
+ err = -1;
+ goto out;
+ }
+
+ if (g.gl_matchc > 1 && !local_is_dir(dst)) {
+ error("Multiple files match pattern, but destination "
+ "\"%s\" is not a directory", dst);
+ err = -1;
+ goto out;
+ }
+
+ for (i = 0; g.gl_pathv[i] && !interrupted; i++) {
+ tmp = xstrdup(g.gl_pathv[i]);
+ if ((filename = basename(tmp)) == NULL) {
+ error("basename %s: %s", tmp, strerror(errno));
+ err = -1;
+ goto out;
+ }
+
+ if (local_is_dir(dst))
+ abs_dst = path_append(dst, filename);
+ else
+ abs_dst = xstrdup(dst);
+
+ debug("Fetching %s to %s\n", g.gl_pathv[i], abs_dst);
+ if (globpath_is_dir(g.gl_pathv[i]) && iamrecursive) {
+ if (download_dir(conn, g.gl_pathv[i], abs_dst, NULL,
+ pflag, SFTP_PROGRESS_ONLY, 0, 0, 1) == -1)
+ err = -1;
+ } else {
+ if (do_download(conn, g.gl_pathv[i], abs_dst, NULL,
+ pflag, 0, 0) == -1)
+ err = -1;
+ }
+ free(abs_dst);
+ abs_dst = NULL;
+ free(tmp);
+ tmp = NULL;
+ }
+
+out:
+ free(abs_src);
+ free(tmp);
+ globfree(&g);
+ if (err == -1) {
+ fatal("Failed to download file '%s'", src);
+ }
+}
+
+
#define TYPE_OVERFLOW(type, val) \
((sizeof(type) == 4 && (val) > INT32_MAX) || \
(sizeof(type) == 8 && (val) > INT64_MAX) || \
@@ -1224,9 +1553,6 @@ sink(int argc, char **argv, const char *src)
{
static BUF buffer;
struct stat stb;
- enum {
- YES, NO, DISPLAYED
- } wrerr;
BUF *bp;
off_t i;
size_t j, count;
@@ -1234,7 +1560,7 @@ sink(int argc, char **argv, const char *src)
mode_t mode, omode, mask;
off_t size, statbytes;
unsigned long long ull;
- int setimes, targisdir, wrerrno = 0;
+ int setimes, targisdir, wrerr;
char ch, *cp, *np, *targ, *why, *vect[1], buf[2048], visbuf[2048];
char **patterns = NULL;
size_t n, npatterns = 0;
@@ -1268,7 +1594,7 @@ sink(int argc, char **argv, const char *src)
* the requested destination file glob.
*/
if (brace_expand(src, &patterns, &npatterns) != 0)
- fatal("%s: could not expand pattern", __func__);
+ fatal_f("could not expand pattern");
}
for (first = 1;; first = 0) {
cp = buf;
@@ -1412,19 +1738,16 @@ sink(int argc, char **argv, const char *src)
if (pflag)
(void) chmod(np, mode);
} else {
- /* Handle copying from a read-only
- directory */
+ /* Handle copying from a read-only directory */
mod_flag = 1;
- if (mkdir(np, mode | S_IRWXU) < 0)
+ if (mkdir(np, mode | S_IRWXU) == -1)
goto bad;
}
vect[0] = xstrdup(np);
sink(1, vect, src);
if (setimes) {
setimes = 0;
- if (utimes(vect[0], tv) < 0)
- run_err("%s: set times: %s",
- vect[0], strerror(errno));
+ (void) utimes(vect[0], tv);
}
if (mod_flag)
(void) chmod(vect[0], mode);
@@ -1433,7 +1756,7 @@ sink(int argc, char **argv, const char *src)
}
omode = mode;
mode |= S_IWUSR;
- if ((ofd = open(np, O_WRONLY|O_CREAT, mode)) < 0) {
+ if ((ofd = open(np, O_WRONLY|O_CREAT, mode)) == -1) {
bad: run_err("%s: %s", np, strerror(errno));
continue;
}
@@ -1443,8 +1766,13 @@ bad: run_err("%s: %s", np, strerror(errno));
continue;
}
cp = bp->buf;
- wrerr = NO;
+ wrerr = 0;
+ /*
+ * NB. do not use run_err() unless immediately followed by
+ * exit() below as it may send a spurious reply that might
+ * desyncronise us from the peer. Use note_err() instead.
+ */
statbytes = 0;
if (showprogress)
start_progress_meter(curfile, size, &statbytes);
@@ -1469,11 +1797,12 @@ bad: run_err("%s: %s", np, strerror(errno));
if (count == bp->cnt) {
/* Keep reading so we stay sync'd up. */
- if (wrerr == NO) {
+ if (!wrerr) {
if (atomicio(vwrite, ofd, bp->buf,
count) != count) {
- wrerr = YES;
- wrerrno = errno;
+ note_err("%s: %s", np,
+ strerror(errno));
+ wrerr = 1;
}
}
count = 0;
@@ -1481,16 +1810,14 @@ bad: run_err("%s: %s", np, strerror(errno));
}
}
unset_nonblock(remin);
- if (count != 0 && wrerr == NO &&
+ if (count != 0 && !wrerr &&
atomicio(vwrite, ofd, bp->buf, count) != count) {
- wrerr = YES;
- wrerrno = errno;
- }
- if (wrerr == NO && (!exists || S_ISREG(stb.st_mode)) &&
- ftruncate(ofd, size) != 0) {
- run_err("%s: truncate: %s", np, strerror(errno));
- wrerr = DISPLAYED;
+ note_err("%s: %s", np, strerror(errno));
+ wrerr = 1;
}
+ if (!wrerr && (!exists || S_ISREG(stb.st_mode)) &&
+ ftruncate(ofd, size) != 0)
+ note_err("%s: truncate: %s", np, strerror(errno));
if (pflag) {
if (exists || omode != mode)
#ifdef HAVE_FCHMOD
@@ -1498,9 +1825,8 @@ bad: run_err("%s: %s", np, strerror(errno));
#else /* HAVE_FCHMOD */
if (chmod(np, omode)) {
#endif /* HAVE_FCHMOD */
- run_err("%s: set mode: %s",
+ note_err("%s: set mode: %s",
np, strerror(errno));
- wrerr = DISPLAYED;
}
} else {
if (!exists && omode != mode)
@@ -1509,36 +1835,25 @@ bad: run_err("%s: %s", np, strerror(errno));
#else /* HAVE_FCHMOD */
if (chmod(np, omode & ~mask)) {
#endif /* HAVE_FCHMOD */
- run_err("%s: set mode: %s",
+ note_err("%s: set mode: %s",
np, strerror(errno));
- wrerr = DISPLAYED;
}
}
- if (close(ofd) == -1) {
- wrerr = YES;
- wrerrno = errno;
- }
+ if (close(ofd) == -1)
+ note_err("%s: close: %s", np, strerror(errno));
(void) response();
if (showprogress)
stop_progress_meter();
- if (setimes && wrerr == NO) {
+ if (setimes && !wrerr) {
setimes = 0;
- if (utimes(np, tv) < 0) {
- run_err("%s: set times: %s",
+ if (utimes(np, tv) == -1) {
+ note_err("%s: set times: %s",
np, strerror(errno));
- wrerr = DISPLAYED;
}
}
- switch (wrerr) {
- case YES:
- run_err("%s: %s", np, strerror(wrerrno));
- break;
- case NO:
+ /* If no error was noted then signal success for this file */
+ if (note_err(NULL) == 0)
(void) atomicio(vwrite, remout, "", 1);
- break;
- case DISPLAYED:
- break;
- }
}
done:
for (n = 0; n < npatterns; n++)
@@ -1553,6 +1868,79 @@ screwup:
exit(1);
}
+void
+throughlocal_sftp(struct sftp_conn *from, struct sftp_conn *to,
+ char *src, char *targ)
+{
+ char *target = NULL, *filename = NULL, *abs_dst = NULL;
+ char *abs_src = NULL, *tmp = NULL;
+ glob_t g;
+ int i, r, targetisdir, err = 0;
+
+ if ((filename = basename(src)) == NULL)
+ fatal("basename %s: %s", src, strerror(errno));
+
+ if ((abs_src = prepare_remote_path(from, src)) == NULL ||
+ (target = prepare_remote_path(to, targ)) == NULL)
+ cleanup_exit(255);
+ memset(&g, 0, sizeof(g));
+
+ targetisdir = remote_is_dir(to, target);
+ if (!targetisdir && targetshouldbedirectory) {
+ error("Destination path \"%s\" is not a directory", target);
+ err = -1;
+ goto out;
+ }
+
+ debug3_f("copying remote %s to remote %s", abs_src, target);
+ if ((r = remote_glob(from, abs_src, GLOB_MARK, NULL, &g)) != 0) {
+ if (r == GLOB_NOSPACE)
+ error("Too many glob matches for \"%s\".", abs_src);
+ else
+ error("File \"%s\" not found.", abs_src);
+ err = -1;
+ goto out;
+ }
+
+ for (i = 0; g.gl_pathv[i] && !interrupted; i++) {
+ tmp = xstrdup(g.gl_pathv[i]);
+ if ((filename = basename(tmp)) == NULL) {
+ error("basename %s: %s", tmp, strerror(errno));
+ err = -1;
+ goto out;
+ }
+
+ if (targetisdir)
+ abs_dst = path_append(target, filename);
+ else
+ abs_dst = xstrdup(target);
+
+ debug("Fetching %s to %s\n", g.gl_pathv[i], abs_dst);
+ if (globpath_is_dir(g.gl_pathv[i]) && iamrecursive) {
+ if (crossload_dir(from, to, g.gl_pathv[i], abs_dst,
+ NULL, pflag, SFTP_PROGRESS_ONLY, 1) == -1)
+ err = -1;
+ } else {
+ if (do_crossload(from, to, g.gl_pathv[i], abs_dst, NULL,
+ pflag) == -1)
+ err = -1;
+ }
+ free(abs_dst);
+ abs_dst = NULL;
+ free(tmp);
+ tmp = NULL;
+ }
+
+out:
+ free(abs_src);
+ free(abs_dst);
+ free(target);
+ free(tmp);
+ globfree(&g);
+ if (err == -1)
+ fatal("Failed to download file '%s'", src);
+}
+
int
response(void)
{
@@ -1595,8 +1983,9 @@ void
usage(void)
{
(void) fprintf(stderr,
- "usage: scp [-346BCpqrTv] [-c cipher] [-F ssh_config] [-i identity_file]\n"
- " [-l limit] [-o ssh_option] [-P port] [-S program] source ... target\n");
+ "usage: scp [-346ABCOpqRrsTv] [-c cipher] [-D sftp_server_path] [-F ssh_config]\n"
+ " [-i identity_file] [-J destination] [-l limit]\n"
+ " [-o ssh_option] [-P port] [-S program] source ... target\n");
exit(1);
}
@@ -1625,6 +2014,38 @@ run_err(const char *fmt,...)
}
}
+/*
+ * Notes a sink error for sending at the end of a file transfer. Returns 0 if
+ * no error has been noted or -1 otherwise. Use note_err(NULL) to flush
+ * any active error at the end of the transfer.
+ */
+int
+note_err(const char *fmt, ...)
+{
+ static char *emsg;
+ va_list ap;
+
+ /* Replay any previously-noted error */
+ if (fmt == NULL) {
+ if (emsg == NULL)
+ return 0;
+ run_err("%s", emsg);
+ free(emsg);
+ emsg = NULL;
+ return -1;
+ }
+
+ errs++;
+ /* Prefer first-noted error */
+ if (emsg != NULL)
+ return -1;
+
+ va_start(ap, fmt);
+ vasnmprintf(&emsg, INT_MAX, NULL, fmt, ap);
+ va_end(ap);
+ return -1;
+}
+
void
verifydir(char *cp)
{
@@ -1676,7 +2097,7 @@ allocbuf(BUF *bp, int fd, int blksize)
#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
struct stat stb;
- if (fstat(fd, &stb) < 0) {
+ if (fstat(fd, &stb) == -1) {
run_err("fstat: %s", strerror(errno));
return (0);
}
@@ -1703,3 +2124,21 @@ lostconn(int signo)
else
exit(1);
}
+
+void
+cleanup_exit(int i)
+{
+ if (remin > 0)
+ close(remin);
+ if (remout > 0)
+ close(remout);
+ if (remin2 > 0)
+ close(remin2);
+ if (remout2 > 0)
+ close(remout2);
+ if (do_cmd_pid > 0)
+ waitpid(do_cmd_pid, NULL, 0);
+ if (do_cmd_pid2 > 0)
+ waitpid(do_cmd_pid2, NULL, 0);
+ exit(i);
+}
diff --git a/crypto/openssh/servconf.c b/crypto/openssh/servconf.c
index 8b07e4b923ae..2dac50232478 100644
--- a/crypto/openssh/servconf.c
+++ b/crypto/openssh/servconf.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: servconf.c,v 1.342 2018/09/20 23:40:16 djm Exp $ */
+/* $OpenBSD: servconf.c,v 1.381 2021/07/02 05:11:21 dtucker Exp $ */
/*
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
* All rights reserved
@@ -16,7 +16,8 @@ __RCSID("$FreeBSD$");
#include <sys/types.h>
#include <sys/socket.h>
-#ifdef HAVE_SYS_SYSCTL_H
+#include <sys/stat.h>
+#ifdef __OpenBSD__
#include <sys/sysctl.h>
#endif
@@ -41,6 +42,11 @@ __RCSID("$FreeBSD$");
#ifdef HAVE_UTIL_H
#include <util.h>
#endif
+#ifdef USE_SYSTEM_GLOB
+# include <glob.h>
+#else
+# include "openbsd-compat/glob.h"
+#endif
#include "openbsd-compat/sys-queue.h"
#include "xmalloc.h"
@@ -71,6 +77,9 @@ static void add_listen_addr(ServerOptions *, const char *,
const char *, int);
static void add_one_listen_addr(ServerOptions *, const char *,
const char *, int);
+static void parse_server_config_depth(ServerOptions *options,
+ const char *filename, struct sshbuf *conf, struct include_list *includes,
+ struct connection_info *connectinfo, int flags, int *activep, int depth);
/* Use of privilege separation or not */
extern int use_privsep;
@@ -115,12 +124,15 @@ initialize_server_options(ServerOptions *options)
options->tcp_keep_alive = -1;
options->log_facility = SYSLOG_FACILITY_NOT_SET;
options->log_level = SYSLOG_LEVEL_NOT_SET;
+ options->num_log_verbose = 0;
+ options->log_verbose = NULL;
options->hostbased_authentication = -1;
options->hostbased_uses_name_from_packet_only = -1;
- options->hostbased_key_types = NULL;
+ options->hostbased_accepted_algos = NULL;
options->hostkeyalgorithms = NULL;
options->pubkey_authentication = -1;
- options->pubkey_key_types = NULL;
+ options->pubkey_auth_options = -1;
+ options->pubkey_accepted_algos = NULL;
options->kerberos_authentication = -1;
options->kerberos_or_local_passwd = -1;
options->kerberos_ticket_cleanup = -1;
@@ -130,10 +142,9 @@ initialize_server_options(ServerOptions *options)
options->gss_strict_acceptor = -1;
options->password_authentication = -1;
options->kbd_interactive_authentication = -1;
- options->challenge_response_authentication = -1;
options->permit_empty_passwd = -1;
options->permit_user_env = -1;
- options->permit_user_env_whitelist = NULL;
+ options->permit_user_env_allowlist = NULL;
options->compression = -1;
options->rekey_limit = -1;
options->rekey_interval = -1;
@@ -155,6 +166,9 @@ initialize_server_options(ServerOptions *options)
options->max_startups_begin = -1;
options->max_startups_rate = -1;
options->max_startups = -1;
+ options->per_source_max_startups = -1;
+ options->per_source_masklen_ipv4 = -1;
+ options->per_source_masklen_ipv6 = -1;
options->max_authtries = -1;
options->max_sessions = -1;
options->banner = NULL;
@@ -172,6 +186,7 @@ initialize_server_options(ServerOptions *options)
options->authorized_keys_command = NULL;
options->authorized_keys_command_user = NULL;
options->revoked_keys_file = NULL;
+ options->sk_provider = NULL;
options->trusted_user_ca_keys = NULL;
options->authorized_principals_file = NULL;
options->authorized_principals_command = NULL;
@@ -196,6 +211,7 @@ static void
assemble_algorithms(ServerOptions *o)
{
char *all_cipher, *all_mac, *all_kex, *all_key, *all_sig;
+ char *def_cipher, *def_mac, *def_kex, *def_key, *def_sig;
int r;
all_cipher = cipher_alg_list(',', 0);
@@ -203,51 +219,50 @@ assemble_algorithms(ServerOptions *o)
all_kex = kex_alg_list(',');
all_key = sshkey_alg_list(0, 0, 1, ',');
all_sig = sshkey_alg_list(0, 1, 1, ',');
+ /* remove unsupported algos from default lists */
+ def_cipher = match_filter_allowlist(KEX_SERVER_ENCRYPT, all_cipher);
+ def_mac = match_filter_allowlist(KEX_SERVER_MAC, all_mac);
+ def_kex = match_filter_allowlist(KEX_SERVER_KEX, all_kex);
+ def_key = match_filter_allowlist(KEX_DEFAULT_PK_ALG, all_key);
+ def_sig = match_filter_allowlist(SSH_ALLOWED_CA_SIGALGS, all_sig);
#define ASSEMBLE(what, defaults, all) \
do { \
if ((r = kex_assemble_names(&o->what, defaults, all)) != 0) \
- fatal("%s: %s: %s", __func__, #what, ssh_err(r)); \
+ fatal_fr(r, "%s", #what); \
} while (0)
- ASSEMBLE(ciphers, KEX_SERVER_ENCRYPT, all_cipher);
- ASSEMBLE(macs, KEX_SERVER_MAC, all_mac);
- ASSEMBLE(kex_algorithms, KEX_SERVER_KEX, all_kex);
- ASSEMBLE(hostkeyalgorithms, KEX_DEFAULT_PK_ALG, all_key);
- ASSEMBLE(hostbased_key_types, KEX_DEFAULT_PK_ALG, all_key);
- ASSEMBLE(pubkey_key_types, KEX_DEFAULT_PK_ALG, all_key);
- ASSEMBLE(ca_sign_algorithms, SSH_ALLOWED_CA_SIGALGS, all_sig);
+ ASSEMBLE(ciphers, def_cipher, all_cipher);
+ ASSEMBLE(macs, def_mac, all_mac);
+ ASSEMBLE(kex_algorithms, def_kex, all_kex);
+ ASSEMBLE(hostkeyalgorithms, def_key, all_key);
+ ASSEMBLE(hostbased_accepted_algos, def_key, all_key);
+ ASSEMBLE(pubkey_accepted_algos, def_key, all_key);
+ ASSEMBLE(ca_sign_algorithms, def_sig, all_sig);
#undef ASSEMBLE
free(all_cipher);
free(all_mac);
free(all_kex);
free(all_key);
free(all_sig);
-}
-
-static void
-array_append(const char *file, const int line, const char *directive,
- char ***array, u_int *lp, const char *s)
-{
-
- if (*lp >= INT_MAX)
- fatal("%s line %d: Too many %s entries", file, line, directive);
-
- *array = xrecallocarray(*array, *lp, *lp + 1, sizeof(**array));
- (*array)[*lp] = xstrdup(s);
- (*lp)++;
+ free(def_cipher);
+ free(def_mac);
+ free(def_kex);
+ free(def_key);
+ free(def_sig);
}
static const char *defaultkey = "[default]";
void
servconf_add_hostkey(const char *file, const int line,
- ServerOptions *options, const char *path)
+ ServerOptions *options, const char *path, int userprovided)
{
char *apath = derelativise_path(path);
if (file == defaultkey && access(path, R_OK) != 0)
return;
- array_append(file, line, "HostKey",
- &options->host_key_files, &options->num_host_key_files, apath);
+ opt_array_append2(file, line, "HostKey",
+ &options->host_key_files, &options->host_key_file_userprovided,
+ &options->num_host_key_files, apath, userprovided);
free(apath);
}
@@ -257,7 +272,7 @@ servconf_add_hostcert(const char *file, const int line,
{
char *apath = derelativise_path(path);
- array_append(file, line, "HostCertificate",
+ opt_array_append(file, line, "HostCertificate",
&options->host_cert_files, &options->num_host_cert_files, apath);
free(apath);
}
@@ -275,18 +290,16 @@ fill_default_server_options(ServerOptions *options)
if (options->num_host_key_files == 0) {
/* fill default hostkeys for protocols */
servconf_add_hostkey(defaultkey, 0, options,
- _PATH_HOST_RSA_KEY_FILE);
- servconf_add_hostkey(defaultkey, 0, options,
- _PATH_HOST_DSA_KEY_FILE);
+ _PATH_HOST_RSA_KEY_FILE, 0);
#ifdef OPENSSL_HAS_ECC
servconf_add_hostkey(defaultkey, 0, options,
- _PATH_HOST_ECDSA_KEY_FILE);
+ _PATH_HOST_ECDSA_KEY_FILE, 0);
#endif
servconf_add_hostkey(defaultkey, 0, options,
- _PATH_HOST_ED25519_KEY_FILE);
+ _PATH_HOST_ED25519_KEY_FILE, 0);
#ifdef WITH_XMSS
servconf_add_hostkey(defaultkey, 0, options,
- _PATH_HOST_XMSS_KEY_FILE);
+ _PATH_HOST_XMSS_KEY_FILE, 0);
#endif /* WITH_XMSS */
}
if (options->num_host_key_files == 0)
@@ -300,6 +313,8 @@ fill_default_server_options(ServerOptions *options)
add_listen_addr(options, NULL, NULL, 0);
if (options->pid_file == NULL)
options->pid_file = xstrdup(_PATH_SSH_DAEMON_PID_FILE);
+ if (options->moduli_file == NULL)
+ options->moduli_file = xstrdup(_PATH_DH_MODULI);
if (options->login_grace_time == -1)
options->login_grace_time = 120;
if (options->permit_root_login == PERMIT_NOT_SET)
@@ -338,6 +353,8 @@ fill_default_server_options(ServerOptions *options)
options->hostbased_uses_name_from_packet_only = 0;
if (options->pubkey_authentication == -1)
options->pubkey_authentication = 1;
+ if (options->pubkey_auth_options == -1)
+ options->pubkey_auth_options = 0;
if (options->kerberos_authentication == -1)
options->kerberos_authentication = 0;
if (options->kerberos_or_local_passwd == -1)
@@ -355,17 +372,20 @@ fill_default_server_options(ServerOptions *options)
if (options->password_authentication == -1)
options->password_authentication = 0;
if (options->kbd_interactive_authentication == -1)
- options->kbd_interactive_authentication = 0;
- if (options->challenge_response_authentication == -1)
- options->challenge_response_authentication = 1;
+ options->kbd_interactive_authentication = 1;
if (options->permit_empty_passwd == -1)
options->permit_empty_passwd = 0;
if (options->permit_user_env == -1) {
options->permit_user_env = 0;
- options->permit_user_env_whitelist = NULL;
+ options->permit_user_env_allowlist = NULL;
}
if (options->compression == -1)
+#ifdef WITH_ZLIB
options->compression = COMP_DELAYED;
+#else
+ options->compression = COMP_NONE;
+#endif
+
if (options->rekey_limit == -1)
options->rekey_limit = 0;
if (options->rekey_interval == -1)
@@ -384,6 +404,12 @@ fill_default_server_options(ServerOptions *options)
options->max_startups_rate = 30; /* 30% */
if (options->max_startups_begin == -1)
options->max_startups_begin = 10;
+ if (options->per_source_max_startups == -1)
+ options->per_source_max_startups = INT_MAX;
+ if (options->per_source_masklen_ipv4 == -1)
+ options->per_source_masklen_ipv4 = 32;
+ if (options->per_source_masklen_ipv6 == -1)
+ options->per_source_masklen_ipv6 = 128;
if (options->max_authtries == -1)
options->max_authtries = DEFAULT_AUTH_FAIL_MAX;
if (options->max_sessions == -1)
@@ -395,11 +421,11 @@ fill_default_server_options(ServerOptions *options)
if (options->client_alive_count_max == -1)
options->client_alive_count_max = 3;
if (options->num_authkeys_files == 0) {
- array_append(defaultkey, 0, "AuthorizedKeysFiles",
+ opt_array_append(defaultkey, 0, "AuthorizedKeysFiles",
&options->authorized_keys_files,
&options->num_authkeys_files,
_PATH_SSH_USER_PERMITTED_KEYS);
- array_append(defaultkey, 0, "AuthorizedKeysFiles",
+ opt_array_append(defaultkey, 0, "AuthorizedKeysFiles",
&options->authorized_keys_files,
&options->num_authkeys_files,
_PATH_SSH_USER_PERMITTED_KEYS2);
@@ -422,6 +448,8 @@ fill_default_server_options(ServerOptions *options)
options->disable_forwarding = 0;
if (options->expose_userauth_info == -1)
options->expose_userauth_info = 0;
+ if (options->sk_provider == NULL)
+ options->sk_provider = xstrdup("internal");
if (options->use_blacklist == -1)
options->use_blacklist = 0;
@@ -443,10 +471,12 @@ fill_default_server_options(ServerOptions *options)
CLEAR_ON_NONE(options->banner);
CLEAR_ON_NONE(options->trusted_user_ca_keys);
CLEAR_ON_NONE(options->revoked_keys_file);
+ CLEAR_ON_NONE(options->sk_provider);
CLEAR_ON_NONE(options->authorized_principals_file);
CLEAR_ON_NONE(options->adm_forced_command);
CLEAR_ON_NONE(options->chroot_directory);
CLEAR_ON_NONE(options->routing_domain);
+ CLEAR_ON_NONE(options->host_key_agent);
for (i = 0; i < options->num_host_key_files; i++)
CLEAR_ON_NONE(options->host_key_files[i]);
for (i = 0; i < options->num_host_cert_files; i++)
@@ -460,16 +490,6 @@ fill_default_server_options(ServerOptions *options)
options->auth_methods[0] = NULL;
options->num_auth_methods = 0;
}
-
-#ifndef HAVE_MMAP
- if (use_privsep && options->compression == 1) {
- error("This platform does not support both privilege "
- "separation and compression");
- error("Compression disabled");
- options->compression = 0;
- }
-#endif
-
}
/* Keyword tokens. */
@@ -479,8 +499,7 @@ typedef enum {
sUsePAM,
/* Standard Options */
sPort, sHostKeyFile, sLoginGraceTime,
- sPermitRootLogin, sLogFacility, sLogLevel,
- sRhostsRSAAuthentication, sRSAAuthentication,
+ sPermitRootLogin, sLogFacility, sLogLevel, sLogVerbose,
sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup,
sKerberosGetAFSToken, sChallengeResponseAuthentication,
sPasswordAuthentication, sKbdInteractiveAuthentication,
@@ -490,18 +509,18 @@ typedef enum {
sPermitTTY, sStrictModes, sEmptyPasswd, sTCPKeepAlive,
sPermitUserEnvironment, sAllowTcpForwarding, sCompression,
sRekeyLimit, sAllowUsers, sDenyUsers, sAllowGroups, sDenyGroups,
- sIgnoreUserKnownHosts, sCiphers, sMacs, sPidFile,
- sGatewayPorts, sPubkeyAuthentication, sPubkeyAcceptedKeyTypes,
+ sIgnoreUserKnownHosts, sCiphers, sMacs, sPidFile, sModuliFile,
+ sGatewayPorts, sPubkeyAuthentication, sPubkeyAcceptedAlgorithms,
sXAuthLocation, sSubsystem, sMaxStartups, sMaxAuthTries, sMaxSessions,
sBanner, sUseDNS, sHostbasedAuthentication,
- sHostbasedUsesNameFromPacketOnly, sHostbasedAcceptedKeyTypes,
- sHostKeyAlgorithms,
+ sHostbasedUsesNameFromPacketOnly, sHostbasedAcceptedAlgorithms,
+ sHostKeyAlgorithms, sPerSourceMaxStartups, sPerSourceNetBlockSize,
sClientAliveInterval, sClientAliveCountMax, sAuthorizedKeysFile,
sGssAuthentication, sGssCleanupCreds, sGssStrictAcceptor,
sAcceptEnv, sSetEnv, sPermitTunnel,
sMatch, sPermitOpen, sPermitListen, sForceCommand, sChrootDirectory,
sUsePrivilegeSeparation, sAllowAgentForwarding,
- sHostCertificate,
+ sHostCertificate, sInclude,
sRevokedKeys, sTrustedUserCAKeys, sAuthorizedPrincipalsFile,
sAuthorizedPrincipalsCommand, sAuthorizedPrincipalsCommandUser,
sKexAlgorithms, sCASignatureAlgorithms, sIPQoS, sVersionAddendum,
@@ -509,14 +528,16 @@ typedef enum {
sAuthenticationMethods, sHostKeyAgent, sPermitUserRC,
sStreamLocalBindMask, sStreamLocalBindUnlink,
sAllowStreamLocalForwarding, sFingerprintHash, sDisableForwarding,
- sExposeAuthInfo, sRDomain,
+ sExposeAuthInfo, sRDomain, sPubkeyAuthOptions, sSecurityKeyProvider,
sUseBlacklist,
sDeprecated, sIgnore, sUnsupported
} ServerOpCodes;
-#define SSHCFG_GLOBAL 0x01 /* allowed in main section of sshd_config */
-#define SSHCFG_MATCH 0x02 /* allowed inside a Match section */
-#define SSHCFG_ALL (SSHCFG_GLOBAL|SSHCFG_MATCH)
+#define SSHCFG_GLOBAL 0x01 /* allowed in main section of config */
+#define SSHCFG_MATCH 0x02 /* allowed inside a Match section */
+#define SSHCFG_ALL (SSHCFG_GLOBAL|SSHCFG_MATCH)
+#define SSHCFG_NEVERMATCH 0x04 /* Match never matches; internal only */
+#define SSHCFG_MATCH_ONLY 0x08 /* Match only in conditional blocks; internal only */
/* Textual representation of the tokens. */
static struct {
@@ -537,21 +558,26 @@ static struct {
{ "hostdsakey", sHostKeyFile, SSHCFG_GLOBAL }, /* alias */
{ "hostkeyagent", sHostKeyAgent, SSHCFG_GLOBAL },
{ "pidfile", sPidFile, SSHCFG_GLOBAL },
+ { "modulifile", sModuliFile, SSHCFG_GLOBAL },
{ "serverkeybits", sDeprecated, SSHCFG_GLOBAL },
{ "logingracetime", sLoginGraceTime, SSHCFG_GLOBAL },
{ "keyregenerationinterval", sDeprecated, SSHCFG_GLOBAL },
{ "permitrootlogin", sPermitRootLogin, SSHCFG_ALL },
{ "syslogfacility", sLogFacility, SSHCFG_GLOBAL },
{ "loglevel", sLogLevel, SSHCFG_ALL },
+ { "logverbose", sLogVerbose, SSHCFG_ALL },
{ "rhostsauthentication", sDeprecated, SSHCFG_GLOBAL },
{ "rhostsrsaauthentication", sDeprecated, SSHCFG_ALL },
{ "hostbasedauthentication", sHostbasedAuthentication, SSHCFG_ALL },
{ "hostbasedusesnamefrompacketonly", sHostbasedUsesNameFromPacketOnly, SSHCFG_ALL },
- { "hostbasedacceptedkeytypes", sHostbasedAcceptedKeyTypes, SSHCFG_ALL },
+ { "hostbasedacceptedalgorithms", sHostbasedAcceptedAlgorithms, SSHCFG_ALL },
+ { "hostbasedacceptedkeytypes", sHostbasedAcceptedAlgorithms, SSHCFG_ALL }, /* obsolete */
{ "hostkeyalgorithms", sHostKeyAlgorithms, SSHCFG_GLOBAL },
{ "rsaauthentication", sDeprecated, SSHCFG_ALL },
{ "pubkeyauthentication", sPubkeyAuthentication, SSHCFG_ALL },
- { "pubkeyacceptedkeytypes", sPubkeyAcceptedKeyTypes, SSHCFG_ALL },
+ { "pubkeyacceptedalgorithms", sPubkeyAcceptedAlgorithms, SSHCFG_ALL },
+ { "pubkeyacceptedkeytypes", sPubkeyAcceptedAlgorithms, SSHCFG_ALL }, /* obsolete */
+ { "pubkeyauthoptions", sPubkeyAuthOptions, SSHCFG_ALL },
{ "dsaauthentication", sPubkeyAuthentication, SSHCFG_GLOBAL }, /* alias */
#ifdef KRB5
{ "kerberosauthentication", sKerberosAuthentication, SSHCFG_ALL },
@@ -581,8 +607,8 @@ static struct {
#endif
{ "passwordauthentication", sPasswordAuthentication, SSHCFG_ALL },
{ "kbdinteractiveauthentication", sKbdInteractiveAuthentication, SSHCFG_ALL },
- { "challengeresponseauthentication", sChallengeResponseAuthentication, SSHCFG_GLOBAL },
- { "skeyauthentication", sDeprecated, SSHCFG_GLOBAL },
+ { "challengeresponseauthentication", sKbdInteractiveAuthentication, SSHCFG_ALL }, /* alias */
+ { "skeyauthentication", sKbdInteractiveAuthentication, SSHCFG_ALL }, /* alias */
{ "checkmail", sDeprecated, SSHCFG_GLOBAL },
{ "listenaddress", sListenAddress, SSHCFG_GLOBAL },
{ "addressfamily", sAddressFamily, SSHCFG_GLOBAL },
@@ -592,7 +618,7 @@ static struct {
#else
{ "printlastlog", sPrintLastLog, SSHCFG_GLOBAL },
#endif
- { "ignorerhosts", sIgnoreRhosts, SSHCFG_GLOBAL },
+ { "ignorerhosts", sIgnoreRhosts, SSHCFG_ALL },
{ "ignoreuserknownhosts", sIgnoreUserKnownHosts, SSHCFG_GLOBAL },
{ "x11forwarding", sX11Forwarding, SSHCFG_ALL },
{ "x11displayoffset", sX11DisplayOffset, SSHCFG_ALL },
@@ -618,6 +644,8 @@ static struct {
{ "gatewayports", sGatewayPorts, SSHCFG_ALL },
{ "subsystem", sSubsystem, SSHCFG_GLOBAL },
{ "maxstartups", sMaxStartups, SSHCFG_GLOBAL },
+ { "persourcemaxstartups", sPerSourceMaxStartups, SSHCFG_GLOBAL },
+ { "persourcenetblocksize", sPerSourceNetBlockSize, SSHCFG_GLOBAL },
{ "maxauthtries", sMaxAuthTries, SSHCFG_ALL },
{ "maxsessions", sMaxSessions, SSHCFG_ALL },
{ "banner", sBanner, SSHCFG_ALL },
@@ -644,6 +672,7 @@ static struct {
{ "trustedusercakeys", sTrustedUserCAKeys, SSHCFG_ALL },
{ "authorizedprincipalsfile", sAuthorizedPrincipalsFile, SSHCFG_ALL },
{ "kexalgorithms", sKexAlgorithms, SSHCFG_GLOBAL },
+ { "include", sInclude, SSHCFG_ALL },
{ "ipqos", sIPQoS, SSHCFG_ALL },
{ "authorizedkeyscommand", sAuthorizedKeysCommand, SSHCFG_ALL },
{ "authorizedkeyscommanduser", sAuthorizedKeysCommandUser, SSHCFG_ALL },
@@ -659,6 +688,7 @@ static struct {
{ "exposeauthinfo", sExposeAuthInfo, SSHCFG_ALL },
{ "rdomain", sRDomain, SSHCFG_ALL },
{ "casignaturealgorithms", sCASignatureAlgorithms, SSHCFG_ALL },
+ { "securitykeyprovider", sSecurityKeyProvider, SSHCFG_GLOBAL },
{ "useblacklist", sUseBlacklist, SSHCFG_GLOBAL },
{ "useblocklist", sUseBlacklist, SSHCFG_GLOBAL }, /* alias */
{ "noneenabled", sUnsupported, SSHCFG_ALL },
@@ -722,10 +752,10 @@ derelativise_path(const char *path)
if (strcasecmp(path, "none") == 0)
return xstrdup("none");
expanded = tilde_expand_filename(path, getuid());
- if (*expanded == '/')
+ if (path_absolute(expanded))
return expanded;
if (getcwd(cwd, sizeof(cwd)) == NULL)
- fatal("%s: getcwd: %s", __func__, strerror(errno));
+ fatal_f("getcwd: %s", strerror(errno));
xasprintf(&ret, "%s/%s", cwd, expanded);
free(expanded);
return ret;
@@ -768,7 +798,7 @@ add_one_listen_addr(ServerOptions *options, const char *addr,
if (i >= options->num_listen_addrs) {
/* No entry for this rdomain; allocate one */
if (i >= INT_MAX)
- fatal("%s: too many listen addresses", __func__);
+ fatal_f("too many listen addresses");
options->listen_addrs = xrecallocarray(options->listen_addrs,
options->num_listen_addrs, options->num_listen_addrs + 1,
sizeof(*options->listen_addrs));
@@ -884,7 +914,7 @@ process_permitopen_list(struct ssh *ssh, ServerOpCodes opcode,
{
u_int i;
int port;
- char *host, *arg, *oarg;
+ char *host, *arg, *oarg, ch;
int where = opcode == sPermitOpen ? FORWARD_LOCAL : FORWARD_REMOTE;
const char *what = lookup_opcode_name(opcode);
@@ -902,12 +932,13 @@ process_permitopen_list(struct ssh *ssh, ServerOpCodes opcode,
/* Otherwise treat it as a list of permitted host:port */
for (i = 0; i < num_opens; i++) {
oarg = arg = xstrdup(opens[i]);
- host = hpdelim(&arg);
- if (host == NULL)
- fatal("%s: missing host in %s", __func__, what);
+ ch = '\0';
+ host = hpdelim2(&arg, &ch);
+ if (host == NULL || ch == '/')
+ fatal_f("missing host in %s", what);
host = cleanhostname(host);
if (arg == NULL || ((port = permitopen_port(arg)) < 0))
- fatal("%s: bad port number in %s", __func__, what);
+ fatal_f("bad port number in %s", what);
/* Send it to channels layer */
channel_add_permission(ssh, FORWARD_ADM,
where, host, port);
@@ -929,12 +960,11 @@ process_permitopen(struct ssh *ssh, ServerOptions *options)
}
struct connection_info *
-get_connection_info(int populate, int use_dns)
+get_connection_info(struct ssh *ssh, int populate, int use_dns)
{
- struct ssh *ssh = active_state; /* XXX */
static struct connection_info ci;
- if (!populate)
+ if (ssh == NULL || !populate)
return &ci;
ci.host = auth_get_canonical_hostname(ssh, use_dns);
ci.address = ssh_remote_ipaddr(ssh);
@@ -1033,35 +1063,46 @@ match_cfg_line(char **condition, int line, struct connection_info *ci)
ci->laddress ? ci->laddress : "(null)", ci->lport);
while ((attrib = strdelim(&cp)) && *attrib != '\0') {
+ /* Terminate on comment */
+ if (*attrib == '#') {
+ cp = NULL; /* mark all arguments consumed */
+ break;
+ }
+ arg = NULL;
attributes++;
+ /* Criterion "all" has no argument and must appear alone */
if (strcasecmp(attrib, "all") == 0) {
- if (attributes != 1 ||
- ((arg = strdelim(&cp)) != NULL && *arg != '\0')) {
+ if (attributes > 1 || ((arg = strdelim(&cp)) != NULL &&
+ *arg != '\0' && *arg != '#')) {
error("'all' cannot be combined with other "
"Match attributes");
return -1;
}
+ if (arg != NULL && *arg == '#')
+ cp = NULL; /* mark all arguments consumed */
*condition = cp;
return 1;
}
- if ((arg = strdelim(&cp)) == NULL || *arg == '\0') {
+ /* All other criteria require an argument */
+ if ((arg = strdelim(&cp)) == NULL ||
+ *arg == '\0' || *arg == '#') {
error("Missing Match criteria for %s", attrib);
return -1;
}
if (strcasecmp(attrib, "user") == 0) {
- if (ci == NULL) {
+ if (ci == NULL || (ci->test && ci->user == NULL)) {
result = 0;
continue;
}
if (ci->user == NULL)
match_test_missing_fatal("User", "user");
- if (match_pattern_list(ci->user, arg, 0) != 1)
+ if (match_usergroup_pattern_list(ci->user, arg) != 1)
result = 0;
else
debug("user %.100s matched 'User %.100s' at "
"line %d", ci->user, arg, line);
} else if (strcasecmp(attrib, "group") == 0) {
- if (ci == NULL) {
+ if (ci == NULL || (ci->test && ci->user == NULL)) {
result = 0;
continue;
}
@@ -1074,7 +1115,7 @@ match_cfg_line(char **condition, int line, struct connection_info *ci)
result = 0;
}
} else if (strcasecmp(attrib, "host") == 0) {
- if (ci == NULL) {
+ if (ci == NULL || (ci->test && ci->host == NULL)) {
result = 0;
continue;
}
@@ -1086,7 +1127,10 @@ match_cfg_line(char **condition, int line, struct connection_info *ci)
debug("connection from %.100s matched 'Host "
"%.100s' at line %d", ci->host, arg, line);
} else if (strcasecmp(attrib, "address") == 0) {
- if (ci == NULL) {
+ if (ci == NULL || (ci->test && ci->address == NULL)) {
+ if (addr_match_list(NULL, arg) != 0)
+ fatal("Invalid Match address argument "
+ "'%s' at line %d", arg, line);
result = 0;
continue;
}
@@ -1105,7 +1149,11 @@ match_cfg_line(char **condition, int line, struct connection_info *ci)
return -1;
}
} else if (strcasecmp(attrib, "localaddress") == 0){
- if (ci == NULL) {
+ if (ci == NULL || (ci->test && ci->laddress == NULL)) {
+ if (addr_match_list(NULL, arg) != 0)
+ fatal("Invalid Match localaddress "
+ "argument '%s' at line %d", arg,
+ line);
result = 0;
continue;
}
@@ -1131,7 +1179,7 @@ match_cfg_line(char **condition, int line, struct connection_info *ci)
arg);
return -1;
}
- if (ci == NULL) {
+ if (ci == NULL || (ci->test && ci->lport == -1)) {
result = 0;
continue;
}
@@ -1145,10 +1193,12 @@ match_cfg_line(char **condition, int line, struct connection_info *ci)
else
result = 0;
} else if (strcasecmp(attrib, "rdomain") == 0) {
- if (ci == NULL || ci->rdomain == NULL) {
+ if (ci == NULL || (ci->test && ci->rdomain == NULL)) {
result = 0;
continue;
}
+ if (ci->rdomain == NULL)
+ match_test_missing_fatal("RDomain", "rdomain");
if (match_pattern_list(ci->rdomain, arg, 0) != 1)
result = 0;
else
@@ -1181,6 +1231,12 @@ static const struct multistate multistate_flag[] = {
{ "no", 0 },
{ NULL, -1 }
};
+static const struct multistate multistate_ignore_rhosts[] = {
+ { "yes", IGNORE_RHOSTS_YES },
+ { "no", IGNORE_RHOSTS_NO },
+ { "shosts-only", IGNORE_RHOSTS_SHOSTS },
+ { NULL, -1 }
+};
static const struct multistate multistate_addressfamily[] = {
{ "inet", AF_INET },
{ "inet6", AF_INET6 },
@@ -1196,8 +1252,10 @@ static const struct multistate multistate_permitrootlogin[] = {
{ NULL, -1 }
};
static const struct multistate multistate_compression[] = {
+#ifdef WITH_ZLIB
{ "yes", COMP_DELAYED },
{ "delayed", COMP_DELAYED },
+#endif
{ "no", COMP_NONE },
{ NULL, -1 }
};
@@ -1216,13 +1274,14 @@ static const struct multistate multistate_tcpfwd[] = {
{ NULL, -1 }
};
-int
-process_server_config_line(ServerOptions *options, char *line,
+static int
+process_server_config_line_depth(ServerOptions *options, char *line,
const char *filename, int linenum, int *activep,
- struct connection_info *connectinfo)
+ struct connection_info *connectinfo, int *inc_flags, int depth,
+ struct include_list *includes)
{
- char *cp, ***chararrayptr, **charptr, *arg, *arg2, *p;
- int cmdline = 0, *intptr, value, value2, n, port;
+ char ch, *str, ***chararrayptr, **charptr, *arg, *arg2, *p, *keyword;
+ int cmdline = 0, *intptr, value, value2, n, port, oactive, r, found;
SyslogFacility *log_facility_ptr;
LogLevel *log_level_ptr;
ServerOpCodes opcode;
@@ -1231,6 +1290,11 @@ process_server_config_line(ServerOptions *options, char *line,
long long val64;
const struct multistate *multistate_ptr;
const char *errstr;
+ struct include_item *item;
+ glob_t gbuf;
+ char **oav = NULL, **av;
+ int oac = 0, ac;
+ int ret = -1;
/* Strip trailing whitespace. Allow \f (form feed) at EOL only */
if ((len = strlen(line)) == 0)
@@ -1241,32 +1305,43 @@ process_server_config_line(ServerOptions *options, char *line,
line[len] = '\0';
}
- cp = line;
- if ((arg = strdelim(&cp)) == NULL)
+ str = line;
+ if ((keyword = strdelim(&str)) == NULL)
return 0;
/* Ignore leading whitespace */
- if (*arg == '\0')
- arg = strdelim(&cp);
- if (!arg || !*arg || *arg == '#')
+ if (*keyword == '\0')
+ keyword = strdelim(&str);
+ if (!keyword || !*keyword || *keyword == '#')
return 0;
+ if (str == NULL || *str == '\0') {
+ error("%s line %d: no argument after keyword \"%s\"",
+ filename, linenum, keyword);
+ return -1;
+ }
intptr = NULL;
charptr = NULL;
- opcode = parse_token(arg, filename, linenum, &flags);
+ opcode = parse_token(keyword, filename, linenum, &flags);
+
+ if (argv_split(str, &oac, &oav, 1) != 0) {
+ error("%s line %d: invalid quotes", filename, linenum);
+ return -1;
+ }
+ ac = oac;
+ av = oav;
if (activep == NULL) { /* We are processing a command line directive */
cmdline = 1;
activep = &cmdline;
}
- if (*activep && opcode != sMatch)
- debug3("%s:%d setting %s %s", filename, linenum, arg, cp);
+ if (*activep && opcode != sMatch && opcode != sInclude)
+ debug3("%s:%d setting %s %s", filename, linenum, keyword, str);
if (*activep == 0 && !(flags & SSHCFG_MATCH)) {
if (connectinfo == NULL) {
fatal("%s line %d: Directive '%s' is not allowed "
- "within a Match block", filename, linenum, arg);
+ "within a Match block", filename, linenum, keyword);
} else { /* this is a directive we have already processed */
- while (arg)
- arg = strdelim(&cp);
- return 0;
+ ret = 0;
+ goto out;
}
}
@@ -1278,15 +1353,17 @@ process_server_config_line(ServerOptions *options, char *line,
/* Standard Options */
case sBadOption:
- return -1;
+ goto out;
case sPort:
/* ignore ports from configfile if cmdline specifies ports */
- if (options->ports_from_cmdline)
- return 0;
+ if (options->ports_from_cmdline) {
+ argv_consume(&ac);
+ break;
+ }
if (options->num_ports >= MAX_PORTS)
fatal("%s line %d: too many ports.",
filename, linenum);
- arg = strdelim(&cp);
+ arg = argv_next(&ac, &av);
if (!arg || *arg == '\0')
fatal("%s line %d: missing port number.",
filename, linenum);
@@ -1299,7 +1376,7 @@ process_server_config_line(ServerOptions *options, char *line,
case sLoginGraceTime:
intptr = &options->login_grace_time;
parse_time:
- arg = strdelim(&cp);
+ arg = argv_next(&ac, &av);
if (!arg || *arg == '\0')
fatal("%s line %d: missing time value.",
filename, linenum);
@@ -1311,7 +1388,7 @@ process_server_config_line(ServerOptions *options, char *line,
break;
case sListenAddress:
- arg = strdelim(&cp);
+ arg = argv_next(&ac, &av);
if (arg == NULL || *arg == '\0')
fatal("%s line %d: missing address",
filename, linenum);
@@ -1321,8 +1398,10 @@ process_server_config_line(ServerOptions *options, char *line,
port = 0;
p = arg;
} else {
- p = hpdelim(&arg);
- if (p == NULL)
+ arg2 = NULL;
+ ch = '\0';
+ p = hpdelim2(&arg, &ch);
+ if (p == NULL || ch == '/')
fatal("%s line %d: bad address:port usage",
filename, linenum);
p = cleanhostname(p);
@@ -1334,16 +1413,15 @@ process_server_config_line(ServerOptions *options, char *line,
}
/* Optional routing table */
arg2 = NULL;
- if ((arg = strdelim(&cp)) != NULL) {
+ if ((arg = argv_next(&ac, &av)) != NULL) {
if (strcmp(arg, "rdomain") != 0 ||
- (arg2 = strdelim(&cp)) == NULL)
+ (arg2 = argv_next(&ac, &av)) == NULL)
fatal("%s line %d: bad ListenAddress syntax",
filename, linenum);
if (!valid_rdomain(arg2))
fatal("%s line %d: bad routing domain",
filename, linenum);
}
-
queue_listen_addr(options, p, arg2, port);
break;
@@ -1352,7 +1430,7 @@ process_server_config_line(ServerOptions *options, char *line,
intptr = &options->address_family;
multistate_ptr = multistate_addressfamily;
parse_multistate:
- arg = strdelim(&cp);
+ arg = argv_next(&ac, &av);
if (!arg || *arg == '\0')
fatal("%s line %d: missing argument.",
filename, linenum);
@@ -1371,17 +1449,19 @@ process_server_config_line(ServerOptions *options, char *line,
break;
case sHostKeyFile:
- arg = strdelim(&cp);
+ arg = argv_next(&ac, &av);
if (!arg || *arg == '\0')
fatal("%s line %d: missing file name.",
filename, linenum);
- if (*activep)
- servconf_add_hostkey(filename, linenum, options, arg);
+ if (*activep) {
+ servconf_add_hostkey(filename, linenum,
+ options, arg, 1);
+ }
break;
case sHostKeyAgent:
charptr = &options->host_key_agent;
- arg = strdelim(&cp);
+ arg = argv_next(&ac, &av);
if (!arg || *arg == '\0')
fatal("%s line %d: missing socket name.",
filename, linenum);
@@ -1391,7 +1471,7 @@ process_server_config_line(ServerOptions *options, char *line,
break;
case sHostCertificate:
- arg = strdelim(&cp);
+ arg = argv_next(&ac, &av);
if (!arg || *arg == '\0')
fatal("%s line %d: missing file name.",
filename, linenum);
@@ -1402,7 +1482,7 @@ process_server_config_line(ServerOptions *options, char *line,
case sPidFile:
charptr = &options->pid_file;
parse_filename:
- arg = strdelim(&cp);
+ arg = argv_next(&ac, &av);
if (!arg || *arg == '\0')
fatal("%s line %d: missing file name.",
filename, linenum);
@@ -1414,6 +1494,10 @@ process_server_config_line(ServerOptions *options, char *line,
}
break;
+ case sModuliFile:
+ charptr = &options->moduli_file;
+ goto parse_filename;
+
case sPermitRootLogin:
intptr = &options->permit_root_login;
multistate_ptr = multistate_permitrootlogin;
@@ -1421,13 +1505,14 @@ process_server_config_line(ServerOptions *options, char *line,
case sIgnoreRhosts:
intptr = &options->ignore_rhosts;
- parse_flag:
- multistate_ptr = multistate_flag;
+ multistate_ptr = multistate_ignore_rhosts;
goto parse_multistate;
case sIgnoreUserKnownHosts:
intptr = &options->ignore_user_known_hosts;
- goto parse_flag;
+ parse_flag:
+ multistate_ptr = multistate_flag;
+ goto parse_multistate;
case sHostbasedAuthentication:
intptr = &options->hostbased_authentication;
@@ -1437,15 +1522,16 @@ process_server_config_line(ServerOptions *options, char *line,
intptr = &options->hostbased_uses_name_from_packet_only;
goto parse_flag;
- case sHostbasedAcceptedKeyTypes:
- charptr = &options->hostbased_key_types;
- parse_keytypes:
- arg = strdelim(&cp);
+ case sHostbasedAcceptedAlgorithms:
+ charptr = &options->hostbased_accepted_algos;
+ parse_pubkey_algos:
+ arg = argv_next(&ac, &av);
if (!arg || *arg == '\0')
fatal("%s line %d: Missing argument.",
filename, linenum);
if (*arg != '-' &&
- !sshkey_names_valid2(*arg == '+' ? arg + 1 : arg, 1))
+ !sshkey_names_valid2(*arg == '+' || *arg == '^' ?
+ arg + 1 : arg, 1))
fatal("%s line %d: Bad key types '%s'.",
filename, linenum, arg ? arg : "<NONE>");
if (*activep && *charptr == NULL)
@@ -1454,19 +1540,39 @@ process_server_config_line(ServerOptions *options, char *line,
case sHostKeyAlgorithms:
charptr = &options->hostkeyalgorithms;
- goto parse_keytypes;
+ goto parse_pubkey_algos;
case sCASignatureAlgorithms:
charptr = &options->ca_sign_algorithms;
- goto parse_keytypes;
+ goto parse_pubkey_algos;
case sPubkeyAuthentication:
intptr = &options->pubkey_authentication;
goto parse_flag;
- case sPubkeyAcceptedKeyTypes:
- charptr = &options->pubkey_key_types;
- goto parse_keytypes;
+ case sPubkeyAcceptedAlgorithms:
+ charptr = &options->pubkey_accepted_algos;
+ goto parse_pubkey_algos;
+
+ case sPubkeyAuthOptions:
+ intptr = &options->pubkey_auth_options;
+ value = 0;
+ while ((arg = argv_next(&ac, &av)) != NULL) {
+ if (strcasecmp(arg, "none") == 0)
+ continue;
+ if (strcasecmp(arg, "touch-required") == 0)
+ value |= PUBKEYAUTH_TOUCH_REQUIRED;
+ else if (strcasecmp(arg, "verify-required") == 0)
+ value |= PUBKEYAUTH_VERIFY_REQUIRED;
+ else {
+ error("%s line %d: unsupported %s option %s",
+ filename, linenum, keyword, arg);
+ goto out;
+ }
+ }
+ if (*activep && *intptr == -1)
+ *intptr = value;
+ break;
case sKerberosAuthentication:
intptr = &options->kerberos_authentication;
@@ -1504,10 +1610,6 @@ process_server_config_line(ServerOptions *options, char *line,
intptr = &options->kbd_interactive_authentication;
goto parse_flag;
- case sChallengeResponseAuthentication:
- intptr = &options->challenge_response_authentication;
- goto parse_flag;
-
case sPrintMotd:
intptr = &options->print_motd;
goto parse_flag;
@@ -1523,10 +1625,10 @@ process_server_config_line(ServerOptions *options, char *line,
case sX11DisplayOffset:
intptr = &options->x11_display_offset;
parse_int:
- arg = strdelim(&cp);
+ arg = argv_next(&ac, &av);
if ((errstr = atoi_err(arg, &value)) != NULL)
- fatal("%s line %d: integer value %s.",
- filename, linenum, errstr);
+ fatal("%s line %d: %s integer value %s.",
+ filename, linenum, keyword, errstr);
if (*activep && *intptr == -1)
*intptr = value;
break;
@@ -1561,11 +1663,11 @@ process_server_config_line(ServerOptions *options, char *line,
case sPermitUserEnvironment:
intptr = &options->permit_user_env;
- charptr = &options->permit_user_env_whitelist;
- arg = strdelim(&cp);
+ charptr = &options->permit_user_env_allowlist;
+ arg = argv_next(&ac, &av);
if (!arg || *arg == '\0')
- fatal("%s line %d: missing argument.",
- filename, linenum);
+ fatal("%s line %d: %s missing argument.",
+ filename, linenum, keyword);
value = 0;
p = NULL;
if (strcmp(arg, "yes") == 0)
@@ -1591,25 +1693,26 @@ process_server_config_line(ServerOptions *options, char *line,
goto parse_multistate;
case sRekeyLimit:
- arg = strdelim(&cp);
+ arg = argv_next(&ac, &av);
if (!arg || *arg == '\0')
- fatal("%.200s line %d: Missing argument.", filename,
- linenum);
+ fatal("%s line %d: %s missing argument.",
+ filename, linenum, keyword);
if (strcmp(arg, "default") == 0) {
val64 = 0;
} else {
if (scan_scaled(arg, &val64) == -1)
- fatal("%.200s line %d: Bad number '%s': %s",
- filename, linenum, arg, strerror(errno));
+ fatal("%.200s line %d: Bad %s number '%s': %s",
+ filename, linenum, keyword,
+ arg, strerror(errno));
if (val64 != 0 && val64 < 16)
- fatal("%.200s line %d: RekeyLimit too small",
- filename, linenum);
+ fatal("%.200s line %d: %s too small",
+ filename, linenum, keyword);
}
if (*activep && options->rekey_limit == -1)
options->rekey_limit = val64;
- if (cp != NULL) { /* optional rekey interval present */
- if (strcmp(cp, "none") == 0) {
- (void)strdelim(&cp); /* discard */
+ if (ac != 0) { /* optional rekey interval present */
+ if (strcmp(av[0], "none") == 0) {
+ (void)argv_next(&ac, &av); /* discard */
break;
}
intptr = &options->rekey_interval;
@@ -1628,7 +1731,7 @@ process_server_config_line(ServerOptions *options, char *line,
case sLogFacility:
log_facility_ptr = &options->log_facility;
- arg = strdelim(&cp);
+ arg = argv_next(&ac, &av);
value = log_facility_number(arg);
if (value == SYSLOG_FACILITY_NOT_SET)
fatal("%.200s line %d: unsupported log facility '%s'",
@@ -1639,7 +1742,7 @@ process_server_config_line(ServerOptions *options, char *line,
case sLogLevel:
log_level_ptr = &options->log_level;
- arg = strdelim(&cp);
+ arg = argv_next(&ac, &av);
value = log_level_number(arg);
if (value == SYSLOG_LEVEL_NOT_SET)
fatal("%.200s line %d: unsupported log level '%s'",
@@ -1648,6 +1751,33 @@ process_server_config_line(ServerOptions *options, char *line,
*log_level_ptr = (LogLevel) value;
break;
+ case sLogVerbose:
+ found = options->num_log_verbose == 0;
+ i = 0;
+ while ((arg = argv_next(&ac, &av)) != NULL) {
+ if (*arg == '\0') {
+ error("%s line %d: keyword %s empty argument",
+ filename, linenum, keyword);
+ goto out;
+ }
+ /* Allow "none" only in first position */
+ if (strcasecmp(arg, "none") == 0) {
+ if (i > 0 || ac > 0) {
+ error("%s line %d: keyword %s \"none\" "
+ "argument must appear alone.",
+ filename, linenum, keyword);
+ goto out;
+ }
+ }
+ i++;
+ if (!found || !*activep)
+ continue;
+ opt_array_append(filename, linenum, keyword,
+ &options->log_verbose, &options->num_log_verbose,
+ arg);
+ }
+ break;
+
case sAllowTcpForwarding:
intptr = &options->allow_tcp_forwarding;
multistate_ptr = multistate_tcpfwd;
@@ -1667,56 +1797,53 @@ process_server_config_line(ServerOptions *options, char *line,
goto parse_flag;
case sAllowUsers:
- while ((arg = strdelim(&cp)) && *arg != '\0') {
- if (match_user(NULL, NULL, NULL, arg) == -1)
- fatal("%s line %d: invalid AllowUsers pattern: "
- "\"%.100s\"", filename, linenum, arg);
+ chararrayptr = &options->allow_users;
+ uintptr = &options->num_allow_users;
+ parse_allowdenyusers:
+ while ((arg = argv_next(&ac, &av)) != NULL) {
+ if (*arg == '\0' ||
+ match_user(NULL, NULL, NULL, arg) == -1)
+ fatal("%s line %d: invalid %s pattern: \"%s\"",
+ filename, linenum, keyword, arg);
if (!*activep)
continue;
- array_append(filename, linenum, "AllowUsers",
- &options->allow_users, &options->num_allow_users,
- arg);
+ opt_array_append(filename, linenum, keyword,
+ chararrayptr, uintptr, arg);
}
break;
case sDenyUsers:
- while ((arg = strdelim(&cp)) && *arg != '\0') {
- if (match_user(NULL, NULL, NULL, arg) == -1)
- fatal("%s line %d: invalid DenyUsers pattern: "
- "\"%.100s\"", filename, linenum, arg);
- if (!*activep)
- continue;
- array_append(filename, linenum, "DenyUsers",
- &options->deny_users, &options->num_deny_users,
- arg);
- }
- break;
+ chararrayptr = &options->deny_users;
+ uintptr = &options->num_deny_users;
+ goto parse_allowdenyusers;
case sAllowGroups:
- while ((arg = strdelim(&cp)) && *arg != '\0') {
+ chararrayptr = &options->allow_groups;
+ uintptr = &options->num_allow_groups;
+ parse_allowdenygroups:
+ while ((arg = argv_next(&ac, &av)) != NULL) {
+ if (*arg == '\0')
+ fatal("%s line %d: empty %s pattern",
+ filename, linenum, keyword);
if (!*activep)
continue;
- array_append(filename, linenum, "AllowGroups",
- &options->allow_groups, &options->num_allow_groups,
- arg);
+ opt_array_append(filename, linenum, keyword,
+ chararrayptr, uintptr, arg);
}
break;
case sDenyGroups:
- while ((arg = strdelim(&cp)) && *arg != '\0') {
- if (!*activep)
- continue;
- array_append(filename, linenum, "DenyGroups",
- &options->deny_groups, &options->num_deny_groups,
- arg);
- }
- break;
+ chararrayptr = &options->deny_groups;
+ uintptr = &options->num_deny_groups;
+ goto parse_allowdenygroups;
case sCiphers:
- arg = strdelim(&cp);
+ arg = argv_next(&ac, &av);
if (!arg || *arg == '\0')
- fatal("%s line %d: Missing argument.", filename, linenum);
- if (*arg != '-' && !ciphers_valid(*arg == '+' ? arg + 1 : arg))
+ fatal("%s line %d: %s missing argument.",
+ filename, linenum, keyword);
+ if (*arg != '-' &&
+ !ciphers_valid(*arg == '+' || *arg == '^' ? arg + 1 : arg))
fatal("%s line %d: Bad SSH2 cipher spec '%s'.",
filename, linenum, arg ? arg : "<NONE>");
if (options->ciphers == NULL)
@@ -1724,10 +1851,12 @@ process_server_config_line(ServerOptions *options, char *line,
break;
case sMacs:
- arg = strdelim(&cp);
+ arg = argv_next(&ac, &av);
if (!arg || *arg == '\0')
- fatal("%s line %d: Missing argument.", filename, linenum);
- if (*arg != '-' && !mac_valid(*arg == '+' ? arg + 1 : arg))
+ fatal("%s line %d: %s missing argument.",
+ filename, linenum, keyword);
+ if (*arg != '-' &&
+ !mac_valid(*arg == '+' || *arg == '^' ? arg + 1 : arg))
fatal("%s line %d: Bad SSH2 mac spec '%s'.",
filename, linenum, arg ? arg : "<NONE>");
if (options->macs == NULL)
@@ -1735,12 +1864,13 @@ process_server_config_line(ServerOptions *options, char *line,
break;
case sKexAlgorithms:
- arg = strdelim(&cp);
+ arg = argv_next(&ac, &av);
if (!arg || *arg == '\0')
- fatal("%s line %d: Missing argument.",
- filename, linenum);
+ fatal("%s line %d: %s missing argument.",
+ filename, linenum, keyword);
if (*arg != '-' &&
- !kex_names_valid(*arg == '+' ? arg + 1 : arg))
+ !kex_names_valid(*arg == '+' || *arg == '^' ?
+ arg + 1 : arg))
fatal("%s line %d: Bad SSH2 KexAlgorithms '%s'.",
filename, linenum, arg ? arg : "<NONE>");
if (options->kex_algorithms == NULL)
@@ -1752,20 +1882,20 @@ process_server_config_line(ServerOptions *options, char *line,
fatal("%s line %d: too many subsystems defined.",
filename, linenum);
}
- arg = strdelim(&cp);
+ arg = argv_next(&ac, &av);
if (!arg || *arg == '\0')
- fatal("%s line %d: Missing subsystem name.",
- filename, linenum);
+ fatal("%s line %d: %s missing argument.",
+ filename, linenum, keyword);
if (!*activep) {
- arg = strdelim(&cp);
+ arg = argv_next(&ac, &av);
break;
}
for (i = 0; i < options->num_subsystems; i++)
if (strcmp(arg, options->subsystem_name[i]) == 0)
- fatal("%s line %d: Subsystem '%s' already defined.",
- filename, linenum, arg);
+ fatal("%s line %d: Subsystem '%s' "
+ "already defined.", filename, linenum, arg);
options->subsystem_name[options->num_subsystems] = xstrdup(arg);
- arg = strdelim(&cp);
+ arg = argv_next(&ac, &av);
if (!arg || *arg == '\0')
fatal("%s line %d: Missing subsystem command.",
filename, linenum);
@@ -1774,7 +1904,7 @@ process_server_config_line(ServerOptions *options, char *line,
/* Collect arguments (separate to executable) */
p = xstrdup(arg);
len = strlen(p) + 1;
- while ((arg = strdelim(&cp)) != NULL && *arg != '\0') {
+ while ((arg = argv_next(&ac, &av)) != NULL) {
len += 1 + strlen(arg);
p = xreallocarray(p, 1, len);
strlcat(p, " ", len);
@@ -1785,10 +1915,10 @@ process_server_config_line(ServerOptions *options, char *line,
break;
case sMaxStartups:
- arg = strdelim(&cp);
+ arg = argv_next(&ac, &av);
if (!arg || *arg == '\0')
- fatal("%s line %d: Missing MaxStartups spec.",
- filename, linenum);
+ fatal("%s line %d: %s missing argument.",
+ filename, linenum, keyword);
if ((n = sscanf(arg, "%d:%d:%d",
&options->max_startups_begin,
&options->max_startups_rate,
@@ -1797,15 +1927,54 @@ process_server_config_line(ServerOptions *options, char *line,
options->max_startups ||
options->max_startups_rate > 100 ||
options->max_startups_rate < 1)
- fatal("%s line %d: Illegal MaxStartups spec.",
- filename, linenum);
+ fatal("%s line %d: Invalid %s spec.",
+ filename, linenum, keyword);
} else if (n != 1)
- fatal("%s line %d: Illegal MaxStartups spec.",
- filename, linenum);
+ fatal("%s line %d: Invalid %s spec.",
+ filename, linenum, keyword);
else
options->max_startups = options->max_startups_begin;
break;
+ case sPerSourceNetBlockSize:
+ arg = argv_next(&ac, &av);
+ if (!arg || *arg == '\0')
+ fatal("%s line %d: %s missing argument.",
+ filename, linenum, keyword);
+ switch (n = sscanf(arg, "%d:%d", &value, &value2)) {
+ case 2:
+ if (value2 < 0 || value2 > 128)
+ n = -1;
+ /* FALLTHROUGH */
+ case 1:
+ if (value < 0 || value > 32)
+ n = -1;
+ }
+ if (n != 1 && n != 2)
+ fatal("%s line %d: Invalid %s spec.",
+ filename, linenum, keyword);
+ if (*activep) {
+ options->per_source_masklen_ipv4 = value;
+ options->per_source_masklen_ipv6 = value2;
+ }
+ break;
+
+ case sPerSourceMaxStartups:
+ arg = argv_next(&ac, &av);
+ if (!arg || *arg == '\0')
+ fatal("%s line %d: %s missing argument.",
+ filename, linenum, keyword);
+ if (strcmp(arg, "none") == 0) { /* no limit */
+ value = INT_MAX;
+ } else {
+ if ((errstr = atoi_err(arg, &value)) != NULL)
+ fatal("%s line %d: %s integer value %s.",
+ filename, linenum, keyword, errstr);
+ }
+ if (*activep)
+ options->per_source_max_startups = value;
+ break;
+
case sMaxAuthTries:
intptr = &options->max_authtries;
goto parse_int;
@@ -1825,24 +1994,29 @@ process_server_config_line(ServerOptions *options, char *line,
* AuthorizedKeysFile /etc/ssh_keys/%u
*/
case sAuthorizedKeysFile:
- if (*activep && options->num_authkeys_files == 0) {
- while ((arg = strdelim(&cp)) && *arg != '\0') {
- arg = tilde_expand_filename(arg, getuid());
- array_append(filename, linenum,
- "AuthorizedKeysFile",
+ uvalue = options->num_authkeys_files;
+ while ((arg = argv_next(&ac, &av)) != NULL) {
+ if (*arg == '\0') {
+ error("%s line %d: keyword %s empty argument",
+ filename, linenum, keyword);
+ goto out;
+ }
+ arg2 = tilde_expand_filename(arg, getuid());
+ if (*activep && uvalue == 0) {
+ opt_array_append(filename, linenum, keyword,
&options->authorized_keys_files,
- &options->num_authkeys_files, arg);
- free(arg);
+ &options->num_authkeys_files, arg2);
}
+ free(arg2);
}
- return 0;
+ break;
case sAuthorizedPrincipalsFile:
charptr = &options->authorized_principals_file;
- arg = strdelim(&cp);
+ arg = argv_next(&ac, &av);
if (!arg || *arg == '\0')
- fatal("%s line %d: missing file name.",
- filename, linenum);
+ fatal("%s line %d: %s missing argument.",
+ filename, linenum, keyword);
if (*activep && *charptr == NULL) {
*charptr = tilde_expand_filename(arg, getuid());
/* increase optional counter */
@@ -1860,13 +2034,13 @@ process_server_config_line(ServerOptions *options, char *line,
goto parse_int;
case sAcceptEnv:
- while ((arg = strdelim(&cp)) && *arg != '\0') {
- if (strchr(arg, '=') != NULL)
+ while ((arg = argv_next(&ac, &av)) != NULL) {
+ if (*arg == '\0' || strchr(arg, '=') != NULL)
fatal("%s line %d: Invalid environment name.",
filename, linenum);
if (!*activep)
continue;
- array_append(filename, linenum, "AcceptEnv",
+ opt_array_append(filename, linenum, keyword,
&options->accept_env, &options->num_accept_env,
arg);
}
@@ -1874,23 +2048,23 @@ process_server_config_line(ServerOptions *options, char *line,
case sSetEnv:
uvalue = options->num_setenv;
- while ((arg = strdelimw(&cp)) && *arg != '\0') {
- if (strchr(arg, '=') == NULL)
+ while ((arg = argv_next(&ac, &av)) != NULL) {
+ if (*arg == '\0' || strchr(arg, '=') == NULL)
fatal("%s line %d: Invalid environment.",
filename, linenum);
if (!*activep || uvalue != 0)
continue;
- array_append(filename, linenum, "SetEnv",
+ opt_array_append(filename, linenum, keyword,
&options->setenv, &options->num_setenv, arg);
}
break;
case sPermitTunnel:
intptr = &options->permit_tun;
- arg = strdelim(&cp);
+ arg = argv_next(&ac, &av);
if (!arg || *arg == '\0')
- fatal("%s line %d: Missing yes/point-to-point/"
- "ethernet/no argument.", filename, linenum);
+ fatal("%s line %d: %s missing argument.",
+ filename, linenum, keyword);
value = -1;
for (i = 0; tunmode_desc[i].val != -1; i++)
if (strcmp(tunmode_desc[i].text, arg) == 0) {
@@ -1898,21 +2072,129 @@ process_server_config_line(ServerOptions *options, char *line,
break;
}
if (value == -1)
- fatal("%s line %d: Bad yes/point-to-point/ethernet/"
- "no argument: %s", filename, linenum, arg);
+ fatal("%s line %d: bad %s argument %s",
+ filename, linenum, keyword, arg);
if (*activep && *intptr == -1)
*intptr = value;
break;
+ case sInclude:
+ if (cmdline) {
+ fatal("Include directive not supported as a "
+ "command-line option");
+ }
+ value = 0;
+ while ((arg2 = argv_next(&ac, &av)) != NULL) {
+ if (*arg2 == '\0') {
+ error("%s line %d: keyword %s empty argument",
+ filename, linenum, keyword);
+ goto out;
+ }
+ value++;
+ found = 0;
+ if (*arg2 != '/' && *arg2 != '~') {
+ xasprintf(&arg, "%s/%s", SSHDIR, arg2);
+ } else
+ arg = xstrdup(arg2);
+
+ /*
+ * Don't let included files clobber the containing
+ * file's Match state.
+ */
+ oactive = *activep;
+
+ /* consult cache of include files */
+ TAILQ_FOREACH(item, includes, entry) {
+ if (strcmp(item->selector, arg) != 0)
+ continue;
+ if (item->filename != NULL) {
+ parse_server_config_depth(options,
+ item->filename, item->contents,
+ includes, connectinfo,
+ (*inc_flags & SSHCFG_MATCH_ONLY
+ ? SSHCFG_MATCH_ONLY : (oactive
+ ? 0 : SSHCFG_NEVERMATCH)),
+ activep, depth + 1);
+ }
+ found = 1;
+ *activep = oactive;
+ }
+ if (found != 0) {
+ free(arg);
+ continue;
+ }
+
+ /* requested glob was not in cache */
+ debug2("%s line %d: new include %s",
+ filename, linenum, arg);
+ if ((r = glob(arg, 0, NULL, &gbuf)) != 0) {
+ if (r != GLOB_NOMATCH) {
+ fatal("%s line %d: include \"%s\" glob "
+ "failed", filename, linenum, arg);
+ }
+ /*
+ * If no entry matched then record a
+ * placeholder to skip later glob calls.
+ */
+ debug2("%s line %d: no match for %s",
+ filename, linenum, arg);
+ item = xcalloc(1, sizeof(*item));
+ item->selector = strdup(arg);
+ TAILQ_INSERT_TAIL(includes,
+ item, entry);
+ }
+ if (gbuf.gl_pathc > INT_MAX)
+ fatal_f("too many glob results");
+ for (n = 0; n < (int)gbuf.gl_pathc; n++) {
+ debug2("%s line %d: including %s",
+ filename, linenum, gbuf.gl_pathv[n]);
+ item = xcalloc(1, sizeof(*item));
+ item->selector = strdup(arg);
+ item->filename = strdup(gbuf.gl_pathv[n]);
+ if ((item->contents = sshbuf_new()) == NULL)
+ fatal_f("sshbuf_new failed");
+ load_server_config(item->filename,
+ item->contents);
+ parse_server_config_depth(options,
+ item->filename, item->contents,
+ includes, connectinfo,
+ (*inc_flags & SSHCFG_MATCH_ONLY
+ ? SSHCFG_MATCH_ONLY : (oactive
+ ? 0 : SSHCFG_NEVERMATCH)),
+ activep, depth + 1);
+ *activep = oactive;
+ TAILQ_INSERT_TAIL(includes, item, entry);
+ }
+ globfree(&gbuf);
+ free(arg);
+ }
+ if (value == 0) {
+ fatal("%s line %d: %s missing filename argument",
+ filename, linenum, keyword);
+ }
+ break;
+
case sMatch:
if (cmdline)
fatal("Match directive not supported as a command-line "
- "option");
- value = match_cfg_line(&cp, linenum, connectinfo);
+ "option");
+ value = match_cfg_line(&str, linenum,
+ (*inc_flags & SSHCFG_NEVERMATCH ? NULL : connectinfo));
if (value < 0)
fatal("%s line %d: Bad Match condition", filename,
linenum);
- *activep = value;
+ *activep = (*inc_flags & SSHCFG_NEVERMATCH) ? 0 : value;
+ /*
+ * The MATCH_ONLY flag is applicable only until the first
+ * match block.
+ */
+ *inc_flags &= ~SSHCFG_MATCH_ONLY;
+ /*
+ * If match_cfg_line() didn't consume all its arguments then
+ * arrange for the extra arguments check below to fail.
+ */
+ if (str == NULL || *str == '\0')
+ argv_consume(&ac);
break;
case sPermitListen:
@@ -1924,10 +2206,10 @@ process_server_config_line(ServerOptions *options, char *line,
uintptr = &options->num_permitted_opens;
chararrayptr = &options->permitted_opens;
}
- arg = strdelim(&cp);
+ arg = argv_next(&ac, &av);
if (!arg || *arg == '\0')
- fatal("%s line %d: missing %s specification",
- filename, linenum, lookup_opcode_name(opcode));
+ fatal("%s line %d: %s missing argument.",
+ filename, linenum, keyword);
uvalue = *uintptr; /* modified later */
if (strcmp(arg, "any") == 0 || strcmp(arg, "none") == 0) {
if (*activep && uvalue == 0) {
@@ -1938,7 +2220,7 @@ process_server_config_line(ServerOptions *options, char *line,
}
break;
}
- for (; arg != NULL && *arg != '\0'; arg = strdelim(&cp)) {
+ for (; arg != NULL && *arg != '\0'; arg = argv_next(&ac, &av)) {
if (opcode == sPermitListen &&
strchr(arg, ':') == NULL) {
/*
@@ -1948,23 +2230,21 @@ process_server_config_line(ServerOptions *options, char *line,
xasprintf(&arg2, "*:%s", arg);
} else {
arg2 = xstrdup(arg);
- p = hpdelim(&arg);
- if (p == NULL) {
- fatal("%s line %d: missing host in %s",
- filename, linenum,
- lookup_opcode_name(opcode));
+ ch = '\0';
+ p = hpdelim2(&arg, &ch);
+ if (p == NULL || ch == '/') {
+ fatal("%s line %d: %s missing host",
+ filename, linenum, keyword);
}
p = cleanhostname(p);
}
if (arg == NULL ||
((port = permitopen_port(arg)) < 0)) {
- fatal("%s line %d: bad port number in %s",
- filename, linenum,
- lookup_opcode_name(opcode));
+ fatal("%s line %d: %s bad port number",
+ filename, linenum, keyword);
}
if (*activep && uvalue == 0) {
- array_append(filename, linenum,
- lookup_opcode_name(opcode),
+ opt_array_append(filename, linenum, keyword,
chararrayptr, uintptr, arg2);
}
free(arg2);
@@ -1972,21 +2252,22 @@ process_server_config_line(ServerOptions *options, char *line,
break;
case sForceCommand:
- if (cp == NULL || *cp == '\0')
- fatal("%.200s line %d: Missing argument.", filename,
- linenum);
- len = strspn(cp, WHITESPACE);
+ if (str == NULL || *str == '\0')
+ fatal("%s line %d: %s missing argument.",
+ filename, linenum, keyword);
+ len = strspn(str, WHITESPACE);
if (*activep && options->adm_forced_command == NULL)
- options->adm_forced_command = xstrdup(cp + len);
- return 0;
+ options->adm_forced_command = xstrdup(str + len);
+ argv_consume(&ac);
+ break;
case sChrootDirectory:
charptr = &options->chroot_directory;
- arg = strdelim(&cp);
+ arg = argv_next(&ac, &av);
if (!arg || *arg == '\0')
- fatal("%s line %d: missing file name.",
- filename, linenum);
+ fatal("%s line %d: %s missing argument.",
+ filename, linenum, keyword);
if (*activep && *charptr == NULL)
*charptr = xstrdup(arg);
break;
@@ -1999,17 +2280,35 @@ process_server_config_line(ServerOptions *options, char *line,
charptr = &options->revoked_keys_file;
goto parse_filename;
+ case sSecurityKeyProvider:
+ charptr = &options->sk_provider;
+ arg = argv_next(&ac, &av);
+ if (!arg || *arg == '\0')
+ fatal("%s line %d: %s missing argument.",
+ filename, linenum, keyword);
+ if (*activep && *charptr == NULL) {
+ *charptr = strcasecmp(arg, "internal") == 0 ?
+ xstrdup(arg) : derelativise_path(arg);
+ /* increase optional counter */
+ if (intptr != NULL)
+ *intptr = *intptr + 1;
+ }
+ break;
+
case sIPQoS:
- arg = strdelim(&cp);
+ arg = argv_next(&ac, &av);
+ if (!arg || *arg == '\0')
+ fatal("%s line %d: %s missing argument.",
+ filename, linenum, keyword);
if ((value = parse_ipqos(arg)) == -1)
- fatal("%s line %d: Bad IPQoS value: %s",
- filename, linenum, arg);
- arg = strdelim(&cp);
+ fatal("%s line %d: Bad %s value: %s",
+ filename, linenum, keyword, arg);
+ arg = argv_next(&ac, &av);
if (arg == NULL)
value2 = value;
else if ((value2 = parse_ipqos(arg)) == -1)
- fatal("%s line %d: Bad IPQoS value: %s",
- filename, linenum, arg);
+ fatal("%s line %d: Bad %s value: %s",
+ filename, linenum, keyword, arg);
if (*activep) {
options->ip_qos_interactive = value;
options->ip_qos_bulk = value2;
@@ -2017,120 +2316,102 @@ process_server_config_line(ServerOptions *options, char *line,
break;
case sVersionAddendum:
- if (cp == NULL || *cp == '\0')
- fatal("%.200s line %d: Missing argument.", filename,
- linenum);
- len = strspn(cp, WHITESPACE);
+ if (str == NULL || *str == '\0')
+ fatal("%s line %d: %s missing argument.",
+ filename, linenum, keyword);
+ len = strspn(str, WHITESPACE);
+ if (strchr(str + len, '\r') != NULL) {
+ fatal("%.200s line %d: Invalid %s argument",
+ filename, linenum, keyword);
+ }
+ if ((arg = strchr(line, '#')) != NULL) {
+ *arg = '\0';
+ rtrim(line);
+ }
if (*activep && options->version_addendum == NULL) {
- if (strcasecmp(cp + len, "none") == 0)
+ if (strcasecmp(str + len, "none") == 0)
options->version_addendum = xstrdup("");
- else if (strchr(cp + len, '\r') != NULL)
- fatal("%.200s line %d: Invalid argument",
- filename, linenum);
else
- options->version_addendum = xstrdup(cp + len);
+ options->version_addendum = xstrdup(str + len);
}
- return 0;
+ argv_consume(&ac);
+ break;
case sAuthorizedKeysCommand:
- if (cp == NULL)
- fatal("%.200s line %d: Missing argument.", filename,
- linenum);
- len = strspn(cp, WHITESPACE);
- if (*activep && options->authorized_keys_command == NULL) {
- if (cp[len] != '/' && strcasecmp(cp + len, "none") != 0)
- fatal("%.200s line %d: AuthorizedKeysCommand "
- "must be an absolute path",
- filename, linenum);
- options->authorized_keys_command = xstrdup(cp + len);
+ charptr = &options->authorized_keys_command;
+ parse_command:
+ len = strspn(str, WHITESPACE);
+ if (str[len] != '/' && strcasecmp(str + len, "none") != 0) {
+ fatal("%.200s line %d: %s must be an absolute path",
+ filename, linenum, keyword);
}
- return 0;
+ if (*activep && options->authorized_keys_command == NULL)
+ *charptr = xstrdup(str + len);
+ argv_consume(&ac);
+ break;
case sAuthorizedKeysCommandUser:
charptr = &options->authorized_keys_command_user;
-
- arg = strdelim(&cp);
- if (!arg || *arg == '\0')
- fatal("%s line %d: missing AuthorizedKeysCommandUser "
- "argument.", filename, linenum);
+ parse_localuser:
+ arg = argv_next(&ac, &av);
+ if (!arg || *arg == '\0') {
+ fatal("%s line %d: missing %s argument.",
+ filename, linenum, keyword);
+ }
if (*activep && *charptr == NULL)
*charptr = xstrdup(arg);
break;
case sAuthorizedPrincipalsCommand:
- if (cp == NULL)
- fatal("%.200s line %d: Missing argument.", filename,
- linenum);
- len = strspn(cp, WHITESPACE);
- if (*activep &&
- options->authorized_principals_command == NULL) {
- if (cp[len] != '/' && strcasecmp(cp + len, "none") != 0)
- fatal("%.200s line %d: "
- "AuthorizedPrincipalsCommand must be "
- "an absolute path", filename, linenum);
- options->authorized_principals_command =
- xstrdup(cp + len);
- }
- return 0;
+ charptr = &options->authorized_principals_command;
+ goto parse_command;
case sAuthorizedPrincipalsCommandUser:
charptr = &options->authorized_principals_command_user;
-
- arg = strdelim(&cp);
- if (!arg || *arg == '\0')
- fatal("%s line %d: missing "
- "AuthorizedPrincipalsCommandUser argument.",
- filename, linenum);
- if (*activep && *charptr == NULL)
- *charptr = xstrdup(arg);
- break;
+ goto parse_localuser;
case sAuthenticationMethods:
- if (options->num_auth_methods == 0) {
- value = 0; /* seen "any" pseudo-method */
- value2 = 0; /* successfully parsed any method */
- while ((arg = strdelim(&cp)) && *arg != '\0') {
- if (strcmp(arg, "any") == 0) {
- if (options->num_auth_methods > 0) {
- fatal("%s line %d: \"any\" "
- "must appear alone in "
- "AuthenticationMethods",
- filename, linenum);
- }
- value = 1;
- } else if (value) {
- fatal("%s line %d: \"any\" must appear "
- "alone in AuthenticationMethods",
- filename, linenum);
- } else if (auth2_methods_valid(arg, 0) != 0) {
- fatal("%s line %d: invalid "
- "authentication method list.",
- filename, linenum);
+ found = options->num_auth_methods == 0;
+ value = 0; /* seen "any" pseudo-method */
+ value2 = 0; /* successfully parsed any method */
+ while ((arg = argv_next(&ac, &av)) != NULL) {
+ if (strcmp(arg, "any") == 0) {
+ if (options->num_auth_methods > 0) {
+ fatal("%s line %d: \"any\" must "
+ "appear alone in %s",
+ filename, linenum, keyword);
}
- value2 = 1;
- if (!*activep)
- continue;
- array_append(filename, linenum,
- "AuthenticationMethods",
- &options->auth_methods,
- &options->num_auth_methods, arg);
- }
- if (value2 == 0) {
- fatal("%s line %d: no AuthenticationMethods "
- "specified", filename, linenum);
+ value = 1;
+ } else if (value) {
+ fatal("%s line %d: \"any\" must appear "
+ "alone in %s", filename, linenum, keyword);
+ } else if (auth2_methods_valid(arg, 0) != 0) {
+ fatal("%s line %d: invalid %s method list.",
+ filename, linenum, keyword);
}
+ value2 = 1;
+ if (!found || !*activep)
+ continue;
+ opt_array_append(filename, linenum, keyword,
+ &options->auth_methods,
+ &options->num_auth_methods, arg);
}
- return 0;
+ if (value2 == 0) {
+ fatal("%s line %d: no %s specified",
+ filename, linenum, keyword);
+ }
+ break;
case sStreamLocalBindMask:
- arg = strdelim(&cp);
+ arg = argv_next(&ac, &av);
if (!arg || *arg == '\0')
- fatal("%s line %d: missing StreamLocalBindMask "
- "argument.", filename, linenum);
+ fatal("%s line %d: %s missing argument.",
+ filename, linenum, keyword);
/* Parse mode in octal format */
value = strtol(arg, &p, 8);
if (arg == p || value < 0 || value > 0777)
- fatal("%s line %d: Bad mask.", filename, linenum);
+ fatal("%s line %d: Invalid %s.",
+ filename, linenum, keyword);
if (*activep)
options->fwd_opts.streamlocal_bind_mask = (mode_t)value;
break;
@@ -2140,13 +2421,13 @@ process_server_config_line(ServerOptions *options, char *line,
goto parse_flag;
case sFingerprintHash:
- arg = strdelim(&cp);
+ arg = argv_next(&ac, &av);
if (!arg || *arg == '\0')
- fatal("%.200s line %d: Missing argument.",
- filename, linenum);
+ fatal("%s line %d: %s missing argument.",
+ filename, linenum, keyword);
if ((value = ssh_digest_alg_by_name(arg)) == -1)
- fatal("%.200s line %d: Invalid hash algorithm \"%s\".",
- filename, linenum, arg);
+ fatal("%.200s line %d: Invalid %s algorithm \"%s\".",
+ filename, linenum, keyword, arg);
if (*activep)
options->fingerprint_hash = value;
break;
@@ -2156,14 +2437,18 @@ process_server_config_line(ServerOptions *options, char *line,
goto parse_flag;
case sRDomain:
+#if !defined(__OpenBSD__) && !defined(HAVE_SYS_SET_PROCESS_RDOMAIN)
+ fatal("%s line %d: setting RDomain not supported on this "
+ "platform.", filename, linenum);
+#endif
charptr = &options->routing_domain;
- arg = strdelim(&cp);
+ arg = argv_next(&ac, &av);
if (!arg || *arg == '\0')
- fatal("%.200s line %d: Missing argument.",
- filename, linenum);
+ fatal("%s line %d: %s missing argument.",
+ filename, linenum, keyword);
if (strcasecmp(arg, "none") != 0 && strcmp(arg, "%D") != 0 &&
!valid_rdomain(arg))
- fatal("%s line %d: bad routing domain",
+ fatal("%s line %d: invalid routing domain",
filename, linenum);
if (*activep && *charptr == NULL)
*charptr = xstrdup(arg);
@@ -2179,65 +2464,89 @@ process_server_config_line(ServerOptions *options, char *line,
do_log2(opcode == sIgnore ?
SYSLOG_LEVEL_DEBUG2 : SYSLOG_LEVEL_INFO,
"%s line %d: %s option %s", filename, linenum,
- opcode == sUnsupported ? "Unsupported" : "Deprecated", arg);
- while (arg)
- arg = strdelim(&cp);
+ opcode == sUnsupported ? "Unsupported" : "Deprecated",
+ keyword);
+ argv_consume(&ac);
break;
default:
fatal("%s line %d: Missing handler for opcode %s (%d)",
- filename, linenum, arg, opcode);
+ filename, linenum, keyword, opcode);
}
- if ((arg = strdelim(&cp)) != NULL && *arg != '\0')
- fatal("%s line %d: garbage at end of line; \"%.200s\".",
- filename, linenum, arg);
- return 0;
+ /* Check that there is no garbage at end of line. */
+ if (ac > 0) {
+ error("%.200s line %d: keyword %s extra arguments "
+ "at end of line", filename, linenum, keyword);
+ goto out;
+ }
+
+ /* success */
+ ret = 0;
+ out:
+ argv_free(oav, oac);
+ return ret;
}
+int
+process_server_config_line(ServerOptions *options, char *line,
+ const char *filename, int linenum, int *activep,
+ struct connection_info *connectinfo, struct include_list *includes)
+{
+ int inc_flags = 0;
+
+ return process_server_config_line_depth(options, line, filename,
+ linenum, activep, connectinfo, &inc_flags, 0, includes);
+}
+
+
/* Reads the server configuration file. */
void
load_server_config(const char *filename, struct sshbuf *conf)
{
+ struct stat st;
char *line = NULL, *cp;
size_t linesize = 0;
FILE *f;
int r, lineno = 0;
- debug2("%s: filename %s", __func__, filename);
+ debug2_f("filename %s", filename);
if ((f = fopen(filename, "r")) == NULL) {
perror(filename);
exit(1);
}
sshbuf_reset(conf);
+ /* grow buffer, so realloc is avoided for large config files */
+ if (fstat(fileno(f), &st) == 0 && st.st_size > 0 &&
+ (r = sshbuf_allocate(conf, st.st_size)) != 0)
+ fatal_fr(r, "allocate");
while (getline(&line, &linesize, f) != -1) {
lineno++;
/*
- * Trim out comments and strip whitespace
+ * Strip whitespace
* NB - preserve newlines, they are needed to reproduce
* line numbers later for error messages
*/
- if ((cp = strchr(line, '#')) != NULL)
- memcpy(cp, "\n", 2);
cp = line + strspn(line, " \t\r");
if ((r = sshbuf_put(conf, cp, strlen(cp))) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "sshbuf_put");
}
free(line);
if ((r = sshbuf_put_u8(conf, 0)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "sshbuf_put_u8");
fclose(f);
- debug2("%s: done config len = %zu", __func__, sshbuf_len(conf));
+ debug2_f("done config len = %zu", sshbuf_len(conf));
}
void
parse_server_match_config(ServerOptions *options,
- struct connection_info *connectinfo)
+ struct include_list *includes, struct connection_info *connectinfo)
{
ServerOptions mo;
initialize_server_options(&mo);
- parse_server_config(&mo, "reprocess config", cfg, connectinfo);
+ parse_server_config(&mo, "reprocess config", cfg, includes,
+ connectinfo);
copy_set_server_options(options, &mo, 0);
}
@@ -2260,12 +2569,12 @@ int parse_server_match_testspec(struct connection_info *ci, char *spec)
ci->lport = a2port(p + 6);
if (ci->lport == -1) {
fprintf(stderr, "Invalid port '%s' in test mode"
- " specification %s\n", p+6, p);
+ " specification %s\n", p+6, p);
return -1;
}
} else {
fprintf(stderr, "Invalid test mode specification %s\n",
- p);
+ p);
return -1;
}
}
@@ -2290,12 +2599,14 @@ copy_set_server_options(ServerOptions *dst, ServerOptions *src, int preauth)
M_CP_INTOPT(password_authentication);
M_CP_INTOPT(gss_authentication);
M_CP_INTOPT(pubkey_authentication);
+ M_CP_INTOPT(pubkey_auth_options);
M_CP_INTOPT(kerberos_authentication);
M_CP_INTOPT(hostbased_authentication);
M_CP_INTOPT(hostbased_uses_name_from_packet_only);
M_CP_INTOPT(kbd_interactive_authentication);
M_CP_INTOPT(permit_root_login);
M_CP_INTOPT(permit_empty_passwd);
+ M_CP_INTOPT(ignore_rhosts);
M_CP_INTOPT(allow_tcp_forwarding);
M_CP_INTOPT(allow_streamlocal_forwarding);
@@ -2380,28 +2691,44 @@ copy_set_server_options(ServerOptions *dst, ServerOptions *src, int preauth)
#undef M_CP_STROPT
#undef M_CP_STRARRAYOPT
-void
-parse_server_config(ServerOptions *options, const char *filename,
- struct sshbuf *conf, struct connection_info *connectinfo)
+#define SERVCONF_MAX_DEPTH 16
+static void
+parse_server_config_depth(ServerOptions *options, const char *filename,
+ struct sshbuf *conf, struct include_list *includes,
+ struct connection_info *connectinfo, int flags, int *activep, int depth)
{
- int active, linenum, bad_options = 0;
+ int linenum, bad_options = 0;
char *cp, *obuf, *cbuf;
- debug2("%s: config %s len %zu", __func__, filename, sshbuf_len(conf));
+ if (depth < 0 || depth > SERVCONF_MAX_DEPTH)
+ fatal("Too many recursive configuration includes");
+
+ debug2_f("config %s len %zu%s", filename, sshbuf_len(conf),
+ (flags & SSHCFG_NEVERMATCH ? " [checking syntax only]" : ""));
if ((obuf = cbuf = sshbuf_dup_string(conf)) == NULL)
- fatal("%s: sshbuf_dup_string failed", __func__);
- active = connectinfo ? 0 : 1;
+ fatal_f("sshbuf_dup_string failed");
linenum = 1;
while ((cp = strsep(&cbuf, "\n")) != NULL) {
- if (process_server_config_line(options, cp, filename,
- linenum++, &active, connectinfo) != 0)
+ if (process_server_config_line_depth(options, cp,
+ filename, linenum++, activep, connectinfo, &flags,
+ depth, includes) != 0)
bad_options++;
}
free(obuf);
if (bad_options > 0)
fatal("%s: terminating, %d bad configuration options",
filename, bad_options);
+}
+
+void
+parse_server_config(ServerOptions *options, const char *filename,
+ struct sshbuf *conf, struct include_list *includes,
+ struct connection_info *connectinfo)
+{
+ int active = connectinfo ? 0 : 1;
+ parse_server_config_depth(options, filename, conf, includes,
+ connectinfo, (connectinfo ? SSHCFG_MATCH_ONLY : 0), &active, 0);
process_queued_listen_addrs(options);
}
@@ -2435,6 +2762,8 @@ fmt_intarg(ServerOpCodes code, int val)
return fmt_multistate_int(val, multistate_tcpfwd);
case sAllowStreamLocalForwarding:
return fmt_multistate_int(val, multistate_tcpfwd);
+ case sIgnoreRhosts:
+ return fmt_multistate_int(val, multistate_ignore_rhosts);
case sFingerprintHash:
return ssh_digest_alg_name(val);
default:
@@ -2589,8 +2918,6 @@ dump_config(ServerOptions *o)
dump_cfg_fmtint(sPasswordAuthentication, o->password_authentication);
dump_cfg_fmtint(sKbdInteractiveAuthentication,
o->kbd_interactive_authentication);
- dump_cfg_fmtint(sChallengeResponseAuthentication,
- o->challenge_response_authentication);
dump_cfg_fmtint(sPrintMotd, o->print_motd);
#ifndef DISABLE_LASTLOG
dump_cfg_fmtint(sPrintLastLog, o->print_lastlog);
@@ -2616,14 +2943,16 @@ dump_config(ServerOptions *o)
/* string arguments */
dump_cfg_string(sPidFile, o->pid_file);
+ dump_cfg_string(sModuliFile, o->moduli_file);
dump_cfg_string(sXAuthLocation, o->xauth_location);
- dump_cfg_string(sCiphers, o->ciphers ? o->ciphers : KEX_SERVER_ENCRYPT);
- dump_cfg_string(sMacs, o->macs ? o->macs : KEX_SERVER_MAC);
+ dump_cfg_string(sCiphers, o->ciphers);
+ dump_cfg_string(sMacs, o->macs);
dump_cfg_string(sBanner, o->banner);
dump_cfg_string(sForceCommand, o->adm_forced_command);
dump_cfg_string(sChrootDirectory, o->chroot_directory);
dump_cfg_string(sTrustedUserCAKeys, o->trusted_user_ca_keys);
dump_cfg_string(sRevokedKeys, o->revoked_keys_file);
+ dump_cfg_string(sSecurityKeyProvider, o->sk_provider);
dump_cfg_string(sAuthorizedPrincipalsFile,
o->authorized_principals_file);
dump_cfg_string(sVersionAddendum, *o->version_addendum == '\0'
@@ -2633,17 +2962,14 @@ dump_config(ServerOptions *o)
dump_cfg_string(sAuthorizedPrincipalsCommand, o->authorized_principals_command);
dump_cfg_string(sAuthorizedPrincipalsCommandUser, o->authorized_principals_command_user);
dump_cfg_string(sHostKeyAgent, o->host_key_agent);
- dump_cfg_string(sKexAlgorithms,
- o->kex_algorithms ? o->kex_algorithms : KEX_SERVER_KEX);
- dump_cfg_string(sCASignatureAlgorithms, o->ca_sign_algorithms ?
- o->ca_sign_algorithms : SSH_ALLOWED_CA_SIGALGS);
- dump_cfg_string(sHostbasedAcceptedKeyTypes, o->hostbased_key_types ?
- o->hostbased_key_types : KEX_DEFAULT_PK_ALG);
- dump_cfg_string(sHostKeyAlgorithms, o->hostkeyalgorithms ?
- o->hostkeyalgorithms : KEX_DEFAULT_PK_ALG);
- dump_cfg_string(sPubkeyAcceptedKeyTypes, o->pubkey_key_types ?
- o->pubkey_key_types : KEX_DEFAULT_PK_ALG);
+ dump_cfg_string(sKexAlgorithms, o->kex_algorithms);
+ dump_cfg_string(sCASignatureAlgorithms, o->ca_sign_algorithms);
+ dump_cfg_string(sHostbasedAcceptedAlgorithms, o->hostbased_accepted_algos);
+ dump_cfg_string(sHostKeyAlgorithms, o->hostkeyalgorithms);
+ dump_cfg_string(sPubkeyAcceptedAlgorithms, o->pubkey_accepted_algos);
+#if defined(__OpenBSD__) || defined(HAVE_SYS_SET_PROCESS_RDOMAIN)
dump_cfg_string(sRDomain, o->routing_domain);
+#endif
/* string arguments requiring a lookup */
dump_cfg_string(sLogLevel, log_level_name(o->log_level));
@@ -2653,9 +2979,9 @@ dump_config(ServerOptions *o)
dump_cfg_strarray_oneline(sAuthorizedKeysFile, o->num_authkeys_files,
o->authorized_keys_files);
dump_cfg_strarray(sHostKeyFile, o->num_host_key_files,
- o->host_key_files);
+ o->host_key_files);
dump_cfg_strarray(sHostCertificate, o->num_host_cert_files,
- o->host_cert_files);
+ o->host_cert_files);
dump_cfg_strarray(sAllowUsers, o->num_allow_users, o->allow_users);
dump_cfg_strarray(sDenyUsers, o->num_deny_users, o->deny_users);
dump_cfg_strarray(sAllowGroups, o->num_allow_groups, o->allow_groups);
@@ -2664,6 +2990,8 @@ dump_config(ServerOptions *o)
dump_cfg_strarray(sSetEnv, o->num_setenv, o->setenv);
dump_cfg_strarray_oneline(sAuthenticationMethods,
o->num_auth_methods, o->auth_methods);
+ dump_cfg_strarray_oneline(sLogVerbose,
+ o->num_log_verbose, o->log_verbose);
/* other arguments */
for (i = 0; i < o->num_subsystems; i++)
@@ -2672,6 +3000,13 @@ dump_config(ServerOptions *o)
printf("maxstartups %d:%d:%d\n", o->max_startups_begin,
o->max_startups_rate, o->max_startups);
+ printf("persourcemaxstartups ");
+ if (o->per_source_max_startups == INT_MAX)
+ printf("none\n");
+ else
+ printf("%d\n", o->per_source_max_startups);
+ printf("persourcenetblocksize %d:%d\n", o->per_source_masklen_ipv4,
+ o->per_source_masklen_ipv6);
s = NULL;
for (i = 0; tunmode_desc[i].val != -1; i++) {
@@ -2705,11 +3040,19 @@ dump_config(ServerOptions *o)
}
printf("\n");
- if (o->permit_user_env_whitelist == NULL) {
+ if (o->permit_user_env_allowlist == NULL) {
dump_cfg_fmtint(sPermitUserEnvironment, o->permit_user_env);
} else {
printf("permituserenvironment %s\n",
- o->permit_user_env_whitelist);
+ o->permit_user_env_allowlist);
}
+ printf("pubkeyauthoptions");
+ if (o->pubkey_auth_options == 0)
+ printf(" none");
+ if (o->pubkey_auth_options & PUBKEYAUTH_TOUCH_REQUIRED)
+ printf(" touch-required");
+ if (o->pubkey_auth_options & PUBKEYAUTH_VERIFY_REQUIRED)
+ printf(" verify-required");
+ printf("\n");
}
diff --git a/crypto/openssh/servconf.h b/crypto/openssh/servconf.h
index 10cad3c8261e..6094e85d99ca 100644
--- a/crypto/openssh/servconf.h
+++ b/crypto/openssh/servconf.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: servconf.h,v 1.137 2018/09/20 03:28:06 djm Exp $ */
+/* $OpenBSD: servconf.h,v 1.155 2021/07/02 05:11:21 dtucker Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -16,6 +16,8 @@
#ifndef SERVCONF_H
#define SERVCONF_H
+#include <openbsd-compat/sys-queue.h>
+
#define MAX_PORTS 256 /* Max # ports. */
#define MAX_SUBSYSTEMS 256 /* Max # subsystems. */
@@ -36,12 +38,21 @@
#define PERMITOPEN_ANY 0
#define PERMITOPEN_NONE -2
+/* IgnoreRhosts */
+#define IGNORE_RHOSTS_NO 0
+#define IGNORE_RHOSTS_YES 1
+#define IGNORE_RHOSTS_SHOSTS 2
+
#define DEFAULT_AUTH_FAIL_MAX 6 /* Default for MaxAuthTries */
#define DEFAULT_SESSIONS_MAX 10 /* Default for MaxSessions */
/* Magic name for internal sftp-server */
#define INTERNAL_SFTP_NAME "internal-sftp"
+/* PubkeyAuthOptions flags */
+#define PUBKEYAUTH_TOUCH_REQUIRED (1)
+#define PUBKEYAUTH_VERIFY_REQUIRED (1<<1)
+
struct ssh;
struct fwd_perm_list;
@@ -75,12 +86,14 @@ typedef struct {
char *routing_domain; /* Bind session to routing domain */
char **host_key_files; /* Files containing host keys. */
+ int *host_key_file_userprovided; /* Key was specified by user. */
u_int num_host_key_files; /* Number of files for host keys. */
char **host_cert_files; /* Files containing host certs. */
u_int num_host_cert_files; /* Number of files for host certs. */
char *host_key_agent; /* ssh-agent socket for host keys. */
char *pid_file; /* Where to put our pid */
+ char *moduli_file; /* moduli file for DH-GEX */
int login_grace_time; /* Disconnect if no auth in this time
* (sec). */
int permit_root_login; /* PERMIT_*, see above */
@@ -106,13 +119,16 @@ typedef struct {
struct ForwardOptions fwd_opts; /* forwarding options */
SyslogFacility log_facility; /* Facility for system logging. */
LogLevel log_level; /* Level for system logging. */
+ u_int num_log_verbose; /* Verbose log overrides */
+ char **log_verbose;
int hostbased_authentication; /* If true, permit ssh2 hostbased auth */
int hostbased_uses_name_from_packet_only; /* experimental */
- char *hostbased_key_types; /* Key types allowed for hostbased */
+ char *hostbased_accepted_algos; /* Algos allowed for hostbased */
char *hostkeyalgorithms; /* SSH2 server key types */
char *ca_sign_algorithms; /* Allowed CA signature algorithms */
int pubkey_authentication; /* If true, permit ssh2 pubkey authentication. */
- char *pubkey_key_types; /* Key types allowed for public key */
+ char *pubkey_accepted_algos; /* Signature algos allowed for pubkey */
+ int pubkey_auth_options; /* -1 or mask of PUBKEYAUTH_* flags */
int kerberos_authentication; /* If true, permit Kerberos
* authentication. */
int kerberos_or_local_passwd; /* If true, permit kerberos
@@ -130,11 +146,10 @@ typedef struct {
int password_authentication; /* If true, permit password
* authentication. */
int kbd_interactive_authentication; /* If true, permit */
- int challenge_response_authentication;
int permit_empty_passwd; /* If false, do not permit empty
* passwords. */
int permit_user_env; /* If true, read ~/.ssh/environment */
- char *permit_user_env_whitelist; /* pattern-list whitelist */
+ char *permit_user_env_allowlist; /* pattern-list of allowed env names */
int compression; /* If true, compression is allowed */
int allow_tcp_forwarding; /* One of FORWARD_* */
int allow_streamlocal_forwarding; /* One of FORWARD_* */
@@ -162,6 +177,9 @@ typedef struct {
int max_startups_begin;
int max_startups_rate;
int max_startups;
+ int per_source_max_startups;
+ int per_source_masklen_ipv4;
+ int per_source_masklen_ipv6;
int max_authtries;
int max_sessions;
char *banner; /* SSH-2 banner message */
@@ -210,6 +228,7 @@ typedef struct {
int fingerprint_hash;
int expose_userauth_info;
u_int64_t timing_secret;
+ char *sk_provider;
int use_blacklist;
} ServerOptions;
@@ -217,17 +236,28 @@ typedef struct {
struct connection_info {
const char *user;
const char *host; /* possibly resolved hostname */
- const char *address; /* remote address */
+ const char *address; /* remote address */
const char *laddress; /* local address */
int lport; /* local port */
const char *rdomain; /* routing domain if available */
+ int test; /* test mode, allow some attributes to be
+ * unspecified */
};
+/* List of included files for re-exec from the parsed configuration */
+struct include_item {
+ char *selector;
+ char *filename;
+ struct sshbuf *contents;
+ TAILQ_ENTRY(include_item) entry;
+};
+TAILQ_HEAD(include_list, include_item);
+
/*
* These are string config options that must be copied between the
* Match sub-config and the main config, and must be sent from the
- * privsep slave to the privsep master. We use a macro to ensure all
+ * privsep child to the privsep master. We use a macro to ensure all
* the options are copied and the copies are done in the correct order.
*
* NB. an option must appear in servconf.c:copy_set_server_options() or
@@ -242,39 +272,42 @@ struct connection_info {
M_CP_STROPT(authorized_principals_file); \
M_CP_STROPT(authorized_principals_command); \
M_CP_STROPT(authorized_principals_command_user); \
- M_CP_STROPT(hostbased_key_types); \
- M_CP_STROPT(pubkey_key_types); \
+ M_CP_STROPT(hostbased_accepted_algos); \
+ M_CP_STROPT(pubkey_accepted_algos); \
M_CP_STROPT(ca_sign_algorithms); \
M_CP_STROPT(routing_domain); \
- M_CP_STROPT(permit_user_env_whitelist); \
+ M_CP_STROPT(permit_user_env_allowlist); \
M_CP_STRARRAYOPT(authorized_keys_files, num_authkeys_files); \
M_CP_STRARRAYOPT(allow_users, num_allow_users); \
M_CP_STRARRAYOPT(deny_users, num_deny_users); \
M_CP_STRARRAYOPT(allow_groups, num_allow_groups); \
M_CP_STRARRAYOPT(deny_groups, num_deny_groups); \
M_CP_STRARRAYOPT(accept_env, num_accept_env); \
+ M_CP_STRARRAYOPT(setenv, num_setenv); \
M_CP_STRARRAYOPT(auth_methods, num_auth_methods); \
M_CP_STRARRAYOPT(permitted_opens, num_permitted_opens); \
M_CP_STRARRAYOPT(permitted_listens, num_permitted_listens); \
+ M_CP_STRARRAYOPT(log_verbose, num_log_verbose); \
} while (0)
-struct connection_info *get_connection_info(int, int);
+struct connection_info *get_connection_info(struct ssh *, int, int);
void initialize_server_options(ServerOptions *);
void fill_default_server_options(ServerOptions *);
int process_server_config_line(ServerOptions *, char *, const char *, int,
- int *, struct connection_info *);
+ int *, struct connection_info *, struct include_list *includes);
void process_permitopen(struct ssh *ssh, ServerOptions *options);
void load_server_config(const char *, struct sshbuf *);
void parse_server_config(ServerOptions *, const char *, struct sshbuf *,
- struct connection_info *);
-void parse_server_match_config(ServerOptions *, struct connection_info *);
+ struct include_list *includes, struct connection_info *);
+void parse_server_match_config(ServerOptions *,
+ struct include_list *includes, struct connection_info *);
int parse_server_match_testspec(struct connection_info *, char *);
int server_match_spec_complete(struct connection_info *);
void copy_set_server_options(ServerOptions *, ServerOptions *, int);
void dump_config(ServerOptions *);
char *derelativise_path(const char *);
void servconf_add_hostkey(const char *, const int,
- ServerOptions *, const char *path);
+ ServerOptions *, const char *path, int);
void servconf_add_hostcert(const char *, const int,
ServerOptions *, const char *path);
diff --git a/crypto/openssh/serverloop.c b/crypto/openssh/serverloop.c
index 7be83e2d338a..e8cfb9205a48 100644
--- a/crypto/openssh/serverloop.c
+++ b/crypto/openssh/serverloop.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: serverloop.c,v 1.209 2018/07/27 05:13:02 dtucker Exp $ */
+/* $OpenBSD: serverloop.c,v 1.228 2021/07/16 09:00:23 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -49,6 +49,7 @@
#include <errno.h>
#include <fcntl.h>
#include <pwd.h>
+#include <limits.h>
#include <signal.h>
#include <string.h>
#include <termios.h>
@@ -87,18 +88,13 @@ extern int use_privsep;
static int no_more_sessions = 0; /* Disallow further sessions. */
-/*
- * This SIGCHLD kludge is used to detect when the child exits. The server
- * will exit after that, as soon as forwarded connections have terminated.
- */
-
static volatile sig_atomic_t child_terminated = 0; /* The child has terminated. */
/* Cleanup on signals (!use_privsep case only) */
static volatile sig_atomic_t received_sigterm = 0;
/* prototypes */
-static void server_init_dispatch(void);
+static void server_init_dispatch(struct ssh *);
/* requested tunnel forwarding interface(s), shared with session.c */
char *tun_fwd_ifnames = NULL;
@@ -114,59 +110,11 @@ bind_permitted(int port, uid_t uid)
return 1;
}
-/*
- * we write to this pipe if a SIGCHLD is caught in order to avoid
- * the race between select() and child_terminated
- */
-static int notify_pipe[2];
-static void
-notify_setup(void)
-{
- if (pipe(notify_pipe) < 0) {
- error("pipe(notify_pipe) failed %s", strerror(errno));
- } else if ((fcntl(notify_pipe[0], F_SETFD, FD_CLOEXEC) == -1) ||
- (fcntl(notify_pipe[1], F_SETFD, FD_CLOEXEC) == -1)) {
- error("fcntl(notify_pipe, F_SETFD) failed %s", strerror(errno));
- close(notify_pipe[0]);
- close(notify_pipe[1]);
- } else {
- set_nonblock(notify_pipe[0]);
- set_nonblock(notify_pipe[1]);
- return;
- }
- notify_pipe[0] = -1; /* read end */
- notify_pipe[1] = -1; /* write end */
-}
-static void
-notify_parent(void)
-{
- if (notify_pipe[1] != -1)
- (void)write(notify_pipe[1], "", 1);
-}
-static void
-notify_prepare(fd_set *readset)
-{
- if (notify_pipe[0] != -1)
- FD_SET(notify_pipe[0], readset);
-}
-static void
-notify_done(fd_set *readset)
-{
- char c;
-
- if (notify_pipe[0] != -1 && FD_ISSET(notify_pipe[0], readset))
- while (read(notify_pipe[0], &c, 1) != -1)
- debug2("%s: reading", __func__);
-}
-
/*ARGSUSED*/
static void
sigchld_handler(int sig)
{
- int save_errno = errno;
child_terminated = 1;
- notify_parent();
- errno = save_errno;
}
/*ARGSUSED*/
@@ -179,11 +127,13 @@ sigterm_handler(int sig)
static void
client_alive_check(struct ssh *ssh)
{
- int channel_id;
char remote_id[512];
+ int r, channel_id;
/* timeout, check to see how many we have had */
- if (packet_inc_alive_timeouts() > options.client_alive_count_max) {
+ if (options.client_alive_count_max > 0 &&
+ ssh_packet_inc_alive_timeouts(ssh) >
+ options.client_alive_count_max) {
sshpkt_fmt_connection_id(ssh, remote_id, sizeof(remote_id));
logit("Timeout, client not responding from %s", remote_id);
cleanup_exit(255);
@@ -194,19 +144,22 @@ client_alive_check(struct ssh *ssh)
* we should get back a failure
*/
if ((channel_id = channel_find_open(ssh)) == -1) {
- packet_start(SSH2_MSG_GLOBAL_REQUEST);
- packet_put_cstring("keepalive@openssh.com");
- packet_put_char(1); /* boolean: want reply */
+ if ((r = sshpkt_start(ssh, SSH2_MSG_GLOBAL_REQUEST)) != 0 ||
+ (r = sshpkt_put_cstring(ssh, "keepalive@openssh.com"))
+ != 0 ||
+ (r = sshpkt_put_u8(ssh, 1)) != 0) /* boolean: want reply */
+ fatal_fr(r, "compose");
} else {
channel_request_start(ssh, channel_id,
"keepalive@openssh.com", 1);
}
- packet_send();
+ if ((r = sshpkt_send(ssh)) != 0)
+ fatal_fr(r, "send");
}
/*
- * Sleep in select() until we can do something. This will initialize the
- * select masks. Upon return, the masks will indicate which descriptors
+ * Sleep in pselect() until we can do something. This will initialize the
+ * pselect masks. Upon return, the masks will indicate which descriptors
* have data or can accept data. Optionally, a maximum time can be specified
* for the duration of the wait (0 = infinite).
*/
@@ -214,15 +167,16 @@ static void
wait_until_can_do_something(struct ssh *ssh,
int connection_in, int connection_out,
fd_set **readsetp, fd_set **writesetp, int *maxfdp,
- u_int *nallocp, u_int64_t max_time_ms)
+ u_int *nallocp, u_int64_t max_time_ms, sigset_t *sigsetp)
{
- struct timeval tv, *tvp;
+ struct timespec ts, *tsp;
int ret;
time_t minwait_secs = 0;
int client_alive_scheduled = 0;
+ /* time we last heard from the client OR sent a keepalive */
static time_t last_client_time;
- /* Allocate and update select() masks for channel descriptors. */
+ /* Allocate and update pselect() masks for channel descriptors. */
channel_prepare_select(ssh, readsetp, writesetp, maxfdp,
nallocp, &minwait_secs);
@@ -242,9 +196,12 @@ wait_until_can_do_something(struct ssh *ssh,
uint64_t keepalive_ms =
(uint64_t)options.client_alive_interval * 1000;
- client_alive_scheduled = 1;
- if (max_time_ms == 0 || max_time_ms > keepalive_ms)
+ if (max_time_ms == 0 || max_time_ms > keepalive_ms) {
max_time_ms = keepalive_ms;
+ client_alive_scheduled = 1;
+ }
+ if (last_client_time == 0)
+ last_client_time = monotime();
}
#if 0
@@ -252,54 +209,53 @@ wait_until_can_do_something(struct ssh *ssh,
if (channel_not_very_much_buffered_data())
#endif
FD_SET(connection_in, *readsetp);
- notify_prepare(*readsetp);
/*
* If we have buffered packet data going to the client, mark that
* descriptor.
*/
- if (packet_have_data_to_write())
+ if (ssh_packet_have_data_to_write(ssh))
FD_SET(connection_out, *writesetp);
/*
* If child has terminated and there is enough buffer space to read
* from it, then read as much as is available and exit.
*/
- if (child_terminated && packet_not_very_much_data_to_write())
+ if (child_terminated && ssh_packet_not_very_much_data_to_write(ssh))
if (max_time_ms == 0 || client_alive_scheduled)
max_time_ms = 100;
if (max_time_ms == 0)
- tvp = NULL;
+ tsp = NULL;
else {
- tv.tv_sec = max_time_ms / 1000;
- tv.tv_usec = 1000 * (max_time_ms % 1000);
- tvp = &tv;
+ ts.tv_sec = max_time_ms / 1000;
+ ts.tv_nsec = 1000000 * (max_time_ms % 1000);
+ tsp = &ts;
}
/* Wait for something to happen, or the timeout to expire. */
- ret = select((*maxfdp)+1, *readsetp, *writesetp, NULL, tvp);
+ ret = pselect((*maxfdp)+1, *readsetp, *writesetp, NULL, tsp, sigsetp);
if (ret == -1) {
memset(*readsetp, 0, *nallocp);
memset(*writesetp, 0, *nallocp);
if (errno != EINTR)
- error("select: %.100s", strerror(errno));
+ error("pselect: %.100s", strerror(errno));
} else if (client_alive_scheduled) {
time_t now = monotime();
- if (ret == 0) { /* timeout */
+ /*
+ * If the pselect timed out, or returned for some other reason
+ * but we haven't heard from the client in time, send keepalive.
+ */
+ if (ret == 0 || (last_client_time != 0 && last_client_time +
+ options.client_alive_interval <= now)) {
client_alive_check(ssh);
- } else if (FD_ISSET(connection_in, *readsetp)) {
last_client_time = now;
- } else if (last_client_time != 0 && last_client_time +
- options.client_alive_interval <= now) {
- client_alive_check(ssh);
+ } else if (FD_ISSET(connection_in, *readsetp)) {
last_client_time = now;
}
}
-
- notify_done(*readsetp);
}
/*
@@ -309,7 +265,7 @@ wait_until_can_do_something(struct ssh *ssh,
static int
process_input(struct ssh *ssh, fd_set *readset, int connection_in)
{
- int len;
+ int r, len;
char buf[16384];
/* Read and buffer any input data from the client. */
@@ -319,19 +275,18 @@ process_input(struct ssh *ssh, fd_set *readset, int connection_in)
verbose("Connection closed by %.100s port %d",
ssh_remote_ipaddr(ssh), ssh_remote_port(ssh));
return -1;
- } else if (len < 0) {
- if (errno != EINTR && errno != EAGAIN &&
- errno != EWOULDBLOCK) {
- verbose("Read error from remote host "
- "%.100s port %d: %.100s",
- ssh_remote_ipaddr(ssh),
- ssh_remote_port(ssh), strerror(errno));
- cleanup_exit(255);
- }
- } else {
- /* Buffer any received data. */
- packet_process_incoming(buf, len);
+ } else if (len == -1) {
+ if (errno == EINTR || errno == EAGAIN ||
+ errno == EWOULDBLOCK)
+ return 0;
+ verbose("Read error from remote host %s port %d: %s",
+ ssh_remote_ipaddr(ssh), ssh_remote_port(ssh),
+ strerror(errno));
+ cleanup_exit(255);
}
+ /* Buffer any received data. */
+ if ((r = ssh_packet_process_incoming(ssh, buf, len)) != 0)
+ fatal_fr(r, "ssh_packet_process_incoming");
}
return 0;
}
@@ -340,11 +295,17 @@ process_input(struct ssh *ssh, fd_set *readset, int connection_in)
* Sends data from internal buffers to client program stdin.
*/
static void
-process_output(fd_set *writeset, int connection_out)
+process_output(struct ssh *ssh, fd_set *writeset, int connection_out)
{
+ int r;
+
/* Send any buffered packet data to the client. */
- if (FD_ISSET(connection_out, writeset))
- packet_write_poll();
+ if (FD_ISSET(connection_out, writeset)) {
+ if ((r = ssh_packet_write_poll(ssh)) != 0) {
+ sshpkt_fatal(ssh, r, "%s: ssh_packet_write_poll",
+ __func__);
+ }
+ }
}
static void
@@ -357,65 +318,73 @@ static void
collect_children(struct ssh *ssh)
{
pid_t pid;
- sigset_t oset, nset;
int status;
- /* block SIGCHLD while we check for dead children */
- sigemptyset(&nset);
- sigaddset(&nset, SIGCHLD);
- sigprocmask(SIG_BLOCK, &nset, &oset);
if (child_terminated) {
debug("Received SIGCHLD.");
while ((pid = waitpid(-1, &status, WNOHANG)) > 0 ||
- (pid < 0 && errno == EINTR))
+ (pid == -1 && errno == EINTR))
if (pid > 0)
session_close_by_pid(ssh, pid, status);
child_terminated = 0;
}
- sigprocmask(SIG_SETMASK, &oset, NULL);
}
void
server_loop2(struct ssh *ssh, Authctxt *authctxt)
{
fd_set *readset = NULL, *writeset = NULL;
- int max_fd;
+ int r, max_fd;
u_int nalloc = 0, connection_in, connection_out;
u_int64_t rekey_timeout_ms = 0;
+ sigset_t bsigset, osigset;
debug("Entering interactive session for SSH2.");
- signal(SIGCHLD, sigchld_handler);
+ if (sigemptyset(&bsigset) == -1 || sigaddset(&bsigset, SIGCHLD) == -1)
+ error_f("bsigset setup: %s", strerror(errno));
+ ssh_signal(SIGCHLD, sigchld_handler);
child_terminated = 0;
- connection_in = packet_get_connection_in();
- connection_out = packet_get_connection_out();
+ connection_in = ssh_packet_get_connection_in(ssh);
+ connection_out = ssh_packet_get_connection_out(ssh);
if (!use_privsep) {
- signal(SIGTERM, sigterm_handler);
- signal(SIGINT, sigterm_handler);
- signal(SIGQUIT, sigterm_handler);
+ ssh_signal(SIGTERM, sigterm_handler);
+ ssh_signal(SIGINT, sigterm_handler);
+ ssh_signal(SIGQUIT, sigterm_handler);
}
- notify_setup();
-
max_fd = MAXIMUM(connection_in, connection_out);
- max_fd = MAXIMUM(max_fd, notify_pipe[0]);
- server_init_dispatch();
+ server_init_dispatch(ssh);
for (;;) {
process_buffered_input_packets(ssh);
if (!ssh_packet_is_rekeying(ssh) &&
- packet_not_very_much_data_to_write())
+ ssh_packet_not_very_much_data_to_write(ssh))
channel_output_poll(ssh);
- if (options.rekey_interval > 0 && !ssh_packet_is_rekeying(ssh))
- rekey_timeout_ms = packet_get_rekey_timeout() * 1000;
- else
+ if (options.rekey_interval > 0 &&
+ !ssh_packet_is_rekeying(ssh)) {
+ rekey_timeout_ms = ssh_packet_get_rekey_timeout(ssh) *
+ 1000;
+ } else {
rekey_timeout_ms = 0;
+ }
+ /*
+ * Block SIGCHLD while we check for dead children, then pass
+ * the old signal mask through to pselect() so that it'll wake
+ * up immediately if a child exits after we've called waitpid().
+ */
+ if (sigprocmask(SIG_BLOCK, &bsigset, &osigset) == -1)
+ error_f("bsigset sigprocmask: %s", strerror(errno));
+ collect_children(ssh);
wait_until_can_do_something(ssh, connection_in, connection_out,
- &readset, &writeset, &max_fd, &nalloc, rekey_timeout_ms);
+ &readset, &writeset, &max_fd, &nalloc, rekey_timeout_ms,
+ &osigset);
+ if (sigprocmask(SIG_UNBLOCK, &bsigset, &osigset) == -1)
+ error_f("osigset sigprocmask: %s", strerror(errno));
if (received_sigterm) {
logit("Exiting on signal %d", (int)received_sigterm);
@@ -423,12 +392,14 @@ server_loop2(struct ssh *ssh, Authctxt *authctxt)
cleanup_exit(255);
}
- collect_children(ssh);
if (!ssh_packet_is_rekeying(ssh))
channel_after_select(ssh, readset, writeset);
if (process_input(ssh, readset, connection_in) < 0)
break;
- process_output(writeset, connection_out);
+ /* A timeout may have triggered rekeying */
+ if ((r = ssh_packet_check_rekey(ssh)) != 0)
+ fatal_fr(r, "cannot start rekeying");
+ process_output(ssh, writeset, connection_out);
}
collect_children(ssh);
@@ -451,7 +422,7 @@ server_input_keep_alive(int type, u_int32_t seq, struct ssh *ssh)
* even if this was generated by something other than
* the bogus CHANNEL_REQUEST we send for keepalives.
*/
- packet_set_alive_timeouts(0);
+ ssh_packet_set_alive_timeouts(ssh, 0);
return 0;
}
@@ -459,16 +430,28 @@ static Channel *
server_request_direct_tcpip(struct ssh *ssh, int *reason, const char **errmsg)
{
Channel *c = NULL;
- char *target, *originator;
- u_short target_port, originator_port;
-
- target = packet_get_string(NULL);
- target_port = packet_get_int();
- originator = packet_get_string(NULL);
- originator_port = packet_get_int();
- packet_check_eom();
+ char *target = NULL, *originator = NULL;
+ u_int target_port = 0, originator_port = 0;
+ int r;
+
+ if ((r = sshpkt_get_cstring(ssh, &target, NULL)) != 0 ||
+ (r = sshpkt_get_u32(ssh, &target_port)) != 0 ||
+ (r = sshpkt_get_cstring(ssh, &originator, NULL)) != 0 ||
+ (r = sshpkt_get_u32(ssh, &originator_port)) != 0 ||
+ (r = sshpkt_get_end(ssh)) != 0)
+ sshpkt_fatal(ssh, r, "%s: parse packet", __func__);
+ if (target_port > 0xFFFF) {
+ error_f("invalid target port");
+ *reason = SSH2_OPEN_ADMINISTRATIVELY_PROHIBITED;
+ goto out;
+ }
+ if (originator_port > 0xFFFF) {
+ error_f("invalid originator port");
+ *reason = SSH2_OPEN_ADMINISTRATIVELY_PROHIBITED;
+ goto out;
+ }
- debug("%s: originator %s port %d, target %s port %d", __func__,
+ debug_f("originator %s port %u, target %s port %u",
originator, originator_port, target, target_port);
/* XXX fine grained permissions */
@@ -485,9 +468,9 @@ server_request_direct_tcpip(struct ssh *ssh, int *reason, const char **errmsg)
*reason = SSH2_OPEN_ADMINISTRATIVELY_PROHIBITED;
}
+ out:
free(originator);
free(target);
-
return c;
}
@@ -495,19 +478,25 @@ static Channel *
server_request_direct_streamlocal(struct ssh *ssh)
{
Channel *c = NULL;
- char *target, *originator;
- u_short originator_port;
+ char *target = NULL, *originator = NULL;
+ u_int originator_port = 0;
struct passwd *pw = the_authctxt->pw;
+ int r;
if (pw == NULL || !the_authctxt->valid)
- fatal("%s: no/invalid user", __func__);
-
- target = packet_get_string(NULL);
- originator = packet_get_string(NULL);
- originator_port = packet_get_int();
- packet_check_eom();
+ fatal_f("no/invalid user");
+
+ if ((r = sshpkt_get_cstring(ssh, &target, NULL)) != 0 ||
+ (r = sshpkt_get_cstring(ssh, &originator, NULL)) != 0 ||
+ (r = sshpkt_get_u32(ssh, &originator_port)) != 0 ||
+ (r = sshpkt_get_end(ssh)) != 0)
+ sshpkt_fatal(ssh, r, "%s: parse packet", __func__);
+ if (originator_port > 0xFFFF) {
+ error_f("invalid originator port");
+ goto out;
+ }
- debug("%s: originator %s port %d, target %s", __func__,
+ debug_f("originator %s port %d, target %s",
originator, originator_port, target);
/* XXX fine grained permissions */
@@ -522,9 +511,9 @@ server_request_direct_streamlocal(struct ssh *ssh)
originator, originator_port, target);
}
+out:
free(originator);
free(target);
-
return c;
}
@@ -532,27 +521,35 @@ static Channel *
server_request_tun(struct ssh *ssh)
{
Channel *c = NULL;
- int mode, tun, sock;
+ u_int mode, tun;
+ int r, sock;
char *tmp, *ifname = NULL;
- mode = packet_get_int();
+ if ((r = sshpkt_get_u32(ssh, &mode)) != 0)
+ sshpkt_fatal(ssh, r, "%s: parse mode", __func__);
switch (mode) {
case SSH_TUNMODE_POINTOPOINT:
case SSH_TUNMODE_ETHERNET:
break;
default:
- packet_send_debug("Unsupported tunnel device mode.");
+ ssh_packet_send_debug(ssh, "Unsupported tunnel device mode.");
return NULL;
}
if ((options.permit_tun & mode) == 0) {
- packet_send_debug("Server has rejected tunnel device "
+ ssh_packet_send_debug(ssh, "Server has rejected tunnel device "
"forwarding");
return NULL;
}
- tun = packet_get_int();
+ if ((r = sshpkt_get_u32(ssh, &tun)) != 0)
+ sshpkt_fatal(ssh, r, "%s: parse device", __func__);
+ if (tun > INT_MAX) {
+ debug_f("invalid tun");
+ goto done;
+ }
if (auth_opts->force_tun_device != -1) {
- if (tun != SSH_TUNID_ANY && auth_opts->force_tun_device != tun)
+ if (tun != SSH_TUNID_ANY &&
+ auth_opts->force_tun_device != (int)tun)
goto done;
tun = auth_opts->force_tun_device;
}
@@ -585,7 +582,7 @@ server_request_tun(struct ssh *ssh)
done:
if (c == NULL)
- packet_send_debug("Failed to open the tunnel device.");
+ ssh_packet_send_debug(ssh, "Failed to open the tunnel device.");
return c;
}
@@ -593,13 +590,15 @@ static Channel *
server_request_session(struct ssh *ssh)
{
Channel *c;
+ int r;
debug("input_session_request");
- packet_check_eom();
+ if ((r = sshpkt_get_end(ssh)) != 0)
+ sshpkt_fatal(ssh, r, "%s: parse packet", __func__);
if (no_more_sessions) {
- packet_disconnect("Possible attack: attempt to open a session "
- "after additional sessions disabled");
+ ssh_packet_disconnect(ssh, "Possible attack: attempt to open a "
+ "session after additional sessions disabled");
}
/*
@@ -624,17 +623,17 @@ static int
server_input_channel_open(int type, u_int32_t seq, struct ssh *ssh)
{
Channel *c = NULL;
- char *ctype;
+ char *ctype = NULL;
const char *errmsg = NULL;
- int rchan, reason = SSH2_OPEN_CONNECT_FAILED;
- u_int rmaxpack, rwindow, len;
-
- ctype = packet_get_string(&len);
- rchan = packet_get_int();
- rwindow = packet_get_int();
- rmaxpack = packet_get_int();
-
- debug("%s: ctype %s rchan %d win %d max %d", __func__,
+ int r, reason = SSH2_OPEN_CONNECT_FAILED;
+ u_int rchan = 0, rmaxpack = 0, rwindow = 0;
+
+ if ((r = sshpkt_get_cstring(ssh, &ctype, NULL)) != 0 ||
+ (r = sshpkt_get_u32(ssh, &rchan)) != 0 ||
+ (r = sshpkt_get_u32(ssh, &rwindow)) != 0 ||
+ (r = sshpkt_get_u32(ssh, &rmaxpack)) != 0)
+ sshpkt_fatal(ssh, r, "%s: parse packet", __func__);
+ debug_f("ctype %s rchan %u win %u max %u",
ctype, rchan, rwindow, rmaxpack);
if (strcmp(ctype, "session") == 0) {
@@ -647,27 +646,33 @@ server_input_channel_open(int type, u_int32_t seq, struct ssh *ssh)
c = server_request_tun(ssh);
}
if (c != NULL) {
- debug("%s: confirm %s", __func__, ctype);
+ debug_f("confirm %s", ctype);
c->remote_id = rchan;
c->have_remote_id = 1;
c->remote_window = rwindow;
c->remote_maxpacket = rmaxpack;
if (c->type != SSH_CHANNEL_CONNECTING) {
- packet_start(SSH2_MSG_CHANNEL_OPEN_CONFIRMATION);
- packet_put_int(c->remote_id);
- packet_put_int(c->self);
- packet_put_int(c->local_window);
- packet_put_int(c->local_maxpacket);
- packet_send();
+ if ((r = sshpkt_start(ssh, SSH2_MSG_CHANNEL_OPEN_CONFIRMATION)) != 0 ||
+ (r = sshpkt_put_u32(ssh, c->remote_id)) != 0 ||
+ (r = sshpkt_put_u32(ssh, c->self)) != 0 ||
+ (r = sshpkt_put_u32(ssh, c->local_window)) != 0 ||
+ (r = sshpkt_put_u32(ssh, c->local_maxpacket)) != 0 ||
+ (r = sshpkt_send(ssh)) != 0) {
+ sshpkt_fatal(ssh, r,
+ "%s: send open confirm", __func__);
+ }
}
} else {
- debug("%s: failure %s", __func__, ctype);
- packet_start(SSH2_MSG_CHANNEL_OPEN_FAILURE);
- packet_put_int(rchan);
- packet_put_int(reason);
- packet_put_cstring(errmsg ? errmsg : "open failed");
- packet_put_cstring("");
- packet_send();
+ debug_f("failure %s", ctype);
+ if ((r = sshpkt_start(ssh, SSH2_MSG_CHANNEL_OPEN_FAILURE)) != 0 ||
+ (r = sshpkt_put_u32(ssh, rchan)) != 0 ||
+ (r = sshpkt_put_u32(ssh, reason)) != 0 ||
+ (r = sshpkt_put_cstring(ssh, errmsg ? errmsg : "open failed")) != 0 ||
+ (r = sshpkt_put_cstring(ssh, "")) != 0 ||
+ (r = sshpkt_send(ssh)) != 0) {
+ sshpkt_fatal(ssh, r,
+ "%s: send open failure", __func__);
+ }
}
free(ctype);
return 0;
@@ -685,7 +690,7 @@ server_input_hostkeys_prove(struct ssh *ssh, struct sshbuf **respp)
size_t blen, slen;
if ((resp = sshbuf_new()) == NULL || (sigbuf = sshbuf_new()) == NULL)
- fatal("%s: sshbuf_new", __func__);
+ fatal_f("sshbuf_new");
kexsigtype = sshkey_type_plain(
sshkey_type_from_name(ssh->kex->hostkey_alg));
@@ -694,8 +699,7 @@ server_input_hostkeys_prove(struct ssh *ssh, struct sshbuf **respp)
key = NULL;
if ((r = sshpkt_get_string_direct(ssh, &blob, &blen)) != 0 ||
(r = sshkey_from_blob(blob, blen, &key)) != 0) {
- error("%s: couldn't parse key: %s",
- __func__, ssh_err(r));
+ error_fr(r, "parse key");
goto out;
}
/*
@@ -703,8 +707,7 @@ server_input_hostkeys_prove(struct ssh *ssh, struct sshbuf **respp)
* before attempting to sign anything with it.
*/
if ((ndx = ssh->kex->host_key_index(key, 1, ssh)) == -1) {
- error("%s: unknown host %s key",
- __func__, sshkey_type(key));
+ error_f("unknown host %s key", sshkey_type(key));
goto out;
}
/*
@@ -713,7 +716,7 @@ server_input_hostkeys_prove(struct ssh *ssh, struct sshbuf **respp)
*/
if ((key_prv = get_hostkey_by_index(ndx)) == NULL &&
(key_pub = get_hostkey_public_by_index(ndx, ssh)) == NULL) {
- error("%s: can't retrieve hostkey %d", __func__, ndx);
+ error_f("can't retrieve hostkey %d", ndx);
goto out;
}
sshbuf_reset(sigbuf);
@@ -727,15 +730,14 @@ server_input_hostkeys_prove(struct ssh *ssh, struct sshbuf **respp)
sshkey_type_plain(key->type) == KEY_RSA;
if ((r = sshbuf_put_cstring(sigbuf,
"hostkeys-prove-00@openssh.com")) != 0 ||
- (r = sshbuf_put_string(sigbuf,
- ssh->kex->session_id, ssh->kex->session_id_len)) != 0 ||
+ (r = sshbuf_put_stringb(sigbuf,
+ ssh->kex->session_id)) != 0 ||
(r = sshkey_puts(key, sigbuf)) != 0 ||
- (r = ssh->kex->sign(key_prv, key_pub, &sig, &slen,
+ (r = ssh->kex->sign(ssh, key_prv, key_pub, &sig, &slen,
sshbuf_ptr(sigbuf), sshbuf_len(sigbuf),
- use_kexsigtype ? ssh->kex->hostkey_alg : NULL, 0)) != 0 ||
+ use_kexsigtype ? ssh->kex->hostkey_alg : NULL)) != 0 ||
(r = sshbuf_put_string(resp, sig, slen)) != 0) {
- error("%s: couldn't prepare signature: %s",
- __func__, ssh_err(r));
+ error_fr(r, "assemble signature");
goto out;
}
}
@@ -754,66 +756,67 @@ server_input_hostkeys_prove(struct ssh *ssh, struct sshbuf **respp)
static int
server_input_global_request(int type, u_int32_t seq, struct ssh *ssh)
{
- char *rtype;
- int want_reply;
+ char *rtype = NULL;
+ u_char want_reply = 0;
int r, success = 0, allocated_listen_port = 0;
+ u_int port = 0;
struct sshbuf *resp = NULL;
struct passwd *pw = the_authctxt->pw;
+ struct Forward fwd;
+ memset(&fwd, 0, sizeof(fwd));
if (pw == NULL || !the_authctxt->valid)
- fatal("%s: no/invalid user", __func__);
+ fatal_f("no/invalid user");
- rtype = packet_get_string(NULL);
- want_reply = packet_get_char();
- debug("%s: rtype %s want_reply %d", __func__, rtype, want_reply);
+ if ((r = sshpkt_get_cstring(ssh, &rtype, NULL)) != 0 ||
+ (r = sshpkt_get_u8(ssh, &want_reply)) != 0)
+ sshpkt_fatal(ssh, r, "%s: parse packet", __func__);
+ debug_f("rtype %s want_reply %d", rtype, want_reply);
/* -R style forwarding */
if (strcmp(rtype, "tcpip-forward") == 0) {
- struct Forward fwd;
-
- memset(&fwd, 0, sizeof(fwd));
- fwd.listen_host = packet_get_string(NULL);
- fwd.listen_port = (u_short)packet_get_int();
- debug("%s: tcpip-forward listen %s port %d", __func__,
- fwd.listen_host, fwd.listen_port);
-
+ if ((r = sshpkt_get_cstring(ssh, &fwd.listen_host, NULL)) != 0 ||
+ (r = sshpkt_get_u32(ssh, &port)) != 0)
+ sshpkt_fatal(ssh, r, "%s: parse tcpip-forward", __func__);
+ debug_f("tcpip-forward listen %s port %u",
+ fwd.listen_host, port);
+ if (port <= INT_MAX)
+ fwd.listen_port = (int)port;
/* check permissions */
- if ((options.allow_tcp_forwarding & FORWARD_REMOTE) == 0 ||
+ if (port > INT_MAX ||
+ (options.allow_tcp_forwarding & FORWARD_REMOTE) == 0 ||
!auth_opts->permit_port_forwarding_flag ||
options.disable_forwarding ||
(!want_reply && fwd.listen_port == 0) ||
(fwd.listen_port != 0 &&
- !bind_permitted(fwd.listen_port, pw->pw_uid))) {
+ !bind_permitted(fwd.listen_port, pw->pw_uid))) {
success = 0;
- packet_send_debug("Server has disabled port forwarding.");
+ ssh_packet_send_debug(ssh, "Server has disabled port forwarding.");
} else {
/* Start listening on the port */
success = channel_setup_remote_fwd_listener(ssh, &fwd,
&allocated_listen_port, &options.fwd_opts);
}
- free(fwd.listen_host);
if ((resp = sshbuf_new()) == NULL)
- fatal("%s: sshbuf_new", __func__);
+ fatal_f("sshbuf_new");
if (allocated_listen_port != 0 &&
(r = sshbuf_put_u32(resp, allocated_listen_port)) != 0)
- fatal("%s: sshbuf_put_u32: %s", __func__, ssh_err(r));
+ fatal_fr(r, "sshbuf_put_u32");
} else if (strcmp(rtype, "cancel-tcpip-forward") == 0) {
- struct Forward fwd;
-
- memset(&fwd, 0, sizeof(fwd));
- fwd.listen_host = packet_get_string(NULL);
- fwd.listen_port = (u_short)packet_get_int();
- debug("%s: cancel-tcpip-forward addr %s port %d", __func__,
- fwd.listen_host, fwd.listen_port);
-
- success = channel_cancel_rport_listener(ssh, &fwd);
- free(fwd.listen_host);
+ if ((r = sshpkt_get_cstring(ssh, &fwd.listen_host, NULL)) != 0 ||
+ (r = sshpkt_get_u32(ssh, &port)) != 0)
+ sshpkt_fatal(ssh, r, "%s: parse cancel-tcpip-forward", __func__);
+
+ debug_f("cancel-tcpip-forward addr %s port %d",
+ fwd.listen_host, port);
+ if (port <= INT_MAX) {
+ fwd.listen_port = (int)port;
+ success = channel_cancel_rport_listener(ssh, &fwd);
+ }
} else if (strcmp(rtype, "streamlocal-forward@openssh.com") == 0) {
- struct Forward fwd;
-
- memset(&fwd, 0, sizeof(fwd));
- fwd.listen_path = packet_get_string(NULL);
- debug("%s: streamlocal-forward listen path %s", __func__,
+ if ((r = sshpkt_get_cstring(ssh, &fwd.listen_path, NULL)) != 0)
+ sshpkt_fatal(ssh, r, "%s: parse streamlocal-forward@openssh.com", __func__);
+ debug_f("streamlocal-forward listen path %s",
fwd.listen_path);
/* check permissions */
@@ -822,39 +825,37 @@ server_input_global_request(int type, u_int32_t seq, struct ssh *ssh)
options.disable_forwarding ||
(pw->pw_uid != 0 && !use_privsep)) {
success = 0;
- packet_send_debug("Server has disabled "
+ ssh_packet_send_debug(ssh, "Server has disabled "
"streamlocal forwarding.");
} else {
/* Start listening on the socket */
success = channel_setup_remote_fwd_listener(ssh,
&fwd, NULL, &options.fwd_opts);
}
- free(fwd.listen_path);
} else if (strcmp(rtype, "cancel-streamlocal-forward@openssh.com") == 0) {
- struct Forward fwd;
-
- memset(&fwd, 0, sizeof(fwd));
- fwd.listen_path = packet_get_string(NULL);
- debug("%s: cancel-streamlocal-forward path %s", __func__,
+ if ((r = sshpkt_get_cstring(ssh, &fwd.listen_path, NULL)) != 0)
+ sshpkt_fatal(ssh, r, "%s: parse cancel-streamlocal-forward@openssh.com", __func__);
+ debug_f("cancel-streamlocal-forward path %s",
fwd.listen_path);
success = channel_cancel_rport_listener(ssh, &fwd);
- free(fwd.listen_path);
} else if (strcmp(rtype, "no-more-sessions@openssh.com") == 0) {
no_more_sessions = 1;
success = 1;
} else if (strcmp(rtype, "hostkeys-prove-00@openssh.com") == 0) {
success = server_input_hostkeys_prove(ssh, &resp);
}
+ /* XXX sshpkt_get_end() */
if (want_reply) {
- packet_start(success ?
- SSH2_MSG_REQUEST_SUCCESS : SSH2_MSG_REQUEST_FAILURE);
- if (success && resp != NULL)
- ssh_packet_put_raw(ssh, sshbuf_ptr(resp),
- sshbuf_len(resp));
- packet_send();
- packet_write_wait();
+ if ((r = sshpkt_start(ssh, success ?
+ SSH2_MSG_REQUEST_SUCCESS : SSH2_MSG_REQUEST_FAILURE)) != 0 ||
+ (success && resp != NULL && (r = sshpkt_putb(ssh, resp)) != 0) ||
+ (r = sshpkt_send(ssh)) != 0 ||
+ (r = ssh_packet_write_wait(ssh)) != 0)
+ sshpkt_fatal(ssh, r, "%s: send reply", __func__);
}
+ free(fwd.listen_host);
+ free(fwd.listen_path);
free(rtype);
sshbuf_free(resp);
return 0;
@@ -864,58 +865,63 @@ static int
server_input_channel_req(int type, u_int32_t seq, struct ssh *ssh)
{
Channel *c;
- int id, reply, success = 0;
- char *rtype;
-
- id = packet_get_int();
- rtype = packet_get_string(NULL);
- reply = packet_get_char();
-
- debug("server_input_channel_req: channel %d request %s reply %d",
- id, rtype, reply);
-
- if ((c = channel_lookup(ssh, id)) == NULL)
- packet_disconnect("server_input_channel_req: "
- "unknown channel %d", id);
+ int r, success = 0;
+ char *rtype = NULL;
+ u_char want_reply = 0;
+ u_int id = 0;
+
+ if ((r = sshpkt_get_u32(ssh, &id)) != 0 ||
+ (r = sshpkt_get_cstring(ssh, &rtype, NULL)) != 0 ||
+ (r = sshpkt_get_u8(ssh, &want_reply)) != 0)
+ sshpkt_fatal(ssh, r, "%s: parse packet", __func__);
+
+ debug("server_input_channel_req: channel %u request %s reply %d",
+ id, rtype, want_reply);
+
+ if (id >= INT_MAX || (c = channel_lookup(ssh, (int)id)) == NULL) {
+ ssh_packet_disconnect(ssh, "%s: unknown channel %d",
+ __func__, id);
+ }
if (!strcmp(rtype, "eow@openssh.com")) {
- packet_check_eom();
+ if ((r = sshpkt_get_end(ssh)) != 0)
+ sshpkt_fatal(ssh, r, "%s: parse packet", __func__);
chan_rcvd_eow(ssh, c);
} else if ((c->type == SSH_CHANNEL_LARVAL ||
c->type == SSH_CHANNEL_OPEN) && strcmp(c->ctype, "session") == 0)
success = session_input_channel_req(ssh, c, rtype);
- if (reply && !(c->flags & CHAN_CLOSE_SENT)) {
+ if (want_reply && !(c->flags & CHAN_CLOSE_SENT)) {
if (!c->have_remote_id)
- fatal("%s: channel %d: no remote_id",
- __func__, c->self);
- packet_start(success ?
- SSH2_MSG_CHANNEL_SUCCESS : SSH2_MSG_CHANNEL_FAILURE);
- packet_put_int(c->remote_id);
- packet_send();
+ fatal_f("channel %d: no remote_id", c->self);
+ if ((r = sshpkt_start(ssh, success ?
+ SSH2_MSG_CHANNEL_SUCCESS : SSH2_MSG_CHANNEL_FAILURE)) != 0 ||
+ (r = sshpkt_put_u32(ssh, c->remote_id)) != 0 ||
+ (r = sshpkt_send(ssh)) != 0)
+ sshpkt_fatal(ssh, r, "%s: send reply", __func__);
}
free(rtype);
return 0;
}
static void
-server_init_dispatch(void)
+server_init_dispatch(struct ssh *ssh)
{
debug("server_init_dispatch");
- dispatch_init(&dispatch_protocol_error);
- dispatch_set(SSH2_MSG_CHANNEL_CLOSE, &channel_input_oclose);
- dispatch_set(SSH2_MSG_CHANNEL_DATA, &channel_input_data);
- dispatch_set(SSH2_MSG_CHANNEL_EOF, &channel_input_ieof);
- dispatch_set(SSH2_MSG_CHANNEL_EXTENDED_DATA, &channel_input_extended_data);
- dispatch_set(SSH2_MSG_CHANNEL_OPEN, &server_input_channel_open);
- dispatch_set(SSH2_MSG_CHANNEL_OPEN_CONFIRMATION, &channel_input_open_confirmation);
- dispatch_set(SSH2_MSG_CHANNEL_OPEN_FAILURE, &channel_input_open_failure);
- dispatch_set(SSH2_MSG_CHANNEL_REQUEST, &server_input_channel_req);
- dispatch_set(SSH2_MSG_CHANNEL_WINDOW_ADJUST, &channel_input_window_adjust);
- dispatch_set(SSH2_MSG_GLOBAL_REQUEST, &server_input_global_request);
+ ssh_dispatch_init(ssh, &dispatch_protocol_error);
+ ssh_dispatch_set(ssh, SSH2_MSG_CHANNEL_CLOSE, &channel_input_oclose);
+ ssh_dispatch_set(ssh, SSH2_MSG_CHANNEL_DATA, &channel_input_data);
+ ssh_dispatch_set(ssh, SSH2_MSG_CHANNEL_EOF, &channel_input_ieof);
+ ssh_dispatch_set(ssh, SSH2_MSG_CHANNEL_EXTENDED_DATA, &channel_input_extended_data);
+ ssh_dispatch_set(ssh, SSH2_MSG_CHANNEL_OPEN, &server_input_channel_open);
+ ssh_dispatch_set(ssh, SSH2_MSG_CHANNEL_OPEN_CONFIRMATION, &channel_input_open_confirmation);
+ ssh_dispatch_set(ssh, SSH2_MSG_CHANNEL_OPEN_FAILURE, &channel_input_open_failure);
+ ssh_dispatch_set(ssh, SSH2_MSG_CHANNEL_REQUEST, &server_input_channel_req);
+ ssh_dispatch_set(ssh, SSH2_MSG_CHANNEL_WINDOW_ADJUST, &channel_input_window_adjust);
+ ssh_dispatch_set(ssh, SSH2_MSG_GLOBAL_REQUEST, &server_input_global_request);
/* client_alive */
- dispatch_set(SSH2_MSG_CHANNEL_SUCCESS, &server_input_keep_alive);
- dispatch_set(SSH2_MSG_CHANNEL_FAILURE, &server_input_keep_alive);
- dispatch_set(SSH2_MSG_REQUEST_SUCCESS, &server_input_keep_alive);
- dispatch_set(SSH2_MSG_REQUEST_FAILURE, &server_input_keep_alive);
+ ssh_dispatch_set(ssh, SSH2_MSG_CHANNEL_SUCCESS, &server_input_keep_alive);
+ ssh_dispatch_set(ssh, SSH2_MSG_CHANNEL_FAILURE, &server_input_keep_alive);
+ ssh_dispatch_set(ssh, SSH2_MSG_REQUEST_SUCCESS, &server_input_keep_alive);
+ ssh_dispatch_set(ssh, SSH2_MSG_REQUEST_FAILURE, &server_input_keep_alive);
/* rekeying */
- dispatch_set(SSH2_MSG_KEXINIT, &kex_input_kexinit);
+ ssh_dispatch_set(ssh, SSH2_MSG_KEXINIT, &kex_input_kexinit);
}
diff --git a/crypto/openssh/session.c b/crypto/openssh/session.c
index dde75920e79c..31d3bb932a50 100644
--- a/crypto/openssh/session.c
+++ b/crypto/openssh/session.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: session.c,v 1.307 2018/10/04 00:10:11 djm Exp $ */
+/* $OpenBSD: session.c,v 1.329 2021/08/11 05:20:17 djm Exp $ */
/*
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
* All rights reserved
@@ -57,10 +57,10 @@ __RCSID("$FreeBSD$");
#endif
#include <pwd.h>
#include <signal.h>
-#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <stdarg.h>
#include <unistd.h>
#include <limits.h>
@@ -124,9 +124,6 @@ int do_exec_no_pty(struct ssh *, Session *, const char *);
int do_exec(struct ssh *, Session *, const char *);
void do_login(struct ssh *, Session *, const char *);
void do_child(struct ssh *, Session *, const char *);
-#ifdef LOGIN_NEEDS_UTMPX
-static void do_pre_login(Session *s);
-#endif
void do_motd(void);
int check_quietlogin(Session *, const char *);
@@ -205,7 +202,7 @@ auth_input_request_forwarding(struct ssh *ssh, struct passwd * pw)
/* Create private directory for socket */
if (mkdtemp(auth_sock_dir) == NULL) {
- packet_send_debug("Agent forwarding disabled: "
+ ssh_packet_send_debug(ssh, "Agent forwarding disabled: "
"mkdtemp() failed: %.100s", strerror(errno));
restore_uid();
free(auth_sock_dir);
@@ -237,7 +234,9 @@ auth_input_request_forwarding(struct ssh *ssh, struct passwd * pw)
authsock_err:
free(auth_sock_name);
if (auth_sock_dir != NULL) {
+ temporarily_use_uid(pw);
rmdir(auth_sock_dir);
+ restore_uid();
free(auth_sock_dir);
}
if (sock != -1)
@@ -255,7 +254,7 @@ display_loginmsg(void)
if (sshbuf_len(loginmsg) == 0)
return;
if ((r = sshbuf_put_u8(loginmsg, 0)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "sshbuf_put_u8");
printf("%s", (char *)sshbuf_ptr(loginmsg));
sshbuf_reset(loginmsg);
}
@@ -271,16 +270,16 @@ prepare_auth_info_file(struct passwd *pw, struct sshbuf *info)
temporarily_use_uid(pw);
auth_info_file = xstrdup("/tmp/sshauth.XXXXXXXXXXXXXXX");
if ((fd = mkstemp(auth_info_file)) == -1) {
- error("%s: mkstemp: %s", __func__, strerror(errno));
+ error_f("mkstemp: %s", strerror(errno));
goto out;
}
if (atomicio(vwrite, fd, sshbuf_mutable_ptr(info),
sshbuf_len(info)) != sshbuf_len(info)) {
- error("%s: write: %s", __func__, strerror(errno));
+ error_f("write: %s", strerror(errno));
goto out;
}
if (close(fd) != 0) {
- error("%s: close: %s", __func__, strerror(errno));
+ error_f("close: %s", strerror(errno));
goto out;
}
success = 1;
@@ -307,11 +306,10 @@ set_fwdpermit_from_authopts(struct ssh *ssh, const struct sshauthopt *opts)
tmp = cp = xstrdup(auth_opts->permitopen[i]);
/* This shouldn't fail as it has already been checked */
if ((host = hpdelim(&cp)) == NULL)
- fatal("%s: internal error: hpdelim", __func__);
+ fatal_f("internal error: hpdelim");
host = cleanhostname(host);
if (cp == NULL || (port = permitopen_port(cp)) < 0)
- fatal("%s: internal error: permitopen port",
- __func__);
+ fatal_f("internal error: permitopen port");
channel_add_permission(ssh,
FORWARD_USER, FORWARD_LOCAL, host, port);
free(tmp);
@@ -323,11 +321,10 @@ set_fwdpermit_from_authopts(struct ssh *ssh, const struct sshauthopt *opts)
tmp = cp = xstrdup(auth_opts->permitlisten[i]);
/* This shouldn't fail as it has already been checked */
if ((host = hpdelim(&cp)) == NULL)
- fatal("%s: internal error: hpdelim", __func__);
+ fatal_f("internal error: hpdelim");
host = cleanhostname(host);
if (cp == NULL || (port = permitopen_port(cp)) < 0)
- fatal("%s: internal error: permitlisten port",
- __func__);
+ fatal_f("internal error: permitlisten port");
channel_add_permission(ssh,
FORWARD_USER, FORWARD_REMOTE, host, port);
free(tmp);
@@ -360,7 +357,7 @@ do_authenticated(struct ssh *ssh, Authctxt *authctxt)
else
channel_permit_all(ssh, FORWARD_REMOTE);
}
- auth_debug_send();
+ auth_debug_send(ssh);
prepare_auth_info_file(authctxt->pw, authctxt->session_info);
@@ -401,19 +398,18 @@ do_exec_no_pty(struct ssh *ssh, Session *s, const char *command)
fatal("do_exec_no_pty: no session");
/* Allocate pipes for communicating with the program. */
- if (pipe(pin) < 0) {
- error("%s: pipe in: %.100s", __func__, strerror(errno));
+ if (pipe(pin) == -1) {
+ error_f("pipe in: %.100s", strerror(errno));
return -1;
}
- if (pipe(pout) < 0) {
- error("%s: pipe out: %.100s", __func__, strerror(errno));
+ if (pipe(pout) == -1) {
+ error_f("pipe out: %.100s", strerror(errno));
close(pin[0]);
close(pin[1]);
return -1;
}
- if (pipe(perr) < 0) {
- error("%s: pipe err: %.100s", __func__,
- strerror(errno));
+ if (pipe(perr) == -1) {
+ error_f("pipe err: %.100s", strerror(errno));
close(pin[0]);
close(pin[1]);
close(pout[0]);
@@ -427,13 +423,12 @@ do_exec_no_pty(struct ssh *ssh, Session *s, const char *command)
fatal("do_exec_no_pty: no session");
/* Uses socket pairs to communicate with the program. */
- if (socketpair(AF_UNIX, SOCK_STREAM, 0, inout) < 0) {
- error("%s: socketpair #1: %.100s", __func__, strerror(errno));
+ if (socketpair(AF_UNIX, SOCK_STREAM, 0, inout) == -1) {
+ error_f("socketpair #1: %.100s", strerror(errno));
return -1;
}
- if (socketpair(AF_UNIX, SOCK_STREAM, 0, err) < 0) {
- error("%s: socketpair #2: %.100s", __func__,
- strerror(errno));
+ if (socketpair(AF_UNIX, SOCK_STREAM, 0, err) == -1) {
+ error_f("socketpair #2: %.100s", strerror(errno));
close(inout[0]);
close(inout[1]);
return -1;
@@ -445,7 +440,7 @@ do_exec_no_pty(struct ssh *ssh, Session *s, const char *command)
/* Fork the child. */
switch ((pid = fork())) {
case -1:
- error("%s: fork: %.100s", __func__, strerror(errno));
+ error_f("fork: %.100s", strerror(errno));
#ifdef USE_PIPES
close(pin[0]);
close(pin[1]);
@@ -467,7 +462,7 @@ do_exec_no_pty(struct ssh *ssh, Session *s, const char *command)
* Create a new session and process group since the 4.4BSD
* setlogin() affects the entire process group.
*/
- if (setsid() < 0)
+ if (setsid() == -1)
error("setsid failed: %.100s", strerror(errno));
#ifdef USE_PIPES
@@ -476,19 +471,19 @@ do_exec_no_pty(struct ssh *ssh, Session *s, const char *command)
* pair, and make the child side the standard input.
*/
close(pin[1]);
- if (dup2(pin[0], 0) < 0)
+ if (dup2(pin[0], 0) == -1)
perror("dup2 stdin");
close(pin[0]);
/* Redirect stdout. */
close(pout[0]);
- if (dup2(pout[1], 1) < 0)
+ if (dup2(pout[1], 1) == -1)
perror("dup2 stdout");
close(pout[1]);
/* Redirect stderr. */
close(perr[0]);
- if (dup2(perr[1], 2) < 0)
+ if (dup2(perr[1], 2) == -1)
perror("dup2 stderr");
close(perr[1]);
#else
@@ -499,12 +494,12 @@ do_exec_no_pty(struct ssh *ssh, Session *s, const char *command)
*/
close(inout[1]);
close(err[1]);
- if (dup2(inout[0], 0) < 0) /* stdin */
+ if (dup2(inout[0], 0) == -1) /* stdin */
perror("dup2 stdin");
- if (dup2(inout[0], 1) < 0) /* stdout (same as stdin) */
+ if (dup2(inout[0], 1) == -1) /* stdout (same as stdin) */
perror("dup2 stdout");
close(inout[0]);
- if (dup2(err[0], 2) < 0) /* stderr */
+ if (dup2(err[0], 2) == -1) /* stderr */
perror("dup2 stderr");
close(err[0]);
#endif
@@ -522,7 +517,7 @@ do_exec_no_pty(struct ssh *ssh, Session *s, const char *command)
s->pid = pid;
/* Set interactive/non-interactive mode. */
- packet_set_interactive(s->display != NULL,
+ ssh_packet_set_interactive(ssh, s->display != NULL,
options.ip_qos_interactive, options.ip_qos_bulk);
/*
@@ -549,7 +544,7 @@ do_exec_no_pty(struct ssh *ssh, Session *s, const char *command)
* Enter the interactive session. Note: server_loop must be able to
* handle the case that fdin and fdout are the same.
*/
- session_set_fds(s, inout[1], inout[1], err[1],
+ session_set_fds(ssh, s, inout[1], inout[1], err[1],
s->is_subsystem, 0);
#endif
return 0;
@@ -579,15 +574,15 @@ do_exec_pty(struct ssh *ssh, Session *s, const char *command)
* Do this before forking (and cleanup in the child) so as to
* detect and gracefully fail out-of-fd conditions.
*/
- if ((fdout = dup(ptyfd)) < 0) {
- error("%s: dup #1: %s", __func__, strerror(errno));
+ if ((fdout = dup(ptyfd)) == -1) {
+ error_f("dup #1: %s", strerror(errno));
close(ttyfd);
close(ptyfd);
return -1;
}
/* we keep a reference to the pty master */
- if ((ptymaster = dup(ptyfd)) < 0) {
- error("%s: dup #2: %s", __func__, strerror(errno));
+ if ((ptymaster = dup(ptyfd)) == -1) {
+ error_f("dup #2: %s", strerror(errno));
close(ttyfd);
close(ptyfd);
close(fdout);
@@ -597,7 +592,7 @@ do_exec_pty(struct ssh *ssh, Session *s, const char *command)
/* Fork the child. */
switch ((pid = fork())) {
case -1:
- error("%s: fork: %.100s", __func__, strerror(errno));
+ error_f("fork: %.100s", strerror(errno));
close(fdout);
close(ptymaster);
close(ttyfd);
@@ -616,11 +611,11 @@ do_exec_pty(struct ssh *ssh, Session *s, const char *command)
pty_make_controlling_tty(&ttyfd, s->tty);
/* Redirect stdin/stdout/stderr from the pseudo tty. */
- if (dup2(ttyfd, 0) < 0)
+ if (dup2(ttyfd, 0) == -1)
error("dup2 stdin: %s", strerror(errno));
- if (dup2(ttyfd, 1) < 0)
+ if (dup2(ttyfd, 1) == -1)
error("dup2 stdout: %s", strerror(errno));
- if (dup2(ttyfd, 2) < 0)
+ if (dup2(ttyfd, 2) == -1)
error("dup2 stderr: %s", strerror(errno));
/* Close the extra descriptor for the pseudo tty. */
@@ -651,41 +646,12 @@ do_exec_pty(struct ssh *ssh, Session *s, const char *command)
/* Enter interactive session. */
s->ptymaster = ptymaster;
- packet_set_interactive(1,
+ ssh_packet_set_interactive(ssh, 1,
options.ip_qos_interactive, options.ip_qos_bulk);
session_set_fds(ssh, s, ptyfd, fdout, -1, 1, 1);
return 0;
}
-#ifdef LOGIN_NEEDS_UTMPX
-static void
-do_pre_login(Session *s)
-{
- struct ssh *ssh = active_state; /* XXX */
- socklen_t fromlen;
- struct sockaddr_storage from;
- pid_t pid = getpid();
-
- /*
- * Get IP address of client. If the connection is not a socket, let
- * the address be 0.0.0.0.
- */
- memset(&from, 0, sizeof(from));
- fromlen = sizeof(from);
- if (packet_connection_is_on_socket()) {
- if (getpeername(packet_get_connection_in(),
- (struct sockaddr *)&from, &fromlen) < 0) {
- debug("getpeername: %.100s", strerror(errno));
- cleanup_exit(255);
- }
- }
-
- record_utmp_only(pid, s->tty, s->pw->pw_name,
- session_get_remote_name_or_ip(ssh, utmp_len, options.use_dns),
- (struct sockaddr *)&from, fromlen);
-}
-#endif
-
/*
* This is called to fork and execute a command. If another command is
* to be forced, execute that instead.
@@ -784,9 +750,9 @@ do_login(struct ssh *ssh, Session *s, const char *command)
*/
memset(&from, 0, sizeof(from));
fromlen = sizeof(from);
- if (packet_connection_is_on_socket()) {
- if (getpeername(packet_get_connection_in(),
- (struct sockaddr *)&from, &fromlen) < 0) {
+ if (ssh_packet_connection_is_on_socket(ssh)) {
+ if (getpeername(ssh_packet_get_connection_in(ssh),
+ (struct sockaddr *)&from, &fromlen) == -1) {
debug("getpeername: %.100s", strerror(errno));
cleanup_exit(255);
}
@@ -874,12 +840,12 @@ check_quietlogin(Session *s, const char *command)
* into the environment. If the file does not exist, this does nothing.
* Otherwise, it must consist of empty lines, comments (line starts with '#')
* and assignments of the form name=value. No other forms are allowed.
- * If whitelist is not NULL, then it is interpreted as a pattern list and
+ * If allowlist is not NULL, then it is interpreted as a pattern list and
* only variable names that match it will be accepted.
*/
static void
read_environment_file(char ***env, u_int *envsize,
- const char *filename, const char *whitelist)
+ const char *filename, const char *allowlist)
{
FILE *f;
char *line = NULL, *cp, *value;
@@ -912,8 +878,8 @@ read_environment_file(char ***env, u_int *envsize,
*/
*value = '\0';
value++;
- if (whitelist != NULL &&
- match_pattern_list(cp, whitelist, 0) != 1)
+ if (allowlist != NULL &&
+ match_pattern_list(cp, allowlist, 0) != 1)
continue;
child_set_env(env, envsize, cp, value);
}
@@ -955,7 +921,7 @@ read_etc_default_login(char ***env, u_int *envsize, uid_t uid)
* interested in.
*/
read_environment_file(&tmpenv, &tmpenvsize, "/etc/default/login",
- options.permit_user_env_whitelist);
+ options.permit_user_env_allowlist);
if (tmpenv == NULL)
return;
@@ -977,9 +943,10 @@ read_etc_default_login(char ***env, u_int *envsize, uid_t uid)
}
#endif /* HAVE_ETC_DEFAULT_LOGIN */
+#if defined(USE_PAM) || defined(HAVE_CYGWIN)
static void
-copy_environment_blacklist(char **source, char ***env, u_int *envsize,
- const char *blacklist)
+copy_environment_denylist(char **source, char ***env, u_int *envsize,
+ const char *denylist)
{
char *var_name, *var_val;
int i;
@@ -995,8 +962,8 @@ copy_environment_blacklist(char **source, char ***env, u_int *envsize,
}
*var_val++ = '\0';
- if (blacklist == NULL ||
- match_pattern_list(var_name, blacklist, 0) != 1) {
+ if (denylist == NULL ||
+ match_pattern_list(var_name, denylist, 0) != 1) {
debug3("Copy environment: %s=%s", var_name, var_val);
child_set_env(env, envsize, var_name, var_val);
}
@@ -1004,12 +971,15 @@ copy_environment_blacklist(char **source, char ***env, u_int *envsize,
free(var_name);
}
}
+#endif /* defined(USE_PAM) || defined(HAVE_CYGWIN) */
-void
+#ifdef HAVE_CYGWIN
+static void
copy_environment(char **source, char ***env, u_int *envsize)
{
- copy_environment_blacklist(source, env, envsize, NULL);
+ copy_environment_denylist(source, env, envsize, NULL);
}
+#endif
static char **
do_setup_env(struct ssh *ssh, Session *s, const char *shell)
@@ -1050,7 +1020,7 @@ do_setup_env(struct ssh *ssh, Session *s, const char *shell)
#ifdef GSSAPI
/* Allow any GSSAPI methods that we've used to alter
- * the childs environment as they see fit
+ * the child's environment as they see fit
*/
ssh_gssapi_do_child(&env, &envsize);
#endif
@@ -1108,6 +1078,12 @@ do_setup_env(struct ssh *ssh, Session *s, const char *shell)
# endif /* HAVE_CYGWIN */
#endif /* HAVE_LOGIN_CAP */
+ if (!options.use_pam) {
+ snprintf(buf, sizeof buf, "%.200s/%.50s",
+ _PATH_MAILDIR, pw->pw_name);
+ child_set_env(&env, &envsize, "MAIL", buf);
+ }
+
/* Normal systems set SHELL by default. */
child_set_env(&env, &envsize, "SHELL", shell);
@@ -1135,7 +1111,7 @@ do_setup_env(struct ssh *ssh, Session *s, const char *shell)
if ((cp = getenv("AUTHSTATE")) != NULL)
child_set_env(&env, &envsize, "AUTHSTATE", cp);
read_environment_file(&env, &envsize, "/etc/environment",
- options.permit_user_env_whitelist);
+ options.permit_user_env_allowlist);
}
#endif
#ifdef KRB5
@@ -1153,12 +1129,12 @@ do_setup_env(struct ssh *ssh, Session *s, const char *shell)
for (n = 0 ; n < auth_opts->nenv; n++) {
ocp = xstrdup(auth_opts->env[n]);
cp = strchr(ocp, '=');
- if (*cp == '=') {
+ if (cp != NULL) {
*cp = '\0';
- /* Apply PermitUserEnvironment whitelist */
- if (options.permit_user_env_whitelist == NULL ||
+ /* Apply PermitUserEnvironment allowlist */
+ if (options.permit_user_env_allowlist == NULL ||
match_pattern_list(ocp,
- options.permit_user_env_whitelist, 0) == 1)
+ options.permit_user_env_allowlist, 0) == 1)
child_set_env(&env, &envsize,
ocp, cp + 1);
}
@@ -1168,10 +1144,10 @@ do_setup_env(struct ssh *ssh, Session *s, const char *shell)
/* read $HOME/.ssh/environment. */
if (options.permit_user_env) {
- snprintf(buf, sizeof buf, "%.200s/.ssh/environment",
- pw->pw_dir);
+ snprintf(buf, sizeof buf, "%.200s/%s/environment",
+ pw->pw_dir, _PATH_SSH_USER_DIR);
read_environment_file(&env, &envsize, buf,
- options.permit_user_env_whitelist);
+ options.permit_user_env_allowlist);
}
#ifdef USE_PAM
@@ -1183,15 +1159,18 @@ do_setup_env(struct ssh *ssh, Session *s, const char *shell)
char **p;
/*
- * Don't allow SSH_AUTH_INFO variables posted to PAM to leak
- * back into the environment.
+ * Don't allow PAM-internal env vars to leak
+ * back into the session environment.
*/
+#define PAM_ENV_DENYLIST "SSH_AUTH_INFO*,SSH_CONNECTION*"
p = fetch_pam_child_environment();
- copy_environment_blacklist(p, &env, &envsize, "SSH_AUTH_INFO*");
+ copy_environment_denylist(p, &env, &envsize,
+ PAM_ENV_DENYLIST);
free_pam_environment(p);
p = fetch_pam_environment();
- copy_environment_blacklist(p, &env, &envsize, "SSH_AUTH_INFO*");
+ copy_environment_denylist(p, &env, &envsize,
+ PAM_ENV_DENYLIST);
free_pam_environment(p);
}
#endif /* USE_PAM */
@@ -1213,7 +1192,7 @@ do_setup_env(struct ssh *ssh, Session *s, const char *shell)
ssh_local_port(ssh));
child_set_env(&env, &envsize, "SSH_CLIENT", buf);
- laddr = get_local_ipaddr(packet_get_connection_in());
+ laddr = get_local_ipaddr(ssh_packet_get_connection_in(ssh));
snprintf(buf, sizeof buf, "%.50s %d %.50s %d",
ssh_remote_ipaddr(ssh), ssh_remote_port(ssh),
laddr, ssh_local_port(ssh));
@@ -1247,19 +1226,21 @@ static void
do_rc_files(struct ssh *ssh, Session *s, const char *shell)
{
FILE *f = NULL;
- char cmd[1024];
+ char *cmd = NULL, *user_rc = NULL;
int do_xauth;
struct stat st;
do_xauth =
s->display != NULL && s->auth_proto != NULL && s->auth_data != NULL;
+ xasprintf(&user_rc, "%s/%s", s->pw->pw_dir, _PATH_SSH_USER_RC);
/* ignore _PATH_SSH_USER_RC for subsystems and admin forced commands */
if (!s->is_subsystem && options.adm_forced_command == NULL &&
auth_opts->permit_user_rc && options.permit_user_rc &&
- stat(_PATH_SSH_USER_RC, &st) >= 0) {
- snprintf(cmd, sizeof cmd, "%s -c '%s %s'",
- shell, _PATH_BSHELL, _PATH_SSH_USER_RC);
+ stat(user_rc, &st) >= 0) {
+ if (xasprintf(&cmd, "%s -c '%s %s'", shell, _PATH_BSHELL,
+ user_rc) == -1)
+ fatal_f("xasprintf: %s", strerror(errno));
if (debug_flag)
fprintf(stderr, "Running %s\n", cmd);
f = popen(cmd, "w");
@@ -1270,7 +1251,7 @@ do_rc_files(struct ssh *ssh, Session *s, const char *shell)
pclose(f);
} else
fprintf(stderr, "Could not run %s\n",
- _PATH_SSH_USER_RC);
+ user_rc);
} else if (stat(_PATH_SSH_SYSTEM_RC, &st) >= 0) {
if (debug_flag)
fprintf(stderr, "Running %s %s\n", _PATH_BSHELL,
@@ -1295,8 +1276,8 @@ do_rc_files(struct ssh *ssh, Session *s, const char *shell)
options.xauth_location, s->auth_display,
s->auth_proto, s->auth_data);
}
- snprintf(cmd, sizeof cmd, "%s -q -",
- options.xauth_location);
+ if (xasprintf(&cmd, "%s -q -", options.xauth_location) == -1)
+ fatal_f("xasprintf: %s", strerror(errno));
f = popen(cmd, "w");
if (f) {
fprintf(f, "remove %s\n",
@@ -1310,6 +1291,8 @@ do_rc_files(struct ssh *ssh, Session *s, const char *shell)
cmd);
}
}
+ free(cmd);
+ free(user_rc);
}
static void
@@ -1353,7 +1336,7 @@ safely_chroot(const char *path, uid_t uid)
char component[PATH_MAX];
struct stat st;
- if (*path != '/')
+ if (!path_absolute(path))
fatal("chroot path does not begin at root");
if (strlen(path) >= sizeof(component))
fatal("chroot path too long");
@@ -1371,14 +1354,14 @@ safely_chroot(const char *path, uid_t uid)
component[cp - path] = '\0';
}
- debug3("%s: checking '%s'", __func__, component);
+ debug3_f("checking '%s'", component);
if (stat(component, &st) != 0)
- fatal("%s: stat(\"%s\"): %s", __func__,
+ fatal_f("stat(\"%s\"): %s",
component, strerror(errno));
if (st.st_uid != 0 || (st.st_mode & 022) != 0)
fatal("bad ownership or modes for chroot "
- "directory %s\"%s\"",
+ "directory %s\"%s\"",
cp == NULL ? "" : "component ", component);
if (!S_ISDIR(st.st_mode))
fatal("chroot path %s\"%s\" is not a directory",
@@ -1392,8 +1375,7 @@ safely_chroot(const char *path, uid_t uid)
if (chroot(path) == -1)
fatal("chroot(\"%s\"): %s", path, strerror(errno));
if (chdir("/") == -1)
- fatal("%s: chdir(/) after chroot: %s",
- __func__, strerror(errno));
+ fatal_f("chdir(/) after chroot: %s", strerror(errno));
verbose("Changed root directory to \"%s\"", path);
}
@@ -1431,7 +1413,7 @@ do_setusercontext(struct passwd *pw)
if (!in_chroot && options.chroot_directory != NULL &&
strcasecmp(options.chroot_directory, "none") != 0) {
- tmp = tilde_expand_filename(options.chroot_directory,
+ tmp = tilde_expand_filename(options.chroot_directory,
pw->pw_uid);
snprintf(uidstr, sizeof(uidstr), "%llu",
(unsigned long long)pw->pw_uid);
@@ -1516,11 +1498,12 @@ child_close_fds(struct ssh *ssh)
auth_sock = -1;
}
- if (packet_get_connection_in() == packet_get_connection_out())
- close(packet_get_connection_in());
+ if (ssh_packet_get_connection_in(ssh) ==
+ ssh_packet_get_connection_out(ssh))
+ close(ssh_packet_get_connection_in(ssh));
else {
- close(packet_get_connection_in());
- close(packet_get_connection_out());
+ close(ssh_packet_get_connection_in(ssh));
+ close(ssh_packet_get_connection_out(ssh));
}
/*
* Close all descriptors related to channels. They will still remain
@@ -1535,6 +1518,9 @@ child_close_fds(struct ssh *ssh)
*/
endpwent();
+ /* Stop directing logs to a high-numbered fd before we close it */
+ log_redirect_stderr_to(NULL);
+
/*
* Close any extra open file descriptors so that we don't have them
* hanging around in clients. Note that we want to do this after
@@ -1554,15 +1540,16 @@ void
do_child(struct ssh *ssh, Session *s, const char *command)
{
extern char **environ;
- char **env;
- char *argv[ARGV_MAX];
+ char **env, *argv[ARGV_MAX], remote_id[512];
const char *shell, *shell0;
struct passwd *pw = s->pw;
int r = 0;
+ sshpkt_fmt_connection_id(ssh, remote_id, sizeof(remote_id));
+
/* remove hostkey from the child's memory */
destroy_sensitive_data();
- packet_clear_keys();
+ ssh_packet_clear_keys(ssh);
/* Force a password change */
if (s->authctxt->force_pwchange) {
@@ -1660,7 +1647,7 @@ do_child(struct ssh *ssh, Session *s, const char *command)
#endif
/* Change current directory to the user's home directory. */
- if (chdir(pw->pw_dir) < 0) {
+ if (chdir(pw->pw_dir) == -1) {
/* Suppress missing homedir warning for chroot case */
#ifdef HAVE_LOGIN_CAP
r = login_getcapbool(lc, "requirehome", 0);
@@ -1679,9 +1666,11 @@ do_child(struct ssh *ssh, Session *s, const char *command)
do_rc_files(ssh, s, shell);
/* restore SIGPIPE for child */
- signal(SIGPIPE, SIG_DFL);
+ ssh_signal(SIGPIPE, SIG_DFL);
if (s->is_subsystem == SUBSYSTEM_INT_SFTP_ERROR) {
+ error("Connection from %s: refusing non-sftp session",
+ remote_id);
printf("This service allows sftp connections only.\n");
fflush(NULL);
exit(1);
@@ -1755,11 +1744,11 @@ do_child(struct ssh *ssh, Session *s, const char *command)
void
session_unused(int id)
{
- debug3("%s: session id %d unused", __func__, id);
+ debug3_f("session id %d unused", id);
if (id >= options.max_sessions ||
id >= sessions_nalloc) {
- fatal("%s: insane session id %d (max %d nalloc %d)",
- __func__, id, options.max_sessions, sessions_nalloc);
+ fatal_f("insane session id %d (max %d nalloc %d)",
+ id, options.max_sessions, sessions_nalloc);
}
memset(&sessions[id], 0, sizeof(*sessions));
sessions[id].self = id;
@@ -1781,13 +1770,13 @@ session_new(void)
if (sessions_first_unused == -1) {
if (sessions_nalloc >= options.max_sessions)
return NULL;
- debug2("%s: allocate (allocated %d max %d)",
- __func__, sessions_nalloc, options.max_sessions);
+ debug2_f("allocate (allocated %d max %d)",
+ sessions_nalloc, options.max_sessions);
tmp = xrecallocarray(sessions, sessions_nalloc,
sessions_nalloc + 1, sizeof(*sessions));
if (tmp == NULL) {
- error("%s: cannot allocate %d sessions",
- __func__, sessions_nalloc + 1);
+ error_f("cannot allocate %d sessions",
+ sessions_nalloc + 1);
return NULL;
}
sessions = tmp;
@@ -1796,16 +1785,14 @@ session_new(void)
if (sessions_first_unused >= sessions_nalloc ||
sessions_first_unused < 0) {
- fatal("%s: insane first_unused %d max %d nalloc %d",
- __func__, sessions_first_unused, options.max_sessions,
+ fatal_f("insane first_unused %d max %d nalloc %d",
+ sessions_first_unused, options.max_sessions,
sessions_nalloc);
}
s = &sessions[sessions_first_unused];
- if (s->used) {
- fatal("%s: session %d already used",
- __func__, sessions_first_unused);
- }
+ if (s->used)
+ fatal_f("session %d already used", sessions_first_unused);
sessions_first_unused = s->next_unused;
s->used = 1;
s->next_unused = -1;
@@ -1821,12 +1808,11 @@ session_dump(void)
for (i = 0; i < sessions_nalloc; i++) {
Session *s = &sessions[i];
- debug("dump: used %d next_unused %d session %d %p "
+ debug("dump: used %d next_unused %d session %d "
"channel %d pid %ld",
s->used,
s->next_unused,
s->self,
- s,
s->chanid,
(long)s->pid);
}
@@ -1924,11 +1910,14 @@ session_by_pid(pid_t pid)
static int
session_window_change_req(struct ssh *ssh, Session *s)
{
- s->col = packet_get_int();
- s->row = packet_get_int();
- s->xpixel = packet_get_int();
- s->ypixel = packet_get_int();
- packet_check_eom();
+ int r;
+
+ if ((r = sshpkt_get_u32(ssh, &s->col)) != 0 ||
+ (r = sshpkt_get_u32(ssh, &s->row)) != 0 ||
+ (r = sshpkt_get_u32(ssh, &s->xpixel)) != 0 ||
+ (r = sshpkt_get_u32(ssh, &s->ypixel)) != 0 ||
+ (r = sshpkt_get_end(ssh)) != 0)
+ sshpkt_fatal(ssh, r, "%s: parse packet", __func__);
pty_change_window_size(s->ptyfd, s->row, s->col, s->xpixel, s->ypixel);
return 1;
}
@@ -1936,22 +1925,23 @@ session_window_change_req(struct ssh *ssh, Session *s)
static int
session_pty_req(struct ssh *ssh, Session *s)
{
- u_int len;
+ int r;
if (!auth_opts->permit_pty_flag || !options.permit_tty) {
debug("Allocating a pty not permitted for this connection.");
return 0;
}
if (s->ttyfd != -1) {
- packet_disconnect("Protocol error: you already have a pty.");
+ ssh_packet_disconnect(ssh, "Protocol error: you already have a pty.");
return 0;
}
- s->term = packet_get_string(&len);
- s->col = packet_get_int();
- s->row = packet_get_int();
- s->xpixel = packet_get_int();
- s->ypixel = packet_get_int();
+ if ((r = sshpkt_get_cstring(ssh, &s->term, NULL)) != 0 ||
+ (r = sshpkt_get_u32(ssh, &s->col)) != 0 ||
+ (r = sshpkt_get_u32(ssh, &s->row)) != 0 ||
+ (r = sshpkt_get_u32(ssh, &s->xpixel)) != 0 ||
+ (r = sshpkt_get_u32(ssh, &s->ypixel)) != 0)
+ sshpkt_fatal(ssh, r, "%s: parse packet", __func__);
if (strcmp(s->term, "") == 0) {
free(s->term);
@@ -1973,13 +1963,15 @@ session_pty_req(struct ssh *ssh, Session *s)
ssh_tty_parse_modes(ssh, s->ttyfd);
+ if ((r = sshpkt_get_end(ssh)) != 0)
+ sshpkt_fatal(ssh, r, "%s: parse packet", __func__);
+
if (!use_privsep)
pty_setowner(s->pw, s->tty);
/* Set window size from the packet. */
pty_change_window_size(s->ptyfd, s->row, s->col, s->xpixel, s->ypixel);
- packet_check_eom();
session_proctitle(s);
return 1;
}
@@ -1988,13 +1980,13 @@ static int
session_subsystem_req(struct ssh *ssh, Session *s)
{
struct stat st;
- u_int len;
- int success = 0;
+ int r, success = 0;
char *prog, *cmd;
u_int i;
- s->subsys = packet_get_string(&len);
- packet_check_eom();
+ if ((r = sshpkt_get_cstring(ssh, &s->subsys, NULL)) != 0 ||
+ (r = sshpkt_get_end(ssh)) != 0)
+ sshpkt_fatal(ssh, r, "%s: parse packet", __func__);
debug2("subsystem request for %.100s by user %s", s->subsys,
s->pw->pw_name);
@@ -2006,7 +1998,7 @@ session_subsystem_req(struct ssh *ssh, Session *s)
s->is_subsystem = SUBSYSTEM_INT_SFTP;
debug("subsystem: %s", prog);
} else {
- if (stat(prog, &st) < 0)
+ if (stat(prog, &st) == -1)
debug("subsystem: cannot stat %s: %s",
prog, strerror(errno));
s->is_subsystem = SUBSYSTEM_EXT;
@@ -2027,18 +2019,22 @@ session_subsystem_req(struct ssh *ssh, Session *s)
static int
session_x11_req(struct ssh *ssh, Session *s)
{
- int success;
+ int r, success;
+ u_char single_connection = 0;
if (s->auth_proto != NULL || s->auth_data != NULL) {
error("session_x11_req: session %d: "
"x11 forwarding already active", s->self);
return 0;
}
- s->single_connection = packet_get_char();
- s->auth_proto = packet_get_string(NULL);
- s->auth_data = packet_get_string(NULL);
- s->screen = packet_get_int();
- packet_check_eom();
+ if ((r = sshpkt_get_u8(ssh, &single_connection)) != 0 ||
+ (r = sshpkt_get_cstring(ssh, &s->auth_proto, NULL)) != 0 ||
+ (r = sshpkt_get_cstring(ssh, &s->auth_data, NULL)) != 0 ||
+ (r = sshpkt_get_u32(ssh, &s->screen)) != 0 ||
+ (r = sshpkt_get_end(ssh)) != 0)
+ sshpkt_fatal(ssh, r, "%s: parse packet", __func__);
+
+ s->single_connection = single_connection;
if (xauth_valid_string(s->auth_proto) &&
xauth_valid_string(s->auth_data))
@@ -2059,17 +2055,24 @@ session_x11_req(struct ssh *ssh, Session *s)
static int
session_shell_req(struct ssh *ssh, Session *s)
{
- packet_check_eom();
+ int r;
+
+ if ((r = sshpkt_get_end(ssh)) != 0)
+ sshpkt_fatal(ssh, r, "%s: parse packet", __func__);
return do_exec(ssh, s, NULL) == 0;
}
static int
session_exec_req(struct ssh *ssh, Session *s)
{
- u_int len, success;
+ u_int success;
+ int r;
+ char *command = NULL;
+
+ if ((r = sshpkt_get_cstring(ssh, &command, NULL)) != 0 ||
+ (r = sshpkt_get_end(ssh)) != 0)
+ sshpkt_fatal(ssh, r, "%s: parse packet", __func__);
- char *command = packet_get_string(&len);
- packet_check_eom();
success = do_exec(ssh, s, command) == 0;
free(command);
return success;
@@ -2078,11 +2081,13 @@ session_exec_req(struct ssh *ssh, Session *s)
static int
session_break_req(struct ssh *ssh, Session *s)
{
+ int r;
- packet_get_int(); /* ignored */
- packet_check_eom();
+ if ((r = sshpkt_get_u32(ssh, NULL)) != 0 || /* ignore */
+ (r = sshpkt_get_end(ssh)) != 0)
+ sshpkt_fatal(ssh, r, "%s: parse packet", __func__);
- if (s->ptymaster == -1 || tcsendbreak(s->ptymaster, 0) < 0)
+ if (s->ptymaster == -1 || tcsendbreak(s->ptymaster, 0) == -1)
return 0;
return 1;
}
@@ -2091,11 +2096,13 @@ static int
session_env_req(struct ssh *ssh, Session *s)
{
char *name, *val;
- u_int name_len, val_len, i;
+ u_int i;
+ int r;
- name = packet_get_cstring(&name_len);
- val = packet_get_cstring(&val_len);
- packet_check_eom();
+ if ((r = sshpkt_get_cstring(ssh, &name, NULL)) != 0 ||
+ (r = sshpkt_get_cstring(ssh, &val, NULL)) != 0 ||
+ (r = sshpkt_get_end(ssh)) != 0)
+ sshpkt_fatal(ssh, r, "%s: parse packet", __func__);
/* Don't set too many environment variables */
if (s->num_env > 128) {
@@ -2154,35 +2161,33 @@ session_signal_req(struct ssh *ssh, Session *s)
if ((r = sshpkt_get_cstring(ssh, &signame, NULL)) != 0 ||
(r = sshpkt_get_end(ssh)) != 0) {
- error("%s: parse packet: %s", __func__, ssh_err(r));
+ error_fr(r, "parse");
goto out;
}
if ((sig = name2sig(signame)) == -1) {
- error("%s: unsupported signal \"%s\"", __func__, signame);
+ error_f("unsupported signal \"%s\"", signame);
goto out;
}
if (s->pid <= 0) {
- error("%s: no pid for session %d", __func__, s->self);
+ error_f("no pid for session %d", s->self);
goto out;
}
if (s->forced || s->is_subsystem) {
- error("%s: refusing to send signal %s to %s session", __func__,
+ error_f("refusing to send signal %s to %s session",
signame, s->forced ? "forced-command" : "subsystem");
goto out;
}
if (!use_privsep || mm_is_monitor()) {
- error("%s: session signalling requires privilege separation",
- __func__);
+ error_f("session signalling requires privilege separation");
goto out;
}
- debug("%s: signal %s, killpg(%ld, %d)", __func__, signame,
- (long)s->pid, sig);
+ debug_f("signal %s, killpg(%ld, %d)", signame, (long)s->pid, sig);
temporarily_use_uid(s->pw);
r = killpg(s->pid, sig);
restore_uid();
if (r != 0) {
- error("%s: killpg(%ld, %d): %s", __func__, (long)s->pid,
+ error_f("killpg(%ld, %d): %s", (long)s->pid,
sig, strerror(errno));
goto out;
}
@@ -2198,11 +2203,13 @@ static int
session_auth_agent_req(struct ssh *ssh, Session *s)
{
static int called = 0;
+ int r;
- packet_check_eom();
+ if ((r = sshpkt_get_end(ssh)) != 0)
+ sshpkt_fatal(ssh, r, "%s: parse packet", __func__);
if (!auth_opts->permit_agent_forwarding_flag ||
!options.allow_agent_forwarding) {
- debug("%s: agent forwarding disabled", __func__);
+ debug_f("agent forwarding disabled");
return 0;
}
if (called) {
@@ -2220,10 +2227,10 @@ session_input_channel_req(struct ssh *ssh, Channel *c, const char *rtype)
Session *s;
if ((s = session_by_channel(c->self)) == NULL) {
- logit("%s: no session %d req %.100s", __func__, c->self, rtype);
+ logit_f("no session %d req %.100s", c->self, rtype);
return 0;
}
- debug("%s: session %d req %s", __func__, s->self, rtype);
+ debug_f("session %d req %s", s->self, rtype);
/*
* a session is in LARVAL state until a shell, a command
@@ -2281,13 +2288,13 @@ void
session_pty_cleanup2(Session *s)
{
if (s == NULL) {
- error("%s: no session", __func__);
+ error_f("no session");
return;
}
if (s->ttyfd == -1)
return;
- debug("%s: session %d release %s", __func__, s->self, s->tty);
+ debug_f("session %d release %s", s->self, s->tty);
/* Record that the user has logged out. */
if (s->pid != 0)
@@ -2302,7 +2309,7 @@ session_pty_cleanup2(Session *s)
* the pty cleanup, so that another process doesn't get this pty
* while we're still cleaning up.
*/
- if (s->ptymaster != -1 && close(s->ptymaster) < 0)
+ if (s->ptymaster != -1 && close(s->ptymaster) == -1)
error("close(s->ptymaster/%d): %s",
s->ptymaster, strerror(errno));
@@ -2343,10 +2350,10 @@ session_close_x11(struct ssh *ssh, int id)
Channel *c;
if ((c = channel_by_id(ssh, id)) == NULL) {
- debug("%s: x11 channel %d missing", __func__, id);
+ debug_f("x11 channel %d missing", id);
} else {
/* Detach X11 listener */
- debug("%s: detach x11 channel %d", __func__, id);
+ debug_f("detach x11 channel %d", id);
channel_cancel_cleanup(ssh, id);
if (c->ostate != CHAN_OUTPUT_CLOSED)
chan_mark_dead(ssh, c);
@@ -2359,13 +2366,13 @@ session_close_single_x11(struct ssh *ssh, int id, void *arg)
Session *s;
u_int i;
- debug3("%s: channel %d", __func__, id);
+ debug3_f("channel %d", id);
channel_cancel_cleanup(ssh, id);
if ((s = session_by_x11_channel(id)) == NULL)
- fatal("%s: no x11 channel %d", __func__, id);
+ fatal_f("no x11 channel %d", id);
for (i = 0; s->x11_chanids[i] != -1; i++) {
- debug("%s: session %d: closing channel %d",
- __func__, s->self, s->x11_chanids[i]);
+ debug_f("session %d: closing channel %d",
+ s->self, s->x11_chanids[i]);
/*
* The channel "id" is already closing, but make sure we
* close all of its siblings.
@@ -2389,40 +2396,41 @@ static void
session_exit_message(struct ssh *ssh, Session *s, int status)
{
Channel *c;
+ int r;
if ((c = channel_lookup(ssh, s->chanid)) == NULL)
- fatal("%s: session %d: no channel %d",
- __func__, s->self, s->chanid);
- debug("%s: session %d channel %d pid %ld",
- __func__, s->self, s->chanid, (long)s->pid);
+ fatal_f("session %d: no channel %d", s->self, s->chanid);
+ debug_f("session %d channel %d pid %ld",
+ s->self, s->chanid, (long)s->pid);
if (WIFEXITED(status)) {
channel_request_start(ssh, s->chanid, "exit-status", 0);
- packet_put_int(WEXITSTATUS(status));
- packet_send();
+ if ((r = sshpkt_put_u32(ssh, WEXITSTATUS(status))) != 0 ||
+ (r = sshpkt_send(ssh)) != 0)
+ sshpkt_fatal(ssh, r, "%s: exit reply", __func__);
} else if (WIFSIGNALED(status)) {
channel_request_start(ssh, s->chanid, "exit-signal", 0);
- packet_put_cstring(sig2name(WTERMSIG(status)));
-#ifdef WCOREDUMP
- packet_put_char(WCOREDUMP(status)? 1 : 0);
-#else /* WCOREDUMP */
- packet_put_char(0);
-#endif /* WCOREDUMP */
- packet_put_cstring("");
- packet_put_cstring("");
- packet_send();
+#ifndef WCOREDUMP
+# define WCOREDUMP(x) (0)
+#endif
+ if ((r = sshpkt_put_cstring(ssh, sig2name(WTERMSIG(status)))) != 0 ||
+ (r = sshpkt_put_u8(ssh, WCOREDUMP(status)? 1 : 0)) != 0 ||
+ (r = sshpkt_put_cstring(ssh, "")) != 0 ||
+ (r = sshpkt_put_cstring(ssh, "")) != 0 ||
+ (r = sshpkt_send(ssh)) != 0)
+ sshpkt_fatal(ssh, r, "%s: exit reply", __func__);
} else {
/* Some weird exit cause. Just exit. */
- packet_disconnect("wait returned status %04x.", status);
+ ssh_packet_disconnect(ssh, "wait returned status %04x.", status);
}
/* disconnect channel */
- debug("%s: release channel %d", __func__, s->chanid);
+ debug_f("release channel %d", s->chanid);
/*
* Adjust cleanup callback attachment to send close messages when
* the channel gets EOF. The session will be then be closed
- * by session_close_by_channel when the childs close their fds.
+ * by session_close_by_channel when the child sessions close their fds.
*/
channel_register_cleanup(ssh, c->self, session_close_by_channel, 1);
@@ -2472,7 +2480,7 @@ session_close_by_pid(struct ssh *ssh, pid_t pid, int status)
{
Session *s = session_by_pid(pid);
if (s == NULL) {
- debug("%s: no session for pid %ld", __func__, (long)pid);
+ debug_f("no session for pid %ld", (long)pid);
return;
}
if (s->chanid != -1)
@@ -2493,13 +2501,12 @@ session_close_by_channel(struct ssh *ssh, int id, void *arg)
u_int i;
if (s == NULL) {
- debug("%s: no session for id %d", __func__, id);
+ debug_f("no session for id %d", id);
return;
}
- debug("%s: channel %d child %ld", __func__, id, (long)s->pid);
+ debug_f("channel %d child %ld", id, (long)s->pid);
if (s->pid != 0) {
- debug("%s: channel %d: has child, ttyfd %d",
- __func__, id, s->ttyfd);
+ debug_f("channel %d: has child, ttyfd %d", id, s->ttyfd);
/*
* delay detach of session, but release pty, since
* the fd's to the child are already closed
@@ -2584,7 +2591,7 @@ session_setup_x11fwd(struct ssh *ssh, Session *s)
u_int i;
if (!auth_opts->permit_x11_forwarding_flag) {
- packet_send_debug("X11 forwarding disabled by key options.");
+ ssh_packet_send_debug(ssh, "X11 forwarding disabled by key options.");
return 0;
}
if (!options.x11_forwarding) {
@@ -2593,7 +2600,7 @@ session_setup_x11fwd(struct ssh *ssh, Session *s)
}
if (options.xauth_location == NULL ||
(stat(options.xauth_location, &st) == -1)) {
- packet_send_debug("No xauth program; cannot forward X11.");
+ ssh_packet_send_debug(ssh, "No xauth program; cannot forward X11.");
return 0;
}
if (s->display != NULL) {
@@ -2612,7 +2619,7 @@ session_setup_x11fwd(struct ssh *ssh, Session *s)
}
/* Set up a suitable value for the DISPLAY variable. */
- if (gethostname(hostname, sizeof(hostname)) < 0)
+ if (gethostname(hostname, sizeof(hostname)) == -1)
fatal("gethostname: %.100s", strerror(errno));
/*
* auth_display must be used as the displayname when the
@@ -2634,7 +2641,7 @@ session_setup_x11fwd(struct ssh *ssh, Session *s)
he = gethostbyname(hostname);
if (he == NULL) {
error("Can't get IP address for X11 DISPLAY.");
- packet_send_debug("Can't get IP address for X11 DISPLAY.");
+ ssh_packet_send_debug(ssh, "Can't get IP address for X11 DISPLAY.");
return 0;
}
memcpy(&my_addr, he->h_addr_list[0], sizeof(struct in_addr));
diff --git a/crypto/openssh/sftp-client.c b/crypto/openssh/sftp-client.c
index 4986d6d8d291..5bfff90d187f 100644
--- a/crypto/openssh/sftp-client.c
+++ b/crypto/openssh/sftp-client.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: sftp-client.c,v 1.130 2018/07/31 03:07:24 djm Exp $ */
+/* $OpenBSD: sftp-client.c,v 1.154 2021/08/09 23:47:44 djm Exp $ */
/*
* Copyright (c) 2001-2004 Damien Miller <djm@openbsd.org>
*
@@ -37,6 +37,13 @@
#include <dirent.h>
#include <errno.h>
+#ifdef HAVE_POLL_H
+#include <poll.h>
+#else
+# ifdef HAVE_SYS_POLL_H
+# include <sys/poll.h>
+# endif
+#endif
#include <fcntl.h>
#include <signal.h>
#include <stdarg.h>
@@ -61,6 +68,12 @@
extern volatile sig_atomic_t interrupted;
extern int showprogress;
+/* Default size of buffer for up/download */
+#define DEFAULT_COPY_BUFLEN 32768
+
+/* Default number of concurrent outstanding requests */
+#define DEFAULT_NUM_REQUESTS 64
+
/* Minimum amount of data to read at a time */
#define MIN_READ_SIZE 512
@@ -77,7 +90,8 @@ extern int showprogress;
struct sftp_conn {
int fd_in;
int fd_out;
- u_int transfer_buflen;
+ u_int download_buflen;
+ u_int upload_buflen;
u_int num_requests;
u_int version;
u_int msg_id;
@@ -86,22 +100,62 @@ struct sftp_conn {
#define SFTP_EXT_FSTATVFS 0x00000004
#define SFTP_EXT_HARDLINK 0x00000008
#define SFTP_EXT_FSYNC 0x00000010
+#define SFTP_EXT_LSETSTAT 0x00000020
+#define SFTP_EXT_LIMITS 0x00000040
+#define SFTP_EXT_PATH_EXPAND 0x00000080
u_int exts;
u_int64_t limit_kbps;
struct bwlimit bwlimit_in, bwlimit_out;
};
+/* Tracks in-progress requests during file transfers */
+struct request {
+ u_int id;
+ size_t len;
+ u_int64_t offset;
+ TAILQ_ENTRY(request) tq;
+};
+TAILQ_HEAD(requests, request);
+
static u_char *
get_handle(struct sftp_conn *conn, u_int expected_id, size_t *len,
const char *errfmt, ...) __attribute__((format(printf, 4, 5)));
+static struct request *
+request_enqueue(struct requests *requests, u_int id, size_t len,
+ uint64_t offset)
+{
+ struct request *req;
+
+ req = xcalloc(1, sizeof(*req));
+ req->id = id;
+ req->len = len;
+ req->offset = offset;
+ TAILQ_INSERT_TAIL(requests, req, tq);
+ return req;
+}
+
+static struct request *
+request_find(struct requests *requests, u_int id)
+{
+ struct request *req;
+
+ for (req = TAILQ_FIRST(requests);
+ req != NULL && req->id != id;
+ req = TAILQ_NEXT(req, tq))
+ ;
+ return req;
+}
+
/* ARGSUSED */
static int
sftpio(void *_bwlimit, size_t amount)
{
struct bwlimit *bwlimit = (struct bwlimit *)_bwlimit;
- bandwidth_limit(bwlimit, amount);
+ refresh_progress_meter(0);
+ if (bwlimit != NULL)
+ bandwidth_limit(bwlimit, amount);
return 0;
}
@@ -121,8 +175,8 @@ send_msg(struct sftp_conn *conn, struct sshbuf *m)
iov[1].iov_base = (u_char *)sshbuf_ptr(m);
iov[1].iov_len = sshbuf_len(m);
- if (atomiciov6(writev, conn->fd_out, iov, 2,
- conn->limit_kbps > 0 ? sftpio : NULL, &conn->bwlimit_out) !=
+ if (atomiciov6(writev, conn->fd_out, iov, 2, sftpio,
+ conn->limit_kbps > 0 ? &conn->bwlimit_out : NULL) !=
sshbuf_len(m) + sizeof(mlen))
fatal("Couldn't send packet: %s", strerror(errno));
@@ -136,10 +190,11 @@ get_msg_extended(struct sftp_conn *conn, struct sshbuf *m, int initial)
u_char *p;
int r;
+ sshbuf_reset(m);
if ((r = sshbuf_reserve(m, 4, &p)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
- if (atomicio6(read, conn->fd_in, p, 4,
- conn->limit_kbps > 0 ? sftpio : NULL, &conn->bwlimit_in) != 4) {
+ fatal_fr(r, "reserve");
+ if (atomicio6(read, conn->fd_in, p, 4, sftpio,
+ conn->limit_kbps > 0 ? &conn->bwlimit_in : NULL) != 4) {
if (errno == EPIPE || errno == ECONNRESET)
fatal("Connection closed");
else
@@ -147,7 +202,7 @@ get_msg_extended(struct sftp_conn *conn, struct sshbuf *m, int initial)
}
if ((r = sshbuf_get_u32(m, &msg_len)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "sshbuf_get_u32");
if (msg_len > SFTP_MAX_MSG_LENGTH) {
do_log2(initial ? SYSLOG_LEVEL_ERROR : SYSLOG_LEVEL_FATAL,
"Received message too long %u", msg_len);
@@ -156,9 +211,9 @@ get_msg_extended(struct sftp_conn *conn, struct sshbuf *m, int initial)
}
if ((r = sshbuf_reserve(m, msg_len, &p)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
- if (atomicio6(read, conn->fd_in, p, msg_len,
- conn->limit_kbps > 0 ? sftpio : NULL, &conn->bwlimit_in)
+ fatal_fr(r, "reserve");
+ if (atomicio6(read, conn->fd_in, p, msg_len, sftpio,
+ conn->limit_kbps > 0 ? &conn->bwlimit_in : NULL)
!= msg_len) {
if (errno == EPIPE)
fatal("Connection closed");
@@ -181,11 +236,11 @@ send_string_request(struct sftp_conn *conn, u_int id, u_int code, const char *s,
int r;
if ((msg = sshbuf_new()) == NULL)
- fatal("%s: sshbuf_new failed", __func__);
+ fatal_f("sshbuf_new failed");
if ((r = sshbuf_put_u8(msg, code)) != 0 ||
(r = sshbuf_put_u32(msg, id)) != 0 ||
(r = sshbuf_put_string(msg, s, len)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "compose");
send_msg(conn, msg);
debug3("Sent message fd %d T:%u I:%u", conn->fd_out, code, id);
sshbuf_free(msg);
@@ -199,14 +254,15 @@ send_string_attrs_request(struct sftp_conn *conn, u_int id, u_int code,
int r;
if ((msg = sshbuf_new()) == NULL)
- fatal("%s: sshbuf_new failed", __func__);
+ fatal_f("sshbuf_new failed");
if ((r = sshbuf_put_u8(msg, code)) != 0 ||
(r = sshbuf_put_u32(msg, id)) != 0 ||
(r = sshbuf_put_string(msg, s, len)) != 0 ||
(r = encode_attrib(msg, a)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "compose");
send_msg(conn, msg);
- debug3("Sent message fd %d T:%u I:%u", conn->fd_out, code, id);
+ debug3("Sent message fd %d T:%u I:%u F:0x%04x M:%05o",
+ conn->fd_out, code, id, a->flags, a->perm);
sshbuf_free(msg);
}
@@ -219,11 +275,11 @@ get_status(struct sftp_conn *conn, u_int expected_id)
int r;
if ((msg = sshbuf_new()) == NULL)
- fatal("%s: sshbuf_new failed", __func__);
+ fatal_f("sshbuf_new failed");
get_msg(conn, msg);
if ((r = sshbuf_get_u8(msg, &type)) != 0 ||
(r = sshbuf_get_u32(msg, &id)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "compose");
if (id != expected_id)
fatal("ID mismatch (%u != %u)", id, expected_id);
@@ -232,7 +288,7 @@ get_status(struct sftp_conn *conn, u_int expected_id)
SSH2_FXP_STATUS, type);
if ((r = sshbuf_get_u32(msg, &status)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "parse");
sshbuf_free(msg);
debug3("SSH2_FXP_STATUS %u", status);
@@ -258,18 +314,18 @@ get_handle(struct sftp_conn *conn, u_int expected_id, size_t *len,
va_end(args);
if ((msg = sshbuf_new()) == NULL)
- fatal("%s: sshbuf_new failed", __func__);
+ fatal_f("sshbuf_new failed");
get_msg(conn, msg);
if ((r = sshbuf_get_u8(msg, &type)) != 0 ||
(r = sshbuf_get_u32(msg, &id)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "parse");
if (id != expected_id)
fatal("%s: ID mismatch (%u != %u)",
errfmt == NULL ? __func__ : errmsg, id, expected_id);
if (type == SSH2_FXP_STATUS) {
if ((r = sshbuf_get_u32(msg, &status)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "parse status");
if (errfmt != NULL)
error("%s: %s", errmsg, fx2txt(status));
sshbuf_free(msg);
@@ -279,12 +335,13 @@ get_handle(struct sftp_conn *conn, u_int expected_id, size_t *len,
errfmt == NULL ? __func__ : errmsg, SSH2_FXP_HANDLE, type);
if ((r = sshbuf_get_string(msg, &handle, len)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "parse handle");
sshbuf_free(msg);
return handle;
}
+/* XXX returing &static is error-prone. Refactor to fill *Attrib argument */
static Attrib *
get_decode_stat(struct sftp_conn *conn, u_int expected_id, int quiet)
{
@@ -295,21 +352,20 @@ get_decode_stat(struct sftp_conn *conn, u_int expected_id, int quiet)
static Attrib a;
if ((msg = sshbuf_new()) == NULL)
- fatal("%s: sshbuf_new failed", __func__);
+ fatal_f("sshbuf_new failed");
get_msg(conn, msg);
if ((r = sshbuf_get_u8(msg, &type)) != 0 ||
(r = sshbuf_get_u32(msg, &id)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "parse");
- debug3("Received stat reply T:%u I:%u", type, id);
if (id != expected_id)
fatal("ID mismatch (%u != %u)", id, expected_id);
if (type == SSH2_FXP_STATUS) {
u_int status;
if ((r = sshbuf_get_u32(msg, &status)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "parse status");
if (quiet)
debug("Couldn't stat remote file: %s", fx2txt(status));
else
@@ -321,10 +377,12 @@ get_decode_stat(struct sftp_conn *conn, u_int expected_id, int quiet)
SSH2_FXP_ATTRS, type);
}
if ((r = decode_attrib(msg, &a)) != 0) {
- error("%s: couldn't decode attrib: %s", __func__, ssh_err(r));
+ error_fr(r, "decode_attrib");
sshbuf_free(msg);
return NULL;
}
+ debug3("Recevied stat reply T:%u I:%u F:0x%04x M:%05o",
+ type, id, a.flags, a.perm);
sshbuf_free(msg);
return &a;
@@ -341,12 +399,12 @@ get_decode_statvfs(struct sftp_conn *conn, struct sftp_statvfs *st,
int r;
if ((msg = sshbuf_new()) == NULL)
- fatal("%s: sshbuf_new failed", __func__);
+ fatal_f("sshbuf_new failed");
get_msg(conn, msg);
if ((r = sshbuf_get_u8(msg, &type)) != 0 ||
(r = sshbuf_get_u32(msg, &id)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "parse");
debug3("Received statvfs reply T:%u I:%u", type, id);
if (id != expected_id)
@@ -355,7 +413,7 @@ get_decode_statvfs(struct sftp_conn *conn, struct sftp_statvfs *st,
u_int status;
if ((r = sshbuf_get_u32(msg, &status)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "parse status");
if (quiet)
debug("Couldn't statvfs: %s", fx2txt(status));
else
@@ -379,7 +437,7 @@ get_decode_statvfs(struct sftp_conn *conn, struct sftp_statvfs *st,
(r = sshbuf_get_u64(msg, &st->f_fsid)) != 0 ||
(r = sshbuf_get_u64(msg, &flag)) != 0 ||
(r = sshbuf_get_u64(msg, &st->f_namemax)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "parse statvfs");
st->f_flag = (flag & SSH2_FXE_STATVFS_ST_RDONLY) ? ST_RDONLY : 0;
st->f_flag |= (flag & SSH2_FXE_STATVFS_ST_NOSUID) ? ST_NOSUID : 0;
@@ -402,25 +460,26 @@ do_init(int fd_in, int fd_out, u_int transfer_buflen, u_int num_requests,
ret->msg_id = 1;
ret->fd_in = fd_in;
ret->fd_out = fd_out;
- ret->transfer_buflen = transfer_buflen;
- ret->num_requests = num_requests;
+ ret->download_buflen = ret->upload_buflen =
+ transfer_buflen ? transfer_buflen : DEFAULT_COPY_BUFLEN;
+ ret->num_requests =
+ num_requests ? num_requests : DEFAULT_NUM_REQUESTS;
ret->exts = 0;
ret->limit_kbps = 0;
if ((msg = sshbuf_new()) == NULL)
- fatal("%s: sshbuf_new failed", __func__);
+ fatal_f("sshbuf_new failed");
if ((r = sshbuf_put_u8(msg, SSH2_FXP_INIT)) != 0 ||
(r = sshbuf_put_u32(msg, SSH2_FILEXFER_VERSION)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
- send_msg(ret, msg);
+ fatal_fr(r, "parse");
- sshbuf_reset(msg);
+ send_msg(ret, msg);
get_msg_extended(ret, msg, 1);
/* Expecting a VERSION reply */
if ((r = sshbuf_get_u8(msg, &type)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "parse type");
if (type != SSH2_FXP_VERSION) {
error("Invalid packet back from SSH2_FXP_INIT (type %u)",
type);
@@ -429,7 +488,7 @@ do_init(int fd_in, int fd_out, u_int transfer_buflen, u_int num_requests,
return(NULL);
}
if ((r = sshbuf_get_u32(msg, &ret->version)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "parse version");
debug2("Remote version: %u", ret->version);
@@ -442,7 +501,7 @@ do_init(int fd_in, int fd_out, u_int transfer_buflen, u_int num_requests,
if ((r = sshbuf_get_cstring(msg, &name, NULL)) != 0 ||
(r = sshbuf_get_string(msg, &value, &vlen)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "parse extension");
if (strcmp(name, "posix-rename@openssh.com") == 0 &&
strcmp((char *)value, "1") == 0) {
ret->exts |= SFTP_EXT_POSIX_RENAME;
@@ -463,6 +522,18 @@ do_init(int fd_in, int fd_out, u_int transfer_buflen, u_int num_requests,
strcmp((char *)value, "1") == 0) {
ret->exts |= SFTP_EXT_FSYNC;
known = 1;
+ } else if (strcmp(name, "lsetstat@openssh.com") == 0 &&
+ strcmp((char *)value, "1") == 0) {
+ ret->exts |= SFTP_EXT_LSETSTAT;
+ known = 1;
+ } else if (strcmp(name, "limits@openssh.com") == 0 &&
+ strcmp((char *)value, "1") == 0) {
+ ret->exts |= SFTP_EXT_LIMITS;
+ known = 1;
+ } else if (strcmp(name, "expand-path@openssh.com") == 0 &&
+ strcmp((char *)value, "1") == 0) {
+ ret->exts |= SFTP_EXT_PATH_EXPAND;
+ known = 1;
}
if (known) {
debug2("Server supports extension \"%s\" revision %s",
@@ -476,16 +547,42 @@ do_init(int fd_in, int fd_out, u_int transfer_buflen, u_int num_requests,
sshbuf_free(msg);
+ /* Query the server for its limits */
+ if (ret->exts & SFTP_EXT_LIMITS) {
+ struct sftp_limits limits;
+ if (do_limits(ret, &limits) != 0)
+ fatal_f("limits failed");
+
+ /* If the caller did not specify, find a good value */
+ if (transfer_buflen == 0) {
+ ret->download_buflen = limits.read_length;
+ ret->upload_buflen = limits.write_length;
+ debug("Using server download size %u", ret->download_buflen);
+ debug("Using server upload size %u", ret->upload_buflen);
+ }
+
+ /* Use the server limit to scale down our value only */
+ if (num_requests == 0 && limits.open_handles) {
+ ret->num_requests =
+ MINIMUM(DEFAULT_NUM_REQUESTS, limits.open_handles);
+ debug("Server handle limit %llu; using %u",
+ (unsigned long long)limits.open_handles,
+ ret->num_requests);
+ }
+ }
+
/* Some filexfer v.0 servers don't support large packets */
- if (ret->version == 0)
- ret->transfer_buflen = MINIMUM(ret->transfer_buflen, 20480);
+ if (ret->version == 0) {
+ ret->download_buflen = MINIMUM(ret->download_buflen, 20480);
+ ret->upload_buflen = MINIMUM(ret->upload_buflen, 20480);
+ }
ret->limit_kbps = limit_kbps;
if (ret->limit_kbps > 0) {
bandwidth_limit_init(&ret->bwlimit_in, ret->limit_kbps,
- ret->transfer_buflen);
+ ret->download_buflen);
bandwidth_limit_init(&ret->bwlimit_out, ret->limit_kbps,
- ret->transfer_buflen);
+ ret->upload_buflen);
}
return ret;
@@ -498,6 +595,60 @@ sftp_proto_version(struct sftp_conn *conn)
}
int
+do_limits(struct sftp_conn *conn, struct sftp_limits *limits)
+{
+ u_int id, msg_id;
+ u_char type;
+ struct sshbuf *msg;
+ int r;
+
+ if ((conn->exts & SFTP_EXT_LIMITS) == 0) {
+ error("Server does not support limits@openssh.com extension");
+ return -1;
+ }
+
+ if ((msg = sshbuf_new()) == NULL)
+ fatal_f("sshbuf_new failed");
+
+ id = conn->msg_id++;
+ if ((r = sshbuf_put_u8(msg, SSH2_FXP_EXTENDED)) != 0 ||
+ (r = sshbuf_put_u32(msg, id)) != 0 ||
+ (r = sshbuf_put_cstring(msg, "limits@openssh.com")) != 0)
+ fatal_fr(r, "compose");
+ send_msg(conn, msg);
+ debug3("Sent message limits@openssh.com I:%u", id);
+
+ get_msg(conn, msg);
+
+ if ((r = sshbuf_get_u8(msg, &type)) != 0 ||
+ (r = sshbuf_get_u32(msg, &msg_id)) != 0)
+ fatal_fr(r, "parse");
+
+ debug3("Received limits reply T:%u I:%u", type, msg_id);
+ if (id != msg_id)
+ fatal("ID mismatch (%u != %u)", msg_id, id);
+ if (type != SSH2_FXP_EXTENDED_REPLY) {
+ debug_f("expected SSH2_FXP_EXTENDED_REPLY(%u) packet, got %u",
+ SSH2_FXP_EXTENDED_REPLY, type);
+ /* Disable the limits extension */
+ conn->exts &= ~SFTP_EXT_LIMITS;
+ sshbuf_free(msg);
+ return 0;
+ }
+
+ memset(limits, 0, sizeof(*limits));
+ if ((r = sshbuf_get_u64(msg, &limits->packet_length)) != 0 ||
+ (r = sshbuf_get_u64(msg, &limits->read_length)) != 0 ||
+ (r = sshbuf_get_u64(msg, &limits->write_length)) != 0 ||
+ (r = sshbuf_get_u64(msg, &limits->open_handles)) != 0)
+ fatal_fr(r, "parse limits");
+
+ sshbuf_free(msg);
+
+ return 0;
+}
+
+int
do_close(struct sftp_conn *conn, const u_char *handle, u_int handle_len)
{
u_int id, status;
@@ -505,13 +656,13 @@ do_close(struct sftp_conn *conn, const u_char *handle, u_int handle_len)
int r;
if ((msg = sshbuf_new()) == NULL)
- fatal("%s: sshbuf_new failed", __func__);
+ fatal_f("sshbuf_new failed");
id = conn->msg_id++;
if ((r = sshbuf_put_u8(msg, SSH2_FXP_CLOSE)) != 0 ||
(r = sshbuf_put_u32(msg, id)) != 0 ||
(r = sshbuf_put_string(msg, handle, handle_len)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "parse");
send_msg(conn, msg);
debug3("Sent message SSH2_FXP_CLOSE I:%u", id);
@@ -542,11 +693,11 @@ do_lsreaddir(struct sftp_conn *conn, const char *path, int print_flag,
id = conn->msg_id++;
if ((msg = sshbuf_new()) == NULL)
- fatal("%s: sshbuf_new failed", __func__);
+ fatal_f("sshbuf_new failed");
if ((r = sshbuf_put_u8(msg, SSH2_FXP_OPENDIR)) != 0 ||
(r = sshbuf_put_u32(msg, id)) != 0 ||
(r = sshbuf_put_cstring(msg, path)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "compose OPENDIR");
send_msg(conn, msg);
handle = get_handle(conn, id, &handle_len,
@@ -571,7 +722,7 @@ do_lsreaddir(struct sftp_conn *conn, const char *path, int print_flag,
if ((r = sshbuf_put_u8(msg, SSH2_FXP_READDIR)) != 0 ||
(r = sshbuf_put_u32(msg, id)) != 0 ||
(r = sshbuf_put_string(msg, handle, handle_len)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "compose READDIR");
send_msg(conn, msg);
sshbuf_reset(msg);
@@ -580,7 +731,7 @@ do_lsreaddir(struct sftp_conn *conn, const char *path, int print_flag,
if ((r = sshbuf_get_u8(msg, &type)) != 0 ||
(r = sshbuf_get_u32(msg, &id)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "parse");
debug3("Received reply T:%u I:%u", type, id);
@@ -591,8 +742,7 @@ do_lsreaddir(struct sftp_conn *conn, const char *path, int print_flag,
u_int rstatus;
if ((r = sshbuf_get_u32(msg, &rstatus)) != 0)
- fatal("%s: buffer error: %s",
- __func__, ssh_err(r));
+ fatal_fr(r, "parse status");
debug3("Received SSH2_FXP_STATUS %d", rstatus);
if (rstatus == SSH2_FX_EOF)
break;
@@ -603,9 +753,9 @@ do_lsreaddir(struct sftp_conn *conn, const char *path, int print_flag,
SSH2_FXP_NAME, type);
if ((r = sshbuf_get_u32(msg, &count)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "parse count");
if (count > SSHBUF_SIZE_MAX)
- fatal("%s: nonsensical number of entries", __func__);
+ fatal_f("nonsensical number of entries");
if (count == 0)
break;
debug3("Received %d SSH2_FXP_NAME responses", count);
@@ -617,15 +767,12 @@ do_lsreaddir(struct sftp_conn *conn, const char *path, int print_flag,
NULL)) != 0 ||
(r = sshbuf_get_cstring(msg, &longname,
NULL)) != 0)
- fatal("%s: buffer error: %s",
- __func__, ssh_err(r));
+ fatal_fr(r, "parse filenames");
if ((r = decode_attrib(msg, &a)) != 0) {
- error("%s: couldn't decode attrib: %s",
- __func__, ssh_err(r));
+ error_fr(r, "couldn't decode attrib");
free(filename);
free(longname);
- sshbuf_free(msg);
- return -1;
+ goto out;
}
if (print_flag)
@@ -822,8 +969,9 @@ do_fsetstat(struct sftp_conn *conn, const u_char *handle, u_int handle_len,
return status == SSH2_FX_OK ? 0 : -1;
}
-char *
-do_realpath(struct sftp_conn *conn, const char *path)
+/* Implements both the realpath and expand-path operations */
+static char *
+do_realpath_expand(struct sftp_conn *conn, const char *path, int expand)
{
struct sshbuf *msg;
u_int expected_id, count, id;
@@ -831,18 +979,30 @@ do_realpath(struct sftp_conn *conn, const char *path)
Attrib a;
u_char type;
int r;
+ const char *what = "SSH2_FXP_REALPATH";
- expected_id = id = conn->msg_id++;
- send_string_request(conn, id, SSH2_FXP_REALPATH, path,
- strlen(path));
-
+ if (expand)
+ what = "expand-path@openssh.com";
if ((msg = sshbuf_new()) == NULL)
- fatal("%s: sshbuf_new failed", __func__);
+ fatal_f("sshbuf_new failed");
+ expected_id = id = conn->msg_id++;
+ if (expand) {
+ if ((r = sshbuf_put_u8(msg, SSH2_FXP_EXTENDED)) != 0 ||
+ (r = sshbuf_put_u32(msg, id)) != 0 ||
+ (r = sshbuf_put_cstring(msg,
+ "expand-path@openssh.com")) != 0 ||
+ (r = sshbuf_put_cstring(msg, path)) != 0)
+ fatal_fr(r, "compose %s", what);
+ send_msg(conn, msg);
+ } else {
+ send_string_request(conn, id, SSH2_FXP_REALPATH,
+ path, strlen(path));
+ }
get_msg(conn, msg);
if ((r = sshbuf_get_u8(msg, &type)) != 0 ||
(r = sshbuf_get_u32(msg, &id)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "parse");
if (id != expected_id)
fatal("ID mismatch (%u != %u)", id, expected_id);
@@ -851,7 +1011,7 @@ do_realpath(struct sftp_conn *conn, const char *path)
u_int status;
if ((r = sshbuf_get_u32(msg, &status)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "parse status");
error("Couldn't canonicalize: %s", fx2txt(status));
sshbuf_free(msg);
return NULL;
@@ -860,17 +1020,16 @@ do_realpath(struct sftp_conn *conn, const char *path)
SSH2_FXP_NAME, type);
if ((r = sshbuf_get_u32(msg, &count)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "parse count");
if (count != 1)
- fatal("Got multiple names (%d) from SSH_FXP_REALPATH", count);
+ fatal("Got multiple names (%d) from %s", count, what);
if ((r = sshbuf_get_cstring(msg, &filename, NULL)) != 0 ||
(r = sshbuf_get_cstring(msg, &longname, NULL)) != 0 ||
(r = decode_attrib(msg, &a)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "parse filename/attrib");
- debug3("SSH_FXP_REALPATH %s -> %s size %lu", path, filename,
- (unsigned long)a.size);
+ debug3("%s %s -> %s", what, path, filename);
free(longname);
@@ -879,6 +1038,28 @@ do_realpath(struct sftp_conn *conn, const char *path)
return(filename);
}
+char *
+do_realpath(struct sftp_conn *conn, const char *path)
+{
+ return do_realpath_expand(conn, path, 0);
+}
+
+int
+can_expand_path(struct sftp_conn *conn)
+{
+ return (conn->exts & SFTP_EXT_PATH_EXPAND) != 0;
+}
+
+char *
+do_expand_path(struct sftp_conn *conn, const char *path)
+{
+ if (!can_expand_path(conn)) {
+ debug3_f("no server support, fallback to realpath");
+ return do_realpath_expand(conn, path, 0);
+ }
+ return do_realpath_expand(conn, path, 1);
+}
+
int
do_rename(struct sftp_conn *conn, const char *oldpath, const char *newpath,
int force_legacy)
@@ -888,7 +1069,7 @@ do_rename(struct sftp_conn *conn, const char *oldpath, const char *newpath,
int r, use_ext = (conn->exts & SFTP_EXT_POSIX_RENAME) && !force_legacy;
if ((msg = sshbuf_new()) == NULL)
- fatal("%s: sshbuf_new failed", __func__);
+ fatal_f("sshbuf_new failed");
/* Send rename request */
id = conn->msg_id++;
@@ -897,15 +1078,15 @@ do_rename(struct sftp_conn *conn, const char *oldpath, const char *newpath,
(r = sshbuf_put_u32(msg, id)) != 0 ||
(r = sshbuf_put_cstring(msg,
"posix-rename@openssh.com")) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "compose posix-rename");
} else {
if ((r = sshbuf_put_u8(msg, SSH2_FXP_RENAME)) != 0 ||
(r = sshbuf_put_u32(msg, id)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "compose rename");
}
if ((r = sshbuf_put_cstring(msg, oldpath)) != 0 ||
(r = sshbuf_put_cstring(msg, newpath)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "compose paths");
send_msg(conn, msg);
debug3("Sent message %s \"%s\" -> \"%s\"",
use_ext ? "posix-rename@openssh.com" :
@@ -933,7 +1114,7 @@ do_hardlink(struct sftp_conn *conn, const char *oldpath, const char *newpath)
}
if ((msg = sshbuf_new()) == NULL)
- fatal("%s: sshbuf_new failed", __func__);
+ fatal_f("sshbuf_new failed");
/* Send link request */
id = conn->msg_id++;
@@ -942,10 +1123,10 @@ do_hardlink(struct sftp_conn *conn, const char *oldpath, const char *newpath)
(r = sshbuf_put_cstring(msg, "hardlink@openssh.com")) != 0 ||
(r = sshbuf_put_cstring(msg, oldpath)) != 0 ||
(r = sshbuf_put_cstring(msg, newpath)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "compose");
send_msg(conn, msg);
debug3("Sent message hardlink@openssh.com \"%s\" -> \"%s\"",
- oldpath, newpath);
+ oldpath, newpath);
sshbuf_free(msg);
status = get_status(conn, id);
@@ -969,7 +1150,7 @@ do_symlink(struct sftp_conn *conn, const char *oldpath, const char *newpath)
}
if ((msg = sshbuf_new()) == NULL)
- fatal("%s: sshbuf_new failed", __func__);
+ fatal_f("sshbuf_new failed");
/* Send symlink request */
id = conn->msg_id++;
@@ -977,7 +1158,7 @@ do_symlink(struct sftp_conn *conn, const char *oldpath, const char *newpath)
(r = sshbuf_put_u32(msg, id)) != 0 ||
(r = sshbuf_put_cstring(msg, oldpath)) != 0 ||
(r = sshbuf_put_cstring(msg, newpath)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "compose");
send_msg(conn, msg);
debug3("Sent message SSH2_FXP_SYMLINK \"%s\" -> \"%s\"", oldpath,
newpath);
@@ -1004,13 +1185,13 @@ do_fsync(struct sftp_conn *conn, u_char *handle, u_int handle_len)
/* Send fsync request */
if ((msg = sshbuf_new()) == NULL)
- fatal("%s: sshbuf_new failed", __func__);
+ fatal_f("sshbuf_new failed");
id = conn->msg_id++;
if ((r = sshbuf_put_u8(msg, SSH2_FXP_EXTENDED)) != 0 ||
(r = sshbuf_put_u32(msg, id)) != 0 ||
(r = sshbuf_put_cstring(msg, "fsync@openssh.com")) != 0 ||
(r = sshbuf_put_string(msg, handle, handle_len)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "compose");
send_msg(conn, msg);
debug3("Sent message fsync@openssh.com I:%u", id);
sshbuf_free(msg);
@@ -1037,12 +1218,12 @@ do_readlink(struct sftp_conn *conn, const char *path)
send_string_request(conn, id, SSH2_FXP_READLINK, path, strlen(path));
if ((msg = sshbuf_new()) == NULL)
- fatal("%s: sshbuf_new failed", __func__);
+ fatal_f("sshbuf_new failed");
get_msg(conn, msg);
if ((r = sshbuf_get_u8(msg, &type)) != 0 ||
(r = sshbuf_get_u32(msg, &id)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "parse");
if (id != expected_id)
fatal("ID mismatch (%u != %u)", id, expected_id);
@@ -1051,7 +1232,7 @@ do_readlink(struct sftp_conn *conn, const char *path)
u_int status;
if ((r = sshbuf_get_u32(msg, &status)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "parse status");
error("Couldn't readlink: %s", fx2txt(status));
sshbuf_free(msg);
return(NULL);
@@ -1060,14 +1241,14 @@ do_readlink(struct sftp_conn *conn, const char *path)
SSH2_FXP_NAME, type);
if ((r = sshbuf_get_u32(msg, &count)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "parse count");
if (count != 1)
fatal("Got multiple names (%d) from SSH_FXP_READLINK", count);
if ((r = sshbuf_get_cstring(msg, &filename, NULL)) != 0 ||
(r = sshbuf_get_cstring(msg, &longname, NULL)) != 0 ||
(r = decode_attrib(msg, &a)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "parse filenames/attrib");
debug3("SSH_FXP_READLINK %s -> %s", path, filename);
@@ -1095,13 +1276,12 @@ do_statvfs(struct sftp_conn *conn, const char *path, struct sftp_statvfs *st,
id = conn->msg_id++;
if ((msg = sshbuf_new()) == NULL)
- fatal("%s: sshbuf_new failed", __func__);
- sshbuf_reset(msg);
+ fatal_f("sshbuf_new failed");
if ((r = sshbuf_put_u8(msg, SSH2_FXP_EXTENDED)) != 0 ||
(r = sshbuf_put_u32(msg, id)) != 0 ||
(r = sshbuf_put_cstring(msg, "statvfs@openssh.com")) != 0 ||
(r = sshbuf_put_cstring(msg, path)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "compose");
send_msg(conn, msg);
sshbuf_free(msg);
@@ -1124,13 +1304,12 @@ do_fstatvfs(struct sftp_conn *conn, const u_char *handle, u_int handle_len,
id = conn->msg_id++;
if ((msg = sshbuf_new()) == NULL)
- fatal("%s: sshbuf_new failed", __func__);
- sshbuf_reset(msg);
+ fatal_f("sshbuf_new failed");
if ((r = sshbuf_put_u8(msg, SSH2_FXP_EXTENDED)) != 0 ||
(r = sshbuf_put_u32(msg, id)) != 0 ||
(r = sshbuf_put_cstring(msg, "fstatvfs@openssh.com")) != 0 ||
(r = sshbuf_put_string(msg, handle, handle_len)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "compose");
send_msg(conn, msg);
sshbuf_free(msg);
@@ -1138,6 +1317,38 @@ do_fstatvfs(struct sftp_conn *conn, const u_char *handle, u_int handle_len,
}
#endif
+int
+do_lsetstat(struct sftp_conn *conn, const char *path, Attrib *a)
+{
+ struct sshbuf *msg;
+ u_int status, id;
+ int r;
+
+ if ((conn->exts & SFTP_EXT_LSETSTAT) == 0) {
+ error("Server does not support lsetstat@openssh.com extension");
+ return -1;
+ }
+
+ id = conn->msg_id++;
+ if ((msg = sshbuf_new()) == NULL)
+ fatal_f("sshbuf_new failed");
+ if ((r = sshbuf_put_u8(msg, SSH2_FXP_EXTENDED)) != 0 ||
+ (r = sshbuf_put_u32(msg, id)) != 0 ||
+ (r = sshbuf_put_cstring(msg, "lsetstat@openssh.com")) != 0 ||
+ (r = sshbuf_put_cstring(msg, path)) != 0 ||
+ (r = encode_attrib(msg, a)) != 0)
+ fatal_fr(r, "compose");
+ send_msg(conn, msg);
+ sshbuf_free(msg);
+
+ status = get_status(conn, id);
+ if (status != SSH2_FX_OK)
+ error("Couldn't setstat on \"%s\": %s", path,
+ fx2txt(status));
+
+ return status == SSH2_FX_OK ? 0 : -1;
+}
+
static void
send_read_request(struct sftp_conn *conn, u_int id, u_int64_t offset,
u_int len, const u_char *handle, u_int handle_len)
@@ -1146,16 +1357,69 @@ send_read_request(struct sftp_conn *conn, u_int id, u_int64_t offset,
int r;
if ((msg = sshbuf_new()) == NULL)
- fatal("%s: sshbuf_new failed", __func__);
- sshbuf_reset(msg);
+ fatal_f("sshbuf_new failed");
if ((r = sshbuf_put_u8(msg, SSH2_FXP_READ)) != 0 ||
(r = sshbuf_put_u32(msg, id)) != 0 ||
(r = sshbuf_put_string(msg, handle, handle_len)) != 0 ||
(r = sshbuf_put_u64(msg, offset)) != 0 ||
(r = sshbuf_put_u32(msg, len)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "compose");
+ send_msg(conn, msg);
+ sshbuf_free(msg);
+}
+
+static int
+send_open(struct sftp_conn *conn, const char *path, const char *tag,
+ u_int openmode, Attrib *a, u_char **handlep, size_t *handle_lenp)
+{
+ Attrib junk;
+ u_char *handle;
+ size_t handle_len;
+ struct sshbuf *msg;
+ int r;
+ u_int id;
+
+ *handlep = NULL;
+ *handle_lenp = 0;
+
+ if (a == NULL) {
+ attrib_clear(&junk); /* Send empty attributes */
+ a = &junk;
+ }
+ /* Send open request */
+ if ((msg = sshbuf_new()) == NULL)
+ fatal_f("sshbuf_new failed");
+ id = conn->msg_id++;
+ if ((r = sshbuf_put_u8(msg, SSH2_FXP_OPEN)) != 0 ||
+ (r = sshbuf_put_u32(msg, id)) != 0 ||
+ (r = sshbuf_put_cstring(msg, path)) != 0 ||
+ (r = sshbuf_put_u32(msg, openmode)) != 0 ||
+ (r = encode_attrib(msg, a)) != 0)
+ fatal_fr(r, "compose %s open", tag);
send_msg(conn, msg);
sshbuf_free(msg);
+ debug3("Sent %s message SSH2_FXP_OPEN I:%u P:%s M:0x%04x",
+ tag, id, path, openmode);
+ if ((handle = get_handle(conn, id, &handle_len,
+ "%s open(\"%s\")", tag, path)) == NULL)
+ return -1;
+ /* success */
+ *handlep = handle;
+ *handle_lenp = handle_len;
+ return 0;
+}
+
+static const char *
+progress_meter_path(const char *path)
+{
+ const char *progresspath;
+
+ if ((progresspath = strrchr(path, '/')) == NULL)
+ return path;
+ progresspath++;
+ if (*progresspath == '\0')
+ return path;
+ return progresspath;
}
int
@@ -1163,23 +1427,16 @@ do_download(struct sftp_conn *conn, const char *remote_path,
const char *local_path, Attrib *a, int preserve_flag, int resume_flag,
int fsync_flag)
{
- Attrib junk;
struct sshbuf *msg;
u_char *handle;
int local_fd = -1, write_error;
- int read_error, write_errno, reordered = 0, r;
+ int read_error, write_errno, lmodified = 0, reordered = 0, r;
u_int64_t offset = 0, size, highwater;
u_int mode, id, buflen, num_req, max_req, status = SSH2_FX_OK;
off_t progress_counter;
size_t handle_len;
struct stat st;
- struct request {
- u_int id;
- size_t len;
- u_int64_t offset;
- TAILQ_ENTRY(request) tq;
- };
- TAILQ_HEAD(reqhead, request) requests;
+ struct requests requests;
struct request *req;
u_char type;
@@ -1205,29 +1462,12 @@ do_download(struct sftp_conn *conn, const char *remote_path,
else
size = 0;
- buflen = conn->transfer_buflen;
- if ((msg = sshbuf_new()) == NULL)
- fatal("%s: sshbuf_new failed", __func__);
-
- attrib_clear(&junk); /* Send empty attributes */
+ buflen = conn->download_buflen;
/* Send open request */
- id = conn->msg_id++;
- if ((r = sshbuf_put_u8(msg, SSH2_FXP_OPEN)) != 0 ||
- (r = sshbuf_put_u32(msg, id)) != 0 ||
- (r = sshbuf_put_cstring(msg, remote_path)) != 0 ||
- (r = sshbuf_put_u32(msg, SSH2_FXF_READ)) != 0 ||
- (r = encode_attrib(msg, &junk)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
- send_msg(conn, msg);
- debug3("Sent message SSH2_FXP_OPEN I:%u P:%s", id, remote_path);
-
- handle = get_handle(conn, id, &handle_len,
- "remote open(\"%s\")", remote_path);
- if (handle == NULL) {
- sshbuf_free(msg);
- return(-1);
- }
+ if (send_open(conn, remote_path, "remote", SSH2_FXF_READ, NULL,
+ &handle, &handle_len) != 0)
+ return -1;
local_fd = open(local_path,
O_WRONLY | O_CREAT | (resume_flag ? 0 : O_TRUNC), mode | S_IWUSR);
@@ -1252,7 +1492,6 @@ do_download(struct sftp_conn *conn, const char *remote_path,
"local file is larger than remote", local_path);
fail:
do_close(conn, handle, handle_len);
- sshbuf_free(msg);
free(handle);
if (local_fd != -1)
close(local_fd);
@@ -1266,8 +1505,13 @@ do_download(struct sftp_conn *conn, const char *remote_path,
max_req = 1;
progress_counter = offset;
- if (showprogress && size != 0)
- start_progress_meter(remote_path, size, &progress_counter);
+ if (showprogress && size != 0) {
+ start_progress_meter(progress_meter_path(remote_path),
+ size, &progress_counter);
+ }
+
+ if ((msg = sshbuf_new()) == NULL)
+ fatal_f("sshbuf_new failed");
while (num_req > 0 || max_req > 0) {
u_char *data;
@@ -1289,13 +1533,10 @@ do_download(struct sftp_conn *conn, const char *remote_path,
(unsigned long long)offset,
(unsigned long long)offset + buflen - 1,
num_req, max_req);
- req = xcalloc(1, sizeof(*req));
- req->id = conn->msg_id++;
- req->len = buflen;
- req->offset = offset;
+ req = request_enqueue(&requests, conn->msg_id++,
+ buflen, offset);
offset += buflen;
num_req++;
- TAILQ_INSERT_TAIL(&requests, req, tq);
send_read_request(conn, req->id, req->offset,
req->len, handle, handle_len);
}
@@ -1304,22 +1545,17 @@ do_download(struct sftp_conn *conn, const char *remote_path,
get_msg(conn, msg);
if ((r = sshbuf_get_u8(msg, &type)) != 0 ||
(r = sshbuf_get_u32(msg, &id)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "parse");
debug3("Received reply T:%u I:%u R:%d", type, id, max_req);
/* Find the request in our queue */
- for (req = TAILQ_FIRST(&requests);
- req != NULL && req->id != id;
- req = TAILQ_NEXT(req, tq))
- ;
- if (req == NULL)
+ if ((req = request_find(&requests, id)) == NULL)
fatal("Unexpected reply %u", id);
switch (type) {
case SSH2_FXP_STATUS:
if ((r = sshbuf_get_u32(msg, &status)) != 0)
- fatal("%s: buffer error: %s",
- __func__, ssh_err(r));
+ fatal_fr(r, "parse status");
if (status != SSH2_FX_EOF)
read_error = 1;
max_req = 0;
@@ -1329,14 +1565,14 @@ do_download(struct sftp_conn *conn, const char *remote_path,
break;
case SSH2_FXP_DATA:
if ((r = sshbuf_get_string(msg, &data, &len)) != 0)
- fatal("%s: buffer error: %s",
- __func__, ssh_err(r));
+ fatal_fr(r, "parse data");
debug3("Received data %llu -> %llu",
(unsigned long long)req->offset,
(unsigned long long)req->offset + len - 1);
if (len > req->len)
fatal("Received more data than asked for "
"%zu > %zu", len, req->len);
+ lmodified = 1;
if ((lseek(local_fd, req->offset, SEEK_SET) == -1 ||
atomicio(vwrite, local_fd, data, len) != len) &&
!write_error) {
@@ -1379,7 +1615,7 @@ do_download(struct sftp_conn *conn, const char *remote_path,
(unsigned long long)offset,
num_req);
max_req = 1;
- } else if (max_req <= conn->num_requests) {
+ } else if (max_req < conn->num_requests) {
++max_req;
}
}
@@ -1440,7 +1676,9 @@ do_download(struct sftp_conn *conn, const char *remote_path,
error("Can't set times on \"%s\": %s",
local_path, strerror(errno));
}
- if (fsync_flag) {
+ if (resume_flag && !lmodified)
+ logit("File \"%s\" was not modified", local_path);
+ else if (fsync_flag) {
debug("syncing \"%s\"", local_path);
if (fsync(local_fd) == -1)
error("Couldn't sync file \"%s\": %s",
@@ -1457,12 +1695,12 @@ do_download(struct sftp_conn *conn, const char *remote_path,
static int
download_dir_internal(struct sftp_conn *conn, const char *src, const char *dst,
int depth, Attrib *dirattrib, int preserve_flag, int print_flag,
- int resume_flag, int fsync_flag)
+ int resume_flag, int fsync_flag, int follow_link_flag)
{
int i, ret = 0;
SFTP_DIRENT **dir_entries;
char *filename, *new_src = NULL, *new_dst = NULL;
- mode_t mode = 0777;
+ mode_t mode = 0777, tmpmode = mode;
if (depth >= MAX_DIR_DEPTH) {
error("Maximum directory depth exceeded: %d levels", depth);
@@ -1478,17 +1716,18 @@ download_dir_internal(struct sftp_conn *conn, const char *src, const char *dst,
error("\"%s\" is not a directory", src);
return -1;
}
- if (print_flag)
+ if (print_flag && print_flag != SFTP_PROGRESS_ONLY)
mprintf("Retrieving %s\n", src);
- if (dirattrib->flags & SSH2_FILEXFER_ATTR_PERMISSIONS)
+ if (dirattrib->flags & SSH2_FILEXFER_ATTR_PERMISSIONS) {
mode = dirattrib->perm & 01777;
- else {
+ tmpmode = mode | (S_IWUSR|S_IXUSR);
+ } else {
debug("Server did not send permissions for "
"directory \"%s\"", dst);
}
- if (mkdir(dst, mode) == -1 && errno != EEXIST) {
+ if (mkdir(dst, tmpmode) == -1 && errno != EEXIST) {
error("mkdir %s: %s", dst, strerror(errno));
return -1;
}
@@ -1512,12 +1751,20 @@ download_dir_internal(struct sftp_conn *conn, const char *src, const char *dst,
continue;
if (download_dir_internal(conn, new_src, new_dst,
depth + 1, &(dir_entries[i]->a), preserve_flag,
- print_flag, resume_flag, fsync_flag) == -1)
+ print_flag, resume_flag,
+ fsync_flag, follow_link_flag) == -1)
ret = -1;
- } else if (S_ISREG(dir_entries[i]->a.perm) ) {
+ } else if (S_ISREG(dir_entries[i]->a.perm) ||
+ (follow_link_flag && S_ISLNK(dir_entries[i]->a.perm))) {
+ /*
+ * If this is a symlink then don't send the link's
+ * Attrib. do_download() will do a FXP_STAT operation
+ * and get the link target's attributes.
+ */
if (do_download(conn, new_src, new_dst,
- &(dir_entries[i]->a), preserve_flag,
- resume_flag, fsync_flag) == -1) {
+ S_ISLNK(dir_entries[i]->a.perm) ? NULL :
+ &(dir_entries[i]->a),
+ preserve_flag, resume_flag, fsync_flag) == -1) {
error("Download of file %s to %s failed",
new_src, new_dst);
ret = -1;
@@ -1543,6 +1790,10 @@ download_dir_internal(struct sftp_conn *conn, const char *src, const char *dst,
"\"%s\"", dst);
}
+ if (mode != tmpmode && chmod(dst, mode) == -1)
+ error("Can't set final mode on \"%s\": %s", dst,
+ strerror(errno));
+
free_sftp_dirents(dir_entries);
return ret;
@@ -1551,7 +1802,7 @@ download_dir_internal(struct sftp_conn *conn, const char *src, const char *dst,
int
download_dir(struct sftp_conn *conn, const char *src, const char *dst,
Attrib *dirattrib, int preserve_flag, int print_flag, int resume_flag,
- int fsync_flag)
+ int fsync_flag, int follow_link_flag)
{
char *src_canon;
int ret;
@@ -1562,7 +1813,8 @@ download_dir(struct sftp_conn *conn, const char *src, const char *dst,
}
ret = download_dir_internal(conn, src_canon, dst, 0,
- dirattrib, preserve_flag, print_flag, resume_flag, fsync_flag);
+ dirattrib, preserve_flag, print_flag, resume_flag, fsync_flag,
+ follow_link_flag);
free(src_canon);
return ret;
}
@@ -1582,14 +1834,8 @@ do_upload(struct sftp_conn *conn, const char *local_path,
Attrib a, *c = NULL;
u_int32_t startid;
u_int32_t ackid;
- struct outstanding_ack {
- u_int id;
- u_int len;
- off_t offset;
- TAILQ_ENTRY(outstanding_ack) tq;
- };
- TAILQ_HEAD(ackhead, outstanding_ack) acks;
- struct outstanding_ack *ack = NULL;
+ struct request *ack = NULL;
+ struct requests acks;
size_t handle_len;
TAILQ_INIT(&acks);
@@ -1627,7 +1873,7 @@ do_upload(struct sftp_conn *conn, const char *local_path,
if ((off_t)c->size >= sb.st_size) {
error("destination file bigger or same size as "
- "source file");
+ "source file");
close(local_fd);
return -1;
}
@@ -1638,40 +1884,27 @@ do_upload(struct sftp_conn *conn, const char *local_path,
}
}
- if ((msg = sshbuf_new()) == NULL)
- fatal("%s: sshbuf_new failed", __func__);
-
/* Send open request */
- id = conn->msg_id++;
- if ((r = sshbuf_put_u8(msg, SSH2_FXP_OPEN)) != 0 ||
- (r = sshbuf_put_u32(msg, id)) != 0 ||
- (r = sshbuf_put_cstring(msg, remote_path)) != 0 ||
- (r = sshbuf_put_u32(msg, SSH2_FXF_WRITE|SSH2_FXF_CREAT|
- (resume ? SSH2_FXF_APPEND : SSH2_FXF_TRUNC))) != 0 ||
- (r = encode_attrib(msg, &a)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
- send_msg(conn, msg);
- debug3("Sent message SSH2_FXP_OPEN I:%u P:%s", id, remote_path);
-
- sshbuf_reset(msg);
-
- handle = get_handle(conn, id, &handle_len,
- "remote open(\"%s\")", remote_path);
- if (handle == NULL) {
+ if (send_open(conn, remote_path, "dest", SSH2_FXF_WRITE|SSH2_FXF_CREAT|
+ (resume ? SSH2_FXF_APPEND : SSH2_FXF_TRUNC),
+ &a, &handle, &handle_len) != 0) {
close(local_fd);
- sshbuf_free(msg);
return -1;
}
+ id = conn->msg_id;
startid = ackid = id + 1;
- data = xmalloc(conn->transfer_buflen);
+ data = xmalloc(conn->upload_buflen);
/* Read from local and write to remote */
offset = progress_counter = (resume ? c->size : 0);
- if (showprogress)
- start_progress_meter(local_path, sb.st_size,
- &progress_counter);
+ if (showprogress) {
+ start_progress_meter(progress_meter_path(local_path),
+ sb.st_size, &progress_counter);
+ }
+ if ((msg = sshbuf_new()) == NULL)
+ fatal_f("sshbuf_new failed");
for (;;) {
int len;
@@ -1684,7 +1917,7 @@ do_upload(struct sftp_conn *conn, const char *local_path,
if (interrupted || status != SSH2_FX_OK)
len = 0;
else do
- len = read(local_fd, data, conn->transfer_buflen);
+ len = read(local_fd, data, conn->upload_buflen);
while ((len == -1) &&
(errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK));
@@ -1693,12 +1926,7 @@ do_upload(struct sftp_conn *conn, const char *local_path,
strerror(errno));
if (len != 0) {
- ack = xcalloc(1, sizeof(*ack));
- ack->id = ++id;
- ack->offset = offset;
- ack->len = len;
- TAILQ_INSERT_TAIL(&acks, ack, tq);
-
+ ack = request_enqueue(&acks, ++id, len, offset);
sshbuf_reset(msg);
if ((r = sshbuf_put_u8(msg, SSH2_FXP_WRITE)) != 0 ||
(r = sshbuf_put_u32(msg, ack->id)) != 0 ||
@@ -1706,8 +1934,7 @@ do_upload(struct sftp_conn *conn, const char *local_path,
handle_len)) != 0 ||
(r = sshbuf_put_u64(msg, offset)) != 0 ||
(r = sshbuf_put_string(msg, data, len)) != 0)
- fatal("%s: buffer error: %s",
- __func__, ssh_err(r));
+ fatal_fr(r, "compose");
send_msg(conn, msg);
debug3("Sent message SSH2_FXP_WRITE I:%u O:%llu S:%u",
id, (unsigned long long)offset, len);
@@ -1725,35 +1952,29 @@ do_upload(struct sftp_conn *conn, const char *local_path,
get_msg(conn, msg);
if ((r = sshbuf_get_u8(msg, &type)) != 0 ||
(r = sshbuf_get_u32(msg, &rid)) != 0)
- fatal("%s: buffer error: %s",
- __func__, ssh_err(r));
+ fatal_fr(r, "parse");
if (type != SSH2_FXP_STATUS)
fatal("Expected SSH2_FXP_STATUS(%d) packet, "
"got %d", SSH2_FXP_STATUS, type);
if ((r = sshbuf_get_u32(msg, &status)) != 0)
- fatal("%s: buffer error: %s",
- __func__, ssh_err(r));
+ fatal_fr(r, "parse status");
debug3("SSH2_FXP_STATUS %u", status);
/* Find the request in our queue */
- for (ack = TAILQ_FIRST(&acks);
- ack != NULL && ack->id != rid;
- ack = TAILQ_NEXT(ack, tq))
- ;
- if (ack == NULL)
+ if ((ack = request_find(&acks, rid)) == NULL)
fatal("Can't find request for ID %u", rid);
TAILQ_REMOVE(&acks, ack, tq);
- debug3("In write loop, ack for %u %u bytes at %lld",
- ack->id, ack->len, (long long)ack->offset);
+ debug3("In write loop, ack for %u %zu bytes at %lld",
+ ack->id, ack->len, (unsigned long long)ack->offset);
++ackid;
progress_counter += ack->len;
free(ack);
}
offset += len;
if (offset < 0)
- fatal("%s: offset < 0", __func__);
+ fatal_f("offset < 0");
}
sshbuf_free(msg);
@@ -1790,7 +2011,8 @@ do_upload(struct sftp_conn *conn, const char *local_path,
static int
upload_dir_internal(struct sftp_conn *conn, const char *src, const char *dst,
- int depth, int preserve_flag, int print_flag, int resume, int fsync_flag)
+ int depth, int preserve_flag, int print_flag, int resume, int fsync_flag,
+ int follow_link_flag)
{
int ret = 0;
DIR *dirp;
@@ -1798,6 +2020,7 @@ upload_dir_internal(struct sftp_conn *conn, const char *src, const char *dst,
char *filename, *new_src = NULL, *new_dst = NULL;
struct stat sb;
Attrib a, *dirattrib;
+ u_int32_t saved_perm;
if (depth >= MAX_DIR_DEPTH) {
error("Maximum directory depth exceeded: %d levels", depth);
@@ -1813,7 +2036,7 @@ upload_dir_internal(struct sftp_conn *conn, const char *src, const char *dst,
error("\"%s\" is not a directory", src);
return -1;
}
- if (print_flag)
+ if (print_flag && print_flag != SFTP_PROGRESS_ONLY)
mprintf("Entering %s\n", src);
attrib_clear(&a);
@@ -1827,8 +2050,11 @@ upload_dir_internal(struct sftp_conn *conn, const char *src, const char *dst,
/*
* sftp lacks a portable status value to match errno EEXIST,
* so if we get a failure back then we must check whether
- * the path already existed and is a directory.
+ * the path already existed and is a directory. Ensure we can
+ * write to the directory we create for the duration of the transfer.
*/
+ saved_perm = a.perm;
+ a.perm |= (S_IWUSR|S_IXUSR);
if (do_mkdir(conn, dst, &a, 0) != 0) {
if ((dirattrib = do_stat(conn, dst, 0)) == NULL)
return -1;
@@ -1837,6 +2063,7 @@ upload_dir_internal(struct sftp_conn *conn, const char *src, const char *dst,
return -1;
}
}
+ a.perm = saved_perm;
if ((dirp = opendir(src)) == NULL) {
error("Failed to open dir \"%s\": %s", src, strerror(errno));
@@ -1863,9 +2090,10 @@ upload_dir_internal(struct sftp_conn *conn, const char *src, const char *dst,
if (upload_dir_internal(conn, new_src, new_dst,
depth + 1, preserve_flag, print_flag, resume,
- fsync_flag) == -1)
+ fsync_flag, follow_link_flag) == -1)
ret = -1;
- } else if (S_ISREG(sb.st_mode)) {
+ } else if (S_ISREG(sb.st_mode) ||
+ (follow_link_flag && S_ISLNK(sb.st_mode))) {
if (do_upload(conn, new_src, new_dst,
preserve_flag, resume, fsync_flag) == -1) {
error("Uploading of file %s to %s failed!",
@@ -1886,7 +2114,8 @@ upload_dir_internal(struct sftp_conn *conn, const char *src, const char *dst,
int
upload_dir(struct sftp_conn *conn, const char *src, const char *dst,
- int preserve_flag, int print_flag, int resume, int fsync_flag)
+ int preserve_flag, int print_flag, int resume, int fsync_flag,
+ int follow_link_flag)
{
char *dst_canon;
int ret;
@@ -1897,12 +2126,448 @@ upload_dir(struct sftp_conn *conn, const char *src, const char *dst,
}
ret = upload_dir_internal(conn, src, dst_canon, 0, preserve_flag,
- print_flag, resume, fsync_flag);
+ print_flag, resume, fsync_flag, follow_link_flag);
free(dst_canon);
return ret;
}
+static void
+handle_dest_replies(struct sftp_conn *to, const char *to_path, int synchronous,
+ u_int *nreqsp, u_int *write_errorp)
+{
+ struct sshbuf *msg;
+ u_char type;
+ u_int id, status;
+ int r;
+ struct pollfd pfd;
+
+ if ((msg = sshbuf_new()) == NULL)
+ fatal_f("sshbuf_new failed");
+
+ /* Try to eat replies from the upload side */
+ while (*nreqsp > 0) {
+ debug3_f("%u outstanding replies", *nreqsp);
+ if (!synchronous) {
+ /* Bail out if no data is ready to be read */
+ pfd.fd = to->fd_in;
+ pfd.events = POLLIN;
+ if ((r = poll(&pfd, 1, 0)) == -1) {
+ if (errno == EINTR)
+ break;
+ fatal_f("poll: %s", strerror(errno));
+ } else if (r == 0)
+ break; /* fd not ready */
+ }
+ sshbuf_reset(msg);
+ get_msg(to, msg);
+
+ if ((r = sshbuf_get_u8(msg, &type)) != 0 ||
+ (r = sshbuf_get_u32(msg, &id)) != 0)
+ fatal_fr(r, "dest parse");
+ debug3("Received dest reply T:%u I:%u R:%u", type, id, *nreqsp);
+ if (type != SSH2_FXP_STATUS) {
+ fatal_f("Expected SSH2_FXP_STATUS(%d) packet, got %d",
+ SSH2_FXP_STATUS, type);
+ }
+ if ((r = sshbuf_get_u32(msg, &status)) != 0)
+ fatal_fr(r, "parse dest status");
+ debug3("dest SSH2_FXP_STATUS %u", status);
+ if (status != SSH2_FX_OK) {
+ /* record first error */
+ if (*write_errorp == 0)
+ *write_errorp = status;
+ }
+ /*
+ * XXX this doesn't do full reply matching like do_upload and
+ * so cannot gracefully truncate terminated uploads at a
+ * high-water mark. ATM the only caller of this function (scp)
+ * doesn't support transfer resumption, so this doesn't matter
+ * a whole lot.
+ *
+ * To be safe, do_crossload truncates the destination file to
+ * zero length on upload failure, since we can't trust the
+ * server not to have reordered replies that could have
+ * inserted holes where none existed in the source file.
+ *
+ * XXX we could get a more accutate progress bar if we updated
+ * the counter based on the reply from the destination...
+ */
+ (*nreqsp)--;
+ }
+ debug3_f("done: %u outstanding replies", *nreqsp);
+}
+
+int
+do_crossload(struct sftp_conn *from, struct sftp_conn *to,
+ const char *from_path, const char *to_path,
+ Attrib *a, int preserve_flag)
+{
+ struct sshbuf *msg;
+ int write_error, read_error, r;
+ u_int64_t offset = 0, size;
+ u_int id, buflen, num_req, max_req, status = SSH2_FX_OK;
+ u_int num_upload_req;
+ off_t progress_counter;
+ u_char *from_handle, *to_handle;
+ size_t from_handle_len, to_handle_len;
+ struct requests requests;
+ struct request *req;
+ u_char type;
+
+ TAILQ_INIT(&requests);
+
+ if (a == NULL && (a = do_stat(from, from_path, 0)) == NULL)
+ return -1;
+
+ if ((a->flags & SSH2_FILEXFER_ATTR_PERMISSIONS) &&
+ (!S_ISREG(a->perm))) {
+ error("Cannot download non-regular file: %s", from_path);
+ return(-1);
+ }
+ if (a->flags & SSH2_FILEXFER_ATTR_SIZE)
+ size = a->size;
+ else
+ size = 0;
+
+ buflen = from->download_buflen;
+ if (buflen > to->upload_buflen)
+ buflen = to->upload_buflen;
+
+ /* Send open request to read side */
+ if (send_open(from, from_path, "origin", SSH2_FXF_READ, NULL,
+ &from_handle, &from_handle_len) != 0)
+ return -1;
+
+ /* Send open request to write side */
+ a->flags &= ~SSH2_FILEXFER_ATTR_SIZE;
+ a->flags &= ~SSH2_FILEXFER_ATTR_UIDGID;
+ a->perm &= 0777;
+ if (!preserve_flag)
+ a->flags &= ~SSH2_FILEXFER_ATTR_ACMODTIME;
+ if (send_open(to, to_path, "dest",
+ SSH2_FXF_WRITE|SSH2_FXF_CREAT|SSH2_FXF_TRUNC, a,
+ &to_handle, &to_handle_len) != 0) {
+ do_close(from, from_handle, from_handle_len);
+ return -1;
+ }
+
+ /* Read from remote "from" and write to remote "to" */
+ offset = 0;
+ write_error = read_error = num_req = num_upload_req = 0;
+ max_req = 1;
+ progress_counter = 0;
+
+ if (showprogress && size != 0) {
+ start_progress_meter(progress_meter_path(from_path),
+ size, &progress_counter);
+ }
+ if ((msg = sshbuf_new()) == NULL)
+ fatal_f("sshbuf_new failed");
+ while (num_req > 0 || max_req > 0) {
+ u_char *data;
+ size_t len;
+
+ /*
+ * Simulate EOF on interrupt: stop sending new requests and
+ * allow outstanding requests to drain gracefully
+ */
+ if (interrupted) {
+ if (num_req == 0) /* If we haven't started yet... */
+ break;
+ max_req = 0;
+ }
+
+ /* Send some more requests */
+ while (num_req < max_req) {
+ debug3("Request range %llu -> %llu (%d/%d)",
+ (unsigned long long)offset,
+ (unsigned long long)offset + buflen - 1,
+ num_req, max_req);
+ req = request_enqueue(&requests, from->msg_id++,
+ buflen, offset);
+ offset += buflen;
+ num_req++;
+ send_read_request(from, req->id, req->offset,
+ req->len, from_handle, from_handle_len);
+ }
+
+ /* Try to eat replies from the upload side (nonblocking) */
+ handle_dest_replies(to, to_path, 0,
+ &num_upload_req, &write_error);
+
+ sshbuf_reset(msg);
+ get_msg(from, msg);
+ if ((r = sshbuf_get_u8(msg, &type)) != 0 ||
+ (r = sshbuf_get_u32(msg, &id)) != 0)
+ fatal_fr(r, "parse");
+ debug3("Received origin reply T:%u I:%u R:%d",
+ type, id, max_req);
+
+ /* Find the request in our queue */
+ if ((req = request_find(&requests, id)) == NULL)
+ fatal("Unexpected reply %u", id);
+
+ switch (type) {
+ case SSH2_FXP_STATUS:
+ if ((r = sshbuf_get_u32(msg, &status)) != 0)
+ fatal_fr(r, "parse status");
+ if (status != SSH2_FX_EOF)
+ read_error = 1;
+ max_req = 0;
+ TAILQ_REMOVE(&requests, req, tq);
+ free(req);
+ num_req--;
+ break;
+ case SSH2_FXP_DATA:
+ if ((r = sshbuf_get_string(msg, &data, &len)) != 0)
+ fatal_fr(r, "parse data");
+ debug3("Received data %llu -> %llu",
+ (unsigned long long)req->offset,
+ (unsigned long long)req->offset + len - 1);
+ if (len > req->len)
+ fatal("Received more data than asked for "
+ "%zu > %zu", len, req->len);
+
+ /* Write this chunk out to the destination */
+ sshbuf_reset(msg);
+ if ((r = sshbuf_put_u8(msg, SSH2_FXP_WRITE)) != 0 ||
+ (r = sshbuf_put_u32(msg, to->msg_id++)) != 0 ||
+ (r = sshbuf_put_string(msg, to_handle,
+ to_handle_len)) != 0 ||
+ (r = sshbuf_put_u64(msg, req->offset)) != 0 ||
+ (r = sshbuf_put_string(msg, data, len)) != 0)
+ fatal_fr(r, "compose write");
+ send_msg(to, msg);
+ debug3("Sent message SSH2_FXP_WRITE I:%u O:%llu S:%zu",
+ id, (unsigned long long)offset, len);
+ num_upload_req++;
+ progress_counter += len;
+ free(data);
+
+ if (len == req->len) {
+ TAILQ_REMOVE(&requests, req, tq);
+ free(req);
+ num_req--;
+ } else {
+ /* Resend the request for the missing data */
+ debug3("Short data block, re-requesting "
+ "%llu -> %llu (%2d)",
+ (unsigned long long)req->offset + len,
+ (unsigned long long)req->offset +
+ req->len - 1, num_req);
+ req->id = from->msg_id++;
+ req->len -= len;
+ req->offset += len;
+ send_read_request(from, req->id,
+ req->offset, req->len,
+ from_handle, from_handle_len);
+ /* Reduce the request size */
+ if (len < buflen)
+ buflen = MAXIMUM(MIN_READ_SIZE, len);
+ }
+ if (max_req > 0) { /* max_req = 0 iff EOF received */
+ if (size > 0 && offset > size) {
+ /* Only one request at a time
+ * after the expected EOF */
+ debug3("Finish at %llu (%2d)",
+ (unsigned long long)offset,
+ num_req);
+ max_req = 1;
+ } else if (max_req < from->num_requests) {
+ ++max_req;
+ }
+ }
+ break;
+ default:
+ fatal("Expected SSH2_FXP_DATA(%u) packet, got %u",
+ SSH2_FXP_DATA, type);
+ }
+ }
+
+ if (showprogress && size)
+ stop_progress_meter();
+
+ /* Drain replies from the server (blocking) */
+ debug3_f("waiting for %u replies from destination", num_upload_req);
+ handle_dest_replies(to, to_path, 1, &num_upload_req, &write_error);
+
+ /* Sanity check */
+ if (TAILQ_FIRST(&requests) != NULL)
+ fatal("Transfer complete, but requests still in queue");
+ /* Truncate at 0 length on interrupt or error to avoid holes at dest */
+ if (read_error || write_error || interrupted) {
+ debug("truncating \"%s\" at 0", to_path);
+ do_close(to, to_handle, to_handle_len);
+ free(to_handle);
+ if (send_open(to, to_path, "dest",
+ SSH2_FXF_WRITE|SSH2_FXF_CREAT|SSH2_FXF_TRUNC, a,
+ &to_handle, &to_handle_len) != 0) {
+ error("truncation failed for \"%s\"", to_path);
+ to_handle = NULL;
+ }
+ }
+ if (read_error) {
+ error("Couldn't read from origin file \"%s\" : %s",
+ from_path, fx2txt(status));
+ status = -1;
+ do_close(from, from_handle, from_handle_len);
+ if (to_handle != NULL)
+ do_close(to, to_handle, to_handle_len);
+ } else if (write_error) {
+ error("Couldn't write to \"%s\": %s",
+ to_path, fx2txt(write_error));
+ status = SSH2_FX_FAILURE;
+ do_close(from, from_handle, from_handle_len);
+ if (to_handle != NULL)
+ do_close(to, to_handle, to_handle_len);
+ } else {
+ if (do_close(from, from_handle, from_handle_len) != 0 ||
+ interrupted)
+ status = -1;
+ else
+ status = SSH2_FX_OK;
+ if (to_handle != NULL) {
+ /* Need to resend utimes after write */
+ if (preserve_flag)
+ do_fsetstat(to, to_handle, to_handle_len, a);
+ do_close(to, to_handle, to_handle_len);
+ }
+ }
+ sshbuf_free(msg);
+ free(from_handle);
+ free(to_handle);
+
+ return status == SSH2_FX_OK ? 0 : -1;
+}
+
+static int
+crossload_dir_internal(struct sftp_conn *from, struct sftp_conn *to,
+ const char *from_path, const char *to_path,
+ int depth, Attrib *dirattrib, int preserve_flag, int print_flag,
+ int follow_link_flag)
+{
+ int i, ret = 0;
+ SFTP_DIRENT **dir_entries;
+ char *filename, *new_from_path = NULL, *new_to_path = NULL;
+ mode_t mode = 0777;
+ Attrib curdir;
+
+ if (depth >= MAX_DIR_DEPTH) {
+ error("Maximum directory depth exceeded: %d levels", depth);
+ return -1;
+ }
+
+ if (dirattrib == NULL &&
+ (dirattrib = do_stat(from, from_path, 1)) == NULL) {
+ error("Unable to stat remote directory \"%s\"", from_path);
+ return -1;
+ }
+ if (!S_ISDIR(dirattrib->perm)) {
+ error("\"%s\" is not a directory", from_path);
+ return -1;
+ }
+ if (print_flag && print_flag != SFTP_PROGRESS_ONLY)
+ mprintf("Retrieving %s\n", from_path);
+
+ curdir = *dirattrib; /* dirattrib will be clobbered */
+ curdir.flags &= ~SSH2_FILEXFER_ATTR_SIZE;
+ curdir.flags &= ~SSH2_FILEXFER_ATTR_UIDGID;
+ if ((curdir.flags & SSH2_FILEXFER_ATTR_PERMISSIONS) == 0) {
+ debug("Origin did not send permissions for "
+ "directory \"%s\"", to_path);
+ curdir.perm = S_IWUSR|S_IXUSR;
+ curdir.flags |= SSH2_FILEXFER_ATTR_PERMISSIONS;
+ }
+ /* We need to be able to write to the directory while we transfer it */
+ mode = curdir.perm & 01777;
+ curdir.perm = mode | (S_IWUSR|S_IXUSR);
+
+ /*
+ * sftp lacks a portable status value to match errno EEXIST,
+ * so if we get a failure back then we must check whether
+ * the path already existed and is a directory. Ensure we can
+ * write to the directory we create for the duration of the transfer.
+ */
+ if (do_mkdir(to, to_path, &curdir, 0) != 0) {
+ if ((dirattrib = do_stat(to, to_path, 0)) == NULL)
+ return -1;
+ if (!S_ISDIR(dirattrib->perm)) {
+ error("\"%s\" exists but is not a directory", to_path);
+ return -1;
+ }
+ }
+ curdir.perm = mode;
+
+ if (do_readdir(from, from_path, &dir_entries) == -1) {
+ error("%s: Failed to get directory contents", from_path);
+ return -1;
+ }
+
+ for (i = 0; dir_entries[i] != NULL && !interrupted; i++) {
+ free(new_from_path);
+ free(new_to_path);
+
+ filename = dir_entries[i]->filename;
+ new_from_path = path_append(from_path, filename);
+ new_to_path = path_append(to_path, filename);
+
+ if (S_ISDIR(dir_entries[i]->a.perm)) {
+ if (strcmp(filename, ".") == 0 ||
+ strcmp(filename, "..") == 0)
+ continue;
+ if (crossload_dir_internal(from, to,
+ new_from_path, new_to_path,
+ depth + 1, &(dir_entries[i]->a), preserve_flag,
+ print_flag, follow_link_flag) == -1)
+ ret = -1;
+ } else if (S_ISREG(dir_entries[i]->a.perm) ||
+ (follow_link_flag && S_ISLNK(dir_entries[i]->a.perm))) {
+ /*
+ * If this is a symlink then don't send the link's
+ * Attrib. do_download() will do a FXP_STAT operation
+ * and get the link target's attributes.
+ */
+ if (do_crossload(from, to, new_from_path, new_to_path,
+ S_ISLNK(dir_entries[i]->a.perm) ? NULL :
+ &(dir_entries[i]->a), preserve_flag) == -1) {
+ error("Transfer of file %s to %s failed",
+ new_from_path, new_to_path);
+ ret = -1;
+ }
+ } else
+ logit("%s: not a regular file\n", new_from_path);
+
+ }
+ free(new_to_path);
+ free(new_from_path);
+
+ do_setstat(to, to_path, &curdir);
+
+ free_sftp_dirents(dir_entries);
+
+ return ret;
+}
+
+int
+crossload_dir(struct sftp_conn *from, struct sftp_conn *to,
+ const char *from_path, const char *to_path,
+ Attrib *dirattrib, int preserve_flag, int print_flag, int follow_link_flag)
+{
+ char *from_path_canon;
+ int ret;
+
+ if ((from_path_canon = do_realpath(from, from_path)) == NULL) {
+ error("Unable to canonicalize path \"%s\"", from_path);
+ return -1;
+ }
+
+ ret = crossload_dir_internal(from, to, from_path_canon, to_path, 0,
+ dirattrib, preserve_flag, print_flag, follow_link_flag);
+ free(from_path_canon);
+ return ret;
+}
+
char *
path_append(const char *p1, const char *p2)
{
@@ -1918,3 +2583,52 @@ path_append(const char *p1, const char *p2)
return(ret);
}
+char *
+make_absolute(char *p, const char *pwd)
+{
+ char *abs_str;
+
+ /* Derelativise */
+ if (p && !path_absolute(p)) {
+ abs_str = path_append(pwd, p);
+ free(p);
+ return(abs_str);
+ } else
+ return(p);
+}
+
+int
+remote_is_dir(struct sftp_conn *conn, const char *path)
+{
+ Attrib *a;
+
+ /* XXX: report errors? */
+ if ((a = do_stat(conn, path, 1)) == NULL)
+ return(0);
+ if (!(a->flags & SSH2_FILEXFER_ATTR_PERMISSIONS))
+ return(0);
+ return(S_ISDIR(a->perm));
+}
+
+
+int
+local_is_dir(const char *path)
+{
+ struct stat sb;
+
+ /* XXX: report errors? */
+ if (stat(path, &sb) == -1)
+ return(0);
+
+ return(S_ISDIR(sb.st_mode));
+}
+
+/* Check whether path returned from glob(..., GLOB_MARK, ...) is a directory */
+int
+globpath_is_dir(const char *pathname)
+{
+ size_t l = strlen(pathname);
+
+ return l > 0 && pathname[l - 1] == '/';
+}
+
diff --git a/crypto/openssh/sftp-client.h b/crypto/openssh/sftp-client.h
index 14a3b8182c49..7d0bd12ae5a3 100644
--- a/crypto/openssh/sftp-client.h
+++ b/crypto/openssh/sftp-client.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: sftp-client.h,v 1.27 2015/05/08 06:45:13 djm Exp $ */
+/* $OpenBSD: sftp-client.h,v 1.34 2021/08/09 23:47:44 djm Exp $ */
/*
* Copyright (c) 2001-2004 Damien Miller <djm@openbsd.org>
@@ -53,6 +53,19 @@ struct sftp_statvfs {
u_int64_t f_namemax;
};
+/* Used for limits response on the wire from the server */
+struct sftp_limits {
+ u_int64_t packet_length;
+ u_int64_t read_length;
+ u_int64_t write_length;
+ u_int64_t open_handles;
+};
+
+/* print flag values */
+#define SFTP_QUIET 0 /* be quiet during transfers */
+#define SFTP_PRINT 1 /* list files and show progress bar */
+#define SFTP_PROGRESS_ONLY 2 /* progress bar only */
+
/*
* Initialise a SSH filexfer connection. Returns NULL on error or
* a pointer to a initialized sftp_conn struct on success.
@@ -61,6 +74,9 @@ struct sftp_conn *do_init(int, int, u_int, u_int, u_int64_t);
u_int sftp_proto_version(struct sftp_conn *);
+/* Query server limits */
+int do_limits(struct sftp_conn *, struct sftp_limits *);
+
/* Close file referred to by 'handle' */
int do_close(struct sftp_conn *, const u_char *, u_int);
@@ -91,14 +107,23 @@ int do_setstat(struct sftp_conn *, const char *, Attrib *);
/* Set file attributes of open file 'handle' */
int do_fsetstat(struct sftp_conn *, const u_char *, u_int, Attrib *);
+/* Set file attributes of 'path', not following symlinks */
+int do_lsetstat(struct sftp_conn *conn, const char *path, Attrib *a);
+
/* Canonicalise 'path' - caller must free result */
char *do_realpath(struct sftp_conn *, const char *);
+/* Canonicalisation with tilde expansion (requires server extension) */
+char *do_expand_path(struct sftp_conn *, const char *);
+
+/* Returns non-zero if server can tilde-expand paths */
+int can_expand_path(struct sftp_conn *);
+
/* Get statistics for filesystem hosting file at "path" */
int do_statvfs(struct sftp_conn *, const char *, struct sftp_statvfs *, int);
/* Rename 'oldpath' to 'newpath' */
-int do_rename(struct sftp_conn *, const char *, const char *, int force_legacy);
+int do_rename(struct sftp_conn *, const char *, const char *, int);
/* Link 'oldpath' to 'newpath' */
int do_hardlink(struct sftp_conn *, const char *, const char *);
@@ -121,7 +146,7 @@ int do_download(struct sftp_conn *, const char *, const char *,
* times if 'pflag' is set
*/
int download_dir(struct sftp_conn *, const char *, const char *,
- Attrib *, int, int, int, int);
+ Attrib *, int, int, int, int, int);
/*
* Upload 'local_path' to 'remote_path'. Preserve permissions and times
@@ -134,9 +159,40 @@ int do_upload(struct sftp_conn *, const char *, const char *, int, int, int);
* times if 'pflag' is set
*/
int upload_dir(struct sftp_conn *, const char *, const char *, int, int, int,
- int);
+ int, int);
+
+/*
+ * Download a 'from_path' from the 'from' connection and upload it to
+ * to 'to' connection at 'to_path'.
+ */
+int
+do_crossload(struct sftp_conn *from, struct sftp_conn *to,
+ const char *from_path, const char *to_path,
+ Attrib *a, int preserve_flag);
+
+/*
+ * Recursively download a directory from 'from_path' from the 'from'
+ * connection and upload it to 'to' connection at 'to_path'.
+ */
+int crossload_dir(struct sftp_conn *from, struct sftp_conn *to,
+ const char *from_path, const char *to_path,
+ Attrib *dirattrib, int preserve_flag, int print_flag,
+ int follow_link_flag);
/* Concatenate paths, taking care of slashes. Caller must free result. */
char *path_append(const char *, const char *);
+/* Make absolute path if relative path and CWD is given. Does not modify
+ * original if the the path is already absolute. */
+char *make_absolute(char *, const char *);
+
+/* Check if remote path is directory */
+int remote_is_dir(struct sftp_conn *conn, const char *path);
+
+/* Check if local path is directory */
+int local_is_dir(const char *path);
+
+/* Check whether path returned from glob(..., GLOB_MARK, ...) is a directory */
+int globpath_is_dir(const char *pathname);
+
#endif
diff --git a/crypto/openssh/sftp-common.c b/crypto/openssh/sftp-common.c
index 3d6681467ffd..bff14228e14b 100644
--- a/crypto/openssh/sftp-common.c
+++ b/crypto/openssh/sftp-common.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: sftp-common.c,v 1.31 2018/09/13 15:23:32 millert Exp $ */
+/* $OpenBSD: sftp-common.c,v 1.32 2020/10/18 11:32:02 djm Exp $ */
/*
* Copyright (c) 2001 Markus Friedl. All rights reserved.
* Copyright (c) 2001 Damien Miller. All rights reserved.
@@ -37,6 +37,7 @@ __RCSID("$FreeBSD$");
#include <string.h>
#include <time.h>
#include <stdarg.h>
+#include <unistd.h>
#ifdef HAVE_UTIL_H
#include <util.h>
#endif
@@ -136,7 +137,7 @@ decode_attrib(struct sshbuf *b, Attrib *a)
u_int i, count;
if ((r = sshbuf_get_u32(b, &count)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ return r;
for (i = 0; i < count; i++) {
if ((r = sshbuf_get_cstring(b, &type, NULL)) != 0 ||
(r = sshbuf_get_string(b, &data, &dlen)) != 0)
diff --git a/crypto/openssh/sftp-glob.c b/crypto/openssh/sftp-glob.c
index 43a1bebadbd4..f573f98f01ec 100644
--- a/crypto/openssh/sftp-glob.c
+++ b/crypto/openssh/sftp-glob.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: sftp-glob.c,v 1.27 2015/01/14 13:54:13 djm Exp $ */
+/* $OpenBSD: sftp-glob.c,v 1.29 2019/11/13 04:47:52 deraadt Exp $ */
/*
* Copyright (c) 2001-2004 Damien Miller <djm@openbsd.org>
*
@@ -25,7 +25,7 @@
#include <dirent.h>
#include <stdlib.h>
#include <string.h>
-#include <stdlib.h>
+#include <stdarg.h>
#include "xmalloc.h"
#include "sftp.h"
diff --git a/crypto/openssh/openbsd-compat/realpath.c b/crypto/openssh/sftp-realpath.c
index a2f090e5512f..9ac40181227f 100644
--- a/crypto/openssh/openbsd-compat/realpath.c
+++ b/crypto/openssh/sftp-realpath.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: realpath.c,v 1.20 2015/10/13 20:55:37 millert Exp $ */
+/* $OpenBSD: sftp-realpath.c,v 1.1 2019/07/05 04:55:40 djm Exp $ */
/*
* Copyright (c) 2003 Constantin S. Svintsoff <kostik@iclub.nsu.ru>
*
@@ -27,12 +27,8 @@
* SUCH DAMAGE.
*/
-/* OPENBSD ORIGINAL: lib/libc/stdlib/realpath.c */
-
#include "includes.h"
-#if !defined(HAVE_REALPATH) || defined(BROKEN_REALPATH)
-
#include <sys/types.h>
#include <sys/param.h>
#include <sys/stat.h>
@@ -48,7 +44,9 @@
# define SYMLOOP_MAX 32
#endif
-/* A slightly modified copy of this file exists in libexec/ld.so */
+/* XXX rewrite sftp-server to use POSIX realpath and remove this hack */
+
+char *sftp_realpath(const char *path, char *resolved);
/*
* char *realpath(const char *path, char resolved[PATH_MAX]);
@@ -58,7 +56,7 @@
* in which case the path which caused trouble is left in (resolved).
*/
char *
-realpath(const char *path, char *resolved)
+sftp_realpath(const char *path, char *resolved)
{
struct stat sb;
char *p, *q, *s;
@@ -226,4 +224,3 @@ err:
free(resolved);
return (NULL);
}
-#endif /* !defined(HAVE_REALPATH) || defined(BROKEN_REALPATH) */
diff --git a/crypto/openssh/sftp-server-main.c b/crypto/openssh/sftp-server-main.c
index c6ccd623eab9..06566d36ed84 100644
--- a/crypto/openssh/sftp-server-main.c
+++ b/crypto/openssh/sftp-server-main.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: sftp-server-main.c,v 1.5 2016/02/15 09:47:49 dtucker Exp $ */
+/* $OpenBSD: sftp-server-main.c,v 1.6 2019/06/06 05:13:13 otto Exp $ */
/*
* Copyright (c) 2008 Markus Friedl. All rights reserved.
*
@@ -39,10 +39,11 @@ main(int argc, char **argv)
{
struct passwd *user_pw;
- ssh_malloc_init(); /* must be called before any mallocs */
/* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */
sanitise_stdfd();
+ seed_rng();
+
if ((user_pw = getpwuid(getuid())) == NULL) {
fprintf(stderr, "No user found for uid %lu\n",
(u_long)getuid());
diff --git a/crypto/openssh/sftp-server.8 b/crypto/openssh/sftp-server.8
index c117398e8583..5311bf9299fa 100644
--- a/crypto/openssh/sftp-server.8
+++ b/crypto/openssh/sftp-server.8
@@ -1,4 +1,4 @@
-.\" $OpenBSD: sftp-server.8,v 1.27 2014/12/11 04:16:14 djm Exp $
+.\" $OpenBSD: sftp-server.8,v 1.31 2021/07/27 14:14:25 jmc Exp $
.\"
.\" Copyright (c) 2000 Markus Friedl. All rights reserved.
.\"
@@ -22,12 +22,12 @@
.\" (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: December 11 2014 $
+.Dd $Mdocdate: July 27 2021 $
.Dt SFTP-SERVER 8
.Os
.Sh NAME
.Nm sftp-server
-.Nd SFTP server subsystem
+.Nd OpenSSH SFTP server subsystem
.Sh SYNOPSIS
.Nm sftp-server
.Bk -words
@@ -35,8 +35,8 @@
.Op Fl d Ar start_directory
.Op Fl f Ar log_facility
.Op Fl l Ar log_level
-.Op Fl P Ar blacklisted_requests
-.Op Fl p Ar whitelisted_requests
+.Op Fl P Ar denied_requests
+.Op Fl p Ar allowed_requests
.Op Fl u Ar umask
.Ek
.Nm
@@ -64,7 +64,7 @@ for more information.
Valid options are:
.Bl -tag -width Ds
.It Fl d Ar start_directory
-specifies an alternate starting directory for users.
+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,
@@ -99,30 +99,30 @@ 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.
-.It Fl P Ar blacklisted_requests
-Specify a comma-separated list of SFTP protocol requests that are banned by
+.It Fl P Ar denied_requests
+Specifies a comma-separated list of SFTP protocol requests that are banned by
the server.
.Nm
-will reply to any blacklisted request with a failure.
+will reply to any denied request with a failure.
The
.Fl 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.
-.It Fl p Ar whitelisted_requests
-Specify a comma-separated list of SFTP protocol requests that are permitted
+If both denied and allowed lists are specified, then the denied list is
+applied before the allowed list.
+.It Fl p Ar allowed_requests
+Specifies 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
+All request types that are not on the allowed list will be logged and replied
to with a failure message.
.Pp
Care must be taken when using this feature to ensure that requests made
implicitly by SFTP clients are permitted.
.It Fl Q Ar protocol_feature
-Query protocol features supported by
+Queries protocol features supported by
.Nm .
At present the only feature that may be queried is
.Dq requests ,
-which may be used for black or whitelisting (flags
+which may be used to deny or allow specific requests (flags
.Fl P
and
.Fl p
diff --git a/crypto/openssh/sftp-server.c b/crypto/openssh/sftp-server.c
index ab1b063f2136..18d194911257 100644
--- a/crypto/openssh/sftp-server.c
+++ b/crypto/openssh/sftp-server.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: sftp-server.c,v 1.112 2018/06/01 03:33:53 djm Exp $ */
+/* $OpenBSD: sftp-server.c,v 1.129 2021/08/09 23:47:44 djm Exp $ */
/*
* Copyright (c) 2000-2004 Markus Friedl. All rights reserved.
*
@@ -19,6 +19,7 @@
#include <sys/types.h>
#include <sys/stat.h>
+#include <sys/resource.h>
#ifdef HAVE_SYS_TIME_H
# include <sys/time.h>
#endif
@@ -51,6 +52,11 @@
#include "sftp.h"
#include "sftp-common.h"
+char *sftp_realpath(const char *, char *); /* sftp-realpath.c */
+
+/* Maximum data read that we are willing to accept */
+#define SFTP_MAX_READ_LENGTH (SFTP_MAX_MSG_LENGTH - 1024)
+
/* Our verbosity */
static LogLevel log_level = SYSLOG_LEVEL_ERROR;
@@ -72,7 +78,7 @@ static int init_done;
static int readonly;
/* Requests that are allowed/denied */
-static char *request_whitelist, *request_blacklist;
+static char *request_allowlist, *request_denylist;
/* portable attributes, etc. */
typedef struct Stat Stat;
@@ -107,6 +113,9 @@ static void process_extended_statvfs(u_int32_t id);
static void process_extended_fstatvfs(u_int32_t id);
static void process_extended_hardlink(u_int32_t id);
static void process_extended_fsync(u_int32_t id);
+static void process_extended_lsetstat(u_int32_t id);
+static void process_extended_limits(u_int32_t id);
+static void process_extended_expand(u_int32_t id);
static void process_extended(u_int32_t id);
struct sftp_handler {
@@ -117,7 +126,7 @@ struct sftp_handler {
int does_write; /* if nonzero, banned for readonly mode */
};
-struct sftp_handler handlers[] = {
+static const struct sftp_handler handlers[] = {
/* NB. SSH2_FXP_OPEN does the readonly check in the handler itself */
{ "open", NULL, SSH2_FXP_OPEN, process_open, 0 },
{ "close", NULL, SSH2_FXP_CLOSE, process_close, 0 },
@@ -141,18 +150,34 @@ struct sftp_handler handlers[] = {
};
/* SSH2_FXP_EXTENDED submessages */
-struct sftp_handler extended_handlers[] = {
+static const struct sftp_handler extended_handlers[] = {
{ "posix-rename", "posix-rename@openssh.com", 0,
- process_extended_posix_rename, 1 },
+ process_extended_posix_rename, 1 },
{ "statvfs", "statvfs@openssh.com", 0, process_extended_statvfs, 0 },
{ "fstatvfs", "fstatvfs@openssh.com", 0, process_extended_fstatvfs, 0 },
{ "hardlink", "hardlink@openssh.com", 0, process_extended_hardlink, 1 },
{ "fsync", "fsync@openssh.com", 0, process_extended_fsync, 1 },
+ { "lsetstat", "lsetstat@openssh.com", 0, process_extended_lsetstat, 1 },
+ { "limits", "limits@openssh.com", 0, process_extended_limits, 0 },
+ { "expand-path", "expand-path@openssh.com", 0,
+ process_extended_expand, 0 },
{ NULL, NULL, 0, NULL, 0 }
};
+static const struct sftp_handler *
+extended_handler_byname(const char *name)
+{
+ int i;
+
+ for (i = 0; extended_handlers[i].handler != NULL; i++) {
+ if (strcmp(name, extended_handlers[i].ext_name) == 0)
+ return &extended_handlers[i];
+ }
+ return NULL;
+}
+
static int
-request_permitted(struct sftp_handler *h)
+request_permitted(const struct sftp_handler *h)
{
char *result;
@@ -160,20 +185,20 @@ request_permitted(struct sftp_handler *h)
verbose("Refusing %s request in read-only mode", h->name);
return 0;
}
- if (request_blacklist != NULL &&
- ((result = match_list(h->name, request_blacklist, NULL))) != NULL) {
+ if (request_denylist != NULL &&
+ ((result = match_list(h->name, request_denylist, NULL))) != NULL) {
free(result);
- verbose("Refusing blacklisted %s request", h->name);
+ verbose("Refusing denylisted %s request", h->name);
return 0;
}
- if (request_whitelist != NULL &&
- ((result = match_list(h->name, request_whitelist, NULL))) != NULL) {
+ if (request_allowlist != NULL &&
+ ((result = match_list(h->name, request_allowlist, NULL))) != NULL) {
free(result);
- debug2("Permitting whitelisted %s request", h->name);
+ debug2("Permitting allowlisted %s request", h->name);
return 1;
}
- if (request_whitelist != NULL) {
- verbose("Refusing non-whitelisted %s request", h->name);
+ if (request_allowlist != NULL) {
+ verbose("Refusing non-allowlisted %s request", h->name);
return 0;
}
return 1;
@@ -285,9 +310,9 @@ enum {
HANDLE_FILE
};
-Handle *handles = NULL;
-u_int num_handles = 0;
-int first_unused_handle = -1;
+static Handle *handles = NULL;
+static u_int num_handles = 0;
+static int first_unused_handle = -1;
static void handle_unused(int i)
{
@@ -485,7 +510,7 @@ send_msg(struct sshbuf *m)
int r;
if ((r = sshbuf_put_stringb(oqueue, m)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "enqueue");
sshbuf_reset(m);
}
@@ -518,16 +543,16 @@ send_status(u_int32_t id, u_int32_t status)
(status != SSH2_FX_OK && status != SSH2_FX_EOF))
logit("sent status %s", status_to_message(status));
if ((msg = sshbuf_new()) == NULL)
- fatal("%s: sshbuf_new failed", __func__);
+ fatal_f("sshbuf_new failed");
if ((r = sshbuf_put_u8(msg, SSH2_FXP_STATUS)) != 0 ||
(r = sshbuf_put_u32(msg, id)) != 0 ||
(r = sshbuf_put_u32(msg, status)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "compose");
if (version >= 3) {
if ((r = sshbuf_put_cstring(msg,
status_to_message(status))) != 0 ||
(r = sshbuf_put_cstring(msg, "")) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "compose message");
}
send_msg(msg);
sshbuf_free(msg);
@@ -539,11 +564,11 @@ send_data_or_handle(char type, u_int32_t id, const u_char *data, int dlen)
int r;
if ((msg = sshbuf_new()) == NULL)
- fatal("%s: sshbuf_new failed", __func__);
+ fatal_f("sshbuf_new failed");
if ((r = sshbuf_put_u8(msg, type)) != 0 ||
(r = sshbuf_put_u32(msg, id)) != 0 ||
(r = sshbuf_put_string(msg, data, dlen)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "compose");
send_msg(msg);
sshbuf_free(msg);
}
@@ -574,17 +599,17 @@ send_names(u_int32_t id, int count, const Stat *stats)
int i, r;
if ((msg = sshbuf_new()) == NULL)
- fatal("%s: sshbuf_new failed", __func__);
+ fatal_f("sshbuf_new failed");
if ((r = sshbuf_put_u8(msg, SSH2_FXP_NAME)) != 0 ||
(r = sshbuf_put_u32(msg, id)) != 0 ||
(r = sshbuf_put_u32(msg, count)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "compose");
debug("request %u: sent names count %d", id, count);
for (i = 0; i < count; i++) {
if ((r = sshbuf_put_cstring(msg, stats[i].name)) != 0 ||
(r = sshbuf_put_cstring(msg, stats[i].long_name)) != 0 ||
(r = encode_attrib(msg, &stats[i].attrib)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "compose filenames/attrib");
}
send_msg(msg);
sshbuf_free(msg);
@@ -598,11 +623,11 @@ send_attrib(u_int32_t id, const Attrib *a)
debug("request %u: sent attrib have 0x%x", id, a->flags);
if ((msg = sshbuf_new()) == NULL)
- fatal("%s: sshbuf_new failed", __func__);
+ fatal_f("sshbuf_new failed");
if ((r = sshbuf_put_u8(msg, SSH2_FXP_ATTRS)) != 0 ||
(r = sshbuf_put_u32(msg, id)) != 0 ||
(r = encode_attrib(msg, a)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "compose");
send_msg(msg);
sshbuf_free(msg);
}
@@ -618,7 +643,7 @@ send_statvfs(u_int32_t id, struct statvfs *st)
flag |= (st->f_flag & ST_NOSUID) ? SSH2_FXE_STATVFS_ST_NOSUID : 0;
if ((msg = sshbuf_new()) == NULL)
- fatal("%s: sshbuf_new failed", __func__);
+ fatal_f("sshbuf_new failed");
if ((r = sshbuf_put_u8(msg, SSH2_FXP_EXTENDED_REPLY)) != 0 ||
(r = sshbuf_put_u32(msg, id)) != 0 ||
(r = sshbuf_put_u64(msg, st->f_bsize)) != 0 ||
@@ -632,11 +657,33 @@ send_statvfs(u_int32_t id, struct statvfs *st)
(r = sshbuf_put_u64(msg, FSID_TO_ULONG(st->f_fsid))) != 0 ||
(r = sshbuf_put_u64(msg, flag)) != 0 ||
(r = sshbuf_put_u64(msg, st->f_namemax)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "compose");
send_msg(msg);
sshbuf_free(msg);
}
+/*
+ * Prepare SSH2_FXP_VERSION extension advertisement for a single extension.
+ * The extension is checked for permission prior to advertisment.
+ */
+static int
+compose_extension(struct sshbuf *msg, const char *name, const char *ver)
+{
+ int r;
+ const struct sftp_handler *exthnd;
+
+ if ((exthnd = extended_handler_byname(name)) == NULL)
+ fatal_f("internal error: no handler for %s", name);
+ if (!request_permitted(exthnd)) {
+ debug2_f("refusing to advertise disallowed extension %s", name);
+ return 0;
+ }
+ if ((r = sshbuf_put_cstring(msg, name)) != 0 ||
+ (r = sshbuf_put_cstring(msg, ver)) != 0)
+ fatal_fr(r, "compose %s", name);
+ return 0;
+}
+
/* parse incoming */
static void
@@ -646,28 +693,24 @@ process_init(void)
int r;
if ((r = sshbuf_get_u32(iqueue, &version)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "parse");
verbose("received client version %u", version);
if ((msg = sshbuf_new()) == NULL)
- fatal("%s: sshbuf_new failed", __func__);
+ fatal_f("sshbuf_new failed");
if ((r = sshbuf_put_u8(msg, SSH2_FXP_VERSION)) != 0 ||
- (r = sshbuf_put_u32(msg, SSH2_FILEXFER_VERSION)) != 0 ||
- /* POSIX rename extension */
- (r = sshbuf_put_cstring(msg, "posix-rename@openssh.com")) != 0 ||
- (r = sshbuf_put_cstring(msg, "1")) != 0 || /* version */
- /* statvfs extension */
- (r = sshbuf_put_cstring(msg, "statvfs@openssh.com")) != 0 ||
- (r = sshbuf_put_cstring(msg, "2")) != 0 || /* version */
- /* fstatvfs extension */
- (r = sshbuf_put_cstring(msg, "fstatvfs@openssh.com")) != 0 ||
- (r = sshbuf_put_cstring(msg, "2")) != 0 || /* version */
- /* hardlink extension */
- (r = sshbuf_put_cstring(msg, "hardlink@openssh.com")) != 0 ||
- (r = sshbuf_put_cstring(msg, "1")) != 0 || /* version */
- /* fsync extension */
- (r = sshbuf_put_cstring(msg, "fsync@openssh.com")) != 0 ||
- (r = sshbuf_put_cstring(msg, "1")) != 0) /* version */
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ (r = sshbuf_put_u32(msg, SSH2_FILEXFER_VERSION)) != 0)
+ fatal_fr(r, "compose");
+
+ /* extension advertisments */
+ compose_extension(msg, "posix-rename@openssh.com", "1");
+ compose_extension(msg, "statvfs@openssh.com", "2");
+ compose_extension(msg, "fstatvfs@openssh.com", "2");
+ compose_extension(msg, "hardlink@openssh.com", "1");
+ compose_extension(msg, "fsync@openssh.com", "1");
+ compose_extension(msg, "lsetstat@openssh.com", "1");
+ compose_extension(msg, "limits@openssh.com", "1");
+ compose_extension(msg, "expand-path@openssh.com", "1");
+
send_msg(msg);
sshbuf_free(msg);
}
@@ -683,7 +726,7 @@ process_open(u_int32_t id)
if ((r = sshbuf_get_cstring(iqueue, &name, NULL)) != 0 ||
(r = sshbuf_get_u32(iqueue, &pflags)) != 0 || /* portable flags */
(r = decode_attrib(iqueue, &a)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "parse");
debug3("request %u: open flags %d", id, pflags);
flags = flags_from_portable(pflags);
@@ -697,7 +740,7 @@ process_open(u_int32_t id)
status = SSH2_FX_PERMISSION_DENIED;
} else {
fd = open(name, flags, mode);
- if (fd < 0) {
+ if (fd == -1) {
status = errno_to_portable(errno);
} else {
handle = handle_new(HANDLE_FILE, name, fd, flags, NULL);
@@ -720,7 +763,7 @@ process_close(u_int32_t id)
int r, handle, ret, status = SSH2_FX_FAILURE;
if ((r = get_handle(iqueue, &handle)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "parse");
debug3("request %u: close handle %u", id, handle);
handle_log_close(handle, NULL);
@@ -732,7 +775,8 @@ process_close(u_int32_t id)
static void
process_read(u_int32_t id)
{
- u_char buf[64*1024];
+ static u_char *buf;
+ static size_t buflen;
u_int32_t len;
int r, handle, fd, ret, status = SSH2_FX_FAILURE;
u_int64_t off;
@@ -740,32 +784,45 @@ process_read(u_int32_t id)
if ((r = get_handle(iqueue, &handle)) != 0 ||
(r = sshbuf_get_u64(iqueue, &off)) != 0 ||
(r = sshbuf_get_u32(iqueue, &len)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "parse");
- debug("request %u: read \"%s\" (handle %d) off %llu len %d",
+ debug("request %u: read \"%s\" (handle %d) off %llu len %u",
id, handle_to_name(handle), handle, (unsigned long long)off, len);
- if (len > sizeof buf) {
- len = sizeof buf;
- debug2("read change len %d", len);
+ if ((fd = handle_to_fd(handle)) == -1)
+ goto out;
+ if (len > SFTP_MAX_READ_LENGTH) {
+ debug2("read change len %u to %u", len, SFTP_MAX_READ_LENGTH);
+ len = SFTP_MAX_READ_LENGTH;
}
- fd = handle_to_fd(handle);
- if (fd >= 0) {
- if (lseek(fd, off, SEEK_SET) < 0) {
- error("process_read: seek failed");
- status = errno_to_portable(errno);
- } else {
- ret = read(fd, buf, len);
- if (ret < 0) {
- status = errno_to_portable(errno);
- } else if (ret == 0) {
- status = SSH2_FX_EOF;
- } else {
- send_data(id, buf, ret);
- status = SSH2_FX_OK;
- handle_update_read(handle, ret);
- }
- }
+ if (len > buflen) {
+ debug3_f("allocate %zu => %u", buflen, len);
+ if ((buf = realloc(NULL, len)) == NULL)
+ fatal_f("realloc failed");
+ buflen = len;
}
+ if (lseek(fd, off, SEEK_SET) == -1) {
+ status = errno_to_portable(errno);
+ error_f("seek \"%.100s\": %s", handle_to_name(handle),
+ strerror(errno));
+ goto out;
+ }
+ if (len == 0) {
+ /* weird, but not strictly disallowed */
+ ret = 0;
+ } else if ((ret = read(fd, buf, len)) == -1) {
+ status = errno_to_portable(errno);
+ error_f("read \"%.100s\": %s", handle_to_name(handle),
+ strerror(errno));
+ goto out;
+ } else if (ret == 0) {
+ status = SSH2_FX_EOF;
+ goto out;
+ }
+ send_data(id, buf, ret);
+ handle_update_read(handle, ret);
+ /* success */
+ status = SSH2_FX_OK;
+ out:
if (status != SSH2_FX_OK)
send_status(id, status);
}
@@ -781,7 +838,7 @@ process_write(u_int32_t id)
if ((r = get_handle(iqueue, &handle)) != 0 ||
(r = sshbuf_get_u64(iqueue, &off)) != 0 ||
(r = sshbuf_get_string(iqueue, &data, &len)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "parse");
debug("request %u: write \"%s\" (handle %d) off %llu len %zu",
id, handle_to_name(handle), handle, (unsigned long long)off, len);
@@ -791,20 +848,22 @@ process_write(u_int32_t id)
status = SSH2_FX_FAILURE;
else {
if (!(handle_to_flags(handle) & O_APPEND) &&
- lseek(fd, off, SEEK_SET) < 0) {
+ lseek(fd, off, SEEK_SET) == -1) {
status = errno_to_portable(errno);
- error("process_write: seek failed");
+ error_f("seek \"%.100s\": %s", handle_to_name(handle),
+ strerror(errno));
} else {
/* XXX ATOMICIO ? */
ret = write(fd, data, len);
- if (ret < 0) {
- error("process_write: write failed");
+ if (ret == -1) {
status = errno_to_portable(errno);
+ error_f("write \"%.100s\": %s",
+ handle_to_name(handle), strerror(errno));
} else if ((size_t)ret == len) {
status = SSH2_FX_OK;
handle_update_write(handle, ret);
} else {
- debug2("nothing at all written");
+ debug2_f("nothing at all written");
status = SSH2_FX_FAILURE;
}
}
@@ -822,12 +881,12 @@ process_do_stat(u_int32_t id, int do_lstat)
int r, status = SSH2_FX_FAILURE;
if ((r = sshbuf_get_cstring(iqueue, &name, NULL)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "parse");
debug3("request %u: %sstat", id, do_lstat ? "l" : "");
verbose("%sstat name \"%s\"", do_lstat ? "l" : "", name);
r = do_lstat ? lstat(name, &st) : stat(name, &st);
- if (r < 0) {
+ if (r == -1) {
status = errno_to_portable(errno);
} else {
stat_to_attrib(&st, &a);
@@ -859,13 +918,13 @@ process_fstat(u_int32_t id)
int fd, r, handle, status = SSH2_FX_FAILURE;
if ((r = get_handle(iqueue, &handle)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "parse");
debug("request %u: fstat \"%s\" (handle %u)",
id, handle_to_name(handle), handle);
fd = handle_to_fd(handle);
if (fd >= 0) {
r = fstat(fd, &st);
- if (r < 0) {
+ if (r == -1) {
status = errno_to_portable(errno);
} else {
stat_to_attrib(&st, &a);
@@ -889,6 +948,18 @@ attrib_to_tv(const Attrib *a)
return tv;
}
+static struct timespec *
+attrib_to_ts(const Attrib *a)
+{
+ static struct timespec ts[2];
+
+ ts[0].tv_sec = a->atime;
+ ts[0].tv_nsec = 0;
+ ts[1].tv_sec = a->mtime;
+ ts[1].tv_nsec = 0;
+ return ts;
+}
+
static void
process_setstat(u_int32_t id)
{
@@ -898,7 +969,7 @@ process_setstat(u_int32_t id)
if ((r = sshbuf_get_cstring(iqueue, &name, NULL)) != 0 ||
(r = decode_attrib(iqueue, &a)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "parse");
debug("request %u: setstat name \"%s\"", id, name);
if (a.flags & SSH2_FILEXFER_ATTR_SIZE) {
@@ -945,7 +1016,7 @@ process_fsetstat(u_int32_t id)
if ((r = get_handle(iqueue, &handle)) != 0 ||
(r = decode_attrib(iqueue, &a)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "parse");
debug("request %u: fsetstat handle %d", id, handle);
fd = handle_to_fd(handle);
@@ -1009,7 +1080,7 @@ process_opendir(u_int32_t id)
int r, handle, status = SSH2_FX_FAILURE;
if ((r = sshbuf_get_cstring(iqueue, &path, NULL)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "parse");
debug3("request %u: opendir", id);
logit("opendir \"%s\"", path);
@@ -1040,7 +1111,7 @@ process_readdir(u_int32_t id)
int r, handle;
if ((r = get_handle(iqueue, &handle)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "parse");
debug("request %u: readdir \"%s\" (handle %d)", id,
handle_to_name(handle), handle);
@@ -1063,7 +1134,7 @@ process_readdir(u_int32_t id)
/* XXX OVERFLOW ? */
snprintf(pathname, sizeof pathname, "%s%s%s", path,
strcmp(path, "/") ? "/" : "", dp->d_name);
- if (lstat(pathname, &st) < 0)
+ if (lstat(pathname, &st) == -1)
continue;
stat_to_attrib(&st, &(stats[count].attrib));
stats[count].name = xstrdup(dp->d_name);
@@ -1094,7 +1165,7 @@ process_remove(u_int32_t id)
int r, status = SSH2_FX_FAILURE;
if ((r = sshbuf_get_cstring(iqueue, &name, NULL)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "parse");
debug3("request %u: remove", id);
logit("remove name \"%s\"", name);
@@ -1113,7 +1184,7 @@ process_mkdir(u_int32_t id)
if ((r = sshbuf_get_cstring(iqueue, &name, NULL)) != 0 ||
(r = decode_attrib(iqueue, &a)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "parse");
mode = (a.flags & SSH2_FILEXFER_ATTR_PERMISSIONS) ?
a.perm & 07777 : 0777;
@@ -1132,7 +1203,7 @@ process_rmdir(u_int32_t id)
int r, status;
if ((r = sshbuf_get_cstring(iqueue, &name, NULL)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "parse");
debug3("request %u: rmdir", id);
logit("rmdir name \"%s\"", name);
@@ -1150,7 +1221,7 @@ process_realpath(u_int32_t id)
int r;
if ((r = sshbuf_get_cstring(iqueue, &path, NULL)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "parse");
if (path[0] == '\0') {
free(path);
@@ -1158,7 +1229,7 @@ process_realpath(u_int32_t id)
}
debug3("request %u: realpath", id);
verbose("realpath \"%s\"", path);
- if (realpath(path, resolvedname) == NULL) {
+ if (sftp_realpath(path, resolvedname) == NULL) {
send_status(id, errno_to_portable(errno));
} else {
Stat s;
@@ -1178,7 +1249,7 @@ process_rename(u_int32_t id)
if ((r = sshbuf_get_cstring(iqueue, &oldpath, NULL)) != 0 ||
(r = sshbuf_get_cstring(iqueue, &newpath, NULL)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "parse");
debug3("request %u: rename", id);
logit("rename old \"%s\" new \"%s\"", oldpath, newpath);
@@ -1237,7 +1308,7 @@ process_readlink(u_int32_t id)
char *path;
if ((r = sshbuf_get_cstring(iqueue, &path, NULL)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "parse");
debug3("request %u: readlink", id);
verbose("readlink \"%s\"", path);
@@ -1262,7 +1333,7 @@ process_symlink(u_int32_t id)
if ((r = sshbuf_get_cstring(iqueue, &oldpath, NULL)) != 0 ||
(r = sshbuf_get_cstring(iqueue, &newpath, NULL)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "parse");
debug3("request %u: symlink", id);
logit("symlink old \"%s\" new \"%s\"", oldpath, newpath);
@@ -1282,7 +1353,7 @@ process_extended_posix_rename(u_int32_t id)
if ((r = sshbuf_get_cstring(iqueue, &oldpath, NULL)) != 0 ||
(r = sshbuf_get_cstring(iqueue, &newpath, NULL)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "parse");
debug3("request %u: posix-rename", id);
logit("posix-rename old \"%s\" new \"%s\"", oldpath, newpath);
@@ -1301,7 +1372,7 @@ process_extended_statvfs(u_int32_t id)
int r;
if ((r = sshbuf_get_cstring(iqueue, &path, NULL)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "parse");
debug3("request %u: statvfs", id);
logit("statvfs \"%s\"", path);
@@ -1309,7 +1380,7 @@ process_extended_statvfs(u_int32_t id)
send_status(id, errno_to_portable(errno));
else
send_statvfs(id, &st);
- free(path);
+ free(path);
}
static void
@@ -1319,7 +1390,7 @@ process_extended_fstatvfs(u_int32_t id)
struct statvfs st;
if ((r = get_handle(iqueue, &handle)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "parse");
debug("request %u: fstatvfs \"%s\" (handle %u)",
id, handle_to_name(handle), handle);
if ((fd = handle_to_fd(handle)) < 0) {
@@ -1340,7 +1411,7 @@ process_extended_hardlink(u_int32_t id)
if ((r = sshbuf_get_cstring(iqueue, &oldpath, NULL)) != 0 ||
(r = sshbuf_get_cstring(iqueue, &newpath, NULL)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "parse");
debug3("request %u: hardlink", id);
logit("hardlink old \"%s\" new \"%s\"", oldpath, newpath);
@@ -1357,7 +1428,7 @@ process_extended_fsync(u_int32_t id)
int handle, fd, r, status = SSH2_FX_OP_UNSUPPORTED;
if ((r = get_handle(iqueue, &handle)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "parse");
debug3("request %u: fsync (handle %u)", id, handle);
verbose("fsync \"%s\"", handle_to_name(handle));
if ((fd = handle_to_fd(handle)) < 0)
@@ -1370,25 +1441,162 @@ process_extended_fsync(u_int32_t id)
}
static void
+process_extended_lsetstat(u_int32_t id)
+{
+ Attrib a;
+ char *name;
+ int r, status = SSH2_FX_OK;
+
+ if ((r = sshbuf_get_cstring(iqueue, &name, NULL)) != 0 ||
+ (r = decode_attrib(iqueue, &a)) != 0)
+ fatal_fr(r, "parse");
+
+ debug("request %u: lsetstat name \"%s\"", id, name);
+ if (a.flags & SSH2_FILEXFER_ATTR_SIZE) {
+ /* nonsensical for links */
+ status = SSH2_FX_BAD_MESSAGE;
+ goto out;
+ }
+ if (a.flags & SSH2_FILEXFER_ATTR_PERMISSIONS) {
+ logit("set \"%s\" mode %04o", name, a.perm);
+ r = fchmodat(AT_FDCWD, name,
+ a.perm & 07777, AT_SYMLINK_NOFOLLOW);
+ if (r == -1)
+ status = errno_to_portable(errno);
+ }
+ if (a.flags & SSH2_FILEXFER_ATTR_ACMODTIME) {
+ char buf[64];
+ time_t t = a.mtime;
+
+ strftime(buf, sizeof(buf), "%Y%m%d-%H:%M:%S",
+ localtime(&t));
+ logit("set \"%s\" modtime %s", name, buf);
+ r = utimensat(AT_FDCWD, name,
+ attrib_to_ts(&a), AT_SYMLINK_NOFOLLOW);
+ if (r == -1)
+ status = errno_to_portable(errno);
+ }
+ if (a.flags & SSH2_FILEXFER_ATTR_UIDGID) {
+ logit("set \"%s\" owner %lu group %lu", name,
+ (u_long)a.uid, (u_long)a.gid);
+ r = fchownat(AT_FDCWD, name, a.uid, a.gid,
+ AT_SYMLINK_NOFOLLOW);
+ if (r == -1)
+ status = errno_to_portable(errno);
+ }
+ out:
+ send_status(id, status);
+ free(name);
+}
+
+static void
+process_extended_limits(u_int32_t id)
+{
+ struct sshbuf *msg;
+ int r;
+ uint64_t nfiles = 0;
+#if defined(HAVE_GETRLIMIT) && defined(RLIMIT_NOFILE)
+ struct rlimit rlim;
+#endif
+
+ debug("request %u: limits", id);
+
+#if defined(HAVE_GETRLIMIT) && defined(RLIMIT_NOFILE)
+ if (getrlimit(RLIMIT_NOFILE, &rlim) != -1 && rlim.rlim_cur > 5)
+ nfiles = rlim.rlim_cur - 5; /* stdio(3) + syslog + spare */
+#endif
+
+ if ((msg = sshbuf_new()) == NULL)
+ fatal_f("sshbuf_new failed");
+ if ((r = sshbuf_put_u8(msg, SSH2_FXP_EXTENDED_REPLY)) != 0 ||
+ (r = sshbuf_put_u32(msg, id)) != 0 ||
+ /* max-packet-length */
+ (r = sshbuf_put_u64(msg, SFTP_MAX_MSG_LENGTH)) != 0 ||
+ /* max-read-length */
+ (r = sshbuf_put_u64(msg, SFTP_MAX_READ_LENGTH)) != 0 ||
+ /* max-write-length */
+ (r = sshbuf_put_u64(msg, SFTP_MAX_MSG_LENGTH - 1024)) != 0 ||
+ /* max-open-handles */
+ (r = sshbuf_put_u64(msg, nfiles)) != 0)
+ fatal_fr(r, "compose");
+ send_msg(msg);
+ sshbuf_free(msg);
+}
+
+static void
+process_extended_expand(u_int32_t id)
+{
+ char cwd[PATH_MAX], resolvedname[PATH_MAX];
+ char *path, *npath;
+ int r;
+ Stat s;
+
+ if ((r = sshbuf_get_cstring(iqueue, &path, NULL)) != 0)
+ fatal_fr(r, "parse");
+ if (getcwd(cwd, sizeof(cwd)) == NULL) {
+ send_status(id, errno_to_portable(errno));
+ goto out;
+ }
+
+ debug3("request %u: expand, original \"%s\"", id, path);
+ if (path[0] == '\0') {
+ /* empty path */
+ free(path);
+ path = xstrdup(".");
+ } else if (*path == '~') {
+ /* ~ expand path */
+ /* Special-case for "~" and "~/" to respect homedir flag */
+ if (strcmp(path, "~") == 0) {
+ free(path);
+ path = xstrdup(cwd);
+ } else if (strncmp(path, "~/", 2) == 0) {
+ npath = xstrdup(path + 2);
+ free(path);
+ xasprintf(&path, "%s/%s", cwd, npath);
+ } else {
+ /* ~user expansions */
+ if (tilde_expand(path, pw->pw_uid, &npath) != 0) {
+ send_status(id, errno_to_portable(EINVAL));
+ goto out;
+ }
+ free(path);
+ path = npath;
+ }
+ } else if (*path != '/') {
+ /* relative path */
+ xasprintf(&npath, "%s/%s", cwd, path);
+ free(path);
+ path = npath;
+ }
+ verbose("expand \"%s\"", path);
+ if (sftp_realpath(path, resolvedname) == NULL) {
+ send_status(id, errno_to_portable(errno));
+ goto out;
+ }
+ attrib_clear(&s.attrib);
+ s.name = s.long_name = resolvedname;
+ send_names(id, 1, &s);
+ out:
+ free(path);
+}
+
+static void
process_extended(u_int32_t id)
{
char *request;
- int i, r;
+ int r;
+ const struct sftp_handler *exthand;
if ((r = sshbuf_get_cstring(iqueue, &request, NULL)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
- for (i = 0; extended_handlers[i].handler != NULL; i++) {
- if (strcmp(request, extended_handlers[i].ext_name) == 0) {
- if (!request_permitted(&extended_handlers[i]))
- send_status(id, SSH2_FX_PERMISSION_DENIED);
- else
- extended_handlers[i].handler(id);
- break;
- }
- }
- if (extended_handlers[i].handler == NULL) {
+ fatal_fr(r, "parse");
+ if ((exthand = extended_handler_byname(request)) == NULL) {
error("Unknown extended request \"%.100s\"", request);
send_status(id, SSH2_FX_OP_UNSUPPORTED); /* MUST */
+ } else {
+ if (!request_permitted(exthand))
+ send_status(id, SSH2_FX_PERMISSION_DENIED);
+ else
+ exthand->handler(id);
}
free(request);
}
@@ -1419,10 +1627,10 @@ process(void)
if (buf_len < msg_len + 4)
return;
if ((r = sshbuf_consume(iqueue, 4)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "consume");
buf_len -= 4;
if ((r = sshbuf_get_u8(iqueue, &type)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "parse type");
switch (type) {
case SSH2_FXP_INIT:
@@ -1433,14 +1641,14 @@ process(void)
if (!init_done)
fatal("Received extended request before init");
if ((r = sshbuf_get_u32(iqueue, &id)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "parse extended ID");
process_extended(id);
break;
default:
if (!init_done)
fatal("Received %u request before init", type);
if ((r = sshbuf_get_u32(iqueue, &id)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "parse ID");
for (i = 0; handlers[i].handler != NULL; i++) {
if (type == handlers[i].type) {
if (!request_permitted(&handlers[i])) {
@@ -1467,7 +1675,7 @@ process(void)
}
if (msg_len > consumed &&
(r = sshbuf_consume(iqueue, msg_len - consumed)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "consume");
}
/* Cleanup handler that logs active handles upon normal exit */
@@ -1489,8 +1697,8 @@ sftp_server_usage(void)
fprintf(stderr,
"usage: %s [-ehR] [-d start_directory] [-f log_facility] "
- "[-l log_level]\n\t[-P blacklisted_requests] "
- "[-p whitelisted_requests] [-u umask]\n"
+ "[-l log_level]\n\t[-P denied_requests] "
+ "[-p allowed_requests] [-u umask]\n"
" %s -Q protocol_feature\n",
__progname, __progname);
exit(1);
@@ -1509,7 +1717,6 @@ sftp_server_main(int argc, char **argv, struct passwd *user_pw)
extern char *optarg;
extern char *__progname;
- ssh_malloc_init(); /* must be called before any mallocs */
__progname = ssh_get_progname(argv[0]);
log_init(__progname, log_level, log_facility, log_stderr);
@@ -1561,14 +1768,14 @@ sftp_server_main(int argc, char **argv, struct passwd *user_pw)
free(cp);
break;
case 'p':
- if (request_whitelist != NULL)
+ if (request_allowlist != NULL)
fatal("Permitted requests already set");
- request_whitelist = xstrdup(optarg);
+ request_allowlist = xstrdup(optarg);
break;
case 'P':
- if (request_blacklist != NULL)
+ if (request_denylist != NULL)
fatal("Refused requests already set");
- request_blacklist = xstrdup(optarg);
+ request_denylist = xstrdup(optarg);
break;
case 'u':
errno = 0;
@@ -1626,9 +1833,9 @@ sftp_server_main(int argc, char **argv, struct passwd *user_pw)
max = out;
if ((iqueue = sshbuf_new()) == NULL)
- fatal("%s: sshbuf_new failed", __func__);
+ fatal_f("sshbuf_new failed");
if ((oqueue = sshbuf_new()) == NULL)
- fatal("%s: sshbuf_new failed", __func__);
+ fatal_f("sshbuf_new failed");
rset = xcalloc(howmany(max + 1, NFDBITS), sizeof(fd_mask));
wset = xcalloc(howmany(max + 1, NFDBITS), sizeof(fd_mask));
@@ -1655,14 +1862,13 @@ sftp_server_main(int argc, char **argv, struct passwd *user_pw)
SFTP_MAX_MSG_LENGTH)) == 0)
FD_SET(in, rset);
else if (r != SSH_ERR_NO_BUFFER_SPACE)
- fatal("%s: sshbuf_check_reserve failed: %s",
- __func__, ssh_err(r));
+ fatal_fr(r, "reserve");
olen = sshbuf_len(oqueue);
if (olen > 0)
FD_SET(out, wset);
- if (select(max+1, rset, wset, NULL, NULL) < 0) {
+ if (select(max+1, rset, wset, NULL, NULL) == -1) {
if (errno == EINTR)
continue;
error("select: %s", strerror(errno));
@@ -1675,24 +1881,20 @@ sftp_server_main(int argc, char **argv, struct passwd *user_pw)
if (len == 0) {
debug("read eof");
sftp_server_cleanup_exit(0);
- } else if (len < 0) {
+ } else if (len == -1) {
error("read: %s", strerror(errno));
sftp_server_cleanup_exit(1);
- } else if ((r = sshbuf_put(iqueue, buf, len)) != 0) {
- fatal("%s: buffer error: %s",
- __func__, ssh_err(r));
- }
+ } else if ((r = sshbuf_put(iqueue, buf, len)) != 0)
+ fatal_fr(r, "sshbuf_put");
}
/* send oqueue to stdout */
if (FD_ISSET(out, wset)) {
len = write(out, sshbuf_ptr(oqueue), olen);
- if (len < 0) {
+ if (len == -1) {
error("write: %s", strerror(errno));
sftp_server_cleanup_exit(1);
- } else if ((r = sshbuf_consume(oqueue, len)) != 0) {
- fatal("%s: buffer error: %s",
- __func__, ssh_err(r));
- }
+ } else if ((r = sshbuf_consume(oqueue, len)) != 0)
+ fatal_fr(r, "consume");
}
/*
@@ -1704,7 +1906,6 @@ sftp_server_main(int argc, char **argv, struct passwd *user_pw)
if (r == 0)
process();
else if (r != SSH_ERR_NO_BUFFER_SPACE)
- fatal("%s: sshbuf_check_reserve: %s",
- __func__, ssh_err(r));
+ fatal_fr(r, "reserve");
}
}
diff --git a/crypto/openssh/sftp.1 b/crypto/openssh/sftp.1
index 0fd54cae090e..7eebeeacbf3f 100644
--- a/crypto/openssh/sftp.1
+++ b/crypto/openssh/sftp.1
@@ -1,4 +1,4 @@
-.\" $OpenBSD: sftp.1,v 1.120 2018/09/20 06:58:48 jmc Exp $
+.\" $OpenBSD: sftp.1,v 1.138 2021/07/02 05:11:21 dtucker Exp $
.\"
.\" Copyright (c) 2001 Damien Miller. All rights reserved.
.\"
@@ -22,21 +22,22 @@
.\" (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: September 20 2018 $
+.Dd $Mdocdate: July 2 2021 $
.Dt SFTP 1
.Os
.Sh NAME
.Nm sftp
-.Nd secure file transfer program
+.Nd OpenSSH secure file transfer
.Sh SYNOPSIS
.Nm sftp
-.Op Fl 46aCfpqrv
+.Op Fl 46AaCfNpqrv
.Op Fl B Ar buffer_size
.Op Fl b Ar batchfile
.Op Fl c Ar cipher
.Op Fl D Ar sftp_server_path
.Op Fl F Ar ssh_config
.Op Fl i Ar identity_file
+.Op Fl J Ar destination
.Op Fl l Ar limit
.Op Fl o Ar ssh_option
.Op Fl P Ar port
@@ -103,6 +104,11 @@ to use IPv4 addresses only.
Forces
.Nm
to use IPv6 addresses only.
+.It Fl A
+Allows forwarding of
+.Xr ssh-agent 1
+to the remote system.
+The default is not to forward an authentication agent.
.It Fl a
Attempt to continue interrupted transfers rather than overwriting
existing partial or complete copies of files.
@@ -127,6 +133,7 @@ at connection time (see
and
.Xr ssh-keygen 1
for details).
+.Pp
A
.Ar batchfile
of
@@ -135,17 +142,23 @@ may be used to indicate standard input.
.Nm
will abort if any of the following
commands fail:
-.Ic get , put , reget , reput, rename , ln ,
+.Ic get , put , reget , reput , rename , ln ,
.Ic rm , mkdir , chdir , ls ,
.Ic lchdir , chmod , chown ,
.Ic chgrp , lpwd , df , symlink ,
and
.Ic lmkdir .
+.Pp
Termination on error can be suppressed on a command by command basis by
prefixing the command with a
.Sq \-
character (for example,
.Ic -rm /tmp/blah* ) .
+Echo of the command may be suppressed by prefixing the command with a
+.Sq @
+character.
+These two prefixes may be combined in any order, for example
+.Ic -@ls /bsd .
.It Fl C
Enables compression (via ssh's
.Fl C
@@ -174,8 +187,25 @@ Selects the file from which the identity (private key) for public key
authentication is read.
This option is directly passed to
.Xr ssh 1 .
+.It Fl J Ar destination
+Connect to the target host by first making an
+.Nm
+connection to the jump host described by
+.Ar destination
+and then establishing a TCP forwarding to the ultimate destination from
+there.
+Multiple jump hops may be specified separated by comma characters.
+This is a shortcut to specify a
+.Cm ProxyJump
+configuration directive.
+This option is directly passed to
+.Xr ssh 1 .
.It Fl l Ar limit
Limits the used bandwidth, specified in Kbit/s.
+.It Fl N
+Disables quiet mode, e.g. to override the implicit quiet mode set by the
+.Fl b
+flag.
.It Fl o Ar ssh_option
Can be used to pass options to
.Nm ssh
@@ -202,7 +232,6 @@ For full details of the options listed below, and their possible values, see
.It CanonicalizePermittedCNAMEs
.It CASignatureAlgorithms
.It CertificateFile
-.It ChallengeResponseAuthentication
.It CheckHostIP
.It Ciphers
.It Compression
@@ -216,11 +245,11 @@ For full details of the options listed below, and their possible values, see
.It GSSAPIDelegateCredentials
.It HashKnownHosts
.It Host
+.It HostbasedAcceptedAlgorithms
.It HostbasedAuthentication
-.It HostbasedKeyTypes
.It HostKeyAlgorithms
.It HostKeyAlias
-.It HostName
+.It Hostname
.It IdentitiesOnly
.It IdentityAgent
.It IdentityFile
@@ -228,6 +257,7 @@ For full details of the options listed below, and their possible values, see
.It KbdInteractiveAuthentication
.It KbdInteractiveDevices
.It KexAlgorithms
+.It KnownHostsCommand
.It LogLevel
.It MACs
.It NoHostAuthenticationForLocalhost
@@ -238,7 +268,7 @@ For full details of the options listed below, and their possible values, see
.It PreferredAuthentications
.It ProxyCommand
.It ProxyJump
-.It PubkeyAcceptedKeyTypes
+.It PubkeyAcceptedAlgorithms
.It PubkeyAuthentication
.It RekeyLimit
.It SendEnv
@@ -309,7 +339,11 @@ Change remote directory to
If
.Ar path
is not specified, then change directory to the one the session started in.
-.It Ic chgrp Ar grp Ar path
+.It Xo Ic chgrp
+.Op Fl h
+.Ar grp
+.Ar path
+.Xc
Change group of file
.Ar path
to
@@ -320,7 +354,17 @@ may contain
characters and may match multiple files.
.Ar grp
must be a numeric GID.
-.It Ic chmod Ar mode Ar path
+.Pp
+If the
+.Fl h
+flag is specified, then symlinks will not be followed.
+Note that this is only supported by servers that implement
+the "lsetstat@openssh.com" extension.
+.It Xo Ic chmod
+.Op Fl h
+.Ar mode
+.Ar path
+.Xc
Change permissions of file
.Ar path
to
@@ -329,7 +373,17 @@ to
may contain
.Xr glob 7
characters and may match multiple files.
-.It Ic chown Ar own Ar path
+.Pp
+If the
+.Fl h
+flag is specified, then symlinks will not be followed.
+Note that this is only supported by servers that implement
+the "lsetstat@openssh.com" extension.
+.It Xo Ic chown
+.Op Fl h
+.Ar own
+.Ar path
+.Xc
Change owner of file
.Ar path
to
@@ -340,6 +394,12 @@ may contain
characters and may match multiple files.
.Ar own
must be a numeric UID.
+.Pp
+If the
+.Fl h
+flag is specified, then symlinks will not be followed.
+Note that this is only supported by servers that implement
+the "lsetstat@openssh.com" extension.
.It Xo Ic df
.Op Fl hi
.Op Ar path
@@ -362,7 +422,7 @@ extension.
Quit
.Nm sftp .
.It Xo Ic get
-.Op Fl afPpr
+.Op Fl afpR
.Ar remote-path
.Op Ar local-path
.Xc
@@ -397,15 +457,19 @@ flag is specified, then
will be called after the file transfer has completed to flush the file
to disk.
.Pp
-If either the
-.Fl P
-or
+If the
.Fl p
+.\" undocumented redundant alias
+.\" or
+.\" .Fl P
flag is specified, then full file permissions and access times are
copied too.
.Pp
If the
-.Fl r
+.Fl R
+.\" undocumented redundant alias
+.\" or
+.\" .Fl r
flag is specified then directories will be copied recursively.
Note that
.Nm
@@ -503,7 +567,7 @@ Create remote directory specified by
.It Ic progress
Toggle display of progress meter.
.It Xo Ic put
-.Op Fl afPpr
+.Op Fl afpR
.Ar local-path
.Op Ar remote-path
.Xc
@@ -539,15 +603,19 @@ after the file has been transferred.
Note that this is only supported by servers that implement
the "fsync@openssh.com" extension.
.Pp
-If either the
-.Fl P
-or
+If the
.Fl p
+.\" undocumented redundant alias
+.\" or
+.\" .Fl P
flag is specified, then full file permissions and access times are
copied too.
.Pp
If the
-.Fl r
+.Fl R
+.\" undocumented redundant alias
+.\" or
+.\" .Fl r
flag is specified then directories will be copied recursively.
Note that
.Nm
@@ -558,7 +626,7 @@ Display remote working directory.
Quit
.Nm sftp .
.It Xo Ic reget
-.Op Fl Ppr
+.Op Fl fpR
.Ar remote-path
.Op Ar local-path
.Xc
@@ -570,18 +638,18 @@ with the
.Fl a
flag set.
.It Xo Ic reput
-.Op Fl Ppr
-.Op Ar local-path
-.Ar remote-path
+.Op Fl fpR
+.Ar local-path
+.Op Ar remote-path
.Xc
Resume upload of
-.Op Ar local-path .
+.Ar local-path .
Equivalent to
.Ic put
with the
.Fl a
flag set.
-.It Ic rename Ar oldpath Ar newpath
+.It Ic rename Ar oldpath newpath
Rename remote file from
.Ar oldpath
to
@@ -592,7 +660,7 @@ Delete remote file specified by
.It Ic rmdir Ar path
Remove remote directory specified by
.Ar path .
-.It Ic symlink Ar oldpath Ar newpath
+.It Ic symlink Ar oldpath newpath
Create a symbolic link from
.Ar oldpath
to
diff --git a/crypto/openssh/sftp.c b/crypto/openssh/sftp.c
index 7db86c2d3cf0..69f84cdcf1a4 100644
--- a/crypto/openssh/sftp.c
+++ b/crypto/openssh/sftp.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: sftp.c,v 1.186 2018/09/07 04:26:56 dtucker Exp $ */
+/* $OpenBSD: sftp.c,v 1.211 2021/08/12 09:59:00 schwarze Exp $ */
/*
* Copyright (c) 2001-2004 Damien Miller <djm@openbsd.org>
*
@@ -53,7 +53,6 @@ typedef void EditLine;
#include <stdio.h>
#include <string.h>
#include <unistd.h>
-#include <stdarg.h>
#ifdef HAVE_UTIL_H
# include <util.h>
@@ -71,9 +70,6 @@ typedef void EditLine;
#include "sftp-common.h"
#include "sftp-client.h"
-#define DEFAULT_COPY_BUFLEN 32768 /* Size of buffer for up/download */
-#define DEFAULT_NUM_REQUESTS 64 /* # concurrent outstanding requests */
-
/* File to read commands from */
FILE* infile;
@@ -83,7 +79,7 @@ int batchmode = 0;
/* PID of ssh transport process */
static volatile pid_t sshpid = -1;
-/* Suppress diagnositic messages */
+/* Suppress diagnostic messages */
int quiet = 0;
/* This is set to 0 if the progressmeter is not desired. */
@@ -221,9 +217,12 @@ static const struct CMD cmds[] = {
static void
killchild(int signo)
{
- if (sshpid > 1) {
- kill(sshpid, SIGTERM);
- waitpid(sshpid, NULL, 0);
+ pid_t pid;
+
+ pid = sshpid;
+ if (pid > 1) {
+ kill(pid, SIGTERM);
+ waitpid(pid, NULL, 0);
}
_exit(1);
@@ -253,6 +252,13 @@ cmd_interrupt(int signo)
errno = olderrno;
}
+/* ARGSUSED */
+static void
+read_interrupt(int signo)
+{
+ interrupted = 1;
+}
+
/*ARGSUSED*/
static void
sigchld_handler(int sig)
@@ -278,15 +284,13 @@ help(void)
printf("Available commands:\n"
"bye Quit sftp\n"
"cd path Change remote directory to 'path'\n"
- "chgrp grp path Change group of file 'path' to 'grp'\n"
- "chmod mode path Change permissions of file 'path' to 'mode'\n"
- "chown own path Change owner of file 'path' to 'own'\n"
+ "chgrp [-h] grp path Change group of file 'path' to 'grp'\n"
+ "chmod [-h] mode path Change permissions of file 'path' to 'mode'\n"
+ "chown [-h] own path Change owner of file 'path' to 'own'\n"
"df [-hi] [path] Display statistics for current directory or\n"
" filesystem containing 'path'\n"
"exit Quit sftp\n"
- "get [-afPpRr] remote [local] Download file\n"
- "reget [-fPpRr] remote [local] Resume download file\n"
- "reput [-fPpRr] [local] remote Resume upload file\n"
+ "get [-afpR] remote [local] Download file\n"
"help Display this help text\n"
"lcd path Change local directory to 'path'\n"
"lls [ls-options [path]] Display local directory listing\n"
@@ -297,10 +301,12 @@ help(void)
"lumask umask Set local umask to 'umask'\n"
"mkdir path Create remote directory\n"
"progress Toggle display of progress meter\n"
- "put [-afPpRr] local [remote] Upload file\n"
+ "put [-afpR] local [remote] Upload file\n"
"pwd Display remote working directory\n"
"quit Quit sftp\n"
+ "reget [-fpR] remote [local] Resume download file\n"
"rename oldpath newpath Rename remote file\n"
+ "reput [-fpR] local [remote] Resume upload file\n"
"rm path Delete remote file\n"
"rmdir path Remove remote directory\n"
"symlink oldpath newpath Symlink remote file\n"
@@ -383,20 +389,6 @@ path_strip(const char *path, const char *strip)
return (xstrdup(path));
}
-static char *
-make_absolute(char *p, const char *pwd)
-{
- char *abs_str;
-
- /* Derelativise */
- if (p && p[0] != '/') {
- abs_str = path_append(pwd, p);
- free(p);
- return(abs_str);
- } else
- return(p);
-}
-
static int
parse_getput_flags(const char *cmd, char **argv, int argc,
int *aflag, int *fflag, int *pflag, int *rflag)
@@ -562,7 +554,7 @@ parse_df_flags(const char *cmd, char **argv, int argc, int *hflag, int *iflag)
}
static int
-parse_no_flags(const char *cmd, char **argv, int argc)
+parse_ch_flags(const char *cmd, char **argv, int argc, int *hflag)
{
extern int opterr, optind, optopt, optreset;
int ch;
@@ -570,8 +562,12 @@ parse_no_flags(const char *cmd, char **argv, int argc)
optind = optreset = 1;
opterr = 0;
- while ((ch = getopt(argc, argv, "")) != -1) {
+ *hflag = 0;
+ while ((ch = getopt(argc, argv, "h")) != -1) {
switch (ch) {
+ case 'h':
+ *hflag = 1;
+ break;
default:
error("%s: Invalid flag -%c", cmd, optopt);
return -1;
@@ -582,37 +578,23 @@ parse_no_flags(const char *cmd, char **argv, int argc)
}
static int
-is_dir(const char *path)
+parse_no_flags(const char *cmd, char **argv, int argc)
{
- struct stat sb;
-
- /* XXX: report errors? */
- if (stat(path, &sb) == -1)
- return(0);
-
- return(S_ISDIR(sb.st_mode));
-}
+ extern int opterr, optind, optopt, optreset;
+ int ch;
-static int
-remote_is_dir(struct sftp_conn *conn, const char *path)
-{
- Attrib *a;
-
- /* XXX: report errors? */
- if ((a = do_stat(conn, path, 1)) == NULL)
- return(0);
- if (!(a->flags & SSH2_FILEXFER_ATTR_PERMISSIONS))
- return(0);
- return(S_ISDIR(a->perm));
-}
+ optind = optreset = 1;
+ opterr = 0;
-/* Check whether path returned from glob(..., GLOB_MARK, ...) is a directory */
-static int
-pathname_is_dir(const char *pathname)
-{
- size_t l = strlen(pathname);
+ while ((ch = getopt(argc, argv, "")) != -1) {
+ switch (ch) {
+ default:
+ error("%s: Invalid flag -%c", cmd, optopt);
+ return -1;
+ }
+ }
- return l > 0 && pathname[l - 1] == '/';
+ return optind;
}
static int
@@ -644,7 +626,7 @@ process_get(struct sftp_conn *conn, const char *src, const char *dst,
* If multiple matches then dst must be a directory or
* unspecified.
*/
- if (g.gl_matchc > 1 && dst != NULL && !is_dir(dst)) {
+ if (g.gl_matchc > 1 && dst != NULL && !local_is_dir(dst)) {
error("Multiple source paths, but destination "
"\"%s\" is not a directory", dst);
err = -1;
@@ -661,7 +643,7 @@ process_get(struct sftp_conn *conn, const char *src, const char *dst,
}
if (g.gl_matchc == 1 && dst) {
- if (is_dir(dst)) {
+ if (local_is_dir(dst)) {
abs_dst = path_append(dst, filename);
} else {
abs_dst = xstrdup(dst);
@@ -680,10 +662,11 @@ process_get(struct sftp_conn *conn, const char *src, const char *dst,
else if (!quiet && !resume)
mprintf("Fetching %s to %s\n",
g.gl_pathv[i], abs_dst);
- if (pathname_is_dir(g.gl_pathv[i]) && (rflag || global_rflag)) {
+ /* XXX follow link flag */
+ if (globpath_is_dir(g.gl_pathv[i]) && (rflag || global_rflag)) {
if (download_dir(conn, g.gl_pathv[i], abs_dst, NULL,
pflag || global_pflag, 1, resume,
- fflag || global_fflag) == -1)
+ fflag || global_fflag, 0) == -1)
err = -1;
} else {
if (do_download(conn, g.gl_pathv[i], abs_dst, NULL,
@@ -766,17 +749,18 @@ process_put(struct sftp_conn *conn, const char *src, const char *dst,
}
free(tmp);
- resume |= global_aflag;
+ resume |= global_aflag;
if (!quiet && resume)
mprintf("Resuming upload of %s to %s\n",
g.gl_pathv[i], abs_dst);
else if (!quiet && !resume)
mprintf("Uploading %s to %s\n",
g.gl_pathv[i], abs_dst);
- if (pathname_is_dir(g.gl_pathv[i]) && (rflag || global_rflag)) {
+ /* XXX follow_link_flag */
+ if (globpath_is_dir(g.gl_pathv[i]) && (rflag || global_rflag)) {
if (upload_dir(conn, g.gl_pathv[i], abs_dst,
pflag || global_pflag, 1, resume,
- fflag || global_fflag) == -1)
+ fflag || global_fflag, 0) == -1)
err = -1;
} else {
if (do_upload(conn, g.gl_pathv[i], abs_dst,
@@ -913,7 +897,10 @@ sglob_comp(const void *aa, const void *bb)
return (rmul * strcmp(ap, bp));
else if (sort_flag & LS_TIME_SORT) {
#if defined(HAVE_STRUCT_STAT_ST_MTIM)
- return (rmul * timespeccmp(&as->st_mtim, &bs->st_mtim, <));
+ if (timespeccmp(&as->st_mtim, &bs->st_mtim, ==))
+ return 0;
+ return timespeccmp(&as->st_mtim, &bs->st_mtim, <) ?
+ rmul : -rmul;
#elif defined(HAVE_STRUCT_STAT_ST_MTIME)
return (rmul * NCMP(as->st_mtime, bs->st_mtime));
#else
@@ -1146,7 +1133,7 @@ undo_glob_escape(char *s)
* last argument's quote has been properly terminated or 0 otherwise.
* This parameter is only of use if "sloppy" is set.
*/
-#define MAXARGS 128
+#define MAXARGS 128
#define MAXARGLEN 8192
static char **
makeargv(const char *arg, int *argcp, int sloppy, char *lastquote,
@@ -1296,7 +1283,7 @@ makeargv(const char *arg, int *argcp, int sloppy, char *lastquote,
}
static int
-parse_args(const char **cpp, int *ignore_errors, int *aflag,
+parse_args(const char **cpp, int *ignore_errors, int *disable_echo, int *aflag,
int *fflag, int *hflag, int *iflag, int *lflag, int *pflag,
int *rflag, int *sflag,
unsigned long *n_arg, char **path1, char **path2)
@@ -1304,19 +1291,29 @@ parse_args(const char **cpp, int *ignore_errors, int *aflag,
const char *cmd, *cp = *cpp;
char *cp2, **argv;
int base = 0;
- long l;
+ long long ll;
int path1_mandatory = 0, i, cmdnum, optidx, argc;
/* Skip leading whitespace */
cp = cp + strspn(cp, WHITESPACE);
- /* Check for leading '-' (disable error processing) */
+ /*
+ * Check for leading '-' (disable error processing) and '@' (suppress
+ * command echo)
+ */
*ignore_errors = 0;
- if (*cp == '-') {
- *ignore_errors = 1;
- cp++;
- cp = cp + strspn(cp, WHITESPACE);
+ *disable_echo = 0;
+ for (;*cp != '\0'; cp++) {
+ if (*cp == '-') {
+ *ignore_errors = 1;
+ } else if (*cp == '@') {
+ *disable_echo = 1;
+ } else {
+ /* all other characters terminate prefix processing */
+ break;
+ }
}
+ cp = cp + strspn(cp, WHITESPACE);
/* Ignore blank lines and lines which begin with comment '#' char */
if (*cp == '\0' || *cp == '#')
@@ -1446,22 +1443,22 @@ parse_args(const char **cpp, int *ignore_errors, int *aflag,
/* FALLTHROUGH */
case I_CHOWN:
case I_CHGRP:
- if ((optidx = parse_no_flags(cmd, argv, argc)) == -1)
+ if ((optidx = parse_ch_flags(cmd, argv, argc, hflag)) == -1)
return -1;
/* Get numeric arg (mandatory) */
if (argc - optidx < 1)
goto need_num_arg;
errno = 0;
- l = strtol(argv[optidx], &cp2, base);
+ ll = strtoll(argv[optidx], &cp2, base);
if (cp2 == argv[optidx] || *cp2 != '\0' ||
- ((l == LONG_MIN || l == LONG_MAX) && errno == ERANGE) ||
- l < 0) {
+ ((ll == LLONG_MIN || ll == LLONG_MAX) && errno == ERANGE) ||
+ ll < 0 || ll > UINT32_MAX) {
need_num_arg:
error("You must supply a numeric argument "
"to the %s command.", cmd);
return -1;
}
- *n_arg = l;
+ *n_arg = ll;
if (cmdnum == I_LUMASK)
break;
/* Get pathname (mandatory) */
@@ -1491,11 +1488,12 @@ parse_args(const char **cpp, int *ignore_errors, int *aflag,
static int
parse_dispatch_command(struct sftp_conn *conn, const char *cmd, char **pwd,
- const char *startdir, int err_abort)
+ const char *startdir, int err_abort, int echo_command)
{
+ const char *ocmd = cmd;
char *path1, *path2, *tmp;
- int ignore_errors = 0, aflag = 0, fflag = 0, hflag = 0,
- iflag = 0;
+ int ignore_errors = 0, disable_echo = 1;
+ int aflag = 0, fflag = 0, hflag = 0, iflag = 0;
int lflag = 0, pflag = 0, rflag = 0, sflag = 0;
int cmdnum, i;
unsigned long n_arg = 0;
@@ -1505,11 +1503,15 @@ parse_dispatch_command(struct sftp_conn *conn, const char *cmd, char **pwd,
glob_t g;
path1 = path2 = NULL;
- cmdnum = parse_args(&cmd, &ignore_errors, &aflag, &fflag, &hflag,
- &iflag, &lflag, &pflag, &rflag, &sflag, &n_arg, &path1, &path2);
+ cmdnum = parse_args(&cmd, &ignore_errors, &disable_echo, &aflag, &fflag,
+ &hflag, &iflag, &lflag, &pflag, &rflag, &sflag, &n_arg,
+ &path1, &path2);
if (ignore_errors != 0)
err_abort = 0;
+ if (echo_command && !disable_echo)
+ mprintf("sftp> %s\n", ocmd);
+
memset(&g, 0, sizeof(g));
/* Perform command */
@@ -1608,7 +1610,7 @@ parse_dispatch_command(struct sftp_conn *conn, const char *cmd, char **pwd,
/* Strip pwd off beginning of non-absolute paths */
tmp = NULL;
- if (*path1 != '/')
+ if (!path_absolute(path1))
tmp = *pwd;
path1 = make_absolute(path1, *pwd);
@@ -1660,7 +1662,8 @@ parse_dispatch_command(struct sftp_conn *conn, const char *cmd, char **pwd,
if (!quiet)
mprintf("Changing mode on %s\n",
g.gl_pathv[i]);
- err = do_setstat(conn, g.gl_pathv[i], &a);
+ err = (hflag ? do_lsetstat : do_setstat)(conn,
+ g.gl_pathv[i], &a);
if (err != 0 && err_abort)
break;
}
@@ -1670,7 +1673,8 @@ parse_dispatch_command(struct sftp_conn *conn, const char *cmd, char **pwd,
path1 = make_absolute(path1, *pwd);
remote_glob(conn, path1, GLOB_NOCHECK, NULL, &g);
for (i = 0; g.gl_pathv[i] && !interrupted; i++) {
- if (!(aa = do_stat(conn, g.gl_pathv[i], 0))) {
+ if (!(aa = (hflag ? do_lstat : do_stat)(conn,
+ g.gl_pathv[i], 0))) {
if (err_abort) {
err = -1;
break;
@@ -1698,7 +1702,8 @@ parse_dispatch_command(struct sftp_conn *conn, const char *cmd, char **pwd,
g.gl_pathv[i]);
aa->gid = n_arg;
}
- err = do_setstat(conn, g.gl_pathv[i], aa);
+ err = (hflag ? do_lsetstat : do_setstat)(conn,
+ g.gl_pathv[i], aa);
if (err != 0 && err_abort)
break;
}
@@ -1936,7 +1941,7 @@ complete_match(EditLine *el, struct sftp_conn *conn, char *remote_path,
xasprintf(&tmp, "%s*", file);
/* Check if the path is absolute. */
- isabs = tmp[0] == '/';
+ isabs = path_absolute(tmp);
memset(&g, 0, sizeof(g));
if (remote != LOCAL) {
@@ -2057,7 +2062,7 @@ complete(EditLine *el, int ch)
lf = el_line(el);
if (el_get(el, EL_CLIENTDATA, (void**)&complete_ctx) != 0)
- fatal("%s: el_get failed", __func__);
+ fatal_f("el_get failed");
/* Figure out which argument the cursor points to */
cursor = lf->cursor - lf->buffer;
@@ -2147,7 +2152,7 @@ interactive_loop(struct sftp_conn *conn, char *file1, char *file2)
el_set(el, EL_BIND, "^I", "ftp-complete", NULL);
/* enable ctrl-left-arrow and ctrl-right-arrow */
el_set(el, EL_BIND, "\\e[1;5C", "em-next-word", NULL);
- el_set(el, EL_BIND, "\\e[5C", "em-next-word", NULL);
+ el_set(el, EL_BIND, "\\e\\e[C", "em-next-word", NULL);
el_set(el, EL_BIND, "\\e[1;5D", "ed-prev-word", NULL);
el_set(el, EL_BIND, "\\e\\e[D", "ed-prev-word", NULL);
/* make ^w match ksh behaviour */
@@ -2169,7 +2174,7 @@ interactive_loop(struct sftp_conn *conn, char *file1, char *file2)
mprintf("Changing to: %s\n", dir);
snprintf(cmd, sizeof cmd, "cd \"%s\"", dir);
if (parse_dispatch_command(conn, cmd,
- &remote_path, startdir, 1) != 0) {
+ &remote_path, startdir, 1, 0) != 0) {
free(dir);
free(startdir);
free(remote_path);
@@ -2183,7 +2188,7 @@ interactive_loop(struct sftp_conn *conn, char *file1, char *file2)
file2 == NULL ? "" : " ",
file2 == NULL ? "" : file2);
err = parse_dispatch_command(conn, cmd,
- &remote_path, startdir, 1);
+ &remote_path, startdir, 1, 0);
free(dir);
free(startdir);
free(remote_path);
@@ -2199,10 +2204,6 @@ interactive_loop(struct sftp_conn *conn, char *file1, char *file2)
interactive = !batchmode && isatty(STDIN_FILENO);
err = 0;
for (;;) {
- char *cp;
-
- signal(SIGINT, SIG_IGN);
-
if (el == NULL) {
if (interactive)
printf("sftp> ");
@@ -2211,21 +2212,26 @@ interactive_loop(struct sftp_conn *conn, char *file1, char *file2)
printf("\n");
break;
}
- if (!interactive) { /* Echo command */
- mprintf("sftp> %s", cmd);
- if (strlen(cmd) > 0 &&
- cmd[strlen(cmd) - 1] != '\n')
- printf("\n");
- }
} else {
#ifdef USE_LIBEDIT
const char *line;
int count = 0;
-
+ struct sigaction sa;
+
+ interrupted = 0;
+ memset(&sa, 0, sizeof(sa));
+ sa.sa_handler = read_interrupt;
+ if (sigaction(SIGINT, &sa, NULL) == -1) {
+ debug3("sigaction(%s): %s",
+ strsignal(SIGINT), strerror(errno));
+ break;
+ }
if ((line = el_gets(el, &count)) == NULL ||
count <= 0) {
printf("\n");
- break;
+ if (interrupted)
+ continue;
+ break;
}
history(hl, &hev, H_ENTER, line);
if (strlcpy(cmd, line, sizeof(cmd)) >= sizeof(cmd)) {
@@ -2235,20 +2241,18 @@ interactive_loop(struct sftp_conn *conn, char *file1, char *file2)
#endif /* USE_LIBEDIT */
}
- cp = strrchr(cmd, '\n');
- if (cp)
- *cp = '\0';
+ cmd[strcspn(cmd, "\n")] = '\0';
/* Handle user interrupts gracefully during commands */
interrupted = 0;
- signal(SIGINT, cmd_interrupt);
+ ssh_signal(SIGINT, cmd_interrupt);
err = parse_dispatch_command(conn, cmd, &remote_path,
- startdir, batchmode);
+ startdir, batchmode, !interactive && el == NULL);
if (err != 0)
break;
}
- signal(SIGCHLD, SIG_DFL);
+ ssh_signal(SIGCHLD, SIG_DFL);
free(remote_path);
free(startdir);
free(conn);
@@ -2305,20 +2309,20 @@ connect_to_server(char *path, char **args, int *in, int *out)
* kill it too. Contrawise, since sftp sends SIGTERMs to the
* underlying ssh, it must *not* ignore that signal.
*/
- signal(SIGINT, SIG_IGN);
- signal(SIGTERM, SIG_DFL);
+ ssh_signal(SIGINT, SIG_IGN);
+ ssh_signal(SIGTERM, SIG_DFL);
execvp(path, args);
fprintf(stderr, "exec: %s: %s\n", path, strerror(errno));
_exit(1);
}
- signal(SIGTERM, killchild);
- signal(SIGINT, killchild);
- signal(SIGHUP, killchild);
- signal(SIGTSTP, suspchild);
- signal(SIGTTIN, suspchild);
- signal(SIGTTOU, suspchild);
- signal(SIGCHLD, sigchld_handler);
+ ssh_signal(SIGTERM, killchild);
+ ssh_signal(SIGINT, killchild);
+ ssh_signal(SIGHUP, killchild);
+ ssh_signal(SIGTSTP, suspchild);
+ ssh_signal(SIGTTIN, suspchild);
+ ssh_signal(SIGTTOU, suspchild);
+ ssh_signal(SIGCHLD, sigchld_handler);
close(c_in);
close(c_out);
}
@@ -2329,12 +2333,11 @@ usage(void)
extern char *__progname;
fprintf(stderr,
- "usage: %s [-46aCfpqrv] [-B buffer_size] [-b batchfile] [-c cipher]\n"
- " [-D sftp_server_path] [-F ssh_config] "
- "[-i identity_file] [-l limit]\n"
- " [-o ssh_option] [-P port] [-R num_requests] "
- "[-S program]\n"
- " [-s subsystem | sftp_server] destination\n",
+ "usage: %s [-46AaCfNpqrv] [-B buffer_size] [-b batchfile] [-c cipher]\n"
+ " [-D sftp_server_path] [-F ssh_config] [-i identity_file]\n"
+ " [-J destination] [-l limit] [-o ssh_option] [-P port]\n"
+ " [-R num_requests] [-S program] [-s subsystem | sftp_server]\n"
+ " destination\n",
__progname);
exit(1);
}
@@ -2342,9 +2345,9 @@ usage(void)
int
main(int argc, char **argv)
{
- int in, out, ch, err, tmp, port = -1;
+ int in, out, ch, err, tmp, port = -1, noisy = 0;
char *host = NULL, *user, *cp, *file2 = NULL;
- int debug_level = 0, sshver = 2;
+ int debug_level = 0;
char *file1 = NULL, *sftp_server = NULL;
char *ssh_program = _PATH_SSH_PROGRAM, *sftp_direct = NULL;
const char *errstr;
@@ -2353,21 +2356,21 @@ main(int argc, char **argv)
extern int optind;
extern char *optarg;
struct sftp_conn *conn;
- size_t copy_buffer_len = DEFAULT_COPY_BUFLEN;
- size_t num_requests = DEFAULT_NUM_REQUESTS;
+ size_t copy_buffer_len = 0;
+ size_t num_requests = 0;
long long limit_kbps = 0;
- ssh_malloc_init(); /* must be called before any mallocs */
/* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */
sanitise_stdfd();
msetlocale();
+ seed_rng();
+
__progname = ssh_get_progname(argv[0]);
memset(&args, '\0', sizeof(args));
args.list = NULL;
addargs(&args, "%s", ssh_program);
addargs(&args, "-oForwardX11 no");
- addargs(&args, "-oForwardAgent no");
addargs(&args, "-oPermitLocalCommand no");
addargs(&args, "-oClearAllForwardings yes");
@@ -2375,9 +2378,10 @@ main(int argc, char **argv)
infile = stdin;
while ((ch = getopt(argc, argv,
- "1246afhpqrvCc:D:i:l:o:s:S:b:B:F:P:R:")) != -1) {
+ "1246AafhNpqrvCc:D:i:l:o:s:S:b:B:F:J:P:R:")) != -1) {
switch (ch) {
/* Passed through to ssh(1) */
+ case 'A':
case '4':
case '6':
case 'C':
@@ -2385,6 +2389,7 @@ main(int argc, char **argv)
break;
/* Passed through to ssh(1) with argument */
case 'F':
+ case 'J':
case 'c':
case 'i':
case 'o':
@@ -2410,12 +2415,10 @@ main(int argc, char **argv)
debug_level++;
break;
case '1':
- sshver = 1;
- if (sftp_server == NULL)
- sftp_server = _PATH_SFTP_SERVER;
+ fatal("SSH protocol v.1 is no longer supported");
break;
case '2':
- sshver = 2;
+ /* accept silently */
break;
case 'a':
global_aflag = 1;
@@ -2440,6 +2443,9 @@ main(int argc, char **argv)
case 'f':
global_fflag = 1;
break;
+ case 'N':
+ noisy = 1; /* Used to clear quiet mode after getopt */
+ break;
case 'p':
global_pflag = 1;
break;
@@ -2475,9 +2481,15 @@ main(int argc, char **argv)
}
}
+ /* Do this last because we want the user to be able to override it */
+ addargs(&args, "-oForwardAgent no");
+
if (!isatty(STDERR_FILENO))
showprogress = 0;
+ if (noisy)
+ quiet = 0;
+
log_init(argv[0], ll, SYSLOG_FACILITY_USER, 1);
if (sftp_direct == NULL) {
@@ -2494,12 +2506,17 @@ main(int argc, char **argv)
port = tmp;
break;
default:
+ /* Try with user, host and path. */
if (parse_user_host_path(*argv, &user, &host,
- &file1) == -1) {
- /* Treat as a plain hostname. */
- host = xstrdup(*argv);
- host = cleanhostname(host);
- }
+ &file1) == 0)
+ break;
+ /* Try with user and host. */
+ if (parse_user_host_port(*argv, &user, &host, NULL)
+ == 0)
+ break;
+ /* Treat as a plain hostname. */
+ host = xstrdup(*argv);
+ host = cleanhostname(host);
break;
}
file2 = *(argv + 1);
@@ -2515,7 +2532,6 @@ main(int argc, char **argv)
addargs(&args, "-l");
addargs(&args, "%s", user);
}
- addargs(&args, "-oProtocol %d", sshver);
/* no subsystem if the server-spec contains a '/' */
if (sftp_server == NULL || strchr(sftp_server, '/') == NULL)
diff --git a/crypto/openssh/sk-api.h b/crypto/openssh/sk-api.h
new file mode 100644
index 000000000000..74921d4c3b99
--- /dev/null
+++ b/crypto/openssh/sk-api.h
@@ -0,0 +1,98 @@
+/* $OpenBSD: sk-api.h,v 1.12 2021/02/18 02:15:07 djm Exp $ */
+/*
+ * Copyright (c) 2019 Google LLC
+ *
+ * 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 _SK_API_H
+#define _SK_API_H 1
+
+#include <stddef.h>
+#ifdef HAVE_STDINT_H
+#include <stdint.h>
+#endif
+
+/* Flags */
+#define SSH_SK_USER_PRESENCE_REQD 0x01
+#define SSH_SK_USER_VERIFICATION_REQD 0x04
+#define SSH_SK_RESIDENT_KEY 0x20
+
+/* Algs */
+#define SSH_SK_ECDSA 0x00
+#define SSH_SK_ED25519 0x01
+
+/* Error codes */
+#define SSH_SK_ERR_GENERAL -1
+#define SSH_SK_ERR_UNSUPPORTED -2
+#define SSH_SK_ERR_PIN_REQUIRED -3
+#define SSH_SK_ERR_DEVICE_NOT_FOUND -4
+
+struct sk_enroll_response {
+ uint8_t *public_key;
+ size_t public_key_len;
+ uint8_t *key_handle;
+ size_t key_handle_len;
+ uint8_t *signature;
+ size_t signature_len;
+ uint8_t *attestation_cert;
+ size_t attestation_cert_len;
+ uint8_t *authdata;
+ size_t authdata_len;
+};
+
+struct sk_sign_response {
+ uint8_t flags;
+ uint32_t counter;
+ uint8_t *sig_r;
+ size_t sig_r_len;
+ uint8_t *sig_s;
+ size_t sig_s_len;
+};
+
+struct sk_resident_key {
+ uint32_t alg;
+ size_t slot;
+ char *application;
+ struct sk_enroll_response key;
+ uint8_t flags;
+};
+
+struct sk_option {
+ char *name;
+ char *value;
+ uint8_t required;
+};
+
+#define SSH_SK_VERSION_MAJOR 0x00070000 /* current API version */
+#define SSH_SK_VERSION_MAJOR_MASK 0xffff0000
+
+/* Return the version of the middleware API */
+uint32_t sk_api_version(void);
+
+/* Enroll a U2F key (private key generation) */
+int sk_enroll(uint32_t alg, const uint8_t *challenge, size_t challenge_len,
+ const char *application, uint8_t flags, const char *pin,
+ struct sk_option **options, struct sk_enroll_response **enroll_response);
+
+/* Sign a challenge */
+int sk_sign(uint32_t alg, const uint8_t *data, size_t data_len,
+ const char *application, const uint8_t *key_handle, size_t key_handle_len,
+ uint8_t flags, const char *pin, struct sk_option **options,
+ struct sk_sign_response **sign_response);
+
+/* Enumerate all resident keys */
+int sk_load_resident_keys(const char *pin, struct sk_option **options,
+ struct sk_resident_key ***rks, size_t *nrks);
+
+#endif /* _SK_API_H */
diff --git a/crypto/openssh/sk-usbhid.c b/crypto/openssh/sk-usbhid.c
new file mode 100644
index 000000000000..438980889cb2
--- /dev/null
+++ b/crypto/openssh/sk-usbhid.c
@@ -0,0 +1,1267 @@
+/* $OpenBSD: sk-usbhid.c,v 1.30 2021/05/31 06:48:42 djm Exp $ */
+/*
+ * Copyright (c) 2019 Markus Friedl
+ * Copyright (c) 2020 Pedro Martelletto
+ *
+ * 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 ENABLE_SK_INTERNAL
+
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <stddef.h>
+#include <stdarg.h>
+#include <time.h>
+#ifdef HAVE_SHA2_H
+#include <sha2.h>
+#endif
+
+#ifdef WITH_OPENSSL
+#include <openssl/opensslv.h>
+#include <openssl/crypto.h>
+#include <openssl/bn.h>
+#include <openssl/ec.h>
+#include <openssl/ecdsa.h>
+#include <openssl/evp.h>
+#endif /* WITH_OPENSSL */
+
+#include <fido.h>
+#include <fido/credman.h>
+
+/* backwards compat for libfido2 */
+#ifndef HAVE_FIDO_CRED_PROT
+#define fido_cred_prot(x) (0)
+#endif
+#ifndef HAVE_FIDO_CRED_SET_PROT
+#define fido_cred_set_prot(x, y) (FIDO_ERR_UNSUPPORTED_OPTION)
+#endif
+#ifndef HAVE_FIDO_DEV_SUPPORTS_CRED_PROT
+#define fido_dev_supports_cred_prot(x) (0)
+#endif
+#ifndef HAVE_FIDO_DEV_GET_TOUCH_BEGIN
+#define fido_dev_get_touch_begin(x) (FIDO_ERR_UNSUPPORTED_OPTION)
+#endif
+#ifndef HAVE_FIDO_DEV_GET_TOUCH_STATUS
+#define fido_dev_get_touch_status(x, y, z) (FIDO_ERR_UNSUPPORTED_OPTION)
+#endif
+#ifndef FIDO_CRED_PROT_UV_REQUIRED
+#define FIDO_CRED_PROT_UV_REQUIRED 0
+#endif
+#ifndef FIDO_CRED_PROT_UV_OPTIONAL_WITH_ID
+#define FIDO_CRED_PROT_UV_OPTIONAL_WITH_ID 0
+#endif
+
+#ifndef SK_STANDALONE
+# include "log.h"
+# include "xmalloc.h"
+# include "misc.h"
+/*
+ * If building as part of OpenSSH, then rename exported functions.
+ * This must be done before including sk-api.h.
+ */
+# define sk_api_version ssh_sk_api_version
+# define sk_enroll ssh_sk_enroll
+# define sk_sign ssh_sk_sign
+# define sk_load_resident_keys ssh_sk_load_resident_keys
+#endif /* !SK_STANDALONE */
+
+#include "sk-api.h"
+
+/* #define SK_DEBUG 1 */
+
+#ifdef SK_DEBUG
+#define SSH_FIDO_INIT_ARG FIDO_DEBUG
+#else
+#define SSH_FIDO_INIT_ARG 0
+#endif
+
+#define MAX_FIDO_DEVICES 8
+#define FIDO_POLL_MS 50
+#define SELECT_MS 15000
+#define POLL_SLEEP_NS 200000000
+
+/* Compatibility with OpenSSH 1.0.x */
+#if (OPENSSL_VERSION_NUMBER < 0x10100000L)
+#define ECDSA_SIG_get0(sig, pr, ps) \
+ do { \
+ (*pr) = sig->r; \
+ (*ps) = sig->s; \
+ } while (0)
+#endif
+
+struct sk_usbhid {
+ fido_dev_t *dev;
+ char *path;
+};
+
+/* Return the version of the middleware API */
+uint32_t sk_api_version(void);
+
+/* Enroll a U2F key (private key generation) */
+int sk_enroll(uint32_t alg, const uint8_t *challenge, size_t challenge_len,
+ const char *application, uint8_t flags, const char *pin,
+ struct sk_option **options, struct sk_enroll_response **enroll_response);
+
+/* Sign a challenge */
+int sk_sign(uint32_t alg, const uint8_t *data, size_t data_len,
+ const char *application, const uint8_t *key_handle, size_t key_handle_len,
+ uint8_t flags, const char *pin, struct sk_option **options,
+ struct sk_sign_response **sign_response);
+
+/* Load resident keys */
+int sk_load_resident_keys(const char *pin, struct sk_option **options,
+ struct sk_resident_key ***rks, size_t *nrks);
+
+static void skdebug(const char *func, const char *fmt, ...)
+ __attribute__((__format__ (printf, 2, 3)));
+
+static void
+skdebug(const char *func, const char *fmt, ...)
+{
+#if !defined(SK_STANDALONE)
+ char *msg;
+ va_list ap;
+
+ va_start(ap, fmt);
+ xvasprintf(&msg, fmt, ap);
+ va_end(ap);
+ debug("%s: %s", func, msg);
+ free(msg);
+#elif defined(SK_DEBUG)
+ va_list ap;
+
+ va_start(ap, fmt);
+ fprintf(stderr, "%s: ", func);
+ vfprintf(stderr, fmt, ap);
+ fputc('\n', stderr);
+ va_end(ap);
+#else
+ (void)func; /* XXX */
+ (void)fmt; /* XXX */
+#endif
+}
+
+uint32_t
+sk_api_version(void)
+{
+ return SSH_SK_VERSION_MAJOR;
+}
+
+static struct sk_usbhid *
+sk_open(const char *path)
+{
+ struct sk_usbhid *sk;
+ int r;
+
+ if (path == NULL) {
+ skdebug(__func__, "path == NULL");
+ return NULL;
+ }
+ if ((sk = calloc(1, sizeof(*sk))) == NULL) {
+ skdebug(__func__, "calloc sk failed");
+ return NULL;
+ }
+ if ((sk->path = strdup(path)) == NULL) {
+ skdebug(__func__, "strdup path failed");
+ free(sk);
+ return NULL;
+ }
+ if ((sk->dev = fido_dev_new()) == NULL) {
+ skdebug(__func__, "fido_dev_new failed");
+ free(sk->path);
+ free(sk);
+ return NULL;
+ }
+ if ((r = fido_dev_open(sk->dev, sk->path)) != FIDO_OK) {
+ skdebug(__func__, "fido_dev_open %s failed: %s", sk->path,
+ fido_strerr(r));
+ fido_dev_free(&sk->dev);
+ free(sk->path);
+ free(sk);
+ return NULL;
+ }
+ return sk;
+}
+
+static void
+sk_close(struct sk_usbhid *sk)
+{
+ if (sk == NULL)
+ return;
+ fido_dev_cancel(sk->dev); /* cancel any pending operation */
+ fido_dev_close(sk->dev);
+ fido_dev_free(&sk->dev);
+ free(sk->path);
+ free(sk);
+}
+
+static struct sk_usbhid **
+sk_openv(const fido_dev_info_t *devlist, size_t ndevs, size_t *nopen)
+{
+ const fido_dev_info_t *di;
+ struct sk_usbhid **skv;
+ size_t i;
+
+ *nopen = 0;
+ if ((skv = calloc(ndevs, sizeof(*skv))) == NULL) {
+ skdebug(__func__, "calloc skv failed");
+ return NULL;
+ }
+ for (i = 0; i < ndevs; i++) {
+ if ((di = fido_dev_info_ptr(devlist, i)) == NULL)
+ skdebug(__func__, "fido_dev_info_ptr failed");
+ else if ((skv[*nopen] = sk_open(fido_dev_info_path(di))) == NULL)
+ skdebug(__func__, "sk_open failed");
+ else
+ (*nopen)++;
+ }
+ if (*nopen == 0) {
+ for (i = 0; i < ndevs; i++)
+ sk_close(skv[i]);
+ free(skv);
+ skv = NULL;
+ }
+
+ return skv;
+}
+
+static void
+sk_closev(struct sk_usbhid **skv, size_t nsk)
+{
+ size_t i;
+
+ for (i = 0; i < nsk; i++)
+ sk_close(skv[i]);
+ free(skv);
+}
+
+static int
+sk_touch_begin(struct sk_usbhid **skv, size_t nsk)
+{
+ size_t i, ok = 0;
+ int r;
+
+ for (i = 0; i < nsk; i++)
+ if ((r = fido_dev_get_touch_begin(skv[i]->dev)) != FIDO_OK)
+ skdebug(__func__, "fido_dev_get_touch_begin %s failed:"
+ " %s", skv[i]->path, fido_strerr(r));
+ else
+ ok++;
+
+ return ok ? 0 : -1;
+}
+
+static int
+sk_touch_poll(struct sk_usbhid **skv, size_t nsk, int *touch, size_t *idx)
+{
+ struct timespec ts_pause;
+ size_t npoll, i;
+ int r;
+
+ ts_pause.tv_sec = 0;
+ ts_pause.tv_nsec = POLL_SLEEP_NS;
+ nanosleep(&ts_pause, NULL);
+ npoll = nsk;
+ for (i = 0; i < nsk; i++) {
+ if (skv[i] == NULL)
+ continue; /* device discarded */
+ skdebug(__func__, "polling %s", skv[i]->path);
+ if ((r = fido_dev_get_touch_status(skv[i]->dev, touch,
+ FIDO_POLL_MS)) != FIDO_OK) {
+ skdebug(__func__, "fido_dev_get_touch_status %s: %s",
+ skv[i]->path, fido_strerr(r));
+ sk_close(skv[i]); /* discard device */
+ skv[i] = NULL;
+ if (--npoll == 0) {
+ skdebug(__func__, "no device left to poll");
+ return -1;
+ }
+ } else if (*touch) {
+ *idx = i;
+ return 0;
+ }
+ }
+ *touch = 0;
+ return 0;
+}
+
+/* Calculate SHA256(m) */
+static int
+sha256_mem(const void *m, size_t mlen, u_char *d, size_t dlen)
+{
+#ifdef WITH_OPENSSL
+ u_int mdlen;
+#endif
+
+ if (dlen != 32)
+ return -1;
+#ifdef WITH_OPENSSL
+ mdlen = dlen;
+ if (!EVP_Digest(m, mlen, d, &mdlen, EVP_sha256(), NULL))
+ return -1;
+#else
+ SHA256Data(m, mlen, d);
+#endif
+ return 0;
+}
+
+/* Check if the specified key handle exists on a given sk. */
+static int
+sk_try(const struct sk_usbhid *sk, const char *application,
+ const uint8_t *key_handle, size_t key_handle_len)
+{
+ fido_assert_t *assert = NULL;
+ /* generate an invalid signature on FIDO2 tokens */
+ const char *data = "";
+ uint8_t message[32];
+ int r = FIDO_ERR_INTERNAL;
+
+ if (sha256_mem(data, strlen(data), message, sizeof(message)) != 0) {
+ skdebug(__func__, "hash message failed");
+ goto out;
+ }
+ if ((assert = fido_assert_new()) == NULL) {
+ skdebug(__func__, "fido_assert_new failed");
+ goto out;
+ }
+ if ((r = fido_assert_set_clientdata_hash(assert, message,
+ sizeof(message))) != FIDO_OK) {
+ skdebug(__func__, "fido_assert_set_clientdata_hash: %s",
+ fido_strerr(r));
+ goto out;
+ }
+ if ((r = fido_assert_set_rp(assert, application)) != FIDO_OK) {
+ skdebug(__func__, "fido_assert_set_rp: %s", fido_strerr(r));
+ goto out;
+ }
+ if ((r = fido_assert_allow_cred(assert, key_handle,
+ key_handle_len)) != FIDO_OK) {
+ skdebug(__func__, "fido_assert_allow_cred: %s", fido_strerr(r));
+ goto out;
+ }
+ if ((r = fido_assert_set_up(assert, FIDO_OPT_FALSE)) != FIDO_OK) {
+ skdebug(__func__, "fido_assert_up: %s", fido_strerr(r));
+ goto out;
+ }
+ r = fido_dev_get_assert(sk->dev, assert, NULL);
+ skdebug(__func__, "fido_dev_get_assert: %s", fido_strerr(r));
+ if (r == FIDO_ERR_USER_PRESENCE_REQUIRED) {
+ /* U2F tokens may return this */
+ r = FIDO_OK;
+ }
+ out:
+ fido_assert_free(&assert);
+
+ return r != FIDO_OK ? -1 : 0;
+}
+
+static struct sk_usbhid *
+sk_select_by_cred(const fido_dev_info_t *devlist, size_t ndevs,
+ const char *application, const uint8_t *key_handle, size_t key_handle_len)
+{
+ struct sk_usbhid **skv, *sk;
+ size_t skvcnt, i;
+
+ if ((skv = sk_openv(devlist, ndevs, &skvcnt)) == NULL) {
+ skdebug(__func__, "sk_openv failed");
+ return NULL;
+ }
+ if (skvcnt == 1) {
+ sk = skv[0];
+ skv[0] = NULL;
+ goto out;
+ }
+ sk = NULL;
+ for (i = 0; i < skvcnt; i++) {
+ if (sk_try(skv[i], application, key_handle,
+ key_handle_len) == 0) {
+ sk = skv[i];
+ skv[i] = NULL;
+ skdebug(__func__, "found key in %s", sk->path);
+ break;
+ }
+ }
+ out:
+ sk_closev(skv, skvcnt);
+ return sk;
+}
+
+static struct sk_usbhid *
+sk_select_by_touch(const fido_dev_info_t *devlist, size_t ndevs)
+{
+ struct sk_usbhid **skv, *sk;
+ struct timeval tv_start, tv_now, tv_delta;
+ size_t skvcnt, idx;
+ int touch, ms_remain;
+
+ if ((skv = sk_openv(devlist, ndevs, &skvcnt)) == NULL) {
+ skdebug(__func__, "sk_openv failed");
+ return NULL;
+ }
+ sk = NULL;
+ if (skvcnt < 2) {
+ if (skvcnt == 1) {
+ /* single candidate */
+ sk = skv[0];
+ skv[0] = NULL;
+ }
+ goto out;
+ }
+#ifndef HAVE_FIDO_DEV_GET_TOUCH_STATUS
+ skdebug(__func__, "libfido2 version does not support a feature needed for multiple tokens. Please upgrade to >=1.5.0");
+ goto out;
+#endif
+
+ if (sk_touch_begin(skv, skvcnt) == -1) {
+ skdebug(__func__, "sk_touch_begin failed");
+ goto out;
+ }
+ monotime_tv(&tv_start);
+ do {
+ if (sk_touch_poll(skv, skvcnt, &touch, &idx) == -1) {
+ skdebug(__func__, "sk_touch_poll failed");
+ goto out;
+ }
+ if (touch) {
+ sk = skv[idx];
+ skv[idx] = NULL;
+ goto out;
+ }
+ monotime_tv(&tv_now);
+ timersub(&tv_now, &tv_start, &tv_delta);
+ ms_remain = SELECT_MS - tv_delta.tv_sec * 1000 -
+ tv_delta.tv_usec / 1000;
+ } while (ms_remain >= FIDO_POLL_MS);
+ skdebug(__func__, "timeout");
+out:
+ sk_closev(skv, skvcnt);
+ return sk;
+}
+
+static struct sk_usbhid *
+sk_probe(const char *application, const uint8_t *key_handle,
+ size_t key_handle_len)
+{
+ struct sk_usbhid *sk;
+ fido_dev_info_t *devlist;
+ size_t ndevs;
+ int r;
+
+ if ((devlist = fido_dev_info_new(MAX_FIDO_DEVICES)) == NULL) {
+ skdebug(__func__, "fido_dev_info_new failed");
+ return NULL;
+ }
+ if ((r = fido_dev_info_manifest(devlist, MAX_FIDO_DEVICES,
+ &ndevs)) != FIDO_OK) {
+ skdebug(__func__, "fido_dev_info_manifest failed: %s",
+ fido_strerr(r));
+ fido_dev_info_free(&devlist, MAX_FIDO_DEVICES);
+ return NULL;
+ }
+ skdebug(__func__, "%zu device(s) detected", ndevs);
+ if (ndevs == 0) {
+ sk = NULL;
+ } else if (application != NULL && key_handle != NULL) {
+ skdebug(__func__, "selecting sk by cred");
+ sk = sk_select_by_cred(devlist, ndevs, application, key_handle,
+ key_handle_len);
+ } else {
+ skdebug(__func__, "selecting sk by touch");
+ sk = sk_select_by_touch(devlist, ndevs);
+ }
+ fido_dev_info_free(&devlist, MAX_FIDO_DEVICES);
+ return sk;
+}
+
+#ifdef WITH_OPENSSL
+/*
+ * The key returned via fido_cred_pubkey_ptr() is in affine coordinates,
+ * but the API expects a SEC1 octet string.
+ */
+static int
+pack_public_key_ecdsa(const fido_cred_t *cred,
+ struct sk_enroll_response *response)
+{
+ const uint8_t *ptr;
+ BIGNUM *x = NULL, *y = NULL;
+ EC_POINT *q = NULL;
+ EC_GROUP *g = NULL;
+ int ret = -1;
+
+ response->public_key = NULL;
+ response->public_key_len = 0;
+
+ if ((x = BN_new()) == NULL ||
+ (y = BN_new()) == NULL ||
+ (g = EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1)) == NULL ||
+ (q = EC_POINT_new(g)) == NULL) {
+ skdebug(__func__, "libcrypto setup failed");
+ goto out;
+ }
+ if ((ptr = fido_cred_pubkey_ptr(cred)) == NULL) {
+ skdebug(__func__, "fido_cred_pubkey_ptr failed");
+ goto out;
+ }
+ if (fido_cred_pubkey_len(cred) != 64) {
+ skdebug(__func__, "bad fido_cred_pubkey_len %zu",
+ fido_cred_pubkey_len(cred));
+ goto out;
+ }
+
+ if (BN_bin2bn(ptr, 32, x) == NULL ||
+ BN_bin2bn(ptr + 32, 32, y) == NULL) {
+ skdebug(__func__, "BN_bin2bn failed");
+ goto out;
+ }
+ if (EC_POINT_set_affine_coordinates_GFp(g, q, x, y, NULL) != 1) {
+ skdebug(__func__, "EC_POINT_set_affine_coordinates_GFp failed");
+ goto out;
+ }
+ response->public_key_len = EC_POINT_point2oct(g, q,
+ POINT_CONVERSION_UNCOMPRESSED, NULL, 0, NULL);
+ if (response->public_key_len == 0 || response->public_key_len > 2048) {
+ skdebug(__func__, "bad pubkey length %zu",
+ response->public_key_len);
+ goto out;
+ }
+ if ((response->public_key = malloc(response->public_key_len)) == NULL) {
+ skdebug(__func__, "malloc pubkey failed");
+ goto out;
+ }
+ if (EC_POINT_point2oct(g, q, POINT_CONVERSION_UNCOMPRESSED,
+ response->public_key, response->public_key_len, NULL) == 0) {
+ skdebug(__func__, "EC_POINT_point2oct failed");
+ goto out;
+ }
+ /* success */
+ ret = 0;
+ out:
+ if (ret != 0 && response->public_key != NULL) {
+ memset(response->public_key, 0, response->public_key_len);
+ free(response->public_key);
+ response->public_key = NULL;
+ }
+ EC_POINT_free(q);
+ EC_GROUP_free(g);
+ BN_clear_free(x);
+ BN_clear_free(y);
+ return ret;
+}
+#endif /* WITH_OPENSSL */
+
+static int
+pack_public_key_ed25519(const fido_cred_t *cred,
+ struct sk_enroll_response *response)
+{
+ const uint8_t *ptr;
+ size_t len;
+ int ret = -1;
+
+ response->public_key = NULL;
+ response->public_key_len = 0;
+
+ if ((len = fido_cred_pubkey_len(cred)) != 32) {
+ skdebug(__func__, "bad fido_cred_pubkey_len len %zu", len);
+ goto out;
+ }
+ if ((ptr = fido_cred_pubkey_ptr(cred)) == NULL) {
+ skdebug(__func__, "fido_cred_pubkey_ptr failed");
+ goto out;
+ }
+ response->public_key_len = len;
+ if ((response->public_key = malloc(response->public_key_len)) == NULL) {
+ skdebug(__func__, "malloc pubkey failed");
+ goto out;
+ }
+ memcpy(response->public_key, ptr, len);
+ ret = 0;
+ out:
+ if (ret != 0)
+ free(response->public_key);
+ return ret;
+}
+
+static int
+pack_public_key(uint32_t alg, const fido_cred_t *cred,
+ struct sk_enroll_response *response)
+{
+ switch(alg) {
+#ifdef WITH_OPENSSL
+ case SSH_SK_ECDSA:
+ return pack_public_key_ecdsa(cred, response);
+#endif /* WITH_OPENSSL */
+ case SSH_SK_ED25519:
+ return pack_public_key_ed25519(cred, response);
+ default:
+ return -1;
+ }
+}
+
+static int
+fidoerr_to_skerr(int fidoerr)
+{
+ switch (fidoerr) {
+ case FIDO_ERR_UNSUPPORTED_OPTION:
+ case FIDO_ERR_UNSUPPORTED_ALGORITHM:
+ return SSH_SK_ERR_UNSUPPORTED;
+ case FIDO_ERR_PIN_REQUIRED:
+ case FIDO_ERR_PIN_INVALID:
+ return SSH_SK_ERR_PIN_REQUIRED;
+ default:
+ return -1;
+ }
+}
+
+static int
+check_enroll_options(struct sk_option **options, char **devicep,
+ uint8_t *user_id, size_t user_id_len)
+{
+ size_t i;
+
+ if (options == NULL)
+ return 0;
+ for (i = 0; options[i] != NULL; i++) {
+ if (strcmp(options[i]->name, "device") == 0) {
+ if ((*devicep = strdup(options[i]->value)) == NULL) {
+ skdebug(__func__, "strdup device failed");
+ return -1;
+ }
+ skdebug(__func__, "requested device %s", *devicep);
+ } else if (strcmp(options[i]->name, "user") == 0) {
+ if (strlcpy(user_id, options[i]->value, user_id_len) >=
+ user_id_len) {
+ skdebug(__func__, "user too long");
+ return -1;
+ }
+ skdebug(__func__, "requested user %s",
+ (char *)user_id);
+ } else {
+ skdebug(__func__, "requested unsupported option %s",
+ options[i]->name);
+ if (options[i]->required) {
+ skdebug(__func__, "unknown required option");
+ return -1;
+ }
+ }
+ }
+ return 0;
+}
+
+int
+sk_enroll(uint32_t alg, const uint8_t *challenge, size_t challenge_len,
+ const char *application, uint8_t flags, const char *pin,
+ struct sk_option **options, struct sk_enroll_response **enroll_response)
+{
+ fido_cred_t *cred = NULL;
+ const uint8_t *ptr;
+ uint8_t user_id[32], chall_hash[32];
+ struct sk_usbhid *sk = NULL;
+ struct sk_enroll_response *response = NULL;
+ size_t len;
+ int credprot;
+ int cose_alg;
+ int ret = SSH_SK_ERR_GENERAL;
+ int r;
+ char *device = NULL;
+
+ fido_init(SSH_FIDO_INIT_ARG);
+
+ if (enroll_response == NULL) {
+ skdebug(__func__, "enroll_response == NULL");
+ goto out;
+ }
+ *enroll_response = NULL;
+ memset(user_id, 0, sizeof(user_id));
+ if (check_enroll_options(options, &device, user_id,
+ sizeof(user_id)) != 0)
+ goto out; /* error already logged */
+
+ switch(alg) {
+#ifdef WITH_OPENSSL
+ case SSH_SK_ECDSA:
+ cose_alg = COSE_ES256;
+ break;
+#endif /* WITH_OPENSSL */
+ case SSH_SK_ED25519:
+ cose_alg = COSE_EDDSA;
+ break;
+ default:
+ skdebug(__func__, "unsupported key type %d", alg);
+ goto out;
+ }
+ if (device != NULL)
+ sk = sk_open(device);
+ else
+ sk = sk_probe(NULL, NULL, 0);
+ if (sk == NULL) {
+ skdebug(__func__, "failed to find sk");
+ goto out;
+ }
+ skdebug(__func__, "using device %s", sk->path);
+ if ((cred = fido_cred_new()) == NULL) {
+ skdebug(__func__, "fido_cred_new failed");
+ goto out;
+ }
+ if ((r = fido_cred_set_type(cred, cose_alg)) != FIDO_OK) {
+ skdebug(__func__, "fido_cred_set_type: %s", fido_strerr(r));
+ goto out;
+ }
+ if (sha256_mem(challenge, challenge_len,
+ chall_hash, sizeof(chall_hash)) != 0) {
+ skdebug(__func__, "hash challenge failed");
+ goto out;
+ }
+ if ((r = fido_cred_set_clientdata_hash(cred, chall_hash,
+ sizeof(chall_hash))) != FIDO_OK) {
+ skdebug(__func__, "fido_cred_set_clientdata_hash: %s",
+ fido_strerr(r));
+ goto out;
+ }
+ if ((r = fido_cred_set_rk(cred, (flags & SSH_SK_RESIDENT_KEY) != 0 ?
+ FIDO_OPT_TRUE : FIDO_OPT_OMIT)) != FIDO_OK) {
+ skdebug(__func__, "fido_cred_set_rk: %s", fido_strerr(r));
+ goto out;
+ }
+ if ((r = fido_cred_set_user(cred, user_id, sizeof(user_id),
+ "openssh", "openssh", NULL)) != FIDO_OK) {
+ skdebug(__func__, "fido_cred_set_user: %s", fido_strerr(r));
+ goto out;
+ }
+ if ((r = fido_cred_set_rp(cred, application, NULL)) != FIDO_OK) {
+ skdebug(__func__, "fido_cred_set_rp: %s", fido_strerr(r));
+ goto out;
+ }
+ if ((flags & (SSH_SK_RESIDENT_KEY|SSH_SK_USER_VERIFICATION_REQD)) != 0) {
+#if !defined(HAVE_FIDO_DEV_SUPPORTS_CRED_PROT) || \
+ !defined(HAVE_FIDO_CRED_SET_PROT)
+ skdebug(__func__, "libfido2 version does not support a feature required for this operation. Please upgrade to >=1.5.0");
+ ret = SSH_SK_ERR_UNSUPPORTED;
+ goto out;
+ credprot = 0; (void)credprot; /* avoid warning */
+#endif
+ if (!fido_dev_supports_cred_prot(sk->dev)) {
+ skdebug(__func__, "%s does not support credprot, "
+ "refusing to create unprotected "
+ "resident/verify-required key", sk->path);
+ ret = SSH_SK_ERR_UNSUPPORTED;
+ goto out;
+ }
+ if ((flags & SSH_SK_USER_VERIFICATION_REQD))
+ credprot = FIDO_CRED_PROT_UV_REQUIRED;
+ else
+ credprot = FIDO_CRED_PROT_UV_OPTIONAL_WITH_ID;
+
+ if ((r = fido_cred_set_prot(cred, credprot)) != FIDO_OK) {
+ skdebug(__func__, "fido_cred_set_prot: %s",
+ fido_strerr(r));
+ ret = fidoerr_to_skerr(r);
+ goto out;
+ }
+ }
+ if ((r = fido_dev_make_cred(sk->dev, cred, pin)) != FIDO_OK) {
+ skdebug(__func__, "fido_dev_make_cred: %s", fido_strerr(r));
+ ret = fidoerr_to_skerr(r);
+ goto out;
+ }
+ if (fido_cred_x5c_ptr(cred) != NULL) {
+ if ((r = fido_cred_verify(cred)) != FIDO_OK) {
+ skdebug(__func__, "fido_cred_verify: %s",
+ fido_strerr(r));
+ goto out;
+ }
+ } else {
+ skdebug(__func__, "self-attested credential");
+ if ((r = fido_cred_verify_self(cred)) != FIDO_OK) {
+ skdebug(__func__, "fido_cred_verify_self: %s",
+ fido_strerr(r));
+ goto out;
+ }
+ }
+ if ((response = calloc(1, sizeof(*response))) == NULL) {
+ skdebug(__func__, "calloc response failed");
+ goto out;
+ }
+ if (pack_public_key(alg, cred, response) != 0) {
+ skdebug(__func__, "pack_public_key failed");
+ goto out;
+ }
+ if ((ptr = fido_cred_id_ptr(cred)) != NULL) {
+ len = fido_cred_id_len(cred);
+ if ((response->key_handle = calloc(1, len)) == NULL) {
+ skdebug(__func__, "calloc key handle failed");
+ goto out;
+ }
+ memcpy(response->key_handle, ptr, len);
+ response->key_handle_len = len;
+ }
+ if ((ptr = fido_cred_sig_ptr(cred)) != NULL) {
+ len = fido_cred_sig_len(cred);
+ if ((response->signature = calloc(1, len)) == NULL) {
+ skdebug(__func__, "calloc signature failed");
+ goto out;
+ }
+ memcpy(response->signature, ptr, len);
+ response->signature_len = len;
+ }
+ if ((ptr = fido_cred_x5c_ptr(cred)) != NULL) {
+ len = fido_cred_x5c_len(cred);
+ skdebug(__func__, "attestation cert len=%zu", len);
+ if ((response->attestation_cert = calloc(1, len)) == NULL) {
+ skdebug(__func__, "calloc attestation cert failed");
+ goto out;
+ }
+ memcpy(response->attestation_cert, ptr, len);
+ response->attestation_cert_len = len;
+ }
+ if ((ptr = fido_cred_authdata_ptr(cred)) != NULL) {
+ len = fido_cred_authdata_len(cred);
+ skdebug(__func__, "authdata len=%zu", len);
+ if ((response->authdata = calloc(1, len)) == NULL) {
+ skdebug(__func__, "calloc authdata failed");
+ goto out;
+ }
+ memcpy(response->authdata, ptr, len);
+ response->authdata_len = len;
+ }
+ *enroll_response = response;
+ response = NULL;
+ ret = 0;
+ out:
+ free(device);
+ if (response != NULL) {
+ free(response->public_key);
+ free(response->key_handle);
+ free(response->signature);
+ free(response->attestation_cert);
+ free(response->authdata);
+ free(response);
+ }
+ sk_close(sk);
+ fido_cred_free(&cred);
+ return ret;
+}
+
+#ifdef WITH_OPENSSL
+static int
+pack_sig_ecdsa(fido_assert_t *assert, struct sk_sign_response *response)
+{
+ ECDSA_SIG *sig = NULL;
+ const BIGNUM *sig_r, *sig_s;
+ const unsigned char *cp;
+ size_t sig_len;
+ int ret = -1;
+
+ cp = fido_assert_sig_ptr(assert, 0);
+ sig_len = fido_assert_sig_len(assert, 0);
+ if ((sig = d2i_ECDSA_SIG(NULL, &cp, sig_len)) == NULL) {
+ skdebug(__func__, "d2i_ECDSA_SIG failed");
+ goto out;
+ }
+ ECDSA_SIG_get0(sig, &sig_r, &sig_s);
+ response->sig_r_len = BN_num_bytes(sig_r);
+ response->sig_s_len = BN_num_bytes(sig_s);
+ if ((response->sig_r = calloc(1, response->sig_r_len)) == NULL ||
+ (response->sig_s = calloc(1, response->sig_s_len)) == NULL) {
+ skdebug(__func__, "calloc signature failed");
+ goto out;
+ }
+ BN_bn2bin(sig_r, response->sig_r);
+ BN_bn2bin(sig_s, response->sig_s);
+ ret = 0;
+ out:
+ ECDSA_SIG_free(sig);
+ if (ret != 0) {
+ free(response->sig_r);
+ free(response->sig_s);
+ response->sig_r = NULL;
+ response->sig_s = NULL;
+ }
+ return ret;
+}
+#endif /* WITH_OPENSSL */
+
+static int
+pack_sig_ed25519(fido_assert_t *assert, struct sk_sign_response *response)
+{
+ const unsigned char *ptr;
+ size_t len;
+ int ret = -1;
+
+ ptr = fido_assert_sig_ptr(assert, 0);
+ len = fido_assert_sig_len(assert, 0);
+ if (len != 64) {
+ skdebug(__func__, "bad length %zu", len);
+ goto out;
+ }
+ response->sig_r_len = len;
+ if ((response->sig_r = calloc(1, response->sig_r_len)) == NULL) {
+ skdebug(__func__, "calloc signature failed");
+ goto out;
+ }
+ memcpy(response->sig_r, ptr, len);
+ ret = 0;
+ out:
+ if (ret != 0) {
+ free(response->sig_r);
+ response->sig_r = NULL;
+ }
+ return ret;
+}
+
+static int
+pack_sig(uint32_t alg, fido_assert_t *assert,
+ struct sk_sign_response *response)
+{
+ switch(alg) {
+#ifdef WITH_OPENSSL
+ case SSH_SK_ECDSA:
+ return pack_sig_ecdsa(assert, response);
+#endif /* WITH_OPENSSL */
+ case SSH_SK_ED25519:
+ return pack_sig_ed25519(assert, response);
+ default:
+ return -1;
+ }
+}
+
+/* Checks sk_options for sk_sign() and sk_load_resident_keys() */
+static int
+check_sign_load_resident_options(struct sk_option **options, char **devicep)
+{
+ size_t i;
+
+ if (options == NULL)
+ return 0;
+ for (i = 0; options[i] != NULL; i++) {
+ if (strcmp(options[i]->name, "device") == 0) {
+ if ((*devicep = strdup(options[i]->value)) == NULL) {
+ skdebug(__func__, "strdup device failed");
+ return -1;
+ }
+ skdebug(__func__, "requested device %s", *devicep);
+ } else {
+ skdebug(__func__, "requested unsupported option %s",
+ options[i]->name);
+ if (options[i]->required) {
+ skdebug(__func__, "unknown required option");
+ return -1;
+ }
+ }
+ }
+ return 0;
+}
+
+int
+sk_sign(uint32_t alg, const uint8_t *data, size_t datalen,
+ const char *application,
+ const uint8_t *key_handle, size_t key_handle_len,
+ uint8_t flags, const char *pin, struct sk_option **options,
+ struct sk_sign_response **sign_response)
+{
+ fido_assert_t *assert = NULL;
+ char *device = NULL;
+ struct sk_usbhid *sk = NULL;
+ struct sk_sign_response *response = NULL;
+ uint8_t message[32];
+ int ret = SSH_SK_ERR_GENERAL;
+ int r;
+
+ fido_init(SSH_FIDO_INIT_ARG);
+
+ if (sign_response == NULL) {
+ skdebug(__func__, "sign_response == NULL");
+ goto out;
+ }
+ *sign_response = NULL;
+ if (check_sign_load_resident_options(options, &device) != 0)
+ goto out; /* error already logged */
+ /* hash data to be signed before it goes to the security key */
+ if ((r = sha256_mem(data, datalen, message, sizeof(message))) != 0) {
+ skdebug(__func__, "hash message failed");
+ goto out;
+ }
+ if (device != NULL)
+ sk = sk_open(device);
+ else if (pin != NULL || (flags & SSH_SK_USER_VERIFICATION_REQD))
+ sk = sk_probe(NULL, NULL, 0);
+ else
+ sk = sk_probe(application, key_handle, key_handle_len);
+ if (sk == NULL) {
+ skdebug(__func__, "failed to find sk");
+ goto out;
+ }
+ if ((assert = fido_assert_new()) == NULL) {
+ skdebug(__func__, "fido_assert_new failed");
+ goto out;
+ }
+ if ((r = fido_assert_set_clientdata_hash(assert, message,
+ sizeof(message))) != FIDO_OK) {
+ skdebug(__func__, "fido_assert_set_clientdata_hash: %s",
+ fido_strerr(r));
+ goto out;
+ }
+ if ((r = fido_assert_set_rp(assert, application)) != FIDO_OK) {
+ skdebug(__func__, "fido_assert_set_rp: %s", fido_strerr(r));
+ goto out;
+ }
+ if ((r = fido_assert_allow_cred(assert, key_handle,
+ key_handle_len)) != FIDO_OK) {
+ skdebug(__func__, "fido_assert_allow_cred: %s", fido_strerr(r));
+ goto out;
+ }
+ if ((r = fido_assert_set_up(assert,
+ (flags & SSH_SK_USER_PRESENCE_REQD) ?
+ FIDO_OPT_TRUE : FIDO_OPT_FALSE)) != FIDO_OK) {
+ skdebug(__func__, "fido_assert_set_up: %s", fido_strerr(r));
+ goto out;
+ }
+ if (pin == NULL && (flags & SSH_SK_USER_VERIFICATION_REQD) &&
+ (r = fido_assert_set_uv(assert, FIDO_OPT_TRUE)) != FIDO_OK) {
+ skdebug(__func__, "fido_assert_set_uv: %s", fido_strerr(r));
+ ret = FIDO_ERR_PIN_REQUIRED;
+ goto out;
+ }
+ if ((r = fido_dev_get_assert(sk->dev, assert, pin)) != FIDO_OK) {
+ skdebug(__func__, "fido_dev_get_assert: %s", fido_strerr(r));
+ ret = fidoerr_to_skerr(r);
+ goto out;
+ }
+ if ((response = calloc(1, sizeof(*response))) == NULL) {
+ skdebug(__func__, "calloc response failed");
+ goto out;
+ }
+ response->flags = fido_assert_flags(assert, 0);
+ response->counter = fido_assert_sigcount(assert, 0);
+ if (pack_sig(alg, assert, response) != 0) {
+ skdebug(__func__, "pack_sig failed");
+ goto out;
+ }
+ *sign_response = response;
+ response = NULL;
+ ret = 0;
+ out:
+ explicit_bzero(message, sizeof(message));
+ free(device);
+ if (response != NULL) {
+ free(response->sig_r);
+ free(response->sig_s);
+ free(response);
+ }
+ sk_close(sk);
+ fido_assert_free(&assert);
+ return ret;
+}
+
+static int
+read_rks(struct sk_usbhid *sk, const char *pin,
+ struct sk_resident_key ***rksp, size_t *nrksp)
+{
+ int ret = SSH_SK_ERR_GENERAL, r = -1;
+ fido_credman_metadata_t *metadata = NULL;
+ fido_credman_rp_t *rp = NULL;
+ fido_credman_rk_t *rk = NULL;
+ size_t i, j, nrp, nrk;
+ const fido_cred_t *cred;
+ struct sk_resident_key *srk = NULL, **tmp;
+
+ if (pin == NULL) {
+ skdebug(__func__, "no PIN specified");
+ ret = SSH_SK_ERR_PIN_REQUIRED;
+ goto out;
+ }
+ if ((metadata = fido_credman_metadata_new()) == NULL) {
+ skdebug(__func__, "alloc failed");
+ goto out;
+ }
+
+ if ((r = fido_credman_get_dev_metadata(sk->dev, metadata, pin)) != 0) {
+ if (r == FIDO_ERR_INVALID_COMMAND) {
+ skdebug(__func__, "device %s does not support "
+ "resident keys", sk->path);
+ ret = 0;
+ goto out;
+ }
+ skdebug(__func__, "get metadata for %s failed: %s",
+ sk->path, fido_strerr(r));
+ ret = fidoerr_to_skerr(r);
+ goto out;
+ }
+ skdebug(__func__, "existing %llu, remaining %llu",
+ (unsigned long long)fido_credman_rk_existing(metadata),
+ (unsigned long long)fido_credman_rk_remaining(metadata));
+ if ((rp = fido_credman_rp_new()) == NULL) {
+ skdebug(__func__, "alloc rp failed");
+ goto out;
+ }
+ if ((r = fido_credman_get_dev_rp(sk->dev, rp, pin)) != 0) {
+ skdebug(__func__, "get RPs for %s failed: %s",
+ sk->path, fido_strerr(r));
+ goto out;
+ }
+ nrp = fido_credman_rp_count(rp);
+ skdebug(__func__, "Device %s has resident keys for %zu RPs",
+ sk->path, nrp);
+
+ /* Iterate over RP IDs that have resident keys */
+ for (i = 0; i < nrp; i++) {
+ skdebug(__func__, "rp %zu: name=\"%s\" id=\"%s\" hashlen=%zu",
+ i, fido_credman_rp_name(rp, i), fido_credman_rp_id(rp, i),
+ fido_credman_rp_id_hash_len(rp, i));
+
+ /* Skip non-SSH RP IDs */
+ if (strncasecmp(fido_credman_rp_id(rp, i), "ssh:", 4) != 0)
+ continue;
+
+ fido_credman_rk_free(&rk);
+ if ((rk = fido_credman_rk_new()) == NULL) {
+ skdebug(__func__, "alloc rk failed");
+ goto out;
+ }
+ if ((r = fido_credman_get_dev_rk(sk->dev,
+ fido_credman_rp_id(rp, i), rk, pin)) != 0) {
+ skdebug(__func__, "get RKs for %s slot %zu failed: %s",
+ sk->path, i, fido_strerr(r));
+ goto out;
+ }
+ nrk = fido_credman_rk_count(rk);
+ skdebug(__func__, "RP \"%s\" has %zu resident keys",
+ fido_credman_rp_id(rp, i), nrk);
+
+ /* Iterate over resident keys for this RP ID */
+ for (j = 0; j < nrk; j++) {
+ if ((cred = fido_credman_rk(rk, j)) == NULL) {
+ skdebug(__func__, "no RK in slot %zu", j);
+ continue;
+ }
+ skdebug(__func__, "Device %s RP \"%s\" slot %zu: "
+ "type %d flags 0x%02x prot 0x%02x", sk->path,
+ fido_credman_rp_id(rp, i), j, fido_cred_type(cred),
+ fido_cred_flags(cred), fido_cred_prot(cred));
+
+ /* build response entry */
+ if ((srk = calloc(1, sizeof(*srk))) == NULL ||
+ (srk->key.key_handle = calloc(1,
+ fido_cred_id_len(cred))) == NULL ||
+ (srk->application = strdup(fido_credman_rp_id(rp,
+ i))) == NULL) {
+ skdebug(__func__, "alloc sk_resident_key");
+ goto out;
+ }
+
+ srk->key.key_handle_len = fido_cred_id_len(cred);
+ memcpy(srk->key.key_handle, fido_cred_id_ptr(cred),
+ srk->key.key_handle_len);
+
+ switch (fido_cred_type(cred)) {
+ case COSE_ES256:
+ srk->alg = SSH_SK_ECDSA;
+ break;
+ case COSE_EDDSA:
+ srk->alg = SSH_SK_ED25519;
+ break;
+ default:
+ skdebug(__func__, "unsupported key type %d",
+ fido_cred_type(cred));
+ goto out; /* XXX free rk and continue */
+ }
+
+ if (fido_cred_prot(cred) == FIDO_CRED_PROT_UV_REQUIRED)
+ srk->flags |= SSH_SK_USER_VERIFICATION_REQD;
+
+ if ((r = pack_public_key(srk->alg, cred,
+ &srk->key)) != 0) {
+ skdebug(__func__, "pack public key failed");
+ goto out;
+ }
+ /* append */
+ if ((tmp = recallocarray(*rksp, *nrksp, (*nrksp) + 1,
+ sizeof(**rksp))) == NULL) {
+ skdebug(__func__, "alloc rksp");
+ goto out;
+ }
+ *rksp = tmp;
+ (*rksp)[(*nrksp)++] = srk;
+ srk = NULL;
+ }
+ }
+ /* Success */
+ ret = 0;
+ out:
+ if (srk != NULL) {
+ free(srk->application);
+ freezero(srk->key.public_key, srk->key.public_key_len);
+ freezero(srk->key.key_handle, srk->key.key_handle_len);
+ freezero(srk, sizeof(*srk));
+ }
+ fido_credman_rp_free(&rp);
+ fido_credman_rk_free(&rk);
+ fido_credman_metadata_free(&metadata);
+ return ret;
+}
+
+int
+sk_load_resident_keys(const char *pin, struct sk_option **options,
+ struct sk_resident_key ***rksp, size_t *nrksp)
+{
+ int ret = SSH_SK_ERR_GENERAL, r = -1;
+ size_t i, nrks = 0;
+ struct sk_resident_key **rks = NULL;
+ struct sk_usbhid *sk = NULL;
+ char *device = NULL;
+
+ *rksp = NULL;
+ *nrksp = 0;
+
+ fido_init(SSH_FIDO_INIT_ARG);
+
+ if (check_sign_load_resident_options(options, &device) != 0)
+ goto out; /* error already logged */
+ if (device != NULL)
+ sk = sk_open(device);
+ else
+ sk = sk_probe(NULL, NULL, 0);
+ if (sk == NULL) {
+ skdebug(__func__, "failed to find sk");
+ goto out;
+ }
+ skdebug(__func__, "trying %s", sk->path);
+ if ((r = read_rks(sk, pin, &rks, &nrks)) != 0) {
+ skdebug(__func__, "read_rks failed for %s", sk->path);
+ ret = r;
+ goto out;
+ }
+ /* success, unless we have no keys but a specific error */
+ if (nrks > 0 || ret == SSH_SK_ERR_GENERAL)
+ ret = 0;
+ *rksp = rks;
+ *nrksp = nrks;
+ rks = NULL;
+ nrks = 0;
+ out:
+ sk_close(sk);
+ for (i = 0; i < nrks; i++) {
+ free(rks[i]->application);
+ freezero(rks[i]->key.public_key, rks[i]->key.public_key_len);
+ freezero(rks[i]->key.key_handle, rks[i]->key.key_handle_len);
+ freezero(rks[i], sizeof(*rks[i]));
+ }
+ free(rks);
+ return ret;
+}
+
+#endif /* ENABLE_SK_INTERNAL */
diff --git a/crypto/openssh/sntrup761.c b/crypto/openssh/sntrup761.c
new file mode 100644
index 000000000000..c63e600fb5b4
--- /dev/null
+++ b/crypto/openssh/sntrup761.c
@@ -0,0 +1,1273 @@
+/* $OpenBSD: sntrup761.c,v 1.5 2021/01/08 02:33:13 dtucker Exp $ */
+
+/*
+ * Public Domain, Authors:
+ * - Daniel J. Bernstein
+ * - Chitchanok Chuengsatiansup
+ * - Tanja Lange
+ * - Christine van Vredendaal
+ */
+
+#include "includes.h"
+
+#ifdef USE_SNTRUP761X25519
+
+#include <string.h>
+#include "crypto_api.h"
+
+#define int8 crypto_int8
+#define uint8 crypto_uint8
+#define int16 crypto_int16
+#define uint16 crypto_uint16
+#define int32 crypto_int32
+#define uint32 crypto_uint32
+#define int64 crypto_int64
+#define uint64 crypto_uint64
+
+/* from supercop-20201130/crypto_sort/int32/portable4/int32_minmax.inc */
+#define int32_MINMAX(a,b) \
+do { \
+ int64_t ab = (int64_t)b ^ (int64_t)a; \
+ int64_t c = (int64_t)b - (int64_t)a; \
+ c ^= ab & (c ^ b); \
+ c >>= 31; \
+ c &= ab; \
+ a ^= c; \
+ b ^= c; \
+} while(0)
+
+/* from supercop-20201130/crypto_sort/int32/portable4/sort.c */
+
+
+static void crypto_sort_int32(void *array,long long n)
+{
+ long long top,p,q,r,i,j;
+ int32 *x = array;
+
+ if (n < 2) return;
+ top = 1;
+ while (top < n - top) top += top;
+
+ for (p = top;p >= 1;p >>= 1) {
+ i = 0;
+ while (i + 2 * p <= n) {
+ for (j = i;j < i + p;++j)
+ int32_MINMAX(x[j],x[j+p]);
+ i += 2 * p;
+ }
+ for (j = i;j < n - p;++j)
+ int32_MINMAX(x[j],x[j+p]);
+
+ i = 0;
+ j = 0;
+ for (q = top;q > p;q >>= 1) {
+ if (j != i) for (;;) {
+ if (j == n - q) goto done;
+ int32 a = x[j + p];
+ for (r = q;r > p;r >>= 1)
+ int32_MINMAX(a,x[j + r]);
+ x[j + p] = a;
+ ++j;
+ if (j == i + p) {
+ i += 2 * p;
+ break;
+ }
+ }
+ while (i + p <= n - q) {
+ for (j = i;j < i + p;++j) {
+ int32 a = x[j + p];
+ for (r = q;r > p;r >>= 1)
+ int32_MINMAX(a,x[j+r]);
+ x[j + p] = a;
+ }
+ i += 2 * p;
+ }
+ /* now i + p > n - q */
+ j = i;
+ while (j < n - q) {
+ int32 a = x[j + p];
+ for (r = q;r > p;r >>= 1)
+ int32_MINMAX(a,x[j+r]);
+ x[j + p] = a;
+ ++j;
+ }
+
+ done: ;
+ }
+ }
+}
+
+/* from supercop-20201130/crypto_sort/uint32/useint32/sort.c */
+
+/* can save time by vectorizing xor loops */
+/* can save time by integrating xor loops with int32_sort */
+
+static void crypto_sort_uint32(void *array,long long n)
+{
+ crypto_uint32 *x = array;
+ long long j;
+ for (j = 0;j < n;++j) x[j] ^= 0x80000000;
+ crypto_sort_int32(array,n);
+ for (j = 0;j < n;++j) x[j] ^= 0x80000000;
+}
+
+/* from supercop-20201130/crypto_kem/sntrup761/ref/uint32.c */
+
+/*
+CPU division instruction typically takes time depending on x.
+This software is designed to take time independent of x.
+Time still varies depending on m; user must ensure that m is constant.
+Time also varies on CPUs where multiplication is variable-time.
+There could be more CPU issues.
+There could also be compiler issues.
+*/
+
+static void uint32_divmod_uint14(uint32 *q,uint16 *r,uint32 x,uint16 m)
+{
+ uint32 v = 0x80000000;
+ uint32 qpart;
+ uint32 mask;
+
+ v /= m;
+
+ /* caller guarantees m > 0 */
+ /* caller guarantees m < 16384 */
+ /* vm <= 2^31 <= vm+m-1 */
+ /* xvm <= 2^31 x <= xvm+x(m-1) */
+
+ *q = 0;
+
+ qpart = (x*(uint64)v)>>31;
+ /* 2^31 qpart <= xv <= 2^31 qpart + 2^31-1 */
+ /* 2^31 qpart m <= xvm <= 2^31 qpart m + (2^31-1)m */
+ /* 2^31 qpart m <= 2^31 x <= 2^31 qpart m + (2^31-1)m + x(m-1) */
+ /* 0 <= 2^31 newx <= (2^31-1)m + x(m-1) */
+ /* 0 <= newx <= (1-1/2^31)m + x(m-1)/2^31 */
+ /* 0 <= newx <= (1-1/2^31)(2^14-1) + (2^32-1)((2^14-1)-1)/2^31 */
+
+ x -= qpart*m; *q += qpart;
+ /* x <= 49146 */
+
+ qpart = (x*(uint64)v)>>31;
+ /* 0 <= newx <= (1-1/2^31)m + x(m-1)/2^31 */
+ /* 0 <= newx <= m + 49146(2^14-1)/2^31 */
+ /* 0 <= newx <= m + 0.4 */
+ /* 0 <= newx <= m */
+
+ x -= qpart*m; *q += qpart;
+ /* x <= m */
+
+ x -= m; *q += 1;
+ mask = -(x>>31);
+ x += mask&(uint32)m; *q += mask;
+ /* x < m */
+
+ *r = x;
+}
+
+
+static uint16 uint32_mod_uint14(uint32 x,uint16 m)
+{
+ uint32 q;
+ uint16 r;
+ uint32_divmod_uint14(&q,&r,x,m);
+ return r;
+}
+
+/* from supercop-20201130/crypto_kem/sntrup761/ref/int32.c */
+
+static void int32_divmod_uint14(int32 *q,uint16 *r,int32 x,uint16 m)
+{
+ uint32 uq,uq2;
+ uint16 ur,ur2;
+ uint32 mask;
+
+ uint32_divmod_uint14(&uq,&ur,0x80000000+(uint32)x,m);
+ uint32_divmod_uint14(&uq2,&ur2,0x80000000,m);
+ ur -= ur2; uq -= uq2;
+ mask = -(uint32)(ur>>15);
+ ur += mask&m; uq += mask;
+ *r = ur; *q = uq;
+}
+
+
+static uint16 int32_mod_uint14(int32 x,uint16 m)
+{
+ int32 q;
+ uint16 r;
+ int32_divmod_uint14(&q,&r,x,m);
+ return r;
+}
+
+/* from supercop-20201130/crypto_kem/sntrup761/ref/paramsmenu.h */
+/* pick one of these three: */
+#define SIZE761
+#undef SIZE653
+#undef SIZE857
+
+/* pick one of these two: */
+#define SNTRUP /* Streamlined NTRU Prime */
+#undef LPR /* NTRU LPRime */
+
+/* from supercop-20201130/crypto_kem/sntrup761/ref/params.h */
+#ifndef params_H
+#define params_H
+
+/* menu of parameter choices: */
+
+
+/* what the menu means: */
+
+#if defined(SIZE761)
+#define p 761
+#define q 4591
+#define Rounded_bytes 1007
+#ifndef LPR
+#define Rq_bytes 1158
+#define w 286
+#else
+#define w 250
+#define tau0 2156
+#define tau1 114
+#define tau2 2007
+#define tau3 287
+#endif
+
+#elif defined(SIZE653)
+#define p 653
+#define q 4621
+#define Rounded_bytes 865
+#ifndef LPR
+#define Rq_bytes 994
+#define w 288
+#else
+#define w 252
+#define tau0 2175
+#define tau1 113
+#define tau2 2031
+#define tau3 290
+#endif
+
+#elif defined(SIZE857)
+#define p 857
+#define q 5167
+#define Rounded_bytes 1152
+#ifndef LPR
+#define Rq_bytes 1322
+#define w 322
+#else
+#define w 281
+#define tau0 2433
+#define tau1 101
+#define tau2 2265
+#define tau3 324
+#endif
+
+#else
+#error "no parameter set defined"
+#endif
+
+#ifdef LPR
+#define I 256
+#endif
+
+#endif
+
+/* from supercop-20201130/crypto_kem/sntrup761/ref/Decode.h */
+#ifndef Decode_H
+#define Decode_H
+
+
+/* Decode(R,s,M,len) */
+/* assumes 0 < M[i] < 16384 */
+/* produces 0 <= R[i] < M[i] */
+
+#endif
+
+/* from supercop-20201130/crypto_kem/sntrup761/ref/Decode.c */
+
+static void Decode(uint16 *out,const unsigned char *S,const uint16 *M,long long len)
+{
+ if (len == 1) {
+ if (M[0] == 1)
+ *out = 0;
+ else if (M[0] <= 256)
+ *out = uint32_mod_uint14(S[0],M[0]);
+ else
+ *out = uint32_mod_uint14(S[0]+(((uint16)S[1])<<8),M[0]);
+ }
+ if (len > 1) {
+ uint16 R2[(len+1)/2];
+ uint16 M2[(len+1)/2];
+ uint16 bottomr[len/2];
+ uint32 bottomt[len/2];
+ long long i;
+ for (i = 0;i < len-1;i += 2) {
+ uint32 m = M[i]*(uint32) M[i+1];
+ if (m > 256*16383) {
+ bottomt[i/2] = 256*256;
+ bottomr[i/2] = S[0]+256*S[1];
+ S += 2;
+ M2[i/2] = (((m+255)>>8)+255)>>8;
+ } else if (m >= 16384) {
+ bottomt[i/2] = 256;
+ bottomr[i/2] = S[0];
+ S += 1;
+ M2[i/2] = (m+255)>>8;
+ } else {
+ bottomt[i/2] = 1;
+ bottomr[i/2] = 0;
+ M2[i/2] = m;
+ }
+ }
+ if (i < len)
+ M2[i/2] = M[i];
+ Decode(R2,S,M2,(len+1)/2);
+ for (i = 0;i < len-1;i += 2) {
+ uint32 r = bottomr[i/2];
+ uint32 r1;
+ uint16 r0;
+ r += bottomt[i/2]*R2[i/2];
+ uint32_divmod_uint14(&r1,&r0,r,M[i]);
+ r1 = uint32_mod_uint14(r1,M[i+1]); /* only needed for invalid inputs */
+ *out++ = r0;
+ *out++ = r1;
+ }
+ if (i < len)
+ *out++ = R2[i/2];
+ }
+}
+
+/* from supercop-20201130/crypto_kem/sntrup761/ref/Encode.h */
+#ifndef Encode_H
+#define Encode_H
+
+
+/* Encode(s,R,M,len) */
+/* assumes 0 <= R[i] < M[i] < 16384 */
+
+#endif
+
+/* from supercop-20201130/crypto_kem/sntrup761/ref/Encode.c */
+
+/* 0 <= R[i] < M[i] < 16384 */
+static void Encode(unsigned char *out,const uint16 *R,const uint16 *M,long long len)
+{
+ if (len == 1) {
+ uint16 r = R[0];
+ uint16 m = M[0];
+ while (m > 1) {
+ *out++ = r;
+ r >>= 8;
+ m = (m+255)>>8;
+ }
+ }
+ if (len > 1) {
+ uint16 R2[(len+1)/2];
+ uint16 M2[(len+1)/2];
+ long long i;
+ for (i = 0;i < len-1;i += 2) {
+ uint32 m0 = M[i];
+ uint32 r = R[i]+R[i+1]*m0;
+ uint32 m = M[i+1]*m0;
+ while (m >= 16384) {
+ *out++ = r;
+ r >>= 8;
+ m = (m+255)>>8;
+ }
+ R2[i/2] = r;
+ M2[i/2] = m;
+ }
+ if (i < len) {
+ R2[i/2] = R[i];
+ M2[i/2] = M[i];
+ }
+ Encode(out,R2,M2,(len+1)/2);
+ }
+}
+
+/* from supercop-20201130/crypto_kem/sntrup761/ref/kem.c */
+
+#ifdef LPR
+#endif
+
+
+/* ----- masks */
+
+#ifndef LPR
+
+/* return -1 if x!=0; else return 0 */
+static int int16_nonzero_mask(int16 x)
+{
+ uint16 u = x; /* 0, else 1...65535 */
+ uint32 v = u; /* 0, else 1...65535 */
+ v = -v; /* 0, else 2^32-65535...2^32-1 */
+ v >>= 31; /* 0, else 1 */
+ return -v; /* 0, else -1 */
+}
+
+#endif
+
+/* return -1 if x<0; otherwise return 0 */
+static int int16_negative_mask(int16 x)
+{
+ uint16 u = x;
+ u >>= 15;
+ return -(int) u;
+ /* alternative with gcc -fwrapv: */
+ /* x>>15 compiles to CPU's arithmetic right shift */
+}
+
+/* ----- arithmetic mod 3 */
+
+typedef int8 small;
+
+/* F3 is always represented as -1,0,1 */
+/* so ZZ_fromF3 is a no-op */
+
+/* x must not be close to top int16 */
+static small F3_freeze(int16 x)
+{
+ return int32_mod_uint14(x+1,3)-1;
+}
+
+/* ----- arithmetic mod q */
+
+#define q12 ((q-1)/2)
+typedef int16 Fq;
+/* always represented as -q12...q12 */
+/* so ZZ_fromFq is a no-op */
+
+/* x must not be close to top int32 */
+static Fq Fq_freeze(int32 x)
+{
+ return int32_mod_uint14(x+q12,q)-q12;
+}
+
+#ifndef LPR
+
+static Fq Fq_recip(Fq a1)
+{
+ int i = 1;
+ Fq ai = a1;
+
+ while (i < q-2) {
+ ai = Fq_freeze(a1*(int32)ai);
+ i += 1;
+ }
+ return ai;
+}
+
+#endif
+
+/* ----- Top and Right */
+
+#ifdef LPR
+#define tau 16
+
+static int8 Top(Fq C)
+{
+ return (tau1*(int32)(C+tau0)+16384)>>15;
+}
+
+static Fq Right(int8 T)
+{
+ return Fq_freeze(tau3*(int32)T-tau2);
+}
+#endif
+
+/* ----- small polynomials */
+
+#ifndef LPR
+
+/* 0 if Weightw_is(r), else -1 */
+static int Weightw_mask(small *r)
+{
+ int weight = 0;
+ int i;
+
+ for (i = 0;i < p;++i) weight += r[i]&1;
+ return int16_nonzero_mask(weight-w);
+}
+
+/* R3_fromR(R_fromRq(r)) */
+static void R3_fromRq(small *out,const Fq *r)
+{
+ int i;
+ for (i = 0;i < p;++i) out[i] = F3_freeze(r[i]);
+}
+
+/* h = f*g in the ring R3 */
+static void R3_mult(small *h,const small *f,const small *g)
+{
+ small fg[p+p-1];
+ small result;
+ int i,j;
+
+ for (i = 0;i < p;++i) {
+ result = 0;
+ for (j = 0;j <= i;++j) result = F3_freeze(result+f[j]*g[i-j]);
+ fg[i] = result;
+ }
+ for (i = p;i < p+p-1;++i) {
+ result = 0;
+ for (j = i-p+1;j < p;++j) result = F3_freeze(result+f[j]*g[i-j]);
+ fg[i] = result;
+ }
+
+ for (i = p+p-2;i >= p;--i) {
+ fg[i-p] = F3_freeze(fg[i-p]+fg[i]);
+ fg[i-p+1] = F3_freeze(fg[i-p+1]+fg[i]);
+ }
+
+ for (i = 0;i < p;++i) h[i] = fg[i];
+}
+
+/* returns 0 if recip succeeded; else -1 */
+static int R3_recip(small *out,const small *in)
+{
+ small f[p+1],g[p+1],v[p+1],r[p+1];
+ int i,loop,delta;
+ int sign,swap,t;
+
+ for (i = 0;i < p+1;++i) v[i] = 0;
+ for (i = 0;i < p+1;++i) r[i] = 0;
+ r[0] = 1;
+ for (i = 0;i < p;++i) f[i] = 0;
+ f[0] = 1; f[p-1] = f[p] = -1;
+ for (i = 0;i < p;++i) g[p-1-i] = in[i];
+ g[p] = 0;
+
+ delta = 1;
+
+ for (loop = 0;loop < 2*p-1;++loop) {
+ for (i = p;i > 0;--i) v[i] = v[i-1];
+ v[0] = 0;
+
+ sign = -g[0]*f[0];
+ swap = int16_negative_mask(-delta) & int16_nonzero_mask(g[0]);
+ delta ^= swap&(delta^-delta);
+ delta += 1;
+
+ for (i = 0;i < p+1;++i) {
+ t = swap&(f[i]^g[i]); f[i] ^= t; g[i] ^= t;
+ t = swap&(v[i]^r[i]); v[i] ^= t; r[i] ^= t;
+ }
+
+ for (i = 0;i < p+1;++i) g[i] = F3_freeze(g[i]+sign*f[i]);
+ for (i = 0;i < p+1;++i) r[i] = F3_freeze(r[i]+sign*v[i]);
+
+ for (i = 0;i < p;++i) g[i] = g[i+1];
+ g[p] = 0;
+ }
+
+ sign = f[0];
+ for (i = 0;i < p;++i) out[i] = sign*v[p-1-i];
+
+ return int16_nonzero_mask(delta);
+}
+
+#endif
+
+/* ----- polynomials mod q */
+
+/* h = f*g in the ring Rq */
+static void Rq_mult_small(Fq *h,const Fq *f,const small *g)
+{
+ Fq fg[p+p-1];
+ Fq result;
+ int i,j;
+
+ for (i = 0;i < p;++i) {
+ result = 0;
+ for (j = 0;j <= i;++j) result = Fq_freeze(result+f[j]*(int32)g[i-j]);
+ fg[i] = result;
+ }
+ for (i = p;i < p+p-1;++i) {
+ result = 0;
+ for (j = i-p+1;j < p;++j) result = Fq_freeze(result+f[j]*(int32)g[i-j]);
+ fg[i] = result;
+ }
+
+ for (i = p+p-2;i >= p;--i) {
+ fg[i-p] = Fq_freeze(fg[i-p]+fg[i]);
+ fg[i-p+1] = Fq_freeze(fg[i-p+1]+fg[i]);
+ }
+
+ for (i = 0;i < p;++i) h[i] = fg[i];
+}
+
+#ifndef LPR
+
+/* h = 3f in Rq */
+static void Rq_mult3(Fq *h,const Fq *f)
+{
+ int i;
+
+ for (i = 0;i < p;++i) h[i] = Fq_freeze(3*f[i]);
+}
+
+/* out = 1/(3*in) in Rq */
+/* returns 0 if recip succeeded; else -1 */
+static int Rq_recip3(Fq *out,const small *in)
+{
+ Fq f[p+1],g[p+1],v[p+1],r[p+1];
+ int i,loop,delta;
+ int swap,t;
+ int32 f0,g0;
+ Fq scale;
+
+ for (i = 0;i < p+1;++i) v[i] = 0;
+ for (i = 0;i < p+1;++i) r[i] = 0;
+ r[0] = Fq_recip(3);
+ for (i = 0;i < p;++i) f[i] = 0;
+ f[0] = 1; f[p-1] = f[p] = -1;
+ for (i = 0;i < p;++i) g[p-1-i] = in[i];
+ g[p] = 0;
+
+ delta = 1;
+
+ for (loop = 0;loop < 2*p-1;++loop) {
+ for (i = p;i > 0;--i) v[i] = v[i-1];
+ v[0] = 0;
+
+ swap = int16_negative_mask(-delta) & int16_nonzero_mask(g[0]);
+ delta ^= swap&(delta^-delta);
+ delta += 1;
+
+ for (i = 0;i < p+1;++i) {
+ t = swap&(f[i]^g[i]); f[i] ^= t; g[i] ^= t;
+ t = swap&(v[i]^r[i]); v[i] ^= t; r[i] ^= t;
+ }
+
+ f0 = f[0];
+ g0 = g[0];
+ for (i = 0;i < p+1;++i) g[i] = Fq_freeze(f0*g[i]-g0*f[i]);
+ for (i = 0;i < p+1;++i) r[i] = Fq_freeze(f0*r[i]-g0*v[i]);
+
+ for (i = 0;i < p;++i) g[i] = g[i+1];
+ g[p] = 0;
+ }
+
+ scale = Fq_recip(f[0]);
+ for (i = 0;i < p;++i) out[i] = Fq_freeze(scale*(int32)v[p-1-i]);
+
+ return int16_nonzero_mask(delta);
+}
+
+#endif
+
+/* ----- rounded polynomials mod q */
+
+static void Round(Fq *out,const Fq *a)
+{
+ int i;
+ for (i = 0;i < p;++i) out[i] = a[i]-F3_freeze(a[i]);
+}
+
+/* ----- sorting to generate short polynomial */
+
+static void Short_fromlist(small *out,const uint32 *in)
+{
+ uint32 L[p];
+ int i;
+
+ for (i = 0;i < w;++i) L[i] = in[i]&(uint32)-2;
+ for (i = w;i < p;++i) L[i] = (in[i]&(uint32)-3)|1;
+ crypto_sort_uint32(L,p);
+ for (i = 0;i < p;++i) out[i] = (L[i]&3)-1;
+}
+
+/* ----- underlying hash function */
+
+#define Hash_bytes 32
+
+/* e.g., b = 0 means out = Hash0(in) */
+static void Hash_prefix(unsigned char *out,int b,const unsigned char *in,int inlen)
+{
+ unsigned char x[inlen+1];
+ unsigned char h[64];
+ int i;
+
+ x[0] = b;
+ for (i = 0;i < inlen;++i) x[i+1] = in[i];
+ crypto_hash_sha512(h,x,inlen+1);
+ for (i = 0;i < 32;++i) out[i] = h[i];
+}
+
+/* ----- higher-level randomness */
+
+static uint32 urandom32(void)
+{
+ unsigned char c[4];
+ uint32 out[4];
+
+ randombytes(c,4);
+ out[0] = (uint32)c[0];
+ out[1] = ((uint32)c[1])<<8;
+ out[2] = ((uint32)c[2])<<16;
+ out[3] = ((uint32)c[3])<<24;
+ return out[0]+out[1]+out[2]+out[3];
+}
+
+static void Short_random(small *out)
+{
+ uint32 L[p];
+ int i;
+
+ for (i = 0;i < p;++i) L[i] = urandom32();
+ Short_fromlist(out,L);
+}
+
+#ifndef LPR
+
+static void Small_random(small *out)
+{
+ int i;
+
+ for (i = 0;i < p;++i) out[i] = (((urandom32()&0x3fffffff)*3)>>30)-1;
+}
+
+#endif
+
+/* ----- Streamlined NTRU Prime Core */
+
+#ifndef LPR
+
+/* h,(f,ginv) = KeyGen() */
+static void KeyGen(Fq *h,small *f,small *ginv)
+{
+ small g[p];
+ Fq finv[p];
+
+ for (;;) {
+ Small_random(g);
+ if (R3_recip(ginv,g) == 0) break;
+ }
+ Short_random(f);
+ Rq_recip3(finv,f); /* always works */
+ Rq_mult_small(h,finv,g);
+}
+
+/* c = Encrypt(r,h) */
+static void Encrypt(Fq *c,const small *r,const Fq *h)
+{
+ Fq hr[p];
+
+ Rq_mult_small(hr,h,r);
+ Round(c,hr);
+}
+
+/* r = Decrypt(c,(f,ginv)) */
+static void Decrypt(small *r,const Fq *c,const small *f,const small *ginv)
+{
+ Fq cf[p];
+ Fq cf3[p];
+ small e[p];
+ small ev[p];
+ int mask;
+ int i;
+
+ Rq_mult_small(cf,c,f);
+ Rq_mult3(cf3,cf);
+ R3_fromRq(e,cf3);
+ R3_mult(ev,e,ginv);
+
+ mask = Weightw_mask(ev); /* 0 if weight w, else -1 */
+ for (i = 0;i < w;++i) r[i] = ((ev[i]^1)&~mask)^1;
+ for (i = w;i < p;++i) r[i] = ev[i]&~mask;
+}
+
+#endif
+
+/* ----- NTRU LPRime Core */
+
+#ifdef LPR
+
+/* (G,A),a = KeyGen(G); leaves G unchanged */
+static void KeyGen(Fq *A,small *a,const Fq *G)
+{
+ Fq aG[p];
+
+ Short_random(a);
+ Rq_mult_small(aG,G,a);
+ Round(A,aG);
+}
+
+/* B,T = Encrypt(r,(G,A),b) */
+static void Encrypt(Fq *B,int8 *T,const int8 *r,const Fq *G,const Fq *A,const small *b)
+{
+ Fq bG[p];
+ Fq bA[p];
+ int i;
+
+ Rq_mult_small(bG,G,b);
+ Round(B,bG);
+ Rq_mult_small(bA,A,b);
+ for (i = 0;i < I;++i) T[i] = Top(Fq_freeze(bA[i]+r[i]*q12));
+}
+
+/* r = Decrypt((B,T),a) */
+static void Decrypt(int8 *r,const Fq *B,const int8 *T,const small *a)
+{
+ Fq aB[p];
+ int i;
+
+ Rq_mult_small(aB,B,a);
+ for (i = 0;i < I;++i)
+ r[i] = -int16_negative_mask(Fq_freeze(Right(T[i])-aB[i]+4*w+1));
+}
+
+#endif
+
+/* ----- encoding I-bit inputs */
+
+#ifdef LPR
+
+#define Inputs_bytes (I/8)
+typedef int8 Inputs[I]; /* passed by reference */
+
+static void Inputs_encode(unsigned char *s,const Inputs r)
+{
+ int i;
+ for (i = 0;i < Inputs_bytes;++i) s[i] = 0;
+ for (i = 0;i < I;++i) s[i>>3] |= r[i]<<(i&7);
+}
+
+#endif
+
+/* ----- Expand */
+
+#ifdef LPR
+
+static const unsigned char aes_nonce[16] = {0};
+
+static void Expand(uint32 *L,const unsigned char *k)
+{
+ int i;
+ crypto_stream_aes256ctr((unsigned char *) L,4*p,aes_nonce,k);
+ for (i = 0;i < p;++i) {
+ uint32 L0 = ((unsigned char *) L)[4*i];
+ uint32 L1 = ((unsigned char *) L)[4*i+1];
+ uint32 L2 = ((unsigned char *) L)[4*i+2];
+ uint32 L3 = ((unsigned char *) L)[4*i+3];
+ L[i] = L0+(L1<<8)+(L2<<16)+(L3<<24);
+ }
+}
+
+#endif
+
+/* ----- Seeds */
+
+#ifdef LPR
+
+#define Seeds_bytes 32
+
+static void Seeds_random(unsigned char *s)
+{
+ randombytes(s,Seeds_bytes);
+}
+
+#endif
+
+/* ----- Generator, HashShort */
+
+#ifdef LPR
+
+/* G = Generator(k) */
+static void Generator(Fq *G,const unsigned char *k)
+{
+ uint32 L[p];
+ int i;
+
+ Expand(L,k);
+ for (i = 0;i < p;++i) G[i] = uint32_mod_uint14(L[i],q)-q12;
+}
+
+/* out = HashShort(r) */
+static void HashShort(small *out,const Inputs r)
+{
+ unsigned char s[Inputs_bytes];
+ unsigned char h[Hash_bytes];
+ uint32 L[p];
+
+ Inputs_encode(s,r);
+ Hash_prefix(h,5,s,sizeof s);
+ Expand(L,h);
+ Short_fromlist(out,L);
+}
+
+#endif
+
+/* ----- NTRU LPRime Expand */
+
+#ifdef LPR
+
+/* (S,A),a = XKeyGen() */
+static void XKeyGen(unsigned char *S,Fq *A,small *a)
+{
+ Fq G[p];
+
+ Seeds_random(S);
+ Generator(G,S);
+ KeyGen(A,a,G);
+}
+
+/* B,T = XEncrypt(r,(S,A)) */
+static void XEncrypt(Fq *B,int8 *T,const int8 *r,const unsigned char *S,const Fq *A)
+{
+ Fq G[p];
+ small b[p];
+
+ Generator(G,S);
+ HashShort(b,r);
+ Encrypt(B,T,r,G,A,b);
+}
+
+#define XDecrypt Decrypt
+
+#endif
+
+/* ----- encoding small polynomials (including short polynomials) */
+
+#define Small_bytes ((p+3)/4)
+
+/* these are the only functions that rely on p mod 4 = 1 */
+
+static void Small_encode(unsigned char *s,const small *f)
+{
+ small x;
+ int i;
+
+ for (i = 0;i < p/4;++i) {
+ x = *f++ + 1;
+ x += (*f++ + 1)<<2;
+ x += (*f++ + 1)<<4;
+ x += (*f++ + 1)<<6;
+ *s++ = x;
+ }
+ x = *f++ + 1;
+ *s++ = x;
+}
+
+static void Small_decode(small *f,const unsigned char *s)
+{
+ unsigned char x;
+ int i;
+
+ for (i = 0;i < p/4;++i) {
+ x = *s++;
+ *f++ = ((small)(x&3))-1; x >>= 2;
+ *f++ = ((small)(x&3))-1; x >>= 2;
+ *f++ = ((small)(x&3))-1; x >>= 2;
+ *f++ = ((small)(x&3))-1;
+ }
+ x = *s++;
+ *f++ = ((small)(x&3))-1;
+}
+
+/* ----- encoding general polynomials */
+
+#ifndef LPR
+
+static void Rq_encode(unsigned char *s,const Fq *r)
+{
+ uint16 R[p],M[p];
+ int i;
+
+ for (i = 0;i < p;++i) R[i] = r[i]+q12;
+ for (i = 0;i < p;++i) M[i] = q;
+ Encode(s,R,M,p);
+}
+
+static void Rq_decode(Fq *r,const unsigned char *s)
+{
+ uint16 R[p],M[p];
+ int i;
+
+ for (i = 0;i < p;++i) M[i] = q;
+ Decode(R,s,M,p);
+ for (i = 0;i < p;++i) r[i] = ((Fq)R[i])-q12;
+}
+
+#endif
+
+/* ----- encoding rounded polynomials */
+
+static void Rounded_encode(unsigned char *s,const Fq *r)
+{
+ uint16 R[p],M[p];
+ int i;
+
+ for (i = 0;i < p;++i) R[i] = ((r[i]+q12)*10923)>>15;
+ for (i = 0;i < p;++i) M[i] = (q+2)/3;
+ Encode(s,R,M,p);
+}
+
+static void Rounded_decode(Fq *r,const unsigned char *s)
+{
+ uint16 R[p],M[p];
+ int i;
+
+ for (i = 0;i < p;++i) M[i] = (q+2)/3;
+ Decode(R,s,M,p);
+ for (i = 0;i < p;++i) r[i] = R[i]*3-q12;
+}
+
+/* ----- encoding top polynomials */
+
+#ifdef LPR
+
+#define Top_bytes (I/2)
+
+static void Top_encode(unsigned char *s,const int8 *T)
+{
+ int i;
+ for (i = 0;i < Top_bytes;++i)
+ s[i] = T[2*i]+(T[2*i+1]<<4);
+}
+
+static void Top_decode(int8 *T,const unsigned char *s)
+{
+ int i;
+ for (i = 0;i < Top_bytes;++i) {
+ T[2*i] = s[i]&15;
+ T[2*i+1] = s[i]>>4;
+ }
+}
+
+#endif
+
+/* ----- Streamlined NTRU Prime Core plus encoding */
+
+#ifndef LPR
+
+typedef small Inputs[p]; /* passed by reference */
+#define Inputs_random Short_random
+#define Inputs_encode Small_encode
+#define Inputs_bytes Small_bytes
+
+#define Ciphertexts_bytes Rounded_bytes
+#define SecretKeys_bytes (2*Small_bytes)
+#define PublicKeys_bytes Rq_bytes
+
+/* pk,sk = ZKeyGen() */
+static void ZKeyGen(unsigned char *pk,unsigned char *sk)
+{
+ Fq h[p];
+ small f[p],v[p];
+
+ KeyGen(h,f,v);
+ Rq_encode(pk,h);
+ Small_encode(sk,f); sk += Small_bytes;
+ Small_encode(sk,v);
+}
+
+/* C = ZEncrypt(r,pk) */
+static void ZEncrypt(unsigned char *C,const Inputs r,const unsigned char *pk)
+{
+ Fq h[p];
+ Fq c[p];
+ Rq_decode(h,pk);
+ Encrypt(c,r,h);
+ Rounded_encode(C,c);
+}
+
+/* r = ZDecrypt(C,sk) */
+static void ZDecrypt(Inputs r,const unsigned char *C,const unsigned char *sk)
+{
+ small f[p],v[p];
+ Fq c[p];
+
+ Small_decode(f,sk); sk += Small_bytes;
+ Small_decode(v,sk);
+ Rounded_decode(c,C);
+ Decrypt(r,c,f,v);
+}
+
+#endif
+
+/* ----- NTRU LPRime Expand plus encoding */
+
+#ifdef LPR
+
+#define Ciphertexts_bytes (Rounded_bytes+Top_bytes)
+#define SecretKeys_bytes Small_bytes
+#define PublicKeys_bytes (Seeds_bytes+Rounded_bytes)
+
+static void Inputs_random(Inputs r)
+{
+ unsigned char s[Inputs_bytes];
+ int i;
+
+ randombytes(s,sizeof s);
+ for (i = 0;i < I;++i) r[i] = 1&(s[i>>3]>>(i&7));
+}
+
+/* pk,sk = ZKeyGen() */
+static void ZKeyGen(unsigned char *pk,unsigned char *sk)
+{
+ Fq A[p];
+ small a[p];
+
+ XKeyGen(pk,A,a); pk += Seeds_bytes;
+ Rounded_encode(pk,A);
+ Small_encode(sk,a);
+}
+
+/* c = ZEncrypt(r,pk) */
+static void ZEncrypt(unsigned char *c,const Inputs r,const unsigned char *pk)
+{
+ Fq A[p];
+ Fq B[p];
+ int8 T[I];
+
+ Rounded_decode(A,pk+Seeds_bytes);
+ XEncrypt(B,T,r,pk,A);
+ Rounded_encode(c,B); c += Rounded_bytes;
+ Top_encode(c,T);
+}
+
+/* r = ZDecrypt(C,sk) */
+static void ZDecrypt(Inputs r,const unsigned char *c,const unsigned char *sk)
+{
+ small a[p];
+ Fq B[p];
+ int8 T[I];
+
+ Small_decode(a,sk);
+ Rounded_decode(B,c);
+ Top_decode(T,c+Rounded_bytes);
+ XDecrypt(r,B,T,a);
+}
+
+#endif
+
+/* ----- confirmation hash */
+
+#define Confirm_bytes 32
+
+/* h = HashConfirm(r,pk,cache); cache is Hash4(pk) */
+static void HashConfirm(unsigned char *h,const unsigned char *r,const unsigned char *pk,const unsigned char *cache)
+{
+#ifndef LPR
+ unsigned char x[Hash_bytes*2];
+ int i;
+
+ Hash_prefix(x,3,r,Inputs_bytes);
+ for (i = 0;i < Hash_bytes;++i) x[Hash_bytes+i] = cache[i];
+#else
+ unsigned char x[Inputs_bytes+Hash_bytes];
+ int i;
+
+ for (i = 0;i < Inputs_bytes;++i) x[i] = r[i];
+ for (i = 0;i < Hash_bytes;++i) x[Inputs_bytes+i] = cache[i];
+#endif
+ Hash_prefix(h,2,x,sizeof x);
+}
+
+/* ----- session-key hash */
+
+/* k = HashSession(b,y,z) */
+static void HashSession(unsigned char *k,int b,const unsigned char *y,const unsigned char *z)
+{
+#ifndef LPR
+ unsigned char x[Hash_bytes+Ciphertexts_bytes+Confirm_bytes];
+ int i;
+
+ Hash_prefix(x,3,y,Inputs_bytes);
+ for (i = 0;i < Ciphertexts_bytes+Confirm_bytes;++i) x[Hash_bytes+i] = z[i];
+#else
+ unsigned char x[Inputs_bytes+Ciphertexts_bytes+Confirm_bytes];
+ int i;
+
+ for (i = 0;i < Inputs_bytes;++i) x[i] = y[i];
+ for (i = 0;i < Ciphertexts_bytes+Confirm_bytes;++i) x[Inputs_bytes+i] = z[i];
+#endif
+ Hash_prefix(k,b,x,sizeof x);
+}
+
+/* ----- Streamlined NTRU Prime and NTRU LPRime */
+
+/* pk,sk = KEM_KeyGen() */
+static void KEM_KeyGen(unsigned char *pk,unsigned char *sk)
+{
+ int i;
+
+ ZKeyGen(pk,sk); sk += SecretKeys_bytes;
+ for (i = 0;i < PublicKeys_bytes;++i) *sk++ = pk[i];
+ randombytes(sk,Inputs_bytes); sk += Inputs_bytes;
+ Hash_prefix(sk,4,pk,PublicKeys_bytes);
+}
+
+/* c,r_enc = Hide(r,pk,cache); cache is Hash4(pk) */
+static void Hide(unsigned char *c,unsigned char *r_enc,const Inputs r,const unsigned char *pk,const unsigned char *cache)
+{
+ Inputs_encode(r_enc,r);
+ ZEncrypt(c,r,pk); c += Ciphertexts_bytes;
+ HashConfirm(c,r_enc,pk,cache);
+}
+
+/* c,k = Encap(pk) */
+static void Encap(unsigned char *c,unsigned char *k,const unsigned char *pk)
+{
+ Inputs r;
+ unsigned char r_enc[Inputs_bytes];
+ unsigned char cache[Hash_bytes];
+
+ Hash_prefix(cache,4,pk,PublicKeys_bytes);
+ Inputs_random(r);
+ Hide(c,r_enc,r,pk,cache);
+ HashSession(k,1,r_enc,c);
+}
+
+/* 0 if matching ciphertext+confirm, else -1 */
+static int Ciphertexts_diff_mask(const unsigned char *c,const unsigned char *c2)
+{
+ uint16 differentbits = 0;
+ int len = Ciphertexts_bytes+Confirm_bytes;
+
+ while (len-- > 0) differentbits |= (*c++)^(*c2++);
+ return (1&((differentbits-1)>>8))-1;
+}
+
+/* k = Decap(c,sk) */
+static void Decap(unsigned char *k,const unsigned char *c,const unsigned char *sk)
+{
+ const unsigned char *pk = sk + SecretKeys_bytes;
+ const unsigned char *rho = pk + PublicKeys_bytes;
+ const unsigned char *cache = rho + Inputs_bytes;
+ Inputs r;
+ unsigned char r_enc[Inputs_bytes];
+ unsigned char cnew[Ciphertexts_bytes+Confirm_bytes];
+ int mask;
+ int i;
+
+ ZDecrypt(r,c,sk);
+ Hide(cnew,r_enc,r,pk,cache);
+ mask = Ciphertexts_diff_mask(c,cnew);
+ for (i = 0;i < Inputs_bytes;++i) r_enc[i] ^= mask&(r_enc[i]^rho[i]);
+ HashSession(k,1+mask,r_enc,c);
+}
+
+/* ----- crypto_kem API */
+
+
+int crypto_kem_sntrup761_keypair(unsigned char *pk,unsigned char *sk)
+{
+ KEM_KeyGen(pk,sk);
+ return 0;
+}
+
+int crypto_kem_sntrup761_enc(unsigned char *c,unsigned char *k,const unsigned char *pk)
+{
+ Encap(c,k,pk);
+ return 0;
+}
+
+int crypto_kem_sntrup761_dec(unsigned char *k,const unsigned char *c,const unsigned char *sk)
+{
+ Decap(k,c,sk);
+ return 0;
+}
+#endif /* USE_SNTRUP761X25519 */
diff --git a/crypto/openssh/sntrup761.sh b/crypto/openssh/sntrup761.sh
new file mode 100644
index 000000000000..5cd5f92c31d7
--- /dev/null
+++ b/crypto/openssh/sntrup761.sh
@@ -0,0 +1,85 @@
+#!/bin/sh
+# $OpenBSD: sntrup761.sh,v 1.5 2021/01/08 02:33:13 dtucker Exp $
+# Placed in the Public Domain.
+#
+AUTHOR="supercop-20201130/crypto_kem/sntrup761/ref/implementors"
+FILES="
+ supercop-20201130/crypto_sort/int32/portable4/int32_minmax.inc
+ supercop-20201130/crypto_sort/int32/portable4/sort.c
+ supercop-20201130/crypto_sort/uint32/useint32/sort.c
+ supercop-20201130/crypto_kem/sntrup761/ref/uint32.c
+ supercop-20201130/crypto_kem/sntrup761/ref/int32.c
+ supercop-20201130/crypto_kem/sntrup761/ref/paramsmenu.h
+ supercop-20201130/crypto_kem/sntrup761/ref/params.h
+ supercop-20201130/crypto_kem/sntrup761/ref/Decode.h
+ supercop-20201130/crypto_kem/sntrup761/ref/Decode.c
+ supercop-20201130/crypto_kem/sntrup761/ref/Encode.h
+ supercop-20201130/crypto_kem/sntrup761/ref/Encode.c
+ supercop-20201130/crypto_kem/sntrup761/ref/kem.c
+"
+###
+
+set -e
+cd $1
+echo -n '/* $'
+echo 'OpenBSD: $ */'
+echo
+echo '/*'
+echo ' * Public Domain, Authors:'
+sed -e '/Alphabetical order:/d' -e 's/^/ * - /' < $AUTHOR
+echo ' */'
+echo
+echo '#include <string.h>'
+echo '#include "crypto_api.h"'
+echo
+# Map the types used in this code to the ones in crypto_api.h. We use #define
+# instead of typedef since some systems have existing intXX types and do not
+# permit multiple typedefs even if they do not conflict.
+for t in int8 uint8 int16 uint16 int32 uint32 int64 uint64; do
+ echo "#define $t crypto_${t}"
+done
+echo
+for i in $FILES; do
+ echo "/* from $i */"
+ # Changes to all files:
+ # - remove all includes, we inline everything required.
+ # - make functions not required elsewhere static.
+ # - rename the functions we do use.
+ # - remove unneccesary defines and externs.
+ sed -e "/#include/d" \
+ -e "s/crypto_kem_/crypto_kem_sntrup761_/g" \
+ -e "s/^void /static void /g" \
+ -e "s/^int16 /static int16 /g" \
+ -e "s/^uint16 /static uint16 /g" \
+ -e "/^extern /d" \
+ -e '/CRYPTO_NAMESPACE/d' \
+ -e "/^#define int32 crypto_int32/d" \
+ $i | \
+ case "$i" in
+ # Use int64_t for intermediate values in int32_MINMAX to prevent signed
+ # 32-bit integer overflow when called by crypto_sort_uint32.
+ */int32_minmax.inc)
+ sed -e "s/int32 ab = b ^ a/int64_t ab = (int64_t)b ^ (int64_t)a/" \
+ -e "s/int32 c = b - a/int64_t c = (int64_t)b - (int64_t)a/"
+ ;;
+ */int32/portable4/sort.c)
+ sed -e "s/void crypto_sort/void crypto_sort_int32/g"
+ ;;
+ */uint32/useint32/sort.c)
+ sed -e "s/void crypto_sort/void crypto_sort_uint32/g"
+ ;;
+ # Remove unused function to prevent warning.
+ */crypto_kem/sntrup761/ref/int32.c)
+ sed -e '/ int32_div_uint14/,/^}$/d'
+ ;;
+ # Remove unused function to prevent warning.
+ */crypto_kem/sntrup761/ref/uint32.c)
+ sed -e '/ uint32_div_uint14/,/^}$/d'
+ ;;
+ # Default: pass through.
+ *)
+ cat
+ ;;
+ esac
+ echo
+done
diff --git a/crypto/openssh/srclimit.c b/crypto/openssh/srclimit.c
new file mode 100644
index 000000000000..5014ed79f296
--- /dev/null
+++ b/crypto/openssh/srclimit.c
@@ -0,0 +1,140 @@
+/*
+ * Copyright (c) 2020 Darren Tucker <dtucker@openbsd.org>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "includes.h"
+
+#include <sys/socket.h>
+#include <sys/types.h>
+
+#include <limits.h>
+#include <netdb.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "addr.h"
+#include "canohost.h"
+#include "log.h"
+#include "misc.h"
+#include "srclimit.h"
+#include "xmalloc.h"
+
+static int max_children, max_persource, ipv4_masklen, ipv6_masklen;
+
+/* Per connection state, used to enforce unauthenticated connection limit. */
+static struct child_info {
+ int id;
+ struct xaddr addr;
+} *child;
+
+void
+srclimit_init(int max, int persource, int ipv4len, int ipv6len)
+{
+ int i;
+
+ max_children = max;
+ ipv4_masklen = ipv4len;
+ ipv6_masklen = ipv6len;
+ max_persource = persource;
+ if (max_persource == INT_MAX) /* no limit */
+ return;
+ debug("%s: max connections %d, per source %d, masks %d,%d", __func__,
+ max, persource, ipv4len, ipv6len);
+ if (max <= 0)
+ fatal("%s: invalid number of sockets: %d", __func__, max);
+ child = xcalloc(max_children, sizeof(*child));
+ for (i = 0; i < max_children; i++)
+ child[i].id = -1;
+}
+
+/* returns 1 if connection allowed, 0 if not allowed. */
+int
+srclimit_check_allow(int sock, int id)
+{
+ struct xaddr xa, xb, xmask;
+ struct sockaddr_storage addr;
+ socklen_t addrlen = sizeof(addr);
+ struct sockaddr *sa = (struct sockaddr *)&addr;
+ int i, bits, first_unused, count = 0;
+ char xas[NI_MAXHOST];
+
+ if (max_persource == INT_MAX) /* no limit */
+ return 1;
+
+ debug("%s: sock %d id %d limit %d", __func__, sock, id, max_persource);
+ if (getpeername(sock, sa, &addrlen) != 0)
+ return 1; /* not remote socket? */
+ if (addr_sa_to_xaddr(sa, addrlen, &xa) != 0)
+ return 1; /* unknown address family? */
+
+ /* Mask address off address to desired size. */
+ bits = xa.af == AF_INET ? ipv4_masklen : ipv6_masklen;
+ if (addr_netmask(xa.af, bits, &xmask) != 0 ||
+ addr_and(&xb, &xa, &xmask) != 0) {
+ debug3("%s: invalid mask %d bits", __func__, bits);
+ return 1;
+ }
+
+ first_unused = max_children;
+ /* Count matching entries and find first unused one. */
+ for (i = 0; i < max_children; i++) {
+ if (child[i].id == -1) {
+ if (i < first_unused)
+ first_unused = i;
+ } else if (addr_cmp(&child[i].addr, &xb) == 0) {
+ count++;
+ }
+ }
+ if (addr_ntop(&xa, xas, sizeof(xas)) != 0) {
+ debug3("%s: addr ntop failed", __func__);
+ return 1;
+ }
+ debug3("%s: new unauthenticated connection from %s/%d, at %d of %d",
+ __func__, xas, bits, count, max_persource);
+
+ if (first_unused == max_children) { /* no free slot found */
+ debug3("%s: no free slot", __func__);
+ return 0;
+ }
+ if (first_unused < 0 || first_unused >= max_children)
+ fatal("%s: internal error: first_unused out of range",
+ __func__);
+
+ if (count >= max_persource)
+ return 0;
+
+ /* Connection allowed, store masked address. */
+ child[first_unused].id = id;
+ memcpy(&child[first_unused].addr, &xb, sizeof(xb));
+ return 1;
+}
+
+void
+srclimit_done(int id)
+{
+ int i;
+
+ if (max_persource == INT_MAX) /* no limit */
+ return;
+
+ debug("%s: id %d", __func__, id);
+ /* Clear corresponding state entry. */
+ for (i = 0; i < max_children; i++) {
+ if (child[i].id == id) {
+ child[i].id = -1;
+ return;
+ }
+ }
+}
diff --git a/crypto/openssh/srclimit.h b/crypto/openssh/srclimit.h
new file mode 100644
index 000000000000..6e04f32b3ff7
--- /dev/null
+++ b/crypto/openssh/srclimit.h
@@ -0,0 +1,18 @@
+/*
+ * Copyright (c) 2020 Darren Tucker <dtucker@openbsd.org>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+void srclimit_init(int, int, int, int);
+int srclimit_check_allow(int, int);
+void srclimit_done(int);
diff --git a/crypto/openssh/ssh-add.1 b/crypto/openssh/ssh-add.1
index d5da9279c5f9..2786df514178 100644
--- a/crypto/openssh/ssh-add.1
+++ b/crypto/openssh/ssh-add.1
@@ -1,4 +1,4 @@
-.\" $OpenBSD: ssh-add.1,v 1.66 2017/08/29 13:05:58 jmc Exp $
+.\" $OpenBSD: ssh-add.1,v 1.81 2020/07/14 23:57:01 djm Exp $
.\"
.\" Author: Tatu Ylonen <ylo@cs.hut.fi>
.\" Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -35,22 +35,26 @@
.\" (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: August 29 2017 $
+.Dd $Mdocdate: July 14 2020 $
.Dt SSH-ADD 1
.Os
.Sh NAME
.Nm ssh-add
-.Nd adds private key identities to the authentication agent
+.Nd adds private key identities to the OpenSSH authentication agent
.Sh SYNOPSIS
.Nm ssh-add
-.Op Fl cDdkLlqXx
+.Op Fl cDdKkLlqvXx
.Op Fl E Ar fingerprint_hash
+.Op Fl S Ar provider
.Op Fl t Ar life
.Op Ar
.Nm ssh-add
.Fl s Ar pkcs11
.Nm ssh-add
.Fl e Ar pkcs11
+.Nm ssh-add
+.Fl T
+.Ar pubkey ...
.Sh DESCRIPTION
.Nm
adds private key identities to the authentication agent,
@@ -59,8 +63,10 @@ When run without arguments, it adds the files
.Pa ~/.ssh/id_rsa ,
.Pa ~/.ssh/id_dsa ,
.Pa ~/.ssh/id_ecdsa ,
+.Pa ~/.ssh/id_ecdsa_sk ,
+.Pa ~/.ssh/id_ed25519 ,
and
-.Pa ~/.ssh/id_ed25519 .
+.Pa ~/.ssh/id_ed25519_sk .
After loading a private key,
.Nm
will try to load corresponding certificate information from the
@@ -107,6 +113,11 @@ If no public key is found at a given path,
will append
.Pa .pub
and retry.
+If the argument list consists of
+.Dq -
+then
+.Nm
+will read public keys to be removed from standard input.
.It Fl E Ar fingerprint_hash
Specifies the hash algorithm used when displaying key fingerprints.
Valid options are:
@@ -118,6 +129,8 @@ The default is
.It Fl e Ar pkcs11
Remove keys provided by the PKCS#11 shared library
.Ar pkcs11 .
+.It Fl K
+Load resident keys from a FIDO authenticator.
.It Fl k
When loading keys into or deleting keys from the agent, process plain private
keys only and skip certificates.
@@ -128,14 +141,32 @@ by the agent.
Lists fingerprints of all identities currently represented by the agent.
.It Fl q
Be quiet after a successful operation.
+.It Fl S Ar provider
+Specifies a path to a library that will be used when adding
+FIDO authenticator-hosted keys, overriding the default of using the
+internal USB HID support.
.It Fl s Ar pkcs11
Add keys provided by the PKCS#11 shared library
.Ar pkcs11 .
+.It Fl T Ar pubkey ...
+Tests whether the private keys that correspond to the specified
+.Ar pubkey
+files are usable by performing sign and verify operations on each.
.It Fl t Ar 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
.Xr sshd_config 5 .
+.It Fl v
+Verbose mode.
+Causes
+.Nm
+to print debugging messages about its progress.
+This is helpful in debugging problems.
+Multiple
+.Fl v
+options increase the verbosity.
+The maximum is 3.
.It Fl X
Unlock the agent.
.It Fl x
@@ -143,7 +174,7 @@ Lock the agent with a password.
.El
.Sh ENVIRONMENT
.Bl -tag -width Ds
-.It Ev "DISPLAY" and "SSH_ASKPASS"
+.It Ev "DISPLAY", "SSH_ASKPASS" and "SSH_ASKPASS_REQUIRE"
If
.Nm
needs a passphrase, it will read the passphrase from the current
@@ -164,25 +195,45 @@ This is particularly useful when calling
from a
.Pa .xsession
or related script.
-(Note that on some machines it
-may be necessary to redirect the input from
-.Pa /dev/null
-to make this work.)
+.Pp
+.Ev SSH_ASKPASS_REQUIRE
+allows further control over the use of an askpass program.
+If this variable is set to
+.Dq never
+then
+.Nm
+will never attempt to use one.
+If it is set to
+.Dq prefer ,
+then
+.Nm
+will prefer to use the askpass program instead of the TTY when requesting
+passwords.
+Finally, if the variable is set to
+.Dq force ,
+then the askpass program will be used for all passphrase input regardless
+of whether
+.Ev DISPLAY
+is set.
.It Ev SSH_AUTH_SOCK
Identifies the path of a
.Ux Ns -domain
socket used to communicate with the agent.
+.It Ev SSH_SK_PROVIDER
+Specifies a path to a library that will be used when loading any
+FIDO authenticator-hosted keys, overriding the default of using
+the built-in USB HID support.
.El
.Sh FILES
-.Bl -tag -width Ds
+.Bl -tag -width Ds -compact
.It Pa ~/.ssh/id_dsa
-Contains the DSA authentication identity of the user.
.It Pa ~/.ssh/id_ecdsa
-Contains the ECDSA authentication identity of the user.
+.It Pa ~/.ssh/id_ecdsa_sk
.It Pa ~/.ssh/id_ed25519
-Contains the Ed25519 authentication identity of the user.
+.It Pa ~/.ssh/id_ed25519_sk
.It Pa ~/.ssh/id_rsa
-Contains the RSA authentication identity of the user.
+Contains the DSA, ECDSA, authenticator-hosted ECDSA, Ed25519,
+authenticator-hosted Ed25519 or RSA authentication identity of the user.
.El
.Pp
Identity files should not be readable by anyone but the user.
diff --git a/crypto/openssh/ssh-add.c b/crypto/openssh/ssh-add.c
index 627c02983685..92192fcfa23c 100644
--- a/crypto/openssh/ssh-add.c
+++ b/crypto/openssh/ssh-add.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssh-add.c,v 1.136 2018/09/19 02:03:02 djm Exp $ */
+/* $OpenBSD: ssh-add.c,v 1.160 2021/04/03 06:18:41 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -40,8 +40,10 @@
#include <sys/types.h>
#include <sys/stat.h>
-#include <openssl/evp.h>
-#include "openbsd-compat/openssl-compat.h"
+#ifdef WITH_OPENSSL
+# include <openssl/evp.h>
+# include "openbsd-compat/openssl-compat.h"
+#endif
#include <errno.h>
#include <fcntl.h>
@@ -64,6 +66,8 @@
#include "misc.h"
#include "ssherr.h"
#include "digest.h"
+#include "ssh-sk.h"
+#include "sk-api.h"
/* argv0 */
extern char *__progname;
@@ -75,9 +79,11 @@ static char *default_files[] = {
_PATH_SSH_CLIENT_ID_DSA,
#ifdef OPENSSL_HAS_ECC
_PATH_SSH_CLIENT_ID_ECDSA,
+ _PATH_SSH_CLIENT_ID_ECDSA_SK,
#endif
#endif /* WITH_OPENSSL */
_PATH_SSH_CLIENT_ID_ED25519,
+ _PATH_SSH_CLIENT_ID_ED25519_SK,
_PATH_SSH_CLIENT_ID_XMSS,
NULL
};
@@ -100,32 +106,75 @@ static void
clear_pass(void)
{
if (pass) {
- explicit_bzero(pass, strlen(pass));
- free(pass);
+ freezero(pass, strlen(pass));
pass = NULL;
}
}
static int
+delete_one(int agent_fd, const struct sshkey *key, const char *comment,
+ const char *path, int qflag)
+{
+ int r;
+
+ if ((r = ssh_remove_identity(agent_fd, key)) != 0) {
+ fprintf(stderr, "Could not remove identity \"%s\": %s\n",
+ path, ssh_err(r));
+ return r;
+ }
+ if (!qflag) {
+ fprintf(stderr, "Identity removed: %s %s (%s)\n", path,
+ sshkey_type(key), comment);
+ }
+ return 0;
+}
+
+static int
+delete_stdin(int agent_fd, int qflag)
+{
+ char *line = NULL, *cp;
+ size_t linesize = 0;
+ struct sshkey *key = NULL;
+ int lnum = 0, r, ret = -1;
+
+ while (getline(&line, &linesize, stdin) != -1) {
+ lnum++;
+ sshkey_free(key);
+ key = NULL;
+ line[strcspn(line, "\n")] = '\0';
+ cp = line + strspn(line, " \t");
+ if (*cp == '#' || *cp == '\0')
+ continue;
+ if ((key = sshkey_new(KEY_UNSPEC)) == NULL)
+ fatal_f("sshkey_new");
+ if ((r = sshkey_read(key, &cp)) != 0) {
+ error_r(r, "(stdin):%d: invalid key", lnum);
+ continue;
+ }
+ if (delete_one(agent_fd, key, cp, "(stdin)", qflag) == 0)
+ ret = 0;
+ }
+ sshkey_free(key);
+ free(line);
+ return ret;
+}
+
+static int
delete_file(int agent_fd, const char *filename, int key_only, int qflag)
{
struct sshkey *public, *cert = NULL;
char *certpath = NULL, *comment = NULL;
int r, ret = -1;
+ if (strcmp(filename, "-") == 0)
+ return delete_stdin(agent_fd, qflag);
+
if ((r = sshkey_load_public(filename, &public, &comment)) != 0) {
printf("Bad key file %s: %s\n", filename, ssh_err(r));
return -1;
}
- if ((r = ssh_remove_identity(agent_fd, public)) == 0) {
- if (!qflag) {
- fprintf(stderr, "Identity removed: %s (%s)\n",
- filename, comment);
- }
+ if (delete_one(agent_fd, public, comment, filename, qflag) == 0)
ret = 0;
- } else
- fprintf(stderr, "Could not remove identity \"%s\": %s\n",
- filename, ssh_err(r));
if (key_only)
goto out;
@@ -136,8 +185,7 @@ delete_file(int agent_fd, const char *filename, int key_only, int qflag)
xasprintf(&certpath, "%s-cert.pub", filename);
if ((r = sshkey_load_public(certpath, &cert, &comment)) != 0) {
if (r != SSH_ERR_SYSTEM_ERROR || errno != ENOENT)
- error("Failed to load certificate \"%s\": %s",
- certpath, ssh_err(r));
+ error_r(r, "Failed to load certificate \"%s\"", certpath);
goto out;
}
@@ -145,15 +193,8 @@ delete_file(int agent_fd, const char *filename, int key_only, int qflag)
fatal("Certificate %s does not match private key %s",
certpath, filename);
- if ((r = ssh_remove_identity(agent_fd, cert)) == 0) {
- if (!qflag) {
- fprintf(stderr, "Identity removed: %s (%s)\n",
- certpath, comment);
- }
+ if (delete_one(agent_fd, cert, comment, certpath, qflag) == 0)
ret = 0;
- } else
- fprintf(stderr, "Could not remove identity \"%s\": %s\n",
- certpath, ssh_err(r));
out:
sshkey_free(cert);
@@ -189,7 +230,8 @@ delete_all(int agent_fd, int qflag)
}
static int
-add_file(int agent_fd, const char *filename, int key_only, int qflag)
+add_file(int agent_fd, const char *filename, int key_only, int qflag,
+ const char *skprovider)
{
struct sshkey *private, *cert;
char *comment = NULL;
@@ -203,7 +245,7 @@ add_file(int agent_fd, const char *filename, int key_only, int qflag)
if (strcmp(filename, "-") == 0) {
fd = STDIN_FILENO;
filename = "(stdin)";
- } else if ((fd = open(filename, O_RDONLY)) < 0) {
+ } else if ((fd = open(filename, O_RDONLY)) == -1) {
perror(filename);
return -1;
}
@@ -218,9 +260,7 @@ add_file(int agent_fd, const char *filename, int key_only, int qflag)
return -1;
}
}
- if ((keyblob = sshbuf_new()) == NULL)
- fatal("%s: sshbuf_new failed", __func__);
- if ((r = sshkey_load_file(fd, keyblob)) != 0) {
+ if ((r = sshbuf_load_fd(fd, &keyblob)) != 0) {
fprintf(stderr, "Error loading key \"%s\": %s\n",
filename, ssh_err(r));
sshbuf_free(keyblob);
@@ -296,10 +336,10 @@ add_file(int agent_fd, const char *filename, int key_only, int qflag)
fprintf(stderr, "Skipping update: ");
if (left == minleft) {
fprintf(stderr,
- "required signatures left (%d).\n", left);
+ "required signatures left (%d).\n", left);
} else {
fprintf(stderr,
- "more signatures left (%d) than"
+ "more signatures left (%d) than"
" required (%d).\n", left, minleft);
}
ssh_free_identitylist(idlist);
@@ -308,8 +348,24 @@ add_file(int agent_fd, const char *filename, int key_only, int qflag)
ssh_free_identitylist(idlist);
}
+ if (sshkey_is_sk(private)) {
+ if (skprovider == NULL) {
+ fprintf(stderr, "Cannot load FIDO key %s "
+ "without provider\n", filename);
+ goto out;
+ }
+ if ((private->sk_flags & SSH_SK_USER_VERIFICATION_REQD) != 0) {
+ fprintf(stderr, "FIDO verify-required key %s is not "
+ "currently supported by ssh-agent\n", filename);
+ goto out;
+ }
+ } else {
+ /* Don't send provider constraint for other keys */
+ skprovider = NULL;
+ }
+
if ((r = ssh_add_identity_constrained(agent_fd, private, comment,
- lifetime, confirm, maxsign)) == 0) {
+ lifetime, confirm, maxsign, skprovider)) == 0) {
ret = 0;
if (!qflag) {
fprintf(stderr, "Identity added: %s (%s)\n",
@@ -336,8 +392,7 @@ add_file(int agent_fd, const char *filename, int key_only, int qflag)
xasprintf(&certpath, "%s-cert.pub", filename);
if ((r = sshkey_load_public(certpath, &cert, NULL)) != 0) {
if (r != SSH_ERR_SYSTEM_ERROR || errno != ENOENT)
- error("Failed to load certificate \"%s\": %s",
- certpath, ssh_err(r));
+ error_r(r, "Failed to load certificate \"%s\"", certpath);
goto out;
}
@@ -350,21 +405,21 @@ add_file(int agent_fd, const char *filename, int key_only, int qflag)
/* Graft with private bits */
if ((r = sshkey_to_certified(private)) != 0) {
- error("%s: sshkey_to_certified: %s", __func__, ssh_err(r));
+ error_fr(r, "sshkey_to_certified");
sshkey_free(cert);
goto out;
}
if ((r = sshkey_cert_copy(cert, private)) != 0) {
- error("%s: sshkey_cert_copy: %s", __func__, ssh_err(r));
+ error_fr(r, "sshkey_cert_copy");
sshkey_free(cert);
goto out;
}
sshkey_free(cert);
if ((r = ssh_add_identity_constrained(agent_fd, private, comment,
- lifetime, confirm, maxsign)) != 0) {
- error("Certificate %s (%s) add failed: %s", certpath,
- private->cert->key_id, ssh_err(r));
+ lifetime, confirm, maxsign, skprovider)) != 0) {
+ error_r(r, "Certificate %s (%s) add failed", certpath,
+ private->cert->key_id);
goto out;
}
/* success */
@@ -418,6 +473,38 @@ update_card(int agent_fd, int add, const char *id, int qflag)
}
static int
+test_key(int agent_fd, const char *filename)
+{
+ struct sshkey *key = NULL;
+ u_char *sig = NULL;
+ size_t slen = 0;
+ int r, ret = -1;
+ char data[1024];
+
+ if ((r = sshkey_load_public(filename, &key, NULL)) != 0) {
+ error_r(r, "Couldn't read public key %s", filename);
+ return -1;
+ }
+ arc4random_buf(data, sizeof(data));
+ if ((r = ssh_agent_sign(agent_fd, key, &sig, &slen, data, sizeof(data),
+ NULL, 0)) != 0) {
+ error_r(r, "Agent signature failed for %s", filename);
+ goto done;
+ }
+ if ((r = sshkey_verify(key, sig, slen, data, sizeof(data),
+ NULL, 0, NULL)) != 0) {
+ error_r(r, "Signature verification failed for %s", filename);
+ goto done;
+ }
+ /* success */
+ ret = 0;
+ done:
+ free(sig);
+ sshkey_free(key);
+ return ret;
+}
+
+static int
list_identities(int agent_fd, int do_fp)
{
char *fp;
@@ -475,8 +562,7 @@ lock_agent(int agent_fd, int lock)
fprintf(stderr, "Passwords do not match.\n");
passok = 0;
}
- explicit_bzero(p2, strlen(p2));
- free(p2);
+ freezero(p2, strlen(p2));
}
if (passok) {
if ((r = ssh_lock_agent(agent_fd, lock, p1)) == 0) {
@@ -487,19 +573,68 @@ lock_agent(int agent_fd, int lock)
lock ? "" : "un", ssh_err(r));
}
}
- explicit_bzero(p1, strlen(p1));
- free(p1);
+ freezero(p1, strlen(p1));
return (ret);
}
static int
-do_file(int agent_fd, int deleting, int key_only, char *file, int qflag)
+load_resident_keys(int agent_fd, const char *skprovider, int qflag)
+{
+ struct sshkey **keys;
+ size_t nkeys, i;
+ int r, ok = 0;
+ char *fp;
+
+ pass = read_passphrase("Enter PIN for authenticator: ", RP_ALLOW_STDIN);
+ if ((r = sshsk_load_resident(skprovider, NULL, pass,
+ &keys, &nkeys)) != 0) {
+ error_r(r, "Unable to load resident keys");
+ return r;
+ }
+ for (i = 0; i < nkeys; i++) {
+ if ((fp = sshkey_fingerprint(keys[i],
+ fingerprint_hash, SSH_FP_DEFAULT)) == NULL)
+ fatal_f("sshkey_fingerprint failed");
+ if ((r = ssh_add_identity_constrained(agent_fd, keys[i], "",
+ lifetime, confirm, maxsign, skprovider)) != 0) {
+ error("Unable to add key %s %s",
+ sshkey_type(keys[i]), fp);
+ free(fp);
+ ok = r;
+ continue;
+ }
+ if (ok == 0)
+ ok = 1;
+ if (!qflag) {
+ fprintf(stderr, "Resident identity added: %s %s\n",
+ sshkey_type(keys[i]), fp);
+ if (lifetime != 0) {
+ fprintf(stderr,
+ "Lifetime set to %d seconds\n", lifetime);
+ }
+ if (confirm != 0) {
+ fprintf(stderr, "The user must confirm "
+ "each use of the key\n");
+ }
+ }
+ free(fp);
+ sshkey_free(keys[i]);
+ }
+ free(keys);
+ if (nkeys == 0)
+ return SSH_ERR_KEY_NOT_FOUND;
+ return ok == 1 ? 0 : ok;
+}
+
+static int
+do_file(int agent_fd, int deleting, int key_only, char *file, int qflag,
+ const char *skprovider)
{
if (deleting) {
if (delete_file(agent_fd, file, key_only, qflag) == -1)
return -1;
} else {
- if (add_file(agent_fd, file, key_only, qflag) == -1)
+ if (add_file(agent_fd, file, key_only, qflag, skprovider) == -1)
return -1;
}
return 0;
@@ -508,23 +643,16 @@ do_file(int agent_fd, int deleting, int key_only, char *file, int qflag)
static void
usage(void)
{
- fprintf(stderr, "usage: %s [options] [file ...]\n", __progname);
- fprintf(stderr, "Options:\n");
- fprintf(stderr, " -l List fingerprints of all identities.\n");
- fprintf(stderr, " -E hash Specify hash algorithm used for fingerprints.\n");
- fprintf(stderr, " -L List public key parameters of all identities.\n");
- fprintf(stderr, " -k Load only keys and not certificates.\n");
- fprintf(stderr, " -c Require confirmation to sign using identities\n");
- fprintf(stderr, " -m minleft Maxsign is only changed if less than minleft are left (for XMSS)\n");
- fprintf(stderr, " -M maxsign Maximum number of signatures allowed (for XMSS)\n");
- fprintf(stderr, " -t life Set lifetime (in seconds) when adding identities.\n");
- fprintf(stderr, " -d Delete identity.\n");
- fprintf(stderr, " -D Delete all identities.\n");
- fprintf(stderr, " -x Lock agent.\n");
- fprintf(stderr, " -X Unlock agent.\n");
- fprintf(stderr, " -s pkcs11 Add keys from PKCS#11 provider.\n");
- fprintf(stderr, " -e pkcs11 Remove keys provided by PKCS#11 provider.\n");
- fprintf(stderr, " -q Be quiet after a successful operation.\n");
+ fprintf(stderr,
+"usage: ssh-add [-cDdKkLlqvXx] [-E fingerprint_hash] [-S provider] [-t life]\n"
+#ifdef WITH_XMSS
+" [-M maxsign] [-m minleft]\n"
+#endif
+" [file ...]\n"
+" ssh-add -s pkcs11\n"
+" ssh-add -e pkcs11\n"
+" ssh-add -T pubkey ...\n"
+ );
}
int
@@ -533,20 +661,19 @@ main(int argc, char **argv)
extern char *optarg;
extern int optind;
int agent_fd;
- char *pkcs11provider = NULL;
- int r, i, ch, deleting = 0, ret = 0, key_only = 0;
- int xflag = 0, lflag = 0, Dflag = 0, qflag = 0;
+ char *pkcs11provider = NULL, *skprovider = NULL;
+ int r, i, ch, deleting = 0, ret = 0, key_only = 0, do_download = 0;
+ int xflag = 0, lflag = 0, Dflag = 0, qflag = 0, Tflag = 0;
+ SyslogFacility log_facility = SYSLOG_FACILITY_AUTH;
+ LogLevel log_level = SYSLOG_LEVEL_INFO;
- ssh_malloc_init(); /* must be called before any mallocs */
/* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */
sanitise_stdfd();
__progname = ssh_get_progname(argv[0]);
seed_rng();
-#ifdef WITH_OPENSSL
- OpenSSL_add_all_algorithms();
-#endif
+ log_init(__progname, log_level, log_facility, 1);
setvbuf(stdout, NULL, _IOLBF, 0);
@@ -563,8 +690,16 @@ main(int argc, char **argv)
exit(2);
}
- while ((ch = getopt(argc, argv, "klLcdDxXE:e:M:m:qs:t:")) != -1) {
+ skprovider = getenv("SSH_SK_PROVIDER");
+
+ while ((ch = getopt(argc, argv, "vkKlLcdDTxXE:e:M:m:qs:S:t:")) != -1) {
switch (ch) {
+ case 'v':
+ if (log_level == SYSLOG_LEVEL_INFO)
+ log_level = SYSLOG_LEVEL_DEBUG1;
+ else if (log_level < SYSLOG_LEVEL_DEBUG3)
+ log_level++;
+ break;
case 'E':
fingerprint_hash = ssh_digest_alg_by_name(optarg);
if (fingerprint_hash == -1)
@@ -573,6 +708,9 @@ main(int argc, char **argv)
case 'k':
key_only = 1;
break;
+ case 'K':
+ do_download = 1;
+ break;
case 'l':
case 'L':
if (lflag != 0)
@@ -613,12 +751,16 @@ main(int argc, char **argv)
case 's':
pkcs11provider = optarg;
break;
+ case 'S':
+ skprovider = optarg;
+ break;
case 'e':
deleting = 1;
pkcs11provider = optarg;
break;
case 't':
- if ((lifetime = convtime(optarg)) == -1) {
+ if ((lifetime = convtime(optarg)) == -1 ||
+ lifetime < 0 || (u_long)lifetime > UINT32_MAX) {
fprintf(stderr, "Invalid lifetime\n");
ret = 1;
goto done;
@@ -627,12 +769,16 @@ main(int argc, char **argv)
case 'q':
qflag = 1;
break;
+ case 'T':
+ Tflag = 1;
+ break;
default:
usage();
ret = 1;
goto done;
}
}
+ log_init(__progname, log_level, log_facility, 1);
if ((xflag != 0) + (lflag != 0) + (Dflag != 0) > 1)
fatal("Invalid combination of actions");
@@ -650,14 +796,34 @@ main(int argc, char **argv)
goto done;
}
+#ifdef ENABLE_SK_INTERNAL
+ if (skprovider == NULL)
+ skprovider = "internal";
+#endif
+
argc -= optind;
argv += optind;
+ if (Tflag) {
+ if (argc <= 0)
+ fatal("no keys to test");
+ for (r = i = 0; i < argc; i++)
+ r |= test_key(agent_fd, argv[i]);
+ ret = r == 0 ? 0 : 1;
+ goto done;
+ }
if (pkcs11provider != NULL) {
if (update_card(agent_fd, !deleting, pkcs11provider,
qflag) == -1)
ret = 1;
goto done;
}
+ if (do_download) {
+ if (skprovider == NULL)
+ fatal("Cannot download keys without provider");
+ if (load_resident_keys(agent_fd, skprovider, qflag) != 0)
+ ret = 1;
+ goto done;
+ }
if (argc == 0) {
char buf[PATH_MAX];
struct passwd *pw;
@@ -674,10 +840,10 @@ main(int argc, char **argv)
for (i = 0; default_files[i]; i++) {
snprintf(buf, sizeof(buf), "%s/%s", pw->pw_dir,
default_files[i]);
- if (stat(buf, &st) < 0)
+ if (stat(buf, &st) == -1)
continue;
if (do_file(agent_fd, deleting, key_only, buf,
- qflag) == -1)
+ qflag, skprovider) == -1)
ret = 1;
else
count++;
@@ -687,13 +853,12 @@ main(int argc, char **argv)
} else {
for (i = 0; i < argc; i++) {
if (do_file(agent_fd, deleting, key_only,
- argv[i], qflag) == -1)
+ argv[i], qflag, skprovider) == -1)
ret = 1;
}
}
- clear_pass();
-
done:
+ clear_pass();
ssh_close_authentication_socket(agent_fd);
return ret;
}
diff --git a/crypto/openssh/ssh-agent.1 b/crypto/openssh/ssh-agent.1
index 8f1b7e8a00b1..0320a2b0ff58 100644
--- a/crypto/openssh/ssh-agent.1
+++ b/crypto/openssh/ssh-agent.1
@@ -1,4 +1,4 @@
-.\" $OpenBSD: ssh-agent.1,v 1.64 2016/11/30 06:54:26 jmc Exp $
+.\" $OpenBSD: ssh-agent.1,v 1.72 2020/06/22 05:52:05 djm Exp $
.\" $FreeBSD$
.\"
.\" Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -35,57 +35,37 @@
.\" (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: November 30 2016 $
+.Dd $Mdocdate: June 22 2020 $
.Dt SSH-AGENT 1
.Os
.Sh NAME
.Nm ssh-agent
-.Nd authentication agent
+.Nd OpenSSH authentication agent
.Sh SYNOPSIS
.Nm ssh-agent
.Op Fl c | s
.Op Fl \&Ddx
.Op Fl a Ar bind_address
.Op Fl E Ar fingerprint_hash
-.Op Fl P Ar pkcs11_whitelist
+.Op Fl P Ar allowed_providers
.Op Fl t Ar life
-.Op Ar command Op Ar arg ...
+.Nm ssh-agent
+.Op Fl a Ar bind_address
+.Op Fl E Ar fingerprint_hash
+.Op Fl P Ar allowed_providers
+.Op Fl t Ar life
+.Ar command Op Ar arg ...
.Nm ssh-agent
.Op Fl c | s
.Fl k
.Sh DESCRIPTION
.Nm
-is a program to hold private keys used for public key authentication
-(RSA, DSA, ECDSA, Ed25519).
-.Nm
-is usually started in the beginning of an X-session or a login session, and
-all other windows or programs are started as clients to the ssh-agent
-program.
+is a program to hold private keys used for public key authentication.
Through use of environment variables the agent can be located
and automatically used for authentication when logging in to other
machines using
.Xr ssh 1 .
.Pp
-The agent initially does not have any private keys.
-Keys are added using
-.Xr ssh 1
-(see
-.Cm AddKeysToAgent
-in
-.Xr ssh_config 5
-for details)
-or
-.Xr ssh-add 1 .
-Multiple identities may be stored in
-.Nm
-concurrently and
-.Xr ssh 1
-will automatically use them if present.
-.Xr ssh-add 1
-is also used to remove keys from
-.Nm
-and to query the keys that are held in one.
-.Pp
The options are as follows:
.Bl -tag -width Ds
.It Fl a Ar bind_address
@@ -123,18 +103,20 @@ The default is
Kill the current agent (given by the
.Ev SSH_AGENT_PID
environment variable).
-.It Fl P Ar pkcs11_whitelist
-Specify a pattern-list of acceptable paths for PKCS#11 shared libraries
-that may be added using the
+.It Fl P Ar allowed_providers
+Specify a pattern-list of acceptable paths for PKCS#11 provider and FIDO
+authenticator middleware shared libraries that may be used with the
+.Fl S
+or
.Fl s
-option to
+options to
.Xr ssh-add 1 .
-The default is to allow loading PKCS#11 libraries from
-.Dq /usr/lib/*,/usr/local/lib/* .
-PKCS#11 libraries that do not match the whitelist will be refused.
+Libraries that do not match the pattern list will be refused.
See PATTERNS in
.Xr ssh_config 5
for a description of pattern-list syntax.
+The default list is
+.Dq /usr/lib/*,/usr/local/lib/* .
.It Fl s
Generate Bourne shell commands on
.Dv stdout .
@@ -149,66 +131,85 @@ A lifetime specified for an identity with
.Xr ssh-add 1
overrides this value.
Without this option the default maximum lifetime is forever.
+.It Ar command Op Ar arg ...
+If a command (and optional arguments) is given,
+this is executed as a subprocess of the agent.
+The agent exits automatically when the command given on the command
+line terminates.
.It Fl x
Exit after the last client has disconnected.
.El
.Pp
-If a command line is given, this is executed as a subprocess of the agent.
-When the command dies, so does the agent.
-.Pp
-The idea is that the agent is run in the user's local PC, laptop, or
-terminal.
-Authentication data need not be stored on any other
-machine, and authentication passphrases never go over the network.
-However, the connection to the agent is forwarded over SSH
-remote logins, and the user can thus use the privileges given by the
-identities anywhere in the network in a secure way.
-.Pp
-There are two main ways to get an agent set up:
-The first is that the agent starts a new subcommand into which some environment
-variables are exported, eg
+There are two main ways to get an agent set up.
+The first is at the start of an X session,
+where all other windows or programs are started as children of the
+.Nm
+program.
+The agent starts a command under which its environment
+variables are exported, for example
.Cm ssh-agent xterm & .
-The second is that the agent prints the needed shell commands (either
-.Xr sh 1
-or
-.Xr csh 1
-syntax can be generated) which can be evaluated in the calling shell, eg
-.Cm eval `ssh-agent -s`
-for Bourne-type shells such as
-.Xr sh 1
-or
-.Xr ksh 1
-and
-.Cm eval `ssh-agent -c`
-for
-.Xr csh 1
-and derivatives.
+When the command terminates, so does the agent.
.Pp
-Later
+The second method is used for a login session.
+When
+.Nm
+is started,
+it prints the shell commands required to set its environment variables,
+which in turn can be evaluated in the calling shell, for example
+.Cm eval `ssh-agent -s` .
+.Pp
+In both cases,
.Xr ssh 1
-looks at these variables and uses them to establish a connection to the agent.
+looks at these environment variables
+and uses them to establish a connection to the agent.
.Pp
-The agent will never send a private key over its request channel.
-Instead, operations that require a private key will be performed
-by the agent, and the result will be returned to the requester.
-This way, private keys are not exposed to clients using the agent.
+The agent initially does not have any private keys.
+Keys are added using
+.Xr ssh-add 1
+or by
+.Xr ssh 1
+when
+.Cm AddKeysToAgent
+is set in
+.Xr ssh_config 5 .
+Multiple identities may be stored in
+.Nm
+concurrently and
+.Xr ssh 1
+will automatically use them if present.
+.Xr ssh-add 1
+is also used to remove keys from
+.Nm
+and to query the keys that are held in one.
.Pp
-A
+Connections to
+.Nm
+may be forwarded from further remote hosts using the
+.Fl A
+option to
+.Xr ssh 1
+(but see the caveats documented therein),
+avoiding the need for authentication data to be stored on other machines.
+Authentication passphrases and private keys never go over the network:
+the connection to the agent is forwarded over SSH remote connections
+and the result is returned to the requester,
+allowing the user access to their identities anywhere in the network
+in a secure fashion.
+.Sh ENVIRONMENT
+.Bl -tag -width "SSH_AGENT_PID"
+.It Ev SSH_AGENT_PID
+When
+.Nm
+starts, it stores the name of the agent's process ID (PID) in this variable.
+.It Ev SSH_AUTH_SOCK
+When
+.Nm
+starts, it creates a
.Ux Ns -domain
-socket is created and the name of this socket is stored in the
-.Ev SSH_AUTH_SOCK
-environment
-variable.
-The socket is made accessible only to the current user.
-This method is easily abused by root or another instance of the same
-user.
-.Pp
-The
-.Ev SSH_AGENT_PID
-environment variable holds the agent's process ID.
-.Pp
-The agent exits automatically when the command given on the command
-line terminates.
+socket and stores its pathname in this variable.
+It is accessible only to the current user,
+but is easily abused by root or another instance of the same user.
+.El
.Sh FILES
.Bl -tag -width Ds
.It Pa $TMPDIR/ssh-XXXXXXXXXX/agent.<ppid>
@@ -221,6 +222,7 @@ The sockets should get automatically removed when the agent exits.
.Xr ssh 1 ,
.Xr ssh-add 1 ,
.Xr ssh-keygen 1 ,
+.Xr ssh_config 5 ,
.Xr sshd 8
.Sh AUTHORS
.An -nosplit
diff --git a/crypto/openssh/ssh-agent.c b/crypto/openssh/ssh-agent.c
index 7a35ca48cb6f..15949d2cc9ec 100644
--- a/crypto/openssh/ssh-agent.c
+++ b/crypto/openssh/ssh-agent.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssh-agent.c,v 1.231 2018/05/11 03:38:51 djm Exp $ */
+/* $OpenBSD: ssh-agent.c,v 1.278 2021/04/03 06:18:41 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -42,6 +42,7 @@ __RCSID("$FreeBSD$");
#include <sys/resource.h>
#include <sys/stat.h>
#include <sys/socket.h>
+#include <sys/wait.h>
#ifdef HAVE_SYS_TIME_H
# include <sys/time.h>
#endif
@@ -77,6 +78,7 @@ __RCSID("$FreeBSD$");
#include "xmalloc.h"
#include "ssh.h"
+#include "ssh2.h"
#include "sshbuf.h"
#include "sshkey.h"
#include "authfd.h"
@@ -86,25 +88,28 @@ __RCSID("$FreeBSD$");
#include "digest.h"
#include "ssherr.h"
#include "match.h"
-
-#ifdef ENABLE_PKCS11
+#include "msg.h"
+#include "ssherr.h"
+#include "pathnames.h"
#include "ssh-pkcs11.h"
-#endif
+#include "sk-api.h"
-#ifndef DEFAULT_PKCS11_WHITELIST
-# define DEFAULT_PKCS11_WHITELIST "/usr/lib*/*,/usr/local/lib*/*"
+#ifndef DEFAULT_ALLOWED_PROVIDERS
+# define DEFAULT_ALLOWED_PROVIDERS "/usr/lib*/*,/usr/local/lib*/*"
#endif
/* Maximum accepted message length */
#define AGENT_MAX_LEN (256*1024)
+/* Maximum bytes to read from client socket */
+#define AGENT_RBUF_LEN (4096)
typedef enum {
- AUTH_UNUSED,
- AUTH_SOCKET,
- AUTH_CONNECTION
+ AUTH_UNUSED = 0,
+ AUTH_SOCKET = 1,
+ AUTH_CONNECTION = 2,
} sock_type;
-typedef struct {
+typedef struct socket_entry {
int fd;
sock_type type;
struct sshbuf *input;
@@ -122,6 +127,7 @@ typedef struct identity {
char *provider;
time_t death;
u_int confirm;
+ char *sk_provider;
} Identity;
struct idtable {
@@ -145,8 +151,8 @@ pid_t cleanup_pid = 0;
char socket_name[PATH_MAX];
char socket_dir[PATH_MAX];
-/* PKCS#11 path whitelist */
-static char *pkcs11_whitelist;
+/* Pattern-list of allowed PKCS#11/Security key paths */
+static char *allowed_providers;
/* locking */
#define LOCK_SIZE 32
@@ -159,10 +165,13 @@ u_char lock_salt[LOCK_SALT_SIZE];
extern char *__progname;
/* Default lifetime in seconds (0 == forever) */
-static long lifetime = 0;
+static int lifetime = 0;
static int fingerprint_hash = SSH_FP_HASH_DEFAULT;
+/* Refuse signing of non-SSH messages for web-origin FIDO keys */
+static int restrict_websafe = 1;
+
/*
* Client connection count; incremented in new_socket() and decremented in
* close_socket(). When it reaches 0, ssh-agent will exit. Since it is
@@ -184,11 +193,12 @@ close_socket(SocketEntry *e)
last = 1;
}
close(e->fd);
- e->fd = -1;
- e->type = AUTH_UNUSED;
sshbuf_free(e->input);
sshbuf_free(e->output);
sshbuf_free(e->request);
+ memset(e, '\0', sizeof(*e));
+ e->fd = -1;
+ e->type = AUTH_UNUSED;
if (last)
cleanup_exit(0);
}
@@ -207,6 +217,7 @@ free_identity(Identity *id)
sshkey_free(id->key);
free(id->provider);
free(id->comment);
+ free(id->sk_provider);
free(id);
}
@@ -225,15 +236,16 @@ lookup_identity(struct sshkey *key)
/* Check confirmation of keysign request */
static int
-confirm_key(Identity *id)
+confirm_key(Identity *id, const char *extra)
{
char *p;
int ret = -1;
p = sshkey_fingerprint(id->key, fingerprint_hash, SSH_FP_DEFAULT);
if (p != NULL &&
- ask_permission("Allow use of key %s?\nKey fingerprint %s.",
- id->comment, p))
+ ask_permission("Allow use of key %s?\nKey fingerprint %s.%s%s",
+ id->comment, p,
+ extra == NULL ? "" : "\n", extra == NULL ? "" : extra))
ret = 0;
free(p);
@@ -248,7 +260,7 @@ send_status(SocketEntry *e, int success)
if ((r = sshbuf_put_u32(e->output, 1)) != 0 ||
(r = sshbuf_put_u8(e->output, success ?
SSH_AGENT_SUCCESS : SSH_AGENT_FAILURE)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "compose");
}
/* send list of supported public keys to 'client' */
@@ -259,22 +271,23 @@ process_request_identities(SocketEntry *e)
struct sshbuf *msg;
int r;
+ debug2_f("entering");
+
if ((msg = sshbuf_new()) == NULL)
- fatal("%s: sshbuf_new failed", __func__);
+ fatal_f("sshbuf_new failed");
if ((r = sshbuf_put_u8(msg, SSH2_AGENT_IDENTITIES_ANSWER)) != 0 ||
(r = sshbuf_put_u32(msg, idtab->nentries)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "compose");
TAILQ_FOREACH(id, &idtab->idlist, next) {
- if ((r = sshkey_puts_opts(id->key, msg, SSHKEY_SERIALIZE_INFO))
- != 0 ||
+ if ((r = sshkey_puts_opts(id->key, msg,
+ SSHKEY_SERIALIZE_INFO)) != 0 ||
(r = sshbuf_put_cstring(msg, id->comment)) != 0) {
- error("%s: put key/comment: %s", __func__,
- ssh_err(r));
+ error_fr(r, "compose key/comment");
continue;
}
}
if ((r = sshbuf_put_stringb(e->output, msg)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "enqueue");
sshbuf_free(msg);
}
@@ -287,60 +300,222 @@ agent_decode_alg(struct sshkey *key, u_int flags)
return "rsa-sha2-256";
else if (flags & SSH_AGENT_RSA_SHA2_512)
return "rsa-sha2-512";
+ } else if (key->type == KEY_RSA_CERT) {
+ if (flags & SSH_AGENT_RSA_SHA2_256)
+ return "rsa-sha2-256-cert-v01@openssh.com";
+ else if (flags & SSH_AGENT_RSA_SHA2_512)
+ return "rsa-sha2-512-cert-v01@openssh.com";
}
return NULL;
}
+/*
+ * Attempt to parse the contents of a buffer as a SSH publickey userauth
+ * request, checking its contents for consistency and matching the embedded
+ * key against the one that is being used for signing.
+ * Note: does not modify msg buffer.
+ * Optionally extract the username and session ID from the request.
+ */
+static int
+parse_userauth_request(struct sshbuf *msg, const struct sshkey *expected_key,
+ char **userp, struct sshbuf **sess_idp)
+{
+ struct sshbuf *b = NULL, *sess_id = NULL;
+ char *user = NULL, *service = NULL, *method = NULL, *pkalg = NULL;
+ int r;
+ u_char t, sig_follows;
+ struct sshkey *mkey = NULL;
+
+ if (userp != NULL)
+ *userp = NULL;
+ if (sess_idp != NULL)
+ *sess_idp = NULL;
+ if ((b = sshbuf_fromb(msg)) == NULL)
+ fatal_f("sshbuf_fromb");
+
+ /* SSH userauth request */
+ if ((r = sshbuf_froms(b, &sess_id)) != 0)
+ goto out;
+ if (sshbuf_len(sess_id) == 0) {
+ r = SSH_ERR_INVALID_FORMAT;
+ goto out;
+ }
+ if ((r = sshbuf_get_u8(b, &t)) != 0 || /* SSH2_MSG_USERAUTH_REQUEST */
+ (r = sshbuf_get_cstring(b, &user, NULL)) != 0 || /* server user */
+ (r = sshbuf_get_cstring(b, &service, NULL)) != 0 || /* service */
+ (r = sshbuf_get_cstring(b, &method, NULL)) != 0 || /* method */
+ (r = sshbuf_get_u8(b, &sig_follows)) != 0 || /* sig-follows */
+ (r = sshbuf_get_cstring(b, &pkalg, NULL)) != 0 || /* alg */
+ (r = sshkey_froms(b, &mkey)) != 0) /* key */
+ goto out;
+ if (t != SSH2_MSG_USERAUTH_REQUEST ||
+ sig_follows != 1 ||
+ strcmp(service, "ssh-connection") != 0 ||
+ !sshkey_equal(expected_key, mkey) ||
+ sshkey_type_from_name(pkalg) != expected_key->type) {
+ r = SSH_ERR_INVALID_FORMAT;
+ goto out;
+ }
+ if (strcmp(method, "publickey") != 0) {
+ r = SSH_ERR_INVALID_FORMAT;
+ goto out;
+ }
+ if (sshbuf_len(b) != 0) {
+ r = SSH_ERR_INVALID_FORMAT;
+ goto out;
+ }
+ /* success */
+ r = 0;
+ debug3_f("well formed userauth");
+ if (userp != NULL) {
+ *userp = user;
+ user = NULL;
+ }
+ if (sess_idp != NULL) {
+ *sess_idp = sess_id;
+ sess_id = NULL;
+ }
+ out:
+ sshbuf_free(b);
+ sshbuf_free(sess_id);
+ free(user);
+ free(service);
+ free(method);
+ free(pkalg);
+ sshkey_free(mkey);
+ return r;
+}
+
+/*
+ * Attempt to parse the contents of a buffer as a SSHSIG signature request.
+ * Note: does not modify buffer.
+ */
+static int
+parse_sshsig_request(struct sshbuf *msg)
+{
+ int r;
+ struct sshbuf *b;
+
+ if ((b = sshbuf_fromb(msg)) == NULL)
+ fatal_f("sshbuf_fromb");
+
+ if ((r = sshbuf_cmp(b, 0, "SSHSIG", 6)) != 0 ||
+ (r = sshbuf_consume(b, 6)) != 0 ||
+ (r = sshbuf_get_cstring(b, NULL, NULL)) != 0 || /* namespace */
+ (r = sshbuf_get_string_direct(b, NULL, NULL)) != 0 || /* reserved */
+ (r = sshbuf_get_cstring(b, NULL, NULL)) != 0 || /* hashalg */
+ (r = sshbuf_get_string_direct(b, NULL, NULL)) != 0) /* H(msg) */
+ goto out;
+ if (sshbuf_len(b) != 0) {
+ r = SSH_ERR_INVALID_FORMAT;
+ goto out;
+ }
+ /* success */
+ r = 0;
+ out:
+ sshbuf_free(b);
+ return r;
+}
+
+/*
+ * This function inspects a message to be signed by a FIDO key that has a
+ * web-like application string (i.e. one that does not begin with "ssh:".
+ * It checks that the message is one of those expected for SSH operations
+ * (pubkey userauth, sshsig, CA key signing) to exclude signing challenges
+ * for the web.
+ */
+static int
+check_websafe_message_contents(struct sshkey *key, struct sshbuf *data)
+{
+ if (parse_userauth_request(data, key, NULL, NULL) == 0) {
+ debug_f("signed data matches public key userauth request");
+ return 1;
+ }
+ if (parse_sshsig_request(data) == 0) {
+ debug_f("signed data matches SSHSIG signature request");
+ return 1;
+ }
+
+ /* XXX check CA signature operation */
+
+ error("web-origin key attempting to sign non-SSH message");
+ return 0;
+}
+
/* ssh2 only */
static void
process_sign_request2(SocketEntry *e)
{
- const u_char *data;
u_char *signature = NULL;
- size_t dlen, slen = 0;
+ size_t slen = 0;
u_int compat = 0, flags;
int r, ok = -1;
- struct sshbuf *msg;
+ char *fp = NULL;
+ struct sshbuf *msg = NULL, *data = NULL;
struct sshkey *key = NULL;
struct identity *id;
+ struct notifier_ctx *notifier = NULL;
- if ((msg = sshbuf_new()) == NULL)
- fatal("%s: sshbuf_new failed", __func__);
+ debug_f("entering");
+
+ if ((msg = sshbuf_new()) == NULL || (data = sshbuf_new()) == NULL)
+ fatal_f("sshbuf_new failed");
if ((r = sshkey_froms(e->request, &key)) != 0 ||
- (r = sshbuf_get_string_direct(e->request, &data, &dlen)) != 0 ||
+ (r = sshbuf_get_stringb(e->request, data)) != 0 ||
(r = sshbuf_get_u32(e->request, &flags)) != 0) {
- error("%s: couldn't parse request: %s", __func__, ssh_err(r));
+ error_fr(r, "parse");
goto send;
}
if ((id = lookup_identity(key)) == NULL) {
- verbose("%s: %s key not found", __func__, sshkey_type(key));
+ verbose_f("%s key not found", sshkey_type(key));
goto send;
}
- if (id->confirm && confirm_key(id) != 0) {
- verbose("%s: user refused key", __func__);
+ if (id->confirm && confirm_key(id, NULL) != 0) {
+ verbose_f("user refused key");
goto send;
}
+ if (sshkey_is_sk(id->key)) {
+ if (strncmp(id->key->sk_application, "ssh:", 4) != 0 &&
+ !check_websafe_message_contents(key, data)) {
+ /* error already logged */
+ goto send;
+ }
+ if ((id->key->sk_flags & SSH_SK_USER_PRESENCE_REQD)) {
+ if ((fp = sshkey_fingerprint(key, SSH_FP_HASH_DEFAULT,
+ SSH_FP_DEFAULT)) == NULL)
+ fatal_f("fingerprint failed");
+ notifier = notify_start(0,
+ "Confirm user presence for key %s %s",
+ sshkey_type(id->key), fp);
+ }
+ }
+ /* XXX support PIN required FIDO keys */
if ((r = sshkey_sign(id->key, &signature, &slen,
- data, dlen, agent_decode_alg(key, flags), compat)) != 0) {
- error("%s: sshkey_sign: %s", __func__, ssh_err(r));
+ sshbuf_ptr(data), sshbuf_len(data), agent_decode_alg(key, flags),
+ id->sk_provider, NULL, compat)) != 0) {
+ error_fr(r, "sshkey_sign");
goto send;
}
/* Success */
ok = 0;
send:
- sshkey_free(key);
+ notify_complete(notifier, "User presence confirmed");
+
if (ok == 0) {
if ((r = sshbuf_put_u8(msg, SSH2_AGENT_SIGN_RESPONSE)) != 0 ||
(r = sshbuf_put_string(msg, signature, slen)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "compose");
} else if ((r = sshbuf_put_u8(msg, SSH_AGENT_FAILURE)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "compose failure");
if ((r = sshbuf_put_stringb(e->output, msg)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "enqueue");
+ sshbuf_free(data);
sshbuf_free(msg);
+ sshkey_free(key);
+ free(fp);
free(signature);
}
@@ -352,24 +527,24 @@ process_remove_identity(SocketEntry *e)
struct sshkey *key = NULL;
Identity *id;
+ debug2_f("entering");
if ((r = sshkey_froms(e->request, &key)) != 0) {
- error("%s: get key: %s", __func__, ssh_err(r));
+ error_fr(r, "parse key");
goto done;
}
if ((id = lookup_identity(key)) == NULL) {
- debug("%s: key not found", __func__);
+ debug_f("key not found");
goto done;
}
/* We have this key, free it. */
if (idtab->nentries < 1)
- fatal("%s: internal error: nentries %d",
- __func__, idtab->nentries);
+ fatal_f("internal error: nentries %d", idtab->nentries);
TAILQ_REMOVE(&idtab->idlist, id, next);
free_identity(id);
idtab->nentries--;
- sshkey_free(key);
success = 1;
done:
+ sshkey_free(key);
send_status(e, success);
}
@@ -378,6 +553,7 @@ process_remove_all_identities(SocketEntry *e)
{
Identity *id;
+ debug2_f("entering");
/* Loop over all identities and clear the keys. */
for (id = TAILQ_FIRST(&idtab->idlist); id;
id = TAILQ_FIRST(&idtab->idlist)) {
@@ -418,65 +594,171 @@ reaper(void)
return (deadline - now);
}
-static void
-process_add_identity(SocketEntry *e)
+static int
+parse_key_constraint_extension(struct sshbuf *m, char **sk_providerp)
{
- Identity *id;
- int success = 0, confirm = 0;
- u_int seconds, maxsign;
- char *comment = NULL;
- time_t death = 0;
- struct sshkey *k = NULL;
- u_char ctype;
- int r = SSH_ERR_INTERNAL_ERROR;
+ char *ext_name = NULL;
+ int r;
- if ((r = sshkey_private_deserialize(e->request, &k)) != 0 ||
- k == NULL ||
- (r = sshbuf_get_cstring(e->request, &comment, NULL)) != 0) {
- error("%s: decode private key: %s", __func__, ssh_err(r));
- goto err;
+ if ((r = sshbuf_get_cstring(m, &ext_name, NULL)) != 0) {
+ error_fr(r, "parse constraint extension");
+ goto out;
+ }
+ debug_f("constraint ext %s", ext_name);
+ if (strcmp(ext_name, "sk-provider@openssh.com") == 0) {
+ if (sk_providerp == NULL) {
+ error_f("%s not valid here", ext_name);
+ r = SSH_ERR_INVALID_FORMAT;
+ goto out;
+ }
+ if (*sk_providerp != NULL) {
+ error_f("%s already set", ext_name);
+ r = SSH_ERR_INVALID_FORMAT;
+ goto out;
+ }
+ if ((r = sshbuf_get_cstring(m, sk_providerp, NULL)) != 0) {
+ error_fr(r, "parse %s", ext_name);
+ goto out;
+ }
+ } else {
+ error_f("unsupported constraint \"%s\"", ext_name);
+ r = SSH_ERR_FEATURE_UNSUPPORTED;
+ goto out;
}
+ /* success */
+ r = 0;
+ out:
+ free(ext_name);
+ return r;
+}
- while (sshbuf_len(e->request)) {
- if ((r = sshbuf_get_u8(e->request, &ctype)) != 0) {
- error("%s: buffer error: %s", __func__, ssh_err(r));
- goto err;
+static int
+parse_key_constraints(struct sshbuf *m, struct sshkey *k, time_t *deathp,
+ u_int *secondsp, int *confirmp, char **sk_providerp)
+{
+ u_char ctype;
+ int r;
+ u_int seconds, maxsign = 0;
+
+ while (sshbuf_len(m)) {
+ if ((r = sshbuf_get_u8(m, &ctype)) != 0) {
+ error_fr(r, "parse constraint type");
+ goto out;
}
switch (ctype) {
case SSH_AGENT_CONSTRAIN_LIFETIME:
- if ((r = sshbuf_get_u32(e->request, &seconds)) != 0) {
- error("%s: bad lifetime constraint: %s",
- __func__, ssh_err(r));
- goto err;
+ if (*deathp != 0) {
+ error_f("lifetime already set");
+ r = SSH_ERR_INVALID_FORMAT;
+ goto out;
+ }
+ if ((r = sshbuf_get_u32(m, &seconds)) != 0) {
+ error_fr(r, "parse lifetime constraint");
+ goto out;
}
- death = monotime() + seconds;
+ *deathp = monotime() + seconds;
+ *secondsp = seconds;
break;
case SSH_AGENT_CONSTRAIN_CONFIRM:
- confirm = 1;
+ if (*confirmp != 0) {
+ error_f("confirm already set");
+ r = SSH_ERR_INVALID_FORMAT;
+ goto out;
+ }
+ *confirmp = 1;
break;
case SSH_AGENT_CONSTRAIN_MAXSIGN:
- if ((r = sshbuf_get_u32(e->request, &maxsign)) != 0) {
- error("%s: bad maxsign constraint: %s",
- __func__, ssh_err(r));
- goto err;
+ if (k == NULL) {
+ error_f("maxsign not valid here");
+ r = SSH_ERR_INVALID_FORMAT;
+ goto out;
+ }
+ if (maxsign != 0) {
+ error_f("maxsign already set");
+ r = SSH_ERR_INVALID_FORMAT;
+ goto out;
+ }
+ if ((r = sshbuf_get_u32(m, &maxsign)) != 0) {
+ error_fr(r, "parse maxsign constraint");
+ goto out;
}
if ((r = sshkey_enable_maxsign(k, maxsign)) != 0) {
- error("%s: cannot enable maxsign: %s",
- __func__, ssh_err(r));
- goto err;
+ error_fr(r, "enable maxsign");
+ goto out;
}
break;
+ case SSH_AGENT_CONSTRAIN_EXTENSION:
+ if ((r = parse_key_constraint_extension(m,
+ sk_providerp)) != 0)
+ goto out; /* error already logged */
+ break;
default:
- error("%s: Unknown constraint %d", __func__, ctype);
- err:
- sshbuf_reset(e->request);
- free(comment);
- sshkey_free(k);
- goto send;
+ error_f("Unknown constraint %d", ctype);
+ r = SSH_ERR_FEATURE_UNSUPPORTED;
+ goto out;
}
}
+ /* success */
+ r = 0;
+ out:
+ return r;
+}
- success = 1;
+static void
+process_add_identity(SocketEntry *e)
+{
+ Identity *id;
+ int success = 0, confirm = 0;
+ char *fp, *comment = NULL, *sk_provider = NULL;
+ char canonical_provider[PATH_MAX];
+ time_t death = 0;
+ u_int seconds = 0;
+ struct sshkey *k = NULL;
+ int r = SSH_ERR_INTERNAL_ERROR;
+
+ debug2_f("entering");
+ if ((r = sshkey_private_deserialize(e->request, &k)) != 0 ||
+ k == NULL ||
+ (r = sshbuf_get_cstring(e->request, &comment, NULL)) != 0) {
+ error_fr(r, "parse");
+ goto out;
+ }
+ if (parse_key_constraints(e->request, k, &death, &seconds, &confirm,
+ &sk_provider) != 0) {
+ error_f("failed to parse constraints");
+ sshbuf_reset(e->request);
+ goto out;
+ }
+
+ if (sk_provider != NULL) {
+ if (!sshkey_is_sk(k)) {
+ error("Cannot add provider: %s is not an "
+ "authenticator-hosted key", sshkey_type(k));
+ goto out;
+ }
+ if (strcasecmp(sk_provider, "internal") == 0) {
+ debug_f("internal provider");
+ } else {
+ if (realpath(sk_provider, canonical_provider) == NULL) {
+ verbose("failed provider \"%.100s\": "
+ "realpath: %s", sk_provider,
+ strerror(errno));
+ goto out;
+ }
+ free(sk_provider);
+ sk_provider = xstrdup(canonical_provider);
+ if (match_pattern_list(sk_provider,
+ allowed_providers, 0) != 1) {
+ error("Refusing add key: "
+ "provider %s not allowed", sk_provider);
+ goto out;
+ }
+ }
+ }
+ if ((r = sshkey_shield_private(k)) != 0) {
+ error_fr(r, "shield private");
+ goto out;
+ }
if (lifetime && !death)
death = monotime() + lifetime;
if ((id = lookup_identity(k)) == NULL) {
@@ -488,12 +770,31 @@ process_add_identity(SocketEntry *e)
/* key state might have been updated */
sshkey_free(id->key);
free(id->comment);
+ free(id->sk_provider);
}
+ /* success */
id->key = k;
id->comment = comment;
id->death = death;
id->confirm = confirm;
-send:
+ id->sk_provider = sk_provider;
+
+ if ((fp = sshkey_fingerprint(k, SSH_FP_HASH_DEFAULT,
+ SSH_FP_DEFAULT)) == NULL)
+ fatal_f("sshkey_fingerprint failed");
+ debug_f("add %s %s \"%.100s\" (life: %u) (confirm: %u) "
+ "(provider: %s)", sshkey_ssh_name(k), fp, comment, seconds,
+ confirm, sk_provider == NULL ? "none" : sk_provider);
+ free(fp);
+ /* transferred */
+ k = NULL;
+ comment = NULL;
+ sk_provider = NULL;
+ success = 1;
+ out:
+ free(sk_provider);
+ free(comment);
+ sshkey_free(k);
send_status(e, success);
}
@@ -507,13 +808,14 @@ process_lock_agent(SocketEntry *e, int lock)
static u_int fail_count = 0;
size_t pwlen;
+ debug2_f("entering");
/*
* This is deliberately fatal: the user has requested that we lock,
* but we can't parse their request properly. The only safe thing to
* do is abort.
*/
if ((r = sshbuf_get_cstring(e->request, &passwd, &pwlen)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "parse");
if (pwlen == 0) {
debug("empty password not supported");
} else if (locked && !lock) {
@@ -545,8 +847,7 @@ process_lock_agent(SocketEntry *e, int lock)
fatal("bcrypt_pbkdf");
success = 1;
}
- explicit_bzero(passwd, pwlen);
- free(passwd);
+ freezero(passwd, pwlen);
send_status(e, success);
}
@@ -557,11 +858,11 @@ no_identities(SocketEntry *e)
int r;
if ((msg = sshbuf_new()) == NULL)
- fatal("%s: sshbuf_new failed", __func__);
+ fatal_f("sshbuf_new failed");
if ((r = sshbuf_put_u8(msg, SSH2_AGENT_IDENTITIES_ANSWER)) != 0 ||
(r = sshbuf_put_u32(msg, 0)) != 0 ||
(r = sshbuf_put_stringb(e->output, msg)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "compose");
sshbuf_free(msg);
}
@@ -570,77 +871,67 @@ static void
process_add_smartcard_key(SocketEntry *e)
{
char *provider = NULL, *pin = NULL, canonical_provider[PATH_MAX];
+ char **comments = NULL;
int r, i, count = 0, success = 0, confirm = 0;
- u_int seconds;
+ u_int seconds = 0;
time_t death = 0;
- u_char type;
struct sshkey **keys = NULL, *k;
Identity *id;
+ debug2_f("entering");
if ((r = sshbuf_get_cstring(e->request, &provider, NULL)) != 0 ||
(r = sshbuf_get_cstring(e->request, &pin, NULL)) != 0) {
- error("%s: buffer error: %s", __func__, ssh_err(r));
+ error_fr(r, "parse");
goto send;
}
-
- while (sshbuf_len(e->request)) {
- if ((r = sshbuf_get_u8(e->request, &type)) != 0) {
- error("%s: buffer error: %s", __func__, ssh_err(r));
- goto send;
- }
- switch (type) {
- case SSH_AGENT_CONSTRAIN_LIFETIME:
- if ((r = sshbuf_get_u32(e->request, &seconds)) != 0) {
- error("%s: buffer error: %s",
- __func__, ssh_err(r));
- goto send;
- }
- death = monotime() + seconds;
- break;
- case SSH_AGENT_CONSTRAIN_CONFIRM:
- confirm = 1;
- break;
- default:
- error("%s: Unknown constraint type %d", __func__, type);
- goto send;
- }
+ if (parse_key_constraints(e->request, NULL, &death, &seconds, &confirm,
+ NULL) != 0) {
+ error_f("failed to parse constraints");
+ goto send;
}
if (realpath(provider, canonical_provider) == NULL) {
verbose("failed PKCS#11 add of \"%.100s\": realpath: %s",
provider, strerror(errno));
goto send;
}
- if (match_pattern_list(canonical_provider, pkcs11_whitelist, 0) != 1) {
+ if (match_pattern_list(canonical_provider, allowed_providers, 0) != 1) {
verbose("refusing PKCS#11 add of \"%.100s\": "
- "provider not whitelisted", canonical_provider);
+ "provider not allowed", canonical_provider);
goto send;
}
- debug("%s: add %.100s", __func__, canonical_provider);
+ debug_f("add %.100s", canonical_provider);
if (lifetime && !death)
death = monotime() + lifetime;
- count = pkcs11_add_provider(canonical_provider, pin, &keys);
+ count = pkcs11_add_provider(canonical_provider, pin, &keys, &comments);
for (i = 0; i < count; i++) {
k = keys[i];
if (lookup_identity(k) == NULL) {
id = xcalloc(1, sizeof(Identity));
id->key = k;
+ keys[i] = NULL; /* transferred */
id->provider = xstrdup(canonical_provider);
- id->comment = xstrdup(canonical_provider); /* XXX */
+ if (*comments[i] != '\0') {
+ id->comment = comments[i];
+ comments[i] = NULL; /* transferred */
+ } else {
+ id->comment = xstrdup(canonical_provider);
+ }
id->death = death;
id->confirm = confirm;
TAILQ_INSERT_TAIL(&idtab->idlist, id, next);
idtab->nentries++;
success = 1;
- } else {
- sshkey_free(k);
}
- keys[i] = NULL;
+ /* XXX update constraints for existing keys */
+ sshkey_free(keys[i]);
+ free(comments[i]);
}
send:
free(pin);
free(provider);
free(keys);
+ free(comments);
send_status(e, success);
}
@@ -651,9 +942,10 @@ process_remove_smartcard_key(SocketEntry *e)
int r, success = 0;
Identity *id, *nxt;
+ debug2_f("entering");
if ((r = sshbuf_get_cstring(e->request, &provider, NULL)) != 0 ||
(r = sshbuf_get_cstring(e->request, &pin, NULL)) != 0) {
- error("%s: buffer error: %s", __func__, ssh_err(r));
+ error_fr(r, "parse");
goto send;
}
free(pin);
@@ -664,7 +956,7 @@ process_remove_smartcard_key(SocketEntry *e)
goto send;
}
- debug("%s: remove %.100s", __func__, canonical_provider);
+ debug_f("remove %.100s", canonical_provider);
for (id = TAILQ_FIRST(&idtab->idlist); id; id = nxt) {
nxt = TAILQ_NEXT(id, next);
/* Skip file--based keys */
@@ -679,15 +971,17 @@ process_remove_smartcard_key(SocketEntry *e)
if (pkcs11_del_provider(canonical_provider) == 0)
success = 1;
else
- error("%s: pkcs11_del_provider failed", __func__);
+ error_f("pkcs11_del_provider failed");
send:
free(provider);
send_status(e, success);
}
#endif /* ENABLE_PKCS11 */
-/* dispatch incoming messages */
-
+/*
+ * dispatch incoming message.
+ * returns 1 on success, 0 for incomplete messages or -1 on error.
+ */
static int
process_message(u_int socknum)
{
@@ -697,10 +991,8 @@ process_message(u_int socknum)
int r;
SocketEntry *e;
- if (socknum >= sockets_alloc) {
- fatal("%s: socket number %u >= allocated %u",
- __func__, socknum, sockets_alloc);
- }
+ if (socknum >= sockets_alloc)
+ fatal_f("sock %u >= allocated %u", socknum, sockets_alloc);
e = &sockets[socknum];
if (sshbuf_len(e->input) < 5)
@@ -708,8 +1000,8 @@ process_message(u_int socknum)
cp = sshbuf_ptr(e->input);
msg_len = PEEK_U32(cp);
if (msg_len > AGENT_MAX_LEN) {
- debug("%s: socket %u (fd=%d) message too long %u > %u",
- __func__, socknum, e->fd, msg_len, AGENT_MAX_LEN);
+ debug_f("socket %u (fd=%d) message too long %u > %u",
+ socknum, e->fd, msg_len, AGENT_MAX_LEN);
return -1;
}
if (sshbuf_len(e->input) < msg_len + 4)
@@ -721,13 +1013,13 @@ process_message(u_int socknum)
(r = sshbuf_get_u8(e->request, &type)) != 0) {
if (r == SSH_ERR_MESSAGE_INCOMPLETE ||
r == SSH_ERR_STRING_TOO_LARGE) {
- debug("%s: buffer error: %s", __func__, ssh_err(r));
+ error_fr(r, "parse");
return -1;
}
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "parse");
}
- debug("%s: socket %u (fd=%d) type %d", __func__, socknum, e->fd, type);
+ debug_f("socket %u (fd=%d) type %d", socknum, e->fd, type);
/* check whether agent is locked */
if (locked && type != SSH_AGENTC_UNLOCK) {
@@ -741,7 +1033,7 @@ process_message(u_int socknum)
/* send a fail message for all other request types */
send_status(e, 0);
}
- return 0;
+ return 1;
}
switch (type) {
@@ -785,7 +1077,7 @@ process_message(u_int socknum)
send_status(e, 0);
break;
}
- return 0;
+ return 1;
}
static void
@@ -793,6 +1085,8 @@ new_socket(sock_type type, int fd)
{
u_int i, old_alloc, new_alloc;
+ debug_f("type = %s", type == AUTH_CONNECTION ? "CONNECTION" :
+ (type == AUTH_SOCKET ? "SOCKET" : "UNKNOWN"));
if (type == AUTH_CONNECTION) {
debug("xcount %d -> %d", xcount, xcount + 1);
++xcount;
@@ -805,28 +1099,25 @@ new_socket(sock_type type, int fd)
for (i = 0; i < sockets_alloc; i++)
if (sockets[i].type == AUTH_UNUSED) {
sockets[i].fd = fd;
- if ((sockets[i].input = sshbuf_new()) == NULL)
- fatal("%s: sshbuf_new failed", __func__);
- if ((sockets[i].output = sshbuf_new()) == NULL)
- fatal("%s: sshbuf_new failed", __func__);
- if ((sockets[i].request = sshbuf_new()) == NULL)
- fatal("%s: sshbuf_new failed", __func__);
+ if ((sockets[i].input = sshbuf_new()) == NULL ||
+ (sockets[i].output = sshbuf_new()) == NULL ||
+ (sockets[i].request = sshbuf_new()) == NULL)
+ fatal_f("sshbuf_new failed");
sockets[i].type = type;
return;
}
old_alloc = sockets_alloc;
new_alloc = sockets_alloc + 10;
- sockets = xreallocarray(sockets, new_alloc, sizeof(sockets[0]));
+ sockets = xrecallocarray(sockets, old_alloc, new_alloc,
+ sizeof(sockets[0]));
for (i = old_alloc; i < new_alloc; i++)
sockets[i].type = AUTH_UNUSED;
sockets_alloc = new_alloc;
sockets[old_alloc].fd = fd;
- if ((sockets[old_alloc].input = sshbuf_new()) == NULL)
- fatal("%s: sshbuf_new failed", __func__);
- if ((sockets[old_alloc].output = sshbuf_new()) == NULL)
- fatal("%s: sshbuf_new failed", __func__);
- if ((sockets[old_alloc].request = sshbuf_new()) == NULL)
- fatal("%s: sshbuf_new failed", __func__);
+ if ((sockets[old_alloc].input = sshbuf_new()) == NULL ||
+ (sockets[old_alloc].output = sshbuf_new()) == NULL ||
+ (sockets[old_alloc].request = sshbuf_new()) == NULL)
+ fatal_f("sshbuf_new failed");
sockets[old_alloc].type = type;
}
@@ -841,11 +1132,11 @@ handle_socket_read(u_int socknum)
slen = sizeof(sunaddr);
fd = accept(sockets[socknum].fd, (struct sockaddr *)&sunaddr, &slen);
- if (fd < 0) {
+ if (fd == -1) {
error("accept from AUTH_SOCKET: %s", strerror(errno));
return -1;
}
- if (getpeereid(fd, &euid, &egid) < 0) {
+ if (getpeereid(fd, &euid, &egid) == -1) {
error("getpeereid %d failed: %s", fd, strerror(errno));
close(fd);
return -1;
@@ -863,7 +1154,7 @@ handle_socket_read(u_int socknum)
static int
handle_conn_read(u_int socknum)
{
- char buf[1024];
+ char buf[AGENT_RBUF_LEN];
ssize_t len;
int r;
@@ -871,16 +1162,20 @@ handle_conn_read(u_int socknum)
if (len == -1) {
if (errno == EAGAIN || errno == EINTR)
return 0;
- error("%s: read error on socket %u (fd %d): %s",
- __func__, socknum, sockets[socknum].fd,
- strerror(errno));
+ error_f("read error on socket %u (fd %d): %s",
+ socknum, sockets[socknum].fd, strerror(errno));
}
return -1;
}
if ((r = sshbuf_put(sockets[socknum].input, buf, len)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "compose");
explicit_bzero(buf, sizeof(buf));
- process_message(socknum);
+ for (;;) {
+ if ((r = process_message(socknum)) == -1)
+ return -1;
+ else if (r == 0)
+ break;
+ }
return 0;
}
@@ -898,14 +1193,13 @@ handle_conn_write(u_int socknum)
if (len == -1) {
if (errno == EAGAIN || errno == EINTR)
return 0;
- error("%s: read error on socket %u (fd %d): %s",
- __func__, socknum, sockets[socknum].fd,
- strerror(errno));
+ error_f("read error on socket %u (fd %d): %s",
+ socknum, sockets[socknum].fd, strerror(errno));
}
return -1;
}
if ((r = sshbuf_consume(sockets[socknum].output, len)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "consume");
return 0;
}
@@ -927,7 +1221,7 @@ after_poll(struct pollfd *pfd, size_t npfd, u_int maxfds)
break;
}
if (socknum >= sockets_alloc) {
- error("%s: no socket for fd %d", __func__, pfd[i].fd);
+ error_f("no socket for fd %d", pfd[i].fd);
continue;
}
/* Process events */
@@ -970,6 +1264,7 @@ prepare_poll(struct pollfd **pfdp, size_t *npfdp, int *timeoutp, u_int maxfds)
struct pollfd *pfd = *pfdp;
size_t i, j, npfd = 0;
time_t deadline;
+ int r;
/* Count active sockets */
for (i = 0; i < sockets_alloc; i++) {
@@ -987,7 +1282,7 @@ prepare_poll(struct pollfd **pfdp, size_t *npfdp, int *timeoutp, u_int maxfds)
}
if (npfd != *npfdp &&
(pfd = recallocarray(pfd, *npfdp, npfd, sizeof(*pfd))) == NULL)
- fatal("%s: recallocarray failed", __func__);
+ fatal_f("recallocarray failed");
*pfdp = pfd;
*npfdp = npfd;
@@ -1007,8 +1302,17 @@ prepare_poll(struct pollfd **pfdp, size_t *npfdp, int *timeoutp, u_int maxfds)
case AUTH_CONNECTION:
pfd[j].fd = sockets[i].fd;
pfd[j].revents = 0;
- /* XXX backoff when input buffer full */
- pfd[j].events = POLLIN;
+ /*
+ * Only prepare to read if we can handle a full-size
+ * input read buffer and enqueue a max size reply..
+ */
+ if ((r = sshbuf_check_reserve(sockets[i].input,
+ AGENT_RBUF_LEN)) == 0 &&
+ (r = sshbuf_check_reserve(sockets[i].output,
+ AGENT_MAX_LEN)) == 0)
+ pfd[j].events = POLLIN;
+ else if (r != SSH_ERR_NO_BUFFER_SPACE)
+ fatal_fr(r, "reserve");
if (sshbuf_len(sockets[i].output) > 0)
pfd[j].events |= POLLOUT;
j++;
@@ -1037,7 +1341,7 @@ cleanup_socket(void)
{
if (cleanup_pid != 0 && getpid() != cleanup_pid)
return;
- debug("%s: cleanup", __func__);
+ debug_f("cleanup");
if (socket_name[0])
unlink(socket_name);
if (socket_dir[0])
@@ -1081,7 +1385,9 @@ usage(void)
{
fprintf(stderr,
"usage: ssh-agent [-c | -s] [-Ddx] [-a bind_address] [-E fingerprint_hash]\n"
- " [-P pkcs11_whitelist] [-t life] [command [arg ...]]\n"
+ " [-P allowed_providers] [-t life]\n"
+ " ssh-agent [-a bind_address] [-E fingerprint_hash] [-P allowed_providers]\n"
+ " [-t life] command [arg ...]\n"
" ssh-agent [-c | -s] -k\n");
exit(1);
}
@@ -1090,7 +1396,7 @@ int
main(int ac, char **av)
{
int c_flag = 0, d_flag = 0, D_flag = 0, k_flag = 0, s_flag = 0;
- int sock, fd, ch, result, saved_errno;
+ int sock, ch, result, saved_errno;
char *shell, *format, *pidstr, *agentsocket = NULL;
#ifdef HAVE_SETRLIMIT
struct rlimit rlim;
@@ -1106,7 +1412,6 @@ main(int ac, char **av)
size_t npfd = 0;
u_int maxfds;
- ssh_malloc_init(); /* must be called before any mallocs */
/* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */
sanitise_stdfd();
@@ -1117,17 +1422,15 @@ main(int ac, char **av)
platform_disable_tracing(0); /* strict=no */
+#ifdef RLIMIT_NOFILE
if (getrlimit(RLIMIT_NOFILE, &rlim) == -1)
fatal("%s: getrlimit: %s", __progname, strerror(errno));
-
-#ifdef WITH_OPENSSL
- OpenSSL_add_all_algorithms();
#endif
__progname = ssh_get_progname(av[0]);
seed_rng();
- while ((ch = getopt(ac, av, "cDdksE:a:P:t:x")) != -1) {
+ while ((ch = getopt(ac, av, "cDdksE:a:O:P:t:x")) != -1) {
switch (ch) {
case 'E':
fingerprint_hash = ssh_digest_alg_by_name(optarg);
@@ -1142,10 +1445,16 @@ main(int ac, char **av)
case 'k':
k_flag++;
break;
+ case 'O':
+ if (strcmp(optarg, "no-restrict-websafe") == 0)
+ restrict_websafe = 0;
+ else
+ fatal("Unknown -O option");
+ break;
case 'P':
- if (pkcs11_whitelist != NULL)
+ if (allowed_providers != NULL)
fatal("-P option already specified");
- pkcs11_whitelist = xstrdup(optarg);
+ allowed_providers = xstrdup(optarg);
break;
case 's':
if (c_flag)
@@ -1184,8 +1493,8 @@ main(int ac, char **av)
if (ac > 0 && (c_flag || k_flag || s_flag || d_flag || D_flag))
usage();
- if (pkcs11_whitelist == NULL)
- pkcs11_whitelist = xstrdup(DEFAULT_PKCS11_WHITELIST);
+ if (allowed_providers == NULL)
+ allowed_providers = xstrdup(DEFAULT_ALLOWED_PROVIDERS);
if (ac == 0 && !c_flag && !s_flag) {
shell = getenv("SHELL");
@@ -1227,7 +1536,7 @@ main(int ac, char **av)
*/
#define SSH_AGENT_MIN_FDS (3+1+1+1+4)
if (rlim.rlim_cur < SSH_AGENT_MIN_FDS)
- fatal("%s: file descriptior rlimit %lld too low (minimum %u)",
+ fatal("%s: file descriptor rlimit %lld too low (minimum %u)",
__progname, (long long)rlim.rlim_cur, SSH_AGENT_MIN_FDS);
maxfds = rlim.rlim_cur - SSH_AGENT_MIN_FDS;
@@ -1311,19 +1620,13 @@ main(int ac, char **av)
}
(void)chdir("/");
- if ((fd = open(_PATH_DEVNULL, O_RDWR, 0)) != -1) {
- /* XXX might close listen socket */
- (void)dup2(fd, STDIN_FILENO);
- (void)dup2(fd, STDOUT_FILENO);
- (void)dup2(fd, STDERR_FILENO);
- if (fd > 2)
- close(fd);
- }
+ if (stdfd_devnull(1, 1, 1) == -1)
+ error_f("stdfd_devnull failed");
#ifdef HAVE_SETRLIMIT
/* deny core dumps, since memory contains unencrypted private keys */
rlim.rlim_cur = rlim.rlim_max = 0;
- if (setrlimit(RLIMIT_CORE, &rlim) < 0) {
+ if (setrlimit(RLIMIT_CORE, &rlim) == -1) {
error("setrlimit RLIMIT_CORE: %s", strerror(errno));
cleanup_exit(1);
}
@@ -1340,10 +1643,10 @@ skip:
if (ac > 0)
parent_alive_interval = 10;
idtab_init();
- signal(SIGPIPE, SIG_IGN);
- signal(SIGINT, (d_flag | D_flag) ? cleanup_handler : SIG_IGN);
- signal(SIGHUP, cleanup_handler);
- signal(SIGTERM, cleanup_handler);
+ ssh_signal(SIGPIPE, SIG_IGN);
+ ssh_signal(SIGINT, (d_flag | D_flag) ? cleanup_handler : SIG_IGN);
+ ssh_signal(SIGHUP, cleanup_handler);
+ ssh_signal(SIGTERM, cleanup_handler);
if (pledge("stdio rpath cpath unix id proc exec", NULL) == -1)
fatal("%s: pledge: %s", __progname, strerror(errno));
@@ -1356,7 +1659,7 @@ skip:
if (parent_alive_interval != 0)
check_parent_exists();
(void) reaper(); /* remove expired keys */
- if (result < 0) {
+ if (result == -1) {
if (saved_errno == EINTR)
continue;
fatal("poll: %s", strerror(saved_errno));
diff --git a/crypto/openssh/ssh-dss.c b/crypto/openssh/ssh-dss.c
index a23c383dc805..fddc29cc9173 100644
--- a/crypto/openssh/ssh-dss.c
+++ b/crypto/openssh/ssh-dss.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssh-dss.c,v 1.37 2018/02/07 02:06:51 jsing Exp $ */
+/* $OpenBSD: ssh-dss.c,v 1.39 2020/02/26 13:40:09 jsg Exp $ */
/*
* Copyright (c) 2000 Markus Friedl. All rights reserved.
*
@@ -200,10 +200,8 @@ ssh_dss_verify(const struct sshkey *key,
BN_clear_free(sig_s);
sshbuf_free(b);
free(ktype);
- if (sigblob != NULL) {
- explicit_bzero(sigblob, len);
- free(sigblob);
- }
+ if (sigblob != NULL)
+ freezero(sigblob, len);
return ret;
}
#endif /* WITH_OPENSSL */
diff --git a/crypto/openssh/ssh-ecdsa-sk.c b/crypto/openssh/ssh-ecdsa-sk.c
new file mode 100644
index 000000000000..c6927ecb27c8
--- /dev/null
+++ b/crypto/openssh/ssh-ecdsa-sk.c
@@ -0,0 +1,324 @@
+/* $OpenBSD: ssh-ecdsa-sk.c,v 1.8 2020/06/22 23:44:27 djm Exp $ */
+/*
+ * Copyright (c) 2000 Markus Friedl. All rights reserved.
+ * Copyright (c) 2010 Damien Miller. All rights reserved.
+ * Copyright (c) 2019 Google Inc. 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.
+ */
+
+/* #define DEBUG_SK 1 */
+
+#include "includes.h"
+
+#include <sys/types.h>
+
+#ifdef WITH_OPENSSL
+#include <openssl/bn.h>
+#include <openssl/ec.h>
+#include <openssl/ecdsa.h>
+#include <openssl/evp.h>
+#endif
+
+#include <string.h>
+#include <stdio.h> /* needed for DEBUG_SK only */
+
+#include "openbsd-compat/openssl-compat.h"
+
+#include "sshbuf.h"
+#include "ssherr.h"
+#include "digest.h"
+#define SSHKEY_INTERNAL
+#include "sshkey.h"
+
+#ifndef OPENSSL_HAS_ECC
+/* ARGSUSED */
+int
+ssh_ecdsa_sk_verify(const struct sshkey *key,
+ const u_char *signature, size_t signaturelen,
+ const u_char *data, size_t datalen, u_int compat,
+ struct sshkey_sig_details **detailsp)
+{
+ return SSH_ERR_FEATURE_UNSUPPORTED;
+}
+#else /* OPENSSL_HAS_ECC */
+
+/*
+ * Check FIDO/W3C webauthn signatures clientData field against the expected
+ * format and prepare a hash of it for use in signature verification.
+ *
+ * webauthn signatures do not sign the hash of the message directly, but
+ * instead sign a JSON-like "clientData" wrapper structure that contains the
+ * message hash along with a other information.
+ *
+ * Fortunately this structure has a fixed format so it is possible to verify
+ * that the hash of the signed message is present within the clientData
+ * structure without needing to implement any JSON parsing.
+ */
+static int
+webauthn_check_prepare_hash(const u_char *data, size_t datalen,
+ const char *origin, const struct sshbuf *wrapper,
+ uint8_t flags, const struct sshbuf *extensions,
+ u_char *msghash, size_t msghashlen)
+{
+ int r = SSH_ERR_INTERNAL_ERROR;
+ struct sshbuf *chall = NULL, *m = NULL;
+
+ if ((m = sshbuf_new()) == NULL ||
+ (chall = sshbuf_from(data, datalen)) == NULL) {
+ r = SSH_ERR_ALLOC_FAIL;
+ goto out;
+ }
+ /*
+ * Ensure origin contains no quote character and that the flags are
+ * consistent with what we received
+ */
+ if (strchr(origin, '\"') != NULL ||
+ (flags & 0x40) != 0 /* AD */ ||
+ ((flags & 0x80) == 0 /* ED */) != (sshbuf_len(extensions) == 0)) {
+ r = SSH_ERR_INVALID_FORMAT;
+ goto out;
+ }
+
+ /*
+ * Prepare the preamble to clientData that we expect, poking the
+ * challenge and origin into their canonical positions in the
+ * structure. The crossOrigin flag and any additional extension
+ * fields present are ignored.
+ */
+#define WEBAUTHN_0 "{\"type\":\"webauthn.get\",\"challenge\":\""
+#define WEBAUTHN_1 "\",\"origin\":\""
+#define WEBAUTHN_2 "\""
+ if ((r = sshbuf_put(m, WEBAUTHN_0, sizeof(WEBAUTHN_0) - 1)) != 0 ||
+ (r = sshbuf_dtourlb64(chall, m, 0)) != 0 ||
+ (r = sshbuf_put(m, WEBAUTHN_1, sizeof(WEBAUTHN_1) - 1)) != 0 ||
+ (r = sshbuf_put(m, origin, strlen(origin))) != 0 ||
+ (r = sshbuf_put(m, WEBAUTHN_2, sizeof(WEBAUTHN_2) - 1)) != 0)
+ goto out;
+#ifdef DEBUG_SK
+ fprintf(stderr, "%s: received origin: %s\n", __func__, origin);
+ fprintf(stderr, "%s: received clientData:\n", __func__);
+ sshbuf_dump(wrapper, stderr);
+ fprintf(stderr, "%s: expected clientData premable:\n", __func__);
+ sshbuf_dump(m, stderr);
+#endif
+ /* Check that the supplied clientData has the preamble we expect */
+ if ((r = sshbuf_cmp(wrapper, 0, sshbuf_ptr(m), sshbuf_len(m))) != 0)
+ goto out;
+
+ /* Prepare hash of clientData */
+ if ((r = ssh_digest_buffer(SSH_DIGEST_SHA256, wrapper,
+ msghash, msghashlen)) != 0)
+ goto out;
+
+ /* success */
+ r = 0;
+ out:
+ sshbuf_free(chall);
+ sshbuf_free(m);
+ return r;
+}
+
+/* ARGSUSED */
+int
+ssh_ecdsa_sk_verify(const struct sshkey *key,
+ const u_char *signature, size_t signaturelen,
+ const u_char *data, size_t datalen, u_int compat,
+ struct sshkey_sig_details **detailsp)
+{
+ ECDSA_SIG *sig = NULL;
+ BIGNUM *sig_r = NULL, *sig_s = NULL;
+ u_char sig_flags;
+ u_char msghash[32], apphash[32], sighash[32];
+ u_int sig_counter;
+ int is_webauthn = 0, ret = SSH_ERR_INTERNAL_ERROR;
+ struct sshbuf *b = NULL, *sigbuf = NULL, *original_signed = NULL;
+ struct sshbuf *webauthn_wrapper = NULL, *webauthn_exts = NULL;
+ char *ktype = NULL, *webauthn_origin = NULL;
+ struct sshkey_sig_details *details = NULL;
+#ifdef DEBUG_SK
+ char *tmp = NULL;
+#endif
+
+ if (detailsp != NULL)
+ *detailsp = NULL;
+ if (key == NULL || key->ecdsa == NULL ||
+ sshkey_type_plain(key->type) != KEY_ECDSA_SK ||
+ signature == NULL || signaturelen == 0)
+ return SSH_ERR_INVALID_ARGUMENT;
+
+ if (key->ecdsa_nid != NID_X9_62_prime256v1)
+ return SSH_ERR_INTERNAL_ERROR;
+
+ /* fetch signature */
+ if ((b = sshbuf_from(signature, signaturelen)) == NULL)
+ return SSH_ERR_ALLOC_FAIL;
+ if ((details = calloc(1, sizeof(*details))) == NULL) {
+ ret = SSH_ERR_ALLOC_FAIL;
+ goto out;
+ }
+ if (sshbuf_get_cstring(b, &ktype, NULL) != 0) {
+ ret = SSH_ERR_INVALID_FORMAT;
+ goto out;
+ }
+ if (strcmp(ktype, "webauthn-sk-ecdsa-sha2-nistp256@openssh.com") == 0)
+ is_webauthn = 1;
+ else if (strcmp(ktype, "sk-ecdsa-sha2-nistp256@openssh.com") != 0) {
+ ret = SSH_ERR_INVALID_FORMAT;
+ goto out;
+ }
+ if (sshbuf_froms(b, &sigbuf) != 0 ||
+ sshbuf_get_u8(b, &sig_flags) != 0 ||
+ sshbuf_get_u32(b, &sig_counter) != 0) {
+ ret = SSH_ERR_INVALID_FORMAT;
+ goto out;
+ }
+ if (is_webauthn) {
+ if (sshbuf_get_cstring(b, &webauthn_origin, NULL) != 0 ||
+ sshbuf_froms(b, &webauthn_wrapper) != 0 ||
+ sshbuf_froms(b, &webauthn_exts) != 0) {
+ ret = SSH_ERR_INVALID_FORMAT;
+ goto out;
+ }
+ }
+ if (sshbuf_len(b) != 0) {
+ ret = SSH_ERR_UNEXPECTED_TRAILING_DATA;
+ goto out;
+ }
+
+ /* parse signature */
+ if (sshbuf_get_bignum2(sigbuf, &sig_r) != 0 ||
+ sshbuf_get_bignum2(sigbuf, &sig_s) != 0) {
+ ret = SSH_ERR_INVALID_FORMAT;
+ goto out;
+ }
+ if (sshbuf_len(sigbuf) != 0) {
+ ret = SSH_ERR_UNEXPECTED_TRAILING_DATA;
+ goto out;
+ }
+
+#ifdef DEBUG_SK
+ fprintf(stderr, "%s: data: (len %zu)\n", __func__, datalen);
+ /* sshbuf_dump_data(data, datalen, stderr); */
+ fprintf(stderr, "%s: sig_r: %s\n", __func__, (tmp = BN_bn2hex(sig_r)));
+ free(tmp);
+ fprintf(stderr, "%s: sig_s: %s\n", __func__, (tmp = BN_bn2hex(sig_s)));
+ free(tmp);
+ fprintf(stderr, "%s: sig_flags = 0x%02x, sig_counter = %u\n",
+ __func__, sig_flags, sig_counter);
+ if (is_webauthn) {
+ fprintf(stderr, "%s: webauthn origin: %s\n", __func__,
+ webauthn_origin);
+ fprintf(stderr, "%s: webauthn_wrapper:\n", __func__);
+ sshbuf_dump(webauthn_wrapper, stderr);
+ }
+#endif
+ if ((sig = ECDSA_SIG_new()) == NULL) {
+ ret = SSH_ERR_ALLOC_FAIL;
+ goto out;
+ }
+ if (!ECDSA_SIG_set0(sig, sig_r, sig_s)) {
+ ret = SSH_ERR_LIBCRYPTO_ERROR;
+ goto out;
+ }
+ sig_r = sig_s = NULL; /* transferred */
+
+ /* Reconstruct data that was supposedly signed */
+ if ((original_signed = sshbuf_new()) == NULL) {
+ ret = SSH_ERR_ALLOC_FAIL;
+ goto out;
+ }
+ if (is_webauthn) {
+ if ((ret = webauthn_check_prepare_hash(data, datalen,
+ webauthn_origin, webauthn_wrapper, sig_flags, webauthn_exts,
+ msghash, sizeof(msghash))) != 0)
+ goto out;
+ } else if ((ret = ssh_digest_memory(SSH_DIGEST_SHA256, data, datalen,
+ msghash, sizeof(msghash))) != 0)
+ goto out;
+ /* Application value is hashed before signature */
+ if ((ret = ssh_digest_memory(SSH_DIGEST_SHA256, key->sk_application,
+ strlen(key->sk_application), apphash, sizeof(apphash))) != 0)
+ goto out;
+#ifdef DEBUG_SK
+ fprintf(stderr, "%s: hashed application:\n", __func__);
+ sshbuf_dump_data(apphash, sizeof(apphash), stderr);
+ fprintf(stderr, "%s: hashed message:\n", __func__);
+ sshbuf_dump_data(msghash, sizeof(msghash), stderr);
+#endif
+ if ((ret = sshbuf_put(original_signed,
+ apphash, sizeof(apphash))) != 0 ||
+ (ret = sshbuf_put_u8(original_signed, sig_flags)) != 0 ||
+ (ret = sshbuf_put_u32(original_signed, sig_counter)) != 0 ||
+ (ret = sshbuf_putb(original_signed, webauthn_exts)) != 0 ||
+ (ret = sshbuf_put(original_signed, msghash, sizeof(msghash))) != 0)
+ goto out;
+ /* Signature is over H(original_signed) */
+ if ((ret = ssh_digest_buffer(SSH_DIGEST_SHA256, original_signed,
+ sighash, sizeof(sighash))) != 0)
+ goto out;
+ details->sk_counter = sig_counter;
+ details->sk_flags = sig_flags;
+#ifdef DEBUG_SK
+ fprintf(stderr, "%s: signed buf:\n", __func__);
+ sshbuf_dump(original_signed, stderr);
+ fprintf(stderr, "%s: signed hash:\n", __func__);
+ sshbuf_dump_data(sighash, sizeof(sighash), stderr);
+#endif
+
+ /* Verify it */
+ switch (ECDSA_do_verify(sighash, sizeof(sighash), sig, key->ecdsa)) {
+ case 1:
+ ret = 0;
+ break;
+ case 0:
+ ret = SSH_ERR_SIGNATURE_INVALID;
+ goto out;
+ default:
+ ret = SSH_ERR_LIBCRYPTO_ERROR;
+ goto out;
+ }
+ /* success */
+ if (detailsp != NULL) {
+ *detailsp = details;
+ details = NULL;
+ }
+ out:
+ explicit_bzero(&sig_flags, sizeof(sig_flags));
+ explicit_bzero(&sig_counter, sizeof(sig_counter));
+ explicit_bzero(msghash, sizeof(msghash));
+ explicit_bzero(sighash, sizeof(msghash));
+ explicit_bzero(apphash, sizeof(apphash));
+ sshkey_sig_details_free(details);
+ sshbuf_free(webauthn_wrapper);
+ sshbuf_free(webauthn_exts);
+ free(webauthn_origin);
+ sshbuf_free(original_signed);
+ sshbuf_free(sigbuf);
+ sshbuf_free(b);
+ ECDSA_SIG_free(sig);
+ BN_clear_free(sig_r);
+ BN_clear_free(sig_s);
+ free(ktype);
+ return ret;
+}
+
+#endif /* OPENSSL_HAS_ECC */
diff --git a/crypto/openssh/ssh-ecdsa.c b/crypto/openssh/ssh-ecdsa.c
index 2f553175267e..599c7199db19 100644
--- a/crypto/openssh/ssh-ecdsa.c
+++ b/crypto/openssh/ssh-ecdsa.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssh-ecdsa.c,v 1.14 2018/02/07 02:06:51 jsing Exp $ */
+/* $OpenBSD: ssh-ecdsa.c,v 1.16 2019/01/21 09:54:11 djm Exp $ */
/*
* Copyright (c) 2000 Markus Friedl. All rights reserved.
* Copyright (c) 2010 Damien Miller. All rights reserved.
@@ -151,15 +151,13 @@ ssh_ecdsa_verify(const struct sshkey *key,
}
/* parse signature */
- if ((sig = ECDSA_SIG_new()) == NULL ||
- (sig_r = BN_new()) == NULL ||
- (sig_s = BN_new()) == NULL) {
- ret = SSH_ERR_ALLOC_FAIL;
+ if (sshbuf_get_bignum2(sigbuf, &sig_r) != 0 ||
+ sshbuf_get_bignum2(sigbuf, &sig_s) != 0) {
+ ret = SSH_ERR_INVALID_FORMAT;
goto out;
}
- if (sshbuf_get_bignum2(sigbuf, sig_r) != 0 ||
- sshbuf_get_bignum2(sigbuf, sig_s) != 0) {
- ret = SSH_ERR_INVALID_FORMAT;
+ if ((sig = ECDSA_SIG_new()) == NULL) {
+ ret = SSH_ERR_ALLOC_FAIL;
goto out;
}
if (!ECDSA_SIG_set0(sig, sig_r, sig_s)) {
diff --git a/crypto/openssh/ssh-ed25519-sk.c b/crypto/openssh/ssh-ed25519-sk.c
new file mode 100644
index 000000000000..4393ca669e17
--- /dev/null
+++ b/crypto/openssh/ssh-ed25519-sk.c
@@ -0,0 +1,163 @@
+/* $OpenBSD: ssh-ed25519-sk.c,v 1.6 2020/10/18 11:32:02 djm Exp $ */
+/*
+ * Copyright (c) 2019 Markus Friedl. 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.
+ */
+
+/* #define DEBUG_SK 1 */
+
+#include "includes.h"
+
+#define SSHKEY_INTERNAL
+#include <sys/types.h>
+#include <limits.h>
+
+#include "crypto_api.h"
+
+#include <string.h>
+#include <stdarg.h>
+
+#include "log.h"
+#include "sshbuf.h"
+#include "sshkey.h"
+#include "ssherr.h"
+#include "ssh.h"
+#include "digest.h"
+
+int
+ssh_ed25519_sk_verify(const struct sshkey *key,
+ const u_char *signature, size_t signaturelen,
+ const u_char *data, size_t datalen, u_int compat,
+ struct sshkey_sig_details **detailsp)
+{
+ struct sshbuf *b = NULL;
+ struct sshbuf *encoded = NULL;
+ char *ktype = NULL;
+ const u_char *sigblob;
+ const u_char *sm;
+ u_char *m = NULL;
+ u_char apphash[32];
+ u_char msghash[32];
+ u_char sig_flags;
+ u_int sig_counter;
+ size_t len;
+ unsigned long long smlen = 0, mlen = 0;
+ int r = SSH_ERR_INTERNAL_ERROR;
+ int ret;
+ struct sshkey_sig_details *details = NULL;
+
+ if (detailsp != NULL)
+ *detailsp = NULL;
+
+ if (key == NULL ||
+ sshkey_type_plain(key->type) != KEY_ED25519_SK ||
+ key->ed25519_pk == NULL ||
+ signature == NULL || signaturelen == 0)
+ return SSH_ERR_INVALID_ARGUMENT;
+
+ if ((b = sshbuf_from(signature, signaturelen)) == NULL)
+ return SSH_ERR_ALLOC_FAIL;
+ if (sshbuf_get_cstring(b, &ktype, NULL) != 0 ||
+ sshbuf_get_string_direct(b, &sigblob, &len) != 0 ||
+ sshbuf_get_u8(b, &sig_flags) != 0 ||
+ sshbuf_get_u32(b, &sig_counter) != 0) {
+ r = SSH_ERR_INVALID_FORMAT;
+ goto out;
+ }
+#ifdef DEBUG_SK
+ fprintf(stderr, "%s: data:\n", __func__);
+ /* sshbuf_dump_data(data, datalen, stderr); */
+ fprintf(stderr, "%s: sigblob:\n", __func__);
+ sshbuf_dump_data(sigblob, len, stderr);
+ fprintf(stderr, "%s: sig_flags = 0x%02x, sig_counter = %u\n",
+ __func__, sig_flags, sig_counter);
+#endif
+ if (strcmp(sshkey_ssh_name_plain(key), ktype) != 0) {
+ r = SSH_ERR_KEY_TYPE_MISMATCH;
+ goto out;
+ }
+ if (sshbuf_len(b) != 0) {
+ r = SSH_ERR_UNEXPECTED_TRAILING_DATA;
+ goto out;
+ }
+ if (len > crypto_sign_ed25519_BYTES) {
+ r = SSH_ERR_INVALID_FORMAT;
+ goto out;
+ }
+ if (ssh_digest_memory(SSH_DIGEST_SHA256, key->sk_application,
+ strlen(key->sk_application), apphash, sizeof(apphash)) != 0 ||
+ ssh_digest_memory(SSH_DIGEST_SHA256, data, datalen,
+ msghash, sizeof(msghash)) != 0) {
+ r = SSH_ERR_INVALID_ARGUMENT;
+ goto out;
+ }
+#ifdef DEBUG_SK
+ fprintf(stderr, "%s: hashed application:\n", __func__);
+ sshbuf_dump_data(apphash, sizeof(apphash), stderr);
+ fprintf(stderr, "%s: hashed message:\n", __func__);
+ sshbuf_dump_data(msghash, sizeof(msghash), stderr);
+#endif
+ if ((details = calloc(1, sizeof(*details))) == NULL) {
+ r = SSH_ERR_ALLOC_FAIL;
+ goto out;
+ }
+ details->sk_counter = sig_counter;
+ details->sk_flags = sig_flags;
+ if ((encoded = sshbuf_new()) == NULL) {
+ r = SSH_ERR_ALLOC_FAIL;
+ goto out;
+ }
+ if (sshbuf_put(encoded, sigblob, len) != 0 ||
+ sshbuf_put(encoded, apphash, sizeof(apphash)) != 0 ||
+ sshbuf_put_u8(encoded, sig_flags) != 0 ||
+ sshbuf_put_u32(encoded, sig_counter) != 0 ||
+ sshbuf_put(encoded, msghash, sizeof(msghash)) != 0) {
+ r = SSH_ERR_ALLOC_FAIL;
+ goto out;
+ }
+#ifdef DEBUG_SK
+ fprintf(stderr, "%s: signed buf:\n", __func__);
+ sshbuf_dump(encoded, stderr);
+#endif
+ sm = sshbuf_ptr(encoded);
+ smlen = sshbuf_len(encoded);
+ mlen = smlen;
+ if ((m = malloc(smlen)) == NULL) {
+ r = SSH_ERR_ALLOC_FAIL;
+ goto out;
+ }
+ if ((ret = crypto_sign_ed25519_open(m, &mlen, sm, smlen,
+ key->ed25519_pk)) != 0) {
+ debug2_f("crypto_sign_ed25519_open failed: %d", ret);
+ }
+ if (ret != 0 || mlen != smlen - len) {
+ r = SSH_ERR_SIGNATURE_INVALID;
+ goto out;
+ }
+ /* XXX compare 'm' and 'sm + len' ? */
+ /* success */
+ r = 0;
+ if (detailsp != NULL) {
+ *detailsp = details;
+ details = NULL;
+ }
+ out:
+ if (m != NULL)
+ freezero(m, smlen); /* NB mlen may be invalid if r != 0 */
+ sshkey_sig_details_free(details);
+ sshbuf_free(b);
+ sshbuf_free(encoded);
+ free(ktype);
+ return r;
+}
diff --git a/crypto/openssh/ssh-ed25519.c b/crypto/openssh/ssh-ed25519.c
index 5163e029728b..23419f3c884a 100644
--- a/crypto/openssh/ssh-ed25519.c
+++ b/crypto/openssh/ssh-ed25519.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssh-ed25519.c,v 1.7 2016/04/21 06:08:02 djm Exp $ */
+/* $OpenBSD: ssh-ed25519.c,v 1.9 2020/10/18 11:32:02 djm Exp $ */
/*
* Copyright (c) 2013 Markus Friedl <markus@openbsd.org>
*
@@ -83,10 +83,8 @@ ssh_ed25519_sign(const struct sshkey *key, u_char **sigp, size_t *lenp,
r = 0;
out:
sshbuf_free(b);
- if (sig != NULL) {
- explicit_bzero(sig, slen);
- free(sig);
- }
+ if (sig != NULL)
+ freezero(sig, slen);
return r;
}
@@ -142,8 +140,7 @@ ssh_ed25519_verify(const struct sshkey *key,
memcpy(sm+len, data, datalen);
if ((ret = crypto_sign_ed25519_open(m, &mlen, sm, smlen,
key->ed25519_pk)) != 0) {
- debug2("%s: crypto_sign_ed25519_open failed: %d",
- __func__, ret);
+ debug2_f("crypto_sign_ed25519_open failed: %d", ret);
}
if (ret != 0 || mlen != datalen) {
r = SSH_ERR_SIGNATURE_INVALID;
@@ -153,14 +150,10 @@ ssh_ed25519_verify(const struct sshkey *key,
/* success */
r = 0;
out:
- if (sm != NULL) {
- explicit_bzero(sm, smlen);
- free(sm);
- }
- if (m != NULL) {
- explicit_bzero(m, smlen); /* NB mlen may be invalid if r != 0 */
- free(m);
- }
+ if (sm != NULL)
+ freezero(sm, smlen);
+ if (m != NULL)
+ freezero(m, smlen); /* NB mlen may be invalid if r != 0 */
sshbuf_free(b);
free(ktype);
return r;
diff --git a/crypto/openssh/ssh-gss.h b/crypto/openssh/ssh-gss.h
index 887399b6b00a..e19009770f5d 100644
--- a/crypto/openssh/ssh-gss.h
+++ b/crypto/openssh/ssh-gss.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssh-gss.h,v 1.14 2018/07/10 09:13:30 djm Exp $ */
+/* $OpenBSD: ssh-gss.h,v 1.15 2021/01/27 10:05:28 djm Exp $ */
/* $FreeBSD$ */
/*
* Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved.
@@ -123,7 +123,7 @@ void ssh_gssapi_build_ctx(Gssctxt **);
void ssh_gssapi_delete_ctx(Gssctxt **);
OM_uint32 ssh_gssapi_sign(Gssctxt *, gss_buffer_t, gss_buffer_t);
void ssh_gssapi_buildmic(struct sshbuf *, const char *,
- const char *, const char *);
+ const char *, const char *, const struct sshbuf *);
int ssh_gssapi_check_mechanism(Gssctxt **, gss_OID, const char *);
/* In the server */
diff --git a/crypto/openssh/ssh-keygen.1 b/crypto/openssh/ssh-keygen.1
index bfa2eb5f3e37..f83f515f6008 100644
--- a/crypto/openssh/ssh-keygen.1
+++ b/crypto/openssh/ssh-keygen.1
@@ -1,4 +1,4 @@
-.\" $OpenBSD: ssh-keygen.1,v 1.150 2018/09/12 06:18:59 djm Exp $
+.\" $OpenBSD: ssh-keygen.1,v 1.216 2021/08/11 08:54:17 djm Exp $
.\"
.\" Author: Tatu Ylonen <ylo@cs.hut.fi>
.\" Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -35,42 +35,50 @@
.\" (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: September 12 2018 $
+.Dd $Mdocdate: August 11 2021 $
.Dt SSH-KEYGEN 1
.Os
.Sh NAME
.Nm ssh-keygen
-.Nd authentication key generation, management and conversion
+.Nd OpenSSH authentication key utility
.Sh SYNOPSIS
-.Bk -words
.Nm ssh-keygen
.Op Fl q
+.Op Fl a Ar rounds
.Op Fl b Ar bits
-.Op Fl t Cm dsa | ecdsa | ed25519 | rsa
-.Op Fl N Ar new_passphrase
.Op Fl C Ar comment
.Op Fl f Ar output_keyfile
+.Op Fl m Ar format
+.Op Fl N Ar new_passphrase
+.Op Fl O Ar option
+.Op Fl t Cm dsa | ecdsa | ecdsa-sk | ed25519 | ed25519-sk | rsa
+.Op Fl w Ar provider
+.Op Fl Z Ar cipher
.Nm ssh-keygen
.Fl p
-.Op Fl P Ar old_passphrase
-.Op Fl N Ar new_passphrase
+.Op Fl a Ar rounds
.Op Fl f Ar keyfile
+.Op Fl m Ar format
+.Op Fl N Ar new_passphrase
+.Op Fl P Ar old_passphrase
+.Op Fl Z Ar cipher
.Nm ssh-keygen
.Fl i
-.Op Fl m Ar key_format
.Op Fl f Ar input_keyfile
+.Op Fl m Ar key_format
.Nm ssh-keygen
.Fl e
-.Op Fl m Ar key_format
.Op Fl f Ar input_keyfile
+.Op Fl m Ar key_format
.Nm ssh-keygen
.Fl y
.Op Fl f Ar input_keyfile
.Nm ssh-keygen
.Fl c
-.Op Fl P Ar passphrase
+.Op Fl a Ar rounds
.Op Fl C Ar comment
.Op Fl f Ar keyfile
+.Op Fl P Ar passphrase
.Nm ssh-keygen
.Fl l
.Op Fl v
@@ -83,38 +91,35 @@
.Fl D Ar pkcs11
.Nm ssh-keygen
.Fl F Ar hostname
+.Op Fl lv
.Op Fl f Ar known_hosts_file
-.Op Fl l
.Nm ssh-keygen
.Fl H
.Op Fl f Ar known_hosts_file
.Nm ssh-keygen
+.Fl K
+.Op Fl a Ar rounds
+.Op Fl w Ar provider
+.Nm ssh-keygen
.Fl R Ar hostname
.Op Fl f Ar known_hosts_file
.Nm ssh-keygen
.Fl r Ar hostname
-.Op Fl f Ar input_keyfile
.Op Fl g
+.Op Fl f Ar input_keyfile
.Nm ssh-keygen
-.Fl G Ar output_file
-.Op Fl v
-.Op Fl b Ar bits
-.Op Fl M Ar memory
-.Op Fl S Ar start_point
+.Fl M Cm generate
+.Op Fl O Ar option
+.Ar output_file
.Nm ssh-keygen
-.Fl T Ar output_file
-.Fl f Ar input_file
-.Op Fl v
-.Op Fl a Ar rounds
-.Op Fl J Ar num_lines
-.Op Fl j Ar start_line
-.Op Fl K Ar checkpt
-.Op Fl W Ar generator
+.Fl M Cm screen
+.Op Fl f Ar input_file
+.Op Fl O Ar option
+.Ar output_file
.Nm ssh-keygen
-.Fl s Ar ca_key
.Fl I Ar certificate_identity
-.Op Fl h
-.Op Fl U
+.Fl s Ar ca_key
+.Op Fl hU
.Op Fl D Ar pkcs11_provider
.Op Fl n Ar principals
.Op Fl O Ar option
@@ -126,6 +131,7 @@
.Op Fl f Ar input_keyfile
.Nm ssh-keygen
.Fl A
+.Op Fl a Ar rounds
.Op Fl f Ar prefix_path
.Nm ssh-keygen
.Fl k
@@ -136,9 +142,32 @@
.Ar
.Nm ssh-keygen
.Fl Q
+.Op Fl l
.Fl f Ar krl_file
.Ar
-.Ek
+.Nm ssh-keygen
+.Fl Y Cm find-principals
+.Op Fl O Ar option
+.Fl s Ar signature_file
+.Fl f Ar allowed_signers_file
+.Nm ssh-keygen
+.Fl Y Cm check-novalidate
+.Op Fl O Ar option
+.Fl n Ar namespace
+.Fl s Ar signature_file
+.Nm ssh-keygen
+.Fl Y Cm sign
+.Fl f Ar key_file
+.Fl n Ar namespace
+.Ar
+.Nm ssh-keygen
+.Fl Y Cm verify
+.Op Fl O Ar option
+.Fl f Ar allowed_signers_file
+.Fl I Ar signer_identity
+.Fl n Ar namespace
+.Fl s Ar signature_file
+.Op Fl r Ar revocation_file
.Sh DESCRIPTION
.Nm
generates, manages and converts authentication keys for
@@ -173,7 +202,9 @@ with public key authentication runs this once to create the authentication
key in
.Pa ~/.ssh/id_dsa ,
.Pa ~/.ssh/id_ecdsa ,
-.Pa ~/.ssh/id_ed25519
+.Pa ~/.ssh/id_ecdsa_sk ,
+.Pa ~/.ssh/id_ed25519 ,
+.Pa ~/.ssh/id_ed25519_sk
or
.Pa ~/.ssh/id_rsa .
Additionally, the system administrator may use this to generate host keys,
@@ -205,17 +236,31 @@ 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.
.Pp
-For keys stored in the newer OpenSSH format,
-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.
+.Nm
+will by default write keys in an OpenSSH-specific format.
+This format is preferred as it offers better protection for
+keys at rest as well as allowing storage of key comments within
+the private key file itself.
+The key comment may be useful to help identify the key.
The comment is initialized to
.Dq user@host
when the key is created, but can be changed using the
.Fl c
option.
.Pp
-After a key is generated, instructions below detail where the keys
+It is still possible for
+.Nm
+to write the previously-used PEM format private keys using the
+.Fl m
+flag.
+This may be used when generating new keys, and existing new-format
+keys may be converted using this option in conjunction with the
+.Fl p
+(change passphrase) flag.
+.Pp
+After a key is generated,
+.Nm
+will ask where the keys
should be placed to be activated.
.Pp
The options are as follows:
@@ -233,21 +278,19 @@ This is used by
.Pa /etc/rc
to generate new host keys.
.It Fl a Ar rounds
-When saving a private key this option specifies the number of KDF
-(key derivation function) rounds used.
+When saving a private key, this option specifies the number of KDF
+(key derivation function, currently
+.Xr bcrypt_pbkdf 3 )
+rounds used.
Higher numbers result in slower passphrase verification and increased
resistance to brute-force password cracking (should the keys be stolen).
-.Pp
-When screening DH-GEX candidates (using the
-.Fl T
-command).
-This option specifies the number of primality tests to perform.
+The default is 16 rounds.
.It Fl B
Show the bubblebabble digest of specified private or public key file.
.It Fl b Ar 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.
+For RSA keys, the minimum size is 1024 bits and the default is 3072 bits.
+Generally, 3072 bits is considered sufficient.
DSA keys must be exactly 1024 bits as specified by FIPS 186-2.
For ECDSA keys, the
.Fl b
@@ -255,7 +298,7 @@ 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
+ECDSA-SK, Ed25519 and Ed25519-SK keys have a fixed length and the
.Fl b
flag will be ignored.
.It Fl C Ar comment
@@ -265,7 +308,7 @@ Requests changing the comment in the private and public key files.
The program will prompt for the file containing the private keys, for
the passphrase if the key has one, and for the new comment.
.It Fl D Ar pkcs11
-Download the RSA public keys provided by the PKCS#11 shared library
+Download the public keys provided by the PKCS#11 shared library
.Ar pkcs11 .
When used in combination with
.Fl s ,
@@ -282,16 +325,17 @@ The default is
.Dq sha256 .
.It Fl 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
+print to stdout a public key in one of the formats specified by the
.Fl m
option.
The default export format is
.Dq RFC4716 .
This option allows exporting OpenSSH keys for use by other programs, including
several commercial SSH implementations.
-.It Fl F Ar hostname
+.It Fl F Ar hostname | [hostname]:port
Search for the specified
.Ar hostname
+(with optional port number)
in a
.Pa known_hosts
file, listing any occurrences found.
@@ -301,12 +345,6 @@ used in conjunction with the
option to print found keys in a hashed format.
.It Fl f Ar filename
Specifies the filename of the key file.
-.It Fl G Ar output_file
-Generate candidate primes for DH-GEX.
-These primes must be screened for
-safety (using the
-.Fl T
-option) before use.
.It Fl g
Use generic DNS format when printing fingerprint resource records using the
.Fl r
@@ -347,24 +385,12 @@ This option allows importing keys from other software, including several
commercial SSH implementations.
The default import format is
.Dq RFC4716 .
-.It Fl J Ar num_lines
-Exit after screening the specified number of lines
-while performing DH candidate screening using the
-.Fl T
-option.
-.It Fl j Ar start_line
-Start screening at the specified line number
-while performing DH candidate screening using the
-.Fl T
-option.
-.It Fl K Ar checkpt
-Write the last line processed to the file
-.Ar checkpt
-while performing DH candidate screening using the
-.Fl T
-option.
-This will be used to skip lines in the input file that have already been
-processed if the job is restarted.
+.It Fl K
+Download resident keys from a FIDO authenticator.
+Public and private key files will be written to the current directory for
+each downloaded key.
+If multiple FIDO authenticators are attached, keys will be downloaded from
+the first touched authenticator.
.It Fl k
Generate a KRL file.
In this mode,
@@ -387,24 +413,46 @@ If combined with
.Fl v ,
a visual ASCII art representation of the key is supplied with the
fingerprint.
-.It Fl M Ar memory
-Specify the amount of memory to use (in megabytes) when generating
-candidate moduli for DH-GEX.
+.It Fl M Cm generate
+Generate candidate Diffie-Hellman Group Exchange (DH-GEX) parameters for
+eventual use by the
+.Sq diffie-hellman-group-exchange-*
+key exchange methods.
+The numbers generated by this operation must be further screened before
+use.
+See the
+.Sx MODULI GENERATION
+section for more information.
+.It Fl M Cm screen
+Screen candidate parameters for Diffie-Hellman Group Exchange.
+This will accept a list of candidate numbers and test that they are
+safe (Sophie Germain) primes with acceptable group generators.
+The results of this operation may be added to the
+.Pa /etc/moduli
+file.
+See the
+.Sx MODULI GENERATION
+section for more information.
.It Fl m Ar key_format
-Specify a key format for the
+Specify a key format for key generation, the
.Fl i
-(import) or
+(import),
.Fl e
-(export) conversion options.
+(export) conversion options, and the
+.Fl p
+change passphrase operation.
+The latter may be used to convert between OpenSSH private key and PEM
+private key formats.
The supported key formats are:
.Dq RFC4716
(RFC 4716/SSH2 public or private key),
.Dq PKCS8
-(PEM PKCS8 public key)
+(PKCS8 public or private key)
or
.Dq PEM
(PEM public key).
-The default conversion format is
+By default OpenSSH will write newly-generated private keys in its own
+format, but when converting public keys for export the default format is
.Dq RFC4716 .
Setting a format of
.Dq PEM
@@ -420,90 +468,87 @@ Please see the
.Sx CERTIFICATES
section for details.
.It Fl O Ar option
-Specify a certificate option when signing a key.
-This option may be specified multiple times.
-See also the
-.Sx CERTIFICATES
-section for further details.
-.Pp
-At present, no standard options are valid for host keys.
-The options that are valid for user certificates are:
-.Pp
-.Bl -tag -width Ds -compact
-.It Ic clear
-Clear all enabled permissions.
-This is useful for clearing the default set of permissions so permissions may
-be added individually.
-.Pp
-.It Ic critical : Ns Ar name Ns Op Ns = Ns Ar contents
-.It Ic extension : Ns Ar name Ns Op Ns = Ns Ar contents
-Includes an arbitrary certificate critical option or extension.
-The specified
-.Ar name
-should include a domain suffix, e.g.\&
-.Dq name@example.com .
-If
-.Ar contents
-is specified then it is included as the contents of the extension/option
-encoded as a string, otherwise the extension/option is created with no
-contents (usually indicating a flag).
-Extensions may be ignored by a client or server that does not recognise them,
-whereas unknown critical options will cause the certificate to be refused.
-.Pp
-.It Ic force-command Ns = Ns Ar command
-Forces the execution of
-.Ar command
-instead of any shell or command specified by the user when
-the certificate is used for authentication.
-.Pp
-.It Ic no-agent-forwarding
-Disable
-.Xr ssh-agent 1
-forwarding (permitted by default).
+Specify a key/value option.
+These are specific to the operation that
+.Nm
+has been requested to perform.
.Pp
-.It Ic no-port-forwarding
-Disable port forwarding (permitted by default).
+When signing certificates, one of the options listed in the
+.Sx CERTIFICATES
+section may be specified here.
.Pp
-.It Ic no-pty
-Disable PTY allocation (permitted by default).
+When performing moduli generation or screening, one of the options
+listed in the
+.Sx MODULI GENERATION
+section may be specified.
.Pp
-.It Ic no-user-rc
-Disable execution of
-.Pa ~/.ssh/rc
-by
+When generating a key that will be hosted on a FIDO authenticator,
+this flag may be used to specify key-specific options.
+Those supported at present are:
+.Bl -tag -width Ds
+.It Cm application
+Override the default FIDO application/origin string of
+.Dq ssh: .
+This may be useful when generating host or domain-specific resident keys.
+The specified application string must begin with
+.Dq ssh: .
+.It Cm challenge Ns = Ns Ar path
+Specifies a path to a challenge string that will be passed to the
+FIDO token during key generation.
+The challenge string may be used as part of an out-of-band
+protocol for key enrollment
+(a random challenge is used by default).
+.It Cm device
+Explicitly specify a
+.Xr fido 4
+device to use, rather than letting the token middleware select one.
+.It Cm no-touch-required
+Indicate that the generated private key should not require touch
+events (user presence) when making signatures.
+Note that
.Xr sshd 8
-(permitted by default).
-.Pp
-.It Ic no-x11-forwarding
-Disable X11 forwarding (permitted by default).
-.Pp
-.It Ic permit-agent-forwarding
-Allows
-.Xr ssh-agent 1
-forwarding.
-.Pp
-.It Ic permit-port-forwarding
-Allows port forwarding.
-.Pp
-.It Ic permit-pty
-Allows PTY allocation.
-.Pp
-.It Ic permit-user-rc
-Allows execution of
-.Pa ~/.ssh/rc
-by
-.Xr sshd 8 .
+will refuse such signatures by default, unless overridden via
+an authorized_keys option.
+.It Cm resident
+Indicate that the key should be stored on the FIDO authenticator itself.
+Resident keys may be supported on FIDO2 tokens and typically require that
+a PIN be set on the token prior to generation.
+Resident keys may be loaded off the token using
+.Xr ssh-add 1 .
+.It Cm user
+A username to be associated with a resident key,
+overriding the empty default username.
+Specifying a username may be useful when generating multiple resident keys
+for the same application name.
+.It Cm verify-required
+Indicate that this private key should require user verification for
+each signature.
+Not all FIDO tokens support this option.
+Currently PIN authentication is the only supported verification method,
+but other methods may be supported in the future.
+.It Cm write-attestation Ns = Ns Ar path
+May be used at key generation time to record the attestation data
+returned from FIDO tokens during key generation.
+Please note that this information is potentially sensitive.
+By default, this information is discarded.
+.El
.Pp
-.It Ic permit-X11-forwarding
-Allows X11 forwarding.
+When performing signature-related options using the
+.Fl Y
+flag, the following options are accepted:
+.Bl -tag -width Ds
+.It Cm print-pubkey
+Print the full public key to standard output after signature verification.
+.It Cm verify-time Ns = Ns Ar timestamp
+Specifies a time to use when validating signatures instead of the current
+time.
+The time may be specified as a date in YYYYMMDD format or a time
+in YYYYMMDDHHMM[SS] format.
+.El
.Pp
-.It Ic source-address Ns = Ns Ar address_list
-Restrict the source addresses from which the certificate is considered valid.
The
-.Ar address_list
-is a comma-separated list of one or more address/netmask pairs in CIDR
-format.
-.El
+.Fl O
+option may be specified multiple times.
.It Fl P Ar passphrase
Provides the (old) passphrase.
.It Fl p
@@ -514,12 +559,16 @@ containing the private key, for the old passphrase, and twice for the
new passphrase.
.It Fl Q
Test whether keys have been revoked in a KRL.
+If the
+.Fl l
+option is also specified then the contents of the KRL will be printed.
.It Fl q
Silence
.Nm ssh-keygen .
-.It Fl R Ar hostname
-Removes all keys belonging to
+.It Fl R Ar hostname | [hostname]:port
+Removes all keys belonging to the specified
.Ar hostname
+(with optional port number)
from a
.Pa known_hosts
file.
@@ -530,8 +579,6 @@ option above).
Print the SSHFP fingerprint resource record named
.Ar hostname
for the specified public key file.
-.It Fl S Ar start
-Specify start point (in hex) when generating candidate moduli for DH-GEX.
.It Fl s Ar ca_key
Certify (sign) a public key using the specified CA key.
Please see the
@@ -545,18 +592,26 @@ by key ID or serial number.
See the
.Sx KEY REVOCATION LISTS
section for details.
-.It Fl T Ar output_file
-Test DH group exchange candidate primes (generated using the
-.Fl G
-option) for safety.
-.It Fl t Cm dsa | ecdsa | ed25519 | rsa
+.It Fl t Cm dsa | ecdsa | ecdsa-sk | ed25519 | ed25519-sk | rsa
Specifies the type of key to create.
The possible values are
.Dq dsa ,
.Dq ecdsa ,
+.Dq ecdsa-sk ,
.Dq ed25519 ,
+.Dq ed25519-sk ,
or
.Dq rsa .
+.Pp
+This flag may also be used to specify the desired signature type when
+signing certificates using an RSA CA key.
+The available RSA signature variants are
+.Dq ssh-rsa
+(SHA1 signatures, not recommended),
+.Dq rsa-sha2-256 ,
+and
+.Dq rsa-sha2-512
+(the default).
.It Fl U
When used in combination with
.Fl s ,
@@ -589,7 +644,7 @@ TIME FORMATS section of
The end time may be specified as a YYYYMMDD date, a YYYYMMDDHHMM[SS] time,
a relative time starting with a plus character or the string
.Dq forever
-to indicate that the certificate has no expirty date.
+to indicate that the certificate has no expiry date.
.Pp
For example:
.Dq +52w1d
@@ -599,7 +654,7 @@ For example:
.Dq 20100101123000:20110101123000
(valid from 12:30 PM, January 1st, 2010 to 12:30 PM, January 1st, 2011),
.Dq -1d:20110101
-(valid from yesterday to midnight, January 1st, 2011).
+(valid from yesterday to midnight, January 1st, 2011),
.Dq -1m:forever
(valid from one minute ago and never expiring).
.It Fl v
@@ -612,14 +667,113 @@ Multiple
.Fl v
options increase the verbosity.
The maximum is 3.
-.It Fl W Ar generator
-Specify desired generator when testing candidate moduli for DH-GEX.
+.It Fl w Ar provider
+Specifies a path to a library that will be used when creating
+FIDO authenticator-hosted keys, overriding the default of using
+the internal USB HID support.
+.It Fl Y Cm find-principals
+Find the principal(s) associated with the public key of a signature,
+provided using the
+.Fl s
+flag in an authorized signers file provided using the
+.Fl f
+flag.
+The format of the allowed signers file is documented in the
+.Sx ALLOWED SIGNERS
+section below.
+If one or more matching principals are found, they are returned on
+standard output.
+.It Fl Y Cm check-novalidate
+Checks that a signature generated using
+.Nm
+.Fl Y Cm sign
+has a valid structure.
+This does not validate if a signature comes from an authorized signer.
+When testing a signature,
+.Nm
+accepts a message on standard input and a signature namespace using
+.Fl n .
+A file containing the corresponding signature must also be supplied using the
+.Fl s
+flag.
+Successful testing of the signature is signalled by
+.Nm
+returning a zero exit status.
+.It Fl Y Cm sign
+Cryptographically sign a file or some data using a SSH key.
+When signing,
+.Nm
+accepts zero or more files to sign on the command-line - if no files
+are specified then
+.Nm
+will sign data presented on standard input.
+Signatures are written to the path of the input file with
+.Dq .sig
+appended, or to standard output if the message to be signed was read from
+standard input.
+.Pp
+The key used for signing is specified using the
+.Fl f
+option and may refer to either a private key, or a public key with the private
+half available via
+.Xr ssh-agent 1 .
+An additional signature namespace, used to prevent signature confusion across
+different domains of use (e.g. file signing vs email signing) must be provided
+via the
+.Fl n
+flag.
+Namespaces are arbitrary strings, and may include:
+.Dq file
+for file signing,
+.Dq email
+for email signing.
+For custom uses, it is recommended to use names following a
+NAMESPACE@YOUR.DOMAIN pattern to generate unambiguous namespaces.
+.It Fl Y Cm verify
+Request to verify a signature generated using
+.Nm
+.Fl Y Cm sign
+as described above.
+When verifying a signature,
+.Nm
+accepts a message on standard input and a signature namespace using
+.Fl n .
+A file containing the corresponding signature must also be supplied using the
+.Fl s
+flag, along with the identity of the signer using
+.Fl I
+and a list of allowed signers via the
+.Fl f
+flag.
+The format of the allowed signers file is documented in the
+.Sx ALLOWED SIGNERS
+section below.
+A file containing revoked keys can be passed using the
+.Fl r
+flag.
+The revocation file may be a KRL or a one-per-line list of public keys.
+Successful verification by an authorized signer is signalled by
+.Nm
+returning a zero exit status.
.It Fl y
This option will read a private
OpenSSH format file and print an OpenSSH public key to stdout.
+.It Fl Z Ar cipher
+Specifies the cipher to use for encryption when writing an OpenSSH-format
+private key file.
+The list of available ciphers may be obtained using
+.Qq ssh -Q cipher .
+The default is
+.Dq aes256-ctr .
.It Fl z Ar serial_number
Specifies a serial number to be embedded in the certificate to distinguish
this certificate from others from the same CA.
+If the
+.Ar serial_number
+is prefixed with a
+.Sq +
+character, then the serial number will be incremented for each certificate
+signed on a single command-line.
The default serial number is zero.
.Pp
When generating a KRL, the
@@ -636,25 +790,25 @@ These candidate primes are then tested for suitability (a CPU-intensive
process).
.Pp
Generation of primes is performed using the
-.Fl G
+.Fl M Cm generate
option.
The desired length of the primes may be specified by the
-.Fl b
+.Fl O Cm bits
option.
For example:
.Pp
-.Dl # ssh-keygen -G moduli-2048.candidates -b 2048
+.Dl # ssh-keygen -M generate -O bits=2048 moduli-2048.candidates
.Pp
By default, the search for primes begins at a random point in the
desired length range.
This may be overridden using the
-.Fl S
+.Fl O Cm start
option, which specifies a different start point (in hex).
.Pp
Once a set of candidates have been generated, they must be screened for
suitability.
This may be performed using the
-.Fl T
+.Fl M Cm screen
option.
In this mode
.Nm
@@ -663,23 +817,46 @@ will read candidates from standard input (or a file specified using the
option).
For example:
.Pp
-.Dl # ssh-keygen -T moduli-2048 -f moduli-2048.candidates
+.Dl # ssh-keygen -M screen -f moduli-2048.candidates moduli-2048
.Pp
By default, each candidate will be subjected to 100 primality tests.
This may be overridden using the
-.Fl a
+.Fl O Cm prime-tests
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
-.Fl W
+.Fl O Cm generator
option.
Valid generator values are 2, 3, and 5.
.Pp
Screened DH groups may be installed in
.Pa /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.
+It is important that this file contains moduli of a range of bit lengths.
+.Pp
+A number of options are available for moduli generation and screening via the
+.Fl O
+flag:
+.Bl -tag -width Ds
+.It Ic lines Ns = Ns Ar number
+Exit after screening the specified number of lines while performing DH
+candidate screening.
+.It Ic start-line Ns = Ns Ar line-number
+Start screening at the specified line number while performing DH candidate
+screening.
+.It Ic checkpoint Ns = Ns Ar filename
+Write the last line processed to the specified file while performing DH
+candidate screening.
+This will be used to skip lines in the input file that have already been
+processed if the job is restarted.
+.It Ic memory Ns = Ns Ar mbytes
+Specify the amount of memory to use (in megabytes) when generating
+candidate moduli for DH-GEX.
+.It Ic start Ns = Ns Ar hex-value
+Specify start point (in hex) when generating candidate moduli for DH-GEX.
+.It Ic generator Ns = Ns Ar value
+Specify desired generator (in decimal) when testing candidate moduli for DH-GEX.
+.El
.Sh CERTIFICATES
.Nm
supports signing of keys to produce certificates that may be used for
@@ -747,9 +924,104 @@ 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
-.Fl O
-option above.
+.Pp
+The options that are valid for user certificates are:
+.Pp
+.Bl -tag -width Ds -compact
+.It Ic clear
+Clear all enabled permissions.
+This is useful for clearing the default set of permissions so permissions may
+be added individually.
+.Pp
+.It Ic critical : Ns Ar name Ns Op Ns = Ns Ar contents
+.It Ic extension : Ns Ar name Ns Op Ns = Ns Ar contents
+Includes an arbitrary certificate critical option or extension.
+The specified
+.Ar name
+should include a domain suffix, e.g.\&
+.Dq name@example.com .
+If
+.Ar contents
+is specified then it is included as the contents of the extension/option
+encoded as a string, otherwise the extension/option is created with no
+contents (usually indicating a flag).
+Extensions may be ignored by a client or server that does not recognise them,
+whereas unknown critical options will cause the certificate to be refused.
+.Pp
+.It Ic force-command Ns = Ns Ar command
+Forces the execution of
+.Ar command
+instead of any shell or command specified by the user when
+the certificate is used for authentication.
+.Pp
+.It Ic no-agent-forwarding
+Disable
+.Xr ssh-agent 1
+forwarding (permitted by default).
+.Pp
+.It Ic no-port-forwarding
+Disable port forwarding (permitted by default).
+.Pp
+.It Ic no-pty
+Disable PTY allocation (permitted by default).
+.Pp
+.It Ic no-user-rc
+Disable execution of
+.Pa ~/.ssh/rc
+by
+.Xr sshd 8
+(permitted by default).
+.Pp
+.It Ic no-x11-forwarding
+Disable X11 forwarding (permitted by default).
+.Pp
+.It Ic permit-agent-forwarding
+Allows
+.Xr ssh-agent 1
+forwarding.
+.Pp
+.It Ic permit-port-forwarding
+Allows port forwarding.
+.Pp
+.It Ic permit-pty
+Allows PTY allocation.
+.Pp
+.It Ic permit-user-rc
+Allows execution of
+.Pa ~/.ssh/rc
+by
+.Xr sshd 8 .
+.Pp
+.It Ic permit-X11-forwarding
+Allows X11 forwarding.
+.Pp
+.It Ic no-touch-required
+Do not require signatures made using this key include demonstration
+of user presence (e.g. by having the user touch the authenticator).
+This option only makes sense for the FIDO authenticator algorithms
+.Cm ecdsa-sk
+and
+.Cm ed25519-sk .
+.Pp
+.It Ic source-address Ns = Ns Ar address_list
+Restrict the source addresses from which the certificate is considered valid.
+The
+.Ar address_list
+is a comma-separated list of one or more address/netmask pairs in CIDR
+format.
+.Pp
+.It Ic verify-required
+Require signatures made using this key indicate that the user was first
+verified.
+This option only makes sense for the FIDO authenticator algorithms
+.Cm ecdsa-sk
+and
+.Cm ed25519-sk .
+Currently PIN authentication is the only supported verification method,
+but other methods may be supported in the future.
+.El
+.Pp
+At present, no standard options are valid for host keys.
.Pp
Finally, certificates may be defined with a validity lifetime.
The
@@ -757,7 +1029,7 @@ The
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
+By default, certificates are valid from the
.Ux
Epoch to the distant future.
.Pp
@@ -847,14 +1119,79 @@ then
.Nm
will exit with a non-zero exit status.
A zero exit status will only be returned if no key was revoked.
+.Sh ALLOWED SIGNERS
+When verifying signatures,
+.Nm
+uses a simple list of identities and keys to determine whether a signature
+comes from an authorized source.
+This "allowed signers" file uses a format patterned after the
+AUTHORIZED_KEYS FILE FORMAT described in
+.Xr sshd 8 .
+Each line of the file contains the following space-separated fields:
+principals, options, keytype, base64-encoded key.
+Empty lines and lines starting with a
+.Ql #
+are ignored as comments.
+.Pp
+The principals field is a pattern-list (see PATTERNS in
+.Xr ssh_config 5 )
+consisting of one or more comma-separated USER@DOMAIN identity patterns
+that are accepted for signing.
+When verifying, the identity presented via the
+.Fl I
+option must match a principals pattern in order for the corresponding key to be
+considered acceptable for verification.
+.Pp
+The options (if present) consist of comma-separated option specifications.
+No spaces are permitted, except within double quotes.
+The following option specifications are supported (note that option keywords
+are case-insensitive):
+.Bl -tag -width Ds
+.It Cm cert-authority
+Indicates that this key is accepted as a certificate authority (CA) and
+that certificates signed by this CA may be accepted for verification.
+.It Cm namespaces Ns = Ns "namespace-list"
+Specifies a pattern-list of namespaces that are accepted for this key.
+If this option is present, the signature namespace embedded in the
+signature object and presented on the verification command-line must
+match the specified list before the key will be considered acceptable.
+.It Cm valid-after Ns = Ns "timestamp"
+Indicates that the key is valid for use at or after the specified timestamp,
+which may be a date in YYYYMMDD format or a time in YYYYMMDDHHMM[SS] format.
+.It Cm valid-before Ns = Ns "timestamp"
+Indicates that the key is valid for use at or before the specified timestamp.
+.El
+.Pp
+When verifying signatures made by certificates, the expected principal
+name must match both the principals pattern in the allowed signers file and
+the principals embedded in the certificate itself.
+.Pp
+An example allowed signers file:
+.Bd -literal -offset 3n
+# Comments allowed at start of line
+user1@example.com,user2@example.com ssh-rsa AAAAX1...
+# A certificate authority, trusted for all principals in a domain.
+*@example.com cert-authority ssh-ed25519 AAAB4...
+# A key that is accepted only for file signing.
+user2@example.com namespaces="file" ssh-ed25519 AAA41...
+.Ed
+.Sh ENVIRONMENT
+.Bl -tag -width Ds
+.It Ev SSH_SK_PROVIDER
+Specifies a path to a library that will be used when loading any
+FIDO authenticator-hosted keys, overriding the default of using
+the built-in USB HID support.
+.El
.Sh FILES
.Bl -tag -width Ds -compact
.It Pa ~/.ssh/id_dsa
.It Pa ~/.ssh/id_ecdsa
+.It Pa ~/.ssh/id_ecdsa_sk
.It Pa ~/.ssh/id_ed25519
+.It Pa ~/.ssh/id_ed25519_sk
.It Pa ~/.ssh/id_rsa
-Contains the DSA, ECDSA, Ed25519 or RSA
-authentication identity of the user.
+Contains the DSA, ECDSA, authenticator-hosted ECDSA, Ed25519,
+authenticator-hosted 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
@@ -867,10 +1204,12 @@ will read this file when a login attempt is made.
.Pp
.It Pa ~/.ssh/id_dsa.pub
.It Pa ~/.ssh/id_ecdsa.pub
+.It Pa ~/.ssh/id_ecdsa_sk.pub
.It Pa ~/.ssh/id_ed25519.pub
+.It Pa ~/.ssh/id_ed25519_sk.pub
.It Pa ~/.ssh/id_rsa.pub
-Contains the DSA, ECDSA, Ed25519 or RSA
-public key for authentication.
+Contains the DSA, ECDSA, authenticator-hosted ECDSA, Ed25519,
+authenticator-hosted Ed25519 or RSA public key for authentication.
The contents of this file should be added to
.Pa ~/.ssh/authorized_keys
on all machines
diff --git a/crypto/openssh/ssh-keygen.c b/crypto/openssh/ssh-keygen.c
index 46b3af5a89ed..18e9f1d180c6 100644
--- a/crypto/openssh/ssh-keygen.c
+++ b/crypto/openssh/ssh-keygen.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssh-keygen.c,v 1.322 2018/09/14 04:17:44 djm Exp $ */
+/* $OpenBSD: ssh-keygen.c,v 1.435 2021/08/11 08:54:17 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1994 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -24,6 +24,9 @@
#include "openbsd-compat/openssl-compat.h"
#endif
+#ifdef HAVE_STDINT_H
+# include <stdint.h>
+#endif
#include <errno.h>
#include <fcntl.h>
#include <netdb.h>
@@ -43,7 +46,6 @@
#include "xmalloc.h"
#include "sshkey.h"
#include "authfile.h"
-#include "uuencode.h"
#include "sshbuf.h"
#include "pathnames.h"
#include "log.h"
@@ -60,6 +62,10 @@
#include "digest.h"
#include "utf8.h"
#include "authfd.h"
+#include "sshsig.h"
+#include "ssh-sk.h"
+#include "sk-api.h" /* XXX for SSH_SK_USER_PRESENCE_REQD; remove */
+#include "cipher.h"
#ifdef WITH_OPENSSL
# define DEFAULT_KEY_TYPE_NAME "rsa"
@@ -67,133 +73,103 @@
# define DEFAULT_KEY_TYPE_NAME "ed25519"
#endif
-/* Number of bits in the RSA/DSA key. This value can be set on the command line. */
-#define DEFAULT_BITS 2048
-#define DEFAULT_BITS_DSA 1024
-#define DEFAULT_BITS_ECDSA 256
-u_int32_t bits = 0;
-
/*
- * Flag indicating that we just want to change the passphrase. This can be
- * set on the command line.
- */
-int change_passphrase = 0;
-
-/*
- * Flag indicating that we just want to change the comment. This can be set
- * on the command line.
+ * Default number of bits in the RSA, DSA and ECDSA keys. These value can be
+ * overridden on the command line.
+ *
+ * These values, with the exception of DSA, provide security equivalent to at
+ * least 128 bits of security according to NIST Special Publication 800-57:
+ * Recommendation for Key Management Part 1 rev 4 section 5.6.1.
+ * For DSA it (and FIPS-186-4 section 4.2) specifies that the only size for
+ * which a 160bit hash is acceptable is 1kbit, and since ssh-dss specifies only
+ * SHA1 we limit the DSA key size 1k bits.
*/
-int change_comment = 0;
-
-int quiet = 0;
-
-int log_level = SYSLOG_LEVEL_INFO;
-
-/* Flag indicating that we want to hash a known_hosts file */
-int hash_hosts = 0;
-/* Flag indicating that we want lookup a host in known_hosts file */
-int find_host = 0;
-/* Flag indicating that we want to delete a host from a known_hosts file */
-int delete_host = 0;
+#define DEFAULT_BITS 3072
+#define DEFAULT_BITS_DSA 1024
+#define DEFAULT_BITS_ECDSA 256
-/* Flag indicating that we want to show the contents of a certificate */
-int show_cert = 0;
+static int quiet = 0;
/* Flag indicating that we just want to see the key fingerprint */
-int print_fingerprint = 0;
-int print_bubblebabble = 0;
+static int print_fingerprint = 0;
+static int print_bubblebabble = 0;
/* Hash algorithm to use for fingerprints. */
-int fingerprint_hash = SSH_FP_HASH_DEFAULT;
+static int fingerprint_hash = SSH_FP_HASH_DEFAULT;
/* The identity file name, given on the command line or entered by the user. */
-char identity_file[1024];
-int have_identity = 0;
+static char identity_file[PATH_MAX];
+static int have_identity = 0;
/* This is set to the passphrase if given on the command line. */
-char *identity_passphrase = NULL;
+static char *identity_passphrase = NULL;
/* This is set to the new passphrase if given on the command line. */
-char *identity_new_passphrase = NULL;
-
-/* This is set to the new comment if given on the command line. */
-char *identity_comment = NULL;
-
-/* Path to CA key when certifying keys. */
-char *ca_key_path = NULL;
-
-/* Prefer to use agent keys for CA signing */
-int prefer_agent = 0;
-
-/* Certificate serial number */
-unsigned long long cert_serial = 0;
+static char *identity_new_passphrase = NULL;
/* Key type when certifying */
-u_int cert_key_type = SSH2_CERT_TYPE_USER;
+static u_int cert_key_type = SSH2_CERT_TYPE_USER;
/* "key ID" of signed key */
-char *cert_key_id = NULL;
+static char *cert_key_id = NULL;
/* Comma-separated list of principal names for certifying keys */
-char *cert_principals = NULL;
+static char *cert_principals = NULL;
/* Validity period for certificates */
-u_int64_t cert_valid_from = 0;
-u_int64_t cert_valid_to = ~0ULL;
+static u_int64_t cert_valid_from = 0;
+static u_int64_t cert_valid_to = ~0ULL;
/* Certificate options */
-#define CERTOPT_X_FWD (1)
-#define CERTOPT_AGENT_FWD (1<<1)
-#define CERTOPT_PORT_FWD (1<<2)
-#define CERTOPT_PTY (1<<3)
-#define CERTOPT_USER_RC (1<<4)
+#define CERTOPT_X_FWD (1)
+#define CERTOPT_AGENT_FWD (1<<1)
+#define CERTOPT_PORT_FWD (1<<2)
+#define CERTOPT_PTY (1<<3)
+#define CERTOPT_USER_RC (1<<4)
+#define CERTOPT_NO_REQUIRE_USER_PRESENCE (1<<5)
#define CERTOPT_DEFAULT (CERTOPT_X_FWD|CERTOPT_AGENT_FWD| \
CERTOPT_PORT_FWD|CERTOPT_PTY|CERTOPT_USER_RC)
-u_int32_t certflags_flags = CERTOPT_DEFAULT;
-char *certflags_command = NULL;
-char *certflags_src_addr = NULL;
+static u_int32_t certflags_flags = CERTOPT_DEFAULT;
+static char *certflags_command = NULL;
+static char *certflags_src_addr = NULL;
/* Arbitrary extensions specified by user */
-struct cert_userext {
+struct cert_ext {
char *key;
char *val;
int crit;
};
-struct cert_userext *cert_userext;
-size_t ncert_userext;
+static struct cert_ext *cert_ext;
+static size_t ncert_ext;
/* Conversion to/from various formats */
-int convert_to = 0;
-int convert_from = 0;
enum {
FMT_RFC4716,
FMT_PKCS8,
FMT_PEM
} convert_format = FMT_RFC4716;
-int print_public = 0;
-int print_generic = 0;
-char *key_type_name = NULL;
+static char *key_type_name = NULL;
/* Load key from this PKCS#11 provider */
-char *pkcs11provider = NULL;
+static char *pkcs11provider = NULL;
+
+/* FIDO/U2F provider to use */
+static char *sk_provider = NULL;
-/* Use new OpenSSH private key format when writing SSH2 keys instead of PEM */
-int use_new_format = 1;
+/* Format for writing private keys */
+static int private_key_format = SSHKEY_PRIVATE_OPENSSH;
/* Cipher for new-format private keys */
-char *new_format_cipher = NULL;
+static char *openssh_format_cipher = NULL;
-/*
- * Number of KDF rounds to derive new format keys /
- * number of primality trials when screening moduli.
- */
-int rounds = 0;
+/* Number of KDF rounds to derive new format keys. */
+static int rounds = 0;
/* argv0 */
extern char *__progname;
-char hostname[NI_MAXHOST];
+static char hostname[NI_MAXHOST];
#ifdef WITH_OPENSSL
/* moduli.c */
@@ -205,31 +181,30 @@ int prime_test(FILE *, FILE *, u_int32_t, u_int32_t, char *, unsigned long,
static void
type_bits_valid(int type, const char *name, u_int32_t *bitsp)
{
-#ifdef WITH_OPENSSL
- u_int maxbits, nid;
-#endif
-
if (type == KEY_UNSPEC)
fatal("unknown key type %s", key_type_name);
if (*bitsp == 0) {
#ifdef WITH_OPENSSL
- if (type == KEY_DSA)
+ int nid;
+
+ switch(type) {
+ case KEY_DSA:
*bitsp = DEFAULT_BITS_DSA;
- else if (type == KEY_ECDSA) {
+ break;
+ case KEY_ECDSA:
if (name != NULL &&
(nid = sshkey_ecdsa_nid_from_name(name)) > 0)
*bitsp = sshkey_curve_nid_to_bits(nid);
if (*bitsp == 0)
*bitsp = DEFAULT_BITS_ECDSA;
- } else
-#endif
+ break;
+ case KEY_RSA:
*bitsp = DEFAULT_BITS;
+ break;
+ }
+#endif
}
#ifdef WITH_OPENSSL
- maxbits = (type == KEY_DSA) ?
- OPENSSL_DSA_MAX_MODULUS_BITS : OPENSSL_RSA_MAX_MODULUS_BITS;
- if (*bitsp > maxbits)
- fatal("key bits exceeds maximum %d", maxbits);
switch (type) {
case KEY_DSA:
if (*bitsp != 1024)
@@ -239,15 +214,47 @@ type_bits_valid(int type, const char *name, u_int32_t *bitsp)
if (*bitsp < SSH_RSA_MINIMUM_MODULUS_SIZE)
fatal("Invalid RSA key length: minimum is %d bits",
SSH_RSA_MINIMUM_MODULUS_SIZE);
+ else if (*bitsp > OPENSSL_RSA_MAX_MODULUS_BITS)
+ fatal("Invalid RSA key length: maximum is %d bits",
+ OPENSSL_RSA_MAX_MODULUS_BITS);
break;
case KEY_ECDSA:
if (sshkey_ecdsa_bits_to_nid(*bitsp) == -1)
+#ifdef OPENSSL_HAS_NISTP521
fatal("Invalid ECDSA key length: valid lengths are "
"256, 384 or 521 bits");
+#else
+ fatal("Invalid ECDSA key length: valid lengths are "
+ "256 or 384 bits");
+#endif
}
#endif
}
+/*
+ * Checks whether a file exists and, if so, asks the user whether they wish
+ * to overwrite it.
+ * Returns nonzero if the file does not already exist or if the user agrees to
+ * overwrite, or zero otherwise.
+ */
+static int
+confirm_overwrite(const char *filename)
+{
+ char yesno[3];
+ struct stat st;
+
+ if (stat(filename, &st) != 0)
+ return 1;
+ printf("%s already exists.\n", filename);
+ printf("Overwrite (y/n)? ");
+ fflush(stdout);
+ if (fgets(yesno, sizeof(yesno), stdin) == NULL)
+ return 0;
+ if (yesno[0] != 'y' && yesno[0] != 'Y')
+ return 0;
+ return 1;
+}
+
static void
ask_filename(struct passwd *pw, const char *prompt)
{
@@ -267,6 +274,10 @@ ask_filename(struct passwd *pw, const char *prompt)
case KEY_ECDSA:
name = _PATH_SSH_CLIENT_ID_ECDSA;
break;
+ case KEY_ECDSA_SK_CERT:
+ case KEY_ECDSA_SK:
+ name = _PATH_SSH_CLIENT_ID_ECDSA_SK;
+ break;
#endif
case KEY_RSA_CERT:
case KEY_RSA:
@@ -276,6 +287,10 @@ ask_filename(struct passwd *pw, const char *prompt)
case KEY_ED25519_CERT:
name = _PATH_SSH_CLIENT_ID_ED25519;
break;
+ case KEY_ED25519_SK:
+ case KEY_ED25519_SK_CERT:
+ name = _PATH_SSH_CLIENT_ID_ED25519_SK;
+ break;
case KEY_XMSS:
case KEY_XMSS_CERT:
name = _PATH_SSH_CLIENT_ID_XMSS;
@@ -297,25 +312,26 @@ ask_filename(struct passwd *pw, const char *prompt)
}
static struct sshkey *
-load_identity(char *filename)
+load_identity(const char *filename, char **commentp)
{
char *pass;
struct sshkey *prv;
int r;
- if ((r = sshkey_load_private(filename, "", &prv, NULL)) == 0)
+ if (commentp != NULL)
+ *commentp = NULL;
+ if ((r = sshkey_load_private(filename, "", &prv, commentp)) == 0)
return prv;
if (r != SSH_ERR_KEY_WRONG_PASSPHRASE)
- fatal("Load key \"%s\": %s", filename, ssh_err(r));
+ fatal_r(r, "Load key \"%s\"", filename);
if (identity_passphrase)
pass = xstrdup(identity_passphrase);
else
pass = read_passphrase("Enter passphrase: ", RP_ALLOW_STDIN);
- r = sshkey_load_private(filename, pass, &prv, NULL);
- explicit_bzero(pass, strlen(pass));
- free(pass);
+ r = sshkey_load_private(filename, pass, &prv, commentp);
+ freezero(pass, strlen(pass));
if (r != 0)
- fatal("Load key \"%s\": %s", filename, ssh_err(r));
+ fatal_r(r, "Load key \"%s\"", filename);
return prv;
}
@@ -328,25 +344,30 @@ load_identity(char *filename)
static void
do_convert_to_ssh2(struct passwd *pw, struct sshkey *k)
{
- size_t len;
- u_char *blob;
- char comment[61];
+ struct sshbuf *b;
+ char comment[61], *b64;
int r;
- if ((r = sshkey_to_blob(k, &blob, &len)) != 0)
- fatal("key_to_blob failed: %s", ssh_err(r));
+ if ((b = sshbuf_new()) == NULL)
+ fatal_f("sshbuf_new failed");
+ if ((r = sshkey_putb(k, b)) != 0)
+ fatal_fr(r, "put key");
+ if ((b64 = sshbuf_dtob64_string(b, 1)) == NULL)
+ fatal_f("sshbuf_dtob64_string failed");
+
/* Comment + surrounds must fit into 72 chars (RFC 4716 sec 3.3) */
snprintf(comment, sizeof(comment),
"%u-bit %s, converted by %s@%s from OpenSSH",
sshkey_size(k), sshkey_type(k),
pw->pw_name, hostname);
+ sshkey_free(k);
+ sshbuf_free(b);
+
fprintf(stdout, "%s\n", SSH_COM_PUBLIC_BEGIN);
- fprintf(stdout, "Comment: \"%s\"\n", comment);
- dump_base64(stdout, blob, len);
+ fprintf(stdout, "Comment: \"%s\"\n%s", comment, b64);
fprintf(stdout, "%s\n", SSH_COM_PUBLIC_END);
- sshkey_free(k);
- free(blob);
+ free(b64);
exit(0);
}
@@ -369,7 +390,7 @@ do_convert_to_pkcs8(struct sshkey *k)
break;
#endif
default:
- fatal("%s: unsupported key type %s", __func__, sshkey_type(k));
+ fatal_f("unsupported key type %s", sshkey_type(k));
}
exit(0);
}
@@ -382,8 +403,18 @@ do_convert_to_pem(struct sshkey *k)
if (!PEM_write_RSAPublicKey(stdout, k->rsa))
fatal("PEM_write_RSAPublicKey failed");
break;
+ case KEY_DSA:
+ if (!PEM_write_DSA_PUBKEY(stdout, k->dsa))
+ fatal("PEM_write_DSA_PUBKEY failed");
+ break;
+#ifdef OPENSSL_HAS_ECC
+ case KEY_ECDSA:
+ if (!PEM_write_EC_PUBKEY(stdout, k->ecdsa))
+ fatal("PEM_write_EC_PUBKEY failed");
+ break;
+#endif
default:
- fatal("%s: unsupported key type %s", __func__, sshkey_type(k));
+ fatal_f("unsupported key type %s", sshkey_type(k));
}
exit(0);
}
@@ -397,10 +428,10 @@ do_convert_to(struct passwd *pw)
if (!have_identity)
ask_filename(pw, "Enter file in which the key is");
- if (stat(identity_file, &st) < 0)
+ if (stat(identity_file, &st) == -1)
fatal("%s: %s: %s", __progname, identity_file, strerror(errno));
if ((r = sshkey_load_public(identity_file, &k, NULL)) != 0)
- k = load_identity(identity_file);
+ k = load_identity(identity_file, NULL);
switch (convert_format) {
case FMT_RFC4716:
do_convert_to_ssh2(pw, k);
@@ -412,7 +443,7 @@ do_convert_to(struct passwd *pw)
do_convert_to_pem(k);
break;
default:
- fatal("%s: unknown key format %d", __func__, convert_format);
+ fatal_f("unknown key format %d", convert_format);
}
exit(0);
}
@@ -428,21 +459,20 @@ buffer_get_bignum_bits(struct sshbuf *b, BIGNUM *value)
int r;
if ((r = sshbuf_get_u32(b, &bignum_bits)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "parse");
bytes = (bignum_bits + 7) / 8;
if (sshbuf_len(b) < bytes)
- fatal("%s: input buffer too small: need %d have %zu",
- __func__, bytes, sshbuf_len(b));
+ fatal_f("input buffer too small: need %d have %zu",
+ bytes, sshbuf_len(b));
if (BN_bin2bn(sshbuf_ptr(b), bytes, value) == NULL)
- fatal("%s: BN_bin2bn failed", __func__);
+ fatal_f("BN_bin2bn failed");
if ((r = sshbuf_consume(b, bytes)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "consume");
}
static struct sshkey *
-do_convert_private_ssh2_from_blob(u_char *blob, u_int blen)
+do_convert_private_ssh2(struct sshbuf *b)
{
- struct sshbuf *b;
struct sshkey *key = NULL;
char *type, *cipher;
u_char e1, e2, e3, *sig = NULL, data[] = "abcde12345";
@@ -454,15 +484,13 @@ do_convert_private_ssh2_from_blob(u_char *blob, u_int blen)
BIGNUM *dsa_pub_key = NULL, *dsa_priv_key = NULL;
BIGNUM *rsa_n = NULL, *rsa_e = NULL, *rsa_d = NULL;
BIGNUM *rsa_p = NULL, *rsa_q = NULL, *rsa_iqmp = NULL;
- if ((b = sshbuf_from(blob, blen)) == NULL)
- fatal("%s: sshbuf_from failed", __func__);
+
if ((r = sshbuf_get_u32(b, &magic)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "parse magic");
if (magic != SSH_COM_PRIVATE_KEY_MAGIC) {
error("bad magic 0x%x != 0x%x", magic,
SSH_COM_PRIVATE_KEY_MAGIC);
- sshbuf_free(b);
return NULL;
}
if ((r = sshbuf_get_u32(b, &i1)) != 0 ||
@@ -471,12 +499,11 @@ do_convert_private_ssh2_from_blob(u_char *blob, u_int blen)
(r = sshbuf_get_u32(b, &i2)) != 0 ||
(r = sshbuf_get_u32(b, &i3)) != 0 ||
(r = sshbuf_get_u32(b, &i4)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "parse");
debug("ignore (%d %d %d %d)", i1, i2, i3, i4);
if (strcmp(cipher, "none") != 0) {
error("unsupported cipher %s", cipher);
free(cipher);
- sshbuf_free(b);
free(type);
return NULL;
}
@@ -487,7 +514,6 @@ do_convert_private_ssh2_from_blob(u_char *blob, u_int blen)
} else if (strstr(type, "rsa")) {
ktype = KEY_RSA;
} else {
- sshbuf_free(b);
free(type);
return NULL;
}
@@ -502,24 +528,24 @@ do_convert_private_ssh2_from_blob(u_char *blob, u_int blen)
(dsa_g = BN_new()) == NULL ||
(dsa_pub_key = BN_new()) == NULL ||
(dsa_priv_key = BN_new()) == NULL)
- fatal("%s: BN_new", __func__);
+ fatal_f("BN_new");
buffer_get_bignum_bits(b, dsa_p);
buffer_get_bignum_bits(b, dsa_g);
buffer_get_bignum_bits(b, dsa_q);
buffer_get_bignum_bits(b, dsa_pub_key);
buffer_get_bignum_bits(b, dsa_priv_key);
if (!DSA_set0_pqg(key->dsa, dsa_p, dsa_q, dsa_g))
- fatal("%s: DSA_set0_pqg failed", __func__);
+ fatal_f("DSA_set0_pqg failed");
dsa_p = dsa_q = dsa_g = NULL; /* transferred */
if (!DSA_set0_key(key->dsa, dsa_pub_key, dsa_priv_key))
- fatal("%s: DSA_set0_key failed", __func__);
+ fatal_f("DSA_set0_key failed");
dsa_pub_key = dsa_priv_key = NULL; /* transferred */
break;
case KEY_RSA:
if ((r = sshbuf_get_u8(b, &e1)) != 0 ||
(e1 < 30 && (r = sshbuf_get_u8(b, &e2)) != 0) ||
(e1 < 30 && (r = sshbuf_get_u8(b, &e3)) != 0))
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "parse RSA");
e = e1;
debug("e %lx", e);
if (e < 30) {
@@ -531,10 +557,9 @@ do_convert_private_ssh2_from_blob(u_char *blob, u_int blen)
debug("e %lx", e);
}
if ((rsa_e = BN_new()) == NULL)
- fatal("%s: BN_new", __func__);
+ fatal_f("BN_new");
if (!BN_set_word(rsa_e, e)) {
BN_clear_free(rsa_e);
- sshbuf_free(b);
sshkey_free(key);
return NULL;
}
@@ -543,32 +568,32 @@ do_convert_private_ssh2_from_blob(u_char *blob, u_int blen)
(rsa_p = BN_new()) == NULL ||
(rsa_q = BN_new()) == NULL ||
(rsa_iqmp = BN_new()) == NULL)
- fatal("%s: BN_new", __func__);
+ fatal_f("BN_new");
buffer_get_bignum_bits(b, rsa_d);
buffer_get_bignum_bits(b, rsa_n);
buffer_get_bignum_bits(b, rsa_iqmp);
buffer_get_bignum_bits(b, rsa_q);
buffer_get_bignum_bits(b, rsa_p);
if (!RSA_set0_key(key->rsa, rsa_n, rsa_e, rsa_d))
- fatal("%s: RSA_set0_key failed", __func__);
+ fatal_f("RSA_set0_key failed");
rsa_n = rsa_e = rsa_d = NULL; /* transferred */
if (!RSA_set0_factors(key->rsa, rsa_p, rsa_q))
- fatal("%s: RSA_set0_factors failed", __func__);
+ fatal_f("RSA_set0_factors failed");
rsa_p = rsa_q = NULL; /* transferred */
if ((r = ssh_rsa_complete_crt_parameters(key, rsa_iqmp)) != 0)
- fatal("generate RSA parameters failed: %s", ssh_err(r));
+ fatal_fr(r, "generate RSA parameters");
BN_clear_free(rsa_iqmp);
break;
}
rlen = sshbuf_len(b);
if (rlen != 0)
- error("do_convert_private_ssh2_from_blob: "
- "remaining bytes in key blob %d", rlen);
- sshbuf_free(b);
+ error_f("remaining bytes in key blob %d", rlen);
/* try the key */
- if (sshkey_sign(key, &sig, &slen, data, sizeof(data), NULL, 0) != 0 ||
- sshkey_verify(key, sig, slen, data, sizeof(data), NULL, 0) != 0) {
+ if (sshkey_sign(key, &sig, &slen, data, sizeof(data),
+ NULL, NULL, NULL, 0) != 0 ||
+ sshkey_verify(key, sig, slen, data, sizeof(data),
+ NULL, 0, NULL) != 0) {
sshkey_free(key);
free(sig);
return NULL;
@@ -609,10 +634,12 @@ do_convert_from_ssh2(struct passwd *pw, struct sshkey **k, int *private)
int r, blen, escaped = 0;
u_int len;
char line[1024];
- u_char blob[8096];
+ struct sshbuf *buf;
char encoded[8096];
FILE *fp;
+ if ((buf = sshbuf_new()) == NULL)
+ fatal("sshbuf_new failed");
if ((fp = fopen(identity_file, "r")) == NULL)
fatal("%s: %s: %s", __progname, identity_file, strerror(errno));
encoded[0] = '\0';
@@ -642,13 +669,14 @@ do_convert_from_ssh2(struct passwd *pw, struct sshkey **k, int *private)
(encoded[len-2] == '=') &&
(encoded[len-3] == '='))
encoded[len-3] = '\0';
- blen = uudecode(encoded, blob, sizeof(blob));
- if (blen < 0)
- fatal("uudecode failed.");
- if (*private)
- *k = do_convert_private_ssh2_from_blob(blob, blen);
- else if ((r = sshkey_from_blob(blob, blen, k)) != 0)
- fatal("decode blob failed: %s", ssh_err(r));
+ if ((r = sshbuf_b64tod(buf, encoded)) != 0)
+ fatal_fr(r, "base64 decode");
+ if (*private) {
+ if ((*k = do_convert_private_ssh2(buf)) == NULL)
+ fatal_f("private key conversion failed");
+ } else if ((r = sshkey_fromb(buf, k)) != 0)
+ fatal_fr(r, "parse key");
+ sshbuf_free(buf);
fclose(fp);
}
@@ -661,7 +689,7 @@ do_convert_from_pkcs8(struct sshkey **k, int *private)
if ((fp = fopen(identity_file, "r")) == NULL)
fatal("%s: %s: %s", __progname, identity_file, strerror(errno));
if ((pubkey = PEM_read_PUBKEY(fp, NULL, NULL, NULL)) == NULL) {
- fatal("%s: %s is not a recognised public key format", __func__,
+ fatal_f("%s is not a recognised public key format",
identity_file);
}
fclose(fp);
@@ -688,7 +716,7 @@ do_convert_from_pkcs8(struct sshkey **k, int *private)
break;
#endif
default:
- fatal("%s: unsupported pubkey type %d", __func__,
+ fatal_f("unsupported pubkey type %d",
EVP_PKEY_base_id(pubkey));
}
EVP_PKEY_free(pubkey);
@@ -711,7 +739,7 @@ do_convert_from_pem(struct sshkey **k, int *private)
fclose(fp);
return;
}
- fatal("%s: unrecognised raw private key format", __func__);
+ fatal_f("unrecognised raw private key format");
}
static void
@@ -723,7 +751,7 @@ do_convert_from(struct passwd *pw)
if (!have_identity)
ask_filename(pw, "Enter file in which the key is");
- if (stat(identity_file, &st) < 0)
+ if (stat(identity_file, &st) == -1)
fatal("%s: %s: %s", __progname, identity_file, strerror(errno));
switch (convert_format) {
@@ -737,7 +765,7 @@ do_convert_from(struct passwd *pw)
do_convert_from_pem(&k, &private);
break;
default:
- fatal("%s: unknown key format %d", __func__, convert_format);
+ fatal_f("unknown key format %d", convert_format);
}
if (!private) {
@@ -762,8 +790,7 @@ do_convert_from(struct passwd *pw)
NULL, 0, NULL, NULL);
break;
default:
- fatal("%s: unsupported key type %s", __func__,
- sshkey_type(k));
+ fatal_f("unsupported key type %s", sshkey_type(k));
}
}
@@ -780,16 +807,24 @@ do_print_public(struct passwd *pw)
struct sshkey *prv;
struct stat st;
int r;
+ char *comment = NULL;
if (!have_identity)
ask_filename(pw, "Enter file in which the key is");
- if (stat(identity_file, &st) < 0)
+ if (stat(identity_file, &st) == -1)
fatal("%s: %s", identity_file, strerror(errno));
- prv = load_identity(identity_file);
+ prv = load_identity(identity_file, &comment);
if ((r = sshkey_write(prv, stdout)) != 0)
- error("sshkey_write failed: %s", ssh_err(r));
- sshkey_free(prv);
+ fatal_fr(r, "write key");
+ if (comment != NULL && *comment != '\0')
+ fprintf(stdout, " %s", comment);
fprintf(stdout, "\n");
+ if (sshkey_is_sk(prv)) {
+ debug("sk_application: \"%s\", sk_flags 0x%02x",
+ prv->sk_application, prv->sk_flags);
+ }
+ sshkey_free(prv);
+ free(comment);
exit(0);
}
@@ -801,13 +836,13 @@ do_download(struct passwd *pw)
int i, nkeys;
enum sshkey_fp_rep rep;
int fptype;
- char *fp, *ra;
+ char *fp, *ra, **comments = NULL;
fptype = print_bubblebabble ? SSH_DIGEST_SHA1 : fingerprint_hash;
rep = print_bubblebabble ? SSH_FP_BUBBLEBABBLE : SSH_FP_DEFAULT;
- pkcs11_init(0);
- nkeys = pkcs11_add_provider(pkcs11provider, NULL, &keys);
+ pkcs11_init(1);
+ nkeys = pkcs11_add_provider(pkcs11provider, NULL, &keys, &comments);
if (nkeys <= 0)
fatal("cannot read public key from pkcs11");
for (i = 0; i < nkeys; i++) {
@@ -816,19 +851,22 @@ do_download(struct passwd *pw)
ra = sshkey_fingerprint(keys[i], fingerprint_hash,
SSH_FP_RANDOMART);
if (fp == NULL || ra == NULL)
- fatal("%s: sshkey_fingerprint fail", __func__);
+ fatal_f("sshkey_fingerprint fail");
printf("%u %s %s (PKCS11 key)\n", sshkey_size(keys[i]),
fp, sshkey_type(keys[i]));
- if (log_level >= SYSLOG_LEVEL_VERBOSE)
+ if (log_level_get() >= SYSLOG_LEVEL_VERBOSE)
printf("%s\n", ra);
free(ra);
free(fp);
} else {
(void) sshkey_write(keys[i], stdout); /* XXX check */
- fprintf(stdout, "\n");
+ fprintf(stdout, "%s%s\n",
+ *(comments[i]) == '\0' ? "" : " ", comments[i]);
}
+ free(comments[i]);
sshkey_free(keys[i]);
}
+ free(comments);
free(keys);
pkcs11_terminate();
exit(0);
@@ -864,10 +902,10 @@ fingerprint_one_key(const struct sshkey *public, const char *comment)
fp = sshkey_fingerprint(public, fptype, rep);
ra = sshkey_fingerprint(public, fingerprint_hash, SSH_FP_RANDOMART);
if (fp == NULL || ra == NULL)
- fatal("%s: sshkey_fingerprint failed", __func__);
+ fatal_f("sshkey_fingerprint failed");
mprintf("%u %s %s (%s)\n", sshkey_size(public), fp,
comment ? comment : "no comment", sshkey_type(public));
- if (log_level >= SYSLOG_LEVEL_VERBOSE)
+ if (log_level_get() >= SYSLOG_LEVEL_VERBOSE)
printf("%s\n", ra);
free(ra);
free(fp);
@@ -878,22 +916,25 @@ fingerprint_private(const char *path)
{
struct stat st;
char *comment = NULL;
- struct sshkey *public = NULL;
+ struct sshkey *privkey = NULL, *pubkey = NULL;
int r;
- if (stat(identity_file, &st) < 0)
+ if (stat(identity_file, &st) == -1)
fatal("%s: %s", path, strerror(errno));
- if ((r = sshkey_load_public(path, &public, &comment)) != 0) {
- debug("load public \"%s\": %s", path, ssh_err(r));
+ if ((r = sshkey_load_public(path, &pubkey, &comment)) != 0)
+ debug_r(r, "load public \"%s\"", path);
+ if (pubkey == NULL || comment == NULL || *comment == '\0') {
+ free(comment);
if ((r = sshkey_load_private(path, NULL,
- &public, &comment)) != 0) {
- debug("load private \"%s\": %s", path, ssh_err(r));
- fatal("%s is not a key file.", path);
- }
+ &privkey, &comment)) != 0)
+ debug_r(r, "load private \"%s\"", path);
}
+ if (pubkey == NULL && privkey == NULL)
+ fatal("%s is not a key file.", path);
- fingerprint_one_key(public, comment);
- sshkey_free(public);
+ fingerprint_one_key(pubkey == NULL ? privkey : pubkey, comment);
+ sshkey_free(pubkey);
+ sshkey_free(privkey);
free(comment);
}
@@ -1015,12 +1056,12 @@ do_gen_all_hostkeys(struct passwd *pw)
{ NULL, NULL, NULL }
};
+ u_int32_t bits = 0;
int first = 0;
struct stat st;
struct sshkey *private, *public;
char comment[1024], *prv_tmp, *pub_tmp, *prv_file, *pub_file;
int i, type, fd, r;
- FILE *f;
for (i = 0; key_types[i].key_type; i++) {
public = private = NULL;
@@ -1058,25 +1099,25 @@ do_gen_all_hostkeys(struct passwd *pw)
fflush(stdout);
type = sshkey_type_from_name(key_types[i].key_type);
if ((fd = mkstemp(prv_tmp)) == -1) {
- error("Could not save your public key in %s: %s",
+ error("Could not save your private key in %s: %s",
prv_tmp, strerror(errno));
goto failnext;
}
- close(fd); /* just using mkstemp() to generate/reserve a name */
+ (void)close(fd); /* just using mkstemp() to reserve a name */
bits = 0;
type_bits_valid(type, NULL, &bits);
if ((r = sshkey_generate(type, bits, &private)) != 0) {
- error("sshkey_generate failed: %s", ssh_err(r));
+ error_r(r, "sshkey_generate failed");
goto failnext;
}
if ((r = sshkey_from_private(private, &public)) != 0)
- fatal("sshkey_from_private failed: %s", ssh_err(r));
+ fatal_fr(r, "sshkey_from_private");
snprintf(comment, sizeof comment, "%s@%s", pw->pw_name,
hostname);
if ((r = sshkey_save_private(private, prv_tmp, "",
- comment, use_new_format, new_format_cipher, rounds)) != 0) {
- error("Saving key \"%s\" failed: %s",
- prv_tmp, ssh_err(r));
+ comment, private_key_format, openssh_format_cipher,
+ rounds)) != 0) {
+ error_r(r, "Saving key \"%s\" failed", prv_tmp);
goto failnext;
}
if ((fd = mkstemp(pub_tmp)) == -1) {
@@ -1085,25 +1126,10 @@ do_gen_all_hostkeys(struct passwd *pw)
goto failnext;
}
(void)fchmod(fd, 0644);
- f = fdopen(fd, "w");
- if (f == NULL) {
- error("fdopen %s failed: %s", pub_tmp, strerror(errno));
- close(fd);
- goto failnext;
- }
- if ((r = sshkey_write(public, f)) != 0) {
- error("write key failed: %s", ssh_err(r));
- fclose(f);
- goto failnext;
- }
- fprintf(f, " %s\n", comment);
- if (ferror(f) != 0) {
- error("write key failed: %s", strerror(errno));
- fclose(f);
- goto failnext;
- }
- if (fclose(f) != 0) {
- error("key close failed: %s", strerror(errno));
+ (void)close(fd);
+ if ((r = sshkey_save_public(public, pub_tmp, comment)) != 0) {
+ error_r(r, "Unable to save public key to %s",
+ identity_file);
goto failnext;
}
@@ -1138,6 +1164,9 @@ struct known_hosts_ctx {
int has_unhashed; /* When hashing, original had unhashed hosts */
int found_key; /* For find/delete, host was found */
int invalid; /* File contained invalid items; don't delete */
+ int hash_hosts; /* Hash hostnames as we go */
+ int find_host; /* Search for specific hostname */
+ int delete_host; /* Delete host from known_hosts */
};
static int
@@ -1157,7 +1186,7 @@ known_hosts_hash(struct hostkey_foreach_line *l, void *_ctx)
*/
if (was_hashed || has_wild || l->marker != MRK_NONE) {
fprintf(ctx->out, "%s\n", l->line);
- if (has_wild && !find_host) {
+ if (has_wild && !ctx->find_host) {
logit("%s:%lu: ignoring host name "
"with wildcard: %.64s", l->path,
l->linenum, l->hosts);
@@ -1197,13 +1226,13 @@ known_hosts_find_delete(struct hostkey_foreach_line *l, void *_ctx)
struct known_hosts_ctx *ctx = (struct known_hosts_ctx *)_ctx;
enum sshkey_fp_rep rep;
int fptype;
- char *fp;
+ char *fp = NULL, *ra = NULL;
fptype = print_bubblebabble ? SSH_DIGEST_SHA1 : fingerprint_hash;
rep = print_bubblebabble ? SSH_FP_BUBBLEBABBLE : SSH_FP_DEFAULT;
if (l->status == HKF_STATUS_MATCHED) {
- if (delete_host) {
+ if (ctx->delete_host) {
if (l->marker != MRK_NONE) {
/* Don't remove CA and revocation lines */
fprintf(ctx->out, "%s\n", l->line);
@@ -1219,7 +1248,7 @@ known_hosts_find_delete(struct hostkey_foreach_line *l, void *_ctx)
ctx->host, l->linenum);
}
return 0;
- } else if (find_host) {
+ } else if (ctx->find_host) {
ctx->found_key = 1;
if (!quiet) {
printf("# Host %s found: line %lu %s\n",
@@ -1227,18 +1256,27 @@ known_hosts_find_delete(struct hostkey_foreach_line *l, void *_ctx)
l->linenum, l->marker == MRK_CA ? "CA" :
(l->marker == MRK_REVOKE ? "REVOKED" : ""));
}
- if (hash_hosts)
+ if (ctx->hash_hosts)
known_hosts_hash(l, ctx);
else if (print_fingerprint) {
fp = sshkey_fingerprint(l->key, fptype, rep);
- mprintf("%s %s %s %s\n", ctx->host,
- sshkey_type(l->key), fp, l->comment);
+ ra = sshkey_fingerprint(l->key,
+ fingerprint_hash, SSH_FP_RANDOMART);
+ if (fp == NULL || ra == NULL)
+ fatal_f("sshkey_fingerprint failed");
+ mprintf("%s %s %s%s%s\n", ctx->host,
+ sshkey_type(l->key), fp,
+ l->comment[0] ? " " : "",
+ l->comment);
+ if (log_level_get() >= SYSLOG_LEVEL_VERBOSE)
+ printf("%s\n", ra);
+ free(ra);
free(fp);
} else
fprintf(ctx->out, "%s\n", l->line);
return 0;
}
- } else if (delete_host) {
+ } else if (ctx->delete_host) {
/* Retain non-matching hosts when deleting */
if (l->status == HKF_STATUS_INVALID) {
ctx->invalid = 1;
@@ -1250,12 +1288,14 @@ known_hosts_find_delete(struct hostkey_foreach_line *l, void *_ctx)
}
static void
-do_known_hosts(struct passwd *pw, const char *name)
+do_known_hosts(struct passwd *pw, const char *name, int find_host,
+ int delete_host, int hash_hosts)
{
char *cp, tmp[PATH_MAX], old[PATH_MAX];
int r, fd, oerrno, inplace = 0;
struct known_hosts_ctx ctx;
u_int foreach_options;
+ struct stat sb;
if (!have_identity) {
cp = tilde_expand_filename(_PATH_SSH_USER_HOSTFILE, pw->pw_uid);
@@ -1265,10 +1305,15 @@ do_known_hosts(struct passwd *pw, const char *name)
free(cp);
have_identity = 1;
}
+ if (stat(identity_file, &sb) != 0)
+ fatal("Cannot stat %s: %s", identity_file, strerror(errno));
memset(&ctx, 0, sizeof(ctx));
ctx.out = stdout;
ctx.host = name;
+ ctx.hash_hosts = hash_hosts;
+ ctx.find_host = find_host;
+ ctx.delete_host = delete_host;
/*
* Find hosts goes to stdout, hash and deletions happen in-place
@@ -1288,6 +1333,7 @@ do_known_hosts(struct passwd *pw, const char *name)
unlink(tmp);
fatal("fdopen: %s", strerror(oerrno));
}
+ fchmod(fd, sb.st_mode & 0644);
inplace = 1;
}
/* XXX support identity_file == "-" for stdin */
@@ -1295,10 +1341,10 @@ do_known_hosts(struct passwd *pw, const char *name)
foreach_options |= print_fingerprint ? HKF_WANT_PARSE_KEY : 0;
if ((r = hostkeys_foreach(identity_file, (find_host || !hash_hosts) ?
known_hosts_find_delete : known_hosts_hash, &ctx, name, NULL,
- foreach_options)) != 0) {
+ foreach_options, 0)) != 0) {
if (inplace)
unlink(tmp);
- fatal("%s: hostkeys_foreach failed: %s", __func__, ssh_err(r));
+ fatal_fr(r, "hostkeys_foreach");
}
if (inplace)
@@ -1359,7 +1405,7 @@ do_change_passphrase(struct passwd *pw)
if (!have_identity)
ask_filename(pw, "Enter file in which the key is");
- if (stat(identity_file, &st) < 0)
+ if (stat(identity_file, &st) == -1)
fatal("%s: %s", identity_file, strerror(errno));
/* Try to load the file with empty passphrase. */
r = sshkey_load_private(identity_file, "", &private, &comment);
@@ -1372,13 +1418,12 @@ do_change_passphrase(struct passwd *pw)
RP_ALLOW_STDIN);
r = sshkey_load_private(identity_file, old_passphrase,
&private, &comment);
- explicit_bzero(old_passphrase, strlen(old_passphrase));
- free(old_passphrase);
+ freezero(old_passphrase, strlen(old_passphrase));
if (r != 0)
goto badkey;
} else if (r != 0) {
badkey:
- fatal("Failed to load key %s: %s", identity_file, ssh_err(r));
+ fatal_r(r, "Failed to load key %s", identity_file);
}
if (comment)
mprintf("Key has comment '%s'\n", comment);
@@ -1404,24 +1449,20 @@ do_change_passphrase(struct passwd *pw)
exit(1);
}
/* Destroy the other copy. */
- explicit_bzero(passphrase2, strlen(passphrase2));
- free(passphrase2);
+ freezero(passphrase2, strlen(passphrase2));
}
/* Save the file using the new passphrase. */
if ((r = sshkey_save_private(private, identity_file, passphrase1,
- comment, use_new_format, new_format_cipher, rounds)) != 0) {
- error("Saving key \"%s\" failed: %s.",
- identity_file, ssh_err(r));
- explicit_bzero(passphrase1, strlen(passphrase1));
- free(passphrase1);
+ comment, private_key_format, openssh_format_cipher, rounds)) != 0) {
+ error_r(r, "Saving key \"%s\" failed", identity_file);
+ freezero(passphrase1, strlen(passphrase1));
sshkey_free(private);
free(comment);
exit(1);
}
/* Destroy the passphrase and the copy of the key in memory. */
- explicit_bzero(passphrase1, strlen(passphrase1));
- free(passphrase1);
+ freezero(passphrase1, strlen(passphrase1));
sshkey_free(private); /* Destroys contents */
free(comment);
@@ -1433,7 +1474,8 @@ do_change_passphrase(struct passwd *pw)
* Print the SSHFP RR.
*/
static int
-do_print_resource_record(struct passwd *pw, char *fname, char *hname)
+do_print_resource_record(struct passwd *pw, char *fname, char *hname,
+ int print_generic)
{
struct sshkey *public;
char *comment = NULL;
@@ -1441,15 +1483,14 @@ do_print_resource_record(struct passwd *pw, char *fname, char *hname)
int r;
if (fname == NULL)
- fatal("%s: no filename", __func__);
- if (stat(fname, &st) < 0) {
+ fatal_f("no filename");
+ if (stat(fname, &st) == -1) {
if (errno == ENOENT)
return 0;
fatal("%s: %s", fname, strerror(errno));
}
if ((r = sshkey_load_public(fname, &public, &comment)) != 0)
- fatal("Failed to read v2 public key from \"%s\": %s.",
- fname, ssh_err(r));
+ fatal_r(r, "Failed to read v2 public key from \"%s\"", fname);
export_dns_rr(hname, public, stdout, print_generic);
sshkey_free(public);
free(comment);
@@ -1460,25 +1501,23 @@ do_print_resource_record(struct passwd *pw, char *fname, char *hname)
* Change the comment of a private key file.
*/
static void
-do_change_comment(struct passwd *pw)
+do_change_comment(struct passwd *pw, const char *identity_comment)
{
char new_comment[1024], *comment, *passphrase;
struct sshkey *private;
struct sshkey *public;
struct stat st;
- FILE *f;
- int r, fd;
+ int r;
if (!have_identity)
ask_filename(pw, "Enter file in which the key is");
- if (stat(identity_file, &st) < 0)
+ if (stat(identity_file, &st) == -1)
fatal("%s: %s", identity_file, strerror(errno));
if ((r = sshkey_load_private(identity_file, "",
&private, &comment)) == 0)
passphrase = xstrdup("");
else if (r != SSH_ERR_KEY_WRONG_PASSPHRASE)
- fatal("Cannot load private key \"%s\": %s.",
- identity_file, ssh_err(r));
+ fatal_r(r, "Cannot load private key \"%s\"", identity_file);
else {
if (identity_passphrase)
passphrase = xstrdup(identity_passphrase);
@@ -1490,15 +1529,14 @@ do_change_comment(struct passwd *pw)
/* Try to load using the passphrase. */
if ((r = sshkey_load_private(identity_file, passphrase,
&private, &comment)) != 0) {
- explicit_bzero(passphrase, strlen(passphrase));
- free(passphrase);
- fatal("Cannot load private key \"%s\": %s.",
- identity_file, ssh_err(r));
+ freezero(passphrase, strlen(passphrase));
+ fatal_r(r, "Cannot load private key \"%s\"",
+ identity_file);
}
}
if (private->type != KEY_ED25519 && private->type != KEY_XMSS &&
- !use_new_format) {
+ private_key_format != SSHKEY_PRIVATE_OPENSSH) {
error("Comments are only supported for keys stored in "
"the new format (-o).");
explicit_bzero(passphrase, strlen(passphrase));
@@ -1506,14 +1544,14 @@ do_change_comment(struct passwd *pw)
exit(1);
}
if (comment)
- printf("Key now has comment '%s'\n", comment);
+ printf("Old comment: %s\n", comment);
else
- printf("Key now has no comment\n");
+ printf("No existing comment\n");
if (identity_comment) {
strlcpy(new_comment, identity_comment, sizeof(new_comment));
} else {
- printf("Enter new comment: ");
+ printf("New comment: ");
fflush(stdout);
if (!fgets(new_comment, sizeof(new_comment), stdin)) {
explicit_bzero(passphrase, strlen(passphrase));
@@ -1522,69 +1560,70 @@ do_change_comment(struct passwd *pw)
}
new_comment[strcspn(new_comment, "\n")] = '\0';
}
+ if (comment != NULL && strcmp(comment, new_comment) == 0) {
+ printf("No change to comment\n");
+ free(passphrase);
+ sshkey_free(private);
+ free(comment);
+ exit(0);
+ }
/* Save the file using the new passphrase. */
if ((r = sshkey_save_private(private, identity_file, passphrase,
- new_comment, use_new_format, new_format_cipher, rounds)) != 0) {
- error("Saving key \"%s\" failed: %s",
- identity_file, ssh_err(r));
- explicit_bzero(passphrase, strlen(passphrase));
- free(passphrase);
+ new_comment, private_key_format, openssh_format_cipher,
+ rounds)) != 0) {
+ error_r(r, "Saving key \"%s\" failed", identity_file);
+ freezero(passphrase, strlen(passphrase));
sshkey_free(private);
free(comment);
exit(1);
}
- explicit_bzero(passphrase, strlen(passphrase));
- free(passphrase);
+ freezero(passphrase, strlen(passphrase));
if ((r = sshkey_from_private(private, &public)) != 0)
- fatal("sshkey_from_private failed: %s", ssh_err(r));
+ fatal_fr(r, "sshkey_from_private");
sshkey_free(private);
strlcat(identity_file, ".pub", sizeof(identity_file));
- fd = open(identity_file, O_WRONLY | O_CREAT | O_TRUNC, 0644);
- if (fd == -1)
- fatal("Could not save your public key in %s", identity_file);
- f = fdopen(fd, "w");
- if (f == NULL)
- fatal("fdopen %s failed: %s", identity_file, strerror(errno));
- if ((r = sshkey_write(public, f)) != 0)
- fatal("write key failed: %s", ssh_err(r));
+ if ((r = sshkey_save_public(public, identity_file, new_comment)) != 0)
+ fatal_r(r, "Unable to save public key to %s", identity_file);
sshkey_free(public);
- fprintf(f, " %s\n", new_comment);
- fclose(f);
-
free(comment);
- printf("The comment in your key file has been changed.\n");
+ if (strlen(new_comment) > 0)
+ printf("Comment '%s' applied\n", new_comment);
+ else
+ printf("Comment removed\n");
+
exit(0);
}
static void
-add_flag_option(struct sshbuf *c, const char *name)
+cert_ext_add(const char *key, const char *value, int iscrit)
{
- int r;
-
- debug3("%s: %s", __func__, name);
- if ((r = sshbuf_put_cstring(c, name)) != 0 ||
- (r = sshbuf_put_string(c, NULL, 0)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ cert_ext = xreallocarray(cert_ext, ncert_ext + 1, sizeof(*cert_ext));
+ cert_ext[ncert_ext].key = xstrdup(key);
+ cert_ext[ncert_ext].val = value == NULL ? NULL : xstrdup(value);
+ cert_ext[ncert_ext].crit = iscrit;
+ ncert_ext++;
}
-static void
-add_string_option(struct sshbuf *c, const char *name, const char *value)
+/* qsort(3) comparison function for certificate extensions */
+static int
+cert_ext_cmp(const void *_a, const void *_b)
{
- struct sshbuf *b;
+ const struct cert_ext *a = (const struct cert_ext *)_a;
+ const struct cert_ext *b = (const struct cert_ext *)_b;
int r;
- debug3("%s: %s=%s", __func__, name, value);
- if ((b = sshbuf_new()) == NULL)
- fatal("%s: sshbuf_new failed", __func__);
- if ((r = sshbuf_put_cstring(b, value)) != 0 ||
- (r = sshbuf_put_cstring(c, name)) != 0 ||
- (r = sshbuf_put_stringb(c, b)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
-
- sshbuf_free(b);
+ if (a->crit != b->crit)
+ return (a->crit < b->crit) ? -1 : 1;
+ if ((r = strcmp(a->key, b->key)) != 0)
+ return r;
+ if ((a->val == NULL) != (b->val == NULL))
+ return (a->val == NULL) ? -1 : 1;
+ if (a->val != NULL && (r = strcmp(a->val, b->val)) != 0)
+ return r;
+ return 0;
}
#define OPTIONS_CRITICAL 1
@@ -1592,41 +1631,62 @@ add_string_option(struct sshbuf *c, const char *name, const char *value)
static void
prepare_options_buf(struct sshbuf *c, int which)
{
+ struct sshbuf *b;
size_t i;
+ int r;
+ const struct cert_ext *ext;
+ if ((b = sshbuf_new()) == NULL)
+ fatal_f("sshbuf_new failed");
sshbuf_reset(c);
- if ((which & OPTIONS_CRITICAL) != 0 &&
- certflags_command != NULL)
- add_string_option(c, "force-command", certflags_command);
- if ((which & OPTIONS_EXTENSIONS) != 0 &&
- (certflags_flags & CERTOPT_X_FWD) != 0)
- add_flag_option(c, "permit-X11-forwarding");
- if ((which & OPTIONS_EXTENSIONS) != 0 &&
- (certflags_flags & CERTOPT_AGENT_FWD) != 0)
- add_flag_option(c, "permit-agent-forwarding");
- if ((which & OPTIONS_EXTENSIONS) != 0 &&
- (certflags_flags & CERTOPT_PORT_FWD) != 0)
- add_flag_option(c, "permit-port-forwarding");
- if ((which & OPTIONS_EXTENSIONS) != 0 &&
- (certflags_flags & CERTOPT_PTY) != 0)
- add_flag_option(c, "permit-pty");
- if ((which & OPTIONS_EXTENSIONS) != 0 &&
- (certflags_flags & CERTOPT_USER_RC) != 0)
- add_flag_option(c, "permit-user-rc");
- if ((which & OPTIONS_CRITICAL) != 0 &&
- certflags_src_addr != NULL)
- add_string_option(c, "source-address", certflags_src_addr);
- for (i = 0; i < ncert_userext; i++) {
- if ((cert_userext[i].crit && (which & OPTIONS_EXTENSIONS)) ||
- (!cert_userext[i].crit && (which & OPTIONS_CRITICAL)))
+ for (i = 0; i < ncert_ext; i++) {
+ ext = &cert_ext[i];
+ if ((ext->crit && (which & OPTIONS_EXTENSIONS)) ||
+ (!ext->crit && (which & OPTIONS_CRITICAL)))
continue;
- if (cert_userext[i].val == NULL)
- add_flag_option(c, cert_userext[i].key);
- else {
- add_string_option(c, cert_userext[i].key,
- cert_userext[i].val);
+ if (ext->val == NULL) {
+ /* flag option */
+ debug3_f("%s", ext->key);
+ if ((r = sshbuf_put_cstring(c, ext->key)) != 0 ||
+ (r = sshbuf_put_string(c, NULL, 0)) != 0)
+ fatal_fr(r, "prepare flag");
+ } else {
+ /* key/value option */
+ debug3_f("%s=%s", ext->key, ext->val);
+ sshbuf_reset(b);
+ if ((r = sshbuf_put_cstring(c, ext->key)) != 0 ||
+ (r = sshbuf_put_cstring(b, ext->val)) != 0 ||
+ (r = sshbuf_put_stringb(c, b)) != 0)
+ fatal_fr(r, "prepare k/v");
}
}
+ sshbuf_free(b);
+}
+
+static void
+finalise_cert_exts(void)
+{
+ /* critical options */
+ if (certflags_command != NULL)
+ cert_ext_add("force-command", certflags_command, 1);
+ if (certflags_src_addr != NULL)
+ cert_ext_add("source-address", certflags_src_addr, 1);
+ /* extensions */
+ if ((certflags_flags & CERTOPT_X_FWD) != 0)
+ cert_ext_add("permit-X11-forwarding", NULL, 0);
+ if ((certflags_flags & CERTOPT_AGENT_FWD) != 0)
+ cert_ext_add("permit-agent-forwarding", NULL, 0);
+ if ((certflags_flags & CERTOPT_PORT_FWD) != 0)
+ cert_ext_add("permit-port-forwarding", NULL, 0);
+ if ((certflags_flags & CERTOPT_PTY) != 0)
+ cert_ext_add("permit-pty", NULL, 0);
+ if ((certflags_flags & CERTOPT_USER_RC) != 0)
+ cert_ext_add("permit-user-rc", NULL, 0);
+ if ((certflags_flags & CERTOPT_NO_REQUIRE_USER_PRESENCE) != 0)
+ cert_ext_add("no-touch-required", NULL, 0);
+ /* order lexically by key */
+ if (ncert_ext > 0)
+ qsort(cert_ext, ncert_ext, sizeof(*cert_ext), cert_ext_cmp);
}
static struct sshkey *
@@ -1637,11 +1697,11 @@ load_pkcs11_key(char *path)
int r, i, nkeys;
if ((r = sshkey_load_public(path, &public, NULL)) != 0)
- fatal("Couldn't load CA public key \"%s\": %s",
- path, ssh_err(r));
+ fatal_r(r, "Couldn't load CA public key \"%s\"", path);
- nkeys = pkcs11_add_provider(pkcs11provider, identity_passphrase, &keys);
- debug3("%s: %d keys", __func__, nkeys);
+ nkeys = pkcs11_add_provider(pkcs11provider, identity_passphrase,
+ &keys, NULL);
+ debug3_f("%d keys", nkeys);
if (nkeys <= 0)
fatal("cannot read public key from pkcs11");
for (i = 0; i < nkeys; i++) {
@@ -1661,9 +1721,10 @@ load_pkcs11_key(char *path)
/* Signer for sshkey_certify_custom that uses the agent */
static int
-agent_signer(const struct sshkey *key, u_char **sigp, size_t *lenp,
+agent_signer(struct sshkey *key, u_char **sigp, size_t *lenp,
const u_char *data, size_t datalen,
- const char *alg, u_int compat, void *ctx)
+ const char *alg, const char *provider, const char *pin,
+ u_int compat, void *ctx)
{
int *agent_fdp = (int *)ctx;
@@ -1672,15 +1733,18 @@ agent_signer(const struct sshkey *key, u_char **sigp, size_t *lenp,
}
static void
-do_ca_sign(struct passwd *pw, int argc, char **argv)
+do_ca_sign(struct passwd *pw, const char *ca_key_path, int prefer_agent,
+ unsigned long long cert_serial, int cert_serial_autoinc,
+ int argc, char **argv)
{
- int r, i, fd, found, agent_fd = -1;
+ int r, i, found, agent_fd = -1;
u_int n;
struct sshkey *ca, *public;
- char valid[64], *otmp, *tmp, *cp, *out, *comment, **plist = NULL;
- FILE *f;
+ char valid[64], *otmp, *tmp, *cp, *out, *comment;
+ char *ca_fp = NULL, **plist = NULL, *pin = NULL;
struct ssh_identitylist *agent_ids;
size_t j;
+ struct notifier_ctx *notifier = NULL;
#ifdef ENABLE_PKCS11
pkcs11_init(1);
@@ -1697,13 +1761,11 @@ do_ca_sign(struct passwd *pw, int argc, char **argv)
* agent.
*/
if ((r = sshkey_load_public(tmp, &ca, NULL)) != 0)
- fatal("Cannot load CA public key %s: %s",
- tmp, ssh_err(r));
+ fatal_r(r, "Cannot load CA public key %s", tmp);
if ((r = ssh_get_authentication_socket(&agent_fd)) != 0)
- fatal("Cannot use public key for CA signature: %s",
- ssh_err(r));
+ fatal_r(r, "Cannot use public key for CA signature");
if ((r = ssh_fetch_identitylist(agent_fd, &agent_ids)) != 0)
- fatal("Retrieve agent key list: %s", ssh_err(r));
+ fatal_r(r, "Retrieve agent key list");
found = 0;
for (j = 0; j < agent_ids->nkeys; j++) {
if (sshkey_equal(ca, agent_ids->keys[j])) {
@@ -1717,16 +1779,28 @@ do_ca_sign(struct passwd *pw, int argc, char **argv)
ca->flags |= SSHKEY_FLAG_EXT;
} else {
/* CA key is assumed to be a private key on the filesystem */
- ca = load_identity(tmp);
+ ca = load_identity(tmp, NULL);
+ if (sshkey_is_sk(ca) &&
+ (ca->sk_flags & SSH_SK_USER_VERIFICATION_REQD)) {
+ if ((pin = read_passphrase("Enter PIN for CA key: ",
+ RP_ALLOW_STDIN)) == NULL)
+ fatal_f("couldn't read PIN");
+ }
}
free(tmp);
- if (key_type_name != NULL &&
- sshkey_type_from_name(key_type_name) != ca->type) {
- fatal("CA key type %s doesn't match specified %s",
- sshkey_ssh_name(ca), key_type_name);
+ if (key_type_name != NULL) {
+ if (sshkey_type_from_name(key_type_name) != ca->type) {
+ fatal("CA key type %s doesn't match specified %s",
+ sshkey_ssh_name(ca), key_type_name);
+ }
+ } else if (ca->type == KEY_RSA) {
+ /* Default to a good signature algorithm */
+ key_type_name = "rsa-sha2-512";
}
+ ca_fp = sshkey_fingerprint(ca, fingerprint_hash, SSH_FP_DEFAULT);
+ finalise_cert_exts();
for (i = 0; i < argc; i++) {
/* Split list of principals */
n = 0;
@@ -1742,21 +1816,17 @@ do_ca_sign(struct passwd *pw, int argc, char **argv)
}
if (n > SSHKEY_CERT_MAX_PRINCIPALS)
fatal("Too many certificate principals specified");
-
+
tmp = tilde_expand_filename(argv[i], pw->pw_uid);
if ((r = sshkey_load_public(tmp, &public, &comment)) != 0)
- fatal("%s: unable to open \"%s\": %s",
- __func__, tmp, ssh_err(r));
- if (public->type != KEY_RSA && public->type != KEY_DSA &&
- public->type != KEY_ECDSA && public->type != KEY_ED25519 &&
- public->type != KEY_XMSS)
- fatal("%s: key \"%s\" type %s cannot be certified",
- __func__, tmp, sshkey_type(public));
+ fatal_r(r, "load pubkey \"%s\"", tmp);
+ if (sshkey_is_cert(public))
+ fatal_f("key \"%s\" type %s cannot be certified",
+ tmp, sshkey_type(public));
/* Prepare certificate to sign */
if ((r = sshkey_to_certified(public)) != 0)
- fatal("Could not upgrade key %s to certificate: %s",
- tmp, ssh_err(r));
+ fatal_r(r, "Could not upgrade key %s to certificate", tmp);
public->cert->type = cert_key_type;
public->cert->serial = (u_int64_t)cert_serial;
public->cert->key_id = xstrdup(cert_key_id);
@@ -1769,17 +1839,25 @@ do_ca_sign(struct passwd *pw, int argc, char **argv)
OPTIONS_EXTENSIONS);
if ((r = sshkey_from_private(ca,
&public->cert->signature_key)) != 0)
- fatal("sshkey_from_private (ca key): %s", ssh_err(r));
+ fatal_r(r, "sshkey_from_private (ca key)");
if (agent_fd != -1 && (ca->flags & SSHKEY_FLAG_EXT) != 0) {
if ((r = sshkey_certify_custom(public, ca,
- key_type_name, agent_signer, &agent_fd)) != 0)
- fatal("Couldn't certify key %s via agent: %s",
- tmp, ssh_err(r));
+ key_type_name, sk_provider, NULL, agent_signer,
+ &agent_fd)) != 0)
+ fatal_r(r, "Couldn't certify %s via agent", tmp);
} else {
- if ((sshkey_certify(public, ca, key_type_name)) != 0)
- fatal("Couldn't certify key %s: %s",
- tmp, ssh_err(r));
+ if (sshkey_is_sk(ca) &&
+ (ca->sk_flags & SSH_SK_USER_PRESENCE_REQD)) {
+ notifier = notify_start(0,
+ "Confirm user presence for key %s %s",
+ sshkey_type(ca), ca_fp);
+ }
+ r = sshkey_certify(public, ca, key_type_name,
+ sk_provider, pin);
+ notify_complete(notifier, "User presence confirmed");
+ if (r != 0)
+ fatal_r(r, "Couldn't certify key %s", tmp);
}
if ((cp = strrchr(tmp, '.')) != NULL && strcmp(cp, ".pub") == 0)
@@ -1787,16 +1865,10 @@ do_ca_sign(struct passwd *pw, int argc, char **argv)
xasprintf(&out, "%s-cert.pub", tmp);
free(tmp);
- if ((fd = open(out, O_WRONLY|O_CREAT|O_TRUNC, 0644)) == -1)
- fatal("Could not open \"%s\" for writing: %s", out,
- strerror(errno));
- if ((f = fdopen(fd, "w")) == NULL)
- fatal("%s: fdopen: %s", __func__, strerror(errno));
- if ((r = sshkey_write(public, f)) != 0)
- fatal("Could not write certified key to %s: %s",
- out, ssh_err(r));
- fprintf(f, " %s\n", comment);
- fclose(f);
+ if ((r = sshkey_save_public(public, out, comment)) != 0) {
+ fatal_r(r, "Unable to save public key to %s",
+ identity_file);
+ }
if (!quiet) {
sshkey_format_cert_validity(public->cert,
@@ -1812,7 +1884,12 @@ do_ca_sign(struct passwd *pw, int argc, char **argv)
sshkey_free(public);
free(out);
+ if (cert_serial_autoinc)
+ cert_serial++;
}
+ if (pin != NULL)
+ freezero(pin, strlen(pin));
+ free(ca_fp);
#ifdef ENABLE_PKCS11
pkcs11_terminate();
#endif
@@ -1911,6 +1988,10 @@ add_cert_option(char *opt)
certflags_flags &= ~CERTOPT_USER_RC;
else if (strcasecmp(opt, "permit-user-rc") == 0)
certflags_flags |= CERTOPT_USER_RC;
+ else if (strcasecmp(opt, "touch-required") == 0)
+ certflags_flags &= ~CERTOPT_NO_REQUIRE_USER_PRESENCE;
+ else if (strcasecmp(opt, "no-touch-required") == 0)
+ certflags_flags |= CERTOPT_NO_REQUIRE_USER_PRESENCE;
else if (strncasecmp(opt, "force-command=", 14) == 0) {
val = opt + 14;
if (*val == '\0')
@@ -1928,17 +2009,12 @@ add_cert_option(char *opt)
fatal("Invalid source-address list");
certflags_src_addr = xstrdup(val);
} else if (strncasecmp(opt, "extension:", 10) == 0 ||
- (iscrit = (strncasecmp(opt, "critical:", 9) == 0))) {
+ (iscrit = (strncasecmp(opt, "critical:", 9) == 0))) {
val = xstrdup(strchr(opt, ':') + 1);
if ((cp = strchr(val, '=')) != NULL)
*cp++ = '\0';
- cert_userext = xreallocarray(cert_userext, ncert_userext + 1,
- sizeof(*cert_userext));
- cert_userext[ncert_userext].key = val;
- cert_userext[ncert_userext].val = cp == NULL ?
- NULL : xstrdup(cp);
- cert_userext[ncert_userext].crit = iscrit;
- ncert_userext++;
+ cert_ext_add(val, cp, iscrit);
+ free(val);
} else
fatal("Unsupported certificate option \"%s\"", opt);
}
@@ -1946,39 +2022,42 @@ add_cert_option(char *opt)
static void
show_options(struct sshbuf *optbuf, int in_critical)
{
- char *name, *arg;
+ char *name, *arg, *hex;
struct sshbuf *options, *option = NULL;
int r;
if ((options = sshbuf_fromb(optbuf)) == NULL)
- fatal("%s: sshbuf_fromb failed", __func__);
+ fatal_f("sshbuf_fromb failed");
while (sshbuf_len(options) != 0) {
sshbuf_free(option);
option = NULL;
if ((r = sshbuf_get_cstring(options, &name, NULL)) != 0 ||
(r = sshbuf_froms(options, &option)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "parse option");
printf(" %s", name);
if (!in_critical &&
(strcmp(name, "permit-X11-forwarding") == 0 ||
strcmp(name, "permit-agent-forwarding") == 0 ||
strcmp(name, "permit-port-forwarding") == 0 ||
strcmp(name, "permit-pty") == 0 ||
- strcmp(name, "permit-user-rc") == 0))
+ strcmp(name, "permit-user-rc") == 0 ||
+ strcmp(name, "no-touch-required") == 0)) {
printf("\n");
- else if (in_critical &&
+ } else if (in_critical &&
(strcmp(name, "force-command") == 0 ||
strcmp(name, "source-address") == 0)) {
if ((r = sshbuf_get_cstring(option, &arg, NULL)) != 0)
- fatal("%s: buffer error: %s",
- __func__, ssh_err(r));
+ fatal_fr(r, "parse critical");
printf(" %s\n", arg);
free(arg);
- } else {
- printf(" UNKNOWN OPTION (len %zu)\n",
- sshbuf_len(option));
+ } else if (sshbuf_len(option) > 0) {
+ hex = sshbuf_dtob16(option);
+ printf(" UNKNOWN OPTION: %s (len %zu)\n",
+ hex, sshbuf_len(option));
sshbuf_reset(option);
- }
+ free(hex);
+ } else
+ printf(" UNKNOWN FLAG OPTION\n");
free(name);
if (sshbuf_len(option) != 0)
fatal("Option corrupt: extra data at end");
@@ -1997,14 +2076,15 @@ print_cert(struct sshkey *key)
ca_fp = sshkey_fingerprint(key->cert->signature_key,
fingerprint_hash, SSH_FP_DEFAULT);
if (key_fp == NULL || ca_fp == NULL)
- fatal("%s: sshkey_fingerprint fail", __func__);
+ fatal_f("sshkey_fingerprint fail");
sshkey_format_cert_validity(key->cert, valid, sizeof(valid));
printf(" Type: %s %s certificate\n", sshkey_ssh_name(key),
sshkey_cert_type(key));
printf(" Public key: %s %s\n", sshkey_type(key), key_fp);
- printf(" Signing CA: %s %s\n",
- sshkey_type(key->cert->signature_key), ca_fp);
+ printf(" Signing CA: %s %s (using %s)\n",
+ sshkey_type(key->cert->signature_key), ca_fp,
+ key->cert->signature_type);
printf(" Key ID: \"%s\"\n", key->cert->key_id);
printf(" Serial: %llu\n", (unsigned long long)key->cert->serial);
printf(" Valid: %s\n", valid);
@@ -2047,7 +2127,7 @@ do_show_cert(struct passwd *pw)
if (!have_identity)
ask_filename(pw, "Enter file in which the key is");
- if (strcmp(identity_file, "-") != 0 && stat(identity_file, &st) < 0)
+ if (strcmp(identity_file, "-") != 0 && stat(identity_file, &st) == -1)
fatal("%s: %s: %s", __progname, identity_file, strerror(errno));
path = identity_file;
@@ -2069,8 +2149,7 @@ do_show_cert(struct passwd *pw)
if ((key = sshkey_new(KEY_UNSPEC)) == NULL)
fatal("sshkey_new");
if ((r = sshkey_read(key, &cp)) != 0) {
- error("%s:%lu: invalid key: %s", path,
- lnum, ssh_err(r));
+ error_r(r, "%s:%lu: invalid key", path, lnum);
continue;
}
if (!sshkey_is_cert(key)) {
@@ -2094,19 +2173,14 @@ static void
load_krl(const char *path, struct ssh_krl **krlp)
{
struct sshbuf *krlbuf;
- int r, fd;
+ int r;
- if ((krlbuf = sshbuf_new()) == NULL)
- fatal("sshbuf_new failed");
- if ((fd = open(path, O_RDONLY)) == -1)
- fatal("open %s: %s", path, strerror(errno));
- if ((r = sshkey_load_file(fd, krlbuf)) != 0)
- fatal("Unable to load KRL: %s", ssh_err(r));
- close(fd);
+ if ((r = sshbuf_load_file(path, &krlbuf)) != 0)
+ fatal_r(r, "Unable to load KRL %s", path);
/* XXX check sigs */
if ((r = ssh_krl_from_blob(krlbuf, krlp, NULL, 0)) != 0 ||
*krlp == NULL)
- fatal("Invalid KRL file: %s", ssh_err(r));
+ fatal_r(r, "Invalid KRL file %s", path);
sshbuf_free(krlbuf);
}
@@ -2135,9 +2209,9 @@ hash_to_blob(const char *cp, u_char **blobp, size_t *lenp,
tmp[tlen] = '\0';
}
if ((b = sshbuf_new()) == NULL)
- fatal("%s: sshbuf_new failed", __func__);
+ fatal_f("sshbuf_new failed");
if ((r = sshbuf_b64tod(b, tmp)) != 0)
- fatal("%s:%lu: decode hash failed: %s", file, lnum, ssh_err(r));
+ fatal_r(r, "%s:%lu: decode hash failed", file, lnum);
free(tmp);
*lenp = sshbuf_len(b);
*blobp = xmalloc(*lenp);
@@ -2223,8 +2297,7 @@ update_krl_from_file(struct passwd *pw, const char *file, int wild_ca,
}
if (ssh_krl_revoke_cert_by_serial_range(krl,
ca, serial, serial2) != 0) {
- fatal("%s: revoke serial failed",
- __func__);
+ fatal_f("revoke serial failed");
}
} else if (strncasecmp(cp, "id:", 3) == 0) {
if (ca == NULL && !wild_ca) {
@@ -2234,12 +2307,14 @@ update_krl_from_file(struct passwd *pw, const char *file, int wild_ca,
cp += 3;
cp = cp + strspn(cp, " \t");
if (ssh_krl_revoke_cert_by_key_id(krl, ca, cp) != 0)
- fatal("%s: revoke key ID failed", __func__);
+ fatal_f("revoke key ID failed");
} else if (strncasecmp(cp, "hash:", 5) == 0) {
cp += 5;
cp = cp + strspn(cp, " \t");
hash_to_blob(cp, &blob, &blen, file, lnum);
r = ssh_krl_revoke_key_sha256(krl, blob, blen);
+ if (r != 0)
+ fatal_fr(r, "revoke key failed");
} else {
if (strncasecmp(cp, "key:", 4) == 0) {
cp += 4;
@@ -2261,8 +2336,7 @@ update_krl_from_file(struct passwd *pw, const char *file, int wild_ca,
if ((key = sshkey_new(KEY_UNSPEC)) == NULL)
fatal("sshkey_new");
if ((r = sshkey_read(key, &cp)) != 0)
- fatal("%s:%lu: invalid key: %s",
- path, lnum, ssh_err(r));
+ fatal_r(r, "%s:%lu: invalid key", path, lnum);
if (was_explicit_key)
r = ssh_krl_revoke_key_explicit(krl, key);
else if (was_sha1) {
@@ -2282,8 +2356,7 @@ update_krl_from_file(struct passwd *pw, const char *file, int wild_ca,
} else
r = ssh_krl_revoke_key(krl, key);
if (r != 0)
- fatal("%s: revoke key failed: %s",
- __func__, ssh_err(r));
+ fatal_fr(r, "revoke key failed");
freezero(blob, blen);
blob = NULL;
blen = 0;
@@ -2297,12 +2370,14 @@ update_krl_from_file(struct passwd *pw, const char *file, int wild_ca,
}
static void
-do_gen_krl(struct passwd *pw, int updating, int argc, char **argv)
+do_gen_krl(struct passwd *pw, int updating, const char *ca_key_path,
+ unsigned long long krl_version, const char *krl_comment,
+ int argc, char **argv)
{
struct ssh_krl *krl;
struct stat sb;
struct sshkey *ca = NULL;
- int fd, i, r, wild_ca = 0;
+ int i, r, wild_ca = 0;
char *tmp;
struct sshbuf *kbuf;
@@ -2321,8 +2396,7 @@ do_gen_krl(struct passwd *pw, int updating, int argc, char **argv)
else {
tmp = tilde_expand_filename(ca_key_path, pw->pw_uid);
if ((r = sshkey_load_public(tmp, &ca, NULL)) != 0)
- fatal("Cannot load CA public key %s: %s",
- tmp, ssh_err(r));
+ fatal_r(r, "Cannot load CA public key %s", tmp);
free(tmp);
}
}
@@ -2332,10 +2406,10 @@ do_gen_krl(struct passwd *pw, int updating, int argc, char **argv)
else if ((krl = ssh_krl_init()) == NULL)
fatal("couldn't create KRL");
- if (cert_serial != 0)
- ssh_krl_set_version(krl, cert_serial);
- if (identity_comment != NULL)
- ssh_krl_set_comment(krl, identity_comment);
+ if (krl_version != 0)
+ ssh_krl_set_version(krl, krl_version);
+ if (krl_comment != NULL)
+ ssh_krl_set_comment(krl, krl_comment);
for (i = 0; i < argc; i++)
update_krl_from_file(pw, argv[i], wild_ca, ca, krl);
@@ -2344,19 +2418,15 @@ do_gen_krl(struct passwd *pw, int updating, int argc, char **argv)
fatal("sshbuf_new failed");
if (ssh_krl_to_blob(krl, kbuf, NULL, 0) != 0)
fatal("Couldn't generate KRL");
- if ((fd = open(identity_file, O_WRONLY|O_CREAT|O_TRUNC, 0644)) == -1)
- fatal("open %s: %s", identity_file, strerror(errno));
- if (atomicio(vwrite, fd, sshbuf_mutable_ptr(kbuf), sshbuf_len(kbuf)) !=
- sshbuf_len(kbuf))
+ if ((r = sshbuf_write_file(identity_file, kbuf)) != 0)
fatal("write %s: %s", identity_file, strerror(errno));
- close(fd);
sshbuf_free(kbuf);
ssh_krl_free(krl);
sshkey_free(ca);
}
static void
-do_check_krl(struct passwd *pw, int argc, char **argv)
+do_check_krl(struct passwd *pw, int print_krl, int argc, char **argv)
{
int i, r, ret = 0;
char *comment;
@@ -2366,10 +2436,11 @@ do_check_krl(struct passwd *pw, int argc, char **argv)
if (*identity_file == '\0')
fatal("KRL checking requires an input file");
load_krl(identity_file, &krl);
+ if (print_krl)
+ krl_dump(krl, stdout);
for (i = 0; i < argc; i++) {
if ((r = sshkey_load_public(argv[i], &k, &comment)) != 0)
- fatal("Cannot load public key %s: %s",
- argv[i], ssh_err(r));
+ fatal_r(r, "Cannot load public key %s", argv[i]);
r = ssh_krl_check_key(krl, k);
printf("%s%s%s%s: %s\n", argv[i],
*comment ? " (" : "", comment, *comment ? ")" : "",
@@ -2383,17 +2454,685 @@ do_check_krl(struct passwd *pw, int argc, char **argv)
exit(ret);
}
+static struct sshkey *
+load_sign_key(const char *keypath, const struct sshkey *pubkey)
+{
+ size_t i, slen, plen = strlen(keypath);
+ char *privpath = xstrdup(keypath);
+ const char *suffixes[] = { "-cert.pub", ".pub", NULL };
+ struct sshkey *ret = NULL, *privkey = NULL;
+ int r;
+
+ /*
+ * If passed a public key filename, then try to locate the corresponding
+ * private key. This lets us specify certificates on the command-line
+ * and have ssh-keygen find the appropriate private key.
+ */
+ for (i = 0; suffixes[i]; i++) {
+ slen = strlen(suffixes[i]);
+ if (plen <= slen ||
+ strcmp(privpath + plen - slen, suffixes[i]) != 0)
+ continue;
+ privpath[plen - slen] = '\0';
+ debug_f("%s looks like a public key, using private key "
+ "path %s instead", keypath, privpath);
+ }
+ if ((privkey = load_identity(privpath, NULL)) == NULL) {
+ error("Couldn't load identity %s", keypath);
+ goto done;
+ }
+ if (!sshkey_equal_public(pubkey, privkey)) {
+ error("Public key %s doesn't match private %s",
+ keypath, privpath);
+ goto done;
+ }
+ if (sshkey_is_cert(pubkey) && !sshkey_is_cert(privkey)) {
+ /*
+ * Graft the certificate onto the private key to make
+ * it capable of signing.
+ */
+ if ((r = sshkey_to_certified(privkey)) != 0) {
+ error_fr(r, "sshkey_to_certified");
+ goto done;
+ }
+ if ((r = sshkey_cert_copy(pubkey, privkey)) != 0) {
+ error_fr(r, "sshkey_cert_copy");
+ goto done;
+ }
+ }
+ /* success */
+ ret = privkey;
+ privkey = NULL;
+ done:
+ sshkey_free(privkey);
+ free(privpath);
+ return ret;
+}
+
+static int
+sign_one(struct sshkey *signkey, const char *filename, int fd,
+ const char *sig_namespace, sshsig_signer *signer, void *signer_ctx)
+{
+ struct sshbuf *sigbuf = NULL, *abuf = NULL;
+ int r = SSH_ERR_INTERNAL_ERROR, wfd = -1, oerrno;
+ char *wfile = NULL, *asig = NULL, *fp = NULL;
+ char *pin = NULL, *prompt = NULL;
+
+ if (!quiet) {
+ if (fd == STDIN_FILENO)
+ fprintf(stderr, "Signing data on standard input\n");
+ else
+ fprintf(stderr, "Signing file %s\n", filename);
+ }
+ if (signer == NULL && sshkey_is_sk(signkey)) {
+ if ((signkey->sk_flags & SSH_SK_USER_VERIFICATION_REQD)) {
+ xasprintf(&prompt, "Enter PIN for %s key: ",
+ sshkey_type(signkey));
+ if ((pin = read_passphrase(prompt,
+ RP_ALLOW_STDIN)) == NULL)
+ fatal_f("couldn't read PIN");
+ }
+ if ((signkey->sk_flags & SSH_SK_USER_PRESENCE_REQD)) {
+ if ((fp = sshkey_fingerprint(signkey, fingerprint_hash,
+ SSH_FP_DEFAULT)) == NULL)
+ fatal_f("fingerprint failed");
+ fprintf(stderr, "Confirm user presence for key %s %s\n",
+ sshkey_type(signkey), fp);
+ free(fp);
+ }
+ }
+ if ((r = sshsig_sign_fd(signkey, NULL, sk_provider, pin,
+ fd, sig_namespace, &sigbuf, signer, signer_ctx)) != 0) {
+ error_r(r, "Signing %s failed", filename);
+ goto out;
+ }
+ if ((r = sshsig_armor(sigbuf, &abuf)) != 0) {
+ error_fr(r, "sshsig_armor");
+ goto out;
+ }
+ if ((asig = sshbuf_dup_string(abuf)) == NULL) {
+ error_f("buffer error");
+ r = SSH_ERR_ALLOC_FAIL;
+ goto out;
+ }
+
+ if (fd == STDIN_FILENO) {
+ fputs(asig, stdout);
+ fflush(stdout);
+ } else {
+ xasprintf(&wfile, "%s.sig", filename);
+ if (confirm_overwrite(wfile)) {
+ if ((wfd = open(wfile, O_WRONLY|O_CREAT|O_TRUNC,
+ 0666)) == -1) {
+ oerrno = errno;
+ error("Cannot open %s: %s",
+ wfile, strerror(errno));
+ errno = oerrno;
+ r = SSH_ERR_SYSTEM_ERROR;
+ goto out;
+ }
+ if (atomicio(vwrite, wfd, asig,
+ strlen(asig)) != strlen(asig)) {
+ oerrno = errno;
+ error("Cannot write to %s: %s",
+ wfile, strerror(errno));
+ errno = oerrno;
+ r = SSH_ERR_SYSTEM_ERROR;
+ goto out;
+ }
+ if (!quiet) {
+ fprintf(stderr, "Write signature to %s\n",
+ wfile);
+ }
+ }
+ }
+ /* success */
+ r = 0;
+ out:
+ free(wfile);
+ free(prompt);
+ free(asig);
+ if (pin != NULL)
+ freezero(pin, strlen(pin));
+ sshbuf_free(abuf);
+ sshbuf_free(sigbuf);
+ if (wfd != -1)
+ close(wfd);
+ return r;
+}
+
+static int
+sig_sign(const char *keypath, const char *sig_namespace, int argc, char **argv)
+{
+ int i, fd = -1, r, ret = -1;
+ int agent_fd = -1;
+ struct sshkey *pubkey = NULL, *privkey = NULL, *signkey = NULL;
+ sshsig_signer *signer = NULL;
+
+ /* Check file arguments. */
+ for (i = 0; i < argc; i++) {
+ if (strcmp(argv[i], "-") != 0)
+ continue;
+ if (i > 0 || argc > 1)
+ fatal("Cannot sign mix of paths and standard input");
+ }
+
+ if ((r = sshkey_load_public(keypath, &pubkey, NULL)) != 0) {
+ error_r(r, "Couldn't load public key %s", keypath);
+ goto done;
+ }
+
+ if ((r = ssh_get_authentication_socket(&agent_fd)) != 0)
+ debug_r(r, "Couldn't get agent socket");
+ else {
+ if ((r = ssh_agent_has_key(agent_fd, pubkey)) == 0)
+ signer = agent_signer;
+ else
+ debug_r(r, "Couldn't find key in agent");
+ }
+
+ if (signer == NULL) {
+ /* Not using agent - try to load private key */
+ if ((privkey = load_sign_key(keypath, pubkey)) == NULL)
+ goto done;
+ signkey = privkey;
+ } else {
+ /* Will use key in agent */
+ signkey = pubkey;
+ }
+
+ if (argc == 0) {
+ if ((r = sign_one(signkey, "(stdin)", STDIN_FILENO,
+ sig_namespace, signer, &agent_fd)) != 0)
+ goto done;
+ } else {
+ for (i = 0; i < argc; i++) {
+ if (strcmp(argv[i], "-") == 0)
+ fd = STDIN_FILENO;
+ else if ((fd = open(argv[i], O_RDONLY)) == -1) {
+ error("Cannot open %s for signing: %s",
+ argv[i], strerror(errno));
+ goto done;
+ }
+ if ((r = sign_one(signkey, argv[i], fd, sig_namespace,
+ signer, &agent_fd)) != 0)
+ goto done;
+ if (fd != STDIN_FILENO)
+ close(fd);
+ fd = -1;
+ }
+ }
+
+ ret = 0;
+done:
+ if (fd != -1 && fd != STDIN_FILENO)
+ close(fd);
+ sshkey_free(pubkey);
+ sshkey_free(privkey);
+ return ret;
+}
+
+static int
+sig_process_opts(char * const *opts, size_t nopts, uint64_t *verify_timep,
+ int *print_pubkey)
+{
+ size_t i;
+ time_t now;
+
+ *verify_timep = 0;
+ *print_pubkey = 0;
+ for (i = 0; i < nopts; i++) {
+ if (strncasecmp(opts[i], "verify-time=", 12) == 0) {
+ if (parse_absolute_time(opts[i] + 12,
+ verify_timep) != 0 || *verify_timep == 0) {
+ error("Invalid \"verify-time\" option");
+ return SSH_ERR_INVALID_ARGUMENT;
+ }
+ } else if (print_pubkey &&
+ strcasecmp(opts[i], "print-pubkey") == 0) {
+ *print_pubkey = 1;
+ } else {
+ error("Invalid option \"%s\"", opts[i]);
+ return SSH_ERR_INVALID_ARGUMENT;
+ }
+ }
+ if (*verify_timep == 0) {
+ if ((now = time(NULL)) < 0) {
+ error("Time is before epoch");
+ return SSH_ERR_INVALID_ARGUMENT;
+ }
+ *verify_timep = (uint64_t)now;
+ }
+ return 0;
+}
+
+static int
+sig_verify(const char *signature, const char *sig_namespace,
+ const char *principal, const char *allowed_keys, const char *revoked_keys,
+ char * const *opts, size_t nopts)
+{
+ int r, ret = -1;
+ int print_pubkey = 0;
+ struct sshbuf *sigbuf = NULL, *abuf = NULL;
+ struct sshkey *sign_key = NULL;
+ char *fp = NULL;
+ struct sshkey_sig_details *sig_details = NULL;
+ uint64_t verify_time = 0;
+
+ if (sig_process_opts(opts, nopts, &verify_time, &print_pubkey) != 0)
+ goto done; /* error already logged */
+
+ memset(&sig_details, 0, sizeof(sig_details));
+ if ((r = sshbuf_load_file(signature, &abuf)) != 0) {
+ error_r(r, "Couldn't read signature file");
+ goto done;
+ }
+
+ if ((r = sshsig_dearmor(abuf, &sigbuf)) != 0) {
+ error_fr(r, "sshsig_armor");
+ goto done;
+ }
+ if ((r = sshsig_verify_fd(sigbuf, STDIN_FILENO, sig_namespace,
+ &sign_key, &sig_details)) != 0)
+ goto done; /* sshsig_verify() prints error */
+
+ if ((fp = sshkey_fingerprint(sign_key, fingerprint_hash,
+ SSH_FP_DEFAULT)) == NULL)
+ fatal_f("sshkey_fingerprint failed");
+ debug("Valid (unverified) signature from key %s", fp);
+ if (sig_details != NULL) {
+ debug2_f("signature details: counter = %u, flags = 0x%02x",
+ sig_details->sk_counter, sig_details->sk_flags);
+ }
+ free(fp);
+ fp = NULL;
+
+ if (revoked_keys != NULL) {
+ if ((r = sshkey_check_revoked(sign_key, revoked_keys)) != 0) {
+ debug3_fr(r, "sshkey_check_revoked");
+ goto done;
+ }
+ }
+
+ if (allowed_keys != NULL && (r = sshsig_check_allowed_keys(allowed_keys,
+ sign_key, principal, sig_namespace, verify_time)) != 0) {
+ debug3_fr(r, "sshsig_check_allowed_keys");
+ goto done;
+ }
+ /* success */
+ ret = 0;
+done:
+ if (!quiet) {
+ if (ret == 0) {
+ if ((fp = sshkey_fingerprint(sign_key, fingerprint_hash,
+ SSH_FP_DEFAULT)) == NULL)
+ fatal_f("sshkey_fingerprint failed");
+ if (principal == NULL) {
+ printf("Good \"%s\" signature with %s key %s\n",
+ sig_namespace, sshkey_type(sign_key), fp);
+
+ } else {
+ printf("Good \"%s\" signature for %s with %s key %s\n",
+ sig_namespace, principal,
+ sshkey_type(sign_key), fp);
+ }
+ } else {
+ printf("Could not verify signature.\n");
+ }
+ }
+ /* Print the signature key if requested */
+ if (ret == 0 && print_pubkey && sign_key != NULL) {
+ if ((r = sshkey_write(sign_key, stdout)) == 0)
+ fputc('\n', stdout);
+ else {
+ error_r(r, "Could not print public key.\n");
+ ret = -1;
+ }
+ }
+ sshbuf_free(sigbuf);
+ sshbuf_free(abuf);
+ sshkey_free(sign_key);
+ sshkey_sig_details_free(sig_details);
+ free(fp);
+ return ret;
+}
+
+static int
+sig_find_principals(const char *signature, const char *allowed_keys,
+ char * const *opts, size_t nopts)
+{
+ int r, ret = -1;
+ struct sshbuf *sigbuf = NULL, *abuf = NULL;
+ struct sshkey *sign_key = NULL;
+ char *principals = NULL, *cp, *tmp;
+ uint64_t verify_time = 0;
+
+ if (sig_process_opts(opts, nopts, &verify_time, NULL) != 0)
+ goto done; /* error already logged */
+
+ if ((r = sshbuf_load_file(signature, &abuf)) != 0) {
+ error_r(r, "Couldn't read signature file");
+ goto done;
+ }
+ if ((r = sshsig_dearmor(abuf, &sigbuf)) != 0) {
+ error_fr(r, "sshsig_armor");
+ goto done;
+ }
+ if ((r = sshsig_get_pubkey(sigbuf, &sign_key)) != 0) {
+ error_fr(r, "sshsig_get_pubkey");
+ goto done;
+ }
+ if ((r = sshsig_find_principals(allowed_keys, sign_key,
+ verify_time, &principals)) != 0) {
+ if (r != SSH_ERR_KEY_NOT_FOUND)
+ error_fr(r, "sshsig_find_principal");
+ goto done;
+ }
+ ret = 0;
+done:
+ if (ret == 0 ) {
+ /* Emit matching principals one per line */
+ tmp = principals;
+ while ((cp = strsep(&tmp, ",")) != NULL && *cp != '\0')
+ puts(cp);
+ } else {
+ fprintf(stderr, "No principal matched.\n");
+ }
+ sshbuf_free(sigbuf);
+ sshbuf_free(abuf);
+ sshkey_free(sign_key);
+ free(principals);
+ return ret;
+}
+
+static void
+do_moduli_gen(const char *out_file, char **opts, size_t nopts)
+{
+#ifdef WITH_OPENSSL
+ /* Moduli generation/screening */
+ u_int32_t memory = 0;
+ BIGNUM *start = NULL;
+ int moduli_bits = 0;
+ FILE *out;
+ size_t i;
+ const char *errstr;
+
+ /* Parse options */
+ for (i = 0; i < nopts; i++) {
+ if (strncmp(opts[i], "memory=", 7) == 0) {
+ memory = (u_int32_t)strtonum(opts[i]+7, 1,
+ UINT_MAX, &errstr);
+ if (errstr) {
+ fatal("Memory limit is %s: %s",
+ errstr, opts[i]+7);
+ }
+ } else if (strncmp(opts[i], "start=", 6) == 0) {
+ /* XXX - also compare length against bits */
+ if (BN_hex2bn(&start, opts[i]+6) == 0)
+ fatal("Invalid start point.");
+ } else if (strncmp(opts[i], "bits=", 5) == 0) {
+ moduli_bits = (int)strtonum(opts[i]+5, 1,
+ INT_MAX, &errstr);
+ if (errstr) {
+ fatal("Invalid number: %s (%s)",
+ opts[i]+12, errstr);
+ }
+ } else {
+ fatal("Option \"%s\" is unsupported for moduli "
+ "generation", opts[i]);
+ }
+ }
+
+ if ((out = fopen(out_file, "w")) == NULL) {
+ fatal("Couldn't open modulus candidate file \"%s\": %s",
+ out_file, strerror(errno));
+ }
+ setvbuf(out, NULL, _IOLBF, 0);
+
+ if (moduli_bits == 0)
+ moduli_bits = DEFAULT_BITS;
+ if (gen_candidates(out, memory, moduli_bits, start) != 0)
+ fatal("modulus candidate generation failed");
+#else /* WITH_OPENSSL */
+ fatal("Moduli generation is not supported");
+#endif /* WITH_OPENSSL */
+}
+
+static void
+do_moduli_screen(const char *out_file, char **opts, size_t nopts)
+{
+#ifdef WITH_OPENSSL
+ /* Moduli generation/screening */
+ char *checkpoint = NULL;
+ u_int32_t generator_wanted = 0;
+ unsigned long start_lineno = 0, lines_to_process = 0;
+ int prime_tests = 0;
+ FILE *out, *in = stdin;
+ size_t i;
+ const char *errstr;
+
+ /* Parse options */
+ for (i = 0; i < nopts; i++) {
+ if (strncmp(opts[i], "lines=", 6) == 0) {
+ lines_to_process = strtoul(opts[i]+6, NULL, 10);
+ } else if (strncmp(opts[i], "start-line=", 11) == 0) {
+ start_lineno = strtoul(opts[i]+11, NULL, 10);
+ } else if (strncmp(opts[i], "checkpoint=", 11) == 0) {
+ checkpoint = xstrdup(opts[i]+11);
+ } else if (strncmp(opts[i], "generator=", 10) == 0) {
+ generator_wanted = (u_int32_t)strtonum(
+ opts[i]+10, 1, UINT_MAX, &errstr);
+ if (errstr != NULL) {
+ fatal("Generator invalid: %s (%s)",
+ opts[i]+10, errstr);
+ }
+ } else if (strncmp(opts[i], "prime-tests=", 12) == 0) {
+ prime_tests = (int)strtonum(opts[i]+12, 1,
+ INT_MAX, &errstr);
+ if (errstr) {
+ fatal("Invalid number: %s (%s)",
+ opts[i]+12, errstr);
+ }
+ } else {
+ fatal("Option \"%s\" is unsupported for moduli "
+ "screening", opts[i]);
+ }
+ }
+
+ if (have_identity && strcmp(identity_file, "-") != 0) {
+ if ((in = fopen(identity_file, "r")) == NULL) {
+ fatal("Couldn't open modulus candidate "
+ "file \"%s\": %s", identity_file,
+ strerror(errno));
+ }
+ }
+
+ if ((out = fopen(out_file, "a")) == NULL) {
+ fatal("Couldn't open moduli file \"%s\": %s",
+ out_file, strerror(errno));
+ }
+ setvbuf(out, NULL, _IOLBF, 0);
+ if (prime_test(in, out, prime_tests == 0 ? 100 : prime_tests,
+ generator_wanted, checkpoint,
+ start_lineno, lines_to_process) != 0)
+ fatal("modulus screening failed");
+#else /* WITH_OPENSSL */
+ fatal("Moduli screening is not supported");
+#endif /* WITH_OPENSSL */
+}
+
+static char *
+private_key_passphrase(void)
+{
+ char *passphrase1, *passphrase2;
+
+ /* Ask for a passphrase (twice). */
+ if (identity_passphrase)
+ passphrase1 = xstrdup(identity_passphrase);
+ else if (identity_new_passphrase)
+ passphrase1 = xstrdup(identity_new_passphrase);
+ else {
+passphrase_again:
+ passphrase1 =
+ read_passphrase("Enter passphrase (empty for no "
+ "passphrase): ", RP_ALLOW_STDIN);
+ passphrase2 = read_passphrase("Enter same passphrase again: ",
+ RP_ALLOW_STDIN);
+ if (strcmp(passphrase1, passphrase2) != 0) {
+ /*
+ * The passphrases do not match. Clear them and
+ * retry.
+ */
+ freezero(passphrase1, strlen(passphrase1));
+ freezero(passphrase2, strlen(passphrase2));
+ printf("Passphrases do not match. Try again.\n");
+ goto passphrase_again;
+ }
+ /* Clear the other copy of the passphrase. */
+ freezero(passphrase2, strlen(passphrase2));
+ }
+ return passphrase1;
+}
+
+static const char *
+skip_ssh_url_preamble(const char *s)
+{
+ if (strncmp(s, "ssh://", 6) == 0)
+ return s + 6;
+ else if (strncmp(s, "ssh:", 4) == 0)
+ return s + 4;
+ return s;
+}
+
+static int
+do_download_sk(const char *skprovider, const char *device)
+{
+ struct sshkey **keys;
+ size_t nkeys, i;
+ int r, ret = -1;
+ char *fp, *pin = NULL, *pass = NULL, *path, *pubpath;
+ const char *ext;
+
+ if (skprovider == NULL)
+ fatal("Cannot download keys without provider");
+
+ pin = read_passphrase("Enter PIN for authenticator: ", RP_ALLOW_STDIN);
+ if (!quiet) {
+ printf("You may need to touch your authenticator "
+ "to authorize key download.\n");
+ }
+ if ((r = sshsk_load_resident(skprovider, device, pin,
+ &keys, &nkeys)) != 0) {
+ if (pin != NULL)
+ freezero(pin, strlen(pin));
+ error_r(r, "Unable to load resident keys");
+ return -1;
+ }
+ if (nkeys == 0)
+ logit("No keys to download");
+ if (pin != NULL)
+ freezero(pin, strlen(pin));
+
+ for (i = 0; i < nkeys; i++) {
+ if (keys[i]->type != KEY_ECDSA_SK &&
+ keys[i]->type != KEY_ED25519_SK) {
+ error("Unsupported key type %s (%d)",
+ sshkey_type(keys[i]), keys[i]->type);
+ continue;
+ }
+ if ((fp = sshkey_fingerprint(keys[i],
+ fingerprint_hash, SSH_FP_DEFAULT)) == NULL)
+ fatal_f("sshkey_fingerprint failed");
+ debug_f("key %zu: %s %s %s (flags 0x%02x)", i,
+ sshkey_type(keys[i]), fp, keys[i]->sk_application,
+ keys[i]->sk_flags);
+ ext = skip_ssh_url_preamble(keys[i]->sk_application);
+ xasprintf(&path, "id_%s_rk%s%s",
+ keys[i]->type == KEY_ECDSA_SK ? "ecdsa_sk" : "ed25519_sk",
+ *ext == '\0' ? "" : "_", ext);
+
+ /* If the file already exists, ask the user to confirm. */
+ if (!confirm_overwrite(path)) {
+ free(path);
+ break;
+ }
+
+ /* Save the key with the application string as the comment */
+ if (pass == NULL)
+ pass = private_key_passphrase();
+ if ((r = sshkey_save_private(keys[i], path, pass,
+ keys[i]->sk_application, private_key_format,
+ openssh_format_cipher, rounds)) != 0) {
+ error_r(r, "Saving key \"%s\" failed", path);
+ free(path);
+ break;
+ }
+ if (!quiet) {
+ printf("Saved %s key%s%s to %s\n",
+ sshkey_type(keys[i]),
+ *ext != '\0' ? " " : "",
+ *ext != '\0' ? keys[i]->sk_application : "",
+ path);
+ }
+
+ /* Save public key too */
+ xasprintf(&pubpath, "%s.pub", path);
+ free(path);
+ if ((r = sshkey_save_public(keys[i], pubpath,
+ keys[i]->sk_application)) != 0) {
+ error_r(r, "Saving public key \"%s\" failed", pubpath);
+ free(pubpath);
+ break;
+ }
+ free(pubpath);
+ }
+
+ if (i >= nkeys)
+ ret = 0; /* success */
+ if (pass != NULL)
+ freezero(pass, strlen(pass));
+ for (i = 0; i < nkeys; i++)
+ sshkey_free(keys[i]);
+ free(keys);
+ return ret;
+}
+
+static void
+save_attestation(struct sshbuf *attest, const char *path)
+{
+ mode_t omask;
+ int r;
+
+ if (path == NULL)
+ return; /* nothing to do */
+ if (attest == NULL || sshbuf_len(attest) == 0)
+ fatal("Enrollment did not return attestation data");
+ omask = umask(077);
+ r = sshbuf_write_file(path, attest);
+ umask(omask);
+ if (r != 0)
+ fatal_r(r, "Unable to write attestation data \"%s\"", path);
+ if (!quiet)
+ printf("Your FIDO attestation certificate has been saved in "
+ "%s\n", path);
+}
+
static void
usage(void)
{
fprintf(stderr,
- "usage: ssh-keygen [-q] [-b bits] [-t dsa | ecdsa | ed25519 | rsa]\n"
- " [-N new_passphrase] [-C comment] [-f output_keyfile]\n"
- " ssh-keygen -p [-P old_passphrase] [-N new_passphrase] [-f keyfile]\n"
- " ssh-keygen -i [-m key_format] [-f input_keyfile]\n"
- " ssh-keygen -e [-m key_format] [-f input_keyfile]\n"
+ "usage: ssh-keygen [-q] [-a rounds] [-b bits] [-C comment] [-f output_keyfile]\n"
+ " [-m format] [-N new_passphrase] [-O option]\n"
+ " [-t dsa | ecdsa | ecdsa-sk | ed25519 | ed25519-sk | rsa]\n"
+ " [-w provider] [-Z cipher]\n"
+ " ssh-keygen -p [-a rounds] [-f keyfile] [-m format] [-N new_passphrase]\n"
+ " [-P old_passphrase] [-Z cipher]\n"
+#ifdef WITH_OPENSSL
+ " ssh-keygen -i [-f input_keyfile] [-m key_format]\n"
+ " ssh-keygen -e [-f input_keyfile] [-m key_format]\n"
+#endif
" ssh-keygen -y [-f input_keyfile]\n"
- " ssh-keygen -c [-P passphrase] [-C comment] [-f keyfile]\n"
+ " ssh-keygen -c [-a rounds] [-C comment] [-f keyfile] [-P passphrase]\n"
" ssh-keygen -l [-v] [-E fingerprint_hash] [-f input_keyfile]\n"
" ssh-keygen -B [-f input_keyfile]\n");
#ifdef ENABLE_PKCS11
@@ -2401,23 +3140,28 @@ usage(void)
" ssh-keygen -D pkcs11\n");
#endif
fprintf(stderr,
- " ssh-keygen -F hostname [-f known_hosts_file] [-l]\n"
+ " ssh-keygen -F hostname [-lv] [-f known_hosts_file]\n"
" ssh-keygen -H [-f known_hosts_file]\n"
+ " ssh-keygen -K [-a rounds] [-w provider]\n"
" ssh-keygen -R hostname [-f known_hosts_file]\n"
- " ssh-keygen -r hostname [-f input_keyfile] [-g]\n"
+ " ssh-keygen -r hostname [-g] [-f input_keyfile]\n"
#ifdef WITH_OPENSSL
- " ssh-keygen -G output_file [-v] [-b bits] [-M memory] [-S start_point]\n"
- " ssh-keygen -T output_file -f input_file [-v] [-a rounds] [-J num_lines]\n"
- " [-j start_line] [-K checkpt] [-W generator]\n"
+ " ssh-keygen -M generate [-O option] output_file\n"
+ " ssh-keygen -M screen [-f input_file] [-O option] output_file\n"
#endif
- " ssh-keygen -s ca_key -I certificate_identity [-h] [-U]\n"
- " [-D pkcs11_provider] [-n principals] [-O option]\n"
- " [-V validity_interval] [-z serial_number] file ...\n"
+ " ssh-keygen -I certificate_identity -s ca_key [-hU] [-D pkcs11_provider]\n"
+ " [-n principals] [-O option] [-V validity_interval]\n"
+ " [-z serial_number] file ...\n"
" ssh-keygen -L [-f input_keyfile]\n"
- " ssh-keygen -A\n"
+ " ssh-keygen -A [-a rounds] [-f prefix_path]\n"
" ssh-keygen -k -f krl_file [-u] [-s ca_public] [-z version_number]\n"
" file ...\n"
- " ssh-keygen -Q -f krl_file file ...\n");
+ " ssh-keygen -Q [-l] -f krl_file [file ...]\n"
+ " ssh-keygen -Y find-principals -s signature_file -f allowed_signers_file\n"
+ " ssh-keygen -Y check-novalidate -n namespace -s signature_file\n"
+ " ssh-keygen -Y sign -f key_file -n namespace file ...\n"
+ " ssh-keygen -Y verify -f allowed_signers_file -I signer_identity\n"
+ " -n namespace -s signature_file [-r revocation_file]\n");
exit(1);
}
@@ -2427,59 +3171,64 @@ usage(void)
int
main(int argc, char **argv)
{
- char dotsshdir[PATH_MAX], comment[1024], *passphrase1, *passphrase2;
+ char comment[1024], *passphrase;
char *rr_hostname = NULL, *ep, *fp, *ra;
struct sshkey *private, *public;
struct passwd *pw;
- struct stat st;
- int r, opt, type, fd;
+ int r, opt, type;
+ int change_passphrase = 0, change_comment = 0, show_cert = 0;
+ int find_host = 0, delete_host = 0, hash_hosts = 0;
int gen_all_hostkeys = 0, gen_krl = 0, update_krl = 0, check_krl = 0;
- FILE *f;
+ int prefer_agent = 0, convert_to = 0, convert_from = 0;
+ int print_public = 0, print_generic = 0, cert_serial_autoinc = 0;
+ int do_gen_candidates = 0, do_screen_candidates = 0, download_sk = 0;
+ unsigned long long cert_serial = 0;
+ char *identity_comment = NULL, *ca_key_path = NULL, **opts = NULL;
+ char *sk_application = NULL, *sk_device = NULL, *sk_user = NULL;
+ char *sk_attestation_path = NULL;
+ struct sshbuf *challenge = NULL, *attest = NULL;
+ size_t i, nopts = 0;
+ u_int32_t bits = 0;
+ uint8_t sk_flags = SSH_SK_USER_PRESENCE_REQD;
const char *errstr;
-#ifdef WITH_OPENSSL
- /* Moduli generation/screening */
- char out_file[PATH_MAX], *checkpoint = NULL;
- u_int32_t memory = 0, generator_wanted = 0;
- int do_gen_candidates = 0, do_screen_candidates = 0;
- unsigned long start_lineno = 0, lines_to_process = 0;
- BIGNUM *start = NULL;
-#endif
+ int log_level = SYSLOG_LEVEL_INFO;
+ char *sign_op = NULL;
extern int optind;
extern char *optarg;
- ssh_malloc_init(); /* must be called before any mallocs */
/* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */
sanitise_stdfd();
__progname = ssh_get_progname(argv[0]);
-#ifdef WITH_OPENSSL
- OpenSSL_add_all_algorithms();
-#endif
- log_init(argv[0], SYSLOG_LEVEL_INFO, SYSLOG_FACILITY_USER, 1);
-
seed_rng();
+ log_init(argv[0], SYSLOG_LEVEL_INFO, SYSLOG_FACILITY_USER, 1);
+
msetlocale();
/* we need this for the home * directory. */
pw = getpwuid(getuid());
if (!pw)
fatal("No user exists for uid %lu", (u_long)getuid());
- if (gethostname(hostname, sizeof(hostname)) < 0)
+ pw = pwcopy(pw);
+ if (gethostname(hostname, sizeof(hostname)) == -1)
fatal("gethostname: %s", strerror(errno));
- /* Remaining characters: Ydw */
- while ((opt = getopt(argc, argv, "ABHLQUXceghiklopquvxy"
- "C:D:E:F:G:I:J:K:M:N:O:P:R:S:T:V:W:Z:"
- "a:b:f:g:j:m:n:r:s:t:z:")) != -1) {
+ sk_provider = getenv("SSH_SK_PROVIDER");
+
+ /* Remaining characters: dGjJSTWx */
+ while ((opt = getopt(argc, argv, "ABHKLQUXceghiklopquvy"
+ "C:D:E:F:I:M:N:O:P:R:V:Y:Z:"
+ "a:b:f:g:m:n:r:s:t:w:z:")) != -1) {
switch (opt) {
case 'A':
gen_all_hostkeys = 1;
break;
case 'b':
- bits = (u_int32_t)strtonum(optarg, 10, 32768, &errstr);
+ bits = (u_int32_t)strtonum(optarg, 1, UINT32_MAX,
+ &errstr);
if (errstr)
fatal("Bits has bad value %s (%s)",
optarg, errstr);
@@ -2520,11 +3269,12 @@ main(int argc, char **argv)
}
if (strcasecmp(optarg, "PKCS8") == 0) {
convert_format = FMT_PKCS8;
+ private_key_format = SSHKEY_PRIVATE_PKCS8;
break;
}
if (strcasecmp(optarg, "PEM") == 0) {
convert_format = FMT_PEM;
- use_new_format = 0;
+ private_key_format = SSHKEY_PRIVATE_PEM;
break;
}
fatal("Unsupported conversion format \"%s\"", optarg);
@@ -2549,6 +3299,9 @@ main(int argc, char **argv)
case 'g':
print_generic = 1;
break;
+ case 'K':
+ download_sk = 1;
+ break;
case 'P':
identity_passphrase = optarg;
break;
@@ -2559,10 +3312,15 @@ main(int argc, char **argv)
check_krl = 1;
break;
case 'O':
- add_cert_option(optarg);
+ opts = xrecallocarray(opts, nopts, nopts + 1,
+ sizeof(*opts));
+ opts[nopts++] = xstrdup(optarg);
break;
case 'Z':
- new_format_cipher = optarg;
+ openssh_format_cipher = optarg;
+ if (cipher_by_name(openssh_format_cipher) == NULL)
+ fatal("Invalid OpenSSH-format cipher '%s'",
+ openssh_format_cipher);
break;
case 'C':
identity_comment = optarg;
@@ -2571,7 +3329,6 @@ main(int argc, char **argv)
quiet = 1;
break;
case 'e':
- case 'x':
/* export key */
convert_to = 1;
break;
@@ -2626,75 +3383,122 @@ main(int argc, char **argv)
case 'V':
parse_cert_times(optarg);
break;
+ case 'Y':
+ sign_op = optarg;
+ break;
+ case 'w':
+ sk_provider = optarg;
+ break;
case 'z':
errno = 0;
+ if (*optarg == '+') {
+ cert_serial_autoinc = 1;
+ optarg++;
+ }
cert_serial = strtoull(optarg, &ep, 10);
if (*optarg < '0' || *optarg > '9' || *ep != '\0' ||
(errno == ERANGE && cert_serial == ULLONG_MAX))
fatal("Invalid serial number \"%s\"", optarg);
break;
-#ifdef WITH_OPENSSL
- /* Moduli generation/screening */
- case 'G':
- do_gen_candidates = 1;
- if (strlcpy(out_file, optarg, sizeof(out_file)) >=
- sizeof(out_file))
- fatal("Output filename too long");
- break;
- case 'J':
- lines_to_process = strtoul(optarg, NULL, 10);
- break;
- case 'j':
- start_lineno = strtoul(optarg, NULL, 10);
- break;
- case 'K':
- if (strlen(optarg) >= PATH_MAX)
- fatal("Checkpoint filename too long");
- checkpoint = xstrdup(optarg);
- break;
case 'M':
- memory = (u_int32_t)strtonum(optarg, 1, UINT_MAX,
- &errstr);
- if (errstr)
- fatal("Memory limit is %s: %s", errstr, optarg);
+ if (strcmp(optarg, "generate") == 0)
+ do_gen_candidates = 1;
+ else if (strcmp(optarg, "screen") == 0)
+ do_screen_candidates = 1;
+ else
+ fatal("Unsupported moduli option %s", optarg);
break;
- case 'S':
- /* XXX - also compare length against bits */
- if (BN_hex2bn(&start, optarg) == 0)
- fatal("Invalid start point.");
- break;
- case 'T':
- do_screen_candidates = 1;
- if (strlcpy(out_file, optarg, sizeof(out_file)) >=
- sizeof(out_file))
- fatal("Output filename too long");
- break;
- case 'W':
- generator_wanted = (u_int32_t)strtonum(optarg, 1,
- UINT_MAX, &errstr);
- if (errstr != NULL)
- fatal("Desired generator invalid: %s (%s)",
- optarg, errstr);
- break;
-#endif /* WITH_OPENSSL */
case '?':
default:
usage();
}
}
+#ifdef ENABLE_SK_INTERNAL
+ if (sk_provider == NULL)
+ sk_provider = "internal";
+#endif
+
/* reinit */
log_init(argv[0], log_level, SYSLOG_FACILITY_USER, 1);
argv += optind;
argc -= optind;
+ if (sign_op != NULL) {
+ if (strncmp(sign_op, "find-principals", 15) == 0) {
+ if (ca_key_path == NULL) {
+ error("Too few arguments for find-principals:"
+ "missing signature file");
+ exit(1);
+ }
+ if (!have_identity) {
+ error("Too few arguments for find-principals:"
+ "missing allowed keys file");
+ exit(1);
+ }
+ return sig_find_principals(ca_key_path, identity_file,
+ opts, nopts);
+ } else if (strncmp(sign_op, "sign", 4) == 0) {
+ if (cert_principals == NULL ||
+ *cert_principals == '\0') {
+ error("Too few arguments for sign: "
+ "missing namespace");
+ exit(1);
+ }
+ if (!have_identity) {
+ error("Too few arguments for sign: "
+ "missing key");
+ exit(1);
+ }
+ return sig_sign(identity_file, cert_principals,
+ argc, argv);
+ } else if (strncmp(sign_op, "check-novalidate", 16) == 0) {
+ if (ca_key_path == NULL) {
+ error("Too few arguments for check-novalidate: "
+ "missing signature file");
+ exit(1);
+ }
+ return sig_verify(ca_key_path, cert_principals,
+ NULL, NULL, NULL, opts, nopts);
+ } else if (strncmp(sign_op, "verify", 6) == 0) {
+ if (cert_principals == NULL ||
+ *cert_principals == '\0') {
+ error("Too few arguments for verify: "
+ "missing namespace");
+ exit(1);
+ }
+ if (ca_key_path == NULL) {
+ error("Too few arguments for verify: "
+ "missing signature file");
+ exit(1);
+ }
+ if (!have_identity) {
+ error("Too few arguments for sign: "
+ "missing allowed keys file");
+ exit(1);
+ }
+ if (cert_key_id == NULL) {
+ error("Too few arguments for verify: "
+ "missing principal ID");
+ exit(1);
+ }
+ return sig_verify(ca_key_path, cert_principals,
+ cert_key_id, identity_file, rr_hostname,
+ opts, nopts);
+ }
+ error("Unsupported operation for -Y: \"%s\"", sign_op);
+ usage();
+ /* NOTREACHED */
+ }
+
if (ca_key_path != NULL) {
if (argc < 1 && !gen_krl) {
error("Too few arguments.");
usage();
}
- } else if (argc > 0 && !gen_krl && !check_krl) {
+ } else if (argc > 0 && !gen_krl && !check_krl &&
+ !do_gen_candidates && !do_screen_candidates) {
error("Too many arguments.");
usage();
}
@@ -2707,106 +3511,104 @@ main(int argc, char **argv)
usage();
}
if (gen_krl) {
- do_gen_krl(pw, update_krl, argc, argv);
+ do_gen_krl(pw, update_krl, ca_key_path,
+ cert_serial, identity_comment, argc, argv);
return (0);
}
if (check_krl) {
- do_check_krl(pw, argc, argv);
+ do_check_krl(pw, print_fingerprint, argc, argv);
return (0);
}
if (ca_key_path != NULL) {
if (cert_key_id == NULL)
fatal("Must specify key id (-I) when certifying");
- do_ca_sign(pw, argc, argv);
+ for (i = 0; i < nopts; i++)
+ add_cert_option(opts[i]);
+ do_ca_sign(pw, ca_key_path, prefer_agent,
+ cert_serial, cert_serial_autoinc, argc, argv);
}
if (show_cert)
do_show_cert(pw);
- if (delete_host || hash_hosts || find_host)
- do_known_hosts(pw, rr_hostname);
+ if (delete_host || hash_hosts || find_host) {
+ do_known_hosts(pw, rr_hostname, find_host,
+ delete_host, hash_hosts);
+ }
if (pkcs11provider != NULL)
do_download(pw);
+ if (download_sk) {
+ for (i = 0; i < nopts; i++) {
+ if (strncasecmp(opts[i], "device=", 7) == 0) {
+ sk_device = xstrdup(opts[i] + 7);
+ } else {
+ fatal("Option \"%s\" is unsupported for "
+ "FIDO authenticator download", opts[i]);
+ }
+ }
+ return do_download_sk(sk_provider, sk_device);
+ }
if (print_fingerprint || print_bubblebabble)
do_fingerprint(pw);
if (change_passphrase)
do_change_passphrase(pw);
if (change_comment)
- do_change_comment(pw);
+ do_change_comment(pw, identity_comment);
#ifdef WITH_OPENSSL
if (convert_to)
do_convert_to(pw);
if (convert_from)
do_convert_from(pw);
-#endif
+#else /* WITH_OPENSSL */
+ if (convert_to || convert_from)
+ fatal("key conversion disabled at compile time");
+#endif /* WITH_OPENSSL */
if (print_public)
do_print_public(pw);
if (rr_hostname != NULL) {
unsigned int n = 0;
if (have_identity) {
- n = do_print_resource_record(pw,
- identity_file, rr_hostname);
+ n = do_print_resource_record(pw, identity_file,
+ rr_hostname, print_generic);
if (n == 0)
fatal("%s: %s", identity_file, strerror(errno));
exit(0);
} else {
n += do_print_resource_record(pw,
- _PATH_HOST_RSA_KEY_FILE, rr_hostname);
+ _PATH_HOST_RSA_KEY_FILE, rr_hostname,
+ print_generic);
n += do_print_resource_record(pw,
- _PATH_HOST_DSA_KEY_FILE, rr_hostname);
+ _PATH_HOST_DSA_KEY_FILE, rr_hostname,
+ print_generic);
n += do_print_resource_record(pw,
- _PATH_HOST_ECDSA_KEY_FILE, rr_hostname);
+ _PATH_HOST_ECDSA_KEY_FILE, rr_hostname,
+ print_generic);
n += do_print_resource_record(pw,
- _PATH_HOST_ED25519_KEY_FILE, rr_hostname);
+ _PATH_HOST_ED25519_KEY_FILE, rr_hostname,
+ print_generic);
n += do_print_resource_record(pw,
- _PATH_HOST_XMSS_KEY_FILE, rr_hostname);
+ _PATH_HOST_XMSS_KEY_FILE, rr_hostname,
+ print_generic);
if (n == 0)
fatal("no keys found.");
exit(0);
}
}
-#ifdef WITH_OPENSSL
+ if (do_gen_candidates || do_screen_candidates) {
+ if (argc <= 0)
+ fatal("No output file specified");
+ else if (argc > 1)
+ fatal("Too many output files specified");
+ }
if (do_gen_candidates) {
- FILE *out = fopen(out_file, "w");
-
- if (out == NULL) {
- error("Couldn't open modulus candidate file \"%s\": %s",
- out_file, strerror(errno));
- return (1);
- }
- if (bits == 0)
- bits = DEFAULT_BITS;
- if (gen_candidates(out, memory, bits, start) != 0)
- fatal("modulus candidate generation failed");
-
- return (0);
+ do_moduli_gen(argv[0], opts, nopts);
+ return 0;
}
-
if (do_screen_candidates) {
- FILE *in;
- FILE *out = fopen(out_file, "a");
-
- if (have_identity && strcmp(identity_file, "-") != 0) {
- if ((in = fopen(identity_file, "r")) == NULL) {
- fatal("Couldn't open modulus candidate "
- "file \"%s\": %s", identity_file,
- strerror(errno));
- }
- } else
- in = stdin;
-
- if (out == NULL) {
- fatal("Couldn't open moduli file \"%s\": %s",
- out_file, strerror(errno));
- }
- if (prime_test(in, out, rounds == 0 ? 100 : rounds,
- generator_wanted, checkpoint,
- start_lineno, lines_to_process) != 0)
- fatal("modulus screening failed");
- return (0);
+ do_moduli_screen(argv[0], opts, nopts);
+ return 0;
}
-#endif
if (gen_all_hostkeys) {
do_gen_all_hostkeys(pw);
@@ -2822,69 +3624,105 @@ main(int argc, char **argv)
if (!quiet)
printf("Generating public/private %s key pair.\n",
key_type_name);
- if ((r = sshkey_generate(type, bits, &private)) != 0)
- fatal("sshkey_generate failed");
+ switch (type) {
+ case KEY_ECDSA_SK:
+ case KEY_ED25519_SK:
+ for (i = 0; i < nopts; i++) {
+ if (strcasecmp(opts[i], "no-touch-required") == 0) {
+ sk_flags &= ~SSH_SK_USER_PRESENCE_REQD;
+ } else if (strcasecmp(opts[i], "verify-required") == 0) {
+ sk_flags |= SSH_SK_USER_VERIFICATION_REQD;
+ } else if (strcasecmp(opts[i], "resident") == 0) {
+ sk_flags |= SSH_SK_RESIDENT_KEY;
+ } else if (strncasecmp(opts[i], "device=", 7) == 0) {
+ sk_device = xstrdup(opts[i] + 7);
+ } else if (strncasecmp(opts[i], "user=", 5) == 0) {
+ sk_user = xstrdup(opts[i] + 5);
+ } else if (strncasecmp(opts[i], "challenge=", 10) == 0) {
+ if ((r = sshbuf_load_file(opts[i] + 10,
+ &challenge)) != 0) {
+ fatal_r(r, "Unable to load FIDO "
+ "enrollment challenge \"%s\"",
+ opts[i] + 10);
+ }
+ } else if (strncasecmp(opts[i],
+ "write-attestation=", 18) == 0) {
+ sk_attestation_path = opts[i] + 18;
+ } else if (strncasecmp(opts[i],
+ "application=", 12) == 0) {
+ sk_application = xstrdup(opts[i] + 12);
+ if (strncmp(sk_application, "ssh:", 4) != 0) {
+ fatal("FIDO application string must "
+ "begin with \"ssh:\"");
+ }
+ } else {
+ fatal("Option \"%s\" is unsupported for "
+ "FIDO authenticator enrollment", opts[i]);
+ }
+ }
+ if (!quiet) {
+ printf("You may need to touch your authenticator "
+ "to authorize key generation.\n");
+ }
+ if ((attest = sshbuf_new()) == NULL)
+ fatal("sshbuf_new failed");
+ if ((sk_flags &
+ (SSH_SK_USER_VERIFICATION_REQD|SSH_SK_RESIDENT_KEY))) {
+ passphrase = read_passphrase("Enter PIN for "
+ "authenticator: ", RP_ALLOW_STDIN);
+ } else {
+ passphrase = NULL;
+ }
+ for (i = 0 ; ; i++) {
+ fflush(stdout);
+ r = sshsk_enroll(type, sk_provider, sk_device,
+ sk_application == NULL ? "ssh:" : sk_application,
+ sk_user, sk_flags, passphrase, challenge,
+ &private, attest);
+ if (r == 0)
+ break;
+ if (r != SSH_ERR_KEY_WRONG_PASSPHRASE)
+ fatal_r(r, "Key enrollment failed");
+ else if (passphrase != NULL) {
+ error("PIN incorrect");
+ freezero(passphrase, strlen(passphrase));
+ passphrase = NULL;
+ }
+ if (i >= 3)
+ fatal("Too many incorrect PINs");
+ passphrase = read_passphrase("Enter PIN for "
+ "authenticator: ", RP_ALLOW_STDIN);
+ if (!quiet) {
+ printf("You may need to touch your "
+ "authenticator (again) to authorize "
+ "key generation.\n");
+ }
+ }
+ if (passphrase != NULL) {
+ freezero(passphrase, strlen(passphrase));
+ passphrase = NULL;
+ }
+ break;
+ default:
+ if ((r = sshkey_generate(type, bits, &private)) != 0)
+ fatal("sshkey_generate failed");
+ break;
+ }
if ((r = sshkey_from_private(private, &public)) != 0)
- fatal("sshkey_from_private failed: %s\n", ssh_err(r));
+ fatal_r(r, "sshkey_from_private");
if (!have_identity)
ask_filename(pw, "Enter file in which to save the key");
/* Create ~/.ssh directory if it doesn't already exist. */
- snprintf(dotsshdir, sizeof dotsshdir, "%s/%s",
- pw->pw_dir, _PATH_SSH_USER_DIR);
- if (strstr(identity_file, dotsshdir) != NULL) {
- if (stat(dotsshdir, &st) < 0) {
- if (errno != ENOENT) {
- error("Could not stat %s: %s", dotsshdir,
- strerror(errno));
- } else if (mkdir(dotsshdir, 0700) < 0) {
- error("Could not create directory '%s': %s",
- dotsshdir, strerror(errno));
- } else if (!quiet)
- printf("Created directory '%s'.\n", dotsshdir);
- }
- }
+ hostfile_create_user_ssh_dir(identity_file, !quiet);
+
/* If the file already exists, ask the user to confirm. */
- if (stat(identity_file, &st) >= 0) {
- char yesno[3];
- printf("%s already exists.\n", identity_file);
- printf("Overwrite (y/n)? ");
- fflush(stdout);
- if (fgets(yesno, sizeof(yesno), stdin) == NULL)
- exit(1);
- if (yesno[0] != 'y' && yesno[0] != 'Y')
- exit(1);
- }
- /* Ask for a passphrase (twice). */
- if (identity_passphrase)
- passphrase1 = xstrdup(identity_passphrase);
- else if (identity_new_passphrase)
- passphrase1 = xstrdup(identity_new_passphrase);
- else {
-passphrase_again:
- passphrase1 =
- read_passphrase("Enter passphrase (empty for no "
- "passphrase): ", RP_ALLOW_STDIN);
- passphrase2 = read_passphrase("Enter same passphrase again: ",
- RP_ALLOW_STDIN);
- if (strcmp(passphrase1, passphrase2) != 0) {
- /*
- * The passphrases do not match. Clear them and
- * retry.
- */
- explicit_bzero(passphrase1, strlen(passphrase1));
- explicit_bzero(passphrase2, strlen(passphrase2));
- free(passphrase1);
- free(passphrase2);
- printf("Passphrases do not match. Try again.\n");
- goto passphrase_again;
- }
- /* Clear the other copy of the passphrase. */
- explicit_bzero(passphrase2, strlen(passphrase2));
- free(passphrase2);
- }
+ if (!confirm_overwrite(identity_file))
+ exit(1);
+ /* Determine the passphrase for the private key */
+ passphrase = private_key_passphrase();
if (identity_comment) {
strlcpy(comment, identity_comment, sizeof(comment));
} else {
@@ -2893,35 +3731,23 @@ passphrase_again:
}
/* Save the key with the given passphrase and comment. */
- if ((r = sshkey_save_private(private, identity_file, passphrase1,
- comment, use_new_format, new_format_cipher, rounds)) != 0) {
- error("Saving key \"%s\" failed: %s",
- identity_file, ssh_err(r));
- explicit_bzero(passphrase1, strlen(passphrase1));
- free(passphrase1);
+ if ((r = sshkey_save_private(private, identity_file, passphrase,
+ comment, private_key_format, openssh_format_cipher, rounds)) != 0) {
+ error_r(r, "Saving key \"%s\" failed", identity_file);
+ freezero(passphrase, strlen(passphrase));
exit(1);
}
- /* Clear the passphrase. */
- explicit_bzero(passphrase1, strlen(passphrase1));
- free(passphrase1);
-
- /* Clear the private key and the random number generator. */
+ freezero(passphrase, strlen(passphrase));
sshkey_free(private);
- if (!quiet)
- printf("Your identification has been saved in %s.\n", identity_file);
+ if (!quiet) {
+ printf("Your identification has been saved in %s\n",
+ identity_file);
+ }
strlcat(identity_file, ".pub", sizeof(identity_file));
- if ((fd = open(identity_file, O_WRONLY|O_CREAT|O_TRUNC, 0644)) == -1)
- fatal("Unable to save public key to %s: %s",
- identity_file, strerror(errno));
- if ((f = fdopen(fd, "w")) == NULL)
- fatal("fdopen %s failed: %s", identity_file, strerror(errno));
- if ((r = sshkey_write(public, f)) != 0)
- error("write key failed: %s", ssh_err(r));
- fprintf(f, " %s\n", comment);
- if (ferror(f) || fclose(f) != 0)
- fatal("write public failed: %s", strerror(errno));
+ if ((r = sshkey_save_public(public, identity_file, comment)) != 0)
+ fatal_r(r, "Unable to save public key to %s", identity_file);
if (!quiet) {
fp = sshkey_fingerprint(public, fingerprint_hash,
@@ -2930,7 +3756,7 @@ passphrase_again:
SSH_FP_RANDOMART);
if (fp == NULL || ra == NULL)
fatal("sshkey_fingerprint failed");
- printf("Your public key has been saved in %s.\n",
+ printf("Your public key has been saved in %s\n",
identity_file);
printf("The key fingerprint is:\n");
printf("%s %s\n", fp, comment);
@@ -2940,6 +3766,11 @@ passphrase_again:
free(fp);
}
+ if (sk_attestation_path != NULL)
+ save_attestation(attest, sk_attestation_path);
+
+ sshbuf_free(attest);
sshkey_free(public);
+
exit(0);
}
diff --git a/crypto/openssh/ssh-keyscan.1 b/crypto/openssh/ssh-keyscan.1
index f3d7a4078f53..f9df75d42f1a 100644
--- a/crypto/openssh/ssh-keyscan.1
+++ b/crypto/openssh/ssh-keyscan.1
@@ -1,4 +1,4 @@
-.\" $OpenBSD: ssh-keyscan.1,v 1.44 2018/03/05 07:03:18 jmc Exp $
+.\" $OpenBSD: ssh-keyscan.1,v 1.45 2019/11/30 07:07:59 jmc Exp $
.\"
.\" Copyright 1995, 1996 by David Mazieres <dm@lcs.mit.edu>.
.\"
@@ -6,12 +6,12 @@
.\" permitted provided that due credit is given to the author and the
.\" OpenBSD project by leaving this copyright notice intact.
.\"
-.Dd $Mdocdate: March 5 2018 $
+.Dd $Mdocdate: November 30 2019 $
.Dt SSH-KEYSCAN 1
.Os
.Sh NAME
.Nm ssh-keyscan
-.Nd gather SSH public keys
+.Nd gather SSH public keys from servers
.Sh SYNOPSIS
.Nm ssh-keyscan
.Op Fl 46cDHv
diff --git a/crypto/openssh/ssh-keyscan.c b/crypto/openssh/ssh-keyscan.c
index 38b1c548be3e..7abbcbff5d00 100644
--- a/crypto/openssh/ssh-keyscan.c
+++ b/crypto/openssh/ssh-keyscan.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssh-keyscan.c,v 1.120 2018/06/06 18:29:18 markus Exp $ */
+/* $OpenBSD: ssh-keyscan.c,v 1.139 2021/01/27 09:26:54 djm Exp $ */
/*
* Copyright 1995, 1996 by David Mazieres <dm@lcs.mit.edu>.
*
@@ -19,7 +19,9 @@
#include <netinet/in.h>
#include <arpa/inet.h>
+#ifdef WITH_OPENSSL
#include <openssl/bn.h>
+#endif
#include <netdb.h>
#include <errno.h>
@@ -59,17 +61,21 @@ int ssh_port = SSH_DEFAULT_PORT;
#define KT_ECDSA (1<<2)
#define KT_ED25519 (1<<3)
#define KT_XMSS (1<<4)
+#define KT_ECDSA_SK (1<<5)
+#define KT_ED25519_SK (1<<6)
#define KT_MIN KT_DSA
-#define KT_MAX KT_XMSS
+#define KT_MAX KT_ED25519_SK
int get_cert = 0;
-int get_keytypes = KT_RSA|KT_ECDSA|KT_ED25519;
+int get_keytypes = KT_RSA|KT_ECDSA|KT_ED25519|KT_ECDSA_SK|KT_ED25519_SK;
int hash_hosts = 0; /* Hash hostname on output */
int print_sshfp = 0; /* Print SSHFP records instead of known_hosts */
+int found_one = 0; /* Successfully found a key */
+
#define MAXMAXFD 256
/* The number of seconds after which to give up on a TCP connection */
@@ -83,8 +89,6 @@ fd_set *read_wait;
size_t read_wait_nfdset;
int ncon;
-struct ssh *active_state = NULL; /* XXX needed for linking */
-
/*
* Keep a connection structure for each file descriptor. The state
* associated with file descriptor n is held in fdcon[n].
@@ -122,7 +126,7 @@ fdlim_get(int hard)
#if defined(HAVE_GETRLIMIT) && defined(RLIMIT_NOFILE)
struct rlimit rlfd;
- if (getrlimit(RLIMIT_NOFILE, &rlfd) < 0)
+ if (getrlimit(RLIMIT_NOFILE, &rlfd) == -1)
return (-1);
if ((hard ? rlfd.rlim_max : rlfd.rlim_cur) == RLIM_INFINITY)
return SSH_SYSFDMAX;
@@ -143,10 +147,10 @@ fdlim_set(int lim)
if (lim <= 0)
return (-1);
#if defined(HAVE_SETRLIMIT) && defined(RLIMIT_NOFILE)
- if (getrlimit(RLIMIT_NOFILE, &rlfd) < 0)
+ if (getrlimit(RLIMIT_NOFILE, &rlfd) == -1)
return (-1);
rlfd.rlim_cur = lim;
- if (setrlimit(RLIMIT_NOFILE, &rlfd) < 0)
+ if (setrlimit(RLIMIT_NOFILE, &rlfd) == -1)
return (-1);
#elif defined (HAVE_SETDTABLESIZE)
setdtablesize(lim);
@@ -233,7 +237,12 @@ keygrab_ssh2(con *c)
break;
case KT_RSA:
myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = get_cert ?
- "ssh-rsa-cert-v01@openssh.com" : "ssh-rsa";
+ "rsa-sha2-512-cert-v01@openssh.com,"
+ "rsa-sha2-256-cert-v01@openssh.com,"
+ "ssh-rsa-cert-v01@openssh.com" :
+ "rsa-sha2-512,"
+ "rsa-sha2-256,"
+ "ssh-rsa";
break;
case KT_ED25519:
myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = get_cert ?
@@ -252,6 +261,16 @@ keygrab_ssh2(con *c)
"ecdsa-sha2-nistp384,"
"ecdsa-sha2-nistp521";
break;
+ case KT_ECDSA_SK:
+ myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = get_cert ?
+ "sk-ecdsa-sha2-nistp256-cert-v01@openssh.com" :
+ "sk-ecdsa-sha2-nistp256@openssh.com";
+ break;
+ case KT_ED25519_SK:
+ myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = get_cert ?
+ "sk-ssh-ed25519-cert-v01@openssh.com" :
+ "sk-ssh-ed25519@openssh.com";
+ break;
default:
fatal("unknown key type %d", c->c_keytype);
break;
@@ -262,18 +281,19 @@ keygrab_ssh2(con *c)
exit(1);
}
#ifdef WITH_OPENSSL
- c->c_ssh->kex->kex[KEX_DH_GRP1_SHA1] = kexdh_client;
- c->c_ssh->kex->kex[KEX_DH_GRP14_SHA1] = kexdh_client;
- c->c_ssh->kex->kex[KEX_DH_GRP14_SHA256] = kexdh_client;
- c->c_ssh->kex->kex[KEX_DH_GRP16_SHA512] = kexdh_client;
- c->c_ssh->kex->kex[KEX_DH_GRP18_SHA512] = kexdh_client;
+ c->c_ssh->kex->kex[KEX_DH_GRP1_SHA1] = kex_gen_client;
+ c->c_ssh->kex->kex[KEX_DH_GRP14_SHA1] = kex_gen_client;
+ c->c_ssh->kex->kex[KEX_DH_GRP14_SHA256] = kex_gen_client;
+ c->c_ssh->kex->kex[KEX_DH_GRP16_SHA512] = kex_gen_client;
+ c->c_ssh->kex->kex[KEX_DH_GRP18_SHA512] = kex_gen_client;
c->c_ssh->kex->kex[KEX_DH_GEX_SHA1] = kexgex_client;
c->c_ssh->kex->kex[KEX_DH_GEX_SHA256] = kexgex_client;
# ifdef OPENSSL_HAS_ECC
- c->c_ssh->kex->kex[KEX_ECDH_SHA2] = kexecdh_client;
+ c->c_ssh->kex->kex[KEX_ECDH_SHA2] = kex_gen_client;
# endif
#endif
- c->c_ssh->kex->kex[KEX_C25519_SHA256] = kexc25519_client;
+ c->c_ssh->kex->kex[KEX_C25519_SHA256] = kex_gen_client;
+ c->c_ssh->kex->kex[KEX_KEM_SNTRUP761X25519_SHA512] = kex_gen_client;
ssh_set_verify_host_key_callback(c->c_ssh, key_print_wrapper);
/*
* do the key-exchange until an error occurs or until
@@ -288,6 +308,8 @@ keyprint_one(const char *host, struct sshkey *key)
char *hostport;
const char *known_host, *hashed;
+ found_one = 1;
+
if (print_sshfp) {
export_dns_rr(host, key, stdout, 0);
return;
@@ -340,13 +362,13 @@ tcpconnect(char *host)
}
for (ai = aitop; ai; ai = ai->ai_next) {
s = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
- if (s < 0) {
+ if (s == -1) {
error("socket: %s", strerror(errno));
continue;
}
if (set_nonblock(s) == -1)
- fatal("%s: set_nonblock(%d)", __func__, s);
- if (connect(s, ai->ai_addr, ai->ai_addrlen) < 0 &&
+ fatal_f("set_nonblock(%d)", s);
+ if (connect(s, ai->ai_addr, ai->ai_addrlen) == -1 &&
errno != EINPROGRESS)
error("connect (`%s'): %s", host, strerror(errno));
else
@@ -379,7 +401,7 @@ conalloc(char *iname, char *oname, int keytype)
if (fdcon[s].c_status)
fatal("conalloc: attempt to reuse fdno %d", s);
- debug3("%s: oname %s kt %d", __func__, oname, keytype);
+ debug3_f("oname %s kt %d", oname, keytype);
fdcon[s].c_fd = s;
fdcon[s].c_status = CS_CON;
fdcon[s].c_namebase = namebase;
@@ -500,11 +522,10 @@ congreet(int s)
fatal("ssh_packet_set_connection failed");
ssh_packet_set_timeout(c->c_ssh, timeout, 1);
ssh_set_app_data(c->c_ssh, c); /* back link */
+ c->c_ssh->compat = 0;
if (sscanf(buf, "SSH-%d.%d-%[^\n]\n",
&remote_major, &remote_minor, remote_version) == 3)
- c->c_ssh->compat = compat_datafellows(remote_version);
- else
- c->c_ssh->compat = 0;
+ compat_banner(c->c_ssh, remote_version);
if (!ssh2_capable(remote_major, remote_minor)) {
debug("%s doesn't support ssh2", c->c_name);
confree(s);
@@ -562,16 +583,9 @@ conloop(void)
monotime_tv(&now);
c = TAILQ_FIRST(&tq);
- if (c && (c->c_tv.tv_sec > now.tv_sec ||
- (c->c_tv.tv_sec == now.tv_sec && c->c_tv.tv_usec > now.tv_usec))) {
- seltime = c->c_tv;
- seltime.tv_sec -= now.tv_sec;
- seltime.tv_usec -= now.tv_usec;
- if (seltime.tv_usec < 0) {
- seltime.tv_usec += 1000000;
- seltime.tv_sec--;
- }
- } else
+ if (c && timercmp(&c->c_tv, &now, >))
+ timersub(&c->c_tv, &now, &seltime);
+ else
timerclear(&seltime);
r = xcalloc(read_wait_nfdset, sizeof(fd_mask));
@@ -594,8 +608,7 @@ conloop(void)
free(e);
c = TAILQ_FIRST(&tq);
- while (c && (c->c_tv.tv_sec < now.tv_sec ||
- (c->c_tv.tv_sec == now.tv_sec && c->c_tv.tv_usec < now.tv_usec))) {
+ while (c && timercmp(&c->c_tv, &now, <)) {
int s = c->c_fd;
c = TAILQ_NEXT(c, c_link);
@@ -621,14 +634,15 @@ do_host(char *host)
}
void
-fatal(const char *fmt,...)
+sshfatal(const char *file, const char *func, int line, int showfunc,
+ LogLevel level, const char *suffix, const char *fmt, ...)
{
va_list args;
va_start(args, fmt);
- do_log(SYSLOG_LEVEL_FATAL, fmt, args);
+ sshlogv(file, func, line, showfunc, level, suffix, fmt, args);
va_end(args);
- exit(255);
+ cleanup_exit(255);
}
static void
@@ -653,7 +667,6 @@ main(int argc, char **argv)
extern int optind;
extern char *optarg;
- ssh_malloc_init(); /* must be called before any mallocs */
__progname = ssh_get_progname(argv[0]);
seed_rng();
TAILQ_INIT(&tq);
@@ -726,6 +739,12 @@ main(int argc, char **argv)
case KEY_XMSS:
get_keytypes |= KT_XMSS;
break;
+ case KEY_ED25519_SK:
+ get_keytypes |= KT_ED25519_SK;
+ break;
+ case KEY_ECDSA_SK:
+ get_keytypes |= KT_ECDSA_SK;
+ break;
case KEY_UNSPEC:
default:
fatal("Unknown key type \"%s\"", tname);
@@ -767,8 +786,7 @@ main(int argc, char **argv)
if (argv[j] == NULL)
fp = stdin;
else if ((fp = fopen(argv[j], "r")) == NULL)
- fatal("%s: %s: %s", __progname, argv[j],
- strerror(errno));
+ fatal("%s: %s: %s", __progname, argv[j], strerror(errno));
while (getline(&line, &linesize, fp) != -1) {
/* Chomp off trailing whitespace and comments */
@@ -790,8 +808,7 @@ main(int argc, char **argv)
}
if (ferror(fp))
- fatal("%s: %s: %s", __progname, argv[j],
- strerror(errno));
+ fatal("%s: %s: %s", __progname, argv[j], strerror(errno));
fclose(fp);
}
@@ -803,5 +820,5 @@ main(int argc, char **argv)
while (ncon > 0)
conloop();
- return (0);
+ return found_one ? 0 : 1;
}
diff --git a/crypto/openssh/ssh-keysign.8 b/crypto/openssh/ssh-keysign.8
index 19b0dbc533c8..73b62397c10b 100644
--- a/crypto/openssh/ssh-keysign.8
+++ b/crypto/openssh/ssh-keysign.8
@@ -1,4 +1,4 @@
-.\" $OpenBSD: ssh-keysign.8,v 1.15 2016/02/17 07:38:19 jmc Exp $
+.\" $OpenBSD: ssh-keysign.8,v 1.16 2019/11/30 07:07:59 jmc Exp $
.\"
.\" Copyright (c) 2002 Markus Friedl. All rights reserved.
.\"
@@ -22,12 +22,12 @@
.\" (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: February 17 2016 $
+.Dd $Mdocdate: November 30 2019 $
.Dt SSH-KEYSIGN 8
.Os
.Sh NAME
.Nm ssh-keysign
-.Nd ssh helper program for host-based authentication
+.Nd OpenSSH helper for host-based authentication
.Sh SYNOPSIS
.Nm
.Sh DESCRIPTION
diff --git a/crypto/openssh/ssh-keysign.c b/crypto/openssh/ssh-keysign.c
index 744ecb4f90f3..d6ac98c6c8c7 100644
--- a/crypto/openssh/ssh-keysign.c
+++ b/crypto/openssh/ssh-keysign.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssh-keysign.c,v 1.55 2018/07/27 05:34:42 dtucker Exp $ */
+/* $OpenBSD: ssh-keysign.c,v 1.67 2021/07/05 01:16:46 dtucker Exp $ */
/*
* Copyright (c) 2002 Markus Friedl. All rights reserved.
*
@@ -31,6 +31,7 @@
#endif
#include <pwd.h>
#include <stdarg.h>
+#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
@@ -40,6 +41,7 @@
#include <openssl/evp.h>
#include <openssl/rand.h>
#include <openssl/rsa.h>
+#include "openbsd-compat/openssl-compat.h"
#endif
#include "xmalloc.h"
@@ -55,11 +57,8 @@
#include "pathnames.h"
#include "readconf.h"
#include "uidswap.h"
-#include "sshkey.h"
#include "ssherr.h"
-struct ssh *active_state = NULL; /* XXX needed for linking */
-
extern char *__progname;
static int
@@ -79,33 +78,33 @@ valid_request(struct passwd *pw, char *host, struct sshkey **ret,
fail = 0;
if ((b = sshbuf_from(data, datalen)) == NULL)
- fatal("%s: sshbuf_from failed", __func__);
+ fatal_f("sshbuf_from failed");
/* session id, currently limited to SHA1 (20 bytes) or SHA256 (32) */
if ((r = sshbuf_get_string(b, NULL, &len)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "parse session ID");
if (len != 20 && len != 32)
fail++;
if ((r = sshbuf_get_u8(b, &type)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "parse type");
if (type != SSH2_MSG_USERAUTH_REQUEST)
fail++;
/* server user */
if ((r = sshbuf_skip_string(b)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "parse user");
/* service */
if ((r = sshbuf_get_cstring(b, &p, NULL)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "parse service");
if (strcmp("ssh-connection", p) != 0)
fail++;
free(p);
/* method */
if ((r = sshbuf_get_cstring(b, &p, NULL)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "parse method");
if (strcmp("hostbased", p) != 0)
fail++;
free(p);
@@ -113,13 +112,13 @@ valid_request(struct passwd *pw, char *host, struct sshkey **ret,
/* pubkey */
if ((r = sshbuf_get_cstring(b, &pkalg, NULL)) != 0 ||
(r = sshbuf_get_string(b, &pkblob, &blen)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "parse pk");
pktype = sshkey_type_from_name(pkalg);
if (pktype == KEY_UNSPEC)
fail++;
else if ((r = sshkey_from_blob(pkblob, blen, &key)) != 0) {
- error("%s: bad key blob: %s", __func__, ssh_err(r));
+ error_fr(r, "decode key");
fail++;
} else if (key->type != pktype)
fail++;
@@ -128,8 +127,8 @@ valid_request(struct passwd *pw, char *host, struct sshkey **ret,
/* client host name, handle trailing dot */
if ((r = sshbuf_get_cstring(b, &p, &len)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
- debug2("%s: check expect chost %s got %s", __func__, host, p);
+ fatal_fr(r, "parse hostname");
+ debug2_f("check expect chost %s got %s", host, p);
if (strlen(host) != len - 1)
fail++;
else if (p[len - 1] != '.')
@@ -140,7 +139,7 @@ valid_request(struct passwd *pw, char *host, struct sshkey **ret,
/* local user */
if ((r = sshbuf_get_cstring(b, &luser, NULL)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "parse luser");
if (strcmp(pw->pw_name, luser) != 0)
fail++;
@@ -151,7 +150,7 @@ valid_request(struct passwd *pw, char *host, struct sshkey **ret,
fail++;
sshbuf_free(b);
- debug3("%s: fail %d", __func__, fail);
+ debug3_f("fail %d", fail);
if (fail)
sshkey_free(key);
@@ -173,11 +172,7 @@ main(int argc, char **argv)
u_char *signature, *data, rver;
char *host, *fp;
size_t slen, dlen;
-#ifdef WITH_OPENSSL
- u_int32_t rnd[256];
-#endif
- ssh_malloc_init(); /* must be called before any mallocs */
if (pledge("stdio rpath getpw dns id", NULL) != 0)
fatal("%s: pledge: %s", __progname, strerror(errno));
@@ -210,8 +205,9 @@ main(int argc, char **argv)
/* verify that ssh-keysign is enabled by the admin */
initialize_options(&options);
- (void)read_config_file(_PATH_HOST_CONFIG_FILE, pw, "", "", &options, 0);
- fill_default_options(&options);
+ (void)read_config_file(_PATH_HOST_CONFIG_FILE, pw, "", "",
+ &options, 0, NULL);
+ (void)fill_default_options(&options);
if (options.enable_ssh_keysign != 1)
fatal("ssh-keysign not enabled in %s",
_PATH_HOST_CONFIG_FILE);
@@ -223,12 +219,6 @@ main(int argc, char **argv)
if (found == 0)
fatal("could not open any host key");
-#ifdef WITH_OPENSSL
- OpenSSL_add_all_algorithms();
- arc4random_buf(rnd, sizeof(rnd));
- RAND_seed(rnd, sizeof(rnd));
-#endif
-
found = 0;
for (i = 0; i < NUM_KEYTYPES; i++) {
keys[i] = NULL;
@@ -238,7 +228,7 @@ main(int argc, char **argv)
NULL, &key, NULL);
close(key_fd[i]);
if (r != 0)
- debug("parse key %d: %s", i, ssh_err(r));
+ debug_r(r, "parse key %d", i);
else if (key != NULL) {
keys[i] = key;
found = 1;
@@ -253,22 +243,23 @@ main(int argc, char **argv)
if ((b = sshbuf_new()) == NULL)
fatal("%s: sshbuf_new failed", __progname);
if (ssh_msg_recv(STDIN_FILENO, b) < 0)
- fatal("ssh_msg_recv failed");
+ fatal("%s: ssh_msg_recv failed", __progname);
if ((r = sshbuf_get_u8(b, &rver)) != 0)
- fatal("%s: buffer error: %s", __progname, ssh_err(r));
+ fatal_r(r, "%s: buffer error", __progname);
if (rver != version)
- fatal("bad version: received %d, expected %d", rver, version);
+ fatal("%s: bad version: received %d, expected %d",
+ __progname, rver, version);
if ((r = sshbuf_get_u32(b, (u_int *)&fd)) != 0)
- fatal("%s: buffer error: %s", __progname, ssh_err(r));
+ fatal_r(r, "%s: buffer error", __progname);
if (fd < 0 || fd == STDIN_FILENO || fd == STDOUT_FILENO)
- fatal("bad fd");
+ fatal("%s: bad fd = %d", __progname, fd);
if ((host = get_local_name(fd)) == NULL)
- fatal("cannot get local name for fd");
+ fatal("%s: cannot get local name for fd", __progname);
if ((r = sshbuf_get_string(b, &data, &dlen)) != 0)
- fatal("%s: buffer error: %s", __progname, ssh_err(r));
+ fatal_r(r, "%s: buffer error", __progname);
if (valid_request(pw, host, &key, data, dlen) < 0)
- fatal("not a valid request");
+ fatal("%s: not a valid request", __progname);
free(host);
found = 0;
@@ -283,21 +274,21 @@ main(int argc, char **argv)
if ((fp = sshkey_fingerprint(key, options.fingerprint_hash,
SSH_FP_DEFAULT)) == NULL)
fatal("%s: sshkey_fingerprint failed", __progname);
- fatal("no matching hostkey found for key %s %s",
+ fatal("%s: no matching hostkey found for key %s %s", __progname,
sshkey_type(key), fp ? fp : "");
}
- if ((r = sshkey_sign(keys[i], &signature, &slen, data, dlen, NULL, 0))
- != 0)
- fatal("sshkey_sign failed: %s", ssh_err(r));
+ if ((r = sshkey_sign(keys[i], &signature, &slen, data, dlen,
+ NULL, NULL, NULL, 0)) != 0)
+ fatal_r(r, "%s: sshkey_sign failed", __progname);
free(data);
/* send reply */
sshbuf_reset(b);
if ((r = sshbuf_put_string(b, signature, slen)) != 0)
- fatal("%s: buffer error: %s", __progname, ssh_err(r));
+ fatal_r(r, "%s: buffer error", __progname);
if (ssh_msg_send(STDOUT_FILENO, version, b) == -1)
- fatal("ssh_msg_send failed");
+ fatal("%s: ssh_msg_send failed", __progname);
return (0);
}
diff --git a/crypto/openssh/ssh-pkcs11-client.c b/crypto/openssh/ssh-pkcs11-client.c
index d1241ce67f32..e724736944f4 100644
--- a/crypto/openssh/ssh-pkcs11-client.c
+++ b/crypto/openssh/ssh-pkcs11-client.c
@@ -1,6 +1,7 @@
-/* $OpenBSD: ssh-pkcs11-client.c,v 1.10 2018/07/09 21:59:10 markus Exp $ */
+/* $OpenBSD: ssh-pkcs11-client.c,v 1.17 2020/10/18 11:32:02 djm Exp $ */
/*
* Copyright (c) 2010 Markus Friedl. All rights reserved.
+ * Copyright (c) 2014 Pedro Martelletto. 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
@@ -30,6 +31,7 @@
#include <unistd.h>
#include <errno.h>
+#include <openssl/ecdsa.h>
#include <openssl/rsa.h>
#include "openbsd-compat/openssl-compat.h"
@@ -47,8 +49,8 @@
/* borrows code from sftp-server and ssh-agent */
-int fd = -1;
-pid_t pid = -1;
+static int fd = -1;
+static pid_t pid = -1;
static void
send_msg(struct sshbuf *m)
@@ -63,7 +65,7 @@ send_msg(struct sshbuf *m)
sshbuf_len(m)) != sshbuf_len(m))
error("write to helper failed");
if ((r = sshbuf_consume(m, mlen)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "consume");
}
static int
@@ -91,11 +93,11 @@ recv_msg(struct sshbuf *m)
return (0); /* XXX */
}
if ((r = sshbuf_put(m, buf, l)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "sshbuf_put");
len -= l;
}
if ((r = sshbuf_get_u8(m, &c)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "parse type");
return c;
}
@@ -113,59 +115,156 @@ pkcs11_terminate(void)
}
static int
-pkcs11_rsa_private_encrypt(int flen, const u_char *from, u_char *to, RSA *rsa,
- int padding)
+rsa_encrypt(int flen, const u_char *from, u_char *to, RSA *rsa, int padding)
{
- struct sshkey key; /* XXX */
- u_char *blob, *signature = NULL;
+ struct sshkey *key = NULL;
+ struct sshbuf *msg = NULL;
+ u_char *blob = NULL, *signature = NULL;
size_t blen, slen = 0;
int r, ret = -1;
- struct sshbuf *msg;
if (padding != RSA_PKCS1_PADDING)
- return (-1);
- key.type = KEY_RSA;
- key.rsa = rsa;
- if ((r = sshkey_to_blob(&key, &blob, &blen)) != 0) {
- error("%s: sshkey_to_blob: %s", __func__, ssh_err(r));
- return -1;
+ goto fail;
+ key = sshkey_new(KEY_UNSPEC);
+ if (key == NULL) {
+ error_f("sshkey_new failed");
+ goto fail;
+ }
+ key->type = KEY_RSA;
+ RSA_up_ref(rsa);
+ key->rsa = rsa;
+ if ((r = sshkey_to_blob(key, &blob, &blen)) != 0) {
+ error_fr(r, "encode key");
+ goto fail;
}
if ((msg = sshbuf_new()) == NULL)
- fatal("%s: sshbuf_new failed", __func__);
+ fatal_f("sshbuf_new failed");
if ((r = sshbuf_put_u8(msg, SSH2_AGENTC_SIGN_REQUEST)) != 0 ||
(r = sshbuf_put_string(msg, blob, blen)) != 0 ||
(r = sshbuf_put_string(msg, from, flen)) != 0 ||
(r = sshbuf_put_u32(msg, 0)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
- free(blob);
+ fatal_fr(r, "compose");
send_msg(msg);
sshbuf_reset(msg);
if (recv_msg(msg) == SSH2_AGENT_SIGN_RESPONSE) {
if ((r = sshbuf_get_string(msg, &signature, &slen)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "parse");
if (slen <= (size_t)RSA_size(rsa)) {
memcpy(to, signature, slen);
ret = slen;
}
free(signature);
}
+ fail:
+ free(blob);
+ sshkey_free(key);
+ sshbuf_free(msg);
+ return (ret);
+}
+
+#ifdef HAVE_EC_KEY_METHOD_NEW
+static ECDSA_SIG *
+ecdsa_do_sign(const unsigned char *dgst, int dgst_len, const BIGNUM *inv,
+ const BIGNUM *rp, EC_KEY *ec)
+{
+ struct sshkey *key = NULL;
+ struct sshbuf *msg = NULL;
+ ECDSA_SIG *ret = NULL;
+ const u_char *cp;
+ u_char *blob = NULL, *signature = NULL;
+ size_t blen, slen = 0;
+ int r, nid;
+
+ nid = sshkey_ecdsa_key_to_nid(ec);
+ if (nid < 0) {
+ error_f("couldn't get curve nid");
+ goto fail;
+ }
+
+ key = sshkey_new(KEY_UNSPEC);
+ if (key == NULL) {
+ error_f("sshkey_new failed");
+ goto fail;
+ }
+ key->ecdsa = ec;
+ key->ecdsa_nid = nid;
+ key->type = KEY_ECDSA;
+ EC_KEY_up_ref(ec);
+
+ if ((r = sshkey_to_blob(key, &blob, &blen)) != 0) {
+ error_fr(r, "encode key");
+ goto fail;
+ }
+ if ((msg = sshbuf_new()) == NULL)
+ fatal_f("sshbuf_new failed");
+ if ((r = sshbuf_put_u8(msg, SSH2_AGENTC_SIGN_REQUEST)) != 0 ||
+ (r = sshbuf_put_string(msg, blob, blen)) != 0 ||
+ (r = sshbuf_put_string(msg, dgst, dgst_len)) != 0 ||
+ (r = sshbuf_put_u32(msg, 0)) != 0)
+ fatal_fr(r, "compose");
+ send_msg(msg);
+ sshbuf_reset(msg);
+
+ if (recv_msg(msg) == SSH2_AGENT_SIGN_RESPONSE) {
+ if ((r = sshbuf_get_string(msg, &signature, &slen)) != 0)
+ fatal_fr(r, "parse");
+ cp = signature;
+ ret = d2i_ECDSA_SIG(NULL, &cp, slen);
+ free(signature);
+ }
+
+ fail:
+ free(blob);
+ sshkey_free(key);
sshbuf_free(msg);
return (ret);
}
+#endif /* HAVE_EC_KEY_METHOD_NEW */
+
+static RSA_METHOD *helper_rsa;
+#ifdef HAVE_EC_KEY_METHOD_NEW
+static EC_KEY_METHOD *helper_ecdsa;
+#endif /* HAVE_EC_KEY_METHOD_NEW */
+
+/* redirect private key crypto operations to the ssh-pkcs11-helper */
+static void
+wrap_key(struct sshkey *k)
+{
+ if (k->type == KEY_RSA)
+ RSA_set_method(k->rsa, helper_rsa);
+#ifdef HAVE_EC_KEY_METHOD_NEW
+ else if (k->type == KEY_ECDSA)
+ EC_KEY_set_method(k->ecdsa, helper_ecdsa);
+#endif /* HAVE_EC_KEY_METHOD_NEW */
+ else
+ fatal_f("unknown key type");
+}
-/* redirect the private key encrypt operation to the ssh-pkcs11-helper */
static int
-wrap_key(RSA *rsa)
+pkcs11_start_helper_methods(void)
{
- static RSA_METHOD *helper_rsa;
+ if (helper_rsa != NULL)
+ return (0);
+
+#ifdef HAVE_EC_KEY_METHOD_NEW
+ int (*orig_sign)(int, const unsigned char *, int, unsigned char *,
+ unsigned int *, const BIGNUM *, const BIGNUM *, EC_KEY *) = NULL;
+ if (helper_ecdsa != NULL)
+ return (0);
+ helper_ecdsa = EC_KEY_METHOD_new(EC_KEY_OpenSSL());
+ if (helper_ecdsa == NULL)
+ return (-1);
+ EC_KEY_METHOD_get_sign(helper_ecdsa, &orig_sign, NULL, NULL);
+ EC_KEY_METHOD_set_sign(helper_ecdsa, orig_sign, NULL, ecdsa_do_sign);
+#endif /* HAVE_EC_KEY_METHOD_NEW */
if ((helper_rsa = RSA_meth_dup(RSA_get_default_method())) == NULL)
- fatal("%s: RSA_meth_dup failed", __func__);
+ fatal_f("RSA_meth_dup failed");
if (!RSA_meth_set1_name(helper_rsa, "ssh-pkcs11-helper") ||
- !RSA_meth_set_priv_enc(helper_rsa, pkcs11_rsa_private_encrypt))
- fatal("%s: failed to prepare method", __func__);
- RSA_set_method(rsa, helper_rsa);
+ !RSA_meth_set_priv_enc(helper_rsa, rsa_encrypt))
+ fatal_f("failed to prepare method");
+
return (0);
}
@@ -173,6 +272,15 @@ static int
pkcs11_start_helper(void)
{
int pair[2];
+ char *helper, *verbosity = NULL;
+
+ if (log_level_get() >= SYSLOG_LEVEL_DEBUG1)
+ verbosity = "-vvv";
+
+ if (pkcs11_start_helper_methods() == -1) {
+ error("pkcs11_start_helper_methods failed");
+ return (-1);
+ }
if (socketpair(AF_UNIX, SOCK_STREAM, 0, pair) == -1) {
error("socketpair: %s", strerror(errno));
@@ -189,10 +297,13 @@ pkcs11_start_helper(void)
}
close(pair[0]);
close(pair[1]);
- execlp(_PATH_SSH_PKCS11_HELPER, _PATH_SSH_PKCS11_HELPER,
- (char *)NULL);
- fprintf(stderr, "exec: %s: %s\n", _PATH_SSH_PKCS11_HELPER,
- strerror(errno));
+ helper = getenv("SSH_PKCS11_HELPER");
+ if (helper == NULL || strlen(helper) == 0)
+ helper = _PATH_SSH_PKCS11_HELPER;
+ debug_f("starting %s %s", helper,
+ verbosity == NULL ? "" : verbosity);
+ execlp(helper, helper, verbosity, (char *)NULL);
+ fprintf(stderr, "exec: %s: %s\n", helper, strerror(errno));
_exit(1);
}
close(pair[1]);
@@ -201,11 +312,13 @@ pkcs11_start_helper(void)
}
int
-pkcs11_add_provider(char *name, char *pin, struct sshkey ***keysp)
+pkcs11_add_provider(char *name, char *pin, struct sshkey ***keysp,
+ char ***labelsp)
{
struct sshkey *k;
- int r;
+ int r, type;
u_char *blob;
+ char *label;
size_t blen;
u_int nkeys, i;
struct sshbuf *msg;
@@ -214,30 +327,39 @@ pkcs11_add_provider(char *name, char *pin, struct sshkey ***keysp)
return (-1);
if ((msg = sshbuf_new()) == NULL)
- fatal("%s: sshbuf_new failed", __func__);
+ fatal_f("sshbuf_new failed");
if ((r = sshbuf_put_u8(msg, SSH_AGENTC_ADD_SMARTCARD_KEY)) != 0 ||
(r = sshbuf_put_cstring(msg, name)) != 0 ||
(r = sshbuf_put_cstring(msg, pin)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "compose");
send_msg(msg);
sshbuf_reset(msg);
- if (recv_msg(msg) == SSH2_AGENT_IDENTITIES_ANSWER) {
+ type = recv_msg(msg);
+ if (type == SSH2_AGENT_IDENTITIES_ANSWER) {
if ((r = sshbuf_get_u32(msg, &nkeys)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "parse nkeys");
*keysp = xcalloc(nkeys, sizeof(struct sshkey *));
+ if (labelsp)
+ *labelsp = xcalloc(nkeys, sizeof(char *));
for (i = 0; i < nkeys; i++) {
/* XXX clean up properly instead of fatal() */
if ((r = sshbuf_get_string(msg, &blob, &blen)) != 0 ||
- (r = sshbuf_skip_string(msg)) != 0)
- fatal("%s: buffer error: %s",
- __func__, ssh_err(r));
+ (r = sshbuf_get_cstring(msg, &label, NULL)) != 0)
+ fatal_fr(r, "parse key");
if ((r = sshkey_from_blob(blob, blen, &k)) != 0)
- fatal("%s: bad key: %s", __func__, ssh_err(r));
- wrap_key(k->rsa);
+ fatal_fr(r, "decode key");
+ wrap_key(k);
(*keysp)[i] = k;
+ if (labelsp)
+ (*labelsp)[i] = label;
+ else
+ free(label);
free(blob);
}
+ } else if (type == SSH2_AGENT_FAILURE) {
+ if ((r = sshbuf_get_u32(msg, &nkeys)) != 0)
+ nkeys = -1;
} else {
nkeys = -1;
}
@@ -252,11 +374,11 @@ pkcs11_del_provider(char *name)
struct sshbuf *msg;
if ((msg = sshbuf_new()) == NULL)
- fatal("%s: sshbuf_new failed", __func__);
+ fatal_f("sshbuf_new failed");
if ((r = sshbuf_put_u8(msg, SSH_AGENTC_REMOVE_SMARTCARD_KEY)) != 0 ||
(r = sshbuf_put_cstring(msg, name)) != 0 ||
(r = sshbuf_put_cstring(msg, "")) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "compose");
send_msg(msg);
sshbuf_reset(msg);
diff --git a/crypto/openssh/ssh-pkcs11-helper.8 b/crypto/openssh/ssh-pkcs11-helper.8
index 3728c4e4e7e4..6a592b1f36e3 100644
--- a/crypto/openssh/ssh-pkcs11-helper.8
+++ b/crypto/openssh/ssh-pkcs11-helper.8
@@ -1,4 +1,4 @@
-.\" $OpenBSD: ssh-pkcs11-helper.8,v 1.4 2013/07/16 00:07:52 schwarze Exp $
+.\" $OpenBSD: ssh-pkcs11-helper.8,v 1.6 2019/11/30 07:07:59 jmc Exp $
.\"
.\" Copyright (c) 2010 Markus Friedl. All rights reserved.
.\"
@@ -14,14 +14,15 @@
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
.\"
-.Dd $Mdocdate: July 16 2013 $
+.Dd $Mdocdate: November 30 2019 $
.Dt SSH-PKCS11-HELPER 8
.Os
.Sh NAME
.Nm ssh-pkcs11-helper
-.Nd ssh-agent helper program for PKCS#11 support
+.Nd OpenSSH helper for PKCS#11 support
.Sh SYNOPSIS
.Nm
+.Op Fl v
.Sh DESCRIPTION
.Nm
is used by
@@ -31,6 +32,28 @@ to access keys provided by a PKCS#11 token.
.Nm
is not intended to be invoked by the user, but from
.Xr ssh-agent 1 .
+.Pp
+A single option is supported:
+.Bl -tag -width Ds
+.It Fl v
+Verbose mode.
+Causes
+.Nm
+to print debugging messages about its progress.
+This is helpful in debugging problems.
+Multiple
+.Fl v
+options increase the verbosity.
+The maximum is 3.
+.Pp
+Note that
+.Xr ssh-agent 1
+will automatically pass the
+.Fl v
+flag to
+.Nm
+when it has itself been placed in debug mode.
+.El
.Sh SEE ALSO
.Xr ssh 1 ,
.Xr ssh-add 1 ,
diff --git a/crypto/openssh/ssh-pkcs11-helper.c b/crypto/openssh/ssh-pkcs11-helper.c
index 6301033c513a..5ca8d03fbd1e 100644
--- a/crypto/openssh/ssh-pkcs11-helper.c
+++ b/crypto/openssh/ssh-pkcs11-helper.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssh-pkcs11-helper.c,v 1.14 2018/01/08 15:18:46 markus Exp $ */
+/* $OpenBSD: ssh-pkcs11-helper.c,v 1.25 2021/08/11 05:20:17 djm Exp $ */
/*
* Copyright (c) 2010 Markus Friedl. All rights reserved.
*
@@ -24,10 +24,14 @@
#include "openbsd-compat/sys-queue.h"
+#include <stdlib.h>
+#include <errno.h>
+#ifdef HAVE_POLL_H
+#include <poll.h>
+#endif
#include <stdarg.h>
#include <string.h>
#include <unistd.h>
-#include <errno.h>
#include "xmalloc.h"
#include "sshbuf.h"
@@ -40,11 +44,13 @@
#ifdef ENABLE_PKCS11
+#ifdef WITH_OPENSSL
+
/* borrows code from sftp-server and ssh-agent */
struct pkcs11_keyinfo {
struct sshkey *key;
- char *providername;
+ char *providername, *label;
TAILQ_ENTRY(pkcs11_keyinfo) next;
};
@@ -57,13 +63,14 @@ struct sshbuf *iqueue;
struct sshbuf *oqueue;
static void
-add_key(struct sshkey *k, char *name)
+add_key(struct sshkey *k, char *name, char *label)
{
struct pkcs11_keyinfo *ki;
ki = xcalloc(1, sizeof(*ki));
ki->providername = xstrdup(name);
ki->key = k;
+ ki->label = xstrdup(label);
TAILQ_INSERT_TAIL(&pkcs11_keylist, ki, next);
}
@@ -77,6 +84,7 @@ del_keys_by_name(char *name)
if (!strcmp(ki->providername, name)) {
TAILQ_REMOVE(&pkcs11_keylist, ki, next);
free(ki->providername);
+ free(ki->label);
sshkey_free(ki->key);
free(ki);
}
@@ -90,7 +98,8 @@ lookup_key(struct sshkey *k)
struct pkcs11_keyinfo *ki;
TAILQ_FOREACH(ki, &pkcs11_keylist, next) {
- debug("check %p %s", ki, ki->providername);
+ debug("check %s %s %s", sshkey_type(ki->key),
+ ki->providername, ki->label);
if (sshkey_equal(k, ki->key))
return (ki->key);
}
@@ -103,47 +112,47 @@ send_msg(struct sshbuf *m)
int r;
if ((r = sshbuf_put_stringb(oqueue, m)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "enqueue");
}
static void
process_add(void)
{
char *name, *pin;
- struct sshkey **keys;
+ struct sshkey **keys = NULL;
int r, i, nkeys;
u_char *blob;
size_t blen;
struct sshbuf *msg;
+ char **labels = NULL;
if ((msg = sshbuf_new()) == NULL)
- fatal("%s: sshbuf_new failed", __func__);
+ fatal_f("sshbuf_new failed");
if ((r = sshbuf_get_cstring(iqueue, &name, NULL)) != 0 ||
(r = sshbuf_get_cstring(iqueue, &pin, NULL)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
- if ((nkeys = pkcs11_add_provider(name, pin, &keys)) > 0) {
+ fatal_fr(r, "parse");
+ if ((nkeys = pkcs11_add_provider(name, pin, &keys, &labels)) > 0) {
if ((r = sshbuf_put_u8(msg,
SSH2_AGENT_IDENTITIES_ANSWER)) != 0 ||
(r = sshbuf_put_u32(msg, nkeys)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "compose");
for (i = 0; i < nkeys; i++) {
if ((r = sshkey_to_blob(keys[i], &blob, &blen)) != 0) {
- debug("%s: sshkey_to_blob: %s",
- __func__, ssh_err(r));
+ debug_fr(r, "encode key");
continue;
}
if ((r = sshbuf_put_string(msg, blob, blen)) != 0 ||
- (r = sshbuf_put_cstring(msg, name)) != 0)
- fatal("%s: buffer error: %s",
- __func__, ssh_err(r));
+ (r = sshbuf_put_cstring(msg, labels[i])) != 0)
+ fatal_fr(r, "compose key");
free(blob);
- add_key(keys[i], name);
+ add_key(keys[i], name, labels[i]);
+ free(labels[i]);
}
- free(keys);
- } else {
- if ((r = sshbuf_put_u8(msg, SSH_AGENT_FAILURE)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
- }
+ } else if ((r = sshbuf_put_u8(msg, SSH_AGENT_FAILURE)) != 0 ||
+ (r = sshbuf_put_u32(msg, -nkeys)) != 0)
+ fatal_fr(r, "compose");
+ free(labels);
+ free(keys); /* keys themselves are transferred to pkcs11_keylist */
free(pin);
free(name);
send_msg(msg);
@@ -158,14 +167,14 @@ process_del(void)
int r;
if ((msg = sshbuf_new()) == NULL)
- fatal("%s: sshbuf_new failed", __func__);
+ fatal_f("sshbuf_new failed");
if ((r = sshbuf_get_cstring(iqueue, &name, NULL)) != 0 ||
(r = sshbuf_get_cstring(iqueue, &pin, NULL)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "parse");
del_keys_by_name(name);
if ((r = sshbuf_put_u8(msg, pkcs11_del_provider(name) == 0 ?
SSH_AGENT_SUCCESS : SSH_AGENT_FAILURE)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "compose");
free(pin);
free(name);
send_msg(msg);
@@ -185,35 +194,54 @@ process_sign(void)
if ((r = sshbuf_get_string(iqueue, &blob, &blen)) != 0 ||
(r = sshbuf_get_string(iqueue, &data, &dlen)) != 0 ||
(r = sshbuf_get_u32(iqueue, NULL)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "parse");
if ((r = sshkey_from_blob(blob, blen, &key)) != 0)
- error("%s: sshkey_from_blob: %s", __func__, ssh_err(r));
+ fatal_fr(r, "decode key");
else {
if ((found = lookup_key(key)) != NULL) {
#ifdef WITH_OPENSSL
int ret;
- slen = RSA_size(key->rsa);
- signature = xmalloc(slen);
- if ((ret = RSA_private_encrypt(dlen, data, signature,
- found->rsa, RSA_PKCS1_PADDING)) != -1) {
- slen = ret;
- ok = 0;
- }
+ if (key->type == KEY_RSA) {
+ slen = RSA_size(key->rsa);
+ signature = xmalloc(slen);
+ ret = RSA_private_encrypt(dlen, data, signature,
+ found->rsa, RSA_PKCS1_PADDING);
+ if (ret != -1) {
+ slen = ret;
+ ok = 0;
+ }
+#ifdef OPENSSL_HAS_ECC
+ } else if (key->type == KEY_ECDSA) {
+ u_int xslen = ECDSA_size(key->ecdsa);
+
+ signature = xmalloc(xslen);
+ /* "The parameter type is ignored." */
+ ret = ECDSA_sign(-1, data, dlen, signature,
+ &xslen, found->ecdsa);
+ if (ret != 0)
+ ok = 0;
+ else
+ error_f("ECDSA_sign returned %d", ret);
+ slen = xslen;
+#endif /* OPENSSL_HAS_ECC */
+ } else
+ error_f("don't know how to sign with key "
+ "type %d", (int)key->type);
#endif /* WITH_OPENSSL */
}
sshkey_free(key);
}
if ((msg = sshbuf_new()) == NULL)
- fatal("%s: sshbuf_new failed", __func__);
+ fatal_f("sshbuf_new failed");
if (ok == 0) {
if ((r = sshbuf_put_u8(msg, SSH2_AGENT_SIGN_RESPONSE)) != 0 ||
(r = sshbuf_put_string(msg, signature, slen)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "compose response");
} else {
if ((r = sshbuf_put_u8(msg, SSH2_AGENT_FAILURE)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "compose failure response");
}
free(data);
free(blob);
@@ -245,7 +273,7 @@ process(void)
return;
if ((r = sshbuf_consume(iqueue, 4)) != 0 ||
(r = sshbuf_get_u8(iqueue, &type)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "parse type/len");
buf_len -= 4;
switch (type) {
case SSH_AGENTC_ADD_SMARTCARD_KEY:
@@ -276,7 +304,7 @@ process(void)
}
if (msg_len > consumed) {
if ((r = sshbuf_consume(iqueue, msg_len - consumed)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "consume");
}
}
@@ -287,48 +315,54 @@ cleanup_exit(int i)
_exit(i);
}
+
int
main(int argc, char **argv)
{
- fd_set *rset, *wset;
- int r, in, out, max, log_stderr = 0;
- ssize_t len, olen, set_size;
+ int r, ch, in, out, log_stderr = 0;
+ ssize_t len;
SyslogFacility log_facility = SYSLOG_FACILITY_AUTH;
LogLevel log_level = SYSLOG_LEVEL_ERROR;
char buf[4*4096];
-
extern char *__progname;
+ struct pollfd pfd[2];
- ssh_malloc_init(); /* must be called before any mallocs */
+ __progname = ssh_get_progname(argv[0]);
+ seed_rng();
TAILQ_INIT(&pkcs11_keylist);
- pkcs11_init(0);
- seed_rng();
- __progname = ssh_get_progname(argv[0]);
+ log_init(__progname, log_level, log_facility, log_stderr);
+
+ while ((ch = getopt(argc, argv, "v")) != -1) {
+ switch (ch) {
+ case 'v':
+ log_stderr = 1;
+ if (log_level == SYSLOG_LEVEL_ERROR)
+ log_level = SYSLOG_LEVEL_DEBUG1;
+ else if (log_level < SYSLOG_LEVEL_DEBUG3)
+ log_level++;
+ break;
+ default:
+ fprintf(stderr, "usage: %s [-v]\n", __progname);
+ exit(1);
+ }
+ }
log_init(__progname, log_level, log_facility, log_stderr);
+ pkcs11_init(0);
in = STDIN_FILENO;
out = STDOUT_FILENO;
- max = 0;
- if (in > max)
- max = in;
- if (out > max)
- max = out;
-
if ((iqueue = sshbuf_new()) == NULL)
- fatal("%s: sshbuf_new failed", __func__);
+ fatal_f("sshbuf_new failed");
if ((oqueue = sshbuf_new()) == NULL)
- fatal("%s: sshbuf_new failed", __func__);
+ fatal_f("sshbuf_new failed");
- set_size = howmany(max + 1, NFDBITS) * sizeof(fd_mask);
- rset = xmalloc(set_size);
- wset = xmalloc(set_size);
-
- for (;;) {
- memset(rset, 0, set_size);
- memset(wset, 0, set_size);
+ while (1) {
+ memset(pfd, 0, sizeof(pfd));
+ pfd[0].fd = in;
+ pfd[1].fd = out;
/*
* Ensure that we can read a full buffer and handle
@@ -337,23 +371,21 @@ main(int argc, char **argv)
*/
if ((r = sshbuf_check_reserve(iqueue, sizeof(buf))) == 0 &&
(r = sshbuf_check_reserve(oqueue, MAX_MSG_LENGTH)) == 0)
- FD_SET(in, rset);
+ pfd[0].events = POLLIN;
else if (r != SSH_ERR_NO_BUFFER_SPACE)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "reserve");
- olen = sshbuf_len(oqueue);
- if (olen > 0)
- FD_SET(out, wset);
+ if (sshbuf_len(oqueue) > 0)
+ pfd[1].events = POLLOUT;
- if (select(max+1, rset, wset, NULL, NULL) < 0) {
- if (errno == EINTR)
+ if ((r = poll(pfd, 2, -1 /* INFTIM */)) <= 0) {
+ if (r == 0 || errno == EINTR)
continue;
- error("select: %s", strerror(errno));
- cleanup_exit(2);
+ fatal("poll: %s", strerror(errno));
}
/* copy stdin to iqueue */
- if (FD_ISSET(in, rset)) {
+ if ((pfd[0].revents & (POLLIN|POLLERR)) != 0) {
len = read(in, buf, sizeof buf);
if (len == 0) {
debug("read eof");
@@ -361,21 +393,18 @@ main(int argc, char **argv)
} else if (len < 0) {
error("read: %s", strerror(errno));
cleanup_exit(1);
- } else if ((r = sshbuf_put(iqueue, buf, len)) != 0) {
- fatal("%s: buffer error: %s",
- __func__, ssh_err(r));
- }
+ } else if ((r = sshbuf_put(iqueue, buf, len)) != 0)
+ fatal_fr(r, "sshbuf_put");
}
/* send oqueue to stdout */
- if (FD_ISSET(out, wset)) {
- len = write(out, sshbuf_ptr(oqueue), olen);
+ if ((pfd[1].revents & (POLLOUT|POLLHUP)) != 0) {
+ len = write(out, sshbuf_ptr(oqueue),
+ sshbuf_len(oqueue));
if (len < 0) {
error("write: %s", strerror(errno));
cleanup_exit(1);
- } else if ((r = sshbuf_consume(oqueue, len)) != 0) {
- fatal("%s: buffer error: %s",
- __func__, ssh_err(r));
- }
+ } else if ((r = sshbuf_consume(oqueue, len)) != 0)
+ fatal_fr(r, "consume");
}
/*
@@ -386,9 +415,24 @@ main(int argc, char **argv)
if ((r = sshbuf_check_reserve(oqueue, MAX_MSG_LENGTH)) == 0)
process();
else if (r != SSH_ERR_NO_BUFFER_SPACE)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "reserve");
}
}
+
+#else /* WITH_OPENSSL */
+void
+cleanup_exit(int i)
+{
+ _exit(i);
+}
+
+int
+main(int argc, char **argv)
+{
+ fprintf(stderr, "PKCS#11 code is not enabled\n");
+ return 1;
+}
+#endif /* WITH_OPENSSL */
#else /* ENABLE_PKCS11 */
int
main(int argc, char **argv)
diff --git a/crypto/openssh/ssh-pkcs11.c b/crypto/openssh/ssh-pkcs11.c
index 775de964210f..37a6b1b5bcae 100644
--- a/crypto/openssh/ssh-pkcs11.c
+++ b/crypto/openssh/ssh-pkcs11.c
@@ -1,6 +1,7 @@
-/* $OpenBSD: ssh-pkcs11.c,v 1.26 2018/02/07 02:06:51 jsing Exp $ */
+/* $OpenBSD: ssh-pkcs11.c,v 1.54 2021/08/11 05:20:17 djm Exp $ */
/*
* Copyright (c) 2010 Markus Friedl. All rights reserved.
+ * Copyright (c) 2014 Pedro Martelletto. 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
@@ -19,20 +20,24 @@
#ifdef ENABLE_PKCS11
-#include <sys/types.h>
#ifdef HAVE_SYS_TIME_H
# include <sys/time.h>
#endif
+
+#include <sys/types.h>
#include <stdarg.h>
#include <stdio.h>
+#include <ctype.h>
#include <string.h>
#include <dlfcn.h>
#include "openbsd-compat/sys-queue.h"
#include "openbsd-compat/openssl-compat.h"
+#include <openssl/ecdsa.h>
#include <openssl/x509.h>
+#include <openssl/err.h>
#define CRYPTOKI_COMPAT
#include "pkcs11.h"
@@ -41,6 +46,7 @@
#include "misc.h"
#include "sshkey.h"
#include "ssh-pkcs11.h"
+#include "digest.h"
#include "xmalloc.h"
struct pkcs11_slotinfo {
@@ -67,14 +73,24 @@ TAILQ_HEAD(, pkcs11_provider) pkcs11_providers;
struct pkcs11_key {
struct pkcs11_provider *provider;
CK_ULONG slotidx;
- int (*orig_finish)(RSA *rsa);
- RSA_METHOD *rsa_method;
char *keyid;
int keyid_len;
};
int pkcs11_interactive = 0;
+#ifdef HAVE_EC_KEY_METHOD_NEW
+static void
+ossl_error(const char *msg)
+{
+ unsigned long e;
+
+ error_f("%s", msg);
+ while ((e = ERR_get_error()) != 0)
+ error_f("libcrypto error: %s", ERR_error_string(e, NULL));
+}
+#endif /* HAVE_EC_KEY_METHOD_NEW */
+
int
pkcs11_init(int interactive)
{
@@ -84,9 +100,9 @@ pkcs11_init(int interactive)
}
/*
- * finalize a provider shared libarary, it's no longer usable.
+ * finalize a provider shared library, it's no longer usable.
* however, there might still be keys referencing this provider,
- * so the actuall freeing of memory is handled by pkcs11_provider_unref().
+ * so the actual freeing of memory is handled by pkcs11_provider_unref().
* this is called when a provider gets unregistered.
*/
static void
@@ -95,8 +111,8 @@ pkcs11_provider_finalize(struct pkcs11_provider *p)
CK_RV rv;
CK_ULONG i;
- debug("pkcs11_provider_finalize: %p refcount %d valid %d",
- p, p->refcount, p->valid);
+ debug_f("provider \"%s\" refcount %d valid %d",
+ p->name, p->refcount, p->valid);
if (!p->valid)
return;
for (i = 0; i < p->nslots; i++) {
@@ -119,10 +135,11 @@ pkcs11_provider_finalize(struct pkcs11_provider *p)
static void
pkcs11_provider_unref(struct pkcs11_provider *p)
{
- debug("pkcs11_provider_unref: %p refcount %d", p, p->refcount);
+ debug_f("provider \"%s\" refcount %d", p->name, p->refcount);
if (--p->refcount <= 0) {
if (p->valid)
- error("pkcs11_provider_unref: %p still valid", p);
+ error_f("provider \"%s\" still valid", p->name);
+ free(p->name);
free(p->slotlist);
free(p->slotinfo);
free(p);
@@ -149,7 +166,7 @@ pkcs11_provider_lookup(char *provider_id)
struct pkcs11_provider *p;
TAILQ_FOREACH(p, &pkcs11_providers, next) {
- debug("check %p %s", p, p->name);
+ debug("check provider \"%s\"", p->name);
if (!strcmp(provider_id, p->name))
return (p);
}
@@ -171,23 +188,27 @@ pkcs11_del_provider(char *provider_id)
return (-1);
}
-/* openssl callback for freeing an RSA key */
-static int
-pkcs11_rsa_finish(RSA *rsa)
+static RSA_METHOD *rsa_method;
+static int rsa_idx = 0;
+#ifdef HAVE_EC_KEY_METHOD_NEW
+static EC_KEY_METHOD *ec_key_method;
+static int ec_key_idx = 0;
+#endif
+
+/* release a wrapped object */
+static void
+pkcs11_k11_free(void *parent, void *ptr, CRYPTO_EX_DATA *ad, int idx,
+ long argl, void *argp)
{
- struct pkcs11_key *k11;
- int rv = -1;
+ struct pkcs11_key *k11 = ptr;
- if ((k11 = RSA_get_app_data(rsa)) != NULL) {
- if (k11->orig_finish)
- rv = k11->orig_finish(rsa);
- if (k11->provider)
- pkcs11_provider_unref(k11->provider);
- RSA_meth_free(k11->rsa_method);
- free(k11->keyid);
- free(k11);
- }
- return (rv);
+ debug_f("parent %p ptr %p idx %d", parent, ptr, idx);
+ if (k11 == NULL)
+ return;
+ if (k11->provider)
+ pkcs11_provider_unref(k11->provider);
+ free(k11->keyid);
+ free(k11);
}
/* find a single 'obj' for given attributes */
@@ -218,88 +239,217 @@ pkcs11_find(struct pkcs11_provider *p, CK_ULONG slotidx, CK_ATTRIBUTE *attr,
return (ret);
}
-/* openssl callback doing the actual signing operation */
static int
-pkcs11_rsa_private_encrypt(int flen, const u_char *from, u_char *to, RSA *rsa,
- int padding)
+pkcs11_login_slot(struct pkcs11_provider *provider, struct pkcs11_slotinfo *si,
+ CK_USER_TYPE type)
+{
+ char *pin = NULL, prompt[1024];
+ CK_RV rv;
+
+ if (provider == NULL || si == NULL || !provider->valid) {
+ error("no pkcs11 (valid) provider found");
+ return (-1);
+ }
+
+ if (!pkcs11_interactive) {
+ error("need pin entry%s",
+ (si->token.flags & CKF_PROTECTED_AUTHENTICATION_PATH) ?
+ " on reader keypad" : "");
+ return (-1);
+ }
+ if (si->token.flags & CKF_PROTECTED_AUTHENTICATION_PATH)
+ verbose("Deferring PIN entry to reader keypad.");
+ else {
+ snprintf(prompt, sizeof(prompt), "Enter PIN for '%s': ",
+ si->token.label);
+ if ((pin = read_passphrase(prompt, RP_ALLOW_EOF)) == NULL) {
+ debug_f("no pin specified");
+ return (-1); /* bail out */
+ }
+ }
+ rv = provider->function_list->C_Login(si->session, type, (u_char *)pin,
+ (pin != NULL) ? strlen(pin) : 0);
+ if (pin != NULL)
+ freezero(pin, strlen(pin));
+
+ switch (rv) {
+ case CKR_OK:
+ case CKR_USER_ALREADY_LOGGED_IN:
+ /* success */
+ break;
+ case CKR_PIN_LEN_RANGE:
+ error("PKCS#11 login failed: PIN length out of range");
+ return -1;
+ case CKR_PIN_INCORRECT:
+ error("PKCS#11 login failed: PIN incorrect");
+ return -1;
+ case CKR_PIN_LOCKED:
+ error("PKCS#11 login failed: PIN locked");
+ return -1;
+ default:
+ error("PKCS#11 login failed: error %lu", rv);
+ return -1;
+ }
+ si->logged_in = 1;
+ return (0);
+}
+
+static int
+pkcs11_login(struct pkcs11_key *k11, CK_USER_TYPE type)
+{
+ if (k11 == NULL || k11->provider == NULL || !k11->provider->valid) {
+ error("no pkcs11 (valid) provider found");
+ return (-1);
+ }
+
+ return pkcs11_login_slot(k11->provider,
+ &k11->provider->slotinfo[k11->slotidx], type);
+}
+
+
+static int
+pkcs11_check_obj_bool_attrib(struct pkcs11_key *k11, CK_OBJECT_HANDLE obj,
+ CK_ATTRIBUTE_TYPE type, int *val)
{
- struct pkcs11_key *k11;
struct pkcs11_slotinfo *si;
CK_FUNCTION_LIST *f;
- CK_OBJECT_HANDLE obj;
- CK_ULONG tlen = 0;
- CK_RV rv;
- CK_OBJECT_CLASS private_key_class = CKO_PRIVATE_KEY;
- CK_BBOOL true_val = CK_TRUE;
- CK_MECHANISM mech = {
- CKM_RSA_PKCS, NULL_PTR, 0
- };
- CK_ATTRIBUTE key_filter[] = {
- {CKA_CLASS, NULL, sizeof(private_key_class) },
- {CKA_ID, NULL, 0},
- {CKA_SIGN, NULL, sizeof(true_val) }
- };
- char *pin = NULL, prompt[1024];
- int rval = -1;
+ CK_BBOOL flag = 0;
+ CK_ATTRIBUTE attr;
+ CK_RV rv;
- key_filter[0].pValue = &private_key_class;
- key_filter[2].pValue = &true_val;
+ *val = 0;
- if ((k11 = RSA_get_app_data(rsa)) == NULL) {
- error("RSA_get_app_data failed for rsa %p", rsa);
+ if (!k11->provider || !k11->provider->valid) {
+ error("no pkcs11 (valid) provider found");
return (-1);
}
+
+ f = k11->provider->function_list;
+ si = &k11->provider->slotinfo[k11->slotidx];
+
+ attr.type = type;
+ attr.pValue = &flag;
+ attr.ulValueLen = sizeof(flag);
+
+ rv = f->C_GetAttributeValue(si->session, obj, &attr, 1);
+ if (rv != CKR_OK) {
+ error("C_GetAttributeValue failed: %lu", rv);
+ return (-1);
+ }
+ *val = flag != 0;
+ debug_f("provider \"%s\" slot %lu object %lu: attrib %lu = %d",
+ k11->provider->name, k11->slotidx, obj, type, *val);
+ return (0);
+}
+
+static int
+pkcs11_get_key(struct pkcs11_key *k11, CK_MECHANISM_TYPE mech_type)
+{
+ struct pkcs11_slotinfo *si;
+ CK_FUNCTION_LIST *f;
+ CK_OBJECT_HANDLE obj;
+ CK_RV rv;
+ CK_OBJECT_CLASS private_key_class;
+ CK_BBOOL true_val;
+ CK_MECHANISM mech;
+ CK_ATTRIBUTE key_filter[3];
+ int always_auth = 0;
+ int did_login = 0;
+
if (!k11->provider || !k11->provider->valid) {
- error("no pkcs11 (valid) provider for rsa %p", rsa);
+ error("no pkcs11 (valid) provider found");
return (-1);
}
+
f = k11->provider->function_list;
si = &k11->provider->slotinfo[k11->slotidx];
+
if ((si->token.flags & CKF_LOGIN_REQUIRED) && !si->logged_in) {
- if (!pkcs11_interactive) {
- error("need pin entry%s", (si->token.flags &
- CKF_PROTECTED_AUTHENTICATION_PATH) ?
- " on reader keypad" : "");
+ if (pkcs11_login(k11, CKU_USER) < 0) {
+ error("login failed");
return (-1);
}
- if (si->token.flags & CKF_PROTECTED_AUTHENTICATION_PATH)
- verbose("Deferring PIN entry to reader keypad.");
- else {
- snprintf(prompt, sizeof(prompt),
- "Enter PIN for '%s': ", si->token.label);
- pin = read_passphrase(prompt, RP_ALLOW_EOF);
- if (pin == NULL)
- return (-1); /* bail out */
- }
- rv = f->C_Login(si->session, CKU_USER, (u_char *)pin,
- (pin != NULL) ? strlen(pin) : 0);
- if (pin != NULL) {
- explicit_bzero(pin, strlen(pin));
- free(pin);
- }
- if (rv != CKR_OK && rv != CKR_USER_ALREADY_LOGGED_IN) {
- error("C_Login failed: %lu", rv);
- return (-1);
- }
- si->logged_in = 1;
+ did_login = 1;
}
+
+ memset(&key_filter, 0, sizeof(key_filter));
+ private_key_class = CKO_PRIVATE_KEY;
+ key_filter[0].type = CKA_CLASS;
+ key_filter[0].pValue = &private_key_class;
+ key_filter[0].ulValueLen = sizeof(private_key_class);
+
+ key_filter[1].type = CKA_ID;
key_filter[1].pValue = k11->keyid;
key_filter[1].ulValueLen = k11->keyid_len;
+
+ true_val = CK_TRUE;
+ key_filter[2].type = CKA_SIGN;
+ key_filter[2].pValue = &true_val;
+ key_filter[2].ulValueLen = sizeof(true_val);
+
/* try to find object w/CKA_SIGN first, retry w/o */
if (pkcs11_find(k11->provider, k11->slotidx, key_filter, 3, &obj) < 0 &&
pkcs11_find(k11->provider, k11->slotidx, key_filter, 2, &obj) < 0) {
error("cannot find private key");
- } else if ((rv = f->C_SignInit(si->session, &mech, obj)) != CKR_OK) {
+ return (-1);
+ }
+
+ memset(&mech, 0, sizeof(mech));
+ mech.mechanism = mech_type;
+ mech.pParameter = NULL_PTR;
+ mech.ulParameterLen = 0;
+
+ if ((rv = f->C_SignInit(si->session, &mech, obj)) != CKR_OK) {
error("C_SignInit failed: %lu", rv);
- } else {
- /* XXX handle CKR_BUFFER_TOO_SMALL */
- tlen = RSA_size(rsa);
- rv = f->C_Sign(si->session, (CK_BYTE *)from, flen, to, &tlen);
- if (rv == CKR_OK)
- rval = tlen;
- else
- error("C_Sign failed: %lu", rv);
+ return (-1);
+ }
+
+ pkcs11_check_obj_bool_attrib(k11, obj, CKA_ALWAYS_AUTHENTICATE,
+ &always_auth); /* ignore errors here */
+ if (always_auth && !did_login) {
+ debug_f("always-auth key");
+ if (pkcs11_login(k11, CKU_CONTEXT_SPECIFIC) < 0) {
+ error("login failed for always-auth key");
+ return (-1);
+ }
+ }
+
+ return (0);
+}
+
+/* openssl callback doing the actual signing operation */
+static int
+pkcs11_rsa_private_encrypt(int flen, const u_char *from, u_char *to, RSA *rsa,
+ int padding)
+{
+ struct pkcs11_key *k11;
+ struct pkcs11_slotinfo *si;
+ CK_FUNCTION_LIST *f;
+ CK_ULONG tlen = 0;
+ CK_RV rv;
+ int rval = -1;
+
+ if ((k11 = RSA_get_ex_data(rsa, rsa_idx)) == NULL) {
+ error("RSA_get_ex_data failed");
+ return (-1);
}
+
+ if (pkcs11_get_key(k11, CKM_RSA_PKCS) == -1) {
+ error("pkcs11_get_key failed");
+ return (-1);
+ }
+
+ f = k11->provider->function_list;
+ si = &k11->provider->slotinfo[k11->slotidx];
+ tlen = RSA_size(rsa);
+
+ /* XXX handle CKR_BUFFER_TOO_SMALL */
+ rv = f->C_Sign(si->session, (CK_BYTE *)from, flen, to, &tlen);
+ if (rv == CKR_OK)
+ rval = tlen;
+ else
+ error("C_Sign failed: %lu", rv);
+
return (rval);
}
@@ -310,13 +460,36 @@ pkcs11_rsa_private_decrypt(int flen, const u_char *from, u_char *to, RSA *rsa,
return (-1);
}
+static int
+pkcs11_rsa_start_wrapper(void)
+{
+ if (rsa_method != NULL)
+ return (0);
+ rsa_method = RSA_meth_dup(RSA_get_default_method());
+ if (rsa_method == NULL)
+ return (-1);
+ rsa_idx = RSA_get_ex_new_index(0, "ssh-pkcs11-rsa",
+ NULL, NULL, pkcs11_k11_free);
+ if (rsa_idx == -1)
+ return (-1);
+ if (!RSA_meth_set1_name(rsa_method, "pkcs11") ||
+ !RSA_meth_set_priv_enc(rsa_method, pkcs11_rsa_private_encrypt) ||
+ !RSA_meth_set_priv_dec(rsa_method, pkcs11_rsa_private_decrypt)) {
+ error_f("setup pkcs11 method failed");
+ return (-1);
+ }
+ return (0);
+}
+
/* redirect private key operations for rsa key to pkcs11 token */
static int
pkcs11_rsa_wrap(struct pkcs11_provider *provider, CK_ULONG slotidx,
CK_ATTRIBUTE *keyid_attrib, RSA *rsa)
{
struct pkcs11_key *k11;
- const RSA_METHOD *def = RSA_get_default_method();
+
+ if (pkcs11_rsa_start_wrapper() == -1)
+ return (-1);
k11 = xcalloc(1, sizeof(*k11));
k11->provider = provider;
@@ -328,22 +501,126 @@ pkcs11_rsa_wrap(struct pkcs11_provider *provider, CK_ULONG slotidx,
k11->keyid = xmalloc(k11->keyid_len);
memcpy(k11->keyid, keyid_attrib->pValue, k11->keyid_len);
}
- k11->rsa_method = RSA_meth_dup(def);
- if (k11->rsa_method == NULL)
- fatal("%s: RSA_meth_dup failed", __func__);
- k11->orig_finish = RSA_meth_get_finish(def);
- if (!RSA_meth_set1_name(k11->rsa_method, "pkcs11") ||
- !RSA_meth_set_priv_enc(k11->rsa_method,
- pkcs11_rsa_private_encrypt) ||
- !RSA_meth_set_priv_dec(k11->rsa_method,
- pkcs11_rsa_private_decrypt) ||
- !RSA_meth_set_finish(k11->rsa_method, pkcs11_rsa_finish))
- fatal("%s: setup pkcs11 method failed", __func__);
- RSA_set_method(rsa, k11->rsa_method);
- RSA_set_app_data(rsa, k11);
+
+ RSA_set_method(rsa, rsa_method);
+ RSA_set_ex_data(rsa, rsa_idx, k11);
+ return (0);
+}
+
+#ifdef HAVE_EC_KEY_METHOD_NEW
+/* openssl callback doing the actual signing operation */
+static ECDSA_SIG *
+ecdsa_do_sign(const unsigned char *dgst, int dgst_len, const BIGNUM *inv,
+ const BIGNUM *rp, EC_KEY *ec)
+{
+ struct pkcs11_key *k11;
+ struct pkcs11_slotinfo *si;
+ CK_FUNCTION_LIST *f;
+ CK_ULONG siglen = 0, bnlen;
+ CK_RV rv;
+ ECDSA_SIG *ret = NULL;
+ u_char *sig;
+ BIGNUM *r = NULL, *s = NULL;
+
+ if ((k11 = EC_KEY_get_ex_data(ec, ec_key_idx)) == NULL) {
+ ossl_error("EC_KEY_get_key_method_data failed for ec");
+ return (NULL);
+ }
+
+ if (pkcs11_get_key(k11, CKM_ECDSA) == -1) {
+ error("pkcs11_get_key failed");
+ return (NULL);
+ }
+
+ f = k11->provider->function_list;
+ si = &k11->provider->slotinfo[k11->slotidx];
+
+ siglen = ECDSA_size(ec);
+ sig = xmalloc(siglen);
+
+ /* XXX handle CKR_BUFFER_TOO_SMALL */
+ rv = f->C_Sign(si->session, (CK_BYTE *)dgst, dgst_len, sig, &siglen);
+ if (rv != CKR_OK) {
+ error("C_Sign failed: %lu", rv);
+ goto done;
+ }
+ if (siglen < 64 || siglen > 132 || siglen % 2) {
+ ossl_error("d2i_ECDSA_SIG failed");
+ goto done;
+ }
+ bnlen = siglen/2;
+ if ((ret = ECDSA_SIG_new()) == NULL) {
+ error("ECDSA_SIG_new failed");
+ goto done;
+ }
+ if ((r = BN_bin2bn(sig, bnlen, NULL)) == NULL ||
+ (s = BN_bin2bn(sig+bnlen, bnlen, NULL)) == NULL) {
+ ossl_error("d2i_ECDSA_SIG failed");
+ ECDSA_SIG_free(ret);
+ ret = NULL;
+ goto done;
+ }
+ if (!ECDSA_SIG_set0(ret, r, s)) {
+ error_f("ECDSA_SIG_set0 failed");
+ ECDSA_SIG_free(ret);
+ ret = NULL;
+ goto done;
+ }
+ r = s = NULL; /* now owned by ret */
+ /* success */
+ done:
+ BN_free(r);
+ BN_free(s);
+ free(sig);
+
+ return (ret);
+}
+
+static int
+pkcs11_ecdsa_start_wrapper(void)
+{
+ int (*orig_sign)(int, const unsigned char *, int, unsigned char *,
+ unsigned int *, const BIGNUM *, const BIGNUM *, EC_KEY *) = NULL;
+
+ if (ec_key_method != NULL)
+ return (0);
+ ec_key_idx = EC_KEY_get_ex_new_index(0, "ssh-pkcs11-ecdsa",
+ NULL, NULL, pkcs11_k11_free);
+ if (ec_key_idx == -1)
+ return (-1);
+ ec_key_method = EC_KEY_METHOD_new(EC_KEY_OpenSSL());
+ if (ec_key_method == NULL)
+ return (-1);
+ EC_KEY_METHOD_get_sign(ec_key_method, &orig_sign, NULL, NULL);
+ EC_KEY_METHOD_set_sign(ec_key_method, orig_sign, NULL, ecdsa_do_sign);
return (0);
}
+static int
+pkcs11_ecdsa_wrap(struct pkcs11_provider *provider, CK_ULONG slotidx,
+ CK_ATTRIBUTE *keyid_attrib, EC_KEY *ec)
+{
+ struct pkcs11_key *k11;
+
+ if (pkcs11_ecdsa_start_wrapper() == -1)
+ return (-1);
+
+ k11 = xcalloc(1, sizeof(*k11));
+ k11->provider = provider;
+ provider->refcount++; /* provider referenced by ECDSA key */
+ k11->slotidx = slotidx;
+ /* identify key object on smartcard */
+ k11->keyid_len = keyid_attrib->ulValueLen;
+ k11->keyid = xmalloc(k11->keyid_len);
+ memcpy(k11->keyid, keyid_attrib->pValue, k11->keyid_len);
+
+ EC_KEY_set_method(ec, ec_key_method);
+ EC_KEY_set_ex_data(ec, ec_key_idx, k11);
+
+ return (0);
+}
+#endif /* HAVE_EC_KEY_METHOD_NEW */
+
/* remove trailing spaces */
static void
rmspace(u_char *buf, size_t len)
@@ -364,79 +641,45 @@ rmspace(u_char *buf, size_t len)
* if pin == NULL we delay login until key use
*/
static int
-pkcs11_open_session(struct pkcs11_provider *p, CK_ULONG slotidx, char *pin)
+pkcs11_open_session(struct pkcs11_provider *p, CK_ULONG slotidx, char *pin,
+ CK_ULONG user)
{
- CK_RV rv;
+ struct pkcs11_slotinfo *si;
CK_FUNCTION_LIST *f;
+ CK_RV rv;
CK_SESSION_HANDLE session;
- int login_required;
+ int login_required, ret;
f = p->function_list;
- login_required = p->slotinfo[slotidx].token.flags & CKF_LOGIN_REQUIRED;
- if (pin && login_required && !strlen(pin)) {
+ si = &p->slotinfo[slotidx];
+
+ login_required = si->token.flags & CKF_LOGIN_REQUIRED;
+
+ /* fail early before opening session */
+ if (login_required && !pkcs11_interactive &&
+ (pin == NULL || strlen(pin) == 0)) {
error("pin required");
- return (-1);
+ return (-SSH_PKCS11_ERR_PIN_REQUIRED);
}
if ((rv = f->C_OpenSession(p->slotlist[slotidx], CKF_RW_SESSION|
- CKF_SERIAL_SESSION, NULL, NULL, &session))
- != CKR_OK) {
+ CKF_SERIAL_SESSION, NULL, NULL, &session)) != CKR_OK) {
error("C_OpenSession failed: %lu", rv);
return (-1);
}
- if (login_required && pin) {
- rv = f->C_Login(session, CKU_USER,
- (u_char *)pin, strlen(pin));
+ if (login_required && pin != NULL && strlen(pin) != 0) {
+ rv = f->C_Login(session, user, (u_char *)pin, strlen(pin));
if (rv != CKR_OK && rv != CKR_USER_ALREADY_LOGGED_IN) {
error("C_Login failed: %lu", rv);
+ ret = (rv == CKR_PIN_LOCKED) ?
+ -SSH_PKCS11_ERR_PIN_LOCKED :
+ -SSH_PKCS11_ERR_LOGIN_FAIL;
if ((rv = f->C_CloseSession(session)) != CKR_OK)
error("C_CloseSession failed: %lu", rv);
- return (-1);
+ return (ret);
}
- p->slotinfo[slotidx].logged_in = 1;
+ si->logged_in = 1;
}
- p->slotinfo[slotidx].session = session;
- return (0);
-}
-
-/*
- * lookup public keys for token in slot identified by slotidx,
- * add 'wrapped' public keys to the 'keysp' array and increment nkeys.
- * keysp points to an (possibly empty) array with *nkeys keys.
- */
-static int pkcs11_fetch_keys_filter(struct pkcs11_provider *, CK_ULONG,
- CK_ATTRIBUTE [], CK_ATTRIBUTE [3], struct sshkey ***, int *)
- __attribute__((__bounded__(__minbytes__,4, 3 * sizeof(CK_ATTRIBUTE))));
-
-static int
-pkcs11_fetch_keys(struct pkcs11_provider *p, CK_ULONG slotidx,
- struct sshkey ***keysp, int *nkeys)
-{
- CK_OBJECT_CLASS pubkey_class = CKO_PUBLIC_KEY;
- CK_OBJECT_CLASS cert_class = CKO_CERTIFICATE;
- CK_ATTRIBUTE pubkey_filter[] = {
- { CKA_CLASS, NULL, sizeof(pubkey_class) }
- };
- CK_ATTRIBUTE cert_filter[] = {
- { CKA_CLASS, NULL, sizeof(cert_class) }
- };
- CK_ATTRIBUTE pubkey_attribs[] = {
- { CKA_ID, NULL, 0 },
- { CKA_MODULUS, NULL, 0 },
- { CKA_PUBLIC_EXPONENT, NULL, 0 }
- };
- CK_ATTRIBUTE cert_attribs[] = {
- { CKA_ID, NULL, 0 },
- { CKA_SUBJECT, NULL, 0 },
- { CKA_VALUE, NULL, 0 }
- };
- pubkey_filter[0].pValue = &pubkey_class;
- cert_filter[0].pValue = &cert_class;
-
- if (pkcs11_fetch_keys_filter(p, slotidx, pubkey_filter, pubkey_attribs,
- keysp, nkeys) < 0 ||
- pkcs11_fetch_keys_filter(p, slotidx, cert_filter, cert_attribs,
- keysp, nkeys) < 0)
- return (-1);
+ si->session = session;
return (0);
}
@@ -451,6 +694,381 @@ pkcs11_key_included(struct sshkey ***keysp, int *nkeys, struct sshkey *key)
return (0);
}
+#ifdef HAVE_EC_KEY_METHOD_NEW
+static struct sshkey *
+pkcs11_fetch_ecdsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx,
+ CK_OBJECT_HANDLE *obj)
+{
+ CK_ATTRIBUTE key_attr[3];
+ CK_SESSION_HANDLE session;
+ CK_FUNCTION_LIST *f = NULL;
+ CK_RV rv;
+ ASN1_OCTET_STRING *octet = NULL;
+ EC_KEY *ec = NULL;
+ EC_GROUP *group = NULL;
+ struct sshkey *key = NULL;
+ const unsigned char *attrp = NULL;
+ int i;
+ int nid;
+
+ memset(&key_attr, 0, sizeof(key_attr));
+ key_attr[0].type = CKA_ID;
+ key_attr[1].type = CKA_EC_POINT;
+ key_attr[2].type = CKA_EC_PARAMS;
+
+ session = p->slotinfo[slotidx].session;
+ f = p->function_list;
+
+ /* figure out size of the attributes */
+ rv = f->C_GetAttributeValue(session, *obj, key_attr, 3);
+ if (rv != CKR_OK) {
+ error("C_GetAttributeValue failed: %lu", rv);
+ return (NULL);
+ }
+
+ /*
+ * Allow CKA_ID (always first attribute) to be empty, but
+ * ensure that none of the others are zero length.
+ * XXX assumes CKA_ID is always first.
+ */
+ if (key_attr[1].ulValueLen == 0 ||
+ key_attr[2].ulValueLen == 0) {
+ error("invalid attribute length");
+ return (NULL);
+ }
+
+ /* allocate buffers for attributes */
+ for (i = 0; i < 3; i++)
+ if (key_attr[i].ulValueLen > 0)
+ key_attr[i].pValue = xcalloc(1, key_attr[i].ulValueLen);
+
+ /* retrieve ID, public point and curve parameters of EC key */
+ rv = f->C_GetAttributeValue(session, *obj, key_attr, 3);
+ if (rv != CKR_OK) {
+ error("C_GetAttributeValue failed: %lu", rv);
+ goto fail;
+ }
+
+ ec = EC_KEY_new();
+ if (ec == NULL) {
+ error("EC_KEY_new failed");
+ goto fail;
+ }
+
+ attrp = key_attr[2].pValue;
+ group = d2i_ECPKParameters(NULL, &attrp, key_attr[2].ulValueLen);
+ if (group == NULL) {
+ ossl_error("d2i_ECPKParameters failed");
+ goto fail;
+ }
+
+ if (EC_KEY_set_group(ec, group) == 0) {
+ ossl_error("EC_KEY_set_group failed");
+ goto fail;
+ }
+
+ if (key_attr[1].ulValueLen <= 2) {
+ error("CKA_EC_POINT too small");
+ goto fail;
+ }
+
+ attrp = key_attr[1].pValue;
+ octet = d2i_ASN1_OCTET_STRING(NULL, &attrp, key_attr[1].ulValueLen);
+ if (octet == NULL) {
+ ossl_error("d2i_ASN1_OCTET_STRING failed");
+ goto fail;
+ }
+ attrp = octet->data;
+ if (o2i_ECPublicKey(&ec, &attrp, octet->length) == NULL) {
+ ossl_error("o2i_ECPublicKey failed");
+ goto fail;
+ }
+
+ nid = sshkey_ecdsa_key_to_nid(ec);
+ if (nid < 0) {
+ error("couldn't get curve nid");
+ goto fail;
+ }
+
+ if (pkcs11_ecdsa_wrap(p, slotidx, &key_attr[0], ec))
+ goto fail;
+
+ key = sshkey_new(KEY_UNSPEC);
+ if (key == NULL) {
+ error("sshkey_new failed");
+ goto fail;
+ }
+
+ key->ecdsa = ec;
+ key->ecdsa_nid = nid;
+ key->type = KEY_ECDSA;
+ key->flags |= SSHKEY_FLAG_EXT;
+ ec = NULL; /* now owned by key */
+
+fail:
+ for (i = 0; i < 3; i++)
+ free(key_attr[i].pValue);
+ if (ec)
+ EC_KEY_free(ec);
+ if (group)
+ EC_GROUP_free(group);
+ if (octet)
+ ASN1_OCTET_STRING_free(octet);
+
+ return (key);
+}
+#endif /* HAVE_EC_KEY_METHOD_NEW */
+
+static struct sshkey *
+pkcs11_fetch_rsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx,
+ CK_OBJECT_HANDLE *obj)
+{
+ CK_ATTRIBUTE key_attr[3];
+ CK_SESSION_HANDLE session;
+ CK_FUNCTION_LIST *f = NULL;
+ CK_RV rv;
+ RSA *rsa = NULL;
+ BIGNUM *rsa_n, *rsa_e;
+ struct sshkey *key = NULL;
+ int i;
+
+ memset(&key_attr, 0, sizeof(key_attr));
+ key_attr[0].type = CKA_ID;
+ key_attr[1].type = CKA_MODULUS;
+ key_attr[2].type = CKA_PUBLIC_EXPONENT;
+
+ session = p->slotinfo[slotidx].session;
+ f = p->function_list;
+
+ /* figure out size of the attributes */
+ rv = f->C_GetAttributeValue(session, *obj, key_attr, 3);
+ if (rv != CKR_OK) {
+ error("C_GetAttributeValue failed: %lu", rv);
+ return (NULL);
+ }
+
+ /*
+ * Allow CKA_ID (always first attribute) to be empty, but
+ * ensure that none of the others are zero length.
+ * XXX assumes CKA_ID is always first.
+ */
+ if (key_attr[1].ulValueLen == 0 ||
+ key_attr[2].ulValueLen == 0) {
+ error("invalid attribute length");
+ return (NULL);
+ }
+
+ /* allocate buffers for attributes */
+ for (i = 0; i < 3; i++)
+ if (key_attr[i].ulValueLen > 0)
+ key_attr[i].pValue = xcalloc(1, key_attr[i].ulValueLen);
+
+ /* retrieve ID, modulus and public exponent of RSA key */
+ rv = f->C_GetAttributeValue(session, *obj, key_attr, 3);
+ if (rv != CKR_OK) {
+ error("C_GetAttributeValue failed: %lu", rv);
+ goto fail;
+ }
+
+ rsa = RSA_new();
+ if (rsa == NULL) {
+ error("RSA_new failed");
+ goto fail;
+ }
+
+ rsa_n = BN_bin2bn(key_attr[1].pValue, key_attr[1].ulValueLen, NULL);
+ rsa_e = BN_bin2bn(key_attr[2].pValue, key_attr[2].ulValueLen, NULL);
+ if (rsa_n == NULL || rsa_e == NULL) {
+ error("BN_bin2bn failed");
+ goto fail;
+ }
+ if (!RSA_set0_key(rsa, rsa_n, rsa_e, NULL))
+ fatal_f("set key");
+ rsa_n = rsa_e = NULL; /* transferred */
+
+ if (pkcs11_rsa_wrap(p, slotidx, &key_attr[0], rsa))
+ goto fail;
+
+ key = sshkey_new(KEY_UNSPEC);
+ if (key == NULL) {
+ error("sshkey_new failed");
+ goto fail;
+ }
+
+ key->rsa = rsa;
+ key->type = KEY_RSA;
+ key->flags |= SSHKEY_FLAG_EXT;
+ rsa = NULL; /* now owned by key */
+
+fail:
+ for (i = 0; i < 3; i++)
+ free(key_attr[i].pValue);
+ RSA_free(rsa);
+
+ return (key);
+}
+
+static int
+pkcs11_fetch_x509_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx,
+ CK_OBJECT_HANDLE *obj, struct sshkey **keyp, char **labelp)
+{
+ CK_ATTRIBUTE cert_attr[3];
+ CK_SESSION_HANDLE session;
+ CK_FUNCTION_LIST *f = NULL;
+ CK_RV rv;
+ X509 *x509 = NULL;
+ X509_NAME *x509_name = NULL;
+ EVP_PKEY *evp;
+ RSA *rsa = NULL;
+#ifdef OPENSSL_HAS_ECC
+ EC_KEY *ec = NULL;
+#endif
+ struct sshkey *key = NULL;
+ int i;
+#ifdef HAVE_EC_KEY_METHOD_NEW
+ int nid;
+#endif
+ const u_char *cp;
+ char *subject = NULL;
+
+ *keyp = NULL;
+ *labelp = NULL;
+
+ memset(&cert_attr, 0, sizeof(cert_attr));
+ cert_attr[0].type = CKA_ID;
+ cert_attr[1].type = CKA_SUBJECT;
+ cert_attr[2].type = CKA_VALUE;
+
+ session = p->slotinfo[slotidx].session;
+ f = p->function_list;
+
+ /* figure out size of the attributes */
+ rv = f->C_GetAttributeValue(session, *obj, cert_attr, 3);
+ if (rv != CKR_OK) {
+ error("C_GetAttributeValue failed: %lu", rv);
+ return -1;
+ }
+
+ /*
+ * Allow CKA_ID (always first attribute) to be empty, but
+ * ensure that none of the others are zero length.
+ * XXX assumes CKA_ID is always first.
+ */
+ if (cert_attr[1].ulValueLen == 0 ||
+ cert_attr[2].ulValueLen == 0) {
+ error("invalid attribute length");
+ return -1;
+ }
+
+ /* allocate buffers for attributes */
+ for (i = 0; i < 3; i++)
+ if (cert_attr[i].ulValueLen > 0)
+ cert_attr[i].pValue = xcalloc(1, cert_attr[i].ulValueLen);
+
+ /* retrieve ID, subject and value of certificate */
+ rv = f->C_GetAttributeValue(session, *obj, cert_attr, 3);
+ if (rv != CKR_OK) {
+ error("C_GetAttributeValue failed: %lu", rv);
+ goto out;
+ }
+
+ /* Decode DER-encoded cert subject */
+ cp = cert_attr[1].pValue;
+ if ((x509_name = d2i_X509_NAME(NULL, &cp,
+ cert_attr[1].ulValueLen)) == NULL ||
+ (subject = X509_NAME_oneline(x509_name, NULL, 0)) == NULL)
+ subject = xstrdup("invalid subject");
+ X509_NAME_free(x509_name);
+
+ cp = cert_attr[2].pValue;
+ if ((x509 = d2i_X509(NULL, &cp, cert_attr[2].ulValueLen)) == NULL) {
+ error("d2i_x509 failed");
+ goto out;
+ }
+
+ if ((evp = X509_get_pubkey(x509)) == NULL) {
+ error("X509_get_pubkey failed");
+ goto out;
+ }
+
+ if (EVP_PKEY_base_id(evp) == EVP_PKEY_RSA) {
+ if (EVP_PKEY_get0_RSA(evp) == NULL) {
+ error("invalid x509; no rsa key");
+ goto out;
+ }
+ if ((rsa = RSAPublicKey_dup(EVP_PKEY_get0_RSA(evp))) == NULL) {
+ error("RSAPublicKey_dup failed");
+ goto out;
+ }
+
+ if (pkcs11_rsa_wrap(p, slotidx, &cert_attr[0], rsa))
+ goto out;
+
+ key = sshkey_new(KEY_UNSPEC);
+ if (key == NULL) {
+ error("sshkey_new failed");
+ goto out;
+ }
+
+ key->rsa = rsa;
+ key->type = KEY_RSA;
+ key->flags |= SSHKEY_FLAG_EXT;
+ rsa = NULL; /* now owned by key */
+#ifdef HAVE_EC_KEY_METHOD_NEW
+ } else if (EVP_PKEY_base_id(evp) == EVP_PKEY_EC) {
+ if (EVP_PKEY_get0_EC_KEY(evp) == NULL) {
+ error("invalid x509; no ec key");
+ goto out;
+ }
+ if ((ec = EC_KEY_dup(EVP_PKEY_get0_EC_KEY(evp))) == NULL) {
+ error("EC_KEY_dup failed");
+ goto out;
+ }
+
+ nid = sshkey_ecdsa_key_to_nid(ec);
+ if (nid < 0) {
+ error("couldn't get curve nid");
+ goto out;
+ }
+
+ if (pkcs11_ecdsa_wrap(p, slotidx, &cert_attr[0], ec))
+ goto out;
+
+ key = sshkey_new(KEY_UNSPEC);
+ if (key == NULL) {
+ error("sshkey_new failed");
+ goto out;
+ }
+
+ key->ecdsa = ec;
+ key->ecdsa_nid = nid;
+ key->type = KEY_ECDSA;
+ key->flags |= SSHKEY_FLAG_EXT;
+ ec = NULL; /* now owned by key */
+#endif /* HAVE_EC_KEY_METHOD_NEW */
+ } else {
+ error("unknown certificate key type");
+ goto out;
+ }
+ out:
+ for (i = 0; i < 3; i++)
+ free(cert_attr[i].pValue);
+ X509_free(x509);
+ RSA_free(rsa);
+#ifdef OPENSSL_HAS_ECC
+ EC_KEY_free(ec);
+#endif
+ if (key == NULL) {
+ free(subject);
+ return -1;
+ }
+ /* success */
+ *keyp = key;
+ *labelp = subject;
+ return 0;
+}
+
+#if 0
static int
have_rsa_key(const RSA *rsa)
{
@@ -459,140 +1077,439 @@ have_rsa_key(const RSA *rsa)
RSA_get0_key(rsa, &rsa_n, &rsa_e, NULL);
return rsa_n != NULL && rsa_e != NULL;
}
+#endif
+
+static void
+note_key(struct pkcs11_provider *p, CK_ULONG slotidx, const char *context,
+ struct sshkey *key)
+{
+ char *fp;
+
+ if ((fp = sshkey_fingerprint(key, SSH_FP_HASH_DEFAULT,
+ SSH_FP_DEFAULT)) == NULL) {
+ error_f("sshkey_fingerprint failed");
+ return;
+ }
+ debug2("%s: provider %s slot %lu: %s %s", context, p->name,
+ (u_long)slotidx, sshkey_type(key), fp);
+ free(fp);
+}
+/*
+ * lookup certificates for token in slot identified by slotidx,
+ * add 'wrapped' public keys to the 'keysp' array and increment nkeys.
+ * keysp points to an (possibly empty) array with *nkeys keys.
+ */
static int
-pkcs11_fetch_keys_filter(struct pkcs11_provider *p, CK_ULONG slotidx,
- CK_ATTRIBUTE filter[], CK_ATTRIBUTE attribs[3],
- struct sshkey ***keysp, int *nkeys)
+pkcs11_fetch_certs(struct pkcs11_provider *p, CK_ULONG slotidx,
+ struct sshkey ***keysp, char ***labelsp, int *nkeys)
{
- struct sshkey *key;
- RSA *rsa;
- X509 *x509;
- EVP_PKEY *evp;
- int i;
- const u_char *cp;
- CK_RV rv;
- CK_OBJECT_HANDLE obj;
- CK_ULONG nfound;
- CK_SESSION_HANDLE session;
- CK_FUNCTION_LIST *f;
+ struct sshkey *key = NULL;
+ CK_OBJECT_CLASS key_class;
+ CK_ATTRIBUTE key_attr[1];
+ CK_SESSION_HANDLE session;
+ CK_FUNCTION_LIST *f = NULL;
+ CK_RV rv;
+ CK_OBJECT_HANDLE obj;
+ CK_ULONG n = 0;
+ int ret = -1;
+ char *label;
+
+ memset(&key_attr, 0, sizeof(key_attr));
+ memset(&obj, 0, sizeof(obj));
+
+ key_class = CKO_CERTIFICATE;
+ key_attr[0].type = CKA_CLASS;
+ key_attr[0].pValue = &key_class;
+ key_attr[0].ulValueLen = sizeof(key_class);
- f = p->function_list;
session = p->slotinfo[slotidx].session;
- /* setup a filter the looks for public keys */
- if ((rv = f->C_FindObjectsInit(session, filter, 1)) != CKR_OK) {
+ f = p->function_list;
+
+ rv = f->C_FindObjectsInit(session, key_attr, 1);
+ if (rv != CKR_OK) {
error("C_FindObjectsInit failed: %lu", rv);
- return (-1);
+ goto fail;
}
+
while (1) {
- /* XXX 3 attributes in attribs[] */
- for (i = 0; i < 3; i++) {
- attribs[i].pValue = NULL;
- attribs[i].ulValueLen = 0;
+ CK_CERTIFICATE_TYPE ck_cert_type;
+
+ rv = f->C_FindObjects(session, &obj, 1, &n);
+ if (rv != CKR_OK) {
+ error("C_FindObjects failed: %lu", rv);
+ goto fail;
}
- if ((rv = f->C_FindObjects(session, &obj, 1, &nfound)) != CKR_OK
- || nfound == 0)
+ if (n == 0)
break;
- /* found a key, so figure out size of the attributes */
- if ((rv = f->C_GetAttributeValue(session, obj, attribs, 3))
- != CKR_OK) {
+
+ memset(&ck_cert_type, 0, sizeof(ck_cert_type));
+ memset(&key_attr, 0, sizeof(key_attr));
+ key_attr[0].type = CKA_CERTIFICATE_TYPE;
+ key_attr[0].pValue = &ck_cert_type;
+ key_attr[0].ulValueLen = sizeof(ck_cert_type);
+
+ rv = f->C_GetAttributeValue(session, obj, key_attr, 1);
+ if (rv != CKR_OK) {
error("C_GetAttributeValue failed: %lu", rv);
- continue;
+ goto fail;
}
- /*
- * Allow CKA_ID (always first attribute) to be empty, but
- * ensure that none of the others are zero length.
- * XXX assumes CKA_ID is always first.
- */
- if (attribs[1].ulValueLen == 0 ||
- attribs[2].ulValueLen == 0) {
+
+ key = NULL;
+ label = NULL;
+ switch (ck_cert_type) {
+ case CKC_X_509:
+ if (pkcs11_fetch_x509_pubkey(p, slotidx, &obj,
+ &key, &label) != 0) {
+ error("failed to fetch key");
+ continue;
+ }
+ break;
+ default:
+ error("skipping unsupported certificate type %lu",
+ ck_cert_type);
continue;
}
- /* allocate buffers for attributes */
- for (i = 0; i < 3; i++) {
- if (attribs[i].ulValueLen > 0) {
- attribs[i].pValue = xmalloc(
- attribs[i].ulValueLen);
+ note_key(p, slotidx, __func__, key);
+ if (pkcs11_key_included(keysp, nkeys, key)) {
+ debug2_f("key already included");;
+ sshkey_free(key);
+ } else {
+ /* expand key array and add key */
+ *keysp = xrecallocarray(*keysp, *nkeys,
+ *nkeys + 1, sizeof(struct sshkey *));
+ (*keysp)[*nkeys] = key;
+ if (labelsp != NULL) {
+ *labelsp = xrecallocarray(*labelsp, *nkeys,
+ *nkeys + 1, sizeof(char *));
+ (*labelsp)[*nkeys] = xstrdup((char *)label);
}
+ *nkeys = *nkeys + 1;
+ debug("have %d keys", *nkeys);
}
+ }
- /*
- * retrieve ID, modulus and public exponent of RSA key,
- * or ID, subject and value for certificates.
- */
- rsa = NULL;
- if ((rv = f->C_GetAttributeValue(session, obj, attribs, 3))
- != CKR_OK) {
+ ret = 0;
+fail:
+ rv = f->C_FindObjectsFinal(session);
+ if (rv != CKR_OK) {
+ error("C_FindObjectsFinal failed: %lu", rv);
+ ret = -1;
+ }
+
+ return (ret);
+}
+
+/*
+ * lookup public keys for token in slot identified by slotidx,
+ * add 'wrapped' public keys to the 'keysp' array and increment nkeys.
+ * keysp points to an (possibly empty) array with *nkeys keys.
+ */
+static int
+pkcs11_fetch_keys(struct pkcs11_provider *p, CK_ULONG slotidx,
+ struct sshkey ***keysp, char ***labelsp, int *nkeys)
+{
+ struct sshkey *key = NULL;
+ CK_OBJECT_CLASS key_class;
+ CK_ATTRIBUTE key_attr[2];
+ CK_SESSION_HANDLE session;
+ CK_FUNCTION_LIST *f = NULL;
+ CK_RV rv;
+ CK_OBJECT_HANDLE obj;
+ CK_ULONG n = 0;
+ int ret = -1;
+
+ memset(&key_attr, 0, sizeof(key_attr));
+ memset(&obj, 0, sizeof(obj));
+
+ key_class = CKO_PUBLIC_KEY;
+ key_attr[0].type = CKA_CLASS;
+ key_attr[0].pValue = &key_class;
+ key_attr[0].ulValueLen = sizeof(key_class);
+
+ session = p->slotinfo[slotidx].session;
+ f = p->function_list;
+
+ rv = f->C_FindObjectsInit(session, key_attr, 1);
+ if (rv != CKR_OK) {
+ error("C_FindObjectsInit failed: %lu", rv);
+ goto fail;
+ }
+
+ while (1) {
+ CK_KEY_TYPE ck_key_type;
+ CK_UTF8CHAR label[256];
+
+ rv = f->C_FindObjects(session, &obj, 1, &n);
+ if (rv != CKR_OK) {
+ error("C_FindObjects failed: %lu", rv);
+ goto fail;
+ }
+ if (n == 0)
+ break;
+
+ memset(&ck_key_type, 0, sizeof(ck_key_type));
+ memset(&key_attr, 0, sizeof(key_attr));
+ key_attr[0].type = CKA_KEY_TYPE;
+ key_attr[0].pValue = &ck_key_type;
+ key_attr[0].ulValueLen = sizeof(ck_key_type);
+ key_attr[1].type = CKA_LABEL;
+ key_attr[1].pValue = &label;
+ key_attr[1].ulValueLen = sizeof(label) - 1;
+
+ rv = f->C_GetAttributeValue(session, obj, key_attr, 2);
+ if (rv != CKR_OK) {
error("C_GetAttributeValue failed: %lu", rv);
- } else if (attribs[1].type == CKA_MODULUS ) {
- if ((rsa = RSA_new()) == NULL) {
- error("RSA_new failed");
- } else {
- BIGNUM *rsa_n, *rsa_e;
-
- rsa_n = BN_bin2bn(attribs[1].pValue,
- attribs[1].ulValueLen, NULL);
- rsa_e = BN_bin2bn(attribs[2].pValue,
- attribs[2].ulValueLen, NULL);
- if (rsa_n != NULL && rsa_e != NULL) {
- if (!RSA_set0_key(rsa,
- rsa_n, rsa_e, NULL))
- fatal("%s: set key", __func__);
- rsa_n = rsa_e = NULL; /* transferred */
- }
- BN_free(rsa_n);
- BN_free(rsa_e);
- }
- } else {
- cp = attribs[2].pValue;
- if ((x509 = X509_new()) == NULL) {
- error("X509_new failed");
- } else if (d2i_X509(&x509, &cp, attribs[2].ulValueLen)
- == NULL) {
- error("d2i_X509 failed");
- } else if ((evp = X509_get_pubkey(x509)) == NULL ||
- EVP_PKEY_base_id(evp) != EVP_PKEY_RSA ||
- EVP_PKEY_get0_RSA(evp) == NULL) {
- debug("X509_get_pubkey failed or no rsa");
- } else if ((rsa = RSAPublicKey_dup(
- EVP_PKEY_get0_RSA(evp))) == NULL) {
- error("RSAPublicKey_dup");
- }
- X509_free(x509);
+ goto fail;
}
- if (rsa && have_rsa_key(rsa) &&
- pkcs11_rsa_wrap(p, slotidx, &attribs[0], rsa) == 0) {
- if ((key = sshkey_new(KEY_UNSPEC)) == NULL)
- fatal("sshkey_new failed");
- key->rsa = rsa;
- key->type = KEY_RSA;
- key->flags |= SSHKEY_FLAG_EXT;
- if (pkcs11_key_included(keysp, nkeys, key)) {
- sshkey_free(key);
- } else {
- /* expand key array and add key */
- *keysp = xrecallocarray(*keysp, *nkeys,
- *nkeys + 1, sizeof(struct sshkey *));
- (*keysp)[*nkeys] = key;
- *nkeys = *nkeys + 1;
- debug("have %d keys", *nkeys);
+
+ label[key_attr[1].ulValueLen] = '\0';
+
+ switch (ck_key_type) {
+ case CKK_RSA:
+ key = pkcs11_fetch_rsa_pubkey(p, slotidx, &obj);
+ break;
+#ifdef HAVE_EC_KEY_METHOD_NEW
+ case CKK_ECDSA:
+ key = pkcs11_fetch_ecdsa_pubkey(p, slotidx, &obj);
+ break;
+#endif /* HAVE_EC_KEY_METHOD_NEW */
+ default:
+ /* XXX print key type? */
+ key = NULL;
+ error("skipping unsupported key type");
+ }
+
+ if (key == NULL) {
+ error("failed to fetch key");
+ continue;
+ }
+ note_key(p, slotidx, __func__, key);
+ if (pkcs11_key_included(keysp, nkeys, key)) {
+ debug2_f("key already included");;
+ sshkey_free(key);
+ } else {
+ /* expand key array and add key */
+ *keysp = xrecallocarray(*keysp, *nkeys,
+ *nkeys + 1, sizeof(struct sshkey *));
+ (*keysp)[*nkeys] = key;
+ if (labelsp != NULL) {
+ *labelsp = xrecallocarray(*labelsp, *nkeys,
+ *nkeys + 1, sizeof(char *));
+ (*labelsp)[*nkeys] = xstrdup((char *)label);
}
- } else if (rsa) {
- RSA_free(rsa);
+ *nkeys = *nkeys + 1;
+ debug("have %d keys", *nkeys);
}
- for (i = 0; i < 3; i++)
- free(attribs[i].pValue);
}
- if ((rv = f->C_FindObjectsFinal(session)) != CKR_OK)
+
+ ret = 0;
+fail:
+ rv = f->C_FindObjectsFinal(session);
+ if (rv != CKR_OK) {
error("C_FindObjectsFinal failed: %lu", rv);
- return (0);
+ ret = -1;
+ }
+
+ return (ret);
}
-/* register a new provider, fails if provider already exists */
-int
-pkcs11_add_provider(char *provider_id, char *pin, struct sshkey ***keyp)
+#ifdef WITH_PKCS11_KEYGEN
+#define FILL_ATTR(attr, idx, typ, val, len) \
+ { (attr[idx]).type=(typ); (attr[idx]).pValue=(val); (attr[idx]).ulValueLen=len; idx++; }
+
+static struct sshkey *
+pkcs11_rsa_generate_private_key(struct pkcs11_provider *p, CK_ULONG slotidx,
+ char *label, CK_ULONG bits, CK_BYTE keyid, u_int32_t *err)
+{
+ struct pkcs11_slotinfo *si;
+ char *plabel = label ? label : "";
+ int npub = 0, npriv = 0;
+ CK_RV rv;
+ CK_FUNCTION_LIST *f;
+ CK_SESSION_HANDLE session;
+ CK_BBOOL true_val = CK_TRUE, false_val = CK_FALSE;
+ CK_OBJECT_HANDLE pubKey, privKey;
+ CK_ATTRIBUTE tpub[16], tpriv[16];
+ CK_MECHANISM mech = {
+ CKM_RSA_PKCS_KEY_PAIR_GEN, NULL_PTR, 0
+ };
+ CK_BYTE pubExponent[] = {
+ 0x01, 0x00, 0x01 /* RSA_F4 in bytes */
+ };
+ pubkey_filter[0].pValue = &pubkey_class;
+ cert_filter[0].pValue = &cert_class;
+
+ *err = 0;
+
+ FILL_ATTR(tpub, npub, CKA_TOKEN, &true_val, sizeof(true_val));
+ FILL_ATTR(tpub, npub, CKA_LABEL, plabel, strlen(plabel));
+ FILL_ATTR(tpub, npub, CKA_ENCRYPT, &false_val, sizeof(false_val));
+ FILL_ATTR(tpub, npub, CKA_VERIFY, &true_val, sizeof(true_val));
+ FILL_ATTR(tpub, npub, CKA_VERIFY_RECOVER, &false_val,
+ sizeof(false_val));
+ FILL_ATTR(tpub, npub, CKA_WRAP, &false_val, sizeof(false_val));
+ FILL_ATTR(tpub, npub, CKA_DERIVE, &false_val, sizeof(false_val));
+ FILL_ATTR(tpub, npub, CKA_MODULUS_BITS, &bits, sizeof(bits));
+ FILL_ATTR(tpub, npub, CKA_PUBLIC_EXPONENT, pubExponent,
+ sizeof(pubExponent));
+ FILL_ATTR(tpub, npub, CKA_ID, &keyid, sizeof(keyid));
+
+ FILL_ATTR(tpriv, npriv, CKA_TOKEN, &true_val, sizeof(true_val));
+ FILL_ATTR(tpriv, npriv, CKA_LABEL, plabel, strlen(plabel));
+ FILL_ATTR(tpriv, npriv, CKA_PRIVATE, &true_val, sizeof(true_val));
+ FILL_ATTR(tpriv, npriv, CKA_SENSITIVE, &true_val, sizeof(true_val));
+ FILL_ATTR(tpriv, npriv, CKA_DECRYPT, &false_val, sizeof(false_val));
+ FILL_ATTR(tpriv, npriv, CKA_SIGN, &true_val, sizeof(true_val));
+ FILL_ATTR(tpriv, npriv, CKA_SIGN_RECOVER, &false_val,
+ sizeof(false_val));
+ FILL_ATTR(tpriv, npriv, CKA_UNWRAP, &false_val, sizeof(false_val));
+ FILL_ATTR(tpriv, npriv, CKA_DERIVE, &false_val, sizeof(false_val));
+ FILL_ATTR(tpriv, npriv, CKA_ID, &keyid, sizeof(keyid));
+
+ f = p->function_list;
+ si = &p->slotinfo[slotidx];
+ session = si->session;
+
+ if ((rv = f->C_GenerateKeyPair(session, &mech, tpub, npub, tpriv, npriv,
+ &pubKey, &privKey)) != CKR_OK) {
+ error_f("key generation failed: error 0x%lx", rv);
+ *err = rv;
+ return NULL;
+ }
+
+ return pkcs11_fetch_rsa_pubkey(p, slotidx, &pubKey);
+}
+
+static int
+pkcs11_decode_hex(const char *hex, unsigned char **dest, size_t *rlen)
+{
+ size_t i, len;
+ char ptr[3];
+
+ if (dest)
+ *dest = NULL;
+ if (rlen)
+ *rlen = 0;
+
+ if ((len = strlen(hex)) % 2)
+ return -1;
+ len /= 2;
+
+ *dest = xmalloc(len);
+
+ ptr[2] = '\0';
+ for (i = 0; i < len; i++) {
+ ptr[0] = hex[2 * i];
+ ptr[1] = hex[(2 * i) + 1];
+ if (!isxdigit(ptr[0]) || !isxdigit(ptr[1]))
+ return -1;
+ (*dest)[i] = (unsigned char)strtoul(ptr, NULL, 16);
+ }
+
+ if (rlen)
+ *rlen = len;
+
+ return 0;
+}
+
+static struct ec_curve_info {
+ const char *name;
+ const char *oid;
+ const char *oid_encoded;
+ size_t size;
+} ec_curve_infos[] = {
+ {"prime256v1", "1.2.840.10045.3.1.7", "06082A8648CE3D030107", 256},
+ {"secp384r1", "1.3.132.0.34", "06052B81040022", 384},
+ {"secp521r1", "1.3.132.0.35", "06052B81040023", 521},
+ {NULL, NULL, NULL, 0},
+};
+
+static struct sshkey *
+pkcs11_ecdsa_generate_private_key(struct pkcs11_provider *p, CK_ULONG slotidx,
+ char *label, CK_ULONG bits, CK_BYTE keyid, u_int32_t *err)
+{
+ struct pkcs11_slotinfo *si;
+ char *plabel = label ? label : "";
+ int i;
+ size_t ecparams_size;
+ unsigned char *ecparams = NULL;
+ int npub = 0, npriv = 0;
+ CK_RV rv;
+ CK_FUNCTION_LIST *f;
+ CK_SESSION_HANDLE session;
+ CK_BBOOL true_val = CK_TRUE, false_val = CK_FALSE;
+ CK_OBJECT_HANDLE pubKey, privKey;
+ CK_MECHANISM mech = {
+ CKM_EC_KEY_PAIR_GEN, NULL_PTR, 0
+ };
+ CK_ATTRIBUTE tpub[16], tpriv[16];
+
+ *err = 0;
+
+ for (i = 0; ec_curve_infos[i].name; i++) {
+ if (ec_curve_infos[i].size == bits)
+ break;
+ }
+ if (!ec_curve_infos[i].name) {
+ error_f("invalid key size %lu", bits);
+ return NULL;
+ }
+ if (pkcs11_decode_hex(ec_curve_infos[i].oid_encoded, &ecparams,
+ &ecparams_size) == -1) {
+ error_f("invalid oid");
+ return NULL;
+ }
+
+ FILL_ATTR(tpub, npub, CKA_TOKEN, &true_val, sizeof(true_val));
+ FILL_ATTR(tpub, npub, CKA_LABEL, plabel, strlen(plabel));
+ FILL_ATTR(tpub, npub, CKA_ENCRYPT, &false_val, sizeof(false_val));
+ FILL_ATTR(tpub, npub, CKA_VERIFY, &true_val, sizeof(true_val));
+ FILL_ATTR(tpub, npub, CKA_VERIFY_RECOVER, &false_val,
+ sizeof(false_val));
+ FILL_ATTR(tpub, npub, CKA_WRAP, &false_val, sizeof(false_val));
+ FILL_ATTR(tpub, npub, CKA_DERIVE, &false_val, sizeof(false_val));
+ FILL_ATTR(tpub, npub, CKA_EC_PARAMS, ecparams, ecparams_size);
+ FILL_ATTR(tpub, npub, CKA_ID, &keyid, sizeof(keyid));
+
+ FILL_ATTR(tpriv, npriv, CKA_TOKEN, &true_val, sizeof(true_val));
+ FILL_ATTR(tpriv, npriv, CKA_LABEL, plabel, strlen(plabel));
+ FILL_ATTR(tpriv, npriv, CKA_PRIVATE, &true_val, sizeof(true_val));
+ FILL_ATTR(tpriv, npriv, CKA_SENSITIVE, &true_val, sizeof(true_val));
+ FILL_ATTR(tpriv, npriv, CKA_DECRYPT, &false_val, sizeof(false_val));
+ FILL_ATTR(tpriv, npriv, CKA_SIGN, &true_val, sizeof(true_val));
+ FILL_ATTR(tpriv, npriv, CKA_SIGN_RECOVER, &false_val,
+ sizeof(false_val));
+ FILL_ATTR(tpriv, npriv, CKA_UNWRAP, &false_val, sizeof(false_val));
+ FILL_ATTR(tpriv, npriv, CKA_DERIVE, &false_val, sizeof(false_val));
+ FILL_ATTR(tpriv, npriv, CKA_ID, &keyid, sizeof(keyid));
+
+ f = p->function_list;
+ si = &p->slotinfo[slotidx];
+ session = si->session;
+
+ if ((rv = f->C_GenerateKeyPair(session, &mech, tpub, npub, tpriv, npriv,
+ &pubKey, &privKey)) != CKR_OK) {
+ error_f("key generation failed: error 0x%lx", rv);
+ *err = rv;
+ return NULL;
+ }
+
+ return pkcs11_fetch_ecdsa_pubkey(p, slotidx, &pubKey);
+}
+#endif /* WITH_PKCS11_KEYGEN */
+
+/*
+ * register a new provider, fails if provider already exists. if
+ * keyp is provided, fetch keys.
+ */
+static int
+pkcs11_register_provider(char *provider_id, char *pin,
+ struct sshkey ***keyp, char ***labelsp,
+ struct pkcs11_provider **providerp, CK_ULONG user)
{
int nkeys, need_finalize = 0;
+ int ret = -1;
struct pkcs11_provider *p = NULL;
void *handle = NULL;
CK_RV (*getfunctionlist)(CK_FUNCTION_LIST **);
@@ -601,13 +1518,20 @@ pkcs11_add_provider(char *provider_id, char *pin, struct sshkey ***keyp)
CK_TOKEN_INFO *token;
CK_ULONG i;
- *keyp = NULL;
+ if (providerp == NULL)
+ goto fail;
+ *providerp = NULL;
+
+ if (keyp != NULL)
+ *keyp = NULL;
+ if (labelsp != NULL)
+ *labelsp = NULL;
+
if (pkcs11_provider_lookup(provider_id) != NULL) {
- debug("%s: provider already registered: %s",
- __func__, provider_id);
+ debug_f("provider already registered: %s", provider_id);
goto fail;
}
- /* open shared pkcs11-libarary */
+ /* open shared pkcs11-library */
if ((handle = dlopen(provider_id, RTLD_NOW)) == NULL) {
error("dlopen %s failed: %s", provider_id, dlerror());
goto fail;
@@ -653,8 +1577,8 @@ pkcs11_add_provider(char *provider_id, char *pin, struct sshkey ***keyp)
goto fail;
}
if (p->nslots == 0) {
- debug("%s: provider %s returned no slots", __func__,
- provider_id);
+ debug_f("provider %s returned no slots", provider_id);
+ ret = -SSH_PKCS11_ERR_NO_SLOTS;
goto fail;
}
p->slotlist = xcalloc(p->nslots, sizeof(CK_SLOT_ID));
@@ -672,13 +1596,12 @@ pkcs11_add_provider(char *provider_id, char *pin, struct sshkey ***keyp)
if ((rv = f->C_GetTokenInfo(p->slotlist[i], token))
!= CKR_OK) {
error("C_GetTokenInfo for provider %s slot %lu "
- "failed: %lu", provider_id, (unsigned long)i, rv);
+ "failed: %lu", provider_id, (u_long)i, rv);
continue;
}
if ((token->flags & CKF_TOKEN_INITIALIZED) == 0) {
- debug2("%s: ignoring uninitialised token in "
- "provider %s slot %lu", __func__,
- provider_id, (unsigned long)i);
+ debug2_f("ignoring uninitialised token in "
+ "provider %s slot %lu", provider_id, (u_long)i);
continue;
}
rmspace(token->label, sizeof(token->label));
@@ -690,43 +1613,274 @@ pkcs11_add_provider(char *provider_id, char *pin, struct sshkey ***keyp)
provider_id, (unsigned long)i,
token->label, token->manufacturerID, token->model,
token->serialNumber, token->flags);
- /* open session, login with pin and retrieve public keys */
- if (pkcs11_open_session(p, i, pin) == 0)
- pkcs11_fetch_keys(p, i, keyp, &nkeys);
- }
- if (nkeys > 0) {
- TAILQ_INSERT_TAIL(&pkcs11_providers, p, next);
- p->refcount++; /* add to provider list */
- return (nkeys);
+ /*
+ * open session, login with pin and retrieve public
+ * keys (if keyp is provided)
+ */
+ if ((ret = pkcs11_open_session(p, i, pin, user)) != 0 ||
+ keyp == NULL)
+ continue;
+ pkcs11_fetch_keys(p, i, keyp, labelsp, &nkeys);
+ pkcs11_fetch_certs(p, i, keyp, labelsp, &nkeys);
+ if (nkeys == 0 && !p->slotinfo[i].logged_in &&
+ pkcs11_interactive) {
+ /*
+ * Some tokens require login before they will
+ * expose keys.
+ */
+ if (pkcs11_login_slot(p, &p->slotinfo[i],
+ CKU_USER) < 0) {
+ error("login failed");
+ continue;
+ }
+ pkcs11_fetch_keys(p, i, keyp, labelsp, &nkeys);
+ pkcs11_fetch_certs(p, i, keyp, labelsp, &nkeys);
+ }
}
- debug("%s: provider %s returned no keys", __func__, provider_id);
- /* don't add the provider, since it does not have any keys */
+
+ /* now owned by caller */
+ *providerp = p;
+
+ TAILQ_INSERT_TAIL(&pkcs11_providers, p, next);
+ p->refcount++; /* add to provider list */
+
+ return (nkeys);
fail:
if (need_finalize && (rv = f->C_Finalize(NULL)) != CKR_OK)
error("C_Finalize for provider %s failed: %lu",
provider_id, rv);
if (p) {
+ free(p->name);
free(p->slotlist);
free(p->slotinfo);
free(p);
}
if (handle)
dlclose(handle);
- return (-1);
+ if (ret > 0)
+ ret = -1;
+ return (ret);
+}
+
+/*
+ * register a new provider and get number of keys hold by the token,
+ * fails if provider already exists
+ */
+int
+pkcs11_add_provider(char *provider_id, char *pin, struct sshkey ***keyp,
+ char ***labelsp)
+{
+ struct pkcs11_provider *p = NULL;
+ int nkeys;
+
+ nkeys = pkcs11_register_provider(provider_id, pin, keyp, labelsp,
+ &p, CKU_USER);
+
+ /* no keys found or some other error, de-register provider */
+ if (nkeys <= 0 && p != NULL) {
+ TAILQ_REMOVE(&pkcs11_providers, p, next);
+ pkcs11_provider_finalize(p);
+ pkcs11_provider_unref(p);
+ }
+ if (nkeys == 0)
+ debug_f("provider %s returned no keys", provider_id);
+
+ return (nkeys);
+}
+
+#ifdef WITH_PKCS11_KEYGEN
+struct sshkey *
+pkcs11_gakp(char *provider_id, char *pin, unsigned int slotidx, char *label,
+ unsigned int type, unsigned int bits, unsigned char keyid, u_int32_t *err)
+{
+ struct pkcs11_provider *p = NULL;
+ struct pkcs11_slotinfo *si;
+ CK_FUNCTION_LIST *f;
+ CK_SESSION_HANDLE session;
+ struct sshkey *k = NULL;
+ int ret = -1, reset_pin = 0, reset_provider = 0;
+ CK_RV rv;
+
+ *err = 0;
+
+ if ((p = pkcs11_provider_lookup(provider_id)) != NULL)
+ debug_f("provider \"%s\" available", provider_id);
+ else if ((ret = pkcs11_register_provider(provider_id, pin, NULL, NULL,
+ &p, CKU_SO)) < 0) {
+ debug_f("could not register provider %s", provider_id);
+ goto out;
+ } else
+ reset_provider = 1;
+
+ f = p->function_list;
+ si = &p->slotinfo[slotidx];
+ session = si->session;
+
+ if ((rv = f->C_SetOperationState(session , pin, strlen(pin),
+ CK_INVALID_HANDLE, CK_INVALID_HANDLE)) != CKR_OK) {
+ debug_f("could not supply SO pin: %lu", rv);
+ reset_pin = 0;
+ } else
+ reset_pin = 1;
+
+ switch (type) {
+ case KEY_RSA:
+ if ((k = pkcs11_rsa_generate_private_key(p, slotidx, label,
+ bits, keyid, err)) == NULL) {
+ debug_f("failed to generate RSA key");
+ goto out;
+ }
+ break;
+ case KEY_ECDSA:
+ if ((k = pkcs11_ecdsa_generate_private_key(p, slotidx, label,
+ bits, keyid, err)) == NULL) {
+ debug_f("failed to generate ECDSA key");
+ goto out;
+ }
+ break;
+ default:
+ *err = SSH_PKCS11_ERR_GENERIC;
+ debug_f("unknown type %d", type);
+ goto out;
+ }
+
+out:
+ if (reset_pin)
+ f->C_SetOperationState(session , NULL, 0, CK_INVALID_HANDLE,
+ CK_INVALID_HANDLE);
+
+ if (reset_provider)
+ pkcs11_del_provider(provider_id);
+
+ return (k);
+}
+
+struct sshkey *
+pkcs11_destroy_keypair(char *provider_id, char *pin, unsigned long slotidx,
+ unsigned char keyid, u_int32_t *err)
+{
+ struct pkcs11_provider *p = NULL;
+ struct pkcs11_slotinfo *si;
+ struct sshkey *k = NULL;
+ int reset_pin = 0, reset_provider = 0;
+ CK_ULONG nattrs;
+ CK_FUNCTION_LIST *f;
+ CK_SESSION_HANDLE session;
+ CK_ATTRIBUTE attrs[16];
+ CK_OBJECT_CLASS key_class;
+ CK_KEY_TYPE key_type;
+ CK_OBJECT_HANDLE obj = CK_INVALID_HANDLE;
+ CK_RV rv;
+
+ *err = 0;
+
+ if ((p = pkcs11_provider_lookup(provider_id)) != NULL) {
+ debug_f("using provider \"%s\"", provider_id);
+ } else if (pkcs11_register_provider(provider_id, pin, NULL, NULL, &p,
+ CKU_SO) < 0) {
+ debug_f("could not register provider %s",
+ provider_id);
+ goto out;
+ } else
+ reset_provider = 1;
+
+ f = p->function_list;
+ si = &p->slotinfo[slotidx];
+ session = si->session;
+
+ if ((rv = f->C_SetOperationState(session , pin, strlen(pin),
+ CK_INVALID_HANDLE, CK_INVALID_HANDLE)) != CKR_OK) {
+ debug_f("could not supply SO pin: %lu", rv);
+ reset_pin = 0;
+ } else
+ reset_pin = 1;
+
+ /* private key */
+ nattrs = 0;
+ key_class = CKO_PRIVATE_KEY;
+ FILL_ATTR(attrs, nattrs, CKA_CLASS, &key_class, sizeof(key_class));
+ FILL_ATTR(attrs, nattrs, CKA_ID, &keyid, sizeof(keyid));
+
+ if (pkcs11_find(p, slotidx, attrs, nattrs, &obj) == 0 &&
+ obj != CK_INVALID_HANDLE) {
+ if ((rv = f->C_DestroyObject(session, obj)) != CKR_OK) {
+ debug_f("could not destroy private key 0x%hhx",
+ keyid);
+ *err = rv;
+ goto out;
+ }
+ }
+
+ /* public key */
+ nattrs = 0;
+ key_class = CKO_PUBLIC_KEY;
+ FILL_ATTR(attrs, nattrs, CKA_CLASS, &key_class, sizeof(key_class));
+ FILL_ATTR(attrs, nattrs, CKA_ID, &keyid, sizeof(keyid));
+
+ if (pkcs11_find(p, slotidx, attrs, nattrs, &obj) == 0 &&
+ obj != CK_INVALID_HANDLE) {
+
+ /* get key type */
+ nattrs = 0;
+ FILL_ATTR(attrs, nattrs, CKA_KEY_TYPE, &key_type,
+ sizeof(key_type));
+ rv = f->C_GetAttributeValue(session, obj, attrs, nattrs);
+ if (rv != CKR_OK) {
+ debug_f("could not get key type of public key 0x%hhx",
+ keyid);
+ *err = rv;
+ key_type = -1;
+ }
+ if (key_type == CKK_RSA)
+ k = pkcs11_fetch_rsa_pubkey(p, slotidx, &obj);
+ else if (key_type == CKK_ECDSA)
+ k = pkcs11_fetch_ecdsa_pubkey(p, slotidx, &obj);
+
+ if ((rv = f->C_DestroyObject(session, obj)) != CKR_OK) {
+ debug_f("could not destroy public key 0x%hhx", keyid);
+ *err = rv;
+ goto out;
+ }
+ }
+
+out:
+ if (reset_pin)
+ f->C_SetOperationState(session , NULL, 0, CK_INVALID_HANDLE,
+ CK_INVALID_HANDLE);
+
+ if (reset_provider)
+ pkcs11_del_provider(provider_id);
+
+ return (k);
}
+#endif /* WITH_PKCS11_KEYGEN */
+#else /* ENABLE_PKCS11 */
-#else
+#include <sys/types.h>
+#include <stdarg.h>
+#include <stdio.h>
+
+#include "log.h"
+#include "sshkey.h"
int
pkcs11_init(int interactive)
{
- return (0);
+ error("%s: dlopen() not supported", __func__);
+ return (-1);
+}
+
+int
+pkcs11_add_provider(char *provider_id, char *pin, struct sshkey ***keyp,
+ char ***labelsp)
+{
+ error("%s: dlopen() not supported", __func__);
+ return (-1);
}
void
pkcs11_terminate(void)
{
- return;
+ error("%s: dlopen() not supported", __func__);
}
-
#endif /* ENABLE_PKCS11 */
diff --git a/crypto/openssh/ssh-pkcs11.h b/crypto/openssh/ssh-pkcs11.h
index 0ced74f29ce7..81f1d7c5d392 100644
--- a/crypto/openssh/ssh-pkcs11.h
+++ b/crypto/openssh/ssh-pkcs11.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssh-pkcs11.h,v 1.4 2015/01/15 09:40:00 djm Exp $ */
+/* $OpenBSD: ssh-pkcs11.h,v 1.6 2020/01/25 00:03:36 djm Exp $ */
/*
* Copyright (c) 2010 Markus Friedl. All rights reserved.
*
@@ -14,10 +14,26 @@
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
+
+/* Errors for pkcs11_add_provider() */
+#define SSH_PKCS11_ERR_GENERIC 1
+#define SSH_PKCS11_ERR_LOGIN_FAIL 2
+#define SSH_PKCS11_ERR_NO_SLOTS 3
+#define SSH_PKCS11_ERR_PIN_REQUIRED 4
+#define SSH_PKCS11_ERR_PIN_LOCKED 5
+
int pkcs11_init(int);
void pkcs11_terminate(void);
-int pkcs11_add_provider(char *, char *, struct sshkey ***);
+int pkcs11_add_provider(char *, char *, struct sshkey ***, char ***);
int pkcs11_del_provider(char *);
+#ifdef WITH_PKCS11_KEYGEN
+struct sshkey *
+ pkcs11_gakp(char *, char *, unsigned int, char *, unsigned int,
+ unsigned int, unsigned char, u_int32_t *);
+struct sshkey *
+ pkcs11_destroy_keypair(char *, char *, unsigned long, unsigned char,
+ u_int32_t *);
+#endif
#if !defined(WITH_OPENSSL) && defined(ENABLE_PKCS11)
#undef ENABLE_PKCS11
diff --git a/crypto/openssh/ssh-sk-client.c b/crypto/openssh/ssh-sk-client.c
new file mode 100644
index 000000000000..e932590094a2
--- /dev/null
+++ b/crypto/openssh/ssh-sk-client.c
@@ -0,0 +1,448 @@
+/* $OpenBSD: ssh-sk-client.c,v 1.9 2021/04/03 06:18:41 djm Exp $ */
+/*
+ * Copyright (c) 2019 Google LLC
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "includes.h"
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/wait.h>
+
+#include <fcntl.h>
+#include <limits.h>
+#include <errno.h>
+#include <signal.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "log.h"
+#include "ssherr.h"
+#include "sshbuf.h"
+#include "sshkey.h"
+#include "msg.h"
+#include "digest.h"
+#include "pathnames.h"
+#include "ssh-sk.h"
+#include "misc.h"
+
+/* #define DEBUG_SK 1 */
+
+static int
+start_helper(int *fdp, pid_t *pidp, void (**osigchldp)(int))
+{
+ void (*osigchld)(int);
+ int oerrno, pair[2];
+ pid_t pid;
+ char *helper, *verbosity = NULL;
+
+ *fdp = -1;
+ *pidp = 0;
+ *osigchldp = SIG_DFL;
+
+ helper = getenv("SSH_SK_HELPER");
+ if (helper == NULL || strlen(helper) == 0)
+ helper = _PATH_SSH_SK_HELPER;
+ if (access(helper, X_OK) != 0) {
+ oerrno = errno;
+ error_f("helper \"%s\" unusable: %s", helper, strerror(errno));
+ errno = oerrno;
+ return SSH_ERR_SYSTEM_ERROR;
+ }
+#ifdef DEBUG_SK
+ verbosity = "-vvv";
+#endif
+
+ /* Start helper */
+ if (socketpair(AF_UNIX, SOCK_STREAM, 0, pair) == -1) {
+ error("socketpair: %s", strerror(errno));
+ return SSH_ERR_SYSTEM_ERROR;
+ }
+ osigchld = ssh_signal(SIGCHLD, SIG_DFL);
+ if ((pid = fork()) == -1) {
+ oerrno = errno;
+ error("fork: %s", strerror(errno));
+ close(pair[0]);
+ close(pair[1]);
+ ssh_signal(SIGCHLD, osigchld);
+ errno = oerrno;
+ return SSH_ERR_SYSTEM_ERROR;
+ }
+ if (pid == 0) {
+ if ((dup2(pair[1], STDIN_FILENO) == -1) ||
+ (dup2(pair[1], STDOUT_FILENO) == -1)) {
+ error_f("dup2: %s", strerror(errno));
+ _exit(1);
+ }
+ close(pair[0]);
+ close(pair[1]);
+ closefrom(STDERR_FILENO + 1);
+ debug_f("starting %s %s", helper,
+ verbosity == NULL ? "" : verbosity);
+ execlp(helper, helper, verbosity, (char *)NULL);
+ error_f("execlp: %s", strerror(errno));
+ _exit(1);
+ }
+ close(pair[1]);
+
+ /* success */
+ debug3_f("started pid=%ld", (long)pid);
+ *fdp = pair[0];
+ *pidp = pid;
+ *osigchldp = osigchld;
+ return 0;
+}
+
+static int
+reap_helper(pid_t pid)
+{
+ int status, oerrno;
+
+ debug3_f("pid=%ld", (long)pid);
+
+ errno = 0;
+ while (waitpid(pid, &status, 0) == -1) {
+ if (errno == EINTR) {
+ errno = 0;
+ continue;
+ }
+ oerrno = errno;
+ error_f("waitpid: %s", strerror(errno));
+ errno = oerrno;
+ return SSH_ERR_SYSTEM_ERROR;
+ }
+ if (!WIFEXITED(status)) {
+ error_f("helper exited abnormally");
+ return SSH_ERR_AGENT_FAILURE;
+ } else if (WEXITSTATUS(status) != 0) {
+ error_f("helper exited with non-zero exit status");
+ return SSH_ERR_AGENT_FAILURE;
+ }
+ return 0;
+}
+
+static int
+client_converse(struct sshbuf *msg, struct sshbuf **respp, u_int type)
+{
+ int oerrno, fd, r2, ll, r = SSH_ERR_INTERNAL_ERROR;
+ u_int rtype, rerr;
+ pid_t pid;
+ u_char version;
+ void (*osigchld)(int);
+ struct sshbuf *req = NULL, *resp = NULL;
+ *respp = NULL;
+
+ if ((r = start_helper(&fd, &pid, &osigchld)) != 0)
+ return r;
+
+ if ((req = sshbuf_new()) == NULL || (resp = sshbuf_new()) == NULL) {
+ r = SSH_ERR_ALLOC_FAIL;
+ goto out;
+ }
+ /* Request preamble: type, log_on_stderr, log_level */
+ ll = log_level_get();
+ if ((r = sshbuf_put_u32(req, type)) != 0 ||
+ (r = sshbuf_put_u8(req, log_is_on_stderr() != 0)) != 0 ||
+ (r = sshbuf_put_u32(req, ll < 0 ? 0 : ll)) != 0 ||
+ (r = sshbuf_putb(req, msg)) != 0) {
+ error_fr(r, "compose");
+ goto out;
+ }
+ if ((r = ssh_msg_send(fd, SSH_SK_HELPER_VERSION, req)) != 0) {
+ error_fr(r, "send");
+ goto out;
+ }
+ if ((r = ssh_msg_recv(fd, resp)) != 0) {
+ error_fr(r, "receive");
+ goto out;
+ }
+ if ((r = sshbuf_get_u8(resp, &version)) != 0) {
+ error_fr(r, "parse version");
+ goto out;
+ }
+ if (version != SSH_SK_HELPER_VERSION) {
+ error_f("unsupported version: got %u, expected %u",
+ version, SSH_SK_HELPER_VERSION);
+ r = SSH_ERR_INVALID_FORMAT;
+ goto out;
+ }
+ if ((r = sshbuf_get_u32(resp, &rtype)) != 0) {
+ error_fr(r, "parse message type");
+ goto out;
+ }
+ if (rtype == SSH_SK_HELPER_ERROR) {
+ if ((r = sshbuf_get_u32(resp, &rerr)) != 0) {
+ error_fr(r, "parse");
+ goto out;
+ }
+ debug_f("helper returned error -%u", rerr);
+ /* OpenSSH error values are negative; encoded as -err on wire */
+ if (rerr == 0 || rerr >= INT_MAX)
+ r = SSH_ERR_INTERNAL_ERROR;
+ else
+ r = -(int)rerr;
+ goto out;
+ } else if (rtype != type) {
+ error_f("helper returned incorrect message type %u, "
+ "expecting %u", rtype, type);
+ r = SSH_ERR_INTERNAL_ERROR;
+ goto out;
+ }
+ /* success */
+ r = 0;
+ out:
+ oerrno = errno;
+ close(fd);
+ if ((r2 = reap_helper(pid)) != 0) {
+ if (r == 0) {
+ r = r2;
+ oerrno = errno;
+ }
+ }
+ if (r == 0) {
+ *respp = resp;
+ resp = NULL;
+ }
+ sshbuf_free(req);
+ sshbuf_free(resp);
+ ssh_signal(SIGCHLD, osigchld);
+ errno = oerrno;
+ return r;
+
+}
+
+int
+sshsk_sign(const char *provider, struct sshkey *key,
+ u_char **sigp, size_t *lenp, const u_char *data, size_t datalen,
+ u_int compat, const char *pin)
+{
+ int oerrno, r = SSH_ERR_INTERNAL_ERROR;
+ char *fp = NULL;
+ struct sshbuf *kbuf = NULL, *req = NULL, *resp = NULL;
+
+ *sigp = NULL;
+ *lenp = 0;
+
+#ifndef ENABLE_SK
+ return SSH_ERR_KEY_TYPE_UNKNOWN;
+#endif
+
+ if ((kbuf = sshbuf_new()) == NULL ||
+ (req = sshbuf_new()) == NULL) {
+ r = SSH_ERR_ALLOC_FAIL;
+ goto out;
+ }
+
+ if ((r = sshkey_private_serialize(key, kbuf)) != 0) {
+ error_fr(r, "encode key");
+ goto out;
+ }
+ if ((r = sshbuf_put_stringb(req, kbuf)) != 0 ||
+ (r = sshbuf_put_cstring(req, provider)) != 0 ||
+ (r = sshbuf_put_string(req, data, datalen)) != 0 ||
+ (r = sshbuf_put_cstring(req, NULL)) != 0 || /* alg */
+ (r = sshbuf_put_u32(req, compat)) != 0 ||
+ (r = sshbuf_put_cstring(req, pin)) != 0) {
+ error_fr(r, "compose");
+ goto out;
+ }
+
+ if ((fp = sshkey_fingerprint(key, SSH_FP_HASH_DEFAULT,
+ SSH_FP_DEFAULT)) == NULL) {
+ error_f("sshkey_fingerprint failed");
+ r = SSH_ERR_ALLOC_FAIL;
+ goto out;
+ }
+ if ((r = client_converse(req, &resp, SSH_SK_HELPER_SIGN)) != 0)
+ goto out;
+
+ if ((r = sshbuf_get_string(resp, sigp, lenp)) != 0) {
+ error_fr(r, "parse signature");
+ r = SSH_ERR_INVALID_FORMAT;
+ goto out;
+ }
+ if (sshbuf_len(resp) != 0) {
+ error_f("trailing data in response");
+ r = SSH_ERR_INVALID_FORMAT;
+ goto out;
+ }
+ /* success */
+ r = 0;
+ out:
+ oerrno = errno;
+ if (r != 0) {
+ freezero(*sigp, *lenp);
+ *sigp = NULL;
+ *lenp = 0;
+ }
+ sshbuf_free(kbuf);
+ sshbuf_free(req);
+ sshbuf_free(resp);
+ errno = oerrno;
+ return r;
+}
+
+int
+sshsk_enroll(int type, const char *provider_path, const char *device,
+ const char *application, const char *userid, uint8_t flags,
+ const char *pin, struct sshbuf *challenge_buf,
+ struct sshkey **keyp, struct sshbuf *attest)
+{
+ int oerrno, r = SSH_ERR_INTERNAL_ERROR;
+ struct sshbuf *kbuf = NULL, *abuf = NULL, *req = NULL, *resp = NULL;
+ struct sshkey *key = NULL;
+
+ *keyp = NULL;
+ if (attest != NULL)
+ sshbuf_reset(attest);
+
+#ifndef ENABLE_SK
+ return SSH_ERR_KEY_TYPE_UNKNOWN;
+#endif
+
+ if (type < 0)
+ return SSH_ERR_INVALID_ARGUMENT;
+
+ if ((abuf = sshbuf_new()) == NULL ||
+ (kbuf = sshbuf_new()) == NULL ||
+ (req = sshbuf_new()) == NULL) {
+ r = SSH_ERR_ALLOC_FAIL;
+ goto out;
+ }
+
+ if ((r = sshbuf_put_u32(req, (u_int)type)) != 0 ||
+ (r = sshbuf_put_cstring(req, provider_path)) != 0 ||
+ (r = sshbuf_put_cstring(req, device)) != 0 ||
+ (r = sshbuf_put_cstring(req, application)) != 0 ||
+ (r = sshbuf_put_cstring(req, userid)) != 0 ||
+ (r = sshbuf_put_u8(req, flags)) != 0 ||
+ (r = sshbuf_put_cstring(req, pin)) != 0 ||
+ (r = sshbuf_put_stringb(req, challenge_buf)) != 0) {
+ error_fr(r, "compose");
+ goto out;
+ }
+
+ if ((r = client_converse(req, &resp, SSH_SK_HELPER_ENROLL)) != 0)
+ goto out;
+
+ if ((r = sshbuf_get_stringb(resp, kbuf)) != 0 ||
+ (r = sshbuf_get_stringb(resp, abuf)) != 0) {
+ error_fr(r, "parse");
+ r = SSH_ERR_INVALID_FORMAT;
+ goto out;
+ }
+ if (sshbuf_len(resp) != 0) {
+ error_f("trailing data in response");
+ r = SSH_ERR_INVALID_FORMAT;
+ goto out;
+ }
+ if ((r = sshkey_private_deserialize(kbuf, &key)) != 0) {
+ error_fr(r, "encode");
+ goto out;
+ }
+ if (attest != NULL && (r = sshbuf_putb(attest, abuf)) != 0) {
+ error_fr(r, "encode attestation information");
+ goto out;
+ }
+
+ /* success */
+ r = 0;
+ *keyp = key;
+ key = NULL;
+ out:
+ oerrno = errno;
+ sshkey_free(key);
+ sshbuf_free(kbuf);
+ sshbuf_free(abuf);
+ sshbuf_free(req);
+ sshbuf_free(resp);
+ errno = oerrno;
+ return r;
+}
+
+int
+sshsk_load_resident(const char *provider_path, const char *device,
+ const char *pin, struct sshkey ***keysp, size_t *nkeysp)
+{
+ int oerrno, r = SSH_ERR_INTERNAL_ERROR;
+ struct sshbuf *kbuf = NULL, *req = NULL, *resp = NULL;
+ struct sshkey *key = NULL, **keys = NULL, **tmp;
+ size_t i, nkeys = 0;
+
+ *keysp = NULL;
+ *nkeysp = 0;
+
+ if ((resp = sshbuf_new()) == NULL ||
+ (kbuf = sshbuf_new()) == NULL ||
+ (req = sshbuf_new()) == NULL) {
+ r = SSH_ERR_ALLOC_FAIL;
+ goto out;
+ }
+
+ if ((r = sshbuf_put_cstring(req, provider_path)) != 0 ||
+ (r = sshbuf_put_cstring(req, device)) != 0 ||
+ (r = sshbuf_put_cstring(req, pin)) != 0) {
+ error_fr(r, "compose");
+ goto out;
+ }
+
+ if ((r = client_converse(req, &resp, SSH_SK_HELPER_LOAD_RESIDENT)) != 0)
+ goto out;
+
+ while (sshbuf_len(resp) != 0) {
+ /* key, comment */
+ if ((r = sshbuf_get_stringb(resp, kbuf)) != 0 ||
+ (r = sshbuf_get_cstring(resp, NULL, NULL)) != 0) {
+ error_fr(r, "parse signature");
+ r = SSH_ERR_INVALID_FORMAT;
+ goto out;
+ }
+ if ((r = sshkey_private_deserialize(kbuf, &key)) != 0) {
+ error_fr(r, "decode key");
+ goto out;
+ }
+ if ((tmp = recallocarray(keys, nkeys, nkeys + 1,
+ sizeof(*keys))) == NULL) {
+ error_f("recallocarray keys failed");
+ goto out;
+ }
+ debug_f("keys[%zu]: %s %s", nkeys, sshkey_type(key),
+ key->sk_application);
+ keys = tmp;
+ keys[nkeys++] = key;
+ key = NULL;
+ }
+
+ /* success */
+ r = 0;
+ *keysp = keys;
+ *nkeysp = nkeys;
+ keys = NULL;
+ nkeys = 0;
+ out:
+ oerrno = errno;
+ for (i = 0; i < nkeys; i++)
+ sshkey_free(keys[i]);
+ free(keys);
+ sshkey_free(key);
+ sshbuf_free(kbuf);
+ sshbuf_free(req);
+ sshbuf_free(resp);
+ errno = oerrno;
+ return r;
+}
diff --git a/crypto/openssh/ssh-sk-helper.8 b/crypto/openssh/ssh-sk-helper.8
new file mode 100644
index 000000000000..3c53da1ec796
--- /dev/null
+++ b/crypto/openssh/ssh-sk-helper.8
@@ -0,0 +1,66 @@
+.\" $OpenBSD: ssh-sk-helper.8,v 1.3 2019/12/21 20:22:34 naddy Exp $
+.\"
+.\" Copyright (c) 2010 Markus Friedl. 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.
+.\"
+.Dd $Mdocdate: December 21 2019 $
+.Dt SSH-SK-HELPER 8
+.Os
+.Sh NAME
+.Nm ssh-sk-helper
+.Nd OpenSSH helper for FIDO authenticator support
+.Sh SYNOPSIS
+.Nm
+.Op Fl v
+.Sh DESCRIPTION
+.Nm
+is used by
+.Xr ssh-agent 1
+to access keys provided by a FIDO authenticator.
+.Pp
+.Nm
+is not intended to be invoked by the user, but from
+.Xr ssh-agent 1 .
+.Pp
+A single option is supported:
+.Bl -tag -width Ds
+.It Fl v
+Verbose mode.
+Causes
+.Nm
+to print debugging messages about its progress.
+This is helpful in debugging problems.
+Multiple
+.Fl v
+options increase the verbosity.
+The maximum is 3.
+.Pp
+Note that
+.Xr ssh-agent 1
+will automatically pass the
+.Fl v
+flag to
+.Nm
+when it has itself been placed in debug mode.
+.El
+.Sh SEE ALSO
+.Xr ssh 1 ,
+.Xr ssh-add 1 ,
+.Xr ssh-agent 1
+.Sh HISTORY
+.Nm
+first appeared in
+.Ox 6.7 .
+.Sh AUTHORS
+.An Damien Miller Aq Mt djm@openbsd.org
diff --git a/crypto/openssh/ssh-sk-helper.c b/crypto/openssh/ssh-sk-helper.c
new file mode 100644
index 000000000000..21a08919d340
--- /dev/null
+++ b/crypto/openssh/ssh-sk-helper.c
@@ -0,0 +1,364 @@
+/* $OpenBSD: ssh-sk-helper.c,v 1.11 2020/10/18 11:32:02 djm Exp $ */
+/*
+ * Copyright (c) 2019 Google LLC
+ *
+ * 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.
+ */
+
+/*
+ * This is a tiny program used to isolate the address space used for
+ * security key middleware signing operations from ssh-agent. It is similar
+ * to ssh-pkcs11-helper.c but considerably simpler as the operations for
+ * security keys are stateless.
+ *
+ * Please crank SSH_SK_HELPER_VERSION in sshkey.h for any incompatible
+ * protocol changes.
+ */
+
+#include "includes.h"
+
+#include <limits.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <errno.h>
+
+#include "xmalloc.h"
+#include "log.h"
+#include "sshkey.h"
+#include "authfd.h"
+#include "misc.h"
+#include "sshbuf.h"
+#include "msg.h"
+#include "uidswap.h"
+#include "sshkey.h"
+#include "ssherr.h"
+#include "ssh-sk.h"
+
+#ifdef ENABLE_SK
+extern char *__progname;
+
+static struct sshbuf *reply_error(int r, char *fmt, ...)
+ __attribute__((__format__ (printf, 2, 3)));
+
+static struct sshbuf *
+reply_error(int r, char *fmt, ...)
+{
+ char *msg;
+ va_list ap;
+ struct sshbuf *resp;
+
+ va_start(ap, fmt);
+ xvasprintf(&msg, fmt, ap);
+ va_end(ap);
+ debug("%s: %s", __progname, msg);
+ free(msg);
+
+ if (r >= 0)
+ fatal_f("invalid error code %d", r);
+
+ if ((resp = sshbuf_new()) == NULL)
+ fatal("%s: sshbuf_new failed", __progname);
+ if (sshbuf_put_u32(resp, SSH_SK_HELPER_ERROR) != 0 ||
+ sshbuf_put_u32(resp, (u_int)-r) != 0)
+ fatal("%s: buffer error", __progname);
+ return resp;
+}
+
+/* If the specified string is zero length, then free it and replace with NULL */
+static void
+null_empty(char **s)
+{
+ if (s == NULL || *s == NULL || **s != '\0')
+ return;
+
+ free(*s);
+ *s = NULL;
+}
+
+static struct sshbuf *
+process_sign(struct sshbuf *req)
+{
+ int r = SSH_ERR_INTERNAL_ERROR;
+ struct sshbuf *resp, *kbuf;
+ struct sshkey *key = NULL;
+ uint32_t compat;
+ const u_char *message;
+ u_char *sig = NULL;
+ size_t msglen, siglen = 0;
+ char *provider = NULL, *pin = NULL;
+
+ if ((r = sshbuf_froms(req, &kbuf)) != 0 ||
+ (r = sshbuf_get_cstring(req, &provider, NULL)) != 0 ||
+ (r = sshbuf_get_string_direct(req, &message, &msglen)) != 0 ||
+ (r = sshbuf_get_cstring(req, NULL, NULL)) != 0 || /* alg */
+ (r = sshbuf_get_u32(req, &compat)) != 0 ||
+ (r = sshbuf_get_cstring(req, &pin, NULL)) != 0)
+ fatal_r(r, "%s: parse", __progname);
+ if (sshbuf_len(req) != 0)
+ fatal("%s: trailing data in request", __progname);
+
+ if ((r = sshkey_private_deserialize(kbuf, &key)) != 0)
+ fatal_r(r, "%s: Unable to parse private key", __progname);
+ if (!sshkey_is_sk(key)) {
+ fatal("%s: Unsupported key type %s",
+ __progname, sshkey_ssh_name(key));
+ }
+
+ debug_f("ready to sign with key %s, provider %s: "
+ "msg len %zu, compat 0x%lx", sshkey_type(key),
+ provider, msglen, (u_long)compat);
+
+ null_empty(&pin);
+
+ if ((r = sshsk_sign(provider, key, &sig, &siglen,
+ message, msglen, compat, pin)) != 0) {
+ resp = reply_error(r, "Signing failed: %s", ssh_err(r));
+ goto out;
+ }
+
+ if ((resp = sshbuf_new()) == NULL)
+ fatal("%s: sshbuf_new failed", __progname);
+
+ if ((r = sshbuf_put_u32(resp, SSH_SK_HELPER_SIGN)) != 0 ||
+ (r = sshbuf_put_string(resp, sig, siglen)) != 0)
+ fatal_r(r, "%s: compose", __progname);
+ out:
+ sshkey_free(key);
+ sshbuf_free(kbuf);
+ free(provider);
+ if (sig != NULL)
+ freezero(sig, siglen);
+ if (pin != NULL)
+ freezero(pin, strlen(pin));
+ return resp;
+}
+
+static struct sshbuf *
+process_enroll(struct sshbuf *req)
+{
+ int r;
+ u_int type;
+ char *provider, *application, *pin, *device, *userid;
+ uint8_t flags;
+ struct sshbuf *challenge, *attest, *kbuf, *resp;
+ struct sshkey *key;
+
+ if ((attest = sshbuf_new()) == NULL ||
+ (kbuf = sshbuf_new()) == NULL)
+ fatal("%s: sshbuf_new failed", __progname);
+
+ if ((r = sshbuf_get_u32(req, &type)) != 0 ||
+ (r = sshbuf_get_cstring(req, &provider, NULL)) != 0 ||
+ (r = sshbuf_get_cstring(req, &device, NULL)) != 0 ||
+ (r = sshbuf_get_cstring(req, &application, NULL)) != 0 ||
+ (r = sshbuf_get_cstring(req, &userid, NULL)) != 0 ||
+ (r = sshbuf_get_u8(req, &flags)) != 0 ||
+ (r = sshbuf_get_cstring(req, &pin, NULL)) != 0 ||
+ (r = sshbuf_froms(req, &challenge)) != 0)
+ fatal_r(r, "%s: parse", __progname);
+ if (sshbuf_len(req) != 0)
+ fatal("%s: trailing data in request", __progname);
+
+ if (type > INT_MAX)
+ fatal("%s: bad type %u", __progname, type);
+ if (sshbuf_len(challenge) == 0) {
+ sshbuf_free(challenge);
+ challenge = NULL;
+ }
+ null_empty(&device);
+ null_empty(&userid);
+ null_empty(&pin);
+
+ if ((r = sshsk_enroll((int)type, provider, device, application, userid,
+ flags, pin, challenge, &key, attest)) != 0) {
+ resp = reply_error(r, "Enrollment failed: %s", ssh_err(r));
+ goto out;
+ }
+
+ if ((resp = sshbuf_new()) == NULL)
+ fatal("%s: sshbuf_new failed", __progname);
+ if ((r = sshkey_private_serialize(key, kbuf)) != 0)
+ fatal_r(r, "%s: encode key", __progname);
+ if ((r = sshbuf_put_u32(resp, SSH_SK_HELPER_ENROLL)) != 0 ||
+ (r = sshbuf_put_stringb(resp, kbuf)) != 0 ||
+ (r = sshbuf_put_stringb(resp, attest)) != 0)
+ fatal_r(r, "%s: compose", __progname);
+
+ out:
+ sshkey_free(key);
+ sshbuf_free(kbuf);
+ sshbuf_free(attest);
+ sshbuf_free(challenge);
+ free(provider);
+ free(application);
+ if (pin != NULL)
+ freezero(pin, strlen(pin));
+
+ return resp;
+}
+
+static struct sshbuf *
+process_load_resident(struct sshbuf *req)
+{
+ int r;
+ char *provider, *pin, *device;
+ struct sshbuf *kbuf, *resp;
+ struct sshkey **keys = NULL;
+ size_t nkeys = 0, i;
+
+ if ((kbuf = sshbuf_new()) == NULL)
+ fatal("%s: sshbuf_new failed", __progname);
+
+ if ((r = sshbuf_get_cstring(req, &provider, NULL)) != 0 ||
+ (r = sshbuf_get_cstring(req, &device, NULL)) != 0 ||
+ (r = sshbuf_get_cstring(req, &pin, NULL)) != 0)
+ fatal_r(r, "%s: parse", __progname);
+ if (sshbuf_len(req) != 0)
+ fatal("%s: trailing data in request", __progname);
+
+ null_empty(&device);
+ null_empty(&pin);
+
+ if ((r = sshsk_load_resident(provider, device, pin,
+ &keys, &nkeys)) != 0) {
+ resp = reply_error(r, " sshsk_load_resident failed: %s",
+ ssh_err(r));
+ goto out;
+ }
+
+ if ((resp = sshbuf_new()) == NULL)
+ fatal("%s: sshbuf_new failed", __progname);
+
+ if ((r = sshbuf_put_u32(resp, SSH_SK_HELPER_LOAD_RESIDENT)) != 0)
+ fatal_r(r, "%s: compose", __progname);
+
+ for (i = 0; i < nkeys; i++) {
+ debug_f("key %zu %s %s", i, sshkey_type(keys[i]),
+ keys[i]->sk_application);
+ sshbuf_reset(kbuf);
+ if ((r = sshkey_private_serialize(keys[i], kbuf)) != 0)
+ fatal_r(r, "%s: encode key", __progname);
+ if ((r = sshbuf_put_stringb(resp, kbuf)) != 0 ||
+ (r = sshbuf_put_cstring(resp, "")) != 0) /* comment */
+ fatal_r(r, "%s: compose key", __progname);
+ }
+
+ out:
+ for (i = 0; i < nkeys; i++)
+ sshkey_free(keys[i]);
+ free(keys);
+ sshbuf_free(kbuf);
+ free(provider);
+ if (pin != NULL)
+ freezero(pin, strlen(pin));
+ return resp;
+}
+
+int
+main(int argc, char **argv)
+{
+ SyslogFacility log_facility = SYSLOG_FACILITY_AUTH;
+ LogLevel log_level = SYSLOG_LEVEL_ERROR;
+ struct sshbuf *req, *resp;
+ int in, out, ch, r, vflag = 0;
+ u_int rtype, ll = 0;
+ uint8_t version, log_stderr = 0;
+
+ sanitise_stdfd();
+ log_init(__progname, log_level, log_facility, log_stderr);
+
+ while ((ch = getopt(argc, argv, "v")) != -1) {
+ switch (ch) {
+ case 'v':
+ vflag = 1;
+ if (log_level == SYSLOG_LEVEL_ERROR)
+ log_level = SYSLOG_LEVEL_DEBUG1;
+ else if (log_level < SYSLOG_LEVEL_DEBUG3)
+ log_level++;
+ break;
+ default:
+ fprintf(stderr, "usage: %s [-v]\n", __progname);
+ exit(1);
+ }
+ }
+ log_init(__progname, log_level, log_facility, vflag);
+
+ /*
+ * Rearrange our file descriptors a little; we don't trust the
+ * providers not to fiddle with stdin/out.
+ */
+ closefrom(STDERR_FILENO + 1);
+ if ((in = dup(STDIN_FILENO)) == -1 || (out = dup(STDOUT_FILENO)) == -1)
+ fatal("%s: dup: %s", __progname, strerror(errno));
+ close(STDIN_FILENO);
+ close(STDOUT_FILENO);
+ sanitise_stdfd(); /* resets to /dev/null */
+
+ if ((req = sshbuf_new()) == NULL)
+ fatal("%s: sshbuf_new failed", __progname);
+ if (ssh_msg_recv(in, req) < 0)
+ fatal("ssh_msg_recv failed");
+ close(in);
+ debug_f("received message len %zu", sshbuf_len(req));
+
+ if ((r = sshbuf_get_u8(req, &version)) != 0)
+ fatal_r(r, "%s: parse version", __progname);
+ if (version != SSH_SK_HELPER_VERSION) {
+ fatal("unsupported version: received %d, expected %d",
+ version, SSH_SK_HELPER_VERSION);
+ }
+
+ if ((r = sshbuf_get_u32(req, &rtype)) != 0 ||
+ (r = sshbuf_get_u8(req, &log_stderr)) != 0 ||
+ (r = sshbuf_get_u32(req, &ll)) != 0)
+ fatal_r(r, "%s: parse", __progname);
+
+ if (!vflag && log_level_name((LogLevel)ll) != NULL)
+ log_init(__progname, (LogLevel)ll, log_facility, log_stderr);
+
+ switch (rtype) {
+ case SSH_SK_HELPER_SIGN:
+ resp = process_sign(req);
+ break;
+ case SSH_SK_HELPER_ENROLL:
+ resp = process_enroll(req);
+ break;
+ case SSH_SK_HELPER_LOAD_RESIDENT:
+ resp = process_load_resident(req);
+ break;
+ default:
+ fatal("%s: unsupported request type %u", __progname, rtype);
+ }
+ sshbuf_free(req);
+ debug_f("reply len %zu", sshbuf_len(resp));
+
+ if (ssh_msg_send(out, SSH_SK_HELPER_VERSION, resp) == -1)
+ fatal("ssh_msg_send failed");
+ sshbuf_free(resp);
+ close(out);
+
+ return (0);
+}
+#else /* ENABLE_SK */
+#include <stdio.h>
+
+int
+main(int argc, char **argv)
+{
+ fprintf(stderr, "ssh-sk-helper: disabled at compile time\n");
+ return -1;
+}
+#endif /* ENABLE_SK */
diff --git a/crypto/openssh/ssh-sk.c b/crypto/openssh/ssh-sk.c
new file mode 100644
index 000000000000..d254e77f9397
--- /dev/null
+++ b/crypto/openssh/ssh-sk.c
@@ -0,0 +1,826 @@
+/* $OpenBSD: ssh-sk.c,v 1.35 2021/02/26 00:16:58 djm Exp $ */
+/*
+ * Copyright (c) 2019 Google LLC
+ *
+ * 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 DEBUG_SK 1 */
+
+#include "includes.h"
+
+#ifdef ENABLE_SK
+
+#include <dlfcn.h>
+#include <stddef.h>
+#ifdef HAVE_STDINT_H
+# include <stdint.h>
+#endif
+#include <string.h>
+#include <stdio.h>
+
+#ifdef WITH_OPENSSL
+#include <openssl/objects.h>
+#include <openssl/ec.h>
+#endif /* WITH_OPENSSL */
+
+#include "log.h"
+#include "misc.h"
+#include "sshbuf.h"
+#include "sshkey.h"
+#include "ssherr.h"
+#include "digest.h"
+
+#include "ssh-sk.h"
+#include "sk-api.h"
+#include "crypto_api.h"
+
+struct sshsk_provider {
+ char *path;
+ void *dlhandle;
+
+ /* Return the version of the middleware API */
+ uint32_t (*sk_api_version)(void);
+
+ /* Enroll a U2F key (private key generation) */
+ int (*sk_enroll)(int alg, const uint8_t *challenge,
+ size_t challenge_len, const char *application, uint8_t flags,
+ const char *pin, struct sk_option **opts,
+ struct sk_enroll_response **enroll_response);
+
+ /* Sign a challenge */
+ int (*sk_sign)(int alg, const uint8_t *message, size_t message_len,
+ const char *application,
+ const uint8_t *key_handle, size_t key_handle_len,
+ uint8_t flags, const char *pin, struct sk_option **opts,
+ struct sk_sign_response **sign_response);
+
+ /* Enumerate resident keys */
+ int (*sk_load_resident_keys)(const char *pin, struct sk_option **opts,
+ struct sk_resident_key ***rks, size_t *nrks);
+};
+
+/* Built-in version */
+int ssh_sk_enroll(int alg, const uint8_t *challenge,
+ size_t challenge_len, const char *application, uint8_t flags,
+ const char *pin, struct sk_option **opts,
+ struct sk_enroll_response **enroll_response);
+int ssh_sk_sign(int alg, const uint8_t *message, size_t message_len,
+ const char *application,
+ const uint8_t *key_handle, size_t key_handle_len,
+ uint8_t flags, const char *pin, struct sk_option **opts,
+ struct sk_sign_response **sign_response);
+int ssh_sk_load_resident_keys(const char *pin, struct sk_option **opts,
+ struct sk_resident_key ***rks, size_t *nrks);
+
+static void
+sshsk_free(struct sshsk_provider *p)
+{
+ if (p == NULL)
+ return;
+ free(p->path);
+ if (p->dlhandle != NULL)
+ dlclose(p->dlhandle);
+ free(p);
+}
+
+static struct sshsk_provider *
+sshsk_open(const char *path)
+{
+ struct sshsk_provider *ret = NULL;
+ uint32_t version;
+
+ if (path == NULL || *path == '\0') {
+ error("No FIDO SecurityKeyProvider specified");
+ return NULL;
+ }
+ if ((ret = calloc(1, sizeof(*ret))) == NULL) {
+ error_f("calloc failed");
+ return NULL;
+ }
+ if ((ret->path = strdup(path)) == NULL) {
+ error_f("strdup failed");
+ goto fail;
+ }
+ /* Skip the rest if we're using the linked in middleware */
+ if (strcasecmp(ret->path, "internal") == 0) {
+#ifdef ENABLE_SK_INTERNAL
+ ret->sk_enroll = ssh_sk_enroll;
+ ret->sk_sign = ssh_sk_sign;
+ ret->sk_load_resident_keys = ssh_sk_load_resident_keys;
+#else
+ error("internal security key support not enabled");
+#endif
+ return ret;
+ }
+ if ((ret->dlhandle = dlopen(path, RTLD_NOW)) == NULL) {
+ error("Provider \"%s\" dlopen failed: %s", path, dlerror());
+ goto fail;
+ }
+ if ((ret->sk_api_version = dlsym(ret->dlhandle,
+ "sk_api_version")) == NULL) {
+ error("Provider \"%s\" dlsym(sk_api_version) failed: %s",
+ path, dlerror());
+ goto fail;
+ }
+ version = ret->sk_api_version();
+ debug_f("provider %s implements version 0x%08lx", ret->path,
+ (u_long)version);
+ if ((version & SSH_SK_VERSION_MAJOR_MASK) != SSH_SK_VERSION_MAJOR) {
+ error("Provider \"%s\" implements unsupported "
+ "version 0x%08lx (supported: 0x%08lx)",
+ path, (u_long)version, (u_long)SSH_SK_VERSION_MAJOR);
+ goto fail;
+ }
+ if ((ret->sk_enroll = dlsym(ret->dlhandle, "sk_enroll")) == NULL) {
+ error("Provider %s dlsym(sk_enroll) failed: %s",
+ path, dlerror());
+ goto fail;
+ }
+ if ((ret->sk_sign = dlsym(ret->dlhandle, "sk_sign")) == NULL) {
+ error("Provider \"%s\" dlsym(sk_sign) failed: %s",
+ path, dlerror());
+ goto fail;
+ }
+ if ((ret->sk_load_resident_keys = dlsym(ret->dlhandle,
+ "sk_load_resident_keys")) == NULL) {
+ error("Provider \"%s\" dlsym(sk_load_resident_keys) "
+ "failed: %s", path, dlerror());
+ goto fail;
+ }
+ /* success */
+ return ret;
+fail:
+ sshsk_free(ret);
+ return NULL;
+}
+
+static void
+sshsk_free_enroll_response(struct sk_enroll_response *r)
+{
+ if (r == NULL)
+ return;
+ freezero(r->key_handle, r->key_handle_len);
+ freezero(r->public_key, r->public_key_len);
+ freezero(r->signature, r->signature_len);
+ freezero(r->attestation_cert, r->attestation_cert_len);
+ freezero(r->authdata, r->authdata_len);
+ freezero(r, sizeof(*r));
+}
+
+static void
+sshsk_free_sign_response(struct sk_sign_response *r)
+{
+ if (r == NULL)
+ return;
+ freezero(r->sig_r, r->sig_r_len);
+ freezero(r->sig_s, r->sig_s_len);
+ freezero(r, sizeof(*r));
+}
+
+#ifdef WITH_OPENSSL
+/* Assemble key from response */
+static int
+sshsk_ecdsa_assemble(struct sk_enroll_response *resp, struct sshkey **keyp)
+{
+ struct sshkey *key = NULL;
+ struct sshbuf *b = NULL;
+ EC_POINT *q = NULL;
+ int r;
+
+ *keyp = NULL;
+ if ((key = sshkey_new(KEY_ECDSA_SK)) == NULL) {
+ error_f("sshkey_new failed");
+ r = SSH_ERR_ALLOC_FAIL;
+ goto out;
+ }
+ key->ecdsa_nid = NID_X9_62_prime256v1;
+ if ((key->ecdsa = EC_KEY_new_by_curve_name(key->ecdsa_nid)) == NULL ||
+ (q = EC_POINT_new(EC_KEY_get0_group(key->ecdsa))) == NULL ||
+ (b = sshbuf_new()) == NULL) {
+ error_f("allocation failed");
+ r = SSH_ERR_ALLOC_FAIL;
+ goto out;
+ }
+ if ((r = sshbuf_put_string(b,
+ resp->public_key, resp->public_key_len)) != 0) {
+ error_fr(r, "sshbuf_put_string");
+ goto out;
+ }
+ if ((r = sshbuf_get_ec(b, q, EC_KEY_get0_group(key->ecdsa))) != 0) {
+ error_fr(r, "parse");
+ r = SSH_ERR_INVALID_FORMAT;
+ goto out;
+ }
+ if (sshkey_ec_validate_public(EC_KEY_get0_group(key->ecdsa), q) != 0) {
+ error("Authenticator returned invalid ECDSA key");
+ r = SSH_ERR_KEY_INVALID_EC_VALUE;
+ goto out;
+ }
+ if (EC_KEY_set_public_key(key->ecdsa, q) != 1) {
+ /* XXX assume it is a allocation error */
+ error_f("allocation failed");
+ r = SSH_ERR_ALLOC_FAIL;
+ goto out;
+ }
+ /* success */
+ *keyp = key;
+ key = NULL; /* transferred */
+ r = 0;
+ out:
+ EC_POINT_free(q);
+ sshkey_free(key);
+ sshbuf_free(b);
+ return r;
+}
+#endif /* WITH_OPENSSL */
+
+static int
+sshsk_ed25519_assemble(struct sk_enroll_response *resp, struct sshkey **keyp)
+{
+ struct sshkey *key = NULL;
+ int r;
+
+ *keyp = NULL;
+ if (resp->public_key_len != ED25519_PK_SZ) {
+ error_f("invalid size: %zu", resp->public_key_len);
+ r = SSH_ERR_INVALID_FORMAT;
+ goto out;
+ }
+ if ((key = sshkey_new(KEY_ED25519_SK)) == NULL) {
+ error_f("sshkey_new failed");
+ r = SSH_ERR_ALLOC_FAIL;
+ goto out;
+ }
+ if ((key->ed25519_pk = malloc(ED25519_PK_SZ)) == NULL) {
+ error_f("malloc failed");
+ r = SSH_ERR_ALLOC_FAIL;
+ goto out;
+ }
+ memcpy(key->ed25519_pk, resp->public_key, ED25519_PK_SZ);
+ /* success */
+ *keyp = key;
+ key = NULL; /* transferred */
+ r = 0;
+ out:
+ sshkey_free(key);
+ return r;
+}
+
+static int
+sshsk_key_from_response(int alg, const char *application, uint8_t flags,
+ struct sk_enroll_response *resp, struct sshkey **keyp)
+{
+ struct sshkey *key = NULL;
+ int r = SSH_ERR_INTERNAL_ERROR;
+
+ *keyp = NULL;
+
+ /* Check response validity */
+ if (resp->public_key == NULL || resp->key_handle == NULL) {
+ error_f("sk_enroll response invalid");
+ r = SSH_ERR_INVALID_FORMAT;
+ goto out;
+ }
+ switch (alg) {
+#ifdef WITH_OPENSSL
+ case SSH_SK_ECDSA:
+ if ((r = sshsk_ecdsa_assemble(resp, &key)) != 0)
+ goto out;
+ break;
+#endif /* WITH_OPENSSL */
+ case SSH_SK_ED25519:
+ if ((r = sshsk_ed25519_assemble(resp, &key)) != 0)
+ goto out;
+ break;
+ default:
+ error_f("unsupported algorithm %d", alg);
+ r = SSH_ERR_INVALID_ARGUMENT;
+ goto out;
+ }
+ key->sk_flags = flags;
+ if ((key->sk_key_handle = sshbuf_new()) == NULL ||
+ (key->sk_reserved = sshbuf_new()) == NULL) {
+ error_f("allocation failed");
+ r = SSH_ERR_ALLOC_FAIL;
+ goto out;
+ }
+ if ((key->sk_application = strdup(application)) == NULL) {
+ error_f("strdup application failed");
+ r = SSH_ERR_ALLOC_FAIL;
+ goto out;
+ }
+ if ((r = sshbuf_put(key->sk_key_handle, resp->key_handle,
+ resp->key_handle_len)) != 0) {
+ error_fr(r, "put key handle");
+ goto out;
+ }
+ /* success */
+ r = 0;
+ *keyp = key;
+ key = NULL;
+ out:
+ sshkey_free(key);
+ return r;
+}
+
+static int
+skerr_to_ssherr(int skerr)
+{
+ switch (skerr) {
+ case SSH_SK_ERR_UNSUPPORTED:
+ return SSH_ERR_FEATURE_UNSUPPORTED;
+ case SSH_SK_ERR_PIN_REQUIRED:
+ return SSH_ERR_KEY_WRONG_PASSPHRASE;
+ case SSH_SK_ERR_DEVICE_NOT_FOUND:
+ return SSH_ERR_DEVICE_NOT_FOUND;
+ case SSH_SK_ERR_GENERAL:
+ default:
+ return SSH_ERR_INVALID_FORMAT;
+ }
+}
+
+static void
+sshsk_free_options(struct sk_option **opts)
+{
+ size_t i;
+
+ if (opts == NULL)
+ return;
+ for (i = 0; opts[i] != NULL; i++) {
+ free(opts[i]->name);
+ free(opts[i]->value);
+ free(opts[i]);
+ }
+ free(opts);
+}
+
+static int
+sshsk_add_option(struct sk_option ***optsp, size_t *noptsp,
+ const char *name, const char *value, uint8_t required)
+{
+ struct sk_option **opts = *optsp;
+ size_t nopts = *noptsp;
+
+ if ((opts = recallocarray(opts, nopts, nopts + 2, /* extra for NULL */
+ sizeof(*opts))) == NULL) {
+ error_f("array alloc failed");
+ return SSH_ERR_ALLOC_FAIL;
+ }
+ *optsp = opts;
+ *noptsp = nopts + 1;
+ if ((opts[nopts] = calloc(1, sizeof(**opts))) == NULL) {
+ error_f("alloc failed");
+ return SSH_ERR_ALLOC_FAIL;
+ }
+ if ((opts[nopts]->name = strdup(name)) == NULL ||
+ (opts[nopts]->value = strdup(value)) == NULL) {
+ error_f("alloc failed");
+ return SSH_ERR_ALLOC_FAIL;
+ }
+ opts[nopts]->required = required;
+ return 0;
+}
+
+static int
+make_options(const char *device, const char *user_id,
+ struct sk_option ***optsp)
+{
+ struct sk_option **opts = NULL;
+ size_t nopts = 0;
+ int r, ret = SSH_ERR_INTERNAL_ERROR;
+
+ if (device != NULL &&
+ (r = sshsk_add_option(&opts, &nopts, "device", device, 0)) != 0) {
+ ret = r;
+ goto out;
+ }
+ if (user_id != NULL &&
+ (r = sshsk_add_option(&opts, &nopts, "user", user_id, 0)) != 0) {
+ ret = r;
+ goto out;
+ }
+ /* success */
+ *optsp = opts;
+ opts = NULL;
+ nopts = 0;
+ ret = 0;
+ out:
+ sshsk_free_options(opts);
+ return ret;
+}
+
+
+static int
+fill_attestation_blob(const struct sk_enroll_response *resp,
+ struct sshbuf *attest)
+{
+ int r;
+
+ if (attest == NULL)
+ return 0; /* nothing to do */
+ if ((r = sshbuf_put_cstring(attest, "ssh-sk-attest-v01")) != 0 ||
+ (r = sshbuf_put_string(attest,
+ resp->attestation_cert, resp->attestation_cert_len)) != 0 ||
+ (r = sshbuf_put_string(attest,
+ resp->signature, resp->signature_len)) != 0 ||
+ (r = sshbuf_put_string(attest,
+ resp->authdata, resp->authdata_len)) != 0 ||
+ (r = sshbuf_put_u32(attest, 0)) != 0 || /* resvd flags */
+ (r = sshbuf_put_string(attest, NULL, 0)) != 0 /* resvd */) {
+ error_fr(r, "compose");
+ return r;
+ }
+ /* success */
+ return 0;
+}
+
+int
+sshsk_enroll(int type, const char *provider_path, const char *device,
+ const char *application, const char *userid, uint8_t flags,
+ const char *pin, struct sshbuf *challenge_buf,
+ struct sshkey **keyp, struct sshbuf *attest)
+{
+ struct sshsk_provider *skp = NULL;
+ struct sshkey *key = NULL;
+ u_char randchall[32];
+ const u_char *challenge;
+ size_t challenge_len;
+ struct sk_enroll_response *resp = NULL;
+ struct sk_option **opts = NULL;
+ int r = SSH_ERR_INTERNAL_ERROR;
+ int alg;
+
+ debug_f("provider \"%s\", device \"%s\", application \"%s\", "
+ "userid \"%s\", flags 0x%02x, challenge len %zu%s",
+ provider_path, device, application, userid, flags,
+ challenge_buf == NULL ? 0 : sshbuf_len(challenge_buf),
+ (pin != NULL && *pin != '\0') ? " with-pin" : "");
+
+ *keyp = NULL;
+ if (attest)
+ sshbuf_reset(attest);
+
+ if ((r = make_options(device, userid, &opts)) != 0)
+ goto out;
+
+ switch (type) {
+#ifdef WITH_OPENSSL
+ case KEY_ECDSA_SK:
+ alg = SSH_SK_ECDSA;
+ break;
+#endif /* WITH_OPENSSL */
+ case KEY_ED25519_SK:
+ alg = SSH_SK_ED25519;
+ break;
+ default:
+ error_f("unsupported key type");
+ r = SSH_ERR_INVALID_ARGUMENT;
+ goto out;
+ }
+ if (provider_path == NULL) {
+ error_f("missing provider");
+ r = SSH_ERR_INVALID_ARGUMENT;
+ goto out;
+ }
+ if (application == NULL || *application == '\0') {
+ error_f("missing application");
+ r = SSH_ERR_INVALID_ARGUMENT;
+ goto out;
+ }
+ if (challenge_buf == NULL) {
+ debug_f("using random challenge");
+ arc4random_buf(randchall, sizeof(randchall));
+ challenge = randchall;
+ challenge_len = sizeof(randchall);
+ } else if (sshbuf_len(challenge_buf) == 0) {
+ error("Missing enrollment challenge");
+ r = SSH_ERR_INVALID_ARGUMENT;
+ goto out;
+ } else {
+ challenge = sshbuf_ptr(challenge_buf);
+ challenge_len = sshbuf_len(challenge_buf);
+ debug3_f("using explicit challenge len=%zd", challenge_len);
+ }
+ if ((skp = sshsk_open(provider_path)) == NULL) {
+ r = SSH_ERR_INVALID_FORMAT; /* XXX sshsk_open return code? */
+ goto out;
+ }
+ /* XXX validate flags? */
+ /* enroll key */
+ if ((r = skp->sk_enroll(alg, challenge, challenge_len, application,
+ flags, pin, opts, &resp)) != 0) {
+ debug_f("provider \"%s\" failure %d", provider_path, r);
+ r = skerr_to_ssherr(r);
+ goto out;
+ }
+
+ if ((r = sshsk_key_from_response(alg, application, flags,
+ resp, &key)) != 0)
+ goto out;
+
+ /* Optionally fill in the attestation information */
+ if ((r = fill_attestation_blob(resp, attest)) != 0)
+ goto out;
+
+ /* success */
+ *keyp = key;
+ key = NULL; /* transferred */
+ r = 0;
+ out:
+ sshsk_free_options(opts);
+ sshsk_free(skp);
+ sshkey_free(key);
+ sshsk_free_enroll_response(resp);
+ explicit_bzero(randchall, sizeof(randchall));
+ return r;
+}
+
+#ifdef WITH_OPENSSL
+static int
+sshsk_ecdsa_sig(struct sk_sign_response *resp, struct sshbuf *sig)
+{
+ struct sshbuf *inner_sig = NULL;
+ int r = SSH_ERR_INTERNAL_ERROR;
+
+ /* Check response validity */
+ if (resp->sig_r == NULL || resp->sig_s == NULL) {
+ error_f("sk_sign response invalid");
+ r = SSH_ERR_INVALID_FORMAT;
+ goto out;
+ }
+ if ((inner_sig = sshbuf_new()) == NULL) {
+ r = SSH_ERR_ALLOC_FAIL;
+ goto out;
+ }
+ /* Prepare and append inner signature object */
+ if ((r = sshbuf_put_bignum2_bytes(inner_sig,
+ resp->sig_r, resp->sig_r_len)) != 0 ||
+ (r = sshbuf_put_bignum2_bytes(inner_sig,
+ resp->sig_s, resp->sig_s_len)) != 0) {
+ error_fr(r, "compose inner");
+ goto out;
+ }
+ if ((r = sshbuf_put_stringb(sig, inner_sig)) != 0 ||
+ (r = sshbuf_put_u8(sig, resp->flags)) != 0 ||
+ (r = sshbuf_put_u32(sig, resp->counter)) != 0) {
+ error_fr(r, "compose");
+ goto out;
+ }
+#ifdef DEBUG_SK
+ fprintf(stderr, "%s: sig_r:\n", __func__);
+ sshbuf_dump_data(resp->sig_r, resp->sig_r_len, stderr);
+ fprintf(stderr, "%s: sig_s:\n", __func__);
+ sshbuf_dump_data(resp->sig_s, resp->sig_s_len, stderr);
+ fprintf(stderr, "%s: inner:\n", __func__);
+ sshbuf_dump(inner_sig, stderr);
+#endif
+ r = 0;
+ out:
+ sshbuf_free(inner_sig);
+ return r;
+}
+#endif /* WITH_OPENSSL */
+
+static int
+sshsk_ed25519_sig(struct sk_sign_response *resp, struct sshbuf *sig)
+{
+ int r = SSH_ERR_INTERNAL_ERROR;
+
+ /* Check response validity */
+ if (resp->sig_r == NULL) {
+ error_f("sk_sign response invalid");
+ r = SSH_ERR_INVALID_FORMAT;
+ goto out;
+ }
+ if ((r = sshbuf_put_string(sig,
+ resp->sig_r, resp->sig_r_len)) != 0 ||
+ (r = sshbuf_put_u8(sig, resp->flags)) != 0 ||
+ (r = sshbuf_put_u32(sig, resp->counter)) != 0) {
+ error_fr(r, "compose");
+ goto out;
+ }
+#ifdef DEBUG_SK
+ fprintf(stderr, "%s: sig_r:\n", __func__);
+ sshbuf_dump_data(resp->sig_r, resp->sig_r_len, stderr);
+#endif
+ r = 0;
+ out:
+ return r;
+}
+
+int
+sshsk_sign(const char *provider_path, struct sshkey *key,
+ u_char **sigp, size_t *lenp, const u_char *data, size_t datalen,
+ u_int compat, const char *pin)
+{
+ struct sshsk_provider *skp = NULL;
+ int r = SSH_ERR_INTERNAL_ERROR;
+ int type, alg;
+ struct sk_sign_response *resp = NULL;
+ struct sshbuf *inner_sig = NULL, *sig = NULL;
+ struct sk_option **opts = NULL;
+
+ debug_f("provider \"%s\", key %s, flags 0x%02x%s",
+ provider_path, sshkey_type(key), key->sk_flags,
+ (pin != NULL && *pin != '\0') ? " with-pin" : "");
+
+ if (sigp != NULL)
+ *sigp = NULL;
+ if (lenp != NULL)
+ *lenp = 0;
+ type = sshkey_type_plain(key->type);
+ switch (type) {
+#ifdef WITH_OPENSSL
+ case KEY_ECDSA_SK:
+ alg = SSH_SK_ECDSA;
+ break;
+#endif /* WITH_OPENSSL */
+ case KEY_ED25519_SK:
+ alg = SSH_SK_ED25519;
+ break;
+ default:
+ return SSH_ERR_INVALID_ARGUMENT;
+ }
+ if (provider_path == NULL ||
+ key->sk_key_handle == NULL ||
+ key->sk_application == NULL || *key->sk_application == '\0') {
+ r = SSH_ERR_INVALID_ARGUMENT;
+ goto out;
+ }
+ if ((skp = sshsk_open(provider_path)) == NULL) {
+ r = SSH_ERR_INVALID_FORMAT; /* XXX sshsk_open return code? */
+ goto out;
+ }
+#ifdef DEBUG_SK
+ fprintf(stderr, "%s: sk_flags = 0x%02x, sk_application = \"%s\"\n",
+ __func__, key->sk_flags, key->sk_application);
+ fprintf(stderr, "%s: sk_key_handle:\n", __func__);
+ sshbuf_dump(key->sk_key_handle, stderr);
+#endif
+ if ((r = skp->sk_sign(alg, data, datalen, key->sk_application,
+ sshbuf_ptr(key->sk_key_handle), sshbuf_len(key->sk_key_handle),
+ key->sk_flags, pin, opts, &resp)) != 0) {
+ debug_f("sk_sign failed with code %d", r);
+ r = skerr_to_ssherr(r);
+ goto out;
+ }
+ /* Assemble signature */
+ if ((sig = sshbuf_new()) == NULL) {
+ r = SSH_ERR_ALLOC_FAIL;
+ goto out;
+ }
+ if ((r = sshbuf_put_cstring(sig, sshkey_ssh_name_plain(key))) != 0) {
+ error_fr(r, "compose outer");
+ goto out;
+ }
+ switch (type) {
+#ifdef WITH_OPENSSL
+ case KEY_ECDSA_SK:
+ if ((r = sshsk_ecdsa_sig(resp, sig)) != 0)
+ goto out;
+ break;
+#endif /* WITH_OPENSSL */
+ case KEY_ED25519_SK:
+ if ((r = sshsk_ed25519_sig(resp, sig)) != 0)
+ goto out;
+ break;
+ }
+#ifdef DEBUG_SK
+ fprintf(stderr, "%s: sig_flags = 0x%02x, sig_counter = %u\n",
+ __func__, resp->flags, resp->counter);
+ fprintf(stderr, "%s: data to sign:\n", __func__);
+ sshbuf_dump_data(data, datalen, stderr);
+ fprintf(stderr, "%s: sigbuf:\n", __func__);
+ sshbuf_dump(sig, stderr);
+#endif
+ if (sigp != NULL) {
+ if ((*sigp = malloc(sshbuf_len(sig))) == NULL) {
+ r = SSH_ERR_ALLOC_FAIL;
+ goto out;
+ }
+ memcpy(*sigp, sshbuf_ptr(sig), sshbuf_len(sig));
+ }
+ if (lenp != NULL)
+ *lenp = sshbuf_len(sig);
+ /* success */
+ r = 0;
+ out:
+ sshsk_free_options(opts);
+ sshsk_free(skp);
+ sshsk_free_sign_response(resp);
+ sshbuf_free(sig);
+ sshbuf_free(inner_sig);
+ return r;
+}
+
+static void
+sshsk_free_sk_resident_keys(struct sk_resident_key **rks, size_t nrks)
+{
+ size_t i;
+
+ if (nrks == 0 || rks == NULL)
+ return;
+ for (i = 0; i < nrks; i++) {
+ free(rks[i]->application);
+ freezero(rks[i]->key.key_handle, rks[i]->key.key_handle_len);
+ freezero(rks[i]->key.public_key, rks[i]->key.public_key_len);
+ freezero(rks[i]->key.signature, rks[i]->key.signature_len);
+ freezero(rks[i]->key.attestation_cert,
+ rks[i]->key.attestation_cert_len);
+ freezero(rks[i], sizeof(**rks));
+ }
+ free(rks);
+}
+
+int
+sshsk_load_resident(const char *provider_path, const char *device,
+ const char *pin, struct sshkey ***keysp, size_t *nkeysp)
+{
+ struct sshsk_provider *skp = NULL;
+ int r = SSH_ERR_INTERNAL_ERROR;
+ struct sk_resident_key **rks = NULL;
+ size_t i, nrks = 0, nkeys = 0;
+ struct sshkey *key = NULL, **keys = NULL, **tmp;
+ uint8_t flags;
+ struct sk_option **opts = NULL;
+
+ debug_f("provider \"%s\"%s", provider_path,
+ (pin != NULL && *pin != '\0') ? ", have-pin": "");
+
+ if (keysp == NULL || nkeysp == NULL)
+ return SSH_ERR_INVALID_ARGUMENT;
+ *keysp = NULL;
+ *nkeysp = 0;
+
+ if ((r = make_options(device, NULL, &opts)) != 0)
+ goto out;
+ if ((skp = sshsk_open(provider_path)) == NULL) {
+ r = SSH_ERR_INVALID_FORMAT; /* XXX sshsk_open return code? */
+ goto out;
+ }
+ if ((r = skp->sk_load_resident_keys(pin, opts, &rks, &nrks)) != 0) {
+ error("Provider \"%s\" returned failure %d", provider_path, r);
+ r = skerr_to_ssherr(r);
+ goto out;
+ }
+ for (i = 0; i < nrks; i++) {
+ debug3_f("rk %zu: slot = %zu, alg = %d, application = \"%s\"",
+ i, rks[i]->slot, rks[i]->alg, rks[i]->application);
+ /* XXX need better filter here */
+ if (strncmp(rks[i]->application, "ssh:", 4) != 0)
+ continue;
+ switch (rks[i]->alg) {
+ case SSH_SK_ECDSA:
+ case SSH_SK_ED25519:
+ break;
+ default:
+ continue;
+ }
+ flags = SSH_SK_USER_PRESENCE_REQD|SSH_SK_RESIDENT_KEY;
+ if ((rks[i]->flags & SSH_SK_USER_VERIFICATION_REQD))
+ flags |= SSH_SK_USER_VERIFICATION_REQD;
+ if ((r = sshsk_key_from_response(rks[i]->alg,
+ rks[i]->application, flags, &rks[i]->key, &key)) != 0)
+ goto out;
+ if ((tmp = recallocarray(keys, nkeys, nkeys + 1,
+ sizeof(*tmp))) == NULL) {
+ error_f("recallocarray failed");
+ r = SSH_ERR_ALLOC_FAIL;
+ goto out;
+ }
+ keys = tmp;
+ keys[nkeys++] = key;
+ key = NULL;
+ /* XXX synthesise comment */
+ }
+ /* success */
+ *keysp = keys;
+ *nkeysp = nkeys;
+ keys = NULL;
+ nkeys = 0;
+ r = 0;
+ out:
+ sshsk_free_options(opts);
+ sshsk_free(skp);
+ sshsk_free_sk_resident_keys(rks, nrks);
+ sshkey_free(key);
+ if (nkeys != 0) {
+ for (i = 0; i < nkeys; i++)
+ sshkey_free(keys[i]);
+ free(keys);
+ }
+ return r;
+}
+
+#endif /* ENABLE_SK */
diff --git a/crypto/openssh/ssh-sk.h b/crypto/openssh/ssh-sk.h
new file mode 100644
index 000000000000..0f566bbc3859
--- /dev/null
+++ b/crypto/openssh/ssh-sk.h
@@ -0,0 +1,69 @@
+/* $OpenBSD: ssh-sk.h,v 1.10 2020/01/10 23:43:26 djm Exp $ */
+/*
+ * Copyright (c) 2019 Google LLC
+ *
+ * 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 _SSH_SK_H
+#define _SSH_SK_H 1
+
+struct sshbuf;
+struct sshkey;
+struct sk_option;
+
+/* Version of protocol expected from ssh-sk-helper */
+#define SSH_SK_HELPER_VERSION 5
+
+/* ssh-sk-helper messages */
+#define SSH_SK_HELPER_ERROR 0 /* Only valid H->C */
+#define SSH_SK_HELPER_SIGN 1
+#define SSH_SK_HELPER_ENROLL 2
+#define SSH_SK_HELPER_LOAD_RESIDENT 3
+
+/*
+ * Enroll (generate) a new security-key hosted private key of given type
+ * via the specified provider middleware.
+ * If challenge_buf is NULL then a random 256 bit challenge will be used.
+ *
+ * Returns 0 on success or a ssherr.h error code on failure.
+ *
+ * If successful and the attest_data buffer is not NULL then attestation
+ * information is placed there.
+ */
+int sshsk_enroll(int type, const char *provider_path, const char *device,
+ const char *application, const char *userid, uint8_t flags,
+ const char *pin, struct sshbuf *challenge_buf,
+ struct sshkey **keyp, struct sshbuf *attest);
+
+/*
+ * Calculate an ECDSA_SK or ED25519_SK signature using the specified key
+ * and provider middleware.
+ *
+ * Returns 0 on success or a ssherr.h error code on failure.
+ */
+int sshsk_sign(const char *provider_path, struct sshkey *key,
+ u_char **sigp, size_t *lenp, const u_char *data, size_t datalen,
+ u_int compat, const char *pin);
+
+/*
+ * Enumerates and loads all SSH-compatible resident keys from a security
+ * key.
+ *
+ * Returns 0 on success or a ssherr.h error code on failure.
+ */
+int sshsk_load_resident(const char *provider_path, const char *device,
+ const char *pin, struct sshkey ***keysp, size_t *nkeysp);
+
+#endif /* _SSH_SK_H */
+
diff --git a/crypto/openssh/ssh-xmss.c b/crypto/openssh/ssh-xmss.c
index 4c734fd7d5e2..7bd3a96a3bf5 100644
--- a/crypto/openssh/ssh-xmss.c
+++ b/crypto/openssh/ssh-xmss.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssh-xmss.c,v 1.1 2018/02/23 15:58:38 markus Exp $*/
+/* $OpenBSD: ssh-xmss.c,v 1.4 2020/10/19 22:49:23 dtucker Exp $*/
/*
* Copyright (c) 2017 Stefan-Lukas Gazdag.
* Copyright (c) 2017 Markus Friedl.
@@ -62,7 +62,7 @@ ssh_xmss_sign(const struct sshkey *key, u_char **sigp, size_t *lenp,
smlen = slen = datalen + required_siglen;
if ((sig = malloc(slen)) == NULL)
return SSH_ERR_ALLOC_FAIL;
- if ((r = sshkey_xmss_get_state(key, error)) != 0)
+ if ((r = sshkey_xmss_get_state(key, 1)) != 0)
goto out;
if ((ret = xmss_sign(key->xmss_sk, sshkey_xmss_bds_state(key), sig, &smlen,
data, datalen, sshkey_xmss_params(key))) != 0 || smlen <= datalen) {
@@ -90,7 +90,7 @@ ssh_xmss_sign(const struct sshkey *key, u_char **sigp, size_t *lenp,
/* success */
r = 0;
out:
- if ((ret = sshkey_xmss_update_state(key, error)) != 0) {
+ if ((ret = sshkey_xmss_update_state(key, 1)) != 0) {
/* discard signature since we cannot update the state */
if (r == 0 && sigp != NULL && *sigp != NULL) {
explicit_bzero(*sigp, len);
@@ -103,10 +103,8 @@ ssh_xmss_sign(const struct sshkey *key, u_char **sigp, size_t *lenp,
r = ret;
}
sshbuf_free(b);
- if (sig != NULL) {
- explicit_bzero(sig, slen);
- free(sig);
- }
+ if (sig != NULL)
+ freezero(sig, slen);
return r;
}
@@ -166,8 +164,7 @@ ssh_xmss_verify(const struct sshkey *key,
memcpy(sm+len, data, datalen);
if ((ret = xmss_sign_open(m, &mlen, sm, smlen,
key->xmss_pk, sshkey_xmss_params(key))) != 0) {
- debug2("%s: crypto_sign_xmss_open failed: %d",
- __func__, ret);
+ debug2_f("xmss_sign_open failed: %d", ret);
}
if (ret != 0 || mlen != datalen) {
r = SSH_ERR_SIGNATURE_INVALID;
@@ -177,14 +174,10 @@ ssh_xmss_verify(const struct sshkey *key,
/* success */
r = 0;
out:
- if (sm != NULL) {
- explicit_bzero(sm, smlen);
- free(sm);
- }
- if (m != NULL) {
- explicit_bzero(m, smlen); /* NB mlen may be invalid if r != 0 */
- free(m);
- }
+ if (sm != NULL)
+ freezero(sm, smlen);
+ if (m != NULL)
+ freezero(m, smlen);
sshbuf_free(b);
free(ktype);
return r;
diff --git a/crypto/openssh/ssh.1 b/crypto/openssh/ssh.1
index bffaadbbae12..645962bc9d9c 100644
--- a/crypto/openssh/ssh.1
+++ b/crypto/openssh/ssh.1
@@ -33,14 +33,14 @@
.\" (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: ssh.1,v 1.399 2018/09/20 06:58:48 jmc Exp $
+.\" $OpenBSD: ssh.1,v 1.425 2021/07/28 05:57:42 jmc Exp $
.\" $FreeBSD$
-.Dd $Mdocdate: September 20 2018 $
+.Dd $Mdocdate: July 28 2021 $
.Dt SSH 1
.Os
.Sh NAME
.Nm ssh
-.Nd OpenSSH SSH client (remote login program)
+.Nd OpenSSH remote login client
.Sh SYNOPSIS
.Nm ssh
.Op Fl 46AaCfGgKkMNnqsTtVvXxYy
@@ -89,7 +89,7 @@ or a URI of the form
.No ssh:// Oo user @ Oc hostname Op : port .
.Sm on
The user must prove
-his/her identity to the remote machine using one of several methods
+their identity to the remote machine using one of several methods
(see below).
.Pp
If a
@@ -111,7 +111,8 @@ Forces
to use IPv6 addresses only.
.Pp
.It Fl A
-Enables forwarding of the authentication agent connection.
+Enables forwarding of connections from an authentication agent such as
+.Xr ssh-agent 1 .
This can also be specified on a per-host basis in a configuration file.
.Pp
Agent forwarding should be enabled with caution.
@@ -122,6 +123,9 @@ 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 safer alternative may be to use a jump host
+(see
+.Fl J ) .
.Pp
.It Fl a
Disables forwarding of the authentication agent connection.
@@ -230,6 +234,9 @@ the system-wide configuration file
will be ignored.
The default for the per-user configuration file is
.Pa ~/.ssh/config .
+If set to
+.Dq none ,
+no configuration files will be read.
.Pp
.It Fl f
Requests
@@ -253,6 +260,11 @@ then a client started with
.Fl f
will wait for all remote port forwards to be successfully established
before placing itself in the background.
+Refer to the description of
+.Cm ForkAfterAuthentication
+in
+.Xr ssh_config 5
+for details.
.Pp
.It Fl G
Causes
@@ -271,8 +283,8 @@ on the master process.
.It Fl I Ar pkcs11
Specify the PKCS#11 shared library
.Nm
-should use to communicate with a PKCS#11 token providing the user's
-private RSA key.
+should use to communicate with a PKCS#11 token providing keys for user
+authentication.
.Pp
.It Fl i Ar identity_file
Selects a file from which the identity (private key) for
@@ -280,7 +292,9 @@ public key authentication is read.
The default is
.Pa ~/.ssh/id_dsa ,
.Pa ~/.ssh/id_ecdsa ,
-.Pa ~/.ssh/id_ed25519
+.Pa ~/.ssh/id_ecdsa_sk ,
+.Pa ~/.ssh/id_ed25519 ,
+.Pa ~/.ssh/id_ed25519_sk
and
.Pa ~/.ssh/id_rsa .
Identity files may also be specified on
@@ -309,6 +323,11 @@ Multiple jump hops may be specified separated by comma characters.
This is a shortcut to specify a
.Cm ProxyJump
configuration directive.
+Note that configuration directives supplied on the command-line generally
+apply to the destination host and not any specified jump hosts.
+Use
+.Pa ~/.ssh/config
+to specify configuration for jump hosts.
.Pp
.It Fl K
Enables GSSAPI-based authentication and forwarding (delegation) of GSSAPI
@@ -412,6 +431,11 @@ keyword for more information.
.It Fl N
Do not execute a remote command.
This is useful for just forwarding ports.
+Refer to the description of
+.Cm SessionType
+in
+.Xr ssh_config 5
+for details.
.Pp
.It Fl n
Redirects stdin from
@@ -433,6 +457,11 @@ program will be put in the background.
needs to ask for a password or passphrase; see also the
.Fl f
option.)
+Refer to the description of
+.Cm StdinNull
+in
+.Xr ssh_config 5
+for details.
.Pp
.It Fl O Ar ctl_cmd
Control an active connection multiplexing master process.
@@ -472,7 +501,6 @@ For full details of the options listed below, and their possible values, see
.It CanonicalizePermittedCNAMEs
.It CASignatureAlgorithms
.It CertificateFile
-.It ChallengeResponseAuthentication
.It CheckHostIP
.It Ciphers
.It ClearAllForwardings
@@ -486,6 +514,7 @@ For full details of the options listed below, and their possible values, see
.It EscapeChar
.It ExitOnForwardFailure
.It FingerprintHash
+.It ForkAfterAuthentication
.It ForwardAgent
.It ForwardX11
.It ForwardX11Timeout
@@ -496,11 +525,11 @@ For full details of the options listed below, and their possible values, see
.It GSSAPIDelegateCredentials
.It HashKnownHosts
.It Host
+.It HostbasedAcceptedAlgorithms
.It HostbasedAuthentication
-.It HostbasedKeyTypes
.It HostKeyAlgorithms
.It HostKeyAlias
-.It HostName
+.It Hostname
.It IdentitiesOnly
.It IdentityAgent
.It IdentityFile
@@ -508,6 +537,7 @@ For full details of the options listed below, and their possible values, see
.It KbdInteractiveAuthentication
.It KbdInteractiveDevices
.It KexAlgorithms
+.It KnownHostsCommand
.It LocalCommand
.It LocalForward
.It LogLevel
@@ -517,13 +547,14 @@ For full details of the options listed below, and their possible values, see
.It NumberOfPasswordPrompts
.It PasswordAuthentication
.It PermitLocalCommand
+.It PermitRemoteOpen
.It PKCS11Provider
.It Port
.It PreferredAuthentications
.It ProxyCommand
.It ProxyJump
.It ProxyUseFdpass
-.It PubkeyAcceptedKeyTypes
+.It PubkeyAcceptedAlgorithms
.It PubkeyAuthentication
.It RekeyLimit
.It RemoteCommand
@@ -532,7 +563,9 @@ For full details of the options listed below, and their possible values, see
.It SendEnv
.It ServerAliveInterval
.It ServerAliveCountMax
+.It SessionType
.It SetEnv
+.It StdinNull
.It StreamLocalBindMask
.It StreamLocalBindUnlink
.It StrictHostKeyChecking
@@ -554,10 +587,7 @@ This can be specified on a
per-host basis in the configuration file.
.Pp
.It Fl Q Ar query_option
-Queries
-.Nm
-for the algorithms supported for the specified version 2.
-The available features are:
+Queries for the algorithms supported by one of the following features:
.Ar cipher
(supported symmetric ciphers),
.Ar cipher-auth
@@ -576,10 +606,18 @@ flag),
(certificate key types),
.Ar key-plain
(non-certificate key types),
+.Ar key-sig
+(all key types and signature algorithms),
.Ar protocol-version
(supported SSH protocol versions), and
.Ar sig
(supported signature algorithms).
+Alternatively, any keyword from
+.Xr ssh_config 5
+or
+.Xr sshd_config 5
+that takes an algorithm list may be used as an alias for the corresponding
+query_option.
.Pp
.It Fl q
Quiet mode.
@@ -682,6 +720,11 @@ Subsystems facilitate the use of SSH
as a secure transport for other applications (e.g.\&
.Xr sftp 1 ) .
The subsystem is specified as the remote command.
+Refer to the description of
+.Cm SessionType
+in
+.Xr ssh_config 5
+for details.
.Pp
.It Fl T
Disable pseudo-terminal allocation.
@@ -811,7 +854,7 @@ The methods available for authentication are:
GSSAPI-based authentication,
host-based authentication,
public key authentication,
-challenge-response authentication,
+keyboard-interactive authentication,
and password authentication.
Authentication methods are tried in the order specified above,
though
@@ -823,7 +866,7 @@ If the machine the user logs in from is listed in
.Pa /etc/hosts.equiv
or
.Pa /etc/shosts.equiv
-on the remote machine, and the user names are
+on the remote machine, the user is non-root and the user names are
the same on both sides, or if the files
.Pa ~/.rhosts
or
@@ -886,15 +929,19 @@ or higher (e.g. by using the
.Fl v
flag).
.Pp
-The user creates his/her key pair by running
+The user creates their key pair by running
.Xr ssh-keygen 1 .
This stores the private key in
.Pa ~/.ssh/id_dsa
(DSA),
.Pa ~/.ssh/id_ecdsa
(ECDSA),
+.Pa ~/.ssh/id_ecdsa_sk
+(authenticator-hosted ECDSA),
.Pa ~/.ssh/id_ed25519
(Ed25519),
+.Pa ~/.ssh/id_ed25519_sk
+(authenticator-hosted Ed25519),
or
.Pa ~/.ssh/id_rsa
(RSA)
@@ -903,8 +950,12 @@ and stores the public key in
(DSA),
.Pa ~/.ssh/id_ecdsa.pub
(ECDSA),
+.Pa ~/.ssh/id_ecdsa_sk.pub
+(authenticator-hosted ECDSA),
.Pa ~/.ssh/id_ed25519.pub
(Ed25519),
+.Pa ~/.ssh/id_ed25519_sk.pub
+(authenticator-hosted Ed25519),
or
.Pa ~/.ssh/id_rsa.pub
(RSA)
@@ -912,7 +963,7 @@ in the user's home directory.
The user should then copy the public key
to
.Pa ~/.ssh/authorized_keys
-in his/her home directory on the remote machine.
+in their home directory on the remote machine.
The
.Pa authorized_keys
file corresponds to the conventional
@@ -941,11 +992,11 @@ directive in
.Xr ssh_config 5
for more information.
.Pp
-Challenge-response authentication works as follows:
+Keyboard-interactive authentication works as follows:
The server sends an arbitrary
.Qq challenge
-text, and prompts for a response.
-Examples of challenge-response authentication include
+text and prompts for a response, possibly multiple times.
+Examples of keyboard-interactive authentication include
.Bx
Authentication (see
.Xr login.conf 5 )
@@ -1087,49 +1138,35 @@ Increase the verbosity
when errors are being written to stderr.
.El
.Sh TCP FORWARDING
-Forwarding of arbitrary TCP connections over the secure channel can
-be specified either on the command line or in a configuration file.
+Forwarding of arbitrary TCP connections over a 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.
.Pp
-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.
+In the example below, we look at encrypting communication for an IRC client,
+even though the IRC server it connects to does not directly
+support encrypted communication.
This works as follows:
the user connects to the remote host using
.Nm ,
-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,
+specifying the ports to be used to forward the connection.
+After that it is possible to start the program locally,
and
.Nm
-will encrypt and forward the connection.
+will encrypt and forward the connection to the remote server.
.Pp
-The following example tunnels an IRC session from client machine
-.Dq 127.0.0.1
-(localhost)
-to remote server
-.Dq server.example.com :
-.Bd -literal -offset 4n
-$ ssh -f -L 1234:localhost:6667 server.example.com sleep 10
-$ irc -c '#users' -p 1234 pinky 127.0.0.1
-.Ed
-.Pp
-This tunnels a connection to IRC server
+The following example tunnels an IRC session from the client
+to an IRC server at
.Dq server.example.com ,
joining channel
.Dq #users ,
nickname
.Dq pinky ,
-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.
+using the standard IRC port, 6667:
+.Bd -literal -offset 4n
+$ ssh -f -L 6667:localhost:6667 server.example.com sleep 10
+$ irc -c '#users' pinky IRC/127.0.0.1
+.Ed
.Pp
The
.Fl f
@@ -1139,7 +1176,7 @@ and the remote command
.Dq sleep 10
is specified to allow an amount of time
(10 seconds, in the example)
-to start the service which is to be tunnelled.
+to start the program which is going to use the tunnel.
If no connections are made within the time specified,
.Nm
will exit.
@@ -1395,6 +1432,25 @@ or related script.
may be necessary to redirect the input from
.Pa /dev/null
to make this work.)
+.It Ev SSH_ASKPASS_REQUIRE
+Allows further control over the use of an askpass program.
+If this variable is set to
+.Dq never
+then
+.Nm
+will never attempt to use one.
+If it is set to
+.Dq prefer ,
+then
+.Nm
+will prefer to use the askpass program instead of the TTY when requesting
+passwords.
+Finally, if the variable is set to
+.Dq force ,
+then the askpass program will be used for all passphrase input regardless
+of whether
+.Ev DISPLAY
+is set.
.It Ev SSH_AUTH_SOCK
Identifies the path of a
.Ux Ns -domain
@@ -1495,7 +1551,9 @@ above.
.Pp
.It Pa ~/.ssh/id_dsa
.It Pa ~/.ssh/id_ecdsa
+.It Pa ~/.ssh/id_ecdsa_sk
.It Pa ~/.ssh/id_ed25519
+.It Pa ~/.ssh/id_ed25519_sk
.It Pa ~/.ssh/id_rsa
Contains the private key for authentication.
These files
@@ -1509,7 +1567,9 @@ sensitive part of this file using AES-128.
.Pp
.It Pa ~/.ssh/id_dsa.pub
.It Pa ~/.ssh/id_ecdsa.pub
+.It Pa ~/.ssh/id_ecdsa_sk.pub
.It Pa ~/.ssh/id_ed25519.pub
+.It Pa ~/.ssh/id_ed25519_sk.pub
.It Pa ~/.ssh/id_rsa.pub
Contains the public key for authentication.
These files are not
diff --git a/crypto/openssh/ssh.c b/crypto/openssh/ssh.c
index 98217813eac1..a5f04f5d0b19 100644
--- a/crypto/openssh/ssh.c
+++ b/crypto/openssh/ssh.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssh.c,v 1.494 2018/10/03 06:38:35 djm Exp $ */
+/* $OpenBSD: ssh.c,v 1.566 2021/08/08 08:49:09 dtucker Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -16,7 +16,7 @@
* Copyright (c) 1999 Niels Provos. All rights reserved.
* Copyright (c) 2000, 2001, 2002, 2003 Markus Friedl. All rights reserved.
*
- * Modified to work with SSL by Niels Provos <provos@citi.umich.edu>
+ * Modified to work with SSLeay by Niels Provos <provos@citi.umich.edu>
* in Canada (German citizen).
*
* Redistribution and use in source and binary forms, with or without
@@ -66,6 +66,7 @@ __RCSID("$FreeBSD$");
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <stdarg.h>
#include <unistd.h>
#include <limits.h>
#include <locale.h>
@@ -86,7 +87,6 @@ __RCSID("$FreeBSD$");
#include "canohost.h"
#include "compat.h"
#include "cipher.h"
-#include "digest.h"
#include "packet.h"
#include "sshbuf.h"
#include "channels.h"
@@ -127,30 +127,14 @@ int debug_flag = 0;
/* Flag indicating whether a tty should be requested */
int tty_flag = 0;
-/* don't exec a shell */
-int no_shell_flag = 0;
-
-/*
- * Flag indicating that nothing should be read from stdin. This can be set
- * on the command line.
- */
-int stdin_null_flag = 0;
-
/*
* Flag indicating that the current process should be backgrounded and
- * a new slave launched in the foreground for ControlPersist.
+ * a new mux-client launched in the foreground for ControlPersist.
*/
int need_controlpersist_detach = 0;
-/* Copies of flags for ControlPersist foreground slave */
-int ostdin_null_flag, ono_shell_flag, otty_flag, orequest_tty;
-
-/*
- * Flag indicating that ssh should fork after authentication. This is useful
- * so that the passphrase can be entered manually, and then ssh goes to the
- * background.
- */
-int fork_after_authentication_flag = 0;
+/* Copies of flags for ControlPersist foreground mux-client */
+int ostdin_null_flag, osession_type, otty_flag, orequest_tty;
/*
* General data structure for command line options and options configurable
@@ -163,14 +147,16 @@ char *config = NULL;
/*
* Name of the host we are connecting to. This is the name given on the
- * command line, or the HostName specified for the user-supplied name in a
+ * command line, or the Hostname specified for the user-supplied name in a
* configuration file.
*/
char *host;
-/* Various strings used to to percent_expand() arguments */
-static char thishost[NI_MAXHOST], shorthost[NI_MAXHOST], portstr[NI_MAXSERV];
-static char uidstr[32], *host_arg, *conn_hash_hex;
+/*
+ * A config can specify a path to forward, overriding SSH_AUTH_SOCK. If this is
+ * not NULL, forward the socket at this path instead.
+ */
+char *forward_agent_sock_path = NULL;
/* socket address the host resolves to */
struct sockaddr_storage hostaddr;
@@ -181,11 +167,8 @@ Sensitive sensitive_data;
/* command to be executed */
struct sshbuf *command;
-/* Should we execute a command or invoke a subsystem? */
-int subsystem_flag = 0;
-
/* # of replies received for global requests */
-static int remote_forward_confirms_received = 0;
+static int forward_confirms_pending = -1;
/* mux.c */
extern int muxserver_sock;
@@ -208,8 +191,8 @@ usage(void)
exit(255);
}
-static int ssh_session2(struct ssh *, struct passwd *);
-static void load_public_identity_files(struct passwd *);
+static int ssh_session2(struct ssh *, const struct ssh_conn_info *);
+static void load_public_identity_files(const struct ssh_conn_info *);
static void main_sigchld_handler(int);
/* ~/ expand a list of paths. NB. assumes path[n] is heap-allocated. */
@@ -227,6 +210,39 @@ tilde_expand_paths(char **paths, u_int num_paths)
}
/*
+ * Expands the set of percent_expand options used by the majority of keywords
+ * in the client that support percent expansion.
+ * Caller must free returned string.
+ */
+static char *
+default_client_percent_expand(const char *str,
+ const struct ssh_conn_info *cinfo)
+{
+ return percent_expand(str,
+ DEFAULT_CLIENT_PERCENT_EXPAND_ARGS(cinfo),
+ (char *)NULL);
+}
+
+/*
+ * Expands the set of percent_expand options used by the majority of keywords
+ * AND perform environment variable substitution.
+ * Caller must free returned string.
+ */
+static char *
+default_client_percent_dollar_expand(const char *str,
+ const struct ssh_conn_info *cinfo)
+{
+ char *ret;
+
+ ret = percent_dollar_expand(str,
+ DEFAULT_CLIENT_PERCENT_EXPAND_ARGS(cinfo),
+ (char *)NULL);
+ if (ret == NULL)
+ fatal("invalid environment variable expansion");
+ return ret;
+}
+
+/*
* Attempt to resolve a host name / port to a set of addresses and
* optionally return any CNAMEs encountered along the way.
* Returns NULL on failure.
@@ -237,10 +253,13 @@ resolve_host(const char *name, int port, int logerr, char *cname, size_t clen)
{
char strport[NI_MAXSERV];
struct addrinfo hints, *res;
- int gaierr, loglevel = SYSLOG_LEVEL_DEBUG1;
+ int gaierr;
+ LogLevel loglevel = SYSLOG_LEVEL_DEBUG1;
if (port <= 0)
port = default_ssh_port();
+ if (cname != NULL)
+ *cname = '\0';
snprintf(strport, sizeof strport, "%d", port);
memset(&hints, 0, sizeof(hints));
@@ -258,8 +277,8 @@ resolve_host(const char *name, int port, int logerr, char *cname, size_t clen)
}
if (cname != NULL && res->ai_canonname != NULL) {
if (strlcpy(cname, res->ai_canonname, clen) >= clen) {
- error("%s: host \"%s\" cname \"%s\" too long (max %lu)",
- __func__, name, res->ai_canonname, (u_long)clen);
+ error_f("host \"%s\" cname \"%s\" too long (max %lu)",
+ name, res->ai_canonname, (u_long)clen);
if (clen > 0)
*cname = '\0';
}
@@ -323,29 +342,27 @@ resolve_addr(const char *name, int port, char *caddr, size_t clen)
hints.ai_socktype = SOCK_STREAM;
hints.ai_flags = AI_NUMERICHOST|AI_NUMERICSERV;
if ((gaierr = getaddrinfo(name, strport, &hints, &res)) != 0) {
- debug2("%s: could not resolve name %.100s as address: %s",
- __func__, name, ssh_gai_strerror(gaierr));
+ debug2_f("could not resolve name %.100s as address: %s",
+ name, ssh_gai_strerror(gaierr));
return NULL;
}
if (res == NULL) {
- debug("%s: getaddrinfo %.100s returned no addresses",
- __func__, name);
+ debug_f("getaddrinfo %.100s returned no addresses", name);
return NULL;
}
if (res->ai_next != NULL) {
- debug("%s: getaddrinfo %.100s returned multiple addresses",
- __func__, name);
+ debug_f("getaddrinfo %.100s returned multiple addresses", name);
goto fail;
}
if ((gaierr = getnameinfo(res->ai_addr, res->ai_addrlen,
addr, sizeof(addr), NULL, 0, NI_NUMERICHOST)) != 0) {
- debug("%s: Could not format address for name %.100s: %s",
- __func__, name, ssh_gai_strerror(gaierr));
+ debug_f("Could not format address for name %.100s: %s",
+ name, ssh_gai_strerror(gaierr));
goto fail;
}
if (strlcpy(caddr, addr, clen) >= clen) {
- error("%s: host \"%s\" addr \"%s\" too long (max %lu)",
- __func__, name, addr, (u_long)clen);
+ error_f("host \"%s\" addr \"%s\" too long (max %lu)",
+ name, addr, (u_long)clen);
if (clen > 0)
*caddr = '\0';
fail:
@@ -378,7 +395,7 @@ check_follow_cname(int direct, char **namep, const char *cname)
if (!direct &&
options.canonicalize_hostname != SSH_CANONICALISE_ALWAYS)
return 0;
- debug3("%s: check \"%s\" CNAME \"%s\"", __func__, *namep, cname);
+ debug3_f("check \"%s\" CNAME \"%s\"", *namep, cname);
for (i = 0; i < options.num_permitted_cnames; i++) {
rule = options.permitted_cnames + i;
if (match_pattern_list(*namep, rule->source_list, 1) != 1 ||
@@ -412,10 +429,10 @@ resolve_canonicalize(char **hostp, int port)
*/
if ((addrs = resolve_addr(*hostp, port,
newname, sizeof(newname))) != NULL) {
- debug2("%s: hostname %.100s is address", __func__, *hostp);
+ debug2_f("hostname %.100s is address", *hostp);
if (strcasecmp(*hostp, newname) != 0) {
- debug2("%s: canonicalised address \"%s\" => \"%s\"",
- __func__, *hostp, newname);
+ debug2_f("canonicalised address \"%s\" => \"%s\"",
+ *hostp, newname);
free(*hostp);
*hostp = xstrdup(newname);
}
@@ -428,8 +445,7 @@ resolve_canonicalize(char **hostp, int port)
* attempts at canonicalisation.
*/
if (is_addr_fast(*hostp)) {
- debug("%s: hostname %.100s is an unrecognised address",
- __func__, *hostp);
+ debug_f("hostname %.100s is an unrecognised address", *hostp);
return NULL;
}
@@ -448,7 +464,7 @@ resolve_canonicalize(char **hostp, int port)
/* If domain name is anchored, then resolve it now */
if ((*hostp)[strlen(*hostp) - 1] == '.') {
- debug3("%s: name is fully qualified", __func__);
+ debug3_f("name is fully qualified");
fullhost = xstrdup(*hostp);
if ((addrs = resolve_host(fullhost, port, 0,
newname, sizeof(newname))) != NULL)
@@ -464,17 +480,17 @@ resolve_canonicalize(char **hostp, int port)
ndots++;
}
if (ndots > options.canonicalize_max_dots) {
- debug3("%s: not canonicalizing hostname \"%s\" (max dots %d)",
- __func__, *hostp, options.canonicalize_max_dots);
+ debug3_f("not canonicalizing hostname \"%s\" (max dots %d)",
+ *hostp, options.canonicalize_max_dots);
return NULL;
}
/* Attempt each supplied suffix */
for (i = 0; i < options.num_canonical_domains; i++) {
- *newname = '\0';
+ if (strcasecmp(options.canonical_domains[i], "none") == 0)
+ break;
xasprintf(&fullhost, "%s.%s.", *hostp,
options.canonical_domains[i]);
- debug3("%s: attempting \"%s\" => \"%s\"", __func__,
- *hostp, fullhost);
+ debug3_f("attempting \"%s\" => \"%s\"", *hostp, fullhost);
if ((addrs = resolve_host(fullhost, port, 0,
newname, sizeof(newname))) == NULL) {
free(fullhost);
@@ -495,7 +511,7 @@ resolve_canonicalize(char **hostp, int port)
notfound:
if (!options.canonicalize_fallback_local)
fatal("%s: Could not resolve host \"%s\"", __progname, *hostp);
- debug2("%s: host %s not found in any suffix", __func__, *hostp);
+ debug2_f("host %s not found in any suffix", *hostp);
return NULL;
}
@@ -511,14 +527,14 @@ check_load(int r, const char *path, const char *message)
break;
case SSH_ERR_INTERNAL_ERROR:
case SSH_ERR_ALLOC_FAIL:
- fatal("load %s \"%s\": %s", message, path, ssh_err(r));
+ fatal_r(r, "load %s \"%s\"", message, path);
case SSH_ERR_SYSTEM_ERROR:
/* Ignore missing files */
if (errno == ENOENT)
break;
/* FALLTHROUGH */
default:
- error("load %s \"%s\": %s", message, path, ssh_err(r));
+ error_r(r, "load %s \"%s\"", message, path);
break;
}
}
@@ -528,7 +544,8 @@ check_load(int r, const char *path, const char *message)
* file if the user specifies a config file on the command line.
*/
static void
-process_config_files(const char *host_name, struct passwd *pw, int post_canon)
+process_config_files(const char *host_name, struct passwd *pw, int final_pass,
+ int *want_final_pass)
{
char buf[PATH_MAX];
int r;
@@ -536,7 +553,8 @@ process_config_files(const char *host_name, struct passwd *pw, int post_canon)
if (config != NULL) {
if (strcasecmp(config, "none") != 0 &&
!read_config_file(config, pw, host, host_name, &options,
- SSHCONF_USERCONF | (post_canon ? SSHCONF_POSTCANON : 0)))
+ SSHCONF_USERCONF | (final_pass ? SSHCONF_FINAL : 0),
+ want_final_pass))
fatal("Can't open user config file %.100s: "
"%.100s", config, strerror(errno));
} else {
@@ -545,12 +563,12 @@ process_config_files(const char *host_name, struct passwd *pw, int post_canon)
if (r > 0 && (size_t)r < sizeof(buf))
(void)read_config_file(buf, pw, host, host_name,
&options, SSHCONF_CHECKPERM | SSHCONF_USERCONF |
- (post_canon ? SSHCONF_POSTCANON : 0));
+ (final_pass ? SSHCONF_FINAL : 0), want_final_pass);
/* Read systemwide configuration file after user config. */
(void)read_config_file(_PATH_HOST_CONFIG_FILE, pw,
host, host_name, &options,
- post_canon ? SSHCONF_POSTCANON : 0);
+ final_pass ? SSHCONF_FINAL : 0, want_final_pass);
}
}
@@ -574,6 +592,25 @@ set_addrinfo_port(struct addrinfo *addrs, int port)
}
}
+static void
+ssh_conn_info_free(struct ssh_conn_info *cinfo)
+{
+ if (cinfo == NULL)
+ return;
+ free(cinfo->conn_hash_hex);
+ free(cinfo->shorthost);
+ free(cinfo->uidstr);
+ free(cinfo->keyalias);
+ free(cinfo->thishost);
+ free(cinfo->host_arg);
+ free(cinfo->portstr);
+ free(cinfo->remhost);
+ free(cinfo->remuser);
+ free(cinfo->homedir);
+ free(cinfo->locuser);
+ free(cinfo);
+}
+
/*
* Main program for the ssh client.
*/
@@ -582,22 +619,28 @@ main(int ac, char **av)
{
struct ssh *ssh = NULL;
int i, r, opt, exit_status, use_syslog, direct, timeout_ms;
- int was_addr, config_test = 0, opt_terminated = 0;
- char *p, *cp, *line, *argv0, buf[PATH_MAX], *logfile;
- char cname[NI_MAXHOST];
+ int was_addr, config_test = 0, opt_terminated = 0, want_final_pass = 0;
+ char *p, *cp, *line, *argv0, *logfile, *host_arg;
+ char cname[NI_MAXHOST], thishost[NI_MAXHOST];
struct stat st;
struct passwd *pw;
extern int optind, optreset;
extern char *optarg;
struct Forward fwd;
struct addrinfo *addrs = NULL;
- struct ssh_digest_ctx *md;
- u_char conn_hash[SSH_DIGEST_MAX_LENGTH];
+ size_t n, len;
+ u_int j;
+ struct ssh_conn_info *cinfo = NULL;
- ssh_malloc_init(); /* must be called before any mallocs */
/* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */
sanitise_stdfd();
+ /*
+ * Discard other fds that are hanging around. These can cause problem
+ * with backgrounded ssh processes started by ControlPersist.
+ */
+ closefrom(STDERR_FILENO + 1);
+
__progname = ssh_get_progname(av[0]);
#ifndef HAVE_SETPROCTITLE
@@ -611,11 +654,7 @@ main(int ac, char **av)
av = saved_av;
#endif
- /*
- * Discard other fds that are hanging around. These can cause problem
- * with backgrounded ssh processes started by ControlPersist.
- */
- closefrom(STDERR_FILENO + 1);
+ seed_rng();
/* Get user data. */
pw = getpwuid(getuid());
@@ -648,7 +687,6 @@ main(int ac, char **av)
if ((ssh = ssh_alloc_session_state()) == NULL)
fatal("Couldn't allocate session state");
channel_init_channels(ssh);
- active_state = ssh; /* XXX legacy API compat */
/* Parse command-line arguments. */
host = NULL;
@@ -673,11 +711,11 @@ main(int ac, char **av)
options.address_family = AF_INET6;
break;
case 'n':
- stdin_null_flag = 1;
+ options.stdin_null = 1;
break;
case 'f':
- fork_after_authentication_flag = 1;
- stdin_null_flag = 1;
+ options.fork_after_authentication = 1;
+ options.stdin_null = 1;
break;
case 'x':
options.forward_x11 = 0;
@@ -726,13 +764,16 @@ main(int ac, char **av)
break;
case 'Q':
cp = NULL;
- if (strcmp(optarg, "cipher") == 0)
+ if (strcmp(optarg, "cipher") == 0 ||
+ strcasecmp(optarg, "Ciphers") == 0)
cp = cipher_alg_list('\n', 0);
else if (strcmp(optarg, "cipher-auth") == 0)
cp = cipher_alg_list('\n', 1);
- else if (strcmp(optarg, "mac") == 0)
+ else if (strcmp(optarg, "mac") == 0 ||
+ strcasecmp(optarg, "MACs") == 0)
cp = mac_alg_list('\n');
- else if (strcmp(optarg, "kex") == 0)
+ else if (strcmp(optarg, "kex") == 0 ||
+ strcasecmp(optarg, "KexAlgorithms") == 0)
cp = kex_alg_list('\n');
else if (strcmp(optarg, "key") == 0)
cp = sshkey_alg_list(0, 0, 0, '\n');
@@ -740,14 +781,28 @@ main(int ac, char **av)
cp = sshkey_alg_list(1, 0, 0, '\n');
else if (strcmp(optarg, "key-plain") == 0)
cp = sshkey_alg_list(0, 1, 0, '\n');
+ else if (strcmp(optarg, "key-sig") == 0 ||
+ strcasecmp(optarg, "PubkeyAcceptedKeyTypes") == 0 || /* deprecated name */
+ strcasecmp(optarg, "PubkeyAcceptedAlgorithms") == 0 ||
+ strcasecmp(optarg, "HostKeyAlgorithms") == 0 ||
+ strcasecmp(optarg, "HostbasedKeyTypes") == 0 || /* deprecated name */
+ strcasecmp(optarg, "HostbasedAcceptedKeyTypes") == 0 || /* deprecated name */
+ strcasecmp(optarg, "HostbasedAcceptedAlgorithms") == 0)
+ cp = sshkey_alg_list(0, 0, 1, '\n');
else if (strcmp(optarg, "sig") == 0)
cp = sshkey_alg_list(0, 1, 1, '\n');
else if (strcmp(optarg, "protocol-version") == 0)
cp = xstrdup("2");
- else if (strcmp(optarg, "help") == 0) {
+ else if (strcmp(optarg, "compression") == 0) {
+ cp = xstrdup(compression_alg_list(0));
+ len = strlen(cp);
+ for (n = 0; n < len; n++)
+ if (cp[n] == ',')
+ cp[n] = '\n';
+ } else if (strcmp(optarg, "help") == 0) {
cp = xstrdup(
- "cipher\ncipher-auth\nkex\nkey\n"
- "key-cert\nkey-plain\nmac\n"
+ "cipher\ncipher-auth\ncompression\nkex\n"
+ "key\nkey-cert\nkey-plain\nkey-sig\nmac\n"
"protocol-version\nsig");
}
if (cp == NULL)
@@ -771,7 +826,7 @@ main(int ac, char **av)
break;
case 'i':
p = tilde_expand_filename(optarg, getuid());
- if (stat(p, &st) < 0)
+ if (stat(p, &st) == -1)
fprintf(stderr, "Warning: Identity file %s "
"not accessible: %s.\n", p,
strerror(errno));
@@ -788,8 +843,11 @@ main(int ac, char **av)
#endif
break;
case 'J':
- if (options.jump_host != NULL)
- fatal("Only a single -J option permitted");
+ if (options.jump_host != NULL) {
+ fatal("Only a single -J option is permitted "
+ "(use commas to separate multiple "
+ "jump hops)");
+ }
if (options.proxy_command != NULL)
fatal("Cannot specify -J with ProxyCommand");
if (parse_jump(optarg, &options, 1) == -1)
@@ -851,7 +909,7 @@ main(int ac, char **av)
exit(255);
}
options.request_tty = REQUEST_TTY_NO;
- no_shell_flag = 1;
+ options.session_type = SESSION_TYPE_NONE;
break;
case 'q':
options.log_level = SYSLOG_LEVEL_QUIET;
@@ -872,7 +930,7 @@ main(int ac, char **av)
}
break;
case 'c':
- if (!ciphers_valid(*optarg == '+' ?
+ if (!ciphers_valid(*optarg == '+' || *optarg == '^' ?
optarg + 1 : optarg)) {
fprintf(stderr, "Unknown cipher type '%s'\n",
optarg);
@@ -947,10 +1005,17 @@ main(int ac, char **av)
break;
case 'C':
+#ifdef WITH_ZLIB
options.compression = 1;
+#else
+ error("Compression not supported, disabling.");
+#endif
break;
case 'N':
- no_shell_flag = 1;
+ if (options.session_type != -1 &&
+ options.session_type != SESSION_TYPE_NONE)
+ fatal("Cannot specify -N with -s/SessionType");
+ options.session_type = SESSION_TYPE_NONE;
options.request_tty = REQUEST_TTY_NO;
break;
case 'T':
@@ -965,7 +1030,10 @@ main(int ac, char **av)
free(line);
break;
case 's':
- subsystem_flag = 1;
+ if (options.session_type != -1 &&
+ options.session_type != SESSION_TYPE_SUBSYSTEM)
+ fatal("Cannot specify -s with -N/SessionType");
+ options.session_type = SESSION_TYPE_SUBSYSTEM;
break;
case 'S':
free(options.control_path);
@@ -1037,11 +1105,6 @@ main(int ac, char **av)
host_arg = xstrdup(host);
-#ifdef WITH_OPENSSL
- OpenSSL_add_all_algorithms();
- ERR_load_crypto_strings();
-#endif
-
/* Initialize the command to execute on remote host. */
if ((command = sshbuf_new()) == NULL)
fatal("sshbuf_new failed");
@@ -1053,7 +1116,7 @@ main(int ac, char **av)
*/
if (!ac) {
/* No command specified - execute shell on a tty. */
- if (subsystem_flag) {
+ if (options.session_type == SESSION_TYPE_SUBSYSTEM) {
fprintf(stderr,
"You must specify a subsystem to invoke.\n");
usage();
@@ -1063,8 +1126,7 @@ main(int ac, char **av)
for (i = 0; i < ac; i++) {
if ((r = sshbuf_putf(command, "%s%s",
i ? " " : "", av[i])) != 0)
- fatal("%s: buffer error: %s",
- __func__, ssh_err(r));
+ fatal_fr(r, "buffer error");
}
}
@@ -1088,7 +1150,9 @@ main(int ac, char **av)
logit("%s, %s", SSH_RELEASE, OPENSSL_VERSION_STRING);
/* Parse the configuration files */
- process_config_files(host_arg, pw, 0);
+ process_config_files(host_arg, pw, 0, &want_final_pass);
+ if (want_final_pass)
+ debug("configuration requests final Match pass");
/* Hostname canonicalisation needs a few options filled. */
fill_default_options_for_canonicalization(&options);
@@ -1145,12 +1209,17 @@ main(int ac, char **av)
* If canonicalisation is enabled then re-parse the configuration
* files as new stanzas may match.
*/
- if (options.canonicalize_hostname != 0) {
- debug("Re-reading configuration after hostname "
- "canonicalisation");
+ if (options.canonicalize_hostname != 0 && !want_final_pass) {
+ debug("hostname canonicalisation enabled, "
+ "will re-parse configuration");
+ want_final_pass = 1;
+ }
+
+ if (want_final_pass) {
+ debug("re-parsing configuration");
free(options.hostname);
options.hostname = xstrdup(host);
- process_config_files(host_arg, pw, 1);
+ process_config_files(host_arg, pw, 1, NULL);
/*
* Address resolution happens early with canonicalisation
* enabled and the port number may have changed since, so
@@ -1161,14 +1230,29 @@ main(int ac, char **av)
}
/* Fill configuration defaults. */
- fill_default_options(&options);
+ if (fill_default_options(&options) != 0)
+ cleanup_exit(255);
+
+ if (options.user == NULL)
+ options.user = xstrdup(pw->pw_name);
/*
* If ProxyJump option specified, then construct a ProxyCommand now.
*/
if (options.jump_host != NULL) {
char port_s[8];
- const char *sshbin = argv0;
+ const char *jumpuser = options.jump_user, *sshbin = argv0;
+ int port = options.port, jumpport = options.jump_port;
+
+ if (port <= 0)
+ port = default_ssh_port();
+ if (jumpport <= 0)
+ jumpport = default_ssh_port();
+ if (jumpuser == NULL)
+ jumpuser = options.user;
+ if (strcmp(options.jump_host, host) == 0 && port == jumpport &&
+ strcmp(options.user, jumpuser) == 0)
+ fatal("jumphost loop via %s", options.jump_host);
/*
* Try to use SSH indicated by argv[0], but fall back to
@@ -1218,11 +1302,21 @@ main(int ac, char **av)
strcmp(options.proxy_command, "-") == 0 &&
options.proxy_use_fdpass)
fatal("ProxyCommand=- and ProxyUseFDPass are incompatible");
- if (options.control_persist &&
- options.update_hostkeys == SSH_UPDATE_HOSTKEYS_ASK) {
- debug("UpdateHostKeys=ask is incompatible with ControlPersist; "
- "disabling");
- options.update_hostkeys = 0;
+ if (options.update_hostkeys == SSH_UPDATE_HOSTKEYS_ASK) {
+ if (options.control_persist && options.control_path != NULL) {
+ debug("UpdateHostKeys=ask is incompatible with "
+ "ControlPersist; disabling");
+ options.update_hostkeys = 0;
+ } else if (sshbuf_len(command) != 0 ||
+ options.remote_command != NULL ||
+ options.request_tty == REQUEST_TTY_NO) {
+ debug("UpdateHostKeys=ask is incompatible with "
+ "remote command execution; disabling");
+ options.update_hostkeys = 0;
+ } else if (options.log_level < SYSLOG_LEVEL_INFO) {
+ /* no point logging anything; user won't see it */
+ options.update_hostkeys = 0;
+ }
}
if (options.connection_attempts <= 0)
fatal("Invalid number of ConnectionAttempts");
@@ -1231,13 +1325,19 @@ main(int ac, char **av)
fatal("Cannot execute command-line and remote command.");
/* Cannot fork to background if no command. */
- if (fork_after_authentication_flag && sshbuf_len(command) == 0 &&
- options.remote_command == NULL && !no_shell_flag)
+ if (options.fork_after_authentication && sshbuf_len(command) == 0 &&
+ options.remote_command == NULL &&
+ options.session_type != SESSION_TYPE_NONE)
fatal("Cannot fork into background without a command "
"to execute.");
/* reinit */
log_init(argv0, options.log_level, options.log_facility, !use_syslog);
+ for (j = 0; j < options.num_log_verbose; j++) {
+ if (strcasecmp(options.log_verbose[j], "none") == 0)
+ break;
+ log_verbose_add(options.log_verbose[j]);
+ }
if (options.request_tty == REQUEST_TTY_YES ||
options.request_tty == REQUEST_TTY_FORCE)
@@ -1252,7 +1352,7 @@ main(int ac, char **av)
(muxclient_command && muxclient_command != SSHMUX_COMMAND_PROXY))
tty_flag = 0;
/* Do not allocate a tty if stdin is not a tty. */
- if ((!isatty(fileno(stdin)) || stdin_null_flag) &&
+ if ((!isatty(fileno(stdin)) || options.stdin_null) &&
options.request_tty != REQUEST_TTY_FORCE) {
if (tty_flag)
logit("Pseudo-terminal will not be allocated because "
@@ -1260,19 +1360,25 @@ main(int ac, char **av)
tty_flag = 0;
}
- seed_rng();
-
- if (options.user == NULL)
- options.user = xstrdup(pw->pw_name);
-
/* Set up strings used to percent_expand() arguments */
+ cinfo = xcalloc(1, sizeof(*cinfo));
if (gethostname(thishost, sizeof(thishost)) == -1)
fatal("gethostname: %s", strerror(errno));
- strlcpy(shorthost, thishost, sizeof(shorthost));
- shorthost[strcspn(thishost, ".")] = '\0';
- snprintf(portstr, sizeof(portstr), "%d", options.port);
- snprintf(uidstr, sizeof(uidstr), "%llu",
+ cinfo->thishost = xstrdup(thishost);
+ thishost[strcspn(thishost, ".")] = '\0';
+ cinfo->shorthost = xstrdup(thishost);
+ xasprintf(&cinfo->portstr, "%d", options.port);
+ xasprintf(&cinfo->uidstr, "%llu",
(unsigned long long)pw->pw_uid);
+ cinfo->keyalias = xstrdup(options.host_key_alias ?
+ options.host_key_alias : host_arg);
+ cinfo->conn_hash_hex = ssh_connection_hash(cinfo->thishost, host,
+ cinfo->portstr, options.user);
+ cinfo->host_arg = xstrdup(host_arg);
+ cinfo->remhost = xstrdup(host);
+ cinfo->remuser = xstrdup(options.user);
+ cinfo->homedir = xstrdup(pw->pw_dir);
+ cinfo->locuser = xstrdup(pw->pw_name);
/* Find canonic host name. */
if (strchr(host, '.') == 0) {
@@ -1291,16 +1397,6 @@ main(int ac, char **av)
}
}
- if ((md = ssh_digest_start(SSH_DIGEST_SHA1)) == NULL ||
- ssh_digest_update(md, thishost, strlen(thishost)) < 0 ||
- ssh_digest_update(md, host, strlen(host)) < 0 ||
- ssh_digest_update(md, portstr, strlen(portstr)) < 0 ||
- ssh_digest_update(md, options.user, strlen(options.user)) < 0 ||
- ssh_digest_final(md, conn_hash, sizeof(conn_hash)) < 0)
- fatal("%s: mux digest failed", __func__);
- ssh_digest_free(md);
- conn_hash_hex = tohex(conn_hash, ssh_digest_bytes(SSH_DIGEST_SHA1));
-
/*
* Expand tokens in arguments. NB. LocalCommand is expanded later,
* after port-forwarding is set up, so it may pick up any local
@@ -1309,55 +1405,148 @@ main(int ac, char **av)
if (options.remote_command != NULL) {
debug3("expanding RemoteCommand: %s", options.remote_command);
cp = options.remote_command;
- options.remote_command = percent_expand(cp,
- "C", conn_hash_hex,
- "L", shorthost,
- "d", pw->pw_dir,
- "h", host,
- "i", uidstr,
- "l", thishost,
- "n", host_arg,
- "p", portstr,
- "r", options.user,
- "u", pw->pw_name,
- (char *)NULL);
+ options.remote_command = default_client_percent_expand(cp,
+ cinfo);
debug3("expanded RemoteCommand: %s", options.remote_command);
free(cp);
if ((r = sshbuf_put(command, options.remote_command,
strlen(options.remote_command))) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "buffer error");
}
if (options.control_path != NULL) {
cp = tilde_expand_filename(options.control_path, getuid());
free(options.control_path);
- options.control_path = percent_expand(cp,
- "C", conn_hash_hex,
- "L", shorthost,
- "h", host,
- "i", uidstr,
- "l", thishost,
- "n", host_arg,
- "p", portstr,
- "r", options.user,
- "u", pw->pw_name,
- "i", uidstr,
- (char *)NULL);
+ options.control_path = default_client_percent_dollar_expand(cp,
+ cinfo);
free(cp);
}
+ if (options.identity_agent != NULL) {
+ p = tilde_expand_filename(options.identity_agent, getuid());
+ cp = default_client_percent_dollar_expand(p, cinfo);
+ free(p);
+ free(options.identity_agent);
+ options.identity_agent = cp;
+ }
+
+ if (options.forward_agent_sock_path != NULL) {
+ p = tilde_expand_filename(options.forward_agent_sock_path,
+ getuid());
+ cp = default_client_percent_dollar_expand(p, cinfo);
+ free(p);
+ free(options.forward_agent_sock_path);
+ options.forward_agent_sock_path = cp;
+ if (stat(options.forward_agent_sock_path, &st) != 0) {
+ error("Cannot forward agent socket path \"%s\": %s",
+ options.forward_agent_sock_path, strerror(errno));
+ if (options.exit_on_forward_failure)
+ cleanup_exit(255);
+ }
+ }
+
+ if (options.num_system_hostfiles > 0 &&
+ strcasecmp(options.system_hostfiles[0], "none") == 0) {
+ if (options.num_system_hostfiles > 1)
+ fatal("Invalid GlobalKnownHostsFiles: \"none\" "
+ "appears with other entries");
+ free(options.system_hostfiles[0]);
+ options.system_hostfiles[0] = NULL;
+ options.num_system_hostfiles = 0;
+ }
+
+ if (options.num_user_hostfiles > 0 &&
+ strcasecmp(options.user_hostfiles[0], "none") == 0) {
+ if (options.num_user_hostfiles > 1)
+ fatal("Invalid UserKnownHostsFiles: \"none\" "
+ "appears with other entries");
+ free(options.user_hostfiles[0]);
+ options.user_hostfiles[0] = NULL;
+ options.num_user_hostfiles = 0;
+ }
+ for (j = 0; j < options.num_user_hostfiles; j++) {
+ if (options.user_hostfiles[j] == NULL)
+ continue;
+ cp = tilde_expand_filename(options.user_hostfiles[j], getuid());
+ p = default_client_percent_dollar_expand(cp, cinfo);
+ if (strcmp(options.user_hostfiles[j], p) != 0)
+ debug3("expanded UserKnownHostsFile '%s' -> "
+ "'%s'", options.user_hostfiles[j], p);
+ free(options.user_hostfiles[j]);
+ free(cp);
+ options.user_hostfiles[j] = p;
+ }
+
+ for (i = 0; i < options.num_local_forwards; i++) {
+ if (options.local_forwards[i].listen_path != NULL) {
+ cp = options.local_forwards[i].listen_path;
+ p = options.local_forwards[i].listen_path =
+ default_client_percent_expand(cp, cinfo);
+ if (strcmp(cp, p) != 0)
+ debug3("expanded LocalForward listen path "
+ "'%s' -> '%s'", cp, p);
+ free(cp);
+ }
+ if (options.local_forwards[i].connect_path != NULL) {
+ cp = options.local_forwards[i].connect_path;
+ p = options.local_forwards[i].connect_path =
+ default_client_percent_expand(cp, cinfo);
+ if (strcmp(cp, p) != 0)
+ debug3("expanded LocalForward connect path "
+ "'%s' -> '%s'", cp, p);
+ free(cp);
+ }
+ }
+
+ for (i = 0; i < options.num_remote_forwards; i++) {
+ if (options.remote_forwards[i].listen_path != NULL) {
+ cp = options.remote_forwards[i].listen_path;
+ p = options.remote_forwards[i].listen_path =
+ default_client_percent_expand(cp, cinfo);
+ if (strcmp(cp, p) != 0)
+ debug3("expanded RemoteForward listen path "
+ "'%s' -> '%s'", cp, p);
+ free(cp);
+ }
+ if (options.remote_forwards[i].connect_path != NULL) {
+ cp = options.remote_forwards[i].connect_path;
+ p = options.remote_forwards[i].connect_path =
+ default_client_percent_expand(cp, cinfo);
+ if (strcmp(cp, p) != 0)
+ debug3("expanded RemoteForward connect path "
+ "'%s' -> '%s'", cp, p);
+ free(cp);
+ }
+ }
+
if (config_test) {
dump_client_config(&options, host);
exit(0);
}
+ /* Expand SecurityKeyProvider if it refers to an environment variable */
+ if (options.sk_provider != NULL && *options.sk_provider == '$' &&
+ strlen(options.sk_provider) > 1) {
+ if ((cp = getenv(options.sk_provider + 1)) == NULL) {
+ debug("Authenticator provider %s did not resolve; "
+ "disabling", options.sk_provider);
+ free(options.sk_provider);
+ options.sk_provider = NULL;
+ } else {
+ debug2("resolved SecurityKeyProvider %s => %s",
+ options.sk_provider, cp);
+ free(options.sk_provider);
+ options.sk_provider = xstrdup(cp);
+ }
+ }
+
if (muxclient_command != 0 && options.control_path == NULL)
fatal("No ControlPath specified for \"-O\" command");
if (options.control_path != NULL) {
int sock;
if ((sock = muxclient(options.control_path)) >= 0) {
ssh_packet_set_connection(ssh, sock, sock);
- packet_set_mux();
+ ssh_packet_set_mux(ssh);
goto skip_connect;
}
}
@@ -1373,22 +1562,23 @@ main(int ac, char **av)
cleanup_exit(255); /* resolve_host logs the error */
}
- timeout_ms = options.connection_timeout * 1000;
+ if (options.connection_timeout >= INT_MAX/1000)
+ timeout_ms = INT_MAX;
+ else
+ timeout_ms = options.connection_timeout * 1000;
/* Open a connection to the remote host. */
- if (ssh_connect(ssh, host, addrs, &hostaddr, options.port,
- options.address_family, options.connection_attempts,
+ if (ssh_connect(ssh, host, host_arg, addrs, &hostaddr, options.port,
+ options.connection_attempts,
&timeout_ms, options.tcp_keep_alive) != 0)
- exit(255);
+ exit(255);
if (addrs != NULL)
freeaddrinfo(addrs);
- packet_set_timeout(options.server_alive_interval,
+ ssh_packet_set_timeout(ssh, options.server_alive_interval,
options.server_alive_count_max);
- ssh = active_state; /* XXX */
-
if (timeout_ms > 0)
debug3("timeout: %d ms remain after connect", timeout_ms);
@@ -1407,13 +1597,13 @@ main(int ac, char **av)
/* XXX check errors? */
#define L_PUBKEY(p,o) do { \
if ((o) >= sensitive_data.nkeys) \
- fatal("%s pubkey out of array bounds", __func__); \
+ fatal_f("pubkey out of array bounds"); \
check_load(sshkey_load_public(p, &(sensitive_data.keys[o]), NULL), \
p, "pubkey"); \
} while (0)
#define L_CERT(p,o) do { \
if ((o) >= sensitive_data.nkeys) \
- fatal("%s cert out of array bounds", __func__); \
+ fatal_f("cert out of array bounds"); \
check_load(sshkey_load_cert(p, &(sensitive_data.keys[o])), p, "cert"); \
} while (0)
@@ -1431,24 +1621,8 @@ main(int ac, char **av)
}
}
- /* Create ~/.ssh * directory if it doesn't already exist. */
- if (config == NULL) {
- r = snprintf(buf, sizeof buf, "%s%s%s", pw->pw_dir,
- strcmp(pw->pw_dir, "/") ? "/" : "", _PATH_SSH_USER_DIR);
- if (r > 0 && (size_t)r < sizeof(buf) && stat(buf, &st) < 0) {
-#ifdef WITH_SELINUX
- ssh_selinux_setfscreatecon(buf);
-#endif
- if (mkdir(buf, 0700) < 0)
- error("Could not create directory '%.200s'.",
- buf);
-#ifdef WITH_SELINUX
- ssh_selinux_setfscreatecon(NULL);
-#endif
- }
- }
/* load options.identity_files */
- load_public_identity_files(pw);
+ load_public_identity_files(cinfo);
/* optionally set the SSH_AUTHSOCKET_ENV_NAME variable */
if (options.identity_agent &&
@@ -1456,24 +1630,9 @@ main(int ac, char **av)
if (strcmp(options.identity_agent, "none") == 0) {
unsetenv(SSH_AUTHSOCKET_ENV_NAME);
} else {
- p = tilde_expand_filename(options.identity_agent,
- getuid());
- cp = percent_expand(p,
- "d", pw->pw_dir,
- "h", host,
- "i", uidstr,
- "l", thishost,
- "r", options.user,
- "u", pw->pw_name,
- (char *)NULL);
- free(p);
- /*
- * If identity_agent represents an environment variable
- * then recheck that it is valid (since processing with
- * percent_expand() may have changed it) and substitute
- * its value.
- */
- if (cp[0] == '$') {
+ cp = options.identity_agent;
+ /* legacy (limited) format */
+ if (cp[0] == '$' && cp[1] != '{') {
if (!valid_env_name(cp + 1)) {
fatal("Invalid IdentityAgent "
"environment variable name %s", cp);
@@ -1486,7 +1645,22 @@ main(int ac, char **av)
/* identity_agent specifies a path directly */
setenv(SSH_AUTHSOCKET_ENV_NAME, cp, 1);
}
+ }
+ }
+
+ if (options.forward_agent && options.forward_agent_sock_path != NULL) {
+ cp = options.forward_agent_sock_path;
+ if (cp[0] == '$') {
+ if (!valid_env_name(cp + 1)) {
+ fatal("Invalid ForwardAgent environment variable name %s", cp);
+ }
+ if ((p = getenv(cp + 1)) != NULL)
+ forward_agent_sock_path = xstrdup(p);
+ else
+ options.forward_agent = 0;
free(cp);
+ } else {
+ forward_agent_sock_path = cp;
}
}
@@ -1495,19 +1669,12 @@ main(int ac, char **av)
options.num_system_hostfiles);
tilde_expand_paths(options.user_hostfiles, options.num_user_hostfiles);
- signal(SIGPIPE, SIG_IGN); /* ignore SIGPIPE early */
- signal(SIGCHLD, main_sigchld_handler);
+ ssh_signal(SIGPIPE, SIG_IGN); /* ignore SIGPIPE early */
+ ssh_signal(SIGCHLD, main_sigchld_handler);
/* Log into the remote system. Never returns if the login fails. */
- ssh_login(&sensitive_data, host, (struct sockaddr *)&hostaddr,
- options.port, pw, timeout_ms);
-
- if (packet_connection_is_on_socket()) {
- verbose("Authenticated to %s ([%s]:%d).", host,
- ssh_remote_ipaddr(ssh), ssh_remote_port(ssh));
- } else {
- verbose("Authenticated to %s (via proxy).", host);
- }
+ ssh_login(ssh, &sensitive_data, host, (struct sockaddr *)&hostaddr,
+ options.port, pw, timeout_ms, cinfo);
/* We no longer need the private host keys. Clear them now. */
if (sensitive_data.nkeys != 0) {
@@ -1534,9 +1701,14 @@ main(int ac, char **av)
options.certificate_files[i] = NULL;
}
+#ifdef ENABLE_PKCS11
+ (void)pkcs11_del_provider(options.pkcs11_provider);
+#endif
+
skip_connect:
- exit_status = ssh_session2(ssh, pw);
- packet_close();
+ exit_status = ssh_session2(ssh, cinfo);
+ ssh_conn_info_free(cinfo);
+ ssh_packet_close(ssh);
if (options.control_path != NULL && muxserver_sock != -1)
unlink(options.control_path);
@@ -1551,9 +1723,8 @@ static void
control_persist_detach(void)
{
pid_t pid;
- int devnull, keep_stderr;
- debug("%s: backgrounding master process", __func__);
+ debug_f("backgrounding master process");
/*
* master (current process) into the background, and make the
@@ -1561,16 +1732,17 @@ control_persist_detach(void)
*/
switch ((pid = fork())) {
case -1:
- fatal("%s: fork: %s", __func__, strerror(errno));
+ fatal_f("fork: %s", strerror(errno));
case 0:
/* Child: master process continues mainloop */
break;
default:
- /* Parent: set up mux slave to connect to backgrounded master */
- debug2("%s: background process is %ld", __func__, (long)pid);
- stdin_null_flag = ostdin_null_flag;
+ /* Parent: set up mux client to connect to backgrounded master */
+ debug2_f("background process is %ld", (long)pid);
+ options.stdin_null = ostdin_null_flag;
options.request_tty = orequest_tty;
tty_flag = otty_flag;
+ options.session_type = osession_type;
close(muxserver_sock);
muxserver_sock = -1;
options.control_master = SSHCTL_MASTER_NO;
@@ -1578,18 +1750,8 @@ control_persist_detach(void)
/* muxclient() doesn't return on success. */
fatal("Failed to connect to new control master");
}
- if ((devnull = open(_PATH_DEVNULL, O_RDWR)) == -1) {
- error("%s: open(\"/dev/null\"): %s", __func__,
- strerror(errno));
- } else {
- keep_stderr = log_is_on_stderr() && debug_flag;
- if (dup2(devnull, STDIN_FILENO) == -1 ||
- dup2(devnull, STDOUT_FILENO) == -1 ||
- (!keep_stderr && dup2(devnull, STDERR_FILENO) == -1))
- error("%s: dup2: %s", __func__, strerror(errno));
- if (devnull > STDERR_FILENO)
- close(devnull);
- }
+ if (stdfd_devnull(1, 1, !(log_is_on_stderr() && debug_flag)) == -1)
+ error_f("stdfd_devnull failed");
daemon(1, 1);
setproctitle("%s [mux]", options.control_path);
}
@@ -1601,9 +1763,26 @@ fork_postauth(void)
if (need_controlpersist_detach)
control_persist_detach();
debug("forking to background");
- fork_after_authentication_flag = 0;
- if (daemon(1, 1) < 0)
+ options.fork_after_authentication = 0;
+ if (daemon(1, 1) == -1)
fatal("daemon() failed: %.200s", strerror(errno));
+ if (stdfd_devnull(1, 1, !(log_is_on_stderr() && debug_flag)) == -1)
+ error_f("stdfd_devnull failed");
+}
+
+static void
+forwarding_success(void)
+{
+ if (forward_confirms_pending == -1)
+ return;
+ if (--forward_confirms_pending == 0) {
+ debug_f("all expected forwarding replies received");
+ if (options.fork_after_authentication)
+ fork_postauth();
+ } else {
+ debug2_f("%d expected forwarding replies remaining",
+ forward_confirms_pending);
+ }
}
/* Callback for remote forward global requests */
@@ -1611,6 +1790,8 @@ static void
ssh_confirm_remote_forward(struct ssh *ssh, int type, u_int32_t seq, void *ctxt)
{
struct Forward *rfwd = (struct Forward *)ctxt;
+ u_int port;
+ int r;
/* XXX verbose() on failure? */
debug("remote forward %s for: listen %s%s%d, connect %s:%d",
@@ -1622,12 +1803,25 @@ ssh_confirm_remote_forward(struct ssh *ssh, int type, u_int32_t seq, void *ctxt)
rfwd->connect_host, rfwd->connect_port);
if (rfwd->listen_path == NULL && rfwd->listen_port == 0) {
if (type == SSH2_MSG_REQUEST_SUCCESS) {
- rfwd->allocated_port = packet_get_int();
- logit("Allocated port %u for remote forward to %s:%d",
- rfwd->allocated_port,
- rfwd->connect_host, rfwd->connect_port);
- channel_update_permission(ssh,
- rfwd->handle, rfwd->allocated_port);
+ if ((r = sshpkt_get_u32(ssh, &port)) != 0)
+ fatal_fr(r, "parse packet");
+ if (port > 65535) {
+ error("Invalid allocated port %u for remote "
+ "forward to %s:%d", port,
+ rfwd->connect_host, rfwd->connect_port);
+ /* Ensure failure processing runs below */
+ type = SSH2_MSG_REQUEST_FAILURE;
+ channel_update_permission(ssh,
+ rfwd->handle, -1);
+ } else {
+ rfwd->allocated_port = (int)port;
+ logit("Allocated port %u for remote "
+ "forward to %s:%d",
+ rfwd->allocated_port, rfwd->connect_host,
+ rfwd->connect_port);
+ channel_update_permission(ssh,
+ rfwd->handle, rfwd->allocated_port);
+ }
} else {
channel_update_permission(ssh, rfwd->handle, -1);
}
@@ -1650,11 +1844,7 @@ ssh_confirm_remote_forward(struct ssh *ssh, int type, u_int32_t seq, void *ctxt)
"for listen port %d", rfwd->listen_port);
}
}
- if (++remote_forward_confirms_received == options.num_remote_forwards) {
- debug("All remote forwarding requests processed");
- if (fork_after_authentication_flag)
- fork_postauth();
- }
+ forwarding_success();
}
static void
@@ -1672,6 +1862,19 @@ ssh_stdio_confirm(struct ssh *ssh, int id, int success, void *arg)
}
static void
+ssh_tun_confirm(struct ssh *ssh, int id, int success, void *arg)
+{
+ if (!success) {
+ error("Tunnel forwarding failed");
+ if (options.exit_on_forward_failure)
+ cleanup_exit(255);
+ }
+
+ debug_f("tunnel forward established, id=%d", id);
+ forwarding_success();
+}
+
+static void
ssh_init_stdio_forwarding(struct ssh *ssh)
{
Channel *c;
@@ -1680,25 +1883,69 @@ ssh_init_stdio_forwarding(struct ssh *ssh)
if (options.stdio_forward_host == NULL)
return;
- debug3("%s: %s:%d", __func__, options.stdio_forward_host,
+ debug3_f("%s:%d", options.stdio_forward_host,
options.stdio_forward_port);
- if ((in = dup(STDIN_FILENO)) < 0 ||
- (out = dup(STDOUT_FILENO)) < 0)
- fatal("channel_connect_stdio_fwd: dup() in/out failed");
+ if ((in = dup(STDIN_FILENO)) == -1 ||
+ (out = dup(STDOUT_FILENO)) == -1)
+ fatal_f("dup() in/out failed");
if ((c = channel_connect_stdio_fwd(ssh, options.stdio_forward_host,
- options.stdio_forward_port, in, out)) == NULL)
- fatal("%s: channel_connect_stdio_fwd failed", __func__);
+ options.stdio_forward_port, in, out,
+ CHANNEL_NONBLOCK_STDIO)) == NULL)
+ fatal_f("channel_connect_stdio_fwd failed");
channel_register_cleanup(ssh, c->self, client_cleanup_stdio_fwd, 0);
channel_register_open_confirm(ssh, c->self, ssh_stdio_confirm, NULL);
}
static void
+ssh_init_forward_permissions(struct ssh *ssh, const char *what, char **opens,
+ u_int num_opens)
+{
+ u_int i;
+ int port;
+ char *addr, *arg, *oarg, ch;
+ int where = FORWARD_LOCAL;
+
+ channel_clear_permission(ssh, FORWARD_ADM, where);
+ if (num_opens == 0)
+ return; /* permit any */
+
+ /* handle keywords: "any" / "none" */
+ if (num_opens == 1 && strcmp(opens[0], "any") == 0)
+ return;
+ if (num_opens == 1 && strcmp(opens[0], "none") == 0) {
+ channel_disable_admin(ssh, where);
+ return;
+ }
+ /* Otherwise treat it as a list of permitted host:port */
+ for (i = 0; i < num_opens; i++) {
+ oarg = arg = xstrdup(opens[i]);
+ ch = '\0';
+ addr = hpdelim2(&arg, &ch);
+ if (addr == NULL || ch == '/')
+ fatal_f("missing host in %s", what);
+ addr = cleanhostname(addr);
+ if (arg == NULL || ((port = permitopen_port(arg)) < 0))
+ fatal_f("bad port number in %s", what);
+ /* Send it to channels layer */
+ channel_add_permission(ssh, FORWARD_ADM,
+ where, addr, port);
+ free(oarg);
+ }
+}
+
+static void
ssh_init_forwarding(struct ssh *ssh, char **ifname)
{
int success = 0;
int i;
+ ssh_init_forward_permissions(ssh, "permitremoteopen",
+ options.permitted_remote_opens,
+ options.num_permitted_remote_opens);
+
+ if (options.exit_on_forward_failure)
+ forward_confirms_pending = 0; /* track pending requests */
/* Initiate local TCP/IP port forwardings. */
for (i = 0; i < options.num_local_forwards; i++) {
debug("Local connections to %.200s:%d forwarded to remote "
@@ -1734,32 +1981,33 @@ ssh_init_forwarding(struct ssh *ssh, char **ifname)
options.remote_forwards[i].connect_path :
options.remote_forwards[i].connect_host,
options.remote_forwards[i].connect_port);
- options.remote_forwards[i].handle =
+ if ((options.remote_forwards[i].handle =
channel_request_remote_forwarding(ssh,
- &options.remote_forwards[i]);
- if (options.remote_forwards[i].handle < 0) {
- if (options.exit_on_forward_failure)
- fatal("Could not request remote forwarding.");
- else
- logit("Warning: Could not request remote "
- "forwarding.");
- } else {
+ &options.remote_forwards[i])) >= 0) {
client_register_global_confirm(
ssh_confirm_remote_forward,
&options.remote_forwards[i]);
- }
+ forward_confirms_pending++;
+ } else if (options.exit_on_forward_failure)
+ fatal("Could not request remote forwarding.");
+ else
+ logit("Warning: Could not request remote forwarding.");
}
/* Initiate tunnel forwarding. */
if (options.tun_open != SSH_TUNMODE_NO) {
if ((*ifname = client_request_tun_fwd(ssh,
options.tun_open, options.tun_local,
- options.tun_remote)) == NULL) {
- if (options.exit_on_forward_failure)
- fatal("Could not request tunnel forwarding.");
- else
- error("Could not request tunnel forwarding.");
- }
+ options.tun_remote, ssh_tun_confirm, NULL)) != NULL)
+ forward_confirms_pending++;
+ else if (options.exit_on_forward_failure)
+ fatal("Could not request tunnel forwarding.");
+ else
+ error("Could not request tunnel forwarding.");
+ }
+ if (forward_confirms_pending > 0) {
+ debug_f("expecting replies for %d forwards",
+ forward_confirms_pending);
}
}
@@ -1773,8 +2021,7 @@ check_agent_present(void)
if ((r = ssh_get_authentication_socket(NULL)) != 0) {
options.forward_agent = 0;
if (r != SSH_ERR_AGENT_NOT_PRESENT)
- debug("ssh_get_authentication_socket: %s",
- ssh_err(r));
+ debug_r(r, "ssh_get_authentication_socket");
}
}
}
@@ -1783,8 +2030,8 @@ static void
ssh_session2_setup(struct ssh *ssh, int id, int success, void *arg)
{
extern char **environ;
- const char *display;
- int interactive = tty_flag;
+ const char *display, *term;
+ int r, interactive = tty_flag;
char *proto = NULL, *data = NULL;
if (!success)
@@ -1810,14 +2057,19 @@ ssh_session2_setup(struct ssh *ssh, int id, int success, void *arg)
if (options.forward_agent) {
debug("Requesting authentication agent forwarding.");
channel_request_start(ssh, id, "auth-agent-req@openssh.com", 0);
- packet_send();
+ if ((r = sshpkt_send(ssh)) != 0)
+ fatal_fr(r, "send packet");
}
/* Tell the packet module whether this is an interactive session. */
- packet_set_interactive(interactive,
+ ssh_packet_set_interactive(ssh, interactive,
options.ip_qos_interactive, options.ip_qos_bulk);
- client_session2_setup(ssh, id, tty_flag, subsystem_flag, getenv("TERM"),
+ if ((term = lookup_env_in_list("TERM", options.setenv,
+ options.num_setenv)) == NULL || *term == '\0')
+ term = getenv("TERM");
+ client_session2_setup(ssh, id, tty_flag,
+ options.session_type == SESSION_TYPE_SUBSYSTEM, term,
NULL, fileno(stdin), command, environ);
}
@@ -1828,7 +2080,7 @@ ssh_session2_open(struct ssh *ssh)
Channel *c;
int window, packetmax, in, out, err;
- if (stdin_null_flag) {
+ if (options.stdin_null) {
in = open(_PATH_DEVNULL, O_RDONLY);
} else {
in = dup(STDIN_FILENO);
@@ -1836,17 +2088,9 @@ ssh_session2_open(struct ssh *ssh)
out = dup(STDOUT_FILENO);
err = dup(STDERR_FILENO);
- if (in < 0 || out < 0 || err < 0)
+ if (in == -1 || out == -1 || err == -1)
fatal("dup() in/out/err failed");
- /* enable nonblocking unless tty */
- if (!isatty(in))
- set_nonblock(in);
- if (!isatty(out))
- set_nonblock(out);
- if (!isatty(err))
- set_nonblock(err);
-
window = CHAN_SES_WINDOW_DEFAULT;
packetmax = CHAN_SES_PACKET_DEFAULT;
if (tty_flag) {
@@ -1856,12 +2100,12 @@ ssh_session2_open(struct ssh *ssh)
c = channel_new(ssh,
"session", SSH_CHANNEL_OPENING, in, out, err,
window, packetmax, CHAN_EXTENDED_WRITE,
- "client-session", /*nonblock*/0);
+ "client-session", CHANNEL_NONBLOCK_STDIO);
- debug3("%s: channel_new: %d", __func__, c->self);
+ debug3_f("channel_new: %d", c->self);
channel_send_open(ssh, c->self);
- if (!no_shell_flag)
+ if (options.session_type != SESSION_TYPE_NONE)
channel_register_open_confirm(ssh, c->self,
ssh_session2_setup, NULL);
@@ -1869,9 +2113,9 @@ ssh_session2_open(struct ssh *ssh)
}
static int
-ssh_session2(struct ssh *ssh, struct passwd *pw)
+ssh_session2(struct ssh *ssh, const struct ssh_conn_info *cinfo)
{
- int devnull, id = -1;
+ int r, id = -1;
char *cp, *tun_fwd_ifname = NULL;
/* XXX should be pre-session */
@@ -1884,16 +2128,7 @@ ssh_session2(struct ssh *ssh, struct passwd *pw)
debug3("expanding LocalCommand: %s", options.local_command);
cp = options.local_command;
options.local_command = percent_expand(cp,
- "C", conn_hash_hex,
- "L", shorthost,
- "d", pw->pw_dir,
- "h", host,
- "i", uidstr,
- "l", thishost,
- "n", host_arg,
- "p", portstr,
- "r", options.user,
- "u", pw->pw_name,
+ DEFAULT_CLIENT_PERCENT_EXPAND_ARGS(cinfo),
"T", tun_fwd_ifname == NULL ? "NONE" : tun_fwd_ifname,
(char *)NULL);
debug3("expanded LocalCommand: %s", options.local_command);
@@ -1901,29 +2136,31 @@ ssh_session2(struct ssh *ssh, struct passwd *pw)
}
/* Start listening for multiplex clients */
- if (!packet_get_mux())
+ if (!ssh_packet_get_mux(ssh))
muxserver_listen(ssh);
/*
* If we are in control persist mode and have a working mux listen
* socket, then prepare to background ourselves and have a foreground
- * client attach as a control slave.
+ * client attach as a control client.
* NB. we must save copies of the flags that we override for
- * the backgrounding, since we defer attachment of the slave until
+ * the backgrounding, since we defer attachment of the client until
* after the connection is fully established (in particular,
* async rfwd replies have been received for ExitOnForwardFailure).
*/
if (options.control_persist && muxserver_sock != -1) {
- ostdin_null_flag = stdin_null_flag;
- ono_shell_flag = no_shell_flag;
+ ostdin_null_flag = options.stdin_null;
+ osession_type = options.session_type;
orequest_tty = options.request_tty;
otty_flag = tty_flag;
- stdin_null_flag = 1;
- no_shell_flag = 1;
+ options.stdin_null = 1;
+ options.session_type = SESSION_TYPE_NONE;
tty_flag = 0;
- if (!fork_after_authentication_flag)
+ if (!options.fork_after_authentication &&
+ (osession_type != SESSION_TYPE_NONE ||
+ options.stdio_forward_host != NULL))
need_controlpersist_detach = 1;
- fork_after_authentication_flag = 1;
+ options.fork_after_authentication = 1;
}
/*
* ControlPersist mux listen socket setup failed, attempt the
@@ -1932,22 +2169,24 @@ ssh_session2(struct ssh *ssh, struct passwd *pw)
if (options.control_persist && muxserver_sock == -1)
ssh_init_stdio_forwarding(ssh);
- if (!no_shell_flag)
+ if (options.session_type != SESSION_TYPE_NONE)
id = ssh_session2_open(ssh);
else {
- packet_set_interactive(
+ ssh_packet_set_interactive(ssh,
options.control_master == SSHCTL_MASTER_NO,
options.ip_qos_interactive, options.ip_qos_bulk);
}
/* If we don't expect to open a new session, then disallow it */
if (options.control_master == SSHCTL_MASTER_NO &&
- (datafellows & SSH_NEW_OPENSSH)) {
+ (ssh->compat & SSH_NEW_OPENSSH)) {
debug("Requesting no-more-sessions@openssh.com");
- packet_start(SSH2_MSG_GLOBAL_REQUEST);
- packet_put_cstring("no-more-sessions@openssh.com");
- packet_put_char(0);
- packet_send();
+ if ((r = sshpkt_start(ssh, SSH2_MSG_GLOBAL_REQUEST)) != 0 ||
+ (r = sshpkt_put_cstring(ssh,
+ "no-more-sessions@openssh.com")) != 0 ||
+ (r = sshpkt_put_u8(ssh, 0)) != 0 ||
+ (r = sshpkt_send(ssh)) != 0)
+ fatal_fr(r, "send packet");
}
/* Execute a local command */
@@ -1961,21 +2200,14 @@ ssh_session2(struct ssh *ssh, struct passwd *pw)
* NB. this can only happen after LocalCommand has completed,
* as it may want to write to stdout.
*/
- if (!need_controlpersist_detach) {
- if ((devnull = open(_PATH_DEVNULL, O_WRONLY)) == -1)
- error("%s: open %s: %s", __func__,
- _PATH_DEVNULL, strerror(errno));
- if (dup2(devnull, STDOUT_FILENO) < 0)
- fatal("%s: dup2() stdout failed", __func__);
- if (devnull > STDERR_FILENO)
- close(devnull);
- }
+ if (!need_controlpersist_detach && stdfd_devnull(0, 1, 0) == -1)
+ error_f("stdfd_devnull failed");
/*
* If requested and we are not interested in replies to remote
* forwarding requests, then let ssh continue in the background.
*/
- if (fork_after_authentication_flag) {
+ if (options.fork_after_authentication) {
if (options.exit_on_forward_failure &&
options.num_remote_forwards > 0) {
debug("deferring postauth fork until remote forward "
@@ -1990,7 +2222,7 @@ ssh_session2(struct ssh *ssh, struct passwd *pw)
/* Loads all IdentityFile and CertificateFile keys */
static void
-load_public_identity_files(struct passwd *pw)
+load_public_identity_files(const struct ssh_conn_info *cinfo)
{
char *filename, *cp;
struct sshkey *public;
@@ -2003,7 +2235,8 @@ load_public_identity_files(struct passwd *pw)
struct sshkey *certificates[SSH_MAX_CERTIFICATE_FILES];
int certificate_file_userprovided[SSH_MAX_CERTIFICATE_FILES];
#ifdef ENABLE_PKCS11
- struct sshkey **keys;
+ struct sshkey **keys = NULL;
+ char **comments = NULL;
int nkeys;
#endif /* PKCS11 */
@@ -2022,18 +2255,19 @@ load_public_identity_files(struct passwd *pw)
options.num_identity_files < SSH_MAX_IDENTITY_FILES &&
(pkcs11_init(!options.batch_mode) == 0) &&
(nkeys = pkcs11_add_provider(options.pkcs11_provider, NULL,
- &keys)) > 0) {
+ &keys, &comments)) > 0) {
for (i = 0; i < nkeys; i++) {
if (n_ids >= SSH_MAX_IDENTITY_FILES) {
sshkey_free(keys[i]);
+ free(comments[i]);
continue;
}
identity_keys[n_ids] = keys[i];
- identity_files[n_ids] =
- xstrdup(options.pkcs11_provider); /* XXX */
+ identity_files[n_ids] = comments[i]; /* transferred */
n_ids++;
}
free(keys);
+ free(comments);
}
#endif /* ENABLE_PKCS11 */
for (i = 0; i < options.num_identity_files; i++) {
@@ -2044,9 +2278,7 @@ load_public_identity_files(struct passwd *pw)
continue;
}
cp = tilde_expand_filename(options.identity_files[i], getuid());
- filename = percent_expand(cp, "d", pw->pw_dir,
- "u", pw->pw_name, "l", thishost, "h", host,
- "r", options.user, (char *)NULL);
+ filename = default_client_percent_dollar_expand(cp, cinfo);
free(cp);
check_load(sshkey_load_public(filename, &public, NULL),
filename, "pubkey");
@@ -2076,8 +2308,8 @@ load_public_identity_files(struct passwd *pw)
continue;
}
if (!sshkey_is_cert(public)) {
- debug("%s: key %s type %s is not a certificate",
- __func__, cp, sshkey_type(public));
+ debug_f("key %s type %s is not a certificate",
+ cp, sshkey_type(public));
sshkey_free(public);
free(cp);
continue;
@@ -2091,18 +2323,11 @@ load_public_identity_files(struct passwd *pw)
}
if (options.num_certificate_files > SSH_MAX_CERTIFICATE_FILES)
- fatal("%s: too many certificates", __func__);
+ fatal_f("too many certificates");
for (i = 0; i < options.num_certificate_files; i++) {
cp = tilde_expand_filename(options.certificate_files[i],
getuid());
- filename = percent_expand(cp,
- "d", pw->pw_dir,
- "h", host,
- "i", uidstr,
- "l", thishost,
- "r", options.user,
- "u", pw->pw_name,
- (char *)NULL);
+ filename = default_client_percent_dollar_expand(cp, cinfo);
free(cp);
check_load(sshkey_load_public(filename, &public, NULL),
@@ -2116,8 +2341,8 @@ load_public_identity_files(struct passwd *pw)
continue;
}
if (!sshkey_is_cert(public)) {
- debug("%s: key %s type %s is not a certificate",
- __func__, filename, sshkey_type(public));
+ debug_f("key %s type %s is not a certificate",
+ filename, sshkey_type(public));
sshkey_free(public);
free(filename);
continue;
@@ -2152,7 +2377,7 @@ main_sigchld_handler(int sig)
int status;
while ((pid = waitpid(-1, &status, WNOHANG)) > 0 ||
- (pid < 0 && errno == EINTR))
+ (pid == -1 && errno == EINTR))
;
errno = save_errno;
}
diff --git a/crypto/openssh/ssh.h b/crypto/openssh/ssh.h
index 5abfd7a688fe..8110c060287f 100644
--- a/crypto/openssh/ssh.h
+++ b/crypto/openssh/ssh.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssh.h,v 1.88 2018/06/06 18:29:18 markus Exp $ */
+/* $OpenBSD: ssh.h,v 1.90 2020/07/14 23:57:01 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -68,6 +68,11 @@
#define SSH_ASKPASS_ENV "SSH_ASKPASS"
/*
+ * Environment variable to control whether or not askpass is used.
+ */
+#define SSH_ASKPASS_REQUIRE_ENV "SSH_ASKPASS_REQUIRE"
+
+/*
* Force host key length and server key length to differ by at least this
* many bits. This is to make double encryption with rsaref work.
*/
@@ -93,3 +98,7 @@
/* Listen backlog for sshd, ssh-agent and forwarding sockets */
#define SSH_LISTEN_BACKLOG 128
+
+/* Limits for banner exchange */
+#define SSH_MAX_BANNER_LEN 8192
+#define SSH_MAX_PRE_BANNER_LINES 1024
diff --git a/crypto/openssh/ssh2.h b/crypto/openssh/ssh2.h
index f2e37c96aa26..32ddae89b33b 100644
--- a/crypto/openssh/ssh2.h
+++ b/crypto/openssh/ssh2.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssh2.h,v 1.18 2016/05/04 14:22:33 markus Exp $ */
+/* $OpenBSD: ssh2.h,v 1.19 2020/11/19 23:05:05 dtucker Exp $ */
/*
* Copyright (c) 2000 Markus Friedl. All rights reserved.
@@ -25,7 +25,7 @@
*/
/*
- * draft-ietf-secsh-architecture-05.txt
+ * RFC4251:
*
* Transport layer protocol:
*
diff --git a/crypto/openssh/ssh_api.c b/crypto/openssh/ssh_api.c
index c84b4e713bf4..d3c6617616bd 100644
--- a/crypto/openssh/ssh_api.c
+++ b/crypto/openssh/ssh_api.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssh_api.c,v 1.8 2017/04/30 23:13:25 djm Exp $ */
+/* $OpenBSD: ssh_api.c,v 1.27 2021/04/03 06:18:41 djm Exp $ */
/*
* Copyright (c) 2012 Markus Friedl. All rights reserved.
*
@@ -17,6 +17,11 @@
#include "includes.h"
+#include <sys/types.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+
#include "ssh_api.h"
#include "compat.h"
#include "log.h"
@@ -29,17 +34,19 @@
#include "ssherr.h"
#include "sshbuf.h"
+#include "openbsd-compat/openssl-compat.h"
+
#include <string.h>
int _ssh_exchange_banner(struct ssh *);
-int _ssh_send_banner(struct ssh *, char **);
-int _ssh_read_banner(struct ssh *, char **);
+int _ssh_send_banner(struct ssh *, struct sshbuf *);
+int _ssh_read_banner(struct ssh *, struct sshbuf *);
int _ssh_order_hostkeyalgs(struct ssh *);
int _ssh_verify_host_key(struct sshkey *, struct ssh *);
struct sshkey *_ssh_host_public_key(int, int, struct ssh *);
struct sshkey *_ssh_host_private_key(int, int, struct ssh *);
-int _ssh_host_key_sign(struct sshkey *, struct sshkey *,
- u_char **, size_t *, const u_char *, size_t, const char *, u_int);
+int _ssh_host_key_sign(struct ssh *, struct sshkey *, struct sshkey *,
+ u_char **, size_t *, const u_char *, size_t, const char *);
/*
* stubs for the server side implementation of kex.
@@ -47,41 +54,41 @@ int _ssh_host_key_sign(struct sshkey *, struct sshkey *,
*/
int use_privsep = 0;
int mm_sshkey_sign(struct sshkey *, u_char **, u_int *,
- u_char *, u_int, char *, u_int);
-DH *mm_choose_dh(int, int, int);
+ const u_char *, u_int, const char *, const char *, const char *, u_int);
-/* Define these two variables here so that they are part of the library */
-u_char *session_id2 = NULL;
-u_int session_id2_len = 0;
+#ifdef WITH_OPENSSL
+DH *mm_choose_dh(int, int, int);
+#endif
int
mm_sshkey_sign(struct sshkey *key, u_char **sigp, u_int *lenp,
- u_char *data, u_int datalen, char *alg, u_int compat)
+ const u_char *data, u_int datalen, const char *alg,
+ const char *sk_provider, const char *sk_pin, u_int compat)
{
return (-1);
}
+#ifdef WITH_OPENSSL
DH *
mm_choose_dh(int min, int nbits, int max)
{
return (NULL);
}
+#endif
/* API */
int
ssh_init(struct ssh **sshp, int is_server, struct kex_params *kex_params)
{
- char *myproposal[PROPOSAL_MAX] = { KEX_CLIENT };
+ char *myproposal[PROPOSAL_MAX] = { KEX_CLIENT };
struct ssh *ssh;
char **proposal;
static int called;
int r;
if (!called) {
-#ifdef WITH_OPENSSL
- OpenSSL_add_all_algorithms();
-#endif /* WITH_OPENSSL */
+ seed_rng();
called = 1;
}
@@ -92,42 +99,44 @@ ssh_init(struct ssh **sshp, int is_server, struct kex_params *kex_params)
/* Initialize key exchange */
proposal = kex_params ? kex_params->proposal : myproposal;
- if ((r = kex_new(ssh, proposal, &ssh->kex)) != 0) {
+ if ((r = kex_ready(ssh, proposal)) != 0) {
ssh_free(ssh);
return r;
}
ssh->kex->server = is_server;
if (is_server) {
#ifdef WITH_OPENSSL
- ssh->kex->kex[KEX_DH_GRP1_SHA1] = kexdh_server;
- ssh->kex->kex[KEX_DH_GRP14_SHA1] = kexdh_server;
- ssh->kex->kex[KEX_DH_GRP14_SHA256] = kexdh_server;
- ssh->kex->kex[KEX_DH_GRP16_SHA512] = kexdh_server;
- ssh->kex->kex[KEX_DH_GRP18_SHA512] = kexdh_server;
+ ssh->kex->kex[KEX_DH_GRP1_SHA1] = kex_gen_server;
+ ssh->kex->kex[KEX_DH_GRP14_SHA1] = kex_gen_server;
+ ssh->kex->kex[KEX_DH_GRP14_SHA256] = kex_gen_server;
+ ssh->kex->kex[KEX_DH_GRP16_SHA512] = kex_gen_server;
+ ssh->kex->kex[KEX_DH_GRP18_SHA512] = kex_gen_server;
ssh->kex->kex[KEX_DH_GEX_SHA1] = kexgex_server;
ssh->kex->kex[KEX_DH_GEX_SHA256] = kexgex_server;
# ifdef OPENSSL_HAS_ECC
- ssh->kex->kex[KEX_ECDH_SHA2] = kexecdh_server;
+ ssh->kex->kex[KEX_ECDH_SHA2] = kex_gen_server;
# endif
#endif /* WITH_OPENSSL */
- ssh->kex->kex[KEX_C25519_SHA256] = kexc25519_server;
+ ssh->kex->kex[KEX_C25519_SHA256] = kex_gen_server;
+ ssh->kex->kex[KEX_KEM_SNTRUP761X25519_SHA512] = kex_gen_server;
ssh->kex->load_host_public_key=&_ssh_host_public_key;
ssh->kex->load_host_private_key=&_ssh_host_private_key;
ssh->kex->sign=&_ssh_host_key_sign;
} else {
#ifdef WITH_OPENSSL
- ssh->kex->kex[KEX_DH_GRP1_SHA1] = kexdh_client;
- ssh->kex->kex[KEX_DH_GRP14_SHA1] = kexdh_client;
- ssh->kex->kex[KEX_DH_GRP14_SHA256] = kexdh_client;
- ssh->kex->kex[KEX_DH_GRP16_SHA512] = kexdh_client;
- ssh->kex->kex[KEX_DH_GRP18_SHA512] = kexdh_client;
+ ssh->kex->kex[KEX_DH_GRP1_SHA1] = kex_gen_client;
+ ssh->kex->kex[KEX_DH_GRP14_SHA1] = kex_gen_client;
+ ssh->kex->kex[KEX_DH_GRP14_SHA256] = kex_gen_client;
+ ssh->kex->kex[KEX_DH_GRP16_SHA512] = kex_gen_client;
+ ssh->kex->kex[KEX_DH_GRP18_SHA512] = kex_gen_client;
ssh->kex->kex[KEX_DH_GEX_SHA1] = kexgex_client;
ssh->kex->kex[KEX_DH_GEX_SHA256] = kexgex_client;
# ifdef OPENSSL_HAS_ECC
- ssh->kex->kex[KEX_ECDH_SHA2] = kexecdh_client;
+ ssh->kex->kex[KEX_ECDH_SHA2] = kex_gen_client;
# endif
#endif /* WITH_OPENSSL */
- ssh->kex->kex[KEX_C25519_SHA256] = kexc25519_client;
+ ssh->kex->kex[KEX_C25519_SHA256] = kex_gen_client;
+ ssh->kex->kex[KEX_KEM_SNTRUP761X25519_SHA512] = kex_gen_client;
ssh->kex->verify_host_key =&_ssh_verify_host_key;
}
*sshp = ssh;
@@ -139,7 +148,9 @@ ssh_free(struct ssh *ssh)
{
struct key_entry *k;
- ssh_packet_close(ssh);
+ if (ssh == NULL)
+ return;
+
/*
* we've only created the public keys variants in case we
* are a acting as a server.
@@ -154,8 +165,7 @@ ssh_free(struct ssh *ssh)
TAILQ_REMOVE(&ssh->private_keys, k, next);
free(k);
}
- if (ssh->kex)
- kex_free(ssh->kex);
+ ssh_packet_close(ssh);
free(ssh);
}
@@ -236,8 +246,8 @@ ssh_packet_next(struct ssh *ssh, u_char *typep)
* enough data.
*/
*typep = SSH_MSG_NONE;
- if (ssh->kex->client_version_string == NULL ||
- ssh->kex->server_version_string == NULL)
+ if (sshbuf_len(ssh->kex->client_version) == 0 ||
+ sshbuf_len(ssh->kex->server_version) == 0)
return _ssh_exchange_banner(ssh);
/*
* If we enough data and a dispatch function then
@@ -312,41 +322,46 @@ ssh_input_space(struct ssh *ssh, size_t len)
/* Read other side's version identification. */
int
-_ssh_read_banner(struct ssh *ssh, char **bannerp)
+_ssh_read_banner(struct ssh *ssh, struct sshbuf *banner)
{
- struct sshbuf *input;
- const char *s;
- char buf[256], remote_version[256]; /* must be same size! */
+ struct sshbuf *input = ssh_packet_get_input(ssh);
const char *mismatch = "Protocol mismatch.\r\n";
- int r, remote_major, remote_minor;
- size_t i, n, j, len;
+ const u_char *s = sshbuf_ptr(input);
+ u_char c;
+ char *cp = NULL, *remote_version = NULL;
+ int r = 0, remote_major, remote_minor, expect_nl;
+ size_t n, j;
- *bannerp = NULL;
- input = ssh_packet_get_input(ssh);
- len = sshbuf_len(input);
- s = (const char *)sshbuf_ptr(input);
for (j = n = 0;;) {
- for (i = 0; i < sizeof(buf) - 1; i++) {
- if (j >= len)
- return (0);
- buf[i] = s[j++];
- if (buf[i] == '\r') {
- buf[i] = '\n';
- buf[i + 1] = 0;
- continue; /**XXX wait for \n */
+ sshbuf_reset(banner);
+ expect_nl = 0;
+ for (;;) {
+ if (j >= sshbuf_len(input))
+ return 0; /* insufficient data in input buf */
+ c = s[j++];
+ if (c == '\r') {
+ expect_nl = 1;
+ continue;
}
- if (buf[i] == '\n') {
- buf[i + 1] = 0;
+ if (c == '\n')
break;
- }
+ if (expect_nl)
+ goto bad;
+ if ((r = sshbuf_put_u8(banner, c)) != 0)
+ return r;
+ if (sshbuf_len(banner) > SSH_MAX_BANNER_LEN)
+ goto bad;
}
- buf[sizeof(buf) - 1] = 0;
- if (strncmp(buf, "SSH-", 4) == 0)
+ if (sshbuf_len(banner) >= 4 &&
+ memcmp(sshbuf_ptr(banner), "SSH-", 4) == 0)
break;
- debug("ssh_exchange_identification: %s", buf);
- if (ssh->kex->server || ++n > 65536) {
+ debug_f("%.*s", (int)sshbuf_len(banner),
+ sshbuf_ptr(banner));
+ /* Accept lines before banner only on client */
+ if (ssh->kex->server || ++n > SSH_MAX_PRE_BANNER_LINES) {
+ bad:
if ((r = sshbuf_put(ssh_packet_get_output(ssh),
- mismatch, strlen(mismatch))) != 0)
+ mismatch, strlen(mismatch))) != 0)
return r;
return SSH_ERR_NO_PROTOCOL_VERSION;
}
@@ -354,44 +369,58 @@ _ssh_read_banner(struct ssh *ssh, char **bannerp)
if ((r = sshbuf_consume(input, j)) != 0)
return r;
+ /* XXX remote version must be the same size as banner for sscanf */
+ if ((cp = sshbuf_dup_string(banner)) == NULL ||
+ (remote_version = calloc(1, sshbuf_len(banner))) == NULL) {
+ r = SSH_ERR_ALLOC_FAIL;
+ goto out;
+ }
+
/*
* Check that the versions match. In future this might accept
* several versions and set appropriate flags to handle them.
*/
- if (sscanf(buf, "SSH-%d.%d-%[^\n]\n",
- &remote_major, &remote_minor, remote_version) != 3)
- return SSH_ERR_INVALID_FORMAT;
+ if (sscanf(cp, "SSH-%d.%d-%[^\n]\n",
+ &remote_major, &remote_minor, remote_version) != 3) {
+ r = SSH_ERR_INVALID_FORMAT;
+ goto out;
+ }
debug("Remote protocol version %d.%d, remote software version %.100s",
remote_major, remote_minor, remote_version);
- ssh->compat = compat_datafellows(remote_version);
+ compat_banner(ssh, remote_version);
if (remote_major == 1 && remote_minor == 99) {
remote_major = 2;
remote_minor = 0;
}
if (remote_major != 2)
- return SSH_ERR_PROTOCOL_MISMATCH;
- chop(buf);
- debug("Remote version string %.100s", buf);
- if ((*bannerp = strdup(buf)) == NULL)
- return SSH_ERR_ALLOC_FAIL;
- return 0;
+ r = SSH_ERR_PROTOCOL_MISMATCH;
+
+ debug("Remote version string %.100s", cp);
+ out:
+ free(cp);
+ free(remote_version);
+ return r;
}
/* Send our own protocol version identification. */
int
-_ssh_send_banner(struct ssh *ssh, char **bannerp)
+_ssh_send_banner(struct ssh *ssh, struct sshbuf *banner)
{
- char buf[256];
+ char *cp;
int r;
- snprintf(buf, sizeof buf, "SSH-2.0-%.100s\r\n", SSH_VERSION);
- if ((r = sshbuf_put(ssh_packet_get_output(ssh), buf, strlen(buf))) != 0)
+ if ((r = sshbuf_putf(banner, "SSH-2.0-%.100s\r\n", SSH_VERSION)) != 0)
+ return r;
+ if ((r = sshbuf_putb(ssh_packet_get_output(ssh), banner)) != 0)
+ return r;
+ /* Remove trailing \r\n */
+ if ((r = sshbuf_consume_end(banner, 2)) != 0)
return r;
- chop(buf);
- debug("Local version string %.100s", buf);
- if ((*bannerp = strdup(buf)) == NULL)
+ if ((cp = sshbuf_dup_string(banner)) == NULL)
return SSH_ERR_ALLOC_FAIL;
+ debug("Local version string %.100s", cp);
+ free(cp);
return 0;
}
@@ -408,25 +437,25 @@ _ssh_exchange_banner(struct ssh *ssh)
r = 0;
if (kex->server) {
- if (kex->server_version_string == NULL)
- r = _ssh_send_banner(ssh, &kex->server_version_string);
+ if (sshbuf_len(ssh->kex->server_version) == 0)
+ r = _ssh_send_banner(ssh, ssh->kex->server_version);
if (r == 0 &&
- kex->server_version_string != NULL &&
- kex->client_version_string == NULL)
- r = _ssh_read_banner(ssh, &kex->client_version_string);
+ sshbuf_len(ssh->kex->server_version) != 0 &&
+ sshbuf_len(ssh->kex->client_version) == 0)
+ r = _ssh_read_banner(ssh, ssh->kex->client_version);
} else {
- if (kex->server_version_string == NULL)
- r = _ssh_read_banner(ssh, &kex->server_version_string);
+ if (sshbuf_len(ssh->kex->server_version) == 0)
+ r = _ssh_read_banner(ssh, ssh->kex->server_version);
if (r == 0 &&
- kex->server_version_string != NULL &&
- kex->client_version_string == NULL)
- r = _ssh_send_banner(ssh, &kex->client_version_string);
+ sshbuf_len(ssh->kex->server_version) != 0 &&
+ sshbuf_len(ssh->kex->client_version) == 0)
+ r = _ssh_send_banner(ssh, ssh->kex->client_version);
}
if (r != 0)
return r;
/* start initial kex as soon as we have exchanged the banners */
- if (kex->server_version_string != NULL &&
- kex->client_version_string != NULL) {
+ if (sshbuf_len(ssh->kex->server_version) != 0 &&
+ sshbuf_len(ssh->kex->client_version) != 0) {
if ((r = _ssh_order_hostkeyalgs(ssh)) != 0 ||
(r = kex_send_kexinit(ssh)) != 0)
return r;
@@ -439,9 +468,9 @@ _ssh_host_public_key(int type, int nid, struct ssh *ssh)
{
struct key_entry *k;
- debug3("%s: need %d", __func__, type);
+ debug3_f("need %d", type);
TAILQ_FOREACH(k, &ssh->public_keys, next) {
- debug3("%s: check %s", __func__, sshkey_type(k->key));
+ debug3_f("check %s", sshkey_type(k->key));
if (k->key->type == type &&
(type != KEY_ECDSA || k->key->ecdsa_nid == nid))
return (k->key);
@@ -454,9 +483,9 @@ _ssh_host_private_key(int type, int nid, struct ssh *ssh)
{
struct key_entry *k;
- debug3("%s: need %d", __func__, type);
+ debug3_f("need %d", type);
TAILQ_FOREACH(k, &ssh->private_keys, next) {
- debug3("%s: check %s", __func__, sshkey_type(k->key));
+ debug3_f("check %s", sshkey_type(k->key));
if (k->key->type == type &&
(type != KEY_ECDSA || k->key->ecdsa_nid == nid))
return (k->key);
@@ -469,9 +498,9 @@ _ssh_verify_host_key(struct sshkey *hostkey, struct ssh *ssh)
{
struct key_entry *k;
- debug3("%s: need %s", __func__, sshkey_type(hostkey));
+ debug3_f("need %s", sshkey_type(hostkey));
TAILQ_FOREACH(k, &ssh->public_keys, next) {
- debug3("%s: check %s", __func__, sshkey_type(k->key));
+ debug3_f("check %s", sshkey_type(k->key));
if (sshkey_equal_public(hostkey, k->key))
return (0); /* ok */
}
@@ -517,8 +546,8 @@ _ssh_order_hostkeyalgs(struct ssh *ssh)
}
}
if (*replace != '\0') {
- debug2("%s: orig/%d %s", __func__, ssh->kex->server, orig);
- debug2("%s: replace/%d %s", __func__, ssh->kex->server, replace);
+ debug2_f("orig/%d %s", ssh->kex->server, orig);
+ debug2_f("replace/%d %s", ssh->kex->server, replace);
free(orig);
proposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = replace;
replace = NULL; /* owned by proposal */
@@ -532,9 +561,10 @@ _ssh_order_hostkeyalgs(struct ssh *ssh)
}
int
-_ssh_host_key_sign(struct sshkey *privkey, struct sshkey *pubkey,
- u_char **signature, size_t *slen, const u_char *data, size_t dlen,
- const char *alg, u_int compat)
+_ssh_host_key_sign(struct ssh *ssh, struct sshkey *privkey,
+ struct sshkey *pubkey, u_char **signature, size_t *slen,
+ const u_char *data, size_t dlen, const char *alg)
{
- return sshkey_sign(privkey, signature, slen, data, dlen, alg, compat);
+ return sshkey_sign(privkey, signature, slen, data, dlen,
+ alg, NULL, NULL, ssh->compat);
}
diff --git a/crypto/openssh/ssh_config b/crypto/openssh/ssh_config
index e7d969abed25..d2a1db35d42e 100644
--- a/crypto/openssh/ssh_config
+++ b/crypto/openssh/ssh_config
@@ -1,4 +1,4 @@
-# $OpenBSD: ssh_config,v 1.33 2017/05/07 23:12:57 djm Exp $
+# $OpenBSD: ssh_config,v 1.35 2020/07/17 03:43:42 dtucker Exp $
# $FreeBSD$
# This is the ssh client system-wide configuration file. See
@@ -35,7 +35,6 @@
# IdentityFile ~/.ssh/id_ecdsa
# IdentityFile ~/.ssh/id_ed25519
# Port 22
-# Protocol 2
# Ciphers aes128-ctr,aes192-ctr,aes256-ctr,aes128-cbc,3des-cbc
# MACs hmac-md5,hmac-sha1,umac-64@openssh.com
# EscapeChar ~
@@ -45,5 +44,6 @@
# VisualHostKey no
# ProxyCommand ssh -q -W %h:%p gateway.example.com
# RekeyLimit 1G 1h
+# UserKnownHostsFile ~/.ssh/known_hosts.d/%k
# VerifyHostKeyDNS yes
-# VersionAddendum FreeBSD-20200214
+# VersionAddendum FreeBSD-20210907
diff --git a/crypto/openssh/ssh_config.5 b/crypto/openssh/ssh_config.5
index e8b52f309b50..3ca36e231c0d 100644
--- a/crypto/openssh/ssh_config.5
+++ b/crypto/openssh/ssh_config.5
@@ -33,14 +33,14 @@
.\" (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: ssh_config.5,v 1.286 2018/10/03 06:38:35 djm Exp $
+.\" $OpenBSD: ssh_config.5,v 1.362 2021/08/12 23:59:25 djm Exp $
.\" $FreeBSD$
-.Dd $Mdocdate: October 3 2018 $
+.Dd $Mdocdate: August 12 2021 $
.Dt SSH_CONFIG 5
.Os
.Sh NAME
.Nm ssh_config
-.Nd OpenSSH SSH client configuration files
+.Nd OpenSSH client configuration file
.Sh DESCRIPTION
.Xr ssh 1
obtains configuration data from the following sources in
@@ -140,6 +140,7 @@ or the single token
which always matches.
The available criteria keywords are:
.Cm canonical ,
+.Cm final ,
.Cm exec ,
.Cm host ,
.Cm originalhost ,
@@ -149,12 +150,15 @@ and
The
.Cm all
criteria must appear alone or immediately after
-.Cm canonical .
+.Cm canonical
+or
+.Cm final .
Other criteria may be combined arbitrarily.
All criteria but
-.Cm all
+.Cm all ,
+.Cm canonical ,
and
-.Cm canonical
+.Cm final
require an argument.
Criteria may be negated by prepending an exclamation mark
.Pq Sq !\& .
@@ -164,9 +168,23 @@ The
keyword matches only when the configuration file is being re-parsed
after hostname canonicalization (see the
.Cm CanonicalizeHostname
-option.)
+option).
This may be useful to specify conditions that work with canonical host
names only.
+.Pp
+The
+.Cm final
+keyword requests that the configuration be re-parsed (regardless of whether
+.Cm CanonicalizeHostname
+is enabled), and matches only during this final pass.
+If
+.Cm CanonicalizeHostname
+is enabled, then
+.Cm canonical
+and
+.Cm final
+match during the same pass.
+.Pp
The
.Cm exec
keyword executes the specified command under the user's shell.
@@ -228,13 +246,22 @@ option was specified to
If this option is set to
.Cm no ,
no keys are added to the agent.
+Alternately, this option may be specified as a time interval
+using the format described in the
+.Sx TIME FORMATS
+section of
+.Xr sshd_config 5
+to specify the key's lifetime in
+.Xr ssh-agent 1 ,
+after which it will automatically be removed.
The argument must be
-.Cm yes ,
-.Cm confirm ,
-.Cm ask ,
-or
.Cm no
-(the default).
+(the default),
+.Cm yes ,
+.Cm confirm
+(optionally followed by a time interval),
+.Cm ask
+or a time interval.
.It Cm AddressFamily
Specifies which address family to use when connecting.
Valid arguments are
@@ -247,9 +274,11 @@ Valid arguments are
.It Cm BatchMode
If set to
.Cm yes ,
-passphrase/password querying will be disabled.
+user interaction such as password prompts and host key confirmation requests
+will be disabled.
This option is useful in scripts and other batch jobs where no user
-is present to supply the password.
+is present to interact with
+.Xr ssh 1 .
The argument must be
.Cm yes
or
@@ -313,6 +342,11 @@ again using the new target name to pick up any new configuration in matching
and
.Cm Match
stanzas.
+A value of
+.Cm none
+disables the use of a
+.Cm ProxyJump
+host.
.It Cm CanonicalizeMaxDots
Specifies the maximum number of dot characters in a hostname before
canonicalization is disabled.
@@ -344,10 +378,22 @@ Specifies which algorithms are allowed for signing of certificates
by certificate authorities (CAs).
The default is:
.Bd -literal -offset indent
-ecdsa-sha2-nistp256.ecdsa-sha2-nistp384,ecdsa-sha2-nistp521,
-ssh-ed25519,rsa-sha2-512,rsa-sha2-256,ssh-rsa
+ssh-ed25519,ecdsa-sha2-nistp256,
+ecdsa-sha2-nistp384,ecdsa-sha2-nistp521,
+sk-ssh-ed25519@openssh.com,
+sk-ecdsa-sha2-nistp256@openssh.com,
+rsa-sha2-512,rsa-sha2-256
.Ed
.Pp
+If the specified list begins with a
+.Sq +
+character, then the specified algorithms will be appended to the default set
+instead of replacing them.
+If the specified list begins with a
+.Sq -
+character, then the specified algorithms (including wildcards) will be removed
+from the default set instead of replacing them.
+.Pp
.Xr ssh 1
will not accept host certificates signed using algorithms other than those
specified.
@@ -364,13 +410,17 @@ flag to
via
.Xr ssh-agent 1 ,
or via a
-.Cm PKCS11Provider .
+.Cm PKCS11Provider
+or
+.Cm SecurityKeyProvider .
.Pp
Arguments to
.Cm CertificateFile
-may use the tilde syntax to refer to a user's home directory
-or the tokens described in the
+may use the tilde syntax to refer to a user's home directory,
+the tokens described in the
.Sx TOKENS
+section and environment variables as described in the
+.Sx ENVIRONMENT VARIABLES
section.
.Pp
It is possible to have multiple certificate files specified in
@@ -379,13 +429,6 @@ Multiple
.Cm CertificateFile
directives will add to the list of certificates used for
authentication.
-.It Cm ChallengeResponseAuthentication
-Specifies whether to use challenge-response authentication.
-The argument to this keyword must be
-.Cm yes
-(the default)
-or
-.Cm no .
.It Cm CheckHostIP
If set to
.Cm yes ,
@@ -399,21 +442,26 @@ and will add addresses of destination hosts to
in the process, regardless of the setting of
.Cm StrictHostKeyChecking .
If the option is set to
-.Cm no ,
+.Cm no
+(the default),
the check will not be executed.
The default is
.Cm no .
.It Cm Ciphers
Specifies the ciphers allowed and their order of preference.
Multiple ciphers must be comma-separated.
-If the specified value begins with a
+If the specified list begins with a
.Sq +
character, then the specified ciphers will be appended to the default set
instead of replacing them.
-If the specified value begins with a
+If the specified list begins with a
.Sq -
character, then the specified ciphers (including wildcards) will be removed
from the default set instead of replacing them.
+If the specified list begins with a
+.Sq ^
+character, then the specified ciphers will be placed at the head of the
+default set.
.Pp
The supported ciphers are:
.Bd -literal -offset indent
@@ -469,8 +517,8 @@ The default is 1.
.It Cm 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.
+This timeout is applied both to establishing the connection and to performing
+the initial SSH protocol handshake and key exchange.
.It Cm ControlMaster
Enables the sharing of multiple sessions over a single network connection.
When set to
@@ -527,9 +575,11 @@ section above or the string
to disable connection sharing.
Arguments to
.Cm ControlPath
-may use the tilde syntax to refer to a user's home directory
-or the tokens described in the
+may use the tilde syntax to refer to a user's home directory,
+the tokens described in the
.Sx TOKENS
+section and environment variables as described in the
+.Sx ENVIRONMENT VARIABLES
section.
It is recommended that any
.Cm ControlPath
@@ -544,7 +594,8 @@ 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
-.Cm no ,
+.Cm no
+(the default),
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
@@ -644,14 +695,56 @@ Valid options are:
and
.Cm sha256
(the default).
+.It Cm ForkAfterAuthentication
+Requests
+.Nm ssh
+to go to background just before command execution.
+This is useful if
+.Nm ssh
+is going to ask for passwords or passphrases, but the user
+wants it in the background.
+This implies the
+.Cm StdinNull
+configuration option being set to
+.Dq yes .
+The recommended way to start X11 programs at a remote site is with
+something like
+.Ic ssh -f host xterm ,
+which is the same as
+.Ic ssh host xterm
+if the
+.Cm ForkAfterAuthentication
+configuration option is set to
+.Dq yes .
+.Pp
+If the
+.Cm ExitOnForwardFailure
+configuration option is set to
+.Dq yes ,
+then a client started with the
+.Cm ForkAfterAuthentication
+configuration option being set to
+.Dq yes
+will wait for all remote port forwards to be successfully established
+before placing itself in the background.
+The argument to this keyword must be
+.Cm yes
+(same as the
+.Fl f
+option) or
+.Cm no
+(the default).
.It Cm ForwardAgent
Specifies whether the connection to the authentication agent (if any)
will be forwarded to the remote machine.
-The argument must be
-.Cm yes
-or
+The argument may be
+.Cm yes ,
.Cm no
-(the default).
+(the default),
+an explicit path to an agent socket or the name of an environment variable
+(beginning with
+.Sq $ )
+in which to find the path.
.Pp
Agent forwarding should be enabled with caution.
Users with the ability to bypass file permissions on the remote host
@@ -751,110 +844,133 @@ These hashed names may be used normally by
.Xr ssh 1
and
.Xr sshd 8 ,
-but they do not reveal identifying information should the file's contents
-be disclosed.
+but they do not visually reveal identifying information if the
+file's contents are disclosed.
The default is
.Cm no .
Note that existing names and addresses in known hosts files
will not be converted automatically,
but may be manually hashed using
.Xr ssh-keygen 1 .
-.It Cm HostbasedAuthentication
-Specifies whether to try rhosts based authentication with public key
-authentication.
-The argument must be
-.Cm yes
-or
-.Cm no
-(the default).
-.It Cm HostbasedKeyTypes
-Specifies the key types that will be used for hostbased authentication
-as a comma-separated list of patterns.
-Alternately if the specified value begins with a
+.It Cm HostbasedAcceptedAlgorithms
+Specifies the signature algorithms that will be used for hostbased
+authentication as a comma-separated list of patterns.
+Alternately if the specified list begins with a
.Sq +
-character, then the specified key types will be appended to the default set
-instead of replacing them.
-If the specified value begins with a
+character, then the specified signature algorithms will be appended
+to the default set instead of replacing them.
+If the specified list begins with a
.Sq -
-character, then the specified key types (including wildcards) will be removed
-from the default set instead of replacing them.
+character, then the specified signature algorithms (including wildcards)
+will be removed from the default set instead of replacing them.
+If the specified list begins with a
+.Sq ^
+character, then the specified signature algorithms will be placed
+at the head of the default set.
The default for this option is:
.Bd -literal -offset 3n
+ssh-ed25519-cert-v01@openssh.com,
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,
-rsa-sha2-512-cert-v01@openssh.com,rsa-sha2-256-cert-v01@openssh.com,
+sk-ssh-ed25519-cert-v01@openssh.com,
+sk-ecdsa-sha2-nistp256-cert-v01@openssh.com,
+rsa-sha2-512-cert-v01@openssh.com,
+rsa-sha2-256-cert-v01@openssh.com,
ssh-rsa-cert-v01@openssh.com,
+ssh-ed25519,
ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521,
-ssh-ed25519,rsa-sha2-512,rsa-sha2-256,ssh-rsa
+sk-ssh-ed25519@openssh.com,
+sk-ecdsa-sha2-nistp256@openssh.com,
+rsa-sha2-512,rsa-sha2-256,ssh-rsa
.Ed
.Pp
The
.Fl Q
option of
.Xr ssh 1
-may be used to list supported key types.
+may be used to list supported signature algorithms.
+This was formerly named HostbasedKeyTypes.
+.It Cm HostbasedAuthentication
+Specifies whether to try rhosts based authentication with public key
+authentication.
+The argument must be
+.Cm yes
+or
+.Cm no
+(the default).
.It Cm HostKeyAlgorithms
-Specifies the host key algorithms
+Specifies the host key signature algorithms
that the client wants to use in order of preference.
-Alternately if the specified value begins with a
+Alternately if the specified list begins with a
.Sq +
-character, then the specified key types will be appended to the default set
-instead of replacing them.
-If the specified value begins with a
+character, then the specified signature algorithms will be appended to
+the default set instead of replacing them.
+If the specified list begins with a
.Sq -
-character, then the specified key types (including wildcards) will be removed
-from the default set instead of replacing them.
+character, then the specified signature algorithms (including wildcards)
+will be removed from the default set instead of replacing them.
+If the specified list begins with a
+.Sq ^
+character, then the specified signature algorithms will be placed
+at the head of the default set.
The default for this option is:
.Bd -literal -offset 3n
+ssh-ed25519-cert-v01@openssh.com,
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,
-rsa-sha2-512-cert-v01@openssh.com,rsa-sha2-256-cert-v01@openssh.com,
+sk-ssh-ed25519-cert-v01@openssh.com,
+sk-ecdsa-sha2-nistp256-cert-v01@openssh.com,
+rsa-sha2-512-cert-v01@openssh.com,
+rsa-sha2-256-cert-v01@openssh.com,
ssh-rsa-cert-v01@openssh.com,
+ssh-ed25519,
ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521,
-ssh-ed25519,rsa-sha2-512,rsa-sha2-256,ssh-rsa
+sk-ecdsa-sha2-nistp256@openssh.com,
+sk-ssh-ed25519@openssh.com,
+rsa-sha2-512,rsa-sha2-256,ssh-rsa
.Ed
.Pp
If hostkeys are known for the destination host then this default is modified
to prefer their algorithms.
.Pp
-The list of available key types may also be obtained using
-.Qq ssh -Q key .
+The list of available signature algorithms may also be obtained using
+.Qq ssh -Q HostKeyAlgorithms .
.It Cm 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 and when validating host certificates.
This option is useful for tunneling SSH connections
or for multiple servers running on a single host.
-.It Cm HostName
+.It Cm Hostname
Specifies the real host name to log into.
This can be used to specify nicknames or abbreviations for hosts.
Arguments to
-.Cm HostName
+.Cm Hostname
accept the tokens described in the
.Sx TOKENS
section.
Numeric IP addresses are also permitted (both on the command line and in
-.Cm HostName
+.Cm Hostname
specifications).
The default is the name given on the command line.
.It Cm IdentitiesOnly
Specifies that
.Xr ssh 1
-should only use the authentication identity and certificate files explicitly
-configured in the
+should only use the configured authentication identity and certificate files
+(either the default files, or those explicitly configured in the
.Nm
files
or passed on the
.Xr ssh 1
-command-line,
+command-line),
even if
.Xr ssh-agent 1
or a
.Cm PKCS11Provider
+or
+.Cm SecurityKeyProvider
offers more identities.
The argument to this keyword must be
.Cm yes
@@ -886,17 +1002,21 @@ the location of the socket.
.Pp
Arguments to
.Cm IdentityAgent
-may use the tilde syntax to refer to a user's home directory
-or the tokens described in the
+may use the tilde syntax to refer to a user's home directory,
+the tokens described in the
.Sx TOKENS
+section and environment variables as described in the
+.Sx ENVIRONMENT VARIABLES
section.
.It Cm IdentityFile
-Specifies a file from which the user's DSA, ECDSA, Ed25519 or RSA authentication
-identity is read.
+Specifies a file from which the user's DSA, ECDSA, authenticator-hosted ECDSA,
+Ed25519, authenticator-hosted Ed25519 or RSA authentication identity is read.
The default is
.Pa ~/.ssh/id_dsa ,
.Pa ~/.ssh/id_ecdsa ,
-.Pa ~/.ssh/id_ed25519
+.Pa ~/.ssh/id_ecdsa_sk ,
+.Pa ~/.ssh/id_ed25519 ,
+.Pa ~/.ssh/id_ed25519_sk
and
.Pa ~/.ssh/id_rsa .
Additionally, any identities represented by the authentication agent
@@ -954,6 +1074,7 @@ Multiple pathnames may be specified and each pathname may contain
wildcards and, for user configurations, shell-like
.Sq ~
references to user home directories.
+Wildcards will be expanded and processed in lexical order.
Files without absolute paths are assumed to be in
.Pa ~/.ssh
if included in a user configuration file or
@@ -990,6 +1111,7 @@ Accepted values are
.Cm cs6 ,
.Cm cs7 ,
.Cm ef ,
+.Cm le ,
.Cm lowdelay ,
.Cm throughput ,
.Cm reliability ,
@@ -1014,6 +1136,8 @@ The argument to this keyword must be
(the default)
or
.Cm no .
+.Cm ChallengeResponseAuthentication
+is a deprecated alias for this.
.It Cm KbdInteractiveDevices
Specifies the list of methods to use in keyboard-interactive authentication.
Multiple method names must be comma-separated.
@@ -1027,14 +1151,18 @@ and
.It Cm KexAlgorithms
Specifies the available KEX (Key Exchange) algorithms.
Multiple algorithms must be comma-separated.
-Alternately if the specified value begins with a
+If the specified list begins with a
.Sq +
character, then the specified methods will be appended to the default set
instead of replacing them.
-If the specified value begins with a
+If the specified list begins with a
.Sq -
character, then the specified methods (including wildcards) will be removed
from the default set instead of replacing them.
+If the specified list begins with a
+.Sq ^
+character, then the specified methods will be placed at the head of the
+default set.
The default is:
.Bd -literal -offset indent
curve25519-sha256,curve25519-sha256@libssh.org,
@@ -1042,13 +1170,36 @@ ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,
diffie-hellman-group-exchange-sha256,
diffie-hellman-group16-sha512,
diffie-hellman-group18-sha512,
-diffie-hellman-group-exchange-sha1,
-diffie-hellman-group14-sha256,
-diffie-hellman-group14-sha1
+diffie-hellman-group14-sha256
.Ed
.Pp
The list of available key exchange algorithms may also be obtained using
.Qq ssh -Q kex .
+.It Cm KnownHostsCommand
+Specifies a command to use to obtain a list of host keys, in addition to
+those listed in
+.Cm UserKnownHostsFile
+and
+.Cm GlobalKnownHostsFile .
+This command is executed after the files have been read.
+It may write host key lines to standard output in identical format to the
+usual files (described in the
+.Sx VERIFYING HOST KEYS
+section in
+.Xr ssh 1 ) .
+Arguments to
+.Cm KnownHostsCommand
+accept the tokens described in the
+.Sx TOKENS
+section.
+The command may be invoked multiple times per connection: once when preparing
+the preference list of host key algorithms to use, again to obtain the
+host key for the requested host name and, if
+.Cm CheckHostIP
+is enabled, one more time to obtain the host key matching the server's
+address.
+If the command exits abnormally or returns a non-zero exit status then the
+connection is terminated.
.It Cm LocalCommand
Specifies a command to execute on the local machine after successfully
connecting to the server.
@@ -1072,12 +1223,15 @@ has been enabled.
.It Cm 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
+The first argument specifies the listener and may be
.Sm off
.Oo Ar bind_address : Oc Ar port
.Sm on
-and the second argument must be
-.Ar host : Ns Ar hostport .
+or a Unix domain socket path.
+The second argument is the destination and may be
+.Ar host : Ns Ar hostport
+or a Unix domain socket path if the remote host supports it.
+.Pp
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.
@@ -1096,6 +1250,11 @@ indicates that the listening port be bound for local use only, while an
empty address or
.Sq *
indicates that the port should be available from all interfaces.
+Unix domain socket paths may use the tokens described in the
+.Sx TOKENS
+section and environment variables as described in the
+.Sx ENVIRONMENT VARIABLES
+section.
.It Cm LogLevel
Gives the verbosity level that is used when logging messages from
.Xr ssh 1 .
@@ -1104,19 +1263,40 @@ 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.
+.It Cm LogVerbose
+Specify one or more overrides to LogLevel.
+An override consists of a pattern lists that matches the source file, function
+and line number to force detailed logging for.
+For example, an override pattern of:
+.Bd -literal -offset indent
+kex.c:*:1000,*:kex_exchange_identification():*,packet.c:*
+.Ed
+.Pp
+would enable detailed logging for line 1000 of
+.Pa kex.c ,
+everything in the
+.Fn kex_exchange_identification
+function, and all code in the
+.Pa packet.c
+file.
+This option is intended for debugging and no overrides are enabled by default.
.It Cm MACs
Specifies the MAC (message authentication code) algorithms
in order of preference.
The MAC algorithm is used for data integrity protection.
Multiple algorithms must be comma-separated.
-If the specified value begins with a
+If the specified list begins with a
.Sq +
character, then the specified algorithms will be appended to the default set
instead of replacing them.
-If the specified value begins with a
+If the specified list begins with a
.Sq -
character, then the specified algorithms (including wildcards) will be removed
from the default set instead of replacing them.
+If the specified list begins with a
+.Sq ^
+character, then the specified algorithms will be placed at the head of the
+default set.
.Pp
The algorithms that contain
.Qq -etm
@@ -1164,12 +1344,50 @@ The argument must be
or
.Cm no
(the default).
+.It Cm PermitRemoteOpen
+Specifies the destinations to which remote TCP port forwarding is permitted when
+.Cm RemoteForward
+is used as a SOCKS proxy.
+The forwarding specification must be one of the following forms:
+.Pp
+.Bl -item -offset indent -compact
+.It
+.Cm PermitRemoteOpen
+.Sm off
+.Ar host : port
+.Sm on
+.It
+.Cm PermitRemoteOpen
+.Sm off
+.Ar IPv4_addr : port
+.Sm on
+.It
+.Cm PermitRemoteOpen
+.Sm off
+.Ar \&[ IPv6_addr \&] : port
+.Sm on
+.El
+.Pp
+Multiple forwards may be specified by separating them with whitespace.
+An argument of
+.Cm any
+can be used to remove all restrictions and permit any forwarding requests.
+An argument of
+.Cm none
+can be used to prohibit all forwarding requests.
+The wildcard
+.Sq *
+can be used for host or port to allow all hosts or ports respectively.
+Otherwise, no pattern matching or address lookups are performed on supplied
+names.
.It Cm PKCS11Provider
-Specifies which PKCS#11 provider to use.
-The argument to this keyword is the PKCS#11 shared library
+Specifies which PKCS#11 provider to use or
+.Cm none
+to indicate that no provider should be used (the default).
+The argument to this keyword is a path to the PKCS#11 shared library
.Xr ssh 1
-should use to communicate with a PKCS#11 token providing the user's
-private RSA key.
+should use to communicate with a PKCS#11 token providing keys for user
+authentication.
.It Cm Port
Specifies the port number to connect on the remote host.
The default is 22.
@@ -1205,8 +1423,8 @@ server running on some machine, or execute
.Ic 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).
+.Cm Hostname
+of the host being connected (defaulting to the name typed by the user).
Setting the command to
.Cm none
disables this option entirely.
@@ -1242,11 +1460,20 @@ connection to the specified
.Cm ProxyJump
host and then establishing a
TCP forwarding to the ultimate target from there.
+Setting the host to
+.Cm none
+disables this option entirely.
.Pp
Note that this option will compete with the
.Cm ProxyCommand
option - whichever is specified first will prevent later instances of the
other from taking effect.
+.Pp
+Note also that the configuration for the destination host (either supplied
+via the command-line or the configuration file) is not generally applied
+to jump hosts.
+.Pa ~/.ssh/config
+should be used if specific configuration is required for jump hosts.
.It Cm ProxyUseFdpass
Specifies that
.Cm ProxyCommand
@@ -1255,31 +1482,41 @@ will pass a connected file descriptor back to
instead of continuing to execute and pass data.
The default is
.Cm no .
-.It Cm PubkeyAcceptedKeyTypes
-Specifies the key types that will be used for public key authentication
-as a comma-separated list of patterns.
-Alternately if the specified value begins with a
+.It Cm PubkeyAcceptedAlgorithms
+Specifies the signature algorithms that will be used for public key
+authentication as a comma-separated list of patterns.
+If the specified list begins with a
.Sq +
-character, then the key types after it will be appended to the default
+character, then the algorithms after it will be appended to the default
instead of replacing it.
-If the specified value begins with a
+If the specified list begins with a
.Sq -
-character, then the specified key types (including wildcards) will be removed
+character, then the specified algorithms (including wildcards) will be removed
from the default set instead of replacing them.
+If the specified list begins with a
+.Sq ^
+character, then the specified algorithms will be placed at the head of the
+default set.
The default for this option is:
.Bd -literal -offset 3n
+ssh-ed25519-cert-v01@openssh.com,
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,
-rsa-sha2-512-cert-v01@openssh.com,rsa-sha2-256-cert-v01@openssh.com,
+sk-ssh-ed25519-cert-v01@openssh.com,
+sk-ecdsa-sha2-nistp256-cert-v01@openssh.com,
+rsa-sha2-512-cert-v01@openssh.com,
+rsa-sha2-256-cert-v01@openssh.com,
ssh-rsa-cert-v01@openssh.com,
+ssh-ed25519,
ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521,
-ssh-ed25519,rsa-sha2-512,rsa-sha2-256,ssh-rsa
+sk-ssh-ed25519@openssh.com,
+sk-ecdsa-sha2-nistp256@openssh.com,
+rsa-sha2-512,rsa-sha2-256,ssh-rsa
.Ed
.Pp
-The list of available key types may also be obtained using
-.Qq ssh -Q key .
+The list of available signature algorithms may also be obtained using
+.Qq ssh -Q PubkeyAcceptedAlgorithms .
.It Cm PubkeyAuthentication
Specifies whether to try public key authentication.
The argument to this keyword must be
@@ -1289,7 +1526,7 @@ or
.Cm no .
.It Cm RekeyLimit
Specifies the maximum amount of data that may be transmitted before the
-session key is renegotiated, optionally followed a maximum amount of
+session key is renegotiated, optionally followed by 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
.Sq K ,
@@ -1303,9 +1540,7 @@ and
.Sq 4G ,
depending on the cipher.
The optional second value is specified in seconds and may use any of the
-units documented in the
-.Sx TIME FORMATS
-section of
+units documented in the TIME FORMATS section of
.Xr sshd_config 5 .
The default value for
.Cm RekeyLimit
@@ -1329,20 +1564,30 @@ the secure channel.
The remote port may either be forwarded to a specified host and port
from the local machine, or may act as a SOCKS 4/5 proxy that allows a remote
client to connect to arbitrary destinations from the local machine.
-The first argument must be
+The first argument is the listening specification and may be
.Sm off
.Oo Ar bind_address : Oc Ar port
.Sm on
+or, if the remote host supports it, a Unix domain socket path.
If forwarding to a specific destination then the second argument must be
-.Ar host : Ns Ar hostport ,
+.Ar host : Ns Ar hostport
+or a Unix domain socket path,
otherwise if no destination argument is specified then the remote forwarding
will be established as a SOCKS proxy.
+When acting as a SOCKS proxy the destination of the connection can be
+restricted by
+.Cm PermitRemoteOpen .
.Pp
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.
+Unix domain socket paths may use the tokens described in the
+.Sx TOKENS
+section and environment variables as described in the
+.Sx ENVIRONMENT VARIABLES
+section.
.Pp
If the
.Ar port
@@ -1392,6 +1637,15 @@ an OpenSSH Key Revocation List (KRL) as generated by
.Xr ssh-keygen 1 .
For more information on KRLs, see the KEY REVOCATION LISTS section in
.Xr ssh-keygen 1 .
+.It Cm SecurityKeyProvider
+Specifies a path to a library that will be used when loading any
+FIDO authenticator-hosted keys, overriding the default of using
+the built-in USB HID support.
+.Pp
+If the specified value begins with a
+.Sq $
+character, then it will be treated as an environment variable containing
+the path to the library.
.It Cm SendEnv
Specifies what variables from the local
.Xr environ 7
@@ -1439,7 +1693,7 @@ The TCP keepalive option enabled by
.Cm TCPKeepAlive
is spoofable.
The server alive mechanism is valuable when the client or
-server depend on knowing when a connection has become inactive.
+server depend on knowing when a connection has become unresponsive.
.Pp
The default value is 3.
If, for example,
@@ -1456,12 +1710,45 @@ 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.
+.It Cm SessionType
+May be used to either request invocation of a subsystem on the remote system,
+or to prevent the execution of a remote command at all.
+The latter is useful for just forwarding ports.
+The argument to this keyword must be
+.Cm none
+(same as the
+.Fl N
+option),
+.Cm subsystem
+(same as the
+.Fl s
+option) or
+.Cm default
+(shell or command execution).
.It Cm SetEnv
Directly specify one or more environment variables and their contents to
be sent to the server.
Similarly to
.Cm SendEnv ,
-the server must be prepared to accept the environment variable.
+with the exception of the
+.Ev TERM
+variable, the server must be prepared to accept the environment variable.
+.It Cm StdinNull
+Redirects stdin from
+.Pa /dev/null
+(actually, prevents reading from stdin).
+Either this or the equivalent
+.Fl n
+option must be used when
+.Nm ssh
+is run in the background.
+The argument to this keyword must be
+.Cm yes
+(same as the
+.Fl n
+option) or
+.Cm no
+(the default).
.It Cm StreamLocalBindMask
Sets the octal file creation mode mask
.Pq umask
@@ -1505,8 +1792,9 @@ add all new hosts.
.Pp
If this flag is set to
.Dq accept-new
-then ssh will automatically add new host keys to the user
-known hosts files, but will not permit connections to hosts with
+then ssh will automatically add new host keys to the user's
+.Pa known_hosts
+file, but will not permit connections to hosts with
changed host keys.
If this flag is set to
.Dq no
@@ -1597,13 +1885,30 @@ after authentication has completed and add them to
The argument must be
.Cm yes ,
.Cm no
-(the default) or
+or
.Cm ask .
-Enabling this option allows learning alternate hostkeys for a server
+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.
+.Pp
Additional hostkeys are only accepted if the key used to authenticate the
-host was already trusted or explicitly accepted by the user.
+host was already trusted or explicitly accepted by the user, the host was
+authenticated via
+.Cm UserKnownHostsFile
+(i.e. not
+.Cm GlobalKnownHostsFile )
+and the host was authenticated using a plain key and not a certificate.
+.Pp
+.Cm UpdateHostKeys
+is enabled by default if the user has not overridden the default
+.Cm UserKnownHostsFile
+setting and has not enabled
+.Cm VerifyHostKeyDNS ,
+otherwise
+.Cm UpdateHostKeys
+will be set to
+.Cm no .
+.Pp
If
.Cm UpdateHostKeys
is set to
@@ -1626,6 +1931,12 @@ having to remember to give the user name on the command line.
.It Cm UserKnownHostsFile
Specifies one or more files to use for the user
host key database, separated by whitespace.
+Each filename may use tilde notation to refer to the user's home directory,
+the tokens described in the
+.Sx TOKENS
+section and environment variables as described in the
+.Sx ENVIRONMENT VARIABLES
+section.
The default is
.Pa ~/.ssh/known_hosts ,
.Pa ~/.ssh/known_hosts2 .
@@ -1658,7 +1969,7 @@ in
Specifies a string to append to the regular version string to identify
OS- or site-specific modifications.
The default is
-.Dq FreeBSD-20200214 .
+.Dq FreeBSD-20210907 .
The value
.Cm none
may be used to disable this.
@@ -1739,10 +2050,34 @@ A literal
Hash of %l%h%p%r.
.It %d
Local user's home directory.
+.It %f
+The fingerprint of the server's host key.
+.It %H
+The
+.Pa known_hosts
+hostname or address that is being searched for.
.It %h
The remote hostname.
+.It \%%I
+A string describing the reason for a
+.Cm KnownHostsCommand
+execution: either
+.Cm ADDRESS
+when looking up a host by address (only when
+.Cm CheckHostIP
+is enabled),
+.Cm HOSTNAME
+when searching by hostname, or
+.Cm ORDER
+when preparing the host key algorithm preference list to use for the
+destination host.
.It %i
The local user ID.
+.It %K
+The base64 encoded host key.
+.It %k
+The host key alias if specified, otherwise the original remote hostname given
+on the command line.
.It %L
The local hostname.
.It %l
@@ -1762,35 +2097,61 @@ network interface assigned if
tunnel forwarding was requested, or
.Qq NONE
otherwise.
+.It %t
+The type of the server host key, e.g.
+.Cm ssh-ed25519 .
.It %u
The local username.
.El
.Pp
-.Cm Match exec
-accepts the tokens %%, %h, %i, %L, %l, %n, %p, %r, and %u.
+.Cm CertificateFile ,
+.Cm ControlPath ,
+.Cm IdentityAgent ,
+.Cm IdentityFile ,
+.Cm KnownHostsCommand ,
+.Cm LocalForward ,
+.Cm Match exec ,
+.Cm RemoteCommand ,
+.Cm RemoteForward ,
+and
+.Cm UserKnownHostsFile
+accept the tokens %%, %C, %d, %h, %i, %k, %L, %l, %n, %p, %r, and %u.
.Pp
-.Cm CertificateFile
-accepts the tokens %%, %d, %h, %i, %l, %r, and %u.
+.Cm KnownHostsCommand
+additionally accepts the tokens %f, %H, %I, %K and %t.
.Pp
-.Cm ControlPath
-accepts the tokens %%, %C, %h, %i, %L, %l, %n, %p, %r, and %u.
-.Pp
-.Cm HostName
+.Cm Hostname
accepts the tokens %% and %h.
.Pp
-.Cm IdentityAgent
-and
-.Cm IdentityFile
-accept the tokens %%, %d, %h, %i, %l, %r, and %u.
-.Pp
.Cm LocalCommand
-accepts the tokens %%, %C, %d, %h, %i, %l, %n, %p, %r, %T, and %u.
+accepts all tokens.
.Pp
.Cm ProxyCommand
-accepts the tokens %%, %h, %p, and %r.
-.Pp
-.Cm RemoteCommand
-accepts the tokens %%, %C, %d, %h, %i, %l, %n, %p, %r, and %u.
+accepts the tokens %%, %h, %n, %p, and %r.
+.Sh ENVIRONMENT VARIABLES
+Arguments to some keywords can be expanded at runtime from environment
+variables on the client by enclosing them in
+.Ic ${} ,
+for example
+.Ic ${HOME}/.ssh
+would refer to the user's .ssh directory.
+If a specified environment variable does not exist then an error will be
+returned and the setting for that keyword will be ignored.
+.Pp
+The keywords
+.Cm CertificateFile ,
+.Cm ControlPath ,
+.Cm IdentityAgent ,
+.Cm IdentityFile ,
+.Cm KnownHostsCommand ,
+and
+.Cm UserKnownHostsFile
+support environment variables.
+The keywords
+.Cm LocalForward
+and
+.Cm RemoteForward
+support environment variables only for Unix domain socket paths.
.Sh FILES
.Bl -tag -width Ds
.It Pa ~/.ssh/config
@@ -1798,7 +2159,7 @@ 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.
+read/write for the user, and not writable by others.
.It Pa /etc/ssh/ssh_config
Systemwide configuration file.
This file provides defaults for those
diff --git a/crypto/openssh/ssh_namespace.h b/crypto/openssh/ssh_namespace.h
index 71accdf4fb59..2c2060567460 100644
--- a/crypto/openssh/ssh_namespace.h
+++ b/crypto/openssh/ssh_namespace.h
@@ -8,11 +8,15 @@
#define Blowfish_expandstate Fssh_Blowfish_expandstate
#define Blowfish_initstate Fssh_Blowfish_initstate
#define Blowfish_stream2word Fssh_Blowfish_stream2word
+#define Decode Fssh_Decode
#define EVP_CIPHER_CTX_get_iv Fssh_EVP_CIPHER_CTX_get_iv
#define EVP_CIPHER_CTX_set_iv Fssh_EVP_CIPHER_CTX_set_iv
+#define Encode Fssh_Encode
+#define Hide Fssh_Hide
+#define Rq_mult_small Fssh_Rq_mult_small
+#define Short_random Fssh_Short_random
#define _ssh__compat_glob Fssh__ssh__compat_glob
#define _ssh__compat_globfree Fssh__ssh__compat_globfree
-#define _ssh_compat_realpath Fssh__ssh_compat_realpath
#define _ssh_exchange_banner Fssh__ssh_exchange_banner
#define _ssh_host_key_sign Fssh__ssh_host_key_sign
#define _ssh_host_private_key Fssh__ssh_host_private_key
@@ -26,14 +30,30 @@
#define add_host_to_hostfile Fssh_add_host_to_hostfile
#define add_p1p1 Fssh_add_p1p1
#define addargs Fssh_addargs
+#define addr_and Fssh_addr_and
+#define addr_cmp Fssh_addr_cmp
+#define addr_host_is_all0s Fssh_addr_host_is_all0s
+#define addr_hostmask Fssh_addr_hostmask
+#define addr_invert Fssh_addr_invert
+#define addr_is_all0s Fssh_addr_is_all0s
#define addr_match_cidr_list Fssh_addr_match_cidr_list
#define addr_match_list Fssh_addr_match_list
#define addr_netmask Fssh_addr_netmask
#define addr_netmatch Fssh_addr_netmatch
+#define addr_ntop Fssh_addr_ntop
+#define addr_pton Fssh_addr_pton
#define addr_pton_cidr Fssh_addr_pton_cidr
+#define addr_sa_pton Fssh_addr_sa_pton
+#define addr_sa_to_xaddr Fssh_addr_sa_to_xaddr
+#define addr_unicast_masklen Fssh_addr_unicast_masklen
+#define addr_xaddr_to_sa Fssh_addr_xaddr_to_sa
#define argv_assemble Fssh_argv_assemble
+#define argv_consume Fssh_argv_consume
+#define argv_free Fssh_argv_free
+#define argv_next Fssh_argv_next
#define argv_split Fssh_argv_split
#define ask_permission Fssh_ask_permission
+#define asmprintf Fssh_asmprintf
#define atoi_err Fssh_atoi_err
#define atomicio Fssh_atomicio
#define atomicio6 Fssh_atomicio6
@@ -67,9 +87,6 @@
#define chacha_encrypt_bytes Fssh_chacha_encrypt_bytes
#define chacha_ivsetup Fssh_chacha_ivsetup
#define chacha_keysetup Fssh_chacha_keysetup
-#define chachapoly_crypt Fssh_chachapoly_crypt
-#define chachapoly_get_length Fssh_chachapoly_get_length
-#define chachapoly_init Fssh_chachapoly_init
#define chan_ibuf_empty Fssh_chan_ibuf_empty
#define chan_is_dead Fssh_chan_is_dead
#define chan_mark_dead Fssh_chan_mark_dead
@@ -188,14 +205,18 @@
#define colon Fssh_colon
#define compare Fssh_compare
#define compare_gps Fssh_compare_gps
+#define compat_banner Fssh_compat_banner
#define compat_cipher_proposal Fssh_compat_cipher_proposal
-#define compat_datafellows Fssh_compat_datafellows
#define compat_kex_proposal Fssh_compat_kex_proposal
#define compat_pkalg_proposal Fssh_compat_pkalg_proposal
+#define compression_alg_list Fssh_compression_alg_list
#define connect_next Fssh_connect_next
#define connect_to_helper Fssh_connect_to_helper
#define convtime Fssh_convtime
#define crypto_hash_sha512 Fssh_crypto_hash_sha512
+#define crypto_kem_sntrup761_dec Fssh_crypto_kem_sntrup761_dec
+#define crypto_kem_sntrup761_enc Fssh_crypto_kem_sntrup761_enc
+#define crypto_kem_sntrup761_keypair Fssh_crypto_kem_sntrup761_keypair
#define crypto_scalarmult_curve25519 Fssh_crypto_scalarmult_curve25519
#define crypto_sign_ed25519 Fssh_crypto_sign_ed25519
#define crypto_sign_ed25519_keypair Fssh_crypto_sign_ed25519_keypair
@@ -240,9 +261,6 @@
#define daemonized Fssh_daemonized
#define dangerous_locale Fssh_dangerous_locale
#define dbl_p1p1 Fssh_dbl_p1p1
-#define debug Fssh_debug
-#define debug2 Fssh_debug2
-#define debug3 Fssh_debug3
#define default_key_sign Fssh_default_key_sign
#define dh_estimate Fssh_dh_estimate
#define dh_gen_key Fssh_dh_gen_key
@@ -254,22 +272,21 @@
#define dh_new_group_asc Fssh_dh_new_group_asc
#define dh_new_group_fallback Fssh_dh_new_group_fallback
#define dh_pub_is_valid Fssh_dh_pub_is_valid
+#define dh_set_moduli_file Fssh_dh_set_moduli_file
#define dispatch_protocol_error Fssh_dispatch_protocol_error
#define dispatch_protocol_ignore Fssh_dispatch_protocol_ignore
-#define dns_read_key Fssh_dns_read_key
#define do_log Fssh_do_log
-#define do_log2 Fssh_do_log2
-#define dump_base64 Fssh_dump_base64
+#define dollar_expand Fssh_dollar_expand
+#define ecdsa_do_sign Fssh_ecdsa_do_sign
#define encode_constraints Fssh_encode_constraints
-#define error Fssh_error
#define exited_cleanly Fssh_exited_cleanly
#define export_dns_rr Fssh_export_dns_rr
-#define fatal Fssh_fatal
#define filter_list Fssh_filter_list
#define fingerprint_b64 Fssh_fingerprint_b64
#define fingerprint_hex Fssh_fingerprint_hex
#define fmprintf Fssh_fmprintf
#define fmt_scaled Fssh_fmt_scaled
+#define fmt_timeframe Fssh_fmt_timeframe
#define format_absolute_time Fssh_format_absolute_time
#define forward_equals Fssh_forward_equals
#define free_hostkeys Fssh_free_hostkeys
@@ -285,6 +302,7 @@
#define get_peer_ipaddr Fssh_get_peer_ipaddr
#define get_peer_port Fssh_get_peer_port
#define get_rdomain Fssh_get_rdomain
+#define get_sock_af Fssh_get_sock_af
#define get_sock_port Fssh_get_sock_port
#define get_socket_address Fssh_get_socket_address
#define get_u16 Fssh_get_u16
@@ -298,21 +316,20 @@
#define globextend Fssh_globextend
#define host_delete Fssh_host_delete
#define host_hash Fssh_host_hash
+#define hostfile_create_user_ssh_dir Fssh_hostfile_create_user_ssh_dir
#define hostfile_read_key Fssh_hostfile_read_key
#define hostfile_replace_entries Fssh_hostfile_replace_entries
#define hostkeys_foreach Fssh_hostkeys_foreach
+#define hostkeys_foreach_file Fssh_hostkeys_foreach_file
#define hpdelim Fssh_hpdelim
+#define hpdelim2 Fssh_hpdelim2
#define init_hostkeys Fssh_init_hostkeys
-#define input_kex_c25519_init Fssh_input_kex_c25519_init
-#define input_kex_c25519_reply Fssh_input_kex_c25519_reply
-#define input_kex_dh Fssh_input_kex_dh
#define input_kex_dh_gex_group Fssh_input_kex_dh_gex_group
#define input_kex_dh_gex_init Fssh_input_kex_dh_gex_init
#define input_kex_dh_gex_reply Fssh_input_kex_dh_gex_reply
#define input_kex_dh_gex_request Fssh_input_kex_dh_gex_request
-#define input_kex_dh_init Fssh_input_kex_dh_init
-#define input_kex_ecdh_init Fssh_input_kex_ecdh_init
-#define input_kex_ecdh_reply Fssh_input_kex_ecdh_reply
+#define input_kex_gen_init Fssh_input_kex_gen_init
+#define input_kex_gen_reply Fssh_input_kex_gen_reply
#define iptos2str Fssh_iptos2str
#define ipv64_normalise_mapped Fssh_ipv64_normalise_mapped
#define is_key_revoked Fssh_is_key_revoked
@@ -320,38 +337,53 @@
#define kex_alg_list Fssh_kex_alg_list
#define kex_assemble_names Fssh_kex_assemble_names
#define kex_buf2prop Fssh_kex_buf2prop
-#define kex_c25519_hash Fssh_kex_c25519_hash
+#define kex_c25519_dec Fssh_kex_c25519_dec
+#define kex_c25519_enc Fssh_kex_c25519_enc
+#define kex_c25519_keypair Fssh_kex_c25519_keypair
#define kex_derive_keys Fssh_kex_derive_keys
-#define kex_derive_keys_bn Fssh_kex_derive_keys_bn
-#define kex_dh_hash Fssh_kex_dh_hash
-#define kex_ecdh_hash Fssh_kex_ecdh_hash
+#define kex_dh_compute_key Fssh_kex_dh_compute_key
+#define kex_dh_dec Fssh_kex_dh_dec
+#define kex_dh_enc Fssh_kex_dh_enc
+#define kex_dh_keygen Fssh_kex_dh_keygen
+#define kex_dh_keypair Fssh_kex_dh_keypair
+#define kex_ecdh_dec Fssh_kex_ecdh_dec
+#define kex_ecdh_dec_key_group Fssh_kex_ecdh_dec_key_group
+#define kex_ecdh_enc Fssh_kex_ecdh_enc
+#define kex_ecdh_keypair Fssh_kex_ecdh_keypair
+#define kex_exchange_identification Fssh_kex_exchange_identification
#define kex_free Fssh_kex_free
#define kex_free_newkeys Fssh_kex_free_newkeys
+#define kex_gen_client Fssh_kex_gen_client
+#define kex_gen_hash Fssh_kex_gen_hash
+#define kex_gen_server Fssh_kex_gen_server
#define kex_input_ext_info Fssh_kex_input_ext_info
#define kex_input_kexinit Fssh_kex_input_kexinit
#define kex_input_newkeys Fssh_kex_input_newkeys
+#define kex_kem_sntrup761x25519_dec Fssh_kex_kem_sntrup761x25519_dec
+#define kex_kem_sntrup761x25519_enc Fssh_kex_kem_sntrup761x25519_enc
+#define kex_kem_sntrup761x25519_keypair Fssh_kex_kem_sntrup761x25519_keypair
+#define kex_load_hostkey Fssh_kex_load_hostkey
#define kex_names_cat Fssh_kex_names_cat
#define kex_names_valid Fssh_kex_names_valid
#define kex_new Fssh_kex_new
#define kex_prop2buf Fssh_kex_prop2buf
#define kex_prop_free Fssh_kex_prop_free
#define kex_protocol_error Fssh_kex_protocol_error
+#define kex_ready Fssh_kex_ready
#define kex_send_kexinit Fssh_kex_send_kexinit
#define kex_send_newkeys Fssh_kex_send_newkeys
#define kex_setup Fssh_kex_setup
#define kex_start_rekex Fssh_kex_start_rekex
-#define kexc25519_client Fssh_kexc25519_client
+#define kex_verify_host_key Fssh_kex_verify_host_key
#define kexc25519_keygen Fssh_kexc25519_keygen
-#define kexc25519_server Fssh_kexc25519_server
#define kexc25519_shared_key Fssh_kexc25519_shared_key
-#define kexdh_client Fssh_kexdh_client
-#define kexdh_server Fssh_kexdh_server
-#define kexecdh_client Fssh_kexecdh_client
-#define kexecdh_server Fssh_kexecdh_server
+#define kexc25519_shared_key_ext Fssh_kexc25519_shared_key_ext
#define kexgex_client Fssh_kexgex_client
#define kexgex_hash Fssh_kexgex_hash
#define kexgex_server Fssh_kexgex_server
+#define krl_dump Fssh_krl_dump
#define load_hostkeys Fssh_load_hostkeys
+#define load_hostkeys_file Fssh_load_hostkeys_file
#define log_change_level Fssh_log_change_level
#define log_facility_name Fssh_log_facility_name
#define log_facility_number Fssh_log_facility_number
@@ -361,9 +393,11 @@
#define log_level_name Fssh_log_level_name
#define log_level_number Fssh_log_level_number
#define log_redirect_stderr_to Fssh_log_redirect_stderr_to
-#define logdie Fssh_logdie
-#define logit Fssh_logit
+#define log_verbose_add Fssh_log_verbose_add
+#define log_verbose_reset Fssh_log_verbose_reset
+#define lookup_env_in_list Fssh_lookup_env_in_list
#define lookup_key_in_hostkeys_by_type Fssh_lookup_key_in_hostkeys_by_type
+#define lookup_marker_in_hostkeys Fssh_lookup_marker_in_hostkeys
#define lowercase Fssh_lowercase
#define mac_alg_list Fssh_mac_alg_list
#define mac_check Fssh_mac_check
@@ -372,15 +406,15 @@
#define mac_init Fssh_mac_init
#define mac_setup Fssh_mac_setup
#define mac_valid Fssh_mac_valid
-#define match Fssh_match
-#define match_filter_blacklist Fssh_match_filter_blacklist
-#define match_filter_whitelist Fssh_match_filter_whitelist
+#define match_filter_allowlist Fssh_match_filter_allowlist
+#define match_filter_denylist Fssh_match_filter_denylist
#define match_host_and_ip Fssh_match_host_and_ip
#define match_hostname Fssh_match_hostname
#define match_list Fssh_match_list
#define match_pattern Fssh_match_pattern
#define match_pattern_list Fssh_match_pattern_list
#define match_user Fssh_match_user
+#define match_usergroup_pattern_list Fssh_match_usergroup_pattern_list
#define mktemp_proto Fssh_mktemp_proto
#define mm_choose_dh Fssh_mm_choose_dh
#define mm_receive_fd Fssh_mm_receive_fd
@@ -394,43 +428,47 @@
#define ms_subtract_diff Fssh_ms_subtract_diff
#define ms_to_timeval Fssh_ms_to_timeval
#define msetlocale Fssh_msetlocale
-#define mysignal Fssh_mysignal
#define newkeys_from_blob Fssh_newkeys_from_blob
#define newkeys_to_blob Fssh_newkeys_to_blob
#define nh_aux Fssh_nh_aux
#define nh_final Fssh_nh_final
+#define note_key Fssh_note_key
+#define notify_complete Fssh_notify_complete
+#define notify_start Fssh_notify_start
#define open_preamble Fssh_open_preamble
-#define packet_close Fssh_packet_close
-#define packet_disconnect Fssh_packet_disconnect
-#define packet_get_char Fssh_packet_get_char
-#define packet_get_int Fssh_packet_get_int
-#define packet_process_incoming Fssh_packet_process_incoming
-#define packet_read_expect Fssh_packet_read_expect
-#define packet_read_poll_seqnr Fssh_packet_read_poll_seqnr
-#define packet_read_seqnr Fssh_packet_read_seqnr
-#define packet_send_debug Fssh_packet_send_debug
-#define packet_set_connection Fssh_packet_set_connection
-#define packet_write_poll Fssh_packet_write_poll
-#define packet_write_wait Fssh_packet_write_wait
+#define opt_array_append Fssh_opt_array_append
+#define opt_array_append2 Fssh_opt_array_append2
+#define opt_dequote Fssh_opt_dequote
+#define opt_flag Fssh_opt_flag
+#define opt_match Fssh_opt_match
+#define ossl_error Fssh_ossl_error
#define parse_absolute_time Fssh_parse_absolute_time
#define parse_ipqos Fssh_parse_ipqos
#define parse_prime Fssh_parse_prime
#define parse_uri Fssh_parse_uri
#define parse_user_host_path Fssh_parse_user_host_path
#define parse_user_host_port Fssh_parse_user_host_port
+#define path_absolute Fssh_path_absolute
#define pem_passphrase_cb Fssh_pem_passphrase_cb
+#define percent_dollar_expand Fssh_percent_dollar_expand
#define percent_expand Fssh_percent_expand
#define permission_set_add Fssh_permission_set_add
#define permitopen_port Fssh_permitopen_port
#define pkcs11_add_provider Fssh_pkcs11_add_provider
#define pkcs11_del_provider Fssh_pkcs11_del_provider
-#define pkcs11_fetch_keys_filter Fssh_pkcs11_fetch_keys_filter
+#define pkcs11_ecdsa_wrap Fssh_pkcs11_ecdsa_wrap
+#define pkcs11_fetch_certs Fssh_pkcs11_fetch_certs
+#define pkcs11_fetch_keys Fssh_pkcs11_fetch_keys
#define pkcs11_find Fssh_pkcs11_find
+#define pkcs11_get_key Fssh_pkcs11_get_key
#define pkcs11_init Fssh_pkcs11_init
+#define pkcs11_k11_free Fssh_pkcs11_k11_free
+#define pkcs11_login_slot Fssh_pkcs11_login_slot
#define pkcs11_provider_finalize Fssh_pkcs11_provider_finalize
-#define pkcs11_rsa_finish Fssh_pkcs11_rsa_finish
+#define pkcs11_provider_unref Fssh_pkcs11_provider_unref
#define pkcs11_rsa_private_decrypt Fssh_pkcs11_rsa_private_decrypt
#define pkcs11_rsa_private_encrypt Fssh_pkcs11_rsa_private_encrypt
+#define pkcs11_rsa_wrap Fssh_pkcs11_rsa_wrap
#define pkcs11_terminate Fssh_pkcs11_terminate
#define plain_key_blob Fssh_plain_key_blob
#define platform_disable_tracing Fssh_platform_disable_tracing
@@ -444,7 +482,7 @@
#define poly_hash Fssh_poly_hash
#define port_open_helper Fssh_port_open_helper
#define prime_test Fssh_prime_test
-#define proto_spec Fssh_proto_spec
+#define private2_uudecode Fssh_private2_uudecode
#define put_host_port Fssh_put_host_port
#define put_u16 Fssh_put_u16
#define put_u32 Fssh_put_u32
@@ -465,32 +503,36 @@
#define revoked_serial_tree_RB_REMOVE Fssh_revoked_serial_tree_RB_REMOVE
#define rijndaelEncrypt Fssh_rijndaelEncrypt
#define rijndaelKeySetupEnc Fssh_rijndaelKeySetupEnc
+#define rtrim Fssh_rtrim
#define safe_path Fssh_safe_path
#define safe_path_fd Fssh_safe_path_fd
#define sanitise_stdfd Fssh_sanitise_stdfd
#define scan_scaled Fssh_scan_scaled
#define seed_rng Fssh_seed_rng
+#define send_error Fssh_send_error
#define set_log_handler Fssh_set_log_handler
#define set_nodelay Fssh_set_nodelay
#define set_nonblock Fssh_set_nonblock
#define set_rdomain Fssh_set_rdomain
#define set_reuseaddr Fssh_set_reuseaddr
+#define set_sock_tos Fssh_set_sock_tos
+#define sftp_realpath Fssh_sftp_realpath
#define shadow_pw Fssh_shadow_pw
#define sieve_large Fssh_sieve_large
+#define sig_alarm Fssh_sig_alarm
#define sig_winch Fssh_sig_winch
-#define sigdie Fssh_sigdie
+#define skip_space Fssh_skip_space
#define snmprintf Fssh_snmprintf
#define sock_set_v6only Fssh_sock_set_v6only
#define speed_to_baud Fssh_speed_to_baud
-#define ssh_OpenSSL_add_all_algorithms Fssh_ssh_OpenSSL_add_all_algorithms
#define ssh_add_hostkey Fssh_ssh_add_hostkey
#define ssh_add_identity_constrained Fssh_ssh_add_identity_constrained
+#define ssh_agent_has_key Fssh_ssh_agent_has_key
#define ssh_agent_sign Fssh_ssh_agent_sign
#define ssh_alloc_session_state Fssh_ssh_alloc_session_state
#define ssh_clear_newkeys Fssh_ssh_clear_newkeys
#define ssh_close_authentication_socket Fssh_ssh_close_authentication_socket
#define ssh_compatible_openssl Fssh_ssh_compatible_openssl
-#define ssh_crc32 Fssh_ssh_crc32
#define ssh_digest_alg_by_name Fssh_ssh_digest_alg_by_name
#define ssh_digest_alg_name Fssh_ssh_digest_alg_name
#define ssh_digest_blocksize Fssh_ssh_digest_blocksize
@@ -521,6 +563,7 @@
#define ssh_gai_strerror Fssh_ssh_gai_strerror
#define ssh_get_app_data Fssh_ssh_get_app_data
#define ssh_get_authentication_socket Fssh_ssh_get_authentication_socket
+#define ssh_get_authentication_socket_path Fssh_ssh_get_authentication_socket_path
#define ssh_get_progname Fssh_ssh_get_progname
#define ssh_hmac_bytes Fssh_ssh_hmac_bytes
#define ssh_hmac_final Fssh_ssh_hmac_final
@@ -547,15 +590,16 @@
#define ssh_krl_set_comment Fssh_ssh_krl_set_comment
#define ssh_krl_set_version Fssh_ssh_krl_set_version
#define ssh_krl_to_blob Fssh_ssh_krl_to_blob
+#define ssh_libcrypto_init Fssh_ssh_libcrypto_init
#define ssh_local_ipaddr Fssh_ssh_local_ipaddr
#define ssh_local_port Fssh_ssh_local_port
#define ssh_lock_agent Fssh_ssh_lock_agent
-#define ssh_malloc_init Fssh_ssh_malloc_init
#define ssh_msg_recv Fssh_ssh_msg_recv
#define ssh_msg_send Fssh_ssh_msg_send
#define ssh_output_consume Fssh_ssh_output_consume
#define ssh_output_ptr Fssh_ssh_output_ptr
#define ssh_output_space Fssh_ssh_output_space
+#define ssh_packet_check_rekey Fssh_ssh_packet_check_rekey
#define ssh_packet_clear_keys Fssh_ssh_packet_clear_keys
#define ssh_packet_close Fssh_ssh_packet_close
#define ssh_packet_close_internal Fssh_ssh_packet_close_internal
@@ -563,24 +607,16 @@
#define ssh_packet_connection_is_on_socket Fssh_ssh_packet_connection_is_on_socket
#define ssh_packet_disconnect Fssh_ssh_packet_disconnect
#define ssh_packet_enable_delayed_compress Fssh_ssh_packet_enable_delayed_compress
-#define ssh_packet_get_bignum2 Fssh_ssh_packet_get_bignum2
#define ssh_packet_get_bytes Fssh_ssh_packet_get_bytes
-#define ssh_packet_get_char Fssh_ssh_packet_get_char
#define ssh_packet_get_connection_in Fssh_ssh_packet_get_connection_in
#define ssh_packet_get_connection_out Fssh_ssh_packet_get_connection_out
-#define ssh_packet_get_cstring Fssh_ssh_packet_get_cstring
-#define ssh_packet_get_ecpoint Fssh_ssh_packet_get_ecpoint
#define ssh_packet_get_input Fssh_ssh_packet_get_input
-#define ssh_packet_get_int Fssh_ssh_packet_get_int
-#define ssh_packet_get_int64 Fssh_ssh_packet_get_int64
#define ssh_packet_get_maxsize Fssh_ssh_packet_get_maxsize
#define ssh_packet_get_mux Fssh_ssh_packet_get_mux
#define ssh_packet_get_output Fssh_ssh_packet_get_output
#define ssh_packet_get_protocol_flags Fssh_ssh_packet_get_protocol_flags
#define ssh_packet_get_rekey_timeout Fssh_ssh_packet_get_rekey_timeout
#define ssh_packet_get_state Fssh_ssh_packet_get_state
-#define ssh_packet_get_string Fssh_ssh_packet_get_string
-#define ssh_packet_get_string_ptr Fssh_ssh_packet_get_string_ptr
#define ssh_packet_have_data_to_write Fssh_ssh_packet_have_data_to_write
#define ssh_packet_inc_alive_timeouts Fssh_ssh_packet_inc_alive_timeouts
#define ssh_packet_is_interactive Fssh_ssh_packet_is_interactive
@@ -592,14 +628,6 @@
#define ssh_packet_payload Fssh_ssh_packet_payload
#define ssh_packet_process_incoming Fssh_ssh_packet_process_incoming
#define ssh_packet_put Fssh_ssh_packet_put
-#define ssh_packet_put_bignum2 Fssh_ssh_packet_put_bignum2
-#define ssh_packet_put_char Fssh_ssh_packet_put_char
-#define ssh_packet_put_cstring Fssh_ssh_packet_put_cstring
-#define ssh_packet_put_ecpoint Fssh_ssh_packet_put_ecpoint
-#define ssh_packet_put_int Fssh_ssh_packet_put_int
-#define ssh_packet_put_int64 Fssh_ssh_packet_put_int64
-#define ssh_packet_put_raw Fssh_ssh_packet_put_raw
-#define ssh_packet_put_string Fssh_ssh_packet_put_string
#define ssh_packet_rdomain_in Fssh_ssh_packet_rdomain_in
#define ssh_packet_read Fssh_ssh_packet_read
#define ssh_packet_read_expect Fssh_ssh_packet_read_expect
@@ -607,7 +635,6 @@
#define ssh_packet_read_poll_seqnr Fssh_ssh_packet_read_poll_seqnr
#define ssh_packet_read_seqnr Fssh_ssh_packet_read_seqnr
#define ssh_packet_remaining Fssh_ssh_packet_remaining
-#define ssh_packet_send Fssh_ssh_packet_send
#define ssh_packet_send2 Fssh_ssh_packet_send2
#define ssh_packet_send2_wrapped Fssh_ssh_packet_send2_wrapped
#define ssh_packet_send_debug Fssh_ssh_packet_send_debug
@@ -626,7 +653,6 @@
#define ssh_packet_set_state Fssh_ssh_packet_set_state
#define ssh_packet_set_timeout Fssh_ssh_packet_set_timeout
#define ssh_packet_set_tos Fssh_ssh_packet_set_tos
-#define ssh_packet_start Fssh_ssh_packet_start
#define ssh_packet_start_discard Fssh_ssh_packet_start_discard
#define ssh_packet_stop_discard Fssh_ssh_packet_stop_discard
#define ssh_packet_write_poll Fssh_ssh_packet_write_poll
@@ -642,6 +668,7 @@
#define ssh_set_app_data Fssh_ssh_set_app_data
#define ssh_set_newkeys Fssh_ssh_set_newkeys
#define ssh_set_verify_host_key_callback Fssh_ssh_set_verify_host_key_callback
+#define ssh_signal Fssh_ssh_signal
#define ssh_tty_make_modes Fssh_ssh_tty_make_modes
#define ssh_tty_parse_modes Fssh_ssh_tty_parse_modes
#define ssh_update_card Fssh_ssh_update_card
@@ -650,19 +677,22 @@
#define sshbuf_avail Fssh_sshbuf_avail
#define sshbuf_b64tod Fssh_sshbuf_b64tod
#define sshbuf_check_reserve Fssh_sshbuf_check_reserve
+#define sshbuf_cmp Fssh_sshbuf_cmp
#define sshbuf_consume Fssh_sshbuf_consume
#define sshbuf_consume_end Fssh_sshbuf_consume_end
#define sshbuf_dtob16 Fssh_sshbuf_dtob16
#define sshbuf_dtob64 Fssh_sshbuf_dtob64
+#define sshbuf_dtob64_string Fssh_sshbuf_dtob64_string
+#define sshbuf_dtourlb64 Fssh_sshbuf_dtourlb64
#define sshbuf_dump Fssh_sshbuf_dump
#define sshbuf_dump_data Fssh_sshbuf_dump_data
#define sshbuf_dup_string Fssh_sshbuf_dup_string
+#define sshbuf_find Fssh_sshbuf_find
#define sshbuf_free Fssh_sshbuf_free
#define sshbuf_from Fssh_sshbuf_from
#define sshbuf_fromb Fssh_sshbuf_fromb
#define sshbuf_froms Fssh_sshbuf_froms
#define sshbuf_get Fssh_sshbuf_get
-#define sshbuf_get_bignum1 Fssh_sshbuf_get_bignum1
#define sshbuf_get_bignum2 Fssh_sshbuf_get_bignum2
#define sshbuf_get_bignum2_bytes_direct Fssh_sshbuf_get_bignum2_bytes_direct
#define sshbuf_get_cstring Fssh_sshbuf_get_cstring
@@ -676,14 +706,24 @@
#define sshbuf_get_u64 Fssh_sshbuf_get_u64
#define sshbuf_get_u8 Fssh_sshbuf_get_u8
#define sshbuf_len Fssh_sshbuf_len
+#define sshbuf_load_fd Fssh_sshbuf_load_fd
+#define sshbuf_load_file Fssh_sshbuf_load_file
#define sshbuf_max_size Fssh_sshbuf_max_size
#define sshbuf_mutable_ptr Fssh_sshbuf_mutable_ptr
#define sshbuf_new Fssh_sshbuf_new
#define sshbuf_parent Fssh_sshbuf_parent
#define sshbuf_peek_string_direct Fssh_sshbuf_peek_string_direct
+#define sshbuf_peek_u16 Fssh_sshbuf_peek_u16
+#define sshbuf_peek_u32 Fssh_sshbuf_peek_u32
+#define sshbuf_peek_u64 Fssh_sshbuf_peek_u64
+#define sshbuf_peek_u8 Fssh_sshbuf_peek_u8
+#define sshbuf_poke Fssh_sshbuf_poke
+#define sshbuf_poke_u16 Fssh_sshbuf_poke_u16
+#define sshbuf_poke_u32 Fssh_sshbuf_poke_u32
+#define sshbuf_poke_u64 Fssh_sshbuf_poke_u64
+#define sshbuf_poke_u8 Fssh_sshbuf_poke_u8
#define sshbuf_ptr Fssh_sshbuf_ptr
#define sshbuf_put Fssh_sshbuf_put
-#define sshbuf_put_bignum1 Fssh_sshbuf_put_bignum1
#define sshbuf_put_bignum2 Fssh_sshbuf_put_bignum2
#define sshbuf_put_bignum2_bytes Fssh_sshbuf_put_bignum2_bytes
#define sshbuf_put_cstring Fssh_sshbuf_put_cstring
@@ -703,8 +743,13 @@
#define sshbuf_reset Fssh_sshbuf_reset
#define sshbuf_set_max_size Fssh_sshbuf_set_max_size
#define sshbuf_set_parent Fssh_sshbuf_set_parent
+#define sshbuf_write_file Fssh_sshbuf_write_file
+#define sshfatal Fssh_sshfatal
+#define sshkey_advance_past_options Fssh_sshkey_advance_past_options
#define sshkey_alg_list Fssh_sshkey_alg_list
#define sshkey_cert_check_authority Fssh_sshkey_cert_check_authority
+#define sshkey_cert_check_authority_now Fssh_sshkey_cert_check_authority_now
+#define sshkey_cert_check_host Fssh_sshkey_cert_check_host
#define sshkey_cert_copy Fssh_sshkey_cert_copy
#define sshkey_cert_type Fssh_sshkey_cert_type
#define sshkey_certify Fssh_sshkey_certify
@@ -738,10 +783,12 @@
#define sshkey_fromb Fssh_sshkey_fromb
#define sshkey_froms Fssh_sshkey_froms
#define sshkey_generate Fssh_sshkey_generate
+#define sshkey_get_sigtype Fssh_sshkey_get_sigtype
#define sshkey_in_file Fssh_sshkey_in_file
#define sshkey_is_cert Fssh_sshkey_is_cert
+#define sshkey_is_shielded Fssh_sshkey_is_shielded
+#define sshkey_is_sk Fssh_sshkey_is_sk
#define sshkey_load_cert Fssh_sshkey_load_cert
-#define sshkey_load_file Fssh_sshkey_load_file
#define sshkey_load_private Fssh_sshkey_load_private
#define sshkey_load_private_cert Fssh_sshkey_load_private_cert
#define sshkey_load_private_type Fssh_sshkey_load_private_type
@@ -752,7 +799,7 @@
#define sshkey_parse_private2 Fssh_sshkey_parse_private2
#define sshkey_parse_private_fileblob Fssh_sshkey_parse_private_fileblob
#define sshkey_parse_private_fileblob_type Fssh_sshkey_parse_private_fileblob_type
-#define sshkey_parse_private_pem_fileblob Fssh_sshkey_parse_private_pem_fileblob
+#define sshkey_parse_pubkey_from_private_fileblob_type Fssh_sshkey_parse_pubkey_from_private_fileblob_type
#define sshkey_perm_ok Fssh_sshkey_perm_ok
#define sshkey_plain_to_blob Fssh_sshkey_plain_to_blob
#define sshkey_private_deserialize Fssh_sshkey_private_deserialize
@@ -767,7 +814,10 @@
#define sshkey_puts_opts Fssh_sshkey_puts_opts
#define sshkey_read Fssh_sshkey_read
#define sshkey_save_private Fssh_sshkey_save_private
+#define sshkey_save_public Fssh_sshkey_save_public
#define sshkey_set_filename Fssh_sshkey_set_filename
+#define sshkey_shield_private Fssh_sshkey_shield_private
+#define sshkey_sig_details_free Fssh_sshkey_sig_details_free
#define sshkey_sigalg_by_name Fssh_sshkey_sigalg_by_name
#define sshkey_sign Fssh_sshkey_sign
#define sshkey_signatures_left Fssh_sshkey_signatures_left
@@ -782,8 +832,13 @@
#define sshkey_type_from_name Fssh_sshkey_type_from_name
#define sshkey_type_is_cert Fssh_sshkey_type_is_cert
#define sshkey_type_plain Fssh_sshkey_type_plain
+#define sshkey_unshield_private Fssh_sshkey_unshield_private
#define sshkey_verify Fssh_sshkey_verify
#define sshkey_write Fssh_sshkey_write
+#define sshlog Fssh_sshlog
+#define sshlogdie Fssh_sshlogdie
+#define sshlogdirect Fssh_sshlogdirect
+#define sshlogv Fssh_sshlogv
#define sshpkt_add_padding Fssh_sshpkt_add_padding
#define sshpkt_disconnect Fssh_sshpkt_disconnect
#define sshpkt_fatal Fssh_sshpkt_fatal
@@ -798,6 +853,7 @@
#define sshpkt_get_u32 Fssh_sshpkt_get_u32
#define sshpkt_get_u64 Fssh_sshpkt_get_u64
#define sshpkt_get_u8 Fssh_sshpkt_get_u8
+#define sshpkt_getb_froms Fssh_sshpkt_getb_froms
#define sshpkt_msg_ignore Fssh_sshpkt_msg_ignore
#define sshpkt_peek_string_direct Fssh_sshpkt_peek_string_direct
#define sshpkt_ptr Fssh_sshpkt_ptr
@@ -813,7 +869,10 @@
#define sshpkt_putb Fssh_sshpkt_putb
#define sshpkt_send Fssh_sshpkt_send
#define sshpkt_start Fssh_sshpkt_start
+#define sshpkt_vfatal Fssh_sshpkt_vfatal
+#define sshsigdie Fssh_sshsigdie
#define start_progress_meter Fssh_start_progress_meter
+#define stdfd_devnull Fssh_stdfd_devnull
#define stop_progress_meter Fssh_stop_progress_meter
#define stravis Fssh_stravis
#define strdelim Fssh_strdelim
@@ -822,8 +881,11 @@
#define strnvis Fssh_strnvis
#define strvis Fssh_strvis
#define strvisx Fssh_strvisx
+#define subprocess Fssh_subprocess
#define sys_tun_open Fssh_sys_tun_open
+#define tilde_expand Fssh_tilde_expand
#define tilde_expand_filename Fssh_tilde_expand_filename
+#define timeout_connect Fssh_timeout_connect
#define to_blob Fssh_to_blob
#define to_blob_buf Fssh_to_blob_buf
#define tohex Fssh_tohex
@@ -838,17 +900,16 @@
#define umac_update Fssh_umac_update
#define unix_listener Fssh_unix_listener
#define unset_nonblock Fssh_unset_nonblock
-#define update_progress_meter Fssh_update_progress_meter
#define urldecode Fssh_urldecode
-#define uudecode Fssh_uudecode
-#define uuencode Fssh_uuencode
#define valid_domain Fssh_valid_domain
#define valid_env_name Fssh_valid_env_name
#define vasnmprintf Fssh_vasnmprintf
-#define verbose Fssh_verbose
+#define vdollar_percent_expand Fssh_vdollar_percent_expand
#define verify_host_key_dns Fssh_verify_host_key_dns
#define vfmprintf Fssh_vfmprintf
#define vis Fssh_vis
+#define waitfd Fssh_waitfd
+#define waitrfd Fssh_waitrfd
#define write_host_entry Fssh_write_host_entry
#define x11_connect_display Fssh_x11_connect_display
#define x11_create_display_inet Fssh_x11_create_display_inet
@@ -856,7 +917,9 @@
#define xasprintf Fssh_xasprintf
#define xcalloc Fssh_xcalloc
#define xcrypt Fssh_xcrypt
+#define xextendf Fssh_xextendf
#define xmalloc Fssh_xmalloc
#define xreallocarray Fssh_xreallocarray
#define xrecallocarray Fssh_xrecallocarray
#define xstrdup Fssh_xstrdup
+#define xvasprintf Fssh_xvasprintf
diff --git a/crypto/openssh/sshbuf-getput-basic.c b/crypto/openssh/sshbuf-getput-basic.c
index 50648258f48d..9803fb5ed904 100644
--- a/crypto/openssh/sshbuf-getput-basic.c
+++ b/crypto/openssh/sshbuf-getput-basic.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: sshbuf-getput-basic.c,v 1.7 2017/06/01 04:51:58 djm Exp $ */
+/* $OpenBSD: sshbuf-getput-basic.c,v 1.11 2020/06/05 03:25:35 djm Exp $ */
/*
* Copyright (c) 2011 Damien Miller
*
@@ -24,6 +24,9 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
+#ifdef HAVE_STDINT_H
+# include <stdint.h>
+#endif
#include "ssherr.h"
#include "sshbuf.h"
@@ -93,6 +96,93 @@ sshbuf_get_u8(struct sshbuf *buf, u_char *valp)
return 0;
}
+static int
+check_offset(const struct sshbuf *buf, int wr, size_t offset, size_t len)
+{
+ if (sshbuf_ptr(buf) == NULL) /* calls sshbuf_check_sanity() */
+ return SSH_ERR_INTERNAL_ERROR;
+ if (offset >= SIZE_MAX - len)
+ return SSH_ERR_INVALID_ARGUMENT;
+ if (offset + len > sshbuf_len(buf)) {
+ return wr ?
+ SSH_ERR_NO_BUFFER_SPACE : SSH_ERR_MESSAGE_INCOMPLETE;
+ }
+ return 0;
+}
+
+static int
+check_roffset(const struct sshbuf *buf, size_t offset, size_t len,
+ const u_char **p)
+{
+ int r;
+
+ *p = NULL;
+ if ((r = check_offset(buf, 0, offset, len)) != 0)
+ return r;
+ *p = sshbuf_ptr(buf) + offset;
+ return 0;
+}
+
+int
+sshbuf_peek_u64(const struct sshbuf *buf, size_t offset, u_int64_t *valp)
+{
+ const u_char *p = NULL;
+ int r;
+
+ if (valp != NULL)
+ *valp = 0;
+ if ((r = check_roffset(buf, offset, 8, &p)) != 0)
+ return r;
+ if (valp != NULL)
+ *valp = PEEK_U64(p);
+ return 0;
+}
+
+int
+sshbuf_peek_u32(const struct sshbuf *buf, size_t offset, u_int32_t *valp)
+{
+ const u_char *p = NULL;
+ int r;
+
+ if (valp != NULL)
+ *valp = 0;
+ if ((r = check_roffset(buf, offset, 4, &p)) != 0)
+ return r;
+ if (valp != NULL)
+ *valp = PEEK_U32(p);
+ return 0;
+}
+
+int
+sshbuf_peek_u16(const struct sshbuf *buf, size_t offset, u_int16_t *valp)
+{
+ const u_char *p = NULL;
+ int r;
+
+ if (valp != NULL)
+ *valp = 0;
+ if ((r = check_roffset(buf, offset, 2, &p)) != 0)
+ return r;
+ if (valp != NULL)
+ *valp = PEEK_U16(p);
+ return 0;
+}
+
+int
+sshbuf_peek_u8(const struct sshbuf *buf, size_t offset, u_char *valp)
+{
+ const u_char *p = NULL;
+ int r;
+
+ if (valp != NULL)
+ *valp = 0;
+ if ((r = check_roffset(buf, offset, 1, &p)) != 0)
+ return r;
+ if (valp != NULL)
+ *valp = *p;
+ return 0;
+}
+
int
sshbuf_get_string(struct sshbuf *buf, u_char **valp, size_t *lenp)
{
@@ -248,6 +338,8 @@ sshbuf_put(struct sshbuf *buf, const void *v, size_t len)
int
sshbuf_putb(struct sshbuf *buf, const struct sshbuf *v)
{
+ if (v == NULL)
+ return 0;
return sshbuf_put(buf, sshbuf_ptr(v), sshbuf_len(v));
}
@@ -344,6 +436,80 @@ sshbuf_put_u8(struct sshbuf *buf, u_char val)
return 0;
}
+static int
+check_woffset(struct sshbuf *buf, size_t offset, size_t len, u_char **p)
+{
+ int r;
+
+ *p = NULL;
+ if ((r = check_offset(buf, 1, offset, len)) != 0)
+ return r;
+ if (sshbuf_mutable_ptr(buf) == NULL)
+ return SSH_ERR_BUFFER_READ_ONLY;
+ *p = sshbuf_mutable_ptr(buf) + offset;
+ return 0;
+}
+
+int
+sshbuf_poke_u64(struct sshbuf *buf, size_t offset, u_int64_t val)
+{
+ u_char *p = NULL;
+ int r;
+
+ if ((r = check_woffset(buf, offset, 8, &p)) != 0)
+ return r;
+ POKE_U64(p, val);
+ return 0;
+}
+
+int
+sshbuf_poke_u32(struct sshbuf *buf, size_t offset, u_int32_t val)
+{
+ u_char *p = NULL;
+ int r;
+
+ if ((r = check_woffset(buf, offset, 4, &p)) != 0)
+ return r;
+ POKE_U32(p, val);
+ return 0;
+}
+
+int
+sshbuf_poke_u16(struct sshbuf *buf, size_t offset, u_int16_t val)
+{
+ u_char *p = NULL;
+ int r;
+
+ if ((r = check_woffset(buf, offset, 2, &p)) != 0)
+ return r;
+ POKE_U16(p, val);
+ return 0;
+}
+
+int
+sshbuf_poke_u8(struct sshbuf *buf, size_t offset, u_char val)
+{
+ u_char *p = NULL;
+ int r;
+
+ if ((r = check_woffset(buf, offset, 1, &p)) != 0)
+ return r;
+ *p = val;
+ return 0;
+}
+
+int
+sshbuf_poke(struct sshbuf *buf, size_t offset, void *v, size_t len)
+{
+ u_char *p = NULL;
+ int r;
+
+ if ((r = check_woffset(buf, offset, len, &p)) != 0)
+ return r;
+ memcpy(p, v, len);
+ return 0;
+}
+
int
sshbuf_put_string(struct sshbuf *buf, const void *v, size_t len)
{
@@ -371,6 +537,9 @@ sshbuf_put_cstring(struct sshbuf *buf, const char *v)
int
sshbuf_put_stringb(struct sshbuf *buf, const struct sshbuf *v)
{
+ if (v == NULL)
+ return sshbuf_put_string(buf, NULL, 0);
+
return sshbuf_put_string(buf, sshbuf_ptr(v), sshbuf_len(v));
}
diff --git a/crypto/openssh/sshbuf-getput-crypto.c b/crypto/openssh/sshbuf-getput-crypto.c
index d0d791b50a34..2e61d3bcd809 100644
--- a/crypto/openssh/sshbuf-getput-crypto.c
+++ b/crypto/openssh/sshbuf-getput-crypto.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: sshbuf-getput-crypto.c,v 1.5 2016/01/12 23:42:54 djm Exp $ */
+/* $OpenBSD: sshbuf-getput-crypto.c,v 1.8 2019/11/15 06:00:20 djm Exp $ */
/*
* Copyright (c) 2011 Damien Miller
*
@@ -23,6 +23,7 @@
#include <stdio.h>
#include <string.h>
+#ifdef WITH_OPENSSL
#include <openssl/bn.h>
#ifdef OPENSSL_HAS_ECC
# include <openssl/ec.h>
@@ -32,41 +33,24 @@
#include "sshbuf.h"
int
-sshbuf_get_bignum2(struct sshbuf *buf, BIGNUM *v)
+sshbuf_get_bignum2(struct sshbuf *buf, BIGNUM **valp)
{
+ BIGNUM *v;
const u_char *d;
size_t len;
int r;
+ if (valp != NULL)
+ *valp = NULL;
if ((r = sshbuf_get_bignum2_bytes_direct(buf, &d, &len)) != 0)
return r;
- if (v != NULL && BN_bin2bn(d, len, v) == NULL)
- return SSH_ERR_ALLOC_FAIL;
- return 0;
-}
-
-int
-sshbuf_get_bignum1(struct sshbuf *buf, BIGNUM *v)
-{
- const u_char *d = sshbuf_ptr(buf);
- u_int16_t len_bits;
- size_t len_bytes;
-
- /* Length in bits */
- if (sshbuf_len(buf) < 2)
- return SSH_ERR_MESSAGE_INCOMPLETE;
- len_bits = PEEK_U16(d);
- len_bytes = (len_bits + 7) >> 3;
- if (len_bytes > SSHBUF_MAX_BIGNUM)
- return SSH_ERR_BIGNUM_TOO_LARGE;
- if (sshbuf_len(buf) < 2 + len_bytes)
- return SSH_ERR_MESSAGE_INCOMPLETE;
- if (v != NULL && BN_bin2bn(d + 2, len_bytes, v) == NULL)
- return SSH_ERR_ALLOC_FAIL;
- if (sshbuf_consume(buf, 2 + len_bytes) != 0) {
- SSHBUF_DBG(("SSH_ERR_INTERNAL_ERROR"));
- SSHBUF_ABORT();
- return SSH_ERR_INTERNAL_ERROR;
+ if (valp != NULL) {
+ if ((v = BN_new()) == NULL ||
+ BN_bin2bn(d, len, v) == NULL) {
+ BN_clear_free(v);
+ return SSH_ERR_ALLOC_FAIL;
+ }
+ *valp = v;
}
return 0;
}
@@ -165,50 +149,22 @@ sshbuf_put_bignum2(struct sshbuf *buf, const BIGNUM *v)
return 0;
}
-int
-sshbuf_put_bignum1(struct sshbuf *buf, const BIGNUM *v)
-{
- int r, len_bits = BN_num_bits(v);
- size_t len_bytes = (len_bits + 7) / 8;
- u_char d[SSHBUF_MAX_BIGNUM], *dp;
-
- if (len_bits < 0 || len_bytes > SSHBUF_MAX_BIGNUM)
- return SSH_ERR_INVALID_ARGUMENT;
- if (BN_bn2bin(v, d) != (int)len_bytes)
- return SSH_ERR_INTERNAL_ERROR; /* Shouldn't happen */
- if ((r = sshbuf_reserve(buf, len_bytes + 2, &dp)) < 0) {
- explicit_bzero(d, sizeof(d));
- return r;
- }
- POKE_U16(dp, len_bits);
- if (len_bytes != 0)
- memcpy(dp + 2, d, len_bytes);
- explicit_bzero(d, sizeof(d));
- return 0;
-}
-
#ifdef OPENSSL_HAS_ECC
int
sshbuf_put_ec(struct sshbuf *buf, const EC_POINT *v, const EC_GROUP *g)
{
u_char d[SSHBUF_MAX_ECPOINT];
- BN_CTX *bn_ctx;
size_t len;
int ret;
- if ((bn_ctx = BN_CTX_new()) == NULL)
- return SSH_ERR_ALLOC_FAIL;
if ((len = EC_POINT_point2oct(g, v, POINT_CONVERSION_UNCOMPRESSED,
- NULL, 0, bn_ctx)) > SSHBUF_MAX_ECPOINT) {
- BN_CTX_free(bn_ctx);
+ NULL, 0, NULL)) > SSHBUF_MAX_ECPOINT) {
return SSH_ERR_INVALID_ARGUMENT;
}
if (EC_POINT_point2oct(g, v, POINT_CONVERSION_UNCOMPRESSED,
- d, len, bn_ctx) != len) {
- BN_CTX_free(bn_ctx);
+ d, len, NULL) != len) {
return SSH_ERR_INTERNAL_ERROR; /* Shouldn't happen */
}
- BN_CTX_free(bn_ctx);
ret = sshbuf_put_string(buf, d, len);
explicit_bzero(d, len);
return ret;
@@ -221,4 +177,4 @@ sshbuf_put_eckey(struct sshbuf *buf, const EC_KEY *v)
EC_KEY_get0_group(v));
}
#endif /* OPENSSL_HAS_ECC */
-
+#endif /* WITH_OPENSSL */
diff --git a/crypto/openssh/sshbuf-io.c b/crypto/openssh/sshbuf-io.c
new file mode 100644
index 000000000000..13ef40e7d272
--- /dev/null
+++ b/crypto/openssh/sshbuf-io.c
@@ -0,0 +1,117 @@
+/* $OpenBSD: sshbuf-io.c,v 1.2 2020/01/25 23:28:06 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.
+ */
+
+#include "includes.h"
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <errno.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <string.h>
+
+#include "ssherr.h"
+#include "sshbuf.h"
+#include "atomicio.h"
+
+/* Load a file from a fd into a buffer */
+int
+sshbuf_load_fd(int fd, struct sshbuf **blobp)
+{
+ u_char buf[4096];
+ size_t len;
+ struct stat st;
+ int r;
+ struct sshbuf *blob;
+
+ *blobp = NULL;
+
+ if (fstat(fd, &st) == -1)
+ return SSH_ERR_SYSTEM_ERROR;
+ if ((st.st_mode & (S_IFSOCK|S_IFCHR|S_IFIFO)) == 0 &&
+ st.st_size > SSHBUF_SIZE_MAX)
+ return SSH_ERR_INVALID_FORMAT;
+ if ((blob = sshbuf_new()) == NULL)
+ return SSH_ERR_ALLOC_FAIL;
+ for (;;) {
+ if ((len = atomicio(read, fd, buf, sizeof(buf))) == 0) {
+ if (errno == EPIPE)
+ break;
+ r = SSH_ERR_SYSTEM_ERROR;
+ goto out;
+ }
+ if ((r = sshbuf_put(blob, buf, len)) != 0)
+ goto out;
+ if (sshbuf_len(blob) > SSHBUF_SIZE_MAX) {
+ r = SSH_ERR_INVALID_FORMAT;
+ goto out;
+ }
+ }
+ if ((st.st_mode & (S_IFSOCK|S_IFCHR|S_IFIFO)) == 0 &&
+ st.st_size != (off_t)sshbuf_len(blob)) {
+ r = SSH_ERR_FILE_CHANGED;
+ goto out;
+ }
+ /* success */
+ *blobp = blob;
+ blob = NULL; /* transferred */
+ r = 0;
+ out:
+ explicit_bzero(buf, sizeof(buf));
+ sshbuf_free(blob);
+ return r;
+}
+
+int
+sshbuf_load_file(const char *path, struct sshbuf **bufp)
+{
+ int r, fd, oerrno;
+
+ *bufp = NULL;
+ if ((fd = open(path, O_RDONLY)) == -1)
+ return SSH_ERR_SYSTEM_ERROR;
+ if ((r = sshbuf_load_fd(fd, bufp)) != 0)
+ goto out;
+ /* success */
+ r = 0;
+ out:
+ oerrno = errno;
+ close(fd);
+ if (r != 0)
+ errno = oerrno;
+ return r;
+}
+
+int
+sshbuf_write_file(const char *path, struct sshbuf *buf)
+{
+ int fd, oerrno;
+
+ if ((fd = open(path, O_WRONLY | O_CREAT | O_TRUNC, 0644)) == -1)
+ return SSH_ERR_SYSTEM_ERROR;
+ if (atomicio(vwrite, fd, sshbuf_mutable_ptr(buf),
+ sshbuf_len(buf)) != sshbuf_len(buf) || close(fd) != 0) {
+ oerrno = errno;
+ close(fd);
+ unlink(path);
+ errno = oerrno;
+ return SSH_ERR_SYSTEM_ERROR;
+ }
+ return 0;
+}
+
diff --git a/crypto/openssh/sshbuf-misc.c b/crypto/openssh/sshbuf-misc.c
index 15dcfbc79196..80714d1f3839 100644
--- a/crypto/openssh/sshbuf-misc.c
+++ b/crypto/openssh/sshbuf-misc.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: sshbuf-misc.c,v 1.6 2016/05/02 08:49:03 djm Exp $ */
+/* $OpenBSD: sshbuf-misc.c,v 1.17 2021/08/11 05:21:32 djm Exp $ */
/*
* Copyright (c) 2011 Damien Miller
*
@@ -23,7 +23,7 @@
#include <errno.h>
#include <stdlib.h>
#ifdef HAVE_STDINT_H
-#include <stdint.h>
+# include <stdint.h>
#endif
#include <stdio.h>
#include <limits.h>
@@ -63,9 +63,9 @@ sshbuf_dump_data(const void *s, size_t len, FILE *f)
}
void
-sshbuf_dump(struct sshbuf *buf, FILE *f)
+sshbuf_dump(const struct sshbuf *buf, FILE *f)
{
- fprintf(f, "buffer %p len = %zu\n", buf, sshbuf_len(buf));
+ fprintf(f, "buffer len = %zu\n", sshbuf_len(buf));
sshbuf_dump_data(sshbuf_ptr(buf), sshbuf_len(buf), f);
}
@@ -89,24 +89,58 @@ sshbuf_dtob16(struct sshbuf *buf)
return ret;
}
+int
+sshbuf_dtob64(const struct sshbuf *d, struct sshbuf *b64, int wrap)
+{
+ size_t i, slen = 0;
+ char *s = NULL;
+ int r;
+
+ if (d == NULL || b64 == NULL || sshbuf_len(d) >= SIZE_MAX / 2)
+ return SSH_ERR_INVALID_ARGUMENT;
+ if (sshbuf_len(d) == 0)
+ return 0;
+ slen = ((sshbuf_len(d) + 2) / 3) * 4 + 1;
+ if ((s = malloc(slen)) == NULL)
+ return SSH_ERR_ALLOC_FAIL;
+ if (b64_ntop(sshbuf_ptr(d), sshbuf_len(d), s, slen) == -1) {
+ r = SSH_ERR_INTERNAL_ERROR;
+ goto fail;
+ }
+ if (wrap) {
+ for (i = 0; s[i] != '\0'; i++) {
+ if ((r = sshbuf_put_u8(b64, s[i])) != 0)
+ goto fail;
+ if (i % 70 == 69 && (r = sshbuf_put_u8(b64, '\n')) != 0)
+ goto fail;
+ }
+ if ((i - 1) % 70 != 69 && (r = sshbuf_put_u8(b64, '\n')) != 0)
+ goto fail;
+ } else {
+ if ((r = sshbuf_put(b64, s, strlen(s))) != 0)
+ goto fail;
+ }
+ /* Success */
+ r = 0;
+ fail:
+ freezero(s, slen);
+ return r;
+}
+
char *
-sshbuf_dtob64(struct sshbuf *buf)
+sshbuf_dtob64_string(const struct sshbuf *buf, int wrap)
{
- size_t len = sshbuf_len(buf), plen;
- const u_char *p = sshbuf_ptr(buf);
+ struct sshbuf *tmp;
char *ret;
- int r;
- if (len == 0)
- return strdup("");
- plen = ((len + 2) / 3) * 4 + 1;
- if (SIZE_MAX / 2 <= len || (ret = malloc(plen)) == NULL)
+ if ((tmp = sshbuf_new()) == NULL)
return NULL;
- if ((r = b64_ntop(p, len, ret, plen)) == -1) {
- explicit_bzero(ret, plen);
- free(ret);
+ if (sshbuf_dtob64(buf, tmp, wrap) != 0) {
+ sshbuf_free(tmp);
return NULL;
}
+ ret = sshbuf_dup_string(tmp);
+ sshbuf_free(tmp);
return ret;
}
@@ -122,20 +156,60 @@ sshbuf_b64tod(struct sshbuf *buf, const char *b64)
if ((p = malloc(plen)) == NULL)
return SSH_ERR_ALLOC_FAIL;
if ((nlen = b64_pton(b64, p, plen)) < 0) {
- explicit_bzero(p, plen);
- free(p);
+ freezero(p, plen);
return SSH_ERR_INVALID_FORMAT;
}
if ((r = sshbuf_put(buf, p, nlen)) < 0) {
- explicit_bzero(p, plen);
- free(p);
+ freezero(p, plen);
return r;
}
- explicit_bzero(p, plen);
- free(p);
+ freezero(p, plen);
return 0;
}
+int
+sshbuf_dtourlb64(const struct sshbuf *d, struct sshbuf *b64, int wrap)
+{
+ int r = SSH_ERR_INTERNAL_ERROR;
+ u_char *p;
+ struct sshbuf *b = NULL;
+ size_t i, l;
+
+ if ((b = sshbuf_new()) == NULL)
+ return SSH_ERR_ALLOC_FAIL;
+ /* Encode using regular base64; we'll transform it once done */
+ if ((r = sshbuf_dtob64(d, b, wrap)) != 0)
+ goto out;
+ /* remove padding from end of encoded string*/
+ for (;;) {
+ l = sshbuf_len(b);
+ if (l <= 1 || sshbuf_ptr(b) == NULL) {
+ r = SSH_ERR_INTERNAL_ERROR;
+ goto out;
+ }
+ if (sshbuf_ptr(b)[l - 1] != '=')
+ break;
+ if ((r = sshbuf_consume_end(b, 1)) != 0)
+ goto out;
+ }
+ /* Replace characters with rfc4648 equivalents */
+ l = sshbuf_len(b);
+ if ((p = sshbuf_mutable_ptr(b)) == NULL) {
+ r = SSH_ERR_INTERNAL_ERROR;
+ goto out;
+ }
+ for (i = 0; i < l; i++) {
+ if (p[i] == '+')
+ p[i] = '-';
+ else if (p[i] == '/')
+ p[i] = '_';
+ }
+ r = sshbuf_putb(b64, b);
+ out:
+ sshbuf_free(b);
+ return r;
+}
+
char *
sshbuf_dup_string(struct sshbuf *buf)
{
@@ -159,3 +233,39 @@ sshbuf_dup_string(struct sshbuf *buf)
return r;
}
+int
+sshbuf_cmp(const struct sshbuf *b, size_t offset,
+ const void *s, size_t len)
+{
+ if (sshbuf_ptr(b) == NULL)
+ return SSH_ERR_INTERNAL_ERROR;
+ if (offset > SSHBUF_SIZE_MAX || len > SSHBUF_SIZE_MAX || len == 0)
+ return SSH_ERR_INVALID_ARGUMENT;
+ if (offset + len > sshbuf_len(b))
+ return SSH_ERR_MESSAGE_INCOMPLETE;
+ if (timingsafe_bcmp(sshbuf_ptr(b) + offset, s, len) != 0)
+ return SSH_ERR_INVALID_FORMAT;
+ return 0;
+}
+
+int
+sshbuf_find(const struct sshbuf *b, size_t start_offset,
+ const void *s, size_t len, size_t *offsetp)
+{
+ void *p;
+
+ if (offsetp != NULL)
+ *offsetp = 0;
+ if (sshbuf_ptr(b) == NULL)
+ return SSH_ERR_INTERNAL_ERROR;
+ if (start_offset > SSHBUF_SIZE_MAX || len > SSHBUF_SIZE_MAX || len == 0)
+ return SSH_ERR_INVALID_ARGUMENT;
+ if (start_offset > sshbuf_len(b) || start_offset + len > sshbuf_len(b))
+ return SSH_ERR_MESSAGE_INCOMPLETE;
+ if ((p = memmem(sshbuf_ptr(b) + start_offset,
+ sshbuf_len(b) - start_offset, s, len)) == NULL)
+ return SSH_ERR_INVALID_FORMAT;
+ if (offsetp != NULL)
+ *offsetp = (const u_char *)p - sshbuf_ptr(b);
+ return 0;
+}
diff --git a/crypto/openssh/sshbuf.c b/crypto/openssh/sshbuf.c
index 20ddf9eb6272..368ba7980b75 100644
--- a/crypto/openssh/sshbuf.c
+++ b/crypto/openssh/sshbuf.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: sshbuf.c,v 1.12 2018/07/09 21:56:06 markus Exp $ */
+/* $OpenBSD: sshbuf.c,v 1.15 2020/02/26 13:40:09 jsg Exp $ */
/*
* Copyright (c) 2011 Damien Miller
*
@@ -42,7 +42,7 @@ sshbuf_check_sanity(const struct sshbuf *buf)
buf->off > buf->size)) {
/* Do not try to recover from corrupted buffer internals */
SSHBUF_DBG(("SSH_ERR_INTERNAL_ERROR"));
- signal(SIGSEGV, SIG_DFL);
+ ssh_signal(SIGSEGV, SIG_DFL);
raise(SIGSEGV);
return SSH_ERR_INTERNAL_ERROR;
}
@@ -143,12 +143,7 @@ sshbuf_free(struct sshbuf *buf)
*/
if (sshbuf_check_sanity(buf) != 0)
return;
- /*
- * If we are a child, the free our parent to decrement its reference
- * count and possibly free it.
- */
- sshbuf_free(buf->parent);
- buf->parent = NULL;
+
/*
* If we are a parent with still-extant children, then don't free just
* yet. The last child's call to sshbuf_free should decrement our
@@ -157,12 +152,19 @@ sshbuf_free(struct sshbuf *buf)
buf->refcount--;
if (buf->refcount > 0)
return;
+
+ /*
+ * If we are a child, the free our parent to decrement its reference
+ * count and possibly free it.
+ */
+ sshbuf_free(buf->parent);
+ buf->parent = NULL;
+
if (!buf->readonly) {
explicit_bzero(buf->d, buf->alloc);
free(buf->d);
}
- explicit_bzero(buf, sizeof(*buf));
- free(buf);
+ freezero(buf, sizeof(*buf));
}
void
diff --git a/crypto/openssh/sshbuf.h b/crypto/openssh/sshbuf.h
index a43598cac4de..2ad0e61be120 100644
--- a/crypto/openssh/sshbuf.h
+++ b/crypto/openssh/sshbuf.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: sshbuf.h,v 1.11 2018/07/09 21:56:06 markus Exp $ */
+/* $OpenBSD: sshbuf.h,v 1.23 2020/06/22 05:54:10 djm Exp $ */
/*
* Copyright (c) 2011 Damien Miller
*
@@ -140,7 +140,7 @@ int sshbuf_allocate(struct sshbuf *buf, size_t len);
/*
* Reserve len bytes in buf.
* Returns 0 on success and a pointer to the first reserved byte via the
- * optional dpp parameter or a negative * SSH_ERR_* error code on failure.
+ * optional dpp parameter or a negative SSH_ERR_* error code on failure.
*/
int sshbuf_reserve(struct sshbuf *buf, size_t len, u_char **dpp);
@@ -176,6 +176,26 @@ int sshbuf_put_u32(struct sshbuf *buf, u_int32_t val);
int sshbuf_put_u16(struct sshbuf *buf, u_int16_t val);
int sshbuf_put_u8(struct sshbuf *buf, u_char val);
+/* Functions to peek at the contents of a buffer without modifying it. */
+int sshbuf_peek_u64(const struct sshbuf *buf, size_t offset,
+ u_int64_t *valp);
+int sshbuf_peek_u32(const struct sshbuf *buf, size_t offset,
+ u_int32_t *valp);
+int sshbuf_peek_u16(const struct sshbuf *buf, size_t offset,
+ u_int16_t *valp);
+int sshbuf_peek_u8(const struct sshbuf *buf, size_t offset,
+ u_char *valp);
+
+/*
+ * Functions to poke values into an existing buffer (e.g. a length header
+ * to a packet). The destination bytes must already exist in the buffer.
+ */
+int sshbuf_poke_u64(struct sshbuf *buf, size_t offset, u_int64_t val);
+int sshbuf_poke_u32(struct sshbuf *buf, size_t offset, u_int32_t val);
+int sshbuf_poke_u16(struct sshbuf *buf, size_t offset, u_int16_t val);
+int sshbuf_poke_u8(struct sshbuf *buf, size_t offset, u_char val);
+int sshbuf_poke(struct sshbuf *buf, size_t offset, void *v, size_t len);
+
/*
* Functions to extract or store SSH wire encoded strings (u32 len || data)
* The "cstring" variants admit no \0 characters in the string contents.
@@ -202,7 +222,6 @@ int sshbuf_get_string_direct(struct sshbuf *buf, const u_char **valp,
/* Another variant: "peeks" into the buffer without modifying it */
int sshbuf_peek_string_direct(const struct sshbuf *buf, const u_char **valp,
size_t *lenp);
-/* XXX peek_u8 / peek_u32 */
/*
* Functions to extract or store SSH wire encoded bignums and elliptic
@@ -212,10 +231,8 @@ int sshbuf_put_bignum2_bytes(struct sshbuf *buf, const void *v, size_t len);
int sshbuf_get_bignum2_bytes_direct(struct sshbuf *buf,
const u_char **valp, size_t *lenp);
#ifdef WITH_OPENSSL
-int sshbuf_get_bignum2(struct sshbuf *buf, BIGNUM *v);
-int sshbuf_get_bignum1(struct sshbuf *buf, BIGNUM *v);
+int sshbuf_get_bignum2(struct sshbuf *buf, BIGNUM **valp);
int sshbuf_put_bignum2(struct sshbuf *buf, const BIGNUM *v);
-int sshbuf_put_bignum1(struct sshbuf *buf, const BIGNUM *v);
# ifdef OPENSSL_HAS_ECC
int sshbuf_get_ec(struct sshbuf *buf, EC_POINT *v, const EC_GROUP *g);
int sshbuf_get_eckey(struct sshbuf *buf, EC_KEY *v);
@@ -225,7 +242,7 @@ int sshbuf_put_eckey(struct sshbuf *buf, const EC_KEY *v);
#endif /* WITH_OPENSSL */
/* Dump the contents of the buffer in a human-readable format */
-void sshbuf_dump(struct sshbuf *buf, FILE *f);
+void sshbuf_dump(const struct sshbuf *buf, FILE *f);
/* Dump specified memory in a human-readable format */
void sshbuf_dump_data(const void *s, size_t len, FILE *f);
@@ -234,18 +251,64 @@ void sshbuf_dump_data(const void *s, size_t len, FILE *f);
char *sshbuf_dtob16(struct sshbuf *buf);
/* Encode the contents of the buffer as base64 */
-char *sshbuf_dtob64(struct sshbuf *buf);
+char *sshbuf_dtob64_string(const struct sshbuf *buf, int wrap);
+int sshbuf_dtob64(const struct sshbuf *d, struct sshbuf *b64, int wrap);
+/* RFC4648 "base64url" encoding variant */
+int sshbuf_dtourlb64(const struct sshbuf *d, struct sshbuf *b64, int wrap);
/* Decode base64 data and append it to the buffer */
int sshbuf_b64tod(struct sshbuf *buf, const char *b64);
/*
+ * Tests whether the buffer contains the specified byte sequence at the
+ * specified offset. Returns 0 on successful match, or a ssherr.h code
+ * otherwise. SSH_ERR_INVALID_FORMAT indicates sufficient bytes were
+ * present but the buffer contents did not match those supplied. Zero-
+ * length comparisons are not allowed.
+ *
+ * If sufficient data is present to make a comparison, then it is
+ * performed with timing independent of the value of the data. If
+ * insufficient data is present then the comparison is not attempted at
+ * all.
+ */
+int sshbuf_cmp(const struct sshbuf *b, size_t offset,
+ const void *s, size_t len);
+
+/*
+ * Searches the buffer for the specified string. Returns 0 on success
+ * and updates *offsetp with the offset of the first match, relative to
+ * the start of the buffer. Otherwise sshbuf_find will return a ssherr.h
+ * error code. SSH_ERR_INVALID_FORMAT indicates sufficient bytes were
+ * present in the buffer for a match to be possible but none was found.
+ * Searches for zero-length data are not allowed.
+ */
+int
+sshbuf_find(const struct sshbuf *b, size_t start_offset,
+ const void *s, size_t len, size_t *offsetp);
+
+/*
* Duplicate the contents of a buffer to a string (caller to free).
* Returns NULL on buffer error, or if the buffer contains a premature
* nul character.
*/
char *sshbuf_dup_string(struct sshbuf *buf);
+/*
+ * Fill a buffer from a file descriptor or filename. Both allocate the
+ * buffer for the caller.
+ */
+int sshbuf_load_fd(int, struct sshbuf **)
+ __attribute__((__nonnull__ (2)));
+int sshbuf_load_file(const char *, struct sshbuf **)
+ __attribute__((__nonnull__ (2)));
+
+/*
+ * Write a buffer to a path, creating/truncating as needed (mode 0644,
+ * subject to umask). The buffer contents are not modified.
+ */
+int sshbuf_write_file(const char *path, struct sshbuf *buf)
+ __attribute__((__nonnull__ (2)));
+
/* Macros for decoding/encoding integers */
#define PEEK_U64(p) \
(((u_int64_t)(((const u_char *)(p))[0]) << 56) | \
diff --git a/crypto/openssh/sshconnect.c b/crypto/openssh/sshconnect.c
index b50029de71b8..8f7541942ac1 100644
--- a/crypto/openssh/sshconnect.c
+++ b/crypto/openssh/sshconnect.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: sshconnect.c,v 1.305 2018/09/20 03:30:44 djm Exp $ */
+/* $OpenBSD: sshconnect.c,v 1.355 2021/07/02 05:11:21 dtucker Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -31,6 +31,7 @@ __RCSID("$FreeBSD$");
#include <ctype.h>
#include <errno.h>
#include <fcntl.h>
+#include <limits.h>
#include <netdb.h>
#ifdef HAVE_PATHS_H
#include <paths.h>
@@ -40,9 +41,9 @@ __RCSID("$FreeBSD$");
#include <poll.h>
#endif
#include <signal.h>
-#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
+#include <stdarg.h>
#include <string.h>
#include <unistd.h>
#ifdef HAVE_IFADDRS_H
@@ -57,7 +58,6 @@ __RCSID("$FreeBSD$");
#include "compat.h"
#include "sshkey.h"
#include "sshconnect.h"
-#include "hostfile.h"
#include "log.h"
#include "misc.h"
#include "readconf.h"
@@ -69,9 +69,8 @@ __RCSID("$FreeBSD$");
#include "authfile.h"
#include "ssherr.h"
#include "authfd.h"
+#include "kex.h"
-char *client_version_string = NULL;
-char *server_version_string = NULL;
struct sshkey *previous_host_key = NULL;
static int matching_host_key_dns = 0;
@@ -79,6 +78,7 @@ static int matching_host_key_dns = 0;
static pid_t proxy_command_pid = 0;
/* import */
+extern int debug_flag;
extern Options options;
extern char *__progname;
@@ -88,14 +88,21 @@ static void warn_changed_key(struct sshkey *);
/* Expand a proxy command */
static char *
expand_proxy_command(const char *proxy_command, const char *user,
- const char *host, int port)
+ const char *host, const char *host_arg, int port)
{
char *tmp, *ret, strport[NI_MAXSERV];
+ const char *keyalias = options.host_key_alias ?
+ options.host_key_alias : host_arg;
snprintf(strport, sizeof strport, "%d", port);
xasprintf(&tmp, "exec %s", proxy_command);
- ret = percent_expand(tmp, "h", host, "p", strport,
- "r", options.user, (char *)NULL);
+ ret = percent_expand(tmp,
+ "h", host,
+ "k", keyalias,
+ "n", host_arg,
+ "p", strport,
+ "r", options.user,
+ (char *)NULL);
free(tmp);
return ret;
}
@@ -105,8 +112,8 @@ expand_proxy_command(const char *proxy_command, const char *user,
* a connected fd back to us.
*/
static int
-ssh_proxy_fdpass_connect(struct ssh *ssh, const char *host, u_short port,
- const char *proxy_command)
+ssh_proxy_fdpass_connect(struct ssh *ssh, const char *host,
+ const char *host_arg, u_short port, const char *proxy_command)
{
char *command_string;
int sp[2], sock;
@@ -116,12 +123,12 @@ ssh_proxy_fdpass_connect(struct ssh *ssh, const char *host, u_short port,
if ((shell = getenv("SHELL")) == NULL)
shell = _PATH_BSHELL;
- if (socketpair(AF_UNIX, SOCK_STREAM, 0, sp) < 0)
+ if (socketpair(AF_UNIX, SOCK_STREAM, 0, sp) == -1)
fatal("Could not create socketpair to communicate with "
"proxy dialer: %.100s", strerror(errno));
command_string = expand_proxy_command(proxy_command, options.user,
- host, port);
+ host, host_arg, port);
debug("Executing proxy dialer command: %.500s", command_string);
/* Fork and execute the proxy command. */
@@ -131,20 +138,24 @@ ssh_proxy_fdpass_connect(struct ssh *ssh, const char *host, u_short port,
close(sp[1]);
/* Redirect stdin and stdout. */
if (sp[0] != 0) {
- if (dup2(sp[0], 0) < 0)
+ if (dup2(sp[0], 0) == -1)
perror("dup2 stdin");
}
if (sp[0] != 1) {
- if (dup2(sp[0], 1) < 0)
+ if (dup2(sp[0], 1) == -1)
perror("dup2 stdout");
}
if (sp[0] >= 2)
close(sp[0]);
/*
- * Stderr is left as it is so that error messages get
- * printed on the user's terminal.
+ * Stderr is left for non-ControlPersist connections is so
+ * error messages may be printed on the user's terminal.
*/
+ if (!debug_flag && options.control_path != NULL &&
+ options.control_persist && stdfd_devnull(0, 0, 1) == -1)
+ error_f("stdfd_devnull failed");
+
argv[0] = shell;
argv[1] = "-c";
argv[2] = command_string;
@@ -159,7 +170,7 @@ ssh_proxy_fdpass_connect(struct ssh *ssh, const char *host, u_short port,
exit(1);
}
/* Parent. */
- if (pid < 0)
+ if (pid == -1)
fatal("fork failed: %.100s", strerror(errno));
close(sp[0]);
free(command_string);
@@ -183,8 +194,8 @@ ssh_proxy_fdpass_connect(struct ssh *ssh, const char *host, u_short port,
* Connect to the given ssh server using a proxy command.
*/
static int
-ssh_proxy_connect(struct ssh *ssh, const char *host, u_short port,
- const char *proxy_command)
+ssh_proxy_connect(struct ssh *ssh, const char *host, const char *host_arg,
+ u_short port, const char *proxy_command)
{
char *command_string;
int pin[2], pout[2];
@@ -195,12 +206,12 @@ ssh_proxy_connect(struct ssh *ssh, const char *host, u_short port,
shell = _PATH_BSHELL;
/* Create pipes for communicating with the proxy. */
- if (pipe(pin) < 0 || pipe(pout) < 0)
+ if (pipe(pin) == -1 || pipe(pout) == -1)
fatal("Could not create pipes to communicate with the proxy: %.100s",
strerror(errno));
command_string = expand_proxy_command(proxy_command, options.user,
- host, port);
+ host, host_arg, port);
debug("Executing proxy command: %.500s", command_string);
/* Fork and execute the proxy command. */
@@ -210,32 +221,40 @@ ssh_proxy_connect(struct ssh *ssh, const char *host, u_short port,
/* Redirect stdin and stdout. */
close(pin[1]);
if (pin[0] != 0) {
- if (dup2(pin[0], 0) < 0)
+ if (dup2(pin[0], 0) == -1)
perror("dup2 stdin");
close(pin[0]);
}
close(pout[0]);
- if (dup2(pout[1], 1) < 0)
+ if (dup2(pout[1], 1) == -1)
perror("dup2 stdout");
/* Cannot be 1 because pin allocated two descriptors. */
close(pout[1]);
- /* Stderr is left as it is so that error messages get
- printed on the user's terminal. */
+ /*
+ * Stderr is left for non-ControlPersist connections is so
+ * error messages may be printed on the user's terminal.
+ */
+ if (!debug_flag && options.control_path != NULL &&
+ options.control_persist && stdfd_devnull(0, 0, 1) == -1)
+ error_f("stdfd_devnull failed");
+
argv[0] = shell;
argv[1] = "-c";
argv[2] = command_string;
argv[3] = NULL;
- /* Execute the proxy command. Note that we gave up any
- extra privileges above. */
- signal(SIGPIPE, SIG_DFL);
+ /*
+ * Execute the proxy command. Note that we gave up any
+ * extra privileges above.
+ */
+ ssh_signal(SIGPIPE, SIG_DFL);
execv(argv[0], argv);
perror(argv[0]);
exit(1);
}
/* Parent. */
- if (pid < 0)
+ if (pid == -1)
fatal("fork failed: %.100s", strerror(errno));
else
proxy_command_pid = pid; /* save pid to clean up later */
@@ -299,8 +318,7 @@ check_ifaddrs(const char *ifname, int af, const struct ifaddrs *ifaddrs,
htonl(INADDR_LOOPBACK))
continue;
if (*rlenp < sizeof(struct sockaddr_in)) {
- error("%s: v4 addr doesn't fit",
- __func__);
+ error_f("v4 addr doesn't fit");
return -1;
}
*rlenp = sizeof(struct sockaddr_in);
@@ -314,8 +332,7 @@ check_ifaddrs(const char *ifname, int af, const struct ifaddrs *ifaddrs,
IN6_IS_ADDR_LOOPBACK(v6addr)))
continue;
if (*rlenp < sizeof(struct sockaddr_in6)) {
- error("%s: v6 addr doesn't fit",
- __func__);
+ error_f("v6 addr doesn't fit");
return -1;
}
*rlenp = sizeof(struct sockaddr_in6);
@@ -344,12 +361,16 @@ ssh_create_socket(struct addrinfo *ai)
char ntop[NI_MAXHOST];
sock = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
- if (sock < 0) {
+ if (sock == -1) {
error("socket: %s", strerror(errno));
return -1;
}
fcntl(sock, F_SETFD, FD_CLOEXEC);
+ /* Use interactive QOS (if specified) until authentication completed */
+ if (options.ip_qos_interactive != INT_MAX)
+ set_sock_tos(sock, options.ip_qos_interactive);
+
/* Bind the socket to an alternative local IP address */
if (options.bind_address == NULL && options.bind_interface == NULL)
return sock;
@@ -370,24 +391,20 @@ ssh_create_socket(struct addrinfo *ai)
error("getaddrinfo: no addrs");
goto fail;
}
- if (res->ai_addrlen > sizeof(bindaddr)) {
- error("%s: addr doesn't fit", __func__);
- goto fail;
- }
memcpy(&bindaddr, res->ai_addr, res->ai_addrlen);
bindaddrlen = res->ai_addrlen;
} else if (options.bind_interface != NULL) {
#ifdef HAVE_IFADDRS_H
if ((r = getifaddrs(&ifaddrs)) != 0) {
error("getifaddrs: %s: %s", options.bind_interface,
- strerror(errno));
+ strerror(errno));
goto fail;
}
bindaddrlen = sizeof(bindaddr);
if (check_ifaddrs(options.bind_interface, ai->ai_family,
ifaddrs, &bindaddr, &bindaddrlen) != 0) {
logit("getifaddrs: %s: no suitable addresses",
- options.bind_interface);
+ options.bind_interface);
goto fail;
}
#else
@@ -396,15 +413,14 @@ ssh_create_socket(struct addrinfo *ai)
}
if ((r = getnameinfo((struct sockaddr *)&bindaddr, bindaddrlen,
ntop, sizeof(ntop), NULL, 0, NI_NUMERICHOST)) != 0) {
- error("%s: getnameinfo failed: %s", __func__,
- ssh_gai_strerror(r));
+ error_f("getnameinfo failed: %s", ssh_gai_strerror(r));
goto fail;
}
if (bind(sock, (struct sockaddr *)&bindaddr, bindaddrlen) != 0) {
error("bind %s: %s", ntop, strerror(errno));
goto fail;
}
- debug("%s: bound to %s", __func__, ntop);
+ debug_f("bound to %s", ntop);
/* success */
goto out;
fail:
@@ -421,73 +437,6 @@ fail:
}
/*
- * Wait up to *timeoutp milliseconds for fd to be readable. Updates
- * *timeoutp with time remaining.
- * Returns 0 if fd ready or -1 on timeout or error (see errno).
- */
-static int
-waitrfd(int fd, int *timeoutp)
-{
- struct pollfd pfd;
- struct timeval t_start;
- int oerrno, r;
-
- monotime_tv(&t_start);
- pfd.fd = fd;
- pfd.events = POLLIN;
- for (; *timeoutp >= 0;) {
- r = poll(&pfd, 1, *timeoutp);
- oerrno = errno;
- ms_subtract_diff(&t_start, timeoutp);
- errno = oerrno;
- if (r > 0)
- return 0;
- else if (r == -1 && errno != EAGAIN)
- return -1;
- else if (r == 0)
- break;
- }
- /* timeout */
- errno = ETIMEDOUT;
- return -1;
-}
-
-static int
-timeout_connect(int sockfd, const struct sockaddr *serv_addr,
- socklen_t addrlen, int *timeoutp)
-{
- int optval = 0;
- socklen_t optlen = sizeof(optval);
-
- /* No timeout: just do a blocking connect() */
- if (*timeoutp <= 0)
- return connect(sockfd, serv_addr, addrlen);
-
- set_nonblock(sockfd);
- if (connect(sockfd, serv_addr, addrlen) == 0) {
- /* Succeeded already? */
- unset_nonblock(sockfd);
- return 0;
- } else if (errno != EINPROGRESS)
- return -1;
-
- if (waitrfd(sockfd, timeoutp) == -1)
- return -1;
-
- /* Completed or failed */
- if (getsockopt(sockfd, SOL_SOCKET, SO_ERROR, &optval, &optlen) == -1) {
- debug("getsockopt: %s", strerror(errno));
- return -1;
- }
- if (optval != 0) {
- errno = optval;
- return -1;
- }
- unset_nonblock(sockfd);
- return 0;
-}
-
-/*
* Opens a TCP/IP connection to the remote server on the given host.
* The address of the remote host will be returned in hostaddr.
* If port is 0, the default port will be used.
@@ -498,15 +447,15 @@ timeout_connect(int sockfd, const struct sockaddr *serv_addr,
*/
static int
ssh_connect_direct(struct ssh *ssh, const char *host, struct addrinfo *aitop,
- struct sockaddr_storage *hostaddr, u_short port, int family,
- int connection_attempts, int *timeout_ms, int want_keepalive)
+ struct sockaddr_storage *hostaddr, u_short port, int connection_attempts,
+ int *timeout_ms, int want_keepalive)
{
- int on = 1;
+ int on = 1, saved_timeout_ms = *timeout_ms;
int oerrno, sock = -1, attempt;
char ntop[NI_MAXHOST], strport[NI_MAXSERV];
struct addrinfo *ai;
- debug2("%s", __func__);
+ debug3_f("entering");
memset(ntop, 0, sizeof(ntop));
memset(strport, 0, sizeof(strport));
@@ -530,7 +479,7 @@ ssh_connect_direct(struct ssh *ssh, const char *host, struct addrinfo *aitop,
ntop, sizeof(ntop), strport, sizeof(strport),
NI_NUMERICHOST|NI_NUMERICSERV) != 0) {
oerrno = errno;
- error("%s: getnameinfo failed", __func__);
+ error_f("getnameinfo failed");
errno = oerrno;
continue;
}
@@ -545,6 +494,7 @@ ssh_connect_direct(struct ssh *ssh, const char *host, struct addrinfo *aitop,
continue;
}
+ *timeout_ms = saved_timeout_ms;
if (timeout_connect(sock, ai->ai_addr, ai->ai_addrlen,
timeout_ms) >= 0) {
/* Successful connection. */
@@ -575,194 +525,74 @@ ssh_connect_direct(struct ssh *ssh, const char *host, struct addrinfo *aitop,
/* Set SO_KEEPALIVE if requested. */
if (want_keepalive &&
setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, (void *)&on,
- sizeof(on)) < 0)
+ sizeof(on)) == -1)
error("setsockopt SO_KEEPALIVE: %.100s", strerror(errno));
/* Set the connection. */
if (ssh_packet_set_connection(ssh, sock, sock) == NULL)
return -1; /* ssh_packet_set_connection logs error */
- return 0;
+ return 0;
}
int
-ssh_connect(struct ssh *ssh, const char *host, struct addrinfo *addrs,
- struct sockaddr_storage *hostaddr, u_short port, int family,
+ssh_connect(struct ssh *ssh, const char *host, const char *host_arg,
+ struct addrinfo *addrs, struct sockaddr_storage *hostaddr, u_short port,
int connection_attempts, int *timeout_ms, int want_keepalive)
{
+ int in, out;
+
if (options.proxy_command == NULL) {
return ssh_connect_direct(ssh, host, addrs, hostaddr, port,
- family, connection_attempts, timeout_ms, want_keepalive);
+ connection_attempts, timeout_ms, want_keepalive);
} else if (strcmp(options.proxy_command, "-") == 0) {
- if ((ssh_packet_set_connection(ssh,
- STDIN_FILENO, STDOUT_FILENO)) == NULL)
+ if ((in = dup(STDIN_FILENO)) == -1 ||
+ (out = dup(STDOUT_FILENO)) == -1) {
+ if (in >= 0)
+ close(in);
+ error_f("dup() in/out failed");
+ return -1; /* ssh_packet_set_connection logs error */
+ }
+ if ((ssh_packet_set_connection(ssh, in, out)) == NULL)
return -1; /* ssh_packet_set_connection logs error */
return 0;
} else if (options.proxy_use_fdpass) {
- return ssh_proxy_fdpass_connect(ssh, host, port,
+ return ssh_proxy_fdpass_connect(ssh, host, host_arg, port,
options.proxy_command);
}
- return ssh_proxy_connect(ssh, host, port, options.proxy_command);
-}
-
-static void
-send_client_banner(int connection_out, int minor1)
-{
- /* Send our own protocol version identification. */
- xasprintf(&client_version_string, "SSH-%d.%d-%.100s%s%s\n",
- PROTOCOL_MAJOR_2, PROTOCOL_MINOR_2, SSH_VERSION,
- *options.version_addendum == '\0' ? "" : " ",
- options.version_addendum);
- if (atomicio(vwrite, connection_out, client_version_string,
- strlen(client_version_string)) != strlen(client_version_string))
- fatal("write: %.100s", strerror(errno));
- chop(client_version_string);
- debug("Local version string %.100s", client_version_string);
-}
-
-/*
- * Waits for the server identification string, and sends our own
- * identification string.
- */
-void
-ssh_exchange_identification(int timeout_ms)
-{
- char buf[256], remote_version[256]; /* must be same size! */
- int remote_major, remote_minor, mismatch;
- int connection_in = packet_get_connection_in();
- int connection_out = packet_get_connection_out();
- u_int i, n;
- size_t len;
- int rc;
-
- send_client_banner(connection_out, 0);
-
- /* Read other side's version identification. */
- for (n = 0;;) {
- for (i = 0; i < sizeof(buf) - 1; i++) {
- if (timeout_ms > 0) {
- rc = waitrfd(connection_in, &timeout_ms);
- if (rc == -1 && errno == ETIMEDOUT) {
- fatal("Connection timed out during "
- "banner exchange");
- } else if (rc == -1) {
- fatal("%s: %s",
- __func__, strerror(errno));
- }
- }
-
- len = atomicio(read, connection_in, &buf[i], 1);
- if (len != 1 && errno == EPIPE)
- fatal("ssh_exchange_identification: "
- "Connection closed by remote host");
- else if (len != 1)
- fatal("ssh_exchange_identification: "
- "read: %.100s", strerror(errno));
- if (buf[i] == '\r') {
- buf[i] = '\n';
- buf[i + 1] = 0;
- continue; /**XXX wait for \n */
- }
- if (buf[i] == '\n') {
- buf[i + 1] = 0;
- break;
- }
- if (++n > 65536)
- fatal("ssh_exchange_identification: "
- "No banner received");
- }
- buf[sizeof(buf) - 1] = 0;
- if (strncmp(buf, "SSH-", 4) == 0)
- break;
- debug("ssh_exchange_identification: %s", buf);
- }
- server_version_string = xstrdup(buf);
-
- /*
- * Check that the versions match. In future this might accept
- * several versions and set appropriate flags to handle them.
- */
- if (sscanf(server_version_string, "SSH-%d.%d-%[^\n]\n",
- &remote_major, &remote_minor, remote_version) != 3)
- fatal("Bad remote protocol version identification: '%.100s'", buf);
- debug("Remote protocol version %d.%d, remote software version %.100s",
- remote_major, remote_minor, remote_version);
-
- active_state->compat = compat_datafellows(remote_version);
- mismatch = 0;
-
- switch (remote_major) {
- case 2:
- break;
- case 1:
- if (remote_minor != 99)
- mismatch = 1;
- break;
- default:
- mismatch = 1;
- break;
- }
- if (mismatch)
- fatal("Protocol major versions differ: %d vs. %d",
- PROTOCOL_MAJOR_2, remote_major);
- if ((datafellows & SSH_BUG_RSASIGMD5) != 0)
- logit("Server version \"%.100s\" uses unsafe RSA signature "
- "scheme; disabling use of RSA keys", remote_version);
- chop(server_version_string);
+ return ssh_proxy_connect(ssh, host, host_arg, port,
+ options.proxy_command);
}
/* defaults to 'no' */
static int
-confirm(const char *prompt)
+confirm(const char *prompt, const char *fingerprint)
{
const char *msg, *again = "Please type 'yes' or 'no': ";
- char *p;
+ const char *again_fp = "Please type 'yes', 'no' or the fingerprint: ";
+ char *p, *cp;
int ret = -1;
if (options.batch_mode)
return 0;
- for (msg = prompt;;msg = again) {
- p = read_passphrase(msg, RP_ECHO);
+ for (msg = prompt;;msg = fingerprint ? again_fp : again) {
+ cp = p = read_passphrase(msg, RP_ECHO);
if (p == NULL)
return 0;
- p[strcspn(p, "\n")] = '\0';
+ p += strspn(p, " \t"); /* skip leading whitespace */
+ p[strcspn(p, " \t\n")] = '\0'; /* remove trailing whitespace */
if (p[0] == '\0' || strcasecmp(p, "no") == 0)
ret = 0;
- else if (strcasecmp(p, "yes") == 0)
+ else if (strcasecmp(p, "yes") == 0 || (fingerprint != NULL &&
+ strcmp(p, fingerprint) == 0))
ret = 1;
- free(p);
+ free(cp);
if (ret != -1)
return ret;
}
}
static int
-check_host_cert(const char *host, const struct sshkey *key)
-{
- const char *reason;
- int r;
-
- if (sshkey_cert_check_authority(key, 1, 0, host, &reason) != 0) {
- error("%s", reason);
- return 0;
- }
- if (sshbuf_len(key->cert->critical) != 0) {
- error("Certificate for %s contains unsupported "
- "critical options(s)", host);
- return 0;
- }
- if ((r = sshkey_check_cert_sigtype(key,
- options.ca_sign_algorithms)) != 0) {
- logit("%s: certificate signature algorithm %s: %s", __func__,
- (key->cert == NULL || key->cert->signature_type == NULL) ?
- "(null)" : key->cert->signature_type, ssh_err(r));
- return 0;
- }
-
- return 1;
-}
-
-static int
sockaddr_is_local(struct sockaddr *hostaddr)
{
switch (hostaddr->sa_family) {
@@ -811,7 +641,7 @@ get_hostfile_hostname_ipaddr(char *hostname, struct sockaddr *hostaddr,
if (options.proxy_command == NULL) {
if (getnameinfo(hostaddr, addrlen,
ntop, sizeof(ntop), NULL, 0, NI_NUMERICHOST) != 0)
- fatal("%s: getnameinfo failed", __func__);
+ fatal_f("getnameinfo failed");
*hostfile_ipaddr = put_host_port(ntop, port);
} else {
*hostfile_ipaddr = xstrdup("<no hostip for proxy "
@@ -835,6 +665,257 @@ get_hostfile_hostname_ipaddr(char *hostname, struct sockaddr *hostaddr,
}
}
+/* returns non-zero if path appears in hostfiles, or 0 if not. */
+static int
+path_in_hostfiles(const char *path, char **hostfiles, u_int num_hostfiles)
+{
+ u_int i;
+
+ for (i = 0; i < num_hostfiles; i++) {
+ if (strcmp(path, hostfiles[i]) == 0)
+ return 1;
+ }
+ return 0;
+}
+
+struct find_by_key_ctx {
+ const char *host, *ip;
+ const struct sshkey *key;
+ char **names;
+ u_int nnames;
+};
+
+/* Try to replace home directory prefix (per $HOME) with a ~/ sequence */
+static char *
+try_tilde_unexpand(const char *path)
+{
+ char *home, *ret = NULL;
+ size_t l;
+
+ if (*path != '/')
+ return xstrdup(path);
+ if ((home = getenv("HOME")) == NULL || (l = strlen(home)) == 0)
+ return xstrdup(path);
+ if (strncmp(path, home, l) != 0)
+ return xstrdup(path);
+ /*
+ * ensure we have matched on a path boundary: either the $HOME that
+ * we just compared ends with a '/' or the next character of the path
+ * must be a '/'.
+ */
+ if (home[l - 1] != '/' && path[l] != '/')
+ return xstrdup(path);
+ if (path[l] == '/')
+ l++;
+ xasprintf(&ret, "~/%s", path + l);
+ return ret;
+}
+
+static int
+hostkeys_find_by_key_cb(struct hostkey_foreach_line *l, void *_ctx)
+{
+ struct find_by_key_ctx *ctx = (struct find_by_key_ctx *)_ctx;
+ char *path;
+
+ /* we are looking for keys with names that *do not* match */
+ if ((l->match & HKF_MATCH_HOST) != 0)
+ return 0;
+ /* not interested in marker lines */
+ if (l->marker != MRK_NONE)
+ return 0;
+ /* we are only interested in exact key matches */
+ if (l->key == NULL || !sshkey_equal(ctx->key, l->key))
+ return 0;
+ path = try_tilde_unexpand(l->path);
+ debug_f("found matching key in %s:%lu", path, l->linenum);
+ ctx->names = xrecallocarray(ctx->names,
+ ctx->nnames, ctx->nnames + 1, sizeof(*ctx->names));
+ xasprintf(&ctx->names[ctx->nnames], "%s:%lu: %s", path, l->linenum,
+ strncmp(l->hosts, HASH_MAGIC, strlen(HASH_MAGIC)) == 0 ?
+ "[hashed name]" : l->hosts);
+ ctx->nnames++;
+ free(path);
+ return 0;
+}
+
+static int
+hostkeys_find_by_key_hostfile(const char *file, const char *which,
+ struct find_by_key_ctx *ctx)
+{
+ int r;
+
+ debug3_f("trying %s hostfile \"%s\"", which, file);
+ if ((r = hostkeys_foreach(file, hostkeys_find_by_key_cb, ctx,
+ ctx->host, ctx->ip, HKF_WANT_PARSE_KEY, 0)) != 0) {
+ if (r == SSH_ERR_SYSTEM_ERROR && errno == ENOENT) {
+ debug_f("hostkeys file %s does not exist", file);
+ return 0;
+ }
+ error_fr(r, "hostkeys_foreach failed for %s", file);
+ return r;
+ }
+ return 0;
+}
+
+/*
+ * Find 'key' in known hosts file(s) that do not match host/ip.
+ * Used to display also-known-as information for previously-unseen hostkeys.
+ */
+static void
+hostkeys_find_by_key(const char *host, const char *ip, const struct sshkey *key,
+ char **user_hostfiles, u_int num_user_hostfiles,
+ char **system_hostfiles, u_int num_system_hostfiles,
+ char ***names, u_int *nnames)
+{
+ struct find_by_key_ctx ctx = {0, 0, 0, 0, 0};
+ u_int i;
+
+ *names = NULL;
+ *nnames = 0;
+
+ if (key == NULL || sshkey_is_cert(key))
+ return;
+
+ ctx.host = host;
+ ctx.ip = ip;
+ ctx.key = key;
+
+ for (i = 0; i < num_user_hostfiles; i++) {
+ if (hostkeys_find_by_key_hostfile(user_hostfiles[i],
+ "user", &ctx) != 0)
+ goto fail;
+ }
+ for (i = 0; i < num_system_hostfiles; i++) {
+ if (hostkeys_find_by_key_hostfile(system_hostfiles[i],
+ "system", &ctx) != 0)
+ goto fail;
+ }
+ /* success */
+ *names = ctx.names;
+ *nnames = ctx.nnames;
+ ctx.names = NULL;
+ ctx.nnames = 0;
+ return;
+ fail:
+ for (i = 0; i < ctx.nnames; i++)
+ free(ctx.names[i]);
+ free(ctx.names);
+}
+
+#define MAX_OTHER_NAMES 8 /* Maximum number of names to list */
+static char *
+other_hostkeys_message(const char *host, const char *ip,
+ const struct sshkey *key,
+ char **user_hostfiles, u_int num_user_hostfiles,
+ char **system_hostfiles, u_int num_system_hostfiles)
+{
+ char *ret = NULL, **othernames = NULL;
+ u_int i, n, num_othernames = 0;
+
+ hostkeys_find_by_key(host, ip, key,
+ user_hostfiles, num_user_hostfiles,
+ system_hostfiles, num_system_hostfiles,
+ &othernames, &num_othernames);
+ if (num_othernames == 0)
+ return xstrdup("This key is not known by any other names");
+
+ xasprintf(&ret, "This host key is known by the following other "
+ "names/addresses:");
+
+ n = num_othernames;
+ if (n > MAX_OTHER_NAMES)
+ n = MAX_OTHER_NAMES;
+ for (i = 0; i < n; i++) {
+ xextendf(&ret, "\n", " %s", othernames[i]);
+ }
+ if (n < num_othernames) {
+ xextendf(&ret, "\n", " (%d additional names omitted)",
+ num_othernames - n);
+ }
+ for (i = 0; i < num_othernames; i++)
+ free(othernames[i]);
+ free(othernames);
+ return ret;
+}
+
+void
+load_hostkeys_command(struct hostkeys *hostkeys, const char *command_template,
+ const char *invocation, const struct ssh_conn_info *cinfo,
+ const struct sshkey *host_key, const char *hostfile_hostname)
+{
+ int r, i, ac = 0;
+ char *key_fp = NULL, *keytext = NULL, *tmp;
+ char *command = NULL, *tag = NULL, **av = NULL;
+ FILE *f = NULL;
+ pid_t pid;
+ void (*osigchld)(int);
+
+ xasprintf(&tag, "KnownHostsCommand-%s", invocation);
+
+ if (host_key != NULL) {
+ if ((key_fp = sshkey_fingerprint(host_key,
+ options.fingerprint_hash, SSH_FP_DEFAULT)) == NULL)
+ fatal_f("sshkey_fingerprint failed");
+ if ((r = sshkey_to_base64(host_key, &keytext)) != 0)
+ fatal_fr(r, "sshkey_to_base64 failed");
+ }
+ /*
+ * NB. all returns later this function should go via "out" to
+ * ensure the original SIGCHLD handler is restored properly.
+ */
+ osigchld = ssh_signal(SIGCHLD, SIG_DFL);
+
+ /* Turn the command into an argument vector */
+ if (argv_split(command_template, &ac, &av, 0) != 0) {
+ error("%s \"%s\" contains invalid quotes", tag,
+ command_template);
+ goto out;
+ }
+ if (ac == 0) {
+ error("%s \"%s\" yielded no arguments", tag,
+ command_template);
+ goto out;
+ }
+ for (i = 1; i < ac; i++) {
+ tmp = percent_dollar_expand(av[i],
+ DEFAULT_CLIENT_PERCENT_EXPAND_ARGS(cinfo),
+ "H", hostfile_hostname,
+ "I", invocation,
+ "t", host_key == NULL ? "NONE" : sshkey_ssh_name(host_key),
+ "f", key_fp == NULL ? "NONE" : key_fp,
+ "K", keytext == NULL ? "NONE" : keytext,
+ (char *)NULL);
+ if (tmp == NULL)
+ fatal_f("percent_expand failed");
+ free(av[i]);
+ av[i] = tmp;
+ }
+ /* Prepare a printable command for logs, etc. */
+ command = argv_assemble(ac, av);
+
+ if ((pid = subprocess(tag, command, ac, av, &f,
+ SSH_SUBPROCESS_STDOUT_CAPTURE|SSH_SUBPROCESS_UNSAFE_PATH|
+ SSH_SUBPROCESS_PRESERVE_ENV, NULL, NULL, NULL)) == 0)
+ goto out;
+
+ load_hostkeys_file(hostkeys, hostfile_hostname, tag, f, 1);
+
+ if (exited_cleanly(pid, tag, command, 0) != 0)
+ fatal("KnownHostsCommand failed");
+
+ out:
+ if (f != NULL)
+ fclose(f);
+ ssh_signal(SIGCHLD, osigchld);
+ for (i = 0; i < ac; i++)
+ free(av[i]);
+ free(av);
+ free(tag);
+ free(command);
+ free(key_fp);
+ free(keytext);
+}
+
/*
* check whether the supplied host key is valid, return -1 if the key
* is not valid. user_hostfile[0] will not be updated if 'readonly' is true.
@@ -843,20 +924,21 @@ get_hostfile_hostname_ipaddr(char *hostname, struct sockaddr *hostaddr,
#define RDONLY 1
#define ROQUIET 2
static int
-check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port,
- struct sshkey *host_key, int readonly,
+check_host_key(char *hostname, const struct ssh_conn_info *cinfo,
+ struct sockaddr *hostaddr, u_short port,
+ struct sshkey *host_key, int readonly, int clobber_port,
char **user_hostfiles, u_int num_user_hostfiles,
- char **system_hostfiles, u_int num_system_hostfiles)
+ char **system_hostfiles, u_int num_system_hostfiles,
+ const char *hostfile_command)
{
- HostStatus host_status;
- HostStatus ip_status;
+ HostStatus host_status = -1, ip_status = -1;
struct sshkey *raw_key = NULL;
char *ip = NULL, *host = NULL;
char hostline[1000], *hostp, *fp, *ra;
char msg[1024];
- const char *type;
- const struct hostkey_entry *host_found, *ip_found;
- int len, cancelled_forwarding = 0;
+ const char *type, *fail_reason;
+ const struct hostkey_entry *host_found = NULL, *ip_found = NULL;
+ int len, cancelled_forwarding = 0, confirmed;
int local = sockaddr_is_local(hostaddr);
int r, want_cert = sshkey_is_cert(host_key), host_ip_differ = 0;
int hostkey_trusted = 0; /* Known or explicitly accepted by user */
@@ -875,6 +957,7 @@ check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port,
options.host_key_alias == NULL) {
debug("Forcing accepting of host key for "
"loopback/localhost.");
+ options.update_hostkeys = 0;
return 0;
}
@@ -882,7 +965,8 @@ check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port,
* Prepare the hostname and address strings used for hostkey lookup.
* In some cases, these will have a port number appended.
*/
- get_hostfile_hostname_ipaddr(hostname, hostaddr, port, &host, &ip);
+ get_hostfile_hostname_ipaddr(hostname, hostaddr,
+ clobber_port ? 0 : port, &host, &ip);
/*
* Turn off check_host_ip if the connection is to localhost, via proxy
@@ -894,17 +978,25 @@ check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port,
host_hostkeys = init_hostkeys();
for (i = 0; i < num_user_hostfiles; i++)
- load_hostkeys(host_hostkeys, host, user_hostfiles[i]);
+ load_hostkeys(host_hostkeys, host, user_hostfiles[i], 0);
for (i = 0; i < num_system_hostfiles; i++)
- load_hostkeys(host_hostkeys, host, system_hostfiles[i]);
+ load_hostkeys(host_hostkeys, host, system_hostfiles[i], 0);
+ if (hostfile_command != NULL && !clobber_port) {
+ load_hostkeys_command(host_hostkeys, hostfile_command,
+ "HOSTNAME", cinfo, host_key, host);
+ }
ip_hostkeys = NULL;
if (!want_cert && options.check_host_ip) {
ip_hostkeys = init_hostkeys();
for (i = 0; i < num_user_hostfiles; i++)
- load_hostkeys(ip_hostkeys, ip, user_hostfiles[i]);
+ load_hostkeys(ip_hostkeys, ip, user_hostfiles[i], 0);
for (i = 0; i < num_system_hostfiles; i++)
- load_hostkeys(ip_hostkeys, ip, system_hostfiles[i]);
+ load_hostkeys(ip_hostkeys, ip, system_hostfiles[i], 0);
+ if (hostfile_command != NULL && !clobber_port) {
+ load_hostkeys_command(ip_hostkeys, hostfile_command,
+ "ADDRESS", cinfo, host_key, ip);
+ }
}
retry:
@@ -920,6 +1012,14 @@ check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port,
&host_found);
/*
+ * If there are no hostfiles, or if the hostkey was found via
+ * KnownHostsCommand, then don't try to touch the disk.
+ */
+ if (!readonly && (num_user_hostfiles == 0 ||
+ (host_found != NULL && host_found->note != 0)))
+ readonly = RDONLY;
+
+ /*
* Also perform check for the ip address, skip the check if we are
* localhost, looking for a certificate, or the hostname was an ip
* address to begin with.
@@ -928,7 +1028,7 @@ check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port,
ip_status = check_key_in_hostkeys(ip_hostkeys, host_key,
&ip_found);
if (host_status == HOST_CHANGED &&
- (ip_status != HOST_CHANGED ||
+ (ip_status != HOST_CHANGED ||
(ip_found != NULL &&
!sshkey_equal(ip_found->key, host_found->key))))
host_ip_differ = 1;
@@ -942,10 +1042,40 @@ check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port,
host, type, want_cert ? "certificate" : "key");
debug("Found %s in %s:%lu", want_cert ? "CA key" : "key",
host_found->file, host_found->line);
- if (want_cert &&
- !check_host_cert(options.host_key_alias == NULL ?
- hostname : options.host_key_alias, host_key))
- goto fail;
+ if (want_cert) {
+ if (sshkey_cert_check_host(host_key,
+ options.host_key_alias == NULL ?
+ hostname : options.host_key_alias, 0,
+ options.ca_sign_algorithms, &fail_reason) != 0) {
+ error("%s", fail_reason);
+ goto fail;
+ }
+ /*
+ * Do not attempt hostkey update if a certificate was
+ * successfully matched.
+ */
+ if (options.update_hostkeys != 0) {
+ options.update_hostkeys = 0;
+ debug3_f("certificate host key in use; "
+ "disabling UpdateHostkeys");
+ }
+ }
+ /* Turn off UpdateHostkeys if key was in system known_hosts */
+ if (options.update_hostkeys != 0 &&
+ (path_in_hostfiles(host_found->file,
+ system_hostfiles, num_system_hostfiles) ||
+ (ip_status == HOST_OK && ip_found != NULL &&
+ path_in_hostfiles(ip_found->file,
+ system_hostfiles, num_system_hostfiles)))) {
+ options.update_hostkeys = 0;
+ debug3_f("host key found in GlobalKnownHostsFile; "
+ "disabling UpdateHostkeys");
+ }
+ if (options.update_hostkeys != 0 && host_found->note) {
+ options.update_hostkeys = 0;
+ debug3_f("host key found via KnownHostsCommand; "
+ "disabling UpdateHostkeys");
+ }
if (options.check_host_ip && ip_status == HOST_NEW) {
if (readonly || want_cert)
logit("%s host key for IP address "
@@ -967,7 +1097,7 @@ check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port,
ra = sshkey_fingerprint(host_key,
options.fingerprint_hash, SSH_FP_RANDOMART);
if (fp == NULL || ra == NULL)
- fatal("%s: sshkey_fingerprint fail", __func__);
+ fatal_f("sshkey_fingerprint failed");
logit("Host key fingerprint is %s\n%s", fp, ra);
free(ra);
free(fp);
@@ -976,11 +1106,13 @@ check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port,
break;
case HOST_NEW:
if (options.host_key_alias == NULL && port != 0 &&
- port != SSH_DEFAULT_PORT) {
+ port != SSH_DEFAULT_PORT && !clobber_port) {
debug("checking without port identifier");
- if (check_host_key(hostname, hostaddr, 0, host_key,
- ROQUIET, user_hostfiles, num_user_hostfiles,
- system_hostfiles, num_system_hostfiles) == 0) {
+ if (check_host_key(hostname, cinfo, hostaddr, 0,
+ host_key, ROQUIET, 1,
+ user_hostfiles, num_user_hostfiles,
+ system_hostfiles, num_system_hostfiles,
+ hostfile_command) == 0) {
debug("found matching key w/out port");
break;
}
@@ -1000,45 +1132,49 @@ check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port,
goto fail;
} else if (options.strict_host_key_checking ==
SSH_STRICT_HOSTKEY_ASK) {
- char msg1[1024], msg2[1024];
+ char *msg1 = NULL, *msg2 = NULL;
+
+ xasprintf(&msg1, "The authenticity of host "
+ "'%.200s (%s)' can't be established", host, ip);
+
+ if (show_other_keys(host_hostkeys, host_key)) {
+ xextendf(&msg1, "\n", "but keys of different "
+ "type are already known for this host.");
+ } else
+ xextendf(&msg1, "", ".");
- if (show_other_keys(host_hostkeys, host_key))
- snprintf(msg1, sizeof(msg1),
- "\nbut keys of different type are already"
- " known for this host.");
- else
- snprintf(msg1, sizeof(msg1), ".");
- /* The default */
fp = sshkey_fingerprint(host_key,
options.fingerprint_hash, SSH_FP_DEFAULT);
ra = sshkey_fingerprint(host_key,
options.fingerprint_hash, SSH_FP_RANDOMART);
if (fp == NULL || ra == NULL)
- fatal("%s: sshkey_fingerprint fail", __func__);
- msg2[0] = '\0';
+ fatal_f("sshkey_fingerprint failed");
+ xextendf(&msg1, "\n", "%s key fingerprint is %s.",
+ type, fp);
+ if (options.visual_host_key)
+ xextendf(&msg1, "\n", "%s", ra);
if (options.verify_host_key_dns) {
- if (matching_host_key_dns)
- snprintf(msg2, sizeof(msg2),
- "Matching host key fingerprint"
- " found in DNS.\n");
- else
- snprintf(msg2, sizeof(msg2),
- "No matching host key fingerprint"
- " found in DNS.\n");
+ xextendf(&msg1, "\n",
+ "%s host key fingerprint found in DNS.",
+ matching_host_key_dns ?
+ "Matching" : "No matching");
}
- snprintf(msg, sizeof(msg),
- "The authenticity of host '%.200s (%s)' can't be "
- "established%s\n"
- "%s key fingerprint is %s.%s%s\n%s"
+ /* msg2 informs for other names matching this key */
+ if ((msg2 = other_hostkeys_message(host, ip, host_key,
+ user_hostfiles, num_user_hostfiles,
+ system_hostfiles, num_system_hostfiles)) != NULL)
+ xextendf(&msg1, "\n", "%s", msg2);
+
+ xextendf(&msg1, "\n",
"Are you sure you want to continue connecting "
- "(yes/no)? ",
- host, ip, msg1, type, fp,
- options.visual_host_key ? "\n" : "",
- options.visual_host_key ? ra : "",
- msg2);
+ "(yes/no/[fingerprint])? ");
+
+ confirmed = confirm(msg1, fp);
free(ra);
free(fp);
- if (!confirm(msg))
+ free(msg1);
+ free(msg2);
+ if (!confirmed)
goto fail;
hostkey_trusted = 1; /* user explicitly confirmed */
}
@@ -1142,8 +1278,8 @@ check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port,
*/
if (options.strict_host_key_checking !=
SSH_STRICT_HOSTKEY_OFF) {
- error("%s host key for %.200s has changed and you have "
- "requested strict checking.", type, host);
+ error("Host key for %.200s has changed and you have "
+ "requested strict checking.", host);
goto fail;
}
@@ -1163,13 +1299,6 @@ check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port,
error("Keyboard-interactive authentication is disabled"
" to avoid man-in-the-middle attacks.");
options.kbd_interactive_authentication = 0;
- options.challenge_response_authentication = 0;
- cancelled_forwarding = 1;
- }
- if (options.challenge_response_authentication) {
- error("Challenge/response authentication is disabled"
- " to avoid man-in-the-middle attacks.");
- options.challenge_response_authentication = 0;
cancelled_forwarding = 1;
}
if (options.forward_agent) {
@@ -1198,6 +1327,11 @@ check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port,
options.tun_open = SSH_TUNMODE_NO;
cancelled_forwarding = 1;
}
+ if (options.update_hostkeys != 0) {
+ error("UpdateHostkeys is disabled because the host "
+ "key is not trusted.");
+ options.update_hostkeys = 0;
+ }
if (options.exit_on_forward_failure && cancelled_forwarding)
fatal("Error: forwarding disabled due to host key "
"check failure");
@@ -1206,7 +1340,7 @@ check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port,
* XXX Should permit the user to change to use the new id.
* This could be done by converting the host key to an
* identifying sentence, tell that the host identifies itself
- * by that sentence, and ask the user if he/she wishes to
+ * by that sentence, and ask the user if they wish to
* accept the authentication.
*/
break;
@@ -1232,7 +1366,7 @@ check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port,
SSH_STRICT_HOSTKEY_ASK) {
strlcat(msg, "\nAre you sure you want "
"to continue connecting (yes/no)? ", sizeof(msg));
- if (!confirm(msg))
+ if (!confirm(msg, NULL))
goto fail;
} else if (options.strict_host_key_checking !=
SSH_STRICT_HOSTKEY_OFF) {
@@ -1245,8 +1379,8 @@ check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port,
}
if (!hostkey_trusted && options.update_hostkeys) {
- debug("%s: hostkey not known or explicitly trusted: "
- "disabling UpdateHostkeys", __func__);
+ debug_f("hostkey not known or explicitly trusted: "
+ "disabling UpdateHostkeys");
options.update_hostkeys = 0;
}
@@ -1266,10 +1400,9 @@ fail:
*/
debug("No matching CA found. Retry with plain key");
if ((r = sshkey_from_private(host_key, &raw_key)) != 0)
- fatal("%s: sshkey_from_private: %s",
- __func__, ssh_err(r));
+ fatal_fr(r, "decode key");
if ((r = sshkey_drop_cert(raw_key)) != 0)
- fatal("Couldn't drop certificate: %s", ssh_err(r));
+ fatal_r(r, "Couldn't drop certificate");
host_key = raw_key;
goto retry;
}
@@ -1285,7 +1418,8 @@ fail:
/* returns 0 if key verifies or -1 if key does NOT verify */
int
-verify_host_key(char *host, struct sockaddr *hostaddr, struct sshkey *host_key)
+verify_host_key(char *host, struct sockaddr *hostaddr, struct sshkey *host_key,
+ const struct ssh_conn_info *cinfo)
{
u_int i;
int r = -1, flags = 0;
@@ -1294,7 +1428,7 @@ verify_host_key(char *host, struct sockaddr *hostaddr, struct sshkey *host_key)
if ((fp = sshkey_fingerprint(host_key,
options.fingerprint_hash, SSH_FP_DEFAULT)) == NULL) {
- error("%s: fingerprint host key: %s", __func__, ssh_err(r));
+ error_fr(r, "fingerprint host key");
r = -1;
goto out;
}
@@ -1302,8 +1436,7 @@ verify_host_key(char *host, struct sockaddr *hostaddr, struct sshkey *host_key)
if (sshkey_is_cert(host_key)) {
if ((cafp = sshkey_fingerprint(host_key->cert->signature_key,
options.fingerprint_hash, SSH_FP_DEFAULT)) == NULL) {
- error("%s: fingerprint CA key: %s",
- __func__, ssh_err(r));
+ error_fr(r, "fingerprint CA key");
r = -1;
goto out;
}
@@ -1325,8 +1458,8 @@ verify_host_key(char *host, struct sockaddr *hostaddr, struct sshkey *host_key)
}
if (sshkey_equal(previous_host_key, host_key)) {
- debug2("%s: server host key %s %s matches cached key",
- __func__, sshkey_type(host_key), fp);
+ debug2_f("server host key %s %s matches cached key",
+ sshkey_type(host_key), fp);
r = 0;
goto out;
}
@@ -1344,9 +1477,9 @@ verify_host_key(char *host, struct sockaddr *hostaddr, struct sshkey *host_key)
r = -1;
goto out;
default:
- error("Error checking host key %s %s in "
- "revoked keys file %s: %s", sshkey_type(host_key),
- fp, options.revoked_host_keys, ssh_err(r));
+ error_r(r, "Error checking host key %s %s in "
+ "revoked keys file %s", sshkey_type(host_key),
+ fp, options.revoked_host_keys);
r = -1;
goto out;
}
@@ -1380,9 +1513,10 @@ verify_host_key(char *host, struct sockaddr *hostaddr, struct sshkey *host_key)
}
}
}
- r = check_host_key(host, hostaddr, options.port, host_key, RDRW,
- options.user_hostfiles, options.num_user_hostfiles,
- options.system_hostfiles, options.num_system_hostfiles);
+ r = check_host_key(host, cinfo, hostaddr, options.port, host_key,
+ RDRW, 0, options.user_hostfiles, options.num_user_hostfiles,
+ options.system_hostfiles, options.num_system_hostfiles,
+ options.known_hosts_command);
out:
sshkey_free(plain);
@@ -1404,11 +1538,13 @@ out:
* This function does not require super-user privileges.
*/
void
-ssh_login(Sensitive *sensitive, const char *orighost,
- struct sockaddr *hostaddr, u_short port, struct passwd *pw, int timeout_ms)
+ssh_login(struct ssh *ssh, Sensitive *sensitive, const char *orighost,
+ struct sockaddr *hostaddr, u_short port, struct passwd *pw, int timeout_ms,
+ const struct ssh_conn_info *cinfo)
{
char *host;
char *server_user, *local_user;
+ int r;
local_user = xstrdup(pw->pw_name);
server_user = options.user ? options.user : local_user;
@@ -1418,35 +1554,20 @@ ssh_login(Sensitive *sensitive, const char *orighost,
lowercase(host);
/* Exchange protocol version identification strings with the server. */
- ssh_exchange_identification(timeout_ms);
+ if ((r = kex_exchange_identification(ssh, timeout_ms,
+ options.version_addendum)) != 0)
+ sshpkt_fatal(ssh, r, "banner exchange");
/* Put the connection into non-blocking mode. */
- packet_set_nonblocking();
+ ssh_packet_set_nonblocking(ssh);
/* key exchange */
/* authenticate user */
debug("Authenticating to %s:%d as '%s'", host, port, server_user);
- ssh_kex2(host, hostaddr, port);
- ssh_userauth2(local_user, server_user, host, sensitive);
+ ssh_kex2(ssh, host, hostaddr, port, cinfo);
+ ssh_userauth2(ssh, local_user, server_user, host, sensitive);
free(local_user);
-}
-
-void
-ssh_put_password(char *password)
-{
- int size;
- char *padded;
-
- if (datafellows & SSH_BUG_PASSWORDPAD) {
- packet_put_cstring(password);
- return;
- }
- size = ROUNDUP(strlen(password) + 1, 32);
- padded = xcalloc(1, size);
- strlcpy(padded, password, size);
- packet_put_string(padded, size);
- explicit_bzero(padded, size);
- free(padded);
+ free(host);
}
/* print all known host keys for a given host, but skip keys of given type */
@@ -1468,14 +1589,15 @@ show_other_keys(struct hostkeys *hostkeys, struct sshkey *key)
for (i = 0; type[i] != -1; i++) {
if (type[i] == key->type)
continue;
- if (!lookup_key_in_hostkeys_by_type(hostkeys, type[i], &found))
+ if (!lookup_key_in_hostkeys_by_type(hostkeys, type[i],
+ -1, &found))
continue;
fp = sshkey_fingerprint(found->key,
options.fingerprint_hash, SSH_FP_DEFAULT);
ra = sshkey_fingerprint(found->key,
options.fingerprint_hash, SSH_FP_RANDOMART);
if (fp == NULL || ra == NULL)
- fatal("%s: sshkey_fingerprint fail", __func__);
+ fatal_f("sshkey_fingerprint fail");
logit("WARNING: %s key found for host %s\n"
"in %s:%lu\n"
"%s key fingerprint %s.",
@@ -1499,7 +1621,7 @@ warn_changed_key(struct sshkey *host_key)
fp = sshkey_fingerprint(host_key, options.fingerprint_hash,
SSH_FP_DEFAULT);
if (fp == NULL)
- fatal("%s: sshkey_fingerprint fail", __func__);
+ fatal_f("sshkey_fingerprint fail");
error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
error("@ WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! @");
@@ -1532,10 +1654,10 @@ ssh_local_cmd(const char *args)
if ((shell = getenv("SHELL")) == NULL || *shell == '\0')
shell = _PATH_BSHELL;
- osighand = signal(SIGCHLD, SIG_DFL);
+ osighand = ssh_signal(SIGCHLD, SIG_DFL);
pid = fork();
if (pid == 0) {
- signal(SIGPIPE, SIG_DFL);
+ ssh_signal(SIGPIPE, SIG_DFL);
debug3("Executing %s -c \"%s\"", shell, args);
execl(shell, shell, "-c", args, (char *)NULL);
error("Couldn't execute %s -c \"%s\": %s",
@@ -1546,7 +1668,7 @@ ssh_local_cmd(const char *args)
while (waitpid(pid, &status, 0) == -1)
if (errno != EINTR)
fatal("Couldn't wait for child: %s", strerror(errno));
- signal(SIGCHLD, osighand);
+ ssh_signal(SIGCHLD, osighand);
if (!WIFEXITED(status))
return (1);
@@ -1555,10 +1677,11 @@ ssh_local_cmd(const char *args)
}
void
-maybe_add_key_to_agent(char *authfile, const struct sshkey *private,
- char *comment, char *passphrase)
+maybe_add_key_to_agent(const char *authfile, struct sshkey *private,
+ const char *comment, const char *passphrase)
{
int auth_sock = -1, r;
+ const char *skprovider = NULL;
if (options.add_keys_to_agent == 0)
return;
@@ -1574,9 +1697,12 @@ maybe_add_key_to_agent(char *authfile, const struct sshkey *private,
close(auth_sock);
return;
}
-
- if ((r = ssh_add_identity_constrained(auth_sock, private, comment, 0,
- (options.add_keys_to_agent == 3), 0)) == 0)
+ if (sshkey_is_sk(private))
+ skprovider = options.sk_provider;
+ if ((r = ssh_add_identity_constrained(auth_sock, private,
+ comment == NULL ? authfile : comment,
+ options.add_keys_to_agent_lifespan,
+ (options.add_keys_to_agent == 3), 0, skprovider)) == 0)
debug("identity added to agent: %s", authfile);
else
debug("could not add identity to agent: %s (%d)", authfile, r);
diff --git a/crypto/openssh/sshconnect.h b/crypto/openssh/sshconnect.h
index 890d857330cd..f518a9a1302f 100644
--- a/crypto/openssh/sshconnect.h
+++ b/crypto/openssh/sshconnect.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: sshconnect.h,v 1.35 2018/07/19 10:28:47 dtucker Exp $ */
+/* $OpenBSD: sshconnect.h,v 1.46 2020/12/22 00:15:23 djm Exp $ */
/*
* Copyright (c) 2000 Markus Friedl. All rights reserved.
@@ -30,30 +30,65 @@ struct Sensitive {
int nkeys;
};
+struct ssh_conn_info {
+ char *conn_hash_hex;
+ char *shorthost;
+ char *uidstr;
+ char *keyalias;
+ char *thishost;
+ char *host_arg;
+ char *portstr;
+ char *remhost;
+ char *remuser;
+ char *homedir;
+ char *locuser;
+};
+
struct addrinfo;
struct ssh;
+struct hostkeys;
+struct ssh_conn_info;
-int ssh_connect(struct ssh *, const char *, struct addrinfo *,
- struct sockaddr_storage *, u_short, int, int, int *, int);
-void ssh_kill_proxy_command(void);
+/* default argument for client percent expansions */
+#define DEFAULT_CLIENT_PERCENT_EXPAND_ARGS(conn_info) \
+ "C", conn_info->conn_hash_hex, \
+ "L", conn_info->shorthost, \
+ "i", conn_info->uidstr, \
+ "k", conn_info->keyalias, \
+ "l", conn_info->thishost, \
+ "n", conn_info->host_arg, \
+ "p", conn_info->portstr, \
+ "d", conn_info->homedir, \
+ "h", conn_info->remhost, \
+ "r", conn_info->remuser, \
+ "u", conn_info->locuser
-void ssh_login(Sensitive *, const char *, struct sockaddr *, u_short,
- struct passwd *, int);
+int ssh_connect(struct ssh *, const char *, const char *,
+ struct addrinfo *, struct sockaddr_storage *, u_short,
+ int, int *, int);
+void ssh_kill_proxy_command(void);
-void ssh_exchange_identification(int);
+void ssh_login(struct ssh *, Sensitive *, const char *,
+ struct sockaddr *, u_short, struct passwd *, int,
+ const struct ssh_conn_info *);
-int verify_host_key(char *, struct sockaddr *, struct sshkey *);
+int verify_host_key(char *, struct sockaddr *, struct sshkey *,
+ const struct ssh_conn_info *);
void get_hostfile_hostname_ipaddr(char *, struct sockaddr *, u_short,
char **, char **);
-void ssh_kex(char *, struct sockaddr *);
-void ssh_kex2(char *, struct sockaddr *, u_short);
+void ssh_kex2(struct ssh *ssh, char *, struct sockaddr *, u_short,
+ const struct ssh_conn_info *);
-void ssh_userauth1(const char *, const char *, char *, Sensitive *);
-void ssh_userauth2(const char *, const char *, char *, Sensitive *);
+void ssh_userauth2(struct ssh *ssh, const char *, const char *,
+ char *, Sensitive *);
-void ssh_put_password(char *);
int ssh_local_cmd(const char *);
-void maybe_add_key_to_agent(char *, const struct sshkey *, char *, char *);
+void maybe_add_key_to_agent(const char *, struct sshkey *,
+ const char *, const char *);
+
+void load_hostkeys_command(struct hostkeys *, const char *,
+ const char *, const struct ssh_conn_info *,
+ const struct sshkey *, const char *);
diff --git a/crypto/openssh/sshconnect2.c b/crypto/openssh/sshconnect2.c
index 1675f393561e..fea50fab61d3 100644
--- a/crypto/openssh/sshconnect2.c
+++ b/crypto/openssh/sshconnect2.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: sshconnect2.c,v 1.288 2018/10/11 03:48:04 djm Exp $ */
+/* $OpenBSD: sshconnect2.c,v 1.351 2021/07/23 05:24:02 djm Exp $ */
/*
* Copyright (c) 2000 Markus Friedl. All rights reserved.
* Copyright (c) 2008 Damien Miller. All rights reserved.
@@ -33,12 +33,13 @@
#include <errno.h>
#include <fcntl.h>
+#include <limits.h>
#include <netdb.h>
#include <pwd.h>
#include <signal.h>
-#include <stdarg.h>
#include <stdio.h>
#include <string.h>
+#include <stdarg.h>
#include <unistd.h>
#if defined(HAVE_STRNVIS) && defined(HAVE_VIS_H) && !defined(BROKEN_STRNVIS)
#include <vis.h>
@@ -72,6 +73,8 @@
#include "hostfile.h"
#include "ssherr.h"
#include "utf8.h"
+#include "ssh-sk.h"
+#include "sk-api.h"
#ifdef GSSAPI
#include "ssh-gss.h"
@@ -86,26 +89,39 @@ extern Options options;
* SSH2 key exchange
*/
-u_char *session_id2 = NULL;
-u_int session_id2_len = 0;
-
-char *xxx_host;
-struct sockaddr *xxx_hostaddr;
+static char *xxx_host;
+static struct sockaddr *xxx_hostaddr;
+static const struct ssh_conn_info *xxx_conn_info;
static int
verify_host_key_callback(struct sshkey *hostkey, struct ssh *ssh)
{
- if (verify_host_key(xxx_host, xxx_hostaddr, hostkey) == -1)
+ if (verify_host_key(xxx_host, xxx_hostaddr, hostkey,
+ xxx_conn_info) == -1)
fatal("Host key verification failed.");
return 0;
}
+/* Returns the first item from a comma-separated algorithm list */
+static char *
+first_alg(const char *algs)
+{
+ char *ret, *cp;
+
+ ret = xstrdup(algs);
+ if ((cp = strchr(ret, ',')) != NULL)
+ *cp = '\0';
+ return ret;
+}
+
static char *
-order_hostkeyalgs(char *host, struct sockaddr *hostaddr, u_short port)
+order_hostkeyalgs(char *host, struct sockaddr *hostaddr, u_short port,
+ const struct ssh_conn_info *cinfo)
{
- char *oavail, *avail, *first, *last, *alg, *hostname, *ret;
+ char *oavail = NULL, *avail = NULL, *first = NULL, *last = NULL;
+ char *alg = NULL, *hostname = NULL, *ret = NULL, *best = NULL;
size_t maxlen;
- struct hostkeys *hostkeys;
+ struct hostkeys *hostkeys = NULL;
int ktype;
u_int i;
@@ -113,11 +129,37 @@ order_hostkeyalgs(char *host, struct sockaddr *hostaddr, u_short port)
get_hostfile_hostname_ipaddr(host, hostaddr, port, &hostname, NULL);
hostkeys = init_hostkeys();
for (i = 0; i < options.num_user_hostfiles; i++)
- load_hostkeys(hostkeys, hostname, options.user_hostfiles[i]);
- for (i = 0; i < options.num_system_hostfiles; i++)
- load_hostkeys(hostkeys, hostname, options.system_hostfiles[i]);
+ load_hostkeys(hostkeys, hostname, options.user_hostfiles[i], 0);
+ for (i = 0; i < options.num_system_hostfiles; i++) {
+ load_hostkeys(hostkeys, hostname,
+ options.system_hostfiles[i], 0);
+ }
+ if (options.known_hosts_command != NULL) {
+ load_hostkeys_command(hostkeys, options.known_hosts_command,
+ "ORDER", cinfo, NULL, host);
+ }
+ /*
+ * If a plain public key exists that matches the type of the best
+ * preference HostkeyAlgorithms, then use the whole list as is.
+ * Note that we ignore whether the best preference algorithm is a
+ * certificate type, as sshconnect.c will downgrade certs to
+ * plain keys if necessary.
+ */
+ best = first_alg(options.hostkeyalgorithms);
+ if (lookup_key_in_hostkeys_by_type(hostkeys,
+ sshkey_type_plain(sshkey_type_from_name(best)),
+ sshkey_ecdsa_nid_from_name(best), NULL)) {
+ debug3_f("have matching best-preference key type %s, "
+ "using HostkeyAlgorithms verbatim", best);
+ ret = xstrdup(options.hostkeyalgorithms);
+ goto out;
+ }
- oavail = avail = xstrdup(KEX_DEFAULT_PK_ALG);
+ /*
+ * Otherwise, prefer the host key algorithms that match known keys
+ * while keeping the ordering of HostkeyAlgorithms as much as possible.
+ */
+ oavail = avail = xstrdup(options.hostkeyalgorithms);
maxlen = strlen(avail) + 1;
first = xmalloc(maxlen);
last = xmalloc(maxlen);
@@ -132,19 +174,35 @@ order_hostkeyalgs(char *host, struct sockaddr *hostaddr, u_short port)
while ((alg = strsep(&avail, ",")) && *alg != '\0') {
if ((ktype = sshkey_type_from_name(alg)) == KEY_UNSPEC)
- fatal("%s: unknown alg %s", __func__, alg);
+ fatal_f("unknown alg %s", alg);
+ /*
+ * If we have a @cert-authority marker in known_hosts then
+ * prefer all certificate algorithms.
+ */
+ if (sshkey_type_is_cert(ktype) &&
+ lookup_marker_in_hostkeys(hostkeys, MRK_CA)) {
+ ALG_APPEND(first, alg);
+ continue;
+ }
+ /* If the key appears in known_hosts then prefer it */
if (lookup_key_in_hostkeys_by_type(hostkeys,
- sshkey_type_plain(ktype), NULL))
+ sshkey_type_plain(ktype),
+ sshkey_ecdsa_nid_from_name(alg), NULL)) {
ALG_APPEND(first, alg);
- else
- ALG_APPEND(last, alg);
+ continue;
+ }
+ /* Otherwise, put it last */
+ ALG_APPEND(last, alg);
}
#undef ALG_APPEND
xasprintf(&ret, "%s%s%s", first,
(*first == '\0' || *last == '\0') ? "" : ",", last);
if (*first != '\0')
- debug3("%s: prefer hostkeyalgs: %s", __func__, first);
-
+ debug3_f("prefer hostkeyalgs: %s", first);
+ else
+ debug3_f("no algorithms matched; accept original");
+ out:
+ free(best);
free(first);
free(last);
free(hostname);
@@ -155,80 +213,87 @@ order_hostkeyalgs(char *host, struct sockaddr *hostaddr, u_short port)
}
void
-ssh_kex2(char *host, struct sockaddr *hostaddr, u_short port)
+ssh_kex2(struct ssh *ssh, char *host, struct sockaddr *hostaddr, u_short port,
+ const struct ssh_conn_info *cinfo)
{
char *myproposal[PROPOSAL_MAX] = { KEX_CLIENT };
char *s, *all_key;
- struct kex *kex;
- int r;
+ int r, use_known_hosts_order = 0;
xxx_host = host;
xxx_hostaddr = hostaddr;
+ xxx_conn_info = cinfo;
+
+ /*
+ * If the user has not specified HostkeyAlgorithms, or has only
+ * appended or removed algorithms from that list then prefer algorithms
+ * that are in the list that are supported by known_hosts keys.
+ */
+ if (options.hostkeyalgorithms == NULL ||
+ options.hostkeyalgorithms[0] == '-' ||
+ options.hostkeyalgorithms[0] == '+')
+ use_known_hosts_order = 1;
+
+ /* Expand or fill in HostkeyAlgorithms */
+ all_key = sshkey_alg_list(0, 0, 1, ',');
+ if ((r = kex_assemble_names(&options.hostkeyalgorithms,
+ kex_default_pk_alg(), all_key)) != 0)
+ fatal_fr(r, "kex_assemble_namelist");
+ free(all_key);
if ((s = kex_names_cat(options.kex_algorithms, "ext-info-c")) == NULL)
- fatal("%s: kex_names_cat", __func__);
- myproposal[PROPOSAL_KEX_ALGS] = compat_kex_proposal(s);
+ fatal_f("kex_names_cat");
+ myproposal[PROPOSAL_KEX_ALGS] = compat_kex_proposal(ssh, s);
myproposal[PROPOSAL_ENC_ALGS_CTOS] =
- compat_cipher_proposal(options.ciphers);
+ compat_cipher_proposal(ssh, options.ciphers);
myproposal[PROPOSAL_ENC_ALGS_STOC] =
- compat_cipher_proposal(options.ciphers);
+ compat_cipher_proposal(ssh, options.ciphers);
myproposal[PROPOSAL_COMP_ALGS_CTOS] =
- myproposal[PROPOSAL_COMP_ALGS_STOC] = options.compression ?
- "zlib@openssh.com,zlib,none" : "none,zlib@openssh.com,zlib";
+ myproposal[PROPOSAL_COMP_ALGS_STOC] =
+ (char *)compression_alg_list(options.compression);
myproposal[PROPOSAL_MAC_ALGS_CTOS] =
myproposal[PROPOSAL_MAC_ALGS_STOC] = options.macs;
- if (options.hostkeyalgorithms != NULL) {
- all_key = sshkey_alg_list(0, 0, 1, ',');
- if (kex_assemble_names(&options.hostkeyalgorithms,
- KEX_DEFAULT_PK_ALG, all_key) != 0)
- fatal("%s: kex_assemble_namelist", __func__);
- free(all_key);
+ if (use_known_hosts_order) {
+ /* Query known_hosts and prefer algorithms that appear there */
myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] =
- compat_pkalg_proposal(options.hostkeyalgorithms);
+ compat_pkalg_proposal(ssh,
+ order_hostkeyalgs(host, hostaddr, port, cinfo));
} else {
- /* Enforce default */
- options.hostkeyalgorithms = xstrdup(KEX_DEFAULT_PK_ALG);
- /* Prefer algorithms that we already have keys for */
+ /* Use specified HostkeyAlgorithms exactly */
myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] =
- compat_pkalg_proposal(
- order_hostkeyalgs(host, hostaddr, port));
+ compat_pkalg_proposal(ssh, options.hostkeyalgorithms);
}
if (options.rekey_limit || options.rekey_interval)
- packet_set_rekey_limits(options.rekey_limit,
+ ssh_packet_set_rekey_limits(ssh, options.rekey_limit,
options.rekey_interval);
/* start key exchange */
- if ((r = kex_setup(active_state, myproposal)) != 0)
- fatal("kex_setup: %s", ssh_err(r));
- kex = active_state->kex;
+ if ((r = kex_setup(ssh, myproposal)) != 0)
+ fatal_r(r, "kex_setup");
#ifdef WITH_OPENSSL
- kex->kex[KEX_DH_GRP1_SHA1] = kexdh_client;
- kex->kex[KEX_DH_GRP14_SHA1] = kexdh_client;
- kex->kex[KEX_DH_GRP14_SHA256] = kexdh_client;
- kex->kex[KEX_DH_GRP16_SHA512] = kexdh_client;
- kex->kex[KEX_DH_GRP18_SHA512] = kexdh_client;
- kex->kex[KEX_DH_GEX_SHA1] = kexgex_client;
- kex->kex[KEX_DH_GEX_SHA256] = kexgex_client;
+ ssh->kex->kex[KEX_DH_GRP1_SHA1] = kex_gen_client;
+ ssh->kex->kex[KEX_DH_GRP14_SHA1] = kex_gen_client;
+ ssh->kex->kex[KEX_DH_GRP14_SHA256] = kex_gen_client;
+ ssh->kex->kex[KEX_DH_GRP16_SHA512] = kex_gen_client;
+ ssh->kex->kex[KEX_DH_GRP18_SHA512] = kex_gen_client;
+ ssh->kex->kex[KEX_DH_GEX_SHA1] = kexgex_client;
+ ssh->kex->kex[KEX_DH_GEX_SHA256] = kexgex_client;
# ifdef OPENSSL_HAS_ECC
- kex->kex[KEX_ECDH_SHA2] = kexecdh_client;
+ ssh->kex->kex[KEX_ECDH_SHA2] = kex_gen_client;
# endif
#endif
- kex->kex[KEX_C25519_SHA256] = kexc25519_client;
- kex->client_version_string=client_version_string;
- kex->server_version_string=server_version_string;
- kex->verify_host_key=&verify_host_key_callback;
+ ssh->kex->kex[KEX_C25519_SHA256] = kex_gen_client;
+ ssh->kex->kex[KEX_KEM_SNTRUP761X25519_SHA512] = kex_gen_client;
+ ssh->kex->verify_host_key=&verify_host_key_callback;
- ssh_dispatch_run_fatal(active_state, DISPATCH_BLOCK, &kex->done);
+ ssh_dispatch_run_fatal(ssh, DISPATCH_BLOCK, &ssh->kex->done);
/* remove ext-info from the KEX proposals for rekeying */
myproposal[PROPOSAL_KEX_ALGS] =
- compat_kex_proposal(options.kex_algorithms);
- if ((r = kex_prop2buf(kex->my, myproposal)) != 0)
- fatal("kex_prop2buf: %s", ssh_err(r));
-
- session_id2 = kex->session_id;
- session_id2_len = kex->session_id_len;
+ compat_kex_proposal(ssh, options.kex_algorithms);
+ if ((r = kex_prop2buf(ssh->kex->my, myproposal)) != 0)
+ fatal_r(r, "kex_prop2buf");
#ifdef DEBUG_KEXDH
/* send 1st encrypted/maced/compressed message */
@@ -236,7 +301,7 @@ ssh_kex2(char *host, struct sockaddr *hostaddr, u_short port)
(r = sshpkt_put_cstring(ssh, "markus")) != 0 ||
(r = sshpkt_send(ssh)) != 0 ||
(r = ssh_packet_write_wait(ssh)) != 0)
- fatal("%s: %s", __func__, ssh_err(r));
+ fatal_fr(r, "send packet");
#endif
}
@@ -268,7 +333,11 @@ struct cauthctxt {
struct cauthmethod *method;
sig_atomic_t success;
char *authlist;
- int attempt;
+#ifdef GSSAPI
+ /* gssapi */
+ gss_OID_set gss_supported_mechs;
+ u_int mech_tried;
+#endif
/* pubkey */
struct idlist keys;
int agent_fd;
@@ -278,49 +347,51 @@ struct cauthctxt {
const char *active_ktype;
/* kbd-interactive */
int info_req_seen;
+ int attempt_kbdint;
+ /* password */
+ int attempt_passwd;
/* generic */
void *methoddata;
};
struct cauthmethod {
char *name; /* string to compare against server's list */
- int (*userauth)(Authctxt *authctxt);
- void (*cleanup)(Authctxt *authctxt);
+ int (*userauth)(struct ssh *ssh);
+ void (*cleanup)(struct ssh *ssh);
int *enabled; /* flag in option struct that enables method */
int *batch_flag; /* flag in option struct that disables method */
};
-int input_userauth_service_accept(int, u_int32_t, struct ssh *);
-int input_userauth_ext_info(int, u_int32_t, struct ssh *);
-int input_userauth_success(int, u_int32_t, struct ssh *);
-int input_userauth_success_unexpected(int, u_int32_t, struct ssh *);
-int input_userauth_failure(int, u_int32_t, struct ssh *);
-int input_userauth_banner(int, u_int32_t, struct ssh *);
-int input_userauth_error(int, u_int32_t, struct ssh *);
-int input_userauth_info_req(int, u_int32_t, struct ssh *);
-int input_userauth_pk_ok(int, u_int32_t, struct ssh *);
-int input_userauth_passwd_changereq(int, u_int32_t, struct ssh *);
-
-int userauth_none(Authctxt *);
-int userauth_pubkey(Authctxt *);
-int userauth_passwd(Authctxt *);
-int userauth_kbdint(Authctxt *);
-int userauth_hostbased(Authctxt *);
+static int input_userauth_service_accept(int, u_int32_t, struct ssh *);
+static int input_userauth_ext_info(int, u_int32_t, struct ssh *);
+static int input_userauth_success(int, u_int32_t, struct ssh *);
+static int input_userauth_failure(int, u_int32_t, struct ssh *);
+static int input_userauth_banner(int, u_int32_t, struct ssh *);
+static int input_userauth_error(int, u_int32_t, struct ssh *);
+static int input_userauth_info_req(int, u_int32_t, struct ssh *);
+static int input_userauth_pk_ok(int, u_int32_t, struct ssh *);
+static int input_userauth_passwd_changereq(int, u_int32_t, struct ssh *);
+
+static int userauth_none(struct ssh *);
+static int userauth_pubkey(struct ssh *);
+static int userauth_passwd(struct ssh *);
+static int userauth_kbdint(struct ssh *);
+static int userauth_hostbased(struct ssh *);
#ifdef GSSAPI
-int userauth_gssapi(Authctxt *authctxt);
-int input_gssapi_response(int type, u_int32_t, struct ssh *);
-int input_gssapi_token(int type, u_int32_t, struct ssh *);
-int input_gssapi_hash(int type, u_int32_t, struct ssh *);
-int input_gssapi_error(int, u_int32_t, struct ssh *);
-int input_gssapi_errtok(int, u_int32_t, struct ssh *);
+static int userauth_gssapi(struct ssh *);
+static void userauth_gssapi_cleanup(struct ssh *);
+static int input_gssapi_response(int type, u_int32_t, struct ssh *);
+static int input_gssapi_token(int type, u_int32_t, struct ssh *);
+static int input_gssapi_error(int, u_int32_t, struct ssh *);
+static int input_gssapi_errtok(int, u_int32_t, struct ssh *);
#endif
-void userauth(Authctxt *, char *);
+void userauth(struct ssh *, char *);
-static int sign_and_send_pubkey(struct ssh *ssh, Authctxt *, Identity *);
+static void pubkey_cleanup(struct ssh *);
+static int sign_and_send_pubkey(struct ssh *ssh, Identity *);
static void pubkey_prepare(Authctxt *);
-static void pubkey_cleanup(Authctxt *);
static void pubkey_reset(Authctxt *);
static struct sshkey *load_identity_file(Identity *);
@@ -332,7 +403,7 @@ Authmethod authmethods[] = {
#ifdef GSSAPI
{"gssapi-with-mic",
userauth_gssapi,
- NULL,
+ userauth_gssapi_cleanup,
&options.gss_authentication,
NULL},
#endif
@@ -365,21 +436,17 @@ Authmethod authmethods[] = {
};
void
-ssh_userauth2(const char *local_user, const char *server_user, char *host,
- Sensitive *sensitive)
+ssh_userauth2(struct ssh *ssh, const char *local_user,
+ const char *server_user, char *host, Sensitive *sensitive)
{
- struct ssh *ssh = active_state;
Authctxt authctxt;
int r;
- if (options.challenge_response_authentication)
- options.kbd_interactive_authentication = 1;
if (options.preferred_authentications == NULL)
options.preferred_authentications = authmethods_get();
/* setup authentication context */
memset(&authctxt, 0, sizeof(authctxt));
- pubkey_prepare(&authctxt);
authctxt.server_user = server_user;
authctxt.local_user = local_user;
authctxt.host = host;
@@ -391,35 +458,49 @@ ssh_userauth2(const char *local_user, const char *server_user, char *host,
authctxt.sensitive = sensitive;
authctxt.active_ktype = authctxt.oktypes = authctxt.ktypes = NULL;
authctxt.info_req_seen = 0;
+ authctxt.attempt_kbdint = 0;
+ authctxt.attempt_passwd = 0;
+#if GSSAPI
+ authctxt.gss_supported_mechs = NULL;
+ authctxt.mech_tried = 0;
+#endif
authctxt.agent_fd = -1;
- if (authctxt.method == NULL)
- fatal("ssh_userauth2: internal error: cannot send userauth none request");
+ pubkey_prepare(&authctxt);
+ if (authctxt.method == NULL) {
+ fatal_f("internal error: cannot send userauth none request");
+ }
if ((r = sshpkt_start(ssh, SSH2_MSG_SERVICE_REQUEST)) != 0 ||
(r = sshpkt_put_cstring(ssh, "ssh-userauth")) != 0 ||
(r = sshpkt_send(ssh)) != 0)
- fatal("%s: %s", __func__, ssh_err(r));
+ fatal_fr(r, "send packet");
ssh->authctxt = &authctxt;
ssh_dispatch_init(ssh, &input_userauth_error);
ssh_dispatch_set(ssh, SSH2_MSG_EXT_INFO, &input_userauth_ext_info);
ssh_dispatch_set(ssh, SSH2_MSG_SERVICE_ACCEPT, &input_userauth_service_accept);
ssh_dispatch_run_fatal(ssh, DISPATCH_BLOCK, &authctxt.success); /* loop until success */
+ pubkey_cleanup(ssh);
ssh->authctxt = NULL;
- pubkey_cleanup(&authctxt);
ssh_dispatch_range(ssh, SSH2_MSG_USERAUTH_MIN, SSH2_MSG_USERAUTH_MAX, NULL);
if (!authctxt.success)
fatal("Authentication failed.");
- debug("Authentication succeeded (%s).", authctxt.method->name);
+ if (ssh_packet_connection_is_on_socket(ssh)) {
+ verbose("Authenticated to %s ([%s]:%d) using \"%s\".", host,
+ ssh_remote_ipaddr(ssh), ssh_remote_port(ssh),
+ authctxt.method->name);
+ } else {
+ verbose("Authenticated to %s (via proxy) using \"%s\".", host,
+ authctxt.method->name);
+ }
}
/* ARGSUSED */
-int
+static int
input_userauth_service_accept(int type, u_int32_t seq, struct ssh *ssh)
{
- Authctxt *authctxt = ssh->authctxt;
int r;
if (ssh_packet_remaining(ssh) > 0) {
@@ -437,7 +518,7 @@ input_userauth_service_accept(int type, u_int32_t seq, struct ssh *ssh)
debug("SSH2_MSG_SERVICE_ACCEPT received");
/* initial userauth request */
- userauth_none(authctxt);
+ userauth_none(ssh);
ssh_dispatch_set(ssh, SSH2_MSG_EXT_INFO, &input_userauth_error);
ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_SUCCESS, &input_userauth_success);
@@ -449,19 +530,19 @@ input_userauth_service_accept(int type, u_int32_t seq, struct ssh *ssh)
}
/* ARGSUSED */
-int
+static int
input_userauth_ext_info(int type, u_int32_t seqnr, struct ssh *ssh)
{
return kex_input_ext_info(type, seqnr, ssh);
}
void
-userauth(Authctxt *authctxt, char *authlist)
+userauth(struct ssh *ssh, char *authlist)
{
- struct ssh *ssh = active_state; /* XXX */
+ Authctxt *authctxt = (Authctxt *)ssh->authctxt;
if (authctxt->method != NULL && authctxt->method->cleanup != NULL)
- authctxt->method->cleanup(authctxt);
+ authctxt->method->cleanup(ssh);
free(authctxt->methoddata);
authctxt->methoddata = NULL;
@@ -483,7 +564,7 @@ userauth(Authctxt *authctxt, char *authlist)
SSH2_MSG_USERAUTH_PER_METHOD_MAX, NULL);
/* and try new method */
- if (method->userauth(authctxt) != 0) {
+ if (method->userauth(ssh) != 0) {
debug2("we sent a %s packet, wait for reply", method->name);
break;
} else {
@@ -494,87 +575,91 @@ userauth(Authctxt *authctxt, char *authlist)
}
/* ARGSUSED */
-int
+static int
input_userauth_error(int type, u_int32_t seq, struct ssh *ssh)
{
- fatal("input_userauth_error: bad message during authentication: "
- "type %d", type);
+ fatal_f("bad message during authentication: type %d", type);
return 0;
}
/* ARGSUSED */
-int
+static int
input_userauth_banner(int type, u_int32_t seq, struct ssh *ssh)
{
- char *msg, *lang;
- u_int len;
+ char *msg = NULL;
+ size_t len;
+ int r;
- debug3("%s", __func__);
- msg = packet_get_string(&len);
- lang = packet_get_string(NULL);
+ debug3_f("entering");
+ if ((r = sshpkt_get_cstring(ssh, &msg, &len)) != 0 ||
+ (r = sshpkt_get_cstring(ssh, NULL, NULL)) != 0)
+ goto out;
if (len > 0 && options.log_level >= SYSLOG_LEVEL_INFO)
fmprintf(stderr, "%s", msg);
+ r = 0;
+ out:
free(msg);
- free(lang);
- return 0;
+ return r;
}
/* ARGSUSED */
-int
+static int
input_userauth_success(int type, u_int32_t seq, struct ssh *ssh)
{
Authctxt *authctxt = ssh->authctxt;
if (authctxt == NULL)
- fatal("input_userauth_success: no authentication context");
+ fatal_f("no authentication context");
free(authctxt->authlist);
authctxt->authlist = NULL;
if (authctxt->method != NULL && authctxt->method->cleanup != NULL)
- authctxt->method->cleanup(authctxt);
+ authctxt->method->cleanup(ssh);
free(authctxt->methoddata);
authctxt->methoddata = NULL;
authctxt->success = 1; /* break out */
return 0;
}
-int
+#if 0
+static int
input_userauth_success_unexpected(int type, u_int32_t seq, struct ssh *ssh)
{
Authctxt *authctxt = ssh->authctxt;
if (authctxt == NULL)
- fatal("%s: no authentication context", __func__);
+ fatal_f("no authentication context");
fatal("Unexpected authentication success during %s.",
authctxt->method->name);
return 0;
}
+#endif
/* ARGSUSED */
-int
+static int
input_userauth_failure(int type, u_int32_t seq, struct ssh *ssh)
{
Authctxt *authctxt = ssh->authctxt;
char *authlist = NULL;
u_char partial;
- int r;
if (authctxt == NULL)
fatal("input_userauth_failure: no authentication context");
- if ((r = sshpkt_get_cstring(ssh, &authlist, NULL)) != 0 ||
- (r = sshpkt_get_u8(ssh, &partial)) != 0 ||
- (r = sshpkt_get_end(ssh)) != 0)
+ if (sshpkt_get_cstring(ssh, &authlist, NULL) != 0 ||
+ sshpkt_get_u8(ssh, &partial) != 0 ||
+ sshpkt_get_end(ssh) != 0)
goto out;
if (partial != 0) {
- verbose("Authenticated with partial success.");
+ verbose("Authenticated using \"%s\" with partial success.",
+ authctxt->method->name);
/* reset state */
pubkey_reset(authctxt);
}
debug("Authentications that can continue: %s", authlist);
- userauth(authctxt, authlist);
+ userauth(ssh, authlist);
authlist = NULL;
out:
free(authlist);
@@ -589,24 +674,30 @@ static char *
format_identity(Identity *id)
{
char *fp = NULL, *ret = NULL;
+ const char *note = "";
if (id->key != NULL) {
- fp = sshkey_fingerprint(id->key, options.fingerprint_hash,
+ fp = sshkey_fingerprint(id->key, options.fingerprint_hash,
SSH_FP_DEFAULT);
}
+ if (id->key) {
+ if ((id->key->flags & SSHKEY_FLAG_EXT) != 0)
+ note = " token";
+ else if (sshkey_is_sk(id->key))
+ note = " authenticator";
+ }
xasprintf(&ret, "%s %s%s%s%s%s%s",
id->filename,
id->key ? sshkey_type(id->key) : "", id->key ? " " : "",
fp ? fp : "",
- id->userprovided ? " explicit" : "",
- (id->key && (id->key->flags & SSHKEY_FLAG_EXT)) ? " token" : "",
+ id->userprovided ? " explicit" : "", note,
id->agent_fd != -1 ? " agent" : "");
free(fp);
return ret;
}
/* ARGSUSED */
-int
+static int
input_userauth_pk_ok(int type, u_int32_t seq, struct ssh *ssh)
{
Authctxt *authctxt = ssh->authctxt;
@@ -627,11 +718,11 @@ input_userauth_pk_ok(int type, u_int32_t seq, struct ssh *ssh)
goto done;
if ((pktype = sshkey_type_from_name(pkalg)) == KEY_UNSPEC) {
- debug("%s: server sent unknown pkalg %s", __func__, pkalg);
+ debug_f("server sent unknown pkalg %s", pkalg);
goto done;
}
if ((r = sshkey_from_blob(pkblob, blen, &key)) != 0) {
- debug("no key from blob. pkalg %s: %s", pkalg, ssh_err(r));
+ debug_r(r, "no key from blob. pkalg %s", pkalg);
goto done;
}
if (key->type != pktype) {
@@ -655,13 +746,13 @@ input_userauth_pk_ok(int type, u_int32_t seq, struct ssh *ssh)
if (!found || id == NULL) {
fp = sshkey_fingerprint(key, options.fingerprint_hash,
SSH_FP_DEFAULT);
- error("%s: server replied with unknown key: %s %s", __func__,
+ error_f("server replied with unknown key: %s %s",
sshkey_type(key), fp == NULL ? "<ERROR>" : fp);
goto done;
}
ident = format_identity(id);
debug("Server accepts key: %s", ident);
- sent = sign_and_send_pubkey(ssh, authctxt, id);
+ sent = sign_and_send_pubkey(ssh, id);
r = 0;
done:
sshkey_free(key);
@@ -672,40 +763,41 @@ input_userauth_pk_ok(int type, u_int32_t seq, struct ssh *ssh)
/* try another method if we did not send a packet */
if (r == 0 && sent == 0)
- userauth(authctxt, NULL);
+ userauth(ssh, NULL);
return r;
}
#ifdef GSSAPI
-int
-userauth_gssapi(Authctxt *authctxt)
+static int
+userauth_gssapi(struct ssh *ssh)
{
- struct ssh *ssh = active_state; /* XXX */
+ Authctxt *authctxt = (Authctxt *)ssh->authctxt;
Gssctxt *gssctxt = NULL;
- static gss_OID_set gss_supported = NULL;
- static u_int mech = 0;
OM_uint32 min;
int r, ok = 0;
+ gss_OID mech = NULL;
/* Try one GSSAPI method at a time, rather than sending them all at
* once. */
- if (gss_supported == NULL)
- gss_indicate_mechs(&min, &gss_supported);
+ if (authctxt->gss_supported_mechs == NULL)
+ gss_indicate_mechs(&min, &authctxt->gss_supported_mechs);
- /* Check to see if the mechanism is usable before we offer it */
- while (mech < gss_supported->count && !ok) {
+ /* Check to see whether the mechanism is usable before we offer it */
+ while (authctxt->mech_tried < authctxt->gss_supported_mechs->count &&
+ !ok) {
+ mech = &authctxt->gss_supported_mechs->
+ elements[authctxt->mech_tried];
/* My DER encoding requires length<128 */
- if (gss_supported->elements[mech].length < 128 &&
- ssh_gssapi_check_mechanism(&gssctxt,
- &gss_supported->elements[mech], authctxt->host)) {
+ if (mech->length < 128 && ssh_gssapi_check_mechanism(&gssctxt,
+ mech, authctxt->host)) {
ok = 1; /* Mechanism works */
} else {
- mech++;
+ authctxt->mech_tried++;
}
}
- if (!ok)
+ if (!ok || mech == NULL)
return 0;
authctxt->methoddata=(void *)gssctxt;
@@ -715,27 +807,36 @@ userauth_gssapi(Authctxt *authctxt)
(r = sshpkt_put_cstring(ssh, authctxt->service)) != 0 ||
(r = sshpkt_put_cstring(ssh, authctxt->method->name)) != 0 ||
(r = sshpkt_put_u32(ssh, 1)) != 0 ||
- (r = sshpkt_put_u32(ssh,
- (gss_supported->elements[mech].length) + 2)) != 0 ||
+ (r = sshpkt_put_u32(ssh, (mech->length) + 2)) != 0 ||
(r = sshpkt_put_u8(ssh, SSH_GSS_OIDTYPE)) != 0 ||
- (r = sshpkt_put_u8(ssh,
- gss_supported->elements[mech].length)) != 0 ||
- (r = sshpkt_put(ssh,
- gss_supported->elements[mech].elements,
- gss_supported->elements[mech].length)) != 0 ||
+ (r = sshpkt_put_u8(ssh, mech->length)) != 0 ||
+ (r = sshpkt_put(ssh, mech->elements, mech->length)) != 0 ||
(r = sshpkt_send(ssh)) != 0)
- fatal("%s: %s", __func__, ssh_err(r));
+ fatal_fr(r, "send packet");
ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_GSSAPI_RESPONSE, &input_gssapi_response);
ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_GSSAPI_TOKEN, &input_gssapi_token);
ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_GSSAPI_ERROR, &input_gssapi_error);
ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_GSSAPI_ERRTOK, &input_gssapi_errtok);
- mech++; /* Move along to next candidate */
+ authctxt->mech_tried++; /* Move along to next candidate */
return 1;
}
+static void
+userauth_gssapi_cleanup(struct ssh *ssh)
+{
+ Authctxt *authctxt = (Authctxt *)ssh->authctxt;
+ Gssctxt *gssctxt = (Gssctxt *)authctxt->methoddata;
+
+ ssh_gssapi_delete_ctx(&gssctxt);
+ authctxt->methoddata = NULL;
+
+ free(authctxt->gss_supported_mechs);
+ authctxt->gss_supported_mechs = NULL;
+}
+
static OM_uint32
process_gssapi_token(struct ssh *ssh, gss_buffer_t recv_tok)
{
@@ -759,7 +860,7 @@ process_gssapi_token(struct ssh *ssh, gss_buffer_t recv_tok)
(r = sshpkt_put_string(ssh, send_tok.value,
send_tok.length)) != 0 ||
(r = sshpkt_send(ssh)) != 0)
- fatal("%s: %s", __func__, ssh_err(r));
+ fatal_fr(r, "send %u packet", type);
gss_release_buffer(&ms, &send_tok);
}
@@ -770,17 +871,18 @@ process_gssapi_token(struct ssh *ssh, gss_buffer_t recv_tok)
if ((r = sshpkt_start(ssh,
SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE)) != 0 ||
(r = sshpkt_send(ssh)) != 0)
- fatal("%s: %s", __func__, ssh_err(r));
+ fatal_fr(r, "send completion");
} else {
struct sshbuf *b;
if ((b = sshbuf_new()) == NULL)
- fatal("%s: sshbuf_new failed", __func__);
+ fatal_f("sshbuf_new failed");
ssh_gssapi_buildmic(b, authctxt->server_user,
- authctxt->service, "gssapi-with-mic");
+ authctxt->service, "gssapi-with-mic",
+ ssh->kex->session_id);
if ((gssbuf.value = sshbuf_mutable_ptr(b)) == NULL)
- fatal("%s: sshbuf_mutable_ptr failed", __func__);
+ fatal_f("sshbuf_mutable_ptr failed");
gssbuf.length = sshbuf_len(b);
status = ssh_gssapi_sign(gssctxt, &gssbuf, &mic);
@@ -791,7 +893,7 @@ process_gssapi_token(struct ssh *ssh, gss_buffer_t recv_tok)
(r = sshpkt_put_string(ssh, mic.value,
mic.length)) != 0 ||
(r = sshpkt_send(ssh)) != 0)
- fatal("%s: %s", __func__, ssh_err(r));
+ fatal_fr(r, "send MIC");
}
sshbuf_free(b);
@@ -803,7 +905,7 @@ process_gssapi_token(struct ssh *ssh, gss_buffer_t recv_tok)
}
/* ARGSUSED */
-int
+static int
input_gssapi_response(int type, u_int32_t plen, struct ssh *ssh)
{
Authctxt *authctxt = ssh->authctxt;
@@ -824,7 +926,7 @@ input_gssapi_response(int type, u_int32_t plen, struct ssh *ssh)
oidv[0] != SSH_GSS_OIDTYPE ||
oidv[1] != oidlen - 2) {
debug("Badly encoded mechanism OID received");
- userauth(authctxt, NULL);
+ userauth(ssh, NULL);
goto ok;
}
@@ -837,7 +939,7 @@ input_gssapi_response(int type, u_int32_t plen, struct ssh *ssh)
if (GSS_ERROR(process_gssapi_token(ssh, GSS_C_NO_BUFFER))) {
/* Start again with next method on list */
debug("Trying to start again");
- userauth(authctxt, NULL);
+ userauth(ssh, NULL);
goto ok;
}
ok:
@@ -848,7 +950,7 @@ input_gssapi_response(int type, u_int32_t plen, struct ssh *ssh)
}
/* ARGSUSED */
-int
+static int
input_gssapi_token(int type, u_int32_t plen, struct ssh *ssh)
{
Authctxt *authctxt = ssh->authctxt;
@@ -871,7 +973,7 @@ input_gssapi_token(int type, u_int32_t plen, struct ssh *ssh)
/* Start again with the next method in the list */
if (GSS_ERROR(status)) {
- userauth(authctxt, NULL);
+ userauth(ssh, NULL);
/* ok */
}
r = 0;
@@ -881,7 +983,7 @@ input_gssapi_token(int type, u_int32_t plen, struct ssh *ssh)
}
/* ARGSUSED */
-int
+static int
input_gssapi_errtok(int type, u_int32_t plen, struct ssh *ssh)
{
Authctxt *authctxt = ssh->authctxt;
@@ -916,7 +1018,7 @@ input_gssapi_errtok(int type, u_int32_t plen, struct ssh *ssh)
}
/* ARGSUSED */
-int
+static int
input_gssapi_error(int type, u_int32_t plen, struct ssh *ssh)
{
char *msg = NULL;
@@ -937,10 +1039,10 @@ input_gssapi_error(int type, u_int32_t plen, struct ssh *ssh)
}
#endif /* GSSAPI */
-int
-userauth_none(Authctxt *authctxt)
+static int
+userauth_none(struct ssh *ssh)
{
- struct ssh *ssh = active_state; /* XXX */
+ Authctxt *authctxt = (Authctxt *)ssh->authctxt;
int r;
/* initial userauth request */
@@ -949,29 +1051,26 @@ userauth_none(Authctxt *authctxt)
(r = sshpkt_put_cstring(ssh, authctxt->service)) != 0 ||
(r = sshpkt_put_cstring(ssh, authctxt->method->name)) != 0 ||
(r = sshpkt_send(ssh)) != 0)
- fatal("%s: %s", __func__, ssh_err(r));
+ fatal_fr(r, "send packet");
return 1;
}
-int
-userauth_passwd(Authctxt *authctxt)
+static int
+userauth_passwd(struct ssh *ssh)
{
- struct ssh *ssh = active_state; /* XXX */
- static int attempt = 0;
- char prompt[256];
- char *password;
+ Authctxt *authctxt = (Authctxt *)ssh->authctxt;
+ char *password, *prompt = NULL;
const char *host = options.host_key_alias ? options.host_key_alias :
authctxt->host;
int r;
- if (attempt++ >= options.number_of_password_prompts)
+ if (authctxt->attempt_passwd++ >= options.number_of_password_prompts)
return 0;
- if (attempt != 1)
+ if (authctxt->attempt_passwd != 1)
error("Permission denied, please try again.");
- snprintf(prompt, sizeof(prompt), "%.30s@%.128s's password: ",
- authctxt->server_user, host);
+ xasprintf(&prompt, "%s@%s's password: ", authctxt->server_user, host);
password = read_passphrase(prompt, 0);
if ((r = sshpkt_start(ssh, SSH2_MSG_USERAUTH_REQUEST)) != 0 ||
(r = sshpkt_put_cstring(ssh, authctxt->server_user)) != 0 ||
@@ -981,9 +1080,10 @@ userauth_passwd(Authctxt *authctxt)
(r = sshpkt_put_cstring(ssh, password)) != 0 ||
(r = sshpkt_add_padding(ssh, 64)) != 0 ||
(r = sshpkt_send(ssh)) != 0)
- fatal("%s: %s", __func__, ssh_err(r));
+ fatal_fr(r, "send packet");
- if (password)
+ free(prompt);
+ if (password != NULL)
freezero(password, strlen(password));
ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_PASSWD_CHANGEREQ,
@@ -996,7 +1096,7 @@ userauth_passwd(Authctxt *authctxt)
* parse PASSWD_CHANGEREQ, prompt user and send SSH2_MSG_USERAUTH_REQUEST
*/
/* ARGSUSED */
-int
+static int
input_userauth_passwd_changereq(int type, u_int32_t seqnr, struct ssh *ssh)
{
Authctxt *authctxt = ssh->authctxt;
@@ -1081,6 +1181,7 @@ static char *
key_sig_algorithm(struct ssh *ssh, const struct sshkey *key)
{
char *allowed, *oallowed, *cp, *tmp, *alg = NULL;
+ const char *server_sig_algs;
/*
* The signature algorithm will only differ from the key algorithm
@@ -1089,23 +1190,32 @@ key_sig_algorithm(struct ssh *ssh, const struct sshkey *key)
*/
if (ssh == NULL || ssh->kex->server_sig_algs == NULL ||
(key->type != KEY_RSA && key->type != KEY_RSA_CERT) ||
- (key->type == KEY_RSA_CERT && (datafellows & SSH_BUG_SIGTYPE))) {
+ (key->type == KEY_RSA_CERT && (ssh->compat & SSH_BUG_SIGTYPE))) {
/* Filter base key signature alg against our configuration */
return match_list(sshkey_ssh_name(key),
- options.pubkey_key_types, NULL);
+ options.pubkey_accepted_algos, NULL);
}
/*
+ * Workaround OpenSSH 7.4 bug: this version supports RSA/SHA-2 but
+ * fails to advertise it via SSH2_MSG_EXT_INFO.
+ */
+ server_sig_algs = ssh->kex->server_sig_algs;
+ if (key->type == KEY_RSA && (ssh->compat & SSH_BUG_SIGTYPE74))
+ server_sig_algs = "rsa-sha2-256,rsa-sha2-512";
+
+ /*
* For RSA keys/certs, since these might have a different sig type:
- * find the first entry in PubkeyAcceptedKeyTypes of the right type
+ * find the first entry in PubkeyAcceptedAlgorithms of the right type
* that also appears in the supported signature algorithms list from
* the server.
*/
- oallowed = allowed = xstrdup(options.pubkey_key_types);
+ oallowed = allowed = xstrdup(options.pubkey_accepted_algos);
while ((cp = strsep(&allowed, ",")) != NULL) {
if (sshkey_type_from_name(cp) != key->type)
continue;
- tmp = match_list(sshkey_sigalg_by_name(cp), ssh->kex->server_sig_algs, NULL);
+ tmp = match_list(sshkey_sigalg_by_name(cp),
+ server_sig_algs, NULL);
if (tmp != NULL)
alg = xstrdup(cp);
free(tmp);
@@ -1120,8 +1230,13 @@ static int
identity_sign(struct identity *id, u_char **sigp, size_t *lenp,
const u_char *data, size_t datalen, u_int compat, const char *alg)
{
- struct sshkey *prv;
- int r;
+ struct sshkey *sign_key = NULL, *prv = NULL;
+ int retried = 0, r = SSH_ERR_INTERNAL_ERROR;
+ struct notifier_ctx *notifier = NULL;
+ char *fp = NULL, *pin = NULL, *prompt = NULL;
+
+ *sigp = NULL;
+ *lenp = 0;
/* The agent supports this key. */
if (id->key != NULL && id->agent_fd != -1) {
@@ -1135,27 +1250,67 @@ identity_sign(struct identity *id, u_char **sigp, size_t *lenp,
*/
if (id->key != NULL &&
(id->isprivate || (id->key->flags & SSHKEY_FLAG_EXT))) {
- if ((r = sshkey_sign(id->key, sigp, lenp, data, datalen,
- alg, compat)) != 0)
- return r;
- /*
- * PKCS#11 tokens may not support all signature algorithms,
- * so check what we get back.
- */
- if ((r = sshkey_check_sigtype(*sigp, *lenp, alg)) != 0)
- return r;
- return 0;
+ sign_key = id->key;
+ } else {
+ /* Load the private key from the file. */
+ if ((prv = load_identity_file(id)) == NULL)
+ return SSH_ERR_KEY_NOT_FOUND;
+ if (id->key != NULL && !sshkey_equal_public(prv, id->key)) {
+ error_f("private key %s contents do not match public",
+ id->filename);
+ r = SSH_ERR_KEY_NOT_FOUND;
+ goto out;
+ }
+ sign_key = prv;
+ if (sshkey_is_sk(sign_key)) {
+ if ((sign_key->sk_flags &
+ SSH_SK_USER_VERIFICATION_REQD)) {
+ retry_pin:
+ xasprintf(&prompt, "Enter PIN for %s key %s: ",
+ sshkey_type(sign_key), id->filename);
+ pin = read_passphrase(prompt, 0);
+ }
+ if ((sign_key->sk_flags & SSH_SK_USER_PRESENCE_REQD)) {
+ /* XXX should batch mode just skip these? */
+ if ((fp = sshkey_fingerprint(sign_key,
+ options.fingerprint_hash,
+ SSH_FP_DEFAULT)) == NULL)
+ fatal_f("fingerprint failed");
+ notifier = notify_start(options.batch_mode,
+ "Confirm user presence for key %s %s",
+ sshkey_type(sign_key), fp);
+ free(fp);
+ }
+ }
+ }
+ if ((r = sshkey_sign(sign_key, sigp, lenp, data, datalen,
+ alg, options.sk_provider, pin, compat)) != 0) {
+ debug_fr(r, "sshkey_sign");
+ if (pin == NULL && !retried && sshkey_is_sk(sign_key) &&
+ r == SSH_ERR_KEY_WRONG_PASSPHRASE) {
+ notify_complete(notifier, NULL);
+ notifier = NULL;
+ retried = 1;
+ goto retry_pin;
+ }
+ goto out;
}
- /* Load the private key from the file. */
- if ((prv = load_identity_file(id)) == NULL)
- return SSH_ERR_KEY_NOT_FOUND;
- if (id->key != NULL && !sshkey_equal_public(prv, id->key)) {
- error("%s: private key %s contents do not match public",
- __func__, id->filename);
- return SSH_ERR_KEY_NOT_FOUND;
+ /*
+ * PKCS#11 tokens may not support all signature algorithms,
+ * so check what we get back.
+ */
+ if ((r = sshkey_check_sigtype(*sigp, *lenp, alg)) != 0) {
+ debug_fr(r, "sshkey_check_sigtype");
+ goto out;
}
- r = sshkey_sign(prv, sigp, lenp, data, datalen, alg, compat);
+ /* success */
+ r = 0;
+ out:
+ free(prompt);
+ if (pin != NULL)
+ freezero(pin, strlen(pin));
+ notify_complete(notifier, r == 0 ? "User presence confirmed" : NULL);
sshkey_free(prv);
return r;
}
@@ -1180,8 +1335,9 @@ id_filename_matches(Identity *id, Identity *private_id)
}
static int
-sign_and_send_pubkey(struct ssh *ssh, Authctxt *authctxt, Identity *id)
+sign_and_send_pubkey(struct ssh *ssh, Identity *id)
{
+ Authctxt *authctxt = (Authctxt *)ssh->authctxt;
struct sshbuf *b = NULL;
Identity *private_id, *sign_id = NULL;
u_char *signature = NULL;
@@ -1194,7 +1350,7 @@ sign_and_send_pubkey(struct ssh *ssh, Authctxt *authctxt, Identity *id)
SSH_FP_DEFAULT)) == NULL)
return 0;
- debug3("%s: %s %s", __func__, sshkey_type(id->key), fp);
+ debug3_f("%s %s", sshkey_type(id->key), fp);
/*
* If the key is an certificate, try to find a matching private key
@@ -1231,12 +1387,12 @@ sign_and_send_pubkey(struct ssh *ssh, Authctxt *authctxt, Identity *id)
}
}
if (sign_id != NULL) {
- debug2("%s: using private key \"%s\"%s for "
- "certificate", __func__, id->filename,
- id->agent_fd != -1 ? " from agent" : "");
+ debug2_f("using private key \"%s\"%s for "
+ "certificate", sign_id->filename,
+ sign_id->agent_fd != -1 ? " from agent" : "");
} else {
- debug("%s: no separate private key for certificate "
- "\"%s\"", __func__, id->filename);
+ debug_f("no separate private key for certificate "
+ "\"%s\"", id->filename);
}
}
@@ -1254,26 +1410,21 @@ sign_and_send_pubkey(struct ssh *ssh, Authctxt *authctxt, Identity *id)
signature = NULL;
if ((alg = key_sig_algorithm(fallback_sigtype ? NULL : ssh,
id->key)) == NULL) {
- error("%s: no mutual signature supported", __func__);
+ error_f("no mutual signature supported");
goto out;
}
- debug3("%s: signing using %s", __func__, alg);
+ debug3_f("signing using %s %s", alg, fp);
sshbuf_free(b);
if ((b = sshbuf_new()) == NULL)
- fatal("%s: sshbuf_new failed", __func__);
- if (datafellows & SSH_OLD_SESSIONID) {
- if ((r = sshbuf_put(b, session_id2,
- session_id2_len)) != 0) {
- fatal("%s: sshbuf_put: %s",
- __func__, ssh_err(r));
- }
+ fatal_f("sshbuf_new failed");
+ if (ssh->compat & SSH_OLD_SESSIONID) {
+ if ((r = sshbuf_putb(b, ssh->kex->session_id)) != 0)
+ fatal_fr(r, "sshbuf_putb");
} else {
- if ((r = sshbuf_put_string(b, session_id2,
- session_id2_len)) != 0) {
- fatal("%s: sshbuf_put_string: %s",
- __func__, ssh_err(r));
- }
+ if ((r = sshbuf_put_stringb(b,
+ ssh->kex->session_id)) != 0)
+ fatal_fr(r, "sshbuf_put_stringb");
}
skip = sshbuf_len(b);
if ((r = sshbuf_put_u8(b, SSH2_MSG_USERAUTH_REQUEST)) != 0 ||
@@ -1283,13 +1434,12 @@ sign_and_send_pubkey(struct ssh *ssh, Authctxt *authctxt, Identity *id)
(r = sshbuf_put_u8(b, 1)) != 0 ||
(r = sshbuf_put_cstring(b, alg)) != 0 ||
(r = sshkey_puts(id->key, b)) != 0) {
- fatal("%s: assemble signed data: %s",
- __func__, ssh_err(r));
+ fatal_fr(r, "assemble signed data");
}
/* generate signature */
r = identity_sign(sign_id, &signature, &slen,
- sshbuf_ptr(b), sshbuf_len(b), datafellows, alg);
+ sshbuf_ptr(b), sshbuf_len(b), ssh->compat, alg);
if (r == 0)
break;
else if (r == SSH_ERR_KEY_NOT_FOUND)
@@ -1304,28 +1454,30 @@ sign_and_send_pubkey(struct ssh *ssh, Authctxt *authctxt, Identity *id)
loc, sshkey_type(id->key), fp);
continue;
}
- error("%s: signing failed: %s", __func__, ssh_err(r));
+ error_fr(r, "signing failed for %s \"%s\"%s",
+ sshkey_type(sign_id->key), sign_id->filename,
+ id->agent_fd != -1 ? " from agent" : "");
goto out;
}
if (slen == 0 || signature == NULL) /* shouldn't happen */
- fatal("%s: no signature", __func__);
+ fatal_f("no signature");
/* append signature */
if ((r = sshbuf_put_string(b, signature, slen)) != 0)
- fatal("%s: append signature: %s", __func__, ssh_err(r));
+ fatal_fr(r, "append signature");
#ifdef DEBUG_PK
sshbuf_dump(b, stderr);
#endif
/* skip session id and packet type */
if ((r = sshbuf_consume(b, skip + 1)) != 0)
- fatal("%s: consume: %s", __func__, ssh_err(r));
+ fatal_fr(r, "consume");
/* put remaining data from buffer into packet */
if ((r = sshpkt_start(ssh, SSH2_MSG_USERAUTH_REQUEST)) != 0 ||
(r = sshpkt_putb(ssh, b)) != 0 ||
(r = sshpkt_send(ssh)) != 0)
- fatal("%s: enqueue request: %s", __func__, ssh_err(r));
+ fatal_fr(r, "enqueue request");
/* success */
sent = 1;
@@ -1339,8 +1491,9 @@ sign_and_send_pubkey(struct ssh *ssh, Authctxt *authctxt, Identity *id)
}
static int
-send_pubkey_test(struct ssh *ssh, Authctxt *authctxt, Identity *id)
+send_pubkey_test(struct ssh *ssh, Identity *id)
{
+ Authctxt *authctxt = (Authctxt *)ssh->authctxt;
u_char *blob = NULL;
char *alg = NULL;
size_t bloblen;
@@ -1348,13 +1501,13 @@ send_pubkey_test(struct ssh *ssh, Authctxt *authctxt, Identity *id)
int sent = 0, r;
if ((alg = key_sig_algorithm(ssh, id->key)) == NULL) {
- debug("%s: no mutual signature algorithm", __func__);
+ debug_f("no mutual signature algorithm");
goto out;
}
if ((r = sshkey_to_blob(id->key, &blob, &bloblen)) != 0) {
/* we cannot handle this key */
- debug3("%s: cannot handle key", __func__);
+ debug3_f("cannot handle key");
goto out;
}
/* register callback for USERAUTH_PK_OK message */
@@ -1368,7 +1521,7 @@ send_pubkey_test(struct ssh *ssh, Authctxt *authctxt, Identity *id)
(r = sshpkt_put_cstring(ssh, alg)) != 0 ||
(r = sshpkt_put_string(ssh, blob, bloblen)) != 0 ||
(r = sshpkt_send(ssh)) != 0)
- fatal("%s: %s", __func__, ssh_err(r));
+ fatal_fr(r, "send packet");
sent = 1;
out:
@@ -1382,12 +1535,13 @@ load_identity_file(Identity *id)
{
struct sshkey *private = NULL;
char prompt[300], *passphrase, *comment;
- int r, perm_ok = 0, quit = 0, i;
+ int r, quit = 0, i;
struct stat st;
- if (stat(id->filename, &st) < 0) {
- (id->userprovided ? logit : debug3)("no such identity: %s: %s",
- id->filename, strerror(errno));
+ if (stat(id->filename, &st) == -1) {
+ do_log2(id->userprovided ?
+ SYSLOG_LEVEL_INFO : SYSLOG_LEVEL_DEBUG3,
+ "no such identity: %s: %s", id->filename, strerror(errno));
return NULL;
}
snprintf(prompt, sizeof prompt,
@@ -1404,7 +1558,7 @@ load_identity_file(Identity *id)
}
}
switch ((r = sshkey_load_private_type(KEY_UNSPEC, id->filename,
- passphrase, &private, &comment, &perm_ok))) {
+ passphrase, &private, &comment))) {
case 0:
break;
case SSH_ERR_KEY_WRONG_PASSPHRASE:
@@ -1417,17 +1571,24 @@ load_identity_file(Identity *id)
break;
case SSH_ERR_SYSTEM_ERROR:
if (errno == ENOENT) {
- debug2("Load key \"%s\": %s",
- id->filename, ssh_err(r));
+ debug2_r(r, "Load key \"%s\"", id->filename);
quit = 1;
break;
}
/* FALLTHROUGH */
default:
- error("Load key \"%s\": %s", id->filename, ssh_err(r));
+ error_r(r, "Load key \"%s\"", id->filename);
quit = 1;
break;
}
+ if (private != NULL && sshkey_is_sk(private) &&
+ options.sk_provider == NULL) {
+ debug("key \"%s\" is an authenticator-hosted key, "
+ "but no provider specified", id->filename);
+ sshkey_free(private);
+ private = NULL;
+ quit = 1;
+ }
if (!quit && private != NULL && id->agent_fd == -1 &&
!(id->key && id->isprivate))
maybe_add_key_to_agent(id->filename, private, comment,
@@ -1445,25 +1606,25 @@ static int
key_type_allowed_by_config(struct sshkey *key)
{
if (match_pattern_list(sshkey_ssh_name(key),
- options.pubkey_key_types, 0) == 1)
+ options.pubkey_accepted_algos, 0) == 1)
return 1;
/* RSA keys/certs might be allowed by alternate signature types */
switch (key->type) {
case KEY_RSA:
if (match_pattern_list("rsa-sha2-512",
- options.pubkey_key_types, 0) == 1)
+ options.pubkey_accepted_algos, 0) == 1)
return 1;
if (match_pattern_list("rsa-sha2-256",
- options.pubkey_key_types, 0) == 1)
+ options.pubkey_accepted_algos, 0) == 1)
return 1;
break;
case KEY_RSA_CERT:
if (match_pattern_list("rsa-sha2-512-cert-v01@openssh.com",
- options.pubkey_key_types, 0) == 1)
+ options.pubkey_accepted_algos, 0) == 1)
return 1;
if (match_pattern_list("rsa-sha2-256-cert-v01@openssh.com",
- options.pubkey_key_types, 0) == 1)
+ options.pubkey_accepted_algos, 0) == 1)
return 1;
break;
}
@@ -1473,8 +1634,8 @@ key_type_allowed_by_config(struct sshkey *key)
/*
* try keys in the following order:
- * 1. certificates listed in the config file
- * 2. other input certificates
+ * 1. certificates listed in the config file
+ * 2. other input certificates
* 3. agent keys that are found in the config file
* 4. other agent keys
* 5. keys that are only listed in the config file
@@ -1498,8 +1659,18 @@ pubkey_prepare(Authctxt *authctxt)
/* list of keys stored in the filesystem and PKCS#11 */
for (i = 0; i < options.num_identity_files; i++) {
key = options.identity_keys[i];
- if (key && key->cert && key->cert->type != SSH2_CERT_TYPE_USER)
+ if (key && key->cert &&
+ key->cert->type != SSH2_CERT_TYPE_USER) {
+ debug_f("ignoring certificate %s: not a user "
+ "certificate", options.identity_files[i]);
continue;
+ }
+ if (key && sshkey_is_sk(key) && options.sk_provider == NULL) {
+ debug_f("ignoring authenticator-hosted key %s as no "
+ "SecurityKeyProvider has been specified",
+ options.identity_files[i]);
+ continue;
+ }
options.identity_keys[i] = NULL;
id = xcalloc(1, sizeof(*id));
id->agent_fd = -1;
@@ -1512,8 +1683,18 @@ pubkey_prepare(Authctxt *authctxt)
for (i = 0; i < options.num_certificate_files; i++) {
key = options.certificates[i];
if (!sshkey_is_cert(key) || key->cert == NULL ||
- key->cert->type != SSH2_CERT_TYPE_USER)
+ key->cert->type != SSH2_CERT_TYPE_USER) {
+ debug_f("ignoring certificate %s: not a user "
+ "certificate", options.identity_files[i]);
+ continue;
+ }
+ if (key && sshkey_is_sk(key) && options.sk_provider == NULL) {
+ debug_f("ignoring authenticator-hosted key "
+ "certificate %s as no "
+ "SecurityKeyProvider has been specified",
+ options.identity_files[i]);
continue;
+ }
id = xcalloc(1, sizeof(*id));
id->agent_fd = -1;
id->key = key;
@@ -1524,12 +1705,10 @@ pubkey_prepare(Authctxt *authctxt)
/* list of keys supported by the agent */
if ((r = ssh_get_authentication_socket(&agent_fd)) != 0) {
if (r != SSH_ERR_AGENT_NOT_PRESENT)
- debug("%s: ssh_get_authentication_socket: %s",
- __func__, ssh_err(r));
+ debug_fr(r, "ssh_get_authentication_socket");
} else if ((r = ssh_fetch_identitylist(agent_fd, &idlist)) != 0) {
if (r != SSH_ERR_AGENT_NO_IDENTITIES)
- debug("%s: ssh_fetch_identitylist: %s",
- __func__, ssh_err(r));
+ debug_fr(r, "ssh_fetch_identitylist");
close(agent_fd);
} else {
for (j = 0; j < idlist->nkeys; j++) {
@@ -1560,10 +1739,7 @@ pubkey_prepare(Authctxt *authctxt)
}
ssh_free_identitylist(idlist);
/* append remaining agent keys */
- for (id = TAILQ_FIRST(&agent); id; id = TAILQ_FIRST(&agent)) {
- TAILQ_REMOVE(&agent, id, next);
- TAILQ_INSERT_TAIL(preferred, id, next);
- }
+ TAILQ_CONCAT(preferred, &agent, next);
authctxt->agent_fd = agent_fd;
}
/* Prefer PKCS11 keys that are explicitly listed */
@@ -1573,7 +1749,7 @@ pubkey_prepare(Authctxt *authctxt)
found = 0;
TAILQ_FOREACH(id2, &files, next) {
if (id2->key == NULL ||
- (id2->key->flags & SSHKEY_FLAG_EXT) == 0)
+ (id2->key->flags & SSHKEY_FLAG_EXT) != 0)
continue;
if (sshkey_equal(id->key, id2->key)) {
TAILQ_REMOVE(&files, id, next);
@@ -1589,15 +1765,12 @@ pubkey_prepare(Authctxt *authctxt)
}
}
/* append remaining keys from the config file */
- for (id = TAILQ_FIRST(&files); id; id = TAILQ_FIRST(&files)) {
- TAILQ_REMOVE(&files, id, next);
- TAILQ_INSERT_TAIL(preferred, id, next);
- }
- /* finally, filter by PubkeyAcceptedKeyTypes */
+ TAILQ_CONCAT(preferred, &files, next);
+ /* finally, filter by PubkeyAcceptedAlgorithms */
TAILQ_FOREACH_SAFE(id, preferred, next, id2) {
if (id->key != NULL && !key_type_allowed_by_config(id->key)) {
debug("Skipping %s key %s - "
- "not in PubkeyAcceptedKeyTypes",
+ "corresponding algo not in PubkeyAcceptedAlgorithms",
sshkey_ssh_name(id->key), id->filename);
TAILQ_REMOVE(preferred, id, next);
sshkey_free(id->key);
@@ -1612,16 +1785,19 @@ pubkey_prepare(Authctxt *authctxt)
debug("Will attempt key: %s", ident);
free(ident);
}
- debug2("%s: done", __func__);
+ debug2_f("done");
}
static void
-pubkey_cleanup(Authctxt *authctxt)
+pubkey_cleanup(struct ssh *ssh)
{
+ Authctxt *authctxt = (Authctxt *)ssh->authctxt;
Identity *id;
- if (authctxt->agent_fd != -1)
+ if (authctxt->agent_fd != -1) {
ssh_close_authentication_socket(authctxt->agent_fd);
+ authctxt->agent_fd = -1;
+ }
for (id = TAILQ_FIRST(&authctxt->keys); id;
id = TAILQ_FIRST(&authctxt->keys)) {
TAILQ_REMOVE(&authctxt->keys, id, next);
@@ -1641,12 +1817,12 @@ pubkey_reset(Authctxt *authctxt)
}
static int
-try_identity(Identity *id)
+try_identity(struct ssh *ssh, Identity *id)
{
if (!id->key)
return (0);
if (sshkey_type_plain(id->key->type) == KEY_RSA &&
- (datafellows & SSH_BUG_RSASIGMD5) != 0) {
+ (ssh->compat & SSH_BUG_RSASIGMD5) != 0) {
debug("Skipped %s key %s for RSA/MD5 server",
sshkey_type(id->key), id->filename);
return (0);
@@ -1654,10 +1830,10 @@ try_identity(Identity *id)
return 1;
}
-int
-userauth_pubkey(Authctxt *authctxt)
+static int
+userauth_pubkey(struct ssh *ssh)
{
- struct ssh *ssh = active_state; /* XXX */
+ Authctxt *authctxt = (Authctxt *)ssh->authctxt;
Identity *id;
int sent = 0;
char *ident;
@@ -1674,20 +1850,19 @@ userauth_pubkey(Authctxt *authctxt)
* private key instead
*/
if (id->key != NULL) {
- if (try_identity(id)) {
+ if (try_identity(ssh, id)) {
ident = format_identity(id);
debug("Offering public key: %s", ident);
free(ident);
- sent = send_pubkey_test(ssh, authctxt, id);
+ sent = send_pubkey_test(ssh, id);
}
} else {
debug("Trying private key: %s", id->filename);
id->key = load_identity_file(id);
if (id->key != NULL) {
- if (try_identity(id)) {
+ if (try_identity(ssh, id)) {
id->isprivate = 1;
- sent = sign_and_send_pubkey(ssh,
- authctxt, id);
+ sent = sign_and_send_pubkey(ssh, id);
}
sshkey_free(id->key);
id->key = NULL;
@@ -1703,17 +1878,16 @@ userauth_pubkey(Authctxt *authctxt)
/*
* Send userauth request message specifying keyboard-interactive method.
*/
-int
-userauth_kbdint(Authctxt *authctxt)
+static int
+userauth_kbdint(struct ssh *ssh)
{
- struct ssh *ssh = active_state; /* XXX */
- static int attempt = 0;
+ Authctxt *authctxt = (Authctxt *)ssh->authctxt;
int r;
- if (attempt++ >= options.number_of_password_prompts)
+ if (authctxt->attempt_kbdint++ >= options.number_of_password_prompts)
return 0;
/* disable if no SSH2_MSG_USERAUTH_INFO_REQUEST has been seen */
- if (attempt > 1 && !authctxt->info_req_seen) {
+ if (authctxt->attempt_kbdint > 1 && !authctxt->info_req_seen) {
debug3("userauth_kbdint: disable: no info_req_seen");
ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_INFO_REQUEST, NULL);
return 0;
@@ -1728,7 +1902,7 @@ userauth_kbdint(Authctxt *authctxt)
(r = sshpkt_put_cstring(ssh, options.kbd_interactive_devices ?
options.kbd_interactive_devices : "")) != 0 ||
(r = sshpkt_send(ssh)) != 0)
- fatal("%s: %s", __func__, ssh_err(r));
+ fatal_fr(r, "send packet");
ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_INFO_REQUEST, &input_userauth_info_req);
return 1;
@@ -1737,20 +1911,20 @@ userauth_kbdint(Authctxt *authctxt)
/*
* parse INFO_REQUEST, prompt user and send INFO_RESPONSE
*/
-int
+static int
input_userauth_info_req(int type, u_int32_t seq, struct ssh *ssh)
{
Authctxt *authctxt = ssh->authctxt;
char *name = NULL, *inst = NULL, *lang = NULL, *prompt = NULL;
- char *response = NULL;
+ char *display_prompt = NULL, *response = NULL;
u_char echo = 0;
u_int num_prompts, i;
int r;
- debug2("input_userauth_info_req");
+ debug2_f("entering");
if (authctxt == NULL)
- fatal("input_userauth_info_req: no authentication context");
+ fatal_f("no authentication context");
authctxt->info_req_seen = 1;
@@ -1775,17 +1949,22 @@ input_userauth_info_req(int type, u_int32_t seq, struct ssh *ssh)
(r = sshpkt_put_u32(ssh, num_prompts)) != 0)
goto out;
- debug2("input_userauth_info_req: num_prompts %d", num_prompts);
+ debug2_f("num_prompts %d", num_prompts);
for (i = 0; i < num_prompts; i++) {
if ((r = sshpkt_get_cstring(ssh, &prompt, NULL)) != 0 ||
(r = sshpkt_get_u8(ssh, &echo)) != 0)
goto out;
- response = read_passphrase(prompt, echo ? RP_ECHO : 0);
+ if (asmprintf(&display_prompt, INT_MAX, NULL, "(%s@%s) %s",
+ authctxt->server_user, options.host_key_alias ?
+ options.host_key_alias : authctxt->host, prompt) == -1)
+ fatal_f("asmprintf failed");
+ response = read_passphrase(display_prompt, echo ? RP_ECHO : 0);
if ((r = sshpkt_put_cstring(ssh, response)) != 0)
goto out;
freezero(response, strlen(response));
free(prompt);
- response = prompt = NULL;
+ free(display_prompt);
+ display_prompt = response = prompt = NULL;
}
/* done with parsing incoming message. */
if ((r = sshpkt_get_end(ssh)) != 0 ||
@@ -1796,6 +1975,7 @@ input_userauth_info_req(int type, u_int32_t seq, struct ssh *ssh)
if (response)
freezero(response, strlen(response));
free(prompt);
+ free(display_prompt);
free(name);
free(inst);
free(lang);
@@ -1803,123 +1983,124 @@ input_userauth_info_req(int type, u_int32_t seq, struct ssh *ssh)
}
static int
-ssh_keysign(struct sshkey *key, u_char **sigp, size_t *lenp,
+ssh_keysign(struct ssh *ssh, struct sshkey *key, u_char **sigp, size_t *lenp,
const u_char *data, size_t datalen)
{
struct sshbuf *b;
struct stat st;
pid_t pid;
- int i, r, to[2], from[2], status, sock = packet_get_connection_in();
+ int r, to[2], from[2], status;
+ int sock = ssh_packet_get_connection_in(ssh);
u_char rversion = 0, version = 2;
void (*osigchld)(int);
*sigp = NULL;
*lenp = 0;
- if (stat(_PATH_SSH_KEY_SIGN, &st) < 0) {
- error("%s: not installed: %s", __func__, strerror(errno));
+ if (stat(_PATH_SSH_KEY_SIGN, &st) == -1) {
+ error_f("not installed: %s", strerror(errno));
return -1;
}
if (fflush(stdout) != 0) {
- error("%s: fflush: %s", __func__, strerror(errno));
+ error_f("fflush: %s", strerror(errno));
return -1;
}
- if (pipe(to) < 0) {
- error("%s: pipe: %s", __func__, strerror(errno));
+ if (pipe(to) == -1) {
+ error_f("pipe: %s", strerror(errno));
return -1;
}
- if (pipe(from) < 0) {
- error("%s: pipe: %s", __func__, strerror(errno));
+ if (pipe(from) == -1) {
+ error_f("pipe: %s", strerror(errno));
return -1;
}
- if ((pid = fork()) < 0) {
- error("%s: fork: %s", __func__, strerror(errno));
+ if ((pid = fork()) == -1) {
+ error_f("fork: %s", strerror(errno));
return -1;
}
- osigchld = signal(SIGCHLD, SIG_DFL);
+ osigchld = ssh_signal(SIGCHLD, SIG_DFL);
if (pid == 0) {
- /* keep the socket on exec */
- fcntl(sock, F_SETFD, 0);
close(from[0]);
- if (dup2(from[1], STDOUT_FILENO) < 0)
- fatal("%s: dup2: %s", __func__, strerror(errno));
+ if (dup2(from[1], STDOUT_FILENO) == -1)
+ fatal_f("dup2: %s", strerror(errno));
close(to[1]);
- if (dup2(to[0], STDIN_FILENO) < 0)
- fatal("%s: dup2: %s", __func__, strerror(errno));
+ if (dup2(to[0], STDIN_FILENO) == -1)
+ fatal_f("dup2: %s", strerror(errno));
close(from[1]);
close(to[0]);
- /* Close everything but stdio and the socket */
- for (i = STDERR_FILENO + 1; i < sock; i++)
- close(i);
+
+ if (dup2(sock, STDERR_FILENO + 1) == -1)
+ fatal_f("dup2: %s", strerror(errno));
+ sock = STDERR_FILENO + 1;
+ fcntl(sock, F_SETFD, 0); /* keep the socket on exec */
closefrom(sock + 1);
- debug3("%s: [child] pid=%ld, exec %s",
- __func__, (long)getpid(), _PATH_SSH_KEY_SIGN);
+
+ debug3_f("[child] pid=%ld, exec %s",
+ (long)getpid(), _PATH_SSH_KEY_SIGN);
execl(_PATH_SSH_KEY_SIGN, _PATH_SSH_KEY_SIGN, (char *)NULL);
- fatal("%s: exec(%s): %s", __func__, _PATH_SSH_KEY_SIGN,
+ fatal_f("exec(%s): %s", _PATH_SSH_KEY_SIGN,
strerror(errno));
}
close(from[1]);
close(to[0]);
+ sock = STDERR_FILENO + 1;
if ((b = sshbuf_new()) == NULL)
- fatal("%s: sshbuf_new failed", __func__);
+ fatal_f("sshbuf_new failed");
/* send # of sock, data to be signed */
if ((r = sshbuf_put_u32(b, sock)) != 0 ||
(r = sshbuf_put_string(b, data, datalen)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "buffer error");
if (ssh_msg_send(to[1], version, b) == -1)
- fatal("%s: couldn't send request", __func__);
+ fatal_f("couldn't send request");
sshbuf_reset(b);
r = ssh_msg_recv(from[0], b);
close(from[0]);
close(to[1]);
if (r < 0) {
- error("%s: no reply", __func__);
+ error_f("no reply");
goto fail;
}
errno = 0;
- while (waitpid(pid, &status, 0) < 0) {
+ while (waitpid(pid, &status, 0) == -1) {
if (errno != EINTR) {
- error("%s: waitpid %ld: %s",
- __func__, (long)pid, strerror(errno));
+ error_f("waitpid %ld: %s", (long)pid, strerror(errno));
goto fail;
}
}
if (!WIFEXITED(status)) {
- error("%s: exited abnormally", __func__);
+ error_f("exited abnormally");
goto fail;
}
if (WEXITSTATUS(status) != 0) {
- error("%s: exited with status %d",
- __func__, WEXITSTATUS(status));
+ error_f("exited with status %d", WEXITSTATUS(status));
goto fail;
}
if ((r = sshbuf_get_u8(b, &rversion)) != 0) {
- error("%s: buffer error: %s", __func__, ssh_err(r));
+ error_fr(r, "buffer error");
goto fail;
}
if (rversion != version) {
- error("%s: bad version", __func__);
+ error_f("bad version");
goto fail;
}
if ((r = sshbuf_get_string(b, sigp, lenp)) != 0) {
- error("%s: buffer error: %s", __func__, ssh_err(r));
+ error_fr(r, "buffer error");
fail:
- signal(SIGCHLD, osigchld);
+ ssh_signal(SIGCHLD, osigchld);
sshbuf_free(b);
return -1;
}
- signal(SIGCHLD, osigchld);
+ ssh_signal(SIGCHLD, osigchld);
sshbuf_free(b);
return 0;
}
-int
-userauth_hostbased(Authctxt *authctxt)
+static int
+userauth_hostbased(struct ssh *ssh)
{
- struct ssh *ssh = active_state; /* XXX */
+ Authctxt *authctxt = (Authctxt *)ssh->authctxt;
struct sshkey *private = NULL;
struct sshbuf *b = NULL;
u_char *sig = NULL, *keyblob = NULL;
@@ -1928,12 +2109,12 @@ userauth_hostbased(Authctxt *authctxt)
int i, r, success = 0;
if (authctxt->ktypes == NULL) {
- authctxt->oktypes = xstrdup(options.hostbased_key_types);
+ authctxt->oktypes = xstrdup(options.hostbased_accepted_algos);
authctxt->ktypes = authctxt->oktypes;
}
/*
- * Work through each listed type pattern in HostbasedKeyTypes,
+ * Work through each listed type pattern in HostbasedAcceptedAlgorithms,
* trying each hostkey that matches the type in turn.
*/
for (;;) {
@@ -1942,8 +2123,7 @@ userauth_hostbased(Authctxt *authctxt)
if (authctxt->active_ktype == NULL ||
*authctxt->active_ktype == '\0')
break;
- debug3("%s: trying key type %s", __func__,
- authctxt->active_ktype);
+ debug3_f("trying key type %s", authctxt->active_ktype);
/* check for a useful key */
private = NULL;
@@ -1976,50 +2156,49 @@ userauth_hostbased(Authctxt *authctxt)
if ((fp = sshkey_fingerprint(private, options.fingerprint_hash,
SSH_FP_DEFAULT)) == NULL) {
- error("%s: sshkey_fingerprint failed", __func__);
+ error_f("sshkey_fingerprint failed");
goto out;
}
- debug("%s: trying hostkey %s %s",
- __func__, sshkey_ssh_name(private), fp);
+ debug_f("trying hostkey %s %s", sshkey_ssh_name(private), fp);
/* figure out a name for the client host */
- if ((lname = get_local_name(packet_get_connection_in())) == NULL) {
- error("%s: cannot get local ipaddr/name", __func__);
+ lname = get_local_name(ssh_packet_get_connection_in(ssh));
+ if (lname == NULL) {
+ error_f("cannot get local ipaddr/name");
goto out;
}
/* XXX sshbuf_put_stringf? */
xasprintf(&chost, "%s.", lname);
- debug2("%s: chost %s", __func__, chost);
+ debug2_f("chost %s", chost);
/* construct data */
if ((b = sshbuf_new()) == NULL) {
- error("%s: sshbuf_new failed", __func__);
+ error_f("sshbuf_new failed");
goto out;
}
if ((r = sshkey_to_blob(private, &keyblob, &keylen)) != 0) {
- error("%s: sshkey_to_blob: %s", __func__, ssh_err(r));
+ error_fr(r, "sshkey_to_blob");
goto out;
}
- if ((r = sshbuf_put_string(b, session_id2, session_id2_len)) != 0 ||
+ if ((r = sshbuf_put_stringb(b, ssh->kex->session_id)) != 0 ||
(r = sshbuf_put_u8(b, SSH2_MSG_USERAUTH_REQUEST)) != 0 ||
(r = sshbuf_put_cstring(b, authctxt->server_user)) != 0 ||
(r = sshbuf_put_cstring(b, authctxt->service)) != 0 ||
(r = sshbuf_put_cstring(b, authctxt->method->name)) != 0 ||
- (r = sshbuf_put_cstring(b, sshkey_ssh_name(private))) != 0 ||
+ (r = sshbuf_put_cstring(b, authctxt->active_ktype)) != 0 ||
(r = sshbuf_put_string(b, keyblob, keylen)) != 0 ||
(r = sshbuf_put_cstring(b, chost)) != 0 ||
(r = sshbuf_put_cstring(b, authctxt->local_user)) != 0) {
- error("%s: buffer error: %s", __func__, ssh_err(r));
+ error_fr(r, "buffer error");
goto out;
}
#ifdef DEBUG_PK
sshbuf_dump(b, stderr);
#endif
- r = ssh_keysign(private, &sig, &siglen,
- sshbuf_ptr(b), sshbuf_len(b));
- if (r != 0) {
+ if ((r = ssh_keysign(ssh, private, &sig, &siglen,
+ sshbuf_ptr(b), sshbuf_len(b))) != 0) {
error("sign using hostkey %s %s failed",
sshkey_ssh_name(private), fp);
goto out;
@@ -2028,13 +2207,13 @@ userauth_hostbased(Authctxt *authctxt)
(r = sshpkt_put_cstring(ssh, authctxt->server_user)) != 0 ||
(r = sshpkt_put_cstring(ssh, authctxt->service)) != 0 ||
(r = sshpkt_put_cstring(ssh, authctxt->method->name)) != 0 ||
- (r = sshpkt_put_cstring(ssh, sshkey_ssh_name(private))) != 0 ||
+ (r = sshpkt_put_cstring(ssh, authctxt->active_ktype)) != 0 ||
(r = sshpkt_put_string(ssh, keyblob, keylen)) != 0 ||
(r = sshpkt_put_cstring(ssh, chost)) != 0 ||
(r = sshpkt_put_cstring(ssh, authctxt->local_user)) != 0 ||
(r = sshpkt_put_string(ssh, sig, siglen)) != 0 ||
(r = sshpkt_send(ssh)) != 0) {
- error("%s: packet error: %s", __func__, ssh_err(r));
+ error_fr(r, "packet error");
goto out;
}
success = 1;
@@ -2143,17 +2322,16 @@ authmethods_get(void)
int r;
if ((b = sshbuf_new()) == NULL)
- fatal("%s: sshbuf_new failed", __func__);
+ fatal_f("sshbuf_new failed");
for (method = authmethods; method->name != NULL; method++) {
if (authmethod_is_enabled(method)) {
if ((r = sshbuf_putf(b, "%s%s",
sshbuf_len(b) ? "," : "", method->name)) != 0)
- fatal("%s: buffer error: %s",
- __func__, ssh_err(r));
+ fatal_fr(r, "buffer error");
}
}
if ((list = sshbuf_dup_string(b)) == NULL)
- fatal("%s: sshbuf_dup_string failed", __func__);
+ fatal_f("sshbuf_dup_string failed");
sshbuf_free(b);
return list;
}
diff --git a/crypto/openssh/sshd.8 b/crypto/openssh/sshd.8
index 72bf498e9f32..be9a57cf2ff7 100644
--- a/crypto/openssh/sshd.8
+++ b/crypto/openssh/sshd.8
@@ -33,14 +33,14 @@
.\" (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: sshd.8,v 1.304 2018/07/22 12:16:59 dtucker Exp $
+.\" $OpenBSD: sshd.8,v 1.316 2021/07/30 14:28:13 jmc Exp $
.\" $FreeBSD$
-.Dd $Mdocdate: July 22 2018 $
+.Dd $Mdocdate: July 30 2021 $
.Dt SSHD 8
.Os
.Sh NAME
.Nm sshd
-.Nd OpenSSH SSH daemon
+.Nd OpenSSH daemon
.Sh SYNOPSIS
.Nm sshd
.Bk -words
@@ -59,8 +59,7 @@
.Nm
(OpenSSH Daemon) is the daemon program for
.Xr ssh 1 .
-Together these programs replace rlogin and rsh,
-and provide secure encrypted communications between two untrusted hosts
+It provides secure encrypted communications between two untrusted hosts
over an insecure network.
.Pp
.Nm
@@ -108,7 +107,7 @@ supplied in any order, either with multiple
.Fl C
options or as a comma-separated list.
The keywords are
-.Dq addr,
+.Dq addr ,
.Dq user ,
.Dq host ,
.Dq laddr ,
@@ -136,7 +135,9 @@ This allows easy monitoring of
Debug mode.
The server sends verbose debug output to standard error,
and does not put itself in the background.
-The server also will not fork and will only process one connection.
+The server also will not
+.Xr fork 2
+and will only process one connection.
This option is only intended for debugging for the server.
Multiple
.Fl d
@@ -254,16 +255,13 @@ Whenever a client connects, the daemon responds with its public
host key.
The client compares the
host key against its own database to verify that it has not changed.
-Forward security is provided through a Diffie-Hellman key agreement.
+Forward secrecy is provided through a Diffie-Hellman key agreement.
This key agreement results in a shared session key.
-The rest of the session is encrypted using a symmetric cipher, currently
-128-bit AES, Blowfish, 3DES, CAST128, Arcfour, 192-bit AES, or 256-bit AES.
+The rest of the session is encrypted using a symmetric cipher.
The client selects the encryption algorithm
to use from those offered by the server.
Additionally, session integrity is provided
-through a cryptographic message authentication code
-(hmac-md5, hmac-sha1, umac-64, umac-128,
-hmac-sha2-256 or hmac-sha2-512).
+through a cryptographic message authentication code (MAC).
.Pp
Finally, the server and the client enter an authentication dialog.
The client tries to authenticate itself using
@@ -432,25 +430,39 @@ comments).
Public keys consist of the following space-separated fields:
options, keytype, base64-encoded key, comment.
The options field is optional.
-The keytype is
-.Dq ecdsa-sha2-nistp256 ,
-.Dq ecdsa-sha2-nistp384 ,
-.Dq ecdsa-sha2-nistp521 ,
-.Dq ssh-ed25519 ,
-.Dq ssh-dss
-or
-.Dq ssh-rsa ;
-the comment field is not used for anything (but may be convenient for the
+The supported key types are:
+.Pp
+.Bl -item -compact -offset indent
+.It
+sk-ecdsa-sha2-nistp256@openssh.com
+.It
+ecdsa-sha2-nistp256
+.It
+ecdsa-sha2-nistp384
+.It
+ecdsa-sha2-nistp521
+.It
+sk-ssh-ed25519@openssh.com
+.It
+ssh-ed25519
+.It
+ssh-dss
+.It
+ssh-rsa
+.El
+.Pp
+The comment field is not used for anything (but may be convenient for the
user to identify the key).
.Pp
Note that lines in this file can be several hundred bytes long
(because of the size of the public key encoding) up to a limit of
-8 kilobytes, which permits DSA keys up to 8 kilobits and RSA
-keys up to 16 kilobits.
+8 kilobytes, which permits RSA keys up to 16 kilobits.
You don't want to type them in; instead, copy the
.Pa id_dsa.pub ,
.Pa id_ecdsa.pub ,
+.Pa id_ecdsa_sk.pub ,
.Pa id_ed25519.pub ,
+.Pa id_ed25519_sk.pub ,
or the
.Pa id_rsa.pub
file and edit it.
@@ -592,8 +604,8 @@ IPv6 addresses can be specified by enclosing the address in square brackets.
Multiple
.Cm permitopen
options may be applied separated by commas.
-No pattern matching is performed on the specified hostnames,
-they must be literal domains or addresses.
+No pattern matching or name lookup is performed on the
+specified hostnames, they must be literal host names and/or addresses.
A port specification of
.Cm *
matches any port.
@@ -616,6 +628,20 @@ option.
Permits tty allocation previously disabled by the
.Cm restrict
option.
+.It Cm no-touch-required
+Do not require demonstration of user presence
+for signatures made using this key.
+This option only makes sense for the FIDO authenticator algorithms
+.Cm ecdsa-sk
+and
+.Cm ed25519-sk .
+.It Cm verify-required
+Require that signatures made using this key attest that they verified
+the user, e.g. via a PIN.
+This option only makes sense for the FIDO authenticator algorithms
+.Cm ecdsa-sk
+and
+.Cm ed25519-sk .
.It Cm restrict
Enable all restrictions, i.e. disable port, agent and X11 forwarding,
as well as disabling PTY allocation
@@ -643,22 +669,25 @@ option.
.Pp
An example authorized_keys file:
.Bd -literal -offset 3n
-# Comments allowed at start of line
-ssh-rsa AAAAB3Nza...LiPk== user@example.net
-from="*.sales.example.net,!pc.sales.example.net" ssh-rsa
-AAAAB2...19Q== john@example.net
-command="dump /home",no-pty,no-port-forwarding ssh-rsa
-AAAAC3...51R== example.net
-permitopen="192.0.2.1:80",permitopen="192.0.2.2:25" ssh-rsa
-AAAAB5...21S==
-permitlisten="localhost:8080",permitopen="localhost:22000" ssh-rsa
-AAAAB5...21S==
-tunnel="0",command="sh /etc/netstart tun0" ssh-rsa AAAA...==
-jane@example.net
-restrict,command="uptime" ssh-rsa AAAA1C8...32Tv==
-user@example.net
-restrict,pty,command="nethack" ssh-rsa AAAA1f8...IrrC5==
-user@example.net
+# Comments are allowed at start of line. Blank lines are allowed.
+# Plain key, no restrictions
+ssh-rsa ...
+# Forced command, disable PTY and all forwarding
+restrict,command="dump /home" ssh-rsa ...
+# Restriction of ssh -L forwarding destinations
+permitopen="192.0.2.1:80",permitopen="192.0.2.2:25" ssh-rsa ...
+# Restriction of ssh -R forwarding listeners
+permitlisten="localhost:8080",permitlisten="[::1]:22000" ssh-rsa ...
+# Configuration for tunnel forwarding
+tunnel="0",command="sh /etc/netstart tun0" ssh-rsa ...
+# Override of restriction to allow PTY allocation
+restrict,pty,command="nethack" ssh-rsa ...
+# Allow FIDO key without requiring touch
+no-touch-required sk-ecdsa-sha2-nistp256@openssh.com ...
+# Require user-verification (e.g. PIN or biometric) for FIDO key
+verify-required sk-ecdsa-sha2-nistp256@openssh.com ...
+# Trust CA key, allow touch-less FIDO if requested in certificate
+cert-authority,no-touch-required,principals="user_a" ssh-rsa ...
.Ed
.Sh SSH_KNOWN_HOSTS FILE FORMAT
The
@@ -671,7 +700,7 @@ be prepared by the administrator (optional), and the per-user file is
maintained automatically: whenever the user connects to an unknown host,
its key is added to the per-user file.
.Pp
-Each line in these files contains the following fields: markers (optional),
+Each line in these files contains the following fields: marker (optional),
hostnames, keytype, base64-encoded key, comment.
The fields are separated by spaces.
.Pp
diff --git a/crypto/openssh/sshd.c b/crypto/openssh/sshd.c
index 532e5dc04fc2..b3a2c4151e01 100644
--- a/crypto/openssh/sshd.c
+++ b/crypto/openssh/sshd.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: sshd.c,v 1.516 2018/09/21 12:23:17 djm Exp $ */
+/* $OpenBSD: sshd.c,v 1.578 2021/07/19 02:21:50 dtucker Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -133,6 +133,9 @@ __RCSID("$FreeBSD$");
#include "auth-options.h"
#include "version.h"
#include "ssherr.h"
+#include "sk-api.h"
+#include "srclimit.h"
+#include "dh.h"
#include "blacklist_client.h"
#ifdef LIBWRAP
@@ -170,45 +173,38 @@ int debug_flag = 0;
* configuration, optionally using connection information provided by the
* "-C" flag.
*/
-int test_flag = 0;
+static int test_flag = 0;
/* Flag indicating that the daemon is being started from inetd. */
-int inetd_flag = 0;
+static int inetd_flag = 0;
/* Flag indicating that sshd should not detach and become a daemon. */
-int no_daemon_flag = 0;
+static int no_daemon_flag = 0;
/* debug goes to stderr unless inetd_flag is set */
-int log_stderr = 0;
+static int log_stderr = 0;
/* Saved arguments to main(). */
-char **saved_argv;
-int saved_argc;
+static char **saved_argv;
+static int saved_argc;
/* re-exec */
-int rexeced_flag = 0;
-int rexec_flag = 1;
-int rexec_argc = 0;
-char **rexec_argv;
+static int rexeced_flag = 0;
+static int rexec_flag = 1;
+static int rexec_argc = 0;
+static char **rexec_argv;
/*
* The sockets that the server is listening; this is used in the SIGHUP
* signal handler.
*/
#define MAX_LISTEN_SOCKS 16
-int listen_socks[MAX_LISTEN_SOCKS];
-int num_listen_socks = 0;
-
-/*
- * the client's version string, passed by sshd2 in compat mode. if != NULL,
- * sshd will skip the version-number exchange
- */
-char *client_version_string = NULL;
-char *server_version_string = NULL;
+static int listen_socks[MAX_LISTEN_SOCKS];
+static int num_listen_socks = 0;
/* Daemon's agent connection */
int auth_sock = -1;
-int have_agent = 0;
+static int have_agent = 0;
/*
* Any really sensitive data in the application is contained in this
@@ -229,19 +225,29 @@ struct {
static volatile sig_atomic_t received_sighup = 0;
static volatile sig_atomic_t received_sigterm = 0;
-/* session identifier, used by RSA-auth */
-u_char session_id[16];
-
-/* same for ssh2 */
-u_char *session_id2 = NULL;
-u_int session_id2_len = 0;
-
/* record remote hostname or ip */
u_int utmp_len = HOST_NAME_MAX+1;
-/* options.max_startup sized array of fd ints */
-int *startup_pipes = NULL;
-int startup_pipe; /* in child */
+/*
+ * startup_pipes/flags are used for tracking children of the listening sshd
+ * process early in their lifespans. This tracking is needed for three things:
+ *
+ * 1) Implementing the MaxStartups limit of concurrent unauthenticated
+ * connections.
+ * 2) Avoiding a race condition for SIGHUP processing, where child processes
+ * may have listen_socks open that could collide with main listener process
+ * after it restarts.
+ * 3) Ensuring that rexec'd sshd processes have received their initial state
+ * from the parent listen process before handling SIGHUP.
+ *
+ * Child processes signal that they have completed closure of the listen_socks
+ * and (if applicable) received their rexec state by sending a char over their
+ * sock. Child processes signal that authentication has completed by closing
+ * the sock (or by exiting).
+ */
+static int *startup_pipes = NULL;
+static int *startup_flags = NULL; /* Indicates child closed listener */
+static int startup_pipe = -1; /* in child */
/* variables used for privilege separation */
int use_privsep = -1;
@@ -249,8 +255,9 @@ struct monitor *pmonitor = NULL;
int privsep_is_preauth = 1;
static int privsep_chroot = 1;
-/* global authentication context */
+/* global connection state and authentication contexts */
Authctxt *the_authctxt = NULL;
+struct ssh *the_active_state;
/* global key/cert auth options. XXX move to permanent ssh->authctxt? */
struct sshauthopt *auth_opts = NULL;
@@ -258,6 +265,9 @@ struct sshauthopt *auth_opts = NULL;
/* sshd_config buffer */
struct sshbuf *cfg;
+/* Included files from the configuration file */
+struct include_list includes = TAILQ_HEAD_INITIALIZER(includes);
+
/* message to be displayed after login */
struct sshbuf *loginmsg;
@@ -267,7 +277,9 @@ struct passwd *privsep_pw = NULL;
/* Prototypes for various functions defined later in this file. */
void destroy_sensitive_data(void);
void demote_sensitive_data(void);
-static void do_ssh2_kex(void);
+static void do_ssh2_kex(struct ssh *);
+
+static char *listener_proctitle;
/*
* Close all listening sockets
@@ -303,10 +315,7 @@ close_startup_pipes(void)
static void
sighup_handler(int sig)
{
- int save_errno = errno;
-
received_sighup = 1;
- errno = save_errno;
}
/*
@@ -322,8 +331,7 @@ sighup_restart(void)
platform_pre_restart();
close_listen_socks();
close_startup_pipes();
- alarm(0); /* alarm timer persists across exec */
- signal(SIGHUP, SIG_IGN); /* will be restored after exec */
+ ssh_signal(SIGHUP, SIG_IGN); /* will be restored after exec */
execv(saved_argv[0], saved_argv);
logit("RESTART FAILED: av[0]='%.100s', error: %.100s.", saved_argv[0],
strerror(errno));
@@ -353,7 +361,7 @@ main_sigchld_handler(int sig)
int status;
while ((pid = waitpid(-1, &status, WNOHANG)) > 0 ||
- (pid < 0 && errno == EINTR))
+ (pid == -1 && errno == EINTR))
;
errno = save_errno;
}
@@ -373,116 +381,19 @@ grace_alarm_handler(int sig)
* keys command helpers.
*/
if (getpgid(0) == getpid()) {
- signal(SIGTERM, SIG_IGN);
+ ssh_signal(SIGTERM, SIG_IGN);
kill(0, SIGTERM);
}
BLACKLIST_NOTIFY(BLACKLIST_AUTH_FAIL, "ssh");
/* Log error and exit. */
- sigdie("Timeout before authentication for %s port %d",
- ssh_remote_ipaddr(active_state), ssh_remote_port(active_state));
-}
-
-static void
-sshd_exchange_identification(struct ssh *ssh, int sock_in, int sock_out)
-{
- u_int i;
- int remote_major, remote_minor;
- char *s;
- char buf[256]; /* Must not be larger than remote_version. */
- char remote_version[256]; /* Must be at least as big as buf. */
-
- xasprintf(&server_version_string, "SSH-%d.%d-%.100s%s%s\r\n",
- PROTOCOL_MAJOR_2, PROTOCOL_MINOR_2, SSH_VERSION,
- *options.version_addendum == '\0' ? "" : " ",
- options.version_addendum);
-
- /* Send our protocol version identification. */
- if (atomicio(vwrite, sock_out, server_version_string,
- strlen(server_version_string))
- != strlen(server_version_string)) {
- logit("Could not write ident string to %s port %d",
- ssh_remote_ipaddr(ssh), ssh_remote_port(ssh));
- cleanup_exit(255);
- }
-
- /* Read other sides version identification. */
- memset(buf, 0, sizeof(buf));
- for (i = 0; i < sizeof(buf) - 1; i++) {
- if (atomicio(read, sock_in, &buf[i], 1) != 1) {
- logit("Did not receive identification string "
- "from %s port %d",
- ssh_remote_ipaddr(ssh), ssh_remote_port(ssh));
- cleanup_exit(255);
- }
- if (buf[i] == '\r') {
- buf[i] = 0;
- /* Kludge for F-Secure Macintosh < 1.0.2 */
- if (i == 12 &&
- strncmp(buf, "SSH-1.5-W1.0", 12) == 0)
- break;
- continue;
- }
- if (buf[i] == '\n') {
- buf[i] = 0;
- break;
- }
- }
- buf[sizeof(buf) - 1] = 0;
- client_version_string = xstrdup(buf);
-
- /*
- * Check that the versions match. In future this might accept
- * several versions and set appropriate flags to handle them.
- */
- if (sscanf(client_version_string, "SSH-%d.%d-%[^\n]\n",
- &remote_major, &remote_minor, remote_version) != 3) {
- s = "Protocol mismatch.\n";
- (void) atomicio(vwrite, sock_out, s, strlen(s));
- logit("Bad protocol version identification '%.100s' "
- "from %s port %d", client_version_string,
- ssh_remote_ipaddr(ssh), ssh_remote_port(ssh));
- close(sock_in);
- close(sock_out);
- cleanup_exit(255);
- }
- debug("Client protocol version %d.%d; client software version %.100s",
- remote_major, remote_minor, remote_version);
-
- ssh->compat = compat_datafellows(remote_version);
-
- if ((ssh->compat & SSH_BUG_PROBE) != 0) {
- logit("probed from %s port %d with %s. Don't panic.",
- ssh_remote_ipaddr(ssh), ssh_remote_port(ssh),
- client_version_string);
- cleanup_exit(255);
- }
- if ((ssh->compat & SSH_BUG_SCANNER) != 0) {
- logit("scanned from %s port %d with %s. Don't panic.",
- ssh_remote_ipaddr(ssh), ssh_remote_port(ssh),
- client_version_string);
- cleanup_exit(255);
- }
- if ((ssh->compat & SSH_BUG_RSASIGMD5) != 0) {
- logit("Client version \"%.100s\" uses unsafe RSA signature "
- "scheme; disabling use of RSA keys", remote_version);
- }
-
- chop(server_version_string);
- debug("Local version string %.200s", server_version_string);
-
- if (remote_major != 2 &&
- !(remote_major == 1 && remote_minor == 99)) {
- s = "Protocol major versions differ.\n";
- (void) atomicio(vwrite, sock_out, s, strlen(s));
- close(sock_in);
- close(sock_out);
- logit("Protocol major versions differ for %s port %d: "
- "%.200s vs. %.200s",
- ssh_remote_ipaddr(ssh), ssh_remote_port(ssh),
- server_version_string, client_version_string);
- cleanup_exit(255);
+ if (use_privsep && pmonitor != NULL && pmonitor->m_pid <= 0)
+ cleanup_exit(255); /* don't log in privsep child */
+ else {
+ sigdie("Timeout before authentication for %s port %d",
+ ssh_remote_ipaddr(the_active_state),
+ ssh_remote_port(the_active_state));
}
}
@@ -516,9 +427,8 @@ demote_sensitive_data(void)
if (sensitive_data.host_keys[i]) {
if ((r = sshkey_from_private(
sensitive_data.host_keys[i], &tmp)) != 0)
- fatal("could not demote host %s key: %s",
- sshkey_type(sensitive_data.host_keys[i]),
- ssh_err(r));
+ fatal_r(r, "could not demote host %s key",
+ sshkey_type(sensitive_data.host_keys[i]));
sshkey_free(sensitive_data.host_keys[i]);
sensitive_data.host_keys[i] = tmp;
}
@@ -578,14 +488,14 @@ privsep_preauth_child(void)
debug3("privsep user:group %u:%u", (u_int)privsep_pw->pw_uid,
(u_int)privsep_pw->pw_gid);
gidset[0] = privsep_pw->pw_gid;
- if (setgroups(1, gidset) < 0)
+ if (setgroups(1, gidset) == -1)
fatal("setgroups: %.100s", strerror(errno));
permanently_set_uid(privsep_pw);
}
}
static int
-privsep_preauth(Authctxt *authctxt)
+privsep_preauth(struct ssh *ssh)
{
int status, r;
pid_t pid;
@@ -594,7 +504,7 @@ privsep_preauth(Authctxt *authctxt)
/* Set up unprivileged child process to deal with network data */
pmonitor = monitor_init();
/* Store a pointer to the kex for later rekeying */
- pmonitor->m_pkex = &active_state->kex;
+ pmonitor->m_pkex = &ssh->kex;
if (use_privsep == PRIVSEP_ON)
box = ssh_sandbox_init(pmonitor);
@@ -608,31 +518,30 @@ privsep_preauth(Authctxt *authctxt)
if (have_agent) {
r = ssh_get_authentication_socket(&auth_sock);
if (r != 0) {
- error("Could not get agent socket: %s",
- ssh_err(r));
+ error_r(r, "Could not get agent socket");
have_agent = 0;
}
}
if (box != NULL)
ssh_sandbox_parent_preauth(box, pid);
- monitor_child_preauth(authctxt, pmonitor);
+ monitor_child_preauth(ssh, pmonitor);
/* Wait for the child's exit status */
- while (waitpid(pid, &status, 0) < 0) {
+ while (waitpid(pid, &status, 0) == -1) {
if (errno == EINTR)
continue;
pmonitor->m_pid = -1;
- fatal("%s: waitpid: %s", __func__, strerror(errno));
+ fatal_f("waitpid: %s", strerror(errno));
}
privsep_is_preauth = 0;
pmonitor->m_pid = -1;
if (WIFEXITED(status)) {
if (WEXITSTATUS(status) != 0)
- fatal("%s: preauth child exited with status %d",
- __func__, WEXITSTATUS(status));
+ fatal_f("preauth child exited with status %d",
+ WEXITSTATUS(status));
} else if (WIFSIGNALED(status))
- fatal("%s: preauth child terminated by signal %d",
- __func__, WTERMSIG(status));
+ fatal_f("preauth child terminated by signal %d",
+ WTERMSIG(status));
if (box != NULL)
ssh_sandbox_parent_finish(box);
return 1;
@@ -654,7 +563,7 @@ privsep_preauth(Authctxt *authctxt)
}
static void
-privsep_postauth(Authctxt *authctxt)
+privsep_postauth(struct ssh *ssh, Authctxt *authctxt)
{
#ifdef DISABLE_FD_PASSING
if (1) {
@@ -675,8 +584,8 @@ privsep_postauth(Authctxt *authctxt)
else if (pmonitor->m_pid != 0) {
verbose("User child is on pid %ld", (long)pmonitor->m_pid);
sshbuf_reset(loginmsg);
- monitor_clear_keystate(pmonitor);
- monitor_child_postauth(pmonitor);
+ monitor_clear_keystate(ssh, pmonitor);
+ monitor_child_postauth(ssh, pmonitor);
/* NEVERREACHED */
exit(0);
@@ -697,13 +606,13 @@ privsep_postauth(Authctxt *authctxt)
skip:
/* It is safe now to apply the key state */
- monitor_apply_keystate(pmonitor);
+ monitor_apply_keystate(ssh, pmonitor);
/*
* Tell the packet layer that authentication was successful, since
* this information is not part of the key state.
*/
- packet_set_authenticated();
+ ssh_packet_set_authenticated(ssh);
}
static void
@@ -712,12 +621,11 @@ append_hostkey_type(struct sshbuf *b, const char *s)
int r;
if (match_pattern_list(s, options.hostkeyalgorithms, 0) != 1) {
- debug3("%s: %s key not permitted by HostkeyAlgorithms",
- __func__, s);
+ debug3_f("%s key not permitted by HostkeyAlgorithms", s);
return;
}
if ((r = sshbuf_putf(b, "%s%s", sshbuf_len(b) > 0 ? "," : "", s)) != 0)
- fatal("%s: sshbuf_putf: %s", __func__, ssh_err(r));
+ fatal_fr(r, "sshbuf_putf");
}
static char *
@@ -729,7 +637,7 @@ list_hostkey_types(void)
u_int i;
if ((b = sshbuf_new()) == NULL)
- fatal("%s: sshbuf_new failed", __func__);
+ fatal_f("sshbuf_new failed");
for (i = 0; i < options.num_host_key_files; i++) {
key = sensitive_data.host_keys[i];
if (key == NULL)
@@ -745,6 +653,8 @@ list_hostkey_types(void)
case KEY_DSA:
case KEY_ECDSA:
case KEY_ED25519:
+ case KEY_ECDSA_SK:
+ case KEY_ED25519_SK:
case KEY_XMSS:
append_hostkey_type(b, sshkey_ssh_name(key));
break;
@@ -764,15 +674,17 @@ list_hostkey_types(void)
case KEY_DSA_CERT:
case KEY_ECDSA_CERT:
case KEY_ED25519_CERT:
+ case KEY_ECDSA_SK_CERT:
+ case KEY_ED25519_SK_CERT:
case KEY_XMSS_CERT:
append_hostkey_type(b, sshkey_ssh_name(key));
break;
}
}
if ((ret = sshbuf_dup_string(b)) == NULL)
- fatal("%s: sshbuf_dup_string failed", __func__);
+ fatal_f("sshbuf_dup_string failed");
sshbuf_free(b);
- debug("%s: %s", __func__, ret);
+ debug_f("%s", ret);
return ret;
}
@@ -788,6 +700,8 @@ get_hostkey_by_type(int type, int nid, int need_private, struct ssh *ssh)
case KEY_DSA_CERT:
case KEY_ECDSA_CERT:
case KEY_ED25519_CERT:
+ case KEY_ECDSA_SK_CERT:
+ case KEY_ED25519_SK_CERT:
case KEY_XMSS_CERT:
key = sensitive_data.host_certificates[i];
break;
@@ -797,10 +711,20 @@ get_hostkey_by_type(int type, int nid, int need_private, struct ssh *ssh)
key = sensitive_data.host_pubkeys[i];
break;
}
- if (key != NULL && key->type == type &&
- (key->type != KEY_ECDSA || key->ecdsa_nid == nid))
+ if (key == NULL || key->type != type)
+ continue;
+ switch (type) {
+ case KEY_ECDSA:
+ case KEY_ECDSA_SK:
+ case KEY_ECDSA_CERT:
+ case KEY_ECDSA_SK_CERT:
+ if (key->ecdsa_nid != nid)
+ continue;
+ /* FALLTHROUGH */
+ default:
return need_private ?
sensitive_data.host_keys[i] : key;
+ }
}
return NULL;
}
@@ -870,11 +794,11 @@ notify_hostkeys(struct ssh *ssh)
char *fp;
/* Some clients cannot cope with the hostkeys message, skip those. */
- if (datafellows & SSH_BUG_HOSTKEYS)
+ if (ssh->compat & SSH_BUG_HOSTKEYS)
return;
if ((buf = sshbuf_new()) == NULL)
- fatal("%s: sshbuf_new", __func__);
+ fatal_f("sshbuf_new");
for (i = nkeys = 0; i < options.num_host_key_files; i++) {
key = get_hostkey_public_by_index(i, ssh);
if (key == NULL || key->type == KEY_UNSPEC ||
@@ -882,25 +806,31 @@ notify_hostkeys(struct ssh *ssh)
continue;
fp = sshkey_fingerprint(key, options.fingerprint_hash,
SSH_FP_DEFAULT);
- debug3("%s: key %d: %s %s", __func__, i,
- sshkey_ssh_name(key), fp);
+ debug3_f("key %d: %s %s", i, sshkey_ssh_name(key), fp);
free(fp);
if (nkeys == 0) {
- packet_start(SSH2_MSG_GLOBAL_REQUEST);
- packet_put_cstring("hostkeys-00@openssh.com");
- packet_put_char(0); /* want-reply */
+ /*
+ * Start building the request when we find the
+ * first usable key.
+ */
+ if ((r = sshpkt_start(ssh, SSH2_MSG_GLOBAL_REQUEST)) != 0 ||
+ (r = sshpkt_put_cstring(ssh, "hostkeys-00@openssh.com")) != 0 ||
+ (r = sshpkt_put_u8(ssh, 0)) != 0) /* want reply */
+ sshpkt_fatal(ssh, r, "%s: start request", __func__);
}
+ /* Append the key to the request */
sshbuf_reset(buf);
if ((r = sshkey_putb(key, buf)) != 0)
- fatal("%s: couldn't put hostkey %d: %s",
- __func__, i, ssh_err(r));
- packet_put_string(sshbuf_ptr(buf), sshbuf_len(buf));
+ fatal_fr(r, "couldn't put hostkey %d", i);
+ if ((r = sshpkt_put_stringb(ssh, buf)) != 0)
+ sshpkt_fatal(ssh, r, "%s: append key", __func__);
nkeys++;
}
- debug3("%s: sent %u hostkeys", __func__, nkeys);
+ debug3_f("sent %u hostkeys", nkeys);
if (nkeys == 0)
- fatal("%s: no hostkeys", __func__);
- packet_send();
+ fatal_f("no hostkeys");
+ if ((r = sshpkt_send(ssh)) != 0)
+ sshpkt_fatal(ssh, r, "%s: send", __func__);
sshbuf_free(buf);
}
@@ -911,7 +841,7 @@ notify_hostkeys(struct ssh *ssh)
* all connections are dropped for startups > max_startups
*/
static int
-drop_connection(int startups)
+should_drop_connection(int startups)
{
int p, r;
@@ -928,10 +858,69 @@ drop_connection(int startups)
p += options.max_startups_rate;
r = arc4random_uniform(100);
- debug("drop_connection: p %d, r %d", p, r);
+ debug_f("p %d, r %d", p, r);
return (r < p) ? 1 : 0;
}
+/*
+ * Check whether connection should be accepted by MaxStartups.
+ * Returns 0 if the connection is accepted. If the connection is refused,
+ * returns 1 and attempts to send notification to client.
+ * Logs when the MaxStartups condition is entered or exited, and periodically
+ * while in that state.
+ */
+static int
+drop_connection(int sock, int startups, int notify_pipe)
+{
+ char *laddr, *raddr;
+ const char msg[] = "Exceeded MaxStartups\r\n";
+ static time_t last_drop, first_drop;
+ static u_int ndropped;
+ LogLevel drop_level = SYSLOG_LEVEL_VERBOSE;
+ time_t now;
+
+ now = monotime();
+ if (!should_drop_connection(startups) &&
+ srclimit_check_allow(sock, notify_pipe) == 1) {
+ if (last_drop != 0 &&
+ startups < options.max_startups_begin - 1) {
+ /* XXX maybe need better hysteresis here */
+ logit("exited MaxStartups throttling after %s, "
+ "%u connections dropped",
+ fmt_timeframe(now - first_drop), ndropped);
+ last_drop = 0;
+ }
+ return 0;
+ }
+
+#define SSHD_MAXSTARTUPS_LOG_INTERVAL (5 * 60)
+ if (last_drop == 0) {
+ error("beginning MaxStartups throttling");
+ drop_level = SYSLOG_LEVEL_INFO;
+ first_drop = now;
+ ndropped = 0;
+ } else if (last_drop + SSHD_MAXSTARTUPS_LOG_INTERVAL < now) {
+ /* Periodic logs */
+ error("in MaxStartups throttling for %s, "
+ "%u connections dropped",
+ fmt_timeframe(now - first_drop), ndropped + 1);
+ drop_level = SYSLOG_LEVEL_INFO;
+ }
+ last_drop = now;
+ ndropped++;
+
+ laddr = get_local_ipaddr(sock);
+ raddr = get_peer_ipaddr(sock);
+ do_log2(drop_level, "drop connection #%d from [%s]:%d on [%s]:%d "
+ "past MaxStartups", startups, raddr, get_peer_port(sock),
+ laddr, get_local_port(sock));
+ free(laddr);
+ free(raddr);
+ /* best-effort notification to client */
+ (void)write(sock, msg, sizeof(msg) - 1);
+ return 1;
+}
+
static void
usage(void)
{
@@ -953,80 +942,103 @@ usage(void)
static void
send_rexec_state(int fd, struct sshbuf *conf)
{
- struct sshbuf *m;
+ struct sshbuf *m = NULL, *inc = NULL;
+ struct include_item *item = NULL;
int r;
- debug3("%s: entering fd = %d config len %zu", __func__, fd,
+ debug3_f("entering fd = %d config len %zu", fd,
sshbuf_len(conf));
+ if ((m = sshbuf_new()) == NULL || (inc = sshbuf_new()) == NULL)
+ fatal_f("sshbuf_new failed");
+
+ /* pack includes into a string */
+ TAILQ_FOREACH(item, &includes, entry) {
+ if ((r = sshbuf_put_cstring(inc, item->selector)) != 0 ||
+ (r = sshbuf_put_cstring(inc, item->filename)) != 0 ||
+ (r = sshbuf_put_stringb(inc, item->contents)) != 0)
+ fatal_fr(r, "compose includes");
+ }
+
/*
* Protocol from reexec master to child:
* string configuration
- * string rngseed (only if OpenSSL is not self-seeded)
+ * string included_files[] {
+ * string selector
+ * string filename
+ * string contents
+ * }
+ * string rng_seed (if required)
*/
- if ((m = sshbuf_new()) == NULL)
- fatal("%s: sshbuf_new failed", __func__);
- if ((r = sshbuf_put_stringb(m, conf)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
-
+ if ((r = sshbuf_put_stringb(m, conf)) != 0 ||
+ (r = sshbuf_put_stringb(m, inc)) != 0)
+ fatal_fr(r, "compose config");
#if defined(WITH_OPENSSL) && !defined(OPENSSL_PRNG_ONLY)
rexec_send_rng_seed(m);
#endif
-
if (ssh_msg_send(fd, 0, m) == -1)
- fatal("%s: ssh_msg_send failed", __func__);
+ error_f("ssh_msg_send failed");
sshbuf_free(m);
+ sshbuf_free(inc);
- debug3("%s: done", __func__);
+ debug3_f("done");
}
static void
recv_rexec_state(int fd, struct sshbuf *conf)
{
- struct sshbuf *m;
+ struct sshbuf *m, *inc;
u_char *cp, ver;
size_t len;
int r;
+ struct include_item *item;
- debug3("%s: entering fd = %d", __func__, fd);
+ debug3_f("entering fd = %d", fd);
- if ((m = sshbuf_new()) == NULL)
- fatal("%s: sshbuf_new failed", __func__);
+ if ((m = sshbuf_new()) == NULL || (inc = sshbuf_new()) == NULL)
+ fatal_f("sshbuf_new failed");
if (ssh_msg_recv(fd, m) == -1)
- fatal("%s: ssh_msg_recv failed", __func__);
+ fatal_f("ssh_msg_recv failed");
if ((r = sshbuf_get_u8(m, &ver)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "parse version");
if (ver != 0)
- fatal("%s: rexec version mismatch", __func__);
- if ((r = sshbuf_get_string(m, &cp, &len)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
- if (conf != NULL && (r = sshbuf_put(conf, cp, len)))
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_f("rexec version mismatch");
+ if ((r = sshbuf_get_string(m, &cp, &len)) != 0 ||
+ (r = sshbuf_get_stringb(m, inc)) != 0)
+ fatal_fr(r, "parse config");
+
#if defined(WITH_OPENSSL) && !defined(OPENSSL_PRNG_ONLY)
rexec_recv_rng_seed(m);
#endif
+ if (conf != NULL && (r = sshbuf_put(conf, cp, len)))
+ fatal_fr(r, "sshbuf_put");
+
+ while (sshbuf_len(inc) != 0) {
+ item = xcalloc(1, sizeof(*item));
+ if ((item->contents = sshbuf_new()) == NULL)
+ fatal_f("sshbuf_new failed");
+ if ((r = sshbuf_get_cstring(inc, &item->selector, NULL)) != 0 ||
+ (r = sshbuf_get_cstring(inc, &item->filename, NULL)) != 0 ||
+ (r = sshbuf_get_stringb(inc, item->contents)) != 0)
+ fatal_fr(r, "parse includes");
+ TAILQ_INSERT_TAIL(&includes, item, entry);
+ }
+
free(cp);
sshbuf_free(m);
- debug3("%s: done", __func__);
+ debug3_f("done");
}
/* Accept a connection from inetd */
static void
server_accept_inetd(int *sock_in, int *sock_out)
{
- int fd;
-
- startup_pipe = -1;
if (rexeced_flag) {
close(REEXEC_CONFIG_PASS_FD);
*sock_in = *sock_out = dup(STDIN_FILENO);
- if (!debug_flag) {
- startup_pipe = dup(REEXEC_STARTUP_PIPE_FD);
- close(REEXEC_STARTUP_PIPE_FD);
- }
} else {
*sock_in = dup(STDIN_FILENO);
*sock_out = dup(STDOUT_FILENO);
@@ -1036,14 +1048,8 @@ server_accept_inetd(int *sock_in, int *sock_out)
* as our code for setting the descriptors won't work if
* ttyfd happens to be one of those.
*/
- if ((fd = open(_PATH_DEVNULL, O_RDWR, 0)) != -1) {
- dup2(fd, STDIN_FILENO);
- dup2(fd, STDOUT_FILENO);
- if (!log_stderr)
- dup2(fd, STDERR_FILENO);
- if (fd > (log_stderr ? STDERR_FILENO : STDOUT_FILENO))
- close(fd);
- }
+ if (stdfd_devnull(1, 1, !log_stderr) == -1)
+ error_f("stdfd_devnull failed");
debug("inetd sockets after dupping: %d, %d", *sock_in, *sock_out);
}
@@ -1073,7 +1079,7 @@ listen_on_addrs(struct listenaddr *la)
/* Create socket for listening. */
listen_sock = socket(ai->ai_family, ai->ai_socktype,
ai->ai_protocol);
- if (listen_sock < 0) {
+ if (listen_sock == -1) {
/* kernel may not support ipv6 */
verbose("socket: %.100s", strerror(errno));
continue;
@@ -1102,7 +1108,7 @@ listen_on_addrs(struct listenaddr *la)
debug("Bind to port %s on %s.", strport, ntop);
/* Bind the socket to the desired port. */
- if (bind(listen_sock, ai->ai_addr, ai->ai_addrlen) < 0) {
+ if (bind(listen_sock, ai->ai_addr, ai->ai_addrlen) == -1) {
error("Bind to port %s on %s failed: %.200s.",
strport, ntop, strerror(errno));
close(listen_sock);
@@ -1112,7 +1118,7 @@ listen_on_addrs(struct listenaddr *la)
num_listen_socks++;
/* Start listening on the port. */
- if (listen(listen_sock, SSH_LISTEN_BACKLOG) < 0)
+ if (listen(listen_sock, SSH_LISTEN_BACKLOG) == -1)
fatal("listen on [%s]:%s: %.100s",
ntop, strport, strerror(errno));
logit("Server listening on %s port %s%s%s.",
@@ -1127,6 +1133,10 @@ server_listen(void)
{
u_int i;
+ /* Initialise per-source limit tracking. */
+ srclimit_init(options.max_startups, options.per_source_max_startups,
+ options.per_source_masklen_ipv4, options.per_source_masklen_ipv6);
+
for (i = 0; i < options.num_listen_addrs; i++) {
listen_on_addrs(&options.listen_addrs[i]);
freeaddrinfo(options.listen_addrs[i].addrs);
@@ -1151,12 +1161,14 @@ server_accept_loop(int *sock_in, int *sock_out, int *newsock, int *config_s)
{
fd_set *fdset;
int i, j, ret, maxfd;
- int startups = 0;
+ int ostartups = -1, startups = 0, listening = 0, lameduck = 0;
int startup_p[2] = { -1 , -1 };
+ char c = 0;
struct sockaddr_storage from;
socklen_t fromlen;
pid_t pid;
u_char rnd[256];
+ sigset_t nsigset, osigset;
/* setup fd set for accept */
fdset = NULL;
@@ -1164,18 +1176,55 @@ server_accept_loop(int *sock_in, int *sock_out, int *newsock, int *config_s)
for (i = 0; i < num_listen_socks; i++)
if (listen_socks[i] > maxfd)
maxfd = listen_socks[i];
- /* pipes connected to unauthenticated childs */
+ /* pipes connected to unauthenticated child sshd processes */
startup_pipes = xcalloc(options.max_startups, sizeof(int));
+ startup_flags = xcalloc(options.max_startups, sizeof(int));
for (i = 0; i < options.max_startups; i++)
startup_pipes[i] = -1;
/*
+ * Prepare signal mask that we use to block signals that might set
+ * received_sigterm or received_sighup, so that we are guaranteed
+ * to immediately wake up the pselect if a signal is received after
+ * the flag is checked.
+ */
+ sigemptyset(&nsigset);
+ sigaddset(&nsigset, SIGHUP);
+ sigaddset(&nsigset, SIGCHLD);
+ sigaddset(&nsigset, SIGTERM);
+ sigaddset(&nsigset, SIGQUIT);
+
+ /*
* Stay listening for connections until the system crashes or
* the daemon is killed with a signal.
*/
for (;;) {
- if (received_sighup)
- sighup_restart();
+ sigprocmask(SIG_BLOCK, &nsigset, &osigset);
+ if (received_sigterm) {
+ logit("Received signal %d; terminating.",
+ (int) received_sigterm);
+ close_listen_socks();
+ if (options.pid_file != NULL)
+ unlink(options.pid_file);
+ exit(received_sigterm == SIGTERM ? 0 : 255);
+ }
+ if (ostartups != startups) {
+ setproctitle("%s [listener] %d of %d-%d startups",
+ listener_proctitle, startups,
+ options.max_startups_begin, options.max_startups);
+ ostartups = startups;
+ }
+ if (received_sighup) {
+ if (!lameduck) {
+ debug("Received SIGHUP; waiting for children");
+ close_listen_socks();
+ lameduck = 1;
+ }
+ if (listening <= 0) {
+ sigprocmask(SIG_SETMASK, &osigset, NULL);
+ sighup_restart();
+ }
+ }
free(fdset);
fdset = xcalloc(howmany(maxfd + 1, NFDBITS),
sizeof(fd_mask));
@@ -1186,41 +1235,53 @@ server_accept_loop(int *sock_in, int *sock_out, int *newsock, int *config_s)
if (startup_pipes[i] != -1)
FD_SET(startup_pipes[i], fdset);
- /* Wait in select until there is a connection. */
- ret = select(maxfd+1, fdset, NULL, NULL, NULL);
- if (ret < 0 && errno != EINTR)
- error("select: %.100s", strerror(errno));
- if (received_sigterm) {
- logit("Received signal %d; terminating.",
- (int) received_sigterm);
- close_listen_socks();
- if (options.pid_file != NULL)
- unlink(options.pid_file);
- exit(received_sigterm == SIGTERM ? 0 : 255);
- }
- if (ret < 0)
+ /* Wait until a connection arrives or a child exits. */
+ ret = pselect(maxfd+1, fdset, NULL, NULL, NULL, &osigset);
+ if (ret == -1 && errno != EINTR)
+ error("pselect: %.100s", strerror(errno));
+ sigprocmask(SIG_SETMASK, &osigset, NULL);
+ if (ret == -1)
continue;
- for (i = 0; i < options.max_startups; i++)
- if (startup_pipes[i] != -1 &&
- FD_ISSET(startup_pipes[i], fdset)) {
- /*
- * the read end of the pipe is ready
- * if the child has closed the pipe
- * after successful authentication
- * or if the child has died
- */
+ for (i = 0; i < options.max_startups; i++) {
+ if (startup_pipes[i] == -1 ||
+ !FD_ISSET(startup_pipes[i], fdset))
+ continue;
+ switch (read(startup_pipes[i], &c, sizeof(c))) {
+ case -1:
+ if (errno == EINTR || errno == EAGAIN)
+ continue;
+ if (errno != EPIPE) {
+ error_f("startup pipe %d (fd=%d): "
+ "read %s", i, startup_pipes[i],
+ strerror(errno));
+ }
+ /* FALLTHROUGH */
+ case 0:
+ /* child exited or completed auth */
close(startup_pipes[i]);
+ srclimit_done(startup_pipes[i]);
startup_pipes[i] = -1;
startups--;
+ if (startup_flags[i])
+ listening--;
+ break;
+ case 1:
+ /* child has finished preliminaries */
+ if (startup_flags[i]) {
+ listening--;
+ startup_flags[i] = 0;
+ }
+ break;
}
+ }
for (i = 0; i < num_listen_socks; i++) {
if (!FD_ISSET(listen_socks[i], fdset))
continue;
fromlen = sizeof(from);
*newsock = accept(listen_socks[i],
(struct sockaddr *)&from, &fromlen);
- if (*newsock < 0) {
+ if (*newsock == -1) {
if (errno != EINTR && errno != EWOULDBLOCK &&
errno != ECONNABORTED && errno != EAGAIN)
error("accept: %.100s",
@@ -1229,25 +1290,13 @@ server_accept_loop(int *sock_in, int *sock_out, int *newsock, int *config_s)
usleep(100 * 1000);
continue;
}
- if (unset_nonblock(*newsock) == -1) {
- close(*newsock);
- continue;
- }
- if (drop_connection(startups) == 1) {
- char *laddr = get_local_ipaddr(*newsock);
- char *raddr = get_peer_ipaddr(*newsock);
-
- verbose("drop connection #%d from [%s]:%d "
- "on [%s]:%d past MaxStartups", startups,
- raddr, get_peer_port(*newsock),
- laddr, get_local_port(*newsock));
- free(laddr);
- free(raddr);
- close(*newsock);
+ if (unset_nonblock(*newsock) == -1 ||
+ pipe(startup_p) == -1)
continue;
- }
- if (pipe(startup_p) == -1) {
+ if (drop_connection(*newsock, startups, startup_p[0])) {
close(*newsock);
+ close(startup_p[0]);
+ close(startup_p[1]);
continue;
}
@@ -1267,6 +1316,7 @@ server_accept_loop(int *sock_in, int *sock_out, int *newsock, int *config_s)
if (maxfd < startup_p[0])
maxfd = startup_p[0];
startups++;
+ startup_flags[j] = 1;
break;
}
@@ -1292,7 +1342,7 @@ server_accept_loop(int *sock_in, int *sock_out, int *newsock, int *config_s)
send_rexec_state(config_s[0], cfg);
close(config_s[0]);
}
- break;
+ return;
}
/*
@@ -1301,13 +1351,14 @@ server_accept_loop(int *sock_in, int *sock_out, int *newsock, int *config_s)
* parent continues listening.
*/
platform_pre_fork();
+ listening++;
if ((pid = fork()) == 0) {
/*
* Child. Close the listening and
* max_startup sockets. Start using
* the accepted socket. Reinitialize
* logging (since our pid has changed).
- * We break out of the loop to handle
+ * We return from this function to handle
* the connection.
*/
platform_post_fork_child();
@@ -1322,12 +1373,23 @@ server_accept_loop(int *sock_in, int *sock_out, int *newsock, int *config_s)
log_stderr);
if (rexec_flag)
close(config_s[0]);
- break;
+ else {
+ /*
+ * Signal parent that the preliminaries
+ * for this child are complete. For the
+ * re-exec case, this happens after the
+ * child has received the rexec state
+ * from the server.
+ */
+ (void)atomicio(vwrite, startup_pipe,
+ "\0", 1);
+ }
+ return;
}
/* Parent. Stay in the loop. */
platform_post_fork_parent(pid);
- if (pid < 0)
+ if (pid == -1)
error("fork: %.100s", strerror(errno));
else
debug("Forked child %ld.", (long)pid);
@@ -1335,9 +1397,9 @@ server_accept_loop(int *sock_in, int *sock_out, int *newsock, int *config_s)
close(startup_p[1]);
if (rexec_flag) {
+ close(config_s[1]);
send_rexec_state(config_s[0], cfg);
close(config_s[0]);
- close(config_s[1]);
}
close(*newsock);
@@ -1354,10 +1416,6 @@ server_accept_loop(int *sock_in, int *sock_out, int *newsock, int *config_s)
#endif
explicit_bzero(rnd, sizeof(rnd));
}
-
- /* child process check (or debug mode) */
- if (num_listen_socks < 0)
- break;
}
}
@@ -1384,7 +1442,7 @@ check_ip_options(struct ssh *ssh)
memset(&from, 0, sizeof(from));
if (getpeername(sock_in, (struct sockaddr *)&from,
- &fromlen) < 0)
+ &fromlen) == -1)
return;
if (from.ss_family != AF_INET)
return;
@@ -1437,7 +1495,7 @@ set_process_rdomain(struct ssh *ssh, const char *name)
if (rtable != ortable && setrtable(rtable) != 0)
fatal("Unable to set routing domain %d: %s",
rtable, strerror(errno));
- debug("%s: set routing domain %d (was %d)", __func__, rtable, ortable);
+ debug_f("set routing domain %d (was %d)", rtable, ortable);
#else /* defined(__OpenBSD__) */
fatal("Unable to set routing domain: not supported in this platform");
#endif
@@ -1445,7 +1503,7 @@ set_process_rdomain(struct ssh *ssh, const char *name)
static void
accumulate_host_timing_secret(struct sshbuf *server_cfg,
- const struct sshkey *key)
+ struct sshkey *key)
{
static struct ssh_digest_ctx *ctx;
u_char *hash;
@@ -1454,16 +1512,16 @@ accumulate_host_timing_secret(struct sshbuf *server_cfg,
int r;
if (ctx == NULL && (ctx = ssh_digest_start(SSH_DIGEST_SHA512)) == NULL)
- fatal("%s: ssh_digest_start", __func__);
+ fatal_f("ssh_digest_start");
if (key == NULL) { /* finalize */
/* add server config in case we are using agent for host keys */
if (ssh_digest_update(ctx, sshbuf_ptr(server_cfg),
sshbuf_len(server_cfg)) != 0)
- fatal("%s: ssh_digest_update", __func__);
+ fatal_f("ssh_digest_update");
len = ssh_digest_bytes(SSH_DIGEST_SHA512);
hash = xmalloc(len);
if (ssh_digest_final(ctx, hash, len) != 0)
- fatal("%s: ssh_digest_final", __func__);
+ fatal_f("ssh_digest_final");
options.timing_secret = PEEK_U64(hash);
freezero(hash, len);
ssh_digest_free(ctx);
@@ -1471,15 +1529,26 @@ accumulate_host_timing_secret(struct sshbuf *server_cfg,
return;
}
if ((buf = sshbuf_new()) == NULL)
- fatal("%s could not allocate buffer", __func__);
+ fatal_f("could not allocate buffer");
if ((r = sshkey_private_serialize(key, buf)) != 0)
- fatal("sshkey_private_serialize: %s", ssh_err(r));
+ fatal_fr(r, "decode key");
if (ssh_digest_update(ctx, sshbuf_ptr(buf), sshbuf_len(buf)) != 0)
- fatal("%s: ssh_digest_update", __func__);
+ fatal_f("ssh_digest_update");
sshbuf_reset(buf);
sshbuf_free(buf);
}
+static char *
+prepare_proctitle(int ac, char **av)
+{
+ char *ret = NULL;
+ int i;
+
+ for (i = 0; i < ac; i++)
+ xextendf(&ret, " ", "%s", av[i]);
+ return ret;
+}
+
/*
* Main program for the daemon.
*/
@@ -1503,8 +1572,6 @@ main(int ac, char **av)
Authctxt *authctxt;
struct connection_info *connection_info = NULL;
- ssh_malloc_init(); /* must be called before any mallocs */
-
#ifdef HAVE_SECUREWARE
(void)set_auth_parameters(ac, av);
#endif
@@ -1530,6 +1597,8 @@ main(int ac, char **av)
/* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */
sanitise_stdfd();
+ seed_rng();
+
/* Initialize configuration options to their default values. */
initialize_server_options(&options);
@@ -1608,7 +1677,7 @@ main(int ac, char **av)
break;
case 'h':
servconf_add_hostkey("[command-line]", 0,
- &options, optarg);
+ &options, optarg, 1);
break;
case 't':
test_flag = 1;
@@ -1617,7 +1686,7 @@ main(int ac, char **av)
test_flag = 2;
break;
case 'C':
- connection_info = get_connection_info(0, 0);
+ connection_info = get_connection_info(ssh, 0, 0);
if (parse_server_match_testspec(connection_info,
optarg) == -1)
exit(1);
@@ -1632,7 +1701,7 @@ main(int ac, char **av)
case 'o':
line = xstrdup(optarg);
if (process_server_config_line(&options, line,
- "command-line", 0, NULL, NULL) != 0)
+ "command-line", 0, NULL, NULL, &includes) != 0)
exit(1);
free(line);
break;
@@ -1644,17 +1713,13 @@ main(int ac, char **av)
}
if (rexeced_flag || inetd_flag)
rexec_flag = 0;
- if (!test_flag && (rexec_flag && (av[0] == NULL || *av[0] != '/')))
+ if (!test_flag && rexec_flag && !path_absolute(av[0]))
fatal("sshd re-exec requires execution with an absolute path");
if (rexeced_flag)
closefrom(REEXEC_MIN_FREE_FD);
else
closefrom(REEXEC_DEVCRYPTO_RESERVED_FD);
-#ifdef WITH_OPENSSL
- OpenSSL_add_all_algorithms();
-#endif
-
/* If requested, redirect the logs to the specified logfile. */
if (logfile != NULL)
log_redirect_stderr_to(logfile);
@@ -1667,7 +1732,7 @@ main(int ac, char **av)
SYSLOG_LEVEL_INFO : options.log_level,
options.log_facility == SYSLOG_FACILITY_NOT_SET ?
SYSLOG_FACILITY_AUTH : options.log_facility,
- log_stderr || !inetd_flag);
+ log_stderr || !inetd_flag || debug_flag);
/*
* Unset KRB5CCNAME, otherwise the user's session may inherit it from
@@ -1684,28 +1749,37 @@ main(int ac, char **av)
*/
if (test_flag < 2 && connection_info != NULL)
fatal("Config test connection parameter (-C) provided without "
- "test mode (-T)");
+ "test mode (-T)");
/* Fetch our configuration */
if ((cfg = sshbuf_new()) == NULL)
- fatal("%s: sshbuf_new failed", __func__);
- if (rexeced_flag)
+ fatal_f("sshbuf_new failed");
+ if (rexeced_flag) {
+ setproctitle("%s", "[rexeced]");
recv_rexec_state(REEXEC_CONFIG_PASS_FD, cfg);
- else if (strcasecmp(config_file_name, "none") != 0)
+ if (!debug_flag) {
+ startup_pipe = dup(REEXEC_STARTUP_PIPE_FD);
+ close(REEXEC_STARTUP_PIPE_FD);
+ /*
+ * Signal parent that this child is at a point where
+ * they can go away if they have a SIGHUP pending.
+ */
+ (void)atomicio(vwrite, startup_pipe, "\0", 1);
+ }
+ } else if (strcasecmp(config_file_name, "none") != 0)
load_server_config(config_file_name, cfg);
parse_server_config(&options, rexeced_flag ? "rexec" : config_file_name,
- cfg, NULL);
+ cfg, &includes, NULL);
- seed_rng();
+#ifdef WITH_OPENSSL
+ if (options.moduli_file != NULL)
+ dh_set_moduli_file(options.moduli_file);
+#endif
/* Fill in default values for those options not explicitly set. */
fill_default_server_options(&options);
- /* challenge-response is implemented via keyboard interactive */
- if (options.challenge_response_authentication)
- options.kbd_interactive_authentication = 1;
-
/* Check that options are sensible */
if (options.authorized_keys_command_user == NULL &&
(options.authorized_keys_command != NULL &&
@@ -1741,13 +1815,7 @@ main(int ac, char **av)
exit(1);
}
- debug("sshd version %s, %s", SSH_VERSION,
-#ifdef WITH_OPENSSL
- OpenSSL_version(OPENSSL_VERSION)
-#else
- "without OpenSSL"
-#endif
- );
+ debug("sshd version %s, %s", SSH_VERSION, SSH_OPENSSL_VERSION);
/* Store privilege separation user for later use if required. */
privsep_chroot = use_privsep && (getuid() == 0 || geteuid() == 0);
@@ -1775,25 +1843,50 @@ main(int ac, char **av)
if ((r = ssh_get_authentication_socket(NULL)) == 0)
have_agent = 1;
else
- error("Could not connect to agent \"%s\": %s",
- options.host_key_agent, ssh_err(r));
+ error_r(r, "Could not connect to agent \"%s\"",
+ options.host_key_agent);
}
for (i = 0; i < options.num_host_key_files; i++) {
+ int ll = options.host_key_file_userprovided[i] ?
+ SYSLOG_LEVEL_ERROR : SYSLOG_LEVEL_DEBUG1;
+
if (options.host_key_files[i] == NULL)
continue;
if ((r = sshkey_load_private(options.host_key_files[i], "",
&key, NULL)) != 0 && r != SSH_ERR_SYSTEM_ERROR)
- error("Error loading host key \"%s\": %s",
- options.host_key_files[i], ssh_err(r));
+ do_log2_r(r, ll, "Unable to load host key \"%s\"",
+ options.host_key_files[i]);
+ if (sshkey_is_sk(key) &&
+ key->sk_flags & SSH_SK_USER_PRESENCE_REQD) {
+ debug("host key %s requires user presence, ignoring",
+ options.host_key_files[i]);
+ key->sk_flags &= ~SSH_SK_USER_PRESENCE_REQD;
+ }
+ if (r == 0 && key != NULL &&
+ (r = sshkey_shield_private(key)) != 0) {
+ do_log2_r(r, ll, "Unable to shield host key \"%s\"",
+ options.host_key_files[i]);
+ sshkey_free(key);
+ key = NULL;
+ }
if ((r = sshkey_load_public(options.host_key_files[i],
&pubkey, NULL)) != 0 && r != SSH_ERR_SYSTEM_ERROR)
- error("Error loading host key \"%s\": %s",
- options.host_key_files[i], ssh_err(r));
- if (pubkey == NULL && key != NULL)
+ do_log2_r(r, ll, "Unable to load host key \"%s\"",
+ options.host_key_files[i]);
+ if (pubkey != NULL && key != NULL) {
+ if (!sshkey_equal(pubkey, key)) {
+ error("Public key for %s does not match "
+ "private key", options.host_key_files[i]);
+ sshkey_free(pubkey);
+ pubkey = NULL;
+ }
+ }
+ if (pubkey == NULL && key != NULL) {
if ((r = sshkey_from_private(key, &pubkey)) != 0)
- fatal("Could not demote key: \"%s\": %s",
- options.host_key_files[i], ssh_err(r));
+ fatal_r(r, "Could not demote key: \"%s\"",
+ options.host_key_files[i]);
+ }
sensitive_data.host_keys[i] = key;
sensitive_data.host_pubkeys[i] = pubkey;
@@ -1805,7 +1898,7 @@ main(int ac, char **av)
keytype = key->type;
accumulate_host_timing_secret(cfg, key);
} else {
- error("Could not load host key: %s",
+ do_log2(ll, "Unable to load host key: %s",
options.host_key_files[i]);
sensitive_data.host_keys[i] = NULL;
sensitive_data.host_pubkeys[i] = NULL;
@@ -1817,6 +1910,8 @@ main(int ac, char **av)
case KEY_DSA:
case KEY_ECDSA:
case KEY_ED25519:
+ case KEY_ECDSA_SK:
+ case KEY_ED25519_SK:
case KEY_XMSS:
if (have_agent || key != NULL)
sensitive_data.have_ssh2_key = 1;
@@ -1849,8 +1944,8 @@ main(int ac, char **av)
continue;
if ((r = sshkey_load_public(options.host_cert_files[i],
&key, NULL)) != 0) {
- error("Could not load host certificate \"%s\": %s",
- options.host_cert_files[i], ssh_err(r));
+ error_r(r, "Could not load host certificate \"%s\"",
+ options.host_cert_files[i]);
continue;
}
if (!sshkey_is_cert(key)) {
@@ -1862,7 +1957,7 @@ main(int ac, char **av)
/* Find matching private key */
for (j = 0; j < options.num_host_key_files; j++) {
if (sshkey_equal_public(key,
- sensitive_data.host_keys[j])) {
+ sensitive_data.host_pubkeys[j])) {
sensitive_data.host_certificates[j] = key;
break;
}
@@ -1903,8 +1998,9 @@ main(int ac, char **av)
* use a blank one that will cause no predicate to match.
*/
if (connection_info == NULL)
- connection_info = get_connection_info(0, 0);
- parse_server_match_config(&options, connection_info);
+ connection_info = get_connection_info(ssh, 0, 0);
+ connection_info->test = 1;
+ parse_server_match_config(&options, &includes, connection_info);
dump_config(&options);
}
@@ -1933,6 +2029,7 @@ main(int ac, char **av)
rexec_argv[rexec_argc] = "-R";
rexec_argv[rexec_argc + 1] = NULL;
}
+ listener_proctitle = prepare_proctitle(ac, av);
/* Ensure that umask disallows at least group and world write */
new_umask = umask(0077) | 0022;
@@ -1941,7 +2038,10 @@ main(int ac, char **av)
/* Initialize the log (it is reinitialized below in case we forked). */
if (debug_flag && (!inetd_flag || rexeced_flag))
log_stderr = 1;
- log_init(__progname, options.log_level, options.log_facility, log_stderr);
+ log_init(__progname, options.log_level,
+ options.log_facility, log_stderr);
+ for (i = 0; i < options.num_log_verbose; i++)
+ log_verbose_add(options.log_verbose[i]);
/*
* If not in debugging mode, not started from inetd and not already
@@ -1951,7 +2051,7 @@ main(int ac, char **av)
already_daemon = daemonized();
if (!(debug_flag || inetd_flag || no_daemon_flag || already_daemon)) {
- if (daemon(0, 0) < 0)
+ if (daemon(0, 0) == -1)
fatal("daemon() failed: %.200s", strerror(errno));
disconnect_controlling_tty();
@@ -1963,13 +2063,15 @@ main(int ac, char **av)
if (!inetd_flag && madvise(NULL, 0, MADV_PROTECT) != 0)
debug("madvise(): %.200s", strerror(errno));
- /* Chdir to the root directory so that the current disk can be
- unmounted if desired. */
+ /*
+ * Chdir to the root directory so that the current disk can be
+ * unmounted if desired.
+ */
if (chdir("/") == -1)
error("chdir(\"/\"): %s", strerror(errno));
/* ignore SIGPIPE */
- signal(SIGPIPE, SIG_IGN);
+ ssh_signal(SIGPIPE, SIG_IGN);
/* Get a connection, either from inetd or a listening TCP socket */
if (inetd_flag) {
@@ -1978,10 +2080,10 @@ main(int ac, char **av)
platform_pre_listen();
server_listen();
- signal(SIGHUP, sighup_handler);
- signal(SIGCHLD, main_sigchld_handler);
- signal(SIGTERM, sigterm_handler);
- signal(SIGQUIT, sigterm_handler);
+ ssh_signal(SIGHUP, sighup_handler);
+ ssh_signal(SIGCHLD, main_sigchld_handler);
+ ssh_signal(SIGTERM, sigterm_handler);
+ ssh_signal(SIGQUIT, sigterm_handler);
/*
* Write out the pid file after the sigterm handler
@@ -2018,13 +2120,11 @@ main(int ac, char **av)
* controlling terminal which will result in "could not set
* controlling tty" errors.
*/
- if (!debug_flag && !inetd_flag && setsid() < 0)
+ if (!debug_flag && !inetd_flag && setsid() == -1)
error("setsid: %.100s", strerror(errno));
#endif
if (rexec_flag) {
- int fd;
-
debug("rexec start in %d out %d newsock %d pipe %d sock %d",
sock_in, sock_out, newsock, startup_pipe, config_s[0]);
dup2(newsock, STDIN_FILENO);
@@ -2040,6 +2140,7 @@ main(int ac, char **av)
dup2(config_s[1], REEXEC_CONFIG_PASS_FD);
close(config_s[1]);
+ ssh_signal(SIGHUP, SIG_IGN); /* avoid reset to SIG_DFL */
execv(rexec_argv[0], rexec_argv);
/* Reexec has failed, fall back and continue */
@@ -2051,12 +2152,8 @@ main(int ac, char **av)
/* Clean up fds */
close(REEXEC_CONFIG_PASS_FD);
newsock = sock_out = sock_in = dup(STDIN_FILENO);
- if ((fd = open(_PATH_DEVNULL, O_RDWR, 0)) != -1) {
- dup2(fd, STDIN_FILENO);
- dup2(fd, STDOUT_FILENO);
- if (fd > STDERR_FILENO)
- close(fd);
- }
+ if (stdfd_devnull(1, 1, 0) == -1)
+ error_f("stdfd_devnull failed");
debug("rexec cleanup in %d out %d newsock %d pipe %d sock %d",
sock_in, sock_out, newsock, startup_pipe, config_s[0]);
}
@@ -2065,18 +2162,13 @@ main(int ac, char **av)
fcntl(sock_out, F_SETFD, FD_CLOEXEC);
fcntl(sock_in, F_SETFD, FD_CLOEXEC);
- /*
- * Disable the key regeneration alarm. We will not regenerate the
- * key since we are no longer in a position to give it to anyone. We
- * will not restart on SIGHUP since it no longer makes sense.
- */
- alarm(0);
- signal(SIGALRM, SIG_DFL);
- signal(SIGHUP, SIG_DFL);
- signal(SIGTERM, SIG_DFL);
- signal(SIGQUIT, SIG_DFL);
- signal(SIGCHLD, SIG_DFL);
- signal(SIGINT, SIG_DFL);
+ /* We will not restart on SIGHUP since it no longer makes sense. */
+ ssh_signal(SIGALRM, SIG_DFL);
+ ssh_signal(SIGHUP, SIG_DFL);
+ ssh_signal(SIGTERM, SIG_DFL);
+ ssh_signal(SIGQUIT, SIG_DFL);
+ ssh_signal(SIGCHLD, SIG_DFL);
+ ssh_signal(SIGINT, SIG_DFL);
#ifdef __FreeBSD__
/*
@@ -2105,9 +2197,10 @@ main(int ac, char **av)
* Register our connection. This turns encryption off because we do
* not have a key.
*/
- packet_set_connection(sock_in, sock_out);
- packet_set_server();
- ssh = active_state; /* XXX */
+ if ((ssh = ssh_packet_set_connection(NULL, sock_in, sock_out)) == NULL)
+ fatal("Unable to create connection");
+ the_active_state = ssh;
+ ssh_packet_set_server(ssh);
check_ip_options(ssh);
@@ -2117,8 +2210,8 @@ main(int ac, char **av)
process_permitopen(ssh, &options);
/* Set SO_KEEPALIVE if requested. */
- if (options.tcp_keep_alive && packet_connection_is_on_socket() &&
- setsockopt(sock_in, SOL_SOCKET, SO_KEEPALIVE, &on, sizeof(on)) < 0)
+ if (options.tcp_keep_alive && ssh_packet_connection_is_on_socket(ssh) &&
+ setsockopt(sock_in, SOL_SOCKET, SO_KEEPALIVE, &on, sizeof(on)) == -1)
error("setsockopt SO_KEEPALIVE: %.100s", strerror(errno));
if ((remote_port = ssh_remote_port(ssh)) < 0) {
@@ -2148,7 +2241,7 @@ main(int ac, char **av)
allow_severity = options.log_facility|LOG_INFO;
deny_severity = options.log_facility|LOG_WARNING;
/* Check whether logins are denied from this host. */
- if (packet_connection_is_on_socket()) {
+ if (ssh_packet_connection_is_on_socket(ssh)) {
struct request_info req;
request_init(&req, RQ_DAEMON, __progname, RQ_FILE, sock_in, 0);
@@ -2182,15 +2275,19 @@ main(int ac, char **av)
* mode; it is just annoying to have the server exit just when you
* are about to discover the bug.
*/
- signal(SIGALRM, grace_alarm_handler);
+ ssh_signal(SIGALRM, grace_alarm_handler);
if (!debug_flag)
alarm(options.login_grace_time);
- sshd_exchange_identification(ssh, sock_in, sock_out);
- packet_set_nonblocking();
+ if ((r = kex_exchange_identification(ssh, -1,
+ options.version_addendum)) != 0)
+ sshpkt_fatal(ssh, r, "banner exchange");
+
+ ssh_packet_set_nonblocking(ssh);
/* allocate authentication context */
authctxt = xcalloc(1, sizeof(*authctxt));
+ ssh->authctxt = authctxt;
authctxt->loginmsg = loginmsg;
@@ -2203,33 +2300,33 @@ main(int ac, char **av)
/* prepare buffer to collect messages to display to user after login */
if ((loginmsg = sshbuf_new()) == NULL)
- fatal("%s: sshbuf_new failed", __func__);
+ fatal_f("sshbuf_new failed");
auth_debug_reset();
BLACKLIST_INIT();
if (use_privsep) {
- if (privsep_preauth(authctxt) == 1)
+ if (privsep_preauth(ssh) == 1)
goto authenticated;
} else if (have_agent) {
if ((r = ssh_get_authentication_socket(&auth_sock)) != 0) {
- error("Unable to get agent socket: %s", ssh_err(r));
+ error_r(r, "Unable to get agent socket");
have_agent = 0;
}
}
/* perform the key exchange */
/* authenticate user and start session */
- do_ssh2_kex();
- do_authentication2(authctxt);
+ do_ssh2_kex(ssh);
+ do_authentication2(ssh);
/*
* If we use privilege separation, the unprivileged child transfers
* the current keystate and exits
*/
if (use_privsep) {
- mm_send_keystate(pmonitor);
- packet_clear_keys();
+ mm_send_keystate(ssh, pmonitor);
+ ssh_packet_clear_keys(ssh);
exit(0);
}
@@ -2239,7 +2336,7 @@ main(int ac, char **av)
* authentication.
*/
alarm(0);
- signal(SIGALRM, SIG_DFL);
+ ssh_signal(SIGALRM, SIG_DFL);
authctxt->authenticated = 1;
if (startup_pipe != -1) {
close(startup_pipe);
@@ -2247,7 +2344,7 @@ main(int ac, char **av)
}
#ifdef SSH_AUDIT_EVENTS
- audit_event(SSH_AUTH_SUCCESS);
+ audit_event(ssh, SSH_AUTH_SUCCESS);
#endif
#ifdef GSSAPI
@@ -2269,11 +2366,11 @@ main(int ac, char **av)
* file descriptor passing.
*/
if (use_privsep) {
- privsep_postauth(authctxt);
+ privsep_postauth(ssh, authctxt);
/* the monitor process [priv] will not return */
}
- packet_set_timeout(options.client_alive_interval,
+ ssh_packet_set_timeout(ssh, options.client_alive_interval,
options.client_alive_count_max);
/* Try to send all our hostkeys to the client */
@@ -2283,7 +2380,7 @@ main(int ac, char **av)
do_authenticated(ssh, authctxt);
/* The connection has been terminated. */
- packet_get_bytes(&ibytes, &obytes);
+ ssh_packet_get_bytes(ssh, &ibytes, &obytes);
verbose("Transferred: sent %llu, received %llu bytes",
(unsigned long long)obytes, (unsigned long long)ibytes);
@@ -2295,10 +2392,10 @@ main(int ac, char **av)
#endif /* USE_PAM */
#ifdef SSH_AUDIT_EVENTS
- PRIVSEP(audit_event(SSH_CONNECTION_CLOSE));
+ PRIVSEP(audit_event(ssh, SSH_CONNECTION_CLOSE));
#endif
- packet_close();
+ ssh_packet_close(ssh);
if (use_privsep)
mm_terminate();
@@ -2307,42 +2404,53 @@ main(int ac, char **av)
}
int
-sshd_hostkey_sign(struct sshkey *privkey, struct sshkey *pubkey,
- u_char **signature, size_t *slenp, const u_char *data, size_t dlen,
- const char *alg, u_int flag)
+sshd_hostkey_sign(struct ssh *ssh, struct sshkey *privkey,
+ struct sshkey *pubkey, u_char **signature, size_t *slenp,
+ const u_char *data, size_t dlen, const char *alg)
{
int r;
- if (privkey) {
- if (PRIVSEP(sshkey_sign(privkey, signature, slenp, data, dlen,
- alg, datafellows)) < 0)
- fatal("%s: key_sign failed", __func__);
- } else if (use_privsep) {
- if (mm_sshkey_sign(pubkey, signature, slenp, data, dlen,
- alg, datafellows) < 0)
- fatal("%s: pubkey_sign failed", __func__);
+ if (use_privsep) {
+ if (privkey) {
+ if (mm_sshkey_sign(ssh, privkey, signature, slenp,
+ data, dlen, alg, options.sk_provider, NULL,
+ ssh->compat) < 0)
+ fatal_f("privkey sign failed");
+ } else {
+ if (mm_sshkey_sign(ssh, pubkey, signature, slenp,
+ data, dlen, alg, options.sk_provider, NULL,
+ ssh->compat) < 0)
+ fatal_f("pubkey sign failed");
+ }
} else {
- if ((r = ssh_agent_sign(auth_sock, pubkey, signature, slenp,
- data, dlen, alg, datafellows)) != 0)
- fatal("%s: ssh_agent_sign failed: %s",
- __func__, ssh_err(r));
+ if (privkey) {
+ if (sshkey_sign(privkey, signature, slenp, data, dlen,
+ alg, options.sk_provider, NULL, ssh->compat) < 0)
+ fatal_f("privkey sign failed");
+ } else {
+ if ((r = ssh_agent_sign(auth_sock, pubkey,
+ signature, slenp, data, dlen, alg,
+ ssh->compat)) != 0) {
+ fatal_fr(r, "agent sign failed");
+ }
+ }
}
return 0;
}
/* SSH2 key exchange */
static void
-do_ssh2_kex(void)
+do_ssh2_kex(struct ssh *ssh)
{
char *myproposal[PROPOSAL_MAX] = { KEX_SERVER };
struct kex *kex;
int r;
- myproposal[PROPOSAL_KEX_ALGS] = compat_kex_proposal(
+ myproposal[PROPOSAL_KEX_ALGS] = compat_kex_proposal(ssh,
options.kex_algorithms);
- myproposal[PROPOSAL_ENC_ALGS_CTOS] = compat_cipher_proposal(
+ myproposal[PROPOSAL_ENC_ALGS_CTOS] = compat_cipher_proposal(ssh,
options.ciphers);
- myproposal[PROPOSAL_ENC_ALGS_STOC] = compat_cipher_proposal(
+ myproposal[PROPOSAL_ENC_ALGS_STOC] = compat_cipher_proposal(ssh,
options.ciphers);
myproposal[PROPOSAL_MAC_ALGS_CTOS] =
myproposal[PROPOSAL_MAC_ALGS_STOC] = options.macs;
@@ -2353,48 +2461,44 @@ do_ssh2_kex(void)
}
if (options.rekey_limit || options.rekey_interval)
- packet_set_rekey_limits(options.rekey_limit,
+ ssh_packet_set_rekey_limits(ssh, options.rekey_limit,
options.rekey_interval);
myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = compat_pkalg_proposal(
- list_hostkey_types());
+ ssh, list_hostkey_types());
/* start key exchange */
- if ((r = kex_setup(active_state, myproposal)) != 0)
- fatal("kex_setup: %s", ssh_err(r));
- kex = active_state->kex;
+ if ((r = kex_setup(ssh, myproposal)) != 0)
+ fatal_r(r, "kex_setup");
+ kex = ssh->kex;
#ifdef WITH_OPENSSL
- kex->kex[KEX_DH_GRP1_SHA1] = kexdh_server;
- kex->kex[KEX_DH_GRP14_SHA1] = kexdh_server;
- kex->kex[KEX_DH_GRP14_SHA256] = kexdh_server;
- kex->kex[KEX_DH_GRP16_SHA512] = kexdh_server;
- kex->kex[KEX_DH_GRP18_SHA512] = kexdh_server;
+ kex->kex[KEX_DH_GRP1_SHA1] = kex_gen_server;
+ kex->kex[KEX_DH_GRP14_SHA1] = kex_gen_server;
+ kex->kex[KEX_DH_GRP14_SHA256] = kex_gen_server;
+ kex->kex[KEX_DH_GRP16_SHA512] = kex_gen_server;
+ kex->kex[KEX_DH_GRP18_SHA512] = kex_gen_server;
kex->kex[KEX_DH_GEX_SHA1] = kexgex_server;
kex->kex[KEX_DH_GEX_SHA256] = kexgex_server;
# ifdef OPENSSL_HAS_ECC
- kex->kex[KEX_ECDH_SHA2] = kexecdh_server;
+ kex->kex[KEX_ECDH_SHA2] = kex_gen_server;
# endif
#endif
- kex->kex[KEX_C25519_SHA256] = kexc25519_server;
- kex->server = 1;
- kex->client_version_string=client_version_string;
- kex->server_version_string=server_version_string;
+ kex->kex[KEX_C25519_SHA256] = kex_gen_server;
+ kex->kex[KEX_KEM_SNTRUP761X25519_SHA512] = kex_gen_server;
kex->load_host_public_key=&get_hostkey_public_by_type;
kex->load_host_private_key=&get_hostkey_private_by_type;
kex->host_key_index=&get_hostkey_index;
kex->sign = sshd_hostkey_sign;
- ssh_dispatch_run_fatal(active_state, DISPATCH_BLOCK, &kex->done);
-
- session_id2 = kex->session_id;
- session_id2_len = kex->session_id_len;
+ ssh_dispatch_run_fatal(ssh, DISPATCH_BLOCK, &kex->done);
#ifdef DEBUG_KEXDH
/* send 1st encrypted/maced/compressed message */
- packet_start(SSH2_MSG_IGNORE);
- packet_put_cstring("markus");
- packet_send();
- packet_write_wait();
+ if ((r = sshpkt_start(ssh, SSH2_MSG_IGNORE)) != 0 ||
+ (r = sshpkt_put_cstring(ssh, "markus")) != 0 ||
+ (r = sshpkt_send(ssh)) != 0 ||
+ (r = ssh_packet_write_wait(ssh)) != 0)
+ fatal_fr(r, "send test");
#endif
debug("KEX done");
}
@@ -2403,23 +2507,22 @@ do_ssh2_kex(void)
void
cleanup_exit(int i)
{
- struct ssh *ssh = active_state; /* XXX */
-
- if (the_authctxt) {
- do_cleanup(ssh, the_authctxt);
+ if (the_active_state != NULL && the_authctxt != NULL) {
+ do_cleanup(the_active_state, the_authctxt);
if (use_privsep && privsep_is_preauth &&
pmonitor != NULL && pmonitor->m_pid > 1) {
debug("Killing privsep child %d", pmonitor->m_pid);
if (kill(pmonitor->m_pid, SIGKILL) != 0 &&
- errno != ESRCH)
- error("%s: kill(%d): %s", __func__,
- pmonitor->m_pid, strerror(errno));
+ errno != ESRCH) {
+ error_f("kill(%d): %s", pmonitor->m_pid,
+ strerror(errno));
+ }
}
}
#ifdef SSH_AUDIT_EVENTS
/* done after do_cleanup so it can cancel the PAM auth 'thread' */
- if (!use_privsep || mm_is_monitor())
- audit_event(SSH_CONNECTION_ABANDON);
+ if (the_active_state != NULL && (!use_privsep || mm_is_monitor()))
+ audit_event(the_active_state, SSH_CONNECTION_ABANDON);
#endif
_exit(i);
}
diff --git a/crypto/openssh/sshd_config b/crypto/openssh/sshd_config
index 4f636bc5c13b..7555b01be832 100644
--- a/crypto/openssh/sshd_config
+++ b/crypto/openssh/sshd_config
@@ -1,4 +1,4 @@
-# $OpenBSD: sshd_config,v 1.103 2018/04/09 20:41:22 tj Exp $
+# $OpenBSD: sshd_config,v 1.104 2021/07/02 05:11:21 dtucker Exp $
# $FreeBSD$
# This is the sshd server system-wide configuration file. See
@@ -62,7 +62,7 @@ AuthorizedKeysFile .ssh/authorized_keys
#PermitEmptyPasswords no
# Change to no to disable PAM authentication
-#ChallengeResponseAuthentication yes
+#KbdInteractiveAuthentication yes
# Kerberos options
#KerberosAuthentication no
@@ -76,13 +76,13 @@ AuthorizedKeysFile .ssh/authorized_keys
# Set this to 'no' to disable PAM authentication, account processing,
# and session processing. If this is enabled, PAM authentication will
-# be allowed through the ChallengeResponseAuthentication and
+# be allowed through the KbdInteractiveAuthentication and
# PasswordAuthentication. Depending on your PAM configuration,
-# PAM authentication via ChallengeResponseAuthentication may bypass
+# PAM authentication via KbdInteractiveAuthentication may bypass
# the setting of "PermitRootLogin without-password".
# If you just want the PAM account and session checks to run without
# PAM authentication, then enable this but set PasswordAuthentication
-# and ChallengeResponseAuthentication to 'no'.
+# and KbdInteractiveAuthentication to 'no'.
#UsePAM yes
#AllowAgentForwarding yes
@@ -105,7 +105,7 @@ AuthorizedKeysFile .ssh/authorized_keys
#PermitTunnel no
#ChrootDirectory none
#UseBlacklist no
-#VersionAddendum FreeBSD-20200214
+#VersionAddendum FreeBSD-20210907
# no default banner path
#Banner none
diff --git a/crypto/openssh/sshd_config.5 b/crypto/openssh/sshd_config.5
index 0ae5e665af3d..c3a747061b8e 100644
--- a/crypto/openssh/sshd_config.5
+++ b/crypto/openssh/sshd_config.5
@@ -33,14 +33,14 @@
.\" (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: sshd_config.5,v 1.282 2018/09/20 03:28:06 djm Exp $
+.\" $OpenBSD: sshd_config.5,v 1.334 2021/08/12 23:59:25 djm Exp $
.\" $FreeBSD$
-.Dd $Mdocdate: July 28 2020 $
+.Dd $Mdocdate: August 12 2021 $
.Dt SSHD_CONFIG 5
.Os
.Sh NAME
.Nm sshd_config
-.Nd OpenSSH SSH daemon configuration file
+.Nd OpenSSH daemon configuration file
.Sh DESCRIPTION
.Xr sshd 8
reads configuration data from
@@ -114,11 +114,8 @@ If specified, login is allowed only for users whose primary
group or supplementary group list matches one of the patterns.
Only group names are valid; a numerical group ID is not recognized.
By default, login is allowed for all groups.
-The allow/deny directives are processed in the following order:
-.Cm DenyUsers ,
-.Cm AllowUsers ,
+The allow/deny groups directives are processed in the following order:
.Cm DenyGroups ,
-and finally
.Cm AllowGroups .
.Pp
See PATTERNS in
@@ -174,12 +171,9 @@ are separately checked, restricting logins to particular
users from particular hosts.
HOST criteria may additionally contain addresses to match in CIDR
address/masklen format.
-The allow/deny directives are processed in the following order:
+The allow/deny users directives are processed in the following order:
.Cm DenyUsers ,
-.Cm AllowUsers ,
-.Cm DenyGroups ,
-and finally
-.Cm AllowGroups .
+.Cm AllowUsers .
.Pp
See PATTERNS in
.Xr ssh_config 5
@@ -254,12 +248,10 @@ more lines of authorized_keys output (see
.Sx AUTHORIZED_KEYS
in
.Xr sshd 8 ) .
-If a key supplied by
.Cm AuthorizedKeysCommand
-does not successfully authenticate
-and authorize the user then public key authentication continues using the usual
+is tried after the usual
.Cm AuthorizedKeysFile
-files.
+files and will not be executed if a matching key is found there.
By default, no
.Cm AuthorizedKeysCommand
is run.
@@ -278,9 +270,7 @@ is not, then
will refuse to start.
.It Cm AuthorizedKeysFile
Specifies the file that contains the public keys used for user authentication.
-The format is described in the
-.Sx AUTHORIZED_KEYS FILE FORMAT
-section of
+The format is described in the AUTHORIZED_KEYS FILE FORMAT section of
.Xr sshd 8 .
Arguments to
.Cm AuthorizedKeysFile
@@ -388,18 +378,24 @@ Specifies which algorithms are allowed for signing of certificates
by certificate authorities (CAs).
The default is:
.Bd -literal -offset indent
-ecdsa-sha2-nistp256.ecdsa-sha2-nistp384,ecdsa-sha2-nistp521,
-ssh-ed25519,rsa-sha2-512,rsa-sha2-256,ssh-rsa
+ssh-ed25519,ecdsa-sha2-nistp256,
+ecdsa-sha2-nistp384,ecdsa-sha2-nistp521,
+sk-ssh-ed25519@openssh.com,
+sk-ecdsa-sha2-nistp256@openssh.com,
+rsa-sha2-512,rsa-sha2-256
.Ed
.Pp
+If the specified list begins with a
+.Sq +
+character, then the specified algorithms will be appended to the default set
+instead of replacing them.
+If the specified list begins with a
+.Sq -
+character, then the specified algorithms (including wildcards) will be removed
+from the default set instead of replacing them.
+.Pp
Certificates signed using other algorithms will not be accepted for
public key or host-based authentication.
-.It Cm ChallengeResponseAuthentication
-Specifies whether challenge-response authentication is allowed (e.g. via
-PAM or through authentication styles supported in
-.Xr login.conf 5 )
-The default is
-.Cm yes .
.It Cm ChrootDirectory
Specifies the pathname of a directory to
.Xr chroot 2
@@ -457,14 +453,18 @@ indicating not to
.It Cm Ciphers
Specifies the ciphers allowed.
Multiple ciphers must be comma-separated.
-If the specified value begins with a
+If the specified list begins with a
.Sq +
character, then the specified ciphers will be appended to the default set
instead of replacing them.
-If the specified value begins with a
+If the specified list begins with a
.Sq -
character, then the specified ciphers (including wildcards) will be removed
from the default set instead of replacing them.
+If the specified list begins with a
+.Sq ^
+character, then the specified ciphers will be placed at the head of the
+default set.
.Pp
The supported ciphers are:
.Pp
@@ -515,7 +515,7 @@ The TCP keepalive option enabled by
.Cm TCPKeepAlive
is spoofable.
The client alive mechanism is valuable when the client or
-server depend on knowing when a connection has become inactive.
+server depend on knowing when a connection has become unresponsive.
.Pp
The default value is 3.
If
@@ -524,6 +524,9 @@ is set to 15, and
.Cm ClientAliveCountMax
is left at the default, unresponsive SSH clients
will be disconnected after approximately 45 seconds.
+Setting a zero
+.Cm ClientAliveCountMax
+disables connection termination.
.It Cm ClientAliveInterval
Sets a timeout interval in seconds after which if no data has been received
from the client,
@@ -551,11 +554,8 @@ Login is disallowed for users whose primary group or supplementary
group list matches one of the patterns.
Only group names are valid; a numerical group ID is not recognized.
By default, login is allowed for all groups.
-The allow/deny directives are processed in the following order:
-.Cm DenyUsers ,
-.Cm AllowUsers ,
+The allow/deny groups directives are processed in the following order:
.Cm DenyGroups ,
-and finally
.Cm AllowGroups .
.Pp
See PATTERNS in
@@ -572,12 +572,9 @@ are separately checked, restricting logins to particular
users from particular hosts.
HOST criteria may additionally contain addresses to match in CIDR
address/masklen format.
-The allow/deny directives are processed in the following order:
+The allow/deny users directives are processed in the following order:
.Cm DenyUsers ,
-.Cm AllowUsers ,
-.Cm DenyGroups ,
-and finally
-.Cm AllowGroups .
+.Cm AllowUsers .
.Pp
See PATTERNS in
.Xr ssh_config 5
@@ -668,31 +665,42 @@ machine's default store.
This facility is provided to assist with operation on multi homed machines.
The default is
.Cm yes .
-.It Cm HostbasedAcceptedKeyTypes
-Specifies the key types that will be accepted for hostbased authentication
-as a list of comma-separated patterns.
-Alternately if the specified value begins with a
+.It Cm HostbasedAcceptedAlgorithms
+Specifies the signature algorithms that will be accepted for hostbased
+authentication as a list of comma-separated patterns.
+Alternately if the specified list begins with a
.Sq +
-character, then the specified key types will be appended to the default set
-instead of replacing them.
-If the specified value begins with a
+character, then the specified signature algorithms will be appended to
+the default set instead of replacing them.
+If the specified list begins with a
.Sq -
-character, then the specified key types (including wildcards) will be removed
-from the default set instead of replacing them.
+character, then the specified signature algorithms (including wildcards)
+will be removed from the default set instead of replacing them.
+If the specified list begins with a
+.Sq ^
+character, then the specified signature algorithms will be placed at
+the head of the default set.
The default for this option is:
.Bd -literal -offset 3n
+ssh-ed25519-cert-v01@openssh.com,
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,
-rsa-sha2-512-cert-v01@openssh.com,rsa-sha2-256-cert-v01@openssh.com,
+sk-ssh-ed25519-cert-v01@openssh.com,
+sk-ecdsa-sha2-nistp256-cert-v01@openssh.com,
+rsa-sha2-512-cert-v01@openssh.com,
+rsa-sha2-256-cert-v01@openssh.com,
ssh-rsa-cert-v01@openssh.com,
+ssh-ed25519,
ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521,
-ssh-ed25519,rsa-sha2-512,rsa-sha2-256,ssh-rsa
+sk-ssh-ed25519@openssh.com,
+sk-ecdsa-sha2-nistp256@openssh.com,
+rsa-sha2-512,rsa-sha2-256,ssh-rsa
.Ed
.Pp
-The list of available key types may also be obtained using
-.Qq ssh -Q key .
+The list of available signature algorithms may also be obtained using
+.Qq ssh -Q HostbasedAcceptedAlgorithms .
+This was formerly named HostbasedAcceptedKeyTypes.
.It Cm HostbasedAuthentication
Specifies whether rhosts or /etc/hosts.equiv authentication together
with successful public key client host authentication is allowed
@@ -755,36 +763,55 @@ is specified, the location of the socket will be read from the
.Ev SSH_AUTH_SOCK
environment variable.
.It Cm HostKeyAlgorithms
-Specifies the host key algorithms
+Specifies the host key signature algorithms
that the server offers.
The default for this option is:
.Bd -literal -offset 3n
+ssh-ed25519-cert-v01@openssh.com,
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,
-rsa-sha2-512-cert-v01@openssh.com,rsa-sha2-256-cert-v01@openssh.com,
+sk-ssh-ed25519-cert-v01@openssh.com,
+sk-ecdsa-sha2-nistp256-cert-v01@openssh.com,
+rsa-sha2-512-cert-v01@openssh.com,
+rsa-sha2-256-cert-v01@openssh.com,
ssh-rsa-cert-v01@openssh.com,
+ssh-ed25519,
ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521,
-ssh-ed25519,rsa-sha2-512,rsa-sha2-256,ssh-rsa
+sk-ssh-ed25519@openssh.com,
+sk-ecdsa-sha2-nistp256@openssh.com,
+rsa-sha2-512,rsa-sha2-256,ssh-rsa
.Ed
.Pp
-The list of available key types may also be obtained using
-.Qq ssh -Q key .
+The list of available signature algorithms may also be obtained using
+.Qq ssh -Q HostKeyAlgorithms .
.It Cm IgnoreRhosts
-Specifies that
+Specifies whether to ignore per-user
.Pa .rhosts
and
.Pa .shosts
-files will not be used in
+files during
.Cm HostbasedAuthentication .
-.Pp
+The system-wide
.Pa /etc/hosts.equiv
and
.Pa /etc/ssh/shosts.equiv
-are still used.
-The default is
-.Cm yes .
+are still used regardless of this setting.
+.Pp
+Accepted values are
+.Cm yes
+(the default) to ignore all per-user files,
+.Cm shosts-only
+to allow the use of
+.Pa .shosts
+but to ignore
+.Pa .rhosts
+or
+.Cm no
+to allow both
+.Pa .shosts
+and
+.Pa rhosts .
.It Cm IgnoreUserKnownHosts
Specifies whether
.Xr sshd 8
@@ -795,7 +822,20 @@ during
and use only the system-wide known hosts file
.Pa /etc/ssh/known_hosts .
The default is
-.Cm no .
+.Dq no .
+.It Cm Include
+Include the specified configuration file(s).
+Multiple pathnames may be specified and each pathname may contain
+.Xr glob 7
+wildcards that will be expanded and processed in lexical order.
+Files without absolute paths are assumed to be in
+.Pa /etc/ssh .
+An
+.Cm Include
+directive may appear inside a
+.Cm Match
+block
+to perform conditional inclusion.
.It Cm IPQoS
Specifies the IPv4 type-of-service or DSCP class for the connection.
Accepted values are
@@ -820,6 +860,7 @@ Accepted values are
.Cm cs6 ,
.Cm cs7 ,
.Cm ef ,
+.Cm le ,
.Cm lowdelay ,
.Cm throughput ,
.Cm reliability ,
@@ -839,15 +880,17 @@ for interactive sessions and
for non-interactive sessions.
.It Cm KbdInteractiveAuthentication
Specifies whether to allow keyboard-interactive authentication.
+All authentication styles from
+.Xr login.conf 5
+are supported.
+The default is
+.Cm yes .
The argument to this keyword must be
.Cm yes
or
.Cm no .
-The default is to use whatever value
.Cm ChallengeResponseAuthentication
-is set to
-(by default
-.Cm yes ) .
+is a deprecated alias for this.
.It Cm KerberosAuthentication
Specifies whether the password provided by the user for
.Cm PasswordAuthentication
@@ -876,14 +919,18 @@ The default is
.It Cm KexAlgorithms
Specifies the available KEX (Key Exchange) algorithms.
Multiple algorithms must be comma-separated.
-Alternately if the specified value begins with a
+Alternately if the specified list begins with a
.Sq +
character, then the specified methods will be appended to the default set
instead of replacing them.
-If the specified value begins with a
+If the specified list begins with a
.Sq -
character, then the specified methods (including wildcards) will be removed
from the default set instead of replacing them.
+If the specified list begins with a
+.Sq ^
+character, then the specified methods will be placed at the head of the
+default set.
The supported algorithms are:
.Pp
.Bl -item -compact -offset indent
@@ -911,6 +958,8 @@ ecdh-sha2-nistp256
ecdh-sha2-nistp384
.It
ecdh-sha2-nistp521
+.It
+sntrup761x25519-sha512@openssh.com
.El
.Pp
The default is:
@@ -919,11 +968,11 @@ curve25519-sha256,curve25519-sha256@libssh.org,
ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,
diffie-hellman-group-exchange-sha256,
diffie-hellman-group16-sha512,diffie-hellman-group18-sha512,
-diffie-hellman-group14-sha256,diffie-hellman-group14-sha1
+diffie-hellman-group14-sha256
.Ed
.Pp
The list of available key exchange algorithms may also be obtained using
-.Qq ssh -Q kex .
+.Qq ssh -Q KexAlgorithms .
.It Cm ListenAddress
Specifies the local addresses
.Xr sshd 8
@@ -989,18 +1038,39 @@ The default is INFO.
DEBUG and DEBUG1 are equivalent.
DEBUG2 and DEBUG3 each specify higher levels of debugging output.
Logging with a DEBUG level violates the privacy of users and is not recommended.
+.It Cm LogVerbose
+Specify one or more overrides to LogLevel.
+An override consists of a pattern lists that matches the source file, function
+and line number to force detailed logging for.
+For example, an override pattern of:
+.Bd -literal -offset indent
+kex.c:*:1000,*:kex_exchange_identification():*,packet.c:*
+.Ed
+.Pp
+would enable detailed logging for line 1000 of
+.Pa kex.c ,
+everything in the
+.Fn kex_exchange_identification
+function, and all code in the
+.Pa packet.c
+file.
+This option is intended for debugging and no overrides are enabled by default.
.It Cm MACs
Specifies the available MAC (message authentication code) algorithms.
The MAC algorithm is used for data integrity protection.
Multiple algorithms must be comma-separated.
-If the specified value begins with a
+If the specified list begins with a
.Sq +
character, then the specified algorithms will be appended to the default set
instead of replacing them.
-If the specified value begins with a
+If the specified list begins with a
.Sq -
character, then the specified algorithms (including wildcards) will be removed
from the default set instead of replacing them.
+If the specified list begins with a
+.Sq ^
+character, then the specified algorithms will be placed at the head of the
+default set.
.Pp
The algorithms that contain
.Qq -etm
@@ -1085,7 +1155,7 @@ and
.Cm RDomain
representing the
.Xr rdomain 4
-on which the connection was received.)
+on which the connection was received).
.Pp
The match patterns may consist of single entries or comma-separated
lists and may use the wildcard and negation operators described in the
@@ -1126,12 +1196,15 @@ Available keywords are
.Cm ClientAliveInterval ,
.Cm DenyGroups ,
.Cm DenyUsers ,
+.Cm DisableForwarding ,
.Cm ForceCommand ,
.Cm GatewayPorts ,
.Cm GSSAPIAuthentication ,
-.Cm HostbasedAcceptedKeyTypes ,
+.Cm HostbasedAcceptedAlgorithms ,
.Cm HostbasedAuthentication ,
.Cm HostbasedUsesNameFromPacketOnly ,
+.Cm IgnoreRhosts ,
+.Cm Include ,
.Cm IPQoS ,
.Cm KbdInteractiveAuthentication ,
.Cm KerberosAuthentication ,
@@ -1146,7 +1219,7 @@ Available keywords are
.Cm PermitTTY ,
.Cm PermitTunnel ,
.Cm PermitUserRC ,
-.Cm PubkeyAcceptedKeyTypes ,
+.Cm PubkeyAcceptedAlgorithms ,
.Cm PubkeyAuthentication ,
.Cm RekeyLimit ,
.Cm RevokedKeys ,
@@ -1158,7 +1231,7 @@ Available keywords are
.Cm X11DisplayOffset ,
.Cm X11Forwarding
and
-.Cm X11UseLocalHost .
+.Cm X11UseLocalhost .
.It Cm MaxAuthTries
Specifies the maximum number of authentication attempts permitted per
connection.
@@ -1192,6 +1265,16 @@ will refuse connection attempts with a probability of rate/100 (30%)
if there are currently start (10) unauthenticated connections.
The probability increases linearly and all connection attempts
are refused if the number of unauthenticated connections reaches full (60).
+.It Cm ModuliFile
+Specifies the
+.Xr moduli 5
+file that contains the Diffie-Hellman groups used for the
+.Dq diffie-hellman-group-exchange-sha1
+and
+.Dq diffie-hellman-group-exchange-sha256
+key exchange methods.
+The default is
+.Pa /etc/moduli .
.It Cm PasswordAuthentication
Specifies whether password authentication is allowed.
See also
@@ -1240,7 +1323,7 @@ Note also that
.Xr ssh 1
will request a listen host of
.Dq localhost
-if no listen host was specifically requested, and this this name is
+if no listen host was specifically requested, and this name is
treated differently to explicit localhost addresses of
.Dq 127.0.0.1
and
@@ -1276,7 +1359,9 @@ An argument of
can be used to prohibit all forwarding requests.
The wildcard
.Sq *
-can be used for host or port to allow all hosts or ports, respectively.
+can be used for host or port to allow all hosts or ports respectively.
+Otherwise, no pattern matching or address lookups are performed on supplied
+names.
By default all port forwarding requests are permitted.
.It Cm PermitRootLogin
Specifies whether root can log in using
@@ -1371,6 +1456,23 @@ Specifies whether any
file is executed.
The default is
.Cm yes .
+.It Cm PerSourceMaxStartups
+Specifies the number of unauthenticated connections allowed from a
+given source address, or
+.Dq none
+if there is no limit.
+This limit is applied in addition to
+.Cm MaxStartups ,
+whichever is lower.
+The default is
+.Cm none .
+.It Cm PerSourceNetBlockSize
+Specifies the number of bits of source address that are grouped together
+for the purposes of applying PerSourceMaxStartups limits.
+Values for IPv4 and optionally IPv6 may be specified, separated by a colon.
+The default is
+.Cm 32:128 ,
+which means each address is considered individually.
.It Cm PidFile
Specifies the file that contains the process ID of the
SSH daemon, or
@@ -1404,38 +1506,83 @@ when a user logs in interactively.
or equivalent.)
The default is
.Cm yes .
-.It Cm PubkeyAcceptedKeyTypes
-Specifies the key types that will be accepted for public key authentication
-as a list of comma-separated patterns.
-Alternately if the specified value begins with a
+.It Cm PubkeyAcceptedAlgorithms
+Specifies the signature algorithms that will be accepted for public key
+authentication as a list of comma-separated patterns.
+Alternately if the specified list begins with a
.Sq +
-character, then the specified key types will be appended to the default set
+character, then the specified algorithms will be appended to the default set
instead of replacing them.
-If the specified value begins with a
+If the specified list begins with a
.Sq -
-character, then the specified key types (including wildcards) will be removed
+character, then the specified algorithms (including wildcards) will be removed
from the default set instead of replacing them.
+If the specified list begins with a
+.Sq ^
+character, then the specified algorithms will be placed at the head of the
+default set.
The default for this option is:
.Bd -literal -offset 3n
+ssh-ed25519-cert-v01@openssh.com,
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,
-rsa-sha2-512-cert-v01@openssh.com,rsa-sha2-256-cert-v01@openssh.com,
+sk-ssh-ed25519-cert-v01@openssh.com,
+sk-ecdsa-sha2-nistp256-cert-v01@openssh.com,
+rsa-sha2-512-cert-v01@openssh.com,
+rsa-sha2-256-cert-v01@openssh.com,
ssh-rsa-cert-v01@openssh.com,
+ssh-ed25519,
ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521,
-ssh-ed25519,rsa-sha2-512,rsa-sha2-256,ssh-rsa
+sk-ssh-ed25519@openssh.com,
+sk-ecdsa-sha2-nistp256@openssh.com,
+rsa-sha2-512,rsa-sha2-256,ssh-rsa
.Ed
.Pp
-The list of available key types may also be obtained using
-.Qq ssh -Q key .
+The list of available signature algorithms may also be obtained using
+.Qq ssh -Q PubkeyAcceptedAlgorithms .
+.It Cm PubkeyAuthOptions
+Sets one or more public key authentication options.
+The supported keywords are:
+.Cm none
+(the default; indicating no additional options are enabled),
+.Cm touch-required
+and
+.Cm verify-required .
+.Pp
+The
+.Cm touch-required
+option causes public key authentication using a FIDO authenticator algorithm
+(i.e.\&
+.Cm ecdsa-sk
+or
+.Cm ed25519-sk )
+to always require the signature to attest that a physically present user
+explicitly confirmed the authentication (usually by touching the authenticator).
+By default,
+.Xr sshd 8
+requires user presence unless overridden with an authorized_keys option.
+The
+.Cm touch-required
+flag disables this override.
+.Pp
+The
+.Cm verify-required
+option requires a FIDO key signature attest that the user was verified,
+e.g. via a PIN.
+.Pp
+Neither the
+.Cm touch-required
+or
+.Cm verify-required
+options have any effect for other, non-FIDO, public key types.
.It Cm PubkeyAuthentication
Specifies whether public key authentication is allowed.
The default is
.Cm yes .
.It Cm RekeyLimit
Specifies the maximum amount of data that may be transmitted before the
-session key is renegotiated, optionally followed a maximum amount of
+session key is renegotiated, optionally followed by 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
.Sq K ,
@@ -1473,12 +1620,16 @@ For more information on KRLs, see the KEY REVOCATION LISTS section in
.It Cm RDomain
Specifies an explicit routing domain that is applied after authentication
has completed.
-The user session, as well and any forwarded or listening IP sockets,
+The user session, as well as any forwarded or listening IP sockets,
will be bound to this
.Xr rdomain 4 .
If the routing domain is set to
.Cm \&%D ,
then the domain in which the incoming connection was received will be applied.
+.It Cm SecurityKeyProvider
+Specifies a path to a library that will be used when loading
+FIDO authenticator-hosted keys, overriding the default of using
+the built-in USB HID support.
.It Cm SetEnv
Specifies one or more environment variables to set in child sessions started
by
@@ -1631,17 +1782,17 @@ Enables the Pluggable Authentication Module interface.
If set to
.Cm yes
this will enable PAM authentication using
-.Cm ChallengeResponseAuthentication
+.Cm KbdInteractiveAuthentication
and
.Cm PasswordAuthentication
in addition to PAM account and session module processing for all
authentication types.
.Pp
-Because PAM challenge-response authentication usually serves an equivalent
+Because PAM keyboard-interactive authentication usually serves an equivalent
role to password authentication, you should disable either
.Cm PasswordAuthentication
or
-.Cm ChallengeResponseAuthentication.
+.Cm KbdInteractiveAuthentication .
.Pp
If
.Cm UsePAM
@@ -1654,7 +1805,7 @@ The default is
Optionally specifies additional text to append to the SSH protocol banner
sent by the server upon connection.
The default is
-.Qq FreeBSD-20200214 .
+.Qq FreeBSD-20210907 .
The value
.Cm none
may be used to disable this.
diff --git a/crypto/openssh/ssherr.c b/crypto/openssh/ssherr.c
index 8ad3d5750190..bd954aadd729 100644
--- a/crypto/openssh/ssherr.c
+++ b/crypto/openssh/ssherr.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssherr.c,v 1.8 2018/07/03 11:39:54 djm Exp $ */
+/* $OpenBSD: ssherr.c,v 1.10 2020/01/25 23:13:09 djm Exp $ */
/*
* Copyright (c) 2011 Damien Miller
*
@@ -141,6 +141,10 @@ ssh_err(int n)
return "number is too large";
case SSH_ERR_SIGN_ALG_UNSUPPORTED:
return "signature algorithm not supported";
+ case SSH_ERR_FEATURE_UNSUPPORTED:
+ return "requested feature not supported";
+ case SSH_ERR_DEVICE_NOT_FOUND:
+ return "device not found";
default:
return "unknown error";
}
diff --git a/crypto/openssh/ssherr.h b/crypto/openssh/ssherr.h
index 348da5a20865..085e752744d8 100644
--- a/crypto/openssh/ssherr.h
+++ b/crypto/openssh/ssherr.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssherr.h,v 1.6 2018/07/03 11:39:54 djm Exp $ */
+/* $OpenBSD: ssherr.h,v 1.8 2020/01/25 23:13:09 djm Exp $ */
/*
* Copyright (c) 2011 Damien Miller
*
@@ -80,6 +80,8 @@
#define SSH_ERR_KEY_LENGTH -56
#define SSH_ERR_NUMBER_TOO_LARGE -57
#define SSH_ERR_SIGN_ALG_UNSUPPORTED -58
+#define SSH_ERR_FEATURE_UNSUPPORTED -59
+#define SSH_ERR_DEVICE_NOT_FOUND -60
/* Translate a numeric error code to a human-readable error string */
const char *ssh_err(int n);
diff --git a/crypto/openssh/sshkey-xmss.c b/crypto/openssh/sshkey-xmss.c
index aaae7028928c..f5235ef2fbd8 100644
--- a/crypto/openssh/sshkey-xmss.c
+++ b/crypto/openssh/sshkey-xmss.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: sshkey-xmss.c,v 1.3 2018/07/09 21:59:10 markus Exp $ */
+/* $OpenBSD: sshkey-xmss.c,v 1.11 2021/04/03 06:18:41 djm Exp $ */
/*
* Copyright (c) 2017 Markus Friedl. All rights reserved.
*
@@ -45,6 +45,7 @@
#include "sshkey.h"
#include "sshkey-xmss.h"
#include "atomicio.h"
+#include "log.h"
#include "xmss_fast.h"
@@ -69,7 +70,7 @@ struct ssh_xmss_state {
u_int32_t maxidx; /* restricted # of signatures */
int have_state; /* .state file exists */
int lockfd; /* locked in sshkey_xmss_get_state() */
- int allow_update; /* allow sshkey_xmss_update_state() */
+ u_char allow_update; /* allow sshkey_xmss_update_state() */
char *enc_ciphername;/* encrypt state with cipher */
u_char *enc_keyiv; /* encrypt state with key */
u_int32_t enc_keyiv_len; /* length of enc_keyiv */
@@ -79,7 +80,7 @@ int sshkey_xmss_init_bds_state(struct sshkey *);
int sshkey_xmss_init_enc_key(struct sshkey *, const char *);
void sshkey_xmss_free_bds(struct sshkey *);
int sshkey_xmss_get_state_from_file(struct sshkey *, const char *,
- int *, sshkey_printfn *);
+ int *, int);
int sshkey_xmss_encrypt_state(const struct sshkey *, struct sshbuf *,
struct sshbuf **);
int sshkey_xmss_decrypt_state(const struct sshkey *, struct sshbuf *,
@@ -87,7 +88,8 @@ int sshkey_xmss_decrypt_state(const struct sshkey *, struct sshbuf *,
int sshkey_xmss_serialize_enc_key(const struct sshkey *, struct sshbuf *);
int sshkey_xmss_deserialize_enc_key(struct sshkey *, struct sshbuf *);
-#define PRINT(s...) do { if (pr) pr(s); } while (0)
+#define PRINT(...) do { if (printerror) sshlog(__FILE__, __func__, __LINE__, \
+ 0, SYSLOG_LEVEL_ERROR, NULL, __VA_ARGS__); } while (0)
int
sshkey_xmss_init(struct sshkey *key, const char *name)
@@ -392,7 +394,7 @@ sshkey_xmss_generate_private_key(struct sshkey *k, u_int bits)
int
sshkey_xmss_get_state_from_file(struct sshkey *k, const char *filename,
- int *have_file, sshkey_printfn *pr)
+ int *have_file, int printerror)
{
struct sshbuf *b = NULL, *enc = NULL;
int ret = SSH_ERR_SYSTEM_ERROR, r, fd = -1;
@@ -403,7 +405,7 @@ sshkey_xmss_get_state_from_file(struct sshkey *k, const char *filename,
if ((fd = open(filename, O_RDONLY)) >= 0) {
*have_file = 1;
if (atomicio(read, fd, buf, sizeof(buf)) != sizeof(buf)) {
- PRINT("%s: corrupt state file: %s", __func__, filename);
+ PRINT("corrupt state file: %s", filename);
goto done;
}
len = PEEK_U32(buf);
@@ -412,7 +414,7 @@ sshkey_xmss_get_state_from_file(struct sshkey *k, const char *filename,
goto done;
}
if (atomicio(read, fd, data, len) != len) {
- PRINT("%s: cannot read blob: %s", __func__, filename);
+ PRINT("cannot read blob: %s", filename);
goto done;
}
if ((enc = sshbuf_from(data, len)) == NULL) {
@@ -440,7 +442,7 @@ done:
}
int
-sshkey_xmss_get_state(const struct sshkey *k, sshkey_printfn *pr)
+sshkey_xmss_get_state(const struct sshkey *k, int printerror)
{
struct ssh_xmss_state *state = k->xmss_state;
u_int32_t idx = 0;
@@ -467,35 +469,35 @@ sshkey_xmss_get_state(const struct sshkey *k, sshkey_printfn *pr)
}
if ((filename = k->xmss_filename) == NULL)
goto done;
- if (asprintf(&lockfile, "%s.lock", filename) < 0 ||
- asprintf(&statefile, "%s.state", filename) < 0 ||
- asprintf(&ostatefile, "%s.ostate", filename) < 0) {
+ if (asprintf(&lockfile, "%s.lock", filename) == -1 ||
+ asprintf(&statefile, "%s.state", filename) == -1 ||
+ asprintf(&ostatefile, "%s.ostate", filename) == -1) {
ret = SSH_ERR_ALLOC_FAIL;
goto done;
}
- if ((lockfd = open(lockfile, O_CREAT|O_RDONLY, 0600)) < 0) {
+ if ((lockfd = open(lockfile, O_CREAT|O_RDONLY, 0600)) == -1) {
ret = SSH_ERR_SYSTEM_ERROR;
- PRINT("%s: cannot open/create: %s", __func__, lockfile);
+ PRINT("cannot open/create: %s", lockfile);
goto done;
}
- while (flock(lockfd, LOCK_EX|LOCK_NB) < 0) {
+ while (flock(lockfd, LOCK_EX|LOCK_NB) == -1) {
if (errno != EWOULDBLOCK) {
ret = SSH_ERR_SYSTEM_ERROR;
- PRINT("%s: cannot lock: %s", __func__, lockfile);
+ PRINT("cannot lock: %s", lockfile);
goto done;
}
if (++tries > 10) {
ret = SSH_ERR_SYSTEM_ERROR;
- PRINT("%s: giving up on: %s", __func__, lockfile);
+ PRINT("giving up on: %s", lockfile);
goto done;
}
usleep(1000*100*tries);
}
/* XXX no longer const */
if ((r = sshkey_xmss_get_state_from_file((struct sshkey *)k,
- statefile, &have_state, pr)) != 0) {
+ statefile, &have_state, printerror)) != 0) {
if ((r = sshkey_xmss_get_state_from_file((struct sshkey *)k,
- ostatefile, &have_ostate, pr)) == 0) {
+ ostatefile, &have_ostate, printerror)) == 0) {
state->allow_update = 1;
r = sshkey_xmss_forward_state(k, 1);
state->idx = PEEK_U32(k->xmss_sk);
@@ -506,13 +508,13 @@ sshkey_xmss_get_state(const struct sshkey *k, sshkey_printfn *pr)
/* check that bds state is initialized */
if (state->bds.auth == NULL)
goto done;
- PRINT("%s: start from scratch idx 0: %u", __func__, state->idx);
+ PRINT("start from scratch idx 0: %u", state->idx);
} else if (r != 0) {
ret = r;
goto done;
}
if (state->idx + 1 < state->idx) {
- PRINT("%s: state wrap: %u", __func__, state->idx);
+ PRINT("state wrap: %u", state->idx);
goto done;
}
state->have_state = have_state;
@@ -563,7 +565,7 @@ sshkey_xmss_forward_state(const struct sshkey *k, u_int32_t reserve)
}
int
-sshkey_xmss_update_state(const struct sshkey *k, sshkey_printfn *pr)
+sshkey_xmss_update_state(const struct sshkey *k, int printerror)
{
struct ssh_xmss_state *state = k->xmss_state;
struct sshbuf *b = NULL, *enc = NULL;
@@ -587,16 +589,16 @@ sshkey_xmss_update_state(const struct sshkey *k, sshkey_printfn *pr)
ret = 0;
goto done;
} else if (idx != state->idx + 1) {
- PRINT("%s: more than one signature happened: idx %u state %u",
- __func__, idx, state->idx);
+ PRINT("more than one signature happened: idx %u state %u",
+ idx, state->idx);
goto done;
}
state->idx = idx;
if ((filename = k->xmss_filename) == NULL)
goto done;
- if (asprintf(&statefile, "%s.state", filename) < 0 ||
- asprintf(&ostatefile, "%s.ostate", filename) < 0 ||
- asprintf(&nstatefile, "%s.nstate", filename) < 0) {
+ if (asprintf(&statefile, "%s.state", filename) == -1 ||
+ asprintf(&ostatefile, "%s.ostate", filename) == -1 ||
+ asprintf(&nstatefile, "%s.nstate", filename) == -1) {
ret = SSH_ERR_ALLOC_FAIL;
goto done;
}
@@ -606,55 +608,54 @@ sshkey_xmss_update_state(const struct sshkey *k, sshkey_printfn *pr)
goto done;
}
if ((ret = sshkey_xmss_serialize_state(k, b)) != 0) {
- PRINT("%s: SERLIALIZE FAILED: %d", __func__, ret);
+ PRINT("SERLIALIZE FAILED: %d", ret);
goto done;
}
if ((ret = sshkey_xmss_encrypt_state(k, b, &enc)) != 0) {
- PRINT("%s: ENCRYPT FAILED: %d", __func__, ret);
+ PRINT("ENCRYPT FAILED: %d", ret);
goto done;
}
- if ((fd = open(nstatefile, O_CREAT|O_WRONLY|O_EXCL, 0600)) < 0) {
+ if ((fd = open(nstatefile, O_CREAT|O_WRONLY|O_EXCL, 0600)) == -1) {
ret = SSH_ERR_SYSTEM_ERROR;
- PRINT("%s: open new state file: %s", __func__, nstatefile);
+ PRINT("open new state file: %s", nstatefile);
goto done;
}
POKE_U32(buf, sshbuf_len(enc));
if (atomicio(vwrite, fd, buf, sizeof(buf)) != sizeof(buf)) {
ret = SSH_ERR_SYSTEM_ERROR;
- PRINT("%s: write new state file hdr: %s", __func__, nstatefile);
+ PRINT("write new state file hdr: %s", nstatefile);
close(fd);
goto done;
}
if (atomicio(vwrite, fd, sshbuf_mutable_ptr(enc), sshbuf_len(enc)) !=
sshbuf_len(enc)) {
ret = SSH_ERR_SYSTEM_ERROR;
- PRINT("%s: write new state file data: %s", __func__, nstatefile);
+ PRINT("write new state file data: %s", nstatefile);
close(fd);
goto done;
}
- if (fsync(fd) < 0) {
+ if (fsync(fd) == -1) {
ret = SSH_ERR_SYSTEM_ERROR;
- PRINT("%s: sync new state file: %s", __func__, nstatefile);
+ PRINT("sync new state file: %s", nstatefile);
close(fd);
goto done;
}
- if (close(fd) < 0) {
+ if (close(fd) == -1) {
ret = SSH_ERR_SYSTEM_ERROR;
- PRINT("%s: close new state file: %s", __func__, nstatefile);
+ PRINT("close new state file: %s", nstatefile);
goto done;
}
if (state->have_state) {
unlink(ostatefile);
if (link(statefile, ostatefile)) {
ret = SSH_ERR_SYSTEM_ERROR;
- PRINT("%s: backup state %s to %s", __func__, statefile,
- ostatefile);
+ PRINT("backup state %s to %s", statefile, ostatefile);
goto done;
}
}
- if (rename(nstatefile, statefile) < 0) {
+ if (rename(nstatefile, statefile) == -1) {
ret = SSH_ERR_SYSTEM_ERROR;
- PRINT("%s: rename %s to %s", __func__, nstatefile, statefile);
+ PRINT("rename %s to %s", nstatefile, statefile);
goto done;
}
ret = 0;
@@ -716,6 +717,7 @@ sshkey_xmss_serialize_state_opt(const struct sshkey *k, struct sshbuf *b,
{
struct ssh_xmss_state *state = k->xmss_state;
int r = SSH_ERR_INVALID_ARGUMENT;
+ u_char have_stack, have_filename, have_enc;
if (state == NULL)
return SSH_ERR_INVALID_ARGUMENT;
@@ -727,9 +729,35 @@ sshkey_xmss_serialize_state_opt(const struct sshkey *k, struct sshbuf *b,
break;
case SSHKEY_SERIALIZE_FULL:
if ((r = sshkey_xmss_serialize_enc_key(k, b)) != 0)
- break;
+ return r;
r = sshkey_xmss_serialize_state(k, b);
break;
+ case SSHKEY_SERIALIZE_SHIELD:
+ /* all of stack/filename/enc are optional */
+ have_stack = state->stack != NULL;
+ if ((r = sshbuf_put_u8(b, have_stack)) != 0)
+ return r;
+ if (have_stack) {
+ state->idx = PEEK_U32(k->xmss_sk); /* update */
+ if ((r = sshkey_xmss_serialize_state(k, b)) != 0)
+ return r;
+ }
+ have_filename = k->xmss_filename != NULL;
+ if ((r = sshbuf_put_u8(b, have_filename)) != 0)
+ return r;
+ if (have_filename &&
+ (r = sshbuf_put_cstring(b, k->xmss_filename)) != 0)
+ return r;
+ have_enc = state->enc_keyiv != NULL;
+ if ((r = sshbuf_put_u8(b, have_enc)) != 0)
+ return r;
+ if (have_enc &&
+ (r = sshkey_xmss_serialize_enc_key(k, b)) != 0)
+ return r;
+ if ((r = sshbuf_put_u32(b, state->maxidx)) != 0 ||
+ (r = sshbuf_put_u8(b, state->allow_update)) != 0)
+ return r;
+ break;
case SSHKEY_SERIALIZE_DEFAULT:
r = 0;
break;
@@ -748,7 +776,7 @@ sshkey_xmss_deserialize_state(struct sshkey *k, struct sshbuf *b)
u_int32_t i, lh, node;
size_t ls, lsl, la, lk, ln, lr;
char *magic;
- int r;
+ int r = SSH_ERR_INTERNAL_ERROR;
if (state == NULL)
return SSH_ERR_INVALID_ARGUMENT;
@@ -767,9 +795,11 @@ sshkey_xmss_deserialize_state(struct sshkey *k, struct sshbuf *b)
(r = sshbuf_get_string(b, &state->th_nodes, &ln)) != 0 ||
(r = sshbuf_get_string(b, &state->retain, &lr)) != 0 ||
(r = sshbuf_get_u32(b, &lh)) != 0)
- return r;
- if (strcmp(magic, SSH_XMSS_K2_MAGIC) != 0)
- return SSH_ERR_INVALID_ARGUMENT;
+ goto out;
+ if (strcmp(magic, SSH_XMSS_K2_MAGIC) != 0) {
+ r = SSH_ERR_INVALID_ARGUMENT;
+ goto out;
+ }
/* XXX check stackoffset */
if (ls != num_stack(state) ||
lsl != num_stacklevels(state) ||
@@ -777,8 +807,10 @@ sshkey_xmss_deserialize_state(struct sshkey *k, struct sshbuf *b)
lk != num_keep(state) ||
ln != num_th_nodes(state) ||
lr != num_retain(state) ||
- lh != num_treehash(state))
- return SSH_ERR_INVALID_ARGUMENT;
+ lh != num_treehash(state)) {
+ r = SSH_ERR_INVALID_ARGUMENT;
+ goto out;
+ }
for (i = 0; i < num_treehash(state); i++) {
th = &state->treehash[i];
if ((r = sshbuf_get_u32(b, &th->h)) != 0 ||
@@ -786,7 +818,7 @@ sshkey_xmss_deserialize_state(struct sshkey *k, struct sshbuf *b)
(r = sshbuf_get_u32(b, &th->stackusage)) != 0 ||
(r = sshbuf_get_u8(b, &th->completed)) != 0 ||
(r = sshbuf_get_u32(b, &node)) != 0)
- return r;
+ goto out;
if (node < num_th_nodes(state))
th->node = &state->th_nodes[node];
}
@@ -794,14 +826,19 @@ sshkey_xmss_deserialize_state(struct sshkey *k, struct sshbuf *b)
xmss_set_bds_state(&state->bds, state->stack, state->stackoffset,
state->stacklevels, state->auth, state->keep, state->treehash,
state->retain, 0);
- return 0;
+ /* success */
+ r = 0;
+ out:
+ free(magic);
+ return r;
}
int
sshkey_xmss_deserialize_state_opt(struct sshkey *k, struct sshbuf *b)
{
+ struct ssh_xmss_state *state = k->xmss_state;
enum sshkey_serialize_rep opts;
- u_char have_state;
+ u_char have_state, have_stack, have_filename, have_enc;
int r;
if ((r = sshbuf_get_u8(b, &have_state)) != 0)
@@ -812,6 +849,26 @@ sshkey_xmss_deserialize_state_opt(struct sshkey *k, struct sshbuf *b)
case SSHKEY_SERIALIZE_DEFAULT:
r = 0;
break;
+ case SSHKEY_SERIALIZE_SHIELD:
+ if ((r = sshbuf_get_u8(b, &have_stack)) != 0)
+ return r;
+ if (have_stack &&
+ (r = sshkey_xmss_deserialize_state(k, b)) != 0)
+ return r;
+ if ((r = sshbuf_get_u8(b, &have_filename)) != 0)
+ return r;
+ if (have_filename &&
+ (r = sshbuf_get_cstring(b, &k->xmss_filename, NULL)) != 0)
+ return r;
+ if ((r = sshbuf_get_u8(b, &have_enc)) != 0)
+ return r;
+ if (have_enc &&
+ (r = sshkey_xmss_deserialize_enc_key(k, b)) != 0)
+ return r;
+ if ((r = sshbuf_get_u32(b, &state->maxidx)) != 0 ||
+ (r = sshbuf_get_u8(b, &state->allow_update)) != 0)
+ return r;
+ break;
case SSHKEY_SERIALIZE_STATE:
if ((r = sshkey_xmss_deserialize_state(k, b)) != 0)
return r;
@@ -977,7 +1034,8 @@ sshkey_xmss_decrypt_state(const struct sshkey *k, struct sshbuf *encoded,
goto out;
}
/* check that an appropriate amount of auth data is present */
- if (sshbuf_len(encoded) < encrypted_len + authlen) {
+ if (sshbuf_len(encoded) < authlen ||
+ sshbuf_len(encoded) - authlen < encrypted_len) {
r = SSH_ERR_INVALID_FORMAT;
goto out;
}
diff --git a/crypto/openssh/sshkey-xmss.h b/crypto/openssh/sshkey-xmss.h
index b9f8ead1047f..32a12be620b1 100644
--- a/crypto/openssh/sshkey-xmss.h
+++ b/crypto/openssh/sshkey-xmss.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: sshkey-xmss.h,v 1.1 2018/02/23 15:58:38 markus Exp $ */
+/* $OpenBSD: sshkey-xmss.h,v 1.3 2021/04/03 06:18:41 djm Exp $ */
/*
* Copyright (c) 2017 Markus Friedl. All rights reserved.
*
@@ -25,10 +25,10 @@
#ifndef SSHKEY_XMSS_H
#define SSHKEY_XMSS_H
-#define XMSS_SHA2_256_W16_H10_NAME "XMSS_SHA2-256_W16_H10"
-#define XMSS_SHA2_256_W16_H16_NAME "XMSS_SHA2-256_W16_H16"
-#define XMSS_SHA2_256_W16_H20_NAME "XMSS_SHA2-256_W16_H20"
-#define XMSS_DEFAULT_NAME XMSS_SHA2_256_W16_H10_NAME
+#define XMSS_SHA2_256_W16_H10_NAME "XMSS_SHA2-256_W16_H10"
+#define XMSS_SHA2_256_W16_H16_NAME "XMSS_SHA2-256_W16_H16"
+#define XMSS_SHA2_256_W16_H20_NAME "XMSS_SHA2-256_W16_H20"
+#define XMSS_DEFAULT_NAME XMSS_SHA2_256_W16_H10_NAME
size_t sshkey_xmss_pklen(const struct sshkey *);
size_t sshkey_xmss_sklen(const struct sshkey *);
@@ -37,7 +37,7 @@ void sshkey_xmss_free_state(struct sshkey *);
int sshkey_xmss_generate_private_key(struct sshkey *, u_int);
int sshkey_xmss_serialize_state(const struct sshkey *, struct sshbuf *);
int sshkey_xmss_serialize_state_opt(const struct sshkey *, struct sshbuf *,
- enum sshkey_serialize_rep);
+ enum sshkey_serialize_rep);
int sshkey_xmss_serialize_pk_info(const struct sshkey *, struct sshbuf *,
enum sshkey_serialize_rep);
int sshkey_xmss_deserialize_state(struct sshkey *, struct sshbuf *);
@@ -47,10 +47,10 @@ int sshkey_xmss_deserialize_pk_info(struct sshkey *, struct sshbuf *);
int sshkey_xmss_siglen(const struct sshkey *, size_t *);
void *sshkey_xmss_params(const struct sshkey *);
void *sshkey_xmss_bds_state(const struct sshkey *);
-int sshkey_xmss_get_state(const struct sshkey *, sshkey_printfn *);
+int sshkey_xmss_get_state(const struct sshkey *, int);
int sshkey_xmss_enable_maxsign(struct sshkey *, u_int32_t);
int sshkey_xmss_forward_state(const struct sshkey *, u_int32_t);
-int sshkey_xmss_update_state(const struct sshkey *, sshkey_printfn *);
+int sshkey_xmss_update_state(const struct sshkey *, int);
u_int32_t sshkey_xmss_signatures_left(const struct sshkey *);
#endif /* SSHKEY_XMSS_H */
diff --git a/crypto/openssh/sshkey.c b/crypto/openssh/sshkey.c
index 6555c5ef8de0..0dbc0d873b4f 100644
--- a/crypto/openssh/sshkey.c
+++ b/crypto/openssh/sshkey.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: sshkey.c,v 1.72 2018/10/11 00:52:46 djm Exp $ */
+/* $OpenBSD: sshkey.c,v 1.119 2021/07/23 03:37:52 djm Exp $ */
/*
* Copyright (c) 2000, 2001 Markus Friedl. All rights reserved.
* Copyright (c) 2008 Alexander von Gernler. All rights reserved.
@@ -43,6 +43,7 @@
#include <stdio.h>
#include <string.h>
#include <resolv.h>
+#include <time.h>
#ifdef HAVE_UTIL_H
#include <util.h>
#endif /* HAVE_UTIL_H */
@@ -55,10 +56,13 @@
#include "digest.h"
#define SSHKEY_INTERNAL
#include "sshkey.h"
-#include "sshkey-xmss.h"
#include "match.h"
+#include "ssh-sk.h"
+#ifdef WITH_XMSS
+#include "sshkey-xmss.h"
#include "xmss_fast.h"
+#endif
#include "openbsd-compat/openssl-compat.h"
@@ -76,11 +80,18 @@
/* Version identification string for SSH v1 identity files. */
#define LEGACY_BEGIN "SSH PRIVATE KEY FILE FORMAT 1.1\n"
-int sshkey_private_serialize_opt(const struct sshkey *key,
+/*
+ * Constants relating to "shielding" support; protection of keys expected
+ * to remain in memory for long durations
+ */
+#define SSHKEY_SHIELD_PREKEY_LEN (16 * 1024)
+#define SSHKEY_SHIELD_CIPHER "aes256-ctr" /* XXX want AES-EME* */
+#define SSHKEY_SHIELD_PREKEY_HASH SSH_DIGEST_SHA512
+
+int sshkey_private_serialize_opt(struct sshkey *key,
struct sshbuf *buf, enum sshkey_serialize_rep);
static int sshkey_from_blob_internal(struct sshbuf *buf,
struct sshkey **keyp, int allow_cert);
-static int get_sigtype(const u_char *sig, size_t siglen, char **sigtypep);
/* Supported key types */
struct keytype {
@@ -96,6 +107,10 @@ static const struct keytype keytypes[] = {
{ "ssh-ed25519", "ED25519", NULL, KEY_ED25519, 0, 0, 0 },
{ "ssh-ed25519-cert-v01@openssh.com", "ED25519-CERT", NULL,
KEY_ED25519_CERT, 0, 1, 0 },
+ { "sk-ssh-ed25519@openssh.com", "ED25519-SK", NULL,
+ KEY_ED25519_SK, 0, 0, 0 },
+ { "sk-ssh-ed25519-cert-v01@openssh.com", "ED25519-SK-CERT", NULL,
+ KEY_ED25519_SK_CERT, 0, 1, 0 },
#ifdef WITH_XMSS
{ "ssh-xmss@openssh.com", "XMSS", NULL, KEY_XMSS, 0, 0, 0 },
{ "ssh-xmss-cert-v01@openssh.com", "XMSS-CERT", NULL,
@@ -115,6 +130,10 @@ static const struct keytype keytypes[] = {
{ "ecdsa-sha2-nistp521", "ECDSA", NULL,
KEY_ECDSA, NID_secp521r1, 0, 0 },
# endif /* OPENSSL_HAS_NISTP521 */
+ { "sk-ecdsa-sha2-nistp256@openssh.com", "ECDSA-SK", NULL,
+ KEY_ECDSA_SK, NID_X9_62_prime256v1, 0, 0 },
+ { "webauthn-sk-ecdsa-sha2-nistp256@openssh.com", "ECDSA-SK", NULL,
+ KEY_ECDSA_SK, NID_X9_62_prime256v1, 0, 1 },
# endif /* OPENSSL_HAS_ECC */
{ "ssh-rsa-cert-v01@openssh.com", "RSA-CERT", NULL,
KEY_RSA_CERT, 0, 1, 0 },
@@ -131,8 +150,10 @@ static const struct keytype keytypes[] = {
KEY_ECDSA_CERT, NID_secp384r1, 1, 0 },
# ifdef OPENSSL_HAS_NISTP521
{ "ecdsa-sha2-nistp521-cert-v01@openssh.com", "ECDSA-CERT", NULL,
- KEY_ECDSA_CERT, NID_secp521r1, 1, 0 },
+ KEY_ECDSA_CERT, NID_secp521r1, 1, 0 },
# endif /* OPENSSL_HAS_NISTP521 */
+ { "sk-ecdsa-sha2-nistp256-cert-v01@openssh.com", "ECDSA-SK-CERT", NULL,
+ KEY_ECDSA_SK_CERT, NID_X9_62_prime256v1, 1, 0 },
# endif /* OPENSSL_HAS_ECC */
#endif /* WITH_OPENSSL */
{ NULL, NULL, NULL, -1, -1, 0, 0 }
@@ -201,13 +222,26 @@ sshkey_type_from_name(const char *name)
return KEY_UNSPEC;
}
+static int
+key_type_is_ecdsa_variant(int type)
+{
+ switch (type) {
+ case KEY_ECDSA:
+ case KEY_ECDSA_CERT:
+ case KEY_ECDSA_SK:
+ case KEY_ECDSA_SK_CERT:
+ return 1;
+ }
+ return 0;
+}
+
int
sshkey_ecdsa_nid_from_name(const char *name)
{
const struct keytype *kt;
for (kt = keytypes; kt->type != -1; kt++) {
- if (kt->type != KEY_ECDSA && kt->type != KEY_ECDSA_CERT)
+ if (!key_type_is_ecdsa_variant(kt->type))
continue;
if (kt->name != NULL && strcmp(name, kt->name) == 0)
return kt->nid;
@@ -303,10 +337,14 @@ sshkey_size(const struct sshkey *k)
return BN_num_bits(dsa_p);
case KEY_ECDSA:
case KEY_ECDSA_CERT:
+ case KEY_ECDSA_SK:
+ case KEY_ECDSA_SK_CERT:
return sshkey_curve_nid_to_bits(k->ecdsa_nid);
#endif /* WITH_OPENSSL */
case KEY_ED25519:
case KEY_ED25519_CERT:
+ case KEY_ED25519_SK:
+ case KEY_ED25519_SK_CERT:
case KEY_XMSS:
case KEY_XMSS_CERT:
return 256; /* XXX */
@@ -321,7 +359,9 @@ sshkey_type_is_valid_ca(int type)
case KEY_RSA:
case KEY_DSA:
case KEY_ECDSA:
+ case KEY_ECDSA_SK:
case KEY_ED25519:
+ case KEY_ED25519_SK:
case KEY_XMSS:
return 1;
default:
@@ -337,6 +377,20 @@ sshkey_is_cert(const struct sshkey *k)
return sshkey_type_is_cert(k->type);
}
+int
+sshkey_is_sk(const struct sshkey *k)
+{
+ if (k == NULL)
+ return 0;
+ switch (sshkey_type_plain(k->type)) {
+ case KEY_ECDSA_SK:
+ case KEY_ED25519_SK:
+ return 1;
+ default:
+ return 0;
+ }
+}
+
/* Return the cert-less equivalent to a certified key type */
int
sshkey_type_plain(int type)
@@ -348,8 +402,12 @@ sshkey_type_plain(int type)
return KEY_DSA;
case KEY_ECDSA_CERT:
return KEY_ECDSA;
+ case KEY_ECDSA_SK_CERT:
+ return KEY_ECDSA_SK;
case KEY_ED25519_CERT:
return KEY_ED25519;
+ case KEY_ED25519_SK_CERT:
+ return KEY_ED25519_SK;
case KEY_XMSS_CERT:
return KEY_XMSS;
default:
@@ -523,11 +581,15 @@ sshkey_new(int type)
break;
case KEY_ECDSA:
case KEY_ECDSA_CERT:
+ case KEY_ECDSA_SK:
+ case KEY_ECDSA_SK_CERT:
/* Cannot do anything until we know the group */
break;
#endif /* WITH_OPENSSL */
case KEY_ED25519:
case KEY_ED25519_CERT:
+ case KEY_ED25519_SK:
+ case KEY_ED25519_SK_CERT:
case KEY_XMSS:
case KEY_XMSS_CERT:
/* no need to prealloc */
@@ -567,6 +629,12 @@ sshkey_free(struct sshkey *k)
k->dsa = NULL;
break;
# ifdef OPENSSL_HAS_ECC
+ case KEY_ECDSA_SK:
+ case KEY_ECDSA_SK_CERT:
+ free(k->sk_application);
+ sshbuf_free(k->sk_key_handle);
+ sshbuf_free(k->sk_reserved);
+ /* FALLTHROUGH */
case KEY_ECDSA:
case KEY_ECDSA_CERT:
EC_KEY_free(k->ecdsa);
@@ -574,6 +642,12 @@ sshkey_free(struct sshkey *k)
break;
# endif /* OPENSSL_HAS_ECC */
#endif /* WITH_OPENSSL */
+ case KEY_ED25519_SK:
+ case KEY_ED25519_SK_CERT:
+ free(k->sk_application);
+ sshbuf_free(k->sk_key_handle);
+ sshbuf_free(k->sk_reserved);
+ /* FALLTHROUGH */
case KEY_ED25519:
case KEY_ED25519_CERT:
freezero(k->ed25519_pk, ED25519_PK_SZ);
@@ -602,6 +676,8 @@ sshkey_free(struct sshkey *k)
}
if (sshkey_is_cert(k))
cert_free(k->cert);
+ freezero(k->shielded_private, k->shielded_len);
+ freezero(k->shield_prekey, k->shield_prekey_len);
freezero(k, sizeof(*k));
}
@@ -632,9 +708,6 @@ sshkey_equal_public(const struct sshkey *a, const struct sshkey *b)
const BIGNUM *rsa_e_b, *rsa_n_b;
const BIGNUM *dsa_p_a, *dsa_q_a, *dsa_g_a, *dsa_pub_key_a;
const BIGNUM *dsa_p_b, *dsa_q_b, *dsa_g_b, *dsa_pub_key_b;
-# if defined(OPENSSL_HAS_ECC)
- BN_CTX *bnctx;
-# endif /* OPENSSL_HAS_ECC */
#endif /* WITH_OPENSSL */
if (a == NULL || b == NULL ||
@@ -664,26 +737,35 @@ sshkey_equal_public(const struct sshkey *a, const struct sshkey *b)
BN_cmp(dsa_g_a, dsa_g_b) == 0 &&
BN_cmp(dsa_pub_key_a, dsa_pub_key_b) == 0;
# ifdef OPENSSL_HAS_ECC
+ case KEY_ECDSA_SK:
+ case KEY_ECDSA_SK_CERT:
+ if (a->sk_application == NULL || b->sk_application == NULL)
+ return 0;
+ if (strcmp(a->sk_application, b->sk_application) != 0)
+ return 0;
+ /* FALLTHROUGH */
case KEY_ECDSA_CERT:
case KEY_ECDSA:
if (a->ecdsa == NULL || b->ecdsa == NULL ||
EC_KEY_get0_public_key(a->ecdsa) == NULL ||
EC_KEY_get0_public_key(b->ecdsa) == NULL)
return 0;
- if ((bnctx = BN_CTX_new()) == NULL)
- return 0;
if (EC_GROUP_cmp(EC_KEY_get0_group(a->ecdsa),
- EC_KEY_get0_group(b->ecdsa), bnctx) != 0 ||
+ EC_KEY_get0_group(b->ecdsa), NULL) != 0 ||
EC_POINT_cmp(EC_KEY_get0_group(a->ecdsa),
EC_KEY_get0_public_key(a->ecdsa),
- EC_KEY_get0_public_key(b->ecdsa), bnctx) != 0) {
- BN_CTX_free(bnctx);
+ EC_KEY_get0_public_key(b->ecdsa), NULL) != 0)
return 0;
- }
- BN_CTX_free(bnctx);
return 1;
# endif /* OPENSSL_HAS_ECC */
#endif /* WITH_OPENSSL */
+ case KEY_ED25519_SK:
+ case KEY_ED25519_SK_CERT:
+ if (a->sk_application == NULL || b->sk_application == NULL)
+ return 0;
+ if (strcmp(a->sk_application, b->sk_application) != 0)
+ return 0;
+ /* FALLTHROUGH */
case KEY_ED25519:
case KEY_ED25519_CERT:
return a->ed25519_pk != NULL && b->ed25519_pk != NULL &&
@@ -739,9 +821,11 @@ to_blob_buf(const struct sshkey *key, struct sshbuf *b, int force_plain,
#ifdef WITH_OPENSSL
case KEY_DSA_CERT:
case KEY_ECDSA_CERT:
+ case KEY_ECDSA_SK_CERT:
case KEY_RSA_CERT:
#endif /* WITH_OPENSSL */
case KEY_ED25519_CERT:
+ case KEY_ED25519_SK_CERT:
#ifdef WITH_XMSS
case KEY_XMSS_CERT:
#endif /* WITH_XMSS */
@@ -765,6 +849,7 @@ to_blob_buf(const struct sshkey *key, struct sshbuf *b, int force_plain,
break;
# ifdef OPENSSL_HAS_ECC
case KEY_ECDSA:
+ case KEY_ECDSA_SK:
if (key->ecdsa == NULL)
return SSH_ERR_INVALID_ARGUMENT;
if ((ret = sshbuf_put_cstring(b, typename)) != 0 ||
@@ -772,6 +857,11 @@ to_blob_buf(const struct sshkey *key, struct sshbuf *b, int force_plain,
sshkey_curve_nid_to_name(key->ecdsa_nid))) != 0 ||
(ret = sshbuf_put_eckey(b, key->ecdsa)) != 0)
return ret;
+ if (type == KEY_ECDSA_SK) {
+ if ((ret = sshbuf_put_cstring(b,
+ key->sk_application)) != 0)
+ return ret;
+ }
break;
# endif
case KEY_RSA:
@@ -785,12 +875,18 @@ to_blob_buf(const struct sshkey *key, struct sshbuf *b, int force_plain,
break;
#endif /* WITH_OPENSSL */
case KEY_ED25519:
+ case KEY_ED25519_SK:
if (key->ed25519_pk == NULL)
return SSH_ERR_INVALID_ARGUMENT;
if ((ret = sshbuf_put_cstring(b, typename)) != 0 ||
(ret = sshbuf_put_string(b,
key->ed25519_pk, ED25519_PK_SZ)) != 0)
return ret;
+ if (type == KEY_ED25519_SK) {
+ if ((ret = sshbuf_put_cstring(b,
+ key->sk_application)) != 0)
+ return ret;
+ }
break;
#ifdef WITH_XMSS
case KEY_XMSS:
@@ -925,10 +1021,8 @@ sshkey_fingerprint_raw(const struct sshkey *k, int dgst_alg,
r = 0;
out:
free(ret);
- if (blob != NULL) {
- explicit_bzero(blob, blob_len);
- free(blob);
- }
+ if (blob != NULL)
+ freezero(blob, blob_len);
return r;
}
@@ -938,7 +1032,6 @@ fingerprint_b64(const char *alg, u_char *dgst_raw, size_t dgst_raw_len)
char *ret;
size_t plen = strlen(alg) + 1;
size_t rlen = ((dgst_raw_len + 2) / 3) * 4 + plen + 1;
- int r;
if (dgst_raw_len > 65536 || (ret = calloc(1, rlen)) == NULL)
return NULL;
@@ -946,8 +1039,7 @@ fingerprint_b64(const char *alg, u_char *dgst_raw, size_t dgst_raw_len)
strlcat(ret, ":", rlen);
if (dgst_raw_len == 0)
return ret;
- if ((r = b64_ntop(dgst_raw, dgst_raw_len,
- ret + plen, rlen - plen)) == -1) {
+ if (b64_ntop(dgst_raw, dgst_raw_len, ret + plen, rlen - plen) == -1) {
freezero(ret, rlen);
return NULL;
}
@@ -1188,12 +1280,10 @@ sshkey_fingerprint(const struct sshkey *k, int dgst_alg,
dgst_raw, dgst_raw_len, k);
break;
default:
- explicit_bzero(dgst_raw, dgst_raw_len);
- free(dgst_raw);
+ freezero(dgst_raw, dgst_raw_len);
return NULL;
}
- explicit_bzero(dgst_raw, dgst_raw_len);
- free(dgst_raw);
+ freezero(dgst_raw, dgst_raw_len);
return retval;
}
@@ -1207,7 +1297,7 @@ peek_type_nid(const char *s, size_t l, int *nid)
continue;
if (memcmp(s, kt->name, l) == 0) {
*nid = -1;
- if (kt->type == KEY_ECDSA || kt->type == KEY_ECDSA_CERT)
+ if (key_type_is_ecdsa_variant(kt->type))
*nid = kt->nid;
return kt->type;
}
@@ -1233,11 +1323,15 @@ sshkey_read(struct sshkey *ret, char **cpp)
case KEY_RSA:
case KEY_DSA:
case KEY_ECDSA:
+ case KEY_ECDSA_SK:
case KEY_ED25519:
+ case KEY_ED25519_SK:
case KEY_DSA_CERT:
case KEY_ECDSA_CERT:
+ case KEY_ECDSA_SK_CERT:
case KEY_RSA_CERT:
case KEY_ED25519_CERT:
+ case KEY_ED25519_SK_CERT:
#ifdef WITH_XMSS
case KEY_XMSS:
case KEY_XMSS_CERT:
@@ -1292,7 +1386,7 @@ sshkey_read(struct sshkey *ret, char **cpp)
sshkey_free(k);
return SSH_ERR_KEY_TYPE_MISMATCH;
}
- if (sshkey_type_plain(type) == KEY_ECDSA && curve_nid != k->ecdsa_nid) {
+ if (key_type_is_ecdsa_variant(type) && curve_nid != k->ecdsa_nid) {
sshkey_free(k);
return SSH_ERR_EC_CURVE_MISMATCH;
}
@@ -1338,6 +1432,19 @@ sshkey_read(struct sshkey *ret, char **cpp)
sshkey_dump_ec_key(ret->ecdsa);
#endif
break;
+ case KEY_ECDSA_SK:
+ EC_KEY_free(ret->ecdsa);
+ ret->ecdsa = k->ecdsa;
+ ret->ecdsa_nid = k->ecdsa_nid;
+ ret->sk_application = k->sk_application;
+ k->ecdsa = NULL;
+ k->ecdsa_nid = -1;
+ k->sk_application = NULL;
+#ifdef DEBUG_PK
+ sshkey_dump_ec_key(ret->ecdsa);
+ fprintf(stderr, "App: %s\n", ret->sk_application);
+#endif
+ break;
# endif /* OPENSSL_HAS_ECC */
#endif /* WITH_OPENSSL */
case KEY_ED25519:
@@ -1348,6 +1455,13 @@ sshkey_read(struct sshkey *ret, char **cpp)
/* XXX */
#endif
break;
+ case KEY_ED25519_SK:
+ freezero(ret->ed25519_pk, ED25519_PK_SZ);
+ ret->ed25519_pk = k->ed25519_pk;
+ ret->sk_application = k->sk_application;
+ k->ed25519_pk = NULL;
+ k->sk_application = NULL;
+ break;
#ifdef WITH_XMSS
case KEY_XMSS:
free(ret->xmss_pk);
@@ -1392,7 +1506,7 @@ sshkey_to_base64(const struct sshkey *key, char **b64p)
return SSH_ERR_ALLOC_FAIL;
if ((r = sshkey_putb(key, b)) != 0)
goto out;
- if ((uu = sshbuf_dtob64(b)) == NULL) {
+ if ((uu = sshbuf_dtob64_string(b, 0)) == NULL) {
r = SSH_ERR_ALLOC_FAIL;
goto out;
}
@@ -1536,7 +1650,6 @@ sshkey_ecdsa_key_to_nid(EC_KEY *k)
};
int nid;
u_int i;
- BN_CTX *bnctx;
const EC_GROUP *g = EC_KEY_get0_group(k);
/*
@@ -1549,18 +1662,13 @@ sshkey_ecdsa_key_to_nid(EC_KEY *k)
*/
if ((nid = EC_GROUP_get_curve_name(g)) > 0)
return nid;
- if ((bnctx = BN_CTX_new()) == NULL)
- return -1;
for (i = 0; nids[i] != -1; i++) {
- if ((eg = EC_GROUP_new_by_curve_name(nids[i])) == NULL) {
- BN_CTX_free(bnctx);
+ if ((eg = EC_GROUP_new_by_curve_name(nids[i])) == NULL)
return -1;
- }
- if (EC_GROUP_cmp(g, eg, bnctx) == 0)
+ if (EC_GROUP_cmp(g, eg, NULL) == 0)
break;
EC_GROUP_free(eg);
}
- BN_CTX_free(bnctx);
if (nids[i] != -1) {
/* Use the group with the NID attached */
EC_GROUP_set_asn1_flag(eg, OPENSSL_EC_NAMED_CURVE);
@@ -1737,15 +1845,14 @@ sshkey_from_private(const struct sshkey *k, struct sshkey **pkp)
#endif /* WITH_OPENSSL */
*pkp = NULL;
+ if ((n = sshkey_new(k->type)) == NULL) {
+ r = SSH_ERR_ALLOC_FAIL;
+ goto out;
+ }
switch (k->type) {
#ifdef WITH_OPENSSL
case KEY_DSA:
case KEY_DSA_CERT:
- if ((n = sshkey_new(k->type)) == NULL) {
- r = SSH_ERR_ALLOC_FAIL;
- goto out;
- }
-
DSA_get0_pqg(k->dsa, &dsa_p, &dsa_q, &dsa_g);
DSA_get0_key(k->dsa, &dsa_pub_key, NULL);
if ((dsa_p_dup = BN_dup(dsa_p)) == NULL ||
@@ -1770,10 +1877,8 @@ sshkey_from_private(const struct sshkey *k, struct sshkey **pkp)
# ifdef OPENSSL_HAS_ECC
case KEY_ECDSA:
case KEY_ECDSA_CERT:
- if ((n = sshkey_new(k->type)) == NULL) {
- r = SSH_ERR_ALLOC_FAIL;
- goto out;
- }
+ case KEY_ECDSA_SK:
+ case KEY_ECDSA_SK_CERT:
n->ecdsa_nid = k->ecdsa_nid;
n->ecdsa = EC_KEY_new_by_curve_name(k->ecdsa_nid);
if (n->ecdsa == NULL) {
@@ -1785,14 +1890,15 @@ sshkey_from_private(const struct sshkey *k, struct sshkey **pkp)
r = SSH_ERR_LIBCRYPTO_ERROR;
goto out;
}
+ if (k->type != KEY_ECDSA_SK && k->type != KEY_ECDSA_SK_CERT)
+ break;
+ /* Append security-key application string */
+ if ((n->sk_application = strdup(k->sk_application)) == NULL)
+ goto out;
break;
# endif /* OPENSSL_HAS_ECC */
case KEY_RSA:
case KEY_RSA_CERT:
- if ((n = sshkey_new(k->type)) == NULL) {
- r = SSH_ERR_ALLOC_FAIL;
- goto out;
- }
RSA_get0_key(k->rsa, &rsa_n, &rsa_e, NULL);
if ((rsa_n_dup = BN_dup(rsa_n)) == NULL ||
(rsa_e_dup = BN_dup(rsa_e)) == NULL) {
@@ -1808,10 +1914,8 @@ sshkey_from_private(const struct sshkey *k, struct sshkey **pkp)
#endif /* WITH_OPENSSL */
case KEY_ED25519:
case KEY_ED25519_CERT:
- if ((n = sshkey_new(k->type)) == NULL) {
- r = SSH_ERR_ALLOC_FAIL;
- goto out;
- }
+ case KEY_ED25519_SK:
+ case KEY_ED25519_SK_CERT:
if (k->ed25519_pk != NULL) {
if ((n->ed25519_pk = malloc(ED25519_PK_SZ)) == NULL) {
r = SSH_ERR_ALLOC_FAIL;
@@ -1819,17 +1923,20 @@ sshkey_from_private(const struct sshkey *k, struct sshkey **pkp)
}
memcpy(n->ed25519_pk, k->ed25519_pk, ED25519_PK_SZ);
}
+ if (k->type != KEY_ED25519_SK &&
+ k->type != KEY_ED25519_SK_CERT)
+ break;
+ /* Append security-key application string */
+ if ((n->sk_application = strdup(k->sk_application)) == NULL)
+ goto out;
break;
#ifdef WITH_XMSS
case KEY_XMSS:
case KEY_XMSS_CERT:
- if ((n = sshkey_new(k->type)) == NULL) {
- r = SSH_ERR_ALLOC_FAIL;
- goto out;
- }
if ((r = sshkey_xmss_init(n, k->xmss_name)) != 0)
goto out;
if (k->xmss_pk != NULL) {
+ u_int32_t left;
size_t pklen = sshkey_xmss_pklen(k);
if (pklen == 0 || sshkey_xmss_pklen(n) != pklen) {
r = SSH_ERR_INTERNAL_ERROR;
@@ -1840,6 +1947,10 @@ sshkey_from_private(const struct sshkey *k, struct sshkey **pkp)
goto out;
}
memcpy(n->xmss_pk, k->xmss_pk, pklen);
+ /* simulate number of signatures left on pubkey */
+ left = sshkey_xmss_signatures_left(k);
+ if (left)
+ sshkey_xmss_enable_maxsign(n, left);
}
break;
#endif /* WITH_XMSS */
@@ -1867,6 +1978,221 @@ sshkey_from_private(const struct sshkey *k, struct sshkey **pkp)
return r;
}
+int
+sshkey_is_shielded(struct sshkey *k)
+{
+ return k != NULL && k->shielded_private != NULL;
+}
+
+int
+sshkey_shield_private(struct sshkey *k)
+{
+ struct sshbuf *prvbuf = NULL;
+ u_char *prekey = NULL, *enc = NULL, keyiv[SSH_DIGEST_MAX_LENGTH];
+ struct sshcipher_ctx *cctx = NULL;
+ const struct sshcipher *cipher;
+ size_t i, enclen = 0;
+ struct sshkey *kswap = NULL, tmp;
+ int r = SSH_ERR_INTERNAL_ERROR;
+
+#ifdef DEBUG_PK
+ fprintf(stderr, "%s: entering for %s\n", __func__, sshkey_ssh_name(k));
+#endif
+ if ((cipher = cipher_by_name(SSHKEY_SHIELD_CIPHER)) == NULL) {
+ r = SSH_ERR_INVALID_ARGUMENT;
+ goto out;
+ }
+ if (cipher_keylen(cipher) + cipher_ivlen(cipher) >
+ ssh_digest_bytes(SSHKEY_SHIELD_PREKEY_HASH)) {
+ r = SSH_ERR_INTERNAL_ERROR;
+ goto out;
+ }
+
+ /* Prepare a random pre-key, and from it an ephemeral key */
+ if ((prekey = malloc(SSHKEY_SHIELD_PREKEY_LEN)) == NULL) {
+ r = SSH_ERR_ALLOC_FAIL;
+ goto out;
+ }
+ arc4random_buf(prekey, SSHKEY_SHIELD_PREKEY_LEN);
+ if ((r = ssh_digest_memory(SSHKEY_SHIELD_PREKEY_HASH,
+ prekey, SSHKEY_SHIELD_PREKEY_LEN,
+ keyiv, SSH_DIGEST_MAX_LENGTH)) != 0)
+ goto out;
+#ifdef DEBUG_PK
+ fprintf(stderr, "%s: key+iv\n", __func__);
+ sshbuf_dump_data(keyiv, ssh_digest_bytes(SSHKEY_SHIELD_PREKEY_HASH),
+ stderr);
+#endif
+ if ((r = cipher_init(&cctx, cipher, keyiv, cipher_keylen(cipher),
+ keyiv + cipher_keylen(cipher), cipher_ivlen(cipher), 1)) != 0)
+ goto out;
+
+ /* Serialise and encrypt the private key using the ephemeral key */
+ if ((prvbuf = sshbuf_new()) == NULL) {
+ r = SSH_ERR_ALLOC_FAIL;
+ goto out;
+ }
+ if (sshkey_is_shielded(k) && (r = sshkey_unshield_private(k)) != 0)
+ goto out;
+ if ((r = sshkey_private_serialize_opt(k, prvbuf,
+ SSHKEY_SERIALIZE_SHIELD)) != 0)
+ goto out;
+ /* pad to cipher blocksize */
+ i = 0;
+ while (sshbuf_len(prvbuf) % cipher_blocksize(cipher)) {
+ if ((r = sshbuf_put_u8(prvbuf, ++i & 0xff)) != 0)
+ goto out;
+ }
+#ifdef DEBUG_PK
+ fprintf(stderr, "%s: serialised\n", __func__);
+ sshbuf_dump(prvbuf, stderr);
+#endif
+ /* encrypt */
+ enclen = sshbuf_len(prvbuf);
+ if ((enc = malloc(enclen)) == NULL) {
+ r = SSH_ERR_ALLOC_FAIL;
+ goto out;
+ }
+ if ((r = cipher_crypt(cctx, 0, enc,
+ sshbuf_ptr(prvbuf), sshbuf_len(prvbuf), 0, 0)) != 0)
+ goto out;
+#ifdef DEBUG_PK
+ fprintf(stderr, "%s: encrypted\n", __func__);
+ sshbuf_dump_data(enc, enclen, stderr);
+#endif
+
+ /* Make a scrubbed, public-only copy of our private key argument */
+ if ((r = sshkey_from_private(k, &kswap)) != 0)
+ goto out;
+
+ /* Swap the private key out (it will be destroyed below) */
+ tmp = *kswap;
+ *kswap = *k;
+ *k = tmp;
+
+ /* Insert the shielded key into our argument */
+ k->shielded_private = enc;
+ k->shielded_len = enclen;
+ k->shield_prekey = prekey;
+ k->shield_prekey_len = SSHKEY_SHIELD_PREKEY_LEN;
+ enc = prekey = NULL; /* transferred */
+ enclen = 0;
+
+ /* preserve key fields that are required for correct operation */
+ k->sk_flags = kswap->sk_flags;
+
+ /* success */
+ r = 0;
+
+ out:
+ /* XXX behaviour on error - invalidate original private key? */
+ cipher_free(cctx);
+ explicit_bzero(keyiv, sizeof(keyiv));
+ explicit_bzero(&tmp, sizeof(tmp));
+ freezero(enc, enclen);
+ freezero(prekey, SSHKEY_SHIELD_PREKEY_LEN);
+ sshkey_free(kswap);
+ sshbuf_free(prvbuf);
+ return r;
+}
+
+int
+sshkey_unshield_private(struct sshkey *k)
+{
+ struct sshbuf *prvbuf = NULL;
+ u_char pad, *cp, keyiv[SSH_DIGEST_MAX_LENGTH];
+ struct sshcipher_ctx *cctx = NULL;
+ const struct sshcipher *cipher;
+ size_t i;
+ struct sshkey *kswap = NULL, tmp;
+ int r = SSH_ERR_INTERNAL_ERROR;
+
+#ifdef DEBUG_PK
+ fprintf(stderr, "%s: entering for %s\n", __func__, sshkey_ssh_name(k));
+#endif
+ if (!sshkey_is_shielded(k))
+ return 0; /* nothing to do */
+
+ if ((cipher = cipher_by_name(SSHKEY_SHIELD_CIPHER)) == NULL) {
+ r = SSH_ERR_INVALID_ARGUMENT;
+ goto out;
+ }
+ if (cipher_keylen(cipher) + cipher_ivlen(cipher) >
+ ssh_digest_bytes(SSHKEY_SHIELD_PREKEY_HASH)) {
+ r = SSH_ERR_INTERNAL_ERROR;
+ goto out;
+ }
+ /* check size of shielded key blob */
+ if (k->shielded_len < cipher_blocksize(cipher) ||
+ (k->shielded_len % cipher_blocksize(cipher)) != 0) {
+ r = SSH_ERR_INVALID_FORMAT;
+ goto out;
+ }
+
+ /* Calculate the ephemeral key from the prekey */
+ if ((r = ssh_digest_memory(SSHKEY_SHIELD_PREKEY_HASH,
+ k->shield_prekey, k->shield_prekey_len,
+ keyiv, SSH_DIGEST_MAX_LENGTH)) != 0)
+ goto out;
+ if ((r = cipher_init(&cctx, cipher, keyiv, cipher_keylen(cipher),
+ keyiv + cipher_keylen(cipher), cipher_ivlen(cipher), 0)) != 0)
+ goto out;
+#ifdef DEBUG_PK
+ fprintf(stderr, "%s: key+iv\n", __func__);
+ sshbuf_dump_data(keyiv, ssh_digest_bytes(SSHKEY_SHIELD_PREKEY_HASH),
+ stderr);
+#endif
+
+ /* Decrypt and parse the shielded private key using the ephemeral key */
+ if ((prvbuf = sshbuf_new()) == NULL) {
+ r = SSH_ERR_ALLOC_FAIL;
+ goto out;
+ }
+ if ((r = sshbuf_reserve(prvbuf, k->shielded_len, &cp)) != 0)
+ goto out;
+ /* decrypt */
+#ifdef DEBUG_PK
+ fprintf(stderr, "%s: encrypted\n", __func__);
+ sshbuf_dump_data(k->shielded_private, k->shielded_len, stderr);
+#endif
+ if ((r = cipher_crypt(cctx, 0, cp,
+ k->shielded_private, k->shielded_len, 0, 0)) != 0)
+ goto out;
+#ifdef DEBUG_PK
+ fprintf(stderr, "%s: serialised\n", __func__);
+ sshbuf_dump(prvbuf, stderr);
+#endif
+ /* Parse private key */
+ if ((r = sshkey_private_deserialize(prvbuf, &kswap)) != 0)
+ goto out;
+ /* Check deterministic padding */
+ i = 0;
+ while (sshbuf_len(prvbuf)) {
+ if ((r = sshbuf_get_u8(prvbuf, &pad)) != 0)
+ goto out;
+ if (pad != (++i & 0xff)) {
+ r = SSH_ERR_INVALID_FORMAT;
+ goto out;
+ }
+ }
+
+ /* Swap the parsed key back into place */
+ tmp = *kswap;
+ *kswap = *k;
+ *k = tmp;
+
+ /* success */
+ r = 0;
+
+ out:
+ cipher_free(cctx);
+ explicit_bzero(keyiv, sizeof(keyiv));
+ explicit_bzero(&tmp, sizeof(tmp));
+ sshkey_free(kswap);
+ sshbuf_free(prvbuf);
+ return r;
+}
+
static int
cert_parse(struct sshbuf *b, struct sshkey *key, struct sshbuf *certbuf)
{
@@ -1976,9 +2302,10 @@ cert_parse(struct sshbuf *b, struct sshkey *key, struct sshbuf *certbuf)
goto out;
}
if ((ret = sshkey_verify(key->cert->signature_key, sig, slen,
- sshbuf_ptr(key->cert->certblob), signed_len, NULL, 0)) != 0)
+ sshbuf_ptr(key->cert->certblob), signed_len, NULL, 0, NULL)) != 0)
goto out;
- if ((ret = get_sigtype(sig, slen, &key->cert->signature_type)) != 0)
+ if ((ret = sshkey_get_sigtype(sig, slen,
+ &key->cert->signature_type)) != 0)
goto out;
/* Success */
@@ -2056,13 +2383,8 @@ sshkey_from_blob_internal(struct sshbuf *b, struct sshkey **keyp,
ret = SSH_ERR_ALLOC_FAIL;
goto out;
}
- if ((rsa_e = BN_new()) == NULL ||
- (rsa_n = BN_new()) == NULL) {
- ret = SSH_ERR_ALLOC_FAIL;
- goto out;
- }
- if (sshbuf_get_bignum2(b, rsa_e) != 0 ||
- sshbuf_get_bignum2(b, rsa_n) != 0) {
+ if (sshbuf_get_bignum2(b, &rsa_e) != 0 ||
+ sshbuf_get_bignum2(b, &rsa_n) != 0) {
ret = SSH_ERR_INVALID_FORMAT;
goto out;
}
@@ -2089,17 +2411,10 @@ sshkey_from_blob_internal(struct sshbuf *b, struct sshkey **keyp,
ret = SSH_ERR_ALLOC_FAIL;
goto out;
}
- if ((dsa_p = BN_new()) == NULL ||
- (dsa_q = BN_new()) == NULL ||
- (dsa_g = BN_new()) == NULL ||
- (dsa_pub_key = BN_new()) == NULL) {
- ret = SSH_ERR_ALLOC_FAIL;
- goto out;
- }
- if (sshbuf_get_bignum2(b, dsa_p) != 0 ||
- sshbuf_get_bignum2(b, dsa_q) != 0 ||
- sshbuf_get_bignum2(b, dsa_g) != 0 ||
- sshbuf_get_bignum2(b, dsa_pub_key) != 0) {
+ if (sshbuf_get_bignum2(b, &dsa_p) != 0 ||
+ sshbuf_get_bignum2(b, &dsa_q) != 0 ||
+ sshbuf_get_bignum2(b, &dsa_g) != 0 ||
+ sshbuf_get_bignum2(b, &dsa_pub_key) != 0) {
ret = SSH_ERR_INVALID_FORMAT;
goto out;
}
@@ -2117,15 +2432,17 @@ sshkey_from_blob_internal(struct sshbuf *b, struct sshkey **keyp,
DSA_print_fp(stderr, key->dsa, 8);
#endif
break;
+# ifdef OPENSSL_HAS_ECC
case KEY_ECDSA_CERT:
+ case KEY_ECDSA_SK_CERT:
/* Skip nonce */
if (sshbuf_get_string_direct(b, NULL, NULL) != 0) {
ret = SSH_ERR_INVALID_FORMAT;
goto out;
}
/* FALLTHROUGH */
-# ifdef OPENSSL_HAS_ECC
case KEY_ECDSA:
+ case KEY_ECDSA_SK:
if ((key = sshkey_new(type)) == NULL) {
ret = SSH_ERR_ALLOC_FAIL;
goto out;
@@ -2166,10 +2483,22 @@ sshkey_from_blob_internal(struct sshbuf *b, struct sshkey **keyp,
#ifdef DEBUG_PK
sshkey_dump_ec_point(EC_KEY_get0_group(key->ecdsa), q);
#endif
+ if (type == KEY_ECDSA_SK || type == KEY_ECDSA_SK_CERT) {
+ /* Parse additional security-key application string */
+ if (sshbuf_get_cstring(b, &key->sk_application,
+ NULL) != 0) {
+ ret = SSH_ERR_INVALID_FORMAT;
+ goto out;
+ }
+#ifdef DEBUG_PK
+ fprintf(stderr, "App: %s\n", key->sk_application);
+#endif
+ }
break;
# endif /* OPENSSL_HAS_ECC */
#endif /* WITH_OPENSSL */
case KEY_ED25519_CERT:
+ case KEY_ED25519_SK_CERT:
/* Skip nonce */
if (sshbuf_get_string_direct(b, NULL, NULL) != 0) {
ret = SSH_ERR_INVALID_FORMAT;
@@ -2177,6 +2506,7 @@ sshkey_from_blob_internal(struct sshbuf *b, struct sshkey **keyp,
}
/* FALLTHROUGH */
case KEY_ED25519:
+ case KEY_ED25519_SK:
if ((ret = sshbuf_get_string(b, &pk, &len)) != 0)
goto out;
if (len != ED25519_PK_SZ) {
@@ -2187,6 +2517,17 @@ sshkey_from_blob_internal(struct sshbuf *b, struct sshkey **keyp,
ret = SSH_ERR_ALLOC_FAIL;
goto out;
}
+ if (type == KEY_ED25519_SK || type == KEY_ED25519_SK_CERT) {
+ /* Parse additional security-key application string */
+ if (sshbuf_get_cstring(b, &key->sk_application,
+ NULL) != 0) {
+ ret = SSH_ERR_INVALID_FORMAT;
+ goto out;
+ }
+#ifdef DEBUG_PK
+ fprintf(stderr, "App: %s\n", key->sk_application);
+#endif
+ }
key->ed25519_pk = pk;
pk = NULL;
break;
@@ -2292,8 +2633,8 @@ sshkey_froms(struct sshbuf *buf, struct sshkey **keyp)
return r;
}
-static int
-get_sigtype(const u_char *sig, size_t siglen, char **sigtypep)
+int
+sshkey_get_sigtype(const u_char *sig, size_t siglen, char **sigtypep)
{
int r;
struct sshbuf *b = NULL;
@@ -2375,7 +2716,7 @@ sshkey_check_sigtype(const u_char *sig, size_t siglen,
return 0;
if ((expected_alg = sshkey_sigalg_by_name(requested_alg)) == NULL)
return SSH_ERR_INVALID_ARGUMENT;
- if ((r = get_sigtype(sig, siglen, &sigtype)) != 0)
+ if ((r = sshkey_get_sigtype(sig, siglen, &sigtype)) != 0)
return r;
r = strcmp(expected_alg, sigtype) == 0;
free(sigtype);
@@ -2383,41 +2724,63 @@ sshkey_check_sigtype(const u_char *sig, size_t siglen,
}
int
-sshkey_sign(const struct sshkey *key,
+sshkey_sign(struct sshkey *key,
u_char **sigp, size_t *lenp,
- const u_char *data, size_t datalen, const char *alg, u_int compat)
+ const u_char *data, size_t datalen,
+ const char *alg, const char *sk_provider, const char *sk_pin, u_int compat)
{
+ int was_shielded = sshkey_is_shielded(key);
+ int r2, r = SSH_ERR_INTERNAL_ERROR;
+
if (sigp != NULL)
*sigp = NULL;
if (lenp != NULL)
*lenp = 0;
if (datalen > SSH_KEY_MAX_SIGN_DATA_SIZE)
return SSH_ERR_INVALID_ARGUMENT;
+ if ((r = sshkey_unshield_private(key)) != 0)
+ return r;
switch (key->type) {
#ifdef WITH_OPENSSL
case KEY_DSA_CERT:
case KEY_DSA:
- return ssh_dss_sign(key, sigp, lenp, data, datalen, compat);
+ r = ssh_dss_sign(key, sigp, lenp, data, datalen, compat);
+ break;
# ifdef OPENSSL_HAS_ECC
case KEY_ECDSA_CERT:
case KEY_ECDSA:
- return ssh_ecdsa_sign(key, sigp, lenp, data, datalen, compat);
+ r = ssh_ecdsa_sign(key, sigp, lenp, data, datalen, compat);
+ break;
# endif /* OPENSSL_HAS_ECC */
case KEY_RSA_CERT:
case KEY_RSA:
- return ssh_rsa_sign(key, sigp, lenp, data, datalen, alg);
+ r = ssh_rsa_sign(key, sigp, lenp, data, datalen, alg);
+ break;
#endif /* WITH_OPENSSL */
case KEY_ED25519:
case KEY_ED25519_CERT:
- return ssh_ed25519_sign(key, sigp, lenp, data, datalen, compat);
+ r = ssh_ed25519_sign(key, sigp, lenp, data, datalen, compat);
+ break;
+ case KEY_ED25519_SK:
+ case KEY_ED25519_SK_CERT:
+ case KEY_ECDSA_SK_CERT:
+ case KEY_ECDSA_SK:
+ r = sshsk_sign(sk_provider, key, sigp, lenp, data,
+ datalen, compat, sk_pin);
+ break;
#ifdef WITH_XMSS
case KEY_XMSS:
case KEY_XMSS_CERT:
- return ssh_xmss_sign(key, sigp, lenp, data, datalen, compat);
+ r = ssh_xmss_sign(key, sigp, lenp, data, datalen, compat);
+ break;
#endif /* WITH_XMSS */
default:
- return SSH_ERR_KEY_TYPE_UNKNOWN;
+ r = SSH_ERR_KEY_TYPE_UNKNOWN;
+ break;
}
+ if (was_shielded && (r2 = sshkey_shield_private(key)) != 0)
+ return r2;
+ return r;
}
/*
@@ -2427,8 +2790,11 @@ sshkey_sign(const struct sshkey *key,
int
sshkey_verify(const struct sshkey *key,
const u_char *sig, size_t siglen,
- const u_char *data, size_t dlen, const char *alg, u_int compat)
+ const u_char *data, size_t dlen, const char *alg, u_int compat,
+ struct sshkey_sig_details **detailsp)
{
+ if (detailsp != NULL)
+ *detailsp = NULL;
if (siglen == 0 || dlen > SSH_KEY_MAX_SIGN_DATA_SIZE)
return SSH_ERR_INVALID_ARGUMENT;
switch (key->type) {
@@ -2440,6 +2806,10 @@ sshkey_verify(const struct sshkey *key,
case KEY_ECDSA_CERT:
case KEY_ECDSA:
return ssh_ecdsa_verify(key, sig, siglen, data, dlen, compat);
+ case KEY_ECDSA_SK_CERT:
+ case KEY_ECDSA_SK:
+ return ssh_ecdsa_sk_verify(key, sig, siglen, data, dlen,
+ compat, detailsp);
# endif /* OPENSSL_HAS_ECC */
case KEY_RSA_CERT:
case KEY_RSA:
@@ -2448,6 +2818,10 @@ sshkey_verify(const struct sshkey *key,
case KEY_ED25519:
case KEY_ED25519_CERT:
return ssh_ed25519_verify(key, sig, siglen, data, dlen, compat);
+ case KEY_ED25519_SK:
+ case KEY_ED25519_SK_CERT:
+ return ssh_ed25519_sk_verify(key, sig, siglen, data, dlen,
+ compat, detailsp);
#ifdef WITH_XMSS
case KEY_XMSS:
case KEY_XMSS_CERT:
@@ -2475,7 +2849,13 @@ sshkey_to_certified(struct sshkey *k)
case KEY_ECDSA:
newtype = KEY_ECDSA_CERT;
break;
+ case KEY_ECDSA_SK:
+ newtype = KEY_ECDSA_SK_CERT;
+ break;
#endif /* WITH_OPENSSL */
+ case KEY_ED25519_SK:
+ newtype = KEY_ED25519_SK_CERT;
+ break;
case KEY_ED25519:
newtype = KEY_ED25519_CERT;
break;
@@ -2508,6 +2888,7 @@ sshkey_drop_cert(struct sshkey *k)
/* Sign a certified key, (re-)generating the signed certblob. */
int
sshkey_certify_custom(struct sshkey *k, struct sshkey *ca, const char *alg,
+ const char *sk_provider, const char *sk_pin,
sshkey_certify_signer *signer, void *signer_ctx)
{
struct sshbuf *principals = NULL;
@@ -2538,6 +2919,13 @@ sshkey_certify_custom(struct sshkey *k, struct sshkey *ca, const char *alg,
strcmp(alg, k->cert->signature_type) != 0)
return SSH_ERR_INVALID_ARGUMENT;
+ /*
+ * If no signing algorithm or signature_type was specified and we're
+ * using a RSA key, then default to a good signature algorithm.
+ */
+ if (alg == NULL && ca->type == KEY_RSA)
+ alg = "rsa-sha2-512";
+
if ((ret = sshkey_to_blob(ca, &ca_blob, &ca_len)) != 0)
return SSH_ERR_KEY_CERT_INVALID_SIGN_KEY;
@@ -2565,12 +2953,18 @@ sshkey_certify_custom(struct sshkey *k, struct sshkey *ca, const char *alg,
break;
# ifdef OPENSSL_HAS_ECC
case KEY_ECDSA_CERT:
+ case KEY_ECDSA_SK_CERT:
if ((ret = sshbuf_put_cstring(cert,
sshkey_curve_nid_to_name(k->ecdsa_nid))) != 0 ||
(ret = sshbuf_put_ec(cert,
EC_KEY_get0_public_key(k->ecdsa),
EC_KEY_get0_group(k->ecdsa))) != 0)
goto out;
+ if (k->type == KEY_ECDSA_SK_CERT) {
+ if ((ret = sshbuf_put_cstring(cert,
+ k->sk_application)) != 0)
+ goto out;
+ }
break;
# endif /* OPENSSL_HAS_ECC */
case KEY_RSA_CERT:
@@ -2581,9 +2975,15 @@ sshkey_certify_custom(struct sshkey *k, struct sshkey *ca, const char *alg,
break;
#endif /* WITH_OPENSSL */
case KEY_ED25519_CERT:
+ case KEY_ED25519_SK_CERT:
if ((ret = sshbuf_put_string(cert,
k->ed25519_pk, ED25519_PK_SZ)) != 0)
goto out;
+ if (k->type == KEY_ED25519_SK_CERT) {
+ if ((ret = sshbuf_put_cstring(cert,
+ k->sk_application)) != 0)
+ goto out;
+ }
break;
#ifdef WITH_XMSS
case KEY_XMSS_CERT:
@@ -2627,10 +3027,10 @@ sshkey_certify_custom(struct sshkey *k, struct sshkey *ca, const char *alg,
/* Sign the whole mess */
if ((ret = signer(ca, &sig_blob, &sig_len, sshbuf_ptr(cert),
- sshbuf_len(cert), alg, 0, signer_ctx)) != 0)
+ sshbuf_len(cert), alg, sk_provider, sk_pin, 0, signer_ctx)) != 0)
goto out;
/* Check and update signature_type against what was actually used */
- if ((ret = get_sigtype(sig_blob, sig_len, &sigtype)) != 0)
+ if ((ret = sshkey_get_sigtype(sig_blob, sig_len, &sigtype)) != 0)
goto out;
if (alg != NULL && strcmp(alg, sigtype) != 0) {
ret = SSH_ERR_SIGN_ALG_UNSUPPORTED;
@@ -2655,32 +3055,38 @@ sshkey_certify_custom(struct sshkey *k, struct sshkey *ca, const char *alg,
}
static int
-default_key_sign(const struct sshkey *key, u_char **sigp, size_t *lenp,
+default_key_sign(struct sshkey *key, u_char **sigp, size_t *lenp,
const u_char *data, size_t datalen,
- const char *alg, u_int compat, void *ctx)
+ const char *alg, const char *sk_provider, const char *sk_pin,
+ u_int compat, void *ctx)
{
if (ctx != NULL)
return SSH_ERR_INVALID_ARGUMENT;
- return sshkey_sign(key, sigp, lenp, data, datalen, alg, compat);
+ return sshkey_sign(key, sigp, lenp, data, datalen, alg,
+ sk_provider, sk_pin, compat);
}
int
-sshkey_certify(struct sshkey *k, struct sshkey *ca, const char *alg)
+sshkey_certify(struct sshkey *k, struct sshkey *ca, const char *alg,
+ const char *sk_provider, const char *sk_pin)
{
- return sshkey_certify_custom(k, ca, alg, default_key_sign, NULL);
+ return sshkey_certify_custom(k, ca, alg, sk_provider, sk_pin,
+ default_key_sign, NULL);
}
int
sshkey_cert_check_authority(const struct sshkey *k,
- int want_host, int require_principal,
- const char *name, const char **reason)
+ int want_host, int require_principal, int wildcard_pattern,
+ uint64_t verify_time, const char *name, const char **reason)
{
u_int i, principal_matches;
- time_t now = time(NULL);
-
- if (reason != NULL)
- *reason = NULL;
+ if (reason == NULL)
+ return SSH_ERR_INVALID_ARGUMENT;
+ if (!sshkey_is_cert(k)) {
+ *reason = "Key is not a certificate";
+ return SSH_ERR_KEY_CERT_INVALID;
+ }
if (want_host) {
if (k->cert->type != SSH2_CERT_TYPE_HOST) {
*reason = "Certificate invalid: not a host certificate";
@@ -2692,16 +3098,11 @@ sshkey_cert_check_authority(const struct sshkey *k,
return SSH_ERR_KEY_CERT_INVALID;
}
}
- if (now < 0) {
- /* yikes - system clock before epoch! */
- *reason = "Certificate invalid: not yet valid";
- return SSH_ERR_KEY_CERT_INVALID;
- }
- if ((u_int64_t)now < k->cert->valid_after) {
+ if (verify_time < k->cert->valid_after) {
*reason = "Certificate invalid: not yet valid";
return SSH_ERR_KEY_CERT_INVALID;
}
- if ((u_int64_t)now >= k->cert->valid_before) {
+ if (verify_time >= k->cert->valid_before) {
*reason = "Certificate invalid: expired";
return SSH_ERR_KEY_CERT_INVALID;
}
@@ -2713,7 +3114,13 @@ sshkey_cert_check_authority(const struct sshkey *k,
} else if (name != NULL) {
principal_matches = 0;
for (i = 0; i < k->cert->nprincipals; i++) {
- if (strcmp(name, k->cert->principals[i]) == 0) {
+ if (wildcard_pattern) {
+ if (match_pattern(k->cert->principals[i],
+ name)) {
+ principal_matches = 1;
+ break;
+ }
+ } else if (strcmp(name, k->cert->principals[i]) == 0) {
principal_matches = 1;
break;
}
@@ -2727,32 +3134,58 @@ sshkey_cert_check_authority(const struct sshkey *k,
return 0;
}
+int
+sshkey_cert_check_authority_now(const struct sshkey *k,
+ int want_host, int require_principal, int wildcard_pattern,
+ const char *name, const char **reason)
+{
+ time_t now;
+
+ if ((now = time(NULL)) < 0) {
+ /* yikes - system clock before epoch! */
+ *reason = "Certificate invalid: not yet valid";
+ return SSH_ERR_KEY_CERT_INVALID;
+ }
+ return sshkey_cert_check_authority(k, want_host, require_principal,
+ wildcard_pattern, (uint64_t)now, name, reason);
+}
+
+int
+sshkey_cert_check_host(const struct sshkey *key, const char *host,
+ int wildcard_principals, const char *ca_sign_algorithms,
+ const char **reason)
+{
+ int r;
+
+ if ((r = sshkey_cert_check_authority_now(key, 1, 0, wildcard_principals,
+ host, reason)) != 0)
+ return r;
+ if (sshbuf_len(key->cert->critical) != 0) {
+ *reason = "Certificate contains unsupported critical options";
+ return SSH_ERR_KEY_CERT_INVALID;
+ }
+ if (ca_sign_algorithms != NULL &&
+ (r = sshkey_check_cert_sigtype(key, ca_sign_algorithms)) != 0) {
+ *reason = "Certificate signed with disallowed algorithm";
+ return SSH_ERR_KEY_CERT_INVALID;
+ }
+ return 0;
+}
+
size_t
sshkey_format_cert_validity(const struct sshkey_cert *cert, char *s, size_t l)
{
- char from[32], to[32], ret[64];
- time_t tt;
- struct tm *tm;
+ char from[32], to[32], ret[128];
*from = *to = '\0';
if (cert->valid_after == 0 &&
cert->valid_before == 0xffffffffffffffffULL)
return strlcpy(s, "forever", l);
- if (cert->valid_after != 0) {
- /* XXX revisit INT_MAX in 2038 :) */
- tt = cert->valid_after > INT_MAX ?
- INT_MAX : cert->valid_after;
- tm = localtime(&tt);
- strftime(from, sizeof(from), "%Y-%m-%dT%H:%M:%S", tm);
- }
- if (cert->valid_before != 0xffffffffffffffffULL) {
- /* XXX revisit INT_MAX in 2038 :) */
- tt = cert->valid_before > INT_MAX ?
- INT_MAX : cert->valid_before;
- tm = localtime(&tt);
- strftime(to, sizeof(to), "%Y-%m-%dT%H:%M:%S", tm);
- }
+ if (cert->valid_after != 0)
+ format_absolute_time(cert->valid_after, from, sizeof(from));
+ if (cert->valid_before != 0xffffffffffffffffULL)
+ format_absolute_time(cert->valid_before, to, sizeof(to));
if (cert->valid_after == 0)
snprintf(ret, sizeof(ret), "before %s", to);
@@ -2765,15 +3198,21 @@ sshkey_format_cert_validity(const struct sshkey_cert *cert, char *s, size_t l)
}
int
-sshkey_private_serialize_opt(const struct sshkey *key, struct sshbuf *b,
+sshkey_private_serialize_opt(struct sshkey *key, struct sshbuf *buf,
enum sshkey_serialize_rep opts)
{
int r = SSH_ERR_INTERNAL_ERROR;
+ int was_shielded = sshkey_is_shielded(key);
+ struct sshbuf *b = NULL;
#ifdef WITH_OPENSSL
const BIGNUM *rsa_n, *rsa_e, *rsa_d, *rsa_iqmp, *rsa_p, *rsa_q;
const BIGNUM *dsa_p, *dsa_q, *dsa_g, *dsa_pub_key, *dsa_priv_key;
#endif /* WITH_OPENSSL */
+ if ((r = sshkey_unshield_private(key)) != 0)
+ return r;
+ if ((b = sshbuf_new()) == NULL)
+ return SSH_ERR_ALLOC_FAIL;
if ((r = sshbuf_put_cstring(b, sshkey_ssh_name(key))) != 0)
goto out;
switch (key->type) {
@@ -2844,6 +3283,28 @@ sshkey_private_serialize_opt(const struct sshkey *key, struct sshbuf *b,
EC_KEY_get0_private_key(key->ecdsa))) != 0)
goto out;
break;
+ case KEY_ECDSA_SK:
+ if ((r = sshbuf_put_cstring(b,
+ sshkey_curve_nid_to_name(key->ecdsa_nid))) != 0 ||
+ (r = sshbuf_put_eckey(b, key->ecdsa)) != 0 ||
+ (r = sshbuf_put_cstring(b, key->sk_application)) != 0 ||
+ (r = sshbuf_put_u8(b, key->sk_flags)) != 0 ||
+ (r = sshbuf_put_stringb(b, key->sk_key_handle)) != 0 ||
+ (r = sshbuf_put_stringb(b, key->sk_reserved)) != 0)
+ goto out;
+ break;
+ case KEY_ECDSA_SK_CERT:
+ if (key->cert == NULL || sshbuf_len(key->cert->certblob) == 0) {
+ r = SSH_ERR_INVALID_ARGUMENT;
+ goto out;
+ }
+ if ((r = sshbuf_put_stringb(b, key->cert->certblob)) != 0 ||
+ (r = sshbuf_put_cstring(b, key->sk_application)) != 0 ||
+ (r = sshbuf_put_u8(b, key->sk_flags)) != 0 ||
+ (r = sshbuf_put_stringb(b, key->sk_key_handle)) != 0 ||
+ (r = sshbuf_put_stringb(b, key->sk_reserved)) != 0)
+ goto out;
+ break;
# endif /* OPENSSL_HAS_ECC */
#endif /* WITH_OPENSSL */
case KEY_ED25519:
@@ -2865,6 +3326,29 @@ sshkey_private_serialize_opt(const struct sshkey *key, struct sshbuf *b,
ED25519_SK_SZ)) != 0)
goto out;
break;
+ case KEY_ED25519_SK:
+ if ((r = sshbuf_put_string(b, key->ed25519_pk,
+ ED25519_PK_SZ)) != 0 ||
+ (r = sshbuf_put_cstring(b, key->sk_application)) != 0 ||
+ (r = sshbuf_put_u8(b, key->sk_flags)) != 0 ||
+ (r = sshbuf_put_stringb(b, key->sk_key_handle)) != 0 ||
+ (r = sshbuf_put_stringb(b, key->sk_reserved)) != 0)
+ goto out;
+ break;
+ case KEY_ED25519_SK_CERT:
+ if (key->cert == NULL || sshbuf_len(key->cert->certblob) == 0) {
+ r = SSH_ERR_INVALID_ARGUMENT;
+ goto out;
+ }
+ if ((r = sshbuf_put_stringb(b, key->cert->certblob)) != 0 ||
+ (r = sshbuf_put_string(b, key->ed25519_pk,
+ ED25519_PK_SZ)) != 0 ||
+ (r = sshbuf_put_cstring(b, key->sk_application)) != 0 ||
+ (r = sshbuf_put_u8(b, key->sk_flags)) != 0 ||
+ (r = sshbuf_put_stringb(b, key->sk_key_handle)) != 0 ||
+ (r = sshbuf_put_stringb(b, key->sk_reserved)) != 0)
+ goto out;
+ break;
#ifdef WITH_XMSS
case KEY_XMSS:
if (key->xmss_name == NULL) {
@@ -2899,14 +3383,23 @@ sshkey_private_serialize_opt(const struct sshkey *key, struct sshbuf *b,
r = SSH_ERR_INVALID_ARGUMENT;
goto out;
}
- /* success */
+ /*
+ * success (but we still need to append the output to buf after
+ * possibly re-shielding the private key)
+ */
r = 0;
out:
+ if (was_shielded)
+ r = sshkey_shield_private(key);
+ if (r == 0)
+ r = sshbuf_putb(buf, b);
+ sshbuf_free(b);
+
return r;
}
int
-sshkey_private_serialize(const struct sshkey *key, struct sshbuf *b)
+sshkey_private_serialize(struct sshkey *key, struct sshbuf *b)
{
return sshkey_private_serialize_opt(key, b,
SSHKEY_SERIALIZE_DEFAULT);
@@ -2916,10 +3409,12 @@ int
sshkey_private_deserialize(struct sshbuf *buf, struct sshkey **kp)
{
char *tname = NULL, *curve = NULL, *xmss_name = NULL;
+ char *expect_sk_application = NULL;
struct sshkey *k = NULL;
size_t pklen = 0, sklen = 0;
int type, r = SSH_ERR_INTERNAL_ERROR;
u_char *ed25519_pk = NULL, *ed25519_sk = NULL;
+ u_char *expect_ed25519_pk = NULL;
u_char *xmss_pk = NULL, *xmss_sk = NULL;
#ifdef WITH_OPENSSL
BIGNUM *exponent = NULL;
@@ -2934,45 +3429,59 @@ sshkey_private_deserialize(struct sshbuf *buf, struct sshkey **kp)
if ((r = sshbuf_get_cstring(buf, &tname, NULL)) != 0)
goto out;
type = sshkey_type_from_name(tname);
- switch (type) {
-#ifdef WITH_OPENSSL
- case KEY_DSA:
- if ((k = sshkey_new(type)) == NULL) {
- r = SSH_ERR_ALLOC_FAIL;
+ if (sshkey_type_is_cert(type)) {
+ /*
+ * Certificate key private keys begin with the certificate
+ * itself. Make sure this matches the type of the enclosing
+ * private key.
+ */
+ if ((r = sshkey_froms(buf, &k)) != 0)
+ goto out;
+ if (k->type != type) {
+ r = SSH_ERR_KEY_CERT_MISMATCH;
+ goto out;
+ }
+ /* For ECDSA keys, the group must match too */
+ if (k->type == KEY_ECDSA &&
+ k->ecdsa_nid != sshkey_ecdsa_nid_from_name(tname)) {
+ r = SSH_ERR_KEY_CERT_MISMATCH;
goto out;
}
- if ((dsa_p = BN_new()) == NULL ||
- (dsa_q = BN_new()) == NULL ||
- (dsa_g = BN_new()) == NULL ||
- (dsa_pub_key = BN_new()) == NULL ||
- (dsa_priv_key = BN_new()) == NULL) {
+ /*
+ * Several fields are redundant between certificate and
+ * private key body, we require these to match.
+ */
+ expect_sk_application = k->sk_application;
+ expect_ed25519_pk = k->ed25519_pk;
+ k->sk_application = NULL;
+ k->ed25519_pk = NULL;
+ } else {
+ if ((k = sshkey_new(type)) == NULL) {
r = SSH_ERR_ALLOC_FAIL;
goto out;
}
- if ((r = sshbuf_get_bignum2(buf, dsa_p)) != 0 ||
- (r = sshbuf_get_bignum2(buf, dsa_q)) != 0 ||
- (r = sshbuf_get_bignum2(buf, dsa_g)) != 0 ||
- (r = sshbuf_get_bignum2(buf, dsa_pub_key)) != 0 ||
- (r = sshbuf_get_bignum2(buf, dsa_priv_key)) != 0)
+ }
+ switch (type) {
+#ifdef WITH_OPENSSL
+ case KEY_DSA:
+ if ((r = sshbuf_get_bignum2(buf, &dsa_p)) != 0 ||
+ (r = sshbuf_get_bignum2(buf, &dsa_q)) != 0 ||
+ (r = sshbuf_get_bignum2(buf, &dsa_g)) != 0 ||
+ (r = sshbuf_get_bignum2(buf, &dsa_pub_key)) != 0)
goto out;
if (!DSA_set0_pqg(k->dsa, dsa_p, dsa_q, dsa_g)) {
r = SSH_ERR_LIBCRYPTO_ERROR;
goto out;
}
dsa_p = dsa_q = dsa_g = NULL; /* transferred */
- if (!DSA_set0_key(k->dsa, dsa_pub_key, dsa_priv_key)) {
+ if (!DSA_set0_key(k->dsa, dsa_pub_key, NULL)) {
r = SSH_ERR_LIBCRYPTO_ERROR;
goto out;
}
- dsa_pub_key = dsa_priv_key = NULL; /* transferred */
- break;
+ dsa_pub_key = NULL; /* transferred */
+ /* FALLTHROUGH */
case KEY_DSA_CERT:
- if ((dsa_priv_key = BN_new()) == NULL) {
- r = SSH_ERR_ALLOC_FAIL;
- goto out;
- }
- if ((r = sshkey_froms(buf, &k)) != 0 ||
- (r = sshbuf_get_bignum2(buf, dsa_priv_key)) != 0)
+ if ((r = sshbuf_get_bignum2(buf, &dsa_priv_key)) != 0)
goto out;
if (!DSA_set0_key(k->dsa, NULL, dsa_priv_key)) {
r = SSH_ERR_LIBCRYPTO_ERROR;
@@ -2982,10 +3491,6 @@ sshkey_private_deserialize(struct sshbuf *buf, struct sshkey **kp)
break;
# ifdef OPENSSL_HAS_ECC
case KEY_ECDSA:
- if ((k = sshkey_new(type)) == NULL) {
- r = SSH_ERR_ALLOC_FAIL;
- goto out;
- }
if ((k->ecdsa_nid = sshkey_ecdsa_nid_from_name(tname)) == -1) {
r = SSH_ERR_INVALID_ARGUMENT;
goto out;
@@ -2997,12 +3502,15 @@ sshkey_private_deserialize(struct sshbuf *buf, struct sshkey **kp)
goto out;
}
k->ecdsa = EC_KEY_new_by_curve_name(k->ecdsa_nid);
- if (k->ecdsa == NULL || (exponent = BN_new()) == NULL) {
+ if (k->ecdsa == NULL) {
r = SSH_ERR_LIBCRYPTO_ERROR;
goto out;
}
- if ((r = sshbuf_get_eckey(buf, k->ecdsa)) != 0 ||
- (r = sshbuf_get_bignum2(buf, exponent)))
+ if ((r = sshbuf_get_eckey(buf, k->ecdsa)) != 0)
+ goto out;
+ /* FALLTHROUGH */
+ case KEY_ECDSA_CERT:
+ if ((r = sshbuf_get_bignum2(buf, &exponent)) != 0)
goto out;
if (EC_KEY_set_private_key(k->ecdsa, exponent) != 1) {
r = SSH_ERR_LIBCRYPTO_ERROR;
@@ -3013,73 +3521,70 @@ sshkey_private_deserialize(struct sshbuf *buf, struct sshkey **kp)
(r = sshkey_ec_validate_private(k->ecdsa)) != 0)
goto out;
break;
- case KEY_ECDSA_CERT:
- if ((exponent = BN_new()) == NULL) {
- r = SSH_ERR_LIBCRYPTO_ERROR;
- goto out;
- }
- if ((r = sshkey_froms(buf, &k)) != 0 ||
- (r = sshbuf_get_bignum2(buf, exponent)) != 0)
- goto out;
- if (EC_KEY_set_private_key(k->ecdsa, exponent) != 1) {
- r = SSH_ERR_LIBCRYPTO_ERROR;
+ case KEY_ECDSA_SK:
+ if ((k->ecdsa_nid = sshkey_ecdsa_nid_from_name(tname)) == -1) {
+ r = SSH_ERR_INVALID_ARGUMENT;
goto out;
}
- if ((r = sshkey_ec_validate_public(EC_KEY_get0_group(k->ecdsa),
- EC_KEY_get0_public_key(k->ecdsa))) != 0 ||
- (r = sshkey_ec_validate_private(k->ecdsa)) != 0)
+ if ((r = sshbuf_get_cstring(buf, &curve, NULL)) != 0)
goto out;
- break;
-# endif /* OPENSSL_HAS_ECC */
- case KEY_RSA:
- if ((k = sshkey_new(type)) == NULL) {
- r = SSH_ERR_ALLOC_FAIL;
+ if (k->ecdsa_nid != sshkey_curve_name_to_nid(curve)) {
+ r = SSH_ERR_EC_CURVE_MISMATCH;
goto out;
}
- if ((rsa_n = BN_new()) == NULL ||
- (rsa_e = BN_new()) == NULL ||
- (rsa_d = BN_new()) == NULL ||
- (rsa_iqmp = BN_new()) == NULL ||
- (rsa_p = BN_new()) == NULL ||
- (rsa_q = BN_new()) == NULL) {
+ if ((k->sk_key_handle = sshbuf_new()) == NULL ||
+ (k->sk_reserved = sshbuf_new()) == NULL) {
r = SSH_ERR_ALLOC_FAIL;
goto out;
}
- if ((r = sshbuf_get_bignum2(buf, rsa_n)) != 0 ||
- (r = sshbuf_get_bignum2(buf, rsa_e)) != 0 ||
- (r = sshbuf_get_bignum2(buf, rsa_d)) != 0 ||
- (r = sshbuf_get_bignum2(buf, rsa_iqmp)) != 0 ||
- (r = sshbuf_get_bignum2(buf, rsa_p)) != 0 ||
- (r = sshbuf_get_bignum2(buf, rsa_q)) != 0)
- goto out;
- if (!RSA_set0_key(k->rsa, rsa_n, rsa_e, rsa_d)) {
+ k->ecdsa = EC_KEY_new_by_curve_name(k->ecdsa_nid);
+ if (k->ecdsa == NULL) {
r = SSH_ERR_LIBCRYPTO_ERROR;
goto out;
}
- rsa_n = rsa_e = rsa_d = NULL; /* transferred */
- if (!RSA_set0_factors(k->rsa, rsa_p, rsa_q)) {
- r = SSH_ERR_LIBCRYPTO_ERROR;
+ if ((r = sshbuf_get_eckey(buf, k->ecdsa)) != 0 ||
+ (r = sshbuf_get_cstring(buf, &k->sk_application,
+ NULL)) != 0 ||
+ (r = sshbuf_get_u8(buf, &k->sk_flags)) != 0 ||
+ (r = sshbuf_get_stringb(buf, k->sk_key_handle)) != 0 ||
+ (r = sshbuf_get_stringb(buf, k->sk_reserved)) != 0)
+ goto out;
+ if ((r = sshkey_ec_validate_public(EC_KEY_get0_group(k->ecdsa),
+ EC_KEY_get0_public_key(k->ecdsa))) != 0)
+ goto out;
+ break;
+ case KEY_ECDSA_SK_CERT:
+ if ((k->sk_key_handle = sshbuf_new()) == NULL ||
+ (k->sk_reserved = sshbuf_new()) == NULL) {
+ r = SSH_ERR_ALLOC_FAIL;
goto out;
}
- rsa_p = rsa_q = NULL; /* transferred */
- if ((r = check_rsa_length(k->rsa)) != 0)
+ if ((r = sshbuf_get_cstring(buf, &k->sk_application,
+ NULL)) != 0 ||
+ (r = sshbuf_get_u8(buf, &k->sk_flags)) != 0 ||
+ (r = sshbuf_get_stringb(buf, k->sk_key_handle)) != 0 ||
+ (r = sshbuf_get_stringb(buf, k->sk_reserved)) != 0)
goto out;
- if ((r = ssh_rsa_complete_crt_parameters(k, rsa_iqmp)) != 0)
+ if ((r = sshkey_ec_validate_public(EC_KEY_get0_group(k->ecdsa),
+ EC_KEY_get0_public_key(k->ecdsa))) != 0)
goto out;
break;
- case KEY_RSA_CERT:
- if ((rsa_d = BN_new()) == NULL ||
- (rsa_iqmp = BN_new()) == NULL ||
- (rsa_p = BN_new()) == NULL ||
- (rsa_q = BN_new()) == NULL) {
- r = SSH_ERR_ALLOC_FAIL;
+# endif /* OPENSSL_HAS_ECC */
+ case KEY_RSA:
+ if ((r = sshbuf_get_bignum2(buf, &rsa_n)) != 0 ||
+ (r = sshbuf_get_bignum2(buf, &rsa_e)) != 0)
+ goto out;
+ if (!RSA_set0_key(k->rsa, rsa_n, rsa_e, NULL)) {
+ r = SSH_ERR_LIBCRYPTO_ERROR;
goto out;
}
- if ((r = sshkey_froms(buf, &k)) != 0 ||
- (r = sshbuf_get_bignum2(buf, rsa_d)) != 0 ||
- (r = sshbuf_get_bignum2(buf, rsa_iqmp)) != 0 ||
- (r = sshbuf_get_bignum2(buf, rsa_p)) != 0 ||
- (r = sshbuf_get_bignum2(buf, rsa_q)) != 0)
+ rsa_n = rsa_e = NULL; /* transferred */
+ /* FALLTHROUGH */
+ case KEY_RSA_CERT:
+ if ((r = sshbuf_get_bignum2(buf, &rsa_d)) != 0 ||
+ (r = sshbuf_get_bignum2(buf, &rsa_iqmp)) != 0 ||
+ (r = sshbuf_get_bignum2(buf, &rsa_p)) != 0 ||
+ (r = sshbuf_get_bignum2(buf, &rsa_q)) != 0)
goto out;
if (!RSA_set0_key(k->rsa, NULL, NULL, rsa_d)) {
r = SSH_ERR_LIBCRYPTO_ERROR;
@@ -3098,10 +3603,7 @@ sshkey_private_deserialize(struct sshbuf *buf, struct sshkey **kp)
break;
#endif /* WITH_OPENSSL */
case KEY_ED25519:
- if ((k = sshkey_new(type)) == NULL) {
- r = SSH_ERR_ALLOC_FAIL;
- goto out;
- }
+ case KEY_ED25519_CERT:
if ((r = sshbuf_get_string(buf, &ed25519_pk, &pklen)) != 0 ||
(r = sshbuf_get_string(buf, &ed25519_sk, &sklen)) != 0)
goto out;
@@ -3111,54 +3613,40 @@ sshkey_private_deserialize(struct sshbuf *buf, struct sshkey **kp)
}
k->ed25519_pk = ed25519_pk;
k->ed25519_sk = ed25519_sk;
- ed25519_pk = ed25519_sk = NULL;
+ ed25519_pk = ed25519_sk = NULL; /* transferred */
break;
- case KEY_ED25519_CERT:
- if ((r = sshkey_froms(buf, &k)) != 0 ||
- (r = sshbuf_get_string(buf, &ed25519_pk, &pklen)) != 0 ||
- (r = sshbuf_get_string(buf, &ed25519_sk, &sklen)) != 0)
+ case KEY_ED25519_SK:
+ case KEY_ED25519_SK_CERT:
+ if ((r = sshbuf_get_string(buf, &ed25519_pk, &pklen)) != 0)
goto out;
- if (pklen != ED25519_PK_SZ || sklen != ED25519_SK_SZ) {
+ if (pklen != ED25519_PK_SZ) {
r = SSH_ERR_INVALID_FORMAT;
goto out;
}
- k->ed25519_pk = ed25519_pk;
- k->ed25519_sk = ed25519_sk;
- ed25519_pk = ed25519_sk = NULL;
- break;
-#ifdef WITH_XMSS
- case KEY_XMSS:
- if ((k = sshkey_new(type)) == NULL) {
+ if ((k->sk_key_handle = sshbuf_new()) == NULL ||
+ (k->sk_reserved = sshbuf_new()) == NULL) {
r = SSH_ERR_ALLOC_FAIL;
goto out;
}
- if ((r = sshbuf_get_cstring(buf, &xmss_name, NULL)) != 0 ||
- (r = sshkey_xmss_init(k, xmss_name)) != 0 ||
- (r = sshbuf_get_string(buf, &xmss_pk, &pklen)) != 0 ||
- (r = sshbuf_get_string(buf, &xmss_sk, &sklen)) != 0)
- goto out;
- if (pklen != sshkey_xmss_pklen(k) ||
- sklen != sshkey_xmss_sklen(k)) {
- r = SSH_ERR_INVALID_FORMAT;
- goto out;
- }
- k->xmss_pk = xmss_pk;
- k->xmss_sk = xmss_sk;
- xmss_pk = xmss_sk = NULL;
- /* optional internal state */
- if ((r = sshkey_xmss_deserialize_state_opt(k, buf)) != 0)
+ if ((r = sshbuf_get_cstring(buf, &k->sk_application,
+ NULL)) != 0 ||
+ (r = sshbuf_get_u8(buf, &k->sk_flags)) != 0 ||
+ (r = sshbuf_get_stringb(buf, k->sk_key_handle)) != 0 ||
+ (r = sshbuf_get_stringb(buf, k->sk_reserved)) != 0)
goto out;
+ k->ed25519_pk = ed25519_pk;
+ ed25519_pk = NULL; /* transferred */
break;
+#ifdef WITH_XMSS
+ case KEY_XMSS:
case KEY_XMSS_CERT:
- if ((r = sshkey_froms(buf, &k)) != 0 ||
- (r = sshbuf_get_cstring(buf, &xmss_name, NULL)) != 0 ||
+ if ((r = sshbuf_get_cstring(buf, &xmss_name, NULL)) != 0 ||
(r = sshbuf_get_string(buf, &xmss_pk, &pklen)) != 0 ||
(r = sshbuf_get_string(buf, &xmss_sk, &sklen)) != 0)
goto out;
- if (strcmp(xmss_name, k->xmss_name)) {
- r = SSH_ERR_INVALID_FORMAT;
+ if (type == KEY_XMSS &&
+ (r = sshkey_xmss_init(k, xmss_name)) != 0)
goto out;
- }
if (pklen != sshkey_xmss_pklen(k) ||
sklen != sshkey_xmss_sklen(k)) {
r = SSH_ERR_INVALID_FORMAT;
@@ -3188,6 +3676,13 @@ sshkey_private_deserialize(struct sshbuf *buf, struct sshkey **kp)
break;
}
#endif /* WITH_OPENSSL */
+ if ((expect_sk_application != NULL && (k->sk_application == NULL ||
+ strcmp(expect_sk_application, k->sk_application) != 0)) ||
+ (expect_ed25519_pk != NULL && (k->ed25519_pk == NULL ||
+ memcmp(expect_ed25519_pk, k->ed25519_pk, ED25519_PK_SZ) != 0))) {
+ r = SSH_ERR_KEY_CERT_MISMATCH;
+ goto out;
+ }
/* success */
r = 0;
if (kp != NULL) {
@@ -3217,6 +3712,8 @@ sshkey_private_deserialize(struct sshbuf *buf, struct sshkey **kp)
free(xmss_name);
freezero(xmss_pk, pklen);
freezero(xmss_sk, sklen);
+ free(expect_sk_application);
+ free(expect_ed25519_pk);
return r;
}
@@ -3224,9 +3721,8 @@ sshkey_private_deserialize(struct sshbuf *buf, struct sshkey **kp)
int
sshkey_ec_validate_public(const EC_GROUP *group, const EC_POINT *public)
{
- BN_CTX *bnctx;
EC_POINT *nq = NULL;
- BIGNUM *order, *x, *y, *tmp;
+ BIGNUM *order = NULL, *x = NULL, *y = NULL, *tmp = NULL;
int ret = SSH_ERR_KEY_INVALID_EC_VALUE;
/*
@@ -3237,10 +3733,6 @@ sshkey_ec_validate_public(const EC_GROUP *group, const EC_POINT *public)
* EC_POINT_oct2point then the caller will need to explicitly check.
*/
- if ((bnctx = BN_CTX_new()) == NULL)
- return SSH_ERR_ALLOC_FAIL;
- BN_CTX_start(bnctx);
-
/*
* We shouldn't ever hit this case because bignum_get_ecpoint()
* refuses to load GF2m points.
@@ -3253,18 +3745,18 @@ sshkey_ec_validate_public(const EC_GROUP *group, const EC_POINT *public)
if (EC_POINT_is_at_infinity(group, public))
goto out;
- if ((x = BN_CTX_get(bnctx)) == NULL ||
- (y = BN_CTX_get(bnctx)) == NULL ||
- (order = BN_CTX_get(bnctx)) == NULL ||
- (tmp = BN_CTX_get(bnctx)) == NULL) {
+ if ((x = BN_new()) == NULL ||
+ (y = BN_new()) == NULL ||
+ (order = BN_new()) == NULL ||
+ (tmp = BN_new()) == NULL) {
ret = SSH_ERR_ALLOC_FAIL;
goto out;
}
/* log2(x) > log2(order)/2, log2(y) > log2(order)/2 */
- if (EC_GROUP_get_order(group, order, bnctx) != 1 ||
+ if (EC_GROUP_get_order(group, order, NULL) != 1 ||
EC_POINT_get_affine_coordinates_GFp(group, public,
- x, y, bnctx) != 1) {
+ x, y, NULL) != 1) {
ret = SSH_ERR_LIBCRYPTO_ERROR;
goto out;
}
@@ -3277,7 +3769,7 @@ sshkey_ec_validate_public(const EC_GROUP *group, const EC_POINT *public)
ret = SSH_ERR_ALLOC_FAIL;
goto out;
}
- if (EC_POINT_mul(group, nq, NULL, public, order, bnctx) != 1) {
+ if (EC_POINT_mul(group, nq, NULL, public, order, NULL) != 1) {
ret = SSH_ERR_LIBCRYPTO_ERROR;
goto out;
}
@@ -3293,7 +3785,10 @@ sshkey_ec_validate_public(const EC_GROUP *group, const EC_POINT *public)
goto out;
ret = 0;
out:
- BN_CTX_free(bnctx);
+ BN_clear_free(x);
+ BN_clear_free(y);
+ BN_clear_free(order);
+ BN_clear_free(tmp);
EC_POINT_free(nq);
return ret;
}
@@ -3301,22 +3796,16 @@ sshkey_ec_validate_public(const EC_GROUP *group, const EC_POINT *public)
int
sshkey_ec_validate_private(const EC_KEY *key)
{
- BN_CTX *bnctx;
- BIGNUM *order, *tmp;
+ BIGNUM *order = NULL, *tmp = NULL;
int ret = SSH_ERR_KEY_INVALID_EC_VALUE;
- if ((bnctx = BN_CTX_new()) == NULL)
- return SSH_ERR_ALLOC_FAIL;
- BN_CTX_start(bnctx);
-
- if ((order = BN_CTX_get(bnctx)) == NULL ||
- (tmp = BN_CTX_get(bnctx)) == NULL) {
+ if ((order = BN_new()) == NULL || (tmp = BN_new()) == NULL) {
ret = SSH_ERR_ALLOC_FAIL;
goto out;
}
/* log2(private) > log2(order)/2 */
- if (EC_GROUP_get_order(EC_KEY_get0_group(key), order, bnctx) != 1) {
+ if (EC_GROUP_get_order(EC_KEY_get0_group(key), order, NULL) != 1) {
ret = SSH_ERR_LIBCRYPTO_ERROR;
goto out;
}
@@ -3333,47 +3822,43 @@ sshkey_ec_validate_private(const EC_KEY *key)
goto out;
ret = 0;
out:
- BN_CTX_free(bnctx);
+ BN_clear_free(order);
+ BN_clear_free(tmp);
return ret;
}
void
sshkey_dump_ec_point(const EC_GROUP *group, const EC_POINT *point)
{
- BIGNUM *x, *y;
- BN_CTX *bnctx;
+ BIGNUM *x = NULL, *y = NULL;
if (point == NULL) {
fputs("point=(NULL)\n", stderr);
return;
}
- if ((bnctx = BN_CTX_new()) == NULL) {
- fprintf(stderr, "%s: BN_CTX_new failed\n", __func__);
- return;
- }
- BN_CTX_start(bnctx);
- if ((x = BN_CTX_get(bnctx)) == NULL ||
- (y = BN_CTX_get(bnctx)) == NULL) {
- fprintf(stderr, "%s: BN_CTX_get failed\n", __func__);
- return;
+ if ((x = BN_new()) == NULL || (y = BN_new()) == NULL) {
+ fprintf(stderr, "%s: BN_new failed\n", __func__);
+ goto out;
}
if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) !=
NID_X9_62_prime_field) {
fprintf(stderr, "%s: group is not a prime field\n", __func__);
- return;
+ goto out;
}
- if (EC_POINT_get_affine_coordinates_GFp(group, point, x, y,
- bnctx) != 1) {
+ if (EC_POINT_get_affine_coordinates_GFp(group, point,
+ x, y, NULL) != 1) {
fprintf(stderr, "%s: EC_POINT_get_affine_coordinates_GFp\n",
__func__);
- return;
+ goto out;
}
fputs("x=", stderr);
BN_print_fp(stderr, x);
fputs("\ny=", stderr);
BN_print_fp(stderr, y);
fputs("\n", stderr);
- BN_CTX_free(bnctx);
+ out:
+ BN_clear_free(x);
+ BN_clear_free(y);
}
void
@@ -3393,7 +3878,7 @@ sshkey_dump_ec_key(const EC_KEY *key)
#endif /* WITH_OPENSSL && OPENSSL_HAS_ECC */
static int
-sshkey_private_to_blob2(const struct sshkey *prv, struct sshbuf *blob,
+sshkey_private_to_blob2(struct sshkey *prv, struct sshbuf *blob,
const char *passphrase, const char *comment, const char *ciphername,
int rounds)
{
@@ -3472,7 +3957,7 @@ sshkey_private_to_blob2(const struct sshkey *prv, struct sshbuf *blob,
/* append private key and comment*/
if ((r = sshkey_private_serialize_opt(prv, encrypted,
- SSHKEY_SERIALIZE_FULL)) != 0 ||
+ SSHKEY_SERIALIZE_FULL)) != 0 ||
(r = sshbuf_put_cstring(encrypted, comment)) != 0)
goto out;
@@ -3495,25 +3980,12 @@ sshkey_private_to_blob2(const struct sshkey *prv, struct sshbuf *blob,
sshbuf_ptr(encrypted), sshbuf_len(encrypted), 0, authlen)) != 0)
goto out;
- /* uuencode */
- if ((b64 = sshbuf_dtob64(encoded)) == NULL) {
- r = SSH_ERR_ALLOC_FAIL;
- goto out;
- }
-
sshbuf_reset(blob);
- if ((r = sshbuf_put(blob, MARK_BEGIN, MARK_BEGIN_LEN)) != 0)
- goto out;
- for (i = 0; i < strlen(b64); i++) {
- if ((r = sshbuf_put_u8(blob, b64[i])) != 0)
- goto out;
- /* insert line breaks */
- if (i % 70 == 69 && (r = sshbuf_put_u8(blob, '\n')) != 0)
- goto out;
- }
- if (i % 70 != 69 && (r = sshbuf_put_u8(blob, '\n')) != 0)
- goto out;
- if ((r = sshbuf_put(blob, MARK_END, MARK_END_LEN)) != 0)
+
+ /* assemble uuencoded key */
+ if ((r = sshbuf_put(blob, MARK_BEGIN, MARK_BEGIN_LEN)) != 0 ||
+ (r = sshbuf_dtob64(encoded, blob, 1)) != 0 ||
+ (r = sshbuf_put(blob, MARK_END, MARK_END_LEN)) != 0)
goto out;
/* success */
@@ -3525,46 +3997,31 @@ sshkey_private_to_blob2(const struct sshkey *prv, struct sshbuf *blob,
sshbuf_free(encrypted);
cipher_free(ciphercontext);
explicit_bzero(salt, sizeof(salt));
- if (key != NULL) {
- explicit_bzero(key, keylen + ivlen);
- free(key);
- }
- if (pubkeyblob != NULL) {
- explicit_bzero(pubkeyblob, pubkeylen);
- free(pubkeyblob);
- }
- if (b64 != NULL) {
- explicit_bzero(b64, strlen(b64));
- free(b64);
- }
+ if (key != NULL)
+ freezero(key, keylen + ivlen);
+ if (pubkeyblob != NULL)
+ freezero(pubkeyblob, pubkeylen);
+ if (b64 != NULL)
+ freezero(b64, strlen(b64));
return r;
}
static int
-sshkey_parse_private2(struct sshbuf *blob, int type, const char *passphrase,
- struct sshkey **keyp, char **commentp)
+private2_uudecode(struct sshbuf *blob, struct sshbuf **decodedp)
{
- char *comment = NULL, *ciphername = NULL, *kdfname = NULL;
- const struct sshcipher *cipher = NULL;
const u_char *cp;
- int r = SSH_ERR_INTERNAL_ERROR;
size_t encoded_len;
- size_t i, keylen = 0, ivlen = 0, authlen = 0, slen = 0;
+ int r;
+ u_char last;
struct sshbuf *encoded = NULL, *decoded = NULL;
- struct sshbuf *kdf = NULL, *decrypted = NULL;
- struct sshcipher_ctx *ciphercontext = NULL;
- struct sshkey *k = NULL;
- u_char *key = NULL, *salt = NULL, *dp, pad, last;
- u_int blocksize, rounds, nkeys, encrypted_len, check1, check2;
- if (keyp != NULL)
- *keyp = NULL;
- if (commentp != NULL)
- *commentp = NULL;
+ if (blob == NULL || decodedp == NULL)
+ return SSH_ERR_INVALID_ARGUMENT;
+
+ *decodedp = NULL;
if ((encoded = sshbuf_new()) == NULL ||
- (decoded = sshbuf_new()) == NULL ||
- (decrypted = sshbuf_new()) == NULL) {
+ (decoded = sshbuf_new()) == NULL) {
r = SSH_ERR_ALLOC_FAIL;
goto out;
}
@@ -3614,13 +4071,56 @@ sshkey_parse_private2(struct sshbuf *blob, int type, const char *passphrase,
r = SSH_ERR_INVALID_FORMAT;
goto out;
}
+ /* success */
+ *decodedp = decoded;
+ decoded = NULL;
+ r = 0;
+ out:
+ sshbuf_free(encoded);
+ sshbuf_free(decoded);
+ return r;
+}
+
+static int
+private2_decrypt(struct sshbuf *decoded, const char *passphrase,
+ struct sshbuf **decryptedp, struct sshkey **pubkeyp)
+{
+ char *ciphername = NULL, *kdfname = NULL;
+ const struct sshcipher *cipher = NULL;
+ int r = SSH_ERR_INTERNAL_ERROR;
+ size_t keylen = 0, ivlen = 0, authlen = 0, slen = 0;
+ struct sshbuf *kdf = NULL, *decrypted = NULL;
+ struct sshcipher_ctx *ciphercontext = NULL;
+ struct sshkey *pubkey = NULL;
+ u_char *key = NULL, *salt = NULL, *dp;
+ u_int blocksize, rounds, nkeys, encrypted_len, check1, check2;
+
+ if (decoded == NULL || decryptedp == NULL || pubkeyp == NULL)
+ return SSH_ERR_INVALID_ARGUMENT;
+
+ *decryptedp = NULL;
+ *pubkeyp = NULL;
+
+ if ((decrypted = sshbuf_new()) == NULL) {
+ r = SSH_ERR_ALLOC_FAIL;
+ goto out;
+ }
+
/* parse public portion of key */
if ((r = sshbuf_consume(decoded, sizeof(AUTH_MAGIC))) != 0 ||
(r = sshbuf_get_cstring(decoded, &ciphername, NULL)) != 0 ||
(r = sshbuf_get_cstring(decoded, &kdfname, NULL)) != 0 ||
(r = sshbuf_froms(decoded, &kdf)) != 0 ||
- (r = sshbuf_get_u32(decoded, &nkeys)) != 0 ||
- (r = sshbuf_skip_string(decoded)) != 0 || /* pubkey */
+ (r = sshbuf_get_u32(decoded, &nkeys)) != 0)
+ goto out;
+
+ if (nkeys != 1) {
+ /* XXX only one key supported at present */
+ r = SSH_ERR_INVALID_FORMAT;
+ goto out;
+ }
+
+ if ((r = sshkey_froms(decoded, &pubkey)) != 0 ||
(r = sshbuf_get_u32(decoded, &encrypted_len)) != 0)
goto out;
@@ -3628,23 +4128,18 @@ sshkey_parse_private2(struct sshbuf *blob, int type, const char *passphrase,
r = SSH_ERR_KEY_UNKNOWN_CIPHER;
goto out;
}
- if ((passphrase == NULL || strlen(passphrase) == 0) &&
- strcmp(ciphername, "none") != 0) {
- /* passphrase required */
- r = SSH_ERR_KEY_WRONG_PASSPHRASE;
- goto out;
- }
if (strcmp(kdfname, "none") != 0 && strcmp(kdfname, "bcrypt") != 0) {
r = SSH_ERR_KEY_UNKNOWN_CIPHER;
goto out;
}
- if (!strcmp(kdfname, "none") && strcmp(ciphername, "none") != 0) {
+ if (strcmp(kdfname, "none") == 0 && strcmp(ciphername, "none") != 0) {
r = SSH_ERR_INVALID_FORMAT;
goto out;
}
- if (nkeys != 1) {
- /* XXX only one key supported */
- r = SSH_ERR_INVALID_FORMAT;
+ if ((passphrase == NULL || strlen(passphrase) == 0) &&
+ strcmp(kdfname, "none") != 0) {
+ /* passphrase required */
+ r = SSH_ERR_KEY_WRONG_PASSPHRASE;
goto out;
}
@@ -3675,7 +4170,8 @@ sshkey_parse_private2(struct sshbuf *blob, int type, const char *passphrase,
}
/* check that an appropriate amount of auth data is present */
- if (sshbuf_len(decoded) < encrypted_len + authlen) {
+ if (sshbuf_len(decoded) < authlen ||
+ sshbuf_len(decoded) - authlen < encrypted_len) {
r = SSH_ERR_INVALID_FORMAT;
goto out;
}
@@ -3708,13 +4204,38 @@ sshkey_parse_private2(struct sshbuf *blob, int type, const char *passphrase,
r = SSH_ERR_KEY_WRONG_PASSPHRASE;
goto out;
}
+ /* success */
+ *decryptedp = decrypted;
+ decrypted = NULL;
+ *pubkeyp = pubkey;
+ pubkey = NULL;
+ r = 0;
+ out:
+ cipher_free(ciphercontext);
+ free(ciphername);
+ free(kdfname);
+ sshkey_free(pubkey);
+ if (salt != NULL) {
+ explicit_bzero(salt, slen);
+ free(salt);
+ }
+ if (key != NULL) {
+ explicit_bzero(key, keylen + ivlen);
+ free(key);
+ }
+ sshbuf_free(kdf);
+ sshbuf_free(decrypted);
+ return r;
+}
- /* Load the private key and comment */
- if ((r = sshkey_private_deserialize(decrypted, &k)) != 0 ||
- (r = sshbuf_get_cstring(decrypted, &comment, NULL)) != 0)
- goto out;
+/* Check deterministic padding after private key */
+static int
+private2_check_padding(struct sshbuf *decrypted)
+{
+ u_char pad;
+ size_t i;
+ int r = SSH_ERR_INTERNAL_ERROR;
- /* Check deterministic padding */
i = 0;
while (sshbuf_len(decrypted)) {
if ((r = sshbuf_get_u8(decrypted, &pad)) != 0)
@@ -3724,8 +4245,54 @@ sshkey_parse_private2(struct sshbuf *blob, int type, const char *passphrase,
goto out;
}
}
+ /* success */
+ r = 0;
+ out:
+ explicit_bzero(&pad, sizeof(pad));
+ explicit_bzero(&i, sizeof(i));
+ return r;
+}
- /* XXX decode pubkey and check against private */
+static int
+sshkey_parse_private2(struct sshbuf *blob, int type, const char *passphrase,
+ struct sshkey **keyp, char **commentp)
+{
+ char *comment = NULL;
+ int r = SSH_ERR_INTERNAL_ERROR;
+ struct sshbuf *decoded = NULL, *decrypted = NULL;
+ struct sshkey *k = NULL, *pubkey = NULL;
+
+ if (keyp != NULL)
+ *keyp = NULL;
+ if (commentp != NULL)
+ *commentp = NULL;
+
+ /* Undo base64 encoding and decrypt the private section */
+ if ((r = private2_uudecode(blob, &decoded)) != 0 ||
+ (r = private2_decrypt(decoded, passphrase,
+ &decrypted, &pubkey)) != 0)
+ goto out;
+
+ if (type != KEY_UNSPEC &&
+ sshkey_type_plain(type) != sshkey_type_plain(pubkey->type)) {
+ r = SSH_ERR_KEY_TYPE_MISMATCH;
+ goto out;
+ }
+
+ /* Load the private key and comment */
+ if ((r = sshkey_private_deserialize(decrypted, &k)) != 0 ||
+ (r = sshbuf_get_cstring(decrypted, &comment, NULL)) != 0)
+ goto out;
+
+ /* Check deterministic padding after private section */
+ if ((r = private2_check_padding(decrypted)) != 0)
+ goto out;
+
+ /* Check that the public key in the envelope matches the private key */
+ if (!sshkey_equal(pubkey, k)) {
+ r = SSH_ERR_INVALID_FORMAT;
+ goto out;
+ }
/* success */
r = 0;
@@ -3738,60 +4305,121 @@ sshkey_parse_private2(struct sshbuf *blob, int type, const char *passphrase,
comment = NULL;
}
out:
- pad = 0;
- cipher_free(ciphercontext);
- free(ciphername);
- free(kdfname);
free(comment);
- if (salt != NULL) {
- explicit_bzero(salt, slen);
- free(salt);
- }
- if (key != NULL) {
- explicit_bzero(key, keylen + ivlen);
- free(key);
- }
- sshbuf_free(encoded);
sshbuf_free(decoded);
- sshbuf_free(kdf);
sshbuf_free(decrypted);
sshkey_free(k);
+ sshkey_free(pubkey);
return r;
}
+static int
+sshkey_parse_private2_pubkey(struct sshbuf *blob, int type,
+ struct sshkey **keyp)
+{
+ int r = SSH_ERR_INTERNAL_ERROR;
+ struct sshbuf *decoded = NULL;
+ struct sshkey *pubkey = NULL;
+ u_int nkeys = 0;
+
+ if (keyp != NULL)
+ *keyp = NULL;
+
+ if ((r = private2_uudecode(blob, &decoded)) != 0)
+ goto out;
+ /* parse public key from unencrypted envelope */
+ if ((r = sshbuf_consume(decoded, sizeof(AUTH_MAGIC))) != 0 ||
+ (r = sshbuf_skip_string(decoded)) != 0 || /* cipher */
+ (r = sshbuf_skip_string(decoded)) != 0 || /* KDF alg */
+ (r = sshbuf_skip_string(decoded)) != 0 || /* KDF hint */
+ (r = sshbuf_get_u32(decoded, &nkeys)) != 0)
+ goto out;
+
+ if (nkeys != 1) {
+ /* XXX only one key supported at present */
+ r = SSH_ERR_INVALID_FORMAT;
+ goto out;
+ }
+
+ /* Parse the public key */
+ if ((r = sshkey_froms(decoded, &pubkey)) != 0)
+ goto out;
+
+ if (type != KEY_UNSPEC &&
+ sshkey_type_plain(type) != sshkey_type_plain(pubkey->type)) {
+ r = SSH_ERR_KEY_TYPE_MISMATCH;
+ goto out;
+ }
+
+ /* success */
+ r = 0;
+ if (keyp != NULL) {
+ *keyp = pubkey;
+ pubkey = NULL;
+ }
+ out:
+ sshbuf_free(decoded);
+ sshkey_free(pubkey);
+ return r;
+}
#ifdef WITH_OPENSSL
-/* convert SSH v2 key in OpenSSL PEM format */
+/* convert SSH v2 key to PEM or PKCS#8 format */
static int
-sshkey_private_pem_to_blob(struct sshkey *key, struct sshbuf *blob,
- const char *_passphrase, const char *comment)
+sshkey_private_to_blob_pem_pkcs8(struct sshkey *key, struct sshbuf *buf,
+ int format, const char *_passphrase, const char *comment)
{
+ int was_shielded = sshkey_is_shielded(key);
int success, r;
int blen, len = strlen(_passphrase);
u_char *passphrase = (len > 0) ? (u_char *)_passphrase : NULL;
const EVP_CIPHER *cipher = (len > 0) ? EVP_aes_128_cbc() : NULL;
char *bptr;
BIO *bio = NULL;
+ struct sshbuf *blob;
+ EVP_PKEY *pkey = NULL;
if (len > 0 && len <= 4)
return SSH_ERR_PASSPHRASE_TOO_SHORT;
- if ((bio = BIO_new(BIO_s_mem())) == NULL)
+ if ((blob = sshbuf_new()) == NULL)
return SSH_ERR_ALLOC_FAIL;
+ if ((bio = BIO_new(BIO_s_mem())) == NULL) {
+ r = SSH_ERR_ALLOC_FAIL;
+ goto out;
+ }
+ if (format == SSHKEY_PRIVATE_PKCS8 && (pkey = EVP_PKEY_new()) == NULL) {
+ r = SSH_ERR_ALLOC_FAIL;
+ goto out;
+ }
+ if ((r = sshkey_unshield_private(key)) != 0)
+ goto out;
switch (key->type) {
case KEY_DSA:
- success = PEM_write_bio_DSAPrivateKey(bio, key->dsa,
- cipher, passphrase, len, NULL, NULL);
+ if (format == SSHKEY_PRIVATE_PEM) {
+ success = PEM_write_bio_DSAPrivateKey(bio, key->dsa,
+ cipher, passphrase, len, NULL, NULL);
+ } else {
+ success = EVP_PKEY_set1_DSA(pkey, key->dsa);
+ }
break;
#ifdef OPENSSL_HAS_ECC
case KEY_ECDSA:
- success = PEM_write_bio_ECPrivateKey(bio, key->ecdsa,
- cipher, passphrase, len, NULL, NULL);
+ if (format == SSHKEY_PRIVATE_PEM) {
+ success = PEM_write_bio_ECPrivateKey(bio, key->ecdsa,
+ cipher, passphrase, len, NULL, NULL);
+ } else {
+ success = EVP_PKEY_set1_EC_KEY(pkey, key->ecdsa);
+ }
break;
#endif
case KEY_RSA:
- success = PEM_write_bio_RSAPrivateKey(bio, key->rsa,
- cipher, passphrase, len, NULL, NULL);
+ if (format == SSHKEY_PRIVATE_PEM) {
+ success = PEM_write_bio_RSAPrivateKey(bio, key->rsa,
+ cipher, passphrase, len, NULL, NULL);
+ } else {
+ success = EVP_PKEY_set1_RSA(pkey, key->rsa);
+ }
break;
default:
success = 0;
@@ -3801,6 +4429,13 @@ sshkey_private_pem_to_blob(struct sshkey *key, struct sshbuf *blob,
r = SSH_ERR_LIBCRYPTO_ERROR;
goto out;
}
+ if (format == SSHKEY_PRIVATE_PKCS8) {
+ if ((success = PEM_write_bio_PrivateKey(bio, pkey, cipher,
+ passphrase, len, NULL, NULL)) == 0) {
+ r = SSH_ERR_LIBCRYPTO_ERROR;
+ goto out;
+ }
+ }
if ((blen = BIO_get_mem_data(bio, &bptr)) <= 0) {
r = SSH_ERR_INTERNAL_ERROR;
goto out;
@@ -3809,6 +4444,13 @@ sshkey_private_pem_to_blob(struct sshkey *key, struct sshbuf *blob,
goto out;
r = 0;
out:
+ if (was_shielded)
+ r = sshkey_shield_private(key);
+ if (r == 0)
+ r = sshbuf_putb(buf, blob);
+
+ EVP_PKEY_free(pkey);
+ sshbuf_free(blob);
BIO_free(bio);
return r;
}
@@ -3818,31 +4460,43 @@ sshkey_private_pem_to_blob(struct sshkey *key, struct sshbuf *blob,
int
sshkey_private_to_fileblob(struct sshkey *key, struct sshbuf *blob,
const char *passphrase, const char *comment,
- int force_new_format, const char *new_format_cipher, int new_format_rounds)
+ int format, const char *openssh_format_cipher, int openssh_format_rounds)
{
switch (key->type) {
#ifdef WITH_OPENSSL
case KEY_DSA:
case KEY_ECDSA:
case KEY_RSA:
- if (force_new_format) {
- return sshkey_private_to_blob2(key, blob, passphrase,
- comment, new_format_cipher, new_format_rounds);
- }
- return sshkey_private_pem_to_blob(key, blob,
- passphrase, comment);
+ break; /* see below */
#endif /* WITH_OPENSSL */
case KEY_ED25519:
+ case KEY_ED25519_SK:
#ifdef WITH_XMSS
case KEY_XMSS:
#endif /* WITH_XMSS */
+#ifdef WITH_OPENSSL
+ case KEY_ECDSA_SK:
+#endif /* WITH_OPENSSL */
return sshkey_private_to_blob2(key, blob, passphrase,
- comment, new_format_cipher, new_format_rounds);
+ comment, openssh_format_cipher, openssh_format_rounds);
default:
return SSH_ERR_KEY_TYPE_UNKNOWN;
}
-}
+#ifdef WITH_OPENSSL
+ switch (format) {
+ case SSHKEY_PRIVATE_OPENSSH:
+ return sshkey_private_to_blob2(key, blob, passphrase,
+ comment, openssh_format_cipher, openssh_format_rounds);
+ case SSHKEY_PRIVATE_PEM:
+ case SSHKEY_PRIVATE_PKCS8:
+ return sshkey_private_to_blob_pem_pkcs8(key, blob,
+ format, passphrase, comment);
+ default:
+ return SSH_ERR_INVALID_ARGUMENT;
+ }
+#endif /* WITH_OPENSSL */
+}
#ifdef WITH_OPENSSL
static int
@@ -3942,12 +4596,12 @@ sshkey_parse_private_pem_fileblob(struct sshbuf *blob, int type,
clear_libcrypto_errors();
if ((pk = PEM_read_bio_PrivateKey(bio, NULL, pem_passphrase_cb,
(char *)passphrase)) == NULL) {
- /*
- * libcrypto may return various ASN.1 errors when attempting
- * to parse a key with an incorrect passphrase.
- * Treat all format errors as "incorrect passphrase" if a
- * passphrase was supplied.
- */
+ /*
+ * libcrypto may return various ASN.1 errors when attempting
+ * to parse a key with an incorrect passphrase.
+ * Treat all format errors as "incorrect passphrase" if a
+ * passphrase was supplied.
+ */
if (passphrase != NULL && *passphrase != '\0')
r = SSH_ERR_KEY_WRONG_PASSPHRASE;
else
@@ -4034,24 +4688,16 @@ sshkey_parse_private_fileblob_type(struct sshbuf *blob, int type,
*commentp = NULL;
switch (type) {
-#ifdef WITH_OPENSSL
- case KEY_DSA:
- case KEY_ECDSA:
- case KEY_RSA:
- return sshkey_parse_private_pem_fileblob(blob, type,
- passphrase, keyp);
-#endif /* WITH_OPENSSL */
case KEY_ED25519:
-#ifdef WITH_XMSS
case KEY_XMSS:
-#endif /* WITH_XMSS */
+ /* No fallback for new-format-only keys */
return sshkey_parse_private2(blob, type, passphrase,
keyp, commentp);
- case KEY_UNSPEC:
+ default:
r = sshkey_parse_private2(blob, type, passphrase, keyp,
commentp);
- /* Do not fallback to PEM parser if only passphrase is wrong. */
- if (r == 0 || r == SSH_ERR_KEY_WRONG_PASSPHRASE)
+ /* Only fallback to PEM parser if a format error occurred. */
+ if (r != SSH_ERR_INVALID_FORMAT)
return r;
#ifdef WITH_OPENSSL
return sshkey_parse_private_pem_fileblob(blob, type,
@@ -4059,8 +4705,6 @@ sshkey_parse_private_fileblob_type(struct sshbuf *blob, int type,
#else
return SSH_ERR_INVALID_FORMAT;
#endif /* WITH_OPENSSL */
- default:
- return SSH_ERR_KEY_TYPE_UNKNOWN;
}
}
@@ -4077,14 +4721,34 @@ sshkey_parse_private_fileblob(struct sshbuf *buffer, const char *passphrase,
passphrase, keyp, commentp);
}
+void
+sshkey_sig_details_free(struct sshkey_sig_details *details)
+{
+ freezero(details, sizeof(*details));
+}
+
+int
+sshkey_parse_pubkey_from_private_fileblob_type(struct sshbuf *blob, int type,
+ struct sshkey **pubkeyp)
+{
+ int r = SSH_ERR_INTERNAL_ERROR;
+
+ if (pubkeyp != NULL)
+ *pubkeyp = NULL;
+ /* only new-format private keys bundle a public key inside */
+ if ((r = sshkey_parse_private2_pubkey(blob, type, pubkeyp)) != 0)
+ return r;
+ return 0;
+}
+
#ifdef WITH_XMSS
/*
* serialize the key with the current state and forward the state
* maxsign times.
*/
int
-sshkey_private_serialize_maxsign(const struct sshkey *k, struct sshbuf *b,
- u_int32_t maxsign, sshkey_printfn *pr)
+sshkey_private_serialize_maxsign(struct sshkey *k, struct sshbuf *b,
+ u_int32_t maxsign, int printerror)
{
int r, rupdate;
@@ -4092,14 +4756,14 @@ sshkey_private_serialize_maxsign(const struct sshkey *k, struct sshbuf *b,
sshkey_type_plain(k->type) != KEY_XMSS)
return sshkey_private_serialize_opt(k, b,
SSHKEY_SERIALIZE_DEFAULT);
- if ((r = sshkey_xmss_get_state(k, pr)) != 0 ||
+ if ((r = sshkey_xmss_get_state(k, printerror)) != 0 ||
(r = sshkey_private_serialize_opt(k, b,
SSHKEY_SERIALIZE_STATE)) != 0 ||
(r = sshkey_xmss_forward_state(k, maxsign)) != 0)
goto out;
r = 0;
out:
- if ((rupdate = sshkey_xmss_update_state(k, pr)) != 0) {
+ if ((rupdate = sshkey_xmss_update_state(k, printerror)) != 0) {
if (r == 0)
r = rupdate;
}
@@ -4137,8 +4801,8 @@ sshkey_set_filename(struct sshkey *k, const char *filename)
}
#else
int
-sshkey_private_serialize_maxsign(const struct sshkey *k, struct sshbuf *b,
- u_int32_t maxsign, sshkey_printfn *pr)
+sshkey_private_serialize_maxsign(struct sshkey *k, struct sshbuf *b,
+ u_int32_t maxsign, int printerror)
{
return sshkey_private_serialize_opt(k, b, SSHKEY_SERIALIZE_DEFAULT);
}
diff --git a/crypto/openssh/sshkey.h b/crypto/openssh/sshkey.h
index f6a007fdff35..6edc6c5a5dbd 100644
--- a/crypto/openssh/sshkey.h
+++ b/crypto/openssh/sshkey.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: sshkey.h,v 1.30 2018/09/14 04:17:44 djm Exp $ */
+/* $OpenBSD: sshkey.h,v 1.50 2021/07/23 03:37:52 djm Exp $ */
/*
* Copyright (c) 2000, 2001 Markus Friedl. All rights reserved.
@@ -33,11 +33,13 @@
#include <openssl/dsa.h>
# ifdef OPENSSL_HAS_ECC
# include <openssl/ec.h>
+# include <openssl/ecdsa.h>
# else /* OPENSSL_HAS_ECC */
# define EC_KEY void
# define EC_GROUP void
# define EC_POINT void
# endif /* OPENSSL_HAS_ECC */
+#define SSH_OPENSSL_VERSION OpenSSL_version(OPENSSL_VERSION)
#else /* WITH_OPENSSL */
# define BIGNUM void
# define RSA void
@@ -45,6 +47,7 @@
# define EC_KEY void
# define EC_GROUP void
# define EC_POINT void
+#define SSH_OPENSSL_VERSION "without OpenSSL"
#endif /* WITH_OPENSSL */
#define SSH_RSA_MINIMUM_MODULUS_SIZE 1024
@@ -64,6 +67,10 @@ enum sshkey_types {
KEY_ED25519_CERT,
KEY_XMSS,
KEY_XMSS_CERT,
+ KEY_ECDSA_SK,
+ KEY_ECDSA_SK_CERT,
+ KEY_ED25519_SK,
+ KEY_ED25519_SK_CERT,
KEY_UNSPEC
};
@@ -82,9 +89,17 @@ enum sshkey_fp_rep {
/* Private key serialisation formats, used on the wire */
enum sshkey_serialize_rep {
SSHKEY_SERIALIZE_DEFAULT = 0,
- SSHKEY_SERIALIZE_STATE = 1,
- SSHKEY_SERIALIZE_FULL = 2,
- SSHKEY_SERIALIZE_INFO = 254,
+ SSHKEY_SERIALIZE_STATE = 1, /* only state is serialized */
+ SSHKEY_SERIALIZE_FULL = 2, /* include keys for saving to disk */
+ SSHKEY_SERIALIZE_SHIELD = 3, /* everything, for encrypting in ram */
+ SSHKEY_SERIALIZE_INFO = 254, /* minimal information */
+};
+
+/* Private key disk formats */
+enum sshkey_private_format {
+ SSHKEY_PRIVATE_OPENSSH = 0,
+ SSHKEY_PRIVATE_PEM = 1,
+ SSHKEY_PRIVATE_PKCS8 = 2,
};
/* key is stored in external hardware */
@@ -110,23 +125,45 @@ struct sshkey_cert {
struct sshkey {
int type;
int flags;
+ /* KEY_RSA */
RSA *rsa;
+ /* KEY_DSA */
DSA *dsa;
+ /* KEY_ECDSA and KEY_ECDSA_SK */
int ecdsa_nid; /* NID of curve */
EC_KEY *ecdsa;
+ /* KEY_ED25519 and KEY_ED25519_SK */
u_char *ed25519_sk;
u_char *ed25519_pk;
+ /* KEY_XMSS */
char *xmss_name;
char *xmss_filename; /* for state file updates */
void *xmss_state; /* depends on xmss_name, opaque */
u_char *xmss_sk;
u_char *xmss_pk;
+ /* KEY_ECDSA_SK and KEY_ED25519_SK */
+ char *sk_application;
+ uint8_t sk_flags;
+ struct sshbuf *sk_key_handle;
+ struct sshbuf *sk_reserved;
+ /* Certificates */
struct sshkey_cert *cert;
+ /* Private key shielding */
+ u_char *shielded_private;
+ size_t shielded_len;
+ u_char *shield_prekey;
+ size_t shield_prekey_len;
};
#define ED25519_SK_SZ crypto_sign_ed25519_SECRETKEYBYTES
#define ED25519_PK_SZ crypto_sign_ed25519_PUBLICKEYBYTES
+/* Additional fields contained in signature */
+struct sshkey_sig_details {
+ uint32_t sk_counter; /* U2F signature counter */
+ uint8_t sk_flags; /* U2F signature flags; see ssh-sk.h */
+};
+
struct sshkey *sshkey_new(int);
void sshkey_free(struct sshkey *);
int sshkey_equal_public(const struct sshkey *,
@@ -145,25 +182,37 @@ u_int sshkey_size(const struct sshkey *);
int sshkey_generate(int type, u_int bits, struct sshkey **keyp);
int sshkey_from_private(const struct sshkey *, struct sshkey **);
+
+int sshkey_is_shielded(struct sshkey *);
+int sshkey_shield_private(struct sshkey *);
+int sshkey_unshield_private(struct sshkey *);
+
int sshkey_type_from_name(const char *);
int sshkey_is_cert(const struct sshkey *);
+int sshkey_is_sk(const struct sshkey *);
int sshkey_type_is_cert(int);
int sshkey_type_plain(int);
int sshkey_to_certified(struct sshkey *);
int sshkey_drop_cert(struct sshkey *);
int sshkey_cert_copy(const struct sshkey *, struct sshkey *);
-int sshkey_cert_check_authority(const struct sshkey *, int, int,
+int sshkey_cert_check_authority(const struct sshkey *, int, int, int,
+ uint64_t, const char *, const char **);
+int sshkey_cert_check_authority_now(const struct sshkey *, int, int, int,
const char *, const char **);
+int sshkey_cert_check_host(const struct sshkey *, const char *,
+ int , const char *, const char **);
size_t sshkey_format_cert_validity(const struct sshkey_cert *,
char *, size_t) __attribute__((__bounded__(__string__, 2, 3)));
int sshkey_check_cert_sigtype(const struct sshkey *, const char *);
-int sshkey_certify(struct sshkey *, struct sshkey *, const char *);
+int sshkey_certify(struct sshkey *, struct sshkey *,
+ const char *, const char *, const char *);
/* Variant allowing use of a custom signature function (e.g. for ssh-agent) */
-typedef int sshkey_certify_signer(const struct sshkey *, u_char **, size_t *,
- const u_char *, size_t, const char *, u_int, void *);
+typedef int sshkey_certify_signer(struct sshkey *, u_char **, size_t *,
+ const u_char *, size_t, const char *, const char *, const char *,
+ u_int, void *);
int sshkey_certify_custom(struct sshkey *, struct sshkey *, const char *,
- sshkey_certify_signer *, void *);
+ const char *, const char *, sshkey_certify_signer *, void *);
int sshkey_ecdsa_nid_from_name(const char *);
int sshkey_curve_name_to_nid(const char *);
@@ -191,47 +240,47 @@ int sshkey_puts_opts(const struct sshkey *, struct sshbuf *,
int sshkey_plain_to_blob(const struct sshkey *, u_char **, size_t *);
int sshkey_putb_plain(const struct sshkey *, struct sshbuf *);
-int sshkey_sign(const struct sshkey *, u_char **, size_t *,
- const u_char *, size_t, const char *, u_int);
+int sshkey_sign(struct sshkey *, u_char **, size_t *,
+ const u_char *, size_t, const char *, const char *, const char *, u_int);
int sshkey_verify(const struct sshkey *, const u_char *, size_t,
- const u_char *, size_t, const char *, u_int);
+ const u_char *, size_t, const char *, u_int, struct sshkey_sig_details **);
int sshkey_check_sigtype(const u_char *, size_t, const char *);
const char *sshkey_sigalg_by_name(const char *);
+int sshkey_get_sigtype(const u_char *, size_t, char **);
/* for debug */
void sshkey_dump_ec_point(const EC_GROUP *, const EC_POINT *);
void sshkey_dump_ec_key(const EC_KEY *);
/* private key parsing and serialisation */
-int sshkey_private_serialize(const struct sshkey *key, struct sshbuf *buf);
-int sshkey_private_serialize_opt(const struct sshkey *key, struct sshbuf *buf,
+int sshkey_private_serialize(struct sshkey *key, struct sshbuf *buf);
+int sshkey_private_serialize_opt(struct sshkey *key, struct sshbuf *buf,
enum sshkey_serialize_rep);
int sshkey_private_deserialize(struct sshbuf *buf, struct sshkey **keyp);
/* private key file format parsing and serialisation */
int sshkey_private_to_fileblob(struct sshkey *key, struct sshbuf *blob,
const char *passphrase, const char *comment,
- int force_new_format, const char *new_format_cipher, int new_format_rounds);
+ int format, const char *openssh_format_cipher, int openssh_format_rounds);
int sshkey_parse_private_fileblob(struct sshbuf *buffer,
const char *passphrase, struct sshkey **keyp, char **commentp);
int sshkey_parse_private_fileblob_type(struct sshbuf *blob, int type,
const char *passphrase, struct sshkey **keyp, char **commentp);
+int sshkey_parse_pubkey_from_private_fileblob_type(struct sshbuf *blob,
+ int type, struct sshkey **pubkeyp);
/* XXX should be internal, but used by ssh-keygen */
int ssh_rsa_complete_crt_parameters(struct sshkey *, const BIGNUM *);
/* stateful keys (e.g. XMSS) */
-#ifdef NO_ATTRIBUTE_ON_PROTOTYPE_ARGS
-typedef void sshkey_printfn(const char *, ...);
-#else
-typedef void sshkey_printfn(const char *, ...) __attribute__((format(printf, 1, 2)));
-#endif
int sshkey_set_filename(struct sshkey *, const char *);
int sshkey_enable_maxsign(struct sshkey *, u_int32_t);
u_int32_t sshkey_signatures_left(const struct sshkey *);
-int sshkey_forward_state(const struct sshkey *, u_int32_t, sshkey_printfn *);
-int sshkey_private_serialize_maxsign(const struct sshkey *key, struct sshbuf *buf,
- u_int32_t maxsign, sshkey_printfn *pr);
+int sshkey_forward_state(const struct sshkey *, u_int32_t, int);
+int sshkey_private_serialize_maxsign(struct sshkey *key,
+ struct sshbuf *buf, u_int32_t maxsign, int);
+
+void sshkey_sig_details_free(struct sshkey_sig_details *);
#ifdef SSHKEY_INTERNAL
int ssh_rsa_sign(const struct sshkey *key,
@@ -250,11 +299,19 @@ int ssh_ecdsa_sign(const struct sshkey *key, u_char **sigp, size_t *lenp,
int ssh_ecdsa_verify(const struct sshkey *key,
const u_char *signature, size_t signaturelen,
const u_char *data, size_t datalen, u_int compat);
+int ssh_ecdsa_sk_verify(const struct sshkey *key,
+ const u_char *signature, size_t signaturelen,
+ const u_char *data, size_t datalen, u_int compat,
+ struct sshkey_sig_details **detailsp);
int ssh_ed25519_sign(const struct sshkey *key, u_char **sigp, size_t *lenp,
const u_char *data, size_t datalen, u_int compat);
int ssh_ed25519_verify(const struct sshkey *key,
const u_char *signature, size_t signaturelen,
const u_char *data, size_t datalen, u_int compat);
+int ssh_ed25519_sk_verify(const struct sshkey *key,
+ const u_char *signature, size_t signaturelen,
+ const u_char *data, size_t datalen, u_int compat,
+ struct sshkey_sig_details **detailsp);
int ssh_xmss_sign(const struct sshkey *key, u_char **sigp, size_t *lenp,
const u_char *data, size_t datalen, u_int compat);
int ssh_xmss_verify(const struct sshkey *key,
diff --git a/crypto/openssh/sshlogin.c b/crypto/openssh/sshlogin.c
index 1b2ee5f858f1..82dd848191b1 100644
--- a/crypto/openssh/sshlogin.c
+++ b/crypto/openssh/sshlogin.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: sshlogin.c,v 1.33 2018/07/09 21:26:02 markus Exp $ */
+/* $OpenBSD: sshlogin.c,v 1.35 2020/10/18 11:32:02 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -90,8 +90,11 @@ static void
store_lastlog_message(const char *user, uid_t uid)
{
#ifndef NO_SSH_LASTLOG
- char *time_string, hostname[HOST_NAME_MAX+1] = "";
+# ifndef CUSTOM_SYS_AUTH_GET_LASTLOGIN_MSG
+ char hostname[HOST_NAME_MAX+1] = "";
time_t last_login_time;
+# endif
+ char *time_string;
int r;
if (!options.print_lastlog)
@@ -119,7 +122,7 @@ store_lastlog_message(const char *user, uid_t uid)
r = sshbuf_putf(loginmsg, "Last login: %s from %s\r\n",
time_string, hostname);
if (r != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "sshbuf_putf");
}
# endif /* CUSTOM_SYS_AUTH_GET_LASTLOGIN_MSG */
#endif /* NO_SSH_LASTLOG */
diff --git a/crypto/openssh/sshpty.c b/crypto/openssh/sshpty.c
index 4da84d05f7cd..cae0b977a585 100644
--- a/crypto/openssh/sshpty.c
+++ b/crypto/openssh/sshpty.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: sshpty.c,v 1.31 2016/11/29 03:54:50 dtucker Exp $ */
+/* $OpenBSD: sshpty.c,v 1.34 2019/07/04 16:20:10 deraadt Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -27,6 +27,7 @@
#endif
#include <pwd.h>
#include <stdarg.h>
+#include <stdio.h>
#include <string.h>
#include <termios.h>
#ifdef HAVE_UTIL_H
@@ -68,7 +69,7 @@ pty_allocate(int *ptyfd, int *ttyfd, char *namebuf, size_t namebuflen)
int i;
i = openpty(ptyfd, ttyfd, NULL, NULL, NULL);
- if (i < 0) {
+ if (i == -1) {
error("openpty: %.100s", strerror(errno));
return 0;
}
@@ -86,9 +87,9 @@ void
pty_release(const char *tty)
{
#if !defined(__APPLE_PRIVPTY__) && !defined(HAVE_OPENPTY)
- if (chown(tty, (uid_t) 0, (gid_t) 0) < 0)
+ if (chown(tty, (uid_t) 0, (gid_t) 0) == -1)
error("chown %.100s 0 0 failed: %.100s", tty, strerror(errno));
- if (chmod(tty, (mode_t) 0666) < 0)
+ if (chmod(tty, (mode_t) 0666) == -1)
error("chmod %.100s 0666 failed: %.100s", tty, strerror(errno));
#endif /* !__APPLE_PRIVPTY__ && !HAVE_OPENPTY */
}
@@ -108,7 +109,7 @@ pty_make_controlling_tty(int *ttyfd, const char *tty)
close(fd);
}
#endif /* TIOCNOTTY */
- if (setsid() < 0)
+ if (setsid() == -1)
error("setsid: %.100s", strerror(errno));
/*
@@ -131,14 +132,14 @@ pty_make_controlling_tty(int *ttyfd, const char *tty)
error("SETPGRP %s",strerror(errno));
#endif /* NEED_SETPGRP */
fd = open(tty, O_RDWR);
- if (fd < 0)
+ if (fd == -1)
error("%.100s: %.100s", tty, strerror(errno));
else
close(fd);
/* Verify that we now have a controlling tty. */
fd = open(_PATH_TTY, O_WRONLY);
- if (fd < 0)
+ if (fd == -1)
error("open /dev/tty failed - could not set controlling tty: %.100s",
strerror(errno));
else
@@ -171,6 +172,8 @@ pty_setowner(struct passwd *pw, const char *tty)
/* Determine the group to make the owner of the tty. */
grp = getgrnam("tty");
+ if (grp == NULL)
+ debug("%s: no tty group", __func__);
gid = (grp != NULL) ? grp->gr_gid : pw->pw_gid;
mode = (grp != NULL) ? 0620 : 0600;
@@ -179,7 +182,7 @@ pty_setowner(struct passwd *pw, const char *tty)
* Warn but continue if filesystem is read-only and the uids match/
* tty is owned by root.
*/
- if (stat(tty, &st))
+ if (stat(tty, &st) == -1)
fatal("stat(%.100s) failed: %.100s", tty,
strerror(errno));
@@ -188,7 +191,7 @@ pty_setowner(struct passwd *pw, const char *tty)
#endif
if (st.st_uid != pw->pw_uid || st.st_gid != gid) {
- if (chown(tty, pw->pw_uid, gid) < 0) {
+ if (chown(tty, pw->pw_uid, gid) == -1) {
if (errno == EROFS &&
(st.st_uid == pw->pw_uid || st.st_uid == 0))
debug("chown(%.100s, %u, %u) failed: %.100s",
@@ -202,7 +205,7 @@ pty_setowner(struct passwd *pw, const char *tty)
}
if ((st.st_mode & (S_IRWXU|S_IRWXG|S_IRWXO)) != mode) {
- if (chmod(tty, mode) < 0) {
+ if (chmod(tty, mode) == -1) {
if (errno == EROFS &&
(st.st_mode & (S_IRGRP | S_IROTH)) == 0)
debug("chmod(%.100s, 0%o) failed: %.100s",
diff --git a/crypto/openssh/sshsig.c b/crypto/openssh/sshsig.c
new file mode 100644
index 000000000000..d0d401a326ee
--- /dev/null
+++ b/crypto/openssh/sshsig.c
@@ -0,0 +1,1098 @@
+/* $OpenBSD: sshsig.c,v 1.21 2021/07/23 04:00:59 djm Exp $ */
+/*
+ * Copyright (c) 2019 Google LLC
+ *
+ * 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 <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <errno.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "authfd.h"
+#include "authfile.h"
+#include "log.h"
+#include "misc.h"
+#include "sshbuf.h"
+#include "sshsig.h"
+#include "ssherr.h"
+#include "sshkey.h"
+#include "match.h"
+#include "digest.h"
+
+#define SIG_VERSION 0x01
+#define MAGIC_PREAMBLE "SSHSIG"
+#define MAGIC_PREAMBLE_LEN (sizeof(MAGIC_PREAMBLE) - 1)
+#define BEGIN_SIGNATURE "-----BEGIN SSH SIGNATURE-----\n"
+#define END_SIGNATURE "-----END SSH SIGNATURE-----"
+#define RSA_SIGN_ALG "rsa-sha2-512" /* XXX maybe make configurable */
+#define RSA_SIGN_ALLOWED "rsa-sha2-512,rsa-sha2-256"
+#define HASHALG_DEFAULT "sha512" /* XXX maybe make configurable */
+#define HASHALG_ALLOWED "sha256,sha512"
+
+int
+sshsig_armor(const struct sshbuf *blob, struct sshbuf **out)
+{
+ struct sshbuf *buf = NULL;
+ int r = SSH_ERR_INTERNAL_ERROR;
+
+ *out = NULL;
+
+ if ((buf = sshbuf_new()) == NULL) {
+ error_f("sshbuf_new failed");
+ r = SSH_ERR_ALLOC_FAIL;
+ goto out;
+ }
+
+ if ((r = sshbuf_put(buf, BEGIN_SIGNATURE,
+ sizeof(BEGIN_SIGNATURE)-1)) != 0) {
+ error_fr(r, "sshbuf_putf");
+ goto out;
+ }
+
+ if ((r = sshbuf_dtob64(blob, buf, 1)) != 0) {
+ error_fr(r, "base64 encode signature");
+ goto out;
+ }
+
+ if ((r = sshbuf_put(buf, END_SIGNATURE,
+ sizeof(END_SIGNATURE)-1)) != 0 ||
+ (r = sshbuf_put_u8(buf, '\n')) != 0) {
+ error_fr(r, "sshbuf_put");
+ goto out;
+ }
+ /* success */
+ *out = buf;
+ buf = NULL; /* transferred */
+ r = 0;
+ out:
+ sshbuf_free(buf);
+ return r;
+}
+
+int
+sshsig_dearmor(struct sshbuf *sig, struct sshbuf **out)
+{
+ int r;
+ size_t eoffset = 0;
+ struct sshbuf *buf = NULL;
+ struct sshbuf *sbuf = NULL;
+ char *b64 = NULL;
+
+ if ((sbuf = sshbuf_fromb(sig)) == NULL) {
+ error_f("sshbuf_fromb failed");
+ return SSH_ERR_ALLOC_FAIL;
+ }
+
+ if ((r = sshbuf_cmp(sbuf, 0,
+ BEGIN_SIGNATURE, sizeof(BEGIN_SIGNATURE)-1)) != 0) {
+ error("Couldn't parse signature: missing header");
+ goto done;
+ }
+
+ if ((r = sshbuf_consume(sbuf, sizeof(BEGIN_SIGNATURE)-1)) != 0) {
+ error_fr(r, "consume");
+ goto done;
+ }
+
+ if ((r = sshbuf_find(sbuf, 0, "\n" END_SIGNATURE,
+ sizeof("\n" END_SIGNATURE)-1, &eoffset)) != 0) {
+ error("Couldn't parse signature: missing footer");
+ goto done;
+ }
+
+ if ((r = sshbuf_consume_end(sbuf, sshbuf_len(sbuf)-eoffset)) != 0) {
+ error_fr(r, "consume");
+ goto done;
+ }
+
+ if ((b64 = sshbuf_dup_string(sbuf)) == NULL) {
+ error_f("sshbuf_dup_string failed");
+ r = SSH_ERR_ALLOC_FAIL;
+ goto done;
+ }
+
+ if ((buf = sshbuf_new()) == NULL) {
+ error_f("sshbuf_new() failed");
+ r = SSH_ERR_ALLOC_FAIL;
+ goto done;
+ }
+
+ if ((r = sshbuf_b64tod(buf, b64)) != 0) {
+ error_fr(r, "decode base64");
+ goto done;
+ }
+
+ /* success */
+ *out = buf;
+ r = 0;
+ buf = NULL; /* transferred */
+done:
+ sshbuf_free(buf);
+ sshbuf_free(sbuf);
+ free(b64);
+ return r;
+}
+
+static int
+sshsig_wrap_sign(struct sshkey *key, const char *hashalg,
+ const char *sk_provider, const char *sk_pin, const struct sshbuf *h_message,
+ const char *sig_namespace, struct sshbuf **out,
+ sshsig_signer *signer, void *signer_ctx)
+{
+ int r;
+ size_t slen = 0;
+ u_char *sig = NULL;
+ struct sshbuf *blob = NULL;
+ struct sshbuf *tosign = NULL;
+ const char *sign_alg = NULL;
+
+ if ((tosign = sshbuf_new()) == NULL ||
+ (blob = sshbuf_new()) == NULL) {
+ error_f("sshbuf_new failed");
+ r = SSH_ERR_ALLOC_FAIL;
+ goto done;
+ }
+
+ if ((r = sshbuf_put(tosign, MAGIC_PREAMBLE, MAGIC_PREAMBLE_LEN)) != 0 ||
+ (r = sshbuf_put_cstring(tosign, sig_namespace)) != 0 ||
+ (r = sshbuf_put_string(tosign, NULL, 0)) != 0 || /* reserved */
+ (r = sshbuf_put_cstring(tosign, hashalg)) != 0 ||
+ (r = sshbuf_put_stringb(tosign, h_message)) != 0) {
+ error_fr(r, "assemble message to sign");
+ goto done;
+ }
+
+ /* If using RSA keys then default to a good signature algorithm */
+ if (sshkey_type_plain(key->type) == KEY_RSA)
+ sign_alg = RSA_SIGN_ALG;
+
+ if (signer != NULL) {
+ if ((r = signer(key, &sig, &slen,
+ sshbuf_ptr(tosign), sshbuf_len(tosign),
+ sign_alg, sk_provider, sk_pin, 0, signer_ctx)) != 0) {
+ error_r(r, "Couldn't sign message (signer)");
+ goto done;
+ }
+ } else {
+ if ((r = sshkey_sign(key, &sig, &slen,
+ sshbuf_ptr(tosign), sshbuf_len(tosign),
+ sign_alg, sk_provider, sk_pin, 0)) != 0) {
+ error_r(r, "Couldn't sign message");
+ goto done;
+ }
+ }
+
+ if ((r = sshbuf_put(blob, MAGIC_PREAMBLE, MAGIC_PREAMBLE_LEN)) != 0 ||
+ (r = sshbuf_put_u32(blob, SIG_VERSION)) != 0 ||
+ (r = sshkey_puts(key, blob)) != 0 ||
+ (r = sshbuf_put_cstring(blob, sig_namespace)) != 0 ||
+ (r = sshbuf_put_string(blob, NULL, 0)) != 0 || /* reserved */
+ (r = sshbuf_put_cstring(blob, hashalg)) != 0 ||
+ (r = sshbuf_put_string(blob, sig, slen)) != 0) {
+ error_fr(r, "assemble signature object");
+ goto done;
+ }
+
+ if (out != NULL) {
+ *out = blob;
+ blob = NULL;
+ }
+ r = 0;
+done:
+ free(sig);
+ sshbuf_free(blob);
+ sshbuf_free(tosign);
+ return r;
+}
+
+/* Check preamble and version. */
+static int
+sshsig_parse_preamble(struct sshbuf *buf)
+{
+ int r = SSH_ERR_INTERNAL_ERROR;
+ uint32_t sversion;
+
+ if ((r = sshbuf_cmp(buf, 0, MAGIC_PREAMBLE, MAGIC_PREAMBLE_LEN)) != 0 ||
+ (r = sshbuf_consume(buf, (sizeof(MAGIC_PREAMBLE)-1))) != 0 ||
+ (r = sshbuf_get_u32(buf, &sversion)) != 0) {
+ error("Couldn't verify signature: invalid format");
+ return r;
+ }
+
+ if (sversion > SIG_VERSION) {
+ error("Signature version %lu is larger than supported "
+ "version %u", (unsigned long)sversion, SIG_VERSION);
+ return SSH_ERR_INVALID_FORMAT;
+ }
+ return 0;
+}
+
+static int
+sshsig_check_hashalg(const char *hashalg)
+{
+ if (hashalg == NULL ||
+ match_pattern_list(hashalg, HASHALG_ALLOWED, 0) == 1)
+ return 0;
+ error_f("unsupported hash algorithm \"%.100s\"", hashalg);
+ return SSH_ERR_SIGN_ALG_UNSUPPORTED;
+}
+
+static int
+sshsig_peek_hashalg(struct sshbuf *signature, char **hashalgp)
+{
+ struct sshbuf *buf = NULL;
+ char *hashalg = NULL;
+ int r = SSH_ERR_INTERNAL_ERROR;
+
+ if (hashalgp != NULL)
+ *hashalgp = NULL;
+ if ((buf = sshbuf_fromb(signature)) == NULL)
+ return SSH_ERR_ALLOC_FAIL;
+ if ((r = sshsig_parse_preamble(buf)) != 0)
+ goto done;
+ if ((r = sshbuf_get_string_direct(buf, NULL, NULL)) != 0 ||
+ (r = sshbuf_get_string_direct(buf, NULL, NULL)) != 0 ||
+ (r = sshbuf_get_string(buf, NULL, NULL)) != 0 ||
+ (r = sshbuf_get_cstring(buf, &hashalg, NULL)) != 0 ||
+ (r = sshbuf_get_string_direct(buf, NULL, NULL)) != 0) {
+ error_fr(r, "parse signature object");
+ goto done;
+ }
+
+ /* success */
+ r = 0;
+ *hashalgp = hashalg;
+ hashalg = NULL;
+ done:
+ free(hashalg);
+ sshbuf_free(buf);
+ return r;
+}
+
+static int
+sshsig_wrap_verify(struct sshbuf *signature, const char *hashalg,
+ const struct sshbuf *h_message, const char *expect_namespace,
+ struct sshkey **sign_keyp, struct sshkey_sig_details **sig_details)
+{
+ int r = SSH_ERR_INTERNAL_ERROR;
+ struct sshbuf *buf = NULL, *toverify = NULL;
+ struct sshkey *key = NULL;
+ const u_char *sig;
+ char *got_namespace = NULL, *sigtype = NULL, *sig_hashalg = NULL;
+ size_t siglen;
+
+ debug_f("verify message length %zu", sshbuf_len(h_message));
+ if (sig_details != NULL)
+ *sig_details = NULL;
+ if (sign_keyp != NULL)
+ *sign_keyp = NULL;
+
+ if ((toverify = sshbuf_new()) == NULL) {
+ error_f("sshbuf_new failed");
+ r = SSH_ERR_ALLOC_FAIL;
+ goto done;
+ }
+ if ((r = sshbuf_put(toverify, MAGIC_PREAMBLE,
+ MAGIC_PREAMBLE_LEN)) != 0 ||
+ (r = sshbuf_put_cstring(toverify, expect_namespace)) != 0 ||
+ (r = sshbuf_put_string(toverify, NULL, 0)) != 0 || /* reserved */
+ (r = sshbuf_put_cstring(toverify, hashalg)) != 0 ||
+ (r = sshbuf_put_stringb(toverify, h_message)) != 0) {
+ error_fr(r, "assemble message to verify");
+ goto done;
+ }
+
+ if ((r = sshsig_parse_preamble(signature)) != 0)
+ goto done;
+
+ if ((r = sshkey_froms(signature, &key)) != 0 ||
+ (r = sshbuf_get_cstring(signature, &got_namespace, NULL)) != 0 ||
+ (r = sshbuf_get_string(signature, NULL, NULL)) != 0 ||
+ (r = sshbuf_get_cstring(signature, &sig_hashalg, NULL)) != 0 ||
+ (r = sshbuf_get_string_direct(signature, &sig, &siglen)) != 0) {
+ error_fr(r, "parse signature object");
+ goto done;
+ }
+
+ if (sshbuf_len(signature) != 0) {
+ error("Signature contains trailing data");
+ r = SSH_ERR_INVALID_FORMAT;
+ goto done;
+ }
+
+ if (strcmp(expect_namespace, got_namespace) != 0) {
+ error("Couldn't verify signature: namespace does not match");
+ debug_f("expected namespace \"%s\" received \"%s\"",
+ expect_namespace, got_namespace);
+ r = SSH_ERR_SIGNATURE_INVALID;
+ goto done;
+ }
+ if (strcmp(hashalg, sig_hashalg) != 0) {
+ error("Couldn't verify signature: hash algorithm mismatch");
+ debug_f("expected algorithm \"%s\" received \"%s\"",
+ hashalg, sig_hashalg);
+ r = SSH_ERR_SIGNATURE_INVALID;
+ goto done;
+ }
+ /* Ensure that RSA keys use an acceptable signature algorithm */
+ if (sshkey_type_plain(key->type) == KEY_RSA) {
+ if ((r = sshkey_get_sigtype(sig, siglen, &sigtype)) != 0) {
+ error_r(r, "Couldn't verify signature: unable to get "
+ "signature type");
+ goto done;
+ }
+ if (match_pattern_list(sigtype, RSA_SIGN_ALLOWED, 0) != 1) {
+ error("Couldn't verify signature: unsupported RSA "
+ "signature algorithm %s", sigtype);
+ r = SSH_ERR_SIGN_ALG_UNSUPPORTED;
+ goto done;
+ }
+ }
+ if ((r = sshkey_verify(key, sig, siglen, sshbuf_ptr(toverify),
+ sshbuf_len(toverify), NULL, 0, sig_details)) != 0) {
+ error_r(r, "Signature verification failed");
+ goto done;
+ }
+
+ /* success */
+ r = 0;
+ if (sign_keyp != NULL) {
+ *sign_keyp = key;
+ key = NULL; /* transferred */
+ }
+done:
+ free(got_namespace);
+ free(sigtype);
+ free(sig_hashalg);
+ sshbuf_free(buf);
+ sshbuf_free(toverify);
+ sshkey_free(key);
+ return r;
+}
+
+static int
+hash_buffer(const struct sshbuf *m, const char *hashalg, struct sshbuf **bp)
+{
+ char *hex, hash[SSH_DIGEST_MAX_LENGTH];
+ int alg, r = SSH_ERR_INTERNAL_ERROR;
+ struct sshbuf *b = NULL;
+
+ *bp = NULL;
+ memset(hash, 0, sizeof(hash));
+
+ if ((r = sshsig_check_hashalg(hashalg)) != 0)
+ return r;
+ if ((alg = ssh_digest_alg_by_name(hashalg)) == -1) {
+ error_f("can't look up hash algorithm %s", hashalg);
+ return SSH_ERR_INTERNAL_ERROR;
+ }
+ if ((r = ssh_digest_buffer(alg, m, hash, sizeof(hash))) != 0) {
+ error_fr(r, "ssh_digest_buffer");
+ return r;
+ }
+ if ((hex = tohex(hash, ssh_digest_bytes(alg))) != NULL) {
+ debug3_f("final hash: %s", hex);
+ freezero(hex, strlen(hex));
+ }
+ if ((b = sshbuf_new()) == NULL) {
+ r = SSH_ERR_ALLOC_FAIL;
+ goto out;
+ }
+ if ((r = sshbuf_put(b, hash, ssh_digest_bytes(alg))) != 0) {
+ error_fr(r, "sshbuf_put");
+ goto out;
+ }
+ *bp = b;
+ b = NULL; /* transferred */
+ /* success */
+ r = 0;
+ out:
+ sshbuf_free(b);
+ explicit_bzero(hash, sizeof(hash));
+ return r;
+}
+
+int
+sshsig_signb(struct sshkey *key, const char *hashalg,
+ const char *sk_provider, const char *sk_pin,
+ const struct sshbuf *message, const char *sig_namespace,
+ struct sshbuf **out, sshsig_signer *signer, void *signer_ctx)
+{
+ struct sshbuf *b = NULL;
+ int r = SSH_ERR_INTERNAL_ERROR;
+
+ if (hashalg == NULL)
+ hashalg = HASHALG_DEFAULT;
+ if (out != NULL)
+ *out = NULL;
+ if ((r = hash_buffer(message, hashalg, &b)) != 0) {
+ error_fr(r, "hash buffer");
+ goto out;
+ }
+ if ((r = sshsig_wrap_sign(key, hashalg, sk_provider, sk_pin, b,
+ sig_namespace, out, signer, signer_ctx)) != 0)
+ goto out;
+ /* success */
+ r = 0;
+ out:
+ sshbuf_free(b);
+ return r;
+}
+
+int
+sshsig_verifyb(struct sshbuf *signature, const struct sshbuf *message,
+ const char *expect_namespace, struct sshkey **sign_keyp,
+ struct sshkey_sig_details **sig_details)
+{
+ struct sshbuf *b = NULL;
+ int r = SSH_ERR_INTERNAL_ERROR;
+ char *hashalg = NULL;
+
+ if (sig_details != NULL)
+ *sig_details = NULL;
+ if (sign_keyp != NULL)
+ *sign_keyp = NULL;
+ if ((r = sshsig_peek_hashalg(signature, &hashalg)) != 0)
+ return r;
+ debug_f("signature made with hash \"%s\"", hashalg);
+ if ((r = hash_buffer(message, hashalg, &b)) != 0) {
+ error_fr(r, "hash buffer");
+ goto out;
+ }
+ if ((r = sshsig_wrap_verify(signature, hashalg, b, expect_namespace,
+ sign_keyp, sig_details)) != 0)
+ goto out;
+ /* success */
+ r = 0;
+ out:
+ sshbuf_free(b);
+ free(hashalg);
+ return r;
+}
+
+static int
+hash_file(int fd, const char *hashalg, struct sshbuf **bp)
+{
+ char *hex, rbuf[8192], hash[SSH_DIGEST_MAX_LENGTH];
+ ssize_t n, total = 0;
+ struct ssh_digest_ctx *ctx;
+ int alg, oerrno, r = SSH_ERR_INTERNAL_ERROR;
+ struct sshbuf *b = NULL;
+
+ *bp = NULL;
+ memset(hash, 0, sizeof(hash));
+
+ if ((r = sshsig_check_hashalg(hashalg)) != 0)
+ return r;
+ if ((alg = ssh_digest_alg_by_name(hashalg)) == -1) {
+ error_f("can't look up hash algorithm %s", hashalg);
+ return SSH_ERR_INTERNAL_ERROR;
+ }
+ if ((ctx = ssh_digest_start(alg)) == NULL) {
+ error_f("ssh_digest_start failed");
+ return SSH_ERR_INTERNAL_ERROR;
+ }
+ for (;;) {
+ if ((n = read(fd, rbuf, sizeof(rbuf))) == -1) {
+ if (errno == EINTR || errno == EAGAIN)
+ continue;
+ oerrno = errno;
+ error_f("read: %s", strerror(errno));
+ ssh_digest_free(ctx);
+ errno = oerrno;
+ r = SSH_ERR_SYSTEM_ERROR;
+ goto out;
+ } else if (n == 0) {
+ debug2_f("hashed %zu bytes", total);
+ break; /* EOF */
+ }
+ total += (size_t)n;
+ if ((r = ssh_digest_update(ctx, rbuf, (size_t)n)) != 0) {
+ error_fr(r, "ssh_digest_update");
+ goto out;
+ }
+ }
+ if ((r = ssh_digest_final(ctx, hash, sizeof(hash))) != 0) {
+ error_fr(r, "ssh_digest_final");
+ goto out;
+ }
+ if ((hex = tohex(hash, ssh_digest_bytes(alg))) != NULL) {
+ debug3_f("final hash: %s", hex);
+ freezero(hex, strlen(hex));
+ }
+ if ((b = sshbuf_new()) == NULL) {
+ r = SSH_ERR_ALLOC_FAIL;
+ goto out;
+ }
+ if ((r = sshbuf_put(b, hash, ssh_digest_bytes(alg))) != 0) {
+ error_fr(r, "sshbuf_put");
+ goto out;
+ }
+ *bp = b;
+ b = NULL; /* transferred */
+ /* success */
+ r = 0;
+ out:
+ sshbuf_free(b);
+ ssh_digest_free(ctx);
+ explicit_bzero(hash, sizeof(hash));
+ return r;
+}
+
+int
+sshsig_sign_fd(struct sshkey *key, const char *hashalg,
+ const char *sk_provider, const char *sk_pin,
+ int fd, const char *sig_namespace, struct sshbuf **out,
+ sshsig_signer *signer, void *signer_ctx)
+{
+ struct sshbuf *b = NULL;
+ int r = SSH_ERR_INTERNAL_ERROR;
+
+ if (hashalg == NULL)
+ hashalg = HASHALG_DEFAULT;
+ if (out != NULL)
+ *out = NULL;
+ if ((r = hash_file(fd, hashalg, &b)) != 0) {
+ error_fr(r, "hash_file");
+ return r;
+ }
+ if ((r = sshsig_wrap_sign(key, hashalg, sk_provider, sk_pin, b,
+ sig_namespace, out, signer, signer_ctx)) != 0)
+ goto out;
+ /* success */
+ r = 0;
+ out:
+ sshbuf_free(b);
+ return r;
+}
+
+int
+sshsig_verify_fd(struct sshbuf *signature, int fd,
+ const char *expect_namespace, struct sshkey **sign_keyp,
+ struct sshkey_sig_details **sig_details)
+{
+ struct sshbuf *b = NULL;
+ int r = SSH_ERR_INTERNAL_ERROR;
+ char *hashalg = NULL;
+
+ if (sig_details != NULL)
+ *sig_details = NULL;
+ if (sign_keyp != NULL)
+ *sign_keyp = NULL;
+ if ((r = sshsig_peek_hashalg(signature, &hashalg)) != 0)
+ return r;
+ debug_f("signature made with hash \"%s\"", hashalg);
+ if ((r = hash_file(fd, hashalg, &b)) != 0) {
+ error_fr(r, "hash_file");
+ goto out;
+ }
+ if ((r = sshsig_wrap_verify(signature, hashalg, b, expect_namespace,
+ sign_keyp, sig_details)) != 0)
+ goto out;
+ /* success */
+ r = 0;
+ out:
+ sshbuf_free(b);
+ free(hashalg);
+ return r;
+}
+
+struct sshsigopt {
+ int ca;
+ char *namespaces;
+ uint64_t valid_after, valid_before;
+};
+
+struct sshsigopt *
+sshsigopt_parse(const char *opts, const char *path, u_long linenum,
+ const char **errstrp)
+{
+ struct sshsigopt *ret;
+ int r;
+ char *opt;
+ const char *errstr = NULL;
+
+ if ((ret = calloc(1, sizeof(*ret))) == NULL)
+ return NULL;
+ if (opts == NULL || *opts == '\0')
+ return ret; /* Empty options yields empty options :) */
+
+ while (*opts && *opts != ' ' && *opts != '\t') {
+ /* flag options */
+ if ((r = opt_flag("cert-authority", 0, &opts)) != -1) {
+ ret->ca = 1;
+ } else if (opt_match(&opts, "namespaces")) {
+ if (ret->namespaces != NULL) {
+ errstr = "multiple \"namespaces\" clauses";
+ goto fail;
+ }
+ ret->namespaces = opt_dequote(&opts, &errstr);
+ if (ret->namespaces == NULL)
+ goto fail;
+ } else if (opt_match(&opts, "valid-after")) {
+ if (ret->valid_after != 0) {
+ errstr = "multiple \"valid-after\" clauses";
+ goto fail;
+ }
+ if ((opt = opt_dequote(&opts, &errstr)) == NULL)
+ goto fail;
+ if (parse_absolute_time(opt, &ret->valid_after) != 0 ||
+ ret->valid_after == 0) {
+ free(opt);
+ errstr = "invalid \"valid-after\" time";
+ goto fail;
+ }
+ free(opt);
+ } else if (opt_match(&opts, "valid-before")) {
+ if (ret->valid_before != 0) {
+ errstr = "multiple \"valid-before\" clauses";
+ goto fail;
+ }
+ if ((opt = opt_dequote(&opts, &errstr)) == NULL)
+ goto fail;
+ if (parse_absolute_time(opt, &ret->valid_before) != 0 ||
+ ret->valid_before == 0) {
+ free(opt);
+ errstr = "invalid \"valid-before\" time";
+ goto fail;
+ }
+ free(opt);
+ }
+ /*
+ * Skip the comma, and move to the next option
+ * (or break out if there are no more).
+ */
+ if (*opts == '\0' || *opts == ' ' || *opts == '\t')
+ break; /* End of options. */
+ /* Anything other than a comma is an unknown option */
+ if (*opts != ',') {
+ errstr = "unknown key option";
+ goto fail;
+ }
+ opts++;
+ if (*opts == '\0') {
+ errstr = "unexpected end-of-options";
+ goto fail;
+ }
+ }
+ /* final consistency check */
+ if (ret->valid_after != 0 && ret->valid_before != 0 &&
+ ret->valid_before <= ret->valid_after) {
+ errstr = "\"valid-before\" time is before \"valid-after\"";
+ goto fail;
+ }
+ /* success */
+ return ret;
+ fail:
+ if (errstrp != NULL)
+ *errstrp = errstr;
+ sshsigopt_free(ret);
+ return NULL;
+}
+
+void
+sshsigopt_free(struct sshsigopt *opts)
+{
+ if (opts == NULL)
+ return;
+ free(opts->namespaces);
+ free(opts);
+}
+
+static int
+parse_principals_key_and_options(const char *path, u_long linenum, char *line,
+ const char *required_principal, char **principalsp, struct sshkey **keyp,
+ struct sshsigopt **sigoptsp)
+{
+ char *opts = NULL, *tmp, *cp, *principals = NULL;
+ const char *reason = NULL;
+ struct sshsigopt *sigopts = NULL;
+ struct sshkey *key = NULL;
+ int r = SSH_ERR_INTERNAL_ERROR;
+
+ if (principalsp != NULL)
+ *principalsp = NULL;
+ if (sigoptsp != NULL)
+ *sigoptsp = NULL;
+ if (keyp != NULL)
+ *keyp = NULL;
+
+ cp = line;
+ cp = cp + strspn(cp, " \t"); /* skip leading whitespace */
+ if (*cp == '#' || *cp == '\0')
+ return SSH_ERR_KEY_NOT_FOUND; /* blank or all-comment line */
+
+ /* format: identity[,identity...] [option[,option...]] key */
+ if ((tmp = strdelimw(&cp)) == NULL) {
+ error("%s:%lu: invalid line", path, linenum);
+ r = SSH_ERR_INVALID_FORMAT;
+ goto out;
+ }
+ if ((principals = strdup(tmp)) == NULL) {
+ error_f("strdup failed");
+ r = SSH_ERR_ALLOC_FAIL;
+ goto out;
+ }
+ /*
+ * Bail out early if we're looking for a particular principal and this
+ * line does not list it.
+ */
+ if (required_principal != NULL) {
+ if (match_pattern_list(required_principal,
+ principals, 0) != 1) {
+ /* principal didn't match */
+ r = SSH_ERR_KEY_NOT_FOUND;
+ goto out;
+ }
+ debug_f("%s:%lu: matched principal \"%s\"",
+ path, linenum, required_principal);
+ }
+
+ if ((key = sshkey_new(KEY_UNSPEC)) == NULL) {
+ error_f("sshkey_new failed");
+ r = SSH_ERR_ALLOC_FAIL;
+ goto out;
+ }
+ if (sshkey_read(key, &cp) != 0) {
+ /* no key? Check for options */
+ opts = cp;
+ if (sshkey_advance_past_options(&cp) != 0) {
+ error("%s:%lu: invalid options", path, linenum);
+ r = SSH_ERR_INVALID_FORMAT;
+ goto out;
+ }
+ *cp++ = '\0';
+ skip_space(&cp);
+ if (sshkey_read(key, &cp) != 0) {
+ error("%s:%lu: invalid key", path, linenum);
+ r = SSH_ERR_INVALID_FORMAT;
+ goto out;
+ }
+ }
+ debug3("%s:%lu: options %s", path, linenum, opts == NULL ? "" : opts);
+ if ((sigopts = sshsigopt_parse(opts, path, linenum, &reason)) == NULL) {
+ error("%s:%lu: bad options: %s", path, linenum, reason);
+ r = SSH_ERR_INVALID_FORMAT;
+ goto out;
+ }
+ /* success */
+ if (principalsp != NULL) {
+ *principalsp = principals;
+ principals = NULL; /* transferred */
+ }
+ if (sigoptsp != NULL) {
+ *sigoptsp = sigopts;
+ sigopts = NULL; /* transferred */
+ }
+ if (keyp != NULL) {
+ *keyp = key;
+ key = NULL; /* transferred */
+ }
+ r = 0;
+ out:
+ free(principals);
+ sshsigopt_free(sigopts);
+ sshkey_free(key);
+ return r;
+}
+
+static int
+check_allowed_keys_line(const char *path, u_long linenum, char *line,
+ const struct sshkey *sign_key, const char *principal,
+ const char *sig_namespace, uint64_t verify_time)
+{
+ struct sshkey *found_key = NULL;
+ int r, success = 0;
+ const char *reason = NULL;
+ struct sshsigopt *sigopts = NULL;
+ char tvalid[64], tverify[64];
+
+ /* Parse the line */
+ if ((r = parse_principals_key_and_options(path, linenum, line,
+ principal, NULL, &found_key, &sigopts)) != 0) {
+ /* error already logged */
+ goto done;
+ }
+
+ if (!sigopts->ca && sshkey_equal(found_key, sign_key)) {
+ /* Exact match of key */
+ debug("%s:%lu: matched key", path, linenum);
+ } else if (sigopts->ca && sshkey_is_cert(sign_key) &&
+ sshkey_equal_public(sign_key->cert->signature_key, found_key)) {
+ /* Match of certificate's CA key */
+ if ((r = sshkey_cert_check_authority(sign_key, 0, 1, 0,
+ verify_time, principal, &reason)) != 0) {
+ error("%s:%lu: certificate not authorized: %s",
+ path, linenum, reason);
+ goto done;
+ }
+ debug("%s:%lu: matched certificate CA key", path, linenum);
+ } else {
+ /* Didn't match key */
+ goto done;
+ }
+
+ /* Check whether options preclude the use of this key */
+ if (sigopts->namespaces != NULL &&
+ match_pattern_list(sig_namespace, sigopts->namespaces, 0) != 1) {
+ error("%s:%lu: key is not permitted for use in signature "
+ "namespace \"%s\"", path, linenum, sig_namespace);
+ goto done;
+ }
+
+ /* check key time validity */
+ format_absolute_time((uint64_t)verify_time, tverify, sizeof(tverify));
+ if (sigopts->valid_after != 0 &&
+ (uint64_t)verify_time < sigopts->valid_after) {
+ format_absolute_time(sigopts->valid_after,
+ tvalid, sizeof(tvalid));
+ error("%s:%lu: key is not yet valid: "
+ "verify time %s < valid-after %s", path, linenum,
+ tverify, tvalid);
+ goto done;
+ }
+ if (sigopts->valid_before != 0 &&
+ (uint64_t)verify_time > sigopts->valid_before) {
+ format_absolute_time(sigopts->valid_before,
+ tvalid, sizeof(tvalid));
+ error("%s:%lu: key has expired: "
+ "verify time %s > valid-before %s", path, linenum,
+ tverify, tvalid);
+ goto done;
+ }
+ success = 1;
+
+ done:
+ sshkey_free(found_key);
+ sshsigopt_free(sigopts);
+ return success ? 0 : SSH_ERR_KEY_NOT_FOUND;
+}
+
+int
+sshsig_check_allowed_keys(const char *path, const struct sshkey *sign_key,
+ const char *principal, const char *sig_namespace, uint64_t verify_time)
+{
+ FILE *f = NULL;
+ char *line = NULL;
+ size_t linesize = 0;
+ u_long linenum = 0;
+ int r = SSH_ERR_INTERNAL_ERROR, oerrno;
+
+ /* Check key and principal against file */
+ if ((f = fopen(path, "r")) == NULL) {
+ oerrno = errno;
+ error("Unable to open allowed keys file \"%s\": %s",
+ path, strerror(errno));
+ errno = oerrno;
+ return SSH_ERR_SYSTEM_ERROR;
+ }
+
+ while (getline(&line, &linesize, f) != -1) {
+ linenum++;
+ r = check_allowed_keys_line(path, linenum, line, sign_key,
+ principal, sig_namespace, verify_time);
+ free(line);
+ line = NULL;
+ linesize = 0;
+ if (r == SSH_ERR_KEY_NOT_FOUND)
+ continue;
+ else if (r == 0) {
+ /* success */
+ fclose(f);
+ return 0;
+ } else
+ break;
+ }
+ /* Either we hit an error parsing or we simply didn't find the key */
+ fclose(f);
+ free(line);
+ return r == 0 ? SSH_ERR_KEY_NOT_FOUND : r;
+}
+
+static int
+cert_filter_principals(const char *path, u_long linenum,
+ char **principalsp, const struct sshkey *cert, uint64_t verify_time)
+{
+ char *cp, *oprincipals, *principals;
+ const char *reason;
+ struct sshbuf *nprincipals;
+ int r = SSH_ERR_INTERNAL_ERROR, success = 0;
+
+ oprincipals = principals = *principalsp;
+ *principalsp = NULL;
+
+ if ((nprincipals = sshbuf_new()) == NULL) {
+ r = SSH_ERR_ALLOC_FAIL;
+ goto out;
+ }
+
+ while ((cp = strsep(&principals, ",")) != NULL && *cp != '\0') {
+ if (strcspn(cp, "!?*") != strlen(cp)) {
+ debug("%s:%lu: principal \"%s\" not authorized: "
+ "contains wildcards", path, linenum, cp);
+ continue;
+ }
+ /* Check against principals list in certificate */
+ if ((r = sshkey_cert_check_authority(cert, 0, 1, 0,
+ verify_time, cp, &reason)) != 0) {
+ debug("%s:%lu: principal \"%s\" not authorized: %s",
+ path, linenum, cp, reason);
+ continue;
+ }
+ if ((r = sshbuf_putf(nprincipals, "%s%s",
+ sshbuf_len(nprincipals) != 0 ? "," : "", cp)) != 0) {
+ error_f("buffer error");
+ goto out;
+ }
+ }
+ if (sshbuf_len(nprincipals) == 0) {
+ error("%s:%lu: no valid principals found", path, linenum);
+ r = SSH_ERR_KEY_CERT_INVALID;
+ goto out;
+ }
+ if ((principals = sshbuf_dup_string(nprincipals)) == NULL) {
+ error_f("buffer error");
+ goto out;
+ }
+ /* success */
+ success = 1;
+ *principalsp = principals;
+ out:
+ sshbuf_free(nprincipals);
+ free(oprincipals);
+ return success ? 0 : r;
+}
+
+static int
+get_matching_principals_from_line(const char *path, u_long linenum, char *line,
+ const struct sshkey *sign_key, uint64_t verify_time, char **principalsp)
+{
+ struct sshkey *found_key = NULL;
+ char *principals = NULL;
+ int r, found = 0;
+ struct sshsigopt *sigopts = NULL;
+
+ if (principalsp != NULL)
+ *principalsp = NULL;
+
+ /* Parse the line */
+ if ((r = parse_principals_key_and_options(path, linenum, line,
+ NULL, &principals, &found_key, &sigopts)) != 0) {
+ /* error already logged */
+ goto done;
+ }
+
+ if (!sigopts->ca && sshkey_equal(found_key, sign_key)) {
+ /* Exact match of key */
+ debug("%s:%lu: matched key", path, linenum);
+ /* success */
+ found = 1;
+ } else if (sigopts->ca && sshkey_is_cert(sign_key) &&
+ sshkey_equal_public(sign_key->cert->signature_key, found_key)) {
+ /* Remove principals listed in file but not allowed by cert */
+ if ((r = cert_filter_principals(path, linenum,
+ &principals, sign_key, verify_time)) != 0) {
+ /* error already displayed */
+ debug_r(r, "%s:%lu: cert_filter_principals",
+ path, linenum);
+ goto done;
+ }
+ debug("%s:%lu: matched certificate CA key", path, linenum);
+ /* success */
+ found = 1;
+ } else {
+ /* Key didn't match */
+ goto done;
+ }
+ done:
+ if (found && principalsp != NULL) {
+ *principalsp = principals;
+ principals = NULL; /* transferred */
+ }
+ free(principals);
+ sshkey_free(found_key);
+ sshsigopt_free(sigopts);
+ return found ? 0 : SSH_ERR_KEY_NOT_FOUND;
+}
+
+int
+sshsig_find_principals(const char *path, const struct sshkey *sign_key,
+ uint64_t verify_time, char **principals)
+{
+ FILE *f = NULL;
+ char *line = NULL;
+ size_t linesize = 0;
+ u_long linenum = 0;
+ int r = SSH_ERR_INTERNAL_ERROR, oerrno;
+
+ if ((f = fopen(path, "r")) == NULL) {
+ oerrno = errno;
+ error("Unable to open allowed keys file \"%s\": %s",
+ path, strerror(errno));
+ errno = oerrno;
+ return SSH_ERR_SYSTEM_ERROR;
+ }
+
+ while (getline(&line, &linesize, f) != -1) {
+ linenum++;
+ r = get_matching_principals_from_line(path, linenum, line,
+ sign_key, verify_time, principals);
+ free(line);
+ line = NULL;
+ linesize = 0;
+ if (r == SSH_ERR_KEY_NOT_FOUND)
+ continue;
+ else if (r == 0) {
+ /* success */
+ fclose(f);
+ return 0;
+ } else
+ break;
+ }
+ free(line);
+ /* Either we hit an error parsing or we simply didn't find the key */
+ if (ferror(f) != 0) {
+ oerrno = errno;
+ fclose(f);
+ error("Unable to read allowed keys file \"%s\": %s",
+ path, strerror(errno));
+ errno = oerrno;
+ return SSH_ERR_SYSTEM_ERROR;
+ }
+ fclose(f);
+ return r == 0 ? SSH_ERR_KEY_NOT_FOUND : r;
+}
+
+int
+sshsig_get_pubkey(struct sshbuf *signature, struct sshkey **pubkey)
+{
+ struct sshkey *pk = NULL;
+ int r = SSH_ERR_SIGNATURE_INVALID;
+
+ if (pubkey == NULL)
+ return SSH_ERR_INTERNAL_ERROR;
+ if ((r = sshsig_parse_preamble(signature)) != 0)
+ return r;
+ if ((r = sshkey_froms(signature, &pk)) != 0)
+ return r;
+
+ *pubkey = pk;
+ pk = NULL;
+ return 0;
+}
diff --git a/crypto/openssh/sshsig.h b/crypto/openssh/sshsig.h
new file mode 100644
index 000000000000..b725c7d7acd1
--- /dev/null
+++ b/crypto/openssh/sshsig.h
@@ -0,0 +1,107 @@
+/* $OpenBSD: sshsig.h,v 1.10 2021/07/23 03:37:52 djm Exp $ */
+/*
+ * Copyright (c) 2019 Google LLC
+ *
+ * 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 SSHSIG_H
+#define SSHSIG_H
+
+struct sshbuf;
+struct sshkey;
+struct sshsigopt;
+struct sshkey_sig_details;
+
+typedef int sshsig_signer(struct sshkey *, u_char **, size_t *,
+ const u_char *, size_t, const char *, const char *, const char *,
+ u_int, void *);
+
+/* Buffer-oriented API */
+
+/*
+ * Creates a detached SSH signature for a given buffer.
+ * Returns 0 on success or a negative SSH_ERR_* error code on failure.
+ * out is populated with the detached signature, or NULL on failure.
+ */
+int sshsig_signb(struct sshkey *key, const char *hashalg,
+ const char *sk_provider, const char *sk_pin, const struct sshbuf *message,
+ const char *sig_namespace, struct sshbuf **out,
+ sshsig_signer *signer, void *signer_ctx);
+
+/*
+ * Verifies that a detached signature is valid and optionally returns key
+ * used to sign via argument.
+ * Returns 0 on success or a negative SSH_ERR_* error code on failure.
+ */
+int sshsig_verifyb(struct sshbuf *signature,
+ const struct sshbuf *message, const char *sig_namespace,
+ struct sshkey **sign_keyp, struct sshkey_sig_details **sig_details);
+
+/* File/FD-oriented API */
+
+/*
+ * Creates a detached SSH signature for a given file.
+ * Returns 0 on success or a negative SSH_ERR_* error code on failure.
+ * out is populated with the detached signature, or NULL on failure.
+ */
+int sshsig_sign_fd(struct sshkey *key, const char *hashalg,
+ const char *sk_provider, const char *sk_pin,
+ int fd, const char *sig_namespace,
+ struct sshbuf **out, sshsig_signer *signer, void *signer_ctx);
+
+/*
+ * Verifies that a detached signature over a file is valid and optionally
+ * returns key used to sign via argument.
+ * Returns 0 on success or a negative SSH_ERR_* error code on failure.
+ */
+int sshsig_verify_fd(struct sshbuf *signature, int fd,
+ const char *sig_namespace, struct sshkey **sign_keyp,
+ struct sshkey_sig_details **sig_details);
+
+/* Utility functions */
+
+/*
+ * Return a base64 encoded "ASCII armoured" version of a raw signature.
+ */
+int sshsig_armor(const struct sshbuf *blob, struct sshbuf **out);
+
+/*
+ * Decode a base64 encoded armoured signature to a raw signature.
+ */
+int sshsig_dearmor(struct sshbuf *sig, struct sshbuf **out);
+
+/*
+ * Checks whether a particular key/principal/namespace is permitted by
+ * an allowed_keys file. Returns 0 on success.
+ */
+int sshsig_check_allowed_keys(const char *path, const struct sshkey *sign_key,
+ const char *principal, const char *ns, uint64_t verify_time);
+
+/* Parse zero or more allowed_keys signature options */
+struct sshsigopt *sshsigopt_parse(const char *opts,
+ const char *path, u_long linenum, const char **errstrp);
+
+/* Free signature options */
+void sshsigopt_free(struct sshsigopt *opts);
+
+/* Get public key from signature */
+int sshsig_get_pubkey(struct sshbuf *signature, struct sshkey **pubkey);
+
+/* Find principal in allowed_keys file, given a sshkey. Returns
+ * 0 on success.
+ */
+int sshsig_find_principals(const char *path, const struct sshkey *sign_key,
+ uint64_t verify_time, char **principal);
+
+#endif /* SSHSIG_H */
diff --git a/crypto/openssh/ttymodes.c b/crypto/openssh/ttymodes.c
index f0c2a5d37d37..1d20ce8005bf 100644
--- a/crypto/openssh/ttymodes.c
+++ b/crypto/openssh/ttymodes.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ttymodes.c,v 1.34 2018/07/09 21:20:26 markus Exp $ */
+/* $OpenBSD: ttymodes.c,v 1.36 2021/01/27 09:26:54 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -283,11 +283,11 @@ ssh_tty_make_modes(struct ssh *ssh, int fd, struct termios *tiop)
int r, ibaud, obaud;
if ((buf = sshbuf_new()) == NULL)
- fatal("%s: sshbuf_new failed", __func__);
+ fatal_f("sshbuf_new failed");
if (tiop == NULL) {
if (fd == -1) {
- debug("%s: no fd or tio", __func__);
+ debug_f("no fd or tio");
goto end;
}
if (tcgetattr(fd, &tio) == -1) {
@@ -304,23 +304,23 @@ ssh_tty_make_modes(struct ssh *ssh, int fd, struct termios *tiop)
(r = sshbuf_put_u32(buf, obaud)) != 0 ||
(r = sshbuf_put_u8(buf, TTY_OP_ISPEED)) != 0 ||
(r = sshbuf_put_u32(buf, ibaud)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "compose");
/* Store values of mode flags. */
#define TTYCHAR(NAME, OP) \
if ((r = sshbuf_put_u8(buf, OP)) != 0 || \
(r = sshbuf_put_u32(buf, \
special_char_encode(tio.c_cc[NAME]))) != 0) \
- fatal("%s: buffer error: %s", __func__, ssh_err(r)); \
+ fatal_fr(r, "compose %s", #NAME);
#define SSH_TTYMODE_IUTF8 42 /* for SSH_BUG_UTF8TTYMODE */
#define TTYMODE(NAME, FIELD, OP) \
- if (OP == SSH_TTYMODE_IUTF8 && (datafellows & SSH_BUG_UTF8TTYMODE)) { \
- debug3("%s: SSH_BUG_UTF8TTYMODE", __func__); \
+ if (OP == SSH_TTYMODE_IUTF8 && (ssh->compat & SSH_BUG_UTF8TTYMODE)) { \
+ debug3_f("SSH_BUG_UTF8TTYMODE"); \
} else if ((r = sshbuf_put_u8(buf, OP)) != 0 || \
(r = sshbuf_put_u32(buf, ((tio.FIELD & NAME) != 0))) != 0) \
- fatal("%s: buffer error: %s", __func__, ssh_err(r)); \
+ fatal_fr(r, "compose %s", #NAME);
#include "ttymodes.h"
@@ -331,7 +331,7 @@ end:
/* Mark end of mode data. */
if ((r = sshbuf_put_u8(buf, TTY_OP_END)) != 0 ||
(r = sshpkt_put_stringb(ssh, buf)) != 0)
- fatal("%s: packet error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "compose end");
sshbuf_free(buf);
}
@@ -351,11 +351,11 @@ ssh_tty_parse_modes(struct ssh *ssh, int fd)
size_t len;
if ((r = sshpkt_get_string_direct(ssh, &data, &len)) != 0)
- fatal("%s: packet error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "parse");
if (len == 0)
return;
if ((buf = sshbuf_from(data, len)) == NULL) {
- error("%s: sshbuf_from failed", __func__);
+ error_f("sshbuf_from failed");
return;
}
@@ -371,15 +371,14 @@ ssh_tty_parse_modes(struct ssh *ssh, int fd)
while (sshbuf_len(buf) > 0) {
if ((r = sshbuf_get_u8(buf, &opcode)) != 0)
- fatal("%s: packet error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "parse opcode");
switch (opcode) {
case TTY_OP_END:
goto set;
case TTY_OP_ISPEED:
if ((r = sshbuf_get_u32(buf, &baud)) != 0)
- fatal("%s: packet error: %s",
- __func__, ssh_err(r));
+ fatal_fr(r, "parse ispeed");
if (failure != -1 &&
cfsetispeed(&tio, baud_to_speed(baud)) == -1)
error("cfsetispeed failed for %d", baud);
@@ -387,8 +386,7 @@ ssh_tty_parse_modes(struct ssh *ssh, int fd)
case TTY_OP_OSPEED:
if ((r = sshbuf_get_u32(buf, &baud)) != 0)
- fatal("%s: packet error: %s",
- __func__, ssh_err(r));
+ fatal_fr(r, "parse ospeed");
if (failure != -1 &&
cfsetospeed(&tio, baud_to_speed(baud)) == -1)
error("cfsetospeed failed for %d", baud);
@@ -397,15 +395,13 @@ ssh_tty_parse_modes(struct ssh *ssh, int fd)
#define TTYCHAR(NAME, OP) \
case OP: \
if ((r = sshbuf_get_u32(buf, &u)) != 0) \
- fatal("%s: packet error: %s", __func__, \
- ssh_err(r)); \
+ fatal_fr(r, "parse %s", #NAME); \
tio.c_cc[NAME] = special_char_decode(u); \
break;
#define TTYMODE(NAME, FIELD, OP) \
case OP: \
if ((r = sshbuf_get_u32(buf, &u)) != 0) \
- fatal("%s: packet error: %s", __func__, \
- ssh_err(r)); \
+ fatal_fr(r, "parse %s", #NAME); \
if (u) \
tio.FIELD |= NAME; \
else \
@@ -429,12 +425,10 @@ ssh_tty_parse_modes(struct ssh *ssh, int fd)
*/
if (opcode > 0 && opcode < 160) {
if ((r = sshbuf_get_u32(buf, NULL)) != 0)
- fatal("%s: packet error: %s", __func__,
- ssh_err(r));
+ fatal_fr(r, "parse arg");
break;
} else {
- logit("%s: unknown opcode %d", __func__,
- opcode);
+ logit_f("unknown opcode %d", opcode);
goto set;
}
}
@@ -444,7 +438,7 @@ set:
len = sshbuf_len(buf);
sshbuf_free(buf);
if (len > 0) {
- logit("%s: %zu bytes left", __func__, len);
+ logit_f("%zu bytes left", len);
return; /* Don't process bytes passed */
}
if (failure == -1)
diff --git a/crypto/openssh/uidswap.c b/crypto/openssh/uidswap.c
index 49f76d818a81..6ed3024d0180 100644
--- a/crypto/openssh/uidswap.c
+++ b/crypto/openssh/uidswap.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: uidswap.c,v 1.41 2018/07/18 11:34:04 dtucker Exp $ */
+/* $OpenBSD: uidswap.c,v 1.42 2019/06/28 13:35:04 deraadt Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -42,7 +42,7 @@
is not part of the posix specification. */
#define SAVED_IDS_WORK_WITH_SETEUID
/* Saved effective uid. */
-static uid_t saved_euid = 0;
+static uid_t saved_euid = 0;
static gid_t saved_egid = 0;
#endif
@@ -84,12 +84,12 @@ temporarily_use_uid(struct passwd *pw)
temporarily_use_uid_effective = 1;
saved_egroupslen = getgroups(0, NULL);
- if (saved_egroupslen < 0)
+ if (saved_egroupslen == -1)
fatal("getgroups: %.100s", strerror(errno));
if (saved_egroupslen > 0) {
saved_egroups = xreallocarray(saved_egroups,
saved_egroupslen, sizeof(gid_t));
- if (getgroups(saved_egroupslen, saved_egroups) < 0)
+ if (getgroups(saved_egroupslen, saved_egroups) == -1)
fatal("getgroups: %.100s", strerror(errno));
} else { /* saved_egroupslen == 0 */
free(saved_egroups);
@@ -98,17 +98,17 @@ temporarily_use_uid(struct passwd *pw)
/* set and save the user's groups */
if (user_groupslen == -1 || user_groups_uid != pw->pw_uid) {
- if (initgroups(pw->pw_name, pw->pw_gid) < 0)
+ if (initgroups(pw->pw_name, pw->pw_gid) == -1)
fatal("initgroups: %s: %.100s", pw->pw_name,
strerror(errno));
user_groupslen = getgroups(0, NULL);
- if (user_groupslen < 0)
+ if (user_groupslen == -1)
fatal("getgroups: %.100s", strerror(errno));
if (user_groupslen > 0) {
user_groups = xreallocarray(user_groups,
user_groupslen, sizeof(gid_t));
- if (getgroups(user_groupslen, user_groups) < 0)
+ if (getgroups(user_groupslen, user_groups) == -1)
fatal("getgroups: %.100s", strerror(errno));
} else { /* user_groupslen == 0 */
free(user_groups);
@@ -117,17 +117,17 @@ temporarily_use_uid(struct passwd *pw)
user_groups_uid = pw->pw_uid;
}
/* Set the effective uid to the given (unprivileged) uid. */
- if (setgroups(user_groupslen, user_groups) < 0)
+ if (setgroups(user_groupslen, user_groups) == -1)
fatal("setgroups: %.100s", strerror(errno));
#ifndef SAVED_IDS_WORK_WITH_SETEUID
/* Propagate the privileged gid to all of our gids. */
- if (setgid(getegid()) < 0)
+ if (setgid(getegid()) == -1)
debug("setgid %u: %.100s", (u_int) getegid(), strerror(errno));
/* Propagate the privileged uid to all of our uids. */
- if (setuid(geteuid()) < 0)
+ if (setuid(geteuid()) == -1)
debug("setuid %u: %.100s", (u_int) geteuid(), strerror(errno));
#endif /* SAVED_IDS_WORK_WITH_SETEUID */
- if (setegid(pw->pw_gid) < 0)
+ if (setegid(pw->pw_gid) == -1)
fatal("setegid %u: %.100s", (u_int)pw->pw_gid,
strerror(errno));
if (seteuid(pw->pw_uid) == -1)
@@ -152,9 +152,9 @@ restore_uid(void)
#ifdef SAVED_IDS_WORK_WITH_SETEUID
debug("restore_uid: %u/%u", (u_int)saved_euid, (u_int)saved_egid);
/* Set the effective uid back to the saved privileged uid. */
- if (seteuid(saved_euid) < 0)
+ if (seteuid(saved_euid) == -1)
fatal("seteuid %u: %.100s", (u_int)saved_euid, strerror(errno));
- if (setegid(saved_egid) < 0)
+ if (setegid(saved_egid) == -1)
fatal("setegid %u: %.100s", (u_int)saved_egid, strerror(errno));
#else /* SAVED_IDS_WORK_WITH_SETEUID */
/*
@@ -162,11 +162,13 @@ restore_uid(void)
* Propagate the real uid (usually more privileged) to effective uid
* as well.
*/
- setuid(getuid());
- setgid(getgid());
+ if (setuid(getuid()) == -1)
+ fatal("%s: setuid failed: %s", __func__, strerror(errno));
+ if (setgid(getgid()) == -1)
+ fatal("%s: setgid failed: %s", __func__, strerror(errno));
#endif /* SAVED_IDS_WORK_WITH_SETEUID */
- if (setgroups(saved_egroupslen, saved_egroups) < 0)
+ if (setgroups(saved_egroupslen, saved_egroups) == -1)
fatal("setgroups: %.100s", strerror(errno));
temporarily_use_uid_effective = 0;
}
@@ -190,7 +192,7 @@ permanently_set_uid(struct passwd *pw)
debug("permanently_set_uid: %u/%u", (u_int)pw->pw_uid,
(u_int)pw->pw_gid);
- if (setresgid(pw->pw_gid, pw->pw_gid, pw->pw_gid) < 0)
+ if (setresgid(pw->pw_gid, pw->pw_gid, pw->pw_gid) == -1)
fatal("setresgid %u: %.100s", (u_int)pw->pw_gid, strerror(errno));
#ifdef __APPLE__
@@ -198,12 +200,12 @@ permanently_set_uid(struct passwd *pw)
* OS X requires initgroups after setgid to opt back into
* memberd support for >16 supplemental groups.
*/
- if (initgroups(pw->pw_name, pw->pw_gid) < 0)
+ if (initgroups(pw->pw_name, pw->pw_gid) == -1)
fatal("initgroups %.100s %u: %.100s",
pw->pw_name, (u_int)pw->pw_gid, strerror(errno));
#endif
- if (setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid) < 0)
+ if (setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid) == -1)
fatal("setresuid %u: %.100s", (u_int)pw->pw_uid, strerror(errno));
#ifndef NO_UID_RESTORATION_TEST
diff --git a/crypto/openssh/umac.c b/crypto/openssh/umac.c
index ccae39f30940..e5ec19f082cb 100644
--- a/crypto/openssh/umac.c
+++ b/crypto/openssh/umac.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: umac.c,v 1.17 2018/04/10 00:10:49 djm Exp $ */
+/* $OpenBSD: umac.c,v 1.21 2021/04/03 06:58:30 djm Exp $ */
/* -----------------------------------------------------------------------
*
* umac.c -- C Implementation UMAC Message Authentication
@@ -39,7 +39,7 @@
* at http://www.esat.kuleuven.ac.be/~rijmen/rijndael/ (search for
* "Barreto"). The only two files needed are rijndael-alg-fst.c and
* rijndael-alg-fst.h. Brian Gladman's version is distributed with the GNU
- * Public lisence at http://fp.gladman.plus.com/AES/index.htm. It
+ * Public license at http://fp.gladman.plus.com/AES/index.htm. It
* includes a fast IA-32 assembly version. The OpenSSL crypo library is
* the third.
*
@@ -74,6 +74,7 @@
#include "includes.h"
#include <sys/types.h>
#include <string.h>
+#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
@@ -289,7 +290,7 @@ static void pdf_gen_xor(pdf_ctx *pc, const UINT8 nonce[8], UINT8 buf[8])
* versions, one expects the entire message being hashed to be passed
* in a single buffer and returns the hash result immediately. The second
* allows the message to be passed in a sequence of buffers. In the
- * muliple-buffer interface, the client calls the routine nh_update() as
+ * multiple-buffer interface, the client calls the routine nh_update() as
* many times as necessary. When there is no more data to be fed to the
* hash, the client calls nh_final() which calculates the hash output.
* Before beginning another hash calculation the nh_reset() routine
@@ -1204,8 +1205,7 @@ int umac_delete(struct umac_ctx *ctx)
if (ctx) {
if (ALLOC_BOUNDARY)
ctx = (struct umac_ctx *)ctx->free_ptr;
- explicit_bzero(ctx, sizeof(*ctx) + ALLOC_BOUNDARY);
- free(ctx);
+ freezero(ctx, sizeof(*ctx) + ALLOC_BOUNDARY);
}
return (1);
}
diff --git a/crypto/openssh/umac.h b/crypto/openssh/umac.h
index 7fb770f8a52b..4651f0d5aaf0 100644
--- a/crypto/openssh/umac.h
+++ b/crypto/openssh/umac.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: umac.h,v 1.3 2013/07/22 12:20:02 djm Exp $ */
+/* $OpenBSD: umac.h,v 1.4 2019/06/07 14:18:48 dtucker Exp $ */
/* -----------------------------------------------------------------------
*
* umac.h -- C Implementation UMAC Message Authentication
@@ -39,7 +39,7 @@
* at http://www.esat.kuleuven.ac.be/~rijmen/rijndael/ (search for
* "Barreto"). The only two files needed are rijndael-alg-fst.c and
* rijndael-alg-fst.h.
- * Brian Gladman's version is distributed with GNU Public lisence
+ * Brian Gladman's version is distributed with GNU Public license
* and can be found at http://fp.gladman.plus.com/AES/index.htm. It
* includes a fast IA-32 assembly version.
*
@@ -107,7 +107,7 @@ int uhash_update(uhash_ctx_t ctx,
long len);
int uhash_final(uhash_ctx_t ctx,
- u_char ouput[]);
+ u_char output[]);
int uhash(uhash_ctx_t ctx,
u_char *input,
diff --git a/crypto/openssh/utf8.c b/crypto/openssh/utf8.c
index db7cb8f35eda..7f63b25aeefc 100644
--- a/crypto/openssh/utf8.c
+++ b/crypto/openssh/utf8.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: utf8.c,v 1.8 2018/08/21 13:56:27 schwarze Exp $ */
+/* $OpenBSD: utf8.c,v 1.11 2020/05/01 06:28:52 djm Exp $ */
/*
* Copyright (c) 2016 Ingo Schwarze <schwarze@openbsd.org>
*
@@ -43,7 +43,6 @@
static int dangerous_locale(void);
static int grow_dst(char **, size_t *, size_t, char **, size_t);
-static int vasnmprintf(char **, size_t, int *, const char *, va_list);
/*
@@ -101,7 +100,7 @@ grow_dst(char **dst, size_t *sz, size_t maxsz, char **dp, size_t need)
* written is returned in *wp.
*/
-static int
+int
vasnmprintf(char **str, size_t maxsz, int *wp, const char *fmt, va_list ap)
{
char *src; /* Source string returned from vasprintf. */
@@ -241,7 +240,7 @@ int
snmprintf(char *str, size_t sz, int *wp, const char *fmt, ...)
{
va_list ap;
- char *cp;
+ char *cp = NULL;
int ret;
va_start(ap, fmt);
@@ -255,6 +254,20 @@ snmprintf(char *str, size_t sz, int *wp, const char *fmt, ...)
return ret;
}
+int
+asmprintf(char **outp, size_t sz, int *wp, const char *fmt, ...)
+{
+ va_list ap;
+ int ret;
+
+ *outp = NULL;
+ va_start(ap, fmt);
+ ret = vasnmprintf(outp, sz, wp, fmt, ap);
+ va_end(ap);
+
+ return ret;
+}
+
/*
* To stay close to the standard interfaces, the following functions
* return the number of non-NUL bytes written.
@@ -263,11 +276,13 @@ snmprintf(char *str, size_t sz, int *wp, const char *fmt, ...)
int
vfmprintf(FILE *stream, const char *fmt, va_list ap)
{
- char *str;
+ char *str = NULL;
int ret;
- if ((ret = vasnmprintf(&str, INT_MAX, NULL, fmt, ap)) < 0)
+ if ((ret = vasnmprintf(&str, INT_MAX, NULL, fmt, ap)) < 0) {
+ free(str);
return -1;
+ }
if (fputs(str, stream) == EOF)
ret = -1;
free(str);
diff --git a/crypto/openssh/utf8.h b/crypto/openssh/utf8.h
index 88c5a34a3436..09941d47180a 100644
--- a/crypto/openssh/utf8.h
+++ b/crypto/openssh/utf8.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: utf8.h,v 1.1 2016/05/25 23:48:45 schwarze Exp $ */
+/* $OpenBSD: utf8.h,v 1.4 2021/04/03 06:18:41 djm Exp $ */
/*
* Copyright (c) 2016 Ingo Schwarze <schwarze@openbsd.org>
*
@@ -15,11 +15,14 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
+int vasnmprintf(char **, size_t, int *, const char *, va_list);
int mprintf(const char *, ...)
- __attribute__((format(printf, 1, 2)));
+ __attribute__((format(printf, 1, 2)));
int fmprintf(FILE *, const char *, ...)
- __attribute__((format(printf, 2, 3)));
+ __attribute__((format(printf, 2, 3)));
int vfmprintf(FILE *, const char *, va_list);
int snmprintf(char *, size_t, int *, const char *, ...)
- __attribute__((format(printf, 4, 5)));
+ __attribute__((format(printf, 4, 5)));
+int asmprintf(char **, size_t, int *, const char *, ...)
+ __attribute__((format(printf, 4, 5)));
void msetlocale(void);
diff --git a/crypto/openssh/uuencode.c b/crypto/openssh/uuencode.c
deleted file mode 100644
index 7fc867a11fd9..000000000000
--- a/crypto/openssh/uuencode.c
+++ /dev/null
@@ -1,95 +0,0 @@
-/* $OpenBSD: uuencode.c,v 1.28 2015/04/24 01:36:24 deraadt Exp $ */
-/*
- * Copyright (c) 2000 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"
-
-#include <sys/types.h>
-#include <netinet/in.h>
-#include <resolv.h>
-#include <stdio.h>
-#include <stdlib.h>
-
-#include "xmalloc.h"
-#include "uuencode.h"
-
-/*
- * Encode binary 'src' of length 'srclength', writing base64-encoded text
- * to 'target' of size 'targsize'. Will always nul-terminate 'target'.
- * Returns the number of bytes stored in 'target' or -1 on error (inc.
- * 'targsize' too small).
- */
-int
-uuencode(const u_char *src, u_int srclength,
- char *target, size_t targsize)
-{
- return __b64_ntop(src, srclength, target, targsize);
-}
-
-/*
- * Decode base64-encoded 'src' into buffer 'target' of 'targsize' bytes.
- * Will skip leading and trailing whitespace. Returns the number of bytes
- * stored in 'target' or -1 on error (inc. targsize too small).
- */
-int
-uudecode(const char *src, u_char *target, size_t targsize)
-{
- int len;
- char *encoded, *p;
-
- /* copy the 'readonly' source */
- encoded = xstrdup(src);
- /* skip whitespace and data */
- for (p = encoded; *p == ' ' || *p == '\t'; p++)
- ;
- for (; *p != '\0' && *p != ' ' && *p != '\t'; p++)
- ;
- /* and remove trailing whitespace because __b64_pton needs this */
- *p = '\0';
- len = __b64_pton(encoded, target, targsize);
- free(encoded);
- return len;
-}
-
-void
-dump_base64(FILE *fp, const u_char *data, u_int len)
-{
- char *buf;
- int i, n;
-
- if (len > 65536) {
- fprintf(fp, "dump_base64: len > 65536\n");
- return;
- }
- buf = xreallocarray(NULL, 2, len);
- n = uuencode(data, len, buf, 2*len);
- for (i = 0; i < n; i++) {
- fprintf(fp, "%c", buf[i]);
- if (i % 70 == 69)
- fprintf(fp, "\n");
- }
- if (i % 70 != 69)
- fprintf(fp, "\n");
- free(buf);
-}
diff --git a/crypto/openssh/uuencode.h b/crypto/openssh/uuencode.h
deleted file mode 100644
index 4d9888126cdc..000000000000
--- a/crypto/openssh/uuencode.h
+++ /dev/null
@@ -1,29 +0,0 @@
-/* $OpenBSD: uuencode.h,v 1.14 2010/08/31 11:54:45 djm Exp $ */
-
-/*
- * Copyright (c) 2000 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.
- */
-
-int uuencode(const u_char *, u_int, char *, size_t);
-int uudecode(const char *, u_char *, size_t);
-void dump_base64(FILE *, const u_char *, u_int);
diff --git a/crypto/openssh/version.h b/crypto/openssh/version.h
index 9dbaf16e7192..bce1a257b927 100644
--- a/crypto/openssh/version.h
+++ b/crypto/openssh/version.h
@@ -1,12 +1,12 @@
-/* $OpenBSD: version.h,v 1.83 2018/10/10 16:43:49 deraadt Exp $ */
+/* $OpenBSD: version.h,v 1.91 2021/08/20 03:22:55 djm Exp $ */
/* $FreeBSD$ */
-#define SSH_VERSION "OpenSSH_7.9"
+#define SSH_VERSION "OpenSSH_8.7"
#define SSH_PORTABLE "p1"
#define SSH_RELEASE SSH_VERSION SSH_PORTABLE
-#define SSH_VERSION_FREEBSD "FreeBSD-20200214"
+#define SSH_VERSION_FREEBSD "FreeBSD-20210907"
#ifdef WITH_OPENSSL
#define OPENSSL_VERSION_STRING OpenSSL_version(OPENSSL_VERSION)
diff --git a/crypto/openssh/xmalloc.c b/crypto/openssh/xmalloc.c
index 5cc0310a4766..b48d33bbf68c 100644
--- a/crypto/openssh/xmalloc.c
+++ b/crypto/openssh/xmalloc.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: xmalloc.c,v 1.34 2017/05/31 09:15:42 deraadt Exp $ */
+/* $OpenBSD: xmalloc.c,v 1.36 2019/11/12 22:32:48 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -17,7 +17,7 @@
#include <stdarg.h>
#ifdef HAVE_STDINT_H
-#include <stdint.h>
+# include <stdint.h>
#endif
#include <stdio.h>
#include <stdlib.h>
@@ -26,15 +26,9 @@
#include "xmalloc.h"
#include "log.h"
-void
-ssh_malloc_init(void)
-{
#if defined(__OpenBSD__)
- extern char *malloc_options;
-
- malloc_options = "S";
+char *malloc_options = "S";
#endif /* __OpenBSD__ */
-}
void *
xmalloc(size_t size)
@@ -102,17 +96,24 @@ xstrdup(const char *str)
}
int
+xvasprintf(char **ret, const char *fmt, va_list ap)
+{
+ int i;
+
+ i = vasprintf(ret, fmt, ap);
+ if (i < 0 || *ret == NULL)
+ fatal("xvasprintf: could not allocate memory");
+ return i;
+}
+
+int
xasprintf(char **ret, const char *fmt, ...)
{
va_list ap;
int i;
va_start(ap, fmt);
- i = vasprintf(ret, fmt, ap);
+ i = xvasprintf(ret, fmt, ap);
va_end(ap);
-
- if (i < 0 || *ret == NULL)
- fatal("xasprintf: could not allocate memory");
-
- return (i);
+ return i;
}
diff --git a/crypto/openssh/xmalloc.h b/crypto/openssh/xmalloc.h
index cf38ddfa48c5..a6b8d23bde8e 100644
--- a/crypto/openssh/xmalloc.h
+++ b/crypto/openssh/xmalloc.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: xmalloc.h,v 1.17 2017/05/31 09:15:42 deraadt Exp $ */
+/* $OpenBSD: xmalloc.h,v 1.20 2021/04/03 06:18:41 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -16,12 +16,12 @@
* called by a name other than "ssh" or "Secure Shell".
*/
-void ssh_malloc_init(void);
void *xmalloc(size_t);
void *xcalloc(size_t, size_t);
void *xreallocarray(void *, size_t, size_t);
void *xrecallocarray(void *, size_t, size_t, size_t);
char *xstrdup(const char *);
int xasprintf(char **, const char *, ...)
- __attribute__((__format__ (printf, 2, 3)))
- __attribute__((__nonnull__ (2)));
+ __attribute__((__format__ (printf, 2, 3))) __attribute__((__nonnull__ (2)));
+int xvasprintf(char **, const char *, va_list)
+ __attribute__((__nonnull__ (2)));
diff --git a/crypto/openssh/xmss_commons.c b/crypto/openssh/xmss_commons.c
index 59486aead708..8d6b80b6eb79 100644
--- a/crypto/openssh/xmss_commons.c
+++ b/crypto/openssh/xmss_commons.c
@@ -13,7 +13,7 @@ Public domain.
#include <stdlib.h>
#include <stdio.h>
#ifdef HAVE_STDINT_H
-#include <stdint.h>
+# include <stdint.h>
#endif
void to_byte(unsigned char *out, unsigned long long in, uint32_t bytes)
diff --git a/crypto/openssh/xmss_fast.c b/crypto/openssh/xmss_fast.c
index e37447f60d8c..421b39a37a9e 100644
--- a/crypto/openssh/xmss_fast.c
+++ b/crypto/openssh/xmss_fast.c
@@ -12,7 +12,7 @@ Public domain.
#include <stdlib.h>
#include <string.h>
#ifdef HAVE_STDINT_H
-#include <stdint.h>
+# include <stdint.h>
#endif
#include "xmss_fast.h"
diff --git a/crypto/openssh/xmss_hash.c b/crypto/openssh/xmss_hash.c
index b9eee7cff293..50a577943974 100644
--- a/crypto/openssh/xmss_hash.c
+++ b/crypto/openssh/xmss_hash.c
@@ -15,7 +15,7 @@ Public domain.
#include <stddef.h>
#ifdef HAVE_STDINT_H
-#include <stdint.h>
+# include <stdint.h>
#endif
#include <stdio.h>
#include <string.h>
diff --git a/crypto/openssh/xmss_hash_address.c b/crypto/openssh/xmss_hash_address.c
index c6c1347e9267..2702c4562bfc 100644
--- a/crypto/openssh/xmss_hash_address.c
+++ b/crypto/openssh/xmss_hash_address.c
@@ -9,7 +9,7 @@ Public domain.
#ifdef WITH_XMSS
#ifdef HAVE_STDINT_H
-#include <stdint.h>
+# include <stdint.h>
#endif
#include "xmss_hash_address.h" /* prototypes */
diff --git a/crypto/openssh/xmss_wots.c b/crypto/openssh/xmss_wots.c
index ed904cd754dd..993e661f6707 100644
--- a/crypto/openssh/xmss_wots.c
+++ b/crypto/openssh/xmss_wots.c
@@ -11,7 +11,7 @@ Public domain.
#include <stdlib.h>
#ifdef HAVE_STDINT_H
-#include <stdint.h>
+# include <stdint.h>
#endif
#include <limits.h>
#include "xmss_commons.h"
diff --git a/lib/libpam/modules/pam_ssh/pam_ssh.c b/lib/libpam/modules/pam_ssh/pam_ssh.c
index 9b30ba935a7b..d066ca253a89 100644
--- a/lib/libpam/modules/pam_ssh/pam_ssh.c
+++ b/lib/libpam/modules/pam_ssh/pam_ssh.c
@@ -65,7 +65,7 @@ __FBSDID("$FreeBSD$");
#include "sshkey.h"
#define ssh_add_identity(auth, key, comment) \
- ssh_add_identity_constrained(auth, key, comment, 0, 0, 0)
+ ssh_add_identity_constrained(auth, key, comment, 0, 0, 0, NULL)
extern char **environ;
diff --git a/secure/lib/libssh/Makefile b/secure/lib/libssh/Makefile
index aa3dc27fb526..b97bd7f2693f 100644
--- a/secure/lib/libssh/Makefile
+++ b/secure/lib/libssh/Makefile
@@ -10,20 +10,21 @@ SRCS= ssh_api.c ssherr.c sshbuf.c sshkey.c sshbuf-getput-basic.c \
SRCS+= authfd.c authfile.c \
canohost.c channels.c cipher.c cipher-aes.c cipher-aesctr.c \
cipher-ctr.c cleanup.c \
- compat.c crc32.c fatal.c hostfile.c \
- log.c match.c moduli.c nchan.c packet.c opacket.c \
- readpass.c ttymodes.c xmalloc.c addrmatch.c \
- atomicio.c dispatch.c mac.c uuencode.c misc.c utf8.c \
+ compat.c fatal.c hostfile.c \
+ log.c match.c moduli.c nchan.c packet.c \
+ readpass.c ttymodes.c xmalloc.c addr.c addrmatch.c \
+ atomicio.c dispatch.c mac.c misc.c utf8.c \
monitor_fdpass.c rijndael.c ssh-dss.c ssh-ecdsa.c ssh-rsa.c dh.c \
msg.c progressmeter.c dns.c entropy.c umac.c umac128.c \
ssh-pkcs11.c smult_curve25519_ref.c \
- poly1305.c chacha.c cipher-chachapoly.c \
+ poly1305.c chacha.c cipher-chachapoly.c cipher-chachapoly-libcrypto.c \
ssh-ed25519.c digest-openssl.c digest-libc.c hmac.c \
sc25519.c ge25519.c fe25519.c ed25519.c verify.c hash.c \
kex.c kexdh.c kexgex.c kexecdh.c kexc25519.c \
- kexdhc.c kexgexc.c kexecdhc.c kexc25519c.c \
- kexdhs.c kexgexs.c kexecdhs.c kexc25519s.c \
- platform-pledge.c platform-tracing.c platform-misc.c
+ kexgexc.c kexgexs.c \
+ kexsntrup761x25519.c sntrup761.c kexgen.c \
+ sftp-realpath.c platform-pledge.c platform-tracing.c platform-misc.c \
+ sshbuf-io.c
PACKAGE= ssh
# gss-genr.c should be in $SRCS but causes linking problems, so it is
@@ -34,7 +35,7 @@ SRCS+= bcrypt_pbkdf.c blowfish.c bsd-misc.c bsd-signal.c explicit_bzero.c \
fmt_scaled.c freezero.c glob.c \
libressl-api-compat.c \
openssl-compat.c port-net.c \
- realpath.c recallocarray.c strtonum.c timingsafe_bcmp.c vis.c xcrypt.c
+ recallocarray.c strtonum.c timingsafe_bcmp.c vis.c xcrypt.c
.if ${MK_LDNS} == "no"
SRCS+= getrrsetbyname.c
diff --git a/secure/usr.bin/scp/Makefile b/secure/usr.bin/scp/Makefile
index 34469a443287..a4e55c1bf86b 100644
--- a/secure/usr.bin/scp/Makefile
+++ b/secure/usr.bin/scp/Makefile
@@ -3,7 +3,7 @@
.include <src.opts.mk>
PROG= scp
-SRCS= scp.c
+SRCS= scp.c sftp-common.c sftp-client.c sftp-glob.c progressmeter.c
PACKAGE= ssh
CFLAGS+=-I${SSHDIR} -include ssh_namespace.h
SRCS+= ssh_namespace.h
diff --git a/secure/usr.bin/ssh-add/Makefile b/secure/usr.bin/ssh-add/Makefile
index acce73d3841d..c76e50a4a91a 100644
--- a/secure/usr.bin/ssh-add/Makefile
+++ b/secure/usr.bin/ssh-add/Makefile
@@ -3,7 +3,7 @@
.include <src.opts.mk>
PROG= ssh-add
-SRCS+= ssh-add.c
+SRCS+= ssh-add.c ssh-sk-client.c
PACKAGE= ssh
CFLAGS+=-I${SSHDIR} -include ssh_namespace.h
SRCS+= ssh_namespace.h
diff --git a/secure/usr.bin/ssh-keygen/Makefile b/secure/usr.bin/ssh-keygen/Makefile
index d6b5616dfc0a..eec0b23e1b3f 100644
--- a/secure/usr.bin/ssh-keygen/Makefile
+++ b/secure/usr.bin/ssh-keygen/Makefile
@@ -3,7 +3,8 @@
.include <src.opts.mk>
PROG= ssh-keygen
-SRCS= ssh-keygen.c
+# XXX ssh-sk-client.c in libssh maybe?
+SRCS= ssh-keygen.c sshsig.c ssh-sk-client.c
PACKAGE= ssh
CFLAGS+=-I${SSHDIR} -include ssh_namespace.h
SRCS+= ssh_namespace.h
diff --git a/secure/usr.sbin/sshd/Makefile b/secure/usr.sbin/sshd/Makefile
index f5a4d94a62e6..b374e737a139 100644
--- a/secure/usr.sbin/sshd/Makefile
+++ b/secure/usr.sbin/sshd/Makefile
@@ -15,7 +15,7 @@ SRCS= sshd.c auth-rhosts.c auth-passwd.c \
monitor.c monitor_wrap.c auth-krb5.c \
auth2-gss.c gss-serv.c gss-serv-krb5.c \
loginrec.c auth-pam.c auth-shadow.c auth-sia.c md5crypt.c \
- sftp-server.c sftp-common.c \
+ srclimit.c sftp-server.c sftp-common.c \
sandbox-null.c sandbox-rlimit.c sandbox-systrace.c sandbox-darwin.c \
sandbox-seccomp-filter.c sandbox-capsicum.c sandbox-pledge.c \
sandbox-solaris.c uidswap.c