summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorColin Watson <cjwatson@debian.org>2021-11-05 22:45:37 +0000
committerColin Watson <cjwatson@debian.org>2021-11-05 22:45:37 +0000
commitdaf0867ae0da20e992a22cd6239a26b5ecee7e4c (patch)
treedc2dc8dba6a712372e3baf23f21b2f52480692c7
parent2b2c99658e3e8ed452e28f88f9cdbcdfb2a461cb (diff)
parente1a596186c81e65a34ce13076449712d3bf97eb4 (diff)
Import openssh_8.7p1.orig.tar.gz
-rw-r--r--.depend345
-rw-r--r--.github/ci-status.md4
-rwxr-xr-x.github/configs170
-rwxr-xr-x.github/configure.sh6
-rwxr-xr-x.github/run_test.sh48
-rwxr-xr-x.github/setup_ci.sh84
-rw-r--r--.github/workflows/c-cpp.yml69
-rw-r--r--.github/workflows/selfhosted.yml93
-rw-r--r--.github/workflows/upstream.yml43
-rw-r--r--.skipped-commit-ids2
-rw-r--r--ChangeLog10117
-rw-r--r--INSTALL5
-rw-r--r--LICENCE62
-rw-r--r--Makefile.in108
-rw-r--r--PROTOCOL81
-rw-r--r--PROTOCOL.agent8
-rw-r--r--PROTOCOL.certkeys35
-rw-r--r--PROTOCOL.key9
-rw-r--r--README2
-rw-r--r--README.md11
-rw-r--r--README.platform16
-rw-r--r--aclocal.m42
-rw-r--r--addr.c423
-rw-r--r--addr.h60
-rw-r--r--addrmatch.c351
-rw-r--r--audit-bsm.c39
-rw-r--r--auth-krb5.c19
-rw-r--r--auth-options.c56
-rw-r--r--auth-options.h7
-rw-r--r--auth-pam.c11
-rw-r--r--auth-passwd.c6
-rw-r--r--auth-rhosts.c6
-rw-r--r--auth.c228
-rw-r--r--auth.h8
-rw-r--r--auth2-chall.c37
-rw-r--r--auth2-gss.c29
-rw-r--r--auth2-hostbased.c60
-rw-r--r--auth2-kbdint.c6
-rw-r--r--auth2-none.c4
-rw-r--r--auth2-passwd.c4
-rw-r--r--auth2-pubkey.c141
-rw-r--r--auth2.c62
-rw-r--r--authfd.c67
-rw-r--r--buildpkg.sh.in8
-rw-r--r--canohost.c8
-rw-r--r--chacha.h4
-rw-r--r--channels.c566
-rw-r--r--channels.h23
-rw-r--r--cipher.c10
-rw-r--r--clientloop.c599
-rw-r--r--compat.c50
-rw-r--r--compat.h14
-rw-r--r--config.h.in31
-rwxr-xr-xconfigure823
-rw-r--r--configure.ac234
-rw-r--r--contrib/Makefile6
-rw-r--r--contrib/gnome-ssh-askpass1.c7
-rw-r--r--contrib/gnome-ssh-askpass2.c10
-rw-r--r--contrib/gnome-ssh-askpass3.c305
-rw-r--r--contrib/redhat/openssh.spec2
-rw-r--r--contrib/ssh-copy-id185
-rw-r--r--contrib/ssh-copy-id.19
-rw-r--r--contrib/suse/openssh.spec2
-rw-r--r--crypto_api.h18
-rw-r--r--defines.h13
-rw-r--r--dh.c29
-rw-r--r--dh.h3
-rw-r--r--digest-openssl.c10
-rw-r--r--dns.c71
-rw-r--r--dns.h3
-rw-r--r--entropy.c123
-rw-r--r--fatal.c7
-rw-r--r--gss-genr.c19
-rw-r--r--hash.c2
-rw-r--r--hostfile.c203
-rw-r--r--hostfile.h24
-rw-r--r--int32_minmax.inc0
-rw-r--r--kex.c135
-rw-r--r--kex.h18
-rw-r--r--kexdh.c5
-rw-r--r--kexgen.c26
-rw-r--r--kexgexc.c14
-rw-r--r--kexgexs.c7
-rw-r--r--kexsntrup761x25519.c (renamed from kexsntrup4591761x25519.c)84
-rw-r--r--krl.c106
-rw-r--r--log.c211
-rw-r--r--log.h91
-rw-r--r--loginrec.h2
-rw-r--r--logintest.c60
-rw-r--r--m4/openssh.m417
-rw-r--r--match.c8
-rw-r--r--misc.c504
-rw-r--r--misc.h49
-rw-r--r--moduli902
-rw-r--r--moduli.02
-rw-r--r--monitor.c392
-rw-r--r--monitor_fdpass.c24
-rw-r--r--monitor_wrap.c252
-rw-r--r--monitor_wrap.h4
-rw-r--r--msg.c16
-rw-r--r--mux.c601
-rw-r--r--myproposal.h14
-rw-r--r--nchan.c73
-rw-r--r--openbsd-compat/Makefile.in2
-rw-r--r--openbsd-compat/arc4random.c12
-rw-r--r--openbsd-compat/base64.c2
-rw-r--r--openbsd-compat/bsd-misc.h6
-rw-r--r--openbsd-compat/bsd-poll.h2
-rw-r--r--openbsd-compat/bsd-pselect.c205
-rw-r--r--openbsd-compat/bsd-snprintf.c16
-rw-r--r--openbsd-compat/bsd-waitpid.h2
-rw-r--r--openbsd-compat/explicit_bzero.c10
-rw-r--r--openbsd-compat/getopt_long.c2
-rw-r--r--openbsd-compat/libressl-api-compat.c2
-rw-r--r--openbsd-compat/memmem.c5
-rw-r--r--openbsd-compat/mktemp.c4
-rw-r--r--openbsd-compat/openbsd-compat.h9
-rw-r--r--openbsd-compat/openssl-compat.h4
-rw-r--r--openbsd-compat/port-aix.c8
-rw-r--r--openbsd-compat/port-linux.c25
-rw-r--r--openbsd-compat/port-net.c3
-rw-r--r--openbsd-compat/port-prngd.c164
-rw-r--r--openbsd-compat/port-solaris.c8
-rw-r--r--openbsd-compat/port-uw.c2
-rw-r--r--openbsd-compat/regress/Makefile.in2
-rw-r--r--openbsd-compat/regress/closefromtest.c4
-rw-r--r--openbsd-compat/regress/opensslvertest.c2
-rw-r--r--openbsd-compat/regress/snprintftest.c2
-rw-r--r--openbsd-compat/regress/strduptest.c2
-rw-r--r--openbsd-compat/regress/strtonumtest.c2
-rw-r--r--openbsd-compat/regress/utimensattest.c2
-rw-r--r--openbsd-compat/setenv.c2
-rw-r--r--openbsd-compat/sha2.c4
-rw-r--r--openbsd-compat/strtonum.c6
-rw-r--r--packet.c123
-rw-r--r--packet.h3
-rw-r--r--readconf.c1065
-rw-r--r--readconf.h27
-rw-r--r--readpass.c77
-rw-r--r--regress/Makefile23
-rw-r--r--regress/agent-getpeereid.sh2
-rw-r--r--regress/agent-pkcs11.sh12
-rw-r--r--regress/agent.sh6
-rw-r--r--regress/allow-deny-users.sh8
-rw-r--r--regress/banner.sh6
-rw-r--r--regress/cert-hostkey.sh16
-rw-r--r--regress/cert-userkey.sh22
-rw-r--r--regress/cfginclude.sh24
-rw-r--r--regress/cfgmatch.sh8
-rw-r--r--regress/connect-privsep.sh5
-rw-r--r--regress/dhgex.sh4
-rw-r--r--regress/ed25519_openssh.prv7
-rw-r--r--regress/ed25519_openssh.pub1
-rw-r--r--regress/forward-control.sh6
-rw-r--r--regress/forwarding.sh8
-rw-r--r--regress/hostkey-rotate.sh7
-rw-r--r--regress/key-options.sh2
-rw-r--r--regress/keygen-convert.sh60
-rw-r--r--regress/keygen-sshfp.sh29
-rw-r--r--regress/keytype.sh6
-rw-r--r--regress/knownhosts-command.sh53
-rw-r--r--regress/limit-keytype.sh18
-rw-r--r--regress/misc/Makefile2
-rw-r--r--regress/misc/fuzz-harness/Makefile46
-rw-r--r--regress/misc/fuzz-harness/agent_fuzz.cc15
-rw-r--r--regress/misc/fuzz-harness/agent_fuzz_helper.c177
-rw-r--r--regress/misc/fuzz-harness/fixed-keys.h119
-rw-r--r--regress/misc/fuzz-harness/kex_fuzz.cc461
-rw-r--r--regress/misc/fuzz-harness/testdata/README4
-rwxr-xr-xregress/misc/fuzz-harness/testdata/create-agent-corpus.sh44
-rw-r--r--regress/misc/fuzz-harness/testdata/id_dsa21
-rw-r--r--regress/misc/fuzz-harness/testdata/id_dsa-cert.pub1
-rw-r--r--regress/misc/fuzz-harness/testdata/id_dsa.pub1
-rw-r--r--regress/misc/fuzz-harness/testdata/id_ecdsa8
-rw-r--r--regress/misc/fuzz-harness/testdata/id_ecdsa-cert.pub1
-rw-r--r--regress/misc/fuzz-harness/testdata/id_ecdsa.pub1
-rw-r--r--regress/misc/fuzz-harness/testdata/id_ecdsa_sk14
-rw-r--r--regress/misc/fuzz-harness/testdata/id_ecdsa_sk-cert.pub1
-rw-r--r--regress/misc/fuzz-harness/testdata/id_ecdsa_sk.pub1
-rw-r--r--regress/misc/fuzz-harness/testdata/id_ed255197
-rw-r--r--regress/misc/fuzz-harness/testdata/id_ed25519-cert.pub1
-rw-r--r--regress/misc/fuzz-harness/testdata/id_ed25519.pub2
-rw-r--r--regress/misc/fuzz-harness/testdata/id_ed25519_sk8
-rw-r--r--regress/misc/fuzz-harness/testdata/id_ed25519_sk-cert.pub1
-rw-r--r--regress/misc/fuzz-harness/testdata/id_ed25519_sk.pub1
-rw-r--r--regress/misc/fuzz-harness/testdata/id_rsa27
-rw-r--r--regress/misc/fuzz-harness/testdata/id_rsa-cert.pub1
-rw-r--r--regress/misc/fuzz-harness/testdata/id_rsa.pub1
-rw-r--r--regress/misc/kexfuzz/Makefile101
-rw-r--r--regress/misc/kexfuzz/README34
-rw-r--r--regress/misc/kexfuzz/kexfuzz.c453
-rw-r--r--regress/misc/sk-dummy/fatal.c11
-rw-r--r--regress/misc/sk-dummy/sk-dummy.c7
-rw-r--r--regress/multipubkey.sh19
-rw-r--r--regress/netcat.c3
-rw-r--r--regress/percent.sh4
-rw-r--r--regress/reconfigure.sh24
-rw-r--r--regress/rekey.sh8
-rw-r--r--regress/scp-uri.sh81
-rw-r--r--regress/scp.sh187
-rw-r--r--regress/scp3.sh60
-rw-r--r--regress/servcfginclude.sh8
-rw-r--r--regress/sftp-perm.sh18
-rwxr-xr-xregress/ssh2putty.sh8
-rw-r--r--regress/sshcfgparse.sh39
-rw-r--r--regress/sshfp-connect.sh66
-rw-r--r--regress/sshsig.sh52
-rw-r--r--regress/test-exec.sh153
-rw-r--r--regress/unittests/authopt/Makefile4
-rw-r--r--regress/unittests/authopt/tests.c10
-rw-r--r--regress/unittests/conversion/Makefile3
-rw-r--r--regress/unittests/conversion/tests.c34
-rw-r--r--regress/unittests/hostkeys/Makefile4
-rw-r--r--regress/unittests/hostkeys/test_iterate.c91
-rw-r--r--regress/unittests/kex/Makefile8
-rw-r--r--regress/unittests/kex/test_kex.c6
-rw-r--r--regress/unittests/match/Makefile4
-rw-r--r--regress/unittests/misc/Makefile23
-rw-r--r--regress/unittests/misc/test_argv.c187
-rw-r--r--regress/unittests/misc/test_convtime.c59
-rw-r--r--regress/unittests/misc/test_expand.c90
-rw-r--r--regress/unittests/misc/test_parse.c86
-rw-r--r--regress/unittests/misc/test_strdelim.c202
-rw-r--r--regress/unittests/misc/tests.c157
-rw-r--r--regress/unittests/sshbuf/Makefile3
-rw-r--r--regress/unittests/sshkey/Makefile4
-rw-r--r--regress/unittests/sshsig/Makefile4
-rw-r--r--regress/unittests/sshsig/webauthn.html80
-rwxr-xr-xregress/valgrind-unit.sh2
-rw-r--r--sandbox-pledge.c8
-rw-r--r--sandbox-rlimit.c18
-rw-r--r--sandbox-seccomp-filter.c18
-rw-r--r--scp.062
-rw-r--r--scp.163
-rw-r--r--scp.c521
-rw-r--r--servconf.c806
-rw-r--r--servconf.h27
-rw-r--r--serverloop.c199
-rw-r--r--session.c167
-rw-r--r--sftp-client.c1098
-rw-r--r--sftp-client.h61
-rw-r--r--sftp-common.c4
-rw-r--r--sftp-server.020
-rw-r--r--sftp-server.812
-rw-r--r--sftp-server.c370
-rw-r--r--sftp.029
-rw-r--r--sftp.137
-rw-r--r--sftp.c118
-rw-r--r--sk-api.h4
-rw-r--r--sk-usbhid.c20
-rw-r--r--sntrup4591761.c1083
-rw-r--r--sntrup4591761.sh57
-rw-r--r--sntrup761.c1273
-rw-r--r--sntrup761.sh85
-rw-r--r--srclimit.c140
-rw-r--r--srclimit.h18
-rw-r--r--ssh-add.02
-rw-r--r--ssh-add.c44
-rw-r--r--ssh-agent.02
-rw-r--r--ssh-agent.13
-rw-r--r--ssh-agent.c605
-rw-r--r--ssh-ed25519-sk.c5
-rw-r--r--ssh-ed25519.c5
-rw-r--r--ssh-gss.h4
-rw-r--r--ssh-keygen.065
-rw-r--r--ssh-keygen.149
-rw-r--r--ssh-keygen.c410
-rw-r--r--ssh-keyscan.02
-rw-r--r--ssh-keyscan.c26
-rw-r--r--ssh-keysign.02
-rw-r--r--ssh-keysign.c55
-rw-r--r--ssh-pkcs11-client.c53
-rw-r--r--ssh-pkcs11-helper.02
-rw-r--r--ssh-pkcs11-helper.c76
-rw-r--r--ssh-pkcs11.c114
-rw-r--r--ssh-sk-client.c83
-rw-r--r--ssh-sk-helper.02
-rw-r--r--ssh-sk-helper.c47
-rw-r--r--ssh-sk.c98
-rw-r--r--ssh-xmss.c9
-rw-r--r--ssh.066
-rw-r--r--ssh.153
-rw-r--r--ssh.c538
-rw-r--r--ssh2.h4
-rw-r--r--ssh_api.c37
-rw-r--r--ssh_config.0268
-rw-r--r--ssh_config.5342
-rw-r--r--sshbuf-misc.c4
-rw-r--r--sshconnect.c565
-rw-r--r--sshconnect.h47
-rw-r--r--sshconnect2.c401
-rw-r--r--sshd.053
-rw-r--r--sshd.855
-rw-r--r--sshd.c303
-rw-r--r--sshd_config10
-rw-r--r--sshd_config.0169
-rw-r--r--sshd_config.5161
-rw-r--r--sshkey-xmss.c55
-rw-r--r--sshkey-xmss.h16
-rw-r--r--sshkey.c138
-rw-r--r--sshkey.h21
-rw-r--r--sshlogin.c4
-rw-r--r--sshpty.c1
-rw-r--r--sshsig.c228
-rw-r--r--sshsig.h6
-rw-r--r--ttymodes.c44
-rw-r--r--uidswap.c2
-rw-r--r--umac.c4
-rw-r--r--utf8.h10
-rw-r--r--version.h4
-rw-r--r--xmalloc.h7
311 files changed, 22621 insertions, 14570 deletions
diff --git a/.depend b/.depend
index f05bd9d74..a94a82d0e 100644
--- a/.depend
+++ b/.depend
@@ -2,179 +2,182 @@
# Run "make depend" to rebuild.
# DO NOT DELETE
-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-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/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.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/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.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/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.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/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.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/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.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/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.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 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/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.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/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.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/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.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 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-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 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/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.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/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.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/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.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 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 authfile.h
-auth.o: 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/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.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 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-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/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.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 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 pathnames.h
-auth2-hostbased.o: 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/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.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 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/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.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 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/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.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 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: canohost.h monitor_wrap.h authfile.h match.h ssherr.h channels.h session.h sk-api.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-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 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 auth-options.h
+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-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 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 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-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/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.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/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.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/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.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 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/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.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/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.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 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-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/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.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-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-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-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-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/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.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/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.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/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.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/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.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 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 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/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.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 compat.h log.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-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/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.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/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.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/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.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 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/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.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/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.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/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.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/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.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/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.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/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.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/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.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/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.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/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.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/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.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: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/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-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
-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-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/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.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 pathnames.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/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.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.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 match.h
-kex.o: misc.h monitor.h ssherr.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-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 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-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/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.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
-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-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 kex.h mac.h crypto_api.h log.h packet.h openbsd-compat/sys-queue.h dispatch.h ssh2.h sshbuf.h digest.h ssherr.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-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/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.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/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.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
-kexsntrup4591761x25519.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/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-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 kex.h mac.h crypto_api.h sshbuf.h digest.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-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 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-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/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.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 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/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.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/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.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/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.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/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.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/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.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/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.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: 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 misc.h servconf.h monitor.h monitor_wrap.h monitor_fdpass.h compat.h ssh2.h authfd.h match.h ssherr.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-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_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-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/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.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 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 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/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.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/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.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 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/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.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 channels.h compat.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/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.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 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 canohost.h misc.h channels.h ssh.h
-packet.o: packet.h dispatch.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/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.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/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.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/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.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/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.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 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-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/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.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 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-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 crypto_api.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-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/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.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/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.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/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.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/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.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/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.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/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.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/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.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/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.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/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.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/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.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/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.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/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.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 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
-servconf.o: mac.h crypto_api.h match.h channels.h groupaccess.h canohost.h packet.h dispatch.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/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.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 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 cipher-aesctr.h
-serverloop.o: 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 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/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.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 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
+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-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/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.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/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.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-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-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
-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-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/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.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/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.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
-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-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
-sntrup4591761.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/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-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
-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-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 log.h sshkey.h sshbuf.h authfd.h authfile.h pathnames.h misc.h ssherr.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-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 sshkey.h authfd.h compat.h log.h misc.h digest.h ssherr.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-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-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-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 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-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-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-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 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-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/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.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 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 sshsig.h ssh-sk.h sk-api.h
-ssh-keyscan.o: atomicio.h misc.h hostfile.h ssherr.h ssh_api.h ssh2.h dns.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-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 crypto_api.h compat.h myproposal.h packet.h dispatch.h log.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-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/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.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/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.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/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.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 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-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-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-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 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-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 authfd.h misc.h sshbuf.h msg.h uidswap.h ssherr.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-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/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.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/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.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 packet.h dispatch.h sshbuf.h channels.h
-ssh.o: sshkey.h authfd.h authfile.h pathnames.h clientloop.h log.h misc.h readconf.h sshconnect.h kex.h mac.h crypto_api.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/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.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 crypto_api.h ssh.h ssh2.h packet.h dispatch.h compat.h log.h authfile.h misc.h
-ssh_api.o: version.h myproposal.h ssherr.h sshbuf.h openbsd-compat/openssl-compat.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-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/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.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-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-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 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-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/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.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
+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-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 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 ssherr.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-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 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 misc.h readconf.h match.h canohost.h msg.h pathnames.h uidswap.h hostfile.h ssherr.h utf8.h ssh-sk.h sk-api.h
-sshd.o: 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 ssherr.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-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 log.h sshbuf.h misc.h match.h servconf.h uidswap.h compat.h cipher.h cipher-chachapoly.h chacha.h poly1305.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/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.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/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.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 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-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 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-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
-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-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 authfd.h authfile.h log.h misc.h sshbuf.h sshsig.h ssherr.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-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/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.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 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/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.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/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.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/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.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/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.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
-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-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/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.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/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.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/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.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/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.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/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.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/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.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/.github/ci-status.md b/.github/ci-status.md
new file mode 100644
index 000000000..0ad8bf5aa
--- /dev/null
+++ b/.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/.github/configs b/.github/configs
new file mode 100755
index 000000000..12578c067
--- /dev/null
+++ b/.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/.github/configure.sh b/.github/configure.sh
new file mode 100755
index 000000000..e098730f0
--- /dev/null
+++ b/.github/configure.sh
@@ -0,0 +1,6 @@
+#!/bin/sh
+
+. .github/configs $1
+
+set -x
+./configure ${CONFIGFLAGS}
diff --git a/.github/run_test.sh b/.github/run_test.sh
index 93c3a5e9e..adf2568ad 100755
--- a/.github/run_test.sh
+++ b/.github/run_test.sh
@@ -1,34 +1,34 @@
-#!/usr/bin/env bash
+#!/bin/sh
-TARGETS=$@
+. .github/configs $1
-TEST_TARGET="tests"
-LTESTS="" # all tests by default
+[ -z "${SUDO}" ] || ${SUDO} mkdir -p /var/empty
set -ex
-for TARGET in $TARGETS; do
- case $TARGET in
- --without-openssl)
- # When built without OpenSSL we can't do the file-based RSA key tests.
- TEST_TARGET=t-exec
- ;;
- esac
-done
+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
- result=$?
+if [ -z "${LTESTS}" ]; then
+ make ${TEST_TARGET} SKIP_LTESTS="${SKIP_LTESTS}"
else
- make $TEST_TARGET LTESTS="$LTESTS"
- result=$?
+ make ${TEST_TARGET} SKIP_LTESTS="${SKIP_LTESTS}" LTESTS="${LTESTS}"
fi
-if [ "$result" -ne "0" ]; then
- for i in regress/failed*; do
- echo -------------------------------------------------------------------------
- echo LOGFILE $i
- cat $i
- echo -------------------------------------------------------------------------
- done
+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/.github/setup_ci.sh b/.github/setup_ci.sh
index e2474ccd7..70a444e4e 100755
--- a/.github/setup_ci.sh
+++ b/.github/setup_ci.sh
@@ -1,4 +1,11 @@
-#!/usr/bin/env bash
+#!/bin/sh
+
+case $(./config.guess) in
+*-darwin*)
+ brew install automake
+ exit 0
+ ;;
+esac
TARGETS=$@
@@ -11,35 +18,65 @@ set -ex
lsb_release -a
+if [ "${TARGETS}" = "kitchensink" ]; then
+ TARGETS="kerberos5 libedit pam sk selinux"
+fi
+
for TARGET in $TARGETS; do
case $TARGET in
- ""|--without-openssl|--without-zlib)
+ default|without-openssl|without-zlib|c89)
# nothing to do
;;
- "--with-kerberos5")
+ kerberos5)
PACKAGES="$PACKAGES heimdal-dev"
#PACKAGES="$PACKAGES libkrb5-dev"
;;
- "--with-libedit")
+ libedit)
PACKAGES="$PACKAGES libedit-dev"
;;
- "--with-pam")
+ *pam)
PACKAGES="$PACKAGES libpam0g-dev"
;;
- "--with-security-key-builtin")
+ sk)
INSTALL_FIDO_PPA="yes"
- PACKAGES="$PACKAGES libfido2-dev libu2f-host-dev"
+ PACKAGES="$PACKAGES libfido2-dev libu2f-host-dev libcbor-dev"
;;
- "--with-selinux")
+ selinux)
PACKAGES="$PACKAGES libselinux1-dev selinux-policy-dev"
;;
- *) echo "Invalid option"
+ 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
+if [ "yes" = "$INSTALL_FIDO_PPA" ]; then
sudo apt update -qq
sudo apt install software-properties-common
sudo apt-add-repository ppa:yubico/stable
@@ -49,3 +86,30 @@ 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/.github/workflows/c-cpp.yml b/.github/workflows/c-cpp.yml
index 2189756bb..289b18b7f 100644
--- a/.github/workflows/c-cpp.yml
+++ b/.github/workflows/c-cpp.yml
@@ -7,22 +7,49 @@ on:
branches: [ master ]
jobs:
- build:
-
- runs-on: ubuntu-latest
-
+ ci:
+ if: github.repository != 'openssh/openssh-portable-selfhosted'
strategy:
+ fail-fast: false
matrix:
- configs:
- - ""
- - "--with-kerberos5"
- - "--with-libedit"
- - "--with-pam"
- - "--with-security-key-builtin"
- - "--with-selinux"
- - "--with-kerberos5 --with-libedit --with-pam --with-security-key-builtin --with-selinux"
- - "--without-openssl --without-zlib"
-
+ # 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
@@ -30,10 +57,20 @@ jobs:
- name: autoreconf
run: autoreconf
- name: configure
- run: ./configure ${{ matrix.configs }}
+ run: ./.github/configure.sh ${{ matrix.configs }}
- name: make
- run: 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/.github/workflows/selfhosted.yml b/.github/workflows/selfhosted.yml
new file mode 100644
index 000000000..df6eca714
--- /dev/null
+++ b/.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/.github/workflows/upstream.yml b/.github/workflows/upstream.yml
new file mode 100644
index 000000000..f0493c12d
--- /dev/null
+++ b/.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/.skipped-commit-ids b/.skipped-commit-ids
index 6abbb99bc..1de781722 100644
--- a/.skipped-commit-ids
+++ b/.skipped-commit-ids
@@ -21,6 +21,8 @@ d9b910e412d139141b072a905e66714870c38ac0 Makefile.inc
3bcae7a754db3fc5ad3cab63dd46774edb35b8ae moduli regen script update
52ff0e3205036147b2499889353ac082e505ea54 moduli update
07b5031e9f49f2b69ac5e85b8da4fc9e393992a0 Makefile.inc
+cc12a9029833d222043aecd252d654965c351a69 moduli-gen Makefile
+7ac6c252d2a5be8fbad4c66d9d35db507c9dac5b moduli update
Old upstream tree:
diff --git a/ChangeLog b/ChangeLog
index bcaa38f94..288e90bbf 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,5667 @@
+commit e1a596186c81e65a34ce13076449712d3bf97eb4
+Author: Damien Miller <djm@mindrot.org>
+Date: Fri Aug 20 14:03:49 2021 +1000
+
+ 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
+
+ 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.
+
+ Spotted by djm@.
+
+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
+
+ 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.
+
+ 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 464ba22f1e38d25402e5ec79a9b8d34a32df5a3f
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Wed Aug 18 12:51:30 2021 +1000
+
+ Check compiler for c99 declarations after code.
+
+ 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 7d878679a4b155a359d32104ff473f789501748d
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Tue Aug 17 15:12:04 2021 +1000
+
+ 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.
+
+ From Tom G. Christensen.
+
+commit 6a24567a29bd7b4ab64e1afad859ea845cbc6b8c
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Mon Aug 16 14:13:02 2021 +1000
+
+ Improve github test driver script.
+
+ - 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 b467cf13705f59ed348b620722ac098fe31879b7
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Mon Aug 16 11:32:23 2021 +1000
+
+ Remove deprecated ubuntu-16.04 test targets.
+
+ Github has deprecated ubuntu-16.04 and it will be removed on 20
+ September.
+
+commit 20e6eefcdf78394f05e453d456c1212ffaa6b6a4
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Sun Aug 15 23:25:26 2021 +1000
+
+ Skip agent ptrace test on hurd.
+
+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.
+
+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
+
+ 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 Aug 12 23:59:25 2021 +0000
+
+ upstream: mention that CASignatureAlgorithms accepts +/- similarly to
+
+ the other algorithm list directives; ok jmc bz#3335
+
+ OpenBSD-Commit-ID: 0d46b53995817052c78e2dce9dbd133963b073d9
+
+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
+
+commit e1371e4f58404d6411d9f95eb774b444cea06a26
+Author: naddy@openbsd.org <naddy@openbsd.org>
+Date: Wed Aug 11 14:07:54 2021 +0000
+
+ 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
+
+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
+
+ 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 2a2cd00783e1da45ee730b7f453408af1358ef5b
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Wed Aug 11 08:55:04 2021 +0000
+
+ upstream: test -Oprint-pubkey
+
+ OpenBSD-Regress-ID: 3d51afb6d1f287975fb6fddd7a2c00a3bc5094e0
+
+commit b9f4635ea5bc33ed5ebbacf332d79bae463b0f54
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Wed Aug 11 08:54:17 2021 +0000
+
+ upstream: when verifying sshsig signatures, support an option
+
+ (-Oprint-pubkey) to dump the full public key to stdout; based on patch from
+ Fabian Stelzer; ok markus@
+
+ OpenBSD-Commit-ID: 0598000e5b9adfb45d42afa76ff80daaa12fc3e2
+
+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
+
+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
+
+ debuggings past. prompted by Michael Forney, ok dtucker@
+
+ OpenBSD-Commit-ID: 4853a0d6c9cecaba9ecfcc19066e52d3a8dcb2ac
+
+commit 419aa01123db5ff5dbc68b2376ef23b222862338
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Wed Aug 11 09:21:09 2021 +1000
+
+ Add includes.h to compat tests.
+
+ 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 931f592f26239154eea3eb35a086585897b1a185
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Tue Aug 10 03:35:45 2021 +0000
+
+ upstream: adapt to scp -M flag change; make scp3.sh test SFTP mode too
+
+ OpenBSD-Regress-ID: 43fea26704a0f0b962b53c1fabcb68179638f9c0
+
+commit 391ca67fb978252c48d20c910553f803f988bd37
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Tue Aug 10 03:33:34 2021 +0000
+
+ upstream: Prepare for a future where scp(1) uses the SFTP protocol by
+
+ 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!).
+
+ prompted by/feedback from deraadt@
+
+ OpenBSD-Commit-ID: 92ad72cc6f0023c9be9e316d8b30eb6d8d749cfc
+
+commit bfdd4b722f124a4fa9173d20dd64dd0fc69856be
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Mon Aug 9 23:56:36 2021 +0000
+
+ 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.
+
+ thanks naddy@ for catching the missing argument in usage()
+
+ "Yes please!" - markus@
+ "makes a lot of sense" - deraadt@
+ "the right thing to do" - dtucker@
+
+ OpenBSD-Commit-ID: d0d2af5f0965c5192ba5b2fa461c9f9b130e5dd9
+
+commit 2f7a3b51cef689ad9e93d0c6c17db5a194eb5555
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Mon Aug 9 23:49:31 2021 +0000
+
+ 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.
+
+ prompted by and much discussion deraadt@
+ ok markus@
+
+ 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
+
+ ~-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: 7d794def9e4de348e1e777f6030fc9bafdfff392
+
+commit 41b019ac067f1d1f7d99914d0ffee4d2a547c3d8
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Mon Aug 9 23:44:32 2021 +0000
+
+ upstream: when scp is in SFTP mode, try to deal better with ~
+
+ prefixed paths. ~user paths aren't supported, but ~/ paths will be accepted
+ and prefixed with the SFTP server starting directory (more to come)
+
+ prompted by and discussed with deraadt@
+ ok markus@
+
+ OpenBSD-Commit-ID: 263a071f14555c045fd03132a8fb6cbd983df00d
+
+commit b4b3f3da6cdceb3fd168b5fab69d11fba73bd0ae
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Mon Aug 9 07:21:01 2021 +0000
+
+ upstream: on fatal errors, make scp wait for ssh connection before
+
+ exiting avoids LogLevel=verbose (or greater) messages from ssh appearing
+ after scp has returned exited and control has returned to the shell; ok
+ markus@
+
+ (this was originally committed as r1.223 along with unrelated stuff that
+ I rolled back in r1.224)
+
+ OpenBSD-Commit-ID: 1261fd667ad918484889ed3d7aec074f3956a74b
+
+commit 2ae7771749e0b4cecb107f9d4860bec16c3f4245
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Mon Aug 9 07:19:12 2021 +0000
+
+ upstream: rever r1.223 - I accidentally committed unrelated changes
+
+ OpenBSD-Commit-ID: fb73f3865b2647a27dd94db73d6589506a9625f9
+
+commit 986abe94d481a1e82a01747360bd767b96b41eda
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Mon Aug 9 07:16:09 2021 +0000
+
+ upstream: show only the final path component in the progress meter;
+
+ more useful with long paths (that may truncate) and better matches
+ traditional scp behaviour; spotted by naddy@ ok deraadt@
+
+ OpenBSD-Commit-ID: 26b544d0074f03ebb8a3ebce42317d8d7ee291a3
+
+commit 2b67932bb3176dee4fd447af4368789e04a82b93
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Mon Aug 9 07:13:54 2021 +0000
+
+ upstream: on fatal errors, make scp wait for ssh connection before
+
+ 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: ef9dab5ef5ae54a6a4c3b15d380568e94263456c
+
+commit 724eb900ace30661d45db2ba01d0f924d95ecccb
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Sun Aug 8 08:49:09 2021 +0000
+
+ upstream: xstrdup environment variable used by ForwardAgent. bz#3328
+
+ from goetze at dovetail.com, ok djm@ deraadt@
+
+ OpenBSD-Commit-ID: 760320dac1c3b26904284ba417a7d63fccc5e742
+
+commit 86b4cb3a884846b358305aad17a6ef53045fa41f
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Sun Aug 8 08:27:28 2021 +0000
+
+ upstream: Although it's POSIX, not all shells used in Portable support
+
+ the implicit 'in "$@"' after 'for i'.
+
+ OpenBSD-Regress-ID: 3c9aec6bca4868f85d2742b6ba5223fce110bdbc
+
+commit f2ccf6c9f395923695f22345e626dfd691227aaf
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Sun Aug 8 17:39:56 2021 +1000
+
+ 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 71b0eb997e220b0fc9331635af409ad84979f2af
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Sun Aug 8 07:27:52 2021 +0000
+
+ upstream: Move setting of USER further down the startup In portable
+
+ we have to change this and having it in the same hunk as the CVS Id string
+ means applying changes fails every. single. time.
+
+ 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.
+
+ 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: 1c1598bb5237a7ae0be99152f185e0071163714d
+
+commit 85de69f64665245786e28c81ab01fe18b0e2a149
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Sat Aug 7 01:55:01 2021 +0000
+
+ upstream: sftp-client.c needs poll.h
+
+ remove unused variable
+
+ 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 a9e2c533195f28627f205682482d9da384c4c52e
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Sat Aug 7 00:14:17 2021 +0000
+
+ upstream: do_upload() used a near-identical structure for
+
+ tracking expected status replies from the server to what do_download() was
+ using.
+
+ Refactor it to use the same structure and factor out some common
+ code into helper functions.
+
+ OpenBSD-Commit-ID: 0c167df8ab6df4a5292c32421922b0cf379e9054
+
+commit 7b1cbcb7599d9f6a3bbad79d412604aa1203b5ee
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Sat Aug 7 00:12:09 2021 +0000
+
+ upstream: make scp(1) in SFTP mode follow symlinks like
+
+ traditional scp(1) ok markus@
+
+ 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
+
+ transfers; ok markus@
+
+ OpenBSD-Commit-ID: 64b2abaa5635a2be65ee2e77688ad9bcebf576c2
+
+commit 98b59244ca10e62ff67a420856770cb700164f59
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Sat Aug 7 00:09:57 2021 +0000
+
+ upstream: a bit more debugging of file attributes being
+
+ sent/received over the wire
+
+ OpenBSD-Commit-ID: f68c4e207b08ef95200a8b2de499d422808e089b
+
+commit c677e65365d6f460c084e41e0c4807bb8a9cf601
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Sat Aug 7 00:08:52 2021 +0000
+
+ 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 48cd39b7a4e5e7c25101c6d1179f98fe544835cd
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Sat Aug 7 00:07:18 2021 +0000
+
+ upstream: factor out a structure duplicated between downloading
+
+ and crossloading; ok markus@
+
+ OpenBSD-Commit-ID: 96eede24d520569232086a129febe342e4765d39
+
+commit 318c06bb04ee21a0cfa6b6022a201eacaa53f388
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Sat Aug 7 00:06:30 2021 +0000
+
+ upstream: use sftp_client crossloading to implement scp -3
+
+ feedback/ok markus@
+
+ 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.
+
+ downloading from one SFTP server while simultaneously uploading to another.
+
+ feedback & ok markus@
+
+ OpenBSD-Commit-ID: 3982878e29d8df0fa4ddc502f5ff6126ac714235
+
+commit a50bd0367ff2063bbc70a387740a2aa6914de094
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Sat Aug 7 00:01:29 2021 +0000
+
+ upstream: factor our SSH2_FXP_OPEN calls into their own function;
+
+ "looks fine" markus@
+
+ OpenBSD-Commit-ID: d3dea2153f08855c6d9dacc01973248944adeffb
+
+commit e3c0ba05873cf3d3f7d19d595667a251026b2d84
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Sat Aug 7 00:00:33 2021 +0000
+
+ upstream: prepare for scp -3 implemented via sftp
+
+ 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.
+
+ 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-Regress-ID: 0e2ec8594556a6f369ed5a0a90c6806419b845f7
+
+commit d247a73ce27b460138599648d9c637c6f2b77605
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Wed Aug 4 21:28:00 2021 +0000
+
+ upstream: regression test for scp -3
+
+ OpenBSD-Regress-ID: b44375d125c827754a1f722ec6b6b75b634de05d
+
+commit 35c8e41a6f6d8ad76f8d1cd81ac2ea23d0d993b2
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Fri Aug 6 05:04:42 2021 +0000
+
+ upstream: Document "ProxyJump none". bz#3334.
+
+ OpenBSD-Commit-ID: f78cc6f55731f2cd35c3a41d5352ac1ee419eba7
+
+commit 911ec6411821bda535d09778df7503b92f0eafab
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Wed Aug 4 01:34:55 2021 +0000
+
+ 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.
+
+ Pinpointed by the -portable Valgrind regress test. ok djm@ deraadt@
+
+ OpenBSD-Commit-ID: 750f3c19bd4440e4210e30dd5d7367386e833374
+
+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: Tue Aug 3 01:05:24 2021 +0000
+
+ upstream: regression tests for scp SFTP protocol support; mostly by
+
+ Jakub Jelen in GHPR#194 ok markus
+
+ OpenBSD-Regress-ID: 36f1458525bcb111741ec8547eaf58b13cddc715
+
+commit e4673b7f67ae7740131a4ecea29a846593049a91
+Author: anton@openbsd.org <anton@openbsd.org>
+Date: Thu Jul 29 15:34:09 2021 +0000
+
+ upstream: Treat doas with arguments as a valid SUDO variable.
+
+ Allows one to specify SUDO="doas -n" which I do while running make regress.
+
+ ok dtucker@
+
+ OpenBSD-Regress-ID: 4fe5814b5010dbf0885500d703bea06048d11005
+
+commit 197e29f1cca190d767c4b2b63a662f9a9e5da0b3
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Mon Aug 2 23:38:27 2021 +0000
+
+ upstream: support for using the SFTP protocol for file transfers in
+
+ scp, via a new "-M sftp" option. Marked as experimental for now.
+
+ 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: 6ce4c9157ff17b650ace571c9f7793d92874051c
+
+commit dd533c7ab79d61a7796b77b64bd81b098e0d7f9f
+Author: jmc@openbsd.org <jmc@openbsd.org>
+Date: Fri Jul 30 14:28:13 2021 +0000
+
+ upstream: fix a formatting error and add some Xr; from debian at
+
+ helgefjell de
+
+ removed references to rlogin etc. as no longer relevant;
+ suggested by djm
+
+ ok djm dtucker
+
+ OpenBSD-Commit-ID: 3c431c303068d3aec5bb18573a0bd5e0cd77c5ae
+
+commit c7cd347a8823819411222c1e10a0d26747d0fd5c
+Author: jmc@openbsd.org <jmc@openbsd.org>
+Date: Fri Jul 30 14:25:01 2021 +0000
+
+ upstream: fix a formatting error and mark up known_hosts
+
+ consistently; issues reported by debian at helgefjell de
+
+ ok djm dtucker
+
+ OpenBSD-Commit-ID: a1fd8d21dc77f507685443832df0c9700481b0ce
+
+commit 4455aec2e4fc90f64ae4fc47e78ebc9c18721738
+Author: jmc@openbsd.org <jmc@openbsd.org>
+Date: Wed Jul 28 05:57:42 2021 +0000
+
+ upstream: no need to talk about version 2 with the -Q option, so
+
+ rewrite the text to read better;
+
+ issue reported by debian at helgefjell de
+ ok djm dtucker
+
+ OpenBSD-Commit-ID: 59fe2e8219c37906740ad062e0fdaea487dbe9cf
+
+commit bec429338e9b30d2c7668060e82608286a8a4777
+Author: jmc@openbsd.org <jmc@openbsd.org>
+Date: Tue Jul 27 14:28:46 2021 +0000
+
+ upstream: word fix; reported by debian at helgefjell de
+
+ 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
+
+ ok dtucker djm
+
+ OpenBSD-Commit-ID: 7ac15575045d82f4b205a42cc7d5207fe4c3f8e6
+
+commit 1e11fb24066f3fc259ee30db3dbb2a3127e05956
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Mon Aug 2 18:56:29 2021 +1000
+
+ Check for RLIMIT_NOFILE before trying to use it.
+
+commit 0f494236b49fb48c1ef33669f14822ca4f3ce2f4
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Tue Jul 27 17:45:34 2021 +1000
+
+ lastenv is only used in setenv.
+
+ Prevents an unused variable warning on platforms that have setenv but
+ not unsetenv.
+
+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
+
+ 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
+
+ we're building with OPENSSL=no.
+
+ 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-Regress-ID: 2d788fade3264d7803e5b54cae8875963f688c4e
+
+commit 55e17101a9075f6a63af724261c5744809dcb95c
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Sat Jul 24 02:57:28 2021 +0000
+
+ upstream: Skip RFC4716 format import and export tests when built
+
+ without OpenSSL.
+
+ OpenBSD-Regress-ID: d2c2d5d38c1acc2b88cc99cfe00a2eb8bb39dfa4
+
+commit f5ccb5895d39cd627ad9e7b2c671d2587616100d
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Sat Jul 24 02:51:14 2021 +0000
+
+ upstream: Don't omit ssh-keygen -y from usage when built without
+
+ OpenSSL. It is actually available, albeit only for ed25519 keys.
+
+ 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
+
+ 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: 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 9d38074b5453c1abbdf888e80828c278d3b886ac
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Sat Jul 24 01:54:23 2021 +0000
+
+ upstream: test for first-match-wins in authorized_keys environment=
+
+ options
+
+ OpenBSD-Regress-ID: 1517c90276fe84b5dc5821c59f88877fcc34c0e8
+
+commit 2b76f1dd19787e784711ea297ad8fc938b4484fd
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Fri Jul 23 05:53:02 2021 +0000
+
+ upstream: Simplify keygen-convert by using $SSH_KEYTYPES directly.
+
+ OpenBSD-Regress-ID: cdbe408ec3671ea9ee9b55651ee551370d2a4108
+
+commit 7d64a9fb587ba9592f027f7a2264226c713d6579
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Sat Jul 24 01:55:19 2021 +0000
+
+ upstream: don't leak environment= variable when it is not the first
+
+ match
+
+ 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: 64be152e378c45975073ab1c07e0db7eddd15806
+
+commit 03190d10980c6fc9124e988cb2df13101f266507
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Fri Jul 23 05:56:47 2021 +0000
+
+ upstream: mention in comment that read_passphrase(..., RP_ALLOW_STDIN)
+
+ will try to use askpass first. bz3314
+
+ convert a couple of debug() -> debug_f() while here
+
+ OpenBSD-Commit-ID: c7e812aebc28fcc5db06d4710e0f73613dee545c
+
+commit 1653ece6832b2b304d46866b262d5f69880a9ec7
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Fri Jul 23 05:07:16 2021 +0000
+
+ upstream: Test conversion of ed25519 and ecdsa keys too.
+
+ OpenBSD-Regress-ID: 3676d2d00e58e0d6d37f2878f108cc2b83bbe4bb
+
+commit 8b7af02dcf9d2b738787efd27da7ffda9859bed2
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Fri Jul 23 04:56:21 2021 +0000
+
+ upstream: Add test for exporting pubkey from a passphrase-protected
+
+ private key.
+
+ OpenBSD-Regress-ID: da99d93e7b235fbd5b5aaa01efc411225e6ba8ac
+
+commit 441095d4a3e5048fe3c87a6c5db5bc3383d767fb
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Fri Jul 23 03:54:55 2021 +0000
+
+ upstream: regression test for time-limited signature keys
+
+ OpenBSD-Regress-ID: 2a6f3bd900dbee0a3c96f1ff23e032c93ab392bc
+
+commit 9e1882ef6489a7dd16b6d7794af96629cae61a53
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Fri Jul 23 05:24:02 2021 +0000
+
+ upstream: note successful authentication method in final "Authenticated
+
+ to ..." message and partial auth success messages (all at LogLevel=verbose)
+ ok dtucker@
+
+ OpenBSD-Commit-ID: 06834b89ceb89f8f16c5321d368a66c08f441984
+
+commit a917e973a1b90b40ff1e950df083364b48fc6c78
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Fri Jul 23 04:04:52 2021 +0000
+
+ upstream: Add a ForkAfterAuthentication ssh_config(5) counterpart
+
+ to the ssh(1) -f flag. Last part of GHPR231 from Volker Diels-Grabsch. ok
+ dtucker
+
+ OpenBSD-Commit-ID: b18aeda12efdebe2093d55263c90fe4ea0bce0d3
+
+commit e0c5088f1c96a145eb6ea1dee438010da78f9ef5
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Fri Jul 23 04:00:59 2021 +0000
+
+ 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 e3957e21ffdc119d6d04c0b1686f8e2fe052f5ea
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Fri Jul 23 03:57:20 2021 +0000
+
+ upstream: make authorized_keys environment="..." directives
+
+ first-match-wins and more strictly limit their maximum number; prompted by
+ OOM reported by OSS-fuzz (35470).
+
+ feedback and ok dtucker@
+
+ OpenBSD-Commit-ID: 01f63fc10dcd995e7aed9c378ad879161af83121
+
+commit d0bb1ce731762c55acb95817df4d5fab526c7ecd
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Fri Jul 23 03:37:52 2021 +0000
+
+ upstream: Let allowed signers files used by ssh-keygen(1)
+
+ 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-Commit-ID: 3e2c67b7dcd94f0610194d1e8e4907829a40cf31
+
+commit 44142068dc7ef783d135e91ff954e754d2ed432e
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Mon Jul 19 08:48:33 2021 +0000
+
+ upstream: Use SUDO when setting up hostkey.
+
+ OpenBSD-Regress-ID: 990cf4481cab8dad62e90818a9b4b36c533851a7
+
+commit 6b67f3f1d1d187597e54a139cc7785c0acebd9a2
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Mon Jul 19 05:08:54 2021 +0000
+
+ upstream: Increase time margin for rekey tests. Should help
+
+ reliability on very heavily loaded hosts.
+
+ OpenBSD-Regress-ID: 4c28a0fce3ea89ebde441d7091464176e9730533
+
+commit 7953e1bfce9e76bec41c1331a29bc6cff9d416b8
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Mon Jul 19 13:47:51 2021 +1000
+
+ Add sshfp-connect.sh file missed in previous.
+
+commit b75a80fa8369864916d4c93a50576155cad4df03
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Mon Jul 19 03:13:28 2021 +0000
+
+ upstream: Ensure that all returned SSHFP records for the specified host
+
+ 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 1cc1fd095393663cd72ddac927d82c6384c622ba
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Mon Jul 19 02:21:50 2021 +0000
+
+ upstream: Id sync only, -portable already has this.
+
+ Put dh_set_moduli_file call inside ifdef WITH_OPENSSL. Fixes
+ build with OPENSSL=no.
+
+ 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-Regress-ID: c52c461bd1df3a803d17498917d156ef64512fd9
+
+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
+
+commit 0075511e27e5394faa28edca02bfbf13b9a6693e
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Mon Jul 19 00:16:26 2021 +0000
+
+ upstream: Group keygen tests together.
+
+ 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-Regress-ID: fde9566b56eeb980e149bbe157a884838507c46b
+
+commit 52c3b6985ef1d5dadb4c4fe212f8b3a78ca96812
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Sat Jul 17 00:38:11 2021 +0000
+
+ upstream: wrap some long lines
+
+ 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
+
+ SessionType change; spotted by sthen@
+
+ OpenBSD-Commit-ID: 4c5ddc5698790ae6ff50d2a4f8f832f0eeeaa234
+
+commit 073f45c236550f158c9a94003e4611c07dea5279
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Fri Jul 16 09:00:23 2021 +0000
+
+ upstream: Explicitly check for and start time-based rekeying in the
+
+ client and server mainloops.
+
+ 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: 4356cf50d7900f3df0a8f2117d9e07c91b9ff987
+
+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: Tue Jul 13 23:48:36 2021 +0000
+
+ upstream: add a SessionType directive to ssh_config, allowing the
+
+ configuration file to offer equivalent control to the -N (no session) and -s
+ (subsystem) command-line flags.
+
+ Part of GHPR#231 by Volker Diels-Grabsch with some minor tweaks;
+ feedback and ok dtucker@
+
+ OpenBSD-Commit-ID: 726ee931dd4c5cc7f1d7a187b26f41257f9a2d12
+
+commit 7ae69f2628e338ba6e0eae7ee8a63bcf8fea7538
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Mon Jul 12 02:12:22 2021 +0000
+
+ upstream: fix some broken tests; clean up output
+
+ 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.
+
+ 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: 835936f6837c86504b07cabb596b613600cf0f6e
+
+commit 6c29b387cd64a57b0ec8ae7d2c8d02789d88fcc3
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Mon Jul 12 06:08:57 2021 +0000
+
+ upstream: Use existing format_absolute_time() function when
+
+ printing cert validity instead of doing it inline. Part of bz#3329.
+
+ OpenBSD-Commit-ID: a13d4e3c4f59644c23745eb02a09b2a4e717c00c
+
+commit 99981d5f8bfa383791afea03f6bce8454e96e323
+Author: djm@openbsd.org <djm@openbsd.org>
+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: Fix a couple of whitespace things. Portable already has
+
+ these so this removes two diffs between the two.
+
+ 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: 8bd7452d809b199c19bfc49511a798f414eb4a77
+
+commit b75624f8733b3ed9e240f86cac5d4a39dae11848
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Mon Jul 5 00:50:25 2021 +0000
+
+ upstream: Remove comment referencing now-removed
+
+ RhostsRSAAuthentication. ok 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,
+
+ and scp -3 remote to remote copies. with & ok dtucker bz#1164
+
+ OpenBSD-Commit-ID: e9b550f3a85ffbb079b6720833da31317901d6dd
+
+commit 8c4ef0943e574f614fc7c6c7e427fd81ee64ab87
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Fri Jul 2 07:20:44 2021 +0000
+
+ upstream: Remove obsolete comments about SSHv1 auth methods. ok
+
+ djm@
+
+ OpenBSD-Commit-ID: 6060f70966f362d8eb4bec3da2f6c4712fbfb98f
+
+commit 88908c9b61bcb99f16e8d398fc41e2b3b4be2003
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Sat Jul 3 23:00:19 2021 +1000
+
+ Remove reference to ChallengeResponse.
+
+ challenge_response_authentication was removed from the struct, keeping
+ kbd_interactive_authentication.
+
+commit 321874416d610ad2158ce6112f094a4862c2e37f
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Sat Jul 3 20:38:09 2021 +1000
+
+ Move signal.h up include order to match upstream.
+
+commit 4fa83e2d0e32c2dd758653e0359984bbf1334f32
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Sat Jul 3 20:36:06 2021 +1000
+
+ Remove old OpenBSD version marker.
+
+ Looks like an accidental leftover from a sync.
+
+commit 9d5e31f55d5f3899b72645bac41a932d298ad73b
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Sat Jul 3 20:34:19 2021 +1000
+
+ Remove duplicate error on error path.
+
+ There's an extra error() call on the listen error path, it looks like
+ its removal was missed during an upstream sync.
+
+commit 888c459925c7478ce22ff206c9ac1fb812a40caf
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Sat Jul 3 20:32:46 2021 +1000
+
+ Remove some whitespace not in upstream.
+
+ Reduces diff vs OpenBSD by a small amount.
+
+commit 4d2d4d47a18d93f3e0a91a241a6fdb545bbf7dc2
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Sat Jul 3 19:27:43 2021 +1000
+
+ Replace remaining references to ChallengeResponse.
+
+ Portable had a few additional references to ChallengeResponse related to
+ UsePAM, replaces these with equivalent keyboard-interactive ones.
+
+commit 53237ac789183946dac6dcb8838bc3b6b9b43be1
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Sat Jul 3 19:23:28 2021 +1000
+
+ Sync remaining ChallengeResponse removal.
+
+ These were omitted from commit 88868fd131.
+
+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
+
+ Remove now-unused SSHv1 enums.
+
+ sRhostsRSAAuthentication and sRSAAuthentication are protocol 1 options
+ and are no longer used.
+
+commit c73b02d92d72458a5312bd098f32ce88868fd131
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Fri Jul 2 05:11:20 2021 +0000
+
+ upstream: Remove references to ChallengeResponseAuthentication in
+
+ 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.
+
+ 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: 2c1bff8e5c9852cfcdab1f3ea94dfef5a22f3b7e
+
+commit f841fc9c8c7568a3b5d84a4cc0cefacb7dbc16b9
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Fri Jul 2 15:20:32 2021 +1000
+
+ 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 0767627cf66574484b9c0834500b42ea04fe528a
+Author: Damien Miller <djm@mindrot.org>
+Date: Fri Jul 2 14:30:23 2021 +1000
+
+ wrap get_random_bytes_prngd() in ifdef
+
+ avoid unused static function warning
+
+commit f93fdc4de158386efe1116bd44c5b3f4a7a82c25
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Mon Jun 28 13:06:37 2021 +1000
+
+ Add rocky84 test target.
+
+commit d443006c0ddfa7f6a5bd9c0ae92036f3d5f2fa3b
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Fri Jun 25 06:30:22 2021 +0000
+
+ upstream: fix decoding of X.509 subject name; from Leif Thuresson
+
+ via bz3327 ok markus@
+
+ 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
+
+ via github PR#250, ok jmc@
+
+ OpenBSD-Commit-ID: 07ca3526626996613e128aeddf7748c93c4d6bbf
+
+commit 4bdf7a04797a0ea1c431a9d54588417c29177d19
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Fri Jun 25 03:38:17 2021 +0000
+
+ 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.
+
+ Based on other changes for bz#2158, ok djm@
+
+ OpenBSD-Commit-ID: 202c85de0b3bdf1744fe53529a05404c5480d813
+
+commit c9f7bba2e6f70b7ac1f5ea190d890cb5162ce127
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Fri Jun 25 15:08:18 2021 +1000
+
+ 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.
+
+ 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.
+
+ When built --without-openssl, try EGD/PRGGD (if configured) as a last
+ resort before failing.
+
+commit e43a898043faa3a965dbaa1193cc60e0b479033d
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Fri Jun 18 18:32:51 2021 +1000
+
+ Split EGD/PRNGD interface into its own file.
+
+ 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.
+
+ 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 31fac20c941126281b527605b73bff30a8f02edd
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Thu Jun 10 09:46:28 2021 +0000
+
+ upstream: Use $SUDO when reading sshd's pidfile here too.
+
+ OpenBSD-Regress-ID: 6bfb0d455d493f24839034a629c5306f84dbd409
+
+commit a3a58acffc8cc527f8fc6729486d34e4c3d27643
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Thu Jun 10 09:43:51 2021 +0000
+
+ upstream: Use $SUDO when reading sshd's pidfile in case it was
+
+ created with a very restrictive umask. This resyncs with -portable.
+
+ OpenBSD-Regress-ID: 07fd2af06df759d4f64b82c59094accca1076a5d
+
+commit 249ad4ae51cd3bc235e75a4846eccdf8b1416611
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Thu Jun 10 09:37:59 2021 +0000
+
+ upstream: Set umask when creating hostkeys to prevent excessive
+
+ permissions warning.
+
+ OpenBSD-Regress-ID: 382841db0ee28dfef7f7bffbd511803e1b8ab0ef
+
+commit 9d0892153c005cc65897e9372b01fa66fcbe2842
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Thu Jun 10 03:45:31 2021 +0000
+
+ upstream: Add regress test for SIGHUP restart
+
+ while handling active and unauthenticated clients. Should catch anything
+ similar to the pselect bug just fixed in sshd.c.
+
+ OpenBSD-Regress-ID: 3b3c19b5e75e43af1ebcb9586875b3ae3a4cac73
+
+commit 73f6f191f44440ca3049b9d3c8e5401d10b55097
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Thu Jun 10 03:14:14 2021 +0000
+
+ upstream: Continue accept loop when pselect
+
+ 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 c785c0ae134a8e8b5c82b2193f64c632a98159e4
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Tue Jun 8 22:30:27 2021 +0000
+
+ upstream: test that UserKnownHostsFile correctly accepts multiple
+
+ arguments; would have caught readconf.c r1.356 regression
+
+ 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
+
+ accepted multiple string arguments, ssh was only recording the first.
+ Reported by Lucas via bugs@
+
+ OpenBSD-Commit-ID: 7cbf182f7449bf1cb7c5b4452667dc2b41170d6d
+
+commit 78e30af3e2b2dd540a341cc827c6b98dd8b0a6de
+Author: djm@openbsd.org <djm@openbsd.org>
+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: Add testcases from bz#3319 for IPQoS and TunnelDevice
+
+ being overridden on the command line.
+
+ OpenBSD-Regress-ID: 801674d5d2d02abd58274a78cab2711f11de14a8
+
+commit 660cea10b2cdc11f13ba99c89b1bbb368a4d9ff2
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Tue Jun 8 06:52:43 2021 +0000
+
+ upstream: sprinkle some "# comment" at end of configuration lines
+
+ to test comment handling
+
+ OpenBSD-Regress-ID: cb82fbf40bda5c257a9f742c63b1798e5a8fdda7
+
+commit acc9c32dcb6def6c7d3688bceb4c0e59bd26b411
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Tue Jun 8 06:51:47 2021 +0000
+
+ upstream: more descriptive failure message
+
+ OpenBSD-Regress-ID: 5300f6faf1d9e99c0cd10827b51756c5510e3509
+
+commit ce04dd4eae23d1c9cf7c424a702f48ee78573bc1
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Mon Jun 7 01:16:34 2021 +0000
+
+ upstream: test AuthenticationMethods inside a Match block as well
+
+ as in the main config section
+
+ OpenBSD-Regress-ID: ebe0a686621b7cb8bb003ac520975279c28747f7
+
+commit 9018bd821fca17e26e92f7a7e51d9b24cd62f2db
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Mon Jun 7 00:00:50 2021 +0000
+
+ upstream: prepare for stricter sshd_config parsing that will refuse
+
+ 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 a10f929d1ce80640129fc5b6bc1acd9bf689169e
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Tue Jun 8 07:09:42 2021 +0000
+
+ 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.
+
+ feedback and ok markus@
+
+ tested in snaps for the last five or so days - thanks Theo and those who
+ caught bugs
+
+ OpenBSD-Commit-ID: 9c4305631d20c2d194661504ce11e1f68b20d93e
+
+commit ea9e45c89a4822d74a9d97fef8480707d584da4d
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Tue Jun 8 07:07:15 2021 +0000
+
+ upstream: Switch ssh_config parsing to use argv_split()
+
+ 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@
+
+ tested in snaps for the last five or so days - thanks Theo and those who
+ caught bugs
+
+ OpenBSD-Commit-ID: dc72fd12af9d5398f4d9e159d671f9269c5b14d5
+
+commit d786424986c04d1d375f231fda177c8408e05c3e
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Tue Jun 8 07:02:46 2021 +0000
+
+ upstream: Check if IPQoS or TunnelDevice are already set before
+
+ overriding. Prevents values in config files from overriding values supplied
+ on the command line. bz#3319, ok markus.
+
+ OpenBSD-Commit-ID: f3b08b898c324debb9195e6865d8999406938f74
+
+commit aae4b4d3585b9f944d7dbd3c9e5ba0006c55e457
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Tue Jun 8 06:54:40 2021 +0000
+
+ upstream: Allow argv_split() to optionally terminate tokenisation
+
+ when it encounters an unquoted comment.
+
+ Add some additional utility function for working with argument
+ vectors, since we'll be switching to using them to parse
+ ssh/sshd_config shortly.
+
+ ok markus@ as part of a larger diff; tested in snaps
+
+ OpenBSD-Commit-ID: fd9c108cef2f713f24e3bc5848861d221bb3a1ac
+
+commit da9f9acaac5bab95dca642b48e0c8182b246ab69
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Mon Jun 7 19:19:23 2021 +1000
+
+ Save logs on failure for upstream test
+
+commit 76883c60161e5f3808787085a27a8c37f8cc4e08
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Mon Jun 7 14:36:32 2021 +1000
+
+ 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
+
+ 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: d5af3be66d0f22c371dc1fe6195e774a18b2327b
+
+commit 530739d42f6102668aecd699be0ce59815c1eceb
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Sun Jun 6 11:34:16 2021 +0000
+
+ 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: 25f5bf70003126d19162862d9eb380bf34bac22a
+
+commit 4265215d7300901fd7097061c7517688ade82f8e
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Sun Jun 6 03:40:39 2021 +0000
+
+ 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.
+
+ Reported by and based on patch from Gordon Messmer via bz3213, thanks
+ also for additional analysis by Jakub Jelen. ok dtucker
+
+ OpenBSD-Commit-ID: d6d0b7351d5d44c45f3daaa26efac65847a564f7
+
+commit bda270d7fb8522d43c21a79a4b02a052d7c64de8
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Sun Jun 6 03:17:02 2021 +0000
+
+ upstream: degrade gracefully if a sftp-server offers the
+
+ limits@openssh.com extension but fails when the client tries to invoke it.
+ Reported by Hector Martin via bz3318
+
+ OpenBSD-Commit-ID: bd9d1839c41811616ede4da467e25746fcd9b967
+
+commit d345d5811afdc2d6923019b653cdd93c4cc95f76
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Sun Jun 6 03:15:39 2021 +0000
+
+ upstream: the limits@openssh.com extension was incorrectly marked
+
+ as an operation that writes to the filesystem, which made it unavailable in
+ sftp-server read-only mode. Spotted by Hector Martin via bz3318
+
+ 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
+
+ Also fix some typos.
+ ok djm@
+
+ OpenBSD-Commit-ID: 5e855b6c5a22b5b13f8ffa3897a868e40d349b44
+
+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
+
+ Add pselect implementation for platforms without.
+
+ 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.
+
+ 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 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 Jun 4 06:19:07 2021 +0000
+
+ upstream: The RB_GENERATE_STATIC(3) macro expands to a series of
+
+ function definitions and not a statement, so there should be no semicolon
+ following them. Patch from Michael Forney
+
+ OpenBSD-Commit-ID: c975dd180580f0bdc0a4d5b7d41ab1f5e9b7bedd
+
+commit c298c4da574ab92df2f051561aeb3e106b0ec954
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Fri Jun 4 05:59:18 2021 +0000
+
+ upstream: rework authorized_keys example section, removing irrelevant
+
+ stuff, de-wrapping the example lines and better aligning the examples with
+ common usage and FAQs; ok jmc
+
+ OpenBSD-Commit-ID: d59f1c9281f828148e2a2e49eb9629266803b75c
+
+commit d9cb35bbec5f623589d7c58fc094817b33030f35
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Fri Jun 4 05:10:03 2021 +0000
+
+ upstream: adjust SetEnv description to clarify $TERM handling
+
+ OpenBSD-Commit-ID: 8b8cc0124856bc1094949d55615e5c44390bcb22
+
+commit 771f57a8626709f2ad207058efd68fbf30d31553
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Fri Jun 4 05:09:08 2021 +0000
+
+ 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.
+
+ 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 f64f8c00d158acc1359b8a096835849b23aa2e86
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Fri Jun 4 05:02:40 2021 +0000
+
+ 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@
+
+ OpenBSD-Commit-ID: 38b1ef4d5bc159c7d9d589d05e3017433e2d5758
+
+commit 60107677dc0ce1e93c61f23c433ad54687fcd9f5
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Fri Jun 4 04:02:21 2021 +0000
+
+ upstream: correct extension name "no-presence-required" =>
+
+ "no-touch-required"
+
+ document "verify-required" option
+
+ 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.
+
+ 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 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 Jun 2 00:17:45 2021 +0000
+
+ upstream: Merge back shell portability changes
+
+ bringing it back in sync with -portable.
+
+ OpenBSD-Regress-ID: c07905ba931e66ad7d849b87b7d19648007175d1
+
+commit 9d482295c9f073e84d75af46b720a1c0f7ec2867
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Tue Jun 1 23:56:20 2021 +0000
+
+ upstream: Use a default value for $OPENSSL,
+
+ 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-Regress-ID: c49dcd6aa7602a8606b7afa192196ca1fa65de16
+
+commit 07660b3c99f8ea74ddf4a440e55c16c9f7fb3dd1
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Mon May 24 10:25:18 2021 +0000
+
+ upstream: Find openssl binary via environment variable. This
+
+ allows overriding if necessary (eg in -portable where we're testing against a
+ specific version of OpenSSL).
+
+ OpenBSD-Regress-ID: 491f39cae9e762c71aa4bf045803d077139815c5
+
+commit 1a4d1da9188d7c88f646b61f0d6a3b34f47c5439
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Fri May 21 04:03:47 2021 +0000
+
+ upstream: fix memleak in test
+
+ 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-Regress-ID: d526fa07253f4eebbc7d6205a0ab3d491ec71a28
+
+commit 39f6cd207851d7b67ca46903bfce4a9f615b5b1c
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Fri May 21 03:48:07 2021 +0000
+
+ upstream: unit test for misc.c:strdelim() that mostly servces to
+
+ highlight its inconsistencies
+
+ 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 59a194825f12fff8a7f75d91bf751ea17645711b
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Mon May 31 06:48:42 2021 +0000
+
+ upstream: Hash challenge supplied by client during FIDO key enrollment
+
+ 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 eb68e669bc8ab968d4cca5bf1357baca7136a826
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Thu May 27 21:14:15 2021 +1000
+
+ Include login_cap.h for login_getpwclass override.
+
+ On minix3, login_getpwclass is __RENAME'ed to __login_getpwclass50 so
+ without this the include overriding login_getpwclass causes a compile
+ error.
+
+commit 2063af71422501b65c7a92a5e14c0e6a3799ed89
+Author: Darren Tucker <dtucker@dtucker.net>
+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
+
+ 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 078a0e60c92700da4c536c93c007257828ccd05b
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Tue May 25 11:40:47 2021 +1000
+
+ Rename README.md to ci-status.md.
+
+ 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 7be4ac813662f68e89f23c50de058a49aa32f7e4
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Wed May 19 01:24:05 2021 +0000
+
+ 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
+
+ This restores the blocking status for fds 0,1,2 (stdio) before ssh(1)
+ abandons/closes them.
+
+ This was reported as bz3280 and GHPR246; ok dtucker@
+
+ OpenBSD-Commit-ID: 8cc67346f05aa85a598bddf2383fcfcc3aae61ce
+
+commit c4902e1a653c67fea850ec99c7537f358904c0af
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Mon May 17 11:43:16 2021 +0000
+
+ upstream: fix breakage of -W forwaring introduced in 1.554; reported by
+
+ naddy@ and sthen@, ok sthen@
+
+ OpenBSD-Commit-ID: f72558e643a26dc4150cff6e5097b5502f6c85fd
+
+commit afea01381ad1fcea1543b133040f75f7542257e6
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Mon May 17 07:22:45 2021 +0000
+
+ upstream: Regenerate moduli.
+
+ OpenBSD-Commit-ID: 83c93a2a07c584c347ac6114d6329b18ce515557
+
+commit be2866d6207b090615ff083c9ef212b603816a56
+Author: Damien Miller <djm@mindrot.org>
+Date: Mon May 17 09:40:23 2021 +1000
+
+ Handle Android libc returning NULL pw->pw_passwd
+
+ Reported by Luke Dashjr
+
+commit 5953c143008259d87342fb5155bd0b8835ba88e5
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Fri May 14 05:20:32 2021 +0000
+
+ upstream: fix previous: test saved no_shell_flag, not the one that just
+
+ got clobbered
+
+ OpenBSD-Commit-ID: b8deace085d9d941b2d02f810243b9c302e5355d
+
+commit 1e9fa55f4dc4b334651d569d3448aaa3841f736f
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Fri May 14 03:09:48 2021 +0000
+
+ 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 d1320c492f655d8f5baef8c93899d79dded217a5
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Wed May 12 11:34:30 2021 +0000
+
+ 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 d3cc4d650ce3e59f3e370b101778b0e8f1c02c4d
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Fri May 7 04:11:51 2021 +0000
+
+ upstream: include pid in LogVerbose spam
+
+ OpenBSD-Commit-ID: aacb86f96ee90c7cb84ec27452374285f89a7f00
+
+commit e3c032333be5fdbbaf2751f6f478e044922b4ec4
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Fri May 7 03:09:38 2021 +0000
+
+ upstream: don't sigdie() in signal handler in privsep child process;
+
+ this can end up causing sandbox violations per bz3286; ok dtucker@
+
+ OpenBSD-Commit-ID: a7f40b2141dca4287920da68ede812bff7ccfdda
+
+commit a4039724a3f2abac810735fc95cf9114a3856049
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Fri May 7 09:23:40 2021 +0000
+
+ upstream: Increase ConnectionAttempts from 4 to 10 as the tests
+
+ occasionally time out on heavily loaded hosts.
+
+ OpenBSD-Regress-ID: 29a8cdef354fc9da471a301f7f65184770434f3a
+
+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
+
+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
+
+ verbatim and not as strings (i.e. no 4-byte length header)
+
+ OpenBSD-Commit-ID: 3606b5d443d72118c5b76c4af6dd87a5d5a4f837
+
+commit f43859159cc62396ad5d080f0b1f2635a67dac02
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Tue May 4 22:53:52 2021 +0000
+
+ upstream: Don't pass NULL as a string in debugging as it does not work
+
+ 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
+
+ upstream: more debugging for UpdateHostKeys signature failures
+
+ OpenBSD-Commit-ID: 1ee95f03875e1725df15d5e4bea3e73493d57d36
+
+commit 8e32e97e788e0676ce83018a742203614df6a2b3
+Author: Darren Tucker <dtucker@dtucker.net>
+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
+
+ upstream: a little debugging in the main mux process for status
+
+ confirmation failures in multiplexed sessions
+
+ OpenBSD-Commit-ID: 6e27b87c95176107597035424e1439c3232bcb49
+
+commit e65cf00da6bc31e5f54603b7feb7252dc018c033
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Fri Apr 30 04:02:52 2021 +0000
+
+ upstream: Remove now-unused skey function prototypes leftover from
+
+ skey removal.
+
+ OpenBSD-Commit-ID: 2fc36d519fd37c6f10ce74854c628561555a94c3
+
+commit ae5f9b0d5c8126214244ee6b35aae29c21028133
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Thu Apr 29 13:01:50 2021 +1000
+
+ Wrap sntrup761x25519 inside ifdef.
+
+ From balu.gajjala at gmail.com via bz#3306.
+
+commit 70a8dc138a6480f85065cdb239915ad4b7f928cf
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Wed Apr 28 14:44:07 2021 +1000
+
+ Add status badges for Actions-based tests.
+
+commit 40b59024cc3365815381474cdf4fe423102e391b
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Wed Apr 28 12:22:11 2021 +1000
+
+ Add obsdsnap (OpenBSD snapshot) test target.
+
+commit e627067ec8ef9ae8e7a638f4dbac91d52dee3e6d
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Wed Apr 28 11:35:28 2021 +1000
+
+ 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.
+
+ 1.1.0g requires a perl glob module that's not installed by default.
+
+commit 9bc20efd39ce8525be33df3ee009f5a4564224f1
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Tue Apr 27 12:37:59 2021 +1000
+
+ Use the default VM type for libcrypto ver tests.
+
+commit 9f79e80dc40965c2e73164531250b83b176c1eea
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Tue Apr 27 12:24:10 2021 +1000
+
+ Always build OpenSSL shared.
+
+ 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.
+
+ 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.
+
+ Add tests against various LibreSSL and OpenSSL versions.
+
+commit b16082aa110fa7128ece2a9037ff420c4a285317
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Mon Apr 26 13:35:44 2021 +1000
+
+ Add fbsd10 test target.
+
+commit 2c805f16b24ea37cc051c6018fcb05defab6e57a
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Sun Apr 25 14:15:02 2021 +1000
+
+ Disable compiler hardening on nbsd4.
+
+ The system compiler supports -fstack-protector-all, but using it will
+ result in an internal compiler error on some files.
+
+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.
+
+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.
+
+ 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 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: Fri Apr 16 03:42:00 2021 +0000
+
+ upstream: openssh-8.6
+
+ OpenBSD-Commit-ID: b5f3e133c846127ec114812248bc17eff07c3e19
+
+commit faf2b86a46c9281d237bcdec18c99e94a4eb820a
+Author: markus@openbsd.org <markus@openbsd.org>
+Date: Thu Apr 15 16:24:31 2021 +0000
+
+ upstream: do not pass file/func to monitor; noted by Ilja van Sprundel;
+
+ ok djm@
+
+ OpenBSD-Commit-ID: 85ae5c063845c410283cbdce685515dcd19479fa
+
+commit 2dc328023f60212cd29504fc05d849133ae47355
+Author: Damien Miller <djm@mindrot.org>
+Date: Wed Apr 14 11:42:55 2021 +1000
+
+ sshd don't exit on transient read errors
+
+ 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 d5d6b7d76d171a2e6861609dcd92e714ee62ad88
+Author: Damien Miller <djm@mindrot.org>
+Date: Sat Apr 10 18:45:00 2021 +1000
+
+ 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
+
+ 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.
+
+ 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 bfa5405da05d906ffd58216eb77c4375b62d64c2
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Thu Apr 8 15:18:15 2021 +1000
+
+ Ensure valgrind-out exists.
+
+ Normally the regress tests would create it, but running the unit tests
+ on their own would fail because the directory did not exist.
+
+commit 1f189181f3ea09a9b08aa866f78843fec800874f
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Thu Apr 8 15:17:19 2021 +1000
+
+ Pass OBJ to unit test make invocation.
+
+ At least the Valgrind unit tests uses $OBJ.
+
+commit f42b550c281d28bd19e9dd6ce65069164f3482b0
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Thu Apr 8 14:20:12 2021 +1000
+
+ Add pattern for valgrind-unit.
+
+commit 19e534462710e98737478fd9c44768b50c27c4c6
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Thu Apr 8 13:31:08 2021 +1000
+
+ Run unit tests under valgrind.
+
+ 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 80032102d05e866dc2a48a5caf760cf42c2e090e
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Thu Apr 8 13:25:57 2021 +1000
+
+ ifdef out MIN and MAX.
+
+ 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 d1bd184046bc310c405f45da3614a1dc5b3e521a
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Wed Apr 7 10:23:51 2021 +1000
+
+ Remove only use of warn().
+
+ 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 fea8f4b1aa85026ad5aee5ad8e1599a8d5141fe0
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Wed Apr 7 10:18:32 2021 +1000
+
+ Move make_tmpdir() into portable-specific area.
+
+ Reduces diff vs OpenBSD and makes it more likely diffs will apply
+ cleanly.
+
+commit 13e5fa2acffd26e754c6ee1d070d0afd035d4cb7
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Tue Apr 6 23:57:56 2021 +0000
+
+ upstream: Add TEST_SSH_ELAPSED_TIMES environment variable to print the
+
+ 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 ef4f46ab4387bb863b471bad124d46e8d911a79a
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Wed Apr 7 09:59:15 2021 +1000
+
+ Move the TEST_SSH_PORT section down a bit.
+
+ 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.
+
+ 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
+
+ bz#3292
+
+ 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
+
+ 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.
+
+ 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
+
+ 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: 31cec6bf26c6db4ffefc8a070715ebef274e68ea
+
+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
+
+ enable authopt and misc unit tests
+
+ 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
+
+ =?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: 93c732381ae0e2b680c79e67c40c1814b7ceed2c
+
+commit 53ea05e09b04fd7b6dea66b42b34d65fe61b9636
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Sat Apr 3 06:55:52 2021 +0000
+
+ upstream: sync CASignatureAlgorithms lists with reality. GHPR#174 from
+
+ Matt Hazinski
+
+ OpenBSD-Commit-ID: f05e4ca54d7e67b90fe58fe1bdb1d2a37e0e2696
+
+commit 57ed647ee07bb883a2f2264231bcd1df6a5b9392
+Author: Damien Miller <djm@mindrot.org>
+Date: Sat Apr 3 17:47:37 2021 +1100
+
+ polish whitespace for portable files
+
+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
+
+ and bad indentation on continuation lines. Prompted by GHPR#185
+
+ OpenBSD-Commit-ID: e5c81f0cbdcc6144df1ce468ec1bac366d8ad6e9
+
+commit 34afde5c73b5570d6f8cce9b49993b23b77bfb86
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Sat Apr 3 05:54:14 2021 +0000
+
+ upstream: whitespace (tab after space)
+
+ OpenBSD-Commit-ID: 0e2b3f7674e985d3f7c27ff5028e690ba1c2efd4
+
+commit 7cd262c1c5a08cc7f4f30e3cab108ef089d0a57b
+Author: Darren Tucker <dtucker@dtucker.net>
+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
+
+ upstream: fix incorrect plural; from Ville Skyt
+
+ =?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 082804c14e548cada75c81003a3c68ee098138ee
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Sat Apr 3 05:40:39 2021 +0000
+
+ 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.
+
+ From Adithya Baglody via GHPR#234; ok markus
+
+ OpenBSD-Commit-ID: f8e770e03b416ee9a58f9762e162add900f832b6
+
+commit 464ebc82aa926dd132ec75a0b064574ef375675e
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Sat Apr 3 05:28:43 2021 +0000
+
+ upstream: unused variable
+
+ 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
+
+ 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-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 4cbc4a722873d9b68cb5496304dc050d7168df78
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Wed Mar 31 21:59:26 2021 +0000
+
+ upstream: cannot effectively test posix-rename extension after
+
+ changes in feature advertisment.
+
+ OpenBSD-Regress-ID: 5e390bf88d379162aaa81b60ed86b34cb0c54d29
+
+commit 259d648e63e82ade4fe2c2c73c8b67fe57d9d049
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Fri Mar 19 04:23:50 2021 +0000
+
+ upstream: add a test for misc.c:argv_split(), currently fails
+
+ 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
+
+ client select good limits based on what the server supports. Split the
+ download and upload buffer sizes to allow them to be chosen independently.
+
+ In practice (and assuming upgraded sftp/sftp-server at each end), this
+ increases the download buffer 32->64KiB and the upload buffer
+ 32->255KiB.
+
+ Patches from Mike Frysinger; ok dtucker@
+
+ OpenBSD-Commit-ID: ebd61c80d85b951b794164acc4b2f2fd8e88606c
+
+commit 6653c61202d104e59c8e741329fcc567f7bc36b8
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Wed Mar 31 21:58:07 2021 +0000
+
+ upstream: do not advertise protocol extensions that have been
+
+ disallowed by the command-line options (e.g. -p/-P/-R); ok dtucker@
+
+ OpenBSD-Commit-ID: 3a8a76b3f5131741aca4b41bfab8d101c9926205
+
+commit 71241fc05db4bbb11bb29340b44b92e2575373d8
+Author: Damien Miller <djm@mindrot.org>
+Date: Mon Mar 29 15:14:25 2021 +1100
+
+ gnome-ssh-askpass3 is a valid target here
+
+commit 8a9520836e71830f4fccca066dba73fea3d16bda
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Fri Mar 19 02:22:34 2021 +0000
+
+ upstream: return non-zero exit status when killed by signal; bz#3281 ok
+
+ dtucker@
+
+ OpenBSD-Commit-ID: 117b31cf3c807993077b596bd730c24da9e9b816
+
+commit 1269b8a686bf1254b03cd38af78167a04aa6ec88
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Fri Mar 19 02:18:28 2021 +0000
+
+ 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: 4e67d60d81bde7b84a742b4ee5a34001bdf80d9c
+
+commit 860b67604416640e8db14f365adc3f840aebcb1f
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Tue Mar 16 06:15:43 2021 +0000
+
+ upstream: don't let logging clobber errno before use
+
+ OpenBSD-Commit-ID: ce6cca370005c270c277c51c111bb6911e1680ec
+
+commit 5ca8a9216559349c56e09039c4335636fd85c241
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Sat Mar 13 14:40:43 2021 +1100
+
+ Only call dh_set_moduli_file if using OpenSSL.
+
+ 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.
+
+ 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.
+
+ 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
+
+ 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
+
+ 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: 8df99d60b14ecaaa28f3469d01fc7f56bff49f66
+
+commit f07519a2af96109325b5a48b1af18b57601074ca
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Fri Mar 12 03:43:40 2021 +0000
+
+ upstream: pwcopy() struct passwd that we're going to reuse across a
+
+ bunch of library calls; bz3273 ok dtucker@
+
+ 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: 7ac6c252d2a5be8fbad4c66d9d35db507c9dac5b
+
+commit e5895e8ecfac65086ea6b34d0d168409a66a15e1
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Wed Mar 10 04:58:45 2021 +0000
+
+ upstream: no need to reset buffer after send_msg() as that is done
+
+ for us; patch from Mike Frysinger
+
+ OpenBSD-Commit-ID: 565516495ff8362a38231e0f1a087b8ae66da59c
+
+commit 721948e67488767df0fa0db71ff2578ee2bb9210
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Sat Mar 13 01:52:16 2021 +0000
+
+ upstream: Add TEST_SSH_MODULI_FILE variable to allow overriding of the
+
+ moduli file used during the test run.
+
+ OpenBSD-Regress-ID: be10f785263120edb64fc87db0e0d6570a10220a
+
+commit 82fef71e20ffef425b932bec26f5bc46aa1ed41c
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Fri Mar 12 15:58:57 2021 +1100
+
+ Allow (but return EACCES) fstatat64 in sandbox.
+
+ This is apparently used in some configurations of OpenSSL when glibc
+ has getrandom(). bz#3276, patch from Kris Karas, ok djm@
+
+commit 1cd67ee15ce3d192ab51be22bc4872a6a7a4b6d9
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Fri Mar 12 13:16:10 2021 +1100
+
+ Move generic includes outside of ifdef.
+
+ 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 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: Wed Mar 3 22:41:49 2021 +0000
+
+ upstream: don't sshbuf_get_u32() into an enum; reported by goetze
+
+ AT dovetail.com via bz3269
+
+ OpenBSD-Commit-ID: 99a30a8f1df9bd72be54e21eee5c56a0f050921a
+
+commit cffd033817a5aa388764b6661855dcdaabab0588
+Author: sthen@openbsd.org <sthen@openbsd.org>
+Date: Wed Mar 3 21:40:16 2021 +0000
+
+ upstream: typo in other_hostkeys_message() display output, ok djm
+
+ OpenBSD-Commit-ID: 276f58afc97b6f5826e0be58380b737603dbf5f5
+
+commit 7fe141b96b13bd7dc67ca985e14d55b9bd8a03fd
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Wed Mar 3 08:42:52 2021 +0000
+
+ upstream: needs FILE*; from Mike Frysinger
+
+ 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
+
+ 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 Mar 2 01:48:18 2021 +0000
+
+ upstream: openssh-8.5
+
+ 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
+
+ =?UTF-8?q?=20Eero=20H=C3=A4kkinenvia=20bz#3267?=
+ MIME-Version: 1.0
+ Content-Type: text/plain; charset=UTF-8
+ Content-Transfer-Encoding: 8bit
+
+ 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
+
+ subprocess. Prevents spurious debug message. ok djm@
+
+ 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
+
+ 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.
+
+ Some very minor fixes, missing 's' and punctuation.
+
+commit 6248b86074804983e8f7a2058856a516dbfe2924
+Author: Damien Miller <djm@mindrot.org>
+Date: Fri Feb 26 16:45:50 2021 +1100
+
+ Revert "ssh: optional bind interface if bind address specified."
+
+ This reverts commit 5a878a71a3528c2626aa1d331934fd964782d41c.
+
+ Apologies - I accidentally pushed this.
+
+commit 493339a940b13be6071629c3c2dd5a3b6fc17023
+Author: Damien Miller <djm@mindrot.org>
+Date: Fri Feb 26 15:45:38 2021 +1100
+
+ detech BSD libc hash functions in libbsd / libmd
+
+ 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 5a878a71a3528c2626aa1d331934fd964782d41c
+Author: Dmitrii Turlupov <dturlupov@factor-ts.ru>
+Date: Thu Feb 4 16:27:31 2021 +0300
+
+ ssh: optional bind interface if bind address specified.
+
+ Allows the -b and -B options to be used together.
+ For example, when the interface is in the VRF.
+
+commit 1fe4d70df94d3bcc2b35fd57cad6b5fc4b2d7b16
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Fri Feb 26 04:18:42 2021 +0000
+
+ 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.
+
+ 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.
+
+ These are failing apparently due to some kind of infrastructure problem,
+ making it look like every commit is busted.
+
+commit 473201783f732ca8b0ec528b56aa55fa0d8cf717
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Fri Feb 26 00:16:58 2021 +0000
+
+ upstream: a bit more debugging behind #ifdef DEBUG_SK
+
+ 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.
+
+ 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
+
+ SSH-Copy-ID-Upstream: 78178aa5017222773e4c23d9001391eeaeca8983
+
+commit 983e05ef3b81329d76d6a802b39ad0d1f637c06c
+Author: Jakub Jelen <jjelen@redhat.com>
+Date: Tue Sep 29 10:02:45 2020 +0000
+
+ if unable to add a missing newline, fail
+
+ 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
+
+ since that was a change made since jjelen's commit was written
+
+ also, quote the variables
+
+ SSH-Copy-ID-Upstream: 588cd8e5cbf95f3443d92b9ab27c5d73ceaf6616
+
+commit 333e25f7bc43cee6e36f766e39dad6f9918b318c
+Author: Jakub Jelen <jjelen@redhat.com>
+Date: Tue Sep 29 10:00:01 2020 +0000
+
+ restorecon the correct directory
+
+ if using different path for authorized_keys file
+
+ SSH-Copy-ID-Upstream: 791a3df47b48412c726bff6f7b1d190721e65d51
+
+commit 9beeab8a37a49a9e3ffb1972fff6621ee5bd7a71
+Author: djm@openbsd.org <djm@openbsd.org>
+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: Rename pubkeyacceptedkeytypes to pubkeyacceptedalgorithms in
+
+ test to match change to config-dump output.
+
+ OpenBSD-Regress-ID: 74c9a4ad50306be873d032819d5e55c24eb74d5d
+
+commit b9225c3a1c3f5827e31d5d64a71b8e0504a25619
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Wed Feb 24 01:18:08 2021 +0000
+
+ 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: Tue Feb 23 21:55:08 2021 +0000
+
+ upstream: lots more s/key types/signature algorithms/ mostly in
+
+ HostbasedAcceptedAlgorithms and HostKeyAlgorithms; prompted by Jakub Jelen
+
+ OpenBSD-Commit-ID: 3f719de4385b1a89e4323b2549c66aae050129cb
+
+commit 0aeb508aaabc4818970c90831e3d21843c3c6d09
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Tue Feb 23 21:50:18 2021 +0000
+
+ upstream: Correct reference to signature algorithms as keys; from
+
+ Jakub Jelen
+
+ OpenBSD-Commit-ID: 36f7ecee86fc811aa0f8e21e7a872eee044b4be5
+
+commit f186a020f2ba5f9c462a23293750e29ba0a746b1
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Tue Feb 23 16:05:22 2021 +1100
+
+ Add a couple more test VMs.
+
+commit ffcdd3d90e74176b3bb22937ad1f65a6c1cd3f9d
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Mon Feb 22 08:09:27 2021 +1100
+
+ Valgrind test: split and move up list.
+
+ 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 c3b1636770785cc2830dedd0f22ef7d3d3491d6d
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Tue Feb 23 00:05:31 2021 +0000
+
+ upstream: warn when the user specifies a ForwardAgent path that does
+
+ not exist and exit if ExitOnForwardFailure is set; bz3264
+
+ OpenBSD-Commit-ID: 72f7875865e723e464c71bf8692e83110699bf26
+
+commit 5fcb0514949d61aadaf4a89cf16eb78fb47491ec
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Sat Feb 20 13:34:02 2021 +1100
+
+ Disable rlimit sandbox, doesn't work with valgrind
+
+ 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.
+
+ Should make it easier to share code or maybe merge at some point.
+
+commit 76c0be0fe0465cb2b975dbd409f8d38b55e55bcb
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Fri Feb 19 22:15:22 2021 +1100
+
+ 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...
+
+ 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 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 Feb 18 02:49:35 2021 +0000
+
+ upstream: Fix the hostkeys rotation extension documentation
+
+ The documentation was lacking the needed want-reply field in the initial
+ global request.
+
+ https://github.com/openssh/openssh-portable/pull/218 by dbussink
+
+ OpenBSD-Commit-ID: 051824fd78edf6d647a0b9ac011bf88e28775054
+
+commit 34c5ef6e2d06d9f0e20cb04a9aebf67a6f96609a
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Thu Feb 18 02:15:07 2021 +0000
+
+ upstream: make names in function prototypes match those in
+
+ definition from https://github.com/openssh/openssh-portable/pull/225 by
+ ZenithalHourlyRate
+
+ OpenBSD-Commit-ID: 7c736307bf3f2c7cb24d6f82f244eee959485acd
+
+commit 88e3d4de31ab4f14cac658e9e0c512043b15b146
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Thu Feb 18 02:13:58 2021 +0000
+
+ upstream: unbreak SK_DEBUG builds
+
+ from https://github.com/openssh/openssh-portable/pull/225 by
+ ZenithalHourlyRate
+
+ OpenBSD-Commit-ID: 28d7259ce1b04d025411464decfa2f1a097b43eb
+
+commit 788cbc5b74a53956ba9fff11e1ca506271a3597f
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Thu Feb 18 00:30:17 2021 +0000
+
+ 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: f96293221e5aa24102d9bf30e4f4ef04d5f4fb51
+
+commit 324449a68d510720d0e4dfcc8e9e5a702fe6a48f
+Author: Damien Miller <djm@mindrot.org>
+Date: Thu Feb 18 12:06:25 2021 +1100
+
+ 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.
+
+ https://github.com/openssl/openssl/issues/13411
+
+ bz#3238 ok dtucker@
+
+commit 845fe9811c047063d935eca89188ed55c993626b
+Author: Damien Miller <djm@mindrot.org>
+Date: Thu Feb 18 11:25:38 2021 +1100
+
+ 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.
+
+ Based on FreeBSD PR 37416 via Ed Maste; ok dtucker@
+
+commit d0763c8d566119cce84d9806e419badf20444b02
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Thu Feb 18 10:45:27 2021 +1100
+
+ 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)
+
+ OpenBSD and NetBSD require the caller to free strings returned
+ bu the login_* functions, but FreeBSD requires that callers don't.
+
+ Fortunately in this case, we can harmlessly leak as the process is
+ about to exec the shell/command.
+
+ 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.
+
+ 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 09f4b84654b71099559492e9aed5e1a38bf24815
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Wed Feb 17 18:41:30 2021 +1100
+
+ 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).
+
+ 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 64bbd7444d658ef7ee14a7ea5ccc7f5810279ee7
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Wed Feb 17 03:59:00 2021 +0000
+
+ upstream: Make sure puttygen is new enough to successfully run the
+
+ PuTTY interop tests, otherwise skip them.
+
+ OpenBSD-Regress-ID: 34565bb50b8aec58331ed02a5e9e0a9a929bef51
+
+commit da0a9afcc446a30ca49dd216612c41ac3cb1f2d4
+Author: markus@openbsd.org <markus@openbsd.org>
+Date: Mon Feb 15 20:43:15 2021 +0000
+
+ upstream: ssh: add PermitRemoteOpen for remote dynamic forwarding
+
+ with SOCKS ok djm@, dtucker@
+
+ OpenBSD-Commit-ID: 64fe7b6360acc4ea56aa61b66498b5ecc0a96a7c
+
+commit b696858a7f9db72a83d02cb6edaca4b30a91b386
+Author: markus@openbsd.org <markus@openbsd.org>
+Date: Mon Feb 15 20:36:35 2021 +0000
+
+ upstream: factor out opt_array_append; ok djm@
+
+ OpenBSD-Commit-ID: 571bc5dd35f99c5cf9de6aaeac428b168218e74a
+
+commit ad74fc127cc45567e170e8c6dfa2cfd9767324ec
+Author: dlg@openbsd.org <dlg@openbsd.org>
+Date: Mon Feb 15 11:09:22 2021 +0000
+
+ upstream: ProxyJump takes "none" to disable processing like
+
+ ProxyCommand does
+
+ ok djm@ jmc@
+
+ OpenBSD-Commit-ID: 941a2399da2193356bdc30b879d6e1692f18b6d3
+
+commit 16eacdb016ccf38dd9959c78edd3a6282513aa53
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Fri Feb 12 03:49:09 2021 +0000
+
+ upstream: sftp: add missing lsetstat@openssh.com documentation
+
+ patch from Mike Frysinger
+
+ OpenBSD-Commit-ID: 9c114db88d505864075bfe7888b7c8745549715b
+
+commit e04fd6dde16de1cdc5a4d9946397ff60d96568db
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Fri Feb 12 03:14:18 2021 +0000
+
+ upstream: factor SSH_AGENT_CONSTRAIN_EXTENSION parsing into its own
+
+ function and remove an unused variable; ok dtucker@
+
+ OpenBSD-Commit-ID: e1a938657fbf7ef0ba5e73b30365734a0cc96559
+
+commit 1bb130ed34721d46452529d094d9bbf045607d79
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Thu Feb 11 10:18:05 2021 +1100
+
+ Add __NR_futex_time64 to seccomp sandbox.
+
+ 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 f88a7a431212a16e572ecabd559e632f369c363e
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Sat Feb 6 09:37:01 2021 +1100
+
+ Add a hostname function for systems that don't have it.
+
+ 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 5e385a71ef2317856f37c91a98658eb12eb5a89c
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Fri Feb 5 22:03:40 2021 +0000
+
+ upstream: Roll back the hostname->uname change in rev 1.10. It turns
+
+ 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-Regress-ID: 827a707d6201d5a8e196a8c28aec1d2c76c52341
+
+commit b446c214279de50ed8388e54897eb1be5281c894
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Fri Feb 5 06:01:58 2021 +0000
+
+ upstream: hostname is not specified by POSIX but uname -n is, so use
+
+ the latter for portability. Patch from Geert Hendrickx via github PR#208.
+
+ OpenBSD-Regress-ID: d6a79c7c4d141a0d05ade4a042eb57dddbce89f3
+
+commit 1cb6ce98d658e5fbdae025a3bd65793980e3b5d9
+Author: David Carlier <devnexen@gmail.com>
+Date: Sat Nov 21 12:22:23 2020 +0000
+
+ Using explicit_memset for the explicit_bzero compatibility layer.
+
+ 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: 3e241d7ac1ee77e3de3651780b5dc47b283a7668
+
+commit 69338ab46afe9e3dfb7762ad65351d854077c998
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Tue Feb 2 22:36:59 2021 +0000
+
+ upstream: whitespace
+
+ OpenBSD-Commit-ID: 544bb092e03fcbecb420196cd0f70af13ea868ad
+
+commit f71219a01d8f71c4b3ed7e456337a84ddba1653e
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Tue Feb 2 22:36:46 2021 +0000
+
+ upstream: fix memleaks in private key deserialisation; enforce more
+
+ consistency between redundant fields in private key certificate and private
+ key body; ok markus@
+
+ 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: 2091a36d6ca3980c81891a6c4bdc544e63cb13a8
+
+commit 3dd0c64e08f1bba21d71996d635c7256c8c139d1
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Sun Jan 31 22:55:29 2021 +0000
+
+ upstream: more strictly enforce KEX state-machine by banning packet
+
+ 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).
+
+ ok markus@
+
+ OpenBSD-Commit-ID: 87331c715c095b587d5c88724694cdeb701c9def
+
+commit 7a92a324a2e351fabd0ba8ef9b434d3b12d54ee3
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Sun Jan 31 10:50:10 2021 +0000
+
+ upstream: Set linesize returned by getline to zero when freeing and
+
+ NULLing the returned string. OpenBSD's getline handles this just fine, but
+ some implementations used by -portable do not. ok djm@
+
+ OpenBSD-Commit-ID: 4d7bd5169d3397654247db9655cc69a9908d165c
+
+commit a5dfc5bae8c16e2a7caf564758d812c7672480b5
+Author: Damien Miller <djm@mindrot.org>
+Date: Sat Jan 30 16:32:29 2021 +1100
+
+ allow a fuzz case to contain more than one request
+
+ loop until input buffer empty, no message consumed or 256 messages
+ processed
+
+commit 0ef24ad60204022f7e33b6e9d171172c50514132
+Author: Damien Miller <djm@mindrot.org>
+Date: Sat Jan 30 16:28:23 2021 +1100
+
+ expect fuzz cases to have length prefix
+
+ 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
+
+ add certificates and missing key types
+
+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: add a SK_DUMMY_INTEGRATE define that allows the dummy
+
+ security key middleware to be directly linked; useful for writing fuzzers,
+ etc.
+
+ OpenBSD-Regress-ID: 0ebd00159b58ebd85e61d8270fc02f1e45df1544
+
+commit 1a4b92758690faa12f49079dd3b72567f909466d
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Fri Jan 29 06:29:46 2021 +0000
+
+ upstream: fix the values of enum sock_type
+
+ 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
+
+ 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 be5f0048ea2aaeddd27be7dcca23aaad345fa16c
+Author: Damien Miller <djm@mindrot.org>
+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
+
+ 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
+
+ OpenBSD-Commit-ID: 3765f4cc3ae1df874dba9102a3588ba7b48b8183
+
+commit 1134a48cdcef8e7363b9f6c73ebdd24405066738
+Author: Damien Miller <djm@mindrot.org>
+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
+
+ upstream: make ssh->kex->session_id a sshbuf instead of u_char*/size_t
+
+ and use that instead of global variables containing copies of it. feedback/ok
+ markus@
+
+ OpenBSD-Commit-ID: a4b1b1ca4afd2e37cb9f64f737b30a6a7f96af68
+
+commit 4ca6a1fac328477c642329676d6469dba59019a3
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Wed Jan 27 09:26:53 2021 +0000
+
+ upstream: remove global variable used to stash compat flags and use the
+
+ purpose-built ssh->compat variable instead; feedback/ok markus@
+
+ 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.
+
+ 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 d1532d90074b212054d5fd965f833231b09982f5
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Wed Jan 27 00:37:26 2021 +0000
+
+ upstream: Logical not bitwise or. 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: d766820d33dd874d944c14b0638239adb522c7ec
+
+commit e26c980778b228bdd42b8353cc70101cf49b731b
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Tue Jan 26 11:25:01 2021 +0000
+
+ upstream: Remove unused variables leftover from refactoring. ok
+
+ djm@
+
+ OpenBSD-Commit-ID: 8b3ad58bff828fcf874e54b2fc27a4cf1d9505e8
+
+commit e9f78d6b06fc323bba1890b2dc3b8423138fb35c
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Tue Jan 26 05:32:21 2021 +0000
+
+ 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@
+
+ OpenBSD-Commit-ID: 49451c382adc6e69d3fa0e0663eeef2daa4b199e
+
+commit 48d0d7a4dd31154c4208ec39029d60646192f978
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Tue Jan 26 14:48:07 2021 +1100
+
+ 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.
+
+ This should allow OpenSSH to build with a plain C89 compiler again.
+ Spotted by tim@, ok djm@.
+
+commit 37c70ea8d4f3664a88141bcdf0bf7a16bd5fd1ac
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Tue Jan 26 00:54:49 2021 +0000
+
+ upstream: refactor key constraint parsing in ssh-agent
+
+ 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.
+
+ ok markus@
+
+ OpenBSD-Commit-ID: 511cb1b1c021ee1d51a4c2d649b937445de7983c
+
+commit e0e8bee8024fa9e31974244d14f03d799e5c0775
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Tue Jan 26 00:53:31 2021 +0000
+
+ upstream: more ssh-agent refactoring
+
+ Allow confirm_key() to accept an additional reason suffix
+
+ 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.
+
+ feedback/ok markus@
+
+ OpenBSD-Commit-ID: 29006515617d1aa2d8b85cd2bf667e849146477e
+
+commit dfe18a295542c169ffde8533b3d7fe42088e2de7
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Tue Jan 26 00:51:30 2021 +0000
+
+ upstream: make struct hostkeys public; I have no idea why I made it
+
+ opaque originally.
+
+ ok markus@
+
+ OpenBSD-Commit-ID: e50780b34d4bbe628d69b2405b024dd749d982f3
+
+commit 3b44f2513cae89c920e8fe927b9bc910a1c8c65a
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Tue Jan 26 00:49:30 2021 +0000
+
+ upstream: move check_host_cert() from sshconnect,c to sshkey.c and
+
+ refactor it to make it more generally usable and testable.
+
+ ok markus@
+
+ OpenBSD-Commit-ID: 536f489f5ff38808c1fa711ba58d4579b636f9e4
+
+commit 1fe16fd61bb53944ec510882acc0491abd66ff76
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Tue Jan 26 00:47:47 2021 +0000
+
+ upstream: use recallocarray to allocate the agent sockets table;
+
+ also clear socket entries that are being marked as unused.
+
+ spinkle in some debug2() spam to make it easier to watch an agent
+ do its thing.
+
+ ok markus
+
+ OpenBSD-Commit-ID: 74582c8e82e96afea46f6c7b6813a429cbc75922
+
+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: 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.
+
+ spotted with dtucker@ ok markus@
+
+ OpenBSD-Commit-ID: 25bffe19f0326972f5728170f7da81d5f45c78c6
+
+commit 95eca1e195a3b41baa1a725c2c5af8a09d885e4b
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Sat Jan 23 18:26:05 2021 +1100
+
+ ifdef new instance of sin6_scope_id
+
+ Put inside HAVE_STRUCT_SOCKADDR_IN6_SIN6_SCOPE_ID similar to
+ existing instance. Should fix error on UnixWare 7.
+
+commit 6ffdcdda128045226dda7fbb3956407978028a1e
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Mon Jan 18 11:43:34 2021 +0000
+
+ upstream: Fix long->int for convtime tests here too. Spotted by
+
+ tobhe@.
+
+ OpenBSD-Regress-ID: a87094f5863312d00938afba771d25f788c849d0
+
+commit b55b7565f15327d82ad7acbddafa90b658c5f0af
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Fri Jan 22 02:46:40 2021 +0000
+
+ upstream: PubkeyAcceptedKeyTypes->PubkeyAcceptedAlgorithms
+
+ here too.
+
+ OpenBSD-Commit-ID: 3b64a640f8ce8c21d9314da9df7ce2420eefde3a
+
+commit ee9c0da8035b3168e8e57c1dedc2d1b0daf00eec
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Fri Jan 22 02:44:58 2021 +0000
+
+ upstream: Rename PubkeyAcceptedKeyTypes keyword to
+
+ 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 a8e798feabe36d02de292bcfd274712cae1d8d17
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Fri Jan 15 02:58:11 2021 +0000
+
+ 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@
+
+ OpenBSD-Regress-ID: ba2b81e9a3257fff204b020affe85b604a44f97e
+
+commit 9bde1a420626da5007bf7ab499fa2159b9eddf72
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Fri Jan 15 04:31:25 2021 +0000
+
+ 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-Commit-ID: 83733f1b01b82da88b9dd1769475952aff10bdd7
+
+commit 02da325f10b214219eae2bb1bc2d3bf0c2f13f9f
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Fri Jan 15 02:58:11 2021 +0000
+
+ 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@
+
+ OpenBSD-Commit-ID: 01dc0475f1484ac2f47facdfcf9221f9472145de
+
+commit 5339ab369c225b40bc64d5ec3374f5c91b3ad609
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Fri Jan 15 02:32:41 2021 +0000
+
+ upstream: In waitfd(), when poll returns early we are subtracting
+
+ 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: 199df060978ee9aa89b8041a3dfaf1bf7ae8dd7a
+
+commit a164862dfa863b54b7897f66e1dd75437f086c11
+Author: rob@openbsd.org <rob@openbsd.org>
+Date: Thu Jan 14 19:45:06 2021 +0000
+
+ upstream: Minor grammatical correction.
+
+ OK jmc@
+
+ 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
+
+ Remove duplicated declaration in fatal.c .
+
+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
+
+ mode.
+
+ OpenBSD-Commit-ID: ecdc49e2b6bde6b6b0e52163d621831f6ac7b13d
+
+commit ba328bd7a6774f30daaf90b83f1933cc4afc866c
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Sat Jan 9 12:31:46 2021 +0000
+
+ upstream: Adjust kexfuzz to addr.c/addrmatch.c split.
+
+ OpenBSD-Regress-ID: 1d8d23bb548078020be2fb52c4c643efb190f0eb
+
+commit b08ef25552443e94c0857d5e3806dd019ccc55d7
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Sat Jan 9 12:24:30 2021 +0000
+
+ upstream: Update unittests for addr.c/addrmatch.c split.
+
+ OpenBSD-Regress-ID: de2b415fb7af084a91c6ef147a90482d8f771eef
+
+commit 6d30673fedec2d251f4962c526fd0451f70c4d97
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Mon Jan 11 02:12:57 2021 +0000
+
+ upstream: Change convtime() from returning long to returning int.
+
+ 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: 8fc932683d6b4660d52f50911d62bd6639c5db31
+
+commit 7a57adb8b07b2ad0aead4b2e09ee18edc04d0481
+Author: jmc@openbsd.org <jmc@openbsd.org>
+Date: Sat Jan 9 12:51:12 2021 +0000
+
+ upstream: add a comma to previous;
+
+ 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
+
+ options which provide more fine grained MaxStartups limits. Man page help
+ jmc@, feedback & ok djm@
+
+ OpenBSD-Commit-ID: e2f68664e3d02c0895b35aa751c48a2af622047b
+
+commit d9a2bc71693ea27461a78110005d5a2d8b0c6a50
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Sat Jan 9 11:58:50 2021 +0000
+
+ upstream: Move address handling functions out into their own file
+
+ 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: 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 6cb52d5bf771f6769b630fce35a8e9b8e433044f
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Fri Jan 8 04:49:13 2021 +0000
+
+ upstream: make CheckHostIP default to 'no'. It doesn't provide any
+
+ 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: 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 4c7af01f9dcc1606dec033e7665a042cb0d8ec52
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Fri Jan 8 02:57:24 2021 +0000
+
+ 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.
+
+ ok dtucker@
+
+ OpenBSD-Commit-ID: 176db8518933d6a5bbf81a2e3cf62447158dc878
+
+commit 64ddd0fe68c4a7acf99b78624f8af45e919cd317
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Fri Jan 8 02:44:14 2021 +0000
+
+ upstream: don't try to use timespeccmp(3) directly as a qsort(3)
+
+ comparison function - it returns 0/1 and not the -1/0/1 that qsort expectes.
+
+ fixes sftp "ls -ltr" under some circumstances.
+
+ Based on patch by Masahiro Matsuya via bz3248.
+
+ 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:
+
+ - 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 djm@
+
+ OpenBSD-Commit-ID: 7b9d0cf3acd5a3c1091da8afe00c904d38cf5783
+
+commit 16448ff529affda7e2a15ee7c3200793abde0759
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Fri Jan 8 02:19:24 2021 +0000
+
+ upstream: mention that DisableForwarding is valid in a sshd_config
+
+ Match block reported by Fredrik Eriksson in bz3239
+
+ OpenBSD-Commit-ID: 3a71c3d84b597f5e43e4b40d5232797daf0993f6
+
+commit 91bac5e95b1b0debf9b2b4f05c20dcfa96b368b9
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Mon Jan 4 21:58:58 2021 +0000
+
+ upstream: estructure sntrup761.sh to process all files in a single
+
+ list, which will make it easier to reorder. Re-inline int32_MINMAX. ok
+ tobhe@
+
+ OpenBSD-Commit-ID: d145c6c19b08bb93c9e14bfaa7af589d90f144c0
+
+commit 4d96a3ebab2224f17e639a15078e03be1ad3736d
+Author: tobhe@openbsd.org <tobhe@openbsd.org>
+Date: Sun Jan 3 18:05:21 2021 +0000
+
+ upstream: Prevent redefinition of `crypto_int32' error with gcc3.
+
+ Fixes compilation on luna88k.
+
+ Feedback millert@
+ Found by and ok aoyama@
+
+ OpenBSD-Commit-ID: f305ddfe575a26cc53431af3fde3f4aeebed9ba6
+
+commit a23954eeb930ccc8a66a2710153730769dba31b6
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Fri Jan 1 22:00:49 2021 +1100
+
+ 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 148b8a661c3f93e4b6d049ee902de3d521261fbc
+Author: Damien Miller <djm@mindrot.org>
+Date: Thu Dec 31 12:47:22 2020 +1100
+
+ fix: missing pieces of previous commit
+
+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: Tue Dec 29 12:40:54 2020 +1100
+
+ adapt KEX fuzzer to PQ kex change
+
+commit 659864fe81dbc57eeed3769c462679d83e026640
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Tue Dec 29 01:02:15 2020 +0000
+
+ upstream: Adapt to replacement of
+
+ sntrup4591761x25519-sha512@tinyssh.org with
+ sntrup761x25519-sha512@openssh.com.
+
+ Also test sntrup761x25519-sha512@openssh.com in unittests/kex
+
+ OpenBSD-Regress-ID: cfa3506b2b077a9cac1877fb521efd2641b6030c
+
+commit 2c71cec020219d69df84055c59eba5799a1233ec
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Tue Dec 29 00:59:15 2020 +0000
+
+ 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).
+
+ 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 09d070ccc3574ae0d7947d212ed53c7268ef7e1f
+Author: jmc@openbsd.org <jmc@openbsd.org>
+Date: Tue Dec 22 07:40:26 2020 +0000
+
+ 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
+
+ OpenBSD-Commit-ID: aba31ebea03f38f8d218857f7ce16a500c3e4aff
+
+commit 931c93389a80e32272712459b1102d303844453d
+Author: Damien Miller <djm@mindrot.org>
+Date: Tue Dec 22 19:43:55 2020 +1100
+
+ whitespace at EOL
+
+commit 397b1c4d393f97427283a4717e9015a2bd31b8a5
+Author: Damien Miller <djm@mindrot.org>
+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
+
+ Include stdio.h for FILE in misc.h.
+
+ Fixes build on at least OpenBSD.
+
+commit 3e9811e57b57ee66b0f70d99d7258da3153b0e8a
+Author: Damien Miller <djm@mindrot.org>
+Date: Tue Dec 22 18:31:50 2020 +1100
+
+ ensure $LOGNAME is set in tests
+
+commit 3eb647cbb34d87a063aa7714256c6e56103fffda
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Tue Dec 22 06:47:24 2020 +0000
+
+ upstream: more detail for failing tests
+
+ OpenBSD-Regress-ID: c68c0e5a521cad7e7f68e54c54ebf86d6c10ee1d
+
+commit 2873f19570d4d8758be24dbf78332be9a779009b
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Tue Dec 22 06:03:36 2020 +0000
+
+ upstream: regress test for KnownHostsCommand
+
+ OpenBSD-Regress-ID: ffc77464320b6dabdcfa0a72e0df02659233a38a
+
+commit 0121aa87bab9ad2365de2d07f2832b56d5ff9871
+Author: tb@openbsd.org <tb@openbsd.org>
+Date: Tue Dec 22 03:05:31 2020 +0000
+
+ upstream: Remove lines accidentally left behind in the ProxyJump
+
+ parsing fix r1.345.
+
+ ok djm
+
+ OpenBSD-Commit-ID: fe767c108c8117bea33767b080ff62eef2c55f5c
+
+commit da4bf0db942b5f0278f33238b86235e5813d7a5a
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Tue Dec 22 00:15:22 2020 +0000
+
+ upstream: add a ssh_config KnownHostsCommand that allows the client
+
+ to obtain known_hosts data from a command in addition to the usual files.
+
+ 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 a34e14a5a0071de2036826a00197ce38c8b4ba8b
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Tue Dec 22 00:12:22 2020 +0000
+
+ 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 649205fe388b56acb3481a1b2461f6b5b7c6efa6
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Mon Dec 21 22:48:41 2020 +0000
+
+ upstream: Remove explicit rijndael-cbc@lysator.liu.se test since the
+
+ cipher was removed.
+
+ OpenBSD-Regress-ID: aa93cddb4ecd9bc21446a79008a1a53050e64f17
+
+commit 03e93c753d7c223063ad8acaf9a30aa511e5f931
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Mon Dec 21 11:09:32 2020 +0000
+
+ 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: fb460acc18290a998fd70910b19c29b4e4f199ad
+
+commit a11ca015879eab941add8c6bdaaec7d41107c6f5
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Mon Dec 21 09:19:53 2020 +0000
+
+ 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: a2991a3794bcaf1ca2b025212cce11cdb5f6b7d6
+
+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: 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
+
+ upstream: allow UserKnownHostsFile=none; feedback and ok markus@
+
+ OpenBSD-Commit-ID: c46d515eac94a35a1d50d5fd71c4b1ca53334b48
+
+commit b4c7cd1185c5dc0593d47eafcc1a34fda569dd1d
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Sun Dec 20 23:36:51 2020 +0000
+
+ upstream: load_hostkeys()/hostkeys_foreach() variants for FILE*
+
+ Add load_hostkeys_file() and hostkeys_foreach_file() that accept a
+ FILE* argument instead of opening the file directly.
+
+ 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 0ebead6593e2441e4af2735bbe2cd097607cd0d3
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Thu Dec 17 23:28:50 2020 +0000
+
+ upstream: fix possible error("%s", NULL) on error paths
+
+ OpenBSD-Commit-ID: 0b3833c2cb985453ecca1d76803ebb8f3b736a11
+
+commit d060bc7f6e6244f001e658208f53e3e2ecbbd382
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Thu Dec 17 23:26:11 2020 +0000
+
+ upstream: refactor client percent_expand() argument passing;
+
+ 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 43026da035cd266db37df1f723d5575056150744
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Thu Dec 17 23:10:27 2020 +0000
+
+ upstream: prepare readconf.c for fuzzing; remove fatal calls and
+
+ fix some (one-off) memory leaks; ok markus@
+
+ OpenBSD-Commit-ID: 91c6aec57b0e7aae9190de188e9fe8933aad5ec5
+
+commit bef92346c4a808f33216e54d6f4948f9df2ad7c1
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Mon Dec 14 03:13:12 2020 +0000
+
+ upstream: use _PATH_SSH_USER_DIR instead of hardcoded .ssh in path
+
+ 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 e4d1a0b40add800b6e9352b40c2223e44acc3a45
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Fri Dec 4 02:41:10 2020 +0000
+
+ upstream: shuffle a few utility functions into sftp-client.c; from
+
+ Jakub Jelen
+
+ OpenBSD-Commit-ID: fdeb1aae1f6149b193f12cd2af158f948c514a2a
+
+commit ace12dc64f8e3a2496ca48d36b53cb3c0a090755
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Fri Dec 4 02:29:56 2020 +0000
+
+ upstream: make ssh_free(NULL) a no-op
+
+ 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: 0e913b542c3764b100b1571fdb0d0e5cc086fe97
+
+commit 553b90feedd7da5b90901d73005f86705456d686
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Fri Dec 4 02:27:57 2020 +0000
+
+ upstream: fix minor memleak of kex->hostkey_alg on rekex
+
+ OpenBSD-Commit-ID: 2c3969c74966d4ccdfeff5e5f0df0791919aef50
+
+commit ac0364b85e66eb53da2f9618f699ba6bd195ceea
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Fri Dec 4 02:27:08 2020 +0000
+
+ upstream: typos: s/hex/kex/ in error messages
+
+ 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
+
+ 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,
+
+ similar to what we already do for sshd_config. bz#2320, with & ok djm@
+
+ OpenBSD-Commit-ID: bdbf9fc5bc72b1a14266f5f61723ed57307a6db4
+
+commit b755264e7d3cdf1de34e18df1af4efaa76a3c015
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Sat Nov 28 12:52:32 2020 +0000
+
+ upstream: Include cipher.h for declaration of cipher_by_name.
+
+ 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
+
+ searched-for characters; from zhongjubin@huawei.com
+
+ OpenBSD-Commit-ID: e6f57de1d4a4d25f8db2d44e8d58d847e247a4fe
+
+commit 57bf03f0217554afb8980f6697a7a0b88658d0a9
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Fri Nov 27 10:12:30 2020 +0000
+
+ upstream: Document ssh-keygen -Z, sanity check its argument earlier and
+
+ provide a better error message if it's not correct. Prompted by bz#2879, ok
+ djm@ jmc@
+
+ 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
+
+ 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.
+
+ ok dtucker@
+
+ OpenBSD-Commit-ID: f31ab10d9233363a6d2c9996007083ba43a093f1
+
+commit b2bcec13f17ce9174238a704e91d52203e916432
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Fri Nov 27 00:37:10 2020 +0000
+
+ 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@
+
+ OpenBSD-Commit-ID: 9925df75a56732c43f3663e70dd15ff413ab3e53
+
+commit 19af04e2231155d513e24fdc81fbec2217ae36a6
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Sun Nov 22 22:38:26 2020 +0000
+
+ upstream: when loading PKCS#11 keys, include the key fingerprints
+
+ and provider/slot information in debug output.
+
+ OpenBSD-Commit-ID: 969a089575d0166a9a364a9901bb6a8d9b8a1431
+
+commit 9b9465ea856e15b9e9890b4ecb4110d7106e7766
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Sun Nov 22 22:37:11 2020 +0000
+
+ 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 637017a7dd3281d3f2df804993cc27c30dbfda47
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Wed Nov 25 17:38:46 2020 +1100
+
+ Use "=" not "==" in string test.
+
+ POSIX says "=" is string comparison and some shells (eg HP-UX) will
+ complain about "==".
+
+commit 9880f3480f9768897f3b8e714d5317fb993bc5b3
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Fri Nov 20 17:16:51 2020 +1100
+
+ Restore correct flags during localtime_r check.
+
+ We were restoring the wrong thing CPPFLAGS (we used CFLAGS) for any
+ platform that doesn't have localtime_r.
+
+commit 41935882f4e82de60dbd6e033eabe79e1b963518
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Fri Nov 20 03:16:56 2020 +0000
+
+ upstream: When doing an sftp recursive upload or download of a
+
+ 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: a82606212f2796e31f0e1af94a63355a7ad5d903
+
+commit 0f90440ca70abab947acbd77795e9f130967956c
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Fri Nov 20 13:37:54 2020 +1100
+
+ Add new pselect6_time64 syscall on ARM.
+
+ This is apparently needed on armhfp/armv7hl. bz#3232, patch from
+ jjelen at redhat.com.
+
+commit 3a7c46c72b6a1f643b1fc3589cd20d8320c3d9e1
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Fri Nov 20 02:14:16 2020 +0000
+
+ 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 076cb616b87d1ea1d292973fcd0ba38c08ea6832
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Thu Nov 19 23:05:05 2020 +0000
+
+ upstream: draft-ietf-secsh-architecture is now RFC4251.
+
+ OpenBSD-Commit-ID: cb0bb58c2711fb5ed519507659be1dcf179ed403
+
+commit 85cceda21f1471548e04111aefe2c4943131c1c8
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Tue Nov 17 11:23:58 2020 +0000
+
+ upstream: Specify that the KDF function is bcrypt. Based on github
+
+ PR#214 from rafork, ok markus@, mdoc correction jmc@
+
+ OpenBSD-Commit-ID: d8f2853e7edbcd483f31b50da77ab80ffa18b4ef
+
+commit 5b9720f9adbd70ba5a994f407fe07a7d016d8d65
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Sun Nov 15 22:34:58 2020 +0000
+
+ upstream: revert r1.341; it breaks ProxyJump; reported by sthen@
+
+ OpenBSD-Commit-ID: 6ac2f945b26cb86d936eed338f77861d6da8356a
+
+commit 04088725ec9c44880c01799b588cd4ba47b3e8bc
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Fri Nov 13 07:30:44 2020 +0000
+
+ upstream: scrub keyboard-interactive authentication prompts coming
+
+ from the server through asmprintf() prior to display; suggested by and ok
+ dtucker@
+
+ OpenBSD-Commit-ID: 31fe93367645c37fbfe4691596bf6cf1e3972a58
+
+commit 5442b491d0ee4bb82f6341ad0ee620ef3947f8c5
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Fri Nov 13 04:53:12 2020 +0000
+
+ upstream: prefix keyboard interactive prompts with (user@host) to
+
+ make it easier to determine which connection they are associated with in
+ cases like scp -3, ProxyJump, etc. bz#3224 ok dtucker
+
+ OpenBSD-Commit-ID: 67e6189b04b46c867662f8a6759cf3ecb5f59170
+
+commit 2992e4e7014ac1047062acfdbbf6feb156fef616
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Fri Nov 13 17:56:11 2020 +1100
+
+ Remove use of TIME_WITH_SYS_TIME.
+
+ 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"
+
+ This reverts commit 5b56bd0affea7b02b540bdbc4d1d271b0e4fc885.
+
+ 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.
+
+ 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 d5d05cdb3d4efd4a618aa52caab5bec73097c163
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Thu Nov 12 22:56:00 2020 +0000
+
+ upstream: when prompting the user to accept a new hostkey, display
+
+ any other host names/addresses already associated with the key. E.g.
+
+ > 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: 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 add926dd1bbe3c4db06e27cab8ab0f9a3d00a0c2
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Wed Nov 11 05:22:32 2020 +0000
+
+ upstream: fix logic error that broke URI parsing in ProxyJump
+
+ directives; ok dtucker@
+
+ OpenBSD-Commit-ID: 96d48839b1704882a0e9a77898f5e14b2d222705
+
+commit 4340dd43928dfe746cb7e75fe920b63c0d909a9a
+Author: claudio@openbsd.org <claudio@openbsd.org>
+Date: Tue Nov 10 07:46:20 2020 +0000
+
+ upstream: Free the previously allocated msg buffer after writing it
+
+ out. OK djm@
+
+ OpenBSD-Commit-ID: 18c055870fc75e4cb9f926c86c7543e2e21d7fa4
+
+commit fcf429a4c69d30d8725612a55b37181594da8ddf
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Wed Nov 11 12:30:46 2020 +1100
+
+ Prevent excessively long username going to PAM.
+
+ 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.
+
+ Based on github PR#212 from Mike Scott but implemented slightly
+ differently. ok tim@ djm@
+
+commit 10dce8ff68ef615362cfcab0c0cc33ce524e7682
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Sun Nov 8 23:19:03 2020 +0000
+
+ upstream: unbreak; missing NULL check
+
+ OpenBSD-Commit-ID: 6613dfab488123f454d348ef496824476b8c11c0
+
+commit d5a0cd4fc430c8eda213a4010a612d4778867cd9
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Sun Nov 8 22:37:24 2020 +0000
+
+ upstream: when requesting a security key touch on stderr, inform the
+
+ user once the touch has been recorded; requested by claudio@ ok markus@
+
+ OpenBSD-Commit-ID: 3b76ee444490e546b9ea7f879e4092ee0d256233
+
+commit 292bcb2479deb27204e3ff796539c003975a5f7a
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Mon Nov 9 00:33:35 2020 +1100
+
+ Remove preprocessor directive from log macro calls.
+
+ 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 71693251b7cbb7dd89aaac18815147124732d0d3
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Sun Nov 8 12:10:20 2020 +0000
+
+ upstream: Add a comment documenting the source of the moduli group
+
+ sizes.
+
+ OpenBSD-Commit-ID: aec0725ce607630caaa62682624c6763b350391c
+
+commit 4d94b031ff88b015f0db57e140f481bff7ae1a91
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Sun Nov 8 11:46:12 2020 +0000
+
+ upstream: Replace WITH_OPENSSL ifdefs in log calls with a macro.
+
+ 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 6d2564b94e51184eb0b73b97d13a36ad50b4f810
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Fri Nov 6 17:11:16 2020 +1100
+
+ Fix function body for variadic macro test.
+
+ AC_LANG_PROGRAM puts its second argument inside main() so we don't need
+ to do it ourselves.
+
+commit 586f9bd2f5980e12f8cf0d3c2a761fa63175da52
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Fri Nov 6 16:53:24 2020 +1100
+
+ Remove AC_PROC_CC_C99 obsoleted in autoconf 2.70.
+
+ Since we only use it to make sure we can handle variadic macros,
+ explicitly check only for that. with & ok djm@
+
+commit a019e353df04de1b2ca78d91b39c393256044ad7
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Fri Nov 6 13:56:41 2020 +1100
+
+ Replace AC_TRY_COMPILE obsoleted in autoconf 2.70.
+
+ Replace with the equivalent AC_COMPILE_IFELSE.
+
+commit 771b7795c0ef6a2fb43b4c6c66b615c2085cb9cd
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Fri Nov 6 13:55:33 2020 +1100
+
+ Move AC_PROG_CC_C99 to immediately afer AC_PROG_CC.
+
+ This puts the related C version selection output in the same place.
+
+commit e5591161f21ab493c6284a85ac3c0710ad94998f
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Fri Nov 6 13:54:17 2020 +1100
+
+ AC_CHECK_HEADER() is obsoleted in autoconf 2.70.
+
+ Replace with the non-obsoleted AC_CHECK_HEADERS().
+
+commit 05bcd0cadf160fd4826a2284afa7cba6ec432633
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Tue Nov 3 22:53:12 2020 +0000
+
+ upstream: fold consecutive '*' wildcards to mitigate combinatorial
+
+ explosion of recursive searches; ok dtucker
+
+ OpenBSD-Commit-ID: d18bcb39c40fb8a1ab61153db987e7d11dd3792b
+
+commit 7d680448db5858dc76307663f78d0b8d3c2b4a3d
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Fri Oct 30 01:50:07 2020 +0000
+
+ upstream: print reason in fatal error message when
+
+ kex_assemble_namelist() fails
+
+ OpenBSD-Commit-ID: a9975ee8db6c98d6f32233d88051b2077ca63dab
+
+commit 95d1109fec7e89ad21f2a97e92bde1305d32a353
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Thu Oct 29 03:13:06 2020 +0000
+
+ upstream: fix sshd_config SetEnv directive inside Match blocks; part of
+
+ github PR#201 from github user manuelm
+
+ OpenBSD-Commit-ID: 9772e3748abff3ad65ae8fc43d026ed569b1d2bc
+
+commit b12b835dc022ba161afe68348e05a83dfbcb1515
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Thu Oct 29 03:01:18 2020 +0000
+
+ upstream: fix type of nid in type_bits_valid(); github PR#202 from
+
+ github user thingsconnected
+
+ OpenBSD-Commit-ID: 769d2b040dec7ab32d323daf54b854dd5dcb5485
+
+commit 1a14c13147618144d1798c36a588397ba9008fcc
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Thu Oct 29 02:52:43 2020 +0000
+
+ upstream: whitespace; no code change
+
+ OpenBSD-Commit-ID: efefc1c47e880887bdee8cd2127ca93177eaad79
+
+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.
+
+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@
+
+ OpenBSD-Commit-ID: 75f155a1ac61e364ed00dc379e2c42df81067ce2
+
+commit 7715a3b171049afa1feffb1d5a1245dfac36ce99
+Author: Darren Tucker <dtucker@dtucker.net>
+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
+
+ upstream: remove a level of macro indirection; ok markus@
+
+ OpenBSD-Commit-ID: 0c529d06e902c5d1a6b231e1bec6157f76dc67c9
+
+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: Sat Oct 17 22:55:24 2020 +1100
+
+ missing header
+
+commit 999d7cb79a3a73d92a6dfbf174c33da0d984c7a2
+Author: Damien Miller <djm@mindrot.org>
+Date: Sat Oct 17 22:47:52 2020 +1100
+
+ sync regress/misc/sk-dummy/fatal.c
+
+commit 3554b4afa38b3483a3302f1be18eaa6f843bb260
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Sat Oct 17 01:28:20 2020 +0000
+
+ 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: Sat Oct 17 12:03:34 2020 +1100
+
+ check for and require a C99 capable compiler
+
+ recent logging changes use __VA_ARGS__.
+
+commit f9ea6515202b59a1e2d5b885cafc1b12eff33016
+Author: Damien Miller <djm@mindrot.org>
+Date: Sat Oct 17 11:51:20 2020 +1100
+
+ logging is now macros, remove function pointers
+
+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: LogVerbose keyword for ssh and sshd
+
+ Allows forcing maximum debug logging by file/function/line pattern-
+ lists.
+
+ ok markus@
+
+ OpenBSD-Commit-ID: c294c25732d1b4fe7e345cb3e044df00531a6356
+
+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: use do_log2 instead of function pointers to different log
+
+ functions
+
+ OpenBSD-Commit-ID: 88077b826d348c58352a6b394755520f4e484480
+
+commit 95b0bcfd1531d59e056ae8af27bb741391f26ab0
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Wed Oct 14 00:55:17 2020 +0000
+
+ upstream: make UpdateHostkeys still more conservative: refuse to
+
+ 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 a336ce8c2c55547cc00e0070a18c55f30bb53fb6
+Author: kn@openbsd.org <kn@openbsd.org>
+Date: Mon Oct 12 08:36:36 2020 +0000
+
+ 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 e545d94b713effab8e6c7dfabbfb76c1d84d7498
+Author: Philip Hands <phil@hands.com>
+Date: Sun Oct 4 00:15:46 2020 +0200
+
+ 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 fd360174596047b52aa1cddda74d85012a03ca4b
+Author: Philip Hands <phil@hands.com>
+Date: Sat Oct 3 23:15:16 2020 +0200
+
+ combine if/elif to avoid duplication of the action
+
+ SSH-Copy-ID-Upstream: 42aeb1cc53d3f7f6e78edc210fb121fda0834914
+
+commit f7c3a39b016dd77709ecbf18da8282f967b86cd7
+Author: Philip Hands <phil@hands.com>
+Date: Sat Oct 3 21:45:16 2020 +0200
+
+ shellcheck tidyage
+
+ SSH-Copy-ID-Upstream: 5b08f840e78ac544288b3983010a1b0585e966fd
+
+commit 108676c3f26be6c873db0dd8754063699908727b
+Author: Philip Hands <phil@hands.com>
+Date: Sat Oct 3 21:10:03 2020 +0200
+
+ tidy up test of $SCRATCH_DIR creation
+
+ SSH-Copy-ID-Upstream: 2d8b22d96c105d87743ffe8874887b06f8989b93
+
+commit a9c9e91a82bc1a2cf801b4e3ef27a941dbd27717
+Author: Philip Hands <phil@hands.com>
+Date: Wed Sep 16 16:13:30 2020 +0200
+
+ 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.
+
+ SSH-Copy-ID-Upstream: f7c76dc64427cd20287a6868f672423b62057614
+
+commit f92424970c02b78852ff149378c7f2616ada4ccf
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Sun Oct 11 22:14:38 2020 +0000
+
+ upstream: UpdateHostkeys: check for keys under other names
+
+ 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: 6444a705ba504c3c8ccddccd8d1b94aa33bd11c1
+
+commit d98f14b5328922ae3085e07007d820c4f655b57a
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Sun Oct 11 22:13:37 2020 +0000
+
+ 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.
+
+ ok markus@
+
+ OpenBSD-Commit-ID: 374dc263103f6b343d9671f87dbf81ffd0d6abdd
+
+commit af5941ae9b013aac12585e84c4cf494f3728982f
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Sun Oct 11 22:12:44 2020 +0000
+
+ 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.
+
+ ok markus@
+
+ OpenBSD-Commit-ID: e434828191fb5f3877d4887c218682825aa59820
+
+commit 6247812c76f70b2245f3c23f5074665b3d436cae
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Thu Oct 8 01:15:16 2020 +0000
+
+ upstream: don't misdetect comma-separated hostkey names as wildcards;
+
+ spotted by naddy@
+
+ OpenBSD-Commit-ID: 4b874edfec7fc324a21b130bdb42f912177739ce
+
+commit 67146c7d022a170be3cdad2f5f40259a663fb266
+Author: wangxp006 <wangxiaopeng7@huawei.com>
+Date: Thu Oct 8 17:49:59 2020 +0800
+
+ 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
+
+ UpdateHostkeys change
+
+ OpenBSD-Regress-ID: a940ad79d59343319613ba8fc46b6ef24aa3f8e1
+
+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
+
+commit f4f14e023cafee1cd9ebe4bb0db4029e6e1fafac
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Wed Oct 7 02:20:35 2020 +0000
+
+ 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: Wed Oct 7 02:18:45 2020 +0000
+
+ upstream: disable UpdateHostkeys by default if VerifyHostKeyDNS is
+
+ enabled; suggested by Mark D. Baushke
+
+ OpenBSD-Commit-ID: 85a1b88592c81bc85df7ee7787dbbe721a0542bf
+
+commit 3d4c2016bae1a6f14b48c1150a4c79ca4c9968bd
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Tue Oct 6 07:12:04 2020 +0000
+
+ upstream: Agent protocol draft is now at rev 4. ok djm@
+
+ 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
+
+ the ECDSA key subtype; ok markus@
+
+ OpenBSD-Commit-ID: 3097686f853c61ff61772ea35f8b699931392ece
+
+commit 2d39fc9f7e039351daa3d6aead1538ac29258add
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+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: There are lots of place where we want to redirect stdin,
+
+ 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-Commit-ID: 3033ba5a4c47cacfd5def020d42cabc52fad3099
+
+commit 1286981d08b8429a64613215ce8bff3f6b32488a
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Sat Oct 3 08:30:47 2020 +0000
+
+ upstream: enable UpdateHostkeys by default when the configuration
+
+ has not overridden UserKnownHostsFile; ok markus@ "The timing is perfect"
+ deraadt@
+
+ OpenBSD-Commit-ID: 62df71c9c5242da5763cb473c2a2deefbd0cef60
+
+commit 332f21537293d66508f7342dc643bc7fe45f0f69
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Sat Oct 3 08:12:59 2020 +0000
+
+ upstream: disable UpdateHostkeys when a wildcard hostname pattern
+
+ is encountered or when a certificate host key is in use. feedback/ok markus@
+
+ 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
+
+ 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: 2ada81853ff9ee7824c62f440bcf4ad62030c901
+
+commit 12ae8f95e2e0c273e9e7ef930b01a028ef796a3f
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Sat Oct 3 04:15:06 2020 +0000
+
+ upstream: prefer ed25519 signature algorithm variants to ECDSA; ok
+
+ markus@
+
+ OpenBSD-Commit-ID: 82187926fca96d35a5b5afbc091afa84e0966e5b
+
+commit e5ed753add7aa8eed6b167e44db6240a76404db2
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Sat Oct 3 03:40:38 2020 +0000
+
+ upstream: want time.h here too
+
+ OpenBSD-Commit-ID: fafee8f1108c64ad8b282f9a1ed5ea830d8c58a7
+
+commit 66bd9fdf8b7762eb6a85cabbb1ae4ed955679f60
+Author: deraadt@openbsd.org <deraadt@openbsd.org>
+Date: Sat Oct 3 02:18:33 2020 +0000
+
+ 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..
+
+ OpenBSD-Commit-ID: 58e1f72d292687f63eb357183036ee242513691c
+
+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
+
+commit 18ea5f4b88e303677d2003b95e5cb864b439e442
+Author: Philip Hands <phil@hands.com>
+Date: Fri Oct 2 21:30:10 2020 +0200
+
+ ksh doesn't grok 'local'
+
+ 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
+
+ Fix `EOF: command not found` error in ssh-copy-id
+
+commit a1a856d50c89be3206f320baa4bfb32fff4e826f
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Wed Sep 30 09:11:39 2020 +0000
+
+ upstream: Regen moduli.
+
+ 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
@@ -8037,4456 +13701,3 @@ Date: Fri Aug 23 10:08:48 2019 +1000
Used by some hardened heap allocators. Requested by Yegor
Timoshenko in https://github.com/openssh/openssh-portable/pull/142
-
-commit e3b6c966b79c3ea5d51b923c3bbdc41e13b96ea0
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Aug 16 06:13:15 2019 +0000
-
- upstream: switch percent_expand() to use sshbuf instead of a limited
-
- fixed buffer; ok markus@
-
- OpenBSD-Commit-ID: 3f9ef20bca5ef5058b48c1cac67c53b9a1d15711
-
-commit 9ab5b9474779ac4f581d402ae397f871ed16b383
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Aug 9 05:05:54 2019 +0000
-
- upstream: produce a useful error message if the user's shell is set
-
- incorrectly during "match exec" processing. bz#2791 reported by Dario
- Bertini; ok dtucker
-
- OpenBSD-Commit-ID: cf9eddd6a6be726cb73bd9c3936f3888cd85c03d
-
-commit 8fdbc7247f432578abaaca1b72a0dbf5058d67e5
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Fri Aug 9 04:24:03 2019 +0000
-
- upstream: Change description of TCPKeepAlive from "inactive" to
-
- "unresponsive" to clarify what it checks for. Patch from jblaine at
- kickflop.net via github pr#129, ok djm@.
-
- OpenBSD-Commit-ID: 3682f8ec7227f5697945daa25d11ce2d933899e9
-
-commit 7afc45c3ed72672690014dc432edc223b23ae288
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Thu Aug 8 08:02:57 2019 +0000
-
- upstream: Allow the maximimum uint32 value for the argument passed to
-
- -b which allows better error messages from later validation. bz#3050, ok
- djm@
-
- OpenBSD-Commit-ID: 10adf6876b2401b3dc02da580ebf67af05861673
-
-commit c31e4f5fb3915c040061981a67224de7650ab34b
-Author: naddy@openbsd.org <naddy@openbsd.org>
-Date: Mon Aug 5 21:45:27 2019 +0000
-
- upstream: Many key types are supported now, so take care to check
-
- the size restrictions and apply the default size only to the matching key
- type. tweak and ok dtucker@
-
- OpenBSD-Commit-ID: b825de92d79cc4cba19b298c61e99909488ff57e
-
-commit 6b39a7b49ebacec4e70e24bfc8ea2f11057aac22
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Mon Aug 5 11:50:33 2019 +0000
-
- upstream: Remove now-redundant perm_ok arg since
-
- sshkey_load_private_type will now return SSH_ERR_KEY_BAD_PERMISSIONS in that
- case. Patch from jitendra.sharma at intel.com, ok djm@
-
- OpenBSD-Commit-ID: 07916a17ed0a252591b71e7fb4be2599cb5b0c77
-
-commit d46075b923bf25e6f25959a3f5b458852161cb3e
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Mon Aug 5 21:36:48 2019 +1000
-
- Fix mem leak in unit test.
-
- Patch from jitendra.sharma at intel.com.
-
-commit c4ffb72593c08921cf9291bc05a5ef1d0aaa6891
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Aug 2 01:41:24 2019 +0000
-
- upstream: fix some memleaks in test_helper code
-
- bz#3037 from Jitendra Sharma
-
- OpenBSD-Regress-ID: 71440fa9186f5842a65ce9a27159385c6cb6f751
-
-commit 6e76e69dc0c7712e9ac599af34bd091b0e7dcdb5
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Aug 2 01:23:19 2019 +0000
-
- upstream: typo; from Christian Hesse
-
- OpenBSD-Commit-ID: 82f6de7438ea7ee5a14f44fdf5058ed57688fdc3
-
-commit 49fa065a1bfaeb88a59abdfa4432d3b9c35b0655
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Tue Jul 30 05:04:49 2019 +0000
-
- upstream: let sshbuf_find/cmp take a void* for the
-
- search/comparison argument, instead of a u_char*. Saves callers needing to
- cast.
-
- OpenBSD-Commit-ID: d63b69b7c5dd570963e682f758f5a47b825605ed
-
-commit 7adf6c430d6fc17901e167bc0789d31638f5c2f8
-Author: mestre@openbsd.org <mestre@openbsd.org>
-Date: Wed Jul 24 08:57:00 2019 +0000
-
- upstream: When using a combination of a Yubikey+GnuPG+remote
-
- forwarding the gpg-agent (and options ControlMaster+RemoteForward in
- ssh_config(5)) then the codepath taken will call mux_client_request_session
- -> mm_send_fd -> sendmsg(2). Since sendmsg(2) is not allowed in that codepath
- then pledge(2) kills the process.
-
- The solution is to add "sendfd" to pledge(2), which is not too bad considering
- a little bit later we reduce pledge(2) to only "stdio proc tty" in that
- codepath.
-
- Problem reported and diff provided by Timothy Brown <tbrown at freeshell.org>
-
- OK deraadt@
-
- OpenBSD-Commit-ID: 7ce38b6542bbec00e441595d0a178e970a9472ac
-
-commit 0e2fe18acc1da853a9120c2e9af68e8d05e6503e
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Tue Jul 23 23:06:57 2019 +0000
-
- upstream: Fix typo in CASignatureAlgorithms wherein what should be
-
- a comma is a dot. Patch from hnj2 via github pr#141.
-
- OpenBSD-Commit-ID: 01f5a460438ff1af09aab483c0a70065309445f0
-
-commit e93ffd1a19fc47c49d68ae2fb332433690ecd389
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Mon Jul 29 16:04:01 2019 +1000
-
- Report success of individual tests as well as all.
-
- This puts the "all tests passed" message back at the end where the
- test harnesses can find it.
-
-commit 2ad5b36b18bddf2965fe60384c29b3f1d451b4ed
-Author: Damien Miller <djm@mindrot.org>
-Date: Mon Jul 29 09:49:23 2019 +1000
-
- convert to UTF-8; from Mike Frysinger
-
-commit d31e7c937ba0b97534f373cf5dea34675bcec602
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Fri Jul 26 04:22:21 2019 +0000
-
- upstream: Restrict limit-keytype to types supported by build. This
-
- means we have to skip a couple tests when only one key type is supported.
-
- OpenBSD-Regress-ID: 22d05befb9c7ce21ce8dc22acf1ffe9e2ef2e95e
-
-commit 0967a233b8a28907ae8a4a6773c89f21d2ace11b
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Thu Jul 25 18:36:28 2019 +1000
-
- Remove override disabling DH-GEX.
-
- The DH-GEX override doesn't work when build without OpenSSL, and
- we'll prefer curve25519 these days, removing the need for it.
-
-commit 061407efc19b41ab4a7485e5adcff2a12befacdb
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Thu Jul 25 09:17:35 2019 +0000
-
- upstream: Only use supported key types during KRL test, preferring
-
- ed25519 since it's supported by both OpenSSL and non-OpenSSL builds.
-
- OpenBSD-Regress-ID: 9f2bb3eadd50fcc8245b1bd8fd6f0e53602f71aa
-
-commit 47f8ff1fa5b76790c1d785815fd13ee6009f8012
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Thu Jul 25 08:48:11 2019 +0000
-
- upstream: Switch keys-command test from rsa to ed25519 since it's
-
- supported for both OpenSSL and non-OpenSSL builds.
-
- OpenBSD-Regress-ID: 174be4be876edd493e4a5c851e5bc579885e7a0a
-
-commit 1e94afdfa8df774ab7dd3bad52912b636dc31bbd
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Thu Jul 25 08:28:15 2019 +0000
-
- upstream: Make certificate tests work with the supported key
-
- algorithms. Allows tests to pass when built without OpenSSL.
-
- OpenBSD-Regress-ID: 617169a6dd9d06db3697a449d9a26c284eca20fc
-
-commit 26bf693661a48b97b6023f702b2af643676ac21a
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Tue Jul 23 13:49:14 2019 +0000
-
- upstream: Construct list of key types to test based on the types
-
- supported by the binaries.
-
- OpenBSD-Regress-ID: fcbd115efacec8ab0ecbdb3faef79ac696cb1d62
-
-commit 773c55b3d1230e8f7714a1b33873c37b85049c74
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Tue Jul 23 13:32:48 2019 +0000
-
- upstream: Only use DSA key type in tests if binaries support it.
-
- OpenBSD-Regress-ID: 770e31fe61dc33ed8eea9c04ce839b33ddb4dc96
-
-commit 159e987a54d92ccd73875e7581ffc64e8927a715
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Wed Jul 24 14:21:19 2019 +1000
-
- Split test targets further.
-
- Splits test into file-tests, t-exec, unit and interop-tests and their
- respective dependencies. Should allow running any set individually
- without having to build the other dependencies that are not needed
- for that specific test.
-
-commit 520d4550a2470106d63e30079bb05ce82f3a4f7d
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Wed Jul 24 11:20:18 2019 +1000
-
- Add lib dependencies for regress binary targets.
-
-commit 4e8d0dd78d5f6142841a07dc8b8c6b4730eaf587
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Wed Jul 24 00:12:51 2019 +1000
-
- Make "unit" a dependency of "test".
-
-commit 4317b2a0480e293e58ba115e47b49d3a384b6568
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Tue Jul 23 23:24:47 2019 +1000
-
- upstream rev 1.28: fix comment typo.
-
-commit e0055af2bd39fdb44566ff6594147664e1fac8b8
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Tue Jul 23 23:06:22 2019 +1000
-
- Split regress-binaries into two targets.
-
- Split the binaries for the unit tests out into a regress-unit-binaries
- target, and add a dependency on it for only the unit tests. This allows
- us to run the integration tests only ("make t-exec") without building
- the unit tests, which allows us to run a subset of the tests when
- building --without-openssl without trying (and failing) to build the
- unit tests.
-
- This means there are two targets for "unit" which I *think* is valid
- (it works in testing, and makedepend will generate Makefiles of this
- form)a but I could be wrong.
-
-commit 7cdf9fdcf11aaaa98c2bd22c92882ea559e772ad
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Tue Jul 23 08:19:29 2019 +0000
-
- upstream: Skip DH group generation test if binaries don't support
-
- DH-GEX.
-
- OpenBSD-Regress-ID: 7c918230d969ecf7656babd6191a74526bffbffd
-
-commit 3a3eab8bb0da3d2f0f32cb85a1a268bcca6e4d69
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Tue Jul 23 07:55:29 2019 +0000
-
- upstream: Only test conversion of key types supported by the
-
- binaries.
-
- OpenBSD-Regress-ID: e3f0938a0a7407e2dfbb90abc3ec979ab6e8eeea
-
-commit 7e66b7d98c6e3f48a1918c3e1940c9b11b10ec63
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Tue Jul 23 07:39:43 2019 +0000
-
- upstream: Only add ssh-dss to allowed key types if it's supported
-
- by the binary.
-
- OpenBSD-Regress-ID: 395a54cab16e9e4ece9aec047ab257954eebd413
-
-commit fd0684b319e664d8821dc4ca3026126dfea3ccf4
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Tue Jul 23 22:36:39 2019 +1000
-
- Remove sys/cdefs.h include.
-
- It's not needed on -portable (that's handled by includes.h) and not all
- platforms have it.
-
-commit 9634ffbf29b3c2493e69d10b37077b09a8cbf5ff
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Tue Jul 23 22:25:44 2019 +1000
-
- Add headers to prevent warnings w/out OpenSSL.
-
-commit 2ea60312e1c08dea88982fec68244f89a40912ff
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Tue Jul 23 22:11:50 2019 +1000
-
- Include stdlib.h for free() and calloc().
-
-commit 11cba2a4523fda447e2554ea457484655bedc831
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Tue Jul 23 21:51:22 2019 +1000
-
- Re-apply portability changes to current sha2.{c,h}.
-
- Rather than attempt to apply 14 years' worth of changes to OpenBSD's sha2
- I imported the current versions directly then re-applied the portability
- changes. This also allowed re-syncing digest-libc.c against upstream.
-
-commit 09159594a3bbd363429ee6fafde57ce77986dd7c
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Tue Jul 23 20:27:51 2019 +1000
-
- Import current sha2.c and sha2.h from OpenBSD.
-
- These are not changed from their original state, the next commit will
- re-apply the portable changes.
-
-commit 2e6035b900cc9d7432d95084e03993d1b426f812
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Tue Jul 23 08:11:22 2019 +1000
-
- Rename valgrind "errors" to "failures".
-
- When valgrind is enabled, test-exec.sh counts the number of invocations
- that valgrind detects failures in, not the total number of errors detected.
- This makes the name to be more accurate.
-
-commit e82c9bb9ffa65725cc2e03ea81cb79ce3387f66b
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Fri Jul 19 18:51:18 2019 +1000
-
- Skip running sftp-chroot under Valgrind.
-
-commit 41e22c2e05cb950b704945ac9408f6109c9b7848
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Sat Jul 20 09:50:58 2019 +0000
-
- upstream: Remove the sleeps and thus races from the forwarding
-
- test. They were originally required to work with Protocol 1, but now we can
- use ssh -N and the control socket without the sleeps. While there, suppress
- output fro the control exit commands.
-
- OpenBSD-Regress-ID: 4c51a1d651242f12c90074c18c61008a74c1c790
-
-commit 0423043c5e54293f4dd56041304fd0046c317be9
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Sat Jul 20 09:37:31 2019 +0000
-
- upstream: Allow SLEEPTIME to be overridden.
-
- OpenBSD-Regress-ID: 1596ab168729954be3d219933b2d01cc93687e76
-
-commit d466b6a5cfba17a83c7aae9f584ab164e2ece0a1
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Sat Jul 20 09:14:40 2019 +0000
-
- upstream: Move sleep time into a variable so that we can increase
-
- it for platforms or configurations that are much slower then usual.
-
- OpenBSD-Regress-ID: 88586cabc800062c260d0b876bdcd4ca3f58a872
-
-commit b4a7c9d2b5f928e0b902b580d35dc8b244a3aae0
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Jul 19 03:45:44 2019 +0000
-
- upstream: add regression tests for scp for out-of-destination path file
-
- creation by Harry Sintonen via Jakub Jelen in bz3007
-
- OpenBSD-Regress-ID: 01ae5fbc6ce400b2df5a84dc3152a9e31f354c07
-
-commit bca0582063f148c7ddf409ec51435a5a726bee4c
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Jul 19 03:38:01 2019 +0000
-
- upstream: Accept the verbose flag when searching for host keys in known
-
- hosts (i.e. "ssh-keygen -vF host") to print the matching host's random- art
- signature too. bz#3003 "amusing, pretty" deraadt@
-
- OpenBSD-Commit-ID: 686221a5447d6507f40a2ffba5393984d889891f
-
-commit 5299a09fa2879a068af200c91028fcfa9283c0f0
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Fri Jul 19 13:50:25 2019 +1000
-
- Revert one dependency per line change.
-
- It turns out that having such a large number of lines in the .depend
- file will cause the memory usage of awk during AC_SUBST to blow up on at
- least NetBSD's awk, causing configure to fail.
-
-commit 01dddb231f23b4a7b616f9d33a0b9d937f9eaf0e
-Author: Damien Miller <djm@mindrot.org>
-Date: Fri Jul 19 13:19:19 2019 +1000
-
- fix SIGWINCH delivery of Solaris for mux sessions
-
- Remove PRIV_PROC_SESSION which was limiting ability to send SIGWINCH
- signals to other sessions. bz#3030; report and fix from Darren Moffat
-
-commit 05500af21d27c1a3ddac232b018cc23da7b1ee95
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Fri Jul 19 13:20:03 2019 +1000
-
- Force dependencies one per line.
-
- Force makedepend to output one dependency per line, which will make
- reading diffs against it much easier. ok djm@
-
-commit b5bc5d016bbb83eb7f8e685390044e78b1ea1427
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Fri Jul 19 13:18:07 2019 +1000
-
- make depend.
-
-commit 65333f7454365fe40f7367630e7dd10903b9d99e
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Fri Jul 19 13:16:11 2019 +1000
-
- Show when skipping valgrind for a test.
-
-commit fccb7eb3436da8ef3dcd22e5936ba1abc7ae6730
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Fri Jul 19 10:41:56 2019 +1000
-
- Enable connect-privsep test with valgrind.
-
- connect-privsep seems to work OK with valgrind now so don't skip
- valgrind on it.
-
-commit d7423017265c5ae6d0be39340feb6c9f016b1f71
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Fri Jul 19 07:43:07 2019 +1000
-
- Show valgrind results and error counts.
-
-commit 22b9b3e944880db906c6ac5527c4228bd92b293a
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Thu Jul 18 13:40:12 2019 +1000
-
- Fix format string integer type in error message.
-
-commit ed46a0c0705895834d3f47a46faa89c2a71b760a
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Thu Jul 18 13:26:00 2019 +0000
-
- upstream: fix off-by-one in sshbuf_dtob64() base64 wrapping that could
-
- cause extra newlines to be appended at the end of the base64 text (ugly, but
- harmless). Found and fixed by Sebastian Kinne
-
- OpenBSD-Commit-ID: 9fe290bd68f706ed8f986a7704ca5a2bd32d7b68
-
-commit a192021fedead23c375077f92346336d531f8cad
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Thu Jul 18 11:09:38 2019 +1000
-
- Fail tests if Valgrind enabled and reports errors.
-
- Also dump the failing valgrind report to stdout (not the cleanest
- solution, but better than nothing).
-
-commit d1c491ecb939ee10b341fa7bb6205dff19d297e5
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Thu Jul 18 10:17:54 2019 +1000
-
- Allow low-priv tests to write to pipe dir.
-
- When running regression tests with Valgrind and SUDO, the low-priv agent
- tests need to be able to create pipes in the appropriate directory.
-
-commit 8a5bb3e78191cc206f970c26d2a26c949971e91a
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Wed Jul 17 21:24:55 2019 +1000
-
- Put valgrind vgdb files to a specific directory.
-
- Valgrind by default puts vgdb files and pipes under /tmp, however it
- is not always able to clean them up, which can cause test failures when
- there's a pid/file collision. Using a specific directory ensures that
- we can clean up and start clean.
-
-commit f8829fe57fb0479d6103cfe1190095da3c032c6d
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Tue Jul 16 22:16:49 2019 +0000
-
- upstream: adapt to sshbuf_dtob64() change
-
- OpenBSD-Regress-ID: 82374a83edf0955fd1477169eee3f5d6467405a6
-
-commit 1254fcbb2f005f745f2265016ee9fa52e16d37b0
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Tue Jul 16 03:21:54 2019 +0000
-
- upstream: Remove ssh1 files from CLEANFILES since ssh1 no longer
-
- supported.
-
- OpenBSD-Regress-ID: 5b9ae869dc669bac05939b4a2fdf44ee067acfa0
-
-commit 9dc81a5adabc9a7d611ed2e63fbf4c85d43b15c6
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Tue Jul 16 02:09:29 2019 +0000
-
- upstream: Update names of host key files in CLEANFILES to match
-
- recent changes to the tests.
-
- OpenBSD-Regress-ID: 28743052de3acf70b06f18333561497cd47c4ecf
-
-commit e44e4ad1190db22ed407a79f32a8cff5bcd2b815
-Author: Damien Miller <djm@mindrot.org>
-Date: Tue Jul 16 23:26:53 2019 +1000
-
- depend
-
-commit 16dd8b2c78a0de106c7429e2a294d203f6bda3c7
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Tue Jul 16 13:18:39 2019 +0000
-
- upstream: remove mostly vestigal uuencode.[ch]; moving the only unique
-
- functionality there (wrapping of base64-encoded data) to sshbuf functions;
- feedback and ok markus@
-
- OpenBSD-Commit-ID: 4dba6735d88c57232f6fccec8a08bdcfea44ac4c
-
-commit 45478898f9590b5cc8bc7104e573b84be67443b0
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Tue Jul 16 09:20:23 2019 +1000
-
- Hook memmem compat code into build.
-
- This fixes builds on platforms that don't have it (at least old DragonFly,
- probably others).
-
-commit c7bd4617293a903bd3fac3394a7e72d439af49a5
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Tue Jul 16 09:07:18 2019 +1000
-
- Import memmem.c from OpenBSD.
-
-commit 477e2a3be8b10df76e8d76f0427b043280d73d68
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Mon Jul 15 13:12:02 2019 +0000
-
- upstream: unit tests for sshbuf_cmp() and sshbuf_find(); ok markus
-
- OpenBSD-Regress-ID: b52d36bc3ab6dc158c1e59a9a4735f821cf9e1fd
-
-commit eb0d8e708a1f958aecd2d6e2ff2450af488d4c2a
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Mon Jul 15 13:16:29 2019 +0000
-
- upstream: support PKCS8 as an optional format for storage of
-
- private keys, enabled via "ssh-keygen -m PKCS8" on operations that save
- private keys to disk.
-
- The OpenSSH native key format remains the default, but PKCS8 is a
- superior format to PEM if interoperability with non-OpenSSH software
- is required, as it may use a less terrible KDF (IIRC PEM uses a single
- round of MD5 as a KDF).
-
- adapted from patch by Jakub Jelen via bz3013; ok markus
-
- OpenBSD-Commit-ID: 027824e3bc0b1c243dc5188504526d73a55accb1
-
-commit e18a27eedccb024acb3cd9820b650a5dff323f01
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Mon Jul 15 13:11:38 2019 +0000
-
- upstream: two more bounds-checking sshbuf counterparts to common
-
- string operations: sshbuf_cmp() (bcmp-like) and sshbuf_find() (memmem like)
-
- feedback and ok markus@
-
- OpenBSD-Commit-ID: fd071ec2485c7198074a168ff363a0d6052a706a
-
-commit bc551dfebb55845537b1095cf3ccd01640a147b7
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Mon Jul 15 12:52:45 2019 +1000
-
- Clear valgrind-out dir to prevent collisions.
-
-commit 5db9ba718e983661a9114ae1418f6e412d1f52d5
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Mon Jul 15 12:02:27 2019 +1000
-
- Allow agent tests to write to valgrind dir.
-
-commit 121e48fa5305f41f0477d9908e3d862987a68a84
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sun Jul 14 23:33:19 2019 +0000
-
- upstream: unit tests for sshbuf_peek/poke bounds-checked random access
-
- functions. ok markus@
-
- OpenBSD-Regress-ID: 034c4284b1da6b12e25c762a6b958efacdafbaef
-
-commit 101d164723ffbc38f8036b6f3ea3bfef771ba250
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sun Jul 14 23:32:27 2019 +0000
-
- upstream: add some functions to perform random-access read/write
-
- operations inside buffers with bounds checking. Intended to replace manual
- pointer arithmetic wherever possible.
-
- feedback and ok markus@
-
- OpenBSD-Commit-ID: 91771fde7732738f1ffed078aa5d3bee6d198409
-
-commit 7250879c72d28275a53f2f220e49646c3e42ef18
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Jul 12 04:08:39 2019 +0000
-
- upstream: include SHA2-variant RSA key algorithms in KEX proposal;
-
- allows ssh-keyscan to harvest keys from servers that disable olde SHA1
- ssh-rsa. bz#3029 from Jakub Jelen
-
- OpenBSD-Commit-ID: 9f95ebf76a150c2f727ca4780fb2599d50bbab7a
-
-commit a0876bd994cab9ba6e47ba2a163a4417c7597487
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Jul 12 03:56:21 2019 +0000
-
- upstream: print explicit "not modified" message if a file was
-
- requested for resumed download but was considered already complete.
-
- bz#2978 ok dtucker
-
- OpenBSD-Commit-ID: f32084b26a662f16215ee4ca4a403d67e49ab986
-
-commit b9b0f2ac9625933db53a35b1c1ce423876630558
-Author: tb@openbsd.org <tb@openbsd.org>
-Date: Wed Jul 10 07:04:27 2019 +0000
-
- upstream: Fix a typo and make <esc><right> move right to the
-
- closest end of a word just like <esc><left> moves left to the closest
- beginning of a word.
-
- ok djm
-
- OpenBSD-Commit-ID: 6afe01b05ed52d8b12eb1fda6e9af5afb5e198ee
-
-commit 8729498a5d239980a91d32f031b34e8c58c52f62
-Author: Damien Miller <djm@mindrot.org>
-Date: Wed Jul 10 09:43:19 2019 +1000
-
- fix typo that prevented detection of Linux VRF
-
- Reported by hexiaowen AT huawei.com
-
-commit 5b2b79ff7c057ee101518545727ed3023372891d
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Tue Jul 9 04:15:00 2019 +0000
-
- upstream: cap the number of permiopen/permitlisten directives we're
-
- willing to parse on a single authorized_keys line; ok deraadt@
-
- OpenBSD-Commit-ID: a43a752c2555d26aa3fc754805a476f6e3e30f46
-
-commit eb0b51dac408fadd1fd13fa6d726ab8fdfcc4152
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Mon Jul 8 17:27:26 2019 +1000
-
- Move log.h include inside ifdefs.
-
- Fixes build on some other platforms that don't have va_list immediately
- available (eg NetBSD).
-
-commit 43702f8e6fa22a258e25c4dd950baaae0bc656b7
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Sat Jul 6 23:07:04 2019 +1000
-
- Include log.h for debug() and friends.
-
- Should fix some compiler warnings on IRIX (bz#3032).
-
-commit 53a6ebf1445a857f5e487b18ee5e5830a9575149
-Author: Damien Miller <djm@mindrot.org>
-Date: Mon Jul 8 13:44:32 2019 +1000
-
- sftp-realpath.c needs includes.h
-
-commit 4efe1adf05ee5d3fce44320fcff68735891f4ee6
-Author: Damien Miller <djm@mindrot.org>
-Date: Mon Jul 8 13:38:39 2019 +1000
-
- remove realpath() compat replacement
-
- We shipped a BSD implementation of realpath() because sftp-server
- depended on its behaviour.
-
- OpenBSD is now moving to a more strictly POSIX-compliant realpath(2),
- so sftp-server now unconditionally requires its own BSD-style realpath
- implementation. As such, there is no need to carry another independant
- implementation in openbsd-compat.
-
- ok dtucker@
-
-commit 696fb4298e80f2ebcd188986a91b49af3b7ca14c
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Sun Jul 7 01:05:00 2019 +0000
-
- upstream: Remove some set but never used variables. ok daraadt@
-
- OpenBSD-Commit-ID: 824baf9c59afc66a4637017e397b9b74a41684e7
-
-commit 156e9e85e92b46ca90226605d9eff49e8ec31b22
-Author: deraadt@openbsd.org <deraadt@openbsd.org>
-Date: Fri Jul 5 12:35:40 2019 +0000
-
- upstream: still compile uuencode.c, unbreaks build
-
- OpenBSD-Commit-ID: 5ea3d63ab972691f43e9087ab5fd8376d48e898f
-
-commit cec9ee527a12b1f6c2e0a1c155fec64a38d71cf6
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Jul 5 07:32:01 2019 +0000
-
- upstream: revert header removal that snuck into previous
-
- OpenBSD-Commit-ID: 3919cdd58989786660b8269b325646ef8856428e
-
-commit 569b650f93b561c09c655f83f128e1dfffe74101
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Jul 5 04:55:40 2019 +0000
-
- upstream: add a local implementation of BSD realpath() for
-
- sftp-server use ahead of OpenBSD's realpath changing to match POSIX;
-
- ok deraadt@ (thanks for snaps testing)
-
- OpenBSD-Commit-ID: 4f8cbf7ed8679f6237264301d104ecec64885d55
-
-commit b8e2b797362526437e0642a6c2f2970d794f2561
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Sat Jul 6 13:13:57 2019 +1000
-
- Add prototype for strnlen to prevent warnings.
-
-commit 4c3e00b1ed7e596610f34590eb5d54ee50d77878
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Sat Jul 6 13:02:34 2019 +1000
-
- Cast *ID types to unsigned long when printing.
-
- UID and GID types vary by platform so cast to u_long and use %lu when
- printing them to prevent warnings.
-
-commit 2753521e899f30d1d58b5da0b4e68fde6fcf341e
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Sat Jul 6 12:54:43 2019 +1000
-
- Add prototype for compat strndup.(bz#3032).
-
-commit 01a1e21cd55d99293c8ff8ed7c590f2ee440da43
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Sat Jul 6 12:00:41 2019 +1000
-
- Add missing bracket in EGD seeding code.
-
- When configured --with-prngd-socket the code had a missing bracket after
- an API change. Fix that and a couple of warnings. bz#3032 , from
- ole.weidner at protonmail.ch
-
-commit e187b1d4607392cf2c19243afe0d0311a4ff3591
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Fri Jul 5 04:19:39 2019 +0000
-
- upstream: Add (recently added) rsa_oldfmt to CLEANFILES.
-
- OpenBSD-Regress-ID: 405beda94e32aa6cc9c80969152fab91f7c54bd3
-
-commit 74b541bfabdcb57c1683cd9b3f1d1f4d5e41563e
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Fri Jul 5 04:12:46 2019 +0000
-
- upstream: Adapt the PuTTY/Conch tests to new key names.
-
- A recent regress change (2a9b3a2ce411d16cda9c79ab713c55f65b0ec257 in
- portable) broke the PuTTY and Twisted Conch interop tests, because the
- key they want to use is now called ssh-rsa rather than rsa. Adapt the
- tests to the new file names. bz#3020, patch from cjwatson at debian.org.
-
- OpenBSD-Regress-ID: fd342a37db4d55aa4ec85316f73082c8eb96e64e
-
-commit de08335a4cfaa9b7081e94ea4a8b7153c230546d
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Fri Jul 5 04:03:13 2019 +0000
-
- upstream: Add a sleep to allow forwards to come up.
-
- Currently when the multiplex client requests a forward it returns
- once the request has been sent but not necessarily when the forward
- is up. This causes intermittent text failures due to this race,
- so add some sleeps to mitigate this until we can fix it properly.
-
- OpenBSD-Regress-ID: 384c7d209d2443d25ea941d7f677e932621fb253
-
-commit 4d249284729f864faa2e8f3e015f9a41b674544a
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Fri Jul 5 14:58:57 2019 +1000
-
- Remove nc stderr redirection to resync w/OpenBSD.
-
-commit c5cfa90e03432181ffcc7ad3f9f815179bd0c626
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Fri Jul 5 13:21:45 2019 +1000
-
- Do not fatal on failed lookup of group "tty".
-
- Some platforms (eg AIX and Cygwin) do not have a "tty" group. In those
- cases we will fall back to making the tty device the user's primary
- group, so do not fatal if the group lookup fails. ok djm@
-
-commit 8b4cc4bdc8a70bf209a274fa2b2a49c1e3c8d8a2
-Author: deraadt@openbsd.org <deraadt@openbsd.org>
-Date: Thu Jul 4 16:20:10 2019 +0000
-
- upstream: fatal() if getgrnam() cannot find "tty"
-
- OpenBSD-Commit-ID: d148c1c052fa0ed7d105b5428b5c1bab91630048
-
-commit 48cccc275c6a1e91d3f80fdb0dc0d5baf529aeca
-Author: deraadt@openbsd.org <deraadt@openbsd.org>
-Date: Thu Jul 4 16:16:51 2019 +0000
-
- upstream: stat() returns precisely -1 to indicate error
-
- OpenBSD-Commit-ID: 668e8d022ed4ab847747214f64119e5865365fa1
-
-commit 8142fcaf9ed8ff66252deecbfd29fc59d5f2df4f
-Author: deraadt@openbsd.org <deraadt@openbsd.org>
-Date: Wed Jul 3 03:24:02 2019 +0000
-
- upstream: snprintf/vsnprintf return < 0 on error, rather than -1.
-
- OpenBSD-Commit-ID: a261c421140a0639bb2b66bbceca72bf8239749d
-
-commit 4d28fa78abce2890e136281950633fae2066cc29
-Author: deraadt@openbsd.org <deraadt@openbsd.org>
-Date: Fri Jun 28 13:35:04 2019 +0000
-
- upstream: When system calls indicate an error they return -1, not
-
- some arbitrary value < 0. errno is only updated in this case. Change all
- (most?) callers of syscalls to follow this better, and let's see if this
- strictness helps us in the future.
-
- OpenBSD-Commit-ID: 48081f00db7518e3b712a49dca06efc2a5428075
-
-commit e8c974043c1648eab0ad67a7ba6a3e444fe79d2d
-Author: deraadt@openbsd.org <deraadt@openbsd.org>
-Date: Fri Jun 28 05:44:09 2019 +0000
-
- upstream: asprintf returns -1, not an arbitrary value < 0. Also
-
- upon error the (very sloppy specification) leaves an undefined value in *ret,
- so it is wrong to inspect it, the error condition is enough. discussed a
- little with nicm, and then much more with millert until we were exasperated
-
- OpenBSD-Commit-ID: 29258fa51edf8115d244b9d4b84028487bf8923e
-
-commit 1b2d55d15c6240c15a1e1cf4203b82e54a766272
-Author: deraadt@openbsd.org <deraadt@openbsd.org>
-Date: Fri Jun 28 01:23:50 2019 +0000
-
- upstream: oops, from asou
-
- OpenBSD-Commit-ID: 702e765d1639b732370d8f003bb84a1c71c4d0c6
-
-commit 5cdbaa78fcb718c39af4522d98016ad89d065427
-Author: deraadt@openbsd.org <deraadt@openbsd.org>
-Date: Thu Jun 27 18:03:37 2019 +0000
-
- upstream: Some asprintf() calls were checked < 0, rather than the
-
- precise == -1. ok millert nicm tb, etc
-
- OpenBSD-Commit-ID: caecf8f57938685c04f125515b9f2806ad408d53
-
-commit b2e3e57be4a933d9464bccbe592573725765486f
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Thu Jun 27 06:29:35 2019 +0000
-
- upstream: fix NULL deference (bzero) on err
-
- =?UTF-8?q?or=20path=20added=20in=20last=20commit;=20spotted=20by=20Reynir?=
- =?UTF-8?q?=20Bj=C3=B6rnsson?=
- MIME-Version: 1.0
- Content-Type: text/plain; charset=UTF-8
- Content-Transfer-Encoding: 8bit
-
- ok deraadt@ markus@ tb@
-
- OpenBSD-Commit-ID: b11b084bcc551b2c630560eb08618dd501027bbd
-
-commit 58ceacdcbaebefc77d120712de55c6fc6aa32bb1
-Author: Jitendra Sharma <jitendra.sharma@intel.com>
-Date: Fri Jun 21 09:54:17 2019 +0530
-
- Update README doc to include missing test cases
-
- Readme regress document is missing various individual tests,
- which are supported currently. Update README to
- include those test cases.
-
-commit 7959330a554051b5587f8af3fec0c2c0d5820f64
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Wed Jun 26 22:29:43 2019 +0000
-
- upstream: Remove unneeded unlink of xauthfile o
-
- =?UTF-8?q?n=20error=20path.=20=20From=20Erik=20Sj=C3=B6lund=20via=20githu?=
- =?UTF-8?q?b,=20ok=20djm@=20deraadt@?=
- MIME-Version: 1.0
- Content-Type: text/plain; charset=UTF-8
- Content-Transfer-Encoding: 8bit
-
- OpenBSD-Commit-ID: 62a4893cf83b29a4bbfedc40e7067c25c203e632
-
-commit 8de52eb224143783a49f9bddd9ab7800022a8276
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sun Jun 23 12:21:46 2019 +0000
-
- upstream: fix mismatch proto/decl from key shielding change; spotted
-
- via oss-fuzz
-
- OpenBSD-Commit-ID: 1ea0ba05ded2c5557507bd844cd446e5c8b5b3b7
-
-commit 1dfadb9b57c2985c95838a0292d1c2f6a501896e
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Jun 21 04:21:45 2019 +0000
-
- upstream: adapt for key shielding API changes (const removal)
-
- OpenBSD-Regress-ID: 298890bc52f0cd09dba76dc1022fabe89bc0ded6
-
-commit 4f7a56d5e02e3d04ab69eac1213817a7536d0562
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Jun 21 04:21:04 2019 +0000
-
- upstream: Add protection for private keys at rest in RAM against
-
- speculation and memory sidechannel attacks like Spectre, Meltdown, Rowhammer
- and Rambleed. This change encrypts private keys when they are not in use with
- a symmetic key that is derived from a relatively large "prekey" consisting of
- random data (currently 16KB).
-
- Attackers must recover the entire prekey with high accuracy before
- they can attempt to decrypt the shielded private key, but the current
- generation of attacks have bit error rates that, when applied
- cumulatively to the entire prekey, make this unlikely.
-
- Implementation-wise, keys are encrypted "shielded" when loaded and then
- automatically and transparently unshielded when used for signatures or
- when being saved/serialised.
-
- Hopefully we can remove this in a few years time when computer
- architecture has become less unsafe.
-
- been in snaps for a bit already; thanks deraadt@
-
- ok dtucker@ deraadt@
-
- OpenBSD-Commit-ID: 19767213c312e46f94b303a512ef8e9218a39bd4
-
-commit 4cd6b12cc9c10bf59c8b425041f3ea5091285a0f
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Jun 21 03:19:59 2019 +0000
-
- upstream: print the correct AuthorizedPrincipalsCommand rather than
-
- an uninitialised variable; spotted by dtucker@
-
- OpenBSD-Commit-ID: 02802018784250f68202f01c8561de82e17b0638
-
-commit 5f68ab436b0e01751d564e9a9041e6ac3673e45a
-Author: jmc@openbsd.org <jmc@openbsd.org>
-Date: Wed Jun 19 20:12:44 2019 +0000
-
- upstream: from tim: - for reput, it is remote-path which is
-
- optional, not local-path - sync help
-
- from deraadt:
- - prefer -R and undocument -r (but add a comment for future editors)
-
- from schwarze:
- - prefer -p and undocument -P (as above. the comment was schwarze's too)
-
- more:
- - add the -f flag to reput and reget
- - sort help (i can;t remember who suggested this originally)
-
- djm and deraadt were ok with earlier versions of this;
- tim and schwarze ok
-
- OpenBSD-Commit-ID: 3c699b53b46111f5c57eed4533f132e7e58bacdd
-
-commit 99bcbbc77fbd5a5027031f42a5931b21b07c947e
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Jun 14 04:03:48 2019 +0000
-
- upstream: check for convtime() refusing to accept times that
-
- resolve to LONG_MAX Reported by Kirk Wolf bz2977; ok dtucker
-
- OpenBSD-Regress-ID: 15c9fe87be1ec241d24707006a31123d3a3117e0
-
-commit e5cccb2410247c9b8151b9510a876abdf5424b24
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Sun Apr 28 22:53:26 2019 +0000
-
- upstream: Add unit tests for user@host and URI parsing.
-
- OpenBSD-Regress-ID: 69d5b6f278e04ed32377046f7692c714c2d07a68
-
-commit 0bb7e38834e3f9886302bbaea630a6b0f8cfb520
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Thu Apr 18 18:57:16 2019 +0000
-
- upstream: Add tests for sshd -T -C with Match.
-
- OpenBSD-Regress-ID: d4c34916fe20d717692f10ef50b5ae5a271c12c7
-
-commit 73eb6cef41daba0359c1888e4756108d41b4e819
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Sun Jun 16 12:55:27 2019 +1000
-
- Include stdio.h for vsnprintf.
-
- Patch from mforney at mforney.org.
-
-commit adcaf40fd0a180e6cb5798317fdf479b52e3c09a
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Sat Jun 8 09:07:04 2019 +1000
-
- upstream rev 1.27: fix integer overflow.
-
- Cast bitcount to u_in64_t before bit shifting to prevent integer overflow
- on 32bit platforms which cause incorrect results when adding a block
- >=512M in size. sha1 patch from ante84 at gmail.com via openssh github,
- sha2 with djm@, ok tedu@
-
-commit 7689048e6103d3c34cba24ac5aeea7bf8405d19a
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Sat Jun 8 09:06:06 2019 +1000
-
- upstream rev 1.25: add DEF_WEAK.
-
- Wrap blowfish, sha*, md5, and rmd160 so that internal calls go direct
- ok deraadt@
-
-commit 55f3153393ac7e072a4b4b21b194864460d8f44a
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Sat Jun 8 09:02:24 2019 +1000
-
- upstream rev 1.25: add sys/types.h
-
-commit 10974f986fa842a3a3a693e3d5761072540002b4
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Sat Jun 8 09:01:14 2019 +1000
-
- upstream: Use explicit_bzero instead of memset
-
- in hash Final and End functions. OK deraadt@ djm@
-
-commit cb8f56570f70b00abae4267d4bcce2bfae7dfff6
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Jun 14 04:13:58 2019 +0000
-
- upstream: slightly more instructive error message when the user
-
- specifies multiple -J options on the commandline. bz3015 ok dtucker@
-
- OpenBSD-Commit-ID: 181c15a65cac3b575819bc8d9a56212c3c748179
-
-commit 2317ce4b0ed7d8c4b0c684e2d47bff5006bd1178
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Jun 14 03:51:47 2019 +0000
-
- upstream: process agent requests for RSA certificate private keys using
-
- correct signature algorithm when requested. Patch from Jakub Jelen in bz3016
- ok dtucker markus
-
- OpenBSD-Commit-ID: 61f86efbeb4a1857a3e91298c1ccc6cf49b79624
-
-commit c95b90d40170473825904be561b1eafba354f376
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Jun 14 03:39:59 2019 +0000
-
- upstream: for public key authentication, check AuthorizedKeysFiles
-
- files before consulting AuthorizedKeysCommand; ok dtucker markus
-
- OpenBSD-Commit-ID: 13652998bea5cb93668999c39c3c48e8429db8b3
-
-commit a5a53914989ddd3521b6edc452bc3291784a4f4f
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Jun 14 03:28:19 2019 +0000
-
- upstream: if passed a bad fd, log what it was
-
- OpenBSD-Commit-ID: 582e2bd05854e49365195b58989b68ac67f09140
-
-commit 7349149da1074d82b71722338e05b6a282f126cc
-Author: jmc@openbsd.org <jmc@openbsd.org>
-Date: Wed Jun 12 11:31:50 2019 +0000
-
- upstream: Hostname->HostName cleanup; from lauri tirkkonen ok
-
- dtucker
-
- OpenBSD-Commit-ID: 4ade73629ede63b691f36f9a929f943d4e7a44e4
-
-commit 76af9c57387243556d38935555c227d0b34062c5
-Author: jmc@openbsd.org <jmc@openbsd.org>
-Date: Wed Jun 12 05:53:21 2019 +0000
-
- upstream: deraadt noticed some inconsistency in the way we denote
-
- the "Hostname" and "X11UseLocalhost" keywords; this makes things consistent
- (effectively reversing my commit of yesterday);
-
- ok deraadt markus djm
-
- OpenBSD-Commit-ID: 255c02adb29186ac91dcf47dfad7adb1b1e54667
-
-commit d1bbfdd932db9b9b799db865ee1ff50060dfc895
-Author: jmc@openbsd.org <jmc@openbsd.org>
-Date: Tue Jun 11 13:39:40 2019 +0000
-
- upstream: consistent lettering for "HostName" keyword; from lauri
-
- tirkkonen
-
- OpenBSD-Commit-ID: 0c267a1257ed7482b13ef550837b6496e657d563
-
-commit fc0340f7c4ee29bfb12bd1de9f99defa797e16b4
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Sat Jun 8 00:10:59 2019 +1000
-
- Typo fixes in error messages.
-
- Patch from knweiss at gmail.com via github pull req #97 (portable-
- specific parts).
-
-commit 4b7dd22b02b64b1ededd3c0e98a6e7ae21e31d38
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Fri Jun 7 14:18:48 2019 +0000
-
- upstream: Typo and spelling fixes in comments and error messages.
-
- Patch from knweiss at gmail.com via -portable.
-
- OpenBSD-Commit-ID: 2577465442f761a39703762c4f87a8dfcb918b4b
-
-commit 130ef0695e1731392ca33831939fe89e8b70cc17
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Sat Jun 8 00:47:07 2019 +1000
-
- Include missed bits from previous sync.
-
-commit 25e3bccbaa63d27b9d5e09c123f1eb28594d2bd6
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Fri Jun 7 03:47:12 2019 +0000
-
- upstream: Check for user@host when parsing sftp target. This
-
- allows user@[1.2.3.4] to work without a path in addition to with one.
- bz#2999, ok djm@
-
- OpenBSD-Commit-ID: d989217110932490ba8ce92127a9a6838878928b
-
-commit 0323d9b619d512f80c57575b810a05791891f657
-Author: otto@openbsd.org <otto@openbsd.org>
-Date: Thu Jun 6 05:13:13 2019 +0000
-
- upstream: Replace calls to ssh_malloc_init() by a static init of
-
- malloc_options. Prepares for changes in the way malloc is initialized. ok
- guenther@ dtucker@
-
- OpenBSD-Commit-ID: 154f4e3e174f614b09f792d4d06575e08de58a6b
-
-commit c586d2d3129265ea64b12960c379d634bccb6535
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri May 31 03:20:07 2019 +0000
-
- upstream: fix ssh-keysign fd handling problem introduced in r1.304
-
- caused by a typo (STDIN_FILENO vs STDERR_FILENO)
-
- OpenBSD-Commit-ID: 57a0b4be7bef23963afe24150e24bf014fdd9cb0
-
-commit 410b231aa41ff830b2f5b09b5aaf5e5cdc1ab86b
-Author: lum@openbsd.org <lum@openbsd.org>
-Date: Wed May 29 08:30:26 2019 +0000
-
- upstream: Make the standard output messages of both methods of
-
- changing a key pair's comments (using -c and -C) more applicable to both
- methods. ok and suggestions djm@ dtucker@
-
- OpenBSD-Commit-ID: b379338118109eb36e14a65bc0a12735205b3de6
-
-commit 2b3402dc9f1d9b0df70291b424f36e436cdfa7e0
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Sat Jun 8 00:03:07 2019 +1000
-
- Always clean up before and after utimensat test.
-
-commit 182898192d4b720e4faeafd5b39c2cfb3b92aa21
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Fri Jun 7 23:47:37 2019 +1000
-
- Update utimensat test.
-
- 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 instead of following a
- symlink when explicitly asked not to. Instead of checking for an explicit
- failure, check that it does not update the destination, which both the
- real and compat implmentations should honour.
-
- Inspired by github pull req #125 from chutzpah at gentoo.org.
-
-commit d220b675205185e0b4d6b6524acc2e5c599ef0e2
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Fri Jun 7 14:26:54 2019 +1000
-
- Have pthread_create return errno on failure.
-
- According to POSIX, pthread_create returns the failure reason in
- the non-zero function return code so make the fork wrapper do that.
- Matches previous change.
-
-commit 1bd4f7f25f653e0cadb2e6f25d79bc3c35c6aa4d
-Author: Elliott Hughes <enh@google.com>
-Date: Thu Apr 25 13:36:27 2019 -0700
-
- pthread_create(3) returns positive values on failure.
-
- Found by inspection after finding similar bugs in other code used by
- Android.
-
-commit b3a77b25e5f7880222b179431a74fad76d2cf60c
-Author: Harald Freudenberger <freude@linux.ibm.com>
-Date: Fri May 24 10:11:15 2019 +0200
-
- allow s390 specific ioctl for ecc hardware support
-
- Adding another s390 specific ioctl to be able to support ECC hardware
- acceleration to the sandbox seccomp filter rules.
-
- Now the ibmca openssl engine provides elliptic curve cryptography
- support with the help of libica and CCA crypto cards. This is done via
- jet another ioctl call to the zcrypt device driver and so there is a
- need to enable this on the openssl sandbox.
-
- Code is s390 specific and has been tested, verified and reviewed.
-
- Please note that I am also the originator of the previous changes in
- that area. I posted these changes to Eduardo and he forwarded the
- patches to the openssl community.
-
- Signed-off-by: Harald Freudenberger <freude@linux.ibm.com>
- Reviewed-by: Joerg Schmidbauer <jschmidb@de.ibm.com>
-
-commit 2459df9aa11820f8092a8651aeb381af7ebbccb1
-Author: Sorin Adrian Savu <sorin25@users.noreply.github.com>
-Date: Sun May 26 21:50:08 2019 +0300
-
- openssl-devel is obsoleted by libssl-devel
-
- openssl-devel is no longer installable via the cygwin setup and
- it's hidden by default, so you can't see the replacement very easy.
-
-commit 85ceb0e64bff672558fc87958cd548f135c83cdd
-Author: jmc@openbsd.org <jmc@openbsd.org>
-Date: Mon May 20 06:01:59 2019 +0000
-
- upstream: tweak previous;
-
- OpenBSD-Commit-ID: 42f39f22f53cfcb913bce401ae0f1bb93e08dd6c
-
-commit 30615295609f5c57b3137b3021fe63bfa45c1985
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Mon May 20 00:25:55 2019 +0000
-
- upstream: embiggen format buffer size for certificate serial number so
-
- that it will fit a full 64 bit integer. bz#3012 from Manoel Domingues Junior
-
- OpenBSD-Commit-ID: a51f3013056d05b976e5af6b978dcb9e27bbc12b
-
-commit 476e3551b2952ef73acc43d995e832539bf9bc4d
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Mon May 20 00:20:35 2019 +0000
-
- upstream: When signing certificates with an RSA key, default to
-
- using the rsa-sha2-512 signature algorithm. Certificates signed by RSA keys
- will therefore be incompatible with OpenSSH < 7.2 unless the default is
- overridden.
-
- Document the ability of the ssh-keygen -t flag to override the
- signature algorithm when signing certificates, and the new default.
-
- ok deraadt@
-
- OpenBSD-Commit-ID: 400c9c15013978204c2cb80f294b03ae4cfc8b95
-
-commit 606077ee1e77af5908431d003fb28461ef7be092
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Fri May 17 13:14:12 2019 +1000
-
- Add no-op implementation of pam_putenv.
-
- Some platforms such as HP-UX do not have pam_putenv. Currently the
- calls are ifdef'ed out, but a new one was recently added. Remove the
- ifdefs and add a no-op implementation. bz#3008, ok djm.
-
-commit 1ac98be8724c9789d770ddb8e7f0dbf1b55e05a0
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Fri May 17 12:42:17 2019 +1000
-
- Use the correct macro for SSH_ALLOWED_CA_SIGALGS.
-
-commit 97370f6c2c3b825f8c577b7e6c00b1a98d30a6cf
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Fri May 17 10:54:51 2019 +1000
-
- Fix building w/out ECC.
-
- Ifdef out ECC specific code so that that it'll build against an OpenSSL
- configured w/out ECC. With & ok djm@
-
-commit 633703babf8d9a88da85f23b800e1b88dec7cdbd
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Fri May 17 10:50:29 2019 +1000
-
- Conditionalize ECDH methods in CA algos.
-
- When building against an OpenSSL configured without ECC, don't include
- those algos in CASignatureAlgorithms. ok djm@
-
-commit 5c8d14c512f5d413095b22bdba08a6bb990f1e97
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Thu May 16 08:47:27 2019 +0000
-
- upstream: Move a variable declaration to the block where it's used
-
- to make things a little tidier for -portable.
-
- OpenBSD-Commit-ID: 616379861be95619e5358768b7dee4793e2f3a75
-
-commit a1d29cc36a5e6eeabc935065a8780e1ba5b67014
-Author: deraadt@openbsd.org <deraadt@openbsd.org>
-Date: Wed May 15 04:43:31 2019 +0000
-
- upstream: When doing the fork+exec'ing for ssh-keysign, rearrange
-
- the socket into fd3, so as to not mistakenly leak other fd forward
- accidentally. ok djm
-
- OpenBSD-Commit-ID: 24cc753f5aa2c6a7d0fbf62766adbc75cd785296
-
-commit db7606d4a62fee67b0cb2f32dfcbd7b3642bfef5
-Author: schwarze@openbsd.org <schwarze@openbsd.org>
-Date: Tue May 14 12:47:17 2019 +0000
-
- upstream: Delete some .Sx macros that were used in a wrong way.
-
- Part of a patch from Stephen Gregoratto <dev at sgregoratto dot me>.
-
- OpenBSD-Commit-ID: 15501ed13c595f135e7610b1a5d8345ccdb513b7
-
-commit cb4accb1233865d9151f8a50cc5f0c61a3fd4077
-Author: florian@openbsd.org <florian@openbsd.org>
-Date: Fri May 10 18:55:17 2019 +0000
-
- upstream: For PermitOpen violations add the remote host and port to
-
- be able to find out from where the request was comming.
-
- Add the same logging for PermitListen violations which where not
- logged at all.
-
- Pointed out by Robert Kisteleki (robert AT ripe.net)
-
- input markus
- OK deraadt
-
- OpenBSD-Commit-ID: 8a7d0f1b7175504c0d1dca8d9aca1588b66448c8
-
-commit cd16aceec148d55088fc8df6be88335578d85258
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Thu May 16 07:53:20 2019 +1000
-
- Add OpenSSL 1.1.1 to the supported list.
-
- Clarify the language around prngd and egd.
-
-commit 6fd4aa2aafbce90acb11a328ca0aa0696cb01c6b
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Wed May 15 16:19:14 2019 +1000
-
- Fix typo in man page formatter selector.
-
-commit 285546b73e2c172565c992a695927ac8cf3b4cc6
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Fri May 10 15:04:42 2019 +1000
-
- Use "doc" man page format if mandoc present.
-
- Previously configure would not select the "doc" man page format if
- mandoc was present but nroff was not. This checks for mandoc first
- and removes a now-superflous AC_PATH_PROG. Based on a patch from
- vehk at vehk.de and feedback from schwarze at usta.de.
-
-commit 62dd70613b77b229f53db3cc1c3e8a206fa2b582
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Fri May 3 06:06:30 2019 +0000
-
- upstream: Use the correct (according to POSIX) format for
-
- left-justification in snmprintf. bz#3002, patch from velemas at gmail.com, ok
- markus@.
-
- OpenBSD-Commit-ID: 65d252b799be0cc8f68b6c47cece0a57bb00fea7
-
-commit 62be1ffe5ffc68cfaac183320503c00a8c72e0b1
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Fri May 3 04:11:00 2019 +0000
-
- upstream: Free channel objects on exit path. Patch from markus at
-
- blueflash.cc, ok deraadt
-
- OpenBSD-Commit-ID: dbe4db381603909482211ffdd2b48abd72169117
-
-commit 1c554a5d94b9de6bd5374e2992a5662746cc39ba
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Fri May 3 03:27:38 2019 +0000
-
- upstream: Free host on exit path. Patch from markus at
-
- blueflash.cc, ok djm@
-
- OpenBSD-Commit-ID: c54e9945d93c4ce28350d8b9fa8b71f744ef2b5a
-
-commit 99043bd64e5e0f427173f4fa83ef25a4676624a3
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Fri May 3 03:25:18 2019 +0000
-
- upstream: Wrap XMSS including in ifdef. Patch from markus at
-
- blueflash.cc, ok djm
-
- OpenBSD-Commit-ID: e3b34fc35cf12d33bde91ac03633210a3bc0f8b5
-
-commit 8fcfb7789c43a19d24162a7a4055cd09ee951b34
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Fri Apr 26 08:37:17 2019 +0000
-
- upstream: Import regenerated moduli.
-
- OpenBSD-Commit-ID: db6375fc302e3bdf07d96430c63c991b2c2bd3ff
-
-commit 3a7db919d5dd09f797971b3cf8ee301767459774
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Tue Apr 23 11:56:41 2019 +0000
-
- upstream: Use the LogLevel typdef instead of int where appropriate. Patch from Markus Schmidt via openssh-unix-dev, ok markus@
-
- OpenBSD-Commit-ID: 4c0f0f458e3da7807806b35e3eb5c1e8403c968a
-
-commit d7c6e38b87efab1f140745fd8b1106b82e6e4a68
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Fri Apr 19 05:47:44 2019 +0000
-
- upstream: Document new default RSA key size. From
-
- sebastiaanlokhorst at gmail.com via bz#2997.
-
- OpenBSD-Commit-ID: bdd62ff5d4d649d2147904e91bf7cefa82fe11e1
-
-commit e826bbcafe26dac349a8593da5569e82faa45ab8
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Thu Apr 18 18:56:16 2019 +0000
-
- upstream: When running sshd -T, assume any attibute not provided by
-
- -C does not match, which allows it to work when sshd_config contains a Match
- directive with or without -C. bz#2858, ok djm@
-
- OpenBSD-Commit-ID: 1a701f0a33e3bc96753cfda2fe0b0378520b82eb
-
-commit 5696512d7ad57e85e89f8011ce8dec617be686aa
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Thu Apr 18 07:32:56 2019 +0000
-
- upstream: Remove crc32.{c,h} which were only used by the now-gone
-
- SSH1 protocol. Patch from yumkam at gmail.com, ok deraadt.
-
- OpenBSD-Commit-ID: cceda5876c5ba6b4d8abcd52335329198cee3240
-
-commit 34e87fb5d9ce607f5701ab4c31d837ad8133e2d1
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Tue Apr 30 12:27:57 2019 +1000
-
- Remove unused variables from RLIMIT_NOFILE test.
-
-commit 35e82e62c1ef53cfa457473a4c4d957d6197371a
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Fri Apr 26 18:38:27 2019 +1000
-
- Import regenerated moduli.
-
-commit 5590f53f99219e95dc23b0ebd220f19a6f46b101
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Fri Apr 26 18:22:10 2019 +1000
-
- Whitespace resync w/OpenBSD.
-
- Patch from markus at blueflash.cc via openssh-unix-dev.
-
-commit b7b8334914fb9397a6725f3b5d2de999b0bb69ac
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Fri Apr 26 18:06:34 2019 +1000
-
- Don't install duplicate STREAMS modules on Solaris
-
- Check if STREAMS modules are already installed on pty before installing
- since when compiling with XPG>=4 they will likely be installed already.
- Prevents hangs and duplicate lines on the terminal. bz#2945 and bz#2998,
- patch from djm@
-
-commit fd0fa130ecf06d7d092932adcd5d77f1549bfc8d
-Author: Damien Miller <djm@mindrot.org>
-Date: Thu Apr 18 08:52:57 2019 +1000
-
- makedepend
-
-commit 5de397a876b587ba05a9169237deffdc71f273b0
-Author: Damien Miller <djm@mindrot.org>
-Date: Fri Apr 5 11:29:51 2019 -0700
-
- second thoughts: leave README in place
-
- A number of contrib/* files refer to the existing README so let's leave
- it in place for release and add the new markdown version in parallel.
-
- I'll get rid of README after release.
-
-commit 5d3127d9274519b25ed10e320f45045ba8d7f3be
-Author: Damien Miller <djm@mindrot.org>
-Date: Fri Apr 5 11:29:31 2019 -0700
-
- Revert "rewrite README"
-
- This reverts commit 9444d82678cb7781820da4d1c23b3c2b9fb1e12f.
-
-commit 9444d82678cb7781820da4d1c23b3c2b9fb1e12f
-Author: Damien Miller <djm@mindrot.org>
-Date: Fri Apr 5 11:21:48 2019 -0700
-
- rewrite README
-
- Include basic build instructions and comments on commonly-used build-
- time flags, links to the manual pages and other resources.
-
- Now in Markdown format for better viewing on github, etc.
-
-commit a924de0c4908902433813ba205bee1446bd1a157
-Author: Damien Miller <djm@mindrot.org>
-Date: Fri Apr 5 03:41:52 2019 +1100
-
- update versions
-
-commit 312dcee739bca5d6878c536537b2a8a497314b75
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Wed Apr 3 15:48:45 2019 +0000
-
- upstream: openssh-8.0
-
- OpenBSD-Commit-ID: 5aafdf218679dab982fea20771afd643be9a127b
-
-commit 885bc114692046d55e2a170b932bdc0092fa3456
-Author: Damien Miller <djm@mindrot.org>
-Date: Thu Apr 4 02:47:40 2019 +1100
-
- session: Do not use removed API
-
- from Jakub Jelen
-
-commit 9d7b2882b0c9a5e9bf8312ce4075bf178e2b98be
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Mar 29 11:31:40 2019 +0000
-
- upstream: when logging/fataling on error, include a bit more detail
-
- than just the function name and the error message
-
- OpenBSD-Commit-ID: dd72d7eba2215fcb89be516c378f633ea5bcca9f
-
-commit 79a87d32783d6c9db40af8f35e091d9d30365ae7
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Wed Apr 3 06:27:45 2019 +1100
-
- Remove "struct ssh" from sys_auth_record_login.
-
- It's not needed, and is not available from the call site in loginrec.c
- Should only affect AIX, spotted by Kevin Brott.
-
-commit 138c0d52cdc90f9895333b82fc57d81cce7a3d90
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Tue Apr 2 18:21:35 2019 +1100
-
- Adapt custom_failed_login to new prototype.
-
- Spotted by Kevin Brott.
-
-commit a0ca4009ab2f0b1007ec8ab6864dbf9b760a8ed5
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Mon Apr 1 20:07:23 2019 +1100
-
- Add includes.h for compat layer.
-
- Should fix build on AIX 7.2.
-
-commit 00991151786ce9b1d577bdad1f83a81d19c8236d
-Author: Tim Rice <tim@multitalents.net>
-Date: Sun Mar 31 22:14:22 2019 -0700
-
- Stop USL compilers for erroring with "integral constant expression expected"
-
-commit 43f47ebbdd4037b569c23b8f4f7981f53b567f1d
-Author: Tim Rice <tim@multitalents.net>
-Date: Sun Mar 31 19:22:19 2019 -0700
-
- Only use O_NOFOLLOW in fchownat and fchmodat if defined
-
-commit 342d6e51589b184c337cccfc4c788b60ff8b3765
-Author: Jakub Jelen <jjelen@redhat.com>
-Date: Fri Mar 29 12:29:41 2019 +0100
-
- Adjust softhsm2 path on Fedora Linux for regress
-
- The SoftHSM lives in Fedora in /usr/lib64/pkcs11/libsofthsm2.so
-
-commit f5abb05f8c7358dacdcb866fe2813f6d8efd5830
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Thu Mar 28 09:26:14 2019 +1100
-
- Only use O_NOFOLLOW in utimensat if defined.
-
- Fixes build on systems that don't have it (Solaris <=9) Found by
- Tom G. Christensen.
-
-commit 786cd4c1837fdc3fe7b4befe54a3f37db7df8715
-Author: Corinna Vinschen <vinschen@redhat.com>
-Date: Wed Mar 27 18:18:21 2019 +0100
-
- drop old Cygwin considerations
-
- - Cygwin supports non-DOS characters in filenames
- - Cygwin does not support Windows XP anymore
-
- Signed-off-by: Corinna Vinschen <vinschen@redhat.com>
-
-commit 21da87f439b48a85b951ef1518fe85ac0273e719
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Wed Mar 27 09:29:14 2019 +0000
-
- upstream: fix interaction between ClientAliveInterval and RekeyLimit
-
- that could cause connection to close incorrectly; Report and patch from Jakub
- Jelen in bz#2757; ok dtucker@ markus@
-
- OpenBSD-Commit-ID: 17229a8a65bd8e6c2080318ec2b7a61e1aede3fb
-
-commit 4f0019a9afdb4a94d83b75e82dbbbe0cbe826c56
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Mon Mar 25 22:34:52 2019 +0000
-
- upstream: Fix authentication failures when "AuthenticationMethods
-
- any" in a Match block overrides a more restrictive global default.
-
- Spotted by jmc@, ok markus@
-
- OpenBSD-Commit-ID: a90a4fe2ab81d0eeeb8fdfc21af81f7eabda6666
-
-commit d6e5def308610f194c0ec3ef97a34a3e9630e190
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Mon Mar 25 22:33:44 2019 +0000
-
- upstream: whitespace
-
- OpenBSD-Commit-ID: 106e853ae8a477e8385bc53824d3884a8159db07
-
-commit 26e0cef07b04479537c971dec898741df1290fe5
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Mon Mar 25 16:19:44 2019 +0000
-
- upstream: Expand comment to document rationale for default key
-
- sizes. "seems worthwhile" deraadt.
-
- OpenBSD-Commit-ID: 72e5c0983d7da1fb72f191870f36cb58263a2456
-
-commit f47269ea67eb4ff87454bf0d2a03e55532786482
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Mon Mar 25 15:49:00 2019 +0000
-
- upstream: Increase the default RSA key size to 3072 bits. Based on
-
- the estimates from NIST Special Publication 800-57, 3k bits provides security
- equivalent to 128 bits which is the smallest symmetric cipher we enable by
- default. ok markus@ deraadt@
-
- OpenBSD-Commit-ID: 461dd32ebe808f88f4fc3ec74749b0e6bef2276b
-
-commit 62949c5b37af28d8490d94866e314a76be683a5e
-Author: jmc@openbsd.org <jmc@openbsd.org>
-Date: Fri Mar 22 20:58:34 2019 +0000
-
- upstream: full stop in the wrong place;
-
- OpenBSD-Commit-ID: 478a0567c83553a2aebf95d0f1bd67ac1b1253e4
-
-commit 1b1332b5bb975d759a50b37f0e8bc8cfb07a0bb0
-Author: jmc@openbsd.org <jmc@openbsd.org>
-Date: Sat Mar 16 19:14:21 2019 +0000
-
- upstream: benno helped me clean up the tcp forwarding section;
-
- OpenBSD-Commit-ID: d4bec27edefde636fb632b7f0b7c656b9c7b7f08
-
-commit 2aee9a49f668092ac5c9d34e904ef7a9722e541d
-Author: markus@openbsd.org <markus@openbsd.org>
-Date: Fri Mar 8 17:24:43 2019 +0000
-
- upstream: fix use-after-free in ssh-pkcs11; found by hshoexer w/AFL
-
- OpenBSD-Commit-ID: febce81cca72b71f70513fbee4ff52ca050f675c
-
-commit 9edbd7821e6837e98e7e95546cede804dac96754
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Thu Mar 14 10:17:28 2019 +1100
-
- Fix build when configured --without-openssl.
-
- ok djm@
-
-commit 825ab32f0d04a791e9d19d743c61ff8ed9b4d8e5
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Thu Mar 14 08:51:17 2019 +1100
-
- On Cygwin run sshd as SYSTEM where possible.
-
- Seteuid now creates user token using S4U. We don't create a token
- from scratch anymore, so we don't need the "Create a process token"
- privilege. The service can run under SYSTEM again...
-
- ...unless Cygwin is running on Windows Vista or Windows 7 in the
- WOW64 32 bit emulation layer. It turns out that WOW64 on these systems
- didn't implement MsV1_0 S4U Logon so we still need the fallback
- to NtCreateToken for these systems.
-
- Signed-off-by: Corinna Vinschen <vinschen@redhat.com>
-
-commit a212107bfdf4d3e870ab7a443e4d906e5b9578c3
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Wed Mar 13 10:49:16 2019 +1100
-
- Replace alloca with xcalloc.
-
- The latter checks for memory exhaustion and integer overflow and may be
- at a less predictable place. Sanity check by vinschen at redhat.com, ok
- djm@
-
-commit daa7505aadca68ba1a2c70cbdfce423208eb91ee
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Tue Mar 12 09:19:19 2019 +1100
-
- Use Cygwin-specific matching only for users+groups.
-
- Patch from vinschen at redhat.com, updated a little by me.
-
-commit fd10cf027b56f9aaa80c9e3844626a05066589a4
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Wed Mar 6 22:14:23 2019 +0000
-
- upstream: Move checks for lists of users or groups into their own
-
- function. This is a no-op on OpenBSD but will make things easier in
- -portable, eg on systems where these checks should be case-insensitive. ok
- djm@
-
- OpenBSD-Commit-ID: 8bc9c8d98670e23f8eaaaefe29c1f98e7ba0487e
-
-commit ab5fee8eb6a011002fd9e32b1597f02aa8804a25
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Wed Mar 6 21:06:59 2019 +0000
-
- upstream: Reset last-seen time when sending a keepalive. Prevents
-
- sending two keepalives successively and prematurely terminating connection
- when ClientAliveCount=1. While there, collapse two similar tests into one.
- ok markus@
-
- OpenBSD-Commit-ID: 043670d201dfe222537a2a4bed16ce1087de5ddd
-
-commit c13b74530f9f1d9df7aeae012004b31b2de4438e
-Author: naddy@openbsd.org <naddy@openbsd.org>
-Date: Tue Mar 5 16:17:12 2019 +0000
-
- upstream: PKCS#11 support is no longer limited to RSA; ok benno@
-
- kn@
-
- OpenBSD-Commit-ID: 1a9bec64d530aed5f434a960e7515a3e80cbc826
-
-commit e9552d6043db7cd170ac6ba1b4d2c7a5eb2c3201
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Mar 1 03:29:32 2019 +0000
-
- upstream: in ssh_set_newkeys(), mention the direction that we're
-
- keying in debug messages. Previously it would be difficult to tell which
- direction it was talking about
-
- OpenBSD-Commit-ID: c2b71bfcceb2a7389b9d0b497fb2122a406a522d
-
-commit 76a24b3fa193a9ca3e47a8779d497cb06500798b
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Mar 1 02:32:39 2019 +0000
-
- upstream: Fix two race conditions in sshd relating to SIGHUP:
-
- 1. Recently-forked child processes will briefly remain listening to
- listen_socks. If the main server sshd process completes its restart
- via execv() before these sockets are closed by the child processes
- then it can fail to listen at the desired addresses/ports and/or
- fail to restart.
-
- 2. When a SIGHUP is received, there may be forked child processes that
- are awaiting their reexecution state. If the main server sshd
- process restarts before passing this state, these child processes
- will yield errors and use a fallback path of reading the current
- sshd_config from the filesystem rather than use the one that sshd
- was started with.
-
- To fix both of these cases, we reuse the startup_pipes that are shared
- between the main server sshd and forked children. Previously this was
- used solely to implement tracking of pre-auth child processes for
- MaxStartups, but this extends the messaging over these pipes to include
- a child->parent message that the parent process is safe to restart. This
- message is sent from the child after it has completed its preliminaries:
- closing listen_socks and receiving its reexec state.
-
- bz#2953, reported by Michal Koutný; ok markus@ dtucker@
-
- OpenBSD-Commit-ID: 7df09eacfa3ce13e9a7b1e9f17276ecc924d65ab
-
-commit de817e9dfab99473017d28cdf69e60397d00ea21
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Mar 1 02:16:47 2019 +0000
-
- upstream: mention PKCS11Provide=none, reword a little and remove
-
- mention of RSA keys only (since we support ECDSA now and might support others
- in the future). Inspired by Jakub Jelen via bz#2974
-
- OpenBSD-Commit-ID: a92e3686561bf624ccc64ab320c96c9e9a263aa5
-
-commit 95a8058c1a90a27acbb91392ba206854abc85226
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Mar 1 02:08:50 2019 +0000
-
- upstream: let PKCS11Provider=none do what users expect
-
- print PKCS11Provider instead of obsolete SmartcardDevice in config dump.
-
- bz#2974 ok dtucker@
-
- OpenBSD-Commit-ID: c303d6f0230a33aa2dd92dc9b68843d56a64f846
-
-commit 8e7bac35aa576d2fd7560836da83733e864ce649
-Author: markus@openbsd.org <markus@openbsd.org>
-Date: Wed Feb 27 19:37:01 2019 +0000
-
- upstream: dup stdout/in for proxycommand=-, otherwise stdout might
-
- be redirected to /dev/null; ok djm@
-
- OpenBSD-Commit-ID: 97dfce4c47ed4055042de8ebde85b7d88793e595
-
-commit 9b61130fbd95d196bce81ebeca94a4cb7c0d5ba0
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sat Feb 23 08:20:43 2019 +0000
-
- upstream: openssh-7.9 accidentally reused the server's algorithm lists
-
- in the client for KEX, ciphers and MACs. The ciphers and MACs were identical
- between the client and server, but the error accidentially disabled the
- diffie-hellman-group-exchange-sha1 KEX method.
-
- This fixes the client code to use the correct method list, but
- because nobody complained, it also disables the
- diffie-hellman-group-exchange-sha1 KEX method.
-
- Reported by nuxi AT vault24.org via bz#2697; ok dtucker
-
- OpenBSD-Commit-ID: e30c33a23c10fd536fefa120e86af1842e33fd57
-
-commit 37638c752041d591371900df820f070037878a2d
-Author: Corinna Vinschen <vinschen@redhat.com>
-Date: Wed Feb 20 13:41:25 2019 +0100
-
- Cygwin: implement case-insensitive Unicode user and group name matching
-
- The previous revert enabled case-insensitive user names again. This
- patch implements the case-insensitive user and group name matching.
- To allow Unicode chars, implement the matcher using wchar_t chars in
- Cygwin-specific code. Keep the generic code changes as small as possible.
- Cygwin: implement case-insensitive Unicode user and group name matching
-
- Signed-off-by: Corinna Vinschen <vinschen@redhat.com>
-
-commit bed1d43698807a07bb4ddb93a46b0bd84b9970b3
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Fri Feb 22 15:21:21 2019 +1100
-
- Revert unintended parts of previous commit.
-
-commit f02afa350afac1b2f2d1413259a27a4ba1e2ca24
-Author: Corinna Vinschen <vinschen@redhat.com>
-Date: Wed Feb 20 13:41:24 2019 +0100
-
- Revert "[auth.c] On Cygwin, refuse usernames that have differences in case"
-
- This reverts commit acc9b29486dfd649dfda474e5c1a03b317449f1c.
-
- Signed-off-by: Corinna Vinschen <vinschen@redhat.com>
-
-commit 4c55b674835478eb80a1a7aeae588aa654e2a433
-Author: Corinna Vinschen <vinschen@redhat.com>
-Date: Sat Feb 16 14:13:43 2019 +0100
-
- Add tags to .gitignore
-
- Signed-off-by: Corinna Vinschen <vinschen@redhat.com>
-
-commit 625b62634c33eaef4b80d07529954fe5c6435fe5
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Feb 22 03:37:11 2019 +0000
-
- upstream: perform removal of agent-forwarding directory in forward
-
- setup error path with user's privileged. This is a no-op as this code always
- runs with user privilege now that we no longer support running sshd with
- privilege separation disabled, but as long as the privsep skeleton is there
- we should follow the rules.
- MIME-Version: 1.0
- Content-Type: text/plain; charset=UTF-8
- Content-Transfer-Encoding: 8bit
-
- bz#2969 with patch from Erik Sjölund
-
- OpenBSD-Commit-ID: 2b708401a5a8d6133c865d7698d9852210dca846
-
-commit d9ecfaba0b2f1887d20e4368230632e709ca83be
-Author: jmc@openbsd.org <jmc@openbsd.org>
-Date: Mon Feb 18 07:02:34 2019 +0000
-
- upstream: sync the description of ~/.ssh/config with djm's updated
-
- description in ssh.1; issue pointed out by andreas kahari
-
- ok dtucker djm
-
- OpenBSD-Commit-ID: 1b01ef0ae2c6328165150badae317ec92e52b01c
-
-commit 38e83e4f219c752ebb1560633b73f06f0392018b
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Tue Feb 12 23:53:10 2019 +0000
-
- upstream: fix regression in r1.302 reported by naddy@ - only the first
-
- public key from the agent was being attempted for use.
-
- OpenBSD-Commit-ID: 07116aea521a04888718b2157f1ca723b2f46c8d
-
-commit 5c68ea8da790d711e6dd5f4c30d089c54032c59a
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Mon Feb 11 09:44:42 2019 +0000
-
- upstream: cleanup GSSAPI authentication context after completion of the
-
- authmethod. Move function-static GSSAPI state to the client Authctxt
- structure. Make static a bunch of functions that aren't used outside this
- file.
-
- Based on patch from Markus Schmidt <markus@blueflash.cc>; ok markus@
-
- OpenBSD-Commit-ID: 497fb792c0ddb4f1ba631b6eed526861f115dbe5
-
-commit a8c807f1956f81a92a758d3d0237d0ff06d0be5d
-Author: benno@openbsd.org <benno@openbsd.org>
-Date: Sun Feb 10 16:35:41 2019 +0000
-
- upstream: ssh-keygen -D pkcs11.so needs to initialize pkcs11
-
- interactive, so it can ask for the smartcards PIN. ok markus@
-
- OpenBSD-Commit-ID: 1be7ccf88f1876e0fc4d7c9b3f96019ac5655bab
-
-commit 3d896c157c722bc47adca51a58dca859225b5874
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sun Feb 10 11:15:52 2019 +0000
-
- upstream: when checking that filenames sent by the server side
-
- match what the client requested, be prepared to handle shell-style brace
- alternations, e.g. "{foo,bar}".
-
- "looks good to me" millert@ + in snaps for the last week courtesy
- deraadt@
-
- OpenBSD-Commit-ID: 3b1ce7639b0b25b2248e3a30f561a548f6815f3e
-
-commit 318e4f8548a4f5c0c913f61e27d4fc21ffb1eaae
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sun Feb 10 11:10:57 2019 +0000
-
- upstream: syslog when connection is dropped for attempting to run a
-
- command when ForceCommand=internal-sftp is in effect; bz2960; ok dtucker@
-
- OpenBSD-Commit-ID: 8c87fa66d7fc6c0fffa3a3c28e8ab5e8dde234b8
-
-commit 2ff2e19653b8c0798b8b8eff209651bdb1be2761
-Author: Damien Miller <djm@mindrot.org>
-Date: Fri Feb 8 14:53:35 2019 +1100
-
- don't set $MAIL if UsePam=yes
-
- PAM typically specifies the user environment if it's enabled, so don't
- second guess. bz#2937; ok dtucker@
-
-commit 03e92dd27d491fe6d1a54e7b2f44ef1b0a916e52
-Author: Damien Miller <djm@mindrot.org>
-Date: Fri Feb 8 14:50:36 2019 +1100
-
- use same close logic for stderr as stdout
-
- Avoids sending SIGPIPE to child processes after their parent exits
- if they attempt to write to stderr.
-
- Analysis and patch from JD Paul; patch reworked by Jakub Jelen and
- myself. bz#2071; ok dtucker@
-
-commit 8c53d409baeeaf652c0c125a9b164edc9dbeb6de
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Tue Feb 5 11:35:56 2019 +0000
-
- upstream: Adapt code in the non-USE_PIPES codepath to the new packet
-
- API. This code is not normally reachable since USE_PIPES is always defined.
- bz#2961, patch from adrian.fita at gmail com.
-
- OpenBSD-Commit-ID: 8d8428d678d1d5eb4bb21921df34e8173e6d238a
-
-commit 7a7fdca78de4b4774950be056099e579ef595414
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Mon Feb 4 23:37:54 2019 +0000
-
- upstream: fix NULL-deref crash in PKCS#11 code when attempting
-
- login to a token requiring a PIN; reported by benno@ fix mostly by markus@
-
- OpenBSD-Commit-ID: 438d0b114b1b4ba25a9869733db1921209aa9a31
-
-commit cac302a4b42a988e54d32eb254b29b79b648dbf5
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Mon Feb 4 02:39:42 2019 +0000
-
- upstream: Remove obsolete "Protocol" from commented out examples. Patch
-
- from samy.mahmoudi at gmail com.
-
- OpenBSD-Commit-ID: 16aede33dae299725a03abdac5dcb4d73f5d0cbf
-
-commit 483b3b638500fd498b4b529356e5a0e18cf76891
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Fri Feb 1 03:52:23 2019 +0000
-
- upstream: Save connection timeout and restore for 2nd and
-
- subsequent attempts, preventing them from having no timeout. bz#2918, ok
- djm@
-
- OpenBSD-Commit-ID: 4977f1d0521d9b6bba0c9a20d3d226cefac48292
-
-commit 5f004620fdc1b2108139300ee12f4014530fb559
-Author: markus@openbsd.org <markus@openbsd.org>
-Date: Wed Jan 30 19:51:15 2019 +0000
-
- upstream: Add authors for public domain sntrup4591761 code;
-
- confirmed by Daniel J. Bernstein
-
- OpenBSD-Commit-ID: b4621f22b8b8ef13e063c852af5e54dbbfa413c1
-
-commit 2c21b75a7be6ebdcbceaebb43157c48dbb36f3d8
-Author: jmc@openbsd.org <jmc@openbsd.org>
-Date: Sun Jan 27 07:14:11 2019 +0000
-
- upstream: add -T to usage();
-
- OpenBSD-Commit-ID: a7ae14d9436c64e1bd05022329187ea3a0ce1899
-
-commit 19a0f0529d3df04118da829528cac7ceff380b24
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Mon Jan 28 03:50:39 2019 +0000
-
- upstream: The test sshd_config in in $OBJ.
-
- OpenBSD-Regress-ID: 1e5d908a286d8e7de3a15a0020c8857f3a7c9172
-
-commit 8fe25440206319d15b52d12b948a5dfdec14dca3
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Mon Jan 28 03:28:10 2019 +0000
-
- upstream: Remove leftover debugging.
-
- OpenBSD-Regress-ID: 3d86c3d4867e46b35af3fd2ac8c96df0ffdcfeb9
-
-commit e30d32364d12c351eec9e14be6c61116f9d6cc90
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Mon Jan 28 00:12:36 2019 +0000
-
- upstream: Enable ssh-dss for the agent test. Disable it for the
-
- certificate test.
-
- OpenBSD-Regress-ID: 388c1e03e1def539d350f139b37d69f12334668d
-
-commit ffdde469ed56249f5dc8af98da468dde35531398
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Mon Jan 28 00:08:26 2019 +0000
-
- upstream: Count the number of key types instead of assuming there
-
- are only two.
-
- OpenBSD-Regress-ID: 0998702c41235782cf0beee396ec49b5056eaed9
-
-commit 1d05b4adcba08ab068466e5c08dee2f5417ec53a
-Author: Corinna Vinschen <vinschen@redhat.com>
-Date: Sat Jan 26 23:42:40 2019 +0100
-
- Cygwin: only tweak sshd_config file if it's new, drop creating sshd user
-
- The sshd_config tweaks were executed even if the old file was
- still in place. Fix that. Also disable sshd user creation.
- It's not used on Cygwin.
-
-commit 89843de0c4c733501f6b4f988098e6e06963df37
-Author: Corinna Vinschen <vinschen@redhat.com>
-Date: Sat Jan 26 23:03:12 2019 +0100
-
- Cygwin: Change service name to cygsshd
-
- Microsoft hijacked the sshd service name without asking.
-
-commit 2a9b3a2ce411d16cda9c79ab713c55f65b0ec257
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Sun Jan 27 06:30:53 2019 +0000
-
- upstream: Generate all key supported key types and enable for keyscan
-
- test.
-
- OpenBSD-Regress-ID: 72f72ff49946c61bc949e1692dd9e3d71370891b
-
-commit 391ffc4b9d31fa1f4ad566499fef9176ff8a07dc
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sat Jan 26 22:41:28 2019 +0000
-
- upstream: check in scp client that filenames sent during
-
- remote->local directory copies satisfy the wildcard specified by the user.
-
- This checking provides some protection against a malicious server
- sending unexpected filenames, but it comes at a risk of rejecting wanted
- files due to differences between client and server wildcard expansion rules.
-
- For this reason, this also adds a new -T flag to disable the check.
-
- reported by Harry Sintonen
- fix approach suggested by markus@;
- has been in snaps for ~1wk courtesy deraadt@
-
- OpenBSD-Commit-ID: 00f44b50d2be8e321973f3c6d014260f8f7a8eda
-
-commit c2c18a39683db382a15b438632afab3f551d50ce
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sat Jan 26 22:35:01 2019 +0000
-
- upstream: make ssh-keyscan return a non-zero exit status if it
-
- finds no keys. bz#2903
-
- OpenBSD-Commit-ID: 89f1081fb81d950ebb48e6e73d21807b2723d488
-
-commit 05b9a466700b44d49492edc2aa415fc2e8913dfe
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Thu Jan 24 17:00:29 2019 +0000
-
- upstream: Accept the host key fingerprint as a synonym for "yes"
-
- when accepting an unknown host key. This allows you to paste a fingerprint
- obtained out of band into the yes/no prompt and have the client do the
- comparison for you. ok markus@ djm@
-
- OpenBSD-Commit-ID: 3c47d10b9f43d3d345e044fd9ec09709583a2767
-
-commit bdc6c63c80b55bcbaa66b5fde31c1cb1d09a41eb
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Thu Jan 24 16:52:17 2019 +0000
-
- upstream: Have progressmeter force an update at the beginning and
-
- end of each transfer. Fixes the problem recently introduces where very quick
- transfers do not display the progressmeter at all. Spotted by naddy@
-
- OpenBSD-Commit-ID: 68dc46c259e8fdd4f5db3ec2a130f8e4590a7a9a
-
-commit 258e6ca003e47f944688ad8b8de087b58a7d966c
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Thu Jan 24 02:42:23 2019 +0000
-
- upstream: Check for both EAGAIN and EWOULDBLOCK. This is a no-op
-
- in OpenBSD (they are the same value) but makes things easier in -portable
- where they may be distinct values. "sigh ok" deraadt@
-
- (ID sync only, portable already had this change).
-
- OpenBSD-Commit-ID: 91f2bc7c0ecec905915ed59fa37feb9cc90e17d7
-
-commit 281ce042579b834cdc1e74314f1fb2eeb75d2612
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Thu Jan 24 02:34:52 2019 +0000
-
- upstream: Always initialize 2nd arg to hpdelim2. It populates that
-
- *ONLY IF* there's a delimiter. If there's not (the common case) it checked
- uninitialized memory, which usually passed, but if not would cause spurious
- failures when the uninitialized memory happens to contain "/". ok deraadt.
-
- OpenBSD-Commit-ID: 4291611eaf2a53d4c92f4a57c7f267c9f944e0d3
-
-commit d05ea255678d9402beda4416cd0360f3e5dfe938
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Wed Jan 23 21:50:56 2019 +0000
-
- upstream: Remove support for obsolete host/port syntax.
-
- host/port was added in 2001 as an alternative to host:port syntax for
- the benefit of IPv6 users. These days there are establised standards
- for this like [::1]:22 and the slash syntax is easily mistaken for CIDR
- notation, which OpenSSH now supports for some things. Remove the slash
- notation from ListenAddress and PermitOpen. bz#2335, patch from jjelen
- at redhat.com, ok markus@
-
- OpenBSD-Commit-ID: fae5f4e23c51a368d6b2d98376069ac2b10ad4b7
-
-commit 177d6c80c557a5e060cd343a0c116a2f1a7f43db
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Wed Jan 23 20:48:52 2019 +0000
-
- upstream: Remove duplicate word. bz#2958, patch from jjelen at
-
- redhat.com
-
- OpenBSD-Commit-ID: cca3965a8333f2b6aae48b79ec1d72f7a830dd2c
-
-commit be3e6cba95dffe5fcf190c713525b48c837e7875
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Wed Jan 23 09:49:00 2019 +0000
-
- upstream: Remove 3 as a guess for possible generator during moduli
-
- generation. It's not mentioned in RFC4419 and it's not possible for
- Sophie-Germain primes greater than 5. bz#2330, from Christian Wittenhorst ,
- ok djm@ tb@
-
- OpenBSD-Commit-ID: 1467652e6802ad3333b0959282d8d49dfe22c8cd
-
-commit 8976f1c4b2721c26e878151f52bdf346dfe2d54c
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Wed Jan 23 08:01:46 2019 +0000
-
- upstream: Sanitize scp filenames via snmprintf. To do this we move
-
- the progressmeter formatting outside of signal handler context and have the
- atomicio callback called for EINTR too. bz#2434 with contributions from djm
- and jjelen at redhat.com, ok djm@
-
- OpenBSD-Commit-ID: 1af61c1f70e4f3bd8ab140b9f1fa699481db57d8
-
-commit 6249451f381755f792c6b9e2c2f80cdc699c14e2
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Thu Jan 24 10:00:20 2019 +1100
-
- For broken read/readv comparisons, poll(RW).
-
- In the cases where we can't compare to read or readv function pointers
- for some reason we currently ifdef out the poll() used to block while
- waiting for reads or writes, falling back to busy waiting. This restores
- the poll() in this case, but has it always check for read or write,
- removing an inline ifdef in the process.
-
-commit 5cb503dff4db251520e8bf7d23b9c97c06eee031
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Thu Jan 24 09:55:16 2019 +1100
-
- Include unistd.h for strmode().
-
-commit f236ca2741f29b5c443c0b2db3aa9afb9ad9befe
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Thu Jan 24 09:50:58 2019 +1100
-
- Also undef SIMPLEQ_FOREACH_SAFE.
-
- Prevents macro redefinition warning on at least NetBSD 6.1.
-
-commit be063945e4e7d46b1734d973bf244c350fae172a
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Wed Jan 23 04:51:02 2019 +0000
-
- upstream: allow auto-incrementing certificate serial number for certs
-
- signed in a single commandline.
-
- OpenBSD-Commit-ID: 39881087641efb8cd83c7ec13b9c98280633f45b
-
-commit 851f80328931975fe68f71af363c4537cb896da2
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Wed Jan 23 04:16:22 2019 +0000
-
- upstream: move a bunch of global flag variables to main(); make the
-
- rest static
-
- OpenBSD-Commit-ID: fa431d92584e81fe99f95882f4c56b43fe3242dc
-
-commit 2265402dc7d701a9aca9f8a7b7b0fd45b65c479f
-Author: Damien Miller <djm@mindrot.org>
-Date: Wed Jan 23 13:03:16 2019 +1100
-
- depend
-
-commit 2c223878e53cc46def760add459f5f7c4fb43e35
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Wed Jan 23 02:01:10 2019 +0000
-
- upstream: switch mainloop from select(2) to poll(2); ok deraadt@
-
- OpenBSD-Commit-ID: 37645419a330037d297f6f0adc3b3663e7ae7b2e
-
-commit bb956eaa94757ad058ff43631c3a7d6c94d38c2f
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Wed Jan 23 00:30:41 2019 +0000
-
- upstream: pass most arguments to the KEX hash functions as sshbuf
-
- rather than pointer+length; ok markus@
-
- OpenBSD-Commit-ID: ef0c89c52ccc89817a13a5205725148a28492bf7
-
-commit d691588b8e29622c66abf8932362b522cf7f4051
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Tue Jan 22 22:58:50 2019 +0000
-
- upstream: backoff reading messages from active connections when the
-
- input buffer is too full to read one, or if the output buffer is too full to
- enqueue a response; feedback & ok dtucker@
-
- OpenBSD-Commit-ID: df3c5b6d57c968975875de40d8955cbfed05a6c8
-
-commit f99ef8de967949a1fc25a5c28263ea32736e5943
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Tue Jan 22 20:48:01 2019 +0000
-
- upstream: add -m to usage(); reminded by jmc@
-
- OpenBSD-Commit-ID: bca476a5236e8f94210290b3e6a507af0434613e
-
-commit 41923ce06ac149453debe472238e0cca7d5a2e5f
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Tue Jan 22 12:03:58 2019 +0000
-
- upstream: Correct some bugs in PKCS#11 token PIN handling at
-
- initial login, the attempt at reading the PIN could be skipped in some cases
- especially on devices with integrated PIN readers.
-
- based on patch from Daniel Kucera in bz#2652; ok markus@
-
- OpenBSD-Commit-ID: fad70a61c60610afe8bb0db538c90e343e75e58e
-
-commit 2162171ad517501ba511fa9f8191945d01857bb4
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Tue Jan 22 12:00:50 2019 +0000
-
- upstream: Support keys that set the CKA_ALWAYS_AUTHENTICATE by
-
- requring a fresh login after the C_SignInit operation.
-
- based on patch from Jakub Jelen in bz#2638; ok markus
-
- OpenBSD-Commit-ID: a76e66996ba7c0923b46b74d46d499b811786661
-
-commit 7a2cb18a215b2cb335da3dc99489c52a91f4925b
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Tue Jan 22 11:51:25 2019 +0000
-
- upstream: Mention that configuration for the destination host is
-
- not applied to any ProxyJump/-J hosts. This has confused a few people...
-
- OpenBSD-Commit-ID: 03f4f641df6ca236c1bfc69836a256b873db868b
-
-commit ecd2f33cb772db4fa76776543599f1c1ab6f9fa0
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Tue Jan 22 11:40:42 2019 +0000
-
- upstream: Include -m in the synopsis for a few more commands that
-
- support it
-
- Be more explicit in the description of -m about where it may be used
-
- Prompted by Jakub Jelen in bz2904
-
- OpenBSD-Commit-ID: 3b398ac5e05d8a6356710d0ff114536c9d71046c
-
-commit ff5d2cf4ca373bb4002eef395ed2cbe2ff0826c1
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Tue Jan 22 11:26:16 2019 +0000
-
- upstream: print the full pubkey being attempted at loglevel >=
-
- debug2; bz2939
-
- OpenBSD-Commit-ID: ac0fe5ca1429ebf4d460bad602adc96de0d7e290
-
-commit 180b520e2bab33b566b4b0cbac7d5f9940935011
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Tue Jan 22 11:19:42 2019 +0000
-
- upstream: clarify: ssh-keygen -e only writes public keys, never
-
- private
-
- OpenBSD-Commit-ID: 7de7ff6d274d82febf9feb641e2415ffd6a30bfb
-
-commit c45616a199c322ca674315de88e788f1d2596e26
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Tue Jan 22 11:00:15 2019 +0000
-
- upstream: mention the new vs. old key formats in the introduction
-
- and give some hints on how keys may be converted or written in the old
- format.
-
- OpenBSD-Commit-ID: 9c90a9f92eddc249e07fad1204d0e15c8aa13823
-
-commit fd8eb1383a34c986a00ef13d745ae9bd3ea21760
-Author: jmc@openbsd.org <jmc@openbsd.org>
-Date: Tue Jan 22 06:58:31 2019 +0000
-
- upstream: tweak previous;
-
- OpenBSD-Commit-ID: d2a80e389da8e7ed71978643d8cbaa8605b597a8
-
-commit 68e924d5473c00057f8532af57741d258c478223
-Author: tb@openbsd.org <tb@openbsd.org>
-Date: Mon Jan 21 23:55:12 2019 +0000
-
- upstream: Forgot to add -J to the synopsis.
-
- OpenBSD-Commit-ID: 26d95e409a0b72526526fc56ca1caca5cc3d3c5e
-
-commit 622dedf1a884f2927a9121e672bd9955e12ba108
-Author: tb@openbsd.org <tb@openbsd.org>
-Date: Mon Jan 21 22:50:42 2019 +0000
-
- upstream: Add a -J option as a shortcut for -o Proxyjump= to scp(1)
-
- and sftp(1) to match ssh(1)'s interface.
-
- ok djm
-
- OpenBSD-Commit-ID: a75bc2d5f329caa7229a7e9fe346c4f41c2663fc
-
-commit c882d74652800150d538e22c80dd2bd3cdd5fae2
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Tue Jan 22 20:38:40 2019 +1100
-
- Allow building against OpenSSL dev (3.x) version.
-
-commit d5520393572eb24aa0e001a1c61f49b104396e45
-Author: Damien Miller <djm@mindrot.org>
-Date: Tue Jan 22 10:50:40 2019 +1100
-
- typo
-
-commit 2de9cec54230998ab10161576f77860a2559ccb7
-Author: Damien Miller <djm@mindrot.org>
-Date: Tue Jan 22 10:49:52 2019 +1100
-
- add missing header
-
-commit 533cfb01e49a2a30354e191669dc3159e03e99a7
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Mon Jan 21 22:18:24 2019 +0000
-
- upstream: switch sntrup implementation source from supercop to
-
- libpqcrypto; the latter is almost identical but doesn't rely on signed
- underflow to implement an optimised integer sort; from markus@
-
- OpenBSD-Commit-ID: cd09bbf0e0fcef1bedca69fdf7990dc360567cf8
-
-commit d50ab3cd6fb859888a26b4d4e333239b4f6bf573
-Author: Damien Miller <djm@mindrot.org>
-Date: Tue Jan 22 00:02:23 2019 +1100
-
- new files need includes.h
-
-commit c7670b091a7174760d619ef6738b4f26b2093301
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Mon Jan 21 12:53:35 2019 +0000
-
- upstream: add "-v" flags to ssh-add and ssh-pkcs11-helper to turn up
-
- debug verbosity.
-
- Make ssh-agent turn on ssh-pkcs11-helper's verbosity when it is run
- in debug mode ("ssh-agent -d"), so we get to see errors from the
- PKCS#11 code.
-
- ok markus@
-
- OpenBSD-Commit-ID: 0a798643c6a92a508df6bd121253ba1c8bee659d
-
-commit 49d8c8e214d39acf752903566b105d06c565442a
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Mon Jan 21 12:50:12 2019 +0000
-
- upstream: adapt to changes in KEX APIs and file removals
-
- OpenBSD-Regress-ID: 54d6857e7c58999c7a6d40942ab0fed3529f43ca
-
-commit 35ecc53a83f8e8baab2e37549addfd05c73c30f1
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Mon Jan 21 12:35:20 2019 +0000
-
- upstream: adapt to changes in KEX API and file removals
-
- OpenBSD-Regress-ID: 92cad022d3b0d11e08f3e0055d6a14b8f994c0d7
-
-commit 7d69aae64c35868cc4f644583ab973113a79480e
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Mon Jan 21 12:29:35 2019 +0000
-
- upstream: adapt to bignum1 API removal and bignum2 API change
-
- OpenBSD-Regress-ID: cea6ff270f3d560de86b355a87a2c95b55a5ca63
-
-commit beab553f0a9578ef9bffe28b2c779725e77b39ec
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Mon Jan 21 09:13:41 2019 +0000
-
- upstream: remove hack to use non-system libcrypto
-
- OpenBSD-Regress-ID: ce72487327eee4dfae1ab0212a1f33871fe0809f
-
-commit 4dc06bd57996f1a46b4c3bababe0d09bc89098f7
-Author: Damien Miller <djm@mindrot.org>
-Date: Mon Jan 21 23:14:04 2019 +1100
-
- depend
-
-commit 70edd73edc4df54e5eee50cd27c25427b34612f8
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Mon Jan 21 12:08:13 2019 +0000
-
- upstream: fix reversed arguments to kex_load_hostkey(); manifested as
-
- errors in cert-hostkey.sh regress failures.
-
- OpenBSD-Commit-ID: 12dab63850b844f84d5a67e86d9e21a42fba93ba
-
-commit f1185abbf0c9108e639297addc77f8757ee00eb3
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Mon Jan 21 11:22:00 2019 +0000
-
- upstream: forgot to cvs add this file in previous series of commits;
-
- grrr
-
- OpenBSD-Commit-ID: bcff316c3e7da8fd15333e05d244442c3aaa66b0
-
-commit 7bef390b625bdc080f0fd4499ef03cef60fca4fa
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Mon Jan 21 10:44:21 2019 +0000
-
- upstream: nothing shall escape this purge
-
- OpenBSD-Commit-ID: 4795b0ff142b45448f7e15f3c2f77a947191b217
-
-commit aaca72d6f1279b842066e07bff797019efeb2c23
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Mon Jan 21 10:40:11 2019 +0000
-
- upstream: rename kex->kem_client_pub -> kex->client_pub now that
-
- KEM has been renamed to kexgen
-
- from markus@ ok djm@
-
- OpenBSD-Commit-ID: fac6da5dc63530ad0da537db022a9a4cfbe8bed8
-
-commit 70867e1ca2eb08bbd494fe9c568df4fd3b35b867
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Mon Jan 21 10:38:54 2019 +0000
-
- upstream: merge kexkem[cs] into kexgen
-
- from markus@ ok djm@
-
- OpenBSD-Commit-ID: 87d886b7f1812ff9355fda1435f6ea9b71a0ac89
-
-commit 71e67fff946396caa110a7964da23480757258ff
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Mon Jan 21 10:35:09 2019 +0000
-
- upstream: pass values used in KEX hash computation as sshbuf
-
- rather than pointer+len
-
- suggested by me; implemented by markus@ ok me
-
- OpenBSD-Commit-ID: 994f33c464f4a9e0f1d21909fa3e379f5a0910f0
-
-commit 4b83e2a2cc0c12e671a77eaba1c1245894f4e884
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Mon Jan 21 10:33:49 2019 +0000
-
- upstream: remove kex_derive_keys_bn wrapper; no unused since the
-
- DH-like KEX methods have moved to KEM
-
- from markus@ ok djm@
-
- OpenBSD-Commit-ID: bde9809103832f349545e4f5bb733d316db9a060
-
-commit 92dda34e373832f34a1944e5d9ebbebb184dedc1
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Mon Jan 21 10:29:56 2019 +0000
-
- upstream: use KEM API for vanilla ECDH
-
- from markus@ ok djm@
-
- OpenBSD-Commit-ID: 6fbff96339a929835536b5730585d1d6057a352c
-
-commit b72357217cbe510a3ae155307a7be6b9181f1d1b
-Author: Damien Miller <djm@mindrot.org>
-Date: Mon Jan 21 23:11:21 2019 +1100
-
- fixup missing ssherr.h
-
-commit 9c9c97e14fe190931f341876ad98213e1e1dc19f
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Mon Jan 21 10:28:01 2019 +0000
-
- upstream: use KEM API for vanilla DH KEX
-
- from markus@ ok djm@
-
- OpenBSD-Commit-ID: af56466426b08a8be275412ae2743319e3d277c9
-
-commit 2f6a9ddbbf6ca8623c53c323ff17fb6d68d66970
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Mon Jan 21 10:24:09 2019 +0000
-
- upstream: use KEM API for vanilla c25519 KEX
-
- OpenBSD-Commit-ID: 38d937b85ff770886379dd66a8f32ab0c1c35c1f
-
-commit dfd591618cdf2c96727ac0eb65f89cf54af0d97e
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Mon Jan 21 10:20:12 2019 +0000
-
- upstream: Add support for a PQC KEX/KEM:
-
- sntrup4591761x25519-sha512@tinyssh.org using the Streamlined NTRU Prime
- 4591^761 implementation from SUPERCOP coupled with X25519 as a stop-loss. Not
- enabled by default.
-
- introduce KEM API; a simplified framework for DH-ish KEX methods.
-
- from markus@ feedback & ok djm@
-
- OpenBSD-Commit-ID: d687f76cffd3561dd73eb302d17a1c3bf321d1a7
-
-commit b1b2ff4ed559051d1035419f8f236275fa66d5d6
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Mon Jan 21 10:07:22 2019 +0000
-
- upstream: factor out kex_verify_hostkey() - again, duplicated
-
- almost exactly across client and server for several KEX methods.
-
- from markus@ ok djm@
-
- OpenBSD-Commit-ID: 4e4a16d949dadde002a0aacf6d280a684e20829c
-
-commit bb39bafb6dc520cc097780f4611a52da7f19c3e2
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Mon Jan 21 10:05:09 2019 +0000
-
- upstream: factor out kex_load_hostkey() - this is duplicated in
-
- both the client and server implementations for most KEX methods.
-
- from markus@ ok djm@
-
- OpenBSD-Commit-ID: 8232fa7c21fbfbcaf838313b0c166dc6c8762f3c
-
-commit dec5e9d33891e3bc3f1395d7db0e56fdc7f86dfc
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Mon Jan 21 10:03:37 2019 +0000
-
- upstream: factor out kex_dh_compute_key() - it's shared between
-
- plain DH KEX and DH GEX in both the client and server implementations
-
- from markus@ ok djm@
-
- OpenBSD-Commit-ID: 12186e18791fffcd4642c82e7e0cfdd7ea37e2ec
-
-commit e93bd98eab79b9a78f64ee8dd4dffc4d3979c7ae
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Mon Jan 21 10:00:23 2019 +0000
-
- upstream: factor out DH keygen; it's identical between the client
-
- and the server
-
- from markus@ ok djm@
-
- OpenBSD-Commit-ID: 2be57f6a0d44f1ab2c8de2b1b5d6f530c387fae9
-
-commit 5ae3f6d314465026d028af82609c1d49ad197655
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Mon Jan 21 09:55:52 2019 +0000
-
- upstream: save the derived session id in kex_derive_keys() rather
-
- than making each kex method implementation do it.
-
- from markus@ ok djm@
-
- OpenBSD-Commit-ID: d61ade9c8d1e13f665f8663c552abff8c8a30673
-
-commit 7be8572b32a15d5c3dba897f252e2e04e991c307
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Mon Jan 21 09:54:11 2019 +0000
-
- upstream: Make sshpkt_get_bignum2() allocate the bignum it is
-
- parsing rather than make the caller do it. Saves a lot of boilerplate code.
-
- from markus@ ok djm@
-
- OpenBSD-Commit-ID: 576bf784f9a240f5a1401f7005364e59aed3bce9
-
-commit 803178bd5da7e72be94ba5b4c4c196d4b542da4d
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Mon Jan 21 09:52:25 2019 +0000
-
- upstream: remove obsolete (SSH v.1) sshbuf_get/put_bignum1
-
- functions
-
- from markus@ ok djm@
-
- OpenBSD-Commit-ID: 0380b1b2d9de063de3c5a097481a622e6a04943e
-
-commit f3ebaffd8714be31d4345f90af64992de4b3bba2
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Mon Jan 21 09:49:37 2019 +0000
-
- upstream: fix all-zero check in kexc25519_shared_key
-
- from markus@ ok djm@
-
- OpenBSD-Commit-ID: 60b1d364e0d9d34d1d1ef1620cb92e36cf06712d
-
-commit 9d1a9771d0ad3a83af733bf3d2650b53f43c269f
-Author: jmc@openbsd.org <jmc@openbsd.org>
-Date: Mon Jan 21 07:09:10 2019 +0000
-
- upstream: - -T was added to the first synopsis by mistake - since
-
- "..." denotes optional, no need to surround it in []
-
- ok djm
-
- OpenBSD-Commit-ID: 918f6d8eed4e0d8d9ef5eadae1b8983d796f0e25
-
-commit 2f0bad2bf85391dbb41315ab55032ec522660617
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Mon Jan 21 21:28:27 2019 +1100
-
- Make --with-rpath take a flag instead of yes/no.
-
- Linkers need various flags for -rpath and similar, so make --with-rpath
- take an optional flag argument which is passed to the linker. ok djm@
-
-commit 23490a6c970ea1d03581a3b4208f2eb7a675f453
-Author: Damien Miller <djm@mindrot.org>
-Date: Mon Jan 21 15:05:43 2019 +1100
-
- fix previous test
-
-commit b6dd3277f2c49f9584a2097bc792e8f480397e87
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Mon Jan 21 13:50:17 2019 +1100
-
- Wrap ECC static globals in EC_KEY_METHOD_NEW too.
-
-commit b2eb9db35b7191613f2f4b934d57b25938bb34b3
-Author: Damien Miller <djm@mindrot.org>
-Date: Mon Jan 21 12:53:40 2019 +1100
-
- pass TEST_SSH_SSHPKCS11HELPER to regress tests
-
-commit ba58a529f45b3dae2db68607d8c54ae96e90e705
-Author: Damien Miller <djm@mindrot.org>
-Date: Mon Jan 21 12:31:29 2019 +1100
-
- make agent-pkcs11 search harder for softhsm2.so
-
-commit 662be40c62339ab645113c930ce689466f028938
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Mon Jan 21 02:05:38 2019 +0000
-
- upstream: always print the caller's error message in ossl_error(),
-
- even when there are no libcrypto errors to report.
-
- OpenBSD-Commit-ID: 09ebaa8f706e0eccedd209775baa1eee2ada806a
-
-commit ce46c3a077dfb4c531ccffcfff03f37775725b75
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Mon Jan 21 02:01:03 2019 +0000
-
- upstream: get the ex_data (pkcs11_key object) back from the keys at
-
- the index at which it was inserted, rather than assuming index 0
-
- OpenBSD-Commit-ID: 1f3a6ce0346c8014e895e50423bef16401510aa8
-
-commit 0a5f2ea35626022299ece3c8817a1abe8cf37b3e
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Mon Jan 21 01:05:00 2019 +0000
-
- upstream: GSSAPI code got missed when converting to new packet API
-
- OpenBSD-Commit-ID: 37e4f06ab4a0f4214430ff462ba91acba28b7851
-
-commit 2efcf812b4c1555ca3aff744820a3b3bccd68298
-Author: Damien Miller <djm@mindrot.org>
-Date: Mon Jan 21 11:57:21 2019 +1100
-
- Fix -Wunused when compiling PKCS#11 without ECDSA
-
-commit 3c0c657ed7cd335fc05c0852d88232ca7e92a5d9
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sun Jan 20 23:26:44 2019 +0000
-
- upstream: allow override of ssh-pkcs11-helper binary via
-
- $TEST_SSH_SSHPKCS11HELPER from markus@
-
- OpenBSD-Regress-ID: 7382a3d76746f5a792d106912a5819fd5e49e469
-
-commit 760ae37b4505453c6fa4faf1aa39a8671ab053af
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sun Jan 20 23:25:25 2019 +0000
-
- upstream: adapt agent-pkcs11.sh test to softhsm2 and add support
-
- for ECDSA keys
-
- work by markus@, ok djm@
-
- OpenBSD-Regress-ID: 1ebc2be0e88eff1b6d8be2f9c00cdc60723509fe
-
-commit b2ce8b31a1f974a13e6d12e0a0c132b50bc45115
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sun Jan 20 23:24:19 2019 +0000
-
- upstream: add "extra:" target to run some extra tests that are not
-
- enabled by default (currently includes agent-pkcs11.sh); from markus@
-
- OpenBSD-Regress-ID: 9a969e1adcd117fea174d368dcb9c61eb50a2a3c
-
-commit 632976418d60b7193597bbc6ac7ca33981a41aab
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Mon Jan 21 00:47:34 2019 +0000
-
- upstream: use ECDSA_SIG_set0() instead of poking signature values into
-
- structure directly; the latter works on LibreSSL but not on OpenSSL. From
- portable.
-
- OpenBSD-Commit-ID: 5b22a1919d9cee907d3f8a029167f70a481891c6
-
-commit 5de6ac2bad11175135d9b819b3546db0ca0b4878
-Author: Damien Miller <djm@mindrot.org>
-Date: Mon Jan 21 11:44:19 2019 +1100
-
- remove HAVE_DLOPEN that snuck in
-
- portable doesn't use this
-
-commit e2cb445d786f7572da2af93e3433308eaed1093a
-Author: Damien Miller <djm@mindrot.org>
-Date: Mon Jan 21 11:32:28 2019 +1100
-
- conditionalise ECDSA PKCS#11 support
-
- Require EC_KEY_METHOD support in libcrypto, evidenced by presence
- of EC_KEY_METHOD_new() function.
-
-commit fcb1b0937182d0137a3c357c89735d0dc5869d54
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sun Jan 20 23:12:35 2019 +0000
-
- upstream: we use singleton pkcs#11 RSA_METHOD and EC_KEY_METHOD
-
- now, so there is no need to keep a copy of each in the pkcs11_key object.
-
- work by markus@, ok djm@
-
- OpenBSD-Commit-ID: 43b4856516e45c0595f17a8e95b2daee05f12faa
-
-commit 6529409e85890cd6df7e5e81d04e393b1d2e4b0b
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sun Jan 20 23:11:11 2019 +0000
-
- upstream: KNF previous; from markus@
-
- OpenBSD-Commit-ID: 3dfe35e25b310c3968b1e4e53a0cb1d03bda5395
-
-commit 58622a8c82f4e2aad630580543f51ba537c1f39e
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sun Jan 20 23:10:33 2019 +0000
-
- upstream: use OpenSSL's RSA reference counting hooks to
-
- implicitly clean up pkcs11_key objects when their owning RSA object's
- reference count drops to zero. Simplifies the cleanup path and makes it more
- like ECDSA's
-
- work by markus@, ok djm@
-
- OpenBSD-Commit-ID: 74b9c98f405cd78f7148e9e4a4982336cd3df25c
-
-commit f118542fc82a3b3ab0360955b33bc5a271ea709f
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sun Jan 20 23:08:24 2019 +0000
-
- upstream: make the PKCS#11 RSA code more like the new PKCS#11
-
- ECDSA code: use a single custom RSA_METHOD instead of a method per key
-
- suggested by me, but markus@ did all the work.
- ok djm@
-
- OpenBSD-Commit-ID: 8aafcebe923dc742fc5537a995cee549d07e4b2e
-
-commit 445cfce49dfc904c6b8ab25afa2f43130296c1a5
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sun Jan 20 23:05:52 2019 +0000
-
- upstream: fix leak of ECDSA pkcs11_key objects
-
- work by markus, ok djm@
-
- OpenBSD-Commit-ID: 9fc0c4f1d640aaa5f19b8d70f37ea19b8ad284a1
-
-commit 8a2467583f0b5760787273796ec929190c3f16ee
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sun Jan 20 23:03:26 2019 +0000
-
- upstream: use EVP_PKEY_get0_EC_KEY() instead of direct access of
-
- EC_KEY internals as that won't work on OpenSSL
-
- work by markus@, feedback and ok djm@
-
- OpenBSD-Commit-ID: 4a99cdb89fbd6f5155ef8c521c99dc66e2612700
-
-commit 24757c1ae309324e98d50e5935478655be04e549
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sun Jan 20 23:01:59 2019 +0000
-
- upstream: cleanup PKCS#11 ECDSA pubkey loading: the returned
-
- object should never have a DER header
-
- work by markus; feedback and ok djm@
-
- OpenBSD-Commit-ID: b617fa585eddbbf0b1245b58b7a3c4b8d613db17
-
-commit 749aef30321595435ddacef2f31d7a8f2b289309
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sun Jan 20 23:00:12 2019 +0000
-
- upstream: cleanup unnecessary code in ECDSA pkcs#11 signature
-
- work by markus@, feedback and ok djm@
-
- OpenBSD-Commit-ID: affa5ca7d58d59fbd16169f77771dcdbd2b0306d
-
-commit 0c50992af49b562970dd0ba3f8f151f1119e260e
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sun Jan 20 22:57:45 2019 +0000
-
- upstream: cleanup pkcs#11 client code: use sshkey_new in instead
-
- of stack- allocating a sshkey
-
- work by markus@, ok djm@
-
- OpenBSD-Commit-ID: a048eb6ec8aa7fa97330af927022c0da77521f91
-
-commit 854bd8674ee5074a239f7cadf757d55454802e41
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sun Jan 20 22:54:30 2019 +0000
-
- upstream: allow override of the pkcs#11 helper binary via
-
- $SSH_PKCS11_HELPER; needed for regress tests.
-
- work by markus@, ok me
-
- OpenBSD-Commit-ID: f78d8185500bd7c37aeaf7bd27336db62f0f7a83
-
-commit 93f02107f44d63a016d8c23ebd2ca9205c495c48
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sun Jan 20 22:51:37 2019 +0000
-
- upstream: add support for ECDSA keys in PKCS#11 tokens
-
- Work by markus@ and Pedro Martelletto, feedback and ok me@
-
- OpenBSD-Commit-ID: a37d651e221341376636056512bddfc16efb4424
-
-commit aa22c20e0c36c2fc610cfcc793b0d14079c38814
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sun Jan 20 22:03:29 2019 +0000
-
- upstream: add option to test whether keys in an agent are usable,
-
- by performing a signature and a verification using each key "ssh-add -T
- pubkey [...]"
-
- work by markus@, ok djm@
-
- OpenBSD-Commit-ID: 931b888a600b6a883f65375bd5f73a4776c6d19b
-
-commit a36b0b14a12971086034d53c0c3dfbad07665abe
-Author: tb@openbsd.org <tb@openbsd.org>
-Date: Sun Jan 20 02:01:59 2019 +0000
-
- upstream: Fix BN_is_prime_* calls in SSH, the API returns -1 on
-
- error.
-
- Found thanks to BoringSSL's commit 53409ee3d7595ed37da472bc73b010cd2c8a5ffd
- by David Benjamin.
-
- ok djm, dtucker
-
- OpenBSD-Commit-ID: 1ee832be3c44b1337f76b8562ec6d203f3b072f8
-
-commit ec4776bb01dd8d61fddc7d2a31ab10bf3d3d829a
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Sun Jan 20 01:12:40 2019 +0000
-
- upstream: DH-GEX min value is now specified in RFC8270. ok djm@
-
- OpenBSD-Commit-ID: 1229d0feb1d0ecefe05bf67a17578b263e991acc
-
-commit c90a7928c4191303e76a8c58b9008d464287ae1b
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Mon Jan 21 09:22:36 2019 +1100
-
- Check for cc before gcc.
-
- If cc is something other than gcc and is the system compiler prefer using
- that, unless otherwise told via $CC. ok djm@
-
-commit 9b655dc9c9a353f0a527f0c6c43a5e35653c9503
-Author: Damien Miller <djm@mindrot.org>
-Date: Sun Jan 20 14:55:27 2019 +1100
-
- last bits of old packet API / active_state global
-
-commit 3f0786bbe73609ac96e5a0d91425ee21129f8e04
-Author: Damien Miller <djm@mindrot.org>
-Date: Sun Jan 20 10:22:18 2019 +1100
-
- remove PAM dependencies on old packet API
-
- Requires some caching of values, because the PAM code isn't
- always called with packet context.
-
-commit 08f66d9f17e12c1140d1f1cf5c4dce67e915d3cc
-Author: Damien Miller <djm@mindrot.org>
-Date: Sun Jan 20 09:58:45 2019 +1100
-
- remove vestiges of old packet API from loginrec.c
-
-commit c327813ea1d740e3e367109c17873815aba1328e
-Author: Damien Miller <djm@mindrot.org>
-Date: Sun Jan 20 09:45:38 2019 +1100
-
- depend
-
-commit 135e302cfdbe91817294317c337cc38c3ff01cba
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sat Jan 19 22:30:52 2019 +0000
-
- upstream: fix error in refactor: use ssh_packet_disconnect() instead of
-
- sshpkt_error(). The first one logs the error and exits (what we want) instead
- of just logging and blundering on.
-
- OpenBSD-Commit-ID: 39f51b43641dce9ce0f408ea6c0e6e077e2e91ae
-
-commit 245c6a0b220b58686ee35bc5fc1c359e9be2faaa
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sat Jan 19 21:45:31 2019 +0000
-
- upstream: remove last traces of old packet API!
-
- with & ok markus@
-
- OpenBSD-Commit-ID: 9bd10437026423eb8245636ad34797a20fbafd7d
-
-commit 04c091fc199f17dacf8921df0a06634b454e2722
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sat Jan 19 21:43:56 2019 +0000
-
- upstream: remove last references to active_state
-
- with & ok markus@
-
- OpenBSD-Commit-ID: 78619a50ea7e4ca2f3b54d4658b3227277490ba2
-
-commit ec00f918b8ad90295044266c433340a8adc93452
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sat Jan 19 21:43:07 2019 +0000
-
- upstream: convert monitor.c to new packet API
-
- with & ok markus@
-
- OpenBSD-Commit-ID: 61ecd154bd9804461a0cf5f495a29d919e0014d5
-
-commit 6350e0316981489d4205952d6904d6fedba5bfe0
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sat Jan 19 21:42:30 2019 +0000
-
- upstream: convert sshd.c to new packet API
-
- with & ok markus@
-
- OpenBSD-Commit-ID: ea569d3eaf9b5cf1bad52779fbfa5fa0b28af891
-
-commit a5e2ad88acff2b7d131ee6d5dc5d339b0f8c6a6d
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sat Jan 19 21:41:53 2019 +0000
-
- upstream: convert session.c to new packet API
-
- with & ok markus@
-
- OpenBSD-Commit-ID: fae817207e23099ddd248960c984f7b7f26ea68e
-
-commit 3a00a921590d4c4b7e96df11bb10e6f9253ad45e
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sat Jan 19 21:41:18 2019 +0000
-
- upstream: convert auth.c to new packet API
-
- with & ok markus@
-
- OpenBSD-Commit-ID: 7e10359f614ff522b52a3f05eec576257794e8e4
-
-commit 7ec5cb4d15ed2f2c5c9f5d00e6b361d136fc1e2d
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sat Jan 19 21:40:48 2019 +0000
-
- upstream: convert serverloop.c to new packet API
-
- with & ok markus@
-
- OpenBSD-Commit-ID: c92dd19b55457541478f95c0d6b318426d86d885
-
-commit 64c9598ac05332d1327cbf55334dee4172d216c4
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sat Jan 19 21:40:21 2019 +0000
-
- upstream: convert the remainder of sshconnect2.c to new packet
-
- API
-
- with & ok markus@
-
- OpenBSD-Commit-ID: 0986d324f2ceb5e8a12ac21c1bb10b3b4b1e0f71
-
-commit bc5e1169d101d16e3a5962a928db2bc49a8ef5a3
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sat Jan 19 21:39:12 2019 +0000
-
- upstream: convert the remainder of clientloop.c to new packet API
-
- with & ok markus@
-
- OpenBSD-Commit-ID: ce2fbbacb86a290f31da1e7bf04cddf2bdae3d1e
-
-commit 5ebce136a6105f084db8f0d7ee41981d42daec40
-Author: Damien Miller <djm@mindrot.org>
-Date: Sun Jan 20 09:44:53 2019 +1100
-
- upstream: convert auth2.c to new packet API
-
- OpenBSD-Commit-ID: ed831bb95ad228c6791bc18b60ce7a2edef2c999
-
-commit 172a592a53ebe8649c4ac0d7946e6c08eb151af6
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sat Jan 19 21:37:48 2019 +0000
-
- upstream: convert servconf.c to new packet API
-
- with & ok markus@
-
- OpenBSD-Commit-ID: 126553aecca302c9e02fd77e333b9cb217e623b4
-
-commit 8cc7a679d29cf6ecccfa08191e688c7f81ef95c2
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sat Jan 19 21:37:13 2019 +0000
-
- upstream: convert channels.c to new packet API
-
- with & ok markus@
-
- OpenBSD-Commit-ID: 0b8279b56113cbd4011fc91315c0796b63dc862c
-
-commit 06232038c794c7dfcb087be0ab0b3e65b09fd396
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sat Jan 19 21:36:38 2019 +0000
-
- upstream: convert sshconnect.c to new packet API
-
- with & ok markus@
-
- OpenBSD-Commit-ID: 222337cf6c96c347f1022d976fac74b4257c061f
-
-commit 25b2ed667216314471bb66752442c55b95792dc3
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sat Jan 19 21:36:06 2019 +0000
-
- upstream: convert ssh.c to new packet API
-
- with & ok markus@
-
- OpenBSD-Commit-ID: eb146878b24e85c2a09ee171afa6797c166a2e21
-
-commit e3128b38623eef2fa8d6e7ae934d3bd08c7e973e
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sat Jan 19 21:35:25 2019 +0000
-
- upstream: convert mux.c to new packet API
-
- with & ok markus@
-
- OpenBSD-Commit-ID: 4e3893937bae66416e984b282d8f0f800aafd802
-
-commit ed1df7226caf3a943a36d580d4d4e9275f8a61ee
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sat Jan 19 21:34:45 2019 +0000
-
- upstream: convert sshconnect2.c to new packet API
-
- with & ok markus@
-
- OpenBSD-Commit-ID: 1cb869e0d6e03539f943235641ea070cae2ebc58
-
-commit 23f22a4aaa923c61ec49a99ebaa383656e87fa40
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sat Jan 19 21:33:57 2019 +0000
-
- upstream: convert clientloop.c to new packet API
-
- with & ok markus@
-
- OpenBSD-Commit-ID: 497b36500191f452a22abf283aa8d4a9abaee7fa
-
-commit ad60b1179c9682ca5aef0b346f99ef68cbbbc4e5
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sat Jan 19 21:33:13 2019 +0000
-
- upstream: allow sshpkt_fatal() to take a varargs format; we'll
-
- use this to give packet-related fatal error messages more context (esp. the
- remote endpoint) ok markus@
-
- OpenBSD-Commit-ID: de57211f9543426b515a8a10a4f481666b2b2a50
-
-commit 0fa174ebe129f3d0aeaf4e2d1dd8de745870d0ff
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sat Jan 19 21:31:32 2019 +0000
-
- upstream: begin landing remaining refactoring of packet parsing
-
- API, started almost exactly six years ago.
-
- This change stops including the old packet_* API by default and makes
- each file that requires the old API include it explicitly. We will
- commit file-by-file refactoring to remove the old API in consistent
- steps.
-
- with & ok markus@
-
- OpenBSD-Commit-ID: 93c98a6b38f6911fd1ae025a1ec57807fb4d4ef4
-
-commit 4ae7f80dfd02f2bde912a67c9f338f61e90fa79f
-Author: tb@openbsd.org <tb@openbsd.org>
-Date: Sat Jan 19 04:15:56 2019 +0000
-
- upstream: Print an \r in front of the password prompt so parts of
-
- a password that was entered too early are likely clobbered by the prompt.
- Idea from doas.
-
- from and ok djm
- "i like it" deraadt
-
- OpenBSD-Commit-ID: 5fb97c68df6d8b09ab37f77bca1d84d799c4084e
-
-commit a6258e5dc314c7d504ac9f0fbc3be96475581dbe
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Fri Jan 18 11:09:01 2019 +1100
-
- Add minimal fchownat and fchmodat implementations.
-
- Fixes builds on at least OS X Lion, NetBSD 6 and Solaris 10.
-
-commit 091093d25802b87d3b2b09f2c88d9f33e1ae5562
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Fri Jan 18 12:11:42 2019 +1300
-
- Add a minimal implementation of utimensat().
-
- Some systems (eg older OS X) do not have utimensat, so provide minimal
- implementation in compat layer. Fixes build on at least El Capitan.
-
-commit 609644027dde1f82213699cb6599e584c7efcb75
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Tue Jan 1 22:20:16 2019 +0000
-
- upstream: regress bits for banner processing refactor (this test was
-
- depending on ssh returning a particular error message for banner parsing
- failure)
-
- reminded by bluhm@
-
- OpenBSD-Regress-ID: f24fc303d40931157431df589b386abf5e1be575
-
-commit f47d72ddad75b93d3cbc781718b0fa9046c03df8
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Thu Jan 17 04:45:09 2019 +0000
-
- upstream: tun_fwd_ifnames variable should b
-
- =?UTF-8?q?e=20extern;=20from=20Hanno=20B=C3=B6ck?=
- MIME-Version: 1.0
- Content-Type: text/plain; charset=UTF-8
- Content-Transfer-Encoding: 8bit
-
- OpenBSD-Commit-ID: d53dede6e521161bf04d39d09947db6253a38271
-
-commit 943d0965263cae1c080ce5a9d0b5aa341885e55d
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Thu Jan 17 04:20:53 2019 +0000
-
- upstream: include time.h for time(3)/nanosleep(2); from Ian
-
- McKellar
-
- OpenBSD-Commit-ID: 6412ccd06a88f65b207a1089345f51fa1244ea51
-
-commit dbb4dec6d5d671b5e9d67ef02162a610ad052068
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Thu Jan 17 01:50:24 2019 +0000
-
- upstream: many of the global variables in this file can be made static;
-
- patch from Markus Schmidt
-
- OpenBSD-Commit-ID: f3db619f67beb53257b21bac0e92b4fb7d5d5737
-
-commit 60d8c84e0887514c99c9ce071965fafaa1c3d34a
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Wed Jan 16 23:23:45 2019 +0000
-
- upstream: Add "-h" flag to sftp chown/chgrp/chmod commands to
-
- request they do not follow symlinks. Requires recently-committed
- lsetstat@openssh.com extension on the server side.
-
- ok markus@ dtucker@
-
- OpenBSD-Commit-ID: f93bb3f6f7eb2fb7ef1e59126e72714f1626d604
-
-commit dbbc7e0eab7262f34b8e0cd6efecd1c77b905ed0
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Wed Jan 16 23:22:10 2019 +0000
-
- upstream: add support for a "lsetstat@openssh.com" extension. This
-
- replicates the functionality of the existing SSH2_FXP_SETSTAT operation but
- does not follow symlinks. Based on a patch from Bert Haverkamp in bz#2067 but
- with more attribute modifications supported.
-
- ok markus@ dtucker@
-
- OpenBSD-Commit-ID: f7234f6e90db19655d55d936a115ee4ccb6aaf80
-
-commit 4a526941d328fc3d97068c6a4cbd9b71b70fe5e1
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Jan 4 03:27:50 2019 +0000
-
- upstream: eliminate function-static attempt counters for
-
- passwd/kbdint authmethods by moving them to the client authctxt; Patch from
- Markus Schmidt, ok markus@
-
- OpenBSD-Commit-ID: 4df4404a5d5416eb056f68e0e2f4fa91ba3b3f7f
-
-commit 8a8183474c41bd6cebaa917346b549af2239ba2f
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Jan 4 03:23:00 2019 +0000
-
- upstream: fix memory leak of ciphercontext when rekeying; bz#2942
-
- Patch from Markus Schmidt; ok markus@
-
- OpenBSD-Commit-ID: 7877f1b82e249986f1ef98d0ae76ce987d332bdd
-
-commit 5bed70afce0907b6217418d0655724c99b683d93
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Tue Jan 1 23:10:53 2019 +0000
-
- upstream: static on global vars, const on handler tables that contain
-
- function pointers; from Mike Frysinger
-
- OpenBSD-Commit-ID: 7ef2305e50d3caa6326286db43cf2cfaf03960e0
-
-commit 007a88b48c97d092ed2f501bbdcb70d9925277be
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Thu Dec 27 23:02:11 2018 +0000
-
- upstream: Request RSA-SHA2 signatures for
-
- rsa-sha2-{256|512}-cert-v01@openssh.com cert algorithms; ok markus@
-
- OpenBSD-Commit-ID: afc6f7ca216ccd821656d1c911d2a3deed685033
-
-commit eb347d086c35428c47fe52b34588cbbc9b49d9a6
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Thu Dec 27 03:37:49 2018 +0000
-
- upstream: ssh_packet_set_state() now frees ssh->kex implicitly, so
-
- don't do explicit kex_free() beforehand
-
- OpenBSD-Regress-ID: f2f73bad47f62a2040ccba0a72cadcb12eda49cf
-
-commit bb542f0cf6f7511a22a08c492861e256a82376a9
-Author: tedu@openbsd.org <tedu@openbsd.org>
-Date: Sat Dec 15 00:50:21 2018 +0000
-
- upstream: remove unused and problematic sudo clean. ok espie
-
- OpenBSD-Regress-ID: ca90c20a15a85b661e13e98b80c10e65cd662f7b
-
-commit 0a843d9a0e805f14653a555f5c7a8ba99d62c12d
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Thu Dec 27 03:25:24 2018 +0000
-
- upstream: move client/server SSH-* banners to buffers under
-
- ssh->kex and factor out the banner exchange. This eliminates some common code
- from the client and server.
-
- Also be more strict about handling \r characters - these should only
- be accepted immediately before \n (pointed out by Jann Horn).
-
- Inspired by a patch from Markus Schmidt.
- (lots of) feedback and ok markus@
-
- OpenBSD-Commit-ID: 1cc7885487a6754f63641d7d3279b0941890275b
-
-commit 434b587afe41c19391821e7392005068fda76248
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Fri Dec 7 04:36:09 2018 +0000
-
- upstream: Fix calculation of initial bandwidth limits. Account for
-
- written bytes before the initial timer check so that the first buffer written
- is accounted. Set the threshold after which the timer is checked such that
- the limit starts being computed as soon as possible, ie after the second
- buffer is written. This prevents an initial burst of traffic and provides a
- more accurate bandwidth limit. bz#2927, ok djm.
-
- OpenBSD-Commit-ID: ff3ef76e4e43040ec198c2718d5682c36b255cb6
-
-commit a6a0788cbbe8dfce2819ee43b09c80725742e21c
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Dec 7 03:39:40 2018 +0000
-
- upstream: only consider the ext-info-c extension during the initial
-
- KEX. It shouldn't be sent in subsequent ones, but if it is present we should
- ignore it.
-
- This prevents sshd from sending a SSH_MSG_EXT_INFO for REKEX for buggy
- these clients. Reported by Jakub Jelen via bz2929; ok dtucker@
-
- OpenBSD-Commit-ID: 91564118547f7807030ec537480303e2371902f9
-
-commit 63bba57a32c5bb6158d57cf4c47022daf89c14a0
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Dec 7 03:33:18 2018 +0000
-
- upstream: fix option letter pasto in previous
-
- OpenBSD-Commit-ID: e26c8bf2f2a808f3c47960e1e490d2990167ec39
-
-commit 737e4edd82406595815efadc28ed5161b8b0c01a
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Dec 7 03:32:26 2018 +0000
-
- upstream: mention that the ssh-keygen -F (find host in
-
- authorized_keys) and -R (remove host from authorized_keys) options may accept
- either a bare hostname or a [hostname]:port combo. bz#2935
-
- OpenBSD-Commit-ID: 5535cf4ce78375968b0d2cd7aa316fa3eb176780
-
-commit 8a22ffaa13391cfe5b40316d938fe0fb931e9296
-Author: Damien Miller <djm@mindrot.org>
-Date: Fri Dec 7 15:41:16 2018 +1100
-
- expose $SSH_CONNECTION in the PAM environment
-
- This makes the connection 4-tuple available to PAM modules that
- wish to use it in decision-making. bz#2741
-
-commit a784fa8c7a7b084d63bae82ccfea902131bb45c5
-Author: Kevin Adler <kadler@us.ibm.com>
-Date: Wed Dec 12 22:12:45 2018 -0600
-
- Don't pass loginmsg by address now that it's an sshbuf*
-
- In 120a1ec74, loginmsg was changed from the legacy Buffer type
- to struct sshbuf*, but it missed changing calls to
- sys_auth_allowed_user and sys_auth_record_login which passed
- loginmsg by address. Now that it's a pointer, just pass it directly.
-
- This only affects AIX, unless there are out of tree users.
-
-commit 285310b897969a63ef224d39e7cc2b7316d86940
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Dec 7 02:31:20 2018 +0000
-
- upstream: no need to allocate channels_pre/channels_post in
-
- channel_init_channels() as we do it anyway in channel_handler_init() that we
- call at the end of the function. Fix from Markus Schmidt via bz#2938
-
- OpenBSD-Commit-ID: 74893638af49e3734f1e33a54af1b7ea533373ed
-
-commit 87d6cf1cbc91df6815db8fe0acc7c910bc3d18e4
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Nov 30 02:24:52 2018 +0000
-
- upstream: don't attempt to connect to empty SSH_AUTH_SOCK; bz#293
-
- OpenBSD-Commit-ID: 0e8fc8f19f14b21adef7109e0faa583d87c0e929
-
-commit 91b19198c3f604f5eef2c56dbe36f29478243141
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Wed Nov 28 06:00:38 2018 +0000
-
- upstream: don't truncate user or host name in "user@host's
-
- OpenBSD-Commit-ID: e6ca01a8d58004b7f2cac0b1b7ce8f87e425e360
-
-commit dd0cf6318d9b4b3533bda1e3bc021b2cd7246b7a
-Author: jmc@openbsd.org <jmc@openbsd.org>
-Date: Fri Nov 23 06:58:28 2018 +0000
-
- upstream: tweak previous;
-
- OpenBSD-Commit-ID: 08f096922eb00c98251501c193ff9e83fbb5de4f
-
-commit 8a85f5458d1c802471ca899c97f89946f6666e61
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Sun Nov 25 21:44:05 2018 +1100
-
- Include stdio.h for FILE if needed.
-
-commit 16fb23f25454991272bfe4598cc05d20fcd25116
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Sun Nov 25 14:05:57 2018 +1100
-
- Reverse order of OpenSSL init functions.
-
- Try the new init function (OPENSSL_init_crypto) before falling back to
- the old one (OpenSSL_add_all_algorithms).
-
-commit 98f878d2272bf8dff21f2a0265d963c29e33fed2
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Sun Nov 25 14:05:08 2018 +1100
-
- Improve OpenSSL_add_all_algorithms check.
-
- OpenSSL_add_all_algorithms() may be a macro so check for that too.
-
-commit 9e34e0c59ab04514f9de9934a772283f7f372afe
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Nov 23 05:08:07 2018 +0000
-
- upstream: add a ssh_config "Match final" predicate
-
- Matches in same pass as "Match canonical" but doesn't require
- hostname canonicalisation be enabled. bz#2906 ok markus
-
- OpenBSD-Commit-ID: fba1dfe9f6e0cabcd0e2b3be13f7a434199beffa
-
-commit 4da58d58736b065b1182b563d10ad6765d811c6d
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Fri Nov 23 02:53:57 2018 +0000
-
- upstream: Remove now-unneeded ifdef SIGINFO around handler since it is
-
- now always used for SIGUSR1 even when SIGINFO is not defined. This will make
- things simpler in -portable.
-
- OpenBSD-Regress-ID: 4ff0265b335820b0646d37beb93f036ded0dc43f
-
-commit c721d5877509875c8515df0215fa1dab862013bc
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Fri Nov 23 14:11:20 2018 +1100
-
- Move RANDOM_SEED_SIZE outside ifdef.
-
- RANDOM_SEED_SIZE is used by both the OpenSSL and non-OpenSSL code
- This fixes the build with configureed --without-openssl.
-
-commit deb51552c3ce7ce72c8d0232e4f36f2e7c118c7d
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Thu Nov 22 19:59:28 2018 +1100
-
- Resync with OpenBSD by pulling in an ifdef SIGINFO.
-
-commit 28c7b2cd050f4416bfcf3869a20e3ea138aa52fe
-Author: Damien Miller <djm@mindrot.org>
-Date: Fri Nov 23 10:45:20 2018 +1100
-
- fix configure test for OpenSSL version
-
- square brackets in case statements may be eaten by autoconf.
-
- Report and fix from Filipp Gunbin; tweaked by naddy@
-
-commit 42c5ec4b97b6a1bae70f323952d0646af16ce710
-Author: Damien Miller <djm@mindrot.org>
-Date: Fri Nov 23 10:40:06 2018 +1100
-
- refactor libcrypto initialisation
-
- Don't call OpenSSL_add_all_algorithms() unless OpenSSL actually
- supports it.
-
- Move all libcrypto initialisation to a single function, and call that
- from seed_rng() that is called early in each tool's main().
-
- Prompted by patch from Rosen Penev
-
-commit 5b60b6c02009547a3e2a99d4886965de2a4719da
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Thu Nov 22 08:59:11 2018 +0000
-
- upstream: Output info on SIGUSR1 as well as
-
- SIGINFO to resync with portable. (ID sync only).
-
- OpenBSD-Regress-ID: 699d153e2de22dce51a1b270c40a98472d1a1b16
-
-commit e4ae345dc75b34fd870c2e8690d831d2c1088eb7
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Thu Nov 22 08:48:32 2018 +0000
-
- upstream: Append pid to temp files in /var/run and set a cleanup
-
- trap for them. This allows multiple instances of tests to run without
- colliding.
-
- OpenBSD-Regress-ID: 57add105ecdfc54752d8003acdd99eb68c3e0b4c
-
-commit f72d0f52effca5aa20a193217346615ecd3eed53
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Wed Oct 31 11:09:27 2018 +0000
-
- upstream: UsePrivilegeSeparation no is deprecated
-
- test "yes" and "sandbox".
-
- OpenBSD-Regress-ID: 80e685ed8990766527dc629b1affc09a75bfe2da
-
-commit 35d0e5fefc419bddcbe09d7fc163d8cd3417125b
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Wed Oct 17 23:28:05 2018 +0000
-
- upstream: add some knobs:
-
- 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).
-
- useful if you want to run the tests as a smoke test to exercise the
- functionality without waiting for all the fuzzers to run.
-
- OpenBSD-Regress-ID: e04d82ebec86068198cd903acf1c67563c57315e
-
-commit c1941293d9422a14dda372b4c21895e72aa7a063
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Thu Nov 22 15:52:26 2018 +1100
-
- Resync Makefile.inc with upstream.
-
- It's unused in -portable, but having it out of sync makes other syncs
- fail to apply.
-
-commit 928f1231f65f88cd4c73e6e0edd63d2cf6295d77
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Mon Nov 19 04:12:32 2018 +0000
-
- upstream: silence (to log level debug2) failure messages when
-
- loading the default hostkeys. Hostkeys explicitly specified in the
- configuration or on the command-line are still reported as errors, and
- failure to load at least one host key remains a fatal error.
- MIME-Version: 1.0
- Content-Type: text/plain; charset=UTF-8
- Content-Transfer-Encoding: 8bit
-
- Based on patch from Dag-Erling Smørgrav via
- https://github.com/openssh/openssh-portable/pull/103
-
- ok markus@
-
- OpenBSD-Commit-ID: ffc2e35a75d1008effaf05a5e27425041c27b684
-
-commit 7fca94edbe8ca9f879da9fdd2afd959c4180f4c7
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Sun Nov 18 22:43:29 2018 +0000
-
- upstream: Fix inverted logic for redirecting ProxyCommand stderr to
-
- /dev/null. Fixes mosh in proxycommand mode that was broken by the previous
- ProxyCommand change that was reported by matthieu@. ok djm@ danj@
-
- OpenBSD-Commit-ID: c6fc9641bc250221a0a81c6beb2e72d603f8add6
-
-commit ccef7c4faf914993b53035cd2b25ce02ab039c9d
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Nov 16 06:17:38 2018 +0000
-
- upstream: redirect stderr of ProxyCommands to /dev/null when ssh is
-
- started with ControlPersist; based on patch from Steffen Prohaska
-
- OpenBSD-Commit-ID: 1bcaa14a03ae80369d31021271ec75dce2597957
-
-commit 15182fd96845a03216d7ac5a2cf31c4e77e406e3
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Nov 16 06:10:29 2018 +0000
-
- upstream: make grandparent-parent-child sshbuf chains robust to
-
- use-after-free faults if the ancestors are freed before the descendents.
- Nothing in OpenSSH uses this deallocation pattern. Reported by Jann Horn
-
- OpenBSD-Commit-ID: d93501d1d2734245aac802a252b9bb2eccdba0f2
-
-commit 2a35862e664afde774d4a72497d394fe7306ccb5
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Nov 16 03:26:01 2018 +0000
-
- upstream: use path_absolute() for pathname checks; from Manoj Ampalam
-
- OpenBSD-Commit-ID: 482ce71a5ea5c5f3bc4d00fd719481a6a584d925
-
-commit d0d1dfa55be1c5c0d77ab3096b198a64235f936d
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Fri Nov 16 14:11:44 2018 +1100
-
- Test for OPENSSL_init_crypto before using.
-
- Check for the presence of OPENSSL_init_crypto and all the flags we want
- before trying to use it (bz#2931).
-
-commit 6010c0303a422a9c5fa8860c061bf7105eb7f8b2
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Nov 16 03:03:10 2018 +0000
-
- upstream: disallow empty incoming filename or ones that refer to the
-
- current directory; based on report/patch from Harry Sintonen
-
- OpenBSD-Commit-ID: f27651b30eaee2df49540ab68d030865c04f6de9
-
-commit aaed635e3a401cfcc4cc97f33788179c458901c3
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Nov 16 02:46:20 2018 +0000
-
- upstream: fix bug in client that was keeping a redundant ssh-agent
-
- socket around for the life of the connection; bz#2912; reported by Simon
- Tatham; ok dtucker@
-
- OpenBSD-Commit-ID: 4ded588301183d343dce3e8c5fc1398e35058478
-
-commit e76135e3007f1564427b2956c628923d8dc2f75a
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Nov 16 02:43:56 2018 +0000
-
- upstream: fix bug in HostbasedAcceptedKeyTypes and
-
- PubkeyAcceptedKeyTypes options. If only RSA-SHA2 siganture types were
- specified, then authentication would always fail for RSA keys as the monitor
- checks only the base key (not the signature algorithm) type against
- *AcceptedKeyTypes. bz#2746; reported by Jakub Jelen; ok dtucker
-
- OpenBSD-Commit-ID: 117bc3dc54578dbdb515a1d3732988cb5b00461b
-
-commit 5c1a63562cac0574c226224075b0829a50b48c9d
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Nov 16 02:30:20 2018 +0000
-
- upstream: support a prefix of '@' to suppress echo of sftp batch
-
- commands; bz#2926; ok dtucker@
-
- OpenBSD-Commit-ID: 9d635636bc84aeae796467e059f7634de990a79d
-
-commit 90ef45f7aac33eaf55ec344e101548a01e570f29
-Author: schwarze@openbsd.org <schwarze@openbsd.org>
-Date: Tue Nov 13 07:22:45 2018 +0000
-
- upstream: fix markup error (missing blank before delimiter); from
-
- Mike Frysinger <vapier at gentoo dot org>
-
- OpenBSD-Commit-ID: 1bc5392f795ca86318d695e0947eaf71a5a4f6d9
-
-commit 960e7c672dc106f3b759c081de3edb4d1138b36e
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Nov 9 02:57:58 2018 +0000
-
- upstream: typo in error message; caught by Debian lintian, via
-
- Colin Watson
-
- OpenBSD-Commit-ID: bff614c7bd1f4ca491a84e9b5999f848d0d66758
-
-commit 81f1620c836e6c79c0823ba44acca605226a80f1
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Nov 9 02:56:22 2018 +0000
-
- upstream: correct local variable name; from yawang AT microsoft.com
-
- OpenBSD-Commit-ID: a0c228390856a215bb66319c89cb3959d3af8c87
-
-commit 1293740e800fa2e5ccd38842a2e4970c6f3b9831
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Wed Oct 31 11:20:05 2018 +0000
-
- upstream: Import new moduli.
-
- OpenBSD-Commit-ID: c07772f58028fda683ee6abd41c73da3ff70d403
-
-commit 46925ae28e53fc9add336a4fcdb7ed4b86c3591c
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Oct 26 01:23:03 2018 +0000
-
- upstream: mention ssh-ed25519-cert-v01@openssh.com in list of cert
-
- key type at start of doc
-
- OpenBSD-Commit-ID: b46b0149256d67f05f2d5d01e160634ed1a67324
-
-commit 8d8340e2c215155637fe19cb1a837f71b2d55f7b
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Fri Nov 16 13:32:13 2018 +1100
-
- Remove fallback check for /usr/local/ssl.
-
- If configure could not find a working OpenSSL installation it would
- fall back to checking in /usr/local/ssl. This made sense back when
- systems did not ship with OpenSSL, but most do and OpenSSL 1.1 doesn't
- use that as a default any more. The fallback behaviour also meant
- that if you pointed --with-ssl-dir at a specific directory and it
- didn't work, it would silently use either the system libs or the ones
- in /usr/local/ssl. If you want to use /usr/local/ssl you'll need to
- pass configure --with-ssl-dir=/usr/local/ssl. ok djm@
-
-commit ce93472134fb22eff73edbcd173a21ae38889331
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Fri Nov 16 12:44:01 2018 +1100
-
- Fix check for OpenSSL 1.0.1 exactly.
-
- Both INSTALL and configure.ac claim OpenSSL >= 1.0.1 is supported; fix
- compile-time check for 1.0.1 to match.
-
-commit f2970868f86161a22b2c377057fa3891863a692a
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Sun Nov 11 15:58:20 2018 +1100
-
- Improve warnings in cygwin service setup.
-
- bz#2922, patch from vinschen at redhat.com.
-
-commit bd2d54fc1eee84bf87158a1277a50e6c8a303339
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Sun Nov 11 15:54:54 2018 +1100
-
- Remove hardcoded service name in cygwin setup.
-
- bz#2922, patch from Christian.Lupien at USherbrooke.ca, sanity check
- by vinschen at redhat.com.
-
-commit d0153c77bf7964e694f1d26c56c41a571b8e9466
-Author: Dag-Erling Smørgrav <des@des.no>
-Date: Tue Oct 9 23:03:40 2018 +0200
-
- AC_CHECK_SIZEOF() no longer needs a second argument.
-
-commit 9b47b083ca9d866249ada9f02dbd57c87b13806e
-Author: Manoj Ampalam <manojamp@microsoft.com>
-Date: Thu Nov 8 22:41:59 2018 -0800
-
- Fix error message w/out nistp521.
-
- Correct error message when OpenSSL doesn't support certain ECDSA key
- lengths.
-
-commit 624d19ac2d56fa86a22417c35536caceb3be346f
-Author: Eneas U de Queiroz <cote2004-github@yahoo.com>
-Date: Tue Oct 9 16:17:42 2018 -0300
-
- fix compilation with openssl built without ECC
-
- ECDSA code in openssh-compat.h and libressl-api-compat.c needs to be
- guarded by OPENSSL_HAS_ECC
-
- Signed-off-by: Eneas U de Queiroz <cote2004-github@yahoo.com>
-
-commit 1801cd11d99d05a66ab5248c0555f55909a355ce
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Thu Nov 8 15:03:11 2018 +1100
-
- Simplify OpenSSL 1.1 function checks.
-
- Replace AC_SEARCH_LIBS checks for OpenSSL 1.1 functions with a single
- AC_CHECK_FUNCS. ok djm@
-
-commit bc32f118d484e4d71d2a0828fd4eab7e4176c9af
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Mon Nov 5 17:31:24 2018 +1100
-
- Fix pasto for HAVE_EVP_CIPHER_CTX_SET_IV.
-
- Prevents unnecessary redefinition. Patch from mforney at mforney.org.
-
-commit 3719df60c66abc4b47200d41f571d67772f293ba
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Wed Oct 31 22:21:03 2018 +1100
-
- Import new moduli.
-
-commit 595605d4abede475339d6a1f07a8cc674c11d1c3
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Sun Oct 28 15:18:13 2018 +1100
-
- Update check for minimum OpenSSL version.
-
-commit 6ab75aba340d827140d7ba719787aabaf39a0355
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Sun Oct 28 15:16:31 2018 +1100
-
- Update required OpenSSL versions to match current.
-
-commit c801b0e38eae99427f37869370151b78f8e15c5d
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Sun Oct 28 14:34:12 2018 +1100
-
- Use detected version functions in openssl compat.
-
- Use detected functions in compat layer instead of guessing based on
- versions. Really fixes builds with LibreSSL, not just configure.
-
-commit 262d81a259d4aa1507c709ec9d5caa21c7740722
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Sat Oct 27 16:45:59 2018 +1100
-
- Check for the existence of openssl version funcs.
-
- Check for the existence of openssl version functions and use the ones
- detected instead of trying to guess based on the int32 version
- identifier. Fixes builds with LibreSSL.
-
-commit 406a24b25d6a2bdd70cacd16de7e899dcb2a8829
-Author: Damien Miller <djm@mindrot.org>
-Date: Fri Oct 26 13:43:28 2018 +1100
-
- fix builds on OpenSSL <= 1.0.x
-
- I thought OpenSSL 1.0.x offered the new-style OpenSSL_version_num() API
- to obtain version number, but they don't.
-
-commit 859754bdeb41373d372e36b5dc89c547453addb3
-Author: Damien Miller <djm@mindrot.org>
-Date: Tue Oct 23 17:10:41 2018 +1100
-
- remove remaining references to SSLeay
-
- Prompted by Rosen Penev
-
-commit b9fea45a68946c8dfeace72ad1f6657c18f2a98a
-Author: Damien Miller <djm@mindrot.org>
-Date: Tue Oct 23 17:10:35 2018 +1100
-
- regen depend
-
-commit a65784c9f9c5d00cf1a0e235090170abc8d07c73
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Tue Oct 23 05:56:35 2018 +0000
-
- upstream: refer to OpenSSL not SSLeay;
-
- we're old, but we don't have to act it
-
- OpenBSD-Commit-ID: 9ca38d11f8ed19e61a55108d1e892d696cee08ec
-
-commit c0a35265907533be10ca151ac797f34ae0d68969
-Author: Damien Miller <djm@mindrot.org>
-Date: Mon Oct 22 11:22:50 2018 +1100
-
- fix compile for openssl 1.0.x w/ --with-ssl-engine
-
- bz#2921, patch from cotequeiroz
-
-commit 31b49525168245abe16ad49d7b7f519786b53a38
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Mon Oct 22 20:05:18 2018 +1100
-
- Include openssl compatibility.
-
- Patch from rosenp at gmail.com via openssh-unix-dev.
-
-commit a4fc253f5f44f0e4c47aafe2a17d2c46481d3c04
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Oct 19 03:12:42 2018 +0000
-
- upstream: when printing certificate contents "ssh-keygen -Lf
-
- /path/certificate", include the algorithm that the CA used to sign the cert.
-
- OpenBSD-Commit-ID: 1ea20b5048a851a7a0758dcb9777a211a2c0dddd
-
-commit 83b3d99d2b47321b7ebb8db6f6ea04f3808bc069
-Author: florian@openbsd.org <florian@openbsd.org>
-Date: Mon Oct 15 11:28:50 2018 +0000
-
- upstream: struct sockaddr_storage is guaranteed to be large enough,
-
- no need to check the size. OK kn, deraadt
-
- OpenBSD-Commit-ID: 0aa56e92eb49c79f495b31a5093109ec5841f439
-
-commit aede1c34243a6f7feae2fb2cb686ade5f9be6f3d
-Author: Damien Miller <djm@mindrot.org>
-Date: Wed Oct 17 11:01:20 2018 +1100
-
- Require OpenSSL 1.1.x series 1.1.0g or greater
-
- Previous versions have a bug with EVP_CipherInit() when passed a
- NULL EVP_CIPHER, per https://github.com/openssl/openssl/pull/4613
-
- ok dtucker@
-
-commit 08300c211409c212e010fe2e2f2883e573a04ce2
-Author: Damien Miller <djm@mindrot.org>
-Date: Wed Oct 17 08:12:02 2018 +1100
-
- unbreak compilation with --with-ssl-engine
-
- Missing last argument to OPENSSL_init_crypto()
-
-commit 1673274aee67ce0eb6f00578b6f3d2bcbd58f937
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Tue Oct 16 14:45:57 2018 +1100
-
- Remove gcc spectre mitigation flags.
-
- 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@
-
-commit 4e23deefd7959ef83c73ed9cce574423438f6133
-Author: Damien Miller <djm@mindrot.org>
-Date: Tue Oct 16 10:51:52 2018 +1100
-
- Avoid deprecated OPENSSL_config when using 1.1.x
-
- OpenSSL 1.1.x soft-deprecated OPENSSL_config in favour of
- OPENSSL_init_crypto; pointed out by Jakub Jelen
-
-commit 797cdd9c8468ed1125ce60d590ae3f1397866af4
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Fri Oct 12 16:58:47 2018 +1100
-
- Don't avoid our *sprintf replacements.
-
- Don't let systems with broken printf(3) avoid our replacements
- via asprintf(3)/vasprintf(3) calling libc internally. From djm@
-
-commit e526127cbd2f8ad88fb41229df0c9b850c722830
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Fri Oct 12 16:43:35 2018 +1100
-
- Check if snprintf understands %zu.
-
- If the platforms snprintf and friends don't understand %zu, use the
- compat replacement. Prevents segfaults on those platforms.
-
-commit cf39f875191708c5f2f1a3c1c9019f106e74aea3
-Author: Damien Miller <djm@mindrot.org>
-Date: Fri Oct 12 09:48:05 2018 +1100
-
- remove stale link, tweak
-
-commit a7205e68decf7de2005810853b4ce6b222b65e2a
-Author: Damien Miller <djm@mindrot.org>
-Date: Fri Oct 12 09:47:20 2018 +1100
-
- update version numbers ahead of release
-
-commit 1a4a9cf80f5b92b9d1dadd0bfa8867c04d195391
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Thu Oct 11 03:48:04 2018 +0000
-
- upstream: don't send new-style rsa-sha2-*-cert-v01@openssh.com names to
-
- older OpenSSH that can't handle them. spotted by Adam Eijdenberg; ok dtucker
-
- OpenBSD-Commit-ID: 662bbc402e3d7c9b6c322806269698106a6ae631
-
-commit dc8ddcdf1a95e011c263486c25869bb5bf4e30ec
-Author: Damien Miller <djm@mindrot.org>
-Date: Thu Oct 11 13:08:59 2018 +1100
-
- update depends
-
-commit 26841ac265603fd2253e6832e03602823dbb4022
-Author: Damien Miller <djm@mindrot.org>
-Date: Thu Oct 11 13:02:11 2018 +1100
-
- some more duplicated key algorithm lines
-
- From Adam Eijdenberg
-
-commit 5d9d17603bfbb620195a4581025052832b4c4adc
-Author: Damien Miller <djm@mindrot.org>
-Date: Thu Oct 11 11:56:36 2018 +1100
-
- fix duplicated algorithm specification lines
-
- Spotted by Adam Eijdenberg
-
-commit ebfafd9c7a5b2a7fb515ee95dbe0e44e11d0a663
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Thu Oct 11 00:52:46 2018 +0000
-
- upstream: typo in plain RSA algorithm counterpart names for
-
- certificates; spotted by Adam Eijdenberg; ok dtucker@
-
- OpenBSD-Commit-ID: bfcdeb6f4fc9e7607f5096574c8f118f2e709e00
-
-commit c29b111e7d87c2324ff71c80653dd8da168c13b9
-Author: Damien Miller <djm@mindrot.org>
-Date: Thu Oct 11 11:29:35 2018 +1100
-
- check pw_passwd != NULL here too
-
- Again, for systems with broken NIS implementations.
-
- Prompted by coolbugcheckers AT gmail.com
-
-commit fe8e8f349a553ef4c567acd418aac769a82b7729
-Author: Damien Miller <djm@mindrot.org>
-Date: Thu Oct 11 11:03:15 2018 +1100
-
- check for NULL return from shadow_pw()
-
- probably unreachable on this platform; pointed out by
- coolbugcheckers AT gmail.com
-
-commit acc59cbe7a1fb169e1c3caba65a39bd74d6e030d
-Author: deraadt@openbsd.org <deraadt@openbsd.org>
-Date: Wed Oct 10 16:43:49 2018 +0000
-
- upstream: introducing openssh 7.9
-
- OpenBSD-Commit-ID: 42d526a9fe01a40dd299ac58014d3349adf40e25
-
-commit 12731158c75c8760a8bea06350eeb3e763fe1a07
-Author: Damien Miller <djm@mindrot.org>
-Date: Thu Oct 11 10:29:29 2018 +1100
-
- supply callback to PEM_read_bio_PrivateKey
-
- 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.
-
- Avoid this by providing a basic callback to avoid passing empty
- passphrases to OpenSSL in cases where one is required.
-
- Based on patch from Jakub Jelen in bz#2913; ok dtucker@
-
-commit d1d301a1dd5d6cc3a9ed93ab7ab09dda4cb456e0
-Author: Damien Miller <djm@mindrot.org>
-Date: Wed Oct 10 14:57:00 2018 +1100
-
- in pick_salt() avoid dereference of NULL passwords
-
- Apparently some NIS implementations can leave pw->pw_passwd (or the
- shadow equivalent) NULL.
-
- bz#2909; based on patch from Todd Eigenschink
-
-commit edbb6febccee084d212fdc0cb05b40cb1c646ab1
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Tue Oct 9 05:42:23 2018 +0000
-
- upstream: Treat all PEM_read_bio_PrivateKey() errors when a passphrase
-
- is specified as "incorrect passphrase" instead of trying to choose between
- that and "invalid format".
-
- 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.
-
- Report and repro recipe from Thomas Deutschmann in bz#2901
-
- ok markus@
-
- OpenBSD-Commit-ID: b1d4cd92395f9743f81c0d23aab2524109580870
-
-commit 2581333d564d8697837729b3d07d45738eaf5a54
-Author: naddy@openbsd.org <naddy@openbsd.org>
-Date: Fri Oct 5 14:26:09 2018 +0000
-
- upstream: Support using service names for port numbers.
-
- * 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.
-
- ok dtucker@ deraadt@
-
- OpenBSD-Commit-ID: e7f03633133205ab3dfbc67f9df7475fabae660d
-
-commit e0d6501e86734c48c8c503f81e1c0926e98c5c4c
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Thu Oct 4 07:47:35 2018 +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.
-
- Report and analysis by Nelson Elhage and Geoffrey Thomas in bz#2863
-
- ok dtucker@ markus@
-
- OpenBSD-Commit-ID: a48a2467fe938de4de69d2e7193d5fa701f12ae9
-
-commit 6f1aabb128246f445e33b8844fad3de9cb1d18cb
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Thu Oct 4 01:04:52 2018 +0000
-
- upstream: factor out channel status formatting from
-
- channel_open_message() so we can use it in other debug messages
-
- OpenBSD-Commit-ID: 9c3903ca28fcabad57f566c9d0045b41ab7d52ba
-
-commit f1dd179e122bdfdb7ca3072d9603607740efda05
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Thu Oct 4 00:10:11 2018 +0000
-
- upstream: include a little more information about the status and
-
- disposition of channel's extended (stderr) fd; makes debugging some things a
- bit easier. No behaviour change.
-
- OpenBSD-Commit-ID: 483eb6467dc7d5dbca8eb109c453e7a43075f7ce
-
-commit 2d1428b11c8b6f616f070f2ecedce12328526944
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Thu Oct 4 00:04:41 2018 +0000
-
- upstream: explicit_bzero here to be consistent with other kex*.c;
-
- report from coolbugcheckers AT gmail.com
-
- OpenBSD-Commit-ID: a90f146c5b5f5b1408700395e394f70b440856cb
-
-commit 5eff5b858e717e901e6af6596306a114de9f79f2
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Wed Oct 3 06:38:35 2018 +0000
-
- upstream: Allow ssh_config IdentityAgent directive to accept
-
- environment variable names as well as explicit paths. ok dtucker@
-
- OpenBSD-Commit-ID: 2f0996e103876c53d8c9dd51dcce9889d700767b
-
-commit a46ac4d86b25414d78b632e8173578b37e5f8a83
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Tue Oct 2 12:51:58 2018 +0000
-
- upstream: mention INFO@openssh.com for sending SIGINFO
-
- OpenBSD-Commit-ID: 132471eeb0df658210afd27852fe65131b26e900
-
-commit ff3a411cae0b484274b7900ef52ff4dad3e12876
-Author: Damien Miller <djm@mindrot.org>
-Date: Tue Oct 2 22:49:40 2018 +1000
-
- only support SIGINFO on systems with SIGINFO
-
-commit cd98925c6405e972dc9f211afc7e75e838abe81c
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Tue Oct 2 12:40:07 2018 +0000
-
- upstream: Add server support for signalling sessions via the SSH
-
- channel/ session protocol. Signalling is only supported to sesssions that are
- not subsystems and were not started with a forced command.
-
- Long requested in bz#1424
-
- Based on a patch from markus@ and reworked by dtucker@;
- ok markus@ dtucker@
-
- OpenBSD-Commit-ID: 4bea826f575862eaac569c4bedd1056a268be1c3
diff --git a/INSTALL b/INSTALL
index ee621da43..dddd912c5 100644
--- a/INSTALL
+++ b/INSTALL
@@ -1,3 +1,4 @@
+1. Prerequisites
----------------
A C compiler. Any C89 or better compiler should work. Where supported,
@@ -260,8 +261,8 @@ Replacing /etc/ssh with the correct path to the configuration directory.
(${prefix}/etc or whatever you specified with --sysconfdir during
configuration).
-If you have configured OpenSSH with EGD support, ensure that EGD is
-running and has collected some Entropy.
+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.
diff --git a/LICENCE b/LICENCE
index a2278a05d..5999c5e9d 100644
--- a/LICENCE
+++ b/LICENCE
@@ -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/Makefile.in b/Makefile.in
index acfb919da..b0293841a 100644
--- a/Makefile.in
+++ b/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@
@@ -95,7 +96,7 @@ LIBSSH_OBJS=${LIBOPENSSH_OBJS} \
cipher-ctr.o cleanup.o \
compat.o fatal.o hostfile.o \
log.o match.o moduli.o nchan.o packet.o \
- readpass.o ttymodes.o xmalloc.o addrmatch.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 \
@@ -106,7 +107,7 @@ LIBSSH_OBJS=${LIBOPENSSH_OBJS} \
hmac.o sc25519.o ge25519.o fe25519.o ed25519.o verify.o hash.o \
kex.o kexdh.o kexgex.o kexecdh.o kexc25519.o \
kexgexc.o kexgexs.o \
- sntrup4591761.o kexsntrup4591761x25519.o kexgen.o \
+ kexsntrup761x25519.o sntrup761.o kexgen.o \
sftp-realpath.o platform-pledge.o platform-tracing.o platform-misc.o \
sshbuf-io.o
@@ -125,12 +126,14 @@ 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 $(SKOBJS)
-SCP_OBJS= scp.o progressmeter.o
+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)
@@ -148,7 +151,7 @@ SSHKEYSCAN_OBJS=ssh-keyscan.o $(SKOBJS)
SFTPSERVER_OBJS=sftp-common.o sftp-server.o sftp-server-main.o
-SFTP_OBJS= sftp.o sftp-client.o sftp-common.o sftp-glob.o progressmeter.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
@@ -234,7 +237,7 @@ ssh-keyscan$(EXEEXT): $(LIBCOMPAT) libssh.a $(SSHKEYSCAN_OBJS)
$(LD) -o $@ $(SSHKEYSCAN_OBJS) $(LDFLAGS) -lssh -lopenbsd-compat -lssh $(LIBS)
sftp-server$(EXEEXT): $(LIBCOMPAT) libssh.a $(SFTPSERVER_OBJS)
- $(LD) -o $@ $(SFTPSERVER_OBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS)
+ $(LD) -o $@ $(SFTPSERVER_OBJS) $(LDFLAGS) -lssh -lopenbsd-compat -lssh $(LIBS)
sftp$(EXEEXT): $(LIBCOMPAT) libssh.a $(SFTP_OBJS)
$(LD) -o $@ $(SFTP_OBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) $(LIBEDIT)
@@ -271,12 +274,8 @@ clean: regressclean
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/sshsig/*.o
- rm -f regress/unittests/sshsig/test_sshsig$(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
@@ -287,10 +286,16 @@ 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
@@ -306,12 +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/sshsig/*.o
- rm -f regress/unittests/sshsig/test_sshsig
+ 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
@@ -322,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 ; \
@@ -488,16 +495,17 @@ uninstall:
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/sshsig
+ $(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
@@ -582,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
@@ -625,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
@@ -635,14 +670,6 @@ 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 \
- $(SKOBJS)
-
-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)
-
# These all need to be compiled -fPIC, so they are treated differently.
SK_DUMMY_OBJS=\
regress/misc/sk-dummy/sk-dummy.lo \
@@ -667,16 +694,17 @@ regress-binaries: regress-prep $(LIBCOMPAT) \
$(SK_DUMMY_LIBRARY)
regress-unit-binaries: regress-prep $(REGRESSLIBS) \
- regress/unittests/sshbuf/test_sshbuf$(EXEEXT) \
- regress/unittests/sshkey/test_sshkey$(EXEEXT) \
- regress/unittests/sshsig/test_sshsig$(EXEEXT) \
+ 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
@@ -687,6 +715,7 @@ unit: regress-unit-binaries
$(MAKE) \
.OBJDIR="$${BUILDDIR}/regress" \
.CURDIR="`pwd`" \
+ OBJ="$${BUILDDIR}/regress" \
$@ && echo $@ tests passed
interop-tests t-exec file-tests: regress-prep regress-binaries $(TARGETS)
@@ -713,6 +742,7 @@ interop-tests t-exec file-tests: regress-prep regress-binaries $(TARGETS)
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" \
diff --git a/PROTOCOL b/PROTOCOL
index ecdacb9dc..3141cda6f 100644
--- a/PROTOCOL
+++ b/PROTOCOL
@@ -292,6 +292,7 @@ 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
@@ -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.38 2020/07/05 23:59:45 djm Exp $
+$OpenBSD: PROTOCOL,v 1.42 2021/08/09 23:47:44 djm Exp $
diff --git a/PROTOCOL.agent b/PROTOCOL.agent
index 6947b46cd..ed47146a3 100644
--- a/PROTOCOL.agent
+++ b/PROTOCOL.agent
@@ -1,7 +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
-$OpenBSD: PROTOCOL.agent,v 1.13 2020/08/31 00:17:41 djm Exp $
-
-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/PROTOCOL.certkeys b/PROTOCOL.certkeys
index 1fce87006..68622e607 100644
--- a/PROTOCOL.certkeys
+++ b/PROTOCOL.certkeys
@@ -45,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.
@@ -159,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
@@ -217,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
@@ -234,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
@@ -256,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
----------
@@ -280,11 +287,11 @@ their data fields are:
Name Format Description
-----------------------------------------------------------------------------
-no-presence-required empty Flag indicating that signatures made
+no-touch-required empty Flag indicating that signatures made
with this certificate need not assert
- user presence. This option only make
- sense for the U2F/FIDO security key
- types that support this feature in
+ 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
@@ -298,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
@@ -311,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.17 2019/11/25 00:57:51 djm Exp $
+$OpenBSD: PROTOCOL.certkeys,v 1.19 2021/06/05 13:47:00 naddy Exp $
diff --git a/PROTOCOL.key b/PROTOCOL.key
index 959bd7aee..38df268b6 100644
--- a/PROTOCOL.key
+++ b/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/README b/README
index f69b441b5..5c7f8647d 100644
--- a/README
+++ b/README
@@ -1,4 +1,4 @@
-See https://www.openssh.com/releasenotes.html#8.4p1 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
diff --git a/README.md b/README.md
index 28fb43d2a..de4717737 100644
--- a/README.md
+++ b/README.md
@@ -1,5 +1,6 @@
# 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.
@@ -27,9 +28,13 @@ Stable release tarballs are available from a number of [download mirrors](https:
### Dependencies
-Portable OpenSSH is built using autoconf and make. It requires a working C compiler, standard library and headers, and [zlib](https://www.zlib.net/). ``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.
+Portable OpenSSH is built using autoconf and make. It requires a working C compiler, standard library and headers.
-FIDO security token support need [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.
+``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
@@ -43,7 +48,7 @@ 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:
diff --git a/README.platform b/README.platform
index 9210e07c8..7b754ba42 100644
--- a/README.platform
+++ b/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/aclocal.m4 b/aclocal.m4
index c1b774884..9d85d34d4 100644
--- a/aclocal.m4
+++ b/aclocal.m4
@@ -1,4 +1,4 @@
-# generated automatically by aclocal 1.16.2 -*- Autoconf -*-
+# generated automatically by aclocal 1.16.3 -*- Autoconf -*-
# Copyright (C) 1996-2020 Free Software Foundation, Inc.
diff --git a/addr.c b/addr.c
new file mode 100644
index 000000000..ba0fad4e9
--- /dev/null
+++ b/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/addr.h b/addr.h
new file mode 100644
index 000000000..5eff02628
--- /dev/null
+++ b/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/addrmatch.c b/addrmatch.c
index 5a402d065..b0dc09680 100644
--- a/addrmatch.c
+++ b/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/audit-bsm.c b/audit-bsm.c
index 0ba16c72c..ccfcf6f7f 100644
--- a/audit-bsm.c
+++ b/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);
diff --git a/auth-krb5.c b/auth-krb5.c
index 3096f1c8e..c99e4e430 100644
--- a/auth-krb5.c
+++ b/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/auth-options.c b/auth-options.c
index 98afdf5fe..335f03238 100644
--- a/auth-options.c
+++ b/auth-options.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: auth-options.c,v 1.93 2020/08/27 01:07:09 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>
*
@@ -79,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;
}
@@ -88,8 +88,7 @@ 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",
@@ -125,8 +124,8 @@ cert_option_list(struct sshauthopt *opts, struct sshbuf *oblob,
} 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) {
@@ -140,8 +139,8 @@ cert_option_list(struct sshauthopt *opts, struct sshbuf *oblob,
} 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) {
@@ -325,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;
@@ -398,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;
}
@@ -410,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)
@@ -811,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 */
diff --git a/auth-options.h b/auth-options.h
index 118a32087..6e29b727c 100644
--- a/auth-options.h
+++ b/auth-options.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: auth-options.h,v 1.30 2020/08/27 01:07:09 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>
@@ -23,7 +23,10 @@ struct passwd;
struct sshkey;
/* Maximum number of permitopen/permitlisten directives to accept */
-#define SSH_AUTHOPT_PERMIT_MAX 4096
+#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
diff --git a/auth-pam.c b/auth-pam.c
index 832382151..f39d03f4b 100644
--- a/auth-pam.c
+++ b/auth-pam.c
@@ -689,6 +689,12 @@ sshpam_init(struct ssh *ssh, Authctxt *authctxt)
const char *pam_user, *user = authctxt->user;
const char **ptr_pam_user = &pam_user;
+#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 "
@@ -721,9 +727,9 @@ sshpam_init(struct ssh *ssh, Authctxt *authctxt)
*/
sshpam_rhost = xstrdup(auth_get_canonical_hostname(ssh,
options.use_dns));
- sshpam_laddr = get_local_ipaddr(
+ sshpam_laddr = get_local_ipaddr(
ssh_packet_get_connection_in(ssh));
- xasprintf(&sshpam_conninfo, "SSH_CONNECTION=%.50s %d %.50s %d",
+ xasprintf(&sshpam_conninfo, "SSH_CONNECTION=%.50s %d %.50s %d",
ssh_remote_ipaddr(ssh), ssh_remote_port(ssh),
sshpam_laddr, ssh_local_port(ssh));
}
@@ -1386,6 +1392,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/auth-passwd.c b/auth-passwd.c
index 24fcb67b2..347d91e25 100644
--- a/auth-passwd.c
+++ b/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/auth-rhosts.c b/auth-rhosts.c
index e81321b49..0bc4d424c 100644
--- a/auth-rhosts.c
+++ b/auth-rhosts.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: auth-rhosts.c,v 1.52 2020/04/17 03:30:05 djm 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
@@ -223,7 +223,7 @@ auth_rhosts2(struct passwd *pw, const char *client_user, const char *hostname,
if (!rhosts_files[rhosts_file_index] &&
stat(_PATH_RHOSTS_EQUIV, &st) == -1 &&
stat(_PATH_SSH_HOSTS_EQUIV, &st) == -1) {
- debug3("%s: no hosts access files exist", __func__);
+ debug3_f("no hosts access files exist");
return 0;
}
@@ -232,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)) {
diff --git a/auth.c b/auth.c
index 9a5498b66..00b168b4e 100644
--- a/auth.c
+++ b/auth.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: auth.c,v 1.147 2020/08/27 01:07:09 djm Exp $ */
+/* $OpenBSD: auth.c,v 1.153 2021/07/05 00:50:25 dtucker Exp $ */
/*
* Copyright (c) 2000 Markus Friedl. All rights reserved.
*
@@ -352,27 +352,29 @@ auth_log(struct ssh *ssh, 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(ssh, 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(ssh, audit_classify_auth(method));
#endif
}
-
void
auth_maxtries_exceeded(struct ssh *ssh)
{
@@ -468,7 +470,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 &&
@@ -482,7 +484,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);
@@ -492,10 +494,10 @@ check_key_in_hostfiles(struct passwd *pw, struct sshkey *key, const char *host,
error("WARNING: revoked key for %s attempted authentication",
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);
@@ -514,7 +516,7 @@ 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;
}
@@ -569,11 +571,15 @@ getpwnamallow(struct ssh *ssh, const char *user)
#endif
struct passwd *pw;
struct connection_info *ci;
+ u_int i;
ci = get_connection_info(ssh, 1, options.use_dns);
ci->user = user;
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)
@@ -600,7 +606,7 @@ getpwnamallow(struct ssh *ssh, const char *user)
if (!allowed_user(ssh, pw))
return (NULL);
#ifdef HAVE_LOGIN_CAP
- if ((lc = login_getclass(pw->pw_class)) == NULL) {
+ if ((lc = login_getpwclass(pw)) == NULL) {
debug("unable to get login class: %s", user);
return (NULL);
}
@@ -631,7 +637,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;
}
@@ -644,9 +650,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;
}
@@ -672,7 +678,7 @@ 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
@@ -685,8 +691,7 @@ auth_debug_send(struct ssh *ssh)
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);
}
@@ -698,7 +703,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 *
@@ -729,9 +734,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 *
@@ -838,158 +841,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 (!path_absolute(av[0])) {
- error("%s path is not absolute", tag);
- return 0;
- }
- temporarily_use_uid(pw);
- if (stat(av[0], &st) == -1) {
- 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) == -1) {
- 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++)
- 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);
-
- /* Don't use permanently_set_uid() here to avoid fatal() */
- 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);
- }
-
- 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 */
@@ -1069,7 +920,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;
@@ -1083,7 +934,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();
@@ -1091,7 +942,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);
}
@@ -1166,8 +1017,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/auth.h b/auth.h
index becc672b5..43c7d3d40 100644
--- a/auth.h
+++ b/auth.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: auth.h,v 1.100 2019/09/06 05:23:55 djm Exp $ */
+/* $OpenBSD: auth.h,v 1.101 2020/12/22 00:12:22 djm Exp $ */
/*
* Copyright (c) 2000 Markus Friedl. All rights reserved.
@@ -225,12 +225,6 @@ 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)
diff --git a/auth2-chall.c b/auth2-chall.c
index 3acd0a837..021df8291 100644
--- a/auth2-chall.c
+++ b/auth2-chall.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: auth2-chall.c,v 1.53 2020/02/26 13:40:09 jsg 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.
@@ -112,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);
@@ -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/auth2-gss.c b/auth2-gss.c
index 9351e0428..60e36961c 100644
--- a/auth2-gss.c
+++ b/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/auth2-hostbased.c b/auth2-hostbased.c
index 5e9b7c65d..3a29126c3 100644
--- a/auth2-hostbased.c
+++ b/auth2-hostbased.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: auth2-hostbased.c,v 1.42 2019/11/25 00:51:37 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.
*
@@ -35,6 +35,7 @@
#include "xmalloc.h"
#include "ssh2.h"
#include "packet.h"
+#include "kex.h"
#include "sshbuf.h"
#include "log.h"
#include "misc.h"
@@ -54,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)
@@ -74,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:");
@@ -85,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 &&
@@ -108,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 ||
@@ -138,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
@@ -157,7 +156,7 @@ userauth_hostbased(struct ssh *ssh)
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);
@@ -183,7 +182,7 @@ hostbased_key_allowed(struct ssh *ssh, struct passwd *pw,
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] == '.') {
@@ -193,9 +192,8 @@ hostbased_key_allowed(struct ssh *ssh, struct passwd *pw,
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;
@@ -205,17 +203,17 @@ hostbased_key_allowed(struct ssh *ssh, struct passwd *pw,
"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;
@@ -237,7 +235,7 @@ hostbased_key_allowed(struct ssh *ssh, struct passwd *pw,
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,
@@ -245,7 +243,7 @@ hostbased_key_allowed(struct ssh *ssh, struct passwd *pw,
} 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/auth2-kbdint.c b/auth2-kbdint.c
index e23d2edd2..037139d44 100644
--- a/auth2-kbdint.c
+++ b/auth2-kbdint.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: auth2-kbdint.c,v 1.11 2019/11/13 04:47:52 deraadt Exp $ */
+/* $OpenBSD: auth2-kbdint.c,v 1.13 2021/07/02 05:11:20 dtucker Exp $ */
/*
* Copyright (c) 2000 Markus Friedl. All rights reserved.
*
@@ -52,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/auth2-none.c b/auth2-none.c
index dacb5fb83..02d6e341c 100644
--- a/auth2-none.c
+++ b/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/auth2-passwd.c b/auth2-passwd.c
index bb5f8192d..be4b8606a 100644
--- a/auth2-passwd.c
+++ b/auth2-passwd.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: auth2-passwd.c,v 1.18 2020/02/26 13:40:09 jsg Exp $ */
+/* $OpenBSD: auth2-passwd.c,v 1.19 2020/10/18 11:32:01 djm Exp $ */
/*
* Copyright (c) 2000 Markus Friedl. All rights reserved.
*
@@ -60,7 +60,7 @@ 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");
diff --git a/auth2-pubkey.c b/auth2-pubkey.c
index c3ecd9afc..9e32259a5 100644
--- a/auth2-pubkey.c
+++ b/auth2-pubkey.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: auth2-pubkey.c,v 1.100 2020/08/27 01:07:09 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.
*
@@ -47,6 +47,7 @@
#include "ssh.h"
#include "ssh2.h"
#include "packet.h"
+#include "kex.h"
#include "sshbuf.h"
#include "log.h"
#include "misc.h"
@@ -72,8 +73,6 @@
/* import */
extern ServerOptions options;
-extern u_char *session_id2;
-extern u_int session_id2_len;
static char *
format_key(const struct sshkey *key)
@@ -104,17 +103,17 @@ userauth_pubkey(struct ssh *ssh)
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("%s: sshbuf_from failed", __func__);
+ fatal_f("sshbuf_from failed");
if ((keystring = sshbuf_dtob64_string(pkbuf, 0)) == NULL)
- fatal("%s: sshbuf_dtob64 failed", __func__);
- debug2("%s: %s user %s %s public key %s %s", __func__,
+ 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);
@@ -124,21 +123,20 @@ userauth_pubkey(struct ssh *ssh)
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 &&
@@ -151,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);
@@ -168,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 */
@@ -204,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
@@ -221,9 +212,8 @@ userauth_pubkey(struct ssh *ssh)
if (authenticated == 1 && sig_details != NULL) {
auth2_record_info(authctxt, "signature count = %u",
sig_details->sk_counter);
- debug("%s: sk_counter = %u, sk_flags = 0x%02x",
- __func__, sig_details->sk_counter,
- sig_details->sk_flags);
+ 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;
@@ -256,17 +246,14 @@ userauth_pubkey(struct ssh *ssh)
}
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 ? */
@@ -284,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);
@@ -488,7 +475,8 @@ 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", options.authorized_principals_command);
goto out;
@@ -500,20 +488,20 @@ match_principals_command(struct ssh *ssh, struct passwd *user_pw,
}
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",
@@ -535,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;
@@ -598,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;
}
@@ -640,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);
@@ -685,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) "
@@ -697,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;
@@ -776,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;
}
/*
@@ -797,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;
@@ -928,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",
@@ -959,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;
}
@@ -980,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;
diff --git a/auth2.c b/auth2.c
index 242a7adbe..84d0ed16e 100644
--- a/auth2.c
+++ b/auth2.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: auth2.c,v 1.158 2020/03/06 18:16:21 markus Exp $ */
+/* $OpenBSD: auth2.c,v 1.161 2021/04/03 06:18:40 djm Exp $ */
/*
* Copyright (c) 2000 Markus Friedl. All rights reserved.
*
@@ -61,8 +61,6 @@
/* import */
extern ServerOptions options;
-extern u_char *session_id2;
-extern u_int session_id2_len;
extern struct sshbuf *loginmsg;
/* methods */
@@ -145,7 +143,7 @@ userauth_send_banner(struct ssh *ssh, const char *msg)
(r = sshpkt_put_cstring(ssh, msg)) != 0 ||
(r = sshpkt_put_cstring(ssh, "")) != 0 || /* language, unused */
(r = sshpkt_send(ssh)) != 0)
- fatal("%s: %s", __func__, ssh_err(r));
+ fatal_fr(r, "send packet");
debug("%s: sent", __func__);
}
@@ -230,13 +228,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;
}
@@ -252,8 +250,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);
}
@@ -286,8 +284,7 @@ input_userauth_request(int type, u_int32_t seq, struct ssh *ssh)
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();
@@ -417,7 +414,7 @@ userauth_finish(struct ssh *ssh, int authenticated, const char *method,
if ((r = sshpkt_start(ssh, SSH2_MSG_USERAUTH_SUCCESS)) != 0 ||
(r = sshpkt_send(ssh)) != 0 ||
(r = ssh_packet_write_wait(ssh)) != 0)
- fatal("%s: %s", __func__, ssh_err(r));
+ fatal_fr(r, "send success packet");
/* now we can break out */
authctxt->success = 1;
ssh_packet_set_log_preamble(ssh, "user %s", authctxt->user);
@@ -433,14 +430,14 @@ userauth_finish(struct ssh *ssh, int authenticated, const char *method,
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);
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("%s: %s", __func__, ssh_err(r));
+ fatal_fr(r, "send failure packet");
free(methods);
}
}
@@ -478,7 +475,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;
@@ -490,10 +487,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;
}
@@ -585,7 +582,7 @@ auth2_setup_methods_lists(Authctxt *authctxt)
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;
@@ -673,7 +670,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))
@@ -688,7 +685,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;
}
@@ -706,7 +703,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;
@@ -716,7 +713,7 @@ auth2_record_info(Authctxt *authctxt, const char *fmt, ...)
va_end(ap);
if (i == -1)
- fatal("%s: vasprintf failed", __func__);
+ fatal_f("vasprintf failed");
}
/*
@@ -732,7 +729,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;
@@ -741,11 +738,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++;
@@ -763,7 +760,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);
@@ -785,35 +782,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/authfd.c b/authfd.c
index 8288ef215..9f092f7cf 100644
--- a/authfd.c
+++ b/authfd.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: authfd.c,v 1.124 2020/06/26 05:03:36 djm 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
@@ -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) \
@@ -177,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
@@ -200,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)
+ (r = sshbuf_put_cstring(msg, password)) != 0 ||
+ (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;
@@ -507,7 +526,7 @@ ssh_add_identity_constrained(int sock, 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;
@@ -519,11 +538,10 @@ ssh_add_identity_constrained(int sock, struct sshkey *key,
(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;
@@ -538,7 +556,7 @@ 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)
@@ -555,11 +573,10 @@ ssh_remove_identity(int sock, const 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)
freezero(blob, blen);
@@ -595,11 +612,10 @@ ssh_update_card(int sock, int add, const char *reader_id, const char *pin,
if (constrained &&
(r = encode_constraints(msg, life, confirm, 0, NULL)) != 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;
@@ -626,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)
+ 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;
diff --git a/buildpkg.sh.in b/buildpkg.sh.in
index 4ccc5f8d1..15555cd7e 100644
--- a/buildpkg.sh.in
+++ b/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/canohost.c b/canohost.c
index abea9c6e6..a810da0ee 100644
--- a/canohost.c
+++ b/canohost.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: canohost.c,v 1.74 2019/06/28 13:35:04 deraadt 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);
@@ -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/chacha.h b/chacha.h
index 762052565..19a61e294 100644
--- a/chacha.h
+++ b/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/channels.c b/channels.c
index e4917f3c9..fd72f371d 100644
--- a/channels.c
+++ b/channels.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: channels.c,v 1.402 2020/09/20 05:47:25 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
@@ -228,7 +228,7 @@ channel_init_channels(struct ssh *ssh)
struct ssh_channels *sc;
if ((sc = calloc(1, sizeof(*sc))) == NULL)
- fatal("%s: allocation failed", __func__);
+ fatal_f("allocation failed");
sc->channels_alloc = 10;
sc->channels = xcalloc(sc->channels_alloc, sizeof(*sc->channels));
sc->IPv4or6 = AF_UNSPEC;
@@ -243,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;
@@ -333,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)
@@ -371,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;
@@ -383,9 +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("%s: sshbuf_set_max_size: %s", __func__, ssh_err(r));
+ 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);
@@ -422,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;
}
@@ -442,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
@@ -492,7 +518,7 @@ 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);
}
}
@@ -513,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);
}
}
@@ -530,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)++;
@@ -570,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 */
}
@@ -703,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;
}
@@ -771,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 */
}
}
@@ -813,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 */
}
}
@@ -870,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)
@@ -904,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;
}
@@ -930,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);
}
}
@@ -947,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
@@ -957,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);
}
}
@@ -980,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;
@@ -996,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;
@@ -1010,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;
@@ -1023,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;
@@ -1037,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;
@@ -1056,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;
@@ -1066,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
@@ -1295,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 */
@@ -1336,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);
@@ -1355,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;
}
@@ -1411,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 */
@@ -1457,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';
@@ -1502,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;
@@ -1602,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;
}
@@ -1637,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) {
@@ -1672,7 +1676,7 @@ 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;
}
@@ -1696,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);
}
@@ -1731,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);
}
@@ -1870,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
@@ -1883,7 +1874,7 @@ 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) == -1) {
@@ -1903,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",
@@ -1934,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);
}
}
@@ -1965,7 +1948,7 @@ channel_handle_rfd(struct ssh *ssh, Channel *c,
((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)))) {
@@ -1988,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;
}
@@ -2023,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);
@@ -2076,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);
@@ -2109,12 +2085,10 @@ channel_handle_efd_write(struct ssh *ssh, Channel *c,
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;
@@ -2139,18 +2113,12 @@ channel_handle_efd_read(struct ssh *ssh, Channel *c,
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;
}
@@ -2184,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;
}
@@ -2231,10 +2196,8 @@ read_mux(struct ssh *ssh, Channel *c, u_int need)
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);
}
@@ -2295,8 +2258,7 @@ channel_post_mux_client_write(struct ssh *ssh, Channel *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
@@ -2330,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) == -1) {
- error("%s getpeereid failed: %s", __func__,
- strerror(errno));
+ error_f("getpeereid failed: %s", strerror(errno));
close(newsock);
return;
}
@@ -2352,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 */
@@ -2365,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;
@@ -2458,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)
@@ -2469,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);
}
/*
@@ -2569,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
@@ -2589,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;
}
@@ -2607,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;
}
@@ -2638,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);
}
@@ -2746,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];
@@ -2758,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;
}
@@ -2792,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;
@@ -2809,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. */
@@ -2859,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;
}
}
@@ -2917,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 */
@@ -2937,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) {
@@ -2975,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;
@@ -3020,8 +2970,7 @@ channel_input_data(int type, u_int32_t seq, struct ssh *ssh)
/* Get the data. */
if ((r = sshpkt_get_string_direct(ssh, &data, &data_len)) != 0 ||
(r = sshpkt_get_end(ssh)) != 0)
- fatal("%s: channel %d: get data: %s", __func__,
- c->self, ssh_err(r));
+ fatal_fr(r, "channel %i: get data", c->self);
win_len = data_len;
if (c->datagram)
@@ -3052,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;
}
@@ -3077,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
@@ -3086,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 ||
@@ -3097,7 +3044,7 @@ channel_input_extended_data(int type, u_int32_t seq, struct ssh *ssh)
}
if ((r = sshpkt_get_string_direct(ssh, &data, &data_len)) != 0 ||
(r = sshpkt_get_end(ssh)) != 0) {
- error("%s: parse data: %s", __func__, ssh_err(r));
+ error_fr(r, "parse data");
ssh_packet_disconnect(ssh, "Invalid extended_data message");
}
@@ -3109,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;
}
@@ -3121,7 +3068,7 @@ channel_input_ieof(int type, u_int32_t seq, struct ssh *ssh)
int r;
if ((r = sshpkt_get_end(ssh)) != 0) {
- error("%s: parse data: %s", __func__, ssh_err(r));
+ error_fr(r, "parse data");
ssh_packet_disconnect(ssh, "Invalid ieof message");
}
@@ -3148,7 +3095,7 @@ channel_input_oclose(int type, u_int32_t seq, struct ssh *ssh)
if (channel_proxy_upstream(c, type, seq, ssh))
return 0;
if ((r = sshpkt_get_end(ssh)) != 0) {
- error("%s: parse data: %s", __func__, ssh_err(r));
+ error_fr(r, "parse data");
ssh_packet_disconnect(ssh, "Invalid oclose message");
}
chan_rcvd_oclose(ssh, c);
@@ -3175,7 +3122,7 @@ channel_input_open_confirmation(int type, u_int32_t seq, struct ssh *ssh)
(r = sshpkt_get_u32(ssh, &remote_window)) != 0 ||
(r = sshpkt_get_u32(ssh, &remote_maxpacket)) != 0 ||
(r = sshpkt_get_end(ssh)) != 0) {
- error("%s: window/maxpacket: %s", __func__, ssh_err(r));
+ error_fr(r, "window/maxpacket");
ssh_packet_disconnect(ssh, "Invalid open confirmation message");
}
@@ -3184,9 +3131,9 @@ channel_input_open_confirmation(int type, u_int32_t seq, struct ssh *ssh)
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);
@@ -3223,23 +3170,23 @@ channel_input_open_failure(int type, u_int32_t seq, struct ssh *ssh)
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));
+ 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 ||
(r = sshpkt_get_end(ssh)) != 0) {
- error("%s: message/lang: %s", __func__, ssh_err(r));
+ error_fr(r, "parse msg/lang");
ssh_packet_disconnect(ssh, "Invalid open failure message");
}
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);
@@ -3264,7 +3211,7 @@ channel_input_window_adjust(int type, u_int32_t seq, struct ssh *ssh)
return 0;
if ((r = sshpkt_get_u32(ssh, &adjust)) != 0 ||
(r = sshpkt_get_end(ssh)) != 0) {
- error("%s: adjust: %s", __func__, ssh_err(r));
+ error_fr(r, "parse adjust");
ssh_packet_disconnect(ssh, "Invalid window adjust message");
}
debug2("channel %d: rcvd adjust %u", c->self, adjust);
@@ -3286,10 +3233,10 @@ channel_input_status_confirm(int type, u_int32_t seq, struct ssh *ssh)
/* Reset keepalive timeout */
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))
@@ -3340,7 +3287,7 @@ channel_fwd_bind_addr(struct ssh *ssh, 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)) {
@@ -3414,8 +3361,8 @@ 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(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
@@ -3432,7 +3379,7 @@ channel_setup_fwd_listener_tcpip(struct ssh *ssh, int type,
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;
@@ -3464,7 +3411,7 @@ 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. */
@@ -3501,7 +3448,6 @@ channel_setup_fwd_listener_tcpip(struct ssh *ssh, int type,
}
/* Start listening for connections on the socket. */
if (listen(sock, SSH_LISTEN_BACKLOG) == -1) {
- error("listen: %.100s", strerror(errno));
error("listen [%s]:%s: %.100s", ntop, strport,
strerror(errno));
close(sock);
@@ -3529,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;
}
@@ -3580,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;
}
@@ -3593,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);
@@ -3628,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;
}
@@ -3650,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;
}
@@ -3698,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;
}
@@ -3714,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;
}
@@ -3725,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;
}
@@ -3897,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 ||
@@ -3908,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;
@@ -4017,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 ||
@@ -4026,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 */
@@ -4053,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 ||
@@ -4062,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.
*/
@@ -4157,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",
@@ -4170,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;
}
}
@@ -4225,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): "
@@ -4528,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);
}
}
@@ -4553,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;
}
@@ -4564,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);
@@ -4643,8 +4602,8 @@ x11_create_display_inet(struct ssh *ssh, int x11_display_offset,
if (x11_use_localhost)
set_reuseaddr(sock);
if (bind(sock, ai->ai_addr, ai->ai_addrlen) == -1) {
- debug2("%s: bind port %d: %.100s", __func__,
- port, strerror(errno));
+ debug2_f("bind port %d: %.100s", port,
+ strerror(errno));
close(sock);
for (n = 0; n < num_socks; n++)
close(socks[n]);
@@ -4902,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;
@@ -4926,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/channels.h b/channels.h
index 74e9b3f87..6bf86b003 100644
--- a/channels.h
+++ b/channels.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: channels.h,v 1.135 2020/09/20 05:47:25 djm Exp $ */
+/* $OpenBSD: channels.h,v 1.138 2021/05/19 01:24:05 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -63,6 +63,16 @@
#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)
@@ -139,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
@@ -177,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 */
@@ -187,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
@@ -266,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 */
@@ -289,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 *);
@@ -313,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/cipher.c b/cipher.c
index 8195199b3..5b3a86d69 100644
--- a/cipher.c
+++ b/cipher.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: cipher.c,v 1.117 2020/04/03 04:27:03 djm 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
@@ -91,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 },
@@ -496,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/clientloop.c b/clientloop.c
index 60b46d161..bfcd50c26 100644
--- a/clientloop.c
+++ b/clientloop.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: clientloop.c,v 1.346 2020/09/16 03:07:31 dtucker 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
@@ -115,15 +115,6 @@
/* 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 */
@@ -233,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 */
@@ -307,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;
@@ -322,15 +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__);
+ error_f("xauthfile path too long");
rmdir(xauthdir);
return -1;
}
@@ -356,7 +346,7 @@ client_x11_get_proto(struct ssh *ssh, const char *display,
SSH_X11_PROTO, x11_timeout_real,
_PATH_DEVNULL);
}
- debug2("%s: xauth command: %s", __func__, cmd);
+ debug2_f("xauth command: %s", cmd);
if (timeout != 0 && x11_refuse_time == 0) {
now = monotime() + 1;
@@ -445,7 +435,7 @@ client_check_window_change(struct ssh *ssh)
if (!received_window_change_signal)
return;
received_window_change_signal = 0;
- debug2("%s: changed", __func__);
+ debug2_f("changed");
channel_send_window_changes(ssh);
}
@@ -487,7 +477,7 @@ server_alive_check(struct ssh *ssh)
(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("%s: send packet: %s", __func__, ssh_err(r));
+ fatal_fr(r, "send packet");
/* Insert an empty placeholder to maintain ordering */
client_register_global_confirm(NULL, NULL);
schedule_server_alive_check();
@@ -569,10 +559,10 @@ client_wait_until_can_do_something(struct ssh *ssh,
/* 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 (options.server_alive_interval > 0 && !FD_ISSET(connection_in,
- *readsetp) && monotime() >= server_alive_time)
+ *readsetp) && monotime() >= server_alive_time)
/*
* ServerAlive check is needed. We can't rely on the select
* timing out since traffic on the client side such as port
@@ -629,8 +619,7 @@ client_process_net_input(struct ssh *ssh, 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;
}
@@ -650,8 +639,7 @@ client_process_net_input(struct ssh *ssh, 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;
}
@@ -699,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) {
@@ -750,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;
}
@@ -914,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) |
@@ -926,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");
}
/*
@@ -973,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);
@@ -1003,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);
@@ -1023,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: send packet: %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
@@ -1049,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 >
@@ -1063,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 '&':
@@ -1082,11 +1064,9 @@ 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();
@@ -1101,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,
@@ -1113,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;
@@ -1132,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 */
@@ -1160,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;
@@ -1246,30 +1222,30 @@ client_loop(struct ssh *ssh, int have_pty, int escape_char_arg,
debug("pledge: id");
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();
@@ -1285,7 +1261,7 @@ client_loop(struct ssh *ssh, int have_pty, int escape_char_arg,
/* Initialize buffer. */
if ((stderr_buffer = sshbuf_new()) == NULL)
- fatal("%s: sshbuf_new failed", __func__);
+ fatal_f("sshbuf_new failed");
client_init_dispatch(ssh);
@@ -1336,8 +1312,7 @@ 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 {
/*
@@ -1377,6 +1352,10 @@ client_loop(struct ssh *ssh, int have_pty, int escape_char_arg,
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.
@@ -1414,34 +1393,26 @@ client_loop(struct ssh *ssh, int have_pty, int escape_char_arg,
(r = sshpkt_put_cstring(ssh, "")) != 0 || /* language tag */
(r = sshpkt_send(ssh)) != 0 ||
(r = ssh_packet_write_wait(ssh)) != 0)
- fatal("%s: send disconnect: %s", __func__, ssh_err(r));
+ 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);
}
/*
@@ -1451,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. */
@@ -1462,7 +1433,7 @@ 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. */
@@ -1499,15 +1470,15 @@ client_request_forwarded_tcpip(struct ssh *ssh, const char *request_type,
(r = sshpkt_get_cstring(ssh, &originator_address, NULL)) != 0 ||
(r = sshpkt_get_u32(ssh, &originator_port)) != 0 ||
(r = sshpkt_get_end(ssh)) != 0)
- fatal("%s: parse packet: %s", __func__, ssh_err(r));
+ fatal_fr(r, "parse packet");
- debug("%s: listen %s port %d, originator %s port %d", __func__,
+ debug_f("listen %s port %d, originator %s port %d",
listen_address, listen_port, originator_address, originator_port);
if (listen_port > 0xffff)
- error("%s: invalid listen port", __func__);
+ error_f("invalid listen port");
else if (originator_port > 0xffff)
- error("%s: invalid originator port", __func__);
+ error_f("invalid originator port");
else {
c = channel_connect_by_listen_address(ssh,
listen_address, listen_port, "forwarded-tcpip",
@@ -1516,7 +1487,7 @@ client_request_forwarded_tcpip(struct ssh *ssh, const char *request_type,
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 */
@@ -1531,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;
}
}
@@ -1556,9 +1526,9 @@ client_request_forwarded_streamlocal(struct ssh *ssh,
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("%s: parse packet: %s", __func__, ssh_err(r));
+ fatal_fr(r, "parse packet");
- debug("%s: request: %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");
@@ -1588,7 +1558,7 @@ client_request_x11(struct ssh *ssh, const char *request_type, int rchan)
if ((r = sshpkt_get_cstring(ssh, &originator, NULL)) != 0 ||
(r = sshpkt_get_u32(ssh, &originator_port)) != 0 ||
(r = sshpkt_get_end(ssh)) != 0)
- fatal("%s: parse packet: %s", __func__, ssh_err(r));
+ fatal_fr(r, "parse packet");
/* XXX check permission */
/* XXX range check originator port? */
debug("client_request_x11: request from %s %u", originator,
@@ -1623,8 +1593,7 @@ client_request_agent(struct ssh *ssh, const char *request_type, int rchan)
}
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",
@@ -1785,16 +1754,15 @@ client_input_channel_req(int type, u_int32_t seq, struct ssh *ssh)
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);
}
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);
+ 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 ||
@@ -1814,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
@@ -1828,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
@@ -1840,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);
@@ -1849,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)
{
@@ -1856,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;
@@ -1882,6 +1930,63 @@ 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)
{
@@ -1901,11 +2006,11 @@ update_known_hosts(struct hostkeys_update_ctx *ctx)
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",
@@ -1916,7 +2021,7 @@ update_known_hosts(struct hostkeys_update_ctx *ctx)
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",
@@ -1965,11 +2070,12 @@ update_known_hosts(struct hostkeys_update_ctx *ctx)
*/
if (stat(options.user_hostfiles[i], &sb) != 0) {
if (errno == ENOENT) {
- debug("%s: known hosts file %s does not exist",
- __func__, strerror(errno));
+ debug_f("known hosts file %s does not "
+ "exist", options.user_hostfiles[i]);
} else {
- error("%s: known hosts file %s inaccessible",
- __func__, strerror(errno));
+ error_f("known hosts file %s "
+ "inaccessible: %s",
+ options.user_hostfiles[i], strerror(errno));
}
continue;
}
@@ -1978,8 +2084,8 @@ update_known_hosts(struct hostkeys_update_ctx *ctx)
i == 0 ? ctx->keys : NULL, i == 0 ? ctx->nkeys : 0,
options.hash_known_hosts, 0,
options.fingerprint_hash)) != 0) {
- error("%s: hostfile_replace_entries failed for %s: %s",
- __func__, options.user_hostfiles[i], ssh_err(r));
+ error_fr(r, "hostfile_replace_entries failed for %s",
+ options.user_hostfiles[i]);
}
}
}
@@ -1996,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");
@@ -2007,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;
}
/*
@@ -2040,23 +2141,26 @@ 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,
NULL)) != 0) {
- error("%s: server gave bad signature for %s key %zu",
- __func__, sshkey_type(ctx->keys[i]), i);
+ 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 */
+ fatal_f("ndone != ctx->nnew (%zu / %zu)", ndone, ctx->nnew);
if ((r = sshpkt_get_end(ssh)) != 0) {
- error("%s: protocol error", __func__);
+ error_f("protocol error");
goto out;
}
@@ -2102,9 +2206,10 @@ client_input_hostkeys(struct ssh *ssh)
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 */
@@ -2116,59 +2221,59 @@ client_input_hostkeys(struct ssh *ssh)
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) {
- do_log2(r == SSH_ERR_KEY_TYPE_UNKNOWN ?
+ do_log2_fr(r, r == SSH_ERR_KEY_TYPE_UNKNOWN ?
SYSLOG_LEVEL_DEBUG1 : SYSLOG_LEVEL_ERROR,
- "%s: parse key: %s", __func__, ssh_err(r));
+ "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,
@@ -2177,68 +2282,107 @@ client_input_hostkeys(struct ssh *ssh)
/* Find which keys we already know about. */
for (i = 0; i < options.num_user_hostfiles; i++) {
- debug("%s: searching %s for %s / %s", __func__,
+ 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|HKF_WANT_MATCH)) != 0) {
+ HKF_WANT_PARSE_KEY, 0)) != 0) {
if (r == SSH_ERR_SYSTEM_ERROR && errno == ENOENT) {
- debug("%s: hostkeys file %s does not exist",
- __func__, options.user_hostfiles[i]);
+ debug_f("hostkeys file %s does not exist",
+ options.user_hostfiles[i]);
continue;
}
- error("%s: hostkeys_foreach failed for %s: %s",
- __func__, options.user_hostfiles[i], ssh_err(r));
+ 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:
@@ -2279,6 +2423,19 @@ client_input_global_request(int type, u_int32_t seq, struct ssh *ssh)
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
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,
@@ -2288,10 +2445,10 @@ client_session2_setup(struct ssh *ssh, int id, int want_tty, int want_subsystem,
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);
ssh_packet_set_interactive(ssh, want_tty,
options.ip_qos_interactive, options.ip_qos_bulk);
@@ -2311,12 +2468,12 @@ client_session2_setup(struct ssh *ssh, int id, int want_tty, int want_subsystem,
(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("%s: build packet: %s", __func__, ssh_err(r));
+ fatal_fr(r, "build pty-req");
if (tiop == NULL)
tiop = get_saved_tio();
ssh_tty_make_modes(ssh, -1, tiop);
if ((r = sshpkt_send(ssh)) != 0)
- fatal("%s: send packet: %s", __func__, ssh_err(r));
+ fatal_fr(r, "send pty-req");
/* XXX wait for reply */
c->client_tty = 1;
}
@@ -2345,15 +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);
- if ((r = sshpkt_put_cstring(ssh, name)) != 0 ||
- (r = sshpkt_put_cstring(ssh, val)) != 0 ||
- (r = sshpkt_send(ssh)) != 0) {
- fatal("%s: send packet: %s",
- __func__, ssh_err(r));
- }
+ client_send_env(ssh, id, name, val);
free(name);
}
}
@@ -2365,13 +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);
- if ((r = sshpkt_put_cstring(ssh, name)) != 0 ||
- (r = sshpkt_put_cstring(ssh, val)) != 0 ||
- (r = sshpkt_send(ssh)) != 0)
- fatal("%s: send packet: %s", __func__, ssh_err(r));
+ client_send_env(ssh, id, name, val);
free(name);
}
@@ -2393,14 +2536,12 @@ client_session2_setup(struct ssh *ssh, int id, int want_tty, int want_subsystem,
}
if ((r = sshpkt_put_stringb(ssh, cmd)) != 0 ||
(r = sshpkt_send(ssh)) != 0)
- fatal("%s: send command: %s", __func__, ssh_err(r));
+ fatal_fr(r, "send command");
} else {
channel_request_start(ssh, id, "shell", 1);
client_expect_confirm(ssh, id, "shell", CONFIRM_CLOSE);
- if ((r = sshpkt_send(ssh)) != 0) {
- fatal("%s: send shell request: %s",
- __func__, ssh_err(r));
- }
+ if ((r = sshpkt_send(ssh)) != 0)
+ fatal_fr(r, "send shell");
}
}
@@ -2439,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]");
}
diff --git a/compat.c b/compat.c
index dec8e7e93..3f153bd42 100644
--- a/compat.c
+++ b/compat.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: compat.c,v 1.115 2020/07/05 23:59:45 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,63 +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;
+ ssh->compat = check[i].bugs;
+ return;
}
}
- debug("no match: %s", version);
- return 0;
+ 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);
+ debug2_f("original cipher proposal: %s", cipher_prop);
if ((cipher_prop = match_filter_denylist(cipher_prop, "aes*")) == NULL)
fatal("match_filter_denylist failed");
- debug2("%s: compat cipher proposal: %s", __func__, cipher_prop);
+ 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);
+ 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("%s: compat public key proposal: %s", __func__, pkalg_prop);
+ 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)
+ 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_denylist failed");
- if ((datafellows & SSH_OLD_DHGEX) != 0) {
+ 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_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/compat.h b/compat.h
index 66db42cc0..167409b2b 100644
--- a/compat.h
+++ b/compat.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: compat.h,v 1.55 2020/06/01 07:11:38 dtucker 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.
@@ -29,7 +29,7 @@
#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 */
@@ -58,10 +58,10 @@
#define SSH_BUG_HOSTKEYS 0x20000000
#define SSH_BUG_DHGEX_LARGE 0x40000000
-u_int compat_datafellows(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/config.h.in b/config.h.in
index 18e0b90c2..3b3222a8e 100644
--- a/config.h.in
+++ b/config.h.in
@@ -501,6 +501,9 @@
/* Define to 1 if you have the `EVP_CIPHER_CTX_get_iv' function. */
#undef HAVE_EVP_CIPHER_CTX_GET_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. */
#undef HAVE_EVP_CIPHER_CTX_IV
@@ -549,6 +552,9 @@
/* Define to 1 if you have the `explicit_bzero' function. */
#undef HAVE_EXPLICIT_BZERO
+/* Define to 1 if you have the `explicit_memset' function. */
+#undef HAVE_EXPLICIT_MEMSET
+
/* Define to 1 if you have the `fchmod' function. */
#undef HAVE_FCHMOD
@@ -906,6 +912,9 @@
/* Define to 1 if you have the `login_getcapbool' function. */
#undef HAVE_LOGIN_GETCAPBOOL
+/* Define to 1 if you have the `login_getpwclass' function. */
+#undef HAVE_LOGIN_GETPWCLASS
+
/* Define to 1 if you have the <login.h> header file. */
#undef HAVE_LOGIN_H
@@ -1058,6 +1067,9 @@
/* Define to 1 if you have the `proc_pidinfo' function. */
#undef HAVE_PROC_PIDINFO
+/* Define to 1 if you have the `pselect' function. */
+#undef HAVE_PSELECT
+
/* Define to 1 if you have the `pstat' function. */
#undef HAVE_PSTAT
@@ -1266,6 +1278,9 @@
/* Define to 1 if you have the `sigaction' function. */
#undef HAVE_SIGACTION
+/* Define to 1 if the system has the type `sighandler_t'. */
+#undef HAVE_SIGHANDLER_T
+
/* Define to 1 if you have the `sigvec' function. */
#undef HAVE_SIGVEC
@@ -1320,9 +1335,6 @@
/* Define to 1 if you have the `strftime' function. */
#undef HAVE_STRFTIME
-/* Silly mkstemp() */
-#undef HAVE_STRICT_MKSTEMP
-
/* Define to 1 if you have the <strings.h> header file. */
#undef HAVE_STRINGS_H
@@ -1874,8 +1886,8 @@
/* The size of `short int', as computed by sizeof. */
#undef SIZEOF_SHORT_INT
-/* The size of `size_t', as computed by sizeof. */
-#undef SIZEOF_SIZE_T
+/* The size of `time_t', as computed by sizeof. */
+#undef SIZEOF_TIME_T
/* Define as const if snprintf() can declare const char *fmt */
#undef SNPRINTF_CONST
@@ -1932,9 +1944,6 @@
/* Support routing domains using Linux VRF */
#undef SYS_RDOMAIN_LINUX
-/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */
-#undef TIME_WITH_SYS_TIME
-
/* Support passwords > 8 chars */
#undef UNIXWARE_LONG_PASSWORDS
@@ -1974,6 +1983,12 @@
/* Define if you have Solaris projects */
#undef USE_SOLARIS_PROJECTS
+/* compiler variable declarations after code */
+#undef VARIABLE_DECLARATION_AFTER_CODE
+
+/* compiler supports variable length arrays */
+#undef VARIABLE_LENGTH_ARRAYS
+
/* Define if you shouldn't strip 'tty' from your ttyname in [uw]tmp */
#undef WITH_ABBREV_NO_TTY
diff --git a/configure b/configure
index 57b261503..b66cfd657 100755
--- a/configure
+++ b/configure
@@ -1914,6 +1914,127 @@ fi
} # ac_fn_c_check_header_mongrel
+# ac_fn_c_check_func LINENO FUNC VAR
+# ----------------------------------
+# Tests whether FUNC exists, setting the cache variable VAR accordingly
+ac_fn_c_check_func ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if eval \${$3+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+/* Define $2 to an innocuous variant, in case <limits.h> declares $2.
+ For example, HP-UX 11i <limits.h> declares gettimeofday. */
+#define $2 innocuous_$2
+
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $2 (); below.
+ Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ <limits.h> exists even on freestanding compilers. */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $2
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char $2 ();
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined __stub_$2 || defined __stub___$2
+choke me
+#endif
+
+int
+main ()
+{
+return $2 ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ eval "$3=yes"
+else
+ eval "$3=no"
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+eval ac_res=\$$3
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+
+} # ac_fn_c_check_func
+
+# ac_fn_c_check_type LINENO TYPE VAR INCLUDES
+# -------------------------------------------
+# Tests whether TYPE exists after having included INCLUDES, setting cache
+# variable VAR accordingly.
+ac_fn_c_check_type ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if eval \${$3+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ eval "$3=no"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$4
+int
+main ()
+{
+if (sizeof ($2))
+ return 0;
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$4
+int
+main ()
+{
+if (sizeof (($2)))
+ return 0;
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+else
+ eval "$3=yes"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+eval ac_res=\$$3
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+
+} # ac_fn_c_check_type
+
# ac_fn_c_compute_int LINENO EXPR VAR INCLUDES
# --------------------------------------------
# Tries to find the compile-time value of EXPR in a program that includes
@@ -2097,127 +2218,6 @@ rm -f conftest.val
} # ac_fn_c_compute_int
-# ac_fn_c_check_func LINENO FUNC VAR
-# ----------------------------------
-# Tests whether FUNC exists, setting the cache variable VAR accordingly
-ac_fn_c_check_func ()
-{
- as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
-$as_echo_n "checking for $2... " >&6; }
-if eval \${$3+:} false; then :
- $as_echo_n "(cached) " >&6
-else
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-/* Define $2 to an innocuous variant, in case <limits.h> declares $2.
- For example, HP-UX 11i <limits.h> declares gettimeofday. */
-#define $2 innocuous_$2
-
-/* System header to define __stub macros and hopefully few prototypes,
- which can conflict with char $2 (); below.
- Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
- <limits.h> exists even on freestanding compilers. */
-
-#ifdef __STDC__
-# include <limits.h>
-#else
-# include <assert.h>
-#endif
-
-#undef $2
-
-/* Override any GCC internal prototype to avoid an error.
- Use char because int might match the return type of a GCC
- builtin and then its argument prototype would still apply. */
-#ifdef __cplusplus
-extern "C"
-#endif
-char $2 ();
-/* The GNU C library defines this for functions which it implements
- to always fail with ENOSYS. Some functions are actually named
- something starting with __ and the normal name is an alias. */
-#if defined __stub_$2 || defined __stub___$2
-choke me
-#endif
-
-int
-main ()
-{
-return $2 ();
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
- eval "$3=yes"
-else
- eval "$3=no"
-fi
-rm -f core conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
-fi
-eval ac_res=\$$3
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
-$as_echo "$ac_res" >&6; }
- eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
-
-} # ac_fn_c_check_func
-
-# ac_fn_c_check_type LINENO TYPE VAR INCLUDES
-# -------------------------------------------
-# Tests whether TYPE exists after having included INCLUDES, setting cache
-# variable VAR accordingly.
-ac_fn_c_check_type ()
-{
- as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
-$as_echo_n "checking for $2... " >&6; }
-if eval \${$3+:} false; then :
- $as_echo_n "(cached) " >&6
-else
- eval "$3=no"
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-$4
-int
-main ()
-{
-if (sizeof ($2))
- return 0;
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-$4
-int
-main ()
-{
-if (sizeof (($2)))
- return 0;
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
-
-else
- eval "$3=yes"
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-eval ac_res=\$$3
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
-$as_echo "$ac_res" >&6; }
- eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
-
-} # ac_fn_c_check_type
-
# ac_fn_c_check_member LINENO AGGR MEMBER VAR INCLUDES
# ----------------------------------------------------
# Tries to find if the field MEMBER exists in type AGGR, after including
@@ -3234,6 +3234,34 @@ ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+# XXX relax this after reimplementing logit() etc.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC supports C99-style variadic macros" >&5
+$as_echo_n "checking if $CC supports C99-style variadic macros... " >&6; }
+
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int f(int a, int b, int c) { return a + b + c; }
+#define F(a, ...) f(a, __VA_ARGS__)
+
+int
+main ()
+{
+return F(1, 2, -3);
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+else
+ as_fn_error $? "*** OpenSSH requires support for C99-style variadic macros" "$LINENO" 5
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
ac_aux_dir=
for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do
if test -f "$ac_dir/install-sh"; then
@@ -3334,7 +3362,6 @@ IFS=$ac_save_IFS
case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac
-
ac_ext=c
ac_cpp='$CPP $CPPFLAGS'
ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
@@ -6896,6 +6923,58 @@ $as_echo "#define NO_ATTRIBUTE_ON_PROTOTYPE_ARGS 1" >>confdefs.h
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if compiler supports variable length arrays" >&5
+$as_echo_n "checking if compiler supports variable length arrays... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <stdlib.h>
+int
+main ()
+{
+ int i; for (i=0; i<3; i++){int a[i]; a[i-1]=0;} exit(0);
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define VARIABLE_LENGTH_ARRAYS 1" >>confdefs.h
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if compiler accepts variable declarations after code" >&5
+$as_echo_n "checking if compiler accepts variable declarations after code... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <stdlib.h>
+int
+main ()
+{
+ int a; a = 1; int b = 1; exit(a-b);
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define VARIABLE_DECLARATION_AFTER_CODE 1" >>confdefs.h
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
if test "x$no_attrib_nonnull" != "x1" ; then
$as_echo "#define HAVE_ATTRIBUTE__NONNULL__ 1" >>confdefs.h
@@ -7266,40 +7345,6 @@ SPP_MSG="no"
# the --with-solaris-privs option and --with-sandbox=solaris).
SOLARIS_PRIVS="no"
-# The cast to long int works around a bug in the HP C Compiler
-# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
-# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
-# This bug is HP SR number 8606223364.
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of size_t" >&5
-$as_echo_n "checking size of size_t... " >&6; }
-if ${ac_cv_sizeof_size_t+:} false; then :
- $as_echo_n "(cached) " >&6
-else
- if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (size_t))" "ac_cv_sizeof_size_t" "$ac_includes_default"; then :
-
-else
- if test "$ac_cv_type_size_t" = yes; then
- { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
-$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-as_fn_error 77 "cannot compute sizeof (size_t)
-See \`config.log' for more details" "$LINENO" 5; }
- else
- ac_cv_sizeof_size_t=0
- fi
-fi
-
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_size_t" >&5
-$as_echo "$ac_cv_sizeof_size_t" >&6; }
-
-
-
-cat >>confdefs.h <<_ACEOF
-#define SIZEOF_SIZE_T $ac_cv_sizeof_size_t
-_ACEOF
-
-
-
# Check for some target-specific stuff
case "$host" in
*-*-aix*)
@@ -8235,10 +8280,6 @@ $as_echo_n "checking for seccomp architecture... " >&6; }
case "$host" in
x86_64-*)
seccomp_audit_arch=AUDIT_ARCH_X86_64
- # X32: AMD64 instructions in 32bit address space.
- if test "x$ac_cv_sizeof_size_t" = "x4" ; then
- seccomp_audit_arch=AUDIT_ARCH_I386
- fi
;;
i*86-*)
seccomp_audit_arch=AUDIT_ARCH_I386
@@ -10202,6 +10243,65 @@ if test "$ac_res" != no; then :
fi
+# Some Linux distribtions ship the BSD libc hashing functions in
+# separate libraries.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing SHA256Update" >&5
+$as_echo_n "checking for library containing SHA256Update... " >&6; }
+if ${ac_cv_search_SHA256Update+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_func_search_save_LIBS=$LIBS
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char SHA256Update ();
+int
+main ()
+{
+return SHA256Update ();
+ ;
+ return 0;
+}
+_ACEOF
+for ac_lib in '' md bsd; do
+ if test -z "$ac_lib"; then
+ ac_res="none required"
+ else
+ ac_res=-l$ac_lib
+ LIBS="-l$ac_lib $ac_func_search_save_LIBS"
+ fi
+ if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_search_SHA256Update=$ac_res
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext
+ if ${ac_cv_search_SHA256Update+:} false; then :
+ break
+fi
+done
+if ${ac_cv_search_SHA256Update+:} false; then :
+
+else
+ ac_cv_search_SHA256Update=no
+fi
+rm conftest.$ac_ext
+LIBS=$ac_func_search_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_SHA256Update" >&5
+$as_echo "$ac_cv_search_SHA256Update" >&6; }
+ac_res=$ac_cv_search_SHA256Update
+if test "$ac_res" != no; then :
+ test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
+
+fi
+
+
# "Particular Function Checks"
# see https://www.gnu.org/software/autoconf/manual/autoconf-2.69/html_node/Particular-Functions.html
for ac_func in strftime
@@ -11366,6 +11466,7 @@ for ac_func in \
err \
errx \
explicit_bzero \
+ explicit_memset \
fchmod \
fchmodat \
fchown \
@@ -11401,6 +11502,7 @@ for ac_func in \
llabs \
localtime_r \
login_getcapbool \
+ login_getpwclass \
md5_crypt \
memmem \
memmove \
@@ -11413,6 +11515,7 @@ for ac_func in \
pledge \
poll \
prctl \
+ pselect \
pstat \
raise \
readpassphrase \
@@ -11858,7 +11961,7 @@ ac_fn_c_check_decl "$LINENO" "localtime_r" "ac_cv_have_decl_localtime_r" " #incl
if test "x$ac_cv_have_decl_localtime_r" = xyes; then :
else
- saved_CPPFLAGS="$CFLAGS"
+ saved_CPPFLAGS="$CPPFLAGS"
CPPFLAGS="$CPPFLAGS -D_REENTRANT"
unset ac_cv_have_decl_localtime_r
ac_fn_c_check_decl "$LINENO" "localtime_r" "ac_cv_have_decl_localtime_r" " #include <time.h>
@@ -12667,58 +12770,6 @@ fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
fi
-if test "x$ac_cv_func_mkdtemp" = "xyes" ; then
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for (overly) strict mkstemp" >&5
-$as_echo_n "checking for (overly) strict mkstemp... " >&6; }
-if test "$cross_compiling" = yes; then :
-
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
-$as_echo "yes" >&6; }
- $as_echo "#define HAVE_STRICT_MKSTEMP 1" >>confdefs.h
-
-
-
-else
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-
-#include <stdlib.h>
-#include <unistd.h>
-
-int
-main ()
-{
-
- char template[]="conftest.mkstemp-test";
- if (mkstemp(template) == -1)
- exit(1);
- unlink(template);
- exit(0);
-
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_run "$LINENO"; then :
-
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-
-else
-
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
-$as_echo "yes" >&6; }
-
-$as_echo "#define HAVE_STRICT_MKSTEMP 1" >>confdefs.h
-
-
-fi
-rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
- conftest.$ac_objext conftest.beam conftest.$ac_ext
-fi
-
-fi
-
if test ! -z "$check_for_openpty_ctty_bug"; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if openpty correctly handles controlling tty" >&5
$as_echo_n "checking if openpty correctly handles controlling tty... " >&6; }
@@ -13623,6 +13674,7 @@ fi
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 \
@@ -15294,7 +15346,7 @@ if test ! -z "$SONY" ; then
LIBS="$LIBS -liberty";
fi
-# Check for long long datatypes
+# Check for long long datatypes
ac_fn_c_check_type "$LINENO" "long long" "ac_cv_type_long_long" "$ac_includes_default"
if test "x$ac_cv_type_long_long" = xyes; then :
@@ -15457,6 +15509,49 @@ cat >>confdefs.h <<_ACEOF
_ACEOF
+# The cast to long int works around a bug in the HP C Compiler
+# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
+# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
+# This bug is HP SR number 8606223364.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of time_t" >&5
+$as_echo_n "checking size of time_t... " >&6; }
+if ${ac_cv_sizeof_time_t+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (time_t))" "ac_cv_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
+
+
+"; then :
+
+else
+ if test "$ac_cv_type_time_t" = yes; then
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error 77 "cannot compute sizeof (time_t)
+See \`config.log' for more details" "$LINENO" 5; }
+ else
+ ac_cv_sizeof_time_t=0
+ fi
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_time_t" >&5
+$as_echo "$ac_cv_sizeof_time_t" >&6; }
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define SIZEOF_TIME_T $ac_cv_sizeof_time_t
+_ACEOF
+
+
# Sanity check long long for some platforms (AIX)
if test "x$ac_cv_sizeof_long_long_int" = "x4" ; then
@@ -16123,21 +16218,22 @@ else
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
- #include <sys/types.h>
- #include <sys/socket.h>
- int getpeername (int, $arg2 *, $t *);
+ #include <sys/types.h>
+ #include <sys/socket.h>
+ int getpeername (int, $arg2 *, $t *);
int
main ()
{
- $t len;
- getpeername(0,0,&len);
+ $t len;
+ getpeername(0,0,&len);
;
return 0;
}
+
_ACEOF
if ac_fn_c_try_compile "$LINENO"; then :
@@ -16176,6 +16272,16 @@ _ACEOF
fi
+ac_fn_c_check_type "$LINENO" "sighandler_t" "ac_cv_type_sighandler_t" "#include <signal.h>
+"
+if test "x$ac_cv_type_sighandler_t" = xyes; then :
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_SIGHANDLER_T 1
+_ACEOF
+
+
+fi
ac_fn_c_check_type "$LINENO" "fsblkcnt_t" "ac_cv_type_fsblkcnt_t" "
#include <sys/types.h>
@@ -16699,42 +16805,6 @@ $as_echo "#define HAVE_STRUCT_ADDRINFO 1" >>confdefs.h
fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether time.h and sys/time.h may both be included" >&5
-$as_echo_n "checking whether time.h and sys/time.h may both be included... " >&6; }
-if ${ac_cv_header_time+:} false; then :
- $as_echo_n "(cached) " >&6
-else
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-#include <sys/types.h>
-#include <sys/time.h>
-#include <time.h>
-
-int
-main ()
-{
-if ((struct tm *) 0)
-return 0;
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
- ac_cv_header_time=yes
-else
- ac_cv_header_time=no
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_time" >&5
-$as_echo "$ac_cv_header_time" >&6; }
-if test $ac_cv_header_time = yes; then
-
-$as_echo "#define TIME_WITH_SYS_TIME 1" >>confdefs.h
-
-fi
-
-
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for struct timeval" >&5
$as_echo_n "checking for struct timeval... " >&6; }
if ${ac_cv_have_struct_timeval+:} false; then :
@@ -16779,15 +16849,11 @@ else
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
- #ifdef TIME_WITH_SYS_TIME
+ #ifdef HAVE_SYS_TIME_H
# include <sys/time.h>
+ #endif
+ #ifdef HAVE_TIME_H
# include <time.h>
- #else
- # ifdef HAVE_SYS_TIME_H
- # include <sys/time.h>
- # else
- # include <time.h>
- # endif
#endif
int
@@ -18647,6 +18713,164 @@ $as_echo "#define KRB5 1" >>confdefs.h
KRB5_MSG="yes"
if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}pkg-config", so it can be a program name with args.
+set dummy ${ac_tool_prefix}pkg-config; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_PKGCONFIG+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ case $PKGCONFIG in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_PKGCONFIG="$PKGCONFIG" # Let the user override the test with a path.
+ ;;
+ *)
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_path_PKGCONFIG="$as_dir/$ac_word$ac_exec_ext"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+ ;;
+esac
+fi
+PKGCONFIG=$ac_cv_path_PKGCONFIG
+if test -n "$PKGCONFIG"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PKGCONFIG" >&5
+$as_echo "$PKGCONFIG" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_path_PKGCONFIG"; then
+ ac_pt_PKGCONFIG=$PKGCONFIG
+ # Extract the first word of "pkg-config", so it can be a program name with args.
+set dummy pkg-config; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_ac_pt_PKGCONFIG+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ case $ac_pt_PKGCONFIG in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_ac_pt_PKGCONFIG="$ac_pt_PKGCONFIG" # Let the user override the test with a path.
+ ;;
+ *)
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_path_ac_pt_PKGCONFIG="$as_dir/$ac_word$ac_exec_ext"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+ ;;
+esac
+fi
+ac_pt_PKGCONFIG=$ac_cv_path_ac_pt_PKGCONFIG
+if test -n "$ac_pt_PKGCONFIG"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_pt_PKGCONFIG" >&5
+$as_echo "$ac_pt_PKGCONFIG" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_pt_PKGCONFIG" = x; then
+ PKGCONFIG="no"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ PKGCONFIG=$ac_pt_PKGCONFIG
+ fi
+else
+ PKGCONFIG="$ac_cv_path_PKGCONFIG"
+fi
+
+ use_pkgconfig_for_krb5=
+ if test "x$PKGCONFIG" != "xno"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $PKGCONFIG knows about kerberos5" >&5
+$as_echo_n "checking if $PKGCONFIG knows about kerberos5... " >&6; }
+ if "$PKGCONFIG" krb5; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ use_pkgconfig_for_krb5=yes
+ else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ fi
+ fi
+ if test "x$use_pkgconfig_for_krb5" = "xyes"; then
+ K5CFLAGS=`$PKGCONFIG --cflags krb5`
+ K5LIBS=`$PKGCONFIG --libs krb5`
+ CPPFLAGS="$CPPFLAGS $K5CFLAGS"
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gssapi support" >&5
+$as_echo_n "checking for gssapi support... " >&6; }
+ if "$PKGCONFIG" krb5-gssapi; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define GSSAPI 1" >>confdefs.h
+
+ GSSCFLAGS="`$PKGCONFIG --cflags krb5-gssapi`"
+ GSSLIBS="`$PKGCONFIG --libs krb5-gssapi`"
+ CPPFLAGS="$CPPFLAGS $GSSCFLAGS"
+ else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using Heimdal" >&5
+$as_echo_n "checking whether we are using Heimdal... " >&6; }
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+ #include <krb5.h>
+
+int
+main ()
+{
+ char *tmp = heimdal_version;
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HEIMDAL 1" >>confdefs.h
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ else
+ if test -n "$ac_tool_prefix"; then
# Extract the first word of "${ac_tool_prefix}krb5-config", so it can be a program name with args.
set dummy ${ac_tool_prefix}krb5-config; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
@@ -18746,29 +18970,29 @@ else
KRB5CONF="$ac_cv_path_KRB5CONF"
fi
- if test -x $KRB5CONF ; then
- K5CFLAGS="`$KRB5CONF --cflags`"
- K5LIBS="`$KRB5CONF --libs`"
- CPPFLAGS="$CPPFLAGS $K5CFLAGS"
+ if test -x $KRB5CONF ; then
+ K5CFLAGS="`$KRB5CONF --cflags`"
+ K5LIBS="`$KRB5CONF --libs`"
+ CPPFLAGS="$CPPFLAGS $K5CFLAGS"
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gssapi support" >&5
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gssapi support" >&5
$as_echo_n "checking for gssapi support... " >&6; }
- if $KRB5CONF | grep gssapi >/dev/null ; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+ if $KRB5CONF | grep gssapi >/dev/null ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
$as_echo "yes" >&6; }
$as_echo "#define GSSAPI 1" >>confdefs.h
- GSSCFLAGS="`$KRB5CONF --cflags gssapi`"
- GSSLIBS="`$KRB5CONF --libs gssapi`"
- CPPFLAGS="$CPPFLAGS $GSSCFLAGS"
- else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+ GSSCFLAGS="`$KRB5CONF --cflags gssapi`"
+ GSSLIBS="`$KRB5CONF --libs gssapi`"
+ CPPFLAGS="$CPPFLAGS $GSSCFLAGS"
+ else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
- fi
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using Heimdal" >&5
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using Heimdal" >&5
$as_echo_n "checking whether we are using Heimdal... " >&6; }
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
#include <krb5.h>
@@ -18792,12 +19016,12 @@ $as_echo "no" >&6; }
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
- else
- CPPFLAGS="$CPPFLAGS -I${KRB5ROOT}/include"
- LDFLAGS="$LDFLAGS -L${KRB5ROOT}/lib"
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using Heimdal" >&5
+ else
+ CPPFLAGS="$CPPFLAGS -I${KRB5ROOT}/include"
+ LDFLAGS="$LDFLAGS -L${KRB5ROOT}/lib"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using Heimdal" >&5
$as_echo_n "checking whether we are using Heimdal... " >&6; }
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
#include <krb5.h>
@@ -18812,11 +19036,11 @@ _ACEOF
if ac_fn_c_try_compile "$LINENO"; then :
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
$as_echo "yes" >&6; }
- $as_echo "#define HEIMDAL 1" >>confdefs.h
+ $as_echo "#define HEIMDAL 1" >>confdefs.h
- K5LIBS="-lkrb5"
- K5LIBS="$K5LIBS -lcom_err -lasn1"
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for net_write in -lroken" >&5
+ K5LIBS="-lkrb5"
+ K5LIBS="$K5LIBS -lcom_err -lasn1"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for net_write in -lroken" >&5
$as_echo_n "checking for net_write in -lroken... " >&6; }
if ${ac_cv_lib_roken_net_write+:} false; then :
$as_echo_n "(cached) " >&6
@@ -18856,7 +19080,7 @@ if test "x$ac_cv_lib_roken_net_write" = xyes; then :
K5LIBS="$K5LIBS -lroken"
fi
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for des_cbc_encrypt in -ldes" >&5
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for des_cbc_encrypt in -ldes" >&5
$as_echo_n "checking for des_cbc_encrypt in -ldes... " >&6; }
if ${ac_cv_lib_des_des_cbc_encrypt+:} false; then :
$as_echo_n "(cached) " >&6
@@ -18900,11 +19124,11 @@ fi
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
- K5LIBS="-lkrb5 -lk5crypto -lcom_err"
+ K5LIBS="-lkrb5 -lk5crypto -lcom_err"
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing dn_expand" >&5
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing dn_expand" >&5
$as_echo_n "checking for library containing dn_expand... " >&6; }
if ${ac_cv_search_dn_expand+:} false; then :
$as_echo_n "(cached) " >&6
@@ -18961,7 +19185,7 @@ if test "$ac_res" != no; then :
fi
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gss_init_sec_context in -lgssapi_krb5" >&5
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gss_init_sec_context in -lgssapi_krb5" >&5
$as_echo_n "checking for gss_init_sec_context in -lgssapi_krb5... " >&6; }
if ${ac_cv_lib_gssapi_krb5_gss_init_sec_context+:} false; then :
$as_echo_n "(cached) " >&6
@@ -19000,7 +19224,7 @@ $as_echo "$ac_cv_lib_gssapi_krb5_gss_init_sec_context" >&6; }
if test "x$ac_cv_lib_gssapi_krb5_gss_init_sec_context" = xyes; then :
$as_echo "#define GSSAPI 1" >>confdefs.h
- GSSLIBS="-lgssapi_krb5"
+ GSSLIBS="-lgssapi_krb5"
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for gss_init_sec_context in -lgssapi" >&5
$as_echo_n "checking for gss_init_sec_context in -lgssapi... " >&6; }
@@ -19041,7 +19265,7 @@ $as_echo "$ac_cv_lib_gssapi_gss_init_sec_context" >&6; }
if test "x$ac_cv_lib_gssapi_gss_init_sec_context" = xyes; then :
$as_echo "#define GSSAPI 1" >>confdefs.h
- GSSLIBS="-lgssapi"
+ GSSLIBS="-lgssapi"
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for gss_init_sec_context in -lgss" >&5
$as_echo_n "checking for gss_init_sec_context in -lgss... " >&6; }
@@ -19082,7 +19306,7 @@ $as_echo "$ac_cv_lib_gss_gss_init_sec_context" >&6; }
if test "x$ac_cv_lib_gss_gss_init_sec_context" = xyes; then :
$as_echo "#define GSSAPI 1" >>confdefs.h
- GSSLIBS="-lgss"
+ GSSLIBS="-lgss"
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Cannot find any suitable gss-api library - build may fail" >&5
$as_echo "$as_me: WARNING: Cannot find any suitable gss-api library - build may fail" >&2;}
@@ -19095,13 +19319,13 @@ fi
fi
- ac_fn_c_check_header_mongrel "$LINENO" "gssapi.h" "ac_cv_header_gssapi_h" "$ac_includes_default"
+ ac_fn_c_check_header_mongrel "$LINENO" "gssapi.h" "ac_cv_header_gssapi_h" "$ac_includes_default"
if test "x$ac_cv_header_gssapi_h" = xyes; then :
else
unset ac_cv_header_gssapi_h
- CPPFLAGS="$CPPFLAGS -I${KRB5ROOT}/include/gssapi"
- for ac_header in gssapi.h
+ CPPFLAGS="$CPPFLAGS -I${KRB5ROOT}/include/gssapi"
+ for ac_header in gssapi.h
do :
ac_fn_c_check_header_mongrel "$LINENO" "gssapi.h" "ac_cv_header_gssapi_h" "$ac_includes_default"
if test "x$ac_cv_header_gssapi_h" = xyes; then :
@@ -19123,9 +19347,9 @@ fi
- oldCPP="$CPPFLAGS"
- CPPFLAGS="$CPPFLAGS -I${KRB5ROOT}/include/gssapi"
- ac_fn_c_check_header_mongrel "$LINENO" "gssapi_krb5.h" "ac_cv_header_gssapi_krb5_h" "$ac_includes_default"
+ oldCPP="$CPPFLAGS"
+ CPPFLAGS="$CPPFLAGS -I${KRB5ROOT}/include/gssapi"
+ ac_fn_c_check_header_mongrel "$LINENO" "gssapi_krb5.h" "ac_cv_header_gssapi_krb5_h" "$ac_includes_default"
if test "x$ac_cv_header_gssapi_krb5_h" = xyes; then :
else
@@ -19134,6 +19358,7 @@ fi
+ fi
fi
if test -n "${rpath_opt}" ; then
LDFLAGS="$LDFLAGS ${rpath_opt}${KRB5ROOT}/lib"
diff --git a/configure.ac b/configure.ac
index 7005a503e..01e7d2a4f 100644
--- a/configure.ac
+++ b/configure.ac
@@ -18,8 +18,19 @@ AC_CONFIG_MACRO_DIR([m4])
AC_CONFIG_SRCDIR([ssh.c])
AC_LANG([C])
-AC_CONFIG_HEADER([config.h])
+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
@@ -286,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
@@ -521,8 +552,6 @@ SPP_MSG="no"
# the --with-solaris-privs option and --with-sandbox=solaris).
SOLARIS_PRIVS="no"
-AC_CHECK_SIZEOF([size_t])
-
# Check for some target-specific stuff
case "$host" in
*-*-aix*)
@@ -867,10 +896,6 @@ main() { if (NSVersionOfRunTimeLibrary("System") >= (60 << 16))
case "$host" in
x86_64-*)
seccomp_audit_arch=AUDIT_ARCH_X86_64
- # X32: AMD64 instructions in 32bit address space.
- if test "x$ac_cv_sizeof_size_t" = "x4" ; then
- seccomp_audit_arch=AUDIT_ARCH_I386
- fi
;;
i*86-*)
seccomp_audit_arch=AUDIT_ARCH_I386
@@ -1431,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
@@ -1790,6 +1819,7 @@ AC_CHECK_FUNCS([ \
err \
errx \
explicit_bzero \
+ explicit_memset \
fchmod \
fchmodat \
fchown \
@@ -1825,6 +1855,7 @@ AC_CHECK_FUNCS([ \
llabs \
localtime_r \
login_getcapbool \
+ login_getpwclass \
md5_crypt \
memmem \
memmove \
@@ -1837,6 +1868,7 @@ AC_CHECK_FUNCS([ \
pledge \
poll \
prctl \
+ pselect \
pstat \
raise \
readpassphrase \
@@ -1987,7 +2019,7 @@ AC_SEARCH_LIBS([clock_gettime], [rt],
dnl check if we need -D_REENTRANT for localtime_r declaration.
AC_CHECK_DECL([localtime_r], [],
- [ saved_CPPFLAGS="$CFLAGS"
+ [ saved_CPPFLAGS="$CPPFLAGS"
CPPFLAGS="$CPPFLAGS -D_REENTRANT"
unset ac_cv_have_decl_localtime_r
AC_CHECK_DECL([localtime_r], [],
@@ -2282,34 +2314,6 @@ 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>
-#include <unistd.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])
@@ -2878,6 +2882,7 @@ if test "x$openssl" = "xyes" ; then
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 \
@@ -3669,7 +3674,7 @@ 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
@@ -3677,6 +3682,16 @@ 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
@@ -3978,7 +3993,7 @@ AC_CHECK_TYPES([intmax_t, uintmax_t], , , [
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
@@ -4155,8 +4170,6 @@ if test "x$ac_cv_have_struct_addrinfo" = "xyes" ; then
[define if you have struct addrinfo data type])
fi
-AC_HEADER_TIME
-
AC_CACHE_CHECK([for struct timeval], ac_cv_have_struct_timeval, [
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include <sys/time.h> ]],
[[ struct timeval tv; tv.tv_sec = 1;]])],
@@ -4171,15 +4184,11 @@ fi
AC_CACHE_CHECK([for struct timespec], ac_cv_have_struct_timespec, [
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
- #ifdef TIME_WITH_SYS_TIME
+ #ifdef HAVE_SYS_TIME_H
# include <sys/time.h>
+ #endif
+ #ifdef HAVE_TIME_H
# include <time.h>
- #else
- # ifdef HAVE_SYS_TIME_H
- # include <sys/time.h>
- # else
- # include <time.h>
- # endif
#endif
]],
[[ struct timespec ts; ts.tv_sec = 1;]])],
@@ -4591,22 +4600,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])
@@ -4621,51 +4638,82 @@ 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 -n "${rpath_opt}" ; then
LDFLAGS="$LDFLAGS ${rpath_opt}${KRB5ROOT}/lib"
diff --git a/contrib/Makefile b/contrib/Makefile
index 3a36387b3..45d878bdc 100644
--- a/contrib/Makefile
+++ b/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/contrib/gnome-ssh-askpass1.c b/contrib/gnome-ssh-askpass1.c
index 4d51032d1..4c92c177b 100644
--- a/contrib/gnome-ssh-askpass1.c
+++ b/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/contrib/gnome-ssh-askpass2.c b/contrib/gnome-ssh-askpass2.c
index f7912727c..a62f98152 100644
--- a/contrib/gnome-ssh-askpass2.c
+++ b/contrib/gnome-ssh-askpass2.c
@@ -68,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));
@@ -225,7 +223,7 @@ passphrase_dialog(char *message, int prompt_type)
*/
gtk_widget_realize(entry);
g_signal_connect(G_OBJECT(entry), "key_press_event",
- G_CALLBACK(check_none), dialog);
+ G_CALLBACK(check_none), dialog);
}
}
diff --git a/contrib/gnome-ssh-askpass3.c b/contrib/gnome-ssh-askpass3.c
new file mode 100644
index 000000000..e1a0533ef
--- /dev/null
+++ b/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/contrib/redhat/openssh.spec b/contrib/redhat/openssh.spec
index df99f7d73..5fb81ce31 100644
--- a/contrib/redhat/openssh.spec
+++ b/contrib/redhat/openssh.spec
@@ -1,4 +1,4 @@
-%global ver 8.4p1
+%global ver 8.7p1
%global rel 1%{?dist}
# OpenSSH privilege separation requires a user & group ID
diff --git a/contrib/ssh-copy-id b/contrib/ssh-copy-id
index 392f64f94..cd122def3 100644
--- a/contrib/ssh-copy-id
+++ b/contrib/ssh-copy-id
@@ -1,6 +1,7 @@
#!/bin/sh
# 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>
@@ -61,11 +62,14 @@ fi
# 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] [-F alternative ssh_config file] [[-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
}
@@ -76,7 +80,7 @@ quote() {
}
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"
@@ -94,7 +98,7 @@ 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/.*: *//')"
exit 1
@@ -108,9 +112,8 @@ if [ -n "$SSH_AUTH_SOCK" ] && ssh-add -L >/dev/null 2>&1 ; then
GET_ID="ssh-add -L"
fi
-while getopts "i:o:p:F:fnh?" OPT
+while getopts "i:o:p:F:fnsh?" OPT
do
-
case "$OPT" in
i)
[ "${SEEN_OPT_I}" ] && {
@@ -129,6 +132,9 @@ do
n)
DRY_RUN=1
;;
+ s)
+ SFTP=sftp
+ ;;
h|\?)
usage
;;
@@ -137,9 +143,6 @@ done
#shift all args to keep only USER_HOST
shift $((OPTIND-1))
-
-
-
if [ $# = 0 ] ; then
usage
fi
@@ -166,60 +169,57 @@ if [ -z "$(eval $GET_ID)" ] ; then
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"
-
- # shellcheck disable=SC2086
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
- 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\""
- # shellcheck disable=SC2064
- 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
# shellcheck disable=SC2086
- NEW_IDS=$(
- eval $GET_ID | {
- 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 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
+ 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
@@ -237,7 +237,8 @@ populate_new_ids() {
# produce a one-liner to add the keys to remote authorized_keys file
# optionally takes an alternative path for authorized_keys
installkeys_sh() {
- local AUTH_KEY_FILE=${1:-.ssh/authorized_keys}
+ 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)
@@ -247,23 +248,67 @@ installkeys_sh() {
# 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)
+ INSTALLKEYS_SH=$(tr '\t\n' ' ' <<-EOF
cd;
umask 077;
- mkdir -p $(dirname "${AUTH_KEY_FILE}") &&
- { [ -z \`tail -1c ${AUTH_KEY_FILE} 2>/dev/null\` ] || echo >> ${AUTH_KEY_FILE}; } &&
- cat >> ${AUTH_KEY_FILE} ||
- exit 1;
+ 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 .ssh ${AUTH_KEY_FILE};
+ restorecon -F "${AUTH_KEY_DIR}" "${AUTH_KEY_FILE}";
fi
-EOF
+ EOF
+ )
# to defend against quirky remote shells: use 'exec sh -c' to get POSIX;
printf "exec sh -c '%s'" "${INSTALLKEYS_SH}"
}
-REMOTE_VERSION=$(ssh -v -o PreferredAuthentications=',' -o ControlPath=none "$@" 2>&1 |
+#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
@@ -276,7 +321,7 @@ case "$REMOTE_VERSION" in
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
@@ -290,16 +335,22 @@ case "$REMOTE_VERSION" in
dropbear*)
populate_new_ids 0
[ "$DRY_RUN" ] || printf '%s\n' "$NEW_IDS" | \
- ssh "$@" "$(installkeys_sh /etc/dropbear/authorized_keys)" \
+ $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
- [ "$DRY_RUN" ] || printf '%s\n' "$NEW_IDS" | \
- ssh "$@" "$(installkeys_sh)" \
- || exit 1
+ 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
@@ -317,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/contrib/ssh-copy-id.1 b/contrib/ssh-copy-id.1
index b75a88365..c141a296f 100644
--- a/contrib/ssh-copy-id.1
+++ b/contrib/ssh-copy-id.1
@@ -1,5 +1,5 @@
.ig \" -*- nroff -*-
-Copyright (c) 1999-2016 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
diff --git a/contrib/suse/openssh.spec b/contrib/suse/openssh.spec
index e6459e82d..6cd222e5a 100644
--- a/contrib/suse/openssh.spec
+++ b/contrib/suse/openssh.spec
@@ -13,7 +13,7 @@
Summary: OpenSSH, a free Secure Shell (SSH) protocol implementation
Name: openssh
-Version: 8.4p1
+Version: 8.7p1
URL: https://www.openssh.com/
Release: 1
Source0: openssh-%{version}.tar.gz
diff --git a/crypto_api.h b/crypto_api.h
index eb05251ff..5c3d97eaa 100644
--- a/crypto_api.h
+++ b/crypto_api.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: crypto_api.h,v 1.5 2019/01/21 10:20:12 djm 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.
@@ -21,6 +21,8 @@ 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()
@@ -42,15 +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_sntrup4591761_PUBLICKEYBYTES 1218
-#define crypto_kem_sntrup4591761_SECRETKEYBYTES 1600
-#define crypto_kem_sntrup4591761_CIPHERTEXTBYTES 1047
-#define crypto_kem_sntrup4591761_BYTES 32
+#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_sntrup4591761_enc(unsigned char *cstr, unsigned char *k,
+int crypto_kem_sntrup761_enc(unsigned char *cstr, unsigned char *k,
const unsigned char *pk);
-int crypto_kem_sntrup4591761_dec(unsigned char *k,
+int crypto_kem_sntrup761_dec(unsigned char *k,
const unsigned char *cstr, const unsigned char *sk);
-int crypto_kem_sntrup4591761_keypair(unsigned char *pk, unsigned char *sk);
+int crypto_kem_sntrup761_keypair(unsigned char *pk, unsigned char *sk);
#endif /* crypto_api_h */
diff --git a/defines.h b/defines.h
index 79dcb507f..857abb8b1 100644
--- a/defines.h
+++ b/defines.h
@@ -304,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
@@ -894,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/dh.c b/dh.c
index 7cb135d7d..ce2eb4725 100644
--- a/dh.c
+++ b/dh.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: dh.c,v 1.71 2019/09/06 06:08:11 djm Exp $ */
+/* $OpenBSD: dh.c,v 1.74 2021/04/03 06:18:40 djm Exp $ */
/*
* Copyright (c) 2000 Niels Provos. All rights reserved.
*
@@ -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;
@@ -458,7 +471,7 @@ dh_new_group18(void)
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/dh.h b/dh.h
index 5d6df6297..c6326a39d 100644
--- a/dh.h
+++ b/dh.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: dh.h,v 1.18 2019/09/06 05:23:55 djm Exp $ */
+/* $OpenBSD: dh.h,v 1.19 2021/03/12 04:08:19 dtucker Exp $ */
/*
* Copyright (c) 2000 Niels Provos. All rights reserved.
@@ -47,6 +47,7 @@ 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.
diff --git a/digest-openssl.c b/digest-openssl.c
index dbbea4251..e073a807b 100644
--- a/digest-openssl.c
+++ b/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>
*
@@ -56,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/dns.c b/dns.c
index e4f9bf830..1cfc38e7c 100644
--- a/dns.c
+++ b/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.
@@ -75,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,
@@ -86,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) {
@@ -128,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;
@@ -213,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;
@@ -249,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;
@@ -272,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");
@@ -348,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/dns.h b/dns.h
index 91f3c632d..c9b61c4f2 100644
--- a/dns.h
+++ b/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/entropy.c b/entropy.c
index 19ddeeafa..a4088e43c 100644
--- a/entropy.c
+++ b/entropy.c
@@ -29,20 +29,12 @@
#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>
@@ -67,121 +59,6 @@
*/
#ifndef OPENSSL_PRNG_ONLY
-/*
- * 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;
- 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;
-}
-
-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)
{
diff --git a/fatal.c b/fatal.c
index 5e5aa3fe1..16fbd3204 100644
--- a/fatal.c
+++ b/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/gss-genr.c b/gss-genr.c
index d56257b4a..685280517 100644
--- a/gss-genr.c
+++ b/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/hash.c b/hash.c
index fb81e4786..b4f8f6c50 100644
--- a/hash.c
+++ b/hash.c
@@ -1,5 +1,3 @@
-/* $OpenBSD: hash.c,v 1.4 2017/12/14 21:07:39 naddy Exp $ */
-
/* $OpenBSD: hash.c,v 1.6 2019/11/29 00:11:21 djm Exp $ */
/*
* Public domain. Author: Christian Weisgerber <naddy@openbsd.org>
diff --git a/hostfile.c b/hostfile.c
index 936d8c9be..ce00cd713 100644
--- a/hostfile.c
+++ b/hostfile.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: hostfile.c,v 1.82 2020/06/26 05:42:16 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
@@ -61,11 +61,7 @@
#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);
@@ -246,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);
@@ -260,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++;
@@ -267,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;
@@ -276,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
@@ -338,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;
@@ -354,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;
@@ -376,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;
@@ -396,14 +411,14 @@ 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);
}
@@ -431,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;
}
@@ -445,8 +460,11 @@ 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;
}
@@ -513,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;
@@ -527,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;
}
/*
@@ -577,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;
@@ -602,43 +619,65 @@ hostfile_replace_entries(const char *filename, const char *host, const char *ip,
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) {
+ HKF_WANT_PARSE_KEY, 0)) != 0) {
oerrno = errno;
- error("%s: hostkeys_foreach failed: %s", __func__, ssh_err(r));
+ 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);
@@ -648,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 */
@@ -683,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;
@@ -709,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;
@@ -725,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';
@@ -742,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++)
@@ -756,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;
@@ -773,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) {
@@ -786,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) {
@@ -823,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;
}
@@ -879,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/hostfile.h b/hostfile.h
index de8b677e3..a24a4e329 100644
--- a/hostfile.h
+++ b/hostfile.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: hostfile.h,v 1.26 2020/06/26 05:02:03 dtucker Exp $ */
+/* $OpenBSD: hostfile.h,v 1.29 2021/01/26 00:51:30 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -28,16 +28,23 @@ 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);
@@ -93,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 */
};
/*
@@ -103,8 +111,12 @@ 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);
diff --git a/int32_minmax.inc b/int32_minmax.inc
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/int32_minmax.inc
diff --git a/kex.c b/kex.c
index aecb9394d..709a0ec63 100644
--- a/kex.c
+++ b/kex.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kex.c,v 1.159 2020/07/05 23:59:45 djm Exp $ */
+/* $OpenBSD: kex.c,v 1.168 2021/04/03 06:18:40 djm Exp $ */
/*
* Copyright (c) 2000, 2001 Markus Friedl. All rights reserved.
*
@@ -110,8 +110,10 @@ 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 },
- { KEX_SNTRUP4591761X25519_SHA512, KEX_KEM_SNTRUP4591761X25519_SHA512, 0,
+#ifdef USE_SNTRUP761X25519
+ { KEX_SNTRUP761X25519_SHA512, KEX_KEM_SNTRUP761X25519_SHA512, 0,
SSH_DIGEST_SHA512 },
+#endif
#endif /* HAVE_EVP_SHA256 || !WITH_OPENSSL */
{ NULL, 0, -1, -1},
};
@@ -360,14 +362,13 @@ kex_buf2prop(struct sshbuf *raw, int *first_kex_follows, char ***propp)
goto out;
}
if ((r = sshbuf_consume(b, KEX_COOKIE_LEN)) != 0) { /* skip cookie */
- error("%s: consume cookie: %s", __func__, ssh_err(r));
+ 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) {
- error("%s: parse proposal %u: %s", __func__,
- i, ssh_err(r));
+ error_fr(r, "parse proposal %u", i);
goto out;
}
debug2("%s: %s", proposal_names[i], proposal[i]);
@@ -375,7 +376,7 @@ kex_buf2prop(struct sshbuf *raw, int *first_kex_follows, char ***propp)
/* first kex follows / reserved */
if ((r = sshbuf_get_u8(b, &v)) != 0 || /* first_kex_follows */
(r = sshbuf_get_u32(b, &i)) != 0) { /* reserved */
- error("%s: parse: %s", __func__, ssh_err(r));
+ error_fr(r, "parse");
goto out;
}
if (first_kex_follows != NULL)
@@ -404,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;
@@ -439,7 +440,7 @@ kex_send_ext_info(struct ssh *ssh)
(r = sshpkt_put_cstring(ssh, "server-sig-algs")) != 0 ||
(r = sshpkt_put_cstring(ssh, algs)) != 0 ||
(r = sshpkt_send(ssh)) != 0) {
- error("%s: compose: %s", __func__, ssh_err(r));
+ error_fr(r, "compose");
goto out;
}
/* success */
@@ -491,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);
}
@@ -536,7 +537,7 @@ kex_send_kexinit(struct ssh *ssh)
int r;
if (kex == NULL) {
- error("%s: no hex", __func__);
+ error_f("no kex");
return SSH_ERR_INTERNAL_ERROR;
}
if (kex->flags & KEX_INIT_SENT)
@@ -545,12 +546,12 @@ kex_send_kexinit(struct ssh *ssh)
/* generate a random cookie */
if (sshbuf_len(kex->my) < KEX_COOKIE_LEN) {
- error("%s: bad kex length: %zu < %d", __func__,
+ 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) {
- error("%s: buffer error", __func__);
+ error_f("buffer error");
return SSH_ERR_INTERNAL_ERROR;
}
arc4random_buf(cookie, KEX_COOKIE_LEN);
@@ -558,7 +559,7 @@ kex_send_kexinit(struct ssh *ssh)
if ((r = sshpkt_start(ssh, SSH2_MSG_KEXINIT)) != 0 ||
(r = sshpkt_putb(ssh, kex->my)) != 0 ||
(r = sshpkt_send(ssh)) != 0) {
- error("%s: compose reply: %s", __func__, ssh_err(r));
+ error_fr(r, "compose reply");
return r;
}
debug("SSH2_MSG_KEXINIT sent");
@@ -578,7 +579,7 @@ kex_input_kexinit(int type, u_int32_t seq, struct ssh *ssh)
debug("SSH2_MSG_KEXINIT received");
if (kex == NULL) {
- error("%s: no hex", __func__);
+ error_f("no kex");
return SSH_ERR_INTERNAL_ERROR;
}
ssh_dispatch_set(ssh, SSH2_MSG_KEXINIT, NULL);
@@ -589,13 +590,13 @@ kex_input_kexinit(int type, u_int32_t seq, struct ssh *ssh)
/* discard packet */
for (i = 0; i < KEX_COOKIE_LEN; i++) {
if ((r = sshpkt_get_u8(ssh, NULL)) != 0) {
- error("%s: discard cookie: %s", __func__, ssh_err(r));
+ error_fr(r, "discard cookie");
return r;
}
}
for (i = 0; i < PROPOSAL_MAX; i++) {
if ((r = sshpkt_get_string(ssh, NULL, NULL)) != 0) {
- error("%s: discard proposal: %s", __func__, ssh_err(r));
+ error_fr(r, "discard proposal");
return r;
}
}
@@ -623,7 +624,7 @@ 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("%s: unknown kex type %u", __func__, kex->kex_type);
+ error_f("unknown kex type %u", kex->kex_type);
return SSH_ERR_INTERNAL_ERROR;
}
@@ -636,7 +637,8 @@ kex_new(void)
(kex->peer = sshbuf_new()) == NULL ||
(kex->my = sshbuf_new()) == NULL ||
(kex->client_version = sshbuf_new()) == NULL ||
- (kex->server_version = sshbuf_new()) == NULL) {
+ (kex->server_version = sshbuf_new()) == NULL ||
+ (kex->session_id = sshbuf_new()) == NULL) {
kex_free(kex);
return NULL;
}
@@ -696,7 +698,7 @@ kex_free(struct kex *kex)
sshbuf_free(kex->client_version);
sshbuf_free(kex->server_version);
sshbuf_free(kex->client_pub);
- free(kex->session_id);
+ sshbuf_free(kex->session_id);
free(kex->failed_choice);
free(kex->hostkey_alg);
free(kex->name);
@@ -739,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;
@@ -758,7 +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("%s: unsupported cipher %s", __func__, name);
+ error_f("unsupported cipher %s", name);
free(name);
return SSH_ERR_INTERNAL_ERROR;
}
@@ -780,7 +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("%s: unsupported MAC %s", __func__, name);
+ error_f("unsupported MAC %s", name);
free(name);
return SSH_ERR_INTERNAL_ERROR;
}
@@ -807,7 +809,7 @@ choose_comp(struct sshcomp *comp, char *client, char *server)
if (strcmp(name, "none") == 0) {
comp->type = COMP_NONE;
} else {
- error("%s: unsupported compression scheme %s", __func__, name);
+ error_f("unsupported compression scheme %s", name);
free(name);
return SSH_ERR_INTERNAL_ERROR;
}
@@ -826,7 +828,7 @@ choose_kex(struct kex *k, char *client, char *server)
if (k->name == NULL)
return SSH_ERR_NO_KEX_ALG_MATCH;
if ((kexalg = kex_alg_by_name(k->name)) == NULL) {
- error("%s: unsupported KEX method %s", __func__, k->name);
+ error_f("unsupported KEX method %s", k->name);
return SSH_ERR_INTERNAL_ERROR;
}
k->kex_type = kexalg->type;
@@ -838,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",
@@ -846,8 +849,7 @@ choose_hostkeyalg(struct kex *k, char *client, char *server)
return SSH_ERR_NO_HOSTKEY_ALG_MATCH;
k->hostkey_type = sshkey_type_from_name(k->hostkey_alg);
if (k->hostkey_type == KEY_UNSPEC) {
- error("%s: unsupported hostkey algorithm %s", __func__,
- k->hostkey_alg);
+ 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);
@@ -1014,11 +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("%s: KEX hash failed", __func__);
+ error_f("KEX hash failed");
goto out;
}
ssh_digest_free(hashctx);
@@ -1035,7 +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("%s: KDF failed", __func__);
+ error_f("KDF failed");
r = SSH_ERR_LIBCRYPTO_ERROR;
goto out;
}
@@ -1066,12 +1067,16 @@ kex_derive_keys(struct ssh *ssh, u_char *hash, u_int hashlen,
int r;
/* save initial hash as 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)
- return SSH_ERR_ALLOC_FAIL;
- memcpy(kex->session_id, hash, kex->session_id_len);
+ 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,
@@ -1100,7 +1105,7 @@ kex_load_hostkey(struct ssh *ssh, struct sshkey **prvp, struct sshkey **pubp)
*prvp = NULL;
if (kex->load_host_public_key == NULL ||
kex->load_host_private_key == NULL) {
- error("%s: missing hostkey loader", __func__);
+ error_f("missing hostkey loader");
return SSH_ERR_INVALID_ARGUMENT;
}
*pubp = kex->load_host_public_key(kex->hostkey_type,
@@ -1118,7 +1123,7 @@ kex_verify_host_key(struct ssh *ssh, struct sshkey *server_host_key)
struct kex *kex = ssh->kex;
if (kex->verify_host_key == NULL) {
- error("%s: missing hostkey verifier", __func__);
+ error_f("missing hostkey verifier");
return SSH_ERR_INVALID_ARGUMENT;
}
if (server_host_key->type != kex->hostkey_type ||
@@ -1155,7 +1160,7 @@ send_error(struct ssh *ssh, char *msg)
msg, strlen(msg)) != strlen(msg) ||
atomicio(vwrite, ssh_packet_get_connection_out(ssh),
crnl, strlen(crnl)) != strlen(crnl))
- error("%s: write: %.100s", __func__, strerror(errno));
+ error_f("write: %.100s", strerror(errno));
}
/*
@@ -1183,11 +1188,11 @@ kex_exchange_identification(struct ssh *ssh, int timeout_ms,
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,
+ PROTOCOL_MAJOR_2, PROTOCOL_MINOR_2, SSH_VERSION,
version_addendum == NULL ? "" : " ",
version_addendum == NULL ? "" : version_addendum)) != 0) {
oerrno = errno;
- error("%s: sshbuf_putf: %s", __func__, ssh_err(r));
+ error_fr(r, "sshbuf_putf");
goto out;
}
@@ -1195,18 +1200,18 @@ kex_exchange_identification(struct ssh *ssh, int timeout_ms,
sshbuf_mutable_ptr(our_version),
sshbuf_len(our_version)) != sshbuf_len(our_version)) {
oerrno = errno;
- debug("%s: write: %.100s", __func__, strerror(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("%s: sshbuf_consume_end: %s", __func__, ssh_err(r));
+ error_fr(r, "sshbuf_consume_end");
goto out;
}
our_version_string = sshbuf_dup_string(our_version);
if (our_version_string == NULL) {
- error("%s: sshbuf_dup_string failed", __func__);
+ error_f("sshbuf_dup_string failed");
r = SSH_ERR_ALLOC_FAIL;
goto out;
}
@@ -1217,8 +1222,8 @@ kex_exchange_identification(struct ssh *ssh, int timeout_ms,
if (n >= SSH_MAX_PRE_BANNER_LINES) {
send_error(ssh, "No SSH identification string "
"received.");
- error("%s: No SSH version received in first %u lines "
- "from server", __func__, SSH_MAX_PRE_BANNER_LINES);
+ error_f("No SSH version received in first %u lines "
+ "from server", SSH_MAX_PRE_BANNER_LINES);
r = SSH_ERR_INVALID_FORMAT;
goto out;
}
@@ -1237,8 +1242,7 @@ kex_exchange_identification(struct ssh *ssh, int timeout_ms,
goto out;
} else if (r == -1) {
oerrno = errno;
- error("%s: %s",
- __func__, strerror(errno));
+ error_f("%s", strerror(errno));
r = SSH_ERR_SYSTEM_ERROR;
goto out;
}
@@ -1247,14 +1251,12 @@ kex_exchange_identification(struct ssh *ssh, int timeout_ms,
len = atomicio(read, ssh_packet_get_connection_in(ssh),
&c, 1);
if (len != 1 && errno == EPIPE) {
- error("%s: Connection closed by remote host",
- __func__);
+ error_f("Connection closed by remote host");
r = SSH_ERR_CONN_CLOSED;
goto out;
} else if (len != 1) {
oerrno = errno;
- error("%s: read: %.100s",
- __func__, strerror(errno));
+ error_f("read: %.100s", strerror(errno));
r = SSH_ERR_SYSTEM_ERROR;
goto out;
}
@@ -1265,18 +1267,17 @@ kex_exchange_identification(struct ssh *ssh, int timeout_ms,
if (c == '\n')
break;
if (c == '\0' || expect_nl) {
- error("%s: banner line contains invalid "
- "characters", __func__);
+ error_f("banner line contains invalid "
+ "characters");
goto invalid;
}
if ((r = sshbuf_put_u8(peer_version, c)) != 0) {
oerrno = errno;
- error("%s: sshbuf_put: %s",
- __func__, ssh_err(r));
+ error_fr(r, "sshbuf_put");
goto out;
}
if (sshbuf_len(peer_version) > SSH_MAX_BANNER_LEN) {
- error("%s: banner line too long", __func__);
+ error_f("banner line too long");
goto invalid;
}
}
@@ -1286,26 +1287,26 @@ kex_exchange_identification(struct ssh *ssh, int timeout_ms,
break;
/* If not, then just log the line and continue */
if ((cp = sshbuf_dup_string(peer_version)) == NULL) {
- error("%s: sshbuf_dup_string failed", __func__);
+ 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("%s: client sent invalid protocol identifier "
- "\"%.256s\"", __func__, cp);
+ error_f("client sent invalid protocol identifier "
+ "\"%.256s\"", cp);
free(cp);
goto invalid;
}
- debug("%s: banner line %zu: %s", __func__, n, cp);
+ debug_f("banner line %zu: %s", n, cp);
free(cp);
}
peer_version_string = sshbuf_dup_string(peer_version);
if (peer_version_string == NULL)
- error("%s: sshbuf_dup_string failed", __func__);
+ error_f("sshbuf_dup_string failed");
/* XXX must be same size for sscanf */
if ((remote_version = calloc(1, sshbuf_len(peer_version))) == NULL) {
- error("%s: calloc failed", __func__);
+ error_f("calloc failed");
r = SSH_ERR_ALLOC_FAIL;
goto out;
}
@@ -1325,7 +1326,7 @@ kex_exchange_identification(struct ssh *ssh, int timeout_ms,
}
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);
mismatch = 0;
switch (remote_major) {
diff --git a/kex.h b/kex.h
index a5ae6ac05..9605ed528 100644
--- a/kex.h
+++ b/kex.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: kex.h,v 1.109 2019/09/06 05:23:55 djm Exp $ */
+/* $OpenBSD: kex.h,v 1.114 2021/01/31 22:55:29 djm Exp $ */
/*
* Copyright (c) 2000, 2001 Markus Friedl. All rights reserved.
@@ -62,7 +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_SNTRUP4591761X25519_SHA512 "sntrup4591761x25519-sha512@tinyssh.org"
+#define KEX_SNTRUP761X25519_SHA512 "sntrup761x25519-sha512@openssh.com"
#define COMP_NONE 0
/* pre-auth compression (COMP_ZLIB) is only supported in the client */
@@ -101,7 +101,7 @@ enum kex_exchange {
KEX_DH_GEX_SHA256,
KEX_ECDH_SHA2,
KEX_C25519_SHA256,
- KEX_KEM_SNTRUP4591761X25519_SHA512,
+ KEX_KEM_SNTRUP761X25519_SHA512,
KEX_MAX
};
@@ -132,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;
@@ -149,6 +147,7 @@ struct kex {
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;
@@ -168,7 +167,7 @@ struct kex {
const EC_GROUP *ec_group; /* ECDH */
u_char c25519_client_key[CURVE25519_SIZE]; /* 25519 + KEM */
u_char c25519_client_pubkey[CURVE25519_SIZE]; /* 25519 */
- u_char sntrup4591761_client_key[crypto_kem_sntrup4591761_SECRETKEYBYTES]; /* KEM */
+ u_char sntrup761_client_key[crypto_kem_sntrup761_SECRETKEYBYTES]; /* KEM */
struct sshbuf *client_pub;
};
@@ -194,6 +193,7 @@ 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_send_newkeys(struct ssh *);
int kex_start_rekex(struct ssh *);
@@ -218,10 +218,10 @@ 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_kem_sntrup4591761x25519_keypair(struct kex *);
-int kex_kem_sntrup4591761x25519_enc(struct kex *, const struct sshbuf *,
+int kex_kem_sntrup761x25519_keypair(struct kex *);
+int kex_kem_sntrup761x25519_enc(struct kex *, const struct sshbuf *,
struct sshbuf **, struct sshbuf **);
-int kex_kem_sntrup4591761x25519_dec(struct kex *, const struct sshbuf *,
+int kex_kem_sntrup761x25519_dec(struct kex *, const struct sshbuf *,
struct sshbuf **);
int kex_dh_keygen(struct kex *);
diff --git a/kexdh.c b/kexdh.c
index 6e0159f9f..c1084f214 100644
--- a/kexdh.c
+++ b/kexdh.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kexdh.c,v 1.33 2020/05/08 05:13:14 djm Exp $ */
+/* $OpenBSD: kexdh.c,v 1.34 2020/12/04 02:29:25 djm Exp $ */
/*
* Copyright (c) 2019 Markus Friedl. All rights reserved.
*
@@ -29,9 +29,9 @@
#include <sys/types.h>
-#include <signal.h>
#include <stdio.h>
#include <string.h>
+#include <signal.h>
#include "openbsd-compat/openssl-compat.h"
#include <openssl/dh.h>
@@ -194,6 +194,7 @@ kex_dh_dec(struct kex *kex, const struct sshbuf *dh_blob,
*shared_secretp = buf;
buf = NULL;
out:
+ BN_free(dh_pub);
DH_free(kex->dh);
kex->dh = NULL;
sshbuf_free(buf);
diff --git a/kexgen.c b/kexgen.c
index 69348b964..bde28053d 100644
--- a/kexgen.c
+++ b/kexgen.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kexgen.c,v 1.4 2019/11/25 00:51:37 djm Exp $ */
+/* $OpenBSD: kexgen.c,v 1.7 2021/04/03 06:18:40 djm Exp $ */
/*
* Copyright (c) 2019 Markus Friedl. All rights reserved.
*
@@ -117,8 +117,8 @@ kex_gen_client(struct ssh *ssh)
case KEX_C25519_SHA256:
r = kex_c25519_keypair(kex);
break;
- case KEX_KEM_SNTRUP4591761X25519_SHA512:
- r = kex_kem_sntrup4591761x25519_keypair(kex);
+ case KEX_KEM_SNTRUP761X25519_SHA512:
+ r = kex_kem_sntrup761x25519_keypair(kex);
break;
default:
r = SSH_ERR_INVALID_ARGUMENT;
@@ -148,6 +148,9 @@ input_kex_gen_reply(int type, u_int32_t seq, struct ssh *ssh)
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;
@@ -185,8 +188,8 @@ input_kex_gen_reply(int type, u_int32_t seq, struct ssh *ssh)
case KEX_C25519_SHA256:
r = kex_c25519_dec(kex, server_blob, &shared_secret);
break;
- case KEX_KEM_SNTRUP4591761X25519_SHA512:
- r = kex_kem_sntrup4591761x25519_dec(kex, server_blob,
+ case KEX_KEM_SNTRUP761X25519_SHA512:
+ r = kex_kem_sntrup761x25519_dec(kex, server_blob,
&shared_secret);
break;
default:
@@ -220,8 +223,8 @@ input_kex_gen_reply(int type, u_int32_t seq, struct ssh *ssh)
out:
explicit_bzero(hash, sizeof(hash));
explicit_bzero(kex->c25519_client_key, sizeof(kex->c25519_client_key));
- explicit_bzero(kex->sntrup4591761_client_key,
- sizeof(kex->sntrup4591761_client_key));
+ explicit_bzero(kex->sntrup761_client_key,
+ sizeof(kex->sntrup761_client_key));
sshbuf_free(server_host_key_blob);
free(signature);
sshbuf_free(tmp);
@@ -254,6 +257,9 @@ input_kex_gen_init(int type, u_int32_t seq, struct ssh *ssh)
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;
@@ -282,8 +288,8 @@ input_kex_gen_init(int type, u_int32_t seq, struct ssh *ssh)
r = kex_c25519_enc(kex, client_pubkey, &server_pubkey,
&shared_secret);
break;
- case KEX_KEM_SNTRUP4591761X25519_SHA512:
- r = kex_kem_sntrup4591761x25519_enc(kex, client_pubkey,
+ case KEX_KEM_SNTRUP761X25519_SHA512:
+ r = kex_kem_sntrup761x25519_enc(kex, client_pubkey,
&server_pubkey, &shared_secret);
break;
default:
@@ -316,7 +322,7 @@ input_kex_gen_init(int type, u_int32_t seq, struct ssh *ssh)
/* sign H */
if ((r = kex->sign(ssh, server_host_private, server_host_public,
- &signature, &slen, hash, hashlen, kex->hostkey_alg)) != 0)
+ &signature, &slen, hash, hashlen, kex->hostkey_alg)) != 0)
goto out;
/* send server hostkey, ECDH pubkey 'Q_S' and signed H */
diff --git a/kexgexc.c b/kexgexc.c
index 323a659b7..4a2e741d8 100644
--- a/kexgexc.c
+++ b/kexgexc.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kexgexc.c,v 1.35 2019/11/25 00:51:37 djm 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,7 +99,8 @@ 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 ((r = sshpkt_get_bignum2(ssh, &p)) != 0 ||
(r = sshpkt_get_bignum2(ssh, &g)) != 0 ||
@@ -130,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:
@@ -153,7 +155,9 @@ input_kex_dh_gex_reply(int type, u_int32_t seq, struct ssh *ssh)
size_t slen, hashlen;
int r;
- debug("got SSH2_MSG_KEX_DH_GEX_REPLY");
+ debug("SSH2_MSG_KEX_DH_GEX_REPLY received");
+ ssh_dispatch_set(ssh, SSH2_MSG_KEX_DH_GEX_REPLY, &kex_protocol_error);
+
/* key, cert */
if ((r = sshpkt_getb_froms(ssh, &server_host_key_blob)) != 0)
goto out;
diff --git a/kexgexs.c b/kexgexs.c
index 8ee3aaccb..f0fbcb912 100644
--- a/kexgexs.c
+++ b/kexgexs.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kexgexs.c,v 1.42 2019/01/23 00:30: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 ||
@@ -136,6 +138,9 @@ input_kex_dh_gex_init(int type, u_int32_t seq, struct ssh *ssh)
size_t slen, hashlen;
int r;
+ 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;
diff --git a/kexsntrup4591761x25519.c b/kexsntrup761x25519.c
index 3b9b664f8..e3007fa29 100644
--- a/kexsntrup4591761x25519.c
+++ b/kexsntrup761x25519.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kexsntrup4591761x25519.c,v 1.3 2019/01/21 10:40:11 djm Exp $ */
+/* $OpenBSD: kexsntrup761x25519.c,v 1.1 2020/12/29 00:59:15 djm Exp $ */
/*
* Copyright (c) 2019 Markus Friedl. All rights reserved.
*
@@ -25,6 +25,8 @@
#include "includes.h"
+#ifdef USE_SNTRUP761X25519
+
#include <sys/types.h>
#include <stdio.h>
@@ -38,7 +40,7 @@
#include "ssherr.h"
int
-kex_kem_sntrup4591761x25519_keypair(struct kex *kex)
+kex_kem_sntrup761x25519_keypair(struct kex *kex)
{
struct sshbuf *buf = NULL;
u_char *cp = NULL;
@@ -47,15 +49,15 @@ kex_kem_sntrup4591761x25519_keypair(struct kex *kex)
if ((buf = sshbuf_new()) == NULL)
return SSH_ERR_ALLOC_FAIL;
- need = crypto_kem_sntrup4591761_PUBLICKEYBYTES + CURVE25519_SIZE;
+ need = crypto_kem_sntrup761_PUBLICKEYBYTES + CURVE25519_SIZE;
if ((r = sshbuf_reserve(buf, need, &cp)) != 0)
goto out;
- crypto_kem_sntrup4591761_keypair(cp, kex->sntrup4591761_client_key);
+ crypto_kem_sntrup761_keypair(cp, kex->sntrup761_client_key);
#ifdef DEBUG_KEXECDH
- dump_digest("client public key sntrup4591761:", cp,
- crypto_kem_sntrup4591761_PUBLICKEYBYTES);
+ dump_digest("client public key sntrup761:", cp,
+ crypto_kem_sntrup761_PUBLICKEYBYTES);
#endif
- cp += crypto_kem_sntrup4591761_PUBLICKEYBYTES;
+ cp += crypto_kem_sntrup761_PUBLICKEYBYTES;
kexc25519_keygen(kex->c25519_client_key, cp);
#ifdef DEBUG_KEXECDH
dump_digest("client public key c25519:", cp, CURVE25519_SIZE);
@@ -68,7 +70,7 @@ kex_kem_sntrup4591761x25519_keypair(struct kex *kex)
}
int
-kex_kem_sntrup4591761x25519_enc(struct kex *kex,
+kex_kem_sntrup761x25519_enc(struct kex *kex,
const struct sshbuf *client_blob, struct sshbuf **server_blobp,
struct sshbuf **shared_secretp)
{
@@ -85,17 +87,17 @@ kex_kem_sntrup4591761x25519_enc(struct kex *kex,
*shared_secretp = NULL;
/* client_blob contains both KEM and ECDH client pubkeys */
- need = crypto_kem_sntrup4591761_PUBLICKEYBYTES + CURVE25519_SIZE;
+ 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 sntrup4591761:", client_pub,
- crypto_kem_sntrup4591761_PUBLICKEYBYTES);
+ dump_digest("client public key sntrup761:", client_pub,
+ crypto_kem_sntrup761_PUBLICKEYBYTES);
dump_digest("client public key 25519:",
- client_pub + crypto_kem_sntrup4591761_PUBLICKEYBYTES,
+ client_pub + crypto_kem_sntrup761_PUBLICKEYBYTES,
CURVE25519_SIZE);
#endif
/* allocate buffer for concatenation of KEM key and ECDH shared key */
@@ -104,7 +106,7 @@ kex_kem_sntrup4591761x25519_enc(struct kex *kex,
r = SSH_ERR_ALLOC_FAIL;
goto out;
}
- if ((r = sshbuf_reserve(buf, crypto_kem_sntrup4591761_BYTES,
+ if ((r = sshbuf_reserve(buf, crypto_kem_sntrup761_BYTES,
&kem_key)) != 0)
goto out;
/* allocate space for encrypted KEM key and ECDH pub key */
@@ -112,16 +114,16 @@ kex_kem_sntrup4591761x25519_enc(struct kex *kex,
r = SSH_ERR_ALLOC_FAIL;
goto out;
}
- need = crypto_kem_sntrup4591761_CIPHERTEXTBYTES + CURVE25519_SIZE;
+ 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_sntrup4591761_enc(ciphertext, kem_key, client_pub);
+ crypto_kem_sntrup761_enc(ciphertext, kem_key, client_pub);
/* generate ECDH key pair, store server pubkey after ciphertext */
- server_pub = ciphertext + crypto_kem_sntrup4591761_CIPHERTEXTBYTES;
+ server_pub = ciphertext + crypto_kem_sntrup761_CIPHERTEXTBYTES;
kexc25519_keygen(server_key, server_pub);
/* append ECDH shared key */
- client_pub += crypto_kem_sntrup4591761_PUBLICKEYBYTES;
+ 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)
@@ -129,7 +131,7 @@ kex_kem_sntrup4591761x25519_enc(struct kex *kex,
#ifdef DEBUG_KEXECDH
dump_digest("server public key 25519:", server_pub, CURVE25519_SIZE);
dump_digest("server cipher text:", ciphertext,
- crypto_kem_sntrup4591761_CIPHERTEXTBYTES);
+ 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));
@@ -155,7 +157,7 @@ kex_kem_sntrup4591761x25519_enc(struct kex *kex,
}
int
-kex_kem_sntrup4591761x25519_dec(struct kex *kex,
+kex_kem_sntrup761x25519_dec(struct kex *kex,
const struct sshbuf *server_blob, struct sshbuf **shared_secretp)
{
struct sshbuf *buf = NULL;
@@ -167,16 +169,16 @@ kex_kem_sntrup4591761x25519_dec(struct kex *kex,
*shared_secretp = NULL;
- need = crypto_kem_sntrup4591761_CIPHERTEXTBYTES + CURVE25519_SIZE;
+ 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_sntrup4591761_CIPHERTEXTBYTES;
+ server_pub = ciphertext + crypto_kem_sntrup761_CIPHERTEXTBYTES;
#ifdef DEBUG_KEXECDH
dump_digest("server cipher text:", ciphertext,
- crypto_kem_sntrup4591761_CIPHERTEXTBYTES);
+ crypto_kem_sntrup761_CIPHERTEXTBYTES);
dump_digest("server public key c25519:", server_pub, CURVE25519_SIZE);
#endif
/* hash concatenation of KEM key and ECDH shared key */
@@ -184,18 +186,18 @@ kex_kem_sntrup4591761x25519_dec(struct kex *kex,
r = SSH_ERR_ALLOC_FAIL;
goto out;
}
- if ((r = sshbuf_reserve(buf, crypto_kem_sntrup4591761_BYTES,
+ if ((r = sshbuf_reserve(buf, crypto_kem_sntrup761_BYTES,
&kem_key)) != 0)
goto out;
- decoded = crypto_kem_sntrup4591761_dec(kem_key, ciphertext,
- kex->sntrup4591761_client_key);
+ 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, sizeof(kem_key));
+ 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
@@ -217,3 +219,33 @@ kex_kem_sntrup4591761x25519_dec(struct kex *kex,
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/krl.c b/krl.c
index 3a69b636a..17b88edde 100644
--- a/krl.c
+++ b/krl.c
@@ -14,7 +14,7 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-/* $OpenBSD: krl.c,v 1.51 2020/08/27 01:06:18 djm Exp $ */
+/* $OpenBSD: krl.c,v 1.53 2021/06/04 06:19:07 djm Exp $ */
#include "includes.h"
@@ -44,7 +44,7 @@
/* #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
@@ -61,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 {
@@ -70,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 {
@@ -80,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 {
@@ -241,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;
}
@@ -252,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;
@@ -264,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.
@@ -290,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;
}
@@ -352,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);
@@ -411,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);
@@ -437,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);
@@ -446,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);
@@ -542,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,
@@ -602,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));
@@ -622,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:
@@ -642,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);
@@ -678,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++) {
@@ -694,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:
@@ -711,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;
}
@@ -772,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;
}
@@ -783,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;
}
@@ -795,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;
}
@@ -807,8 +802,7 @@ 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;
@@ -817,7 +811,7 @@ ssh_krl_to_blob(struct ssh_krl *krl, struct sshbuf *buf,
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;
}
@@ -874,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) {
@@ -911,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;
}
@@ -970,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;
}
@@ -1001,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;
}
@@ -1014,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;
}
@@ -1051,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 "
@@ -1127,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:
@@ -1230,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;
}
@@ -1245,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;
}
@@ -1268,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));
@@ -1278,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;
}
@@ -1289,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;
}
@@ -1312,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;
}
@@ -1321,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;
}
@@ -1348,7 +1342,7 @@ ssh_krl_file_contains_key(const char *path, const struct sshkey *key)
}
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:
sshbuf_free(krlbuf);
@@ -1385,7 +1379,7 @@ krl_dump(struct ssh_krl *krl, FILE *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("Parse key in KRL: %s", ssh_err(r));
+ error_r(r, "parse KRL key");
continue;
}
if ((fp = sshkey_fingerprint(key, SSH_FP_HASH_DEFAULT,
diff --git a/log.c b/log.c
index 6b1a7a314..42c6f9a60 100644
--- a/log.c
+++ b/log.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: log.c,v 1.52 2020/07/03 06:46:41 djm 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,...)
-{
- 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,...)
+log_verbose_add(const char *s)
{
- 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;
@@ -380,7 +318,7 @@ log_redirect_stderr_to(const char *logfile)
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;
@@ -395,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;
@@ -418,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) {
@@ -461,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",
@@ -486,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/log.h b/log.h
index 78cda287d..6218b4177 100644
--- a/log.h
+++ b/log.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: log.h,v 1.24 2019/09/06 04:53:27 djm Exp $ */
+/* $OpenBSD: log.h,v 1.33 2021/04/15 16:24:31 markus Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -16,6 +16,7 @@
#define SSH_LOG_H
#include <stdarg.h> /* va_list */
+#include "ssherr.h" /* ssh_err() */
/* Supported syslog facilities and levels. */
typedef enum {
@@ -48,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/loginrec.h b/loginrec.h
index 62cc0e78c..02bceb604 100644
--- a/loginrec.h
+++ b/loginrec.h
@@ -94,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);
diff --git a/logintest.c b/logintest.c
index 4897ae0f9..6ee1cdc23 100644
--- a/logintest.c
+++ b/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/m4/openssh.m4 b/m4/openssh.m4
index 6a49f10fa..4f9c3792d 100644
--- a/m4/openssh.m4
+++ b/m4/openssh.m4
@@ -171,14 +171,15 @@ AC_DEFUN([TYPE_SOCKLEN_T],
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);
+ 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
diff --git a/match.c b/match.c
index 927565c18..3ac854d38 100644
--- a/match.c
+++ b/match.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: match.c,v 1.42 2020/07/05 23:59:45 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
@@ -53,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)
{
@@ -63,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)
diff --git a/misc.c b/misc.c
index 4623b5755..b8d1040d1 100644
--- a/misc.c
+++ b/misc.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: misc.c,v 1.153 2020/06/26 05:16:38 djm 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-2020 Damien Miller. All rights reserved.
@@ -85,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)
@@ -231,6 +245,60 @@ 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.
@@ -243,10 +311,10 @@ waitfd(int fd, int *timeoutp, short events)
struct timeval t_start;
int oerrno, r;
- monotime_tv(&t_start);
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);
@@ -391,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
@@ -489,7 +557,7 @@ a2tun(const char *s, int *remote)
*
* Return -1 if time string is invalid.
*/
-long
+int
convtime(const char *s)
{
long total, secs, multiplier;
@@ -506,7 +574,7 @@ 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;
@@ -537,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)
@@ -1047,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);
@@ -1082,10 +1158,23 @@ 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;
}
/*
@@ -1111,9 +1200,9 @@ vdollar_percent_expand(int *parseerror, int dollar, int percent,
size_t len;
if ((buf = sshbuf_new()) == NULL)
- fatal("%s: sshbuf_new failed", __func__);
+ fatal_f("sshbuf_new failed");
if (parseerror == NULL)
- fatal("%s: null parseerror arg", __func__);
+ fatal_f("null parseerror arg");
*parseerror = 1;
/* Gather keys if we're doing percent expansion. */
@@ -1123,14 +1212,15 @@ vdollar_percent_expand(int *parseerror, int dollar, int percent,
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 for token %s", __func__, keys[num_keys].key);
+ 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("%s: too many keys", __func__);
+ fatal_f("too many keys");
if (num_keys == 0)
- fatal("%s: percent expansion without token list",
- __func__);
+ fatal_f("percent expansion without token list");
}
/* Expand string */
@@ -1139,28 +1229,24 @@ vdollar_percent_expand(int *parseerror, int dollar, int percent,
if (dollar && string[0] == '$' && string[1] == '{') {
string += 2; /* skip over '${' */
if ((varend = strchr(string, '}')) == NULL) {
- error("%s: environment variable '%s' missing "
- "closing '}'", __func__, string);
+ error_f("environment variable '%s' missing "
+ "closing '}'", string);
goto out;
}
len = varend - string;
if (len == 0) {
- error("%s: zero-length environment variable",
- __func__);
+ error_f("zero-length environment variable");
goto out;
}
var = xmalloc(len + 1);
(void)strlcpy(var, string, len + 1);
if ((val = getenv(var)) == NULL) {
- error("%s: env var ${%s} has no value",
- __func__, var);
+ error_f("env var ${%s} has no value", var);
missingvar = 1;
} else {
- debug3("%s: expand ${%s} -> '%s'", __func__,
- var, val);
+ debug3_f("expand ${%s} -> '%s'", var, val);
if ((r = sshbuf_put(buf, val, strlen(val))) !=0)
- fatal("%s: sshbuf_put: %s", __func__,
- ssh_err(r));
+ fatal_fr(r, "sshbuf_put ${}");
}
free(var);
string += len;
@@ -1174,10 +1260,8 @@ vdollar_percent_expand(int *parseerror, int dollar, int percent,
*/
if (*string != '%' || !percent) {
append:
- if ((r = sshbuf_put_u8(buf, *string)) != 0) {
- fatal("%s: sshbuf_put_u8: %s",
- __func__, ssh_err(r));
- }
+ if ((r = sshbuf_put_u8(buf, *string)) != 0)
+ fatal_fr(r, "sshbuf_put_u8 %%");
continue;
}
string++;
@@ -1185,26 +1269,24 @@ vdollar_percent_expand(int *parseerror, int dollar, int percent,
if (*string == '%')
goto append;
if (*string == '\0') {
- error("%s: invalid format", __func__);
+ 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("%s: sshbuf_put: %s",
- __func__, ssh_err(r));
- }
+ strlen(keys[i].repl))) != 0)
+ fatal_fr(r, "sshbuf_put %%-repl");
break;
}
}
if (i >= num_keys) {
- error("%s: unknown key %%%c", __func__, *string);
+ error_f("unknown key %%%c", *string);
goto out;
}
}
if (!missingvar && (ret = sshbuf_dup_string(buf)) == NULL)
- fatal("%s: sshbuf_dup_string failed", __func__);
+ fatal_f("sshbuf_dup_string failed");
*parseerror = 0;
out:
sshbuf_free(buf);
@@ -1248,7 +1330,7 @@ percent_expand(const char *string, ...)
ret = vdollar_percent_expand(&err, 0, 1, string, ap);
va_end(ap);
if (err)
- fatal("%s failed", __func__);
+ fatal_f("failed");
return ret;
}
@@ -1267,7 +1349,7 @@ percent_dollar_expand(const char *string, ...)
ret = vdollar_percent_expand(&err, 1, 1, string, ap);
va_end(ap);
if (err)
- fatal("%s failed", __func__);
+ fatal_f("failed");
return ret;
}
@@ -1300,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 == -1) {
- debug("%s: %s open: %s", __func__, name, strerror(errno));
+ 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);
@@ -1317,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;
}
}
@@ -1677,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 {
@@ -1764,8 +1846,7 @@ 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;
}
@@ -1773,7 +1854,7 @@ unix_listener(const char *path, int backlog, int unlink_first)
sock = socket(PF_UNIX, SOCK_STREAM, 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;
}
@@ -1783,16 +1864,14 @@ unix_listener(const char *path, int backlog, int unlink_first)
}
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) == -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;
@@ -1868,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;
@@ -1888,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);
@@ -1906,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 {
@@ -1915,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];
}
@@ -1956,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;
@@ -1981,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);
@@ -1999,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)
@@ -2007,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;
}
}
@@ -2298,10 +2404,13 @@ 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);
@@ -2396,6 +2505,32 @@ opt_match(const char **opts, const char *term)
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)
{
@@ -2415,3 +2550,208 @@ ssh_signal(int signum, sshsig_t handler)
}
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/misc.h b/misc.h
index ab94a79c0..2e2dca54b 100644
--- a/misc.h
+++ b/misc.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: misc.h,v 1.87 2020/05/29 11:17:56 dtucker Exp $ */
+/* $OpenBSD: misc.h,v 1.98 2021/08/09 23:47:44 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -18,6 +18,7 @@
#include <sys/time.h>
#include <sys/types.h>
#include <sys/socket.h>
+#include <stdio.h>
/* Data structure for representing a forwarding request. */
struct Forward {
@@ -44,6 +45,7 @@ struct ForwardOptions {
/* misc.c */
char *chop(char *);
+void rtrim(char *);
void skip_space(char **);
char *strdelim(char **);
char *strdelimw(char **);
@@ -53,6 +55,8 @@ 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 *);
@@ -65,8 +69,9 @@ 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, ...);
@@ -90,12 +95,23 @@ 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;
@@ -103,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 **);
@@ -160,23 +176,36 @@ 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 */
#define RP_ECHO 0x0001
@@ -190,7 +219,8 @@ 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 *);
+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))
@@ -198,4 +228,5 @@ void notify_complete(struct notifier_ctx *);
typedef void (*sshsig_t)(int);
sshsig_t ssh_signal(int, sshsig_t);
+
#endif /* _MISC_H */
diff --git a/moduli b/moduli
index 85b70a13d..81afe331b 100644
--- a/moduli
+++ b/moduli
@@ -1,454 +1,450 @@
-# $OpenBSD: moduli,v 1.27 2020/06/03 08:23:16 dtucker Exp $
+# $OpenBSD: moduli,v 1.30 2021/05/17 07:22:45 dtucker Exp $
# Time Type Tests Tries Size Generator Modulus
-20200227022907 2 6 100 2047 2 E5137884F699D3C3A5C899C39CE0DF08A0DECD4DCC6DAD746BDB407C8320AC77CA92EFCDE8EE708B23789C26A9DF03A9C1383CB3B0F8CE764F223899197124958E6C82CFE52CDA5F9DFDF1B89AF0F006F175049BA9055D8A9B3A6603018F2B00AD4524A7F699A5210047C116087FB2C186194F4DC78C95568B9A95CD29B4BD6BC8D71FF5D520E238693B41481C66EEB53CE30995CEF4835138A6A998EF39C879B3E3939FBC6CA7D1BCFCE7BDE8A9AA5CB7E00B7CD7FA83B754275B231FD808BB11A52E493BBC7CF063C19220D47448FDD6F72A7CC5799B3FFEC10D75C6240B378CAB489C2D3AB7E66D6921F0A4441A1CC0F7269EAAF775E8B2F24A43A5D2A1AB
-20200227023015 2 6 100 2047 2 E5137884F699D3C3A5C899C39CE0DF08A0DECD4DCC6DAD746BDB407C8320AC77CA92EFCDE8EE708B23789C26A9DF03A9C1383CB3B0F8CE764F223899197124958E6C82CFE52CDA5F9DFDF1B89AF0F006F175049BA9055D8A9B3A6603018F2B00AD4524A7F699A5210047C116087FB2C186194F4DC78C95568B9A95CD29B4BD6BC8D71FF5D520E238693B41481C66EEB53CE30995CEF4835138A6A998EF39C879B3E3939FBC6CA7D1BCFCE7BDE8A9AA5CB7E00B7CD7FA83B754275B231FD808BB11A52E493BBC7CF063C19220D47448FDD6F72A7CC5799B3FFEC10D75C6240B378CAB489C2D3AB7E66D6921F0A4441A1CC0F7269EAAF775E8B2F24A43A5E70AEB
-20200227023031 2 6 100 2047 2 E5137884F699D3C3A5C899C39CE0DF08A0DECD4DCC6DAD746BDB407C8320AC77CA92EFCDE8EE708B23789C26A9DF03A9C1383CB3B0F8CE764F223899197124958E6C82CFE52CDA5F9DFDF1B89AF0F006F175049BA9055D8A9B3A6603018F2B00AD4524A7F699A5210047C116087FB2C186194F4DC78C95568B9A95CD29B4BD6BC8D71FF5D520E238693B41481C66EEB53CE30995CEF4835138A6A998EF39C879B3E3939FBC6CA7D1BCFCE7BDE8A9AA5CB7E00B7CD7FA83B754275B231FD808BB11A52E493BBC7CF063C19220D47448FDD6F72A7CC5799B3FFEC10D75C6240B378CAB489C2D3AB7E66D6921F0A4441A1CC0F7269EAAF775E8B2F24A43A5FCC5F3
-20200227023127 2 6 100 2047 5 E5137884F699D3C3A5C899C39CE0DF08A0DECD4DCC6DAD746BDB407C8320AC77CA92EFCDE8EE708B23789C26A9DF03A9C1383CB3B0F8CE764F223899197124958E6C82CFE52CDA5F9DFDF1B89AF0F006F175049BA9055D8A9B3A6603018F2B00AD4524A7F699A5210047C116087FB2C186194F4DC78C95568B9A95CD29B4BD6BC8D71FF5D520E238693B41481C66EEB53CE30995CEF4835138A6A998EF39C879B3E3939FBC6CA7D1BCFCE7BDE8A9AA5CB7E00B7CD7FA83B754275B231FD808BB11A52E493BBC7CF063C19220D47448FDD6F72A7CC5799B3FFEC10D75C6240B378CAB489C2D3AB7E66D6921F0A4441A1CC0F7269EAAF775E8B2F24A43A6503737
-20200227023144 2 6 100 2047 2 E5137884F699D3C3A5C899C39CE0DF08A0DECD4DCC6DAD746BDB407C8320AC77CA92EFCDE8EE708B23789C26A9DF03A9C1383CB3B0F8CE764F223899197124958E6C82CFE52CDA5F9DFDF1B89AF0F006F175049BA9055D8A9B3A6603018F2B00AD4524A7F699A5210047C116087FB2C186194F4DC78C95568B9A95CD29B4BD6BC8D71FF5D520E238693B41481C66EEB53CE30995CEF4835138A6A998EF39C879B3E3939FBC6CA7D1BCFCE7BDE8A9AA5CB7E00B7CD7FA83B754275B231FD808BB11A52E493BBC7CF063C19220D47448FDD6F72A7CC5799B3FFEC10D75C6240B378CAB489C2D3AB7E66D6921F0A4441A1CC0F7269EAAF775E8B2F24A43A66A2FBB
-20200227023150 2 6 100 2047 2 E5137884F699D3C3A5C899C39CE0DF08A0DECD4DCC6DAD746BDB407C8320AC77CA92EFCDE8EE708B23789C26A9DF03A9C1383CB3B0F8CE764F223899197124958E6C82CFE52CDA5F9DFDF1B89AF0F006F175049BA9055D8A9B3A6603018F2B00AD4524A7F699A5210047C116087FB2C186194F4DC78C95568B9A95CD29B4BD6BC8D71FF5D520E238693B41481C66EEB53CE30995CEF4835138A6A998EF39C879B3E3939FBC6CA7D1BCFCE7BDE8A9AA5CB7E00B7CD7FA83B754275B231FD808BB11A52E493BBC7CF063C19220D47448FDD6F72A7CC5799B3FFEC10D75C6240B378CAB489C2D3AB7E66D6921F0A4441A1CC0F7269EAAF775E8B2F24A43A66D7443
-20200227023222 2 6 100 2047 5 E5137884F699D3C3A5C899C39CE0DF08A0DECD4DCC6DAD746BDB407C8320AC77CA92EFCDE8EE708B23789C26A9DF03A9C1383CB3B0F8CE764F223899197124958E6C82CFE52CDA5F9DFDF1B89AF0F006F175049BA9055D8A9B3A6603018F2B00AD4524A7F699A5210047C116087FB2C186194F4DC78C95568B9A95CD29B4BD6BC8D71FF5D520E238693B41481C66EEB53CE30995CEF4835138A6A998EF39C879B3E3939FBC6CA7D1BCFCE7BDE8A9AA5CB7E00B7CD7FA83B754275B231FD808BB11A52E493BBC7CF063C19220D47448FDD6F72A7CC5799B3FFEC10D75C6240B378CAB489C2D3AB7E66D6921F0A4441A1CC0F7269EAAF775E8B2F24A43A69A79BF
-20200227023252 2 6 100 2047 5 E5137884F699D3C3A5C899C39CE0DF08A0DECD4DCC6DAD746BDB407C8320AC77CA92EFCDE8EE708B23789C26A9DF03A9C1383CB3B0F8CE764F223899197124958E6C82CFE52CDA5F9DFDF1B89AF0F006F175049BA9055D8A9B3A6603018F2B00AD4524A7F699A5210047C116087FB2C186194F4DC78C95568B9A95CD29B4BD6BC8D71FF5D520E238693B41481C66EEB53CE30995CEF4835138A6A998EF39C879B3E3939FBC6CA7D1BCFCE7BDE8A9AA5CB7E00B7CD7FA83B754275B231FD808BB11A52E493BBC7CF063C19220D47448FDD6F72A7CC5799B3FFEC10D75C6240B378CAB489C2D3AB7E66D6921F0A4441A1CC0F7269EAAF775E8B2F24A43A6CDB577
-20200227023257 2 6 100 2047 5 E5137884F699D3C3A5C899C39CE0DF08A0DECD4DCC6DAD746BDB407C8320AC77CA92EFCDE8EE708B23789C26A9DF03A9C1383CB3B0F8CE764F223899197124958E6C82CFE52CDA5F9DFDF1B89AF0F006F175049BA9055D8A9B3A6603018F2B00AD4524A7F699A5210047C116087FB2C186194F4DC78C95568B9A95CD29B4BD6BC8D71FF5D520E238693B41481C66EEB53CE30995CEF4835138A6A998EF39C879B3E3939FBC6CA7D1BCFCE7BDE8A9AA5CB7E00B7CD7FA83B754275B231FD808BB11A52E493BBC7CF063C19220D47448FDD6F72A7CC5799B3FFEC10D75C6240B378CAB489C2D3AB7E66D6921F0A4441A1CC0F7269EAAF775E8B2F24A43A6CE48A7
-20200227023317 2 6 100 2047 2 E5137884F699D3C3A5C899C39CE0DF08A0DECD4DCC6DAD746BDB407C8320AC77CA92EFCDE8EE708B23789C26A9DF03A9C1383CB3B0F8CE764F223899197124958E6C82CFE52CDA5F9DFDF1B89AF0F006F175049BA9055D8A9B3A6603018F2B00AD4524A7F699A5210047C116087FB2C186194F4DC78C95568B9A95CD29B4BD6BC8D71FF5D520E238693B41481C66EEB53CE30995CEF4835138A6A998EF39C879B3E3939FBC6CA7D1BCFCE7BDE8A9AA5CB7E00B7CD7FA83B754275B231FD808BB11A52E493BBC7CF063C19220D47448FDD6F72A7CC5799B3FFEC10D75C6240B378CAB489C2D3AB7E66D6921F0A4441A1CC0F7269EAAF775E8B2F24A43A6E457D3
-20200227023359 2 6 100 2047 2 E5137884F699D3C3A5C899C39CE0DF08A0DECD4DCC6DAD746BDB407C8320AC77CA92EFCDE8EE708B23789C26A9DF03A9C1383CB3B0F8CE764F223899197124958E6C82CFE52CDA5F9DFDF1B89AF0F006F175049BA9055D8A9B3A6603018F2B00AD4524A7F699A5210047C116087FB2C186194F4DC78C95568B9A95CD29B4BD6BC8D71FF5D520E238693B41481C66EEB53CE30995CEF4835138A6A998EF39C879B3E3939FBC6CA7D1BCFCE7BDE8A9AA5CB7E00B7CD7FA83B754275B231FD808BB11A52E493BBC7CF063C19220D47448FDD6F72A7CC5799B3FFEC10D75C6240B378CAB489C2D3AB7E66D6921F0A4441A1CC0F7269EAAF775E8B2F24A43A70D7E23
-20200227023546 2 6 100 2047 5 E5137884F699D3C3A5C899C39CE0DF08A0DECD4DCC6DAD746BDB407C8320AC77CA92EFCDE8EE708B23789C26A9DF03A9C1383CB3B0F8CE764F223899197124958E6C82CFE52CDA5F9DFDF1B89AF0F006F175049BA9055D8A9B3A6603018F2B00AD4524A7F699A5210047C116087FB2C186194F4DC78C95568B9A95CD29B4BD6BC8D71FF5D520E238693B41481C66EEB53CE30995CEF4835138A6A998EF39C879B3E3939FBC6CA7D1BCFCE7BDE8A9AA5CB7E00B7CD7FA83B754275B231FD808BB11A52E493BBC7CF063C19220D47448FDD6F72A7CC5799B3FFEC10D75C6240B378CAB489C2D3AB7E66D6921F0A4441A1CC0F7269EAAF775E8B2F24A43A76B9A27
-20200227023624 2 6 100 2047 2 E5137884F699D3C3A5C899C39CE0DF08A0DECD4DCC6DAD746BDB407C8320AC77CA92EFCDE8EE708B23789C26A9DF03A9C1383CB3B0F8CE764F223899197124958E6C82CFE52CDA5F9DFDF1B89AF0F006F175049BA9055D8A9B3A6603018F2B00AD4524A7F699A5210047C116087FB2C186194F4DC78C95568B9A95CD29B4BD6BC8D71FF5D520E238693B41481C66EEB53CE30995CEF4835138A6A998EF39C879B3E3939FBC6CA7D1BCFCE7BDE8A9AA5CB7E00B7CD7FA83B754275B231FD808BB11A52E493BBC7CF063C19220D47448FDD6F72A7CC5799B3FFEC10D75C6240B378CAB489C2D3AB7E66D6921F0A4441A1CC0F7269EAAF775E8B2F24A43A7957D9B
-20200227023645 2 6 100 2047 2 E5137884F699D3C3A5C899C39CE0DF08A0DECD4DCC6DAD746BDB407C8320AC77CA92EFCDE8EE708B23789C26A9DF03A9C1383CB3B0F8CE764F223899197124958E6C82CFE52CDA5F9DFDF1B89AF0F006F175049BA9055D8A9B3A6603018F2B00AD4524A7F699A5210047C116087FB2C186194F4DC78C95568B9A95CD29B4BD6BC8D71FF5D520E238693B41481C66EEB53CE30995CEF4835138A6A998EF39C879B3E3939FBC6CA7D1BCFCE7BDE8A9AA5CB7E00B7CD7FA83B754275B231FD808BB11A52E493BBC7CF063C19220D47448FDD6F72A7CC5799B3FFEC10D75C6240B378CAB489C2D3AB7E66D6921F0A4441A1CC0F7269EAAF775E8B2F24A43A7A54E7B
-20200227023732 2 6 100 2047 2 E5137884F699D3C3A5C899C39CE0DF08A0DECD4DCC6DAD746BDB407C8320AC77CA92EFCDE8EE708B23789C26A9DF03A9C1383CB3B0F8CE764F223899197124958E6C82CFE52CDA5F9DFDF1B89AF0F006F175049BA9055D8A9B3A6603018F2B00AD4524A7F699A5210047C116087FB2C186194F4DC78C95568B9A95CD29B4BD6BC8D71FF5D520E238693B41481C66EEB53CE30995CEF4835138A6A998EF39C879B3E3939FBC6CA7D1BCFCE7BDE8A9AA5CB7E00B7CD7FA83B754275B231FD808BB11A52E493BBC7CF063C19220D47448FDD6F72A7CC5799B3FFEC10D75C6240B378CAB489C2D3AB7E66D6921F0A4441A1CC0F7269EAAF775E8B2F24A43A7AA8E03
-20200227024118 2 6 100 2047 2 E5137884F699D3C3A5C899C39CE0DF08A0DECD4DCC6DAD746BDB407C8320AC77CA92EFCDE8EE708B23789C26A9DF03A9C1383CB3B0F8CE764F223899197124958E6C82CFE52CDA5F9DFDF1B89AF0F006F175049BA9055D8A9B3A6603018F2B00AD4524A7F699A5210047C116087FB2C186194F4DC78C95568B9A95CD29B4BD6BC8D71FF5D520E238693B41481C66EEB53CE30995CEF4835138A6A998EF39C879B3E3939FBC6CA7D1BCFCE7BDE8A9AA5CB7E00B7CD7FA83B754275B231FD808BB11A52E493BBC7CF063C19220D47448FDD6F72A7CC5799B3FFEC10D75C6240B378CAB489C2D3AB7E66D6921F0A4441A1CC0F7269EAAF775E8B2F24A43A83E307B
-20200227024150 2 6 100 2047 2 E5137884F699D3C3A5C899C39CE0DF08A0DECD4DCC6DAD746BDB407C8320AC77CA92EFCDE8EE708B23789C26A9DF03A9C1383CB3B0F8CE764F223899197124958E6C82CFE52CDA5F9DFDF1B89AF0F006F175049BA9055D8A9B3A6603018F2B00AD4524A7F699A5210047C116087FB2C186194F4DC78C95568B9A95CD29B4BD6BC8D71FF5D520E238693B41481C66EEB53CE30995CEF4835138A6A998EF39C879B3E3939FBC6CA7D1BCFCE7BDE8A9AA5CB7E00B7CD7FA83B754275B231FD808BB11A52E493BBC7CF063C19220D47448FDD6F72A7CC5799B3FFEC10D75C6240B378CAB489C2D3AB7E66D6921F0A4441A1CC0F7269EAAF775E8B2F24A43A8735923
-20200227024216 2 6 100 2047 2 E5137884F699D3C3A5C899C39CE0DF08A0DECD4DCC6DAD746BDB407C8320AC77CA92EFCDE8EE708B23789C26A9DF03A9C1383CB3B0F8CE764F223899197124958E6C82CFE52CDA5F9DFDF1B89AF0F006F175049BA9055D8A9B3A6603018F2B00AD4524A7F699A5210047C116087FB2C186194F4DC78C95568B9A95CD29B4BD6BC8D71FF5D520E238693B41481C66EEB53CE30995CEF4835138A6A998EF39C879B3E3939FBC6CA7D1BCFCE7BDE8A9AA5CB7E00B7CD7FA83B754275B231FD808BB11A52E493BBC7CF063C19220D47448FDD6F72A7CC5799B3FFEC10D75C6240B378CAB489C2D3AB7E66D6921F0A4441A1CC0F7269EAAF775E8B2F24A43A890B0C3
-20200227024317 2 6 100 2047 5 E5137884F699D3C3A5C899C39CE0DF08A0DECD4DCC6DAD746BDB407C8320AC77CA92EFCDE8EE708B23789C26A9DF03A9C1383CB3B0F8CE764F223899197124958E6C82CFE52CDA5F9DFDF1B89AF0F006F175049BA9055D8A9B3A6603018F2B00AD4524A7F699A5210047C116087FB2C186194F4DC78C95568B9A95CD29B4BD6BC8D71FF5D520E238693B41481C66EEB53CE30995CEF4835138A6A998EF39C879B3E3939FBC6CA7D1BCFCE7BDE8A9AA5CB7E00B7CD7FA83B754275B231FD808BB11A52E493BBC7CF063C19220D47448FDD6F72A7CC5799B3FFEC10D75C6240B378CAB489C2D3AB7E66D6921F0A4441A1CC0F7269EAAF775E8B2F24A43A8ECA377
-20200227024323 2 6 100 2047 2 E5137884F699D3C3A5C899C39CE0DF08A0DECD4DCC6DAD746BDB407C8320AC77CA92EFCDE8EE708B23789C26A9DF03A9C1383CB3B0F8CE764F223899197124958E6C82CFE52CDA5F9DFDF1B89AF0F006F175049BA9055D8A9B3A6603018F2B00AD4524A7F699A5210047C116087FB2C186194F4DC78C95568B9A95CD29B4BD6BC8D71FF5D520E238693B41481C66EEB53CE30995CEF4835138A6A998EF39C879B3E3939FBC6CA7D1BCFCE7BDE8A9AA5CB7E00B7CD7FA83B754275B231FD808BB11A52E493BBC7CF063C19220D47448FDD6F72A7CC5799B3FFEC10D75C6240B378CAB489C2D3AB7E66D6921F0A4441A1CC0F7269EAAF775E8B2F24A43A8F09443
-20200227024339 2 6 100 2047 2 E5137884F699D3C3A5C899C39CE0DF08A0DECD4DCC6DAD746BDB407C8320AC77CA92EFCDE8EE708B23789C26A9DF03A9C1383CB3B0F8CE764F223899197124958E6C82CFE52CDA5F9DFDF1B89AF0F006F175049BA9055D8A9B3A6603018F2B00AD4524A7F699A5210047C116087FB2C186194F4DC78C95568B9A95CD29B4BD6BC8D71FF5D520E238693B41481C66EEB53CE30995CEF4835138A6A998EF39C879B3E3939FBC6CA7D1BCFCE7BDE8A9AA5CB7E00B7CD7FA83B754275B231FD808BB11A52E493BBC7CF063C19220D47448FDD6F72A7CC5799B3FFEC10D75C6240B378CAB489C2D3AB7E66D6921F0A4441A1CC0F7269EAAF775E8B2F24A43A9083FE3
-20200227024354 2 6 100 2047 2 E5137884F699D3C3A5C899C39CE0DF08A0DECD4DCC6DAD746BDB407C8320AC77CA92EFCDE8EE708B23789C26A9DF03A9C1383CB3B0F8CE764F223899197124958E6C82CFE52CDA5F9DFDF1B89AF0F006F175049BA9055D8A9B3A6603018F2B00AD4524A7F699A5210047C116087FB2C186194F4DC78C95568B9A95CD29B4BD6BC8D71FF5D520E238693B41481C66EEB53CE30995CEF4835138A6A998EF39C879B3E3939FBC6CA7D1BCFCE7BDE8A9AA5CB7E00B7CD7FA83B754275B231FD808BB11A52E493BBC7CF063C19220D47448FDD6F72A7CC5799B3FFEC10D75C6240B378CAB489C2D3AB7E66D6921F0A4441A1CC0F7269EAAF775E8B2F24A43A91CBC2B
-20200227024401 2 6 100 2047 5 E5137884F699D3C3A5C899C39CE0DF08A0DECD4DCC6DAD746BDB407C8320AC77CA92EFCDE8EE708B23789C26A9DF03A9C1383CB3B0F8CE764F223899197124958E6C82CFE52CDA5F9DFDF1B89AF0F006F175049BA9055D8A9B3A6603018F2B00AD4524A7F699A5210047C116087FB2C186194F4DC78C95568B9A95CD29B4BD6BC8D71FF5D520E238693B41481C66EEB53CE30995CEF4835138A6A998EF39C879B3E3939FBC6CA7D1BCFCE7BDE8A9AA5CB7E00B7CD7FA83B754275B231FD808BB11A52E493BBC7CF063C19220D47448FDD6F72A7CC5799B3FFEC10D75C6240B378CAB489C2D3AB7E66D6921F0A4441A1CC0F7269EAAF775E8B2F24A43A92295AF
-20200227024451 2 6 100 2047 5 E5137884F699D3C3A5C899C39CE0DF08A0DECD4DCC6DAD746BDB407C8320AC77CA92EFCDE8EE708B23789C26A9DF03A9C1383CB3B0F8CE764F223899197124958E6C82CFE52CDA5F9DFDF1B89AF0F006F175049BA9055D8A9B3A6603018F2B00AD4524A7F699A5210047C116087FB2C186194F4DC78C95568B9A95CD29B4BD6BC8D71FF5D520E238693B41481C66EEB53CE30995CEF4835138A6A998EF39C879B3E3939FBC6CA7D1BCFCE7BDE8A9AA5CB7E00B7CD7FA83B754275B231FD808BB11A52E493BBC7CF063C19220D47448FDD6F72A7CC5799B3FFEC10D75C6240B378CAB489C2D3AB7E66D6921F0A4441A1CC0F7269EAAF775E8B2F24A43A96B524F
-20200227024519 2 6 100 2047 5 E5137884F699D3C3A5C899C39CE0DF08A0DECD4DCC6DAD746BDB407C8320AC77CA92EFCDE8EE708B23789C26A9DF03A9C1383CB3B0F8CE764F223899197124958E6C82CFE52CDA5F9DFDF1B89AF0F006F175049BA9055D8A9B3A6603018F2B00AD4524A7F699A5210047C116087FB2C186194F4DC78C95568B9A95CD29B4BD6BC8D71FF5D520E238693B41481C66EEB53CE30995CEF4835138A6A998EF39C879B3E3939FBC6CA7D1BCFCE7BDE8A9AA5CB7E00B7CD7FA83B754275B231FD808BB11A52E493BBC7CF063C19220D47448FDD6F72A7CC5799B3FFEC10D75C6240B378CAB489C2D3AB7E66D6921F0A4441A1CC0F7269EAAF775E8B2F24A43A9893C5F
-20200227024616 2 6 100 2047 2 E5137884F699D3C3A5C899C39CE0DF08A0DECD4DCC6DAD746BDB407C8320AC77CA92EFCDE8EE708B23789C26A9DF03A9C1383CB3B0F8CE764F223899197124958E6C82CFE52CDA5F9DFDF1B89AF0F006F175049BA9055D8A9B3A6603018F2B00AD4524A7F699A5210047C116087FB2C186194F4DC78C95568B9A95CD29B4BD6BC8D71FF5D520E238693B41481C66EEB53CE30995CEF4835138A6A998EF39C879B3E3939FBC6CA7D1BCFCE7BDE8A9AA5CB7E00B7CD7FA83B754275B231FD808BB11A52E493BBC7CF063C19220D47448FDD6F72A7CC5799B3FFEC10D75C6240B378CAB489C2D3AB7E66D6921F0A4441A1CC0F7269EAAF775E8B2F24A43A9DF0DE3
-20200227024648 2 6 100 2047 5 E5137884F699D3C3A5C899C39CE0DF08A0DECD4DCC6DAD746BDB407C8320AC77CA92EFCDE8EE708B23789C26A9DF03A9C1383CB3B0F8CE764F223899197124958E6C82CFE52CDA5F9DFDF1B89AF0F006F175049BA9055D8A9B3A6603018F2B00AD4524A7F699A5210047C116087FB2C186194F4DC78C95568B9A95CD29B4BD6BC8D71FF5D520E238693B41481C66EEB53CE30995CEF4835138A6A998EF39C879B3E3939FBC6CA7D1BCFCE7BDE8A9AA5CB7E00B7CD7FA83B754275B231FD808BB11A52E493BBC7CF063C19220D47448FDD6F72A7CC5799B3FFEC10D75C6240B378CAB489C2D3AB7E66D6921F0A4441A1CC0F7269EAAF775E8B2F24A43AA1356E7
-20200227024719 2 6 100 2047 5 E5137884F699D3C3A5C899C39CE0DF08A0DECD4DCC6DAD746BDB407C8320AC77CA92EFCDE8EE708B23789C26A9DF03A9C1383CB3B0F8CE764F223899197124958E6C82CFE52CDA5F9DFDF1B89AF0F006F175049BA9055D8A9B3A6603018F2B00AD4524A7F699A5210047C116087FB2C186194F4DC78C95568B9A95CD29B4BD6BC8D71FF5D520E238693B41481C66EEB53CE30995CEF4835138A6A998EF39C879B3E3939FBC6CA7D1BCFCE7BDE8A9AA5CB7E00B7CD7FA83B754275B231FD808BB11A52E493BBC7CF063C19220D47448FDD6F72A7CC5799B3FFEC10D75C6240B378CAB489C2D3AB7E66D6921F0A4441A1CC0F7269EAAF775E8B2F24A43AA391F8F
-20200227024740 2 6 100 2047 2 E5137884F699D3C3A5C899C39CE0DF08A0DECD4DCC6DAD746BDB407C8320AC77CA92EFCDE8EE708B23789C26A9DF03A9C1383CB3B0F8CE764F223899197124958E6C82CFE52CDA5F9DFDF1B89AF0F006F175049BA9055D8A9B3A6603018F2B00AD4524A7F699A5210047C116087FB2C186194F4DC78C95568B9A95CD29B4BD6BC8D71FF5D520E238693B41481C66EEB53CE30995CEF4835138A6A998EF39C879B3E3939FBC6CA7D1BCFCE7BDE8A9AA5CB7E00B7CD7FA83B754275B231FD808BB11A52E493BBC7CF063C19220D47448FDD6F72A7CC5799B3FFEC10D75C6240B378CAB489C2D3AB7E66D6921F0A4441A1CC0F7269EAAF775E8B2F24A43AA5A232B
-20200227024759 2 6 100 2047 5 E5137884F699D3C3A5C899C39CE0DF08A0DECD4DCC6DAD746BDB407C8320AC77CA92EFCDE8EE708B23789C26A9DF03A9C1383CB3B0F8CE764F223899197124958E6C82CFE52CDA5F9DFDF1B89AF0F006F175049BA9055D8A9B3A6603018F2B00AD4524A7F699A5210047C116087FB2C186194F4DC78C95568B9A95CD29B4BD6BC8D71FF5D520E238693B41481C66EEB53CE30995CEF4835138A6A998EF39C879B3E3939FBC6CA7D1BCFCE7BDE8A9AA5CB7E00B7CD7FA83B754275B231FD808BB11A52E493BBC7CF063C19220D47448FDD6F72A7CC5799B3FFEC10D75C6240B378CAB489C2D3AB7E66D6921F0A4441A1CC0F7269EAAF775E8B2F24A43AA76C92F
-20200227024841 2 6 100 2047 2 E5137884F699D3C3A5C899C39CE0DF08A0DECD4DCC6DAD746BDB407C8320AC77CA92EFCDE8EE708B23789C26A9DF03A9C1383CB3B0F8CE764F223899197124958E6C82CFE52CDA5F9DFDF1B89AF0F006F175049BA9055D8A9B3A6603018F2B00AD4524A7F699A5210047C116087FB2C186194F4DC78C95568B9A95CD29B4BD6BC8D71FF5D520E238693B41481C66EEB53CE30995CEF4835138A6A998EF39C879B3E3939FBC6CA7D1BCFCE7BDE8A9AA5CB7E00B7CD7FA83B754275B231FD808BB11A52E493BBC7CF063C19220D47448FDD6F72A7CC5799B3FFEC10D75C6240B378CAB489C2D3AB7E66D6921F0A4441A1CC0F7269EAAF775E8B2F24A43AAB2E483
-20200227024942 2 6 100 2047 2 E5137884F699D3C3A5C899C39CE0DF08A0DECD4DCC6DAD746BDB407C8320AC77CA92EFCDE8EE708B23789C26A9DF03A9C1383CB3B0F8CE764F223899197124958E6C82CFE52CDA5F9DFDF1B89AF0F006F175049BA9055D8A9B3A6603018F2B00AD4524A7F699A5210047C116087FB2C186194F4DC78C95568B9A95CD29B4BD6BC8D71FF5D520E238693B41481C66EEB53CE30995CEF4835138A6A998EF39C879B3E3939FBC6CA7D1BCFCE7BDE8A9AA5CB7E00B7CD7FA83B754275B231FD808BB11A52E493BBC7CF063C19220D47448FDD6F72A7CC5799B3FFEC10D75C6240B378CAB489C2D3AB7E66D6921F0A4441A1CC0F7269EAAF775E8B2F24A43AB0D731B
-20200227024953 2 6 100 2047 5 E5137884F699D3C3A5C899C39CE0DF08A0DECD4DCC6DAD746BDB407C8320AC77CA92EFCDE8EE708B23789C26A9DF03A9C1383CB3B0F8CE764F223899197124958E6C82CFE52CDA5F9DFDF1B89AF0F006F175049BA9055D8A9B3A6603018F2B00AD4524A7F699A5210047C116087FB2C186194F4DC78C95568B9A95CD29B4BD6BC8D71FF5D520E238693B41481C66EEB53CE30995CEF4835138A6A998EF39C879B3E3939FBC6CA7D1BCFCE7BDE8A9AA5CB7E00B7CD7FA83B754275B231FD808BB11A52E493BBC7CF063C19220D47448FDD6F72A7CC5799B3FFEC10D75C6240B378CAB489C2D3AB7E66D6921F0A4441A1CC0F7269EAAF775E8B2F24A43AB1A9FE7
-20200227025000 2 6 100 2047 5 E5137884F699D3C3A5C899C39CE0DF08A0DECD4DCC6DAD746BDB407C8320AC77CA92EFCDE8EE708B23789C26A9DF03A9C1383CB3B0F8CE764F223899197124958E6C82CFE52CDA5F9DFDF1B89AF0F006F175049BA9055D8A9B3A6603018F2B00AD4524A7F699A5210047C116087FB2C186194F4DC78C95568B9A95CD29B4BD6BC8D71FF5D520E238693B41481C66EEB53CE30995CEF4835138A6A998EF39C879B3E3939FBC6CA7D1BCFCE7BDE8A9AA5CB7E00B7CD7FA83B754275B231FD808BB11A52E493BBC7CF063C19220D47448FDD6F72A7CC5799B3FFEC10D75C6240B378CAB489C2D3AB7E66D6921F0A4441A1CC0F7269EAAF775E8B2F24A43AB22AF6F
-20200227025133 2 6 100 2047 5 E5137884F699D3C3A5C899C39CE0DF08A0DECD4DCC6DAD746BDB407C8320AC77CA92EFCDE8EE708B23789C26A9DF03A9C1383CB3B0F8CE764F223899197124958E6C82CFE52CDA5F9DFDF1B89AF0F006F175049BA9055D8A9B3A6603018F2B00AD4524A7F699A5210047C116087FB2C186194F4DC78C95568B9A95CD29B4BD6BC8D71FF5D520E238693B41481C66EEB53CE30995CEF4835138A6A998EF39C879B3E3939FBC6CA7D1BCFCE7BDE8A9AA5CB7E00B7CD7FA83B754275B231FD808BB11A52E493BBC7CF063C19220D47448FDD6F72A7CC5799B3FFEC10D75C6240B378CAB489C2D3AB7E66D6921F0A4441A1CC0F7269EAAF775E8B2F24A43ABA90D27
-20200227025147 2 6 100 2047 2 E5137884F699D3C3A5C899C39CE0DF08A0DECD4DCC6DAD746BDB407C8320AC77CA92EFCDE8EE708B23789C26A9DF03A9C1383CB3B0F8CE764F223899197124958E6C82CFE52CDA5F9DFDF1B89AF0F006F175049BA9055D8A9B3A6603018F2B00AD4524A7F699A5210047C116087FB2C186194F4DC78C95568B9A95CD29B4BD6BC8D71FF5D520E238693B41481C66EEB53CE30995CEF4835138A6A998EF39C879B3E3939FBC6CA7D1BCFCE7BDE8A9AA5CB7E00B7CD7FA83B754275B231FD808BB11A52E493BBC7CF063C19220D47448FDD6F72A7CC5799B3FFEC10D75C6240B378CAB489C2D3AB7E66D6921F0A4441A1CC0F7269EAAF775E8B2F24A43ABBC77EB
-20200227025251 2 6 100 2047 5 E5137884F699D3C3A5C899C39CE0DF08A0DECD4DCC6DAD746BDB407C8320AC77CA92EFCDE8EE708B23789C26A9DF03A9C1383CB3B0F8CE764F223899197124958E6C82CFE52CDA5F9DFDF1B89AF0F006F175049BA9055D8A9B3A6603018F2B00AD4524A7F699A5210047C116087FB2C186194F4DC78C95568B9A95CD29B4BD6BC8D71FF5D520E238693B41481C66EEB53CE30995CEF4835138A6A998EF39C879B3E3939FBC6CA7D1BCFCE7BDE8A9AA5CB7E00B7CD7FA83B754275B231FD808BB11A52E493BBC7CF063C19220D47448FDD6F72A7CC5799B3FFEC10D75C6240B378CAB489C2D3AB7E66D6921F0A4441A1CC0F7269EAAF775E8B2F24A43AC1EA27F
-20200227025455 2 6 100 2047 5 E5137884F699D3C3A5C899C39CE0DF08A0DECD4DCC6DAD746BDB407C8320AC77CA92EFCDE8EE708B23789C26A9DF03A9C1383CB3B0F8CE764F223899197124958E6C82CFE52CDA5F9DFDF1B89AF0F006F175049BA9055D8A9B3A6603018F2B00AD4524A7F699A5210047C116087FB2C186194F4DC78C95568B9A95CD29B4BD6BC8D71FF5D520E238693B41481C66EEB53CE30995CEF4835138A6A998EF39C879B3E3939FBC6CA7D1BCFCE7BDE8A9AA5CB7E00B7CD7FA83B754275B231FD808BB11A52E493BBC7CF063C19220D47448FDD6F72A7CC5799B3FFEC10D75C6240B378CAB489C2D3AB7E66D6921F0A4441A1CC0F7269EAAF775E8B2F24A43ACE67607
-20200227025504 2 6 100 2047 5 E5137884F699D3C3A5C899C39CE0DF08A0DECD4DCC6DAD746BDB407C8320AC77CA92EFCDE8EE708B23789C26A9DF03A9C1383CB3B0F8CE764F223899197124958E6C82CFE52CDA5F9DFDF1B89AF0F006F175049BA9055D8A9B3A6603018F2B00AD4524A7F699A5210047C116087FB2C186194F4DC78C95568B9A95CD29B4BD6BC8D71FF5D520E238693B41481C66EEB53CE30995CEF4835138A6A998EF39C879B3E3939FBC6CA7D1BCFCE7BDE8A9AA5CB7E00B7CD7FA83B754275B231FD808BB11A52E493BBC7CF063C19220D47448FDD6F72A7CC5799B3FFEC10D75C6240B378CAB489C2D3AB7E66D6921F0A4441A1CC0F7269EAAF775E8B2F24A43ACEC2507
-20200227025617 2 6 100 2047 5 E5137884F699D3C3A5C899C39CE0DF08A0DECD4DCC6DAD746BDB407C8320AC77CA92EFCDE8EE708B23789C26A9DF03A9C1383CB3B0F8CE764F223899197124958E6C82CFE52CDA5F9DFDF1B89AF0F006F175049BA9055D8A9B3A6603018F2B00AD4524A7F699A5210047C116087FB2C186194F4DC78C95568B9A95CD29B4BD6BC8D71FF5D520E238693B41481C66EEB53CE30995CEF4835138A6A998EF39C879B3E3939FBC6CA7D1BCFCE7BDE8A9AA5CB7E00B7CD7FA83B754275B231FD808BB11A52E493BBC7CF063C19220D47448FDD6F72A7CC5799B3FFEC10D75C6240B378CAB489C2D3AB7E66D6921F0A4441A1CC0F7269EAAF775E8B2F24A43AD55383F
-20200227025658 2 6 100 2047 2 E5137884F699D3C3A5C899C39CE0DF08A0DECD4DCC6DAD746BDB407C8320AC77CA92EFCDE8EE708B23789C26A9DF03A9C1383CB3B0F8CE764F223899197124958E6C82CFE52CDA5F9DFDF1B89AF0F006F175049BA9055D8A9B3A6603018F2B00AD4524A7F699A5210047C116087FB2C186194F4DC78C95568B9A95CD29B4BD6BC8D71FF5D520E238693B41481C66EEB53CE30995CEF4835138A6A998EF39C879B3E3939FBC6CA7D1BCFCE7BDE8A9AA5CB7E00B7CD7FA83B754275B231FD808BB11A52E493BBC7CF063C19220D47448FDD6F72A7CC5799B3FFEC10D75C6240B378CAB489C2D3AB7E66D6921F0A4441A1CC0F7269EAAF775E8B2F24A43AD9D09CB
-20200227025748 2 6 100 2047 5 C3A05E8BC687376881415BEB6C1506DA767E191DB4C5F4C587A839B341C2271B95F1B52E48C5CFF818CECB2E9BFBD3DB4B282B0D334A4992CF173E7A66B94D8B55F15CB610D5287917131C7CF4D966572EA2E0F1D6A89DFB54FB8B73B9B504D095446B8BA1C2EF49C8BC60D0074E3A25D1EC67FF95FD26D0A60CE0D692E32CB7326A8E5F698179DDE616D758DCB3F9F100623B23A3CF1699914515F5F97476AD124229CE5745A94417339C5D15F406A7D1A6D7BAB235E50D4A998DBD52B72347DB4870BD4D7CD1D5BE6E1D8E54381298791146FFACA089A066C9304067CA0CB8CF493C89EFAEA9836553F05187BA74DE1D7862392B43A94D439B3FD988C6223F
-20200227025916 2 6 100 2047 2 C3A05E8BC687376881415BEB6C1506DA767E191DB4C5F4C587A839B341C2271B95F1B52E48C5CFF818CECB2E9BFBD3DB4B282B0D334A4992CF173E7A66B94D8B55F15CB610D5287917131C7CF4D966572EA2E0F1D6A89DFB54FB8B73B9B504D095446B8BA1C2EF49C8BC60D0074E3A25D1EC67FF95FD26D0A60CE0D692E32CB7326A8E5F698179DDE616D758DCB3F9F100623B23A3CF1699914515F5F97476AD124229CE5745A94417339C5D15F406A7D1A6D7BAB235E50D4A998DBD52B72347DB4870BD4D7CD1D5BE6E1D8E54381298791146FFACA089A066C9304067CA0CB8CF493C89EFAEA9836553F05187BA74DE1D7862392B43A94D439B3FD989456A23
-20200227025954 2 6 100 2047 2 C3A05E8BC687376881415BEB6C1506DA767E191DB4C5F4C587A839B341C2271B95F1B52E48C5CFF818CECB2E9BFBD3DB4B282B0D334A4992CF173E7A66B94D8B55F15CB610D5287917131C7CF4D966572EA2E0F1D6A89DFB54FB8B73B9B504D095446B8BA1C2EF49C8BC60D0074E3A25D1EC67FF95FD26D0A60CE0D692E32CB7326A8E5F698179DDE616D758DCB3F9F100623B23A3CF1699914515F5F97476AD124229CE5745A94417339C5D15F406A7D1A6D7BAB235E50D4A998DBD52B72347DB4870BD4D7CD1D5BE6E1D8E54381298791146FFACA089A066C9304067CA0CB8CF493C89EFAEA9836553F05187BA74DE1D7862392B43A94D439B3FD98982F93B
-20200227030134 2 6 100 2047 5 C3A05E8BC687376881415BEB6C1506DA767E191DB4C5F4C587A839B341C2271B95F1B52E48C5CFF818CECB2E9BFBD3DB4B282B0D334A4992CF173E7A66B94D8B55F15CB610D5287917131C7CF4D966572EA2E0F1D6A89DFB54FB8B73B9B504D095446B8BA1C2EF49C8BC60D0074E3A25D1EC67FF95FD26D0A60CE0D692E32CB7326A8E5F698179DDE616D758DCB3F9F100623B23A3CF1699914515F5F97476AD124229CE5745A94417339C5D15F406A7D1A6D7BAB235E50D4A998DBD52B72347DB4870BD4D7CD1D5BE6E1D8E54381298791146FFACA089A066C9304067CA0CB8CF493C89EFAEA9836553F05187BA74DE1D7862392B43A94D439B3FD98A1A5BD7
-20200227030145 2 6 100 2047 5 C3A05E8BC687376881415BEB6C1506DA767E191DB4C5F4C587A839B341C2271B95F1B52E48C5CFF818CECB2E9BFBD3DB4B282B0D334A4992CF173E7A66B94D8B55F15CB610D5287917131C7CF4D966572EA2E0F1D6A89DFB54FB8B73B9B504D095446B8BA1C2EF49C8BC60D0074E3A25D1EC67FF95FD26D0A60CE0D692E32CB7326A8E5F698179DDE616D758DCB3F9F100623B23A3CF1699914515F5F97476AD124229CE5745A94417339C5D15F406A7D1A6D7BAB235E50D4A998DBD52B72347DB4870BD4D7CD1D5BE6E1D8E54381298791146FFACA089A066C9304067CA0CB8CF493C89EFAEA9836553F05187BA74DE1D7862392B43A94D439B3FD98A276D4F
-20200227030156 2 6 100 2047 2 C3A05E8BC687376881415BEB6C1506DA767E191DB4C5F4C587A839B341C2271B95F1B52E48C5CFF818CECB2E9BFBD3DB4B282B0D334A4992CF173E7A66B94D8B55F15CB610D5287917131C7CF4D966572EA2E0F1D6A89DFB54FB8B73B9B504D095446B8BA1C2EF49C8BC60D0074E3A25D1EC67FF95FD26D0A60CE0D692E32CB7326A8E5F698179DDE616D758DCB3F9F100623B23A3CF1699914515F5F97476AD124229CE5745A94417339C5D15F406A7D1A6D7BAB235E50D4A998DBD52B72347DB4870BD4D7CD1D5BE6E1D8E54381298791146FFACA089A066C9304067CA0CB8CF493C89EFAEA9836553F05187BA74DE1D7862392B43A94D439B3FD98A35BBCB
-20200227030205 2 6 100 2047 5 C3A05E8BC687376881415BEB6C1506DA767E191DB4C5F4C587A839B341C2271B95F1B52E48C5CFF818CECB2E9BFBD3DB4B282B0D334A4992CF173E7A66B94D8B55F15CB610D5287917131C7CF4D966572EA2E0F1D6A89DFB54FB8B73B9B504D095446B8BA1C2EF49C8BC60D0074E3A25D1EC67FF95FD26D0A60CE0D692E32CB7326A8E5F698179DDE616D758DCB3F9F100623B23A3CF1699914515F5F97476AD124229CE5745A94417339C5D15F406A7D1A6D7BAB235E50D4A998DBD52B72347DB4870BD4D7CD1D5BE6E1D8E54381298791146FFACA089A066C9304067CA0CB8CF493C89EFAEA9836553F05187BA74DE1D7862392B43A94D439B3FD98A3A766F
-20200227030254 2 6 100 2047 2 C3A05E8BC687376881415BEB6C1506DA767E191DB4C5F4C587A839B341C2271B95F1B52E48C5CFF818CECB2E9BFBD3DB4B282B0D334A4992CF173E7A66B94D8B55F15CB610D5287917131C7CF4D966572EA2E0F1D6A89DFB54FB8B73B9B504D095446B8BA1C2EF49C8BC60D0074E3A25D1EC67FF95FD26D0A60CE0D692E32CB7326A8E5F698179DDE616D758DCB3F9F100623B23A3CF1699914515F5F97476AD124229CE5745A94417339C5D15F406A7D1A6D7BAB235E50D4A998DBD52B72347DB4870BD4D7CD1D5BE6E1D8E54381298791146FFACA089A066C9304067CA0CB8CF493C89EFAEA9836553F05187BA74DE1D7862392B43A94D439B3FD98A8957DB
-20200227030322 2 6 100 2047 2 C3A05E8BC687376881415BEB6C1506DA767E191DB4C5F4C587A839B341C2271B95F1B52E48C5CFF818CECB2E9BFBD3DB4B282B0D334A4992CF173E7A66B94D8B55F15CB610D5287917131C7CF4D966572EA2E0F1D6A89DFB54FB8B73B9B504D095446B8BA1C2EF49C8BC60D0074E3A25D1EC67FF95FD26D0A60CE0D692E32CB7326A8E5F698179DDE616D758DCB3F9F100623B23A3CF1699914515F5F97476AD124229CE5745A94417339C5D15F406A7D1A6D7BAB235E50D4A998DBD52B72347DB4870BD4D7CD1D5BE6E1D8E54381298791146FFACA089A066C9304067CA0CB8CF493C89EFAEA9836553F05187BA74DE1D7862392B43A94D439B3FD98AA57A4B
-20200227030336 2 6 100 2047 2 C3A05E8BC687376881415BEB6C1506DA767E191DB4C5F4C587A839B341C2271B95F1B52E48C5CFF818CECB2E9BFBD3DB4B282B0D334A4992CF173E7A66B94D8B55F15CB610D5287917131C7CF4D966572EA2E0F1D6A89DFB54FB8B73B9B504D095446B8BA1C2EF49C8BC60D0074E3A25D1EC67FF95FD26D0A60CE0D692E32CB7326A8E5F698179DDE616D758DCB3F9F100623B23A3CF1699914515F5F97476AD124229CE5745A94417339C5D15F406A7D1A6D7BAB235E50D4A998DBD52B72347DB4870BD4D7CD1D5BE6E1D8E54381298791146FFACA089A066C9304067CA0CB8CF493C89EFAEA9836553F05187BA74DE1D7862392B43A94D439B3FD98AB5D4FB
-20200227030430 2 6 100 2047 5 C3A05E8BC687376881415BEB6C1506DA767E191DB4C5F4C587A839B341C2271B95F1B52E48C5CFF818CECB2E9BFBD3DB4B282B0D334A4992CF173E7A66B94D8B55F15CB610D5287917131C7CF4D966572EA2E0F1D6A89DFB54FB8B73B9B504D095446B8BA1C2EF49C8BC60D0074E3A25D1EC67FF95FD26D0A60CE0D692E32CB7326A8E5F698179DDE616D758DCB3F9F100623B23A3CF1699914515F5F97476AD124229CE5745A94417339C5D15F406A7D1A6D7BAB235E50D4A998DBD52B72347DB4870BD4D7CD1D5BE6E1D8E54381298791146FFACA089A066C9304067CA0CB8CF493C89EFAEA9836553F05187BA74DE1D7862392B43A94D439B3FD98B0921AF
-20200227030443 2 6 100 2047 2 C3A05E8BC687376881415BEB6C1506DA767E191DB4C5F4C587A839B341C2271B95F1B52E48C5CFF818CECB2E9BFBD3DB4B282B0D334A4992CF173E7A66B94D8B55F15CB610D5287917131C7CF4D966572EA2E0F1D6A89DFB54FB8B73B9B504D095446B8BA1C2EF49C8BC60D0074E3A25D1EC67FF95FD26D0A60CE0D692E32CB7326A8E5F698179DDE616D758DCB3F9F100623B23A3CF1699914515F5F97476AD124229CE5745A94417339C5D15F406A7D1A6D7BAB235E50D4A998DBD52B72347DB4870BD4D7CD1D5BE6E1D8E54381298791146FFACA089A066C9304067CA0CB8CF493C89EFAEA9836553F05187BA74DE1D7862392B43A94D439B3FD98B1ADA93
-20200227030556 2 6 100 2047 2 C3A05E8BC687376881415BEB6C1506DA767E191DB4C5F4C587A839B341C2271B95F1B52E48C5CFF818CECB2E9BFBD3DB4B282B0D334A4992CF173E7A66B94D8B55F15CB610D5287917131C7CF4D966572EA2E0F1D6A89DFB54FB8B73B9B504D095446B8BA1C2EF49C8BC60D0074E3A25D1EC67FF95FD26D0A60CE0D692E32CB7326A8E5F698179DDE616D758DCB3F9F100623B23A3CF1699914515F5F97476AD124229CE5745A94417339C5D15F406A7D1A6D7BAB235E50D4A998DBD52B72347DB4870BD4D7CD1D5BE6E1D8E54381298791146FFACA089A066C9304067CA0CB8CF493C89EFAEA9836553F05187BA74DE1D7862392B43A94D439B3FD98B8D5E93
-20200227030619 2 6 100 2047 2 C3A05E8BC687376881415BEB6C1506DA767E191DB4C5F4C587A839B341C2271B95F1B52E48C5CFF818CECB2E9BFBD3DB4B282B0D334A4992CF173E7A66B94D8B55F15CB610D5287917131C7CF4D966572EA2E0F1D6A89DFB54FB8B73B9B504D095446B8BA1C2EF49C8BC60D0074E3A25D1EC67FF95FD26D0A60CE0D692E32CB7326A8E5F698179DDE616D758DCB3F9F100623B23A3CF1699914515F5F97476AD124229CE5745A94417339C5D15F406A7D1A6D7BAB235E50D4A998DBD52B72347DB4870BD4D7CD1D5BE6E1D8E54381298791146FFACA089A066C9304067CA0CB8CF493C89EFAEA9836553F05187BA74DE1D7862392B43A94D439B3FD98BA3DE33
-20200227030707 2 6 100 2047 2 C3A05E8BC687376881415BEB6C1506DA767E191DB4C5F4C587A839B341C2271B95F1B52E48C5CFF818CECB2E9BFBD3DB4B282B0D334A4992CF173E7A66B94D8B55F15CB610D5287917131C7CF4D966572EA2E0F1D6A89DFB54FB8B73B9B504D095446B8BA1C2EF49C8BC60D0074E3A25D1EC67FF95FD26D0A60CE0D692E32CB7326A8E5F698179DDE616D758DCB3F9F100623B23A3CF1699914515F5F97476AD124229CE5745A94417339C5D15F406A7D1A6D7BAB235E50D4A998DBD52B72347DB4870BD4D7CD1D5BE6E1D8E54381298791146FFACA089A066C9304067CA0CB8CF493C89EFAEA9836553F05187BA74DE1D7862392B43A94D439B3FD98BF5B1FB
-20200227030728 2 6 100 2047 2 C3A05E8BC687376881415BEB6C1506DA767E191DB4C5F4C587A839B341C2271B95F1B52E48C5CFF818CECB2E9BFBD3DB4B282B0D334A4992CF173E7A66B94D8B55F15CB610D5287917131C7CF4D966572EA2E0F1D6A89DFB54FB8B73B9B504D095446B8BA1C2EF49C8BC60D0074E3A25D1EC67FF95FD26D0A60CE0D692E32CB7326A8E5F698179DDE616D758DCB3F9F100623B23A3CF1699914515F5F97476AD124229CE5745A94417339C5D15F406A7D1A6D7BAB235E50D4A998DBD52B72347DB4870BD4D7CD1D5BE6E1D8E54381298791146FFACA089A066C9304067CA0CB8CF493C89EFAEA9836553F05187BA74DE1D7862392B43A94D439B3FD98C0DCC3B
-20200227030738 2 6 100 2047 2 C3A05E8BC687376881415BEB6C1506DA767E191DB4C5F4C587A839B341C2271B95F1B52E48C5CFF818CECB2E9BFBD3DB4B282B0D334A4992CF173E7A66B94D8B55F15CB610D5287917131C7CF4D966572EA2E0F1D6A89DFB54FB8B73B9B504D095446B8BA1C2EF49C8BC60D0074E3A25D1EC67FF95FD26D0A60CE0D692E32CB7326A8E5F698179DDE616D758DCB3F9F100623B23A3CF1699914515F5F97476AD124229CE5745A94417339C5D15F406A7D1A6D7BAB235E50D4A998DBD52B72347DB4870BD4D7CD1D5BE6E1D8E54381298791146FFACA089A066C9304067CA0CB8CF493C89EFAEA9836553F05187BA74DE1D7862392B43A94D439B3FD98C19C5C3
-20200227030750 2 6 100 2047 5 C3A05E8BC687376881415BEB6C1506DA767E191DB4C5F4C587A839B341C2271B95F1B52E48C5CFF818CECB2E9BFBD3DB4B282B0D334A4992CF173E7A66B94D8B55F15CB610D5287917131C7CF4D966572EA2E0F1D6A89DFB54FB8B73B9B504D095446B8BA1C2EF49C8BC60D0074E3A25D1EC67FF95FD26D0A60CE0D692E32CB7326A8E5F698179DDE616D758DCB3F9F100623B23A3CF1699914515F5F97476AD124229CE5745A94417339C5D15F406A7D1A6D7BAB235E50D4A998DBD52B72347DB4870BD4D7CD1D5BE6E1D8E54381298791146FFACA089A066C9304067CA0CB8CF493C89EFAEA9836553F05187BA74DE1D7862392B43A94D439B3FD98C2994E7
-20200227030837 2 6 100 2047 2 C3A05E8BC687376881415BEB6C1506DA767E191DB4C5F4C587A839B341C2271B95F1B52E48C5CFF818CECB2E9BFBD3DB4B282B0D334A4992CF173E7A66B94D8B55F15CB610D5287917131C7CF4D966572EA2E0F1D6A89DFB54FB8B73B9B504D095446B8BA1C2EF49C8BC60D0074E3A25D1EC67FF95FD26D0A60CE0D692E32CB7326A8E5F698179DDE616D758DCB3F9F100623B23A3CF1699914515F5F97476AD124229CE5745A94417339C5D15F406A7D1A6D7BAB235E50D4A998DBD52B72347DB4870BD4D7CD1D5BE6E1D8E54381298791146FFACA089A066C9304067CA0CB8CF493C89EFAEA9836553F05187BA74DE1D7862392B43A94D439B3FD98C6D2993
-20200227030928 2 6 100 2047 2 C3A05E8BC687376881415BEB6C1506DA767E191DB4C5F4C587A839B341C2271B95F1B52E48C5CFF818CECB2E9BFBD3DB4B282B0D334A4992CF173E7A66B94D8B55F15CB610D5287917131C7CF4D966572EA2E0F1D6A89DFB54FB8B73B9B504D095446B8BA1C2EF49C8BC60D0074E3A25D1EC67FF95FD26D0A60CE0D692E32CB7326A8E5F698179DDE616D758DCB3F9F100623B23A3CF1699914515F5F97476AD124229CE5745A94417339C5D15F406A7D1A6D7BAB235E50D4A998DBD52B72347DB4870BD4D7CD1D5BE6E1D8E54381298791146FFACA089A066C9304067CA0CB8CF493C89EFAEA9836553F05187BA74DE1D7862392B43A94D439B3FD98CB6E833
-20200227031020 2 6 100 2047 2 C3A05E8BC687376881415BEB6C1506DA767E191DB4C5F4C587A839B341C2271B95F1B52E48C5CFF818CECB2E9BFBD3DB4B282B0D334A4992CF173E7A66B94D8B55F15CB610D5287917131C7CF4D966572EA2E0F1D6A89DFB54FB8B73B9B504D095446B8BA1C2EF49C8BC60D0074E3A25D1EC67FF95FD26D0A60CE0D692E32CB7326A8E5F698179DDE616D758DCB3F9F100623B23A3CF1699914515F5F97476AD124229CE5745A94417339C5D15F406A7D1A6D7BAB235E50D4A998DBD52B72347DB4870BD4D7CD1D5BE6E1D8E54381298791146FFACA089A066C9304067CA0CB8CF493C89EFAEA9836553F05187BA74DE1D7862392B43A94D439B3FD98CFA7F73
-20200227031051 2 6 100 2047 2 C3A05E8BC687376881415BEB6C1506DA767E191DB4C5F4C587A839B341C2271B95F1B52E48C5CFF818CECB2E9BFBD3DB4B282B0D334A4992CF173E7A66B94D8B55F15CB610D5287917131C7CF4D966572EA2E0F1D6A89DFB54FB8B73B9B504D095446B8BA1C2EF49C8BC60D0074E3A25D1EC67FF95FD26D0A60CE0D692E32CB7326A8E5F698179DDE616D758DCB3F9F100623B23A3CF1699914515F5F97476AD124229CE5745A94417339C5D15F406A7D1A6D7BAB235E50D4A998DBD52B72347DB4870BD4D7CD1D5BE6E1D8E54381298791146FFACA089A066C9304067CA0CB8CF493C89EFAEA9836553F05187BA74DE1D7862392B43A94D439B3FD98D315F23
-20200227031130 2 6 100 2047 5 C3A05E8BC687376881415BEB6C1506DA767E191DB4C5F4C587A839B341C2271B95F1B52E48C5CFF818CECB2E9BFBD3DB4B282B0D334A4992CF173E7A66B94D8B55F15CB610D5287917131C7CF4D966572EA2E0F1D6A89DFB54FB8B73B9B504D095446B8BA1C2EF49C8BC60D0074E3A25D1EC67FF95FD26D0A60CE0D692E32CB7326A8E5F698179DDE616D758DCB3F9F100623B23A3CF1699914515F5F97476AD124229CE5745A94417339C5D15F406A7D1A6D7BAB235E50D4A998DBD52B72347DB4870BD4D7CD1D5BE6E1D8E54381298791146FFACA089A066C9304067CA0CB8CF493C89EFAEA9836553F05187BA74DE1D7862392B43A94D439B3FD98D61499F
-20200227031151 2 6 100 2047 5 C3A05E8BC687376881415BEB6C1506DA767E191DB4C5F4C587A839B341C2271B95F1B52E48C5CFF818CECB2E9BFBD3DB4B282B0D334A4992CF173E7A66B94D8B55F15CB610D5287917131C7CF4D966572EA2E0F1D6A89DFB54FB8B73B9B504D095446B8BA1C2EF49C8BC60D0074E3A25D1EC67FF95FD26D0A60CE0D692E32CB7326A8E5F698179DDE616D758DCB3F9F100623B23A3CF1699914515F5F97476AD124229CE5745A94417339C5D15F406A7D1A6D7BAB235E50D4A998DBD52B72347DB4870BD4D7CD1D5BE6E1D8E54381298791146FFACA089A066C9304067CA0CB8CF493C89EFAEA9836553F05187BA74DE1D7862392B43A94D439B3FD98D7FD90F
-20200227031214 2 6 100 2047 2 C3A05E8BC687376881415BEB6C1506DA767E191DB4C5F4C587A839B341C2271B95F1B52E48C5CFF818CECB2E9BFBD3DB4B282B0D334A4992CF173E7A66B94D8B55F15CB610D5287917131C7CF4D966572EA2E0F1D6A89DFB54FB8B73B9B504D095446B8BA1C2EF49C8BC60D0074E3A25D1EC67FF95FD26D0A60CE0D692E32CB7326A8E5F698179DDE616D758DCB3F9F100623B23A3CF1699914515F5F97476AD124229CE5745A94417339C5D15F406A7D1A6D7BAB235E50D4A998DBD52B72347DB4870BD4D7CD1D5BE6E1D8E54381298791146FFACA089A066C9304067CA0CB8CF493C89EFAEA9836553F05187BA74DE1D7862392B43A94D439B3FD98D94476B
-20200227031250 2 6 100 2047 2 C3A05E8BC687376881415BEB6C1506DA767E191DB4C5F4C587A839B341C2271B95F1B52E48C5CFF818CECB2E9BFBD3DB4B282B0D334A4992CF173E7A66B94D8B55F15CB610D5287917131C7CF4D966572EA2E0F1D6A89DFB54FB8B73B9B504D095446B8BA1C2EF49C8BC60D0074E3A25D1EC67FF95FD26D0A60CE0D692E32CB7326A8E5F698179DDE616D758DCB3F9F100623B23A3CF1699914515F5F97476AD124229CE5745A94417339C5D15F406A7D1A6D7BAB235E50D4A998DBD52B72347DB4870BD4D7CD1D5BE6E1D8E54381298791146FFACA089A066C9304067CA0CB8CF493C89EFAEA9836553F05187BA74DE1D7862392B43A94D439B3FD98DD00E53
-20200227031339 2 6 100 2047 5 C3A05E8BC687376881415BEB6C1506DA767E191DB4C5F4C587A839B341C2271B95F1B52E48C5CFF818CECB2E9BFBD3DB4B282B0D334A4992CF173E7A66B94D8B55F15CB610D5287917131C7CF4D966572EA2E0F1D6A89DFB54FB8B73B9B504D095446B8BA1C2EF49C8BC60D0074E3A25D1EC67FF95FD26D0A60CE0D692E32CB7326A8E5F698179DDE616D758DCB3F9F100623B23A3CF1699914515F5F97476AD124229CE5745A94417339C5D15F406A7D1A6D7BAB235E50D4A998DBD52B72347DB4870BD4D7CD1D5BE6E1D8E54381298791146FFACA089A066C9304067CA0CB8CF493C89EFAEA9836553F05187BA74DE1D7862392B43A94D439B3FD98E1E199F
-20200227031416 2 6 100 2047 2 C3A05E8BC687376881415BEB6C1506DA767E191DB4C5F4C587A839B341C2271B95F1B52E48C5CFF818CECB2E9BFBD3DB4B282B0D334A4992CF173E7A66B94D8B55F15CB610D5287917131C7CF4D966572EA2E0F1D6A89DFB54FB8B73B9B504D095446B8BA1C2EF49C8BC60D0074E3A25D1EC67FF95FD26D0A60CE0D692E32CB7326A8E5F698179DDE616D758DCB3F9F100623B23A3CF1699914515F5F97476AD124229CE5745A94417339C5D15F406A7D1A6D7BAB235E50D4A998DBD52B72347DB4870BD4D7CD1D5BE6E1D8E54381298791146FFACA089A066C9304067CA0CB8CF493C89EFAEA9836553F05187BA74DE1D7862392B43A94D439B3FD98E4B1F93
-20200227031635 2 6 100 2047 2 C3A05E8BC687376881415BEB6C1506DA767E191DB4C5F4C587A839B341C2271B95F1B52E48C5CFF818CECB2E9BFBD3DB4B282B0D334A4992CF173E7A66B94D8B55F15CB610D5287917131C7CF4D966572EA2E0F1D6A89DFB54FB8B73B9B504D095446B8BA1C2EF49C8BC60D0074E3A25D1EC67FF95FD26D0A60CE0D692E32CB7326A8E5F698179DDE616D758DCB3F9F100623B23A3CF1699914515F5F97476AD124229CE5745A94417339C5D15F406A7D1A6D7BAB235E50D4A998DBD52B72347DB4870BD4D7CD1D5BE6E1D8E54381298791146FFACA089A066C9304067CA0CB8CF493C89EFAEA9836553F05187BA74DE1D7862392B43A94D439B3FD98F2240D3
-20200227031653 2 6 100 2047 2 C3A05E8BC687376881415BEB6C1506DA767E191DB4C5F4C587A839B341C2271B95F1B52E48C5CFF818CECB2E9BFBD3DB4B282B0D334A4992CF173E7A66B94D8B55F15CB610D5287917131C7CF4D966572EA2E0F1D6A89DFB54FB8B73B9B504D095446B8BA1C2EF49C8BC60D0074E3A25D1EC67FF95FD26D0A60CE0D692E32CB7326A8E5F698179DDE616D758DCB3F9F100623B23A3CF1699914515F5F97476AD124229CE5745A94417339C5D15F406A7D1A6D7BAB235E50D4A998DBD52B72347DB4870BD4D7CD1D5BE6E1D8E54381298791146FFACA089A066C9304067CA0CB8CF493C89EFAEA9836553F05187BA74DE1D7862392B43A94D439B3FD98F3EADE3
-20200227031817 2 6 100 2047 2 C3A05E8BC687376881415BEB6C1506DA767E191DB4C5F4C587A839B341C2271B95F1B52E48C5CFF818CECB2E9BFBD3DB4B282B0D334A4992CF173E7A66B94D8B55F15CB610D5287917131C7CF4D966572EA2E0F1D6A89DFB54FB8B73B9B504D095446B8BA1C2EF49C8BC60D0074E3A25D1EC67FF95FD26D0A60CE0D692E32CB7326A8E5F698179DDE616D758DCB3F9F100623B23A3CF1699914515F5F97476AD124229CE5745A94417339C5D15F406A7D1A6D7BAB235E50D4A998DBD52B72347DB4870BD4D7CD1D5BE6E1D8E54381298791146FFACA089A066C9304067CA0CB8CF493C89EFAEA9836553F05187BA74DE1D7862392B43A94D439B3FD98FB2594B
-20200227031826 2 6 100 2047 5 C3A05E8BC687376881415BEB6C1506DA767E191DB4C5F4C587A839B341C2271B95F1B52E48C5CFF818CECB2E9BFBD3DB4B282B0D334A4992CF173E7A66B94D8B55F15CB610D5287917131C7CF4D966572EA2E0F1D6A89DFB54FB8B73B9B504D095446B8BA1C2EF49C8BC60D0074E3A25D1EC67FF95FD26D0A60CE0D692E32CB7326A8E5F698179DDE616D758DCB3F9F100623B23A3CF1699914515F5F97476AD124229CE5745A94417339C5D15F406A7D1A6D7BAB235E50D4A998DBD52B72347DB4870BD4D7CD1D5BE6E1D8E54381298791146FFACA089A066C9304067CA0CB8CF493C89EFAEA9836553F05187BA74DE1D7862392B43A94D439B3FD98FB9CA6F
-20200227031845 2 6 100 2047 5 C3A05E8BC687376881415BEB6C1506DA767E191DB4C5F4C587A839B341C2271B95F1B52E48C5CFF818CECB2E9BFBD3DB4B282B0D334A4992CF173E7A66B94D8B55F15CB610D5287917131C7CF4D966572EA2E0F1D6A89DFB54FB8B73B9B504D095446B8BA1C2EF49C8BC60D0074E3A25D1EC67FF95FD26D0A60CE0D692E32CB7326A8E5F698179DDE616D758DCB3F9F100623B23A3CF1699914515F5F97476AD124229CE5745A94417339C5D15F406A7D1A6D7BAB235E50D4A998DBD52B72347DB4870BD4D7CD1D5BE6E1D8E54381298791146FFACA089A066C9304067CA0CB8CF493C89EFAEA9836553F05187BA74DE1D7862392B43A94D439B3FD98FD75E3F
-20200227031937 2 6 100 2047 2 C3A05E8BC687376881415BEB6C1506DA767E191DB4C5F4C587A839B341C2271B95F1B52E48C5CFF818CECB2E9BFBD3DB4B282B0D334A4992CF173E7A66B94D8B55F15CB610D5287917131C7CF4D966572EA2E0F1D6A89DFB54FB8B73B9B504D095446B8BA1C2EF49C8BC60D0074E3A25D1EC67FF95FD26D0A60CE0D692E32CB7326A8E5F698179DDE616D758DCB3F9F100623B23A3CF1699914515F5F97476AD124229CE5745A94417339C5D15F406A7D1A6D7BAB235E50D4A998DBD52B72347DB4870BD4D7CD1D5BE6E1D8E54381298791146FFACA089A066C9304067CA0CB8CF493C89EFAEA9836553F05187BA74DE1D7862392B43A94D439B3FD99022227B
-20200227031944 2 6 100 2047 2 C3A05E8BC687376881415BEB6C1506DA767E191DB4C5F4C587A839B341C2271B95F1B52E48C5CFF818CECB2E9BFBD3DB4B282B0D334A4992CF173E7A66B94D8B55F15CB610D5287917131C7CF4D966572EA2E0F1D6A89DFB54FB8B73B9B504D095446B8BA1C2EF49C8BC60D0074E3A25D1EC67FF95FD26D0A60CE0D692E32CB7326A8E5F698179DDE616D758DCB3F9F100623B23A3CF1699914515F5F97476AD124229CE5745A94417339C5D15F406A7D1A6D7BAB235E50D4A998DBD52B72347DB4870BD4D7CD1D5BE6E1D8E54381298791146FFACA089A066C9304067CA0CB8CF493C89EFAEA9836553F05187BA74DE1D7862392B43A94D439B3FD990262A33
-20200227031950 2 6 100 2047 2 C3A05E8BC687376881415BEB6C1506DA767E191DB4C5F4C587A839B341C2271B95F1B52E48C5CFF818CECB2E9BFBD3DB4B282B0D334A4992CF173E7A66B94D8B55F15CB610D5287917131C7CF4D966572EA2E0F1D6A89DFB54FB8B73B9B504D095446B8BA1C2EF49C8BC60D0074E3A25D1EC67FF95FD26D0A60CE0D692E32CB7326A8E5F698179DDE616D758DCB3F9F100623B23A3CF1699914515F5F97476AD124229CE5745A94417339C5D15F406A7D1A6D7BAB235E50D4A998DBD52B72347DB4870BD4D7CD1D5BE6E1D8E54381298791146FFACA089A066C9304067CA0CB8CF493C89EFAEA9836553F05187BA74DE1D7862392B43A94D439B3FD9902A81E3
-20200227031955 2 6 100 2047 2 C3A05E8BC687376881415BEB6C1506DA767E191DB4C5F4C587A839B341C2271B95F1B52E48C5CFF818CECB2E9BFBD3DB4B282B0D334A4992CF173E7A66B94D8B55F15CB610D5287917131C7CF4D966572EA2E0F1D6A89DFB54FB8B73B9B504D095446B8BA1C2EF49C8BC60D0074E3A25D1EC67FF95FD26D0A60CE0D692E32CB7326A8E5F698179DDE616D758DCB3F9F100623B23A3CF1699914515F5F97476AD124229CE5745A94417339C5D15F406A7D1A6D7BAB235E50D4A998DBD52B72347DB4870BD4D7CD1D5BE6E1D8E54381298791146FFACA089A066C9304067CA0CB8CF493C89EFAEA9836553F05187BA74DE1D7862392B43A94D439B3FD9902AEB73
-20200227032012 2 6 100 2047 2 C3A05E8BC687376881415BEB6C1506DA767E191DB4C5F4C587A839B341C2271B95F1B52E48C5CFF818CECB2E9BFBD3DB4B282B0D334A4992CF173E7A66B94D8B55F15CB610D5287917131C7CF4D966572EA2E0F1D6A89DFB54FB8B73B9B504D095446B8BA1C2EF49C8BC60D0074E3A25D1EC67FF95FD26D0A60CE0D692E32CB7326A8E5F698179DDE616D758DCB3F9F100623B23A3CF1699914515F5F97476AD124229CE5745A94417339C5D15F406A7D1A6D7BAB235E50D4A998DBD52B72347DB4870BD4D7CD1D5BE6E1D8E54381298791146FFACA089A066C9304067CA0CB8CF493C89EFAEA9836553F05187BA74DE1D7862392B43A94D439B3FD990348E1B
-20200227032023 2 6 100 2047 5 C3A05E8BC687376881415BEB6C1506DA767E191DB4C5F4C587A839B341C2271B95F1B52E48C5CFF818CECB2E9BFBD3DB4B282B0D334A4992CF173E7A66B94D8B55F15CB610D5287917131C7CF4D966572EA2E0F1D6A89DFB54FB8B73B9B504D095446B8BA1C2EF49C8BC60D0074E3A25D1EC67FF95FD26D0A60CE0D692E32CB7326A8E5F698179DDE616D758DCB3F9F100623B23A3CF1699914515F5F97476AD124229CE5745A94417339C5D15F406A7D1A6D7BAB235E50D4A998DBD52B72347DB4870BD4D7CD1D5BE6E1D8E54381298791146FFACA089A066C9304067CA0CB8CF493C89EFAEA9836553F05187BA74DE1D7862392B43A94D439B3FD9903B6057
-20200227032120 2 6 100 2047 2 C3A05E8BC687376881415BEB6C1506DA767E191DB4C5F4C587A839B341C2271B95F1B52E48C5CFF818CECB2E9BFBD3DB4B282B0D334A4992CF173E7A66B94D8B55F15CB610D5287917131C7CF4D966572EA2E0F1D6A89DFB54FB8B73B9B504D095446B8BA1C2EF49C8BC60D0074E3A25D1EC67FF95FD26D0A60CE0D692E32CB7326A8E5F698179DDE616D758DCB3F9F100623B23A3CF1699914515F5F97476AD124229CE5745A94417339C5D15F406A7D1A6D7BAB235E50D4A998DBD52B72347DB4870BD4D7CD1D5BE6E1D8E54381298791146FFACA089A066C9304067CA0CB8CF493C89EFAEA9836553F05187BA74DE1D7862392B43A94D439B3FD9908EA19B
-20200227032956 2 6 100 3071 5 DCBD1F34999D3EC980A7AEBD1943B18AFB4904E85DB641E8660A4AE3671C152EBB36BED44E5DA6D647F6232C29EE3FF3C20DFDB18D72B705E57F9B23636AF36E395D68651A0D223C816BF904E29134F49667D205B5EB03F613C24B65E386CB8EEE384AF41BDCF4373C885780C3AC2131584DF97F62A50C7E9169A52DC71B8D9F80FBFBEEC935C01D0375AD8BCA0E5C84A041D0BF80230D3AC15E09C2629326E59F70FAD8606BDFB3901284844D4C00155C48301F4E91384454852D47D2D0D992123E42130E6F1F45E429A4C52AFF03522B5C68307B4B1082E7868D8241D143A156C2E40F45A5E34C3D2397A91FF195C49DBABB490900238B6F5801B876EE1EC64D8E20F95C1F409F82D70C7C24DB5EEBACD6D56F0486E49DB009B859F2E757679D5499295783E1080C1369B373C481EA3295C9B8D46F8D10F29C50774959490DBD068D1A81BC118606BF8E58050B7F0D88929678D6A47FDAFE506D91FE5F61D4B2EC286CCF1AD616A875819C1BEE6536D24DAEB7DBAC87C2A7A771EA31DFAF3F
-20200227033345 2 6 100 3071 5 DCBD1F34999D3EC980A7AEBD1943B18AFB4904E85DB641E8660A4AE3671C152EBB36BED44E5DA6D647F6232C29EE3FF3C20DFDB18D72B705E57F9B23636AF36E395D68651A0D223C816BF904E29134F49667D205B5EB03F613C24B65E386CB8EEE384AF41BDCF4373C885780C3AC2131584DF97F62A50C7E9169A52DC71B8D9F80FBFBEEC935C01D0375AD8BCA0E5C84A041D0BF80230D3AC15E09C2629326E59F70FAD8606BDFB3901284844D4C00155C48301F4E91384454852D47D2D0D992123E42130E6F1F45E429A4C52AFF03522B5C68307B4B1082E7868D8241D143A156C2E40F45A5E34C3D2397A91FF195C49DBABB490900238B6F5801B876EE1EC64D8E20F95C1F409F82D70C7C24DB5EEBACD6D56F0486E49DB009B859F2E757679D5499295783E1080C1369B373C481EA3295C9B8D46F8D10F29C50774959490DBD068D1A81BC118606BF8E58050B7F0D88929678D6A47FDAFE506D91FE5F61D4B2EC286CCF1AD616A875819C1BEE6536D24DAEB7DBAC87C2A7A771EA3252345F
-20200227033438 2 6 100 3071 5 DCBD1F34999D3EC980A7AEBD1943B18AFB4904E85DB641E8660A4AE3671C152EBB36BED44E5DA6D647F6232C29EE3FF3C20DFDB18D72B705E57F9B23636AF36E395D68651A0D223C816BF904E29134F49667D205B5EB03F613C24B65E386CB8EEE384AF41BDCF4373C885780C3AC2131584DF97F62A50C7E9169A52DC71B8D9F80FBFBEEC935C01D0375AD8BCA0E5C84A041D0BF80230D3AC15E09C2629326E59F70FAD8606BDFB3901284844D4C00155C48301F4E91384454852D47D2D0D992123E42130E6F1F45E429A4C52AFF03522B5C68307B4B1082E7868D8241D143A156C2E40F45A5E34C3D2397A91FF195C49DBABB490900238B6F5801B876EE1EC64D8E20F95C1F409F82D70C7C24DB5EEBACD6D56F0486E49DB009B859F2E757679D5499295783E1080C1369B373C481EA3295C9B8D46F8D10F29C50774959490DBD068D1A81BC118606BF8E58050B7F0D88929678D6A47FDAFE506D91FE5F61D4B2EC286CCF1AD616A875819C1BEE6536D24DAEB7DBAC87C2A7A771EA32676B4F
-20200227033631 2 6 100 3071 2 DCBD1F34999D3EC980A7AEBD1943B18AFB4904E85DB641E8660A4AE3671C152EBB36BED44E5DA6D647F6232C29EE3FF3C20DFDB18D72B705E57F9B23636AF36E395D68651A0D223C816BF904E29134F49667D205B5EB03F613C24B65E386CB8EEE384AF41BDCF4373C885780C3AC2131584DF97F62A50C7E9169A52DC71B8D9F80FBFBEEC935C01D0375AD8BCA0E5C84A041D0BF80230D3AC15E09C2629326E59F70FAD8606BDFB3901284844D4C00155C48301F4E91384454852D47D2D0D992123E42130E6F1F45E429A4C52AFF03522B5C68307B4B1082E7868D8241D143A156C2E40F45A5E34C3D2397A91FF195C49DBABB490900238B6F5801B876EE1EC64D8E20F95C1F409F82D70C7C24DB5EEBACD6D56F0486E49DB009B859F2E757679D5499295783E1080C1369B373C481EA3295C9B8D46F8D10F29C50774959490DBD068D1A81BC118606BF8E58050B7F0D88929678D6A47FDAFE506D91FE5F61D4B2EC286CCF1AD616A875819C1BEE6536D24DAEB7DBAC87C2A7A771EA32A2AF93
-20200227033648 2 6 100 3071 2 DCBD1F34999D3EC980A7AEBD1943B18AFB4904E85DB641E8660A4AE3671C152EBB36BED44E5DA6D647F6232C29EE3FF3C20DFDB18D72B705E57F9B23636AF36E395D68651A0D223C816BF904E29134F49667D205B5EB03F613C24B65E386CB8EEE384AF41BDCF4373C885780C3AC2131584DF97F62A50C7E9169A52DC71B8D9F80FBFBEEC935C01D0375AD8BCA0E5C84A041D0BF80230D3AC15E09C2629326E59F70FAD8606BDFB3901284844D4C00155C48301F4E91384454852D47D2D0D992123E42130E6F1F45E429A4C52AFF03522B5C68307B4B1082E7868D8241D143A156C2E40F45A5E34C3D2397A91FF195C49DBABB490900238B6F5801B876EE1EC64D8E20F95C1F409F82D70C7C24DB5EEBACD6D56F0486E49DB009B859F2E757679D5499295783E1080C1369B373C481EA3295C9B8D46F8D10F29C50774959490DBD068D1A81BC118606BF8E58050B7F0D88929678D6A47FDAFE506D91FE5F61D4B2EC286CCF1AD616A875819C1BEE6536D24DAEB7DBAC87C2A7A771EA32A57513
-20200227033939 2 6 100 3071 2 DCBD1F34999D3EC980A7AEBD1943B18AFB4904E85DB641E8660A4AE3671C152EBB36BED44E5DA6D647F6232C29EE3FF3C20DFDB18D72B705E57F9B23636AF36E395D68651A0D223C816BF904E29134F49667D205B5EB03F613C24B65E386CB8EEE384AF41BDCF4373C885780C3AC2131584DF97F62A50C7E9169A52DC71B8D9F80FBFBEEC935C01D0375AD8BCA0E5C84A041D0BF80230D3AC15E09C2629326E59F70FAD8606BDFB3901284844D4C00155C48301F4E91384454852D47D2D0D992123E42130E6F1F45E429A4C52AFF03522B5C68307B4B1082E7868D8241D143A156C2E40F45A5E34C3D2397A91FF195C49DBABB490900238B6F5801B876EE1EC64D8E20F95C1F409F82D70C7C24DB5EEBACD6D56F0486E49DB009B859F2E757679D5499295783E1080C1369B373C481EA3295C9B8D46F8D10F29C50774959490DBD068D1A81BC118606BF8E58050B7F0D88929678D6A47FDAFE506D91FE5F61D4B2EC286CCF1AD616A875819C1BEE6536D24DAEB7DBAC87C2A7A771EA32FDB38B
-20200227034338 2 6 100 3071 2 DCBD1F34999D3EC980A7AEBD1943B18AFB4904E85DB641E8660A4AE3671C152EBB36BED44E5DA6D647F6232C29EE3FF3C20DFDB18D72B705E57F9B23636AF36E395D68651A0D223C816BF904E29134F49667D205B5EB03F613C24B65E386CB8EEE384AF41BDCF4373C885780C3AC2131584DF97F62A50C7E9169A52DC71B8D9F80FBFBEEC935C01D0375AD8BCA0E5C84A041D0BF80230D3AC15E09C2629326E59F70FAD8606BDFB3901284844D4C00155C48301F4E91384454852D47D2D0D992123E42130E6F1F45E429A4C52AFF03522B5C68307B4B1082E7868D8241D143A156C2E40F45A5E34C3D2397A91FF195C49DBABB490900238B6F5801B876EE1EC64D8E20F95C1F409F82D70C7C24DB5EEBACD6D56F0486E49DB009B859F2E757679D5499295783E1080C1369B373C481EA3295C9B8D46F8D10F29C50774959490DBD068D1A81BC118606BF8E58050B7F0D88929678D6A47FDAFE506D91FE5F61D4B2EC286CCF1AD616A875819C1BEE6536D24DAEB7DBAC87C2A7A771EA337FBEBB
-20200227034832 2 6 100 3071 5 DCBD1F34999D3EC980A7AEBD1943B18AFB4904E85DB641E8660A4AE3671C152EBB36BED44E5DA6D647F6232C29EE3FF3C20DFDB18D72B705E57F9B23636AF36E395D68651A0D223C816BF904E29134F49667D205B5EB03F613C24B65E386CB8EEE384AF41BDCF4373C885780C3AC2131584DF97F62A50C7E9169A52DC71B8D9F80FBFBEEC935C01D0375AD8BCA0E5C84A041D0BF80230D3AC15E09C2629326E59F70FAD8606BDFB3901284844D4C00155C48301F4E91384454852D47D2D0D992123E42130E6F1F45E429A4C52AFF03522B5C68307B4B1082E7868D8241D143A156C2E40F45A5E34C3D2397A91FF195C49DBABB490900238B6F5801B876EE1EC64D8E20F95C1F409F82D70C7C24DB5EEBACD6D56F0486E49DB009B859F2E757679D5499295783E1080C1369B373C481EA3295C9B8D46F8D10F29C50774959490DBD068D1A81BC118606BF8E58050B7F0D88929678D6A47FDAFE506D91FE5F61D4B2EC286CCF1AD616A875819C1BEE6536D24DAEB7DBAC87C2A7A771EA341DDB0F
-20200227035633 2 6 100 3071 2 DCBD1F34999D3EC980A7AEBD1943B18AFB4904E85DB641E8660A4AE3671C152EBB36BED44E5DA6D647F6232C29EE3FF3C20DFDB18D72B705E57F9B23636AF36E395D68651A0D223C816BF904E29134F49667D205B5EB03F613C24B65E386CB8EEE384AF41BDCF4373C885780C3AC2131584DF97F62A50C7E9169A52DC71B8D9F80FBFBEEC935C01D0375AD8BCA0E5C84A041D0BF80230D3AC15E09C2629326E59F70FAD8606BDFB3901284844D4C00155C48301F4E91384454852D47D2D0D992123E42130E6F1F45E429A4C52AFF03522B5C68307B4B1082E7868D8241D143A156C2E40F45A5E34C3D2397A91FF195C49DBABB490900238B6F5801B876EE1EC64D8E20F95C1F409F82D70C7C24DB5EEBACD6D56F0486E49DB009B859F2E757679D5499295783E1080C1369B373C481EA3295C9B8D46F8D10F29C50774959490DBD068D1A81BC118606BF8E58050B7F0D88929678D6A47FDAFE506D91FE5F61D4B2EC286CCF1AD616A875819C1BEE6536D24DAEB7DBAC87C2A7A771EA3531B9A3
-20200227035941 2 6 100 3071 2 DCBD1F34999D3EC980A7AEBD1943B18AFB4904E85DB641E8660A4AE3671C152EBB36BED44E5DA6D647F6232C29EE3FF3C20DFDB18D72B705E57F9B23636AF36E395D68651A0D223C816BF904E29134F49667D205B5EB03F613C24B65E386CB8EEE384AF41BDCF4373C885780C3AC2131584DF97F62A50C7E9169A52DC71B8D9F80FBFBEEC935C01D0375AD8BCA0E5C84A041D0BF80230D3AC15E09C2629326E59F70FAD8606BDFB3901284844D4C00155C48301F4E91384454852D47D2D0D992123E42130E6F1F45E429A4C52AFF03522B5C68307B4B1082E7868D8241D143A156C2E40F45A5E34C3D2397A91FF195C49DBABB490900238B6F5801B876EE1EC64D8E20F95C1F409F82D70C7C24DB5EEBACD6D56F0486E49DB009B859F2E757679D5499295783E1080C1369B373C481EA3295C9B8D46F8D10F29C50774959490DBD068D1A81BC118606BF8E58050B7F0D88929678D6A47FDAFE506D91FE5F61D4B2EC286CCF1AD616A875819C1BEE6536D24DAEB7DBAC87C2A7A771EA359F1EBB
-20200227040026 2 6 100 3071 5 DCBD1F34999D3EC980A7AEBD1943B18AFB4904E85DB641E8660A4AE3671C152EBB36BED44E5DA6D647F6232C29EE3FF3C20DFDB18D72B705E57F9B23636AF36E395D68651A0D223C816BF904E29134F49667D205B5EB03F613C24B65E386CB8EEE384AF41BDCF4373C885780C3AC2131584DF97F62A50C7E9169A52DC71B8D9F80FBFBEEC935C01D0375AD8BCA0E5C84A041D0BF80230D3AC15E09C2629326E59F70FAD8606BDFB3901284844D4C00155C48301F4E91384454852D47D2D0D992123E42130E6F1F45E429A4C52AFF03522B5C68307B4B1082E7868D8241D143A156C2E40F45A5E34C3D2397A91FF195C49DBABB490900238B6F5801B876EE1EC64D8E20F95C1F409F82D70C7C24DB5EEBACD6D56F0486E49DB009B859F2E757679D5499295783E1080C1369B373C481EA3295C9B8D46F8D10F29C50774959490DBD068D1A81BC118606BF8E58050B7F0D88929678D6A47FDAFE506D91FE5F61D4B2EC286CCF1AD616A875819C1BEE6536D24DAEB7DBAC87C2A7A771EA35B2A26F
-20200227040140 2 6 100 3071 2 DCBD1F34999D3EC980A7AEBD1943B18AFB4904E85DB641E8660A4AE3671C152EBB36BED44E5DA6D647F6232C29EE3FF3C20DFDB18D72B705E57F9B23636AF36E395D68651A0D223C816BF904E29134F49667D205B5EB03F613C24B65E386CB8EEE384AF41BDCF4373C885780C3AC2131584DF97F62A50C7E9169A52DC71B8D9F80FBFBEEC935C01D0375AD8BCA0E5C84A041D0BF80230D3AC15E09C2629326E59F70FAD8606BDFB3901284844D4C00155C48301F4E91384454852D47D2D0D992123E42130E6F1F45E429A4C52AFF03522B5C68307B4B1082E7868D8241D143A156C2E40F45A5E34C3D2397A91FF195C49DBABB490900238B6F5801B876EE1EC64D8E20F95C1F409F82D70C7C24DB5EEBACD6D56F0486E49DB009B859F2E757679D5499295783E1080C1369B373C481EA3295C9B8D46F8D10F29C50774959490DBD068D1A81BC118606BF8E58050B7F0D88929678D6A47FDAFE506D91FE5F61D4B2EC286CCF1AD616A875819C1BEE6536D24DAEB7DBAC87C2A7A771EA35D7858B
-20200227040536 2 6 100 3071 2 DCBD1F34999D3EC980A7AEBD1943B18AFB4904E85DB641E8660A4AE3671C152EBB36BED44E5DA6D647F6232C29EE3FF3C20DFDB18D72B705E57F9B23636AF36E395D68651A0D223C816BF904E29134F49667D205B5EB03F613C24B65E386CB8EEE384AF41BDCF4373C885780C3AC2131584DF97F62A50C7E9169A52DC71B8D9F80FBFBEEC935C01D0375AD8BCA0E5C84A041D0BF80230D3AC15E09C2629326E59F70FAD8606BDFB3901284844D4C00155C48301F4E91384454852D47D2D0D992123E42130E6F1F45E429A4C52AFF03522B5C68307B4B1082E7868D8241D143A156C2E40F45A5E34C3D2397A91FF195C49DBABB490900238B6F5801B876EE1EC64D8E20F95C1F409F82D70C7C24DB5EEBACD6D56F0486E49DB009B859F2E757679D5499295783E1080C1369B373C481EA3295C9B8D46F8D10F29C50774959490DBD068D1A81BC118606BF8E58050B7F0D88929678D6A47FDAFE506D91FE5F61D4B2EC286CCF1AD616A875819C1BEE6536D24DAEB7DBAC87C2A7A771EA36567783
-20200227041037 2 6 100 3071 5 DCBD1F34999D3EC980A7AEBD1943B18AFB4904E85DB641E8660A4AE3671C152EBB36BED44E5DA6D647F6232C29EE3FF3C20DFDB18D72B705E57F9B23636AF36E395D68651A0D223C816BF904E29134F49667D205B5EB03F613C24B65E386CB8EEE384AF41BDCF4373C885780C3AC2131584DF97F62A50C7E9169A52DC71B8D9F80FBFBEEC935C01D0375AD8BCA0E5C84A041D0BF80230D3AC15E09C2629326E59F70FAD8606BDFB3901284844D4C00155C48301F4E91384454852D47D2D0D992123E42130E6F1F45E429A4C52AFF03522B5C68307B4B1082E7868D8241D143A156C2E40F45A5E34C3D2397A91FF195C49DBABB490900238B6F5801B876EE1EC64D8E20F95C1F409F82D70C7C24DB5EEBACD6D56F0486E49DB009B859F2E757679D5499295783E1080C1369B373C481EA3295C9B8D46F8D10F29C50774959490DBD068D1A81BC118606BF8E58050B7F0D88929678D6A47FDAFE506D91FE5F61D4B2EC286CCF1AD616A875819C1BEE6536D24DAEB7DBAC87C2A7A771EA36F6CA8F
-20200227041504 2 6 100 3071 5 DCBD1F34999D3EC980A7AEBD1943B18AFB4904E85DB641E8660A4AE3671C152EBB36BED44E5DA6D647F6232C29EE3FF3C20DFDB18D72B705E57F9B23636AF36E395D68651A0D223C816BF904E29134F49667D205B5EB03F613C24B65E386CB8EEE384AF41BDCF4373C885780C3AC2131584DF97F62A50C7E9169A52DC71B8D9F80FBFBEEC935C01D0375AD8BCA0E5C84A041D0BF80230D3AC15E09C2629326E59F70FAD8606BDFB3901284844D4C00155C48301F4E91384454852D47D2D0D992123E42130E6F1F45E429A4C52AFF03522B5C68307B4B1082E7868D8241D143A156C2E40F45A5E34C3D2397A91FF195C49DBABB490900238B6F5801B876EE1EC64D8E20F95C1F409F82D70C7C24DB5EEBACD6D56F0486E49DB009B859F2E757679D5499295783E1080C1369B373C481EA3295C9B8D46F8D10F29C50774959490DBD068D1A81BC118606BF8E58050B7F0D88929678D6A47FDAFE506D91FE5F61D4B2EC286CCF1AD616A875819C1BEE6536D24DAEB7DBAC87C2A7A771EA3785E44F
-20200227041915 2 6 100 3071 5 DCBD1F34999D3EC980A7AEBD1943B18AFB4904E85DB641E8660A4AE3671C152EBB36BED44E5DA6D647F6232C29EE3FF3C20DFDB18D72B705E57F9B23636AF36E395D68651A0D223C816BF904E29134F49667D205B5EB03F613C24B65E386CB8EEE384AF41BDCF4373C885780C3AC2131584DF97F62A50C7E9169A52DC71B8D9F80FBFBEEC935C01D0375AD8BCA0E5C84A041D0BF80230D3AC15E09C2629326E59F70FAD8606BDFB3901284844D4C00155C48301F4E91384454852D47D2D0D992123E42130E6F1F45E429A4C52AFF03522B5C68307B4B1082E7868D8241D143A156C2E40F45A5E34C3D2397A91FF195C49DBABB490900238B6F5801B876EE1EC64D8E20F95C1F409F82D70C7C24DB5EEBACD6D56F0486E49DB009B859F2E757679D5499295783E1080C1369B373C481EA3295C9B8D46F8D10F29C50774959490DBD068D1A81BC118606BF8E58050B7F0D88929678D6A47FDAFE506D91FE5F61D4B2EC286CCF1AD616A875819C1BEE6536D24DAEB7DBAC87C2A7A771EA3808D25F
-20200227042019 2 6 100 3071 5 DCBD1F34999D3EC980A7AEBD1943B18AFB4904E85DB641E8660A4AE3671C152EBB36BED44E5DA6D647F6232C29EE3FF3C20DFDB18D72B705E57F9B23636AF36E395D68651A0D223C816BF904E29134F49667D205B5EB03F613C24B65E386CB8EEE384AF41BDCF4373C885780C3AC2131584DF97F62A50C7E9169A52DC71B8D9F80FBFBEEC935C01D0375AD8BCA0E5C84A041D0BF80230D3AC15E09C2629326E59F70FAD8606BDFB3901284844D4C00155C48301F4E91384454852D47D2D0D992123E42130E6F1F45E429A4C52AFF03522B5C68307B4B1082E7868D8241D143A156C2E40F45A5E34C3D2397A91FF195C49DBABB490900238B6F5801B876EE1EC64D8E20F95C1F409F82D70C7C24DB5EEBACD6D56F0486E49DB009B859F2E757679D5499295783E1080C1369B373C481EA3295C9B8D46F8D10F29C50774959490DBD068D1A81BC118606BF8E58050B7F0D88929678D6A47FDAFE506D91FE5F61D4B2EC286CCF1AD616A875819C1BEE6536D24DAEB7DBAC87C2A7A771EA3824C37F
-20200227042213 2 6 100 3071 2 DCBD1F34999D3EC980A7AEBD1943B18AFB4904E85DB641E8660A4AE3671C152EBB36BED44E5DA6D647F6232C29EE3FF3C20DFDB18D72B705E57F9B23636AF36E395D68651A0D223C816BF904E29134F49667D205B5EB03F613C24B65E386CB8EEE384AF41BDCF4373C885780C3AC2131584DF97F62A50C7E9169A52DC71B8D9F80FBFBEEC935C01D0375AD8BCA0E5C84A041D0BF80230D3AC15E09C2629326E59F70FAD8606BDFB3901284844D4C00155C48301F4E91384454852D47D2D0D992123E42130E6F1F45E429A4C52AFF03522B5C68307B4B1082E7868D8241D143A156C2E40F45A5E34C3D2397A91FF195C49DBABB490900238B6F5801B876EE1EC64D8E20F95C1F409F82D70C7C24DB5EEBACD6D56F0486E49DB009B859F2E757679D5499295783E1080C1369B373C481EA3295C9B8D46F8D10F29C50774959490DBD068D1A81BC118606BF8E58050B7F0D88929678D6A47FDAFE506D91FE5F61D4B2EC286CCF1AD616A875819C1BEE6536D24DAEB7DBAC87C2A7A771EA385DC613
-20200227042334 2 6 100 3071 2 DCBD1F34999D3EC980A7AEBD1943B18AFB4904E85DB641E8660A4AE3671C152EBB36BED44E5DA6D647F6232C29EE3FF3C20DFDB18D72B705E57F9B23636AF36E395D68651A0D223C816BF904E29134F49667D205B5EB03F613C24B65E386CB8EEE384AF41BDCF4373C885780C3AC2131584DF97F62A50C7E9169A52DC71B8D9F80FBFBEEC935C01D0375AD8BCA0E5C84A041D0BF80230D3AC15E09C2629326E59F70FAD8606BDFB3901284844D4C00155C48301F4E91384454852D47D2D0D992123E42130E6F1F45E429A4C52AFF03522B5C68307B4B1082E7868D8241D143A156C2E40F45A5E34C3D2397A91FF195C49DBABB490900238B6F5801B876EE1EC64D8E20F95C1F409F82D70C7C24DB5EEBACD6D56F0486E49DB009B859F2E757679D5499295783E1080C1369B373C481EA3295C9B8D46F8D10F29C50774959490DBD068D1A81BC118606BF8E58050B7F0D88929678D6A47FDAFE506D91FE5F61D4B2EC286CCF1AD616A875819C1BEE6536D24DAEB7DBAC87C2A7A771EA38849CEB
-20200227043140 2 6 100 3071 2 DCBD1F34999D3EC980A7AEBD1943B18AFB4904E85DB641E8660A4AE3671C152EBB36BED44E5DA6D647F6232C29EE3FF3C20DFDB18D72B705E57F9B23636AF36E395D68651A0D223C816BF904E29134F49667D205B5EB03F613C24B65E386CB8EEE384AF41BDCF4373C885780C3AC2131584DF97F62A50C7E9169A52DC71B8D9F80FBFBEEC935C01D0375AD8BCA0E5C84A041D0BF80230D3AC15E09C2629326E59F70FAD8606BDFB3901284844D4C00155C48301F4E91384454852D47D2D0D992123E42130E6F1F45E429A4C52AFF03522B5C68307B4B1082E7868D8241D143A156C2E40F45A5E34C3D2397A91FF195C49DBABB490900238B6F5801B876EE1EC64D8E20F95C1F409F82D70C7C24DB5EEBACD6D56F0486E49DB009B859F2E757679D5499295783E1080C1369B373C481EA3295C9B8D46F8D10F29C50774959490DBD068D1A81BC118606BF8E58050B7F0D88929678D6A47FDAFE506D91FE5F61D4B2EC286CCF1AD616A875819C1BEE6536D24DAEB7DBAC87C2A7A771EA39923EB3
-20200227043516 2 6 100 3071 2 DCBD1F34999D3EC980A7AEBD1943B18AFB4904E85DB641E8660A4AE3671C152EBB36BED44E5DA6D647F6232C29EE3FF3C20DFDB18D72B705E57F9B23636AF36E395D68651A0D223C816BF904E29134F49667D205B5EB03F613C24B65E386CB8EEE384AF41BDCF4373C885780C3AC2131584DF97F62A50C7E9169A52DC71B8D9F80FBFBEEC935C01D0375AD8BCA0E5C84A041D0BF80230D3AC15E09C2629326E59F70FAD8606BDFB3901284844D4C00155C48301F4E91384454852D47D2D0D992123E42130E6F1F45E429A4C52AFF03522B5C68307B4B1082E7868D8241D143A156C2E40F45A5E34C3D2397A91FF195C49DBABB490900238B6F5801B876EE1EC64D8E20F95C1F409F82D70C7C24DB5EEBACD6D56F0486E49DB009B859F2E757679D5499295783E1080C1369B373C481EA3295C9B8D46F8D10F29C50774959490DBD068D1A81BC118606BF8E58050B7F0D88929678D6A47FDAFE506D91FE5F61D4B2EC286CCF1AD616A875819C1BEE6536D24DAEB7DBAC87C2A7A771EA3A0635DB
-20200227044359 2 6 100 3071 5 DCBD1F34999D3EC980A7AEBD1943B18AFB4904E85DB641E8660A4AE3671C152EBB36BED44E5DA6D647F6232C29EE3FF3C20DFDB18D72B705E57F9B23636AF36E395D68651A0D223C816BF904E29134F49667D205B5EB03F613C24B65E386CB8EEE384AF41BDCF4373C885780C3AC2131584DF97F62A50C7E9169A52DC71B8D9F80FBFBEEC935C01D0375AD8BCA0E5C84A041D0BF80230D3AC15E09C2629326E59F70FAD8606BDFB3901284844D4C00155C48301F4E91384454852D47D2D0D992123E42130E6F1F45E429A4C52AFF03522B5C68307B4B1082E7868D8241D143A156C2E40F45A5E34C3D2397A91FF195C49DBABB490900238B6F5801B876EE1EC64D8E20F95C1F409F82D70C7C24DB5EEBACD6D56F0486E49DB009B859F2E757679D5499295783E1080C1369B373C481EA3295C9B8D46F8D10F29C50774959490DBD068D1A81BC118606BF8E58050B7F0D88929678D6A47FDAFE506D91FE5F61D4B2EC286CCF1AD616A875819C1BEE6536D24DAEB7DBAC87C2A7A771EA3B392D4F
-20200227045601 2 6 100 3071 5 DCBD1F34999D3EC980A7AEBD1943B18AFB4904E85DB641E8660A4AE3671C152EBB36BED44E5DA6D647F6232C29EE3FF3C20DFDB18D72B705E57F9B23636AF36E395D68651A0D223C816BF904E29134F49667D205B5EB03F613C24B65E386CB8EEE384AF41BDCF4373C885780C3AC2131584DF97F62A50C7E9169A52DC71B8D9F80FBFBEEC935C01D0375AD8BCA0E5C84A041D0BF80230D3AC15E09C2629326E59F70FAD8606BDFB3901284844D4C00155C48301F4E91384454852D47D2D0D992123E42130E6F1F45E429A4C52AFF03522B5C68307B4B1082E7868D8241D143A156C2E40F45A5E34C3D2397A91FF195C49DBABB490900238B6F5801B876EE1EC64D8E20F95C1F409F82D70C7C24DB5EEBACD6D56F0486E49DB009B859F2E757679D5499295783E1080C1369B373C481EA3295C9B8D46F8D10F29C50774959490DBD068D1A81BC118606BF8E58050B7F0D88929678D6A47FDAFE506D91FE5F61D4B2EC286CCF1AD616A875819C1BEE6536D24DAEB7DBAC87C2A7A771EA3CCCDC47
-20200227045738 2 6 100 3071 2 DCBD1F34999D3EC980A7AEBD1943B18AFB4904E85DB641E8660A4AE3671C152EBB36BED44E5DA6D647F6232C29EE3FF3C20DFDB18D72B705E57F9B23636AF36E395D68651A0D223C816BF904E29134F49667D205B5EB03F613C24B65E386CB8EEE384AF41BDCF4373C885780C3AC2131584DF97F62A50C7E9169A52DC71B8D9F80FBFBEEC935C01D0375AD8BCA0E5C84A041D0BF80230D3AC15E09C2629326E59F70FAD8606BDFB3901284844D4C00155C48301F4E91384454852D47D2D0D992123E42130E6F1F45E429A4C52AFF03522B5C68307B4B1082E7868D8241D143A156C2E40F45A5E34C3D2397A91FF195C49DBABB490900238B6F5801B876EE1EC64D8E20F95C1F409F82D70C7C24DB5EEBACD6D56F0486E49DB009B859F2E757679D5499295783E1080C1369B373C481EA3295C9B8D46F8D10F29C50774959490DBD068D1A81BC118606BF8E58050B7F0D88929678D6A47FDAFE506D91FE5F61D4B2EC286CCF1AD616A875819C1BEE6536D24DAEB7DBAC87C2A7A771EA3CFCA5F3
-20200227045900 2 6 100 3071 5 DCBD1F34999D3EC980A7AEBD1943B18AFB4904E85DB641E8660A4AE3671C152EBB36BED44E5DA6D647F6232C29EE3FF3C20DFDB18D72B705E57F9B23636AF36E395D68651A0D223C816BF904E29134F49667D205B5EB03F613C24B65E386CB8EEE384AF41BDCF4373C885780C3AC2131584DF97F62A50C7E9169A52DC71B8D9F80FBFBEEC935C01D0375AD8BCA0E5C84A041D0BF80230D3AC15E09C2629326E59F70FAD8606BDFB3901284844D4C00155C48301F4E91384454852D47D2D0D992123E42130E6F1F45E429A4C52AFF03522B5C68307B4B1082E7868D8241D143A156C2E40F45A5E34C3D2397A91FF195C49DBABB490900238B6F5801B876EE1EC64D8E20F95C1F409F82D70C7C24DB5EEBACD6D56F0486E49DB009B859F2E757679D5499295783E1080C1369B373C481EA3295C9B8D46F8D10F29C50774959490DBD068D1A81BC118606BF8E58050B7F0D88929678D6A47FDAFE506D91FE5F61D4B2EC286CCF1AD616A875819C1BEE6536D24DAEB7DBAC87C2A7A771EA3D24B39F
-20200227050201 2 6 100 3071 2 DCBD1F34999D3EC980A7AEBD1943B18AFB4904E85DB641E8660A4AE3671C152EBB36BED44E5DA6D647F6232C29EE3FF3C20DFDB18D72B705E57F9B23636AF36E395D68651A0D223C816BF904E29134F49667D205B5EB03F613C24B65E386CB8EEE384AF41BDCF4373C885780C3AC2131584DF97F62A50C7E9169A52DC71B8D9F80FBFBEEC935C01D0375AD8BCA0E5C84A041D0BF80230D3AC15E09C2629326E59F70FAD8606BDFB3901284844D4C00155C48301F4E91384454852D47D2D0D992123E42130E6F1F45E429A4C52AFF03522B5C68307B4B1082E7868D8241D143A156C2E40F45A5E34C3D2397A91FF195C49DBABB490900238B6F5801B876EE1EC64D8E20F95C1F409F82D70C7C24DB5EEBACD6D56F0486E49DB009B859F2E757679D5499295783E1080C1369B373C481EA3295C9B8D46F8D10F29C50774959490DBD068D1A81BC118606BF8E58050B7F0D88929678D6A47FDAFE506D91FE5F61D4B2EC286CCF1AD616A875819C1BEE6536D24DAEB7DBAC87C2A7A771EA3D83C633
-20200227050551 2 6 100 3071 2 DCBD1F34999D3EC980A7AEBD1943B18AFB4904E85DB641E8660A4AE3671C152EBB36BED44E5DA6D647F6232C29EE3FF3C20DFDB18D72B705E57F9B23636AF36E395D68651A0D223C816BF904E29134F49667D205B5EB03F613C24B65E386CB8EEE384AF41BDCF4373C885780C3AC2131584DF97F62A50C7E9169A52DC71B8D9F80FBFBEEC935C01D0375AD8BCA0E5C84A041D0BF80230D3AC15E09C2629326E59F70FAD8606BDFB3901284844D4C00155C48301F4E91384454852D47D2D0D992123E42130E6F1F45E429A4C52AFF03522B5C68307B4B1082E7868D8241D143A156C2E40F45A5E34C3D2397A91FF195C49DBABB490900238B6F5801B876EE1EC64D8E20F95C1F409F82D70C7C24DB5EEBACD6D56F0486E49DB009B859F2E757679D5499295783E1080C1369B373C481EA3295C9B8D46F8D10F29C50774959490DBD068D1A81BC118606BF8E58050B7F0D88929678D6A47FDAFE506D91FE5F61D4B2EC286CCF1AD616A875819C1BEE6536D24DAEB7DBAC87C2A7A771EA3DFE5163
-20200227051236 2 6 100 3071 5 DCBD1F34999D3EC980A7AEBD1943B18AFB4904E85DB641E8660A4AE3671C152EBB36BED44E5DA6D647F6232C29EE3FF3C20DFDB18D72B705E57F9B23636AF36E395D68651A0D223C816BF904E29134F49667D205B5EB03F613C24B65E386CB8EEE384AF41BDCF4373C885780C3AC2131584DF97F62A50C7E9169A52DC71B8D9F80FBFBEEC935C01D0375AD8BCA0E5C84A041D0BF80230D3AC15E09C2629326E59F70FAD8606BDFB3901284844D4C00155C48301F4E91384454852D47D2D0D992123E42130E6F1F45E429A4C52AFF03522B5C68307B4B1082E7868D8241D143A156C2E40F45A5E34C3D2397A91FF195C49DBABB490900238B6F5801B876EE1EC64D8E20F95C1F409F82D70C7C24DB5EEBACD6D56F0486E49DB009B859F2E757679D5499295783E1080C1369B373C481EA3295C9B8D46F8D10F29C50774959490DBD068D1A81BC118606BF8E58050B7F0D88929678D6A47FDAFE506D91FE5F61D4B2EC286CCF1AD616A875819C1BEE6536D24DAEB7DBAC87C2A7A771EA3ED9C2F7
-20200227051737 2 6 100 3071 2 DCBD1F34999D3EC980A7AEBD1943B18AFB4904E85DB641E8660A4AE3671C152EBB36BED44E5DA6D647F6232C29EE3FF3C20DFDB18D72B705E57F9B23636AF36E395D68651A0D223C816BF904E29134F49667D205B5EB03F613C24B65E386CB8EEE384AF41BDCF4373C885780C3AC2131584DF97F62A50C7E9169A52DC71B8D9F80FBFBEEC935C01D0375AD8BCA0E5C84A041D0BF80230D3AC15E09C2629326E59F70FAD8606BDFB3901284844D4C00155C48301F4E91384454852D47D2D0D992123E42130E6F1F45E429A4C52AFF03522B5C68307B4B1082E7868D8241D143A156C2E40F45A5E34C3D2397A91FF195C49DBABB490900238B6F5801B876EE1EC64D8E20F95C1F409F82D70C7C24DB5EEBACD6D56F0486E49DB009B859F2E757679D5499295783E1080C1369B373C481EA3295C9B8D46F8D10F29C50774959490DBD068D1A81BC118606BF8E58050B7F0D88929678D6A47FDAFE506D91FE5F61D4B2EC286CCF1AD616A875819C1BEE6536D24DAEB7DBAC87C2A7A771EA3F7F3323
-20200227051844 2 6 100 3071 5 DCBD1F34999D3EC980A7AEBD1943B18AFB4904E85DB641E8660A4AE3671C152EBB36BED44E5DA6D647F6232C29EE3FF3C20DFDB18D72B705E57F9B23636AF36E395D68651A0D223C816BF904E29134F49667D205B5EB03F613C24B65E386CB8EEE384AF41BDCF4373C885780C3AC2131584DF97F62A50C7E9169A52DC71B8D9F80FBFBEEC935C01D0375AD8BCA0E5C84A041D0BF80230D3AC15E09C2629326E59F70FAD8606BDFB3901284844D4C00155C48301F4E91384454852D47D2D0D992123E42130E6F1F45E429A4C52AFF03522B5C68307B4B1082E7868D8241D143A156C2E40F45A5E34C3D2397A91FF195C49DBABB490900238B6F5801B876EE1EC64D8E20F95C1F409F82D70C7C24DB5EEBACD6D56F0486E49DB009B859F2E757679D5499295783E1080C1369B373C481EA3295C9B8D46F8D10F29C50774959490DBD068D1A81BC118606BF8E58050B7F0D88929678D6A47FDAFE506D91FE5F61D4B2EC286CCF1AD616A875819C1BEE6536D24DAEB7DBAC87C2A7A771EA3FA0D7E7
-20200227052045 2 6 100 3071 2 DCBD1F34999D3EC980A7AEBD1943B18AFB4904E85DB641E8660A4AE3671C152EBB36BED44E5DA6D647F6232C29EE3FF3C20DFDB18D72B705E57F9B23636AF36E395D68651A0D223C816BF904E29134F49667D205B5EB03F613C24B65E386CB8EEE384AF41BDCF4373C885780C3AC2131584DF97F62A50C7E9169A52DC71B8D9F80FBFBEEC935C01D0375AD8BCA0E5C84A041D0BF80230D3AC15E09C2629326E59F70FAD8606BDFB3901284844D4C00155C48301F4E91384454852D47D2D0D992123E42130E6F1F45E429A4C52AFF03522B5C68307B4B1082E7868D8241D143A156C2E40F45A5E34C3D2397A91FF195C49DBABB490900238B6F5801B876EE1EC64D8E20F95C1F409F82D70C7C24DB5EEBACD6D56F0486E49DB009B859F2E757679D5499295783E1080C1369B373C481EA3295C9B8D46F8D10F29C50774959490DBD068D1A81BC118606BF8E58050B7F0D88929678D6A47FDAFE506D91FE5F61D4B2EC286CCF1AD616A875819C1BEE6536D24DAEB7DBAC87C2A7A771EA3FDE75DB
-20200227052157 2 6 100 3071 2 DCBD1F34999D3EC980A7AEBD1943B18AFB4904E85DB641E8660A4AE3671C152EBB36BED44E5DA6D647F6232C29EE3FF3C20DFDB18D72B705E57F9B23636AF36E395D68651A0D223C816BF904E29134F49667D205B5EB03F613C24B65E386CB8EEE384AF41BDCF4373C885780C3AC2131584DF97F62A50C7E9169A52DC71B8D9F80FBFBEEC935C01D0375AD8BCA0E5C84A041D0BF80230D3AC15E09C2629326E59F70FAD8606BDFB3901284844D4C00155C48301F4E91384454852D47D2D0D992123E42130E6F1F45E429A4C52AFF03522B5C68307B4B1082E7868D8241D143A156C2E40F45A5E34C3D2397A91FF195C49DBABB490900238B6F5801B876EE1EC64D8E20F95C1F409F82D70C7C24DB5EEBACD6D56F0486E49DB009B859F2E757679D5499295783E1080C1369B373C481EA3295C9B8D46F8D10F29C50774959490DBD068D1A81BC118606BF8E58050B7F0D88929678D6A47FDAFE506D91FE5F61D4B2EC286CCF1AD616A875819C1BEE6536D24DAEB7DBAC87C2A7A771EA3FFFCD0B
-20200227052559 2 6 100 3071 5 DCBD1F34999D3EC980A7AEBD1943B18AFB4904E85DB641E8660A4AE3671C152EBB36BED44E5DA6D647F6232C29EE3FF3C20DFDB18D72B705E57F9B23636AF36E395D68651A0D223C816BF904E29134F49667D205B5EB03F613C24B65E386CB8EEE384AF41BDCF4373C885780C3AC2131584DF97F62A50C7E9169A52DC71B8D9F80FBFBEEC935C01D0375AD8BCA0E5C84A041D0BF80230D3AC15E09C2629326E59F70FAD8606BDFB3901284844D4C00155C48301F4E91384454852D47D2D0D992123E42130E6F1F45E429A4C52AFF03522B5C68307B4B1082E7868D8241D143A156C2E40F45A5E34C3D2397A91FF195C49DBABB490900238B6F5801B876EE1EC64D8E20F95C1F409F82D70C7C24DB5EEBACD6D56F0486E49DB009B859F2E757679D5499295783E1080C1369B373C481EA3295C9B8D46F8D10F29C50774959490DBD068D1A81BC118606BF8E58050B7F0D88929678D6A47FDAFE506D91FE5F61D4B2EC286CCF1AD616A875819C1BEE6536D24DAEB7DBAC87C2A7A771EA407E7607
-20200227052656 2 6 100 3071 2 DCBD1F34999D3EC980A7AEBD1943B18AFB4904E85DB641E8660A4AE3671C152EBB36BED44E5DA6D647F6232C29EE3FF3C20DFDB18D72B705E57F9B23636AF36E395D68651A0D223C816BF904E29134F49667D205B5EB03F613C24B65E386CB8EEE384AF41BDCF4373C885780C3AC2131584DF97F62A50C7E9169A52DC71B8D9F80FBFBEEC935C01D0375AD8BCA0E5C84A041D0BF80230D3AC15E09C2629326E59F70FAD8606BDFB3901284844D4C00155C48301F4E91384454852D47D2D0D992123E42130E6F1F45E429A4C52AFF03522B5C68307B4B1082E7868D8241D143A156C2E40F45A5E34C3D2397A91FF195C49DBABB490900238B6F5801B876EE1EC64D8E20F95C1F409F82D70C7C24DB5EEBACD6D56F0486E49DB009B859F2E757679D5499295783E1080C1369B373C481EA3295C9B8D46F8D10F29C50774959490DBD068D1A81BC118606BF8E58050B7F0D88929678D6A47FDAFE506D91FE5F61D4B2EC286CCF1AD616A875819C1BEE6536D24DAEB7DBAC87C2A7A771EA40963EDB
-20200227053254 2 6 100 3071 2 DCBD1F34999D3EC980A7AEBD1943B18AFB4904E85DB641E8660A4AE3671C152EBB36BED44E5DA6D647F6232C29EE3FF3C20DFDB18D72B705E57F9B23636AF36E395D68651A0D223C816BF904E29134F49667D205B5EB03F613C24B65E386CB8EEE384AF41BDCF4373C885780C3AC2131584DF97F62A50C7E9169A52DC71B8D9F80FBFBEEC935C01D0375AD8BCA0E5C84A041D0BF80230D3AC15E09C2629326E59F70FAD8606BDFB3901284844D4C00155C48301F4E91384454852D47D2D0D992123E42130E6F1F45E429A4C52AFF03522B5C68307B4B1082E7868D8241D143A156C2E40F45A5E34C3D2397A91FF195C49DBABB490900238B6F5801B876EE1EC64D8E20F95C1F409F82D70C7C24DB5EEBACD6D56F0486E49DB009B859F2E757679D5499295783E1080C1369B373C481EA3295C9B8D46F8D10F29C50774959490DBD068D1A81BC118606BF8E58050B7F0D88929678D6A47FDAFE506D91FE5F61D4B2EC286CCF1AD616A875819C1BEE6536D24DAEB7DBAC87C2A7A771EA415E3B2B
-20200227053802 2 6 100 3071 2 DCBD1F34999D3EC980A7AEBD1943B18AFB4904E85DB641E8660A4AE3671C152EBB36BED44E5DA6D647F6232C29EE3FF3C20DFDB18D72B705E57F9B23636AF36E395D68651A0D223C816BF904E29134F49667D205B5EB03F613C24B65E386CB8EEE384AF41BDCF4373C885780C3AC2131584DF97F62A50C7E9169A52DC71B8D9F80FBFBEEC935C01D0375AD8BCA0E5C84A041D0BF80230D3AC15E09C2629326E59F70FAD8606BDFB3901284844D4C00155C48301F4E91384454852D47D2D0D992123E42130E6F1F45E429A4C52AFF03522B5C68307B4B1082E7868D8241D143A156C2E40F45A5E34C3D2397A91FF195C49DBABB490900238B6F5801B876EE1EC64D8E20F95C1F409F82D70C7C24DB5EEBACD6D56F0486E49DB009B859F2E757679D5499295783E1080C1369B373C481EA3295C9B8D46F8D10F29C50774959490DBD068D1A81BC118606BF8E58050B7F0D88929678D6A47FDAFE506D91FE5F61D4B2EC286CCF1AD616A875819C1BEE6536D24DAEB7DBAC87C2A7A771EA4208CBCB
-20200227054020 2 6 100 3071 2 DCBD1F34999D3EC980A7AEBD1943B18AFB4904E85DB641E8660A4AE3671C152EBB36BED44E5DA6D647F6232C29EE3FF3C20DFDB18D72B705E57F9B23636AF36E395D68651A0D223C816BF904E29134F49667D205B5EB03F613C24B65E386CB8EEE384AF41BDCF4373C885780C3AC2131584DF97F62A50C7E9169A52DC71B8D9F80FBFBEEC935C01D0375AD8BCA0E5C84A041D0BF80230D3AC15E09C2629326E59F70FAD8606BDFB3901284844D4C00155C48301F4E91384454852D47D2D0D992123E42130E6F1F45E429A4C52AFF03522B5C68307B4B1082E7868D8241D143A156C2E40F45A5E34C3D2397A91FF195C49DBABB490900238B6F5801B876EE1EC64D8E20F95C1F409F82D70C7C24DB5EEBACD6D56F0486E49DB009B859F2E757679D5499295783E1080C1369B373C481EA3295C9B8D46F8D10F29C50774959490DBD068D1A81BC118606BF8E58050B7F0D88929678D6A47FDAFE506D91FE5F61D4B2EC286CCF1AD616A875819C1BEE6536D24DAEB7DBAC87C2A7A771EA424BC4CB
-20200227054242 2 6 100 3071 2 DCBD1F34999D3EC980A7AEBD1943B18AFB4904E85DB641E8660A4AE3671C152EBB36BED44E5DA6D647F6232C29EE3FF3C20DFDB18D72B705E57F9B23636AF36E395D68651A0D223C816BF904E29134F49667D205B5EB03F613C24B65E386CB8EEE384AF41BDCF4373C885780C3AC2131584DF97F62A50C7E9169A52DC71B8D9F80FBFBEEC935C01D0375AD8BCA0E5C84A041D0BF80230D3AC15E09C2629326E59F70FAD8606BDFB3901284844D4C00155C48301F4E91384454852D47D2D0D992123E42130E6F1F45E429A4C52AFF03522B5C68307B4B1082E7868D8241D143A156C2E40F45A5E34C3D2397A91FF195C49DBABB490900238B6F5801B876EE1EC64D8E20F95C1F409F82D70C7C24DB5EEBACD6D56F0486E49DB009B859F2E757679D5499295783E1080C1369B373C481EA3295C9B8D46F8D10F29C50774959490DBD068D1A81BC118606BF8E58050B7F0D88929678D6A47FDAFE506D91FE5F61D4B2EC286CCF1AD616A875819C1BEE6536D24DAEB7DBAC87C2A7A771EA42946B7B
-20200227054918 2 6 100 3071 2 EAF378AA0E2C586E9556B81261F829EE5A8F5F5E6E7A2FC92544555E006535C9EDABC5553D5FE43E8DC0886AC3788355B7B7B8FB8EE5220404D022955DBB3C1CFEB9E3163F80DE6DBECA51E2F2AB680799E4227F29894FA0343483021CF475957D82EBAB1F9E270F681A28DF7E37DDA5398B1DE5E0613048B7C52C349BEF4F11A7455D2322589F593160B2AEF33286DE2C267E6C17FC027253BE1CB1254231F8AB2B1232D37E8E4374D00BAF10FB961F88CD80406AC44EBCC29DEB857BE1F400EB532FC49B575379E56593CE3B609D6A19FAF9751A9BB30CFF6C0B2892612BC313F5966741E913B97BF060B8320734BC5030A9A33110E15967D826BAAC7CB3A2E3A0B818FEF3410BF0D5230D1BC7EC86798DBCA14544AC5D956CB0B08888EACCD57D1E50C48D6511E9FF562F177E03ED08219169FDD999FA75595D67081EEC8192AF3855CADEA45B0122F042D03E0599834190F5C5A5E0B2C414A65AB21B91D32DBFDF02C247D6F085C6AC55114A62D1EC6BA06964FE5283226B37E46617A143
-20200227055927 2 6 100 3071 2 EAF378AA0E2C586E9556B81261F829EE5A8F5F5E6E7A2FC92544555E006535C9EDABC5553D5FE43E8DC0886AC3788355B7B7B8FB8EE5220404D022955DBB3C1CFEB9E3163F80DE6DBECA51E2F2AB680799E4227F29894FA0343483021CF475957D82EBAB1F9E270F681A28DF7E37DDA5398B1DE5E0613048B7C52C349BEF4F11A7455D2322589F593160B2AEF33286DE2C267E6C17FC027253BE1CB1254231F8AB2B1232D37E8E4374D00BAF10FB961F88CD80406AC44EBCC29DEB857BE1F400EB532FC49B575379E56593CE3B609D6A19FAF9751A9BB30CFF6C0B2892612BC313F5966741E913B97BF060B8320734BC5030A9A33110E15967D826BAAC7CB3A2E3A0B818FEF3410BF0D5230D1BC7EC86798DBCA14544AC5D956CB0B08888EACCD57D1E50C48D6511E9FF562F177E03ED08219169FDD999FA75595D67081EEC8192AF3855CADEA45B0122F042D03E0599834190F5C5A5E0B2C414A65AB21B91D32DBFDF02C247D6F085C6AC55114A62D1EC6BA06964FE5283226B37E46766DBEB
-20200227060242 2 6 100 3071 2 EAF378AA0E2C586E9556B81261F829EE5A8F5F5E6E7A2FC92544555E006535C9EDABC5553D5FE43E8DC0886AC3788355B7B7B8FB8EE5220404D022955DBB3C1CFEB9E3163F80DE6DBECA51E2F2AB680799E4227F29894FA0343483021CF475957D82EBAB1F9E270F681A28DF7E37DDA5398B1DE5E0613048B7C52C349BEF4F11A7455D2322589F593160B2AEF33286DE2C267E6C17FC027253BE1CB1254231F8AB2B1232D37E8E4374D00BAF10FB961F88CD80406AC44EBCC29DEB857BE1F400EB532FC49B575379E56593CE3B609D6A19FAF9751A9BB30CFF6C0B2892612BC313F5966741E913B97BF060B8320734BC5030A9A33110E15967D826BAAC7CB3A2E3A0B818FEF3410BF0D5230D1BC7EC86798DBCA14544AC5D956CB0B08888EACCD57D1E50C48D6511E9FF562F177E03ED08219169FDD999FA75595D67081EEC8192AF3855CADEA45B0122F042D03E0599834190F5C5A5E0B2C414A65AB21B91D32DBFDF02C247D6F085C6AC55114A62D1EC6BA06964FE5283226B37E467D1E903
-20200227060411 2 6 100 3071 5 EAF378AA0E2C586E9556B81261F829EE5A8F5F5E6E7A2FC92544555E006535C9EDABC5553D5FE43E8DC0886AC3788355B7B7B8FB8EE5220404D022955DBB3C1CFEB9E3163F80DE6DBECA51E2F2AB680799E4227F29894FA0343483021CF475957D82EBAB1F9E270F681A28DF7E37DDA5398B1DE5E0613048B7C52C349BEF4F11A7455D2322589F593160B2AEF33286DE2C267E6C17FC027253BE1CB1254231F8AB2B1232D37E8E4374D00BAF10FB961F88CD80406AC44EBCC29DEB857BE1F400EB532FC49B575379E56593CE3B609D6A19FAF9751A9BB30CFF6C0B2892612BC313F5966741E913B97BF060B8320734BC5030A9A33110E15967D826BAAC7CB3A2E3A0B818FEF3410BF0D5230D1BC7EC86798DBCA14544AC5D956CB0B08888EACCD57D1E50C48D6511E9FF562F177E03ED08219169FDD999FA75595D67081EEC8192AF3855CADEA45B0122F042D03E0599834190F5C5A5E0B2C414A65AB21B91D32DBFDF02C247D6F085C6AC55114A62D1EC6BA06964FE5283226B37E467F9B8CF
-20200227060700 2 6 100 3071 2 EAF378AA0E2C586E9556B81261F829EE5A8F5F5E6E7A2FC92544555E006535C9EDABC5553D5FE43E8DC0886AC3788355B7B7B8FB8EE5220404D022955DBB3C1CFEB9E3163F80DE6DBECA51E2F2AB680799E4227F29894FA0343483021CF475957D82EBAB1F9E270F681A28DF7E37DDA5398B1DE5E0613048B7C52C349BEF4F11A7455D2322589F593160B2AEF33286DE2C267E6C17FC027253BE1CB1254231F8AB2B1232D37E8E4374D00BAF10FB961F88CD80406AC44EBCC29DEB857BE1F400EB532FC49B575379E56593CE3B609D6A19FAF9751A9BB30CFF6C0B2892612BC313F5966741E913B97BF060B8320734BC5030A9A33110E15967D826BAAC7CB3A2E3A0B818FEF3410BF0D5230D1BC7EC86798DBCA14544AC5D956CB0B08888EACCD57D1E50C48D6511E9FF562F177E03ED08219169FDD999FA75595D67081EEC8192AF3855CADEA45B0122F042D03E0599834190F5C5A5E0B2C414A65AB21B91D32DBFDF02C247D6F085C6AC55114A62D1EC6BA06964FE5283226B37E468561F7B
-20200227060843 2 6 100 3071 5 EAF378AA0E2C586E9556B81261F829EE5A8F5F5E6E7A2FC92544555E006535C9EDABC5553D5FE43E8DC0886AC3788355B7B7B8FB8EE5220404D022955DBB3C1CFEB9E3163F80DE6DBECA51E2F2AB680799E4227F29894FA0343483021CF475957D82EBAB1F9E270F681A28DF7E37DDA5398B1DE5E0613048B7C52C349BEF4F11A7455D2322589F593160B2AEF33286DE2C267E6C17FC027253BE1CB1254231F8AB2B1232D37E8E4374D00BAF10FB961F88CD80406AC44EBCC29DEB857BE1F400EB532FC49B575379E56593CE3B609D6A19FAF9751A9BB30CFF6C0B2892612BC313F5966741E913B97BF060B8320734BC5030A9A33110E15967D826BAAC7CB3A2E3A0B818FEF3410BF0D5230D1BC7EC86798DBCA14544AC5D956CB0B08888EACCD57D1E50C48D6511E9FF562F177E03ED08219169FDD999FA75595D67081EEC8192AF3855CADEA45B0122F042D03E0599834190F5C5A5E0B2C414A65AB21B91D32DBFDF02C247D6F085C6AC55114A62D1EC6BA06964FE5283226B37E46889B29F
-20200227061342 2 6 100 3071 5 EAF378AA0E2C586E9556B81261F829EE5A8F5F5E6E7A2FC92544555E006535C9EDABC5553D5FE43E8DC0886AC3788355B7B7B8FB8EE5220404D022955DBB3C1CFEB9E3163F80DE6DBECA51E2F2AB680799E4227F29894FA0343483021CF475957D82EBAB1F9E270F681A28DF7E37DDA5398B1DE5E0613048B7C52C349BEF4F11A7455D2322589F593160B2AEF33286DE2C267E6C17FC027253BE1CB1254231F8AB2B1232D37E8E4374D00BAF10FB961F88CD80406AC44EBCC29DEB857BE1F400EB532FC49B575379E56593CE3B609D6A19FAF9751A9BB30CFF6C0B2892612BC313F5966741E913B97BF060B8320734BC5030A9A33110E15967D826BAAC7CB3A2E3A0B818FEF3410BF0D5230D1BC7EC86798DBCA14544AC5D956CB0B08888EACCD57D1E50C48D6511E9FF562F177E03ED08219169FDD999FA75595D67081EEC8192AF3855CADEA45B0122F042D03E0599834190F5C5A5E0B2C414A65AB21B91D32DBFDF02C247D6F085C6AC55114A62D1EC6BA06964FE5283226B37E469324A4F
-20200227061525 2 6 100 3071 2 EAF378AA0E2C586E9556B81261F829EE5A8F5F5E6E7A2FC92544555E006535C9EDABC5553D5FE43E8DC0886AC3788355B7B7B8FB8EE5220404D022955DBB3C1CFEB9E3163F80DE6DBECA51E2F2AB680799E4227F29894FA0343483021CF475957D82EBAB1F9E270F681A28DF7E37DDA5398B1DE5E0613048B7C52C349BEF4F11A7455D2322589F593160B2AEF33286DE2C267E6C17FC027253BE1CB1254231F8AB2B1232D37E8E4374D00BAF10FB961F88CD80406AC44EBCC29DEB857BE1F400EB532FC49B575379E56593CE3B609D6A19FAF9751A9BB30CFF6C0B2892612BC313F5966741E913B97BF060B8320734BC5030A9A33110E15967D826BAAC7CB3A2E3A0B818FEF3410BF0D5230D1BC7EC86798DBCA14544AC5D956CB0B08888EACCD57D1E50C48D6511E9FF562F177E03ED08219169FDD999FA75595D67081EEC8192AF3855CADEA45B0122F042D03E0599834190F5C5A5E0B2C414A65AB21B91D32DBFDF02C247D6F085C6AC55114A62D1EC6BA06964FE5283226B37E46967398B
-20200227061630 2 6 100 3071 2 EAF378AA0E2C586E9556B81261F829EE5A8F5F5E6E7A2FC92544555E006535C9EDABC5553D5FE43E8DC0886AC3788355B7B7B8FB8EE5220404D022955DBB3C1CFEB9E3163F80DE6DBECA51E2F2AB680799E4227F29894FA0343483021CF475957D82EBAB1F9E270F681A28DF7E37DDA5398B1DE5E0613048B7C52C349BEF4F11A7455D2322589F593160B2AEF33286DE2C267E6C17FC027253BE1CB1254231F8AB2B1232D37E8E4374D00BAF10FB961F88CD80406AC44EBCC29DEB857BE1F400EB532FC49B575379E56593CE3B609D6A19FAF9751A9BB30CFF6C0B2892612BC313F5966741E913B97BF060B8320734BC5030A9A33110E15967D826BAAC7CB3A2E3A0B818FEF3410BF0D5230D1BC7EC86798DBCA14544AC5D956CB0B08888EACCD57D1E50C48D6511E9FF562F177E03ED08219169FDD999FA75595D67081EEC8192AF3855CADEA45B0122F042D03E0599834190F5C5A5E0B2C414A65AB21B91D32DBFDF02C247D6F085C6AC55114A62D1EC6BA06964FE5283226B37E469871133
-20200227061736 2 6 100 3071 2 EAF378AA0E2C586E9556B81261F829EE5A8F5F5E6E7A2FC92544555E006535C9EDABC5553D5FE43E8DC0886AC3788355B7B7B8FB8EE5220404D022955DBB3C1CFEB9E3163F80DE6DBECA51E2F2AB680799E4227F29894FA0343483021CF475957D82EBAB1F9E270F681A28DF7E37DDA5398B1DE5E0613048B7C52C349BEF4F11A7455D2322589F593160B2AEF33286DE2C267E6C17FC027253BE1CB1254231F8AB2B1232D37E8E4374D00BAF10FB961F88CD80406AC44EBCC29DEB857BE1F400EB532FC49B575379E56593CE3B609D6A19FAF9751A9BB30CFF6C0B2892612BC313F5966741E913B97BF060B8320734BC5030A9A33110E15967D826BAAC7CB3A2E3A0B818FEF3410BF0D5230D1BC7EC86798DBCA14544AC5D956CB0B08888EACCD57D1E50C48D6511E9FF562F177E03ED08219169FDD999FA75595D67081EEC8192AF3855CADEA45B0122F042D03E0599834190F5C5A5E0B2C414A65AB21B91D32DBFDF02C247D6F085C6AC55114A62D1EC6BA06964FE5283226B37E469A5C023
-20200227061919 2 6 100 3071 2 EAF378AA0E2C586E9556B81261F829EE5A8F5F5E6E7A2FC92544555E006535C9EDABC5553D5FE43E8DC0886AC3788355B7B7B8FB8EE5220404D022955DBB3C1CFEB9E3163F80DE6DBECA51E2F2AB680799E4227F29894FA0343483021CF475957D82EBAB1F9E270F681A28DF7E37DDA5398B1DE5E0613048B7C52C349BEF4F11A7455D2322589F593160B2AEF33286DE2C267E6C17FC027253BE1CB1254231F8AB2B1232D37E8E4374D00BAF10FB961F88CD80406AC44EBCC29DEB857BE1F400EB532FC49B575379E56593CE3B609D6A19FAF9751A9BB30CFF6C0B2892612BC313F5966741E913B97BF060B8320734BC5030A9A33110E15967D826BAAC7CB3A2E3A0B818FEF3410BF0D5230D1BC7EC86798DBCA14544AC5D956CB0B08888EACCD57D1E50C48D6511E9FF562F177E03ED08219169FDD999FA75595D67081EEC8192AF3855CADEA45B0122F042D03E0599834190F5C5A5E0B2C414A65AB21B91D32DBFDF02C247D6F085C6AC55114A62D1EC6BA06964FE5283226B37E469DFD25B
-20200227062156 2 6 100 3071 2 EAF378AA0E2C586E9556B81261F829EE5A8F5F5E6E7A2FC92544555E006535C9EDABC5553D5FE43E8DC0886AC3788355B7B7B8FB8EE5220404D022955DBB3C1CFEB9E3163F80DE6DBECA51E2F2AB680799E4227F29894FA0343483021CF475957D82EBAB1F9E270F681A28DF7E37DDA5398B1DE5E0613048B7C52C349BEF4F11A7455D2322589F593160B2AEF33286DE2C267E6C17FC027253BE1CB1254231F8AB2B1232D37E8E4374D00BAF10FB961F88CD80406AC44EBCC29DEB857BE1F400EB532FC49B575379E56593CE3B609D6A19FAF9751A9BB30CFF6C0B2892612BC313F5966741E913B97BF060B8320734BC5030A9A33110E15967D826BAAC7CB3A2E3A0B818FEF3410BF0D5230D1BC7EC86798DBCA14544AC5D956CB0B08888EACCD57D1E50C48D6511E9FF562F177E03ED08219169FDD999FA75595D67081EEC8192AF3855CADEA45B0122F042D03E0599834190F5C5A5E0B2C414A65AB21B91D32DBFDF02C247D6F085C6AC55114A62D1EC6BA06964FE5283226B37E46A4225DB
-20200227062610 2 6 100 3071 5 EAF378AA0E2C586E9556B81261F829EE5A8F5F5E6E7A2FC92544555E006535C9EDABC5553D5FE43E8DC0886AC3788355B7B7B8FB8EE5220404D022955DBB3C1CFEB9E3163F80DE6DBECA51E2F2AB680799E4227F29894FA0343483021CF475957D82EBAB1F9E270F681A28DF7E37DDA5398B1DE5E0613048B7C52C349BEF4F11A7455D2322589F593160B2AEF33286DE2C267E6C17FC027253BE1CB1254231F8AB2B1232D37E8E4374D00BAF10FB961F88CD80406AC44EBCC29DEB857BE1F400EB532FC49B575379E56593CE3B609D6A19FAF9751A9BB30CFF6C0B2892612BC313F5966741E913B97BF060B8320734BC5030A9A33110E15967D826BAAC7CB3A2E3A0B818FEF3410BF0D5230D1BC7EC86798DBCA14544AC5D956CB0B08888EACCD57D1E50C48D6511E9FF562F177E03ED08219169FDD999FA75595D67081EEC8192AF3855CADEA45B0122F042D03E0599834190F5C5A5E0B2C414A65AB21B91D32DBFDF02C247D6F085C6AC55114A62D1EC6BA06964FE5283226B37E46AE7835F
-20200227062733 2 6 100 3071 2 EAF378AA0E2C586E9556B81261F829EE5A8F5F5E6E7A2FC92544555E006535C9EDABC5553D5FE43E8DC0886AC3788355B7B7B8FB8EE5220404D022955DBB3C1CFEB9E3163F80DE6DBECA51E2F2AB680799E4227F29894FA0343483021CF475957D82EBAB1F9E270F681A28DF7E37DDA5398B1DE5E0613048B7C52C349BEF4F11A7455D2322589F593160B2AEF33286DE2C267E6C17FC027253BE1CB1254231F8AB2B1232D37E8E4374D00BAF10FB961F88CD80406AC44EBCC29DEB857BE1F400EB532FC49B575379E56593CE3B609D6A19FAF9751A9BB30CFF6C0B2892612BC313F5966741E913B97BF060B8320734BC5030A9A33110E15967D826BAAC7CB3A2E3A0B818FEF3410BF0D5230D1BC7EC86798DBCA14544AC5D956CB0B08888EACCD57D1E50C48D6511E9FF562F177E03ED08219169FDD999FA75595D67081EEC8192AF3855CADEA45B0122F042D03E0599834190F5C5A5E0B2C414A65AB21B91D32DBFDF02C247D6F085C6AC55114A62D1EC6BA06964FE5283226B37E46B158F5B
-20200227063025 2 6 100 3071 2 EAF378AA0E2C586E9556B81261F829EE5A8F5F5E6E7A2FC92544555E006535C9EDABC5553D5FE43E8DC0886AC3788355B7B7B8FB8EE5220404D022955DBB3C1CFEB9E3163F80DE6DBECA51E2F2AB680799E4227F29894FA0343483021CF475957D82EBAB1F9E270F681A28DF7E37DDA5398B1DE5E0613048B7C52C349BEF4F11A7455D2322589F593160B2AEF33286DE2C267E6C17FC027253BE1CB1254231F8AB2B1232D37E8E4374D00BAF10FB961F88CD80406AC44EBCC29DEB857BE1F400EB532FC49B575379E56593CE3B609D6A19FAF9751A9BB30CFF6C0B2892612BC313F5966741E913B97BF060B8320734BC5030A9A33110E15967D826BAAC7CB3A2E3A0B818FEF3410BF0D5230D1BC7EC86798DBCA14544AC5D956CB0B08888EACCD57D1E50C48D6511E9FF562F177E03ED08219169FDD999FA75595D67081EEC8192AF3855CADEA45B0122F042D03E0599834190F5C5A5E0B2C414A65AB21B91D32DBFDF02C247D6F085C6AC55114A62D1EC6BA06964FE5283226B37E46B8351EB
-20200227063206 2 6 100 3071 2 EAF378AA0E2C586E9556B81261F829EE5A8F5F5E6E7A2FC92544555E006535C9EDABC5553D5FE43E8DC0886AC3788355B7B7B8FB8EE5220404D022955DBB3C1CFEB9E3163F80DE6DBECA51E2F2AB680799E4227F29894FA0343483021CF475957D82EBAB1F9E270F681A28DF7E37DDA5398B1DE5E0613048B7C52C349BEF4F11A7455D2322589F593160B2AEF33286DE2C267E6C17FC027253BE1CB1254231F8AB2B1232D37E8E4374D00BAF10FB961F88CD80406AC44EBCC29DEB857BE1F400EB532FC49B575379E56593CE3B609D6A19FAF9751A9BB30CFF6C0B2892612BC313F5966741E913B97BF060B8320734BC5030A9A33110E15967D826BAAC7CB3A2E3A0B818FEF3410BF0D5230D1BC7EC86798DBCA14544AC5D956CB0B08888EACCD57D1E50C48D6511E9FF562F177E03ED08219169FDD999FA75595D67081EEC8192AF3855CADEA45B0122F042D03E0599834190F5C5A5E0B2C414A65AB21B91D32DBFDF02C247D6F085C6AC55114A62D1EC6BA06964FE5283226B37E46BBA58CB
-20200227063226 2 6 100 3071 2 EAF378AA0E2C586E9556B81261F829EE5A8F5F5E6E7A2FC92544555E006535C9EDABC5553D5FE43E8DC0886AC3788355B7B7B8FB8EE5220404D022955DBB3C1CFEB9E3163F80DE6DBECA51E2F2AB680799E4227F29894FA0343483021CF475957D82EBAB1F9E270F681A28DF7E37DDA5398B1DE5E0613048B7C52C349BEF4F11A7455D2322589F593160B2AEF33286DE2C267E6C17FC027253BE1CB1254231F8AB2B1232D37E8E4374D00BAF10FB961F88CD80406AC44EBCC29DEB857BE1F400EB532FC49B575379E56593CE3B609D6A19FAF9751A9BB30CFF6C0B2892612BC313F5966741E913B97BF060B8320734BC5030A9A33110E15967D826BAAC7CB3A2E3A0B818FEF3410BF0D5230D1BC7EC86798DBCA14544AC5D956CB0B08888EACCD57D1E50C48D6511E9FF562F177E03ED08219169FDD999FA75595D67081EEC8192AF3855CADEA45B0122F042D03E0599834190F5C5A5E0B2C414A65AB21B91D32DBFDF02C247D6F085C6AC55114A62D1EC6BA06964FE5283226B37E46BBEE61B
-20200227063414 2 6 100 3071 2 EAF378AA0E2C586E9556B81261F829EE5A8F5F5E6E7A2FC92544555E006535C9EDABC5553D5FE43E8DC0886AC3788355B7B7B8FB8EE5220404D022955DBB3C1CFEB9E3163F80DE6DBECA51E2F2AB680799E4227F29894FA0343483021CF475957D82EBAB1F9E270F681A28DF7E37DDA5398B1DE5E0613048B7C52C349BEF4F11A7455D2322589F593160B2AEF33286DE2C267E6C17FC027253BE1CB1254231F8AB2B1232D37E8E4374D00BAF10FB961F88CD80406AC44EBCC29DEB857BE1F400EB532FC49B575379E56593CE3B609D6A19FAF9751A9BB30CFF6C0B2892612BC313F5966741E913B97BF060B8320734BC5030A9A33110E15967D826BAAC7CB3A2E3A0B818FEF3410BF0D5230D1BC7EC86798DBCA14544AC5D956CB0B08888EACCD57D1E50C48D6511E9FF562F177E03ED08219169FDD999FA75595D67081EEC8192AF3855CADEA45B0122F042D03E0599834190F5C5A5E0B2C414A65AB21B91D32DBFDF02C247D6F085C6AC55114A62D1EC6BA06964FE5283226B37E46BFF08A3
-20200227063436 2 6 100 3071 2 EAF378AA0E2C586E9556B81261F829EE5A8F5F5E6E7A2FC92544555E006535C9EDABC5553D5FE43E8DC0886AC3788355B7B7B8FB8EE5220404D022955DBB3C1CFEB9E3163F80DE6DBECA51E2F2AB680799E4227F29894FA0343483021CF475957D82EBAB1F9E270F681A28DF7E37DDA5398B1DE5E0613048B7C52C349BEF4F11A7455D2322589F593160B2AEF33286DE2C267E6C17FC027253BE1CB1254231F8AB2B1232D37E8E4374D00BAF10FB961F88CD80406AC44EBCC29DEB857BE1F400EB532FC49B575379E56593CE3B609D6A19FAF9751A9BB30CFF6C0B2892612BC313F5966741E913B97BF060B8320734BC5030A9A33110E15967D826BAAC7CB3A2E3A0B818FEF3410BF0D5230D1BC7EC86798DBCA14544AC5D956CB0B08888EACCD57D1E50C48D6511E9FF562F177E03ED08219169FDD999FA75595D67081EEC8192AF3855CADEA45B0122F042D03E0599834190F5C5A5E0B2C414A65AB21B91D32DBFDF02C247D6F085C6AC55114A62D1EC6BA06964FE5283226B37E46C048EDB
-20200227063458 2 6 100 3071 2 EAF378AA0E2C586E9556B81261F829EE5A8F5F5E6E7A2FC92544555E006535C9EDABC5553D5FE43E8DC0886AC3788355B7B7B8FB8EE5220404D022955DBB3C1CFEB9E3163F80DE6DBECA51E2F2AB680799E4227F29894FA0343483021CF475957D82EBAB1F9E270F681A28DF7E37DDA5398B1DE5E0613048B7C52C349BEF4F11A7455D2322589F593160B2AEF33286DE2C267E6C17FC027253BE1CB1254231F8AB2B1232D37E8E4374D00BAF10FB961F88CD80406AC44EBCC29DEB857BE1F400EB532FC49B575379E56593CE3B609D6A19FAF9751A9BB30CFF6C0B2892612BC313F5966741E913B97BF060B8320734BC5030A9A33110E15967D826BAAC7CB3A2E3A0B818FEF3410BF0D5230D1BC7EC86798DBCA14544AC5D956CB0B08888EACCD57D1E50C48D6511E9FF562F177E03ED08219169FDD999FA75595D67081EEC8192AF3855CADEA45B0122F042D03E0599834190F5C5A5E0B2C414A65AB21B91D32DBFDF02C247D6F085C6AC55114A62D1EC6BA06964FE5283226B37E46C0B9BA3
-20200227064340 2 6 100 3071 5 EAF378AA0E2C586E9556B81261F829EE5A8F5F5E6E7A2FC92544555E006535C9EDABC5553D5FE43E8DC0886AC3788355B7B7B8FB8EE5220404D022955DBB3C1CFEB9E3163F80DE6DBECA51E2F2AB680799E4227F29894FA0343483021CF475957D82EBAB1F9E270F681A28DF7E37DDA5398B1DE5E0613048B7C52C349BEF4F11A7455D2322589F593160B2AEF33286DE2C267E6C17FC027253BE1CB1254231F8AB2B1232D37E8E4374D00BAF10FB961F88CD80406AC44EBCC29DEB857BE1F400EB532FC49B575379E56593CE3B609D6A19FAF9751A9BB30CFF6C0B2892612BC313F5966741E913B97BF060B8320734BC5030A9A33110E15967D826BAAC7CB3A2E3A0B818FEF3410BF0D5230D1BC7EC86798DBCA14544AC5D956CB0B08888EACCD57D1E50C48D6511E9FF562F177E03ED08219169FDD999FA75595D67081EEC8192AF3855CADEA45B0122F042D03E0599834190F5C5A5E0B2C414A65AB21B91D32DBFDF02C247D6F085C6AC55114A62D1EC6BA06964FE5283226B37E46D585367
-20200227064522 2 6 100 3071 2 EAF378AA0E2C586E9556B81261F829EE5A8F5F5E6E7A2FC92544555E006535C9EDABC5553D5FE43E8DC0886AC3788355B7B7B8FB8EE5220404D022955DBB3C1CFEB9E3163F80DE6DBECA51E2F2AB680799E4227F29894FA0343483021CF475957D82EBAB1F9E270F681A28DF7E37DDA5398B1DE5E0613048B7C52C349BEF4F11A7455D2322589F593160B2AEF33286DE2C267E6C17FC027253BE1CB1254231F8AB2B1232D37E8E4374D00BAF10FB961F88CD80406AC44EBCC29DEB857BE1F400EB532FC49B575379E56593CE3B609D6A19FAF9751A9BB30CFF6C0B2892612BC313F5966741E913B97BF060B8320734BC5030A9A33110E15967D826BAAC7CB3A2E3A0B818FEF3410BF0D5230D1BC7EC86798DBCA14544AC5D956CB0B08888EACCD57D1E50C48D6511E9FF562F177E03ED08219169FDD999FA75595D67081EEC8192AF3855CADEA45B0122F042D03E0599834190F5C5A5E0B2C414A65AB21B91D32DBFDF02C247D6F085C6AC55114A62D1EC6BA06964FE5283226B37E46D8D449B
-20200227064747 2 6 100 3071 2 EAF378AA0E2C586E9556B81261F829EE5A8F5F5E6E7A2FC92544555E006535C9EDABC5553D5FE43E8DC0886AC3788355B7B7B8FB8EE5220404D022955DBB3C1CFEB9E3163F80DE6DBECA51E2F2AB680799E4227F29894FA0343483021CF475957D82EBAB1F9E270F681A28DF7E37DDA5398B1DE5E0613048B7C52C349BEF4F11A7455D2322589F593160B2AEF33286DE2C267E6C17FC027253BE1CB1254231F8AB2B1232D37E8E4374D00BAF10FB961F88CD80406AC44EBCC29DEB857BE1F400EB532FC49B575379E56593CE3B609D6A19FAF9751A9BB30CFF6C0B2892612BC313F5966741E913B97BF060B8320734BC5030A9A33110E15967D826BAAC7CB3A2E3A0B818FEF3410BF0D5230D1BC7EC86798DBCA14544AC5D956CB0B08888EACCD57D1E50C48D6511E9FF562F177E03ED08219169FDD999FA75595D67081EEC8192AF3855CADEA45B0122F042D03E0599834190F5C5A5E0B2C414A65AB21B91D32DBFDF02C247D6F085C6AC55114A62D1EC6BA06964FE5283226B37E46DD850B3
-20200227064951 2 6 100 3071 5 EAF378AA0E2C586E9556B81261F829EE5A8F5F5E6E7A2FC92544555E006535C9EDABC5553D5FE43E8DC0886AC3788355B7B7B8FB8EE5220404D022955DBB3C1CFEB9E3163F80DE6DBECA51E2F2AB680799E4227F29894FA0343483021CF475957D82EBAB1F9E270F681A28DF7E37DDA5398B1DE5E0613048B7C52C349BEF4F11A7455D2322589F593160B2AEF33286DE2C267E6C17FC027253BE1CB1254231F8AB2B1232D37E8E4374D00BAF10FB961F88CD80406AC44EBCC29DEB857BE1F400EB532FC49B575379E56593CE3B609D6A19FAF9751A9BB30CFF6C0B2892612BC313F5966741E913B97BF060B8320734BC5030A9A33110E15967D826BAAC7CB3A2E3A0B818FEF3410BF0D5230D1BC7EC86798DBCA14544AC5D956CB0B08888EACCD57D1E50C48D6511E9FF562F177E03ED08219169FDD999FA75595D67081EEC8192AF3855CADEA45B0122F042D03E0599834190F5C5A5E0B2C414A65AB21B91D32DBFDF02C247D6F085C6AC55114A62D1EC6BA06964FE5283226B37E46E17A897
-20200227065115 2 6 100 3071 5 EAF378AA0E2C586E9556B81261F829EE5A8F5F5E6E7A2FC92544555E006535C9EDABC5553D5FE43E8DC0886AC3788355B7B7B8FB8EE5220404D022955DBB3C1CFEB9E3163F80DE6DBECA51E2F2AB680799E4227F29894FA0343483021CF475957D82EBAB1F9E270F681A28DF7E37DDA5398B1DE5E0613048B7C52C349BEF4F11A7455D2322589F593160B2AEF33286DE2C267E6C17FC027253BE1CB1254231F8AB2B1232D37E8E4374D00BAF10FB961F88CD80406AC44EBCC29DEB857BE1F400EB532FC49B575379E56593CE3B609D6A19FAF9751A9BB30CFF6C0B2892612BC313F5966741E913B97BF060B8320734BC5030A9A33110E15967D826BAAC7CB3A2E3A0B818FEF3410BF0D5230D1BC7EC86798DBCA14544AC5D956CB0B08888EACCD57D1E50C48D6511E9FF562F177E03ED08219169FDD999FA75595D67081EEC8192AF3855CADEA45B0122F042D03E0599834190F5C5A5E0B2C414A65AB21B91D32DBFDF02C247D6F085C6AC55114A62D1EC6BA06964FE5283226B37E46E41058F
-20200227070122 2 6 100 3071 5 EAF378AA0E2C586E9556B81261F829EE5A8F5F5E6E7A2FC92544555E006535C9EDABC5553D5FE43E8DC0886AC3788355B7B7B8FB8EE5220404D022955DBB3C1CFEB9E3163F80DE6DBECA51E2F2AB680799E4227F29894FA0343483021CF475957D82EBAB1F9E270F681A28DF7E37DDA5398B1DE5E0613048B7C52C349BEF4F11A7455D2322589F593160B2AEF33286DE2C267E6C17FC027253BE1CB1254231F8AB2B1232D37E8E4374D00BAF10FB961F88CD80406AC44EBCC29DEB857BE1F400EB532FC49B575379E56593CE3B609D6A19FAF9751A9BB30CFF6C0B2892612BC313F5966741E913B97BF060B8320734BC5030A9A33110E15967D826BAAC7CB3A2E3A0B818FEF3410BF0D5230D1BC7EC86798DBCA14544AC5D956CB0B08888EACCD57D1E50C48D6511E9FF562F177E03ED08219169FDD999FA75595D67081EEC8192AF3855CADEA45B0122F042D03E0599834190F5C5A5E0B2C414A65AB21B91D32DBFDF02C247D6F085C6AC55114A62D1EC6BA06964FE5283226B37E46F9C7E5F
-20200227070147 2 6 100 3071 5 EAF378AA0E2C586E9556B81261F829EE5A8F5F5E6E7A2FC92544555E006535C9EDABC5553D5FE43E8DC0886AC3788355B7B7B8FB8EE5220404D022955DBB3C1CFEB9E3163F80DE6DBECA51E2F2AB680799E4227F29894FA0343483021CF475957D82EBAB1F9E270F681A28DF7E37DDA5398B1DE5E0613048B7C52C349BEF4F11A7455D2322589F593160B2AEF33286DE2C267E6C17FC027253BE1CB1254231F8AB2B1232D37E8E4374D00BAF10FB961F88CD80406AC44EBCC29DEB857BE1F400EB532FC49B575379E56593CE3B609D6A19FAF9751A9BB30CFF6C0B2892612BC313F5966741E913B97BF060B8320734BC5030A9A33110E15967D826BAAC7CB3A2E3A0B818FEF3410BF0D5230D1BC7EC86798DBCA14544AC5D956CB0B08888EACCD57D1E50C48D6511E9FF562F177E03ED08219169FDD999FA75595D67081EEC8192AF3855CADEA45B0122F042D03E0599834190F5C5A5E0B2C414A65AB21B91D32DBFDF02C247D6F085C6AC55114A62D1EC6BA06964FE5283226B37E46FA4963F
-20200227070247 2 6 100 3071 5 EAF378AA0E2C586E9556B81261F829EE5A8F5F5E6E7A2FC92544555E006535C9EDABC5553D5FE43E8DC0886AC3788355B7B7B8FB8EE5220404D022955DBB3C1CFEB9E3163F80DE6DBECA51E2F2AB680799E4227F29894FA0343483021CF475957D82EBAB1F9E270F681A28DF7E37DDA5398B1DE5E0613048B7C52C349BEF4F11A7455D2322589F593160B2AEF33286DE2C267E6C17FC027253BE1CB1254231F8AB2B1232D37E8E4374D00BAF10FB961F88CD80406AC44EBCC29DEB857BE1F400EB532FC49B575379E56593CE3B609D6A19FAF9751A9BB30CFF6C0B2892612BC313F5966741E913B97BF060B8320734BC5030A9A33110E15967D826BAAC7CB3A2E3A0B818FEF3410BF0D5230D1BC7EC86798DBCA14544AC5D956CB0B08888EACCD57D1E50C48D6511E9FF562F177E03ED08219169FDD999FA75595D67081EEC8192AF3855CADEA45B0122F042D03E0599834190F5C5A5E0B2C414A65AB21B91D32DBFDF02C247D6F085C6AC55114A62D1EC6BA06964FE5283226B37E46FC0F617
-20200227070844 2 6 100 3071 2 EAF378AA0E2C586E9556B81261F829EE5A8F5F5E6E7A2FC92544555E006535C9EDABC5553D5FE43E8DC0886AC3788355B7B7B8FB8EE5220404D022955DBB3C1CFEB9E3163F80DE6DBECA51E2F2AB680799E4227F29894FA0343483021CF475957D82EBAB1F9E270F681A28DF7E37DDA5398B1DE5E0613048B7C52C349BEF4F11A7455D2322589F593160B2AEF33286DE2C267E6C17FC027253BE1CB1254231F8AB2B1232D37E8E4374D00BAF10FB961F88CD80406AC44EBCC29DEB857BE1F400EB532FC49B575379E56593CE3B609D6A19FAF9751A9BB30CFF6C0B2892612BC313F5966741E913B97BF060B8320734BC5030A9A33110E15967D826BAAC7CB3A2E3A0B818FEF3410BF0D5230D1BC7EC86798DBCA14544AC5D956CB0B08888EACCD57D1E50C48D6511E9FF562F177E03ED08219169FDD999FA75595D67081EEC8192AF3855CADEA45B0122F042D03E0599834190F5C5A5E0B2C414A65AB21B91D32DBFDF02C247D6F085C6AC55114A62D1EC6BA06964FE5283226B37E470861EE3
-20200227071233 2 6 100 3071 2 EAF378AA0E2C586E9556B81261F829EE5A8F5F5E6E7A2FC92544555E006535C9EDABC5553D5FE43E8DC0886AC3788355B7B7B8FB8EE5220404D022955DBB3C1CFEB9E3163F80DE6DBECA51E2F2AB680799E4227F29894FA0343483021CF475957D82EBAB1F9E270F681A28DF7E37DDA5398B1DE5E0613048B7C52C349BEF4F11A7455D2322589F593160B2AEF33286DE2C267E6C17FC027253BE1CB1254231F8AB2B1232D37E8E4374D00BAF10FB961F88CD80406AC44EBCC29DEB857BE1F400EB532FC49B575379E56593CE3B609D6A19FAF9751A9BB30CFF6C0B2892612BC313F5966741E913B97BF060B8320734BC5030A9A33110E15967D826BAAC7CB3A2E3A0B818FEF3410BF0D5230D1BC7EC86798DBCA14544AC5D956CB0B08888EACCD57D1E50C48D6511E9FF562F177E03ED08219169FDD999FA75595D67081EEC8192AF3855CADEA45B0122F042D03E0599834190F5C5A5E0B2C414A65AB21B91D32DBFDF02C247D6F085C6AC55114A62D1EC6BA06964FE5283226B37E471071DF3
-20200227072256 2 6 100 3071 2 EAF378AA0E2C586E9556B81261F829EE5A8F5F5E6E7A2FC92544555E006535C9EDABC5553D5FE43E8DC0886AC3788355B7B7B8FB8EE5220404D022955DBB3C1CFEB9E3163F80DE6DBECA51E2F2AB680799E4227F29894FA0343483021CF475957D82EBAB1F9E270F681A28DF7E37DDA5398B1DE5E0613048B7C52C349BEF4F11A7455D2322589F593160B2AEF33286DE2C267E6C17FC027253BE1CB1254231F8AB2B1232D37E8E4374D00BAF10FB961F88CD80406AC44EBCC29DEB857BE1F400EB532FC49B575379E56593CE3B609D6A19FAF9751A9BB30CFF6C0B2892612BC313F5966741E913B97BF060B8320734BC5030A9A33110E15967D826BAAC7CB3A2E3A0B818FEF3410BF0D5230D1BC7EC86798DBCA14544AC5D956CB0B08888EACCD57D1E50C48D6511E9FF562F177E03ED08219169FDD999FA75595D67081EEC8192AF3855CADEA45B0122F042D03E0599834190F5C5A5E0B2C414A65AB21B91D32DBFDF02C247D6F085C6AC55114A62D1EC6BA06964FE5283226B37E4726F3A13
-20200227072700 2 6 100 3071 2 EAF378AA0E2C586E9556B81261F829EE5A8F5F5E6E7A2FC92544555E006535C9EDABC5553D5FE43E8DC0886AC3788355B7B7B8FB8EE5220404D022955DBB3C1CFEB9E3163F80DE6DBECA51E2F2AB680799E4227F29894FA0343483021CF475957D82EBAB1F9E270F681A28DF7E37DDA5398B1DE5E0613048B7C52C349BEF4F11A7455D2322589F593160B2AEF33286DE2C267E6C17FC027253BE1CB1254231F8AB2B1232D37E8E4374D00BAF10FB961F88CD80406AC44EBCC29DEB857BE1F400EB532FC49B575379E56593CE3B609D6A19FAF9751A9BB30CFF6C0B2892612BC313F5966741E913B97BF060B8320734BC5030A9A33110E15967D826BAAC7CB3A2E3A0B818FEF3410BF0D5230D1BC7EC86798DBCA14544AC5D956CB0B08888EACCD57D1E50C48D6511E9FF562F177E03ED08219169FDD999FA75595D67081EEC8192AF3855CADEA45B0122F042D03E0599834190F5C5A5E0B2C414A65AB21B91D32DBFDF02C247D6F085C6AC55114A62D1EC6BA06964FE5283226B37E472F54A5B
-20200227073459 2 6 100 3071 5 EAF378AA0E2C586E9556B81261F829EE5A8F5F5E6E7A2FC92544555E006535C9EDABC5553D5FE43E8DC0886AC3788355B7B7B8FB8EE5220404D022955DBB3C1CFEB9E3163F80DE6DBECA51E2F2AB680799E4227F29894FA0343483021CF475957D82EBAB1F9E270F681A28DF7E37DDA5398B1DE5E0613048B7C52C349BEF4F11A7455D2322589F593160B2AEF33286DE2C267E6C17FC027253BE1CB1254231F8AB2B1232D37E8E4374D00BAF10FB961F88CD80406AC44EBCC29DEB857BE1F400EB532FC49B575379E56593CE3B609D6A19FAF9751A9BB30CFF6C0B2892612BC313F5966741E913B97BF060B8320734BC5030A9A33110E15967D826BAAC7CB3A2E3A0B818FEF3410BF0D5230D1BC7EC86798DBCA14544AC5D956CB0B08888EACCD57D1E50C48D6511E9FF562F177E03ED08219169FDD999FA75595D67081EEC8192AF3855CADEA45B0122F042D03E0599834190F5C5A5E0B2C414A65AB21B91D32DBFDF02C247D6F085C6AC55114A62D1EC6BA06964FE5283226B37E47401DC37
-20200227073831 2 6 100 3071 5 EAF378AA0E2C586E9556B81261F829EE5A8F5F5E6E7A2FC92544555E006535C9EDABC5553D5FE43E8DC0886AC3788355B7B7B8FB8EE5220404D022955DBB3C1CFEB9E3163F80DE6DBECA51E2F2AB680799E4227F29894FA0343483021CF475957D82EBAB1F9E270F681A28DF7E37DDA5398B1DE5E0613048B7C52C349BEF4F11A7455D2322589F593160B2AEF33286DE2C267E6C17FC027253BE1CB1254231F8AB2B1232D37E8E4374D00BAF10FB961F88CD80406AC44EBCC29DEB857BE1F400EB532FC49B575379E56593CE3B609D6A19FAF9751A9BB30CFF6C0B2892612BC313F5966741E913B97BF060B8320734BC5030A9A33110E15967D826BAAC7CB3A2E3A0B818FEF3410BF0D5230D1BC7EC86798DBCA14544AC5D956CB0B08888EACCD57D1E50C48D6511E9FF562F177E03ED08219169FDD999FA75595D67081EEC8192AF3855CADEA45B0122F042D03E0599834190F5C5A5E0B2C414A65AB21B91D32DBFDF02C247D6F085C6AC55114A62D1EC6BA06964FE5283226B37E474725CAF
-20200227074056 2 6 100 3071 5 EAF378AA0E2C586E9556B81261F829EE5A8F5F5E6E7A2FC92544555E006535C9EDABC5553D5FE43E8DC0886AC3788355B7B7B8FB8EE5220404D022955DBB3C1CFEB9E3163F80DE6DBECA51E2F2AB680799E4227F29894FA0343483021CF475957D82EBAB1F9E270F681A28DF7E37DDA5398B1DE5E0613048B7C52C349BEF4F11A7455D2322589F593160B2AEF33286DE2C267E6C17FC027253BE1CB1254231F8AB2B1232D37E8E4374D00BAF10FB961F88CD80406AC44EBCC29DEB857BE1F400EB532FC49B575379E56593CE3B609D6A19FAF9751A9BB30CFF6C0B2892612BC313F5966741E913B97BF060B8320734BC5030A9A33110E15967D826BAAC7CB3A2E3A0B818FEF3410BF0D5230D1BC7EC86798DBCA14544AC5D956CB0B08888EACCD57D1E50C48D6511E9FF562F177E03ED08219169FDD999FA75595D67081EEC8192AF3855CADEA45B0122F042D03E0599834190F5C5A5E0B2C414A65AB21B91D32DBFDF02C247D6F085C6AC55114A62D1EC6BA06964FE5283226B37E474BE84D7
-20200227074215 2 6 100 3071 5 EAF378AA0E2C586E9556B81261F829EE5A8F5F5E6E7A2FC92544555E006535C9EDABC5553D5FE43E8DC0886AC3788355B7B7B8FB8EE5220404D022955DBB3C1CFEB9E3163F80DE6DBECA51E2F2AB680799E4227F29894FA0343483021CF475957D82EBAB1F9E270F681A28DF7E37DDA5398B1DE5E0613048B7C52C349BEF4F11A7455D2322589F593160B2AEF33286DE2C267E6C17FC027253BE1CB1254231F8AB2B1232D37E8E4374D00BAF10FB961F88CD80406AC44EBCC29DEB857BE1F400EB532FC49B575379E56593CE3B609D6A19FAF9751A9BB30CFF6C0B2892612BC313F5966741E913B97BF060B8320734BC5030A9A33110E15967D826BAAC7CB3A2E3A0B818FEF3410BF0D5230D1BC7EC86798DBCA14544AC5D956CB0B08888EACCD57D1E50C48D6511E9FF562F177E03ED08219169FDD999FA75595D67081EEC8192AF3855CADEA45B0122F042D03E0599834190F5C5A5E0B2C414A65AB21B91D32DBFDF02C247D6F085C6AC55114A62D1EC6BA06964FE5283226B37E474E1A47F
-20200227074642 2 6 100 3071 2 EAF378AA0E2C586E9556B81261F829EE5A8F5F5E6E7A2FC92544555E006535C9EDABC5553D5FE43E8DC0886AC3788355B7B7B8FB8EE5220404D022955DBB3C1CFEB9E3163F80DE6DBECA51E2F2AB680799E4227F29894FA0343483021CF475957D82EBAB1F9E270F681A28DF7E37DDA5398B1DE5E0613048B7C52C349BEF4F11A7455D2322589F593160B2AEF33286DE2C267E6C17FC027253BE1CB1254231F8AB2B1232D37E8E4374D00BAF10FB961F88CD80406AC44EBCC29DEB857BE1F400EB532FC49B575379E56593CE3B609D6A19FAF9751A9BB30CFF6C0B2892612BC313F5966741E913B97BF060B8320734BC5030A9A33110E15967D826BAAC7CB3A2E3A0B818FEF3410BF0D5230D1BC7EC86798DBCA14544AC5D956CB0B08888EACCD57D1E50C48D6511E9FF562F177E03ED08219169FDD999FA75595D67081EEC8192AF3855CADEA45B0122F042D03E0599834190F5C5A5E0B2C414A65AB21B91D32DBFDF02C247D6F085C6AC55114A62D1EC6BA06964FE5283226B37E47575BDFB
-20200227074700 2 6 100 3071 2 EAF378AA0E2C586E9556B81261F829EE5A8F5F5E6E7A2FC92544555E006535C9EDABC5553D5FE43E8DC0886AC3788355B7B7B8FB8EE5220404D022955DBB3C1CFEB9E3163F80DE6DBECA51E2F2AB680799E4227F29894FA0343483021CF475957D82EBAB1F9E270F681A28DF7E37DDA5398B1DE5E0613048B7C52C349BEF4F11A7455D2322589F593160B2AEF33286DE2C267E6C17FC027253BE1CB1254231F8AB2B1232D37E8E4374D00BAF10FB961F88CD80406AC44EBCC29DEB857BE1F400EB532FC49B575379E56593CE3B609D6A19FAF9751A9BB30CFF6C0B2892612BC313F5966741E913B97BF060B8320734BC5030A9A33110E15967D826BAAC7CB3A2E3A0B818FEF3410BF0D5230D1BC7EC86798DBCA14544AC5D956CB0B08888EACCD57D1E50C48D6511E9FF562F177E03ED08219169FDD999FA75595D67081EEC8192AF3855CADEA45B0122F042D03E0599834190F5C5A5E0B2C414A65AB21B91D32DBFDF02C247D6F085C6AC55114A62D1EC6BA06964FE5283226B37E47579CADB
-20200227075116 2 6 100 3071 5 EAF378AA0E2C586E9556B81261F829EE5A8F5F5E6E7A2FC92544555E006535C9EDABC5553D5FE43E8DC0886AC3788355B7B7B8FB8EE5220404D022955DBB3C1CFEB9E3163F80DE6DBECA51E2F2AB680799E4227F29894FA0343483021CF475957D82EBAB1F9E270F681A28DF7E37DDA5398B1DE5E0613048B7C52C349BEF4F11A7455D2322589F593160B2AEF33286DE2C267E6C17FC027253BE1CB1254231F8AB2B1232D37E8E4374D00BAF10FB961F88CD80406AC44EBCC29DEB857BE1F400EB532FC49B575379E56593CE3B609D6A19FAF9751A9BB30CFF6C0B2892612BC313F5966741E913B97BF060B8320734BC5030A9A33110E15967D826BAAC7CB3A2E3A0B818FEF3410BF0D5230D1BC7EC86798DBCA14544AC5D956CB0B08888EACCD57D1E50C48D6511E9FF562F177E03ED08219169FDD999FA75595D67081EEC8192AF3855CADEA45B0122F042D03E0599834190F5C5A5E0B2C414A65AB21B91D32DBFDF02C247D6F085C6AC55114A62D1EC6BA06964FE5283226B37E4760314A7
-20200227075407 2 6 100 3071 2 EAF378AA0E2C586E9556B81261F829EE5A8F5F5E6E7A2FC92544555E006535C9EDABC5553D5FE43E8DC0886AC3788355B7B7B8FB8EE5220404D022955DBB3C1CFEB9E3163F80DE6DBECA51E2F2AB680799E4227F29894FA0343483021CF475957D82EBAB1F9E270F681A28DF7E37DDA5398B1DE5E0613048B7C52C349BEF4F11A7455D2322589F593160B2AEF33286DE2C267E6C17FC027253BE1CB1254231F8AB2B1232D37E8E4374D00BAF10FB961F88CD80406AC44EBCC29DEB857BE1F400EB532FC49B575379E56593CE3B609D6A19FAF9751A9BB30CFF6C0B2892612BC313F5966741E913B97BF060B8320734BC5030A9A33110E15967D826BAAC7CB3A2E3A0B818FEF3410BF0D5230D1BC7EC86798DBCA14544AC5D956CB0B08888EACCD57D1E50C48D6511E9FF562F177E03ED08219169FDD999FA75595D67081EEC8192AF3855CADEA45B0122F042D03E0599834190F5C5A5E0B2C414A65AB21B91D32DBFDF02C247D6F085C6AC55114A62D1EC6BA06964FE5283226B37E4765B8EFB
-20200227075829 2 6 100 3071 5 EAF378AA0E2C586E9556B81261F829EE5A8F5F5E6E7A2FC92544555E006535C9EDABC5553D5FE43E8DC0886AC3788355B7B7B8FB8EE5220404D022955DBB3C1CFEB9E3163F80DE6DBECA51E2F2AB680799E4227F29894FA0343483021CF475957D82EBAB1F9E270F681A28DF7E37DDA5398B1DE5E0613048B7C52C349BEF4F11A7455D2322589F593160B2AEF33286DE2C267E6C17FC027253BE1CB1254231F8AB2B1232D37E8E4374D00BAF10FB961F88CD80406AC44EBCC29DEB857BE1F400EB532FC49B575379E56593CE3B609D6A19FAF9751A9BB30CFF6C0B2892612BC313F5966741E913B97BF060B8320734BC5030A9A33110E15967D826BAAC7CB3A2E3A0B818FEF3410BF0D5230D1BC7EC86798DBCA14544AC5D956CB0B08888EACCD57D1E50C48D6511E9FF562F177E03ED08219169FDD999FA75595D67081EEC8192AF3855CADEA45B0122F042D03E0599834190F5C5A5E0B2C414A65AB21B91D32DBFDF02C247D6F085C6AC55114A62D1EC6BA06964FE5283226B37E476EF083F
-20200227075857 2 6 100 3071 2 EAF378AA0E2C586E9556B81261F829EE5A8F5F5E6E7A2FC92544555E006535C9EDABC5553D5FE43E8DC0886AC3788355B7B7B8FB8EE5220404D022955DBB3C1CFEB9E3163F80DE6DBECA51E2F2AB680799E4227F29894FA0343483021CF475957D82EBAB1F9E270F681A28DF7E37DDA5398B1DE5E0613048B7C52C349BEF4F11A7455D2322589F593160B2AEF33286DE2C267E6C17FC027253BE1CB1254231F8AB2B1232D37E8E4374D00BAF10FB961F88CD80406AC44EBCC29DEB857BE1F400EB532FC49B575379E56593CE3B609D6A19FAF9751A9BB30CFF6C0B2892612BC313F5966741E913B97BF060B8320734BC5030A9A33110E15967D826BAAC7CB3A2E3A0B818FEF3410BF0D5230D1BC7EC86798DBCA14544AC5D956CB0B08888EACCD57D1E50C48D6511E9FF562F177E03ED08219169FDD999FA75595D67081EEC8192AF3855CADEA45B0122F042D03E0599834190F5C5A5E0B2C414A65AB21B91D32DBFDF02C247D6F085C6AC55114A62D1EC6BA06964FE5283226B37E476FA748B
-20200227082813 2 6 100 4095 2 DDFF38E32E0309D5459129AFA6C2F640C7125B85084C79BDD7042DA6E39D4A0DA4A671588016428ECAEC0F6BCC1A95E4B2BE518B7766CD0AC4674949D48B088492394DD9283C09D71CB4F4306E4CD27390575EBF2934E1C97AF880146F0D090DAB3AE1B679CF30AA52D307A8C64382C93F11AF73CAC171741A1C898CD79A680697D1A17A3D63F8C92A9C088E9E490D753D3A4811A8CAABEC2D80C62D66F56660995BC6D82BCCE18C4C6287B848F239C40467BB7EB3B7EB5489A7417D9DE8825FA86D16602AEF9BD3A523DB96B071C2BED3239B5C69AD772A39B18543F517F8BF49E6B5AE875A37E117010E8CA59947571DDC329FFD137998EC151B367525D0647001C4DADB2B95FBA9657A5619A0445E627EC6F71B4A3239E01ED76D85CBCAFFE92283E9408F770D9B8267DF5031C74C9F16CF43EB10881369DA46E692ACB2F94E9136FDA7FF58F54FFAD5749F79E5521D4358A0984AEC1B49C678FA6D6379905ABE4D245EBE854A09282945B4B62EDBDDF30954FBB9E40D751BBCD82ABE4BDC98274CB158F977802ED5E7F267A3F1EE0E6259215AD75798A6088D9AD6ACF4DF5DAA8474D1C8166AE244176D5AA2A7B2697C7C059DF78B07ACC2D47083F5058885E29FD9352243A5643C8237FBEF77F77AEEE32EC6455B4DB32A30ED02409FCBEF0C1C988876B0CBC85C89FA062824E1D35512E8C7731843CA7F6EB741DABA73
-20200227085254 2 6 100 4095 5 DDFF38E32E0309D5459129AFA6C2F640C7125B85084C79BDD7042DA6E39D4A0DA4A671588016428ECAEC0F6BCC1A95E4B2BE518B7766CD0AC4674949D48B088492394DD9283C09D71CB4F4306E4CD27390575EBF2934E1C97AF880146F0D090DAB3AE1B679CF30AA52D307A8C64382C93F11AF73CAC171741A1C898CD79A680697D1A17A3D63F8C92A9C088E9E490D753D3A4811A8CAABEC2D80C62D66F56660995BC6D82BCCE18C4C6287B848F239C40467BB7EB3B7EB5489A7417D9DE8825FA86D16602AEF9BD3A523DB96B071C2BED3239B5C69AD772A39B18543F517F8BF49E6B5AE875A37E117010E8CA59947571DDC329FFD137998EC151B367525D0647001C4DADB2B95FBA9657A5619A0445E627EC6F71B4A3239E01ED76D85CBCAFFE92283E9408F770D9B8267DF5031C74C9F16CF43EB10881369DA46E692ACB2F94E9136FDA7FF58F54FFAD5749F79E5521D4358A0984AEC1B49C678FA6D6379905ABE4D245EBE854A09282945B4B62EDBDDF30954FBB9E40D751BBCD82ABE4BDC98274CB158F977802ED5E7F267A3F1EE0E6259215AD75798A6088D9AD6ACF4DF5DAA8474D1C8166AE244176D5AA2A7B2697C7C059DF78B07ACC2D47083F5058885E29FD9352243A5643C8237FBEF77F77AEEE32EC6455B4DB32A30ED02409FCBEF0C1C988876B0CBC85C89FA062824E1D35512E8C7731843CA7F6EB7435962FF
-20200227085753 2 6 100 4095 5 DDFF38E32E0309D5459129AFA6C2F640C7125B85084C79BDD7042DA6E39D4A0DA4A671588016428ECAEC0F6BCC1A95E4B2BE518B7766CD0AC4674949D48B088492394DD9283C09D71CB4F4306E4CD27390575EBF2934E1C97AF880146F0D090DAB3AE1B679CF30AA52D307A8C64382C93F11AF73CAC171741A1C898CD79A680697D1A17A3D63F8C92A9C088E9E490D753D3A4811A8CAABEC2D80C62D66F56660995BC6D82BCCE18C4C6287B848F239C40467BB7EB3B7EB5489A7417D9DE8825FA86D16602AEF9BD3A523DB96B071C2BED3239B5C69AD772A39B18543F517F8BF49E6B5AE875A37E117010E8CA59947571DDC329FFD137998EC151B367525D0647001C4DADB2B95FBA9657A5619A0445E627EC6F71B4A3239E01ED76D85CBCAFFE92283E9408F770D9B8267DF5031C74C9F16CF43EB10881369DA46E692ACB2F94E9136FDA7FF58F54FFAD5749F79E5521D4358A0984AEC1B49C678FA6D6379905ABE4D245EBE854A09282945B4B62EDBDDF30954FBB9E40D751BBCD82ABE4BDC98274CB158F977802ED5E7F267A3F1EE0E6259215AD75798A6088D9AD6ACF4DF5DAA8474D1C8166AE244176D5AA2A7B2697C7C059DF78B07ACC2D47083F5058885E29FD9352243A5643C8237FBEF77F77AEEE32EC6455B4DB32A30ED02409FCBEF0C1C988876B0CBC85C89FA062824E1D35512E8C7731843CA7F6EB743A213E7
-20200227090042 2 6 100 4095 2 DDFF38E32E0309D5459129AFA6C2F640C7125B85084C79BDD7042DA6E39D4A0DA4A671588016428ECAEC0F6BCC1A95E4B2BE518B7766CD0AC4674949D48B088492394DD9283C09D71CB4F4306E4CD27390575EBF2934E1C97AF880146F0D090DAB3AE1B679CF30AA52D307A8C64382C93F11AF73CAC171741A1C898CD79A680697D1A17A3D63F8C92A9C088E9E490D753D3A4811A8CAABEC2D80C62D66F56660995BC6D82BCCE18C4C6287B848F239C40467BB7EB3B7EB5489A7417D9DE8825FA86D16602AEF9BD3A523DB96B071C2BED3239B5C69AD772A39B18543F517F8BF49E6B5AE875A37E117010E8CA59947571DDC329FFD137998EC151B367525D0647001C4DADB2B95FBA9657A5619A0445E627EC6F71B4A3239E01ED76D85CBCAFFE92283E9408F770D9B8267DF5031C74C9F16CF43EB10881369DA46E692ACB2F94E9136FDA7FF58F54FFAD5749F79E5521D4358A0984AEC1B49C678FA6D6379905ABE4D245EBE854A09282945B4B62EDBDDF30954FBB9E40D751BBCD82ABE4BDC98274CB158F977802ED5E7F267A3F1EE0E6259215AD75798A6088D9AD6ACF4DF5DAA8474D1C8166AE244176D5AA2A7B2697C7C059DF78B07ACC2D47083F5058885E29FD9352243A5643C8237FBEF77F77AEEE32EC6455B4DB32A30ED02409FCBEF0C1C988876B0CBC85C89FA062824E1D35512E8C7731843CA7F6EB743C75A03
-20200227090234 2 6 100 4095 2 DDFF38E32E0309D5459129AFA6C2F640C7125B85084C79BDD7042DA6E39D4A0DA4A671588016428ECAEC0F6BCC1A95E4B2BE518B7766CD0AC4674949D48B088492394DD9283C09D71CB4F4306E4CD27390575EBF2934E1C97AF880146F0D090DAB3AE1B679CF30AA52D307A8C64382C93F11AF73CAC171741A1C898CD79A680697D1A17A3D63F8C92A9C088E9E490D753D3A4811A8CAABEC2D80C62D66F56660995BC6D82BCCE18C4C6287B848F239C40467BB7EB3B7EB5489A7417D9DE8825FA86D16602AEF9BD3A523DB96B071C2BED3239B5C69AD772A39B18543F517F8BF49E6B5AE875A37E117010E8CA59947571DDC329FFD137998EC151B367525D0647001C4DADB2B95FBA9657A5619A0445E627EC6F71B4A3239E01ED76D85CBCAFFE92283E9408F770D9B8267DF5031C74C9F16CF43EB10881369DA46E692ACB2F94E9136FDA7FF58F54FFAD5749F79E5521D4358A0984AEC1B49C678FA6D6379905ABE4D245EBE854A09282945B4B62EDBDDF30954FBB9E40D751BBCD82ABE4BDC98274CB158F977802ED5E7F267A3F1EE0E6259215AD75798A6088D9AD6ACF4DF5DAA8474D1C8166AE244176D5AA2A7B2697C7C059DF78B07ACC2D47083F5058885E29FD9352243A5643C8237FBEF77F77AEEE32EC6455B4DB32A30ED02409FCBEF0C1C988876B0CBC85C89FA062824E1D35512E8C7731843CA7F6EB743DE5FFB
-20200227090848 2 6 100 4095 2 DDFF38E32E0309D5459129AFA6C2F640C7125B85084C79BDD7042DA6E39D4A0DA4A671588016428ECAEC0F6BCC1A95E4B2BE518B7766CD0AC4674949D48B088492394DD9283C09D71CB4F4306E4CD27390575EBF2934E1C97AF880146F0D090DAB3AE1B679CF30AA52D307A8C64382C93F11AF73CAC171741A1C898CD79A680697D1A17A3D63F8C92A9C088E9E490D753D3A4811A8CAABEC2D80C62D66F56660995BC6D82BCCE18C4C6287B848F239C40467BB7EB3B7EB5489A7417D9DE8825FA86D16602AEF9BD3A523DB96B071C2BED3239B5C69AD772A39B18543F517F8BF49E6B5AE875A37E117010E8CA59947571DDC329FFD137998EC151B367525D0647001C4DADB2B95FBA9657A5619A0445E627EC6F71B4A3239E01ED76D85CBCAFFE92283E9408F770D9B8267DF5031C74C9F16CF43EB10881369DA46E692ACB2F94E9136FDA7FF58F54FFAD5749F79E5521D4358A0984AEC1B49C678FA6D6379905ABE4D245EBE854A09282945B4B62EDBDDF30954FBB9E40D751BBCD82ABE4BDC98274CB158F977802ED5E7F267A3F1EE0E6259215AD75798A6088D9AD6ACF4DF5DAA8474D1C8166AE244176D5AA2A7B2697C7C059DF78B07ACC2D47083F5058885E29FD9352243A5643C8237FBEF77F77AEEE32EC6455B4DB32A30ED02409FCBEF0C1C988876B0CBC85C89FA062824E1D35512E8C7731843CA7F6EB7443ADF5B
-20200227093007 2 6 100 4095 2 DDFF38E32E0309D5459129AFA6C2F640C7125B85084C79BDD7042DA6E39D4A0DA4A671588016428ECAEC0F6BCC1A95E4B2BE518B7766CD0AC4674949D48B088492394DD9283C09D71CB4F4306E4CD27390575EBF2934E1C97AF880146F0D090DAB3AE1B679CF30AA52D307A8C64382C93F11AF73CAC171741A1C898CD79A680697D1A17A3D63F8C92A9C088E9E490D753D3A4811A8CAABEC2D80C62D66F56660995BC6D82BCCE18C4C6287B848F239C40467BB7EB3B7EB5489A7417D9DE8825FA86D16602AEF9BD3A523DB96B071C2BED3239B5C69AD772A39B18543F517F8BF49E6B5AE875A37E117010E8CA59947571DDC329FFD137998EC151B367525D0647001C4DADB2B95FBA9657A5619A0445E627EC6F71B4A3239E01ED76D85CBCAFFE92283E9408F770D9B8267DF5031C74C9F16CF43EB10881369DA46E692ACB2F94E9136FDA7FF58F54FFAD5749F79E5521D4358A0984AEC1B49C678FA6D6379905ABE4D245EBE854A09282945B4B62EDBDDF30954FBB9E40D751BBCD82ABE4BDC98274CB158F977802ED5E7F267A3F1EE0E6259215AD75798A6088D9AD6ACF4DF5DAA8474D1C8166AE244176D5AA2A7B2697C7C059DF78B07ACC2D47083F5058885E29FD9352243A5643C8237FBEF77F77AEEE32EC6455B4DB32A30ED02409FCBEF0C1C988876B0CBC85C89FA062824E1D35512E8C7731843CA7F6EB7458D5F63
-20200227094856 2 6 100 4095 5 DDFF38E32E0309D5459129AFA6C2F640C7125B85084C79BDD7042DA6E39D4A0DA4A671588016428ECAEC0F6BCC1A95E4B2BE518B7766CD0AC4674949D48B088492394DD9283C09D71CB4F4306E4CD27390575EBF2934E1C97AF880146F0D090DAB3AE1B679CF30AA52D307A8C64382C93F11AF73CAC171741A1C898CD79A680697D1A17A3D63F8C92A9C088E9E490D753D3A4811A8CAABEC2D80C62D66F56660995BC6D82BCCE18C4C6287B848F239C40467BB7EB3B7EB5489A7417D9DE8825FA86D16602AEF9BD3A523DB96B071C2BED3239B5C69AD772A39B18543F517F8BF49E6B5AE875A37E117010E8CA59947571DDC329FFD137998EC151B367525D0647001C4DADB2B95FBA9657A5619A0445E627EC6F71B4A3239E01ED76D85CBCAFFE92283E9408F770D9B8267DF5031C74C9F16CF43EB10881369DA46E692ACB2F94E9136FDA7FF58F54FFAD5749F79E5521D4358A0984AEC1B49C678FA6D6379905ABE4D245EBE854A09282945B4B62EDBDDF30954FBB9E40D751BBCD82ABE4BDC98274CB158F977802ED5E7F267A3F1EE0E6259215AD75798A6088D9AD6ACF4DF5DAA8474D1C8166AE244176D5AA2A7B2697C7C059DF78B07ACC2D47083F5058885E29FD9352243A5643C8237FBEF77F77AEEE32EC6455B4DB32A30ED02409FCBEF0C1C988876B0CBC85C89FA062824E1D35512E8C7731843CA7F6EB746B8906F
-20200227101124 2 6 100 4095 2 DDFF38E32E0309D5459129AFA6C2F640C7125B85084C79BDD7042DA6E39D4A0DA4A671588016428ECAEC0F6BCC1A95E4B2BE518B7766CD0AC4674949D48B088492394DD9283C09D71CB4F4306E4CD27390575EBF2934E1C97AF880146F0D090DAB3AE1B679CF30AA52D307A8C64382C93F11AF73CAC171741A1C898CD79A680697D1A17A3D63F8C92A9C088E9E490D753D3A4811A8CAABEC2D80C62D66F56660995BC6D82BCCE18C4C6287B848F239C40467BB7EB3B7EB5489A7417D9DE8825FA86D16602AEF9BD3A523DB96B071C2BED3239B5C69AD772A39B18543F517F8BF49E6B5AE875A37E117010E8CA59947571DDC329FFD137998EC151B367525D0647001C4DADB2B95FBA9657A5619A0445E627EC6F71B4A3239E01ED76D85CBCAFFE92283E9408F770D9B8267DF5031C74C9F16CF43EB10881369DA46E692ACB2F94E9136FDA7FF58F54FFAD5749F79E5521D4358A0984AEC1B49C678FA6D6379905ABE4D245EBE854A09282945B4B62EDBDDF30954FBB9E40D751BBCD82ABE4BDC98274CB158F977802ED5E7F267A3F1EE0E6259215AD75798A6088D9AD6ACF4DF5DAA8474D1C8166AE244176D5AA2A7B2697C7C059DF78B07ACC2D47083F5058885E29FD9352243A5643C8237FBEF77F77AEEE32EC6455B4DB32A30ED02409FCBEF0C1C988876B0CBC85C89FA062824E1D35512E8C7731843CA7F6EB7480F5003
-20200227101730 2 6 100 4095 2 DDFF38E32E0309D5459129AFA6C2F640C7125B85084C79BDD7042DA6E39D4A0DA4A671588016428ECAEC0F6BCC1A95E4B2BE518B7766CD0AC4674949D48B088492394DD9283C09D71CB4F4306E4CD27390575EBF2934E1C97AF880146F0D090DAB3AE1B679CF30AA52D307A8C64382C93F11AF73CAC171741A1C898CD79A680697D1A17A3D63F8C92A9C088E9E490D753D3A4811A8CAABEC2D80C62D66F56660995BC6D82BCCE18C4C6287B848F239C40467BB7EB3B7EB5489A7417D9DE8825FA86D16602AEF9BD3A523DB96B071C2BED3239B5C69AD772A39B18543F517F8BF49E6B5AE875A37E117010E8CA59947571DDC329FFD137998EC151B367525D0647001C4DADB2B95FBA9657A5619A0445E627EC6F71B4A3239E01ED76D85CBCAFFE92283E9408F770D9B8267DF5031C74C9F16CF43EB10881369DA46E692ACB2F94E9136FDA7FF58F54FFAD5749F79E5521D4358A0984AEC1B49C678FA6D6379905ABE4D245EBE854A09282945B4B62EDBDDF30954FBB9E40D751BBCD82ABE4BDC98274CB158F977802ED5E7F267A3F1EE0E6259215AD75798A6088D9AD6ACF4DF5DAA8474D1C8166AE244176D5AA2A7B2697C7C059DF78B07ACC2D47083F5058885E29FD9352243A5643C8237FBEF77F77AEEE32EC6455B4DB32A30ED02409FCBEF0C1C988876B0CBC85C89FA062824E1D35512E8C7731843CA7F6EB7486988BB
-20200227103113 2 6 100 4095 2 DDFF38E32E0309D5459129AFA6C2F640C7125B85084C79BDD7042DA6E39D4A0DA4A671588016428ECAEC0F6BCC1A95E4B2BE518B7766CD0AC4674949D48B088492394DD9283C09D71CB4F4306E4CD27390575EBF2934E1C97AF880146F0D090DAB3AE1B679CF30AA52D307A8C64382C93F11AF73CAC171741A1C898CD79A680697D1A17A3D63F8C92A9C088E9E490D753D3A4811A8CAABEC2D80C62D66F56660995BC6D82BCCE18C4C6287B848F239C40467BB7EB3B7EB5489A7417D9DE8825FA86D16602AEF9BD3A523DB96B071C2BED3239B5C69AD772A39B18543F517F8BF49E6B5AE875A37E117010E8CA59947571DDC329FFD137998EC151B367525D0647001C4DADB2B95FBA9657A5619A0445E627EC6F71B4A3239E01ED76D85CBCAFFE92283E9408F770D9B8267DF5031C74C9F16CF43EB10881369DA46E692ACB2F94E9136FDA7FF58F54FFAD5749F79E5521D4358A0984AEC1B49C678FA6D6379905ABE4D245EBE854A09282945B4B62EDBDDF30954FBB9E40D751BBCD82ABE4BDC98274CB158F977802ED5E7F267A3F1EE0E6259215AD75798A6088D9AD6ACF4DF5DAA8474D1C8166AE244176D5AA2A7B2697C7C059DF78B07ACC2D47083F5058885E29FD9352243A5643C8237FBEF77F77AEEE32EC6455B4DB32A30ED02409FCBEF0C1C988876B0CBC85C89FA062824E1D35512E8C7731843CA7F6EB74937A0CB
-20200227104420 2 6 100 4095 2 DDFF38E32E0309D5459129AFA6C2F640C7125B85084C79BDD7042DA6E39D4A0DA4A671588016428ECAEC0F6BCC1A95E4B2BE518B7766CD0AC4674949D48B088492394DD9283C09D71CB4F4306E4CD27390575EBF2934E1C97AF880146F0D090DAB3AE1B679CF30AA52D307A8C64382C93F11AF73CAC171741A1C898CD79A680697D1A17A3D63F8C92A9C088E9E490D753D3A4811A8CAABEC2D80C62D66F56660995BC6D82BCCE18C4C6287B848F239C40467BB7EB3B7EB5489A7417D9DE8825FA86D16602AEF9BD3A523DB96B071C2BED3239B5C69AD772A39B18543F517F8BF49E6B5AE875A37E117010E8CA59947571DDC329FFD137998EC151B367525D0647001C4DADB2B95FBA9657A5619A0445E627EC6F71B4A3239E01ED76D85CBCAFFE92283E9408F770D9B8267DF5031C74C9F16CF43EB10881369DA46E692ACB2F94E9136FDA7FF58F54FFAD5749F79E5521D4358A0984AEC1B49C678FA6D6379905ABE4D245EBE854A09282945B4B62EDBDDF30954FBB9E40D751BBCD82ABE4BDC98274CB158F977802ED5E7F267A3F1EE0E6259215AD75798A6088D9AD6ACF4DF5DAA8474D1C8166AE244176D5AA2A7B2697C7C059DF78B07ACC2D47083F5058885E29FD9352243A5643C8237FBEF77F77AEEE32EC6455B4DB32A30ED02409FCBEF0C1C988876B0CBC85C89FA062824E1D35512E8C7731843CA7F6EB74A04F623
-20200227104854 2 6 100 4095 5 DDFF38E32E0309D5459129AFA6C2F640C7125B85084C79BDD7042DA6E39D4A0DA4A671588016428ECAEC0F6BCC1A95E4B2BE518B7766CD0AC4674949D48B088492394DD9283C09D71CB4F4306E4CD27390575EBF2934E1C97AF880146F0D090DAB3AE1B679CF30AA52D307A8C64382C93F11AF73CAC171741A1C898CD79A680697D1A17A3D63F8C92A9C088E9E490D753D3A4811A8CAABEC2D80C62D66F56660995BC6D82BCCE18C4C6287B848F239C40467BB7EB3B7EB5489A7417D9DE8825FA86D16602AEF9BD3A523DB96B071C2BED3239B5C69AD772A39B18543F517F8BF49E6B5AE875A37E117010E8CA59947571DDC329FFD137998EC151B367525D0647001C4DADB2B95FBA9657A5619A0445E627EC6F71B4A3239E01ED76D85CBCAFFE92283E9408F770D9B8267DF5031C74C9F16CF43EB10881369DA46E692ACB2F94E9136FDA7FF58F54FFAD5749F79E5521D4358A0984AEC1B49C678FA6D6379905ABE4D245EBE854A09282945B4B62EDBDDF30954FBB9E40D751BBCD82ABE4BDC98274CB158F977802ED5E7F267A3F1EE0E6259215AD75798A6088D9AD6ACF4DF5DAA8474D1C8166AE244176D5AA2A7B2697C7C059DF78B07ACC2D47083F5058885E29FD9352243A5643C8237FBEF77F77AEEE32EC6455B4DB32A30ED02409FCBEF0C1C988876B0CBC85C89FA062824E1D35512E8C7731843CA7F6EB74A45CB4F
-20200227110836 2 6 100 4095 2 DDFF38E32E0309D5459129AFA6C2F640C7125B85084C79BDD7042DA6E39D4A0DA4A671588016428ECAEC0F6BCC1A95E4B2BE518B7766CD0AC4674949D48B088492394DD9283C09D71CB4F4306E4CD27390575EBF2934E1C97AF880146F0D090DAB3AE1B679CF30AA52D307A8C64382C93F11AF73CAC171741A1C898CD79A680697D1A17A3D63F8C92A9C088E9E490D753D3A4811A8CAABEC2D80C62D66F56660995BC6D82BCCE18C4C6287B848F239C40467BB7EB3B7EB5489A7417D9DE8825FA86D16602AEF9BD3A523DB96B071C2BED3239B5C69AD772A39B18543F517F8BF49E6B5AE875A37E117010E8CA59947571DDC329FFD137998EC151B367525D0647001C4DADB2B95FBA9657A5619A0445E627EC6F71B4A3239E01ED76D85CBCAFFE92283E9408F770D9B8267DF5031C74C9F16CF43EB10881369DA46E692ACB2F94E9136FDA7FF58F54FFAD5749F79E5521D4358A0984AEC1B49C678FA6D6379905ABE4D245EBE854A09282945B4B62EDBDDF30954FBB9E40D751BBCD82ABE4BDC98274CB158F977802ED5E7F267A3F1EE0E6259215AD75798A6088D9AD6ACF4DF5DAA8474D1C8166AE244176D5AA2A7B2697C7C059DF78B07ACC2D47083F5058885E29FD9352243A5643C8237FBEF77F77AEEE32EC6455B4DB32A30ED02409FCBEF0C1C988876B0CBC85C89FA062824E1D35512E8C7731843CA7F6EB74B74FEEB
-20200227111613 2 6 100 4095 5 DDFF38E32E0309D5459129AFA6C2F640C7125B85084C79BDD7042DA6E39D4A0DA4A671588016428ECAEC0F6BCC1A95E4B2BE518B7766CD0AC4674949D48B088492394DD9283C09D71CB4F4306E4CD27390575EBF2934E1C97AF880146F0D090DAB3AE1B679CF30AA52D307A8C64382C93F11AF73CAC171741A1C898CD79A680697D1A17A3D63F8C92A9C088E9E490D753D3A4811A8CAABEC2D80C62D66F56660995BC6D82BCCE18C4C6287B848F239C40467BB7EB3B7EB5489A7417D9DE8825FA86D16602AEF9BD3A523DB96B071C2BED3239B5C69AD772A39B18543F517F8BF49E6B5AE875A37E117010E8CA59947571DDC329FFD137998EC151B367525D0647001C4DADB2B95FBA9657A5619A0445E627EC6F71B4A3239E01ED76D85CBCAFFE92283E9408F770D9B8267DF5031C74C9F16CF43EB10881369DA46E692ACB2F94E9136FDA7FF58F54FFAD5749F79E5521D4358A0984AEC1B49C678FA6D6379905ABE4D245EBE854A09282945B4B62EDBDDF30954FBB9E40D751BBCD82ABE4BDC98274CB158F977802ED5E7F267A3F1EE0E6259215AD75798A6088D9AD6ACF4DF5DAA8474D1C8166AE244176D5AA2A7B2697C7C059DF78B07ACC2D47083F5058885E29FD9352243A5643C8237FBEF77F77AEEE32EC6455B4DB32A30ED02409FCBEF0C1C988876B0CBC85C89FA062824E1D35512E8C7731843CA7F6EB74BE3FB7F
-20200227112749 2 6 100 4095 5 DDFF38E32E0309D5459129AFA6C2F640C7125B85084C79BDD7042DA6E39D4A0DA4A671588016428ECAEC0F6BCC1A95E4B2BE518B7766CD0AC4674949D48B088492394DD9283C09D71CB4F4306E4CD27390575EBF2934E1C97AF880146F0D090DAB3AE1B679CF30AA52D307A8C64382C93F11AF73CAC171741A1C898CD79A680697D1A17A3D63F8C92A9C088E9E490D753D3A4811A8CAABEC2D80C62D66F56660995BC6D82BCCE18C4C6287B848F239C40467BB7EB3B7EB5489A7417D9DE8825FA86D16602AEF9BD3A523DB96B071C2BED3239B5C69AD772A39B18543F517F8BF49E6B5AE875A37E117010E8CA59947571DDC329FFD137998EC151B367525D0647001C4DADB2B95FBA9657A5619A0445E627EC6F71B4A3239E01ED76D85CBCAFFE92283E9408F770D9B8267DF5031C74C9F16CF43EB10881369DA46E692ACB2F94E9136FDA7FF58F54FFAD5749F79E5521D4358A0984AEC1B49C678FA6D6379905ABE4D245EBE854A09282945B4B62EDBDDF30954FBB9E40D751BBCD82ABE4BDC98274CB158F977802ED5E7F267A3F1EE0E6259215AD75798A6088D9AD6ACF4DF5DAA8474D1C8166AE244176D5AA2A7B2697C7C059DF78B07ACC2D47083F5058885E29FD9352243A5643C8237FBEF77F77AEEE32EC6455B4DB32A30ED02409FCBEF0C1C988876B0CBC85C89FA062824E1D35512E8C7731843CA7F6EB74C93FE2F
-20200227114309 2 6 100 4095 5 DDFF38E32E0309D5459129AFA6C2F640C7125B85084C79BDD7042DA6E39D4A0DA4A671588016428ECAEC0F6BCC1A95E4B2BE518B7766CD0AC4674949D48B088492394DD9283C09D71CB4F4306E4CD27390575EBF2934E1C97AF880146F0D090DAB3AE1B679CF30AA52D307A8C64382C93F11AF73CAC171741A1C898CD79A680697D1A17A3D63F8C92A9C088E9E490D753D3A4811A8CAABEC2D80C62D66F56660995BC6D82BCCE18C4C6287B848F239C40467BB7EB3B7EB5489A7417D9DE8825FA86D16602AEF9BD3A523DB96B071C2BED3239B5C69AD772A39B18543F517F8BF49E6B5AE875A37E117010E8CA59947571DDC329FFD137998EC151B367525D0647001C4DADB2B95FBA9657A5619A0445E627EC6F71B4A3239E01ED76D85CBCAFFE92283E9408F770D9B8267DF5031C74C9F16CF43EB10881369DA46E692ACB2F94E9136FDA7FF58F54FFAD5749F79E5521D4358A0984AEC1B49C678FA6D6379905ABE4D245EBE854A09282945B4B62EDBDDF30954FBB9E40D751BBCD82ABE4BDC98274CB158F977802ED5E7F267A3F1EE0E6259215AD75798A6088D9AD6ACF4DF5DAA8474D1C8166AE244176D5AA2A7B2697C7C059DF78B07ACC2D47083F5058885E29FD9352243A5643C8237FBEF77F77AEEE32EC6455B4DB32A30ED02409FCBEF0C1C988876B0CBC85C89FA062824E1D35512E8C7731843CA7F6EB74D83C6DF
-20200227115500 2 6 100 4095 2 DDFF38E32E0309D5459129AFA6C2F640C7125B85084C79BDD7042DA6E39D4A0DA4A671588016428ECAEC0F6BCC1A95E4B2BE518B7766CD0AC4674949D48B088492394DD9283C09D71CB4F4306E4CD27390575EBF2934E1C97AF880146F0D090DAB3AE1B679CF30AA52D307A8C64382C93F11AF73CAC171741A1C898CD79A680697D1A17A3D63F8C92A9C088E9E490D753D3A4811A8CAABEC2D80C62D66F56660995BC6D82BCCE18C4C6287B848F239C40467BB7EB3B7EB5489A7417D9DE8825FA86D16602AEF9BD3A523DB96B071C2BED3239B5C69AD772A39B18543F517F8BF49E6B5AE875A37E117010E8CA59947571DDC329FFD137998EC151B367525D0647001C4DADB2B95FBA9657A5619A0445E627EC6F71B4A3239E01ED76D85CBCAFFE92283E9408F770D9B8267DF5031C74C9F16CF43EB10881369DA46E692ACB2F94E9136FDA7FF58F54FFAD5749F79E5521D4358A0984AEC1B49C678FA6D6379905ABE4D245EBE854A09282945B4B62EDBDDF30954FBB9E40D751BBCD82ABE4BDC98274CB158F977802ED5E7F267A3F1EE0E6259215AD75798A6088D9AD6ACF4DF5DAA8474D1C8166AE244176D5AA2A7B2697C7C059DF78B07ACC2D47083F5058885E29FD9352243A5643C8237FBEF77F77AEEE32EC6455B4DB32A30ED02409FCBEF0C1C988876B0CBC85C89FA062824E1D35512E8C7731843CA7F6EB74E39954B
-20200227115811 2 6 100 4095 2 DDFF38E32E0309D5459129AFA6C2F640C7125B85084C79BDD7042DA6E39D4A0DA4A671588016428ECAEC0F6BCC1A95E4B2BE518B7766CD0AC4674949D48B088492394DD9283C09D71CB4F4306E4CD27390575EBF2934E1C97AF880146F0D090DAB3AE1B679CF30AA52D307A8C64382C93F11AF73CAC171741A1C898CD79A680697D1A17A3D63F8C92A9C088E9E490D753D3A4811A8CAABEC2D80C62D66F56660995BC6D82BCCE18C4C6287B848F239C40467BB7EB3B7EB5489A7417D9DE8825FA86D16602AEF9BD3A523DB96B071C2BED3239B5C69AD772A39B18543F517F8BF49E6B5AE875A37E117010E8CA59947571DDC329FFD137998EC151B367525D0647001C4DADB2B95FBA9657A5619A0445E627EC6F71B4A3239E01ED76D85CBCAFFE92283E9408F770D9B8267DF5031C74C9F16CF43EB10881369DA46E692ACB2F94E9136FDA7FF58F54FFAD5749F79E5521D4358A0984AEC1B49C678FA6D6379905ABE4D245EBE854A09282945B4B62EDBDDF30954FBB9E40D751BBCD82ABE4BDC98274CB158F977802ED5E7F267A3F1EE0E6259215AD75798A6088D9AD6ACF4DF5DAA8474D1C8166AE244176D5AA2A7B2697C7C059DF78B07ACC2D47083F5058885E29FD9352243A5643C8237FBEF77F77AEEE32EC6455B4DB32A30ED02409FCBEF0C1C988876B0CBC85C89FA062824E1D35512E8C7731843CA7F6EB74E610523
-20200227115926 2 6 100 4095 2 DDFF38E32E0309D5459129AFA6C2F640C7125B85084C79BDD7042DA6E39D4A0DA4A671588016428ECAEC0F6BCC1A95E4B2BE518B7766CD0AC4674949D48B088492394DD9283C09D71CB4F4306E4CD27390575EBF2934E1C97AF880146F0D090DAB3AE1B679CF30AA52D307A8C64382C93F11AF73CAC171741A1C898CD79A680697D1A17A3D63F8C92A9C088E9E490D753D3A4811A8CAABEC2D80C62D66F56660995BC6D82BCCE18C4C6287B848F239C40467BB7EB3B7EB5489A7417D9DE8825FA86D16602AEF9BD3A523DB96B071C2BED3239B5C69AD772A39B18543F517F8BF49E6B5AE875A37E117010E8CA59947571DDC329FFD137998EC151B367525D0647001C4DADB2B95FBA9657A5619A0445E627EC6F71B4A3239E01ED76D85CBCAFFE92283E9408F770D9B8267DF5031C74C9F16CF43EB10881369DA46E692ACB2F94E9136FDA7FF58F54FFAD5749F79E5521D4358A0984AEC1B49C678FA6D6379905ABE4D245EBE854A09282945B4B62EDBDDF30954FBB9E40D751BBCD82ABE4BDC98274CB158F977802ED5E7F267A3F1EE0E6259215AD75798A6088D9AD6ACF4DF5DAA8474D1C8166AE244176D5AA2A7B2697C7C059DF78B07ACC2D47083F5058885E29FD9352243A5643C8237FBEF77F77AEEE32EC6455B4DB32A30ED02409FCBEF0C1C988876B0CBC85C89FA062824E1D35512E8C7731843CA7F6EB74E6BF7B3
-20200227121313 2 6 100 4095 2 DDFF38E32E0309D5459129AFA6C2F640C7125B85084C79BDD7042DA6E39D4A0DA4A671588016428ECAEC0F6BCC1A95E4B2BE518B7766CD0AC4674949D48B088492394DD9283C09D71CB4F4306E4CD27390575EBF2934E1C97AF880146F0D090DAB3AE1B679CF30AA52D307A8C64382C93F11AF73CAC171741A1C898CD79A680697D1A17A3D63F8C92A9C088E9E490D753D3A4811A8CAABEC2D80C62D66F56660995BC6D82BCCE18C4C6287B848F239C40467BB7EB3B7EB5489A7417D9DE8825FA86D16602AEF9BD3A523DB96B071C2BED3239B5C69AD772A39B18543F517F8BF49E6B5AE875A37E117010E8CA59947571DDC329FFD137998EC151B367525D0647001C4DADB2B95FBA9657A5619A0445E627EC6F71B4A3239E01ED76D85CBCAFFE92283E9408F770D9B8267DF5031C74C9F16CF43EB10881369DA46E692ACB2F94E9136FDA7FF58F54FFAD5749F79E5521D4358A0984AEC1B49C678FA6D6379905ABE4D245EBE854A09282945B4B62EDBDDF30954FBB9E40D751BBCD82ABE4BDC98274CB158F977802ED5E7F267A3F1EE0E6259215AD75798A6088D9AD6ACF4DF5DAA8474D1C8166AE244176D5AA2A7B2697C7C059DF78B07ACC2D47083F5058885E29FD9352243A5643C8237FBEF77F77AEEE32EC6455B4DB32A30ED02409FCBEF0C1C988876B0CBC85C89FA062824E1D35512E8C7731843CA7F6EB74F3A3303
-20200227121624 2 6 100 4095 2 DDFF38E32E0309D5459129AFA6C2F640C7125B85084C79BDD7042DA6E39D4A0DA4A671588016428ECAEC0F6BCC1A95E4B2BE518B7766CD0AC4674949D48B088492394DD9283C09D71CB4F4306E4CD27390575EBF2934E1C97AF880146F0D090DAB3AE1B679CF30AA52D307A8C64382C93F11AF73CAC171741A1C898CD79A680697D1A17A3D63F8C92A9C088E9E490D753D3A4811A8CAABEC2D80C62D66F56660995BC6D82BCCE18C4C6287B848F239C40467BB7EB3B7EB5489A7417D9DE8825FA86D16602AEF9BD3A523DB96B071C2BED3239B5C69AD772A39B18543F517F8BF49E6B5AE875A37E117010E8CA59947571DDC329FFD137998EC151B367525D0647001C4DADB2B95FBA9657A5619A0445E627EC6F71B4A3239E01ED76D85CBCAFFE92283E9408F770D9B8267DF5031C74C9F16CF43EB10881369DA46E692ACB2F94E9136FDA7FF58F54FFAD5749F79E5521D4358A0984AEC1B49C678FA6D6379905ABE4D245EBE854A09282945B4B62EDBDDF30954FBB9E40D751BBCD82ABE4BDC98274CB158F977802ED5E7F267A3F1EE0E6259215AD75798A6088D9AD6ACF4DF5DAA8474D1C8166AE244176D5AA2A7B2697C7C059DF78B07ACC2D47083F5058885E29FD9352243A5643C8237FBEF77F77AEEE32EC6455B4DB32A30ED02409FCBEF0C1C988876B0CBC85C89FA062824E1D35512E8C7731843CA7F6EB74F621F43
-20200227121855 2 6 100 4095 2 DDFF38E32E0309D5459129AFA6C2F640C7125B85084C79BDD7042DA6E39D4A0DA4A671588016428ECAEC0F6BCC1A95E4B2BE518B7766CD0AC4674949D48B088492394DD9283C09D71CB4F4306E4CD27390575EBF2934E1C97AF880146F0D090DAB3AE1B679CF30AA52D307A8C64382C93F11AF73CAC171741A1C898CD79A680697D1A17A3D63F8C92A9C088E9E490D753D3A4811A8CAABEC2D80C62D66F56660995BC6D82BCCE18C4C6287B848F239C40467BB7EB3B7EB5489A7417D9DE8825FA86D16602AEF9BD3A523DB96B071C2BED3239B5C69AD772A39B18543F517F8BF49E6B5AE875A37E117010E8CA59947571DDC329FFD137998EC151B367525D0647001C4DADB2B95FBA9657A5619A0445E627EC6F71B4A3239E01ED76D85CBCAFFE92283E9408F770D9B8267DF5031C74C9F16CF43EB10881369DA46E692ACB2F94E9136FDA7FF58F54FFAD5749F79E5521D4358A0984AEC1B49C678FA6D6379905ABE4D245EBE854A09282945B4B62EDBDDF30954FBB9E40D751BBCD82ABE4BDC98274CB158F977802ED5E7F267A3F1EE0E6259215AD75798A6088D9AD6ACF4DF5DAA8474D1C8166AE244176D5AA2A7B2697C7C059DF78B07ACC2D47083F5058885E29FD9352243A5643C8237FBEF77F77AEEE32EC6455B4DB32A30ED02409FCBEF0C1C988876B0CBC85C89FA062824E1D35512E8C7731843CA7F6EB74F826A0B
-20200227123033 2 6 100 4095 2 DDFF38E32E0309D5459129AFA6C2F640C7125B85084C79BDD7042DA6E39D4A0DA4A671588016428ECAEC0F6BCC1A95E4B2BE518B7766CD0AC4674949D48B088492394DD9283C09D71CB4F4306E4CD27390575EBF2934E1C97AF880146F0D090DAB3AE1B679CF30AA52D307A8C64382C93F11AF73CAC171741A1C898CD79A680697D1A17A3D63F8C92A9C088E9E490D753D3A4811A8CAABEC2D80C62D66F56660995BC6D82BCCE18C4C6287B848F239C40467BB7EB3B7EB5489A7417D9DE8825FA86D16602AEF9BD3A523DB96B071C2BED3239B5C69AD772A39B18543F517F8BF49E6B5AE875A37E117010E8CA59947571DDC329FFD137998EC151B367525D0647001C4DADB2B95FBA9657A5619A0445E627EC6F71B4A3239E01ED76D85CBCAFFE92283E9408F770D9B8267DF5031C74C9F16CF43EB10881369DA46E692ACB2F94E9136FDA7FF58F54FFAD5749F79E5521D4358A0984AEC1B49C678FA6D6379905ABE4D245EBE854A09282945B4B62EDBDDF30954FBB9E40D751BBCD82ABE4BDC98274CB158F977802ED5E7F267A3F1EE0E6259215AD75798A6088D9AD6ACF4DF5DAA8474D1C8166AE244176D5AA2A7B2697C7C059DF78B07ACC2D47083F5058885E29FD9352243A5643C8237FBEF77F77AEEE32EC6455B4DB32A30ED02409FCBEF0C1C988876B0CBC85C89FA062824E1D35512E8C7731843CA7F6EB7502D388B
-20200227130625 2 6 100 4095 2 DDFF38E32E0309D5459129AFA6C2F640C7125B85084C79BDD7042DA6E39D4A0DA4A671588016428ECAEC0F6BCC1A95E4B2BE518B7766CD0AC4674949D48B088492394DD9283C09D71CB4F4306E4CD27390575EBF2934E1C97AF880146F0D090DAB3AE1B679CF30AA52D307A8C64382C93F11AF73CAC171741A1C898CD79A680697D1A17A3D63F8C92A9C088E9E490D753D3A4811A8CAABEC2D80C62D66F56660995BC6D82BCCE18C4C6287B848F239C40467BB7EB3B7EB5489A7417D9DE8825FA86D16602AEF9BD3A523DB96B071C2BED3239B5C69AD772A39B18543F517F8BF49E6B5AE875A37E117010E8CA59947571DDC329FFD137998EC151B367525D0647001C4DADB2B95FBA9657A5619A0445E627EC6F71B4A3239E01ED76D85CBCAFFE92283E9408F770D9B8267DF5031C74C9F16CF43EB10881369DA46E692ACB2F94E9136FDA7FF58F54FFAD5749F79E5521D4358A0984AEC1B49C678FA6D6379905ABE4D245EBE854A09282945B4B62EDBDDF30954FBB9E40D751BBCD82ABE4BDC98274CB158F977802ED5E7F267A3F1EE0E6259215AD75798A6088D9AD6ACF4DF5DAA8474D1C8166AE244176D5AA2A7B2697C7C059DF78B07ACC2D47083F5058885E29FD9352243A5643C8237FBEF77F77AEEE32EC6455B4DB32A30ED02409FCBEF0C1C988876B0CBC85C89FA062824E1D35512E8C7731843CA7F6EB7525AE2F3
-20200227135640 2 6 100 4095 5 DDFF38E32E0309D5459129AFA6C2F640C7125B85084C79BDD7042DA6E39D4A0DA4A671588016428ECAEC0F6BCC1A95E4B2BE518B7766CD0AC4674949D48B088492394DD9283C09D71CB4F4306E4CD27390575EBF2934E1C97AF880146F0D090DAB3AE1B679CF30AA52D307A8C64382C93F11AF73CAC171741A1C898CD79A680697D1A17A3D63F8C92A9C088E9E490D753D3A4811A8CAABEC2D80C62D66F56660995BC6D82BCCE18C4C6287B848F239C40467BB7EB3B7EB5489A7417D9DE8825FA86D16602AEF9BD3A523DB96B071C2BED3239B5C69AD772A39B18543F517F8BF49E6B5AE875A37E117010E8CA59947571DDC329FFD137998EC151B367525D0647001C4DADB2B95FBA9657A5619A0445E627EC6F71B4A3239E01ED76D85CBCAFFE92283E9408F770D9B8267DF5031C74C9F16CF43EB10881369DA46E692ACB2F94E9136FDA7FF58F54FFAD5749F79E5521D4358A0984AEC1B49C678FA6D6379905ABE4D245EBE854A09282945B4B62EDBDDF30954FBB9E40D751BBCD82ABE4BDC98274CB158F977802ED5E7F267A3F1EE0E6259215AD75798A6088D9AD6ACF4DF5DAA8474D1C8166AE244176D5AA2A7B2697C7C059DF78B07ACC2D47083F5058885E29FD9352243A5643C8237FBEF77F77AEEE32EC6455B4DB32A30ED02409FCBEF0C1C988876B0CBC85C89FA062824E1D35512E8C7731843CA7F6EB755543337
-20200227140747 2 6 100 4095 2 DDFF38E32E0309D5459129AFA6C2F640C7125B85084C79BDD7042DA6E39D4A0DA4A671588016428ECAEC0F6BCC1A95E4B2BE518B7766CD0AC4674949D48B088492394DD9283C09D71CB4F4306E4CD27390575EBF2934E1C97AF880146F0D090DAB3AE1B679CF30AA52D307A8C64382C93F11AF73CAC171741A1C898CD79A680697D1A17A3D63F8C92A9C088E9E490D753D3A4811A8CAABEC2D80C62D66F56660995BC6D82BCCE18C4C6287B848F239C40467BB7EB3B7EB5489A7417D9DE8825FA86D16602AEF9BD3A523DB96B071C2BED3239B5C69AD772A39B18543F517F8BF49E6B5AE875A37E117010E8CA59947571DDC329FFD137998EC151B367525D0647001C4DADB2B95FBA9657A5619A0445E627EC6F71B4A3239E01ED76D85CBCAFFE92283E9408F770D9B8267DF5031C74C9F16CF43EB10881369DA46E692ACB2F94E9136FDA7FF58F54FFAD5749F79E5521D4358A0984AEC1B49C678FA6D6379905ABE4D245EBE854A09282945B4B62EDBDDF30954FBB9E40D751BBCD82ABE4BDC98274CB158F977802ED5E7F267A3F1EE0E6259215AD75798A6088D9AD6ACF4DF5DAA8474D1C8166AE244176D5AA2A7B2697C7C059DF78B07ACC2D47083F5058885E29FD9352243A5643C8237FBEF77F77AEEE32EC6455B4DB32A30ED02409FCBEF0C1C988876B0CBC85C89FA062824E1D35512E8C7731843CA7F6EB755FCE54B
-20200227141645 2 6 100 4095 5 DDFF38E32E0309D5459129AFA6C2F640C7125B85084C79BDD7042DA6E39D4A0DA4A671588016428ECAEC0F6BCC1A95E4B2BE518B7766CD0AC4674949D48B088492394DD9283C09D71CB4F4306E4CD27390575EBF2934E1C97AF880146F0D090DAB3AE1B679CF30AA52D307A8C64382C93F11AF73CAC171741A1C898CD79A680697D1A17A3D63F8C92A9C088E9E490D753D3A4811A8CAABEC2D80C62D66F56660995BC6D82BCCE18C4C6287B848F239C40467BB7EB3B7EB5489A7417D9DE8825FA86D16602AEF9BD3A523DB96B071C2BED3239B5C69AD772A39B18543F517F8BF49E6B5AE875A37E117010E8CA59947571DDC329FFD137998EC151B367525D0647001C4DADB2B95FBA9657A5619A0445E627EC6F71B4A3239E01ED76D85CBCAFFE92283E9408F770D9B8267DF5031C74C9F16CF43EB10881369DA46E692ACB2F94E9136FDA7FF58F54FFAD5749F79E5521D4358A0984AEC1B49C678FA6D6379905ABE4D245EBE854A09282945B4B62EDBDDF30954FBB9E40D751BBCD82ABE4BDC98274CB158F977802ED5E7F267A3F1EE0E6259215AD75798A6088D9AD6ACF4DF5DAA8474D1C8166AE244176D5AA2A7B2697C7C059DF78B07ACC2D47083F5058885E29FD9352243A5643C8237FBEF77F77AEEE32EC6455B4DB32A30ED02409FCBEF0C1C988876B0CBC85C89FA062824E1D35512E8C7731843CA7F6EB756869BEF
-20200227142156 2 6 100 4095 5 DDFF38E32E0309D5459129AFA6C2F640C7125B85084C79BDD7042DA6E39D4A0DA4A671588016428ECAEC0F6BCC1A95E4B2BE518B7766CD0AC4674949D48B088492394DD9283C09D71CB4F4306E4CD27390575EBF2934E1C97AF880146F0D090DAB3AE1B679CF30AA52D307A8C64382C93F11AF73CAC171741A1C898CD79A680697D1A17A3D63F8C92A9C088E9E490D753D3A4811A8CAABEC2D80C62D66F56660995BC6D82BCCE18C4C6287B848F239C40467BB7EB3B7EB5489A7417D9DE8825FA86D16602AEF9BD3A523DB96B071C2BED3239B5C69AD772A39B18543F517F8BF49E6B5AE875A37E117010E8CA59947571DDC329FFD137998EC151B367525D0647001C4DADB2B95FBA9657A5619A0445E627EC6F71B4A3239E01ED76D85CBCAFFE92283E9408F770D9B8267DF5031C74C9F16CF43EB10881369DA46E692ACB2F94E9136FDA7FF58F54FFAD5749F79E5521D4358A0984AEC1B49C678FA6D6379905ABE4D245EBE854A09282945B4B62EDBDDF30954FBB9E40D751BBCD82ABE4BDC98274CB158F977802ED5E7F267A3F1EE0E6259215AD75798A6088D9AD6ACF4DF5DAA8474D1C8166AE244176D5AA2A7B2697C7C059DF78B07ACC2D47083F5058885E29FD9352243A5643C8237FBEF77F77AEEE32EC6455B4DB32A30ED02409FCBEF0C1C988876B0CBC85C89FA062824E1D35512E8C7731843CA7F6EB756C91ECF
-20200227143711 2 6 100 4095 5 DDFF38E32E0309D5459129AFA6C2F640C7125B85084C79BDD7042DA6E39D4A0DA4A671588016428ECAEC0F6BCC1A95E4B2BE518B7766CD0AC4674949D48B088492394DD9283C09D71CB4F4306E4CD27390575EBF2934E1C97AF880146F0D090DAB3AE1B679CF30AA52D307A8C64382C93F11AF73CAC171741A1C898CD79A680697D1A17A3D63F8C92A9C088E9E490D753D3A4811A8CAABEC2D80C62D66F56660995BC6D82BCCE18C4C6287B848F239C40467BB7EB3B7EB5489A7417D9DE8825FA86D16602AEF9BD3A523DB96B071C2BED3239B5C69AD772A39B18543F517F8BF49E6B5AE875A37E117010E8CA59947571DDC329FFD137998EC151B367525D0647001C4DADB2B95FBA9657A5619A0445E627EC6F71B4A3239E01ED76D85CBCAFFE92283E9408F770D9B8267DF5031C74C9F16CF43EB10881369DA46E692ACB2F94E9136FDA7FF58F54FFAD5749F79E5521D4358A0984AEC1B49C678FA6D6379905ABE4D245EBE854A09282945B4B62EDBDDF30954FBB9E40D751BBCD82ABE4BDC98274CB158F977802ED5E7F267A3F1EE0E6259215AD75798A6088D9AD6ACF4DF5DAA8474D1C8166AE244176D5AA2A7B2697C7C059DF78B07ACC2D47083F5058885E29FD9352243A5643C8237FBEF77F77AEEE32EC6455B4DB32A30ED02409FCBEF0C1C988876B0CBC85C89FA062824E1D35512E8C7731843CA7F6EB75795756F
-20200227144742 2 6 100 4095 5 DDFF38E32E0309D5459129AFA6C2F640C7125B85084C79BDD7042DA6E39D4A0DA4A671588016428ECAEC0F6BCC1A95E4B2BE518B7766CD0AC4674949D48B088492394DD9283C09D71CB4F4306E4CD27390575EBF2934E1C97AF880146F0D090DAB3AE1B679CF30AA52D307A8C64382C93F11AF73CAC171741A1C898CD79A680697D1A17A3D63F8C92A9C088E9E490D753D3A4811A8CAABEC2D80C62D66F56660995BC6D82BCCE18C4C6287B848F239C40467BB7EB3B7EB5489A7417D9DE8825FA86D16602AEF9BD3A523DB96B071C2BED3239B5C69AD772A39B18543F517F8BF49E6B5AE875A37E117010E8CA59947571DDC329FFD137998EC151B367525D0647001C4DADB2B95FBA9657A5619A0445E627EC6F71B4A3239E01ED76D85CBCAFFE92283E9408F770D9B8267DF5031C74C9F16CF43EB10881369DA46E692ACB2F94E9136FDA7FF58F54FFAD5749F79E5521D4358A0984AEC1B49C678FA6D6379905ABE4D245EBE854A09282945B4B62EDBDDF30954FBB9E40D751BBCD82ABE4BDC98274CB158F977802ED5E7F267A3F1EE0E6259215AD75798A6088D9AD6ACF4DF5DAA8474D1C8166AE244176D5AA2A7B2697C7C059DF78B07ACC2D47083F5058885E29FD9352243A5643C8237FBEF77F77AEEE32EC6455B4DB32A30ED02409FCBEF0C1C988876B0CBC85C89FA062824E1D35512E8C7731843CA7F6EB75832B00F
-20200227150218 2 6 100 4095 2 DDFF38E32E0309D5459129AFA6C2F640C7125B85084C79BDD7042DA6E39D4A0DA4A671588016428ECAEC0F6BCC1A95E4B2BE518B7766CD0AC4674949D48B088492394DD9283C09D71CB4F4306E4CD27390575EBF2934E1C97AF880146F0D090DAB3AE1B679CF30AA52D307A8C64382C93F11AF73CAC171741A1C898CD79A680697D1A17A3D63F8C92A9C088E9E490D753D3A4811A8CAABEC2D80C62D66F56660995BC6D82BCCE18C4C6287B848F239C40467BB7EB3B7EB5489A7417D9DE8825FA86D16602AEF9BD3A523DB96B071C2BED3239B5C69AD772A39B18543F517F8BF49E6B5AE875A37E117010E8CA59947571DDC329FFD137998EC151B367525D0647001C4DADB2B95FBA9657A5619A0445E627EC6F71B4A3239E01ED76D85CBCAFFE92283E9408F770D9B8267DF5031C74C9F16CF43EB10881369DA46E692ACB2F94E9136FDA7FF58F54FFAD5749F79E5521D4358A0984AEC1B49C678FA6D6379905ABE4D245EBE854A09282945B4B62EDBDDF30954FBB9E40D751BBCD82ABE4BDC98274CB158F977802ED5E7F267A3F1EE0E6259215AD75798A6088D9AD6ACF4DF5DAA8474D1C8166AE244176D5AA2A7B2697C7C059DF78B07ACC2D47083F5058885E29FD9352243A5643C8237FBEF77F77AEEE32EC6455B4DB32A30ED02409FCBEF0C1C988876B0CBC85C89FA062824E1D35512E8C7731843CA7F6EB7590B9D1B
-20200227150317 2 6 100 4095 2 DDFF38E32E0309D5459129AFA6C2F640C7125B85084C79BDD7042DA6E39D4A0DA4A671588016428ECAEC0F6BCC1A95E4B2BE518B7766CD0AC4674949D48B088492394DD9283C09D71CB4F4306E4CD27390575EBF2934E1C97AF880146F0D090DAB3AE1B679CF30AA52D307A8C64382C93F11AF73CAC171741A1C898CD79A680697D1A17A3D63F8C92A9C088E9E490D753D3A4811A8CAABEC2D80C62D66F56660995BC6D82BCCE18C4C6287B848F239C40467BB7EB3B7EB5489A7417D9DE8825FA86D16602AEF9BD3A523DB96B071C2BED3239B5C69AD772A39B18543F517F8BF49E6B5AE875A37E117010E8CA59947571DDC329FFD137998EC151B367525D0647001C4DADB2B95FBA9657A5619A0445E627EC6F71B4A3239E01ED76D85CBCAFFE92283E9408F770D9B8267DF5031C74C9F16CF43EB10881369DA46E692ACB2F94E9136FDA7FF58F54FFAD5749F79E5521D4358A0984AEC1B49C678FA6D6379905ABE4D245EBE854A09282945B4B62EDBDDF30954FBB9E40D751BBCD82ABE4BDC98274CB158F977802ED5E7F267A3F1EE0E6259215AD75798A6088D9AD6ACF4DF5DAA8474D1C8166AE244176D5AA2A7B2697C7C059DF78B07ACC2D47083F5058885E29FD9352243A5643C8237FBEF77F77AEEE32EC6455B4DB32A30ED02409FCBEF0C1C988876B0CBC85C89FA062824E1D35512E8C7731843CA7F6EB75911AF63
-20200227153455 2 6 100 4095 5 DDFF38E32E0309D5459129AFA6C2F640C7125B85084C79BDD7042DA6E39D4A0DA4A671588016428ECAEC0F6BCC1A95E4B2BE518B7766CD0AC4674949D48B088492394DD9283C09D71CB4F4306E4CD27390575EBF2934E1C97AF880146F0D090DAB3AE1B679CF30AA52D307A8C64382C93F11AF73CAC171741A1C898CD79A680697D1A17A3D63F8C92A9C088E9E490D753D3A4811A8CAABEC2D80C62D66F56660995BC6D82BCCE18C4C6287B848F239C40467BB7EB3B7EB5489A7417D9DE8825FA86D16602AEF9BD3A523DB96B071C2BED3239B5C69AD772A39B18543F517F8BF49E6B5AE875A37E117010E8CA59947571DDC329FFD137998EC151B367525D0647001C4DADB2B95FBA9657A5619A0445E627EC6F71B4A3239E01ED76D85CBCAFFE92283E9408F770D9B8267DF5031C74C9F16CF43EB10881369DA46E692ACB2F94E9136FDA7FF58F54FFAD5749F79E5521D4358A0984AEC1B49C678FA6D6379905ABE4D245EBE854A09282945B4B62EDBDDF30954FBB9E40D751BBCD82ABE4BDC98274CB158F977802ED5E7F267A3F1EE0E6259215AD75798A6088D9AD6ACF4DF5DAA8474D1C8166AE244176D5AA2A7B2697C7C059DF78B07ACC2D47083F5058885E29FD9352243A5643C8237FBEF77F77AEEE32EC6455B4DB32A30ED02409FCBEF0C1C988876B0CBC85C89FA062824E1D35512E8C7731843CA7F6EB75AFB3177
-20200227154347 2 6 100 4095 2 DDFF38E32E0309D5459129AFA6C2F640C7125B85084C79BDD7042DA6E39D4A0DA4A671588016428ECAEC0F6BCC1A95E4B2BE518B7766CD0AC4674949D48B088492394DD9283C09D71CB4F4306E4CD27390575EBF2934E1C97AF880146F0D090DAB3AE1B679CF30AA52D307A8C64382C93F11AF73CAC171741A1C898CD79A680697D1A17A3D63F8C92A9C088E9E490D753D3A4811A8CAABEC2D80C62D66F56660995BC6D82BCCE18C4C6287B848F239C40467BB7EB3B7EB5489A7417D9DE8825FA86D16602AEF9BD3A523DB96B071C2BED3239B5C69AD772A39B18543F517F8BF49E6B5AE875A37E117010E8CA59947571DDC329FFD137998EC151B367525D0647001C4DADB2B95FBA9657A5619A0445E627EC6F71B4A3239E01ED76D85CBCAFFE92283E9408F770D9B8267DF5031C74C9F16CF43EB10881369DA46E692ACB2F94E9136FDA7FF58F54FFAD5749F79E5521D4358A0984AEC1B49C678FA6D6379905ABE4D245EBE854A09282945B4B62EDBDDF30954FBB9E40D751BBCD82ABE4BDC98274CB158F977802ED5E7F267A3F1EE0E6259215AD75798A6088D9AD6ACF4DF5DAA8474D1C8166AE244176D5AA2A7B2697C7C059DF78B07ACC2D47083F5058885E29FD9352243A5643C8237FBEF77F77AEEE32EC6455B4DB32A30ED02409FCBEF0C1C988876B0CBC85C89FA062824E1D35512E8C7731843CA7F6EB75B7E69BB
-20200227154742 2 6 100 4095 5 DDFF38E32E0309D5459129AFA6C2F640C7125B85084C79BDD7042DA6E39D4A0DA4A671588016428ECAEC0F6BCC1A95E4B2BE518B7766CD0AC4674949D48B088492394DD9283C09D71CB4F4306E4CD27390575EBF2934E1C97AF880146F0D090DAB3AE1B679CF30AA52D307A8C64382C93F11AF73CAC171741A1C898CD79A680697D1A17A3D63F8C92A9C088E9E490D753D3A4811A8CAABEC2D80C62D66F56660995BC6D82BCCE18C4C6287B848F239C40467BB7EB3B7EB5489A7417D9DE8825FA86D16602AEF9BD3A523DB96B071C2BED3239B5C69AD772A39B18543F517F8BF49E6B5AE875A37E117010E8CA59947571DDC329FFD137998EC151B367525D0647001C4DADB2B95FBA9657A5619A0445E627EC6F71B4A3239E01ED76D85CBCAFFE92283E9408F770D9B8267DF5031C74C9F16CF43EB10881369DA46E692ACB2F94E9136FDA7FF58F54FFAD5749F79E5521D4358A0984AEC1B49C678FA6D6379905ABE4D245EBE854A09282945B4B62EDBDDF30954FBB9E40D751BBCD82ABE4BDC98274CB158F977802ED5E7F267A3F1EE0E6259215AD75798A6088D9AD6ACF4DF5DAA8474D1C8166AE244176D5AA2A7B2697C7C059DF78B07ACC2D47083F5058885E29FD9352243A5643C8237FBEF77F77AEEE32EC6455B4DB32A30ED02409FCBEF0C1C988876B0CBC85C89FA062824E1D35512E8C7731843CA7F6EB75BB2636F
-20200227155533 2 6 100 4095 5 DDFF38E32E0309D5459129AFA6C2F640C7125B85084C79BDD7042DA6E39D4A0DA4A671588016428ECAEC0F6BCC1A95E4B2BE518B7766CD0AC4674949D48B088492394DD9283C09D71CB4F4306E4CD27390575EBF2934E1C97AF880146F0D090DAB3AE1B679CF30AA52D307A8C64382C93F11AF73CAC171741A1C898CD79A680697D1A17A3D63F8C92A9C088E9E490D753D3A4811A8CAABEC2D80C62D66F56660995BC6D82BCCE18C4C6287B848F239C40467BB7EB3B7EB5489A7417D9DE8825FA86D16602AEF9BD3A523DB96B071C2BED3239B5C69AD772A39B18543F517F8BF49E6B5AE875A37E117010E8CA59947571DDC329FFD137998EC151B367525D0647001C4DADB2B95FBA9657A5619A0445E627EC6F71B4A3239E01ED76D85CBCAFFE92283E9408F770D9B8267DF5031C74C9F16CF43EB10881369DA46E692ACB2F94E9136FDA7FF58F54FFAD5749F79E5521D4358A0984AEC1B49C678FA6D6379905ABE4D245EBE854A09282945B4B62EDBDDF30954FBB9E40D751BBCD82ABE4BDC98274CB158F977802ED5E7F267A3F1EE0E6259215AD75798A6088D9AD6ACF4DF5DAA8474D1C8166AE244176D5AA2A7B2697C7C059DF78B07ACC2D47083F5058885E29FD9352243A5643C8237FBEF77F77AEEE32EC6455B4DB32A30ED02409FCBEF0C1C988876B0CBC85C89FA062824E1D35512E8C7731843CA7F6EB75C283F5F
-20200227155629 2 6 100 4095 2 DDFF38E32E0309D5459129AFA6C2F640C7125B85084C79BDD7042DA6E39D4A0DA4A671588016428ECAEC0F6BCC1A95E4B2BE518B7766CD0AC4674949D48B088492394DD9283C09D71CB4F4306E4CD27390575EBF2934E1C97AF880146F0D090DAB3AE1B679CF30AA52D307A8C64382C93F11AF73CAC171741A1C898CD79A680697D1A17A3D63F8C92A9C088E9E490D753D3A4811A8CAABEC2D80C62D66F56660995BC6D82BCCE18C4C6287B848F239C40467BB7EB3B7EB5489A7417D9DE8825FA86D16602AEF9BD3A523DB96B071C2BED3239B5C69AD772A39B18543F517F8BF49E6B5AE875A37E117010E8CA59947571DDC329FFD137998EC151B367525D0647001C4DADB2B95FBA9657A5619A0445E627EC6F71B4A3239E01ED76D85CBCAFFE92283E9408F770D9B8267DF5031C74C9F16CF43EB10881369DA46E692ACB2F94E9136FDA7FF58F54FFAD5749F79E5521D4358A0984AEC1B49C678FA6D6379905ABE4D245EBE854A09282945B4B62EDBDDF30954FBB9E40D751BBCD82ABE4BDC98274CB158F977802ED5E7F267A3F1EE0E6259215AD75798A6088D9AD6ACF4DF5DAA8474D1C8166AE244176D5AA2A7B2697C7C059DF78B07ACC2D47083F5058885E29FD9352243A5643C8237FBEF77F77AEEE32EC6455B4DB32A30ED02409FCBEF0C1C988876B0CBC85C89FA062824E1D35512E8C7731843CA7F6EB75C2FB09B
-20200227161922 2 6 100 4095 2 DDFF38E32E0309D5459129AFA6C2F640C7125B85084C79BDD7042DA6E39D4A0DA4A671588016428ECAEC0F6BCC1A95E4B2BE518B7766CD0AC4674949D48B088492394DD9283C09D71CB4F4306E4CD27390575EBF2934E1C97AF880146F0D090DAB3AE1B679CF30AA52D307A8C64382C93F11AF73CAC171741A1C898CD79A680697D1A17A3D63F8C92A9C088E9E490D753D3A4811A8CAABEC2D80C62D66F56660995BC6D82BCCE18C4C6287B848F239C40467BB7EB3B7EB5489A7417D9DE8825FA86D16602AEF9BD3A523DB96B071C2BED3239B5C69AD772A39B18543F517F8BF49E6B5AE875A37E117010E8CA59947571DDC329FFD137998EC151B367525D0647001C4DADB2B95FBA9657A5619A0445E627EC6F71B4A3239E01ED76D85CBCAFFE92283E9408F770D9B8267DF5031C74C9F16CF43EB10881369DA46E692ACB2F94E9136FDA7FF58F54FFAD5749F79E5521D4358A0984AEC1B49C678FA6D6379905ABE4D245EBE854A09282945B4B62EDBDDF30954FBB9E40D751BBCD82ABE4BDC98274CB158F977802ED5E7F267A3F1EE0E6259215AD75798A6088D9AD6ACF4DF5DAA8474D1C8166AE244176D5AA2A7B2697C7C059DF78B07ACC2D47083F5058885E29FD9352243A5643C8237FBEF77F77AEEE32EC6455B4DB32A30ED02409FCBEF0C1C988876B0CBC85C89FA062824E1D35512E8C7731843CA7F6EB75D8A8C4B
-20200227163034 2 6 100 4095 5 DDFF38E32E0309D5459129AFA6C2F640C7125B85084C79BDD7042DA6E39D4A0DA4A671588016428ECAEC0F6BCC1A95E4B2BE518B7766CD0AC4674949D48B088492394DD9283C09D71CB4F4306E4CD27390575EBF2934E1C97AF880146F0D090DAB3AE1B679CF30AA52D307A8C64382C93F11AF73CAC171741A1C898CD79A680697D1A17A3D63F8C92A9C088E9E490D753D3A4811A8CAABEC2D80C62D66F56660995BC6D82BCCE18C4C6287B848F239C40467BB7EB3B7EB5489A7417D9DE8825FA86D16602AEF9BD3A523DB96B071C2BED3239B5C69AD772A39B18543F517F8BF49E6B5AE875A37E117010E8CA59947571DDC329FFD137998EC151B367525D0647001C4DADB2B95FBA9657A5619A0445E627EC6F71B4A3239E01ED76D85CBCAFFE92283E9408F770D9B8267DF5031C74C9F16CF43EB10881369DA46E692ACB2F94E9136FDA7FF58F54FFAD5749F79E5521D4358A0984AEC1B49C678FA6D6379905ABE4D245EBE854A09282945B4B62EDBDDF30954FBB9E40D751BBCD82ABE4BDC98274CB158F977802ED5E7F267A3F1EE0E6259215AD75798A6088D9AD6ACF4DF5DAA8474D1C8166AE244176D5AA2A7B2697C7C059DF78B07ACC2D47083F5058885E29FD9352243A5643C8237FBEF77F77AEEE32EC6455B4DB32A30ED02409FCBEF0C1C988876B0CBC85C89FA062824E1D35512E8C7731843CA7F6EB75E3342C7
-20200227163725 2 6 100 4095 5 DDFF38E32E0309D5459129AFA6C2F640C7125B85084C79BDD7042DA6E39D4A0DA4A671588016428ECAEC0F6BCC1A95E4B2BE518B7766CD0AC4674949D48B088492394DD9283C09D71CB4F4306E4CD27390575EBF2934E1C97AF880146F0D090DAB3AE1B679CF30AA52D307A8C64382C93F11AF73CAC171741A1C898CD79A680697D1A17A3D63F8C92A9C088E9E490D753D3A4811A8CAABEC2D80C62D66F56660995BC6D82BCCE18C4C6287B848F239C40467BB7EB3B7EB5489A7417D9DE8825FA86D16602AEF9BD3A523DB96B071C2BED3239B5C69AD772A39B18543F517F8BF49E6B5AE875A37E117010E8CA59947571DDC329FFD137998EC151B367525D0647001C4DADB2B95FBA9657A5619A0445E627EC6F71B4A3239E01ED76D85CBCAFFE92283E9408F770D9B8267DF5031C74C9F16CF43EB10881369DA46E692ACB2F94E9136FDA7FF58F54FFAD5749F79E5521D4358A0984AEC1B49C678FA6D6379905ABE4D245EBE854A09282945B4B62EDBDDF30954FBB9E40D751BBCD82ABE4BDC98274CB158F977802ED5E7F267A3F1EE0E6259215AD75798A6088D9AD6ACF4DF5DAA8474D1C8166AE244176D5AA2A7B2697C7C059DF78B07ACC2D47083F5058885E29FD9352243A5643C8237FBEF77F77AEEE32EC6455B4DB32A30ED02409FCBEF0C1C988876B0CBC85C89FA062824E1D35512E8C7731843CA7F6EB75E9424E7
-20200227165111 2 6 100 4095 2 DDFF38E32E0309D5459129AFA6C2F640C7125B85084C79BDD7042DA6E39D4A0DA4A671588016428ECAEC0F6BCC1A95E4B2BE518B7766CD0AC4674949D48B088492394DD9283C09D71CB4F4306E4CD27390575EBF2934E1C97AF880146F0D090DAB3AE1B679CF30AA52D307A8C64382C93F11AF73CAC171741A1C898CD79A680697D1A17A3D63F8C92A9C088E9E490D753D3A4811A8CAABEC2D80C62D66F56660995BC6D82BCCE18C4C6287B848F239C40467BB7EB3B7EB5489A7417D9DE8825FA86D16602AEF9BD3A523DB96B071C2BED3239B5C69AD772A39B18543F517F8BF49E6B5AE875A37E117010E8CA59947571DDC329FFD137998EC151B367525D0647001C4DADB2B95FBA9657A5619A0445E627EC6F71B4A3239E01ED76D85CBCAFFE92283E9408F770D9B8267DF5031C74C9F16CF43EB10881369DA46E692ACB2F94E9136FDA7FF58F54FFAD5749F79E5521D4358A0984AEC1B49C678FA6D6379905ABE4D245EBE854A09282945B4B62EDBDDF30954FBB9E40D751BBCD82ABE4BDC98274CB158F977802ED5E7F267A3F1EE0E6259215AD75798A6088D9AD6ACF4DF5DAA8474D1C8166AE244176D5AA2A7B2697C7C059DF78B07ACC2D47083F5058885E29FD9352243A5643C8237FBEF77F77AEEE32EC6455B4DB32A30ED02409FCBEF0C1C988876B0CBC85C89FA062824E1D35512E8C7731843CA7F6EB75F623DC3
-20200227170513 2 6 100 4095 2 DDFF38E32E0309D5459129AFA6C2F640C7125B85084C79BDD7042DA6E39D4A0DA4A671588016428ECAEC0F6BCC1A95E4B2BE518B7766CD0AC4674949D48B088492394DD9283C09D71CB4F4306E4CD27390575EBF2934E1C97AF880146F0D090DAB3AE1B679CF30AA52D307A8C64382C93F11AF73CAC171741A1C898CD79A680697D1A17A3D63F8C92A9C088E9E490D753D3A4811A8CAABEC2D80C62D66F56660995BC6D82BCCE18C4C6287B848F239C40467BB7EB3B7EB5489A7417D9DE8825FA86D16602AEF9BD3A523DB96B071C2BED3239B5C69AD772A39B18543F517F8BF49E6B5AE875A37E117010E8CA59947571DDC329FFD137998EC151B367525D0647001C4DADB2B95FBA9657A5619A0445E627EC6F71B4A3239E01ED76D85CBCAFFE92283E9408F770D9B8267DF5031C74C9F16CF43EB10881369DA46E692ACB2F94E9136FDA7FF58F54FFAD5749F79E5521D4358A0984AEC1B49C678FA6D6379905ABE4D245EBE854A09282945B4B62EDBDDF30954FBB9E40D751BBCD82ABE4BDC98274CB158F977802ED5E7F267A3F1EE0E6259215AD75798A6088D9AD6ACF4DF5DAA8474D1C8166AE244176D5AA2A7B2697C7C059DF78B07ACC2D47083F5058885E29FD9352243A5643C8237FBEF77F77AEEE32EC6455B4DB32A30ED02409FCBEF0C1C988876B0CBC85C89FA062824E1D35512E8C7731843CA7F6EB7602FCE73
-20200227171514 2 6 100 4095 2 C7D5773A9200CD53CB4C9244931BB61A711BA1EA3735C53C933074E733E2DAFBBC1F737A508EA82790EF95F7989A889A8FFBC707E9A88090ED5FBA0F485638CBAC547DE653E9D80D09E8795B68C70570547E49D611E08F9D47AEFC22AE8D81D8863CAC593896D4B126CA806247C2954360BDAB96247050BE8C3D7E39C3C2D5B0C74811B0AC00CB338A3F48F7A799F86C563DE5EDAF8BE8A6220106899315714214FBDC466B240833E37029585311F49D8837BCC48A07CA56B505A9D42F14363C3950AB9F768307C2B627FA8DE1263663C251706BFA2F23C5B85CEBC3AFA399FC791D20F1B94C5DFD3E78665FE6846C8E213136E8CA5A24930DAE9EFEBD54616BB3EA08E5FB9346098F42F1593A5D5F1E3B73FE184F5CD674BE7F0C46171E0F83268B3C231C9B552449FA882EAA67EFA52399A3867DFD17248CF52450523777260F4FFE155AE5838A4F883EA27DE00AECE89B984F185A795C34DD71F4F424F919D7F32D48F2FBC9FBE41E631E6443397AA5E75B6AAC98619A9241A8D162DCBFD8EB1056E8ED62A655A2D50FAA162EF86DA4DEA51ECB168193F1C34C558335D27EC393C6AA1B789A23BBC08781011B2FCB2A02A7C33632BB33D1D5FB72E5C9FE9BEDEA1FC4079638D7FD6FFD965CF01ADB026D4638CE0A0D20E47BA0D9AD72ED5136A562AE955374E2A80809076AD250D7E8F59854A820BA342FB921518EE99203
-20200227180811 2 6 100 4095 2 C7D5773A9200CD53CB4C9244931BB61A711BA1EA3735C53C933074E733E2DAFBBC1F737A508EA82790EF95F7989A889A8FFBC707E9A88090ED5FBA0F485638CBAC547DE653E9D80D09E8795B68C70570547E49D611E08F9D47AEFC22AE8D81D8863CAC593896D4B126CA806247C2954360BDAB96247050BE8C3D7E39C3C2D5B0C74811B0AC00CB338A3F48F7A799F86C563DE5EDAF8BE8A6220106899315714214FBDC466B240833E37029585311F49D8837BCC48A07CA56B505A9D42F14363C3950AB9F768307C2B627FA8DE1263663C251706BFA2F23C5B85CEBC3AFA399FC791D20F1B94C5DFD3E78665FE6846C8E213136E8CA5A24930DAE9EFEBD54616BB3EA08E5FB9346098F42F1593A5D5F1E3B73FE184F5CD674BE7F0C46171E0F83268B3C231C9B552449FA882EAA67EFA52399A3867DFD17248CF52450523777260F4FFE155AE5838A4F883EA27DE00AECE89B984F185A795C34DD71F4F424F919D7F32D48F2FBC9FBE41E631E6443397AA5E75B6AAC98619A9241A8D162DCBFD8EB1056E8ED62A655A2D50FAA162EF86DA4DEA51ECB168193F1C34C558335D27EC393C6AA1B789A23BBC08781011B2FCB2A02A7C33632BB33D1D5FB72E5C9FE9BEDEA1FC4079638D7FD6FFD965CF01ADB026D4638CE0A0D20E47BA0D9AD72ED5136A562AE955374E2A80809076AD250D7E8F59854A820BA342FB92151924BA233
-20200227184341 2 6 100 4095 5 C7D5773A9200CD53CB4C9244931BB61A711BA1EA3735C53C933074E733E2DAFBBC1F737A508EA82790EF95F7989A889A8FFBC707E9A88090ED5FBA0F485638CBAC547DE653E9D80D09E8795B68C70570547E49D611E08F9D47AEFC22AE8D81D8863CAC593896D4B126CA806247C2954360BDAB96247050BE8C3D7E39C3C2D5B0C74811B0AC00CB338A3F48F7A799F86C563DE5EDAF8BE8A6220106899315714214FBDC466B240833E37029585311F49D8837BCC48A07CA56B505A9D42F14363C3950AB9F768307C2B627FA8DE1263663C251706BFA2F23C5B85CEBC3AFA399FC791D20F1B94C5DFD3E78665FE6846C8E213136E8CA5A24930DAE9EFEBD54616BB3EA08E5FB9346098F42F1593A5D5F1E3B73FE184F5CD674BE7F0C46171E0F83268B3C231C9B552449FA882EAA67EFA52399A3867DFD17248CF52450523777260F4FFE155AE5838A4F883EA27DE00AECE89B984F185A795C34DD71F4F424F919D7F32D48F2FBC9FBE41E631E6443397AA5E75B6AAC98619A9241A8D162DCBFD8EB1056E8ED62A655A2D50FAA162EF86DA4DEA51ECB168193F1C34C558335D27EC393C6AA1B789A23BBC08781011B2FCB2A02A7C33632BB33D1D5FB72E5C9FE9BEDEA1FC4079638D7FD6FFD965CF01ADB026D4638CE0A0D20E47BA0D9AD72ED5136A562AE955374E2A80809076AD250D7E8F59854A820BA342FB921519490B137
-20200227184640 2 6 100 4095 2 C7D5773A9200CD53CB4C9244931BB61A711BA1EA3735C53C933074E733E2DAFBBC1F737A508EA82790EF95F7989A889A8FFBC707E9A88090ED5FBA0F485638CBAC547DE653E9D80D09E8795B68C70570547E49D611E08F9D47AEFC22AE8D81D8863CAC593896D4B126CA806247C2954360BDAB96247050BE8C3D7E39C3C2D5B0C74811B0AC00CB338A3F48F7A799F86C563DE5EDAF8BE8A6220106899315714214FBDC466B240833E37029585311F49D8837BCC48A07CA56B505A9D42F14363C3950AB9F768307C2B627FA8DE1263663C251706BFA2F23C5B85CEBC3AFA399FC791D20F1B94C5DFD3E78665FE6846C8E213136E8CA5A24930DAE9EFEBD54616BB3EA08E5FB9346098F42F1593A5D5F1E3B73FE184F5CD674BE7F0C46171E0F83268B3C231C9B552449FA882EAA67EFA52399A3867DFD17248CF52450523777260F4FFE155AE5838A4F883EA27DE00AECE89B984F185A795C34DD71F4F424F919D7F32D48F2FBC9FBE41E631E6443397AA5E75B6AAC98619A9241A8D162DCBFD8EB1056E8ED62A655A2D50FAA162EF86DA4DEA51ECB168193F1C34C558335D27EC393C6AA1B789A23BBC08781011B2FCB2A02A7C33632BB33D1D5FB72E5C9FE9BEDEA1FC4079638D7FD6FFD965CF01ADB026D4638CE0A0D20E47BA0D9AD72ED5136A562AE955374E2A80809076AD250D7E8F59854A820BA342FB9215194B6E91B
-20200227185707 2 6 100 4095 2 C7D5773A9200CD53CB4C9244931BB61A711BA1EA3735C53C933074E733E2DAFBBC1F737A508EA82790EF95F7989A889A8FFBC707E9A88090ED5FBA0F485638CBAC547DE653E9D80D09E8795B68C70570547E49D611E08F9D47AEFC22AE8D81D8863CAC593896D4B126CA806247C2954360BDAB96247050BE8C3D7E39C3C2D5B0C74811B0AC00CB338A3F48F7A799F86C563DE5EDAF8BE8A6220106899315714214FBDC466B240833E37029585311F49D8837BCC48A07CA56B505A9D42F14363C3950AB9F768307C2B627FA8DE1263663C251706BFA2F23C5B85CEBC3AFA399FC791D20F1B94C5DFD3E78665FE6846C8E213136E8CA5A24930DAE9EFEBD54616BB3EA08E5FB9346098F42F1593A5D5F1E3B73FE184F5CD674BE7F0C46171E0F83268B3C231C9B552449FA882EAA67EFA52399A3867DFD17248CF52450523777260F4FFE155AE5838A4F883EA27DE00AECE89B984F185A795C34DD71F4F424F919D7F32D48F2FBC9FBE41E631E6443397AA5E75B6AAC98619A9241A8D162DCBFD8EB1056E8ED62A655A2D50FAA162EF86DA4DEA51ECB168193F1C34C558335D27EC393C6AA1B789A23BBC08781011B2FCB2A02A7C33632BB33D1D5FB72E5C9FE9BEDEA1FC4079638D7FD6FFD965CF01ADB026D4638CE0A0D20E47BA0D9AD72ED5136A562AE955374E2A80809076AD250D7E8F59854A820BA342FB9215195546D0B
-20200227192438 2 6 100 4095 2 C7D5773A9200CD53CB4C9244931BB61A711BA1EA3735C53C933074E733E2DAFBBC1F737A508EA82790EF95F7989A889A8FFBC707E9A88090ED5FBA0F485638CBAC547DE653E9D80D09E8795B68C70570547E49D611E08F9D47AEFC22AE8D81D8863CAC593896D4B126CA806247C2954360BDAB96247050BE8C3D7E39C3C2D5B0C74811B0AC00CB338A3F48F7A799F86C563DE5EDAF8BE8A6220106899315714214FBDC466B240833E37029585311F49D8837BCC48A07CA56B505A9D42F14363C3950AB9F768307C2B627FA8DE1263663C251706BFA2F23C5B85CEBC3AFA399FC791D20F1B94C5DFD3E78665FE6846C8E213136E8CA5A24930DAE9EFEBD54616BB3EA08E5FB9346098F42F1593A5D5F1E3B73FE184F5CD674BE7F0C46171E0F83268B3C231C9B552449FA882EAA67EFA52399A3867DFD17248CF52450523777260F4FFE155AE5838A4F883EA27DE00AECE89B984F185A795C34DD71F4F424F919D7F32D48F2FBC9FBE41E631E6443397AA5E75B6AAC98619A9241A8D162DCBFD8EB1056E8ED62A655A2D50FAA162EF86DA4DEA51ECB168193F1C34C558335D27EC393C6AA1B789A23BBC08781011B2FCB2A02A7C33632BB33D1D5FB72E5C9FE9BEDEA1FC4079638D7FD6FFD965CF01ADB026D4638CE0A0D20E47BA0D9AD72ED5136A562AE955374E2A80809076AD250D7E8F59854A820BA342FB9215196FF1A63
-20200227192937 2 6 100 4095 5 C7D5773A9200CD53CB4C9244931BB61A711BA1EA3735C53C933074E733E2DAFBBC1F737A508EA82790EF95F7989A889A8FFBC707E9A88090ED5FBA0F485638CBAC547DE653E9D80D09E8795B68C70570547E49D611E08F9D47AEFC22AE8D81D8863CAC593896D4B126CA806247C2954360BDAB96247050BE8C3D7E39C3C2D5B0C74811B0AC00CB338A3F48F7A799F86C563DE5EDAF8BE8A6220106899315714214FBDC466B240833E37029585311F49D8837BCC48A07CA56B505A9D42F14363C3950AB9F768307C2B627FA8DE1263663C251706BFA2F23C5B85CEBC3AFA399FC791D20F1B94C5DFD3E78665FE6846C8E213136E8CA5A24930DAE9EFEBD54616BB3EA08E5FB9346098F42F1593A5D5F1E3B73FE184F5CD674BE7F0C46171E0F83268B3C231C9B552449FA882EAA67EFA52399A3867DFD17248CF52450523777260F4FFE155AE5838A4F883EA27DE00AECE89B984F185A795C34DD71F4F424F919D7F32D48F2FBC9FBE41E631E6443397AA5E75B6AAC98619A9241A8D162DCBFD8EB1056E8ED62A655A2D50FAA162EF86DA4DEA51ECB168193F1C34C558335D27EC393C6AA1B789A23BBC08781011B2FCB2A02A7C33632BB33D1D5FB72E5C9FE9BEDEA1FC4079638D7FD6FFD965CF01ADB026D4638CE0A0D20E47BA0D9AD72ED5136A562AE955374E2A80809076AD250D7E8F59854A820BA342FB9215197470C5F
-20200227193545 2 6 100 4095 2 C7D5773A9200CD53CB4C9244931BB61A711BA1EA3735C53C933074E733E2DAFBBC1F737A508EA82790EF95F7989A889A8FFBC707E9A88090ED5FBA0F485638CBAC547DE653E9D80D09E8795B68C70570547E49D611E08F9D47AEFC22AE8D81D8863CAC593896D4B126CA806247C2954360BDAB96247050BE8C3D7E39C3C2D5B0C74811B0AC00CB338A3F48F7A799F86C563DE5EDAF8BE8A6220106899315714214FBDC466B240833E37029585311F49D8837BCC48A07CA56B505A9D42F14363C3950AB9F768307C2B627FA8DE1263663C251706BFA2F23C5B85CEBC3AFA399FC791D20F1B94C5DFD3E78665FE6846C8E213136E8CA5A24930DAE9EFEBD54616BB3EA08E5FB9346098F42F1593A5D5F1E3B73FE184F5CD674BE7F0C46171E0F83268B3C231C9B552449FA882EAA67EFA52399A3867DFD17248CF52450523777260F4FFE155AE5838A4F883EA27DE00AECE89B984F185A795C34DD71F4F424F919D7F32D48F2FBC9FBE41E631E6443397AA5E75B6AAC98619A9241A8D162DCBFD8EB1056E8ED62A655A2D50FAA162EF86DA4DEA51ECB168193F1C34C558335D27EC393C6AA1B789A23BBC08781011B2FCB2A02A7C33632BB33D1D5FB72E5C9FE9BEDEA1FC4079638D7FD6FFD965CF01ADB026D4638CE0A0D20E47BA0D9AD72ED5136A562AE955374E2A80809076AD250D7E8F59854A820BA342FB9215197A3CACB
-20200227193904 2 6 100 4095 5 C7D5773A9200CD53CB4C9244931BB61A711BA1EA3735C53C933074E733E2DAFBBC1F737A508EA82790EF95F7989A889A8FFBC707E9A88090ED5FBA0F485638CBAC547DE653E9D80D09E8795B68C70570547E49D611E08F9D47AEFC22AE8D81D8863CAC593896D4B126CA806247C2954360BDAB96247050BE8C3D7E39C3C2D5B0C74811B0AC00CB338A3F48F7A799F86C563DE5EDAF8BE8A6220106899315714214FBDC466B240833E37029585311F49D8837BCC48A07CA56B505A9D42F14363C3950AB9F768307C2B627FA8DE1263663C251706BFA2F23C5B85CEBC3AFA399FC791D20F1B94C5DFD3E78665FE6846C8E213136E8CA5A24930DAE9EFEBD54616BB3EA08E5FB9346098F42F1593A5D5F1E3B73FE184F5CD674BE7F0C46171E0F83268B3C231C9B552449FA882EAA67EFA52399A3867DFD17248CF52450523777260F4FFE155AE5838A4F883EA27DE00AECE89B984F185A795C34DD71F4F424F919D7F32D48F2FBC9FBE41E631E6443397AA5E75B6AAC98619A9241A8D162DCBFD8EB1056E8ED62A655A2D50FAA162EF86DA4DEA51ECB168193F1C34C558335D27EC393C6AA1B789A23BBC08781011B2FCB2A02A7C33632BB33D1D5FB72E5C9FE9BEDEA1FC4079638D7FD6FFD965CF01ADB026D4638CE0A0D20E47BA0D9AD72ED5136A562AE955374E2A80809076AD250D7E8F59854A820BA342FB9215197CFA597
-20200227201541 2 6 100 4095 5 C7D5773A9200CD53CB4C9244931BB61A711BA1EA3735C53C933074E733E2DAFBBC1F737A508EA82790EF95F7989A889A8FFBC707E9A88090ED5FBA0F485638CBAC547DE653E9D80D09E8795B68C70570547E49D611E08F9D47AEFC22AE8D81D8863CAC593896D4B126CA806247C2954360BDAB96247050BE8C3D7E39C3C2D5B0C74811B0AC00CB338A3F48F7A799F86C563DE5EDAF8BE8A6220106899315714214FBDC466B240833E37029585311F49D8837BCC48A07CA56B505A9D42F14363C3950AB9F768307C2B627FA8DE1263663C251706BFA2F23C5B85CEBC3AFA399FC791D20F1B94C5DFD3E78665FE6846C8E213136E8CA5A24930DAE9EFEBD54616BB3EA08E5FB9346098F42F1593A5D5F1E3B73FE184F5CD674BE7F0C46171E0F83268B3C231C9B552449FA882EAA67EFA52399A3867DFD17248CF52450523777260F4FFE155AE5838A4F883EA27DE00AECE89B984F185A795C34DD71F4F424F919D7F32D48F2FBC9FBE41E631E6443397AA5E75B6AAC98619A9241A8D162DCBFD8EB1056E8ED62A655A2D50FAA162EF86DA4DEA51ECB168193F1C34C558335D27EC393C6AA1B789A23BBC08781011B2FCB2A02A7C33632BB33D1D5FB72E5C9FE9BEDEA1FC4079638D7FD6FFD965CF01ADB026D4638CE0A0D20E47BA0D9AD72ED5136A562AE955374E2A80809076AD250D7E8F59854A820BA342FB921519A1D5807
-20200227201830 2 6 100 4095 2 C7D5773A9200CD53CB4C9244931BB61A711BA1EA3735C53C933074E733E2DAFBBC1F737A508EA82790EF95F7989A889A8FFBC707E9A88090ED5FBA0F485638CBAC547DE653E9D80D09E8795B68C70570547E49D611E08F9D47AEFC22AE8D81D8863CAC593896D4B126CA806247C2954360BDAB96247050BE8C3D7E39C3C2D5B0C74811B0AC00CB338A3F48F7A799F86C563DE5EDAF8BE8A6220106899315714214FBDC466B240833E37029585311F49D8837BCC48A07CA56B505A9D42F14363C3950AB9F768307C2B627FA8DE1263663C251706BFA2F23C5B85CEBC3AFA399FC791D20F1B94C5DFD3E78665FE6846C8E213136E8CA5A24930DAE9EFEBD54616BB3EA08E5FB9346098F42F1593A5D5F1E3B73FE184F5CD674BE7F0C46171E0F83268B3C231C9B552449FA882EAA67EFA52399A3867DFD17248CF52450523777260F4FFE155AE5838A4F883EA27DE00AECE89B984F185A795C34DD71F4F424F919D7F32D48F2FBC9FBE41E631E6443397AA5E75B6AAC98619A9241A8D162DCBFD8EB1056E8ED62A655A2D50FAA162EF86DA4DEA51ECB168193F1C34C558335D27EC393C6AA1B789A23BBC08781011B2FCB2A02A7C33632BB33D1D5FB72E5C9FE9BEDEA1FC4079638D7FD6FFD965CF01ADB026D4638CE0A0D20E47BA0D9AD72ED5136A562AE955374E2A80809076AD250D7E8F59854A820BA342FB921519A3EDD33
-20200227202555 2 6 100 4095 2 C7D5773A9200CD53CB4C9244931BB61A711BA1EA3735C53C933074E733E2DAFBBC1F737A508EA82790EF95F7989A889A8FFBC707E9A88090ED5FBA0F485638CBAC547DE653E9D80D09E8795B68C70570547E49D611E08F9D47AEFC22AE8D81D8863CAC593896D4B126CA806247C2954360BDAB96247050BE8C3D7E39C3C2D5B0C74811B0AC00CB338A3F48F7A799F86C563DE5EDAF8BE8A6220106899315714214FBDC466B240833E37029585311F49D8837BCC48A07CA56B505A9D42F14363C3950AB9F768307C2B627FA8DE1263663C251706BFA2F23C5B85CEBC3AFA399FC791D20F1B94C5DFD3E78665FE6846C8E213136E8CA5A24930DAE9EFEBD54616BB3EA08E5FB9346098F42F1593A5D5F1E3B73FE184F5CD674BE7F0C46171E0F83268B3C231C9B552449FA882EAA67EFA52399A3867DFD17248CF52450523777260F4FFE155AE5838A4F883EA27DE00AECE89B984F185A795C34DD71F4F424F919D7F32D48F2FBC9FBE41E631E6443397AA5E75B6AAC98619A9241A8D162DCBFD8EB1056E8ED62A655A2D50FAA162EF86DA4DEA51ECB168193F1C34C558335D27EC393C6AA1B789A23BBC08781011B2FCB2A02A7C33632BB33D1D5FB72E5C9FE9BEDEA1FC4079638D7FD6FFD965CF01ADB026D4638CE0A0D20E47BA0D9AD72ED5136A562AE955374E2A80809076AD250D7E8F59854A820BA342FB921519AAFD1D3
-20200227202936 2 6 100 4095 2 C7D5773A9200CD53CB4C9244931BB61A711BA1EA3735C53C933074E733E2DAFBBC1F737A508EA82790EF95F7989A889A8FFBC707E9A88090ED5FBA0F485638CBAC547DE653E9D80D09E8795B68C70570547E49D611E08F9D47AEFC22AE8D81D8863CAC593896D4B126CA806247C2954360BDAB96247050BE8C3D7E39C3C2D5B0C74811B0AC00CB338A3F48F7A799F86C563DE5EDAF8BE8A6220106899315714214FBDC466B240833E37029585311F49D8837BCC48A07CA56B505A9D42F14363C3950AB9F768307C2B627FA8DE1263663C251706BFA2F23C5B85CEBC3AFA399FC791D20F1B94C5DFD3E78665FE6846C8E213136E8CA5A24930DAE9EFEBD54616BB3EA08E5FB9346098F42F1593A5D5F1E3B73FE184F5CD674BE7F0C46171E0F83268B3C231C9B552449FA882EAA67EFA52399A3867DFD17248CF52450523777260F4FFE155AE5838A4F883EA27DE00AECE89B984F185A795C34DD71F4F424F919D7F32D48F2FBC9FBE41E631E6443397AA5E75B6AAC98619A9241A8D162DCBFD8EB1056E8ED62A655A2D50FAA162EF86DA4DEA51ECB168193F1C34C558335D27EC393C6AA1B789A23BBC08781011B2FCB2A02A7C33632BB33D1D5FB72E5C9FE9BEDEA1FC4079638D7FD6FFD965CF01ADB026D4638CE0A0D20E47BA0D9AD72ED5136A562AE955374E2A80809076AD250D7E8F59854A820BA342FB921519AE21FCB
-20200227203051 2 6 100 4095 2 C7D5773A9200CD53CB4C9244931BB61A711BA1EA3735C53C933074E733E2DAFBBC1F737A508EA82790EF95F7989A889A8FFBC707E9A88090ED5FBA0F485638CBAC547DE653E9D80D09E8795B68C70570547E49D611E08F9D47AEFC22AE8D81D8863CAC593896D4B126CA806247C2954360BDAB96247050BE8C3D7E39C3C2D5B0C74811B0AC00CB338A3F48F7A799F86C563DE5EDAF8BE8A6220106899315714214FBDC466B240833E37029585311F49D8837BCC48A07CA56B505A9D42F14363C3950AB9F768307C2B627FA8DE1263663C251706BFA2F23C5B85CEBC3AFA399FC791D20F1B94C5DFD3E78665FE6846C8E213136E8CA5A24930DAE9EFEBD54616BB3EA08E5FB9346098F42F1593A5D5F1E3B73FE184F5CD674BE7F0C46171E0F83268B3C231C9B552449FA882EAA67EFA52399A3867DFD17248CF52450523777260F4FFE155AE5838A4F883EA27DE00AECE89B984F185A795C34DD71F4F424F919D7F32D48F2FBC9FBE41E631E6443397AA5E75B6AAC98619A9241A8D162DCBFD8EB1056E8ED62A655A2D50FAA162EF86DA4DEA51ECB168193F1C34C558335D27EC393C6AA1B789A23BBC08781011B2FCB2A02A7C33632BB33D1D5FB72E5C9FE9BEDEA1FC4079638D7FD6FFD965CF01ADB026D4638CE0A0D20E47BA0D9AD72ED5136A562AE955374E2A80809076AD250D7E8F59854A820BA342FB921519AEDB593
-20200227203917 2 6 100 4095 2 C7D5773A9200CD53CB4C9244931BB61A711BA1EA3735C53C933074E733E2DAFBBC1F737A508EA82790EF95F7989A889A8FFBC707E9A88090ED5FBA0F485638CBAC547DE653E9D80D09E8795B68C70570547E49D611E08F9D47AEFC22AE8D81D8863CAC593896D4B126CA806247C2954360BDAB96247050BE8C3D7E39C3C2D5B0C74811B0AC00CB338A3F48F7A799F86C563DE5EDAF8BE8A6220106899315714214FBDC466B240833E37029585311F49D8837BCC48A07CA56B505A9D42F14363C3950AB9F768307C2B627FA8DE1263663C251706BFA2F23C5B85CEBC3AFA399FC791D20F1B94C5DFD3E78665FE6846C8E213136E8CA5A24930DAE9EFEBD54616BB3EA08E5FB9346098F42F1593A5D5F1E3B73FE184F5CD674BE7F0C46171E0F83268B3C231C9B552449FA882EAA67EFA52399A3867DFD17248CF52450523777260F4FFE155AE5838A4F883EA27DE00AECE89B984F185A795C34DD71F4F424F919D7F32D48F2FBC9FBE41E631E6443397AA5E75B6AAC98619A9241A8D162DCBFD8EB1056E8ED62A655A2D50FAA162EF86DA4DEA51ECB168193F1C34C558335D27EC393C6AA1B789A23BBC08781011B2FCB2A02A7C33632BB33D1D5FB72E5C9FE9BEDEA1FC4079638D7FD6FFD965CF01ADB026D4638CE0A0D20E47BA0D9AD72ED5136A562AE955374E2A80809076AD250D7E8F59854A820BA342FB921519B6FE6A3
-20200227205155 2 6 100 4095 2 C7D5773A9200CD53CB4C9244931BB61A711BA1EA3735C53C933074E733E2DAFBBC1F737A508EA82790EF95F7989A889A8FFBC707E9A88090ED5FBA0F485638CBAC547DE653E9D80D09E8795B68C70570547E49D611E08F9D47AEFC22AE8D81D8863CAC593896D4B126CA806247C2954360BDAB96247050BE8C3D7E39C3C2D5B0C74811B0AC00CB338A3F48F7A799F86C563DE5EDAF8BE8A6220106899315714214FBDC466B240833E37029585311F49D8837BCC48A07CA56B505A9D42F14363C3950AB9F768307C2B627FA8DE1263663C251706BFA2F23C5B85CEBC3AFA399FC791D20F1B94C5DFD3E78665FE6846C8E213136E8CA5A24930DAE9EFEBD54616BB3EA08E5FB9346098F42F1593A5D5F1E3B73FE184F5CD674BE7F0C46171E0F83268B3C231C9B552449FA882EAA67EFA52399A3867DFD17248CF52450523777260F4FFE155AE5838A4F883EA27DE00AECE89B984F185A795C34DD71F4F424F919D7F32D48F2FBC9FBE41E631E6443397AA5E75B6AAC98619A9241A8D162DCBFD8EB1056E8ED62A655A2D50FAA162EF86DA4DEA51ECB168193F1C34C558335D27EC393C6AA1B789A23BBC08781011B2FCB2A02A7C33632BB33D1D5FB72E5C9FE9BEDEA1FC4079638D7FD6FFD965CF01ADB026D4638CE0A0D20E47BA0D9AD72ED5136A562AE955374E2A80809076AD250D7E8F59854A820BA342FB921519C3628EB
-20200227210720 2 6 100 4095 2 C7D5773A9200CD53CB4C9244931BB61A711BA1EA3735C53C933074E733E2DAFBBC1F737A508EA82790EF95F7989A889A8FFBC707E9A88090ED5FBA0F485638CBAC547DE653E9D80D09E8795B68C70570547E49D611E08F9D47AEFC22AE8D81D8863CAC593896D4B126CA806247C2954360BDAB96247050BE8C3D7E39C3C2D5B0C74811B0AC00CB338A3F48F7A799F86C563DE5EDAF8BE8A6220106899315714214FBDC466B240833E37029585311F49D8837BCC48A07CA56B505A9D42F14363C3950AB9F768307C2B627FA8DE1263663C251706BFA2F23C5B85CEBC3AFA399FC791D20F1B94C5DFD3E78665FE6846C8E213136E8CA5A24930DAE9EFEBD54616BB3EA08E5FB9346098F42F1593A5D5F1E3B73FE184F5CD674BE7F0C46171E0F83268B3C231C9B552449FA882EAA67EFA52399A3867DFD17248CF52450523777260F4FFE155AE5838A4F883EA27DE00AECE89B984F185A795C34DD71F4F424F919D7F32D48F2FBC9FBE41E631E6443397AA5E75B6AAC98619A9241A8D162DCBFD8EB1056E8ED62A655A2D50FAA162EF86DA4DEA51ECB168193F1C34C558335D27EC393C6AA1B789A23BBC08781011B2FCB2A02A7C33632BB33D1D5FB72E5C9FE9BEDEA1FC4079638D7FD6FFD965CF01ADB026D4638CE0A0D20E47BA0D9AD72ED5136A562AE955374E2A80809076AD250D7E8F59854A820BA342FB921519D1EC08B
-20200227211425 2 6 100 4095 5 C7D5773A9200CD53CB4C9244931BB61A711BA1EA3735C53C933074E733E2DAFBBC1F737A508EA82790EF95F7989A889A8FFBC707E9A88090ED5FBA0F485638CBAC547DE653E9D80D09E8795B68C70570547E49D611E08F9D47AEFC22AE8D81D8863CAC593896D4B126CA806247C2954360BDAB96247050BE8C3D7E39C3C2D5B0C74811B0AC00CB338A3F48F7A799F86C563DE5EDAF8BE8A6220106899315714214FBDC466B240833E37029585311F49D8837BCC48A07CA56B505A9D42F14363C3950AB9F768307C2B627FA8DE1263663C251706BFA2F23C5B85CEBC3AFA399FC791D20F1B94C5DFD3E78665FE6846C8E213136E8CA5A24930DAE9EFEBD54616BB3EA08E5FB9346098F42F1593A5D5F1E3B73FE184F5CD674BE7F0C46171E0F83268B3C231C9B552449FA882EAA67EFA52399A3867DFD17248CF52450523777260F4FFE155AE5838A4F883EA27DE00AECE89B984F185A795C34DD71F4F424F919D7F32D48F2FBC9FBE41E631E6443397AA5E75B6AAC98619A9241A8D162DCBFD8EB1056E8ED62A655A2D50FAA162EF86DA4DEA51ECB168193F1C34C558335D27EC393C6AA1B789A23BBC08781011B2FCB2A02A7C33632BB33D1D5FB72E5C9FE9BEDEA1FC4079638D7FD6FFD965CF01ADB026D4638CE0A0D20E47BA0D9AD72ED5136A562AE955374E2A80809076AD250D7E8F59854A820BA342FB921519D892927
-20200227211637 2 6 100 4095 2 C7D5773A9200CD53CB4C9244931BB61A711BA1EA3735C53C933074E733E2DAFBBC1F737A508EA82790EF95F7989A889A8FFBC707E9A88090ED5FBA0F485638CBAC547DE653E9D80D09E8795B68C70570547E49D611E08F9D47AEFC22AE8D81D8863CAC593896D4B126CA806247C2954360BDAB96247050BE8C3D7E39C3C2D5B0C74811B0AC00CB338A3F48F7A799F86C563DE5EDAF8BE8A6220106899315714214FBDC466B240833E37029585311F49D8837BCC48A07CA56B505A9D42F14363C3950AB9F768307C2B627FA8DE1263663C251706BFA2F23C5B85CEBC3AFA399FC791D20F1B94C5DFD3E78665FE6846C8E213136E8CA5A24930DAE9EFEBD54616BB3EA08E5FB9346098F42F1593A5D5F1E3B73FE184F5CD674BE7F0C46171E0F83268B3C231C9B552449FA882EAA67EFA52399A3867DFD17248CF52450523777260F4FFE155AE5838A4F883EA27DE00AECE89B984F185A795C34DD71F4F424F919D7F32D48F2FBC9FBE41E631E6443397AA5E75B6AAC98619A9241A8D162DCBFD8EB1056E8ED62A655A2D50FAA162EF86DA4DEA51ECB168193F1C34C558335D27EC393C6AA1B789A23BBC08781011B2FCB2A02A7C33632BB33D1D5FB72E5C9FE9BEDEA1FC4079638D7FD6FFD965CF01ADB026D4638CE0A0D20E47BA0D9AD72ED5136A562AE955374E2A80809076AD250D7E8F59854A820BA342FB921519DA3F85B
-20200227212024 2 6 100 4095 5 C7D5773A9200CD53CB4C9244931BB61A711BA1EA3735C53C933074E733E2DAFBBC1F737A508EA82790EF95F7989A889A8FFBC707E9A88090ED5FBA0F485638CBAC547DE653E9D80D09E8795B68C70570547E49D611E08F9D47AEFC22AE8D81D8863CAC593896D4B126CA806247C2954360BDAB96247050BE8C3D7E39C3C2D5B0C74811B0AC00CB338A3F48F7A799F86C563DE5EDAF8BE8A6220106899315714214FBDC466B240833E37029585311F49D8837BCC48A07CA56B505A9D42F14363C3950AB9F768307C2B627FA8DE1263663C251706BFA2F23C5B85CEBC3AFA399FC791D20F1B94C5DFD3E78665FE6846C8E213136E8CA5A24930DAE9EFEBD54616BB3EA08E5FB9346098F42F1593A5D5F1E3B73FE184F5CD674BE7F0C46171E0F83268B3C231C9B552449FA882EAA67EFA52399A3867DFD17248CF52450523777260F4FFE155AE5838A4F883EA27DE00AECE89B984F185A795C34DD71F4F424F919D7F32D48F2FBC9FBE41E631E6443397AA5E75B6AAC98619A9241A8D162DCBFD8EB1056E8ED62A655A2D50FAA162EF86DA4DEA51ECB168193F1C34C558335D27EC393C6AA1B789A23BBC08781011B2FCB2A02A7C33632BB33D1D5FB72E5C9FE9BEDEA1FC4079638D7FD6FFD965CF01ADB026D4638CE0A0D20E47BA0D9AD72ED5136A562AE955374E2A80809076AD250D7E8F59854A820BA342FB921519DD7AC4F
-20200227212617 2 6 100 4095 2 C7D5773A9200CD53CB4C9244931BB61A711BA1EA3735C53C933074E733E2DAFBBC1F737A508EA82790EF95F7989A889A8FFBC707E9A88090ED5FBA0F485638CBAC547DE653E9D80D09E8795B68C70570547E49D611E08F9D47AEFC22AE8D81D8863CAC593896D4B126CA806247C2954360BDAB96247050BE8C3D7E39C3C2D5B0C74811B0AC00CB338A3F48F7A799F86C563DE5EDAF8BE8A6220106899315714214FBDC466B240833E37029585311F49D8837BCC48A07CA56B505A9D42F14363C3950AB9F768307C2B627FA8DE1263663C251706BFA2F23C5B85CEBC3AFA399FC791D20F1B94C5DFD3E78665FE6846C8E213136E8CA5A24930DAE9EFEBD54616BB3EA08E5FB9346098F42F1593A5D5F1E3B73FE184F5CD674BE7F0C46171E0F83268B3C231C9B552449FA882EAA67EFA52399A3867DFD17248CF52450523777260F4FFE155AE5838A4F883EA27DE00AECE89B984F185A795C34DD71F4F424F919D7F32D48F2FBC9FBE41E631E6443397AA5E75B6AAC98619A9241A8D162DCBFD8EB1056E8ED62A655A2D50FAA162EF86DA4DEA51ECB168193F1C34C558335D27EC393C6AA1B789A23BBC08781011B2FCB2A02A7C33632BB33D1D5FB72E5C9FE9BEDEA1FC4079638D7FD6FFD965CF01ADB026D4638CE0A0D20E47BA0D9AD72ED5136A562AE955374E2A80809076AD250D7E8F59854A820BA342FB921519E2E0AD3
-20200227213638 2 6 100 4095 2 C7D5773A9200CD53CB4C9244931BB61A711BA1EA3735C53C933074E733E2DAFBBC1F737A508EA82790EF95F7989A889A8FFBC707E9A88090ED5FBA0F485638CBAC547DE653E9D80D09E8795B68C70570547E49D611E08F9D47AEFC22AE8D81D8863CAC593896D4B126CA806247C2954360BDAB96247050BE8C3D7E39C3C2D5B0C74811B0AC00CB338A3F48F7A799F86C563DE5EDAF8BE8A6220106899315714214FBDC466B240833E37029585311F49D8837BCC48A07CA56B505A9D42F14363C3950AB9F768307C2B627FA8DE1263663C251706BFA2F23C5B85CEBC3AFA399FC791D20F1B94C5DFD3E78665FE6846C8E213136E8CA5A24930DAE9EFEBD54616BB3EA08E5FB9346098F42F1593A5D5F1E3B73FE184F5CD674BE7F0C46171E0F83268B3C231C9B552449FA882EAA67EFA52399A3867DFD17248CF52450523777260F4FFE155AE5838A4F883EA27DE00AECE89B984F185A795C34DD71F4F424F919D7F32D48F2FBC9FBE41E631E6443397AA5E75B6AAC98619A9241A8D162DCBFD8EB1056E8ED62A655A2D50FAA162EF86DA4DEA51ECB168193F1C34C558335D27EC393C6AA1B789A23BBC08781011B2FCB2A02A7C33632BB33D1D5FB72E5C9FE9BEDEA1FC4079638D7FD6FFD965CF01ADB026D4638CE0A0D20E47BA0D9AD72ED5136A562AE955374E2A80809076AD250D7E8F59854A820BA342FB921519ECA5D23
-20200227213802 2 6 100 4095 2 C7D5773A9200CD53CB4C9244931BB61A711BA1EA3735C53C933074E733E2DAFBBC1F737A508EA82790EF95F7989A889A8FFBC707E9A88090ED5FBA0F485638CBAC547DE653E9D80D09E8795B68C70570547E49D611E08F9D47AEFC22AE8D81D8863CAC593896D4B126CA806247C2954360BDAB96247050BE8C3D7E39C3C2D5B0C74811B0AC00CB338A3F48F7A799F86C563DE5EDAF8BE8A6220106899315714214FBDC466B240833E37029585311F49D8837BCC48A07CA56B505A9D42F14363C3950AB9F768307C2B627FA8DE1263663C251706BFA2F23C5B85CEBC3AFA399FC791D20F1B94C5DFD3E78665FE6846C8E213136E8CA5A24930DAE9EFEBD54616BB3EA08E5FB9346098F42F1593A5D5F1E3B73FE184F5CD674BE7F0C46171E0F83268B3C231C9B552449FA882EAA67EFA52399A3867DFD17248CF52450523777260F4FFE155AE5838A4F883EA27DE00AECE89B984F185A795C34DD71F4F424F919D7F32D48F2FBC9FBE41E631E6443397AA5E75B6AAC98619A9241A8D162DCBFD8EB1056E8ED62A655A2D50FAA162EF86DA4DEA51ECB168193F1C34C558335D27EC393C6AA1B789A23BBC08781011B2FCB2A02A7C33632BB33D1D5FB72E5C9FE9BEDEA1FC4079638D7FD6FFD965CF01ADB026D4638CE0A0D20E47BA0D9AD72ED5136A562AE955374E2A80809076AD250D7E8F59854A820BA342FB921519ED8B3EB
-20200227215450 2 6 100 4095 2 C7D5773A9200CD53CB4C9244931BB61A711BA1EA3735C53C933074E733E2DAFBBC1F737A508EA82790EF95F7989A889A8FFBC707E9A88090ED5FBA0F485638CBAC547DE653E9D80D09E8795B68C70570547E49D611E08F9D47AEFC22AE8D81D8863CAC593896D4B126CA806247C2954360BDAB96247050BE8C3D7E39C3C2D5B0C74811B0AC00CB338A3F48F7A799F86C563DE5EDAF8BE8A6220106899315714214FBDC466B240833E37029585311F49D8837BCC48A07CA56B505A9D42F14363C3950AB9F768307C2B627FA8DE1263663C251706BFA2F23C5B85CEBC3AFA399FC791D20F1B94C5DFD3E78665FE6846C8E213136E8CA5A24930DAE9EFEBD54616BB3EA08E5FB9346098F42F1593A5D5F1E3B73FE184F5CD674BE7F0C46171E0F83268B3C231C9B552449FA882EAA67EFA52399A3867DFD17248CF52450523777260F4FFE155AE5838A4F883EA27DE00AECE89B984F185A795C34DD71F4F424F919D7F32D48F2FBC9FBE41E631E6443397AA5E75B6AAC98619A9241A8D162DCBFD8EB1056E8ED62A655A2D50FAA162EF86DA4DEA51ECB168193F1C34C558335D27EC393C6AA1B789A23BBC08781011B2FCB2A02A7C33632BB33D1D5FB72E5C9FE9BEDEA1FC4079638D7FD6FFD965CF01ADB026D4638CE0A0D20E47BA0D9AD72ED5136A562AE955374E2A80809076AD250D7E8F59854A820BA342FB921519FDD53D3
-20200227221218 2 6 100 4095 5 C7D5773A9200CD53CB4C9244931BB61A711BA1EA3735C53C933074E733E2DAFBBC1F737A508EA82790EF95F7989A889A8FFBC707E9A88090ED5FBA0F485638CBAC547DE653E9D80D09E8795B68C70570547E49D611E08F9D47AEFC22AE8D81D8863CAC593896D4B126CA806247C2954360BDAB96247050BE8C3D7E39C3C2D5B0C74811B0AC00CB338A3F48F7A799F86C563DE5EDAF8BE8A6220106899315714214FBDC466B240833E37029585311F49D8837BCC48A07CA56B505A9D42F14363C3950AB9F768307C2B627FA8DE1263663C251706BFA2F23C5B85CEBC3AFA399FC791D20F1B94C5DFD3E78665FE6846C8E213136E8CA5A24930DAE9EFEBD54616BB3EA08E5FB9346098F42F1593A5D5F1E3B73FE184F5CD674BE7F0C46171E0F83268B3C231C9B552449FA882EAA67EFA52399A3867DFD17248CF52450523777260F4FFE155AE5838A4F883EA27DE00AECE89B984F185A795C34DD71F4F424F919D7F32D48F2FBC9FBE41E631E6443397AA5E75B6AAC98619A9241A8D162DCBFD8EB1056E8ED62A655A2D50FAA162EF86DA4DEA51ECB168193F1C34C558335D27EC393C6AA1B789A23BBC08781011B2FCB2A02A7C33632BB33D1D5FB72E5C9FE9BEDEA1FC4079638D7FD6FFD965CF01ADB026D4638CE0A0D20E47BA0D9AD72ED5136A562AE955374E2A80809076AD250D7E8F59854A820BA342FB92151A0ECC74F
-20200227221341 2 6 100 4095 2 C7D5773A9200CD53CB4C9244931BB61A711BA1EA3735C53C933074E733E2DAFBBC1F737A508EA82790EF95F7989A889A8FFBC707E9A88090ED5FBA0F485638CBAC547DE653E9D80D09E8795B68C70570547E49D611E08F9D47AEFC22AE8D81D8863CAC593896D4B126CA806247C2954360BDAB96247050BE8C3D7E39C3C2D5B0C74811B0AC00CB338A3F48F7A799F86C563DE5EDAF8BE8A6220106899315714214FBDC466B240833E37029585311F49D8837BCC48A07CA56B505A9D42F14363C3950AB9F768307C2B627FA8DE1263663C251706BFA2F23C5B85CEBC3AFA399FC791D20F1B94C5DFD3E78665FE6846C8E213136E8CA5A24930DAE9EFEBD54616BB3EA08E5FB9346098F42F1593A5D5F1E3B73FE184F5CD674BE7F0C46171E0F83268B3C231C9B552449FA882EAA67EFA52399A3867DFD17248CF52450523777260F4FFE155AE5838A4F883EA27DE00AECE89B984F185A795C34DD71F4F424F919D7F32D48F2FBC9FBE41E631E6443397AA5E75B6AAC98619A9241A8D162DCBFD8EB1056E8ED62A655A2D50FAA162EF86DA4DEA51ECB168193F1C34C558335D27EC393C6AA1B789A23BBC08781011B2FCB2A02A7C33632BB33D1D5FB72E5C9FE9BEDEA1FC4079638D7FD6FFD965CF01ADB026D4638CE0A0D20E47BA0D9AD72ED5136A562AE955374E2A80809076AD250D7E8F59854A820BA342FB92151A0FA2D4B
-20200227222437 2 6 100 4095 2 C7D5773A9200CD53CB4C9244931BB61A711BA1EA3735C53C933074E733E2DAFBBC1F737A508EA82790EF95F7989A889A8FFBC707E9A88090ED5FBA0F485638CBAC547DE653E9D80D09E8795B68C70570547E49D611E08F9D47AEFC22AE8D81D8863CAC593896D4B126CA806247C2954360BDAB96247050BE8C3D7E39C3C2D5B0C74811B0AC00CB338A3F48F7A799F86C563DE5EDAF8BE8A6220106899315714214FBDC466B240833E37029585311F49D8837BCC48A07CA56B505A9D42F14363C3950AB9F768307C2B627FA8DE1263663C251706BFA2F23C5B85CEBC3AFA399FC791D20F1B94C5DFD3E78665FE6846C8E213136E8CA5A24930DAE9EFEBD54616BB3EA08E5FB9346098F42F1593A5D5F1E3B73FE184F5CD674BE7F0C46171E0F83268B3C231C9B552449FA882EAA67EFA52399A3867DFD17248CF52450523777260F4FFE155AE5838A4F883EA27DE00AECE89B984F185A795C34DD71F4F424F919D7F32D48F2FBC9FBE41E631E6443397AA5E75B6AAC98619A9241A8D162DCBFD8EB1056E8ED62A655A2D50FAA162EF86DA4DEA51ECB168193F1C34C558335D27EC393C6AA1B789A23BBC08781011B2FCB2A02A7C33632BB33D1D5FB72E5C9FE9BEDEA1FC4079638D7FD6FFD965CF01ADB026D4638CE0A0D20E47BA0D9AD72ED5136A562AE955374E2A80809076AD250D7E8F59854A820BA342FB92151A19ED9DB
-20200227223018 2 6 100 4095 5 C7D5773A9200CD53CB4C9244931BB61A711BA1EA3735C53C933074E733E2DAFBBC1F737A508EA82790EF95F7989A889A8FFBC707E9A88090ED5FBA0F485638CBAC547DE653E9D80D09E8795B68C70570547E49D611E08F9D47AEFC22AE8D81D8863CAC593896D4B126CA806247C2954360BDAB96247050BE8C3D7E39C3C2D5B0C74811B0AC00CB338A3F48F7A799F86C563DE5EDAF8BE8A6220106899315714214FBDC466B240833E37029585311F49D8837BCC48A07CA56B505A9D42F14363C3950AB9F768307C2B627FA8DE1263663C251706BFA2F23C5B85CEBC3AFA399FC791D20F1B94C5DFD3E78665FE6846C8E213136E8CA5A24930DAE9EFEBD54616BB3EA08E5FB9346098F42F1593A5D5F1E3B73FE184F5CD674BE7F0C46171E0F83268B3C231C9B552449FA882EAA67EFA52399A3867DFD17248CF52450523777260F4FFE155AE5838A4F883EA27DE00AECE89B984F185A795C34DD71F4F424F919D7F32D48F2FBC9FBE41E631E6443397AA5E75B6AAC98619A9241A8D162DCBFD8EB1056E8ED62A655A2D50FAA162EF86DA4DEA51ECB168193F1C34C558335D27EC393C6AA1B789A23BBC08781011B2FCB2A02A7C33632BB33D1D5FB72E5C9FE9BEDEA1FC4079638D7FD6FFD965CF01ADB026D4638CE0A0D20E47BA0D9AD72ED5136A562AE955374E2A80809076AD250D7E8F59854A820BA342FB92151A1F0CA5F
-20200227223552 2 6 100 4095 5 C7D5773A9200CD53CB4C9244931BB61A711BA1EA3735C53C933074E733E2DAFBBC1F737A508EA82790EF95F7989A889A8FFBC707E9A88090ED5FBA0F485638CBAC547DE653E9D80D09E8795B68C70570547E49D611E08F9D47AEFC22AE8D81D8863CAC593896D4B126CA806247C2954360BDAB96247050BE8C3D7E39C3C2D5B0C74811B0AC00CB338A3F48F7A799F86C563DE5EDAF8BE8A6220106899315714214FBDC466B240833E37029585311F49D8837BCC48A07CA56B505A9D42F14363C3950AB9F768307C2B627FA8DE1263663C251706BFA2F23C5B85CEBC3AFA399FC791D20F1B94C5DFD3E78665FE6846C8E213136E8CA5A24930DAE9EFEBD54616BB3EA08E5FB9346098F42F1593A5D5F1E3B73FE184F5CD674BE7F0C46171E0F83268B3C231C9B552449FA882EAA67EFA52399A3867DFD17248CF52450523777260F4FFE155AE5838A4F883EA27DE00AECE89B984F185A795C34DD71F4F424F919D7F32D48F2FBC9FBE41E631E6443397AA5E75B6AAC98619A9241A8D162DCBFD8EB1056E8ED62A655A2D50FAA162EF86DA4DEA51ECB168193F1C34C558335D27EC393C6AA1B789A23BBC08781011B2FCB2A02A7C33632BB33D1D5FB72E5C9FE9BEDEA1FC4079638D7FD6FFD965CF01ADB026D4638CE0A0D20E47BA0D9AD72ED5136A562AE955374E2A80809076AD250D7E8F59854A820BA342FB92151A2441737
-20200227224041 2 6 100 4095 2 C7D5773A9200CD53CB4C9244931BB61A711BA1EA3735C53C933074E733E2DAFBBC1F737A508EA82790EF95F7989A889A8FFBC707E9A88090ED5FBA0F485638CBAC547DE653E9D80D09E8795B68C70570547E49D611E08F9D47AEFC22AE8D81D8863CAC593896D4B126CA806247C2954360BDAB96247050BE8C3D7E39C3C2D5B0C74811B0AC00CB338A3F48F7A799F86C563DE5EDAF8BE8A6220106899315714214FBDC466B240833E37029585311F49D8837BCC48A07CA56B505A9D42F14363C3950AB9F768307C2B627FA8DE1263663C251706BFA2F23C5B85CEBC3AFA399FC791D20F1B94C5DFD3E78665FE6846C8E213136E8CA5A24930DAE9EFEBD54616BB3EA08E5FB9346098F42F1593A5D5F1E3B73FE184F5CD674BE7F0C46171E0F83268B3C231C9B552449FA882EAA67EFA52399A3867DFD17248CF52450523777260F4FFE155AE5838A4F883EA27DE00AECE89B984F185A795C34DD71F4F424F919D7F32D48F2FBC9FBE41E631E6443397AA5E75B6AAC98619A9241A8D162DCBFD8EB1056E8ED62A655A2D50FAA162EF86DA4DEA51ECB168193F1C34C558335D27EC393C6AA1B789A23BBC08781011B2FCB2A02A7C33632BB33D1D5FB72E5C9FE9BEDEA1FC4079638D7FD6FFD965CF01ADB026D4638CE0A0D20E47BA0D9AD72ED5136A562AE955374E2A80809076AD250D7E8F59854A820BA342FB92151A2876443
-20200227225049 2 6 100 4095 5 C7D5773A9200CD53CB4C9244931BB61A711BA1EA3735C53C933074E733E2DAFBBC1F737A508EA82790EF95F7989A889A8FFBC707E9A88090ED5FBA0F485638CBAC547DE653E9D80D09E8795B68C70570547E49D611E08F9D47AEFC22AE8D81D8863CAC593896D4B126CA806247C2954360BDAB96247050BE8C3D7E39C3C2D5B0C74811B0AC00CB338A3F48F7A799F86C563DE5EDAF8BE8A6220106899315714214FBDC466B240833E37029585311F49D8837BCC48A07CA56B505A9D42F14363C3950AB9F768307C2B627FA8DE1263663C251706BFA2F23C5B85CEBC3AFA399FC791D20F1B94C5DFD3E78665FE6846C8E213136E8CA5A24930DAE9EFEBD54616BB3EA08E5FB9346098F42F1593A5D5F1E3B73FE184F5CD674BE7F0C46171E0F83268B3C231C9B552449FA882EAA67EFA52399A3867DFD17248CF52450523777260F4FFE155AE5838A4F883EA27DE00AECE89B984F185A795C34DD71F4F424F919D7F32D48F2FBC9FBE41E631E6443397AA5E75B6AAC98619A9241A8D162DCBFD8EB1056E8ED62A655A2D50FAA162EF86DA4DEA51ECB168193F1C34C558335D27EC393C6AA1B789A23BBC08781011B2FCB2A02A7C33632BB33D1D5FB72E5C9FE9BEDEA1FC4079638D7FD6FFD965CF01ADB026D4638CE0A0D20E47BA0D9AD72ED5136A562AE955374E2A80809076AD250D7E8F59854A820BA342FB92151A31D69A7
-20200227225259 2 6 100 4095 5 C7D5773A9200CD53CB4C9244931BB61A711BA1EA3735C53C933074E733E2DAFBBC1F737A508EA82790EF95F7989A889A8FFBC707E9A88090ED5FBA0F485638CBAC547DE653E9D80D09E8795B68C70570547E49D611E08F9D47AEFC22AE8D81D8863CAC593896D4B126CA806247C2954360BDAB96247050BE8C3D7E39C3C2D5B0C74811B0AC00CB338A3F48F7A799F86C563DE5EDAF8BE8A6220106899315714214FBDC466B240833E37029585311F49D8837BCC48A07CA56B505A9D42F14363C3950AB9F768307C2B627FA8DE1263663C251706BFA2F23C5B85CEBC3AFA399FC791D20F1B94C5DFD3E78665FE6846C8E213136E8CA5A24930DAE9EFEBD54616BB3EA08E5FB9346098F42F1593A5D5F1E3B73FE184F5CD674BE7F0C46171E0F83268B3C231C9B552449FA882EAA67EFA52399A3867DFD17248CF52450523777260F4FFE155AE5838A4F883EA27DE00AECE89B984F185A795C34DD71F4F424F919D7F32D48F2FBC9FBE41E631E6443397AA5E75B6AAC98619A9241A8D162DCBFD8EB1056E8ED62A655A2D50FAA162EF86DA4DEA51ECB168193F1C34C558335D27EC393C6AA1B789A23BBC08781011B2FCB2A02A7C33632BB33D1D5FB72E5C9FE9BEDEA1FC4079638D7FD6FFD965CF01ADB026D4638CE0A0D20E47BA0D9AD72ED5136A562AE955374E2A80809076AD250D7E8F59854A820BA342FB92151A337A56F
-20200227225746 2 6 100 4095 5 C7D5773A9200CD53CB4C9244931BB61A711BA1EA3735C53C933074E733E2DAFBBC1F737A508EA82790EF95F7989A889A8FFBC707E9A88090ED5FBA0F485638CBAC547DE653E9D80D09E8795B68C70570547E49D611E08F9D47AEFC22AE8D81D8863CAC593896D4B126CA806247C2954360BDAB96247050BE8C3D7E39C3C2D5B0C74811B0AC00CB338A3F48F7A799F86C563DE5EDAF8BE8A6220106899315714214FBDC466B240833E37029585311F49D8837BCC48A07CA56B505A9D42F14363C3950AB9F768307C2B627FA8DE1263663C251706BFA2F23C5B85CEBC3AFA399FC791D20F1B94C5DFD3E78665FE6846C8E213136E8CA5A24930DAE9EFEBD54616BB3EA08E5FB9346098F42F1593A5D5F1E3B73FE184F5CD674BE7F0C46171E0F83268B3C231C9B552449FA882EAA67EFA52399A3867DFD17248CF52450523777260F4FFE155AE5838A4F883EA27DE00AECE89B984F185A795C34DD71F4F424F919D7F32D48F2FBC9FBE41E631E6443397AA5E75B6AAC98619A9241A8D162DCBFD8EB1056E8ED62A655A2D50FAA162EF86DA4DEA51ECB168193F1C34C558335D27EC393C6AA1B789A23BBC08781011B2FCB2A02A7C33632BB33D1D5FB72E5C9FE9BEDEA1FC4079638D7FD6FFD965CF01ADB026D4638CE0A0D20E47BA0D9AD72ED5136A562AE955374E2A80809076AD250D7E8F59854A820BA342FB92151A37D3827
-20200227230135 2 6 100 4095 5 C7D5773A9200CD53CB4C9244931BB61A711BA1EA3735C53C933074E733E2DAFBBC1F737A508EA82790EF95F7989A889A8FFBC707E9A88090ED5FBA0F485638CBAC547DE653E9D80D09E8795B68C70570547E49D611E08F9D47AEFC22AE8D81D8863CAC593896D4B126CA806247C2954360BDAB96247050BE8C3D7E39C3C2D5B0C74811B0AC00CB338A3F48F7A799F86C563DE5EDAF8BE8A6220106899315714214FBDC466B240833E37029585311F49D8837BCC48A07CA56B505A9D42F14363C3950AB9F768307C2B627FA8DE1263663C251706BFA2F23C5B85CEBC3AFA399FC791D20F1B94C5DFD3E78665FE6846C8E213136E8CA5A24930DAE9EFEBD54616BB3EA08E5FB9346098F42F1593A5D5F1E3B73FE184F5CD674BE7F0C46171E0F83268B3C231C9B552449FA882EAA67EFA52399A3867DFD17248CF52450523777260F4FFE155AE5838A4F883EA27DE00AECE89B984F185A795C34DD71F4F424F919D7F32D48F2FBC9FBE41E631E6443397AA5E75B6AAC98619A9241A8D162DCBFD8EB1056E8ED62A655A2D50FAA162EF86DA4DEA51ECB168193F1C34C558335D27EC393C6AA1B789A23BBC08781011B2FCB2A02A7C33632BB33D1D5FB72E5C9FE9BEDEA1FC4079638D7FD6FFD965CF01ADB026D4638CE0A0D20E47BA0D9AD72ED5136A562AE955374E2A80809076AD250D7E8F59854A820BA342FB92151A3AF483F
-20200227230918 2 6 100 4095 2 C7D5773A9200CD53CB4C9244931BB61A711BA1EA3735C53C933074E733E2DAFBBC1F737A508EA82790EF95F7989A889A8FFBC707E9A88090ED5FBA0F485638CBAC547DE653E9D80D09E8795B68C70570547E49D611E08F9D47AEFC22AE8D81D8863CAC593896D4B126CA806247C2954360BDAB96247050BE8C3D7E39C3C2D5B0C74811B0AC00CB338A3F48F7A799F86C563DE5EDAF8BE8A6220106899315714214FBDC466B240833E37029585311F49D8837BCC48A07CA56B505A9D42F14363C3950AB9F768307C2B627FA8DE1263663C251706BFA2F23C5B85CEBC3AFA399FC791D20F1B94C5DFD3E78665FE6846C8E213136E8CA5A24930DAE9EFEBD54616BB3EA08E5FB9346098F42F1593A5D5F1E3B73FE184F5CD674BE7F0C46171E0F83268B3C231C9B552449FA882EAA67EFA52399A3867DFD17248CF52450523777260F4FFE155AE5838A4F883EA27DE00AECE89B984F185A795C34DD71F4F424F919D7F32D48F2FBC9FBE41E631E6443397AA5E75B6AAC98619A9241A8D162DCBFD8EB1056E8ED62A655A2D50FAA162EF86DA4DEA51ECB168193F1C34C558335D27EC393C6AA1B789A23BBC08781011B2FCB2A02A7C33632BB33D1D5FB72E5C9FE9BEDEA1FC4079638D7FD6FFD965CF01ADB026D4638CE0A0D20E47BA0D9AD72ED5136A562AE955374E2A80809076AD250D7E8F59854A820BA342FB92151A41FC5AB
-20200227232340 2 6 100 4095 5 C7D5773A9200CD53CB4C9244931BB61A711BA1EA3735C53C933074E733E2DAFBBC1F737A508EA82790EF95F7989A889A8FFBC707E9A88090ED5FBA0F485638CBAC547DE653E9D80D09E8795B68C70570547E49D611E08F9D47AEFC22AE8D81D8863CAC593896D4B126CA806247C2954360BDAB96247050BE8C3D7E39C3C2D5B0C74811B0AC00CB338A3F48F7A799F86C563DE5EDAF8BE8A6220106899315714214FBDC466B240833E37029585311F49D8837BCC48A07CA56B505A9D42F14363C3950AB9F768307C2B627FA8DE1263663C251706BFA2F23C5B85CEBC3AFA399FC791D20F1B94C5DFD3E78665FE6846C8E213136E8CA5A24930DAE9EFEBD54616BB3EA08E5FB9346098F42F1593A5D5F1E3B73FE184F5CD674BE7F0C46171E0F83268B3C231C9B552449FA882EAA67EFA52399A3867DFD17248CF52450523777260F4FFE155AE5838A4F883EA27DE00AECE89B984F185A795C34DD71F4F424F919D7F32D48F2FBC9FBE41E631E6443397AA5E75B6AAC98619A9241A8D162DCBFD8EB1056E8ED62A655A2D50FAA162EF86DA4DEA51ECB168193F1C34C558335D27EC393C6AA1B789A23BBC08781011B2FCB2A02A7C33632BB33D1D5FB72E5C9FE9BEDEA1FC4079638D7FD6FFD965CF01ADB026D4638CE0A0D20E47BA0D9AD72ED5136A562AE955374E2A80809076AD250D7E8F59854A820BA342FB92151A4FCC2DF
-20200227232424 2 6 100 4095 5 C7D5773A9200CD53CB4C9244931BB61A711BA1EA3735C53C933074E733E2DAFBBC1F737A508EA82790EF95F7989A889A8FFBC707E9A88090ED5FBA0F485638CBAC547DE653E9D80D09E8795B68C70570547E49D611E08F9D47AEFC22AE8D81D8863CAC593896D4B126CA806247C2954360BDAB96247050BE8C3D7E39C3C2D5B0C74811B0AC00CB338A3F48F7A799F86C563DE5EDAF8BE8A6220106899315714214FBDC466B240833E37029585311F49D8837BCC48A07CA56B505A9D42F14363C3950AB9F768307C2B627FA8DE1263663C251706BFA2F23C5B85CEBC3AFA399FC791D20F1B94C5DFD3E78665FE6846C8E213136E8CA5A24930DAE9EFEBD54616BB3EA08E5FB9346098F42F1593A5D5F1E3B73FE184F5CD674BE7F0C46171E0F83268B3C231C9B552449FA882EAA67EFA52399A3867DFD17248CF52450523777260F4FFE155AE5838A4F883EA27DE00AECE89B984F185A795C34DD71F4F424F919D7F32D48F2FBC9FBE41E631E6443397AA5E75B6AAC98619A9241A8D162DCBFD8EB1056E8ED62A655A2D50FAA162EF86DA4DEA51ECB168193F1C34C558335D27EC393C6AA1B789A23BBC08781011B2FCB2A02A7C33632BB33D1D5FB72E5C9FE9BEDEA1FC4079638D7FD6FFD965CF01ADB026D4638CE0A0D20E47BA0D9AD72ED5136A562AE955374E2A80809076AD250D7E8F59854A820BA342FB92151A4FEF907
-20200228001546 2 6 100 4095 5 C7D5773A9200CD53CB4C9244931BB61A711BA1EA3735C53C933074E733E2DAFBBC1F737A508EA82790EF95F7989A889A8FFBC707E9A88090ED5FBA0F485638CBAC547DE653E9D80D09E8795B68C70570547E49D611E08F9D47AEFC22AE8D81D8863CAC593896D4B126CA806247C2954360BDAB96247050BE8C3D7E39C3C2D5B0C74811B0AC00CB338A3F48F7A799F86C563DE5EDAF8BE8A6220106899315714214FBDC466B240833E37029585311F49D8837BCC48A07CA56B505A9D42F14363C3950AB9F768307C2B627FA8DE1263663C251706BFA2F23C5B85CEBC3AFA399FC791D20F1B94C5DFD3E78665FE6846C8E213136E8CA5A24930DAE9EFEBD54616BB3EA08E5FB9346098F42F1593A5D5F1E3B73FE184F5CD674BE7F0C46171E0F83268B3C231C9B552449FA882EAA67EFA52399A3867DFD17248CF52450523777260F4FFE155AE5838A4F883EA27DE00AECE89B984F185A795C34DD71F4F424F919D7F32D48F2FBC9FBE41E631E6443397AA5E75B6AAC98619A9241A8D162DCBFD8EB1056E8ED62A655A2D50FAA162EF86DA4DEA51ECB168193F1C34C558335D27EC393C6AA1B789A23BBC08781011B2FCB2A02A7C33632BB33D1D5FB72E5C9FE9BEDEA1FC4079638D7FD6FFD965CF01ADB026D4638CE0A0D20E47BA0D9AD72ED5136A562AE955374E2A80809076AD250D7E8F59854A820BA342FB92151A82A356F
-20200228002300 2 6 100 4095 5 C7D5773A9200CD53CB4C9244931BB61A711BA1EA3735C53C933074E733E2DAFBBC1F737A508EA82790EF95F7989A889A8FFBC707E9A88090ED5FBA0F485638CBAC547DE653E9D80D09E8795B68C70570547E49D611E08F9D47AEFC22AE8D81D8863CAC593896D4B126CA806247C2954360BDAB96247050BE8C3D7E39C3C2D5B0C74811B0AC00CB338A3F48F7A799F86C563DE5EDAF8BE8A6220106899315714214FBDC466B240833E37029585311F49D8837BCC48A07CA56B505A9D42F14363C3950AB9F768307C2B627FA8DE1263663C251706BFA2F23C5B85CEBC3AFA399FC791D20F1B94C5DFD3E78665FE6846C8E213136E8CA5A24930DAE9EFEBD54616BB3EA08E5FB9346098F42F1593A5D5F1E3B73FE184F5CD674BE7F0C46171E0F83268B3C231C9B552449FA882EAA67EFA52399A3867DFD17248CF52450523777260F4FFE155AE5838A4F883EA27DE00AECE89B984F185A795C34DD71F4F424F919D7F32D48F2FBC9FBE41E631E6443397AA5E75B6AAC98619A9241A8D162DCBFD8EB1056E8ED62A655A2D50FAA162EF86DA4DEA51ECB168193F1C34C558335D27EC393C6AA1B789A23BBC08781011B2FCB2A02A7C33632BB33D1D5FB72E5C9FE9BEDEA1FC4079638D7FD6FFD965CF01ADB026D4638CE0A0D20E47BA0D9AD72ED5136A562AE955374E2A80809076AD250D7E8F59854A820BA342FB92151A8959297
-20200228010138 2 6 100 4095 2 C7D5773A9200CD53CB4C9244931BB61A711BA1EA3735C53C933074E733E2DAFBBC1F737A508EA82790EF95F7989A889A8FFBC707E9A88090ED5FBA0F485638CBAC547DE653E9D80D09E8795B68C70570547E49D611E08F9D47AEFC22AE8D81D8863CAC593896D4B126CA806247C2954360BDAB96247050BE8C3D7E39C3C2D5B0C74811B0AC00CB338A3F48F7A799F86C563DE5EDAF8BE8A6220106899315714214FBDC466B240833E37029585311F49D8837BCC48A07CA56B505A9D42F14363C3950AB9F768307C2B627FA8DE1263663C251706BFA2F23C5B85CEBC3AFA399FC791D20F1B94C5DFD3E78665FE6846C8E213136E8CA5A24930DAE9EFEBD54616BB3EA08E5FB9346098F42F1593A5D5F1E3B73FE184F5CD674BE7F0C46171E0F83268B3C231C9B552449FA882EAA67EFA52399A3867DFD17248CF52450523777260F4FFE155AE5838A4F883EA27DE00AECE89B984F185A795C34DD71F4F424F919D7F32D48F2FBC9FBE41E631E6443397AA5E75B6AAC98619A9241A8D162DCBFD8EB1056E8ED62A655A2D50FAA162EF86DA4DEA51ECB168193F1C34C558335D27EC393C6AA1B789A23BBC08781011B2FCB2A02A7C33632BB33D1D5FB72E5C9FE9BEDEA1FC4079638D7FD6FFD965CF01ADB026D4638CE0A0D20E47BA0D9AD72ED5136A562AE955374E2A80809076AD250D7E8F59854A820BA342FB92151AAEFD82B
-20200228010636 2 6 100 4095 5 C7D5773A9200CD53CB4C9244931BB61A711BA1EA3735C53C933074E733E2DAFBBC1F737A508EA82790EF95F7989A889A8FFBC707E9A88090ED5FBA0F485638CBAC547DE653E9D80D09E8795B68C70570547E49D611E08F9D47AEFC22AE8D81D8863CAC593896D4B126CA806247C2954360BDAB96247050BE8C3D7E39C3C2D5B0C74811B0AC00CB338A3F48F7A799F86C563DE5EDAF8BE8A6220106899315714214FBDC466B240833E37029585311F49D8837BCC48A07CA56B505A9D42F14363C3950AB9F768307C2B627FA8DE1263663C251706BFA2F23C5B85CEBC3AFA399FC791D20F1B94C5DFD3E78665FE6846C8E213136E8CA5A24930DAE9EFEBD54616BB3EA08E5FB9346098F42F1593A5D5F1E3B73FE184F5CD674BE7F0C46171E0F83268B3C231C9B552449FA882EAA67EFA52399A3867DFD17248CF52450523777260F4FFE155AE5838A4F883EA27DE00AECE89B984F185A795C34DD71F4F424F919D7F32D48F2FBC9FBE41E631E6443397AA5E75B6AAC98619A9241A8D162DCBFD8EB1056E8ED62A655A2D50FAA162EF86DA4DEA51ECB168193F1C34C558335D27EC393C6AA1B789A23BBC08781011B2FCB2A02A7C33632BB33D1D5FB72E5C9FE9BEDEA1FC4079638D7FD6FFD965CF01ADB026D4638CE0A0D20E47BA0D9AD72ED5136A562AE955374E2A80809076AD250D7E8F59854A820BA342FB92151AB3B04D7
-20200228012037 2 6 100 4095 5 C7D5773A9200CD53CB4C9244931BB61A711BA1EA3735C53C933074E733E2DAFBBC1F737A508EA82790EF95F7989A889A8FFBC707E9A88090ED5FBA0F485638CBAC547DE653E9D80D09E8795B68C70570547E49D611E08F9D47AEFC22AE8D81D8863CAC593896D4B126CA806247C2954360BDAB96247050BE8C3D7E39C3C2D5B0C74811B0AC00CB338A3F48F7A799F86C563DE5EDAF8BE8A6220106899315714214FBDC466B240833E37029585311F49D8837BCC48A07CA56B505A9D42F14363C3950AB9F768307C2B627FA8DE1263663C251706BFA2F23C5B85CEBC3AFA399FC791D20F1B94C5DFD3E78665FE6846C8E213136E8CA5A24930DAE9EFEBD54616BB3EA08E5FB9346098F42F1593A5D5F1E3B73FE184F5CD674BE7F0C46171E0F83268B3C231C9B552449FA882EAA67EFA52399A3867DFD17248CF52450523777260F4FFE155AE5838A4F883EA27DE00AECE89B984F185A795C34DD71F4F424F919D7F32D48F2FBC9FBE41E631E6443397AA5E75B6AAC98619A9241A8D162DCBFD8EB1056E8ED62A655A2D50FAA162EF86DA4DEA51ECB168193F1C34C558335D27EC393C6AA1B789A23BBC08781011B2FCB2A02A7C33632BB33D1D5FB72E5C9FE9BEDEA1FC4079638D7FD6FFD965CF01ADB026D4638CE0A0D20E47BA0D9AD72ED5136A562AE955374E2A80809076AD250D7E8F59854A820BA342FB92151AC0DBACF
-20200228022145 2 6 100 4095 5 C7D5773A9200CD53CB4C9244931BB61A711BA1EA3735C53C933074E733E2DAFBBC1F737A508EA82790EF95F7989A889A8FFBC707E9A88090ED5FBA0F485638CBAC547DE653E9D80D09E8795B68C70570547E49D611E08F9D47AEFC22AE8D81D8863CAC593896D4B126CA806247C2954360BDAB96247050BE8C3D7E39C3C2D5B0C74811B0AC00CB338A3F48F7A799F86C563DE5EDAF8BE8A6220106899315714214FBDC466B240833E37029585311F49D8837BCC48A07CA56B505A9D42F14363C3950AB9F768307C2B627FA8DE1263663C251706BFA2F23C5B85CEBC3AFA399FC791D20F1B94C5DFD3E78665FE6846C8E213136E8CA5A24930DAE9EFEBD54616BB3EA08E5FB9346098F42F1593A5D5F1E3B73FE184F5CD674BE7F0C46171E0F83268B3C231C9B552449FA882EAA67EFA52399A3867DFD17248CF52450523777260F4FFE155AE5838A4F883EA27DE00AECE89B984F185A795C34DD71F4F424F919D7F32D48F2FBC9FBE41E631E6443397AA5E75B6AAC98619A9241A8D162DCBFD8EB1056E8ED62A655A2D50FAA162EF86DA4DEA51ECB168193F1C34C558335D27EC393C6AA1B789A23BBC08781011B2FCB2A02A7C33632BB33D1D5FB72E5C9FE9BEDEA1FC4079638D7FD6FFD965CF01ADB026D4638CE0A0D20E47BA0D9AD72ED5136A562AE955374E2A80809076AD250D7E8F59854A820BA342FB92151AE028CF7
-20200228024919 2 6 100 6143 2 F7E8D9659B6A380E77600433F564EB23739AF15BF41262D170EC8A14567AE58A0465E39314F019B721FE6F113293EF987DCB177ADD8B7C2E547D393B4873E903C4616BA56468A20ABBA70DCDE1E0B5AA01164D612A1996ECA5BF3E7EFF9D94D54066B56057AE148281B5CC663E6D2979FC8B0C1EE9885F58E944E3A28906BBF202A7DB476CA39AD7FF03D3471379305B798A43EE4DBADB53E5994519C2A799D6C52F1FEDD29C8316DA7190A1277702C04BF5DE331D013DD89C24BE50DEDFA9C5E017E873271FB2E270BD563B6F88391EF560307AE8AFEF8290E60FB57ADF3DE8B9062EA0DAC5CC7EE8900EB2F98023B8655CC5646BDF37C43B64EBEC8918E2BABDA6360C74CBBD6E6986B1E506544F7EEBBB275AF18E5A03E704EE4C5459248A23571F724E1DB11F801F2110A813E14DD524358B4F8B0029164C1640D58D6EDC820CA8A8D79C76106BC3CE8345423E640F2E945C24DF557E1203988C085CB62982AC65F567127289B1CD56961305143E5386BCC75454B3C4BB0870E522E38F8C008418897E25F47ED03CF7B10E40EB7CB0153CF6D22CFCD80734FF85266E63FFD3F09B64195C075B50D65F1E0CC73CE5369A6B0E7D4A05F5F4408EBADDB2C21F76A8FF8E800A828AB23089414A6F5DB04F38FD22EA3A4F77F31C35C55D22B38B76DF5C05E6886B8D88C7A014B2A23D4663978363A75C17B97F51BE8C6A55AA6432BE8FBD80220A99DBD897AC1A545690308C5FBED26D5A074CA38D03C5CE904C86DE6BC2B64B4B7E21EB0244FF37EEBB5873296B440B5059816A0E2BA9A7663B84C3ACB607909F4108249F9949FCBFF8FB242012ECFD26C931FB9BE3C93A524C623E41EBF29976B8594688A73CDC36F53B3FC3AB8EA1DEC8A8226DB05D2D90FA523EC62FF03BA659F5D1EB6D6250ECD3E70E06D3E3BD4CCDB78D31BE96F9B8AC679C7341F9E40A3B38727FEC13077393D30C5BE613262C1CCE0C85517CA32D56B4B41CB122DDB39DDFCE5292B2B887554D24616CD1E225D2A79BB6E6FCEB83E231A7DDF680E6A1E3C3E201AB45DA7261D3359434778459F643FA67B3C1F349A3
-20200228034540 2 6 100 6143 2 F7E8D9659B6A380E77600433F564EB23739AF15BF41262D170EC8A14567AE58A0465E39314F019B721FE6F113293EF987DCB177ADD8B7C2E547D393B4873E903C4616BA56468A20ABBA70DCDE1E0B5AA01164D612A1996ECA5BF3E7EFF9D94D54066B56057AE148281B5CC663E6D2979FC8B0C1EE9885F58E944E3A28906BBF202A7DB476CA39AD7FF03D3471379305B798A43EE4DBADB53E5994519C2A799D6C52F1FEDD29C8316DA7190A1277702C04BF5DE331D013DD89C24BE50DEDFA9C5E017E873271FB2E270BD563B6F88391EF560307AE8AFEF8290E60FB57ADF3DE8B9062EA0DAC5CC7EE8900EB2F98023B8655CC5646BDF37C43B64EBEC8918E2BABDA6360C74CBBD6E6986B1E506544F7EEBBB275AF18E5A03E704EE4C5459248A23571F724E1DB11F801F2110A813E14DD524358B4F8B0029164C1640D58D6EDC820CA8A8D79C76106BC3CE8345423E640F2E945C24DF557E1203988C085CB62982AC65F567127289B1CD56961305143E5386BCC75454B3C4BB0870E522E38F8C008418897E25F47ED03CF7B10E40EB7CB0153CF6D22CFCD80734FF85266E63FFD3F09B64195C075B50D65F1E0CC73CE5369A6B0E7D4A05F5F4408EBADDB2C21F76A8FF8E800A828AB23089414A6F5DB04F38FD22EA3A4F77F31C35C55D22B38B76DF5C05E6886B8D88C7A014B2A23D4663978363A75C17B97F51BE8C6A55AA6432BE8FBD80220A99DBD897AC1A545690308C5FBED26D5A074CA38D03C5CE904C86DE6BC2B64B4B7E21EB0244FF37EEBB5873296B440B5059816A0E2BA9A7663B84C3ACB607909F4108249F9949FCBFF8FB242012ECFD26C931FB9BE3C93A524C623E41EBF29976B8594688A73CDC36F53B3FC3AB8EA1DEC8A8226DB05D2D90FA523EC62FF03BA659F5D1EB6D6250ECD3E70E06D3E3BD4CCDB78D31BE96F9B8AC679C7341F9E40A3B38727FEC13077393D30C5BE613262C1CCE0C85517CA32D56B4B41CB122DDB39DDFCE5292B2B887554D24616CD1E225D2A79BB6E6FCEB83E231A7DDF680E6A1E3C3E201AB45DA7261D3359434778459F643FA67B3C283A14B
-20200228094553 2 6 100 6143 2 F7E8D9659B6A380E77600433F564EB23739AF15BF41262D170EC8A14567AE58A0465E39314F019B721FE6F113293EF987DCB177ADD8B7C2E547D393B4873E903C4616BA56468A20ABBA70DCDE1E0B5AA01164D612A1996ECA5BF3E7EFF9D94D54066B56057AE148281B5CC663E6D2979FC8B0C1EE9885F58E944E3A28906BBF202A7DB476CA39AD7FF03D3471379305B798A43EE4DBADB53E5994519C2A799D6C52F1FEDD29C8316DA7190A1277702C04BF5DE331D013DD89C24BE50DEDFA9C5E017E873271FB2E270BD563B6F88391EF560307AE8AFEF8290E60FB57ADF3DE8B9062EA0DAC5CC7EE8900EB2F98023B8655CC5646BDF37C43B64EBEC8918E2BABDA6360C74CBBD6E6986B1E506544F7EEBBB275AF18E5A03E704EE4C5459248A23571F724E1DB11F801F2110A813E14DD524358B4F8B0029164C1640D58D6EDC820CA8A8D79C76106BC3CE8345423E640F2E945C24DF557E1203988C085CB62982AC65F567127289B1CD56961305143E5386BCC75454B3C4BB0870E522E38F8C008418897E25F47ED03CF7B10E40EB7CB0153CF6D22CFCD80734FF85266E63FFD3F09B64195C075B50D65F1E0CC73CE5369A6B0E7D4A05F5F4408EBADDB2C21F76A8FF8E800A828AB23089414A6F5DB04F38FD22EA3A4F77F31C35C55D22B38B76DF5C05E6886B8D88C7A014B2A23D4663978363A75C17B97F51BE8C6A55AA6432BE8FBD80220A99DBD897AC1A545690308C5FBED26D5A074CA38D03C5CE904C86DE6BC2B64B4B7E21EB0244FF37EEBB5873296B440B5059816A0E2BA9A7663B84C3ACB607909F4108249F9949FCBFF8FB242012ECFD26C931FB9BE3C93A524C623E41EBF29976B8594688A73CDC36F53B3FC3AB8EA1DEC8A8226DB05D2D90FA523EC62FF03BA659F5D1EB6D6250ECD3E70E06D3E3BD4CCDB78D31BE96F9B8AC679C7341F9E40A3B38727FEC13077393D30C5BE613262C1CCE0C85517CA32D56B4B41CB122DDB39DDFCE5292B2B887554D24616CD1E225D2A79BB6E6FCEB83E231A7DDF680E6A1E3C3E201AB45DA7261D3359434778459F643FA67B3C9D8E343
-20200228122045 2 6 100 6143 2 F7E8D9659B6A380E77600433F564EB23739AF15BF41262D170EC8A14567AE58A0465E39314F019B721FE6F113293EF987DCB177ADD8B7C2E547D393B4873E903C4616BA56468A20ABBA70DCDE1E0B5AA01164D612A1996ECA5BF3E7EFF9D94D54066B56057AE148281B5CC663E6D2979FC8B0C1EE9885F58E944E3A28906BBF202A7DB476CA39AD7FF03D3471379305B798A43EE4DBADB53E5994519C2A799D6C52F1FEDD29C8316DA7190A1277702C04BF5DE331D013DD89C24BE50DEDFA9C5E017E873271FB2E270BD563B6F88391EF560307AE8AFEF8290E60FB57ADF3DE8B9062EA0DAC5CC7EE8900EB2F98023B8655CC5646BDF37C43B64EBEC8918E2BABDA6360C74CBBD6E6986B1E506544F7EEBBB275AF18E5A03E704EE4C5459248A23571F724E1DB11F801F2110A813E14DD524358B4F8B0029164C1640D58D6EDC820CA8A8D79C76106BC3CE8345423E640F2E945C24DF557E1203988C085CB62982AC65F567127289B1CD56961305143E5386BCC75454B3C4BB0870E522E38F8C008418897E25F47ED03CF7B10E40EB7CB0153CF6D22CFCD80734FF85266E63FFD3F09B64195C075B50D65F1E0CC73CE5369A6B0E7D4A05F5F4408EBADDB2C21F76A8FF8E800A828AB23089414A6F5DB04F38FD22EA3A4F77F31C35C55D22B38B76DF5C05E6886B8D88C7A014B2A23D4663978363A75C17B97F51BE8C6A55AA6432BE8FBD80220A99DBD897AC1A545690308C5FBED26D5A074CA38D03C5CE904C86DE6BC2B64B4B7E21EB0244FF37EEBB5873296B440B5059816A0E2BA9A7663B84C3ACB607909F4108249F9949FCBFF8FB242012ECFD26C931FB9BE3C93A524C623E41EBF29976B8594688A73CDC36F53B3FC3AB8EA1DEC8A8226DB05D2D90FA523EC62FF03BA659F5D1EB6D6250ECD3E70E06D3E3BD4CCDB78D31BE96F9B8AC679C7341F9E40A3B38727FEC13077393D30C5BE613262C1CCE0C85517CA32D56B4B41CB122DDB39DDFCE5292B2B887554D24616CD1E225D2A79BB6E6FCEB83E231A7DDF680E6A1E3C3E201AB45DA7261D3359434778459F643FA67B3CD2640CB
-20200304105045 2 6 100 6143 5 F7E8D9659B6A380E77600433F564EB23739AF15BF41262D170EC8A14567AE58A0465E39314F019B721FE6F113293EF987DCB177ADD8B7C2E547D393B4873E903C4616BA56468A20ABBA70DCDE1E0B5AA01164D612A1996ECA5BF3E7EFF9D94D54066B56057AE148281B5CC663E6D2979FC8B0C1EE9885F58E944E3A28906BBF202A7DB476CA39AD7FF03D3471379305B798A43EE4DBADB53E5994519C2A799D6C52F1FEDD29C8316DA7190A1277702C04BF5DE331D013DD89C24BE50DEDFA9C5E017E873271FB2E270BD563B6F88391EF560307AE8AFEF8290E60FB57ADF3DE8B9062EA0DAC5CC7EE8900EB2F98023B8655CC5646BDF37C43B64EBEC8918E2BABDA6360C74CBBD6E6986B1E506544F7EEBBB275AF18E5A03E704EE4C5459248A23571F724E1DB11F801F2110A813E14DD524358B4F8B0029164C1640D58D6EDC820CA8A8D79C76106BC3CE8345423E640F2E945C24DF557E1203988C085CB62982AC65F567127289B1CD56961305143E5386BCC75454B3C4BB0870E522E38F8C008418897E25F47ED03CF7B10E40EB7CB0153CF6D22CFCD80734FF85266E63FFD3F09B64195C075B50D65F1E0CC73CE5369A6B0E7D4A05F5F4408EBADDB2C21F76A8FF8E800A828AB23089414A6F5DB04F38FD22EA3A4F77F31C35C55D22B38B76DF5C05E6886B8D88C7A014B2A23D4663978363A75C17B97F51BE8C6A55AA6432BE8FBD80220A99DBD897AC1A545690308C5FBED26D5A074CA38D03C5CE904C86DE6BC2B64B4B7E21EB0244FF37EEBB5873296B440B5059816A0E2BA9A7663B84C3ACB607909F4108249F9949FCBFF8FB242012ECFD26C931FB9BE3C93A524C623E41EBF29976B8594688A73CDC36F53B3FC3AB8EA1DEC8A8226DB05D2D90FA523EC62FF03BA659F5D1EB6D6250ECD3E70E06D3E3BD4CCDB78D31BE96F9B8AC679C7341F9E40A3B38727FEC13077393D30C5BE613262C1CCE0C85517CA32D56B4B41CB122DDB39DDFCE5292B2B887554D24616CD1E225D2A79BB6E6FCEB83E231A7DDF680E6A1E3C3E201AB45DA7261D3359434778459F643FA67B3D032E31F
-20200304111455 2 6 100 6143 2 F7E8D9659B6A380E77600433F564EB23739AF15BF41262D170EC8A14567AE58A0465E39314F019B721FE6F113293EF987DCB177ADD8B7C2E547D393B4873E903C4616BA56468A20ABBA70DCDE1E0B5AA01164D612A1996ECA5BF3E7EFF9D94D54066B56057AE148281B5CC663E6D2979FC8B0C1EE9885F58E944E3A28906BBF202A7DB476CA39AD7FF03D3471379305B798A43EE4DBADB53E5994519C2A799D6C52F1FEDD29C8316DA7190A1277702C04BF5DE331D013DD89C24BE50DEDFA9C5E017E873271FB2E270BD563B6F88391EF560307AE8AFEF8290E60FB57ADF3DE8B9062EA0DAC5CC7EE8900EB2F98023B8655CC5646BDF37C43B64EBEC8918E2BABDA6360C74CBBD6E6986B1E506544F7EEBBB275AF18E5A03E704EE4C5459248A23571F724E1DB11F801F2110A813E14DD524358B4F8B0029164C1640D58D6EDC820CA8A8D79C76106BC3CE8345423E640F2E945C24DF557E1203988C085CB62982AC65F567127289B1CD56961305143E5386BCC75454B3C4BB0870E522E38F8C008418897E25F47ED03CF7B10E40EB7CB0153CF6D22CFCD80734FF85266E63FFD3F09B64195C075B50D65F1E0CC73CE5369A6B0E7D4A05F5F4408EBADDB2C21F76A8FF8E800A828AB23089414A6F5DB04F38FD22EA3A4F77F31C35C55D22B38B76DF5C05E6886B8D88C7A014B2A23D4663978363A75C17B97F51BE8C6A55AA6432BE8FBD80220A99DBD897AC1A545690308C5FBED26D5A074CA38D03C5CE904C86DE6BC2B64B4B7E21EB0244FF37EEBB5873296B440B5059816A0E2BA9A7663B84C3ACB607909F4108249F9949FCBFF8FB242012ECFD26C931FB9BE3C93A524C623E41EBF29976B8594688A73CDC36F53B3FC3AB8EA1DEC8A8226DB05D2D90FA523EC62FF03BA659F5D1EB6D6250ECD3E70E06D3E3BD4CCDB78D31BE96F9B8AC679C7341F9E40A3B38727FEC13077393D30C5BE613262C1CCE0C85517CA32D56B4B41CB122DDB39DDFCE5292B2B887554D24616CD1E225D2A79BB6E6FCEB83E231A7DDF680E6A1E3C3E201AB45DA7261D3359434778459F643FA67B3D0B6997B
-20200304114010 2 6 100 6143 5 F7E8D9659B6A380E77600433F564EB23739AF15BF41262D170EC8A14567AE58A0465E39314F019B721FE6F113293EF987DCB177ADD8B7C2E547D393B4873E903C4616BA56468A20ABBA70DCDE1E0B5AA01164D612A1996ECA5BF3E7EFF9D94D54066B56057AE148281B5CC663E6D2979FC8B0C1EE9885F58E944E3A28906BBF202A7DB476CA39AD7FF03D3471379305B798A43EE4DBADB53E5994519C2A799D6C52F1FEDD29C8316DA7190A1277702C04BF5DE331D013DD89C24BE50DEDFA9C5E017E873271FB2E270BD563B6F88391EF560307AE8AFEF8290E60FB57ADF3DE8B9062EA0DAC5CC7EE8900EB2F98023B8655CC5646BDF37C43B64EBEC8918E2BABDA6360C74CBBD6E6986B1E506544F7EEBBB275AF18E5A03E704EE4C5459248A23571F724E1DB11F801F2110A813E14DD524358B4F8B0029164C1640D58D6EDC820CA8A8D79C76106BC3CE8345423E640F2E945C24DF557E1203988C085CB62982AC65F567127289B1CD56961305143E5386BCC75454B3C4BB0870E522E38F8C008418897E25F47ED03CF7B10E40EB7CB0153CF6D22CFCD80734FF85266E63FFD3F09B64195C075B50D65F1E0CC73CE5369A6B0E7D4A05F5F4408EBADDB2C21F76A8FF8E800A828AB23089414A6F5DB04F38FD22EA3A4F77F31C35C55D22B38B76DF5C05E6886B8D88C7A014B2A23D4663978363A75C17B97F51BE8C6A55AA6432BE8FBD80220A99DBD897AC1A545690308C5FBED26D5A074CA38D03C5CE904C86DE6BC2B64B4B7E21EB0244FF37EEBB5873296B440B5059816A0E2BA9A7663B84C3ACB607909F4108249F9949FCBFF8FB242012ECFD26C931FB9BE3C93A524C623E41EBF29976B8594688A73CDC36F53B3FC3AB8EA1DEC8A8226DB05D2D90FA523EC62FF03BA659F5D1EB6D6250ECD3E70E06D3E3BD4CCDB78D31BE96F9B8AC679C7341F9E40A3B38727FEC13077393D30C5BE613262C1CCE0C85517CA32D56B4B41CB122DDB39DDFCE5292B2B887554D24616CD1E225D2A79BB6E6FCEB83E231A7DDF680E6A1E3C3E201AB45DA7261D3359434778459F643FA67B3D140C2DF
-20200304121904 2 6 100 6143 2 F7E8D9659B6A380E77600433F564EB23739AF15BF41262D170EC8A14567AE58A0465E39314F019B721FE6F113293EF987DCB177ADD8B7C2E547D393B4873E903C4616BA56468A20ABBA70DCDE1E0B5AA01164D612A1996ECA5BF3E7EFF9D94D54066B56057AE148281B5CC663E6D2979FC8B0C1EE9885F58E944E3A28906BBF202A7DB476CA39AD7FF03D3471379305B798A43EE4DBADB53E5994519C2A799D6C52F1FEDD29C8316DA7190A1277702C04BF5DE331D013DD89C24BE50DEDFA9C5E017E873271FB2E270BD563B6F88391EF560307AE8AFEF8290E60FB57ADF3DE8B9062EA0DAC5CC7EE8900EB2F98023B8655CC5646BDF37C43B64EBEC8918E2BABDA6360C74CBBD6E6986B1E506544F7EEBBB275AF18E5A03E704EE4C5459248A23571F724E1DB11F801F2110A813E14DD524358B4F8B0029164C1640D58D6EDC820CA8A8D79C76106BC3CE8345423E640F2E945C24DF557E1203988C085CB62982AC65F567127289B1CD56961305143E5386BCC75454B3C4BB0870E522E38F8C008418897E25F47ED03CF7B10E40EB7CB0153CF6D22CFCD80734FF85266E63FFD3F09B64195C075B50D65F1E0CC73CE5369A6B0E7D4A05F5F4408EBADDB2C21F76A8FF8E800A828AB23089414A6F5DB04F38FD22EA3A4F77F31C35C55D22B38B76DF5C05E6886B8D88C7A014B2A23D4663978363A75C17B97F51BE8C6A55AA6432BE8FBD80220A99DBD897AC1A545690308C5FBED26D5A074CA38D03C5CE904C86DE6BC2B64B4B7E21EB0244FF37EEBB5873296B440B5059816A0E2BA9A7663B84C3ACB607909F4108249F9949FCBFF8FB242012ECFD26C931FB9BE3C93A524C623E41EBF29976B8594688A73CDC36F53B3FC3AB8EA1DEC8A8226DB05D2D90FA523EC62FF03BA659F5D1EB6D6250ECD3E70E06D3E3BD4CCDB78D31BE96F9B8AC679C7341F9E40A3B38727FEC13077393D30C5BE613262C1CCE0C85517CA32D56B4B41CB122DDB39DDFCE5292B2B887554D24616CD1E225D2A79BB6E6FCEB83E231A7DDF680E6A1E3C3E201AB45DA7261D3359434778459F643FA67B3D2192573
-20200304123148 2 6 100 6143 2 F7E8D9659B6A380E77600433F564EB23739AF15BF41262D170EC8A14567AE58A0465E39314F019B721FE6F113293EF987DCB177ADD8B7C2E547D393B4873E903C4616BA56468A20ABBA70DCDE1E0B5AA01164D612A1996ECA5BF3E7EFF9D94D54066B56057AE148281B5CC663E6D2979FC8B0C1EE9885F58E944E3A28906BBF202A7DB476CA39AD7FF03D3471379305B798A43EE4DBADB53E5994519C2A799D6C52F1FEDD29C8316DA7190A1277702C04BF5DE331D013DD89C24BE50DEDFA9C5E017E873271FB2E270BD563B6F88391EF560307AE8AFEF8290E60FB57ADF3DE8B9062EA0DAC5CC7EE8900EB2F98023B8655CC5646BDF37C43B64EBEC8918E2BABDA6360C74CBBD6E6986B1E506544F7EEBBB275AF18E5A03E704EE4C5459248A23571F724E1DB11F801F2110A813E14DD524358B4F8B0029164C1640D58D6EDC820CA8A8D79C76106BC3CE8345423E640F2E945C24DF557E1203988C085CB62982AC65F567127289B1CD56961305143E5386BCC75454B3C4BB0870E522E38F8C008418897E25F47ED03CF7B10E40EB7CB0153CF6D22CFCD80734FF85266E63FFD3F09B64195C075B50D65F1E0CC73CE5369A6B0E7D4A05F5F4408EBADDB2C21F76A8FF8E800A828AB23089414A6F5DB04F38FD22EA3A4F77F31C35C55D22B38B76DF5C05E6886B8D88C7A014B2A23D4663978363A75C17B97F51BE8C6A55AA6432BE8FBD80220A99DBD897AC1A545690308C5FBED26D5A074CA38D03C5CE904C86DE6BC2B64B4B7E21EB0244FF37EEBB5873296B440B5059816A0E2BA9A7663B84C3ACB607909F4108249F9949FCBFF8FB242012ECFD26C931FB9BE3C93A524C623E41EBF29976B8594688A73CDC36F53B3FC3AB8EA1DEC8A8226DB05D2D90FA523EC62FF03BA659F5D1EB6D6250ECD3E70E06D3E3BD4CCDB78D31BE96F9B8AC679C7341F9E40A3B38727FEC13077393D30C5BE613262C1CCE0C85517CA32D56B4B41CB122DDB39DDFCE5292B2B887554D24616CD1E225D2A79BB6E6FCEB83E231A7DDF680E6A1E3C3E201AB45DA7261D3359434778459F643FA67B3D25B4313
-20200304123330 2 6 100 6143 5 F7E8D9659B6A380E77600433F564EB23739AF15BF41262D170EC8A14567AE58A0465E39314F019B721FE6F113293EF987DCB177ADD8B7C2E547D393B4873E903C4616BA56468A20ABBA70DCDE1E0B5AA01164D612A1996ECA5BF3E7EFF9D94D54066B56057AE148281B5CC663E6D2979FC8B0C1EE9885F58E944E3A28906BBF202A7DB476CA39AD7FF03D3471379305B798A43EE4DBADB53E5994519C2A799D6C52F1FEDD29C8316DA7190A1277702C04BF5DE331D013DD89C24BE50DEDFA9C5E017E873271FB2E270BD563B6F88391EF560307AE8AFEF8290E60FB57ADF3DE8B9062EA0DAC5CC7EE8900EB2F98023B8655CC5646BDF37C43B64EBEC8918E2BABDA6360C74CBBD6E6986B1E506544F7EEBBB275AF18E5A03E704EE4C5459248A23571F724E1DB11F801F2110A813E14DD524358B4F8B0029164C1640D58D6EDC820CA8A8D79C76106BC3CE8345423E640F2E945C24DF557E1203988C085CB62982AC65F567127289B1CD56961305143E5386BCC75454B3C4BB0870E522E38F8C008418897E25F47ED03CF7B10E40EB7CB0153CF6D22CFCD80734FF85266E63FFD3F09B64195C075B50D65F1E0CC73CE5369A6B0E7D4A05F5F4408EBADDB2C21F76A8FF8E800A828AB23089414A6F5DB04F38FD22EA3A4F77F31C35C55D22B38B76DF5C05E6886B8D88C7A014B2A23D4663978363A75C17B97F51BE8C6A55AA6432BE8FBD80220A99DBD897AC1A545690308C5FBED26D5A074CA38D03C5CE904C86DE6BC2B64B4B7E21EB0244FF37EEBB5873296B440B5059816A0E2BA9A7663B84C3ACB607909F4108249F9949FCBFF8FB242012ECFD26C931FB9BE3C93A524C623E41EBF29976B8594688A73CDC36F53B3FC3AB8EA1DEC8A8226DB05D2D90FA523EC62FF03BA659F5D1EB6D6250ECD3E70E06D3E3BD4CCDB78D31BE96F9B8AC679C7341F9E40A3B38727FEC13077393D30C5BE613262C1CCE0C85517CA32D56B4B41CB122DDB39DDFCE5292B2B887554D24616CD1E225D2A79BB6E6FCEB83E231A7DDF680E6A1E3C3E201AB45DA7261D3359434778459F643FA67B3D25B8FE7
-20200304132134 2 6 100 6143 2 F7E8D9659B6A380E77600433F564EB23739AF15BF41262D170EC8A14567AE58A0465E39314F019B721FE6F113293EF987DCB177ADD8B7C2E547D393B4873E903C4616BA56468A20ABBA70DCDE1E0B5AA01164D612A1996ECA5BF3E7EFF9D94D54066B56057AE148281B5CC663E6D2979FC8B0C1EE9885F58E944E3A28906BBF202A7DB476CA39AD7FF03D3471379305B798A43EE4DBADB53E5994519C2A799D6C52F1FEDD29C8316DA7190A1277702C04BF5DE331D013DD89C24BE50DEDFA9C5E017E873271FB2E270BD563B6F88391EF560307AE8AFEF8290E60FB57ADF3DE8B9062EA0DAC5CC7EE8900EB2F98023B8655CC5646BDF37C43B64EBEC8918E2BABDA6360C74CBBD6E6986B1E506544F7EEBBB275AF18E5A03E704EE4C5459248A23571F724E1DB11F801F2110A813E14DD524358B4F8B0029164C1640D58D6EDC820CA8A8D79C76106BC3CE8345423E640F2E945C24DF557E1203988C085CB62982AC65F567127289B1CD56961305143E5386BCC75454B3C4BB0870E522E38F8C008418897E25F47ED03CF7B10E40EB7CB0153CF6D22CFCD80734FF85266E63FFD3F09B64195C075B50D65F1E0CC73CE5369A6B0E7D4A05F5F4408EBADDB2C21F76A8FF8E800A828AB23089414A6F5DB04F38FD22EA3A4F77F31C35C55D22B38B76DF5C05E6886B8D88C7A014B2A23D4663978363A75C17B97F51BE8C6A55AA6432BE8FBD80220A99DBD897AC1A545690308C5FBED26D5A074CA38D03C5CE904C86DE6BC2B64B4B7E21EB0244FF37EEBB5873296B440B5059816A0E2BA9A7663B84C3ACB607909F4108249F9949FCBFF8FB242012ECFD26C931FB9BE3C93A524C623E41EBF29976B8594688A73CDC36F53B3FC3AB8EA1DEC8A8226DB05D2D90FA523EC62FF03BA659F5D1EB6D6250ECD3E70E06D3E3BD4CCDB78D31BE96F9B8AC679C7341F9E40A3B38727FEC13077393D30C5BE613262C1CCE0C85517CA32D56B4B41CB122DDB39DDFCE5292B2B887554D24616CD1E225D2A79BB6E6FCEB83E231A7DDF680E6A1E3C3E201AB45DA7261D3359434778459F643FA67B3D363A65B
-20200304153236 2 6 100 6143 2 F7E8D9659B6A380E77600433F564EB23739AF15BF41262D170EC8A14567AE58A0465E39314F019B721FE6F113293EF987DCB177ADD8B7C2E547D393B4873E903C4616BA56468A20ABBA70DCDE1E0B5AA01164D612A1996ECA5BF3E7EFF9D94D54066B56057AE148281B5CC663E6D2979FC8B0C1EE9885F58E944E3A28906BBF202A7DB476CA39AD7FF03D3471379305B798A43EE4DBADB53E5994519C2A799D6C52F1FEDD29C8316DA7190A1277702C04BF5DE331D013DD89C24BE50DEDFA9C5E017E873271FB2E270BD563B6F88391EF560307AE8AFEF8290E60FB57ADF3DE8B9062EA0DAC5CC7EE8900EB2F98023B8655CC5646BDF37C43B64EBEC8918E2BABDA6360C74CBBD6E6986B1E506544F7EEBBB275AF18E5A03E704EE4C5459248A23571F724E1DB11F801F2110A813E14DD524358B4F8B0029164C1640D58D6EDC820CA8A8D79C76106BC3CE8345423E640F2E945C24DF557E1203988C085CB62982AC65F567127289B1CD56961305143E5386BCC75454B3C4BB0870E522E38F8C008418897E25F47ED03CF7B10E40EB7CB0153CF6D22CFCD80734FF85266E63FFD3F09B64195C075B50D65F1E0CC73CE5369A6B0E7D4A05F5F4408EBADDB2C21F76A8FF8E800A828AB23089414A6F5DB04F38FD22EA3A4F77F31C35C55D22B38B76DF5C05E6886B8D88C7A014B2A23D4663978363A75C17B97F51BE8C6A55AA6432BE8FBD80220A99DBD897AC1A545690308C5FBED26D5A074CA38D03C5CE904C86DE6BC2B64B4B7E21EB0244FF37EEBB5873296B440B5059816A0E2BA9A7663B84C3ACB607909F4108249F9949FCBFF8FB242012ECFD26C931FB9BE3C93A524C623E41EBF29976B8594688A73CDC36F53B3FC3AB8EA1DEC8A8226DB05D2D90FA523EC62FF03BA659F5D1EB6D6250ECD3E70E06D3E3BD4CCDB78D31BE96F9B8AC679C7341F9E40A3B38727FEC13077393D30C5BE613262C1CCE0C85517CA32D56B4B41CB122DDB39DDFCE5292B2B887554D24616CD1E225D2A79BB6E6FCEB83E231A7DDF680E6A1E3C3E201AB45DA7261D3359434778459F643FA67B3D651690B
-20200304170756 2 6 100 6143 2 F7E8D9659B6A380E77600433F564EB23739AF15BF41262D170EC8A14567AE58A0465E39314F019B721FE6F113293EF987DCB177ADD8B7C2E547D393B4873E903C4616BA56468A20ABBA70DCDE1E0B5AA01164D612A1996ECA5BF3E7EFF9D94D54066B56057AE148281B5CC663E6D2979FC8B0C1EE9885F58E944E3A28906BBF202A7DB476CA39AD7FF03D3471379305B798A43EE4DBADB53E5994519C2A799D6C52F1FEDD29C8316DA7190A1277702C04BF5DE331D013DD89C24BE50DEDFA9C5E017E873271FB2E270BD563B6F88391EF560307AE8AFEF8290E60FB57ADF3DE8B9062EA0DAC5CC7EE8900EB2F98023B8655CC5646BDF37C43B64EBEC8918E2BABDA6360C74CBBD6E6986B1E506544F7EEBBB275AF18E5A03E704EE4C5459248A23571F724E1DB11F801F2110A813E14DD524358B4F8B0029164C1640D58D6EDC820CA8A8D79C76106BC3CE8345423E640F2E945C24DF557E1203988C085CB62982AC65F567127289B1CD56961305143E5386BCC75454B3C4BB0870E522E38F8C008418897E25F47ED03CF7B10E40EB7CB0153CF6D22CFCD80734FF85266E63FFD3F09B64195C075B50D65F1E0CC73CE5369A6B0E7D4A05F5F4408EBADDB2C21F76A8FF8E800A828AB23089414A6F5DB04F38FD22EA3A4F77F31C35C55D22B38B76DF5C05E6886B8D88C7A014B2A23D4663978363A75C17B97F51BE8C6A55AA6432BE8FBD80220A99DBD897AC1A545690308C5FBED26D5A074CA38D03C5CE904C86DE6BC2B64B4B7E21EB0244FF37EEBB5873296B440B5059816A0E2BA9A7663B84C3ACB607909F4108249F9949FCBFF8FB242012ECFD26C931FB9BE3C93A524C623E41EBF29976B8594688A73CDC36F53B3FC3AB8EA1DEC8A8226DB05D2D90FA523EC62FF03BA659F5D1EB6D6250ECD3E70E06D3E3BD4CCDB78D31BE96F9B8AC679C7341F9E40A3B38727FEC13077393D30C5BE613262C1CCE0C85517CA32D56B4B41CB122DDB39DDFCE5292B2B887554D24616CD1E225D2A79BB6E6FCEB83E231A7DDF680E6A1E3C3E201AB45DA7261D3359434778459F643FA67B3D8694EF3
-20200304175528 2 6 100 6143 5 F7E8D9659B6A380E77600433F564EB23739AF15BF41262D170EC8A14567AE58A0465E39314F019B721FE6F113293EF987DCB177ADD8B7C2E547D393B4873E903C4616BA56468A20ABBA70DCDE1E0B5AA01164D612A1996ECA5BF3E7EFF9D94D54066B56057AE148281B5CC663E6D2979FC8B0C1EE9885F58E944E3A28906BBF202A7DB476CA39AD7FF03D3471379305B798A43EE4DBADB53E5994519C2A799D6C52F1FEDD29C8316DA7190A1277702C04BF5DE331D013DD89C24BE50DEDFA9C5E017E873271FB2E270BD563B6F88391EF560307AE8AFEF8290E60FB57ADF3DE8B9062EA0DAC5CC7EE8900EB2F98023B8655CC5646BDF37C43B64EBEC8918E2BABDA6360C74CBBD6E6986B1E506544F7EEBBB275AF18E5A03E704EE4C5459248A23571F724E1DB11F801F2110A813E14DD524358B4F8B0029164C1640D58D6EDC820CA8A8D79C76106BC3CE8345423E640F2E945C24DF557E1203988C085CB62982AC65F567127289B1CD56961305143E5386BCC75454B3C4BB0870E522E38F8C008418897E25F47ED03CF7B10E40EB7CB0153CF6D22CFCD80734FF85266E63FFD3F09B64195C075B50D65F1E0CC73CE5369A6B0E7D4A05F5F4408EBADDB2C21F76A8FF8E800A828AB23089414A6F5DB04F38FD22EA3A4F77F31C35C55D22B38B76DF5C05E6886B8D88C7A014B2A23D4663978363A75C17B97F51BE8C6A55AA6432BE8FBD80220A99DBD897AC1A545690308C5FBED26D5A074CA38D03C5CE904C86DE6BC2B64B4B7E21EB0244FF37EEBB5873296B440B5059816A0E2BA9A7663B84C3ACB607909F4108249F9949FCBFF8FB242012ECFD26C931FB9BE3C93A524C623E41EBF29976B8594688A73CDC36F53B3FC3AB8EA1DEC8A8226DB05D2D90FA523EC62FF03BA659F5D1EB6D6250ECD3E70E06D3E3BD4CCDB78D31BE96F9B8AC679C7341F9E40A3B38727FEC13077393D30C5BE613262C1CCE0C85517CA32D56B4B41CB122DDB39DDFCE5292B2B887554D24616CD1E225D2A79BB6E6FCEB83E231A7DDF680E6A1E3C3E201AB45DA7261D3359434778459F643FA67B3D96C51EF
-20200304175824 2 6 100 6143 5 F7E8D9659B6A380E77600433F564EB23739AF15BF41262D170EC8A14567AE58A0465E39314F019B721FE6F113293EF987DCB177ADD8B7C2E547D393B4873E903C4616BA56468A20ABBA70DCDE1E0B5AA01164D612A1996ECA5BF3E7EFF9D94D54066B56057AE148281B5CC663E6D2979FC8B0C1EE9885F58E944E3A28906BBF202A7DB476CA39AD7FF03D3471379305B798A43EE4DBADB53E5994519C2A799D6C52F1FEDD29C8316DA7190A1277702C04BF5DE331D013DD89C24BE50DEDFA9C5E017E873271FB2E270BD563B6F88391EF560307AE8AFEF8290E60FB57ADF3DE8B9062EA0DAC5CC7EE8900EB2F98023B8655CC5646BDF37C43B64EBEC8918E2BABDA6360C74CBBD6E6986B1E506544F7EEBBB275AF18E5A03E704EE4C5459248A23571F724E1DB11F801F2110A813E14DD524358B4F8B0029164C1640D58D6EDC820CA8A8D79C76106BC3CE8345423E640F2E945C24DF557E1203988C085CB62982AC65F567127289B1CD56961305143E5386BCC75454B3C4BB0870E522E38F8C008418897E25F47ED03CF7B10E40EB7CB0153CF6D22CFCD80734FF85266E63FFD3F09B64195C075B50D65F1E0CC73CE5369A6B0E7D4A05F5F4408EBADDB2C21F76A8FF8E800A828AB23089414A6F5DB04F38FD22EA3A4F77F31C35C55D22B38B76DF5C05E6886B8D88C7A014B2A23D4663978363A75C17B97F51BE8C6A55AA6432BE8FBD80220A99DBD897AC1A545690308C5FBED26D5A074CA38D03C5CE904C86DE6BC2B64B4B7E21EB0244FF37EEBB5873296B440B5059816A0E2BA9A7663B84C3ACB607909F4108249F9949FCBFF8FB242012ECFD26C931FB9BE3C93A524C623E41EBF29976B8594688A73CDC36F53B3FC3AB8EA1DEC8A8226DB05D2D90FA523EC62FF03BA659F5D1EB6D6250ECD3E70E06D3E3BD4CCDB78D31BE96F9B8AC679C7341F9E40A3B38727FEC13077393D30C5BE613262C1CCE0C85517CA32D56B4B41CB122DDB39DDFCE5292B2B887554D24616CD1E225D2A79BB6E6FCEB83E231A7DDF680E6A1E3C3E201AB45DA7261D3359434778459F643FA67B3D972E9E7
-20200304192109 2 6 100 6143 2 F7E8D9659B6A380E77600433F564EB23739AF15BF41262D170EC8A14567AE58A0465E39314F019B721FE6F113293EF987DCB177ADD8B7C2E547D393B4873E903C4616BA56468A20ABBA70DCDE1E0B5AA01164D612A1996ECA5BF3E7EFF9D94D54066B56057AE148281B5CC663E6D2979FC8B0C1EE9885F58E944E3A28906BBF202A7DB476CA39AD7FF03D3471379305B798A43EE4DBADB53E5994519C2A799D6C52F1FEDD29C8316DA7190A1277702C04BF5DE331D013DD89C24BE50DEDFA9C5E017E873271FB2E270BD563B6F88391EF560307AE8AFEF8290E60FB57ADF3DE8B9062EA0DAC5CC7EE8900EB2F98023B8655CC5646BDF37C43B64EBEC8918E2BABDA6360C74CBBD6E6986B1E506544F7EEBBB275AF18E5A03E704EE4C5459248A23571F724E1DB11F801F2110A813E14DD524358B4F8B0029164C1640D58D6EDC820CA8A8D79C76106BC3CE8345423E640F2E945C24DF557E1203988C085CB62982AC65F567127289B1CD56961305143E5386BCC75454B3C4BB0870E522E38F8C008418897E25F47ED03CF7B10E40EB7CB0153CF6D22CFCD80734FF85266E63FFD3F09B64195C075B50D65F1E0CC73CE5369A6B0E7D4A05F5F4408EBADDB2C21F76A8FF8E800A828AB23089414A6F5DB04F38FD22EA3A4F77F31C35C55D22B38B76DF5C05E6886B8D88C7A014B2A23D4663978363A75C17B97F51BE8C6A55AA6432BE8FBD80220A99DBD897AC1A545690308C5FBED26D5A074CA38D03C5CE904C86DE6BC2B64B4B7E21EB0244FF37EEBB5873296B440B5059816A0E2BA9A7663B84C3ACB607909F4108249F9949FCBFF8FB242012ECFD26C931FB9BE3C93A524C623E41EBF29976B8594688A73CDC36F53B3FC3AB8EA1DEC8A8226DB05D2D90FA523EC62FF03BA659F5D1EB6D6250ECD3E70E06D3E3BD4CCDB78D31BE96F9B8AC679C7341F9E40A3B38727FEC13077393D30C5BE613262C1CCE0C85517CA32D56B4B41CB122DDB39DDFCE5292B2B887554D24616CD1E225D2A79BB6E6FCEB83E231A7DDF680E6A1E3C3E201AB45DA7261D3359434778459F643FA67B3DB488D03
-20200305083948 2 6 100 6143 5 F7E8D9659B6A380E77600433F564EB23739AF15BF41262D170EC8A14567AE58A0465E39314F019B721FE6F113293EF987DCB177ADD8B7C2E547D393B4873E903C4616BA56468A20ABBA70DCDE1E0B5AA01164D612A1996ECA5BF3E7EFF9D94D54066B56057AE148281B5CC663E6D2979FC8B0C1EE9885F58E944E3A28906BBF202A7DB476CA39AD7FF03D3471379305B798A43EE4DBADB53E5994519C2A799D6C52F1FEDD29C8316DA7190A1277702C04BF5DE331D013DD89C24BE50DEDFA9C5E017E873271FB2E270BD563B6F88391EF560307AE8AFEF8290E60FB57ADF3DE8B9062EA0DAC5CC7EE8900EB2F98023B8655CC5646BDF37C43B64EBEC8918E2BABDA6360C74CBBD6E6986B1E506544F7EEBBB275AF18E5A03E704EE4C5459248A23571F724E1DB11F801F2110A813E14DD524358B4F8B0029164C1640D58D6EDC820CA8A8D79C76106BC3CE8345423E640F2E945C24DF557E1203988C085CB62982AC65F567127289B1CD56961305143E5386BCC75454B3C4BB0870E522E38F8C008418897E25F47ED03CF7B10E40EB7CB0153CF6D22CFCD80734FF85266E63FFD3F09B64195C075B50D65F1E0CC73CE5369A6B0E7D4A05F5F4408EBADDB2C21F76A8FF8E800A828AB23089414A6F5DB04F38FD22EA3A4F77F31C35C55D22B38B76DF5C05E6886B8D88C7A014B2A23D4663978363A75C17B97F51BE8C6A55AA6432BE8FBD80220A99DBD897AC1A545690308C5FBED26D5A074CA38D03C5CE904C86DE6BC2B64B4B7E21EB0244FF37EEBB5873296B440B5059816A0E2BA9A7663B84C3ACB607909F4108249F9949FCBFF8FB242012ECFD26C931FB9BE3C93A524C623E41EBF29976B8594688A73CDC36F53B3FC3AB8EA1DEC8A8226DB05D2D90FA523EC62FF03BA659F5D1EB6D6250ECD3E70E06D3E3BD4CCDB78D31BE96F9B8AC679C7341F9E40A3B38727FEC13077393D30C5BE613262C1CCE0C85517CA32D56B4B41CB122DDB39DDFCE5292B2B887554D24616CD1E225D2A79BB6E6FCEB83E231A7DDF680E6A1E3C3E201AB45DA7261D3359434778459F643FA67B3E1E947A7
-20200305094127 2 6 100 6143 5 F7E8D9659B6A380E77600433F564EB23739AF15BF41262D170EC8A14567AE58A0465E39314F019B721FE6F113293EF987DCB177ADD8B7C2E547D393B4873E903C4616BA56468A20ABBA70DCDE1E0B5AA01164D612A1996ECA5BF3E7EFF9D94D54066B56057AE148281B5CC663E6D2979FC8B0C1EE9885F58E944E3A28906BBF202A7DB476CA39AD7FF03D3471379305B798A43EE4DBADB53E5994519C2A799D6C52F1FEDD29C8316DA7190A1277702C04BF5DE331D013DD89C24BE50DEDFA9C5E017E873271FB2E270BD563B6F88391EF560307AE8AFEF8290E60FB57ADF3DE8B9062EA0DAC5CC7EE8900EB2F98023B8655CC5646BDF37C43B64EBEC8918E2BABDA6360C74CBBD6E6986B1E506544F7EEBBB275AF18E5A03E704EE4C5459248A23571F724E1DB11F801F2110A813E14DD524358B4F8B0029164C1640D58D6EDC820CA8A8D79C76106BC3CE8345423E640F2E945C24DF557E1203988C085CB62982AC65F567127289B1CD56961305143E5386BCC75454B3C4BB0870E522E38F8C008418897E25F47ED03CF7B10E40EB7CB0153CF6D22CFCD80734FF85266E63FFD3F09B64195C075B50D65F1E0CC73CE5369A6B0E7D4A05F5F4408EBADDB2C21F76A8FF8E800A828AB23089414A6F5DB04F38FD22EA3A4F77F31C35C55D22B38B76DF5C05E6886B8D88C7A014B2A23D4663978363A75C17B97F51BE8C6A55AA6432BE8FBD80220A99DBD897AC1A545690308C5FBED26D5A074CA38D03C5CE904C86DE6BC2B64B4B7E21EB0244FF37EEBB5873296B440B5059816A0E2BA9A7663B84C3ACB607909F4108249F9949FCBFF8FB242012ECFD26C931FB9BE3C93A524C623E41EBF29976B8594688A73CDC36F53B3FC3AB8EA1DEC8A8226DB05D2D90FA523EC62FF03BA659F5D1EB6D6250ECD3E70E06D3E3BD4CCDB78D31BE96F9B8AC679C7341F9E40A3B38727FEC13077393D30C5BE613262C1CCE0C85517CA32D56B4B41CB122DDB39DDFCE5292B2B887554D24616CD1E225D2A79BB6E6FCEB83E231A7DDF680E6A1E3C3E201AB45DA7261D3359434778459F643FA67B3E337E7CF
-20200305112549 2 6 100 6143 5 F7E8D9659B6A380E77600433F564EB23739AF15BF41262D170EC8A14567AE58A0465E39314F019B721FE6F113293EF987DCB177ADD8B7C2E547D393B4873E903C4616BA56468A20ABBA70DCDE1E0B5AA01164D612A1996ECA5BF3E7EFF9D94D54066B56057AE148281B5CC663E6D2979FC8B0C1EE9885F58E944E3A28906BBF202A7DB476CA39AD7FF03D3471379305B798A43EE4DBADB53E5994519C2A799D6C52F1FEDD29C8316DA7190A1277702C04BF5DE331D013DD89C24BE50DEDFA9C5E017E873271FB2E270BD563B6F88391EF560307AE8AFEF8290E60FB57ADF3DE8B9062EA0DAC5CC7EE8900EB2F98023B8655CC5646BDF37C43B64EBEC8918E2BABDA6360C74CBBD6E6986B1E506544F7EEBBB275AF18E5A03E704EE4C5459248A23571F724E1DB11F801F2110A813E14DD524358B4F8B0029164C1640D58D6EDC820CA8A8D79C76106BC3CE8345423E640F2E945C24DF557E1203988C085CB62982AC65F567127289B1CD56961305143E5386BCC75454B3C4BB0870E522E38F8C008418897E25F47ED03CF7B10E40EB7CB0153CF6D22CFCD80734FF85266E63FFD3F09B64195C075B50D65F1E0CC73CE5369A6B0E7D4A05F5F4408EBADDB2C21F76A8FF8E800A828AB23089414A6F5DB04F38FD22EA3A4F77F31C35C55D22B38B76DF5C05E6886B8D88C7A014B2A23D4663978363A75C17B97F51BE8C6A55AA6432BE8FBD80220A99DBD897AC1A545690308C5FBED26D5A074CA38D03C5CE904C86DE6BC2B64B4B7E21EB0244FF37EEBB5873296B440B5059816A0E2BA9A7663B84C3ACB607909F4108249F9949FCBFF8FB242012ECFD26C931FB9BE3C93A524C623E41EBF29976B8594688A73CDC36F53B3FC3AB8EA1DEC8A8226DB05D2D90FA523EC62FF03BA659F5D1EB6D6250ECD3E70E06D3E3BD4CCDB78D31BE96F9B8AC679C7341F9E40A3B38727FEC13077393D30C5BE613262C1CCE0C85517CA32D56B4B41CB122DDB39DDFCE5292B2B887554D24616CD1E225D2A79BB6E6FCEB83E231A7DDF680E6A1E3C3E201AB45DA7261D3359434778459F643FA67B3E5787ED7
-20200305114326 2 6 100 6143 2 F7E8D9659B6A380E77600433F564EB23739AF15BF41262D170EC8A14567AE58A0465E39314F019B721FE6F113293EF987DCB177ADD8B7C2E547D393B4873E903C4616BA56468A20ABBA70DCDE1E0B5AA01164D612A1996ECA5BF3E7EFF9D94D54066B56057AE148281B5CC663E6D2979FC8B0C1EE9885F58E944E3A28906BBF202A7DB476CA39AD7FF03D3471379305B798A43EE4DBADB53E5994519C2A799D6C52F1FEDD29C8316DA7190A1277702C04BF5DE331D013DD89C24BE50DEDFA9C5E017E873271FB2E270BD563B6F88391EF560307AE8AFEF8290E60FB57ADF3DE8B9062EA0DAC5CC7EE8900EB2F98023B8655CC5646BDF37C43B64EBEC8918E2BABDA6360C74CBBD6E6986B1E506544F7EEBBB275AF18E5A03E704EE4C5459248A23571F724E1DB11F801F2110A813E14DD524358B4F8B0029164C1640D58D6EDC820CA8A8D79C76106BC3CE8345423E640F2E945C24DF557E1203988C085CB62982AC65F567127289B1CD56961305143E5386BCC75454B3C4BB0870E522E38F8C008418897E25F47ED03CF7B10E40EB7CB0153CF6D22CFCD80734FF85266E63FFD3F09B64195C075B50D65F1E0CC73CE5369A6B0E7D4A05F5F4408EBADDB2C21F76A8FF8E800A828AB23089414A6F5DB04F38FD22EA3A4F77F31C35C55D22B38B76DF5C05E6886B8D88C7A014B2A23D4663978363A75C17B97F51BE8C6A55AA6432BE8FBD80220A99DBD897AC1A545690308C5FBED26D5A074CA38D03C5CE904C86DE6BC2B64B4B7E21EB0244FF37EEBB5873296B440B5059816A0E2BA9A7663B84C3ACB607909F4108249F9949FCBFF8FB242012ECFD26C931FB9BE3C93A524C623E41EBF29976B8594688A73CDC36F53B3FC3AB8EA1DEC8A8226DB05D2D90FA523EC62FF03BA659F5D1EB6D6250ECD3E70E06D3E3BD4CCDB78D31BE96F9B8AC679C7341F9E40A3B38727FEC13077393D30C5BE613262C1CCE0C85517CA32D56B4B41CB122DDB39DDFCE5292B2B887554D24616CD1E225D2A79BB6E6FCEB83E231A7DDF680E6A1E3C3E201AB45DA7261D3359434778459F643FA67B3E5CC07BB
-20200305125429 2 6 100 6143 2 F7E8D9659B6A380E77600433F564EB23739AF15BF41262D170EC8A14567AE58A0465E39314F019B721FE6F113293EF987DCB177ADD8B7C2E547D393B4873E903C4616BA56468A20ABBA70DCDE1E0B5AA01164D612A1996ECA5BF3E7EFF9D94D54066B56057AE148281B5CC663E6D2979FC8B0C1EE9885F58E944E3A28906BBF202A7DB476CA39AD7FF03D3471379305B798A43EE4DBADB53E5994519C2A799D6C52F1FEDD29C8316DA7190A1277702C04BF5DE331D013DD89C24BE50DEDFA9C5E017E873271FB2E270BD563B6F88391EF560307AE8AFEF8290E60FB57ADF3DE8B9062EA0DAC5CC7EE8900EB2F98023B8655CC5646BDF37C43B64EBEC8918E2BABDA6360C74CBBD6E6986B1E506544F7EEBBB275AF18E5A03E704EE4C5459248A23571F724E1DB11F801F2110A813E14DD524358B4F8B0029164C1640D58D6EDC820CA8A8D79C76106BC3CE8345423E640F2E945C24DF557E1203988C085CB62982AC65F567127289B1CD56961305143E5386BCC75454B3C4BB0870E522E38F8C008418897E25F47ED03CF7B10E40EB7CB0153CF6D22CFCD80734FF85266E63FFD3F09B64195C075B50D65F1E0CC73CE5369A6B0E7D4A05F5F4408EBADDB2C21F76A8FF8E800A828AB23089414A6F5DB04F38FD22EA3A4F77F31C35C55D22B38B76DF5C05E6886B8D88C7A014B2A23D4663978363A75C17B97F51BE8C6A55AA6432BE8FBD80220A99DBD897AC1A545690308C5FBED26D5A074CA38D03C5CE904C86DE6BC2B64B4B7E21EB0244FF37EEBB5873296B440B5059816A0E2BA9A7663B84C3ACB607909F4108249F9949FCBFF8FB242012ECFD26C931FB9BE3C93A524C623E41EBF29976B8594688A73CDC36F53B3FC3AB8EA1DEC8A8226DB05D2D90FA523EC62FF03BA659F5D1EB6D6250ECD3E70E06D3E3BD4CCDB78D31BE96F9B8AC679C7341F9E40A3B38727FEC13077393D30C5BE613262C1CCE0C85517CA32D56B4B41CB122DDB39DDFCE5292B2B887554D24616CD1E225D2A79BB6E6FCEB83E231A7DDF680E6A1E3C3E201AB45DA7261D3359434778459F643FA67B3E74D719B
-20200305133907 2 6 100 6143 2 F7E8D9659B6A380E77600433F564EB23739AF15BF41262D170EC8A14567AE58A0465E39314F019B721FE6F113293EF987DCB177ADD8B7C2E547D393B4873E903C4616BA56468A20ABBA70DCDE1E0B5AA01164D612A1996ECA5BF3E7EFF9D94D54066B56057AE148281B5CC663E6D2979FC8B0C1EE9885F58E944E3A28906BBF202A7DB476CA39AD7FF03D3471379305B798A43EE4DBADB53E5994519C2A799D6C52F1FEDD29C8316DA7190A1277702C04BF5DE331D013DD89C24BE50DEDFA9C5E017E873271FB2E270BD563B6F88391EF560307AE8AFEF8290E60FB57ADF3DE8B9062EA0DAC5CC7EE8900EB2F98023B8655CC5646BDF37C43B64EBEC8918E2BABDA6360C74CBBD6E6986B1E506544F7EEBBB275AF18E5A03E704EE4C5459248A23571F724E1DB11F801F2110A813E14DD524358B4F8B0029164C1640D58D6EDC820CA8A8D79C76106BC3CE8345423E640F2E945C24DF557E1203988C085CB62982AC65F567127289B1CD56961305143E5386BCC75454B3C4BB0870E522E38F8C008418897E25F47ED03CF7B10E40EB7CB0153CF6D22CFCD80734FF85266E63FFD3F09B64195C075B50D65F1E0CC73CE5369A6B0E7D4A05F5F4408EBADDB2C21F76A8FF8E800A828AB23089414A6F5DB04F38FD22EA3A4F77F31C35C55D22B38B76DF5C05E6886B8D88C7A014B2A23D4663978363A75C17B97F51BE8C6A55AA6432BE8FBD80220A99DBD897AC1A545690308C5FBED26D5A074CA38D03C5CE904C86DE6BC2B64B4B7E21EB0244FF37EEBB5873296B440B5059816A0E2BA9A7663B84C3ACB607909F4108249F9949FCBFF8FB242012ECFD26C931FB9BE3C93A524C623E41EBF29976B8594688A73CDC36F53B3FC3AB8EA1DEC8A8226DB05D2D90FA523EC62FF03BA659F5D1EB6D6250ECD3E70E06D3E3BD4CCDB78D31BE96F9B8AC679C7341F9E40A3B38727FEC13077393D30C5BE613262C1CCE0C85517CA32D56B4B41CB122DDB39DDFCE5292B2B887554D24616CD1E225D2A79BB6E6FCEB83E231A7DDF680E6A1E3C3E201AB45DA7261D3359434778459F643FA67B3E837E803
-20200305143048 2 6 100 6143 2 F7E8D9659B6A380E77600433F564EB23739AF15BF41262D170EC8A14567AE58A0465E39314F019B721FE6F113293EF987DCB177ADD8B7C2E547D393B4873E903C4616BA56468A20ABBA70DCDE1E0B5AA01164D612A1996ECA5BF3E7EFF9D94D54066B56057AE148281B5CC663E6D2979FC8B0C1EE9885F58E944E3A28906BBF202A7DB476CA39AD7FF03D3471379305B798A43EE4DBADB53E5994519C2A799D6C52F1FEDD29C8316DA7190A1277702C04BF5DE331D013DD89C24BE50DEDFA9C5E017E873271FB2E270BD563B6F88391EF560307AE8AFEF8290E60FB57ADF3DE8B9062EA0DAC5CC7EE8900EB2F98023B8655CC5646BDF37C43B64EBEC8918E2BABDA6360C74CBBD6E6986B1E506544F7EEBBB275AF18E5A03E704EE4C5459248A23571F724E1DB11F801F2110A813E14DD524358B4F8B0029164C1640D58D6EDC820CA8A8D79C76106BC3CE8345423E640F2E945C24DF557E1203988C085CB62982AC65F567127289B1CD56961305143E5386BCC75454B3C4BB0870E522E38F8C008418897E25F47ED03CF7B10E40EB7CB0153CF6D22CFCD80734FF85266E63FFD3F09B64195C075B50D65F1E0CC73CE5369A6B0E7D4A05F5F4408EBADDB2C21F76A8FF8E800A828AB23089414A6F5DB04F38FD22EA3A4F77F31C35C55D22B38B76DF5C05E6886B8D88C7A014B2A23D4663978363A75C17B97F51BE8C6A55AA6432BE8FBD80220A99DBD897AC1A545690308C5FBED26D5A074CA38D03C5CE904C86DE6BC2B64B4B7E21EB0244FF37EEBB5873296B440B5059816A0E2BA9A7663B84C3ACB607909F4108249F9949FCBFF8FB242012ECFD26C931FB9BE3C93A524C623E41EBF29976B8594688A73CDC36F53B3FC3AB8EA1DEC8A8226DB05D2D90FA523EC62FF03BA659F5D1EB6D6250ECD3E70E06D3E3BD4CCDB78D31BE96F9B8AC679C7341F9E40A3B38727FEC13077393D30C5BE613262C1CCE0C85517CA32D56B4B41CB122DDB39DDFCE5292B2B887554D24616CD1E225D2A79BB6E6FCEB83E231A7DDF680E6A1E3C3E201AB45DA7261D3359434778459F643FA67B3E9457303
-20200305145210 2 6 100 6143 5 F7E8D9659B6A380E77600433F564EB23739AF15BF41262D170EC8A14567AE58A0465E39314F019B721FE6F113293EF987DCB177ADD8B7C2E547D393B4873E903C4616BA56468A20ABBA70DCDE1E0B5AA01164D612A1996ECA5BF3E7EFF9D94D54066B56057AE148281B5CC663E6D2979FC8B0C1EE9885F58E944E3A28906BBF202A7DB476CA39AD7FF03D3471379305B798A43EE4DBADB53E5994519C2A799D6C52F1FEDD29C8316DA7190A1277702C04BF5DE331D013DD89C24BE50DEDFA9C5E017E873271FB2E270BD563B6F88391EF560307AE8AFEF8290E60FB57ADF3DE8B9062EA0DAC5CC7EE8900EB2F98023B8655CC5646BDF37C43B64EBEC8918E2BABDA6360C74CBBD6E6986B1E506544F7EEBBB275AF18E5A03E704EE4C5459248A23571F724E1DB11F801F2110A813E14DD524358B4F8B0029164C1640D58D6EDC820CA8A8D79C76106BC3CE8345423E640F2E945C24DF557E1203988C085CB62982AC65F567127289B1CD56961305143E5386BCC75454B3C4BB0870E522E38F8C008418897E25F47ED03CF7B10E40EB7CB0153CF6D22CFCD80734FF85266E63FFD3F09B64195C075B50D65F1E0CC73CE5369A6B0E7D4A05F5F4408EBADDB2C21F76A8FF8E800A828AB23089414A6F5DB04F38FD22EA3A4F77F31C35C55D22B38B76DF5C05E6886B8D88C7A014B2A23D4663978363A75C17B97F51BE8C6A55AA6432BE8FBD80220A99DBD897AC1A545690308C5FBED26D5A074CA38D03C5CE904C86DE6BC2B64B4B7E21EB0244FF37EEBB5873296B440B5059816A0E2BA9A7663B84C3ACB607909F4108249F9949FCBFF8FB242012ECFD26C931FB9BE3C93A524C623E41EBF29976B8594688A73CDC36F53B3FC3AB8EA1DEC8A8226DB05D2D90FA523EC62FF03BA659F5D1EB6D6250ECD3E70E06D3E3BD4CCDB78D31BE96F9B8AC679C7341F9E40A3B38727FEC13077393D30C5BE613262C1CCE0C85517CA32D56B4B41CB122DDB39DDFCE5292B2B887554D24616CD1E225D2A79BB6E6FCEB83E231A7DDF680E6A1E3C3E201AB45DA7261D3359434778459F643FA67B3E9AE72AF
-20200305151101 2 6 100 6143 2 F7E8D9659B6A380E77600433F564EB23739AF15BF41262D170EC8A14567AE58A0465E39314F019B721FE6F113293EF987DCB177ADD8B7C2E547D393B4873E903C4616BA56468A20ABBA70DCDE1E0B5AA01164D612A1996ECA5BF3E7EFF9D94D54066B56057AE148281B5CC663E6D2979FC8B0C1EE9885F58E944E3A28906BBF202A7DB476CA39AD7FF03D3471379305B798A43EE4DBADB53E5994519C2A799D6C52F1FEDD29C8316DA7190A1277702C04BF5DE331D013DD89C24BE50DEDFA9C5E017E873271FB2E270BD563B6F88391EF560307AE8AFEF8290E60FB57ADF3DE8B9062EA0DAC5CC7EE8900EB2F98023B8655CC5646BDF37C43B64EBEC8918E2BABDA6360C74CBBD6E6986B1E506544F7EEBBB275AF18E5A03E704EE4C5459248A23571F724E1DB11F801F2110A813E14DD524358B4F8B0029164C1640D58D6EDC820CA8A8D79C76106BC3CE8345423E640F2E945C24DF557E1203988C085CB62982AC65F567127289B1CD56961305143E5386BCC75454B3C4BB0870E522E38F8C008418897E25F47ED03CF7B10E40EB7CB0153CF6D22CFCD80734FF85266E63FFD3F09B64195C075B50D65F1E0CC73CE5369A6B0E7D4A05F5F4408EBADDB2C21F76A8FF8E800A828AB23089414A6F5DB04F38FD22EA3A4F77F31C35C55D22B38B76DF5C05E6886B8D88C7A014B2A23D4663978363A75C17B97F51BE8C6A55AA6432BE8FBD80220A99DBD897AC1A545690308C5FBED26D5A074CA38D03C5CE904C86DE6BC2B64B4B7E21EB0244FF37EEBB5873296B440B5059816A0E2BA9A7663B84C3ACB607909F4108249F9949FCBFF8FB242012ECFD26C931FB9BE3C93A524C623E41EBF29976B8594688A73CDC36F53B3FC3AB8EA1DEC8A8226DB05D2D90FA523EC62FF03BA659F5D1EB6D6250ECD3E70E06D3E3BD4CCDB78D31BE96F9B8AC679C7341F9E40A3B38727FEC13077393D30C5BE613262C1CCE0C85517CA32D56B4B41CB122DDB39DDFCE5292B2B887554D24616CD1E225D2A79BB6E6FCEB83E231A7DDF680E6A1E3C3E201AB45DA7261D3359434778459F643FA67B3EA0B73AB
-20200305173752 2 6 100 6143 2 F7E8D9659B6A380E77600433F564EB23739AF15BF41262D170EC8A14567AE58A0465E39314F019B721FE6F113293EF987DCB177ADD8B7C2E547D393B4873E903C4616BA56468A20ABBA70DCDE1E0B5AA01164D612A1996ECA5BF3E7EFF9D94D54066B56057AE148281B5CC663E6D2979FC8B0C1EE9885F58E944E3A28906BBF202A7DB476CA39AD7FF03D3471379305B798A43EE4DBADB53E5994519C2A799D6C52F1FEDD29C8316DA7190A1277702C04BF5DE331D013DD89C24BE50DEDFA9C5E017E873271FB2E270BD563B6F88391EF560307AE8AFEF8290E60FB57ADF3DE8B9062EA0DAC5CC7EE8900EB2F98023B8655CC5646BDF37C43B64EBEC8918E2BABDA6360C74CBBD6E6986B1E506544F7EEBBB275AF18E5A03E704EE4C5459248A23571F724E1DB11F801F2110A813E14DD524358B4F8B0029164C1640D58D6EDC820CA8A8D79C76106BC3CE8345423E640F2E945C24DF557E1203988C085CB62982AC65F567127289B1CD56961305143E5386BCC75454B3C4BB0870E522E38F8C008418897E25F47ED03CF7B10E40EB7CB0153CF6D22CFCD80734FF85266E63FFD3F09B64195C075B50D65F1E0CC73CE5369A6B0E7D4A05F5F4408EBADDB2C21F76A8FF8E800A828AB23089414A6F5DB04F38FD22EA3A4F77F31C35C55D22B38B76DF5C05E6886B8D88C7A014B2A23D4663978363A75C17B97F51BE8C6A55AA6432BE8FBD80220A99DBD897AC1A545690308C5FBED26D5A074CA38D03C5CE904C86DE6BC2B64B4B7E21EB0244FF37EEBB5873296B440B5059816A0E2BA9A7663B84C3ACB607909F4108249F9949FCBFF8FB242012ECFD26C931FB9BE3C93A524C623E41EBF29976B8594688A73CDC36F53B3FC3AB8EA1DEC8A8226DB05D2D90FA523EC62FF03BA659F5D1EB6D6250ECD3E70E06D3E3BD4CCDB78D31BE96F9B8AC679C7341F9E40A3B38727FEC13077393D30C5BE613262C1CCE0C85517CA32D56B4B41CB122DDB39DDFCE5292B2B887554D24616CD1E225D2A79BB6E6FCEB83E231A7DDF680E6A1E3C3E201AB45DA7261D3359434778459F643FA67B3ED2976C3
-20200305182017 2 6 100 6143 5 F7E8D9659B6A380E77600433F564EB23739AF15BF41262D170EC8A14567AE58A0465E39314F019B721FE6F113293EF987DCB177ADD8B7C2E547D393B4873E903C4616BA56468A20ABBA70DCDE1E0B5AA01164D612A1996ECA5BF3E7EFF9D94D54066B56057AE148281B5CC663E6D2979FC8B0C1EE9885F58E944E3A28906BBF202A7DB476CA39AD7FF03D3471379305B798A43EE4DBADB53E5994519C2A799D6C52F1FEDD29C8316DA7190A1277702C04BF5DE331D013DD89C24BE50DEDFA9C5E017E873271FB2E270BD563B6F88391EF560307AE8AFEF8290E60FB57ADF3DE8B9062EA0DAC5CC7EE8900EB2F98023B8655CC5646BDF37C43B64EBEC8918E2BABDA6360C74CBBD6E6986B1E506544F7EEBBB275AF18E5A03E704EE4C5459248A23571F724E1DB11F801F2110A813E14DD524358B4F8B0029164C1640D58D6EDC820CA8A8D79C76106BC3CE8345423E640F2E945C24DF557E1203988C085CB62982AC65F567127289B1CD56961305143E5386BCC75454B3C4BB0870E522E38F8C008418897E25F47ED03CF7B10E40EB7CB0153CF6D22CFCD80734FF85266E63FFD3F09B64195C075B50D65F1E0CC73CE5369A6B0E7D4A05F5F4408EBADDB2C21F76A8FF8E800A828AB23089414A6F5DB04F38FD22EA3A4F77F31C35C55D22B38B76DF5C05E6886B8D88C7A014B2A23D4663978363A75C17B97F51BE8C6A55AA6432BE8FBD80220A99DBD897AC1A545690308C5FBED26D5A074CA38D03C5CE904C86DE6BC2B64B4B7E21EB0244FF37EEBB5873296B440B5059816A0E2BA9A7663B84C3ACB607909F4108249F9949FCBFF8FB242012ECFD26C931FB9BE3C93A524C623E41EBF29976B8594688A73CDC36F53B3FC3AB8EA1DEC8A8226DB05D2D90FA523EC62FF03BA659F5D1EB6D6250ECD3E70E06D3E3BD4CCDB78D31BE96F9B8AC679C7341F9E40A3B38727FEC13077393D30C5BE613262C1CCE0C85517CA32D56B4B41CB122DDB39DDFCE5292B2B887554D24616CD1E225D2A79BB6E6FCEB83E231A7DDF680E6A1E3C3E201AB45DA7261D3359434778459F643FA67B3EE08294F
-20200305183227 2 6 100 6143 2 F7E8D9659B6A380E77600433F564EB23739AF15BF41262D170EC8A14567AE58A0465E39314F019B721FE6F113293EF987DCB177ADD8B7C2E547D393B4873E903C4616BA56468A20ABBA70DCDE1E0B5AA01164D612A1996ECA5BF3E7EFF9D94D54066B56057AE148281B5CC663E6D2979FC8B0C1EE9885F58E944E3A28906BBF202A7DB476CA39AD7FF03D3471379305B798A43EE4DBADB53E5994519C2A799D6C52F1FEDD29C8316DA7190A1277702C04BF5DE331D013DD89C24BE50DEDFA9C5E017E873271FB2E270BD563B6F88391EF560307AE8AFEF8290E60FB57ADF3DE8B9062EA0DAC5CC7EE8900EB2F98023B8655CC5646BDF37C43B64EBEC8918E2BABDA6360C74CBBD6E6986B1E506544F7EEBBB275AF18E5A03E704EE4C5459248A23571F724E1DB11F801F2110A813E14DD524358B4F8B0029164C1640D58D6EDC820CA8A8D79C76106BC3CE8345423E640F2E945C24DF557E1203988C085CB62982AC65F567127289B1CD56961305143E5386BCC75454B3C4BB0870E522E38F8C008418897E25F47ED03CF7B10E40EB7CB0153CF6D22CFCD80734FF85266E63FFD3F09B64195C075B50D65F1E0CC73CE5369A6B0E7D4A05F5F4408EBADDB2C21F76A8FF8E800A828AB23089414A6F5DB04F38FD22EA3A4F77F31C35C55D22B38B76DF5C05E6886B8D88C7A014B2A23D4663978363A75C17B97F51BE8C6A55AA6432BE8FBD80220A99DBD897AC1A545690308C5FBED26D5A074CA38D03C5CE904C86DE6BC2B64B4B7E21EB0244FF37EEBB5873296B440B5059816A0E2BA9A7663B84C3ACB607909F4108249F9949FCBFF8FB242012ECFD26C931FB9BE3C93A524C623E41EBF29976B8594688A73CDC36F53B3FC3AB8EA1DEC8A8226DB05D2D90FA523EC62FF03BA659F5D1EB6D6250ECD3E70E06D3E3BD4CCDB78D31BE96F9B8AC679C7341F9E40A3B38727FEC13077393D30C5BE613262C1CCE0C85517CA32D56B4B41CB122DDB39DDFCE5292B2B887554D24616CD1E225D2A79BB6E6FCEB83E231A7DDF680E6A1E3C3E201AB45DA7261D3359434778459F643FA67B3EE448B23
-20200305205936 2 6 100 6143 2 F7E8D9659B6A380E77600433F564EB23739AF15BF41262D170EC8A14567AE58A0465E39314F019B721FE6F113293EF987DCB177ADD8B7C2E547D393B4873E903C4616BA56468A20ABBA70DCDE1E0B5AA01164D612A1996ECA5BF3E7EFF9D94D54066B56057AE148281B5CC663E6D2979FC8B0C1EE9885F58E944E3A28906BBF202A7DB476CA39AD7FF03D3471379305B798A43EE4DBADB53E5994519C2A799D6C52F1FEDD29C8316DA7190A1277702C04BF5DE331D013DD89C24BE50DEDFA9C5E017E873271FB2E270BD563B6F88391EF560307AE8AFEF8290E60FB57ADF3DE8B9062EA0DAC5CC7EE8900EB2F98023B8655CC5646BDF37C43B64EBEC8918E2BABDA6360C74CBBD6E6986B1E506544F7EEBBB275AF18E5A03E704EE4C5459248A23571F724E1DB11F801F2110A813E14DD524358B4F8B0029164C1640D58D6EDC820CA8A8D79C76106BC3CE8345423E640F2E945C24DF557E1203988C085CB62982AC65F567127289B1CD56961305143E5386BCC75454B3C4BB0870E522E38F8C008418897E25F47ED03CF7B10E40EB7CB0153CF6D22CFCD80734FF85266E63FFD3F09B64195C075B50D65F1E0CC73CE5369A6B0E7D4A05F5F4408EBADDB2C21F76A8FF8E800A828AB23089414A6F5DB04F38FD22EA3A4F77F31C35C55D22B38B76DF5C05E6886B8D88C7A014B2A23D4663978363A75C17B97F51BE8C6A55AA6432BE8FBD80220A99DBD897AC1A545690308C5FBED26D5A074CA38D03C5CE904C86DE6BC2B64B4B7E21EB0244FF37EEBB5873296B440B5059816A0E2BA9A7663B84C3ACB607909F4108249F9949FCBFF8FB242012ECFD26C931FB9BE3C93A524C623E41EBF29976B8594688A73CDC36F53B3FC3AB8EA1DEC8A8226DB05D2D90FA523EC62FF03BA659F5D1EB6D6250ECD3E70E06D3E3BD4CCDB78D31BE96F9B8AC679C7341F9E40A3B38727FEC13077393D30C5BE613262C1CCE0C85517CA32D56B4B41CB122DDB39DDFCE5292B2B887554D24616CD1E225D2A79BB6E6FCEB83E231A7DDF680E6A1E3C3E201AB45DA7261D3359434778459F643FA67B3F16DF2CB
-20200305230320 2 6 100 6143 2 F7E8D9659B6A380E77600433F564EB23739AF15BF41262D170EC8A14567AE58A0465E39314F019B721FE6F113293EF987DCB177ADD8B7C2E547D393B4873E903C4616BA56468A20ABBA70DCDE1E0B5AA01164D612A1996ECA5BF3E7EFF9D94D54066B56057AE148281B5CC663E6D2979FC8B0C1EE9885F58E944E3A28906BBF202A7DB476CA39AD7FF03D3471379305B798A43EE4DBADB53E5994519C2A799D6C52F1FEDD29C8316DA7190A1277702C04BF5DE331D013DD89C24BE50DEDFA9C5E017E873271FB2E270BD563B6F88391EF560307AE8AFEF8290E60FB57ADF3DE8B9062EA0DAC5CC7EE8900EB2F98023B8655CC5646BDF37C43B64EBEC8918E2BABDA6360C74CBBD6E6986B1E506544F7EEBBB275AF18E5A03E704EE4C5459248A23571F724E1DB11F801F2110A813E14DD524358B4F8B0029164C1640D58D6EDC820CA8A8D79C76106BC3CE8345423E640F2E945C24DF557E1203988C085CB62982AC65F567127289B1CD56961305143E5386BCC75454B3C4BB0870E522E38F8C008418897E25F47ED03CF7B10E40EB7CB0153CF6D22CFCD80734FF85266E63FFD3F09B64195C075B50D65F1E0CC73CE5369A6B0E7D4A05F5F4408EBADDB2C21F76A8FF8E800A828AB23089414A6F5DB04F38FD22EA3A4F77F31C35C55D22B38B76DF5C05E6886B8D88C7A014B2A23D4663978363A75C17B97F51BE8C6A55AA6432BE8FBD80220A99DBD897AC1A545690308C5FBED26D5A074CA38D03C5CE904C86DE6BC2B64B4B7E21EB0244FF37EEBB5873296B440B5059816A0E2BA9A7663B84C3ACB607909F4108249F9949FCBFF8FB242012ECFD26C931FB9BE3C93A524C623E41EBF29976B8594688A73CDC36F53B3FC3AB8EA1DEC8A8226DB05D2D90FA523EC62FF03BA659F5D1EB6D6250ECD3E70E06D3E3BD4CCDB78D31BE96F9B8AC679C7341F9E40A3B38727FEC13077393D30C5BE613262C1CCE0C85517CA32D56B4B41CB122DDB39DDFCE5292B2B887554D24616CD1E225D2A79BB6E6FCEB83E231A7DDF680E6A1E3C3E201AB45DA7261D3359434778459F643FA67B3F412E2BB
-20200306003322 2 6 100 6143 2 F7E8D9659B6A380E77600433F564EB23739AF15BF41262D170EC8A14567AE58A0465E39314F019B721FE6F113293EF987DCB177ADD8B7C2E547D393B4873E903C4616BA56468A20ABBA70DCDE1E0B5AA01164D612A1996ECA5BF3E7EFF9D94D54066B56057AE148281B5CC663E6D2979FC8B0C1EE9885F58E944E3A28906BBF202A7DB476CA39AD7FF03D3471379305B798A43EE4DBADB53E5994519C2A799D6C52F1FEDD29C8316DA7190A1277702C04BF5DE331D013DD89C24BE50DEDFA9C5E017E873271FB2E270BD563B6F88391EF560307AE8AFEF8290E60FB57ADF3DE8B9062EA0DAC5CC7EE8900EB2F98023B8655CC5646BDF37C43B64EBEC8918E2BABDA6360C74CBBD6E6986B1E506544F7EEBBB275AF18E5A03E704EE4C5459248A23571F724E1DB11F801F2110A813E14DD524358B4F8B0029164C1640D58D6EDC820CA8A8D79C76106BC3CE8345423E640F2E945C24DF557E1203988C085CB62982AC65F567127289B1CD56961305143E5386BCC75454B3C4BB0870E522E38F8C008418897E25F47ED03CF7B10E40EB7CB0153CF6D22CFCD80734FF85266E63FFD3F09B64195C075B50D65F1E0CC73CE5369A6B0E7D4A05F5F4408EBADDB2C21F76A8FF8E800A828AB23089414A6F5DB04F38FD22EA3A4F77F31C35C55D22B38B76DF5C05E6886B8D88C7A014B2A23D4663978363A75C17B97F51BE8C6A55AA6432BE8FBD80220A99DBD897AC1A545690308C5FBED26D5A074CA38D03C5CE904C86DE6BC2B64B4B7E21EB0244FF37EEBB5873296B440B5059816A0E2BA9A7663B84C3ACB607909F4108249F9949FCBFF8FB242012ECFD26C931FB9BE3C93A524C623E41EBF29976B8594688A73CDC36F53B3FC3AB8EA1DEC8A8226DB05D2D90FA523EC62FF03BA659F5D1EB6D6250ECD3E70E06D3E3BD4CCDB78D31BE96F9B8AC679C7341F9E40A3B38727FEC13077393D30C5BE613262C1CCE0C85517CA32D56B4B41CB122DDB39DDFCE5292B2B887554D24616CD1E225D2A79BB6E6FCEB83E231A7DDF680E6A1E3C3E201AB45DA7261D3359434778459F643FA67B3F5F45EB3
-20200306005357 2 6 100 6143 5 F7E8D9659B6A380E77600433F564EB23739AF15BF41262D170EC8A14567AE58A0465E39314F019B721FE6F113293EF987DCB177ADD8B7C2E547D393B4873E903C4616BA56468A20ABBA70DCDE1E0B5AA01164D612A1996ECA5BF3E7EFF9D94D54066B56057AE148281B5CC663E6D2979FC8B0C1EE9885F58E944E3A28906BBF202A7DB476CA39AD7FF03D3471379305B798A43EE4DBADB53E5994519C2A799D6C52F1FEDD29C8316DA7190A1277702C04BF5DE331D013DD89C24BE50DEDFA9C5E017E873271FB2E270BD563B6F88391EF560307AE8AFEF8290E60FB57ADF3DE8B9062EA0DAC5CC7EE8900EB2F98023B8655CC5646BDF37C43B64EBEC8918E2BABDA6360C74CBBD6E6986B1E506544F7EEBBB275AF18E5A03E704EE4C5459248A23571F724E1DB11F801F2110A813E14DD524358B4F8B0029164C1640D58D6EDC820CA8A8D79C76106BC3CE8345423E640F2E945C24DF557E1203988C085CB62982AC65F567127289B1CD56961305143E5386BCC75454B3C4BB0870E522E38F8C008418897E25F47ED03CF7B10E40EB7CB0153CF6D22CFCD80734FF85266E63FFD3F09B64195C075B50D65F1E0CC73CE5369A6B0E7D4A05F5F4408EBADDB2C21F76A8FF8E800A828AB23089414A6F5DB04F38FD22EA3A4F77F31C35C55D22B38B76DF5C05E6886B8D88C7A014B2A23D4663978363A75C17B97F51BE8C6A55AA6432BE8FBD80220A99DBD897AC1A545690308C5FBED26D5A074CA38D03C5CE904C86DE6BC2B64B4B7E21EB0244FF37EEBB5873296B440B5059816A0E2BA9A7663B84C3ACB607909F4108249F9949FCBFF8FB242012ECFD26C931FB9BE3C93A524C623E41EBF29976B8594688A73CDC36F53B3FC3AB8EA1DEC8A8226DB05D2D90FA523EC62FF03BA659F5D1EB6D6250ECD3E70E06D3E3BD4CCDB78D31BE96F9B8AC679C7341F9E40A3B38727FEC13077393D30C5BE613262C1CCE0C85517CA32D56B4B41CB122DDB39DDFCE5292B2B887554D24616CD1E225D2A79BB6E6FCEB83E231A7DDF680E6A1E3C3E201AB45DA7261D3359434778459F643FA67B3F65E4A6F
-20200306052421 2 6 100 6143 2 F7E8D9659B6A380E77600433F564EB23739AF15BF41262D170EC8A14567AE58A0465E39314F019B721FE6F113293EF987DCB177ADD8B7C2E547D393B4873E903C4616BA56468A20ABBA70DCDE1E0B5AA01164D612A1996ECA5BF3E7EFF9D94D54066B56057AE148281B5CC663E6D2979FC8B0C1EE9885F58E944E3A28906BBF202A7DB476CA39AD7FF03D3471379305B798A43EE4DBADB53E5994519C2A799D6C52F1FEDD29C8316DA7190A1277702C04BF5DE331D013DD89C24BE50DEDFA9C5E017E873271FB2E270BD563B6F88391EF560307AE8AFEF8290E60FB57ADF3DE8B9062EA0DAC5CC7EE8900EB2F98023B8655CC5646BDF37C43B64EBEC8918E2BABDA6360C74CBBD6E6986B1E506544F7EEBBB275AF18E5A03E704EE4C5459248A23571F724E1DB11F801F2110A813E14DD524358B4F8B0029164C1640D58D6EDC820CA8A8D79C76106BC3CE8345423E640F2E945C24DF557E1203988C085CB62982AC65F567127289B1CD56961305143E5386BCC75454B3C4BB0870E522E38F8C008418897E25F47ED03CF7B10E40EB7CB0153CF6D22CFCD80734FF85266E63FFD3F09B64195C075B50D65F1E0CC73CE5369A6B0E7D4A05F5F4408EBADDB2C21F76A8FF8E800A828AB23089414A6F5DB04F38FD22EA3A4F77F31C35C55D22B38B76DF5C05E6886B8D88C7A014B2A23D4663978363A75C17B97F51BE8C6A55AA6432BE8FBD80220A99DBD897AC1A545690308C5FBED26D5A074CA38D03C5CE904C86DE6BC2B64B4B7E21EB0244FF37EEBB5873296B440B5059816A0E2BA9A7663B84C3ACB607909F4108249F9949FCBFF8FB242012ECFD26C931FB9BE3C93A524C623E41EBF29976B8594688A73CDC36F53B3FC3AB8EA1DEC8A8226DB05D2D90FA523EC62FF03BA659F5D1EB6D6250ECD3E70E06D3E3BD4CCDB78D31BE96F9B8AC679C7341F9E40A3B38727FEC13077393D30C5BE613262C1CCE0C85517CA32D56B4B41CB122DDB39DDFCE5292B2B887554D24616CD1E225D2A79BB6E6FCEB83E231A7DDF680E6A1E3C3E201AB45DA7261D3359434778459F643FA67B3FC141813
-20200306071740 2 6 100 6143 5 F7E8D9659B6A380E77600433F564EB23739AF15BF41262D170EC8A14567AE58A0465E39314F019B721FE6F113293EF987DCB177ADD8B7C2E547D393B4873E903C4616BA56468A20ABBA70DCDE1E0B5AA01164D612A1996ECA5BF3E7EFF9D94D54066B56057AE148281B5CC663E6D2979FC8B0C1EE9885F58E944E3A28906BBF202A7DB476CA39AD7FF03D3471379305B798A43EE4DBADB53E5994519C2A799D6C52F1FEDD29C8316DA7190A1277702C04BF5DE331D013DD89C24BE50DEDFA9C5E017E873271FB2E270BD563B6F88391EF560307AE8AFEF8290E60FB57ADF3DE8B9062EA0DAC5CC7EE8900EB2F98023B8655CC5646BDF37C43B64EBEC8918E2BABDA6360C74CBBD6E6986B1E506544F7EEBBB275AF18E5A03E704EE4C5459248A23571F724E1DB11F801F2110A813E14DD524358B4F8B0029164C1640D58D6EDC820CA8A8D79C76106BC3CE8345423E640F2E945C24DF557E1203988C085CB62982AC65F567127289B1CD56961305143E5386BCC75454B3C4BB0870E522E38F8C008418897E25F47ED03CF7B10E40EB7CB0153CF6D22CFCD80734FF85266E63FFD3F09B64195C075B50D65F1E0CC73CE5369A6B0E7D4A05F5F4408EBADDB2C21F76A8FF8E800A828AB23089414A6F5DB04F38FD22EA3A4F77F31C35C55D22B38B76DF5C05E6886B8D88C7A014B2A23D4663978363A75C17B97F51BE8C6A55AA6432BE8FBD80220A99DBD897AC1A545690308C5FBED26D5A074CA38D03C5CE904C86DE6BC2B64B4B7E21EB0244FF37EEBB5873296B440B5059816A0E2BA9A7663B84C3ACB607909F4108249F9949FCBFF8FB242012ECFD26C931FB9BE3C93A524C623E41EBF29976B8594688A73CDC36F53B3FC3AB8EA1DEC8A8226DB05D2D90FA523EC62FF03BA659F5D1EB6D6250ECD3E70E06D3E3BD4CCDB78D31BE96F9B8AC679C7341F9E40A3B38727FEC13077393D30C5BE613262C1CCE0C85517CA32D56B4B41CB122DDB39DDFCE5292B2B887554D24616CD1E225D2A79BB6E6FCEB83E231A7DDF680E6A1E3C3E201AB45DA7261D3359434778459F643FA67B3FE6DC957
-20200306093244 2 6 100 6143 2 F7E8D9659B6A380E77600433F564EB23739AF15BF41262D170EC8A14567AE58A0465E39314F019B721FE6F113293EF987DCB177ADD8B7C2E547D393B4873E903C4616BA56468A20ABBA70DCDE1E0B5AA01164D612A1996ECA5BF3E7EFF9D94D54066B56057AE148281B5CC663E6D2979FC8B0C1EE9885F58E944E3A28906BBF202A7DB476CA39AD7FF03D3471379305B798A43EE4DBADB53E5994519C2A799D6C52F1FEDD29C8316DA7190A1277702C04BF5DE331D013DD89C24BE50DEDFA9C5E017E873271FB2E270BD563B6F88391EF560307AE8AFEF8290E60FB57ADF3DE8B9062EA0DAC5CC7EE8900EB2F98023B8655CC5646BDF37C43B64EBEC8918E2BABDA6360C74CBBD6E6986B1E506544F7EEBBB275AF18E5A03E704EE4C5459248A23571F724E1DB11F801F2110A813E14DD524358B4F8B0029164C1640D58D6EDC820CA8A8D79C76106BC3CE8345423E640F2E945C24DF557E1203988C085CB62982AC65F567127289B1CD56961305143E5386BCC75454B3C4BB0870E522E38F8C008418897E25F47ED03CF7B10E40EB7CB0153CF6D22CFCD80734FF85266E63FFD3F09B64195C075B50D65F1E0CC73CE5369A6B0E7D4A05F5F4408EBADDB2C21F76A8FF8E800A828AB23089414A6F5DB04F38FD22EA3A4F77F31C35C55D22B38B76DF5C05E6886B8D88C7A014B2A23D4663978363A75C17B97F51BE8C6A55AA6432BE8FBD80220A99DBD897AC1A545690308C5FBED26D5A074CA38D03C5CE904C86DE6BC2B64B4B7E21EB0244FF37EEBB5873296B440B5059816A0E2BA9A7663B84C3ACB607909F4108249F9949FCBFF8FB242012ECFD26C931FB9BE3C93A524C623E41EBF29976B8594688A73CDC36F53B3FC3AB8EA1DEC8A8226DB05D2D90FA523EC62FF03BA659F5D1EB6D6250ECD3E70E06D3E3BD4CCDB78D31BE96F9B8AC679C7341F9E40A3B38727FEC13077393D30C5BE613262C1CCE0C85517CA32D56B4B41CB122DDB39DDFCE5292B2B887554D24616CD1E225D2A79BB6E6FCEB83E231A7DDF680E6A1E3C3E201AB45DA7261D3359434778459F643FA67B4014328CB
-20200306114315 2 6 100 6143 5 F7E8D9659B6A380E77600433F564EB23739AF15BF41262D170EC8A14567AE58A0465E39314F019B721FE6F113293EF987DCB177ADD8B7C2E547D393B4873E903C4616BA56468A20ABBA70DCDE1E0B5AA01164D612A1996ECA5BF3E7EFF9D94D54066B56057AE148281B5CC663E6D2979FC8B0C1EE9885F58E944E3A28906BBF202A7DB476CA39AD7FF03D3471379305B798A43EE4DBADB53E5994519C2A799D6C52F1FEDD29C8316DA7190A1277702C04BF5DE331D013DD89C24BE50DEDFA9C5E017E873271FB2E270BD563B6F88391EF560307AE8AFEF8290E60FB57ADF3DE8B9062EA0DAC5CC7EE8900EB2F98023B8655CC5646BDF37C43B64EBEC8918E2BABDA6360C74CBBD6E6986B1E506544F7EEBBB275AF18E5A03E704EE4C5459248A23571F724E1DB11F801F2110A813E14DD524358B4F8B0029164C1640D58D6EDC820CA8A8D79C76106BC3CE8345423E640F2E945C24DF557E1203988C085CB62982AC65F567127289B1CD56961305143E5386BCC75454B3C4BB0870E522E38F8C008418897E25F47ED03CF7B10E40EB7CB0153CF6D22CFCD80734FF85266E63FFD3F09B64195C075B50D65F1E0CC73CE5369A6B0E7D4A05F5F4408EBADDB2C21F76A8FF8E800A828AB23089414A6F5DB04F38FD22EA3A4F77F31C35C55D22B38B76DF5C05E6886B8D88C7A014B2A23D4663978363A75C17B97F51BE8C6A55AA6432BE8FBD80220A99DBD897AC1A545690308C5FBED26D5A074CA38D03C5CE904C86DE6BC2B64B4B7E21EB0244FF37EEBB5873296B440B5059816A0E2BA9A7663B84C3ACB607909F4108249F9949FCBFF8FB242012ECFD26C931FB9BE3C93A524C623E41EBF29976B8594688A73CDC36F53B3FC3AB8EA1DEC8A8226DB05D2D90FA523EC62FF03BA659F5D1EB6D6250ECD3E70E06D3E3BD4CCDB78D31BE96F9B8AC679C7341F9E40A3B38727FEC13077393D30C5BE613262C1CCE0C85517CA32D56B4B41CB122DDB39DDFCE5292B2B887554D24616CD1E225D2A79BB6E6FCEB83E231A7DDF680E6A1E3C3E201AB45DA7261D3359434778459F643FA67B403F2AAAF
-20200306115622 2 6 100 6143 5 F7E8D9659B6A380E77600433F564EB23739AF15BF41262D170EC8A14567AE58A0465E39314F019B721FE6F113293EF987DCB177ADD8B7C2E547D393B4873E903C4616BA56468A20ABBA70DCDE1E0B5AA01164D612A1996ECA5BF3E7EFF9D94D54066B56057AE148281B5CC663E6D2979FC8B0C1EE9885F58E944E3A28906BBF202A7DB476CA39AD7FF03D3471379305B798A43EE4DBADB53E5994519C2A799D6C52F1FEDD29C8316DA7190A1277702C04BF5DE331D013DD89C24BE50DEDFA9C5E017E873271FB2E270BD563B6F88391EF560307AE8AFEF8290E60FB57ADF3DE8B9062EA0DAC5CC7EE8900EB2F98023B8655CC5646BDF37C43B64EBEC8918E2BABDA6360C74CBBD6E6986B1E506544F7EEBBB275AF18E5A03E704EE4C5459248A23571F724E1DB11F801F2110A813E14DD524358B4F8B0029164C1640D58D6EDC820CA8A8D79C76106BC3CE8345423E640F2E945C24DF557E1203988C085CB62982AC65F567127289B1CD56961305143E5386BCC75454B3C4BB0870E522E38F8C008418897E25F47ED03CF7B10E40EB7CB0153CF6D22CFCD80734FF85266E63FFD3F09B64195C075B50D65F1E0CC73CE5369A6B0E7D4A05F5F4408EBADDB2C21F76A8FF8E800A828AB23089414A6F5DB04F38FD22EA3A4F77F31C35C55D22B38B76DF5C05E6886B8D88C7A014B2A23D4663978363A75C17B97F51BE8C6A55AA6432BE8FBD80220A99DBD897AC1A545690308C5FBED26D5A074CA38D03C5CE904C86DE6BC2B64B4B7E21EB0244FF37EEBB5873296B440B5059816A0E2BA9A7663B84C3ACB607909F4108249F9949FCBFF8FB242012ECFD26C931FB9BE3C93A524C623E41EBF29976B8594688A73CDC36F53B3FC3AB8EA1DEC8A8226DB05D2D90FA523EC62FF03BA659F5D1EB6D6250ECD3E70E06D3E3BD4CCDB78D31BE96F9B8AC679C7341F9E40A3B38727FEC13077393D30C5BE613262C1CCE0C85517CA32D56B4B41CB122DDB39DDFCE5292B2B887554D24616CD1E225D2A79BB6E6FCEB83E231A7DDF680E6A1E3C3E201AB45DA7261D3359434778459F643FA67B404300D27
-20200306115809 2 6 100 6143 5 F7E8D9659B6A380E77600433F564EB23739AF15BF41262D170EC8A14567AE58A0465E39314F019B721FE6F113293EF987DCB177ADD8B7C2E547D393B4873E903C4616BA56468A20ABBA70DCDE1E0B5AA01164D612A1996ECA5BF3E7EFF9D94D54066B56057AE148281B5CC663E6D2979FC8B0C1EE9885F58E944E3A28906BBF202A7DB476CA39AD7FF03D3471379305B798A43EE4DBADB53E5994519C2A799D6C52F1FEDD29C8316DA7190A1277702C04BF5DE331D013DD89C24BE50DEDFA9C5E017E873271FB2E270BD563B6F88391EF560307AE8AFEF8290E60FB57ADF3DE8B9062EA0DAC5CC7EE8900EB2F98023B8655CC5646BDF37C43B64EBEC8918E2BABDA6360C74CBBD6E6986B1E506544F7EEBBB275AF18E5A03E704EE4C5459248A23571F724E1DB11F801F2110A813E14DD524358B4F8B0029164C1640D58D6EDC820CA8A8D79C76106BC3CE8345423E640F2E945C24DF557E1203988C085CB62982AC65F567127289B1CD56961305143E5386BCC75454B3C4BB0870E522E38F8C008418897E25F47ED03CF7B10E40EB7CB0153CF6D22CFCD80734FF85266E63FFD3F09B64195C075B50D65F1E0CC73CE5369A6B0E7D4A05F5F4408EBADDB2C21F76A8FF8E800A828AB23089414A6F5DB04F38FD22EA3A4F77F31C35C55D22B38B76DF5C05E6886B8D88C7A014B2A23D4663978363A75C17B97F51BE8C6A55AA6432BE8FBD80220A99DBD897AC1A545690308C5FBED26D5A074CA38D03C5CE904C86DE6BC2B64B4B7E21EB0244FF37EEBB5873296B440B5059816A0E2BA9A7663B84C3ACB607909F4108249F9949FCBFF8FB242012ECFD26C931FB9BE3C93A524C623E41EBF29976B8594688A73CDC36F53B3FC3AB8EA1DEC8A8226DB05D2D90FA523EC62FF03BA659F5D1EB6D6250ECD3E70E06D3E3BD4CCDB78D31BE96F9B8AC679C7341F9E40A3B38727FEC13077393D30C5BE613262C1CCE0C85517CA32D56B4B41CB122DDB39DDFCE5292B2B887554D24616CD1E225D2A79BB6E6FCEB83E231A7DDF680E6A1E3C3E201AB45DA7261D3359434778459F643FA67B40430C46F
-20200306123631 2 6 100 6143 2 F7E8D9659B6A380E77600433F564EB23739AF15BF41262D170EC8A14567AE58A0465E39314F019B721FE6F113293EF987DCB177ADD8B7C2E547D393B4873E903C4616BA56468A20ABBA70DCDE1E0B5AA01164D612A1996ECA5BF3E7EFF9D94D54066B56057AE148281B5CC663E6D2979FC8B0C1EE9885F58E944E3A28906BBF202A7DB476CA39AD7FF03D3471379305B798A43EE4DBADB53E5994519C2A799D6C52F1FEDD29C8316DA7190A1277702C04BF5DE331D013DD89C24BE50DEDFA9C5E017E873271FB2E270BD563B6F88391EF560307AE8AFEF8290E60FB57ADF3DE8B9062EA0DAC5CC7EE8900EB2F98023B8655CC5646BDF37C43B64EBEC8918E2BABDA6360C74CBBD6E6986B1E506544F7EEBBB275AF18E5A03E704EE4C5459248A23571F724E1DB11F801F2110A813E14DD524358B4F8B0029164C1640D58D6EDC820CA8A8D79C76106BC3CE8345423E640F2E945C24DF557E1203988C085CB62982AC65F567127289B1CD56961305143E5386BCC75454B3C4BB0870E522E38F8C008418897E25F47ED03CF7B10E40EB7CB0153CF6D22CFCD80734FF85266E63FFD3F09B64195C075B50D65F1E0CC73CE5369A6B0E7D4A05F5F4408EBADDB2C21F76A8FF8E800A828AB23089414A6F5DB04F38FD22EA3A4F77F31C35C55D22B38B76DF5C05E6886B8D88C7A014B2A23D4663978363A75C17B97F51BE8C6A55AA6432BE8FBD80220A99DBD897AC1A545690308C5FBED26D5A074CA38D03C5CE904C86DE6BC2B64B4B7E21EB0244FF37EEBB5873296B440B5059816A0E2BA9A7663B84C3ACB607909F4108249F9949FCBFF8FB242012ECFD26C931FB9BE3C93A524C623E41EBF29976B8594688A73CDC36F53B3FC3AB8EA1DEC8A8226DB05D2D90FA523EC62FF03BA659F5D1EB6D6250ECD3E70E06D3E3BD4CCDB78D31BE96F9B8AC679C7341F9E40A3B38727FEC13077393D30C5BE613262C1CCE0C85517CA32D56B4B41CB122DDB39DDFCE5292B2B887554D24616CD1E225D2A79BB6E6FCEB83E231A7DDF680E6A1E3C3E201AB45DA7261D3359434778459F643FA67B404FB7883
-20200306155841 2 6 100 6143 2 F7E8D9659B6A380E77600433F564EB23739AF15BF41262D170EC8A14567AE58A0465E39314F019B721FE6F113293EF987DCB177ADD8B7C2E547D393B4873E903C4616BA56468A20ABBA70DCDE1E0B5AA01164D612A1996ECA5BF3E7EFF9D94D54066B56057AE148281B5CC663E6D2979FC8B0C1EE9885F58E944E3A28906BBF202A7DB476CA39AD7FF03D3471379305B798A43EE4DBADB53E5994519C2A799D6C52F1FEDD29C8316DA7190A1277702C04BF5DE331D013DD89C24BE50DEDFA9C5E017E873271FB2E270BD563B6F88391EF560307AE8AFEF8290E60FB57ADF3DE8B9062EA0DAC5CC7EE8900EB2F98023B8655CC5646BDF37C43B64EBEC8918E2BABDA6360C74CBBD6E6986B1E506544F7EEBBB275AF18E5A03E704EE4C5459248A23571F724E1DB11F801F2110A813E14DD524358B4F8B0029164C1640D58D6EDC820CA8A8D79C76106BC3CE8345423E640F2E945C24DF557E1203988C085CB62982AC65F567127289B1CD56961305143E5386BCC75454B3C4BB0870E522E38F8C008418897E25F47ED03CF7B10E40EB7CB0153CF6D22CFCD80734FF85266E63FFD3F09B64195C075B50D65F1E0CC73CE5369A6B0E7D4A05F5F4408EBADDB2C21F76A8FF8E800A828AB23089414A6F5DB04F38FD22EA3A4F77F31C35C55D22B38B76DF5C05E6886B8D88C7A014B2A23D4663978363A75C17B97F51BE8C6A55AA6432BE8FBD80220A99DBD897AC1A545690308C5FBED26D5A074CA38D03C5CE904C86DE6BC2B64B4B7E21EB0244FF37EEBB5873296B440B5059816A0E2BA9A7663B84C3ACB607909F4108249F9949FCBFF8FB242012ECFD26C931FB9BE3C93A524C623E41EBF29976B8594688A73CDC36F53B3FC3AB8EA1DEC8A8226DB05D2D90FA523EC62FF03BA659F5D1EB6D6250ECD3E70E06D3E3BD4CCDB78D31BE96F9B8AC679C7341F9E40A3B38727FEC13077393D30C5BE613262C1CCE0C85517CA32D56B4B41CB122DDB39DDFCE5292B2B887554D24616CD1E225D2A79BB6E6FCEB83E231A7DDF680E6A1E3C3E201AB45DA7261D3359434778459F643FA67B4091B35AB
-20200306171429 2 6 100 6143 5 F3D69BF99011E14ADF3A48E2FE265E067E9E02590D657BD9B87EF896253C2D3E138DD0B1290D92C9E3897C64E6B5D68CC524F18F073D39A1DC53562764B08A71A10564F53CE21A7428EE3E9801773D4E427909A240AE149342F596C2EF87414DBC486DF52C9F4015FD6B6192B77E91590E85BEDD079D9A5C273ED2544352BF913F1824D15B7CE331B5895E7DABB1E932FE9416CCC087E911E0952AE243F1F2FD43C9FF8B294330ED47B38A400A89144A87E461EC6B561654D6D3B5036A412358D781C6AE935901E71C7051FCA3F4BB0049272AC9F1B43847ED0CCA1F8A4670D2378F1AE1338B00D107ED004FB86168512172360F2D40B8F6BFB9E3721A74F637C916AA434DA842009BF9ABE9CE7942A0394042E338C8E61A032440292472D2B3AF3CC5396C84F14DAC115400D3D2FE72E29DD6FC98968523167E853550F8AF4684E70FF48431950DA69958CB9D3D0A03821249739EB909A2E78EB80F651C0553598DD4345ED9F21436D7A49DFA774F15817980CFD72EEE4620BA713D6BF81A953BABE83F5E292A099F07749ECFF6E2258D48F239DD1D0951DE9C3AE22B00098A510FF5230C8CFFFC8B9BE76F1904A05649FD0766D94038ED4AB901433FEEA667D196B7E0242620C6895725DA782234CDA8D1BD49FA586BEB793D2CBB6D3DC8B8FC18992393CA84923FD17774C82EE67D46050910A8D3B823EB253B9A73DBF388DC91DA2A6F14E92D7DF58E2F7AE3D6DAEF74ACEF7B39F068D4E895E6D0020E84AC0095C0991D11F09E02DC024C22A41809898662B58DE47649736CA74F4AA0A2F2B8E09C3B154D1904B82337881030DD9699BD397BE9CD4DC152BD097F3078B69F47465C4B787232227E4F7966E021FBB3F974182022BC35C415BE677C96B08E1A7DD1C3810EF28AD6975730167365DD8335993F96529F36DE245736358E9F9360EB53494247E382496380A006F077F6A1B42F72ED63B7B22CA0D10A410194A2D714C974142E86DF6639BC37714564983322EF900F0E0CA785907DECF7C9557056E09DC242E10D69C3EB604BF96DC2BBE1F69203EF664EA68CD23526BA783157
-20200306192708 2 6 100 6143 2 F3D69BF99011E14ADF3A48E2FE265E067E9E02590D657BD9B87EF896253C2D3E138DD0B1290D92C9E3897C64E6B5D68CC524F18F073D39A1DC53562764B08A71A10564F53CE21A7428EE3E9801773D4E427909A240AE149342F596C2EF87414DBC486DF52C9F4015FD6B6192B77E91590E85BEDD079D9A5C273ED2544352BF913F1824D15B7CE331B5895E7DABB1E932FE9416CCC087E911E0952AE243F1F2FD43C9FF8B294330ED47B38A400A89144A87E461EC6B561654D6D3B5036A412358D781C6AE935901E71C7051FCA3F4BB0049272AC9F1B43847ED0CCA1F8A4670D2378F1AE1338B00D107ED004FB86168512172360F2D40B8F6BFB9E3721A74F637C916AA434DA842009BF9ABE9CE7942A0394042E338C8E61A032440292472D2B3AF3CC5396C84F14DAC115400D3D2FE72E29DD6FC98968523167E853550F8AF4684E70FF48431950DA69958CB9D3D0A03821249739EB909A2E78EB80F651C0553598DD4345ED9F21436D7A49DFA774F15817980CFD72EEE4620BA713D6BF81A953BABE83F5E292A099F07749ECFF6E2258D48F239DD1D0951DE9C3AE22B00098A510FF5230C8CFFFC8B9BE76F1904A05649FD0766D94038ED4AB901433FEEA667D196B7E0242620C6895725DA782234CDA8D1BD49FA586BEB793D2CBB6D3DC8B8FC18992393CA84923FD17774C82EE67D46050910A8D3B823EB253B9A73DBF388DC91DA2A6F14E92D7DF58E2F7AE3D6DAEF74ACEF7B39F068D4E895E6D0020E84AC0095C0991D11F09E02DC024C22A41809898662B58DE47649736CA74F4AA0A2F2B8E09C3B154D1904B82337881030DD9699BD397BE9CD4DC152BD097F3078B69F47465C4B787232227E4F7966E021FBB3F974182022BC35C415BE677C96B08E1A7DD1C3810EF28AD6975730167365DD8335993F96529F36DE245736358E9F9360EB53494247E382496380A006F077F6A1B42F72ED63B7B22CA0D10A410194A2D714C974142E86DF6639BC37714564983322EF900F0E0CA785907DECF7C9557056E09DC242E10D69C3EB604BF96DC2BBE1F69203EF664EA68CD23526BD730693
-20200306193640 2 6 100 6143 2 F3D69BF99011E14ADF3A48E2FE265E067E9E02590D657BD9B87EF896253C2D3E138DD0B1290D92C9E3897C64E6B5D68CC524F18F073D39A1DC53562764B08A71A10564F53CE21A7428EE3E9801773D4E427909A240AE149342F596C2EF87414DBC486DF52C9F4015FD6B6192B77E91590E85BEDD079D9A5C273ED2544352BF913F1824D15B7CE331B5895E7DABB1E932FE9416CCC087E911E0952AE243F1F2FD43C9FF8B294330ED47B38A400A89144A87E461EC6B561654D6D3B5036A412358D781C6AE935901E71C7051FCA3F4BB0049272AC9F1B43847ED0CCA1F8A4670D2378F1AE1338B00D107ED004FB86168512172360F2D40B8F6BFB9E3721A74F637C916AA434DA842009BF9ABE9CE7942A0394042E338C8E61A032440292472D2B3AF3CC5396C84F14DAC115400D3D2FE72E29DD6FC98968523167E853550F8AF4684E70FF48431950DA69958CB9D3D0A03821249739EB909A2E78EB80F651C0553598DD4345ED9F21436D7A49DFA774F15817980CFD72EEE4620BA713D6BF81A953BABE83F5E292A099F07749ECFF6E2258D48F239DD1D0951DE9C3AE22B00098A510FF5230C8CFFFC8B9BE76F1904A05649FD0766D94038ED4AB901433FEEA667D196B7E0242620C6895725DA782234CDA8D1BD49FA586BEB793D2CBB6D3DC8B8FC18992393CA84923FD17774C82EE67D46050910A8D3B823EB253B9A73DBF388DC91DA2A6F14E92D7DF58E2F7AE3D6DAEF74ACEF7B39F068D4E895E6D0020E84AC0095C0991D11F09E02DC024C22A41809898662B58DE47649736CA74F4AA0A2F2B8E09C3B154D1904B82337881030DD9699BD397BE9CD4DC152BD097F3078B69F47465C4B787232227E4F7966E021FBB3F974182022BC35C415BE677C96B08E1A7DD1C3810EF28AD6975730167365DD8335993F96529F36DE245736358E9F9360EB53494247E382496380A006F077F6A1B42F72ED63B7B22CA0D10A410194A2D714C974142E86DF6639BC37714564983322EF900F0E0CA785907DECF7C9557056E09DC242E10D69C3EB604BF96DC2BBE1F69203EF664EA68CD23526BDA39813
-20200306200518 2 6 100 6143 5 F3D69BF99011E14ADF3A48E2FE265E067E9E02590D657BD9B87EF896253C2D3E138DD0B1290D92C9E3897C64E6B5D68CC524F18F073D39A1DC53562764B08A71A10564F53CE21A7428EE3E9801773D4E427909A240AE149342F596C2EF87414DBC486DF52C9F4015FD6B6192B77E91590E85BEDD079D9A5C273ED2544352BF913F1824D15B7CE331B5895E7DABB1E932FE9416CCC087E911E0952AE243F1F2FD43C9FF8B294330ED47B38A400A89144A87E461EC6B561654D6D3B5036A412358D781C6AE935901E71C7051FCA3F4BB0049272AC9F1B43847ED0CCA1F8A4670D2378F1AE1338B00D107ED004FB86168512172360F2D40B8F6BFB9E3721A74F637C916AA434DA842009BF9ABE9CE7942A0394042E338C8E61A032440292472D2B3AF3CC5396C84F14DAC115400D3D2FE72E29DD6FC98968523167E853550F8AF4684E70FF48431950DA69958CB9D3D0A03821249739EB909A2E78EB80F651C0553598DD4345ED9F21436D7A49DFA774F15817980CFD72EEE4620BA713D6BF81A953BABE83F5E292A099F07749ECFF6E2258D48F239DD1D0951DE9C3AE22B00098A510FF5230C8CFFFC8B9BE76F1904A05649FD0766D94038ED4AB901433FEEA667D196B7E0242620C6895725DA782234CDA8D1BD49FA586BEB793D2CBB6D3DC8B8FC18992393CA84923FD17774C82EE67D46050910A8D3B823EB253B9A73DBF388DC91DA2A6F14E92D7DF58E2F7AE3D6DAEF74ACEF7B39F068D4E895E6D0020E84AC0095C0991D11F09E02DC024C22A41809898662B58DE47649736CA74F4AA0A2F2B8E09C3B154D1904B82337881030DD9699BD397BE9CD4DC152BD097F3078B69F47465C4B787232227E4F7966E021FBB3F974182022BC35C415BE677C96B08E1A7DD1C3810EF28AD6975730167365DD8335993F96529F36DE245736358E9F9360EB53494247E382496380A006F077F6A1B42F72ED63B7B22CA0D10A410194A2D714C974142E86DF6639BC37714564983322EF900F0E0CA785907DECF7C9557056E09DC242E10D69C3EB604BF96DC2BBE1F69203EF664EA68CD23526BE4254B7
-20200306224443 2 6 100 6143 2 F3D69BF99011E14ADF3A48E2FE265E067E9E02590D657BD9B87EF896253C2D3E138DD0B1290D92C9E3897C64E6B5D68CC524F18F073D39A1DC53562764B08A71A10564F53CE21A7428EE3E9801773D4E427909A240AE149342F596C2EF87414DBC486DF52C9F4015FD6B6192B77E91590E85BEDD079D9A5C273ED2544352BF913F1824D15B7CE331B5895E7DABB1E932FE9416CCC087E911E0952AE243F1F2FD43C9FF8B294330ED47B38A400A89144A87E461EC6B561654D6D3B5036A412358D781C6AE935901E71C7051FCA3F4BB0049272AC9F1B43847ED0CCA1F8A4670D2378F1AE1338B00D107ED004FB86168512172360F2D40B8F6BFB9E3721A74F637C916AA434DA842009BF9ABE9CE7942A0394042E338C8E61A032440292472D2B3AF3CC5396C84F14DAC115400D3D2FE72E29DD6FC98968523167E853550F8AF4684E70FF48431950DA69958CB9D3D0A03821249739EB909A2E78EB80F651C0553598DD4345ED9F21436D7A49DFA774F15817980CFD72EEE4620BA713D6BF81A953BABE83F5E292A099F07749ECFF6E2258D48F239DD1D0951DE9C3AE22B00098A510FF5230C8CFFFC8B9BE76F1904A05649FD0766D94038ED4AB901433FEEA667D196B7E0242620C6895725DA782234CDA8D1BD49FA586BEB793D2CBB6D3DC8B8FC18992393CA84923FD17774C82EE67D46050910A8D3B823EB253B9A73DBF388DC91DA2A6F14E92D7DF58E2F7AE3D6DAEF74ACEF7B39F068D4E895E6D0020E84AC0095C0991D11F09E02DC024C22A41809898662B58DE47649736CA74F4AA0A2F2B8E09C3B154D1904B82337881030DD9699BD397BE9CD4DC152BD097F3078B69F47465C4B787232227E4F7966E021FBB3F974182022BC35C415BE677C96B08E1A7DD1C3810EF28AD6975730167365DD8335993F96529F36DE245736358E9F9360EB53494247E382496380A006F077F6A1B42F72ED63B7B22CA0D10A410194A2D714C974142E86DF6639BC37714564983322EF900F0E0CA785907DECF7C9557056E09DC242E10D69C3EB604BF96DC2BBE1F69203EF664EA68CD23526C1D59903
-20200307001909 2 6 100 6143 2 F3D69BF99011E14ADF3A48E2FE265E067E9E02590D657BD9B87EF896253C2D3E138DD0B1290D92C9E3897C64E6B5D68CC524F18F073D39A1DC53562764B08A71A10564F53CE21A7428EE3E9801773D4E427909A240AE149342F596C2EF87414DBC486DF52C9F4015FD6B6192B77E91590E85BEDD079D9A5C273ED2544352BF913F1824D15B7CE331B5895E7DABB1E932FE9416CCC087E911E0952AE243F1F2FD43C9FF8B294330ED47B38A400A89144A87E461EC6B561654D6D3B5036A412358D781C6AE935901E71C7051FCA3F4BB0049272AC9F1B43847ED0CCA1F8A4670D2378F1AE1338B00D107ED004FB86168512172360F2D40B8F6BFB9E3721A74F637C916AA434DA842009BF9ABE9CE7942A0394042E338C8E61A032440292472D2B3AF3CC5396C84F14DAC115400D3D2FE72E29DD6FC98968523167E853550F8AF4684E70FF48431950DA69958CB9D3D0A03821249739EB909A2E78EB80F651C0553598DD4345ED9F21436D7A49DFA774F15817980CFD72EEE4620BA713D6BF81A953BABE83F5E292A099F07749ECFF6E2258D48F239DD1D0951DE9C3AE22B00098A510FF5230C8CFFFC8B9BE76F1904A05649FD0766D94038ED4AB901433FEEA667D196B7E0242620C6895725DA782234CDA8D1BD49FA586BEB793D2CBB6D3DC8B8FC18992393CA84923FD17774C82EE67D46050910A8D3B823EB253B9A73DBF388DC91DA2A6F14E92D7DF58E2F7AE3D6DAEF74ACEF7B39F068D4E895E6D0020E84AC0095C0991D11F09E02DC024C22A41809898662B58DE47649736CA74F4AA0A2F2B8E09C3B154D1904B82337881030DD9699BD397BE9CD4DC152BD097F3078B69F47465C4B787232227E4F7966E021FBB3F974182022BC35C415BE677C96B08E1A7DD1C3810EF28AD6975730167365DD8335993F96529F36DE245736358E9F9360EB53494247E382496380A006F077F6A1B42F72ED63B7B22CA0D10A410194A2D714C974142E86DF6639BC37714564983322EF900F0E0CA785907DECF7C9557056E09DC242E10D69C3EB604BF96DC2BBE1F69203EF664EA68CD23526C3EFBF1B
-20200307015658 2 6 100 6143 5 F3D69BF99011E14ADF3A48E2FE265E067E9E02590D657BD9B87EF896253C2D3E138DD0B1290D92C9E3897C64E6B5D68CC524F18F073D39A1DC53562764B08A71A10564F53CE21A7428EE3E9801773D4E427909A240AE149342F596C2EF87414DBC486DF52C9F4015FD6B6192B77E91590E85BEDD079D9A5C273ED2544352BF913F1824D15B7CE331B5895E7DABB1E932FE9416CCC087E911E0952AE243F1F2FD43C9FF8B294330ED47B38A400A89144A87E461EC6B561654D6D3B5036A412358D781C6AE935901E71C7051FCA3F4BB0049272AC9F1B43847ED0CCA1F8A4670D2378F1AE1338B00D107ED004FB86168512172360F2D40B8F6BFB9E3721A74F637C916AA434DA842009BF9ABE9CE7942A0394042E338C8E61A032440292472D2B3AF3CC5396C84F14DAC115400D3D2FE72E29DD6FC98968523167E853550F8AF4684E70FF48431950DA69958CB9D3D0A03821249739EB909A2E78EB80F651C0553598DD4345ED9F21436D7A49DFA774F15817980CFD72EEE4620BA713D6BF81A953BABE83F5E292A099F07749ECFF6E2258D48F239DD1D0951DE9C3AE22B00098A510FF5230C8CFFFC8B9BE76F1904A05649FD0766D94038ED4AB901433FEEA667D196B7E0242620C6895725DA782234CDA8D1BD49FA586BEB793D2CBB6D3DC8B8FC18992393CA84923FD17774C82EE67D46050910A8D3B823EB253B9A73DBF388DC91DA2A6F14E92D7DF58E2F7AE3D6DAEF74ACEF7B39F068D4E895E6D0020E84AC0095C0991D11F09E02DC024C22A41809898662B58DE47649736CA74F4AA0A2F2B8E09C3B154D1904B82337881030DD9699BD397BE9CD4DC152BD097F3078B69F47465C4B787232227E4F7966E021FBB3F974182022BC35C415BE677C96B08E1A7DD1C3810EF28AD6975730167365DD8335993F96529F36DE245736358E9F9360EB53494247E382496380A006F077F6A1B42F72ED63B7B22CA0D10A410194A2D714C974142E86DF6639BC37714564983322EF900F0E0CA785907DECF7C9557056E09DC242E10D69C3EB604BF96DC2BBE1F69203EF664EA68CD23526C6174D0F
-20200307031316 2 6 100 6143 2 F3D69BF99011E14ADF3A48E2FE265E067E9E02590D657BD9B87EF896253C2D3E138DD0B1290D92C9E3897C64E6B5D68CC524F18F073D39A1DC53562764B08A71A10564F53CE21A7428EE3E9801773D4E427909A240AE149342F596C2EF87414DBC486DF52C9F4015FD6B6192B77E91590E85BEDD079D9A5C273ED2544352BF913F1824D15B7CE331B5895E7DABB1E932FE9416CCC087E911E0952AE243F1F2FD43C9FF8B294330ED47B38A400A89144A87E461EC6B561654D6D3B5036A412358D781C6AE935901E71C7051FCA3F4BB0049272AC9F1B43847ED0CCA1F8A4670D2378F1AE1338B00D107ED004FB86168512172360F2D40B8F6BFB9E3721A74F637C916AA434DA842009BF9ABE9CE7942A0394042E338C8E61A032440292472D2B3AF3CC5396C84F14DAC115400D3D2FE72E29DD6FC98968523167E853550F8AF4684E70FF48431950DA69958CB9D3D0A03821249739EB909A2E78EB80F651C0553598DD4345ED9F21436D7A49DFA774F15817980CFD72EEE4620BA713D6BF81A953BABE83F5E292A099F07749ECFF6E2258D48F239DD1D0951DE9C3AE22B00098A510FF5230C8CFFFC8B9BE76F1904A05649FD0766D94038ED4AB901433FEEA667D196B7E0242620C6895725DA782234CDA8D1BD49FA586BEB793D2CBB6D3DC8B8FC18992393CA84923FD17774C82EE67D46050910A8D3B823EB253B9A73DBF388DC91DA2A6F14E92D7DF58E2F7AE3D6DAEF74ACEF7B39F068D4E895E6D0020E84AC0095C0991D11F09E02DC024C22A41809898662B58DE47649736CA74F4AA0A2F2B8E09C3B154D1904B82337881030DD9699BD397BE9CD4DC152BD097F3078B69F47465C4B787232227E4F7966E021FBB3F974182022BC35C415BE677C96B08E1A7DD1C3810EF28AD6975730167365DD8335993F96529F36DE245736358E9F9360EB53494247E382496380A006F077F6A1B42F72ED63B7B22CA0D10A410194A2D714C974142E86DF6639BC37714564983322EF900F0E0CA785907DECF7C9557056E09DC242E10D69C3EB604BF96DC2BBE1F69203EF664EA68CD23526C7C7F63B
-20200307045138 2 6 100 6143 2 F3D69BF99011E14ADF3A48E2FE265E067E9E02590D657BD9B87EF896253C2D3E138DD0B1290D92C9E3897C64E6B5D68CC524F18F073D39A1DC53562764B08A71A10564F53CE21A7428EE3E9801773D4E427909A240AE149342F596C2EF87414DBC486DF52C9F4015FD6B6192B77E91590E85BEDD079D9A5C273ED2544352BF913F1824D15B7CE331B5895E7DABB1E932FE9416CCC087E911E0952AE243F1F2FD43C9FF8B294330ED47B38A400A89144A87E461EC6B561654D6D3B5036A412358D781C6AE935901E71C7051FCA3F4BB0049272AC9F1B43847ED0CCA1F8A4670D2378F1AE1338B00D107ED004FB86168512172360F2D40B8F6BFB9E3721A74F637C916AA434DA842009BF9ABE9CE7942A0394042E338C8E61A032440292472D2B3AF3CC5396C84F14DAC115400D3D2FE72E29DD6FC98968523167E853550F8AF4684E70FF48431950DA69958CB9D3D0A03821249739EB909A2E78EB80F651C0553598DD4345ED9F21436D7A49DFA774F15817980CFD72EEE4620BA713D6BF81A953BABE83F5E292A099F07749ECFF6E2258D48F239DD1D0951DE9C3AE22B00098A510FF5230C8CFFFC8B9BE76F1904A05649FD0766D94038ED4AB901433FEEA667D196B7E0242620C6895725DA782234CDA8D1BD49FA586BEB793D2CBB6D3DC8B8FC18992393CA84923FD17774C82EE67D46050910A8D3B823EB253B9A73DBF388DC91DA2A6F14E92D7DF58E2F7AE3D6DAEF74ACEF7B39F068D4E895E6D0020E84AC0095C0991D11F09E02DC024C22A41809898662B58DE47649736CA74F4AA0A2F2B8E09C3B154D1904B82337881030DD9699BD397BE9CD4DC152BD097F3078B69F47465C4B787232227E4F7966E021FBB3F974182022BC35C415BE677C96B08E1A7DD1C3810EF28AD6975730167365DD8335993F96529F36DE245736358E9F9360EB53494247E382496380A006F077F6A1B42F72ED63B7B22CA0D10A410194A2D714C974142E86DF6639BC37714564983322EF900F0E0CA785907DECF7C9557056E09DC242E10D69C3EB604BF96DC2BBE1F69203EF664EA68CD23526C9FD8D93
-20200307095446 2 6 100 6143 2 F3D69BF99011E14ADF3A48E2FE265E067E9E02590D657BD9B87EF896253C2D3E138DD0B1290D92C9E3897C64E6B5D68CC524F18F073D39A1DC53562764B08A71A10564F53CE21A7428EE3E9801773D4E427909A240AE149342F596C2EF87414DBC486DF52C9F4015FD6B6192B77E91590E85BEDD079D9A5C273ED2544352BF913F1824D15B7CE331B5895E7DABB1E932FE9416CCC087E911E0952AE243F1F2FD43C9FF8B294330ED47B38A400A89144A87E461EC6B561654D6D3B5036A412358D781C6AE935901E71C7051FCA3F4BB0049272AC9F1B43847ED0CCA1F8A4670D2378F1AE1338B00D107ED004FB86168512172360F2D40B8F6BFB9E3721A74F637C916AA434DA842009BF9ABE9CE7942A0394042E338C8E61A032440292472D2B3AF3CC5396C84F14DAC115400D3D2FE72E29DD6FC98968523167E853550F8AF4684E70FF48431950DA69958CB9D3D0A03821249739EB909A2E78EB80F651C0553598DD4345ED9F21436D7A49DFA774F15817980CFD72EEE4620BA713D6BF81A953BABE83F5E292A099F07749ECFF6E2258D48F239DD1D0951DE9C3AE22B00098A510FF5230C8CFFFC8B9BE76F1904A05649FD0766D94038ED4AB901433FEEA667D196B7E0242620C6895725DA782234CDA8D1BD49FA586BEB793D2CBB6D3DC8B8FC18992393CA84923FD17774C82EE67D46050910A8D3B823EB253B9A73DBF388DC91DA2A6F14E92D7DF58E2F7AE3D6DAEF74ACEF7B39F068D4E895E6D0020E84AC0095C0991D11F09E02DC024C22A41809898662B58DE47649736CA74F4AA0A2F2B8E09C3B154D1904B82337881030DD9699BD397BE9CD4DC152BD097F3078B69F47465C4B787232227E4F7966E021FBB3F974182022BC35C415BE677C96B08E1A7DD1C3810EF28AD6975730167365DD8335993F96529F36DE245736358E9F9360EB53494247E382496380A006F077F6A1B42F72ED63B7B22CA0D10A410194A2D714C974142E86DF6639BC37714564983322EF900F0E0CA785907DECF7C9557056E09DC242E10D69C3EB604BF96DC2BBE1F69203EF664EA68CD23526D0AC7613
-20200307141219 2 6 100 6143 2 F3D69BF99011E14ADF3A48E2FE265E067E9E02590D657BD9B87EF896253C2D3E138DD0B1290D92C9E3897C64E6B5D68CC524F18F073D39A1DC53562764B08A71A10564F53CE21A7428EE3E9801773D4E427909A240AE149342F596C2EF87414DBC486DF52C9F4015FD6B6192B77E91590E85BEDD079D9A5C273ED2544352BF913F1824D15B7CE331B5895E7DABB1E932FE9416CCC087E911E0952AE243F1F2FD43C9FF8B294330ED47B38A400A89144A87E461EC6B561654D6D3B5036A412358D781C6AE935901E71C7051FCA3F4BB0049272AC9F1B43847ED0CCA1F8A4670D2378F1AE1338B00D107ED004FB86168512172360F2D40B8F6BFB9E3721A74F637C916AA434DA842009BF9ABE9CE7942A0394042E338C8E61A032440292472D2B3AF3CC5396C84F14DAC115400D3D2FE72E29DD6FC98968523167E853550F8AF4684E70FF48431950DA69958CB9D3D0A03821249739EB909A2E78EB80F651C0553598DD4345ED9F21436D7A49DFA774F15817980CFD72EEE4620BA713D6BF81A953BABE83F5E292A099F07749ECFF6E2258D48F239DD1D0951DE9C3AE22B00098A510FF5230C8CFFFC8B9BE76F1904A05649FD0766D94038ED4AB901433FEEA667D196B7E0242620C6895725DA782234CDA8D1BD49FA586BEB793D2CBB6D3DC8B8FC18992393CA84923FD17774C82EE67D46050910A8D3B823EB253B9A73DBF388DC91DA2A6F14E92D7DF58E2F7AE3D6DAEF74ACEF7B39F068D4E895E6D0020E84AC0095C0991D11F09E02DC024C22A41809898662B58DE47649736CA74F4AA0A2F2B8E09C3B154D1904B82337881030DD9699BD397BE9CD4DC152BD097F3078B69F47465C4B787232227E4F7966E021FBB3F974182022BC35C415BE677C96B08E1A7DD1C3810EF28AD6975730167365DD8335993F96529F36DE245736358E9F9360EB53494247E382496380A006F077F6A1B42F72ED63B7B22CA0D10A410194A2D714C974142E86DF6639BC37714564983322EF900F0E0CA785907DECF7C9557056E09DC242E10D69C3EB604BF96DC2BBE1F69203EF664EA68CD23526D6467463
-20200307141549 2 6 100 6143 5 F3D69BF99011E14ADF3A48E2FE265E067E9E02590D657BD9B87EF896253C2D3E138DD0B1290D92C9E3897C64E6B5D68CC524F18F073D39A1DC53562764B08A71A10564F53CE21A7428EE3E9801773D4E427909A240AE149342F596C2EF87414DBC486DF52C9F4015FD6B6192B77E91590E85BEDD079D9A5C273ED2544352BF913F1824D15B7CE331B5895E7DABB1E932FE9416CCC087E911E0952AE243F1F2FD43C9FF8B294330ED47B38A400A89144A87E461EC6B561654D6D3B5036A412358D781C6AE935901E71C7051FCA3F4BB0049272AC9F1B43847ED0CCA1F8A4670D2378F1AE1338B00D107ED004FB86168512172360F2D40B8F6BFB9E3721A74F637C916AA434DA842009BF9ABE9CE7942A0394042E338C8E61A032440292472D2B3AF3CC5396C84F14DAC115400D3D2FE72E29DD6FC98968523167E853550F8AF4684E70FF48431950DA69958CB9D3D0A03821249739EB909A2E78EB80F651C0553598DD4345ED9F21436D7A49DFA774F15817980CFD72EEE4620BA713D6BF81A953BABE83F5E292A099F07749ECFF6E2258D48F239DD1D0951DE9C3AE22B00098A510FF5230C8CFFFC8B9BE76F1904A05649FD0766D94038ED4AB901433FEEA667D196B7E0242620C6895725DA782234CDA8D1BD49FA586BEB793D2CBB6D3DC8B8FC18992393CA84923FD17774C82EE67D46050910A8D3B823EB253B9A73DBF388DC91DA2A6F14E92D7DF58E2F7AE3D6DAEF74ACEF7B39F068D4E895E6D0020E84AC0095C0991D11F09E02DC024C22A41809898662B58DE47649736CA74F4AA0A2F2B8E09C3B154D1904B82337881030DD9699BD397BE9CD4DC152BD097F3078B69F47465C4B787232227E4F7966E021FBB3F974182022BC35C415BE677C96B08E1A7DD1C3810EF28AD6975730167365DD8335993F96529F36DE245736358E9F9360EB53494247E382496380A006F077F6A1B42F72ED63B7B22CA0D10A410194A2D714C974142E86DF6639BC37714564983322EF900F0E0CA785907DECF7C9557056E09DC242E10D69C3EB604BF96DC2BBE1F69203EF664EA68CD23526D65211FF
-20200307150658 2 6 100 6143 2 F3D69BF99011E14ADF3A48E2FE265E067E9E02590D657BD9B87EF896253C2D3E138DD0B1290D92C9E3897C64E6B5D68CC524F18F073D39A1DC53562764B08A71A10564F53CE21A7428EE3E9801773D4E427909A240AE149342F596C2EF87414DBC486DF52C9F4015FD6B6192B77E91590E85BEDD079D9A5C273ED2544352BF913F1824D15B7CE331B5895E7DABB1E932FE9416CCC087E911E0952AE243F1F2FD43C9FF8B294330ED47B38A400A89144A87E461EC6B561654D6D3B5036A412358D781C6AE935901E71C7051FCA3F4BB0049272AC9F1B43847ED0CCA1F8A4670D2378F1AE1338B00D107ED004FB86168512172360F2D40B8F6BFB9E3721A74F637C916AA434DA842009BF9ABE9CE7942A0394042E338C8E61A032440292472D2B3AF3CC5396C84F14DAC115400D3D2FE72E29DD6FC98968523167E853550F8AF4684E70FF48431950DA69958CB9D3D0A03821249739EB909A2E78EB80F651C0553598DD4345ED9F21436D7A49DFA774F15817980CFD72EEE4620BA713D6BF81A953BABE83F5E292A099F07749ECFF6E2258D48F239DD1D0951DE9C3AE22B00098A510FF5230C8CFFFC8B9BE76F1904A05649FD0766D94038ED4AB901433FEEA667D196B7E0242620C6895725DA782234CDA8D1BD49FA586BEB793D2CBB6D3DC8B8FC18992393CA84923FD17774C82EE67D46050910A8D3B823EB253B9A73DBF388DC91DA2A6F14E92D7DF58E2F7AE3D6DAEF74ACEF7B39F068D4E895E6D0020E84AC0095C0991D11F09E02DC024C22A41809898662B58DE47649736CA74F4AA0A2F2B8E09C3B154D1904B82337881030DD9699BD397BE9CD4DC152BD097F3078B69F47465C4B787232227E4F7966E021FBB3F974182022BC35C415BE677C96B08E1A7DD1C3810EF28AD6975730167365DD8335993F96529F36DE245736358E9F9360EB53494247E382496380A006F077F6A1B42F72ED63B7B22CA0D10A410194A2D714C974142E86DF6639BC37714564983322EF900F0E0CA785907DECF7C9557056E09DC242E10D69C3EB604BF96DC2BBE1F69203EF664EA68CD23526D7636293
-20200307152317 2 6 100 6143 2 F3D69BF99011E14ADF3A48E2FE265E067E9E02590D657BD9B87EF896253C2D3E138DD0B1290D92C9E3897C64E6B5D68CC524F18F073D39A1DC53562764B08A71A10564F53CE21A7428EE3E9801773D4E427909A240AE149342F596C2EF87414DBC486DF52C9F4015FD6B6192B77E91590E85BEDD079D9A5C273ED2544352BF913F1824D15B7CE331B5895E7DABB1E932FE9416CCC087E911E0952AE243F1F2FD43C9FF8B294330ED47B38A400A89144A87E461EC6B561654D6D3B5036A412358D781C6AE935901E71C7051FCA3F4BB0049272AC9F1B43847ED0CCA1F8A4670D2378F1AE1338B00D107ED004FB86168512172360F2D40B8F6BFB9E3721A74F637C916AA434DA842009BF9ABE9CE7942A0394042E338C8E61A032440292472D2B3AF3CC5396C84F14DAC115400D3D2FE72E29DD6FC98968523167E853550F8AF4684E70FF48431950DA69958CB9D3D0A03821249739EB909A2E78EB80F651C0553598DD4345ED9F21436D7A49DFA774F15817980CFD72EEE4620BA713D6BF81A953BABE83F5E292A099F07749ECFF6E2258D48F239DD1D0951DE9C3AE22B00098A510FF5230C8CFFFC8B9BE76F1904A05649FD0766D94038ED4AB901433FEEA667D196B7E0242620C6895725DA782234CDA8D1BD49FA586BEB793D2CBB6D3DC8B8FC18992393CA84923FD17774C82EE67D46050910A8D3B823EB253B9A73DBF388DC91DA2A6F14E92D7DF58E2F7AE3D6DAEF74ACEF7B39F068D4E895E6D0020E84AC0095C0991D11F09E02DC024C22A41809898662B58DE47649736CA74F4AA0A2F2B8E09C3B154D1904B82337881030DD9699BD397BE9CD4DC152BD097F3078B69F47465C4B787232227E4F7966E021FBB3F974182022BC35C415BE677C96B08E1A7DD1C3810EF28AD6975730167365DD8335993F96529F36DE245736358E9F9360EB53494247E382496380A006F077F6A1B42F72ED63B7B22CA0D10A410194A2D714C974142E86DF6639BC37714564983322EF900F0E0CA785907DECF7C9557056E09DC242E10D69C3EB604BF96DC2BBE1F69203EF664EA68CD23526D7B5C68B
-20200307160123 2 6 100 6143 2 F3D69BF99011E14ADF3A48E2FE265E067E9E02590D657BD9B87EF896253C2D3E138DD0B1290D92C9E3897C64E6B5D68CC524F18F073D39A1DC53562764B08A71A10564F53CE21A7428EE3E9801773D4E427909A240AE149342F596C2EF87414DBC486DF52C9F4015FD6B6192B77E91590E85BEDD079D9A5C273ED2544352BF913F1824D15B7CE331B5895E7DABB1E932FE9416CCC087E911E0952AE243F1F2FD43C9FF8B294330ED47B38A400A89144A87E461EC6B561654D6D3B5036A412358D781C6AE935901E71C7051FCA3F4BB0049272AC9F1B43847ED0CCA1F8A4670D2378F1AE1338B00D107ED004FB86168512172360F2D40B8F6BFB9E3721A74F637C916AA434DA842009BF9ABE9CE7942A0394042E338C8E61A032440292472D2B3AF3CC5396C84F14DAC115400D3D2FE72E29DD6FC98968523167E853550F8AF4684E70FF48431950DA69958CB9D3D0A03821249739EB909A2E78EB80F651C0553598DD4345ED9F21436D7A49DFA774F15817980CFD72EEE4620BA713D6BF81A953BABE83F5E292A099F07749ECFF6E2258D48F239DD1D0951DE9C3AE22B00098A510FF5230C8CFFFC8B9BE76F1904A05649FD0766D94038ED4AB901433FEEA667D196B7E0242620C6895725DA782234CDA8D1BD49FA586BEB793D2CBB6D3DC8B8FC18992393CA84923FD17774C82EE67D46050910A8D3B823EB253B9A73DBF388DC91DA2A6F14E92D7DF58E2F7AE3D6DAEF74ACEF7B39F068D4E895E6D0020E84AC0095C0991D11F09E02DC024C22A41809898662B58DE47649736CA74F4AA0A2F2B8E09C3B154D1904B82337881030DD9699BD397BE9CD4DC152BD097F3078B69F47465C4B787232227E4F7966E021FBB3F974182022BC35C415BE677C96B08E1A7DD1C3810EF28AD6975730167365DD8335993F96529F36DE245736358E9F9360EB53494247E382496380A006F077F6A1B42F72ED63B7B22CA0D10A410194A2D714C974142E86DF6639BC37714564983322EF900F0E0CA785907DECF7C9557056E09DC242E10D69C3EB604BF96DC2BBE1F69203EF664EA68CD23526D8814873
-20200307163910 2 6 100 6143 2 F3D69BF99011E14ADF3A48E2FE265E067E9E02590D657BD9B87EF896253C2D3E138DD0B1290D92C9E3897C64E6B5D68CC524F18F073D39A1DC53562764B08A71A10564F53CE21A7428EE3E9801773D4E427909A240AE149342F596C2EF87414DBC486DF52C9F4015FD6B6192B77E91590E85BEDD079D9A5C273ED2544352BF913F1824D15B7CE331B5895E7DABB1E932FE9416CCC087E911E0952AE243F1F2FD43C9FF8B294330ED47B38A400A89144A87E461EC6B561654D6D3B5036A412358D781C6AE935901E71C7051FCA3F4BB0049272AC9F1B43847ED0CCA1F8A4670D2378F1AE1338B00D107ED004FB86168512172360F2D40B8F6BFB9E3721A74F637C916AA434DA842009BF9ABE9CE7942A0394042E338C8E61A032440292472D2B3AF3CC5396C84F14DAC115400D3D2FE72E29DD6FC98968523167E853550F8AF4684E70FF48431950DA69958CB9D3D0A03821249739EB909A2E78EB80F651C0553598DD4345ED9F21436D7A49DFA774F15817980CFD72EEE4620BA713D6BF81A953BABE83F5E292A099F07749ECFF6E2258D48F239DD1D0951DE9C3AE22B00098A510FF5230C8CFFFC8B9BE76F1904A05649FD0766D94038ED4AB901433FEEA667D196B7E0242620C6895725DA782234CDA8D1BD49FA586BEB793D2CBB6D3DC8B8FC18992393CA84923FD17774C82EE67D46050910A8D3B823EB253B9A73DBF388DC91DA2A6F14E92D7DF58E2F7AE3D6DAEF74ACEF7B39F068D4E895E6D0020E84AC0095C0991D11F09E02DC024C22A41809898662B58DE47649736CA74F4AA0A2F2B8E09C3B154D1904B82337881030DD9699BD397BE9CD4DC152BD097F3078B69F47465C4B787232227E4F7966E021FBB3F974182022BC35C415BE677C96B08E1A7DD1C3810EF28AD6975730167365DD8335993F96529F36DE245736358E9F9360EB53494247E382496380A006F077F6A1B42F72ED63B7B22CA0D10A410194A2D714C974142E86DF6639BC37714564983322EF900F0E0CA785907DECF7C9557056E09DC242E10D69C3EB604BF96DC2BBE1F69203EF664EA68CD23526D9511B93
-20200307211457 2 6 100 6143 5 F3D69BF99011E14ADF3A48E2FE265E067E9E02590D657BD9B87EF896253C2D3E138DD0B1290D92C9E3897C64E6B5D68CC524F18F073D39A1DC53562764B08A71A10564F53CE21A7428EE3E9801773D4E427909A240AE149342F596C2EF87414DBC486DF52C9F4015FD6B6192B77E91590E85BEDD079D9A5C273ED2544352BF913F1824D15B7CE331B5895E7DABB1E932FE9416CCC087E911E0952AE243F1F2FD43C9FF8B294330ED47B38A400A89144A87E461EC6B561654D6D3B5036A412358D781C6AE935901E71C7051FCA3F4BB0049272AC9F1B43847ED0CCA1F8A4670D2378F1AE1338B00D107ED004FB86168512172360F2D40B8F6BFB9E3721A74F637C916AA434DA842009BF9ABE9CE7942A0394042E338C8E61A032440292472D2B3AF3CC5396C84F14DAC115400D3D2FE72E29DD6FC98968523167E853550F8AF4684E70FF48431950DA69958CB9D3D0A03821249739EB909A2E78EB80F651C0553598DD4345ED9F21436D7A49DFA774F15817980CFD72EEE4620BA713D6BF81A953BABE83F5E292A099F07749ECFF6E2258D48F239DD1D0951DE9C3AE22B00098A510FF5230C8CFFFC8B9BE76F1904A05649FD0766D94038ED4AB901433FEEA667D196B7E0242620C6895725DA782234CDA8D1BD49FA586BEB793D2CBB6D3DC8B8FC18992393CA84923FD17774C82EE67D46050910A8D3B823EB253B9A73DBF388DC91DA2A6F14E92D7DF58E2F7AE3D6DAEF74ACEF7B39F068D4E895E6D0020E84AC0095C0991D11F09E02DC024C22A41809898662B58DE47649736CA74F4AA0A2F2B8E09C3B154D1904B82337881030DD9699BD397BE9CD4DC152BD097F3078B69F47465C4B787232227E4F7966E021FBB3F974182022BC35C415BE677C96B08E1A7DD1C3810EF28AD6975730167365DD8335993F96529F36DE245736358E9F9360EB53494247E382496380A006F077F6A1B42F72ED63B7B22CA0D10A410194A2D714C974142E86DF6639BC37714564983322EF900F0E0CA785907DECF7C9557056E09DC242E10D69C3EB604BF96DC2BBE1F69203EF664EA68CD23526DF2AC807
-20200307221749 2 6 100 6143 5 F3D69BF99011E14ADF3A48E2FE265E067E9E02590D657BD9B87EF896253C2D3E138DD0B1290D92C9E3897C64E6B5D68CC524F18F073D39A1DC53562764B08A71A10564F53CE21A7428EE3E9801773D4E427909A240AE149342F596C2EF87414DBC486DF52C9F4015FD6B6192B77E91590E85BEDD079D9A5C273ED2544352BF913F1824D15B7CE331B5895E7DABB1E932FE9416CCC087E911E0952AE243F1F2FD43C9FF8B294330ED47B38A400A89144A87E461EC6B561654D6D3B5036A412358D781C6AE935901E71C7051FCA3F4BB0049272AC9F1B43847ED0CCA1F8A4670D2378F1AE1338B00D107ED004FB86168512172360F2D40B8F6BFB9E3721A74F637C916AA434DA842009BF9ABE9CE7942A0394042E338C8E61A032440292472D2B3AF3CC5396C84F14DAC115400D3D2FE72E29DD6FC98968523167E853550F8AF4684E70FF48431950DA69958CB9D3D0A03821249739EB909A2E78EB80F651C0553598DD4345ED9F21436D7A49DFA774F15817980CFD72EEE4620BA713D6BF81A953BABE83F5E292A099F07749ECFF6E2258D48F239DD1D0951DE9C3AE22B00098A510FF5230C8CFFFC8B9BE76F1904A05649FD0766D94038ED4AB901433FEEA667D196B7E0242620C6895725DA782234CDA8D1BD49FA586BEB793D2CBB6D3DC8B8FC18992393CA84923FD17774C82EE67D46050910A8D3B823EB253B9A73DBF388DC91DA2A6F14E92D7DF58E2F7AE3D6DAEF74ACEF7B39F068D4E895E6D0020E84AC0095C0991D11F09E02DC024C22A41809898662B58DE47649736CA74F4AA0A2F2B8E09C3B154D1904B82337881030DD9699BD397BE9CD4DC152BD097F3078B69F47465C4B787232227E4F7966E021FBB3F974182022BC35C415BE677C96B08E1A7DD1C3810EF28AD6975730167365DD8335993F96529F36DE245736358E9F9360EB53494247E382496380A006F077F6A1B42F72ED63B7B22CA0D10A410194A2D714C974142E86DF6639BC37714564983322EF900F0E0CA785907DECF7C9557056E09DC242E10D69C3EB604BF96DC2BBE1F69203EF664EA68CD23526E0727157
-20200308011553 2 6 100 6143 5 F3D69BF99011E14ADF3A48E2FE265E067E9E02590D657BD9B87EF896253C2D3E138DD0B1290D92C9E3897C64E6B5D68CC524F18F073D39A1DC53562764B08A71A10564F53CE21A7428EE3E9801773D4E427909A240AE149342F596C2EF87414DBC486DF52C9F4015FD6B6192B77E91590E85BEDD079D9A5C273ED2544352BF913F1824D15B7CE331B5895E7DABB1E932FE9416CCC087E911E0952AE243F1F2FD43C9FF8B294330ED47B38A400A89144A87E461EC6B561654D6D3B5036A412358D781C6AE935901E71C7051FCA3F4BB0049272AC9F1B43847ED0CCA1F8A4670D2378F1AE1338B00D107ED004FB86168512172360F2D40B8F6BFB9E3721A74F637C916AA434DA842009BF9ABE9CE7942A0394042E338C8E61A032440292472D2B3AF3CC5396C84F14DAC115400D3D2FE72E29DD6FC98968523167E853550F8AF4684E70FF48431950DA69958CB9D3D0A03821249739EB909A2E78EB80F651C0553598DD4345ED9F21436D7A49DFA774F15817980CFD72EEE4620BA713D6BF81A953BABE83F5E292A099F07749ECFF6E2258D48F239DD1D0951DE9C3AE22B00098A510FF5230C8CFFFC8B9BE76F1904A05649FD0766D94038ED4AB901433FEEA667D196B7E0242620C6895725DA782234CDA8D1BD49FA586BEB793D2CBB6D3DC8B8FC18992393CA84923FD17774C82EE67D46050910A8D3B823EB253B9A73DBF388DC91DA2A6F14E92D7DF58E2F7AE3D6DAEF74ACEF7B39F068D4E895E6D0020E84AC0095C0991D11F09E02DC024C22A41809898662B58DE47649736CA74F4AA0A2F2B8E09C3B154D1904B82337881030DD9699BD397BE9CD4DC152BD097F3078B69F47465C4B787232227E4F7966E021FBB3F974182022BC35C415BE677C96B08E1A7DD1C3810EF28AD6975730167365DD8335993F96529F36DE245736358E9F9360EB53494247E382496380A006F077F6A1B42F72ED63B7B22CA0D10A410194A2D714C974142E86DF6639BC37714564983322EF900F0E0CA785907DECF7C9557056E09DC242E10D69C3EB604BF96DC2BBE1F69203EF664EA68CD23526E440D17F
-20200308035011 2 6 100 6143 5 F3D69BF99011E14ADF3A48E2FE265E067E9E02590D657BD9B87EF896253C2D3E138DD0B1290D92C9E3897C64E6B5D68CC524F18F073D39A1DC53562764B08A71A10564F53CE21A7428EE3E9801773D4E427909A240AE149342F596C2EF87414DBC486DF52C9F4015FD6B6192B77E91590E85BEDD079D9A5C273ED2544352BF913F1824D15B7CE331B5895E7DABB1E932FE9416CCC087E911E0952AE243F1F2FD43C9FF8B294330ED47B38A400A89144A87E461EC6B561654D6D3B5036A412358D781C6AE935901E71C7051FCA3F4BB0049272AC9F1B43847ED0CCA1F8A4670D2378F1AE1338B00D107ED004FB86168512172360F2D40B8F6BFB9E3721A74F637C916AA434DA842009BF9ABE9CE7942A0394042E338C8E61A032440292472D2B3AF3CC5396C84F14DAC115400D3D2FE72E29DD6FC98968523167E853550F8AF4684E70FF48431950DA69958CB9D3D0A03821249739EB909A2E78EB80F651C0553598DD4345ED9F21436D7A49DFA774F15817980CFD72EEE4620BA713D6BF81A953BABE83F5E292A099F07749ECFF6E2258D48F239DD1D0951DE9C3AE22B00098A510FF5230C8CFFFC8B9BE76F1904A05649FD0766D94038ED4AB901433FEEA667D196B7E0242620C6895725DA782234CDA8D1BD49FA586BEB793D2CBB6D3DC8B8FC18992393CA84923FD17774C82EE67D46050910A8D3B823EB253B9A73DBF388DC91DA2A6F14E92D7DF58E2F7AE3D6DAEF74ACEF7B39F068D4E895E6D0020E84AC0095C0991D11F09E02DC024C22A41809898662B58DE47649736CA74F4AA0A2F2B8E09C3B154D1904B82337881030DD9699BD397BE9CD4DC152BD097F3078B69F47465C4B787232227E4F7966E021FBB3F974182022BC35C415BE677C96B08E1A7DD1C3810EF28AD6975730167365DD8335993F96529F36DE245736358E9F9360EB53494247E382496380A006F077F6A1B42F72ED63B7B22CA0D10A410194A2D714C974142E86DF6639BC37714564983322EF900F0E0CA785907DECF7C9557056E09DC242E10D69C3EB604BF96DC2BBE1F69203EF664EA68CD23526E79AC177
-20200308050733 2 6 100 6143 5 F3D69BF99011E14ADF3A48E2FE265E067E9E02590D657BD9B87EF896253C2D3E138DD0B1290D92C9E3897C64E6B5D68CC524F18F073D39A1DC53562764B08A71A10564F53CE21A7428EE3E9801773D4E427909A240AE149342F596C2EF87414DBC486DF52C9F4015FD6B6192B77E91590E85BEDD079D9A5C273ED2544352BF913F1824D15B7CE331B5895E7DABB1E932FE9416CCC087E911E0952AE243F1F2FD43C9FF8B294330ED47B38A400A89144A87E461EC6B561654D6D3B5036A412358D781C6AE935901E71C7051FCA3F4BB0049272AC9F1B43847ED0CCA1F8A4670D2378F1AE1338B00D107ED004FB86168512172360F2D40B8F6BFB9E3721A74F637C916AA434DA842009BF9ABE9CE7942A0394042E338C8E61A032440292472D2B3AF3CC5396C84F14DAC115400D3D2FE72E29DD6FC98968523167E853550F8AF4684E70FF48431950DA69958CB9D3D0A03821249739EB909A2E78EB80F651C0553598DD4345ED9F21436D7A49DFA774F15817980CFD72EEE4620BA713D6BF81A953BABE83F5E292A099F07749ECFF6E2258D48F239DD1D0951DE9C3AE22B00098A510FF5230C8CFFFC8B9BE76F1904A05649FD0766D94038ED4AB901433FEEA667D196B7E0242620C6895725DA782234CDA8D1BD49FA586BEB793D2CBB6D3DC8B8FC18992393CA84923FD17774C82EE67D46050910A8D3B823EB253B9A73DBF388DC91DA2A6F14E92D7DF58E2F7AE3D6DAEF74ACEF7B39F068D4E895E6D0020E84AC0095C0991D11F09E02DC024C22A41809898662B58DE47649736CA74F4AA0A2F2B8E09C3B154D1904B82337881030DD9699BD397BE9CD4DC152BD097F3078B69F47465C4B787232227E4F7966E021FBB3F974182022BC35C415BE677C96B08E1A7DD1C3810EF28AD6975730167365DD8335993F96529F36DE245736358E9F9360EB53494247E382496380A006F077F6A1B42F72ED63B7B22CA0D10A410194A2D714C974142E86DF6639BC37714564983322EF900F0E0CA785907DECF7C9557056E09DC242E10D69C3EB604BF96DC2BBE1F69203EF664EA68CD23526E93970AF
-20200308080136 2 6 100 6143 2 F3D69BF99011E14ADF3A48E2FE265E067E9E02590D657BD9B87EF896253C2D3E138DD0B1290D92C9E3897C64E6B5D68CC524F18F073D39A1DC53562764B08A71A10564F53CE21A7428EE3E9801773D4E427909A240AE149342F596C2EF87414DBC486DF52C9F4015FD6B6192B77E91590E85BEDD079D9A5C273ED2544352BF913F1824D15B7CE331B5895E7DABB1E932FE9416CCC087E911E0952AE243F1F2FD43C9FF8B294330ED47B38A400A89144A87E461EC6B561654D6D3B5036A412358D781C6AE935901E71C7051FCA3F4BB0049272AC9F1B43847ED0CCA1F8A4670D2378F1AE1338B00D107ED004FB86168512172360F2D40B8F6BFB9E3721A74F637C916AA434DA842009BF9ABE9CE7942A0394042E338C8E61A032440292472D2B3AF3CC5396C84F14DAC115400D3D2FE72E29DD6FC98968523167E853550F8AF4684E70FF48431950DA69958CB9D3D0A03821249739EB909A2E78EB80F651C0553598DD4345ED9F21436D7A49DFA774F15817980CFD72EEE4620BA713D6BF81A953BABE83F5E292A099F07749ECFF6E2258D48F239DD1D0951DE9C3AE22B00098A510FF5230C8CFFFC8B9BE76F1904A05649FD0766D94038ED4AB901433FEEA667D196B7E0242620C6895725DA782234CDA8D1BD49FA586BEB793D2CBB6D3DC8B8FC18992393CA84923FD17774C82EE67D46050910A8D3B823EB253B9A73DBF388DC91DA2A6F14E92D7DF58E2F7AE3D6DAEF74ACEF7B39F068D4E895E6D0020E84AC0095C0991D11F09E02DC024C22A41809898662B58DE47649736CA74F4AA0A2F2B8E09C3B154D1904B82337881030DD9699BD397BE9CD4DC152BD097F3078B69F47465C4B787232227E4F7966E021FBB3F974182022BC35C415BE677C96B08E1A7DD1C3810EF28AD6975730167365DD8335993F96529F36DE245736358E9F9360EB53494247E382496380A006F077F6A1B42F72ED63B7B22CA0D10A410194A2D714C974142E86DF6639BC37714564983322EF900F0E0CA785907DECF7C9557056E09DC242E10D69C3EB604BF96DC2BBE1F69203EF664EA68CD23526ECED5C7B
-20200308102232 2 6 100 6143 2 F3D69BF99011E14ADF3A48E2FE265E067E9E02590D657BD9B87EF896253C2D3E138DD0B1290D92C9E3897C64E6B5D68CC524F18F073D39A1DC53562764B08A71A10564F53CE21A7428EE3E9801773D4E427909A240AE149342F596C2EF87414DBC486DF52C9F4015FD6B6192B77E91590E85BEDD079D9A5C273ED2544352BF913F1824D15B7CE331B5895E7DABB1E932FE9416CCC087E911E0952AE243F1F2FD43C9FF8B294330ED47B38A400A89144A87E461EC6B561654D6D3B5036A412358D781C6AE935901E71C7051FCA3F4BB0049272AC9F1B43847ED0CCA1F8A4670D2378F1AE1338B00D107ED004FB86168512172360F2D40B8F6BFB9E3721A74F637C916AA434DA842009BF9ABE9CE7942A0394042E338C8E61A032440292472D2B3AF3CC5396C84F14DAC115400D3D2FE72E29DD6FC98968523167E853550F8AF4684E70FF48431950DA69958CB9D3D0A03821249739EB909A2E78EB80F651C0553598DD4345ED9F21436D7A49DFA774F15817980CFD72EEE4620BA713D6BF81A953BABE83F5E292A099F07749ECFF6E2258D48F239DD1D0951DE9C3AE22B00098A510FF5230C8CFFFC8B9BE76F1904A05649FD0766D94038ED4AB901433FEEA667D196B7E0242620C6895725DA782234CDA8D1BD49FA586BEB793D2CBB6D3DC8B8FC18992393CA84923FD17774C82EE67D46050910A8D3B823EB253B9A73DBF388DC91DA2A6F14E92D7DF58E2F7AE3D6DAEF74ACEF7B39F068D4E895E6D0020E84AC0095C0991D11F09E02DC024C22A41809898662B58DE47649736CA74F4AA0A2F2B8E09C3B154D1904B82337881030DD9699BD397BE9CD4DC152BD097F3078B69F47465C4B787232227E4F7966E021FBB3F974182022BC35C415BE677C96B08E1A7DD1C3810EF28AD6975730167365DD8335993F96529F36DE245736358E9F9360EB53494247E382496380A006F077F6A1B42F72ED63B7B22CA0D10A410194A2D714C974142E86DF6639BC37714564983322EF900F0E0CA785907DECF7C9557056E09DC242E10D69C3EB604BF96DC2BBE1F69203EF664EA68CD23526EFDD20EB
-20200308103627 2 6 100 6143 2 F3D69BF99011E14ADF3A48E2FE265E067E9E02590D657BD9B87EF896253C2D3E138DD0B1290D92C9E3897C64E6B5D68CC524F18F073D39A1DC53562764B08A71A10564F53CE21A7428EE3E9801773D4E427909A240AE149342F596C2EF87414DBC486DF52C9F4015FD6B6192B77E91590E85BEDD079D9A5C273ED2544352BF913F1824D15B7CE331B5895E7DABB1E932FE9416CCC087E911E0952AE243F1F2FD43C9FF8B294330ED47B38A400A89144A87E461EC6B561654D6D3B5036A412358D781C6AE935901E71C7051FCA3F4BB0049272AC9F1B43847ED0CCA1F8A4670D2378F1AE1338B00D107ED004FB86168512172360F2D40B8F6BFB9E3721A74F637C916AA434DA842009BF9ABE9CE7942A0394042E338C8E61A032440292472D2B3AF3CC5396C84F14DAC115400D3D2FE72E29DD6FC98968523167E853550F8AF4684E70FF48431950DA69958CB9D3D0A03821249739EB909A2E78EB80F651C0553598DD4345ED9F21436D7A49DFA774F15817980CFD72EEE4620BA713D6BF81A953BABE83F5E292A099F07749ECFF6E2258D48F239DD1D0951DE9C3AE22B00098A510FF5230C8CFFFC8B9BE76F1904A05649FD0766D94038ED4AB901433FEEA667D196B7E0242620C6895725DA782234CDA8D1BD49FA586BEB793D2CBB6D3DC8B8FC18992393CA84923FD17774C82EE67D46050910A8D3B823EB253B9A73DBF388DC91DA2A6F14E92D7DF58E2F7AE3D6DAEF74ACEF7B39F068D4E895E6D0020E84AC0095C0991D11F09E02DC024C22A41809898662B58DE47649736CA74F4AA0A2F2B8E09C3B154D1904B82337881030DD9699BD397BE9CD4DC152BD097F3078B69F47465C4B787232227E4F7966E021FBB3F974182022BC35C415BE677C96B08E1A7DD1C3810EF28AD6975730167365DD8335993F96529F36DE245736358E9F9360EB53494247E382496380A006F077F6A1B42F72ED63B7B22CA0D10A410194A2D714C974142E86DF6639BC37714564983322EF900F0E0CA785907DECF7C9557056E09DC242E10D69C3EB604BF96DC2BBE1F69203EF664EA68CD23526F01E61C3
-20200308124828 2 6 100 6143 5 F3D69BF99011E14ADF3A48E2FE265E067E9E02590D657BD9B87EF896253C2D3E138DD0B1290D92C9E3897C64E6B5D68CC524F18F073D39A1DC53562764B08A71A10564F53CE21A7428EE3E9801773D4E427909A240AE149342F596C2EF87414DBC486DF52C9F4015FD6B6192B77E91590E85BEDD079D9A5C273ED2544352BF913F1824D15B7CE331B5895E7DABB1E932FE9416CCC087E911E0952AE243F1F2FD43C9FF8B294330ED47B38A400A89144A87E461EC6B561654D6D3B5036A412358D781C6AE935901E71C7051FCA3F4BB0049272AC9F1B43847ED0CCA1F8A4670D2378F1AE1338B00D107ED004FB86168512172360F2D40B8F6BFB9E3721A74F637C916AA434DA842009BF9ABE9CE7942A0394042E338C8E61A032440292472D2B3AF3CC5396C84F14DAC115400D3D2FE72E29DD6FC98968523167E853550F8AF4684E70FF48431950DA69958CB9D3D0A03821249739EB909A2E78EB80F651C0553598DD4345ED9F21436D7A49DFA774F15817980CFD72EEE4620BA713D6BF81A953BABE83F5E292A099F07749ECFF6E2258D48F239DD1D0951DE9C3AE22B00098A510FF5230C8CFFFC8B9BE76F1904A05649FD0766D94038ED4AB901433FEEA667D196B7E0242620C6895725DA782234CDA8D1BD49FA586BEB793D2CBB6D3DC8B8FC18992393CA84923FD17774C82EE67D46050910A8D3B823EB253B9A73DBF388DC91DA2A6F14E92D7DF58E2F7AE3D6DAEF74ACEF7B39F068D4E895E6D0020E84AC0095C0991D11F09E02DC024C22A41809898662B58DE47649736CA74F4AA0A2F2B8E09C3B154D1904B82337881030DD9699BD397BE9CD4DC152BD097F3078B69F47465C4B787232227E4F7966E021FBB3F974182022BC35C415BE677C96B08E1A7DD1C3810EF28AD6975730167365DD8335993F96529F36DE245736358E9F9360EB53494247E382496380A006F077F6A1B42F72ED63B7B22CA0D10A410194A2D714C974142E86DF6639BC37714564983322EF900F0E0CA785907DECF7C9557056E09DC242E10D69C3EB604BF96DC2BBE1F69203EF664EA68CD23526F2DFA4EF
-20200308152719 2 6 100 6143 5 F3D69BF99011E14ADF3A48E2FE265E067E9E02590D657BD9B87EF896253C2D3E138DD0B1290D92C9E3897C64E6B5D68CC524F18F073D39A1DC53562764B08A71A10564F53CE21A7428EE3E9801773D4E427909A240AE149342F596C2EF87414DBC486DF52C9F4015FD6B6192B77E91590E85BEDD079D9A5C273ED2544352BF913F1824D15B7CE331B5895E7DABB1E932FE9416CCC087E911E0952AE243F1F2FD43C9FF8B294330ED47B38A400A89144A87E461EC6B561654D6D3B5036A412358D781C6AE935901E71C7051FCA3F4BB0049272AC9F1B43847ED0CCA1F8A4670D2378F1AE1338B00D107ED004FB86168512172360F2D40B8F6BFB9E3721A74F637C916AA434DA842009BF9ABE9CE7942A0394042E338C8E61A032440292472D2B3AF3CC5396C84F14DAC115400D3D2FE72E29DD6FC98968523167E853550F8AF4684E70FF48431950DA69958CB9D3D0A03821249739EB909A2E78EB80F651C0553598DD4345ED9F21436D7A49DFA774F15817980CFD72EEE4620BA713D6BF81A953BABE83F5E292A099F07749ECFF6E2258D48F239DD1D0951DE9C3AE22B00098A510FF5230C8CFFFC8B9BE76F1904A05649FD0766D94038ED4AB901433FEEA667D196B7E0242620C6895725DA782234CDA8D1BD49FA586BEB793D2CBB6D3DC8B8FC18992393CA84923FD17774C82EE67D46050910A8D3B823EB253B9A73DBF388DC91DA2A6F14E92D7DF58E2F7AE3D6DAEF74ACEF7B39F068D4E895E6D0020E84AC0095C0991D11F09E02DC024C22A41809898662B58DE47649736CA74F4AA0A2F2B8E09C3B154D1904B82337881030DD9699BD397BE9CD4DC152BD097F3078B69F47465C4B787232227E4F7966E021FBB3F974182022BC35C415BE677C96B08E1A7DD1C3810EF28AD6975730167365DD8335993F96529F36DE245736358E9F9360EB53494247E382496380A006F077F6A1B42F72ED63B7B22CA0D10A410194A2D714C974142E86DF6639BC37714564983322EF900F0E0CA785907DECF7C9557056E09DC242E10D69C3EB604BF96DC2BBE1F69203EF664EA68CD23526F6336937
-20200308160131 2 6 100 6143 2 F3D69BF99011E14ADF3A48E2FE265E067E9E02590D657BD9B87EF896253C2D3E138DD0B1290D92C9E3897C64E6B5D68CC524F18F073D39A1DC53562764B08A71A10564F53CE21A7428EE3E9801773D4E427909A240AE149342F596C2EF87414DBC486DF52C9F4015FD6B6192B77E91590E85BEDD079D9A5C273ED2544352BF913F1824D15B7CE331B5895E7DABB1E932FE9416CCC087E911E0952AE243F1F2FD43C9FF8B294330ED47B38A400A89144A87E461EC6B561654D6D3B5036A412358D781C6AE935901E71C7051FCA3F4BB0049272AC9F1B43847ED0CCA1F8A4670D2378F1AE1338B00D107ED004FB86168512172360F2D40B8F6BFB9E3721A74F637C916AA434DA842009BF9ABE9CE7942A0394042E338C8E61A032440292472D2B3AF3CC5396C84F14DAC115400D3D2FE72E29DD6FC98968523167E853550F8AF4684E70FF48431950DA69958CB9D3D0A03821249739EB909A2E78EB80F651C0553598DD4345ED9F21436D7A49DFA774F15817980CFD72EEE4620BA713D6BF81A953BABE83F5E292A099F07749ECFF6E2258D48F239DD1D0951DE9C3AE22B00098A510FF5230C8CFFFC8B9BE76F1904A05649FD0766D94038ED4AB901433FEEA667D196B7E0242620C6895725DA782234CDA8D1BD49FA586BEB793D2CBB6D3DC8B8FC18992393CA84923FD17774C82EE67D46050910A8D3B823EB253B9A73DBF388DC91DA2A6F14E92D7DF58E2F7AE3D6DAEF74ACEF7B39F068D4E895E6D0020E84AC0095C0991D11F09E02DC024C22A41809898662B58DE47649736CA74F4AA0A2F2B8E09C3B154D1904B82337881030DD9699BD397BE9CD4DC152BD097F3078B69F47465C4B787232227E4F7966E021FBB3F974182022BC35C415BE677C96B08E1A7DD1C3810EF28AD6975730167365DD8335993F96529F36DE245736358E9F9360EB53494247E382496380A006F077F6A1B42F72ED63B7B22CA0D10A410194A2D714C974142E86DF6639BC37714564983322EF900F0E0CA785907DECF7C9557056E09DC242E10D69C3EB604BF96DC2BBE1F69203EF664EA68CD23526F6E350AB
-20200308164518 2 6 100 6143 5 F3D69BF99011E14ADF3A48E2FE265E067E9E02590D657BD9B87EF896253C2D3E138DD0B1290D92C9E3897C64E6B5D68CC524F18F073D39A1DC53562764B08A71A10564F53CE21A7428EE3E9801773D4E427909A240AE149342F596C2EF87414DBC486DF52C9F4015FD6B6192B77E91590E85BEDD079D9A5C273ED2544352BF913F1824D15B7CE331B5895E7DABB1E932FE9416CCC087E911E0952AE243F1F2FD43C9FF8B294330ED47B38A400A89144A87E461EC6B561654D6D3B5036A412358D781C6AE935901E71C7051FCA3F4BB0049272AC9F1B43847ED0CCA1F8A4670D2378F1AE1338B00D107ED004FB86168512172360F2D40B8F6BFB9E3721A74F637C916AA434DA842009BF9ABE9CE7942A0394042E338C8E61A032440292472D2B3AF3CC5396C84F14DAC115400D3D2FE72E29DD6FC98968523167E853550F8AF4684E70FF48431950DA69958CB9D3D0A03821249739EB909A2E78EB80F651C0553598DD4345ED9F21436D7A49DFA774F15817980CFD72EEE4620BA713D6BF81A953BABE83F5E292A099F07749ECFF6E2258D48F239DD1D0951DE9C3AE22B00098A510FF5230C8CFFFC8B9BE76F1904A05649FD0766D94038ED4AB901433FEEA667D196B7E0242620C6895725DA782234CDA8D1BD49FA586BEB793D2CBB6D3DC8B8FC18992393CA84923FD17774C82EE67D46050910A8D3B823EB253B9A73DBF388DC91DA2A6F14E92D7DF58E2F7AE3D6DAEF74ACEF7B39F068D4E895E6D0020E84AC0095C0991D11F09E02DC024C22A41809898662B58DE47649736CA74F4AA0A2F2B8E09C3B154D1904B82337881030DD9699BD397BE9CD4DC152BD097F3078B69F47465C4B787232227E4F7966E021FBB3F974182022BC35C415BE677C96B08E1A7DD1C3810EF28AD6975730167365DD8335993F96529F36DE245736358E9F9360EB53494247E382496380A006F077F6A1B42F72ED63B7B22CA0D10A410194A2D714C974142E86DF6639BC37714564983322EF900F0E0CA785907DECF7C9557056E09DC242E10D69C3EB604BF96DC2BBE1F69203EF664EA68CD23526F7C6DB3F
-20200308175233 2 6 100 6143 2 F3D69BF99011E14ADF3A48E2FE265E067E9E02590D657BD9B87EF896253C2D3E138DD0B1290D92C9E3897C64E6B5D68CC524F18F073D39A1DC53562764B08A71A10564F53CE21A7428EE3E9801773D4E427909A240AE149342F596C2EF87414DBC486DF52C9F4015FD6B6192B77E91590E85BEDD079D9A5C273ED2544352BF913F1824D15B7CE331B5895E7DABB1E932FE9416CCC087E911E0952AE243F1F2FD43C9FF8B294330ED47B38A400A89144A87E461EC6B561654D6D3B5036A412358D781C6AE935901E71C7051FCA3F4BB0049272AC9F1B43847ED0CCA1F8A4670D2378F1AE1338B00D107ED004FB86168512172360F2D40B8F6BFB9E3721A74F637C916AA434DA842009BF9ABE9CE7942A0394042E338C8E61A032440292472D2B3AF3CC5396C84F14DAC115400D3D2FE72E29DD6FC98968523167E853550F8AF4684E70FF48431950DA69958CB9D3D0A03821249739EB909A2E78EB80F651C0553598DD4345ED9F21436D7A49DFA774F15817980CFD72EEE4620BA713D6BF81A953BABE83F5E292A099F07749ECFF6E2258D48F239DD1D0951DE9C3AE22B00098A510FF5230C8CFFFC8B9BE76F1904A05649FD0766D94038ED4AB901433FEEA667D196B7E0242620C6895725DA782234CDA8D1BD49FA586BEB793D2CBB6D3DC8B8FC18992393CA84923FD17774C82EE67D46050910A8D3B823EB253B9A73DBF388DC91DA2A6F14E92D7DF58E2F7AE3D6DAEF74ACEF7B39F068D4E895E6D0020E84AC0095C0991D11F09E02DC024C22A41809898662B58DE47649736CA74F4AA0A2F2B8E09C3B154D1904B82337881030DD9699BD397BE9CD4DC152BD097F3078B69F47465C4B787232227E4F7966E021FBB3F974182022BC35C415BE677C96B08E1A7DD1C3810EF28AD6975730167365DD8335993F96529F36DE245736358E9F9360EB53494247E382496380A006F077F6A1B42F72ED63B7B22CA0D10A410194A2D714C974142E86DF6639BC37714564983322EF900F0E0CA785907DECF7C9557056E09DC242E10D69C3EB604BF96DC2BBE1F69203EF664EA68CD23526F910C19B
-20200308195051 2 6 100 6143 5 F3D69BF99011E14ADF3A48E2FE265E067E9E02590D657BD9B87EF896253C2D3E138DD0B1290D92C9E3897C64E6B5D68CC524F18F073D39A1DC53562764B08A71A10564F53CE21A7428EE3E9801773D4E427909A240AE149342F596C2EF87414DBC486DF52C9F4015FD6B6192B77E91590E85BEDD079D9A5C273ED2544352BF913F1824D15B7CE331B5895E7DABB1E932FE9416CCC087E911E0952AE243F1F2FD43C9FF8B294330ED47B38A400A89144A87E461EC6B561654D6D3B5036A412358D781C6AE935901E71C7051FCA3F4BB0049272AC9F1B43847ED0CCA1F8A4670D2378F1AE1338B00D107ED004FB86168512172360F2D40B8F6BFB9E3721A74F637C916AA434DA842009BF9ABE9CE7942A0394042E338C8E61A032440292472D2B3AF3CC5396C84F14DAC115400D3D2FE72E29DD6FC98968523167E853550F8AF4684E70FF48431950DA69958CB9D3D0A03821249739EB909A2E78EB80F651C0553598DD4345ED9F21436D7A49DFA774F15817980CFD72EEE4620BA713D6BF81A953BABE83F5E292A099F07749ECFF6E2258D48F239DD1D0951DE9C3AE22B00098A510FF5230C8CFFFC8B9BE76F1904A05649FD0766D94038ED4AB901433FEEA667D196B7E0242620C6895725DA782234CDA8D1BD49FA586BEB793D2CBB6D3DC8B8FC18992393CA84923FD17774C82EE67D46050910A8D3B823EB253B9A73DBF388DC91DA2A6F14E92D7DF58E2F7AE3D6DAEF74ACEF7B39F068D4E895E6D0020E84AC0095C0991D11F09E02DC024C22A41809898662B58DE47649736CA74F4AA0A2F2B8E09C3B154D1904B82337881030DD9699BD397BE9CD4DC152BD097F3078B69F47465C4B787232227E4F7966E021FBB3F974182022BC35C415BE677C96B08E1A7DD1C3810EF28AD6975730167365DD8335993F96529F36DE245736358E9F9360EB53494247E382496380A006F077F6A1B42F72ED63B7B22CA0D10A410194A2D714C974142E86DF6639BC37714564983322EF900F0E0CA785907DECF7C9557056E09DC242E10D69C3EB604BF96DC2BBE1F69203EF664EA68CD23526FB70712F
-20200308200253 2 6 100 6143 5 F3D69BF99011E14ADF3A48E2FE265E067E9E02590D657BD9B87EF896253C2D3E138DD0B1290D92C9E3897C64E6B5D68CC524F18F073D39A1DC53562764B08A71A10564F53CE21A7428EE3E9801773D4E427909A240AE149342F596C2EF87414DBC486DF52C9F4015FD6B6192B77E91590E85BEDD079D9A5C273ED2544352BF913F1824D15B7CE331B5895E7DABB1E932FE9416CCC087E911E0952AE243F1F2FD43C9FF8B294330ED47B38A400A89144A87E461EC6B561654D6D3B5036A412358D781C6AE935901E71C7051FCA3F4BB0049272AC9F1B43847ED0CCA1F8A4670D2378F1AE1338B00D107ED004FB86168512172360F2D40B8F6BFB9E3721A74F637C916AA434DA842009BF9ABE9CE7942A0394042E338C8E61A032440292472D2B3AF3CC5396C84F14DAC115400D3D2FE72E29DD6FC98968523167E853550F8AF4684E70FF48431950DA69958CB9D3D0A03821249739EB909A2E78EB80F651C0553598DD4345ED9F21436D7A49DFA774F15817980CFD72EEE4620BA713D6BF81A953BABE83F5E292A099F07749ECFF6E2258D48F239DD1D0951DE9C3AE22B00098A510FF5230C8CFFFC8B9BE76F1904A05649FD0766D94038ED4AB901433FEEA667D196B7E0242620C6895725DA782234CDA8D1BD49FA586BEB793D2CBB6D3DC8B8FC18992393CA84923FD17774C82EE67D46050910A8D3B823EB253B9A73DBF388DC91DA2A6F14E92D7DF58E2F7AE3D6DAEF74ACEF7B39F068D4E895E6D0020E84AC0095C0991D11F09E02DC024C22A41809898662B58DE47649736CA74F4AA0A2F2B8E09C3B154D1904B82337881030DD9699BD397BE9CD4DC152BD097F3078B69F47465C4B787232227E4F7966E021FBB3F974182022BC35C415BE677C96B08E1A7DD1C3810EF28AD6975730167365DD8335993F96529F36DE245736358E9F9360EB53494247E382496380A006F077F6A1B42F72ED63B7B22CA0D10A410194A2D714C974142E86DF6639BC37714564983322EF900F0E0CA785907DECF7C9557056E09DC242E10D69C3EB604BF96DC2BBE1F69203EF664EA68CD23526FBA523E7
-20200308202652 2 6 100 6143 2 F3D69BF99011E14ADF3A48E2FE265E067E9E02590D657BD9B87EF896253C2D3E138DD0B1290D92C9E3897C64E6B5D68CC524F18F073D39A1DC53562764B08A71A10564F53CE21A7428EE3E9801773D4E427909A240AE149342F596C2EF87414DBC486DF52C9F4015FD6B6192B77E91590E85BEDD079D9A5C273ED2544352BF913F1824D15B7CE331B5895E7DABB1E932FE9416CCC087E911E0952AE243F1F2FD43C9FF8B294330ED47B38A400A89144A87E461EC6B561654D6D3B5036A412358D781C6AE935901E71C7051FCA3F4BB0049272AC9F1B43847ED0CCA1F8A4670D2378F1AE1338B00D107ED004FB86168512172360F2D40B8F6BFB9E3721A74F637C916AA434DA842009BF9ABE9CE7942A0394042E338C8E61A032440292472D2B3AF3CC5396C84F14DAC115400D3D2FE72E29DD6FC98968523167E853550F8AF4684E70FF48431950DA69958CB9D3D0A03821249739EB909A2E78EB80F651C0553598DD4345ED9F21436D7A49DFA774F15817980CFD72EEE4620BA713D6BF81A953BABE83F5E292A099F07749ECFF6E2258D48F239DD1D0951DE9C3AE22B00098A510FF5230C8CFFFC8B9BE76F1904A05649FD0766D94038ED4AB901433FEEA667D196B7E0242620C6895725DA782234CDA8D1BD49FA586BEB793D2CBB6D3DC8B8FC18992393CA84923FD17774C82EE67D46050910A8D3B823EB253B9A73DBF388DC91DA2A6F14E92D7DF58E2F7AE3D6DAEF74ACEF7B39F068D4E895E6D0020E84AC0095C0991D11F09E02DC024C22A41809898662B58DE47649736CA74F4AA0A2F2B8E09C3B154D1904B82337881030DD9699BD397BE9CD4DC152BD097F3078B69F47465C4B787232227E4F7966E021FBB3F974182022BC35C415BE677C96B08E1A7DD1C3810EF28AD6975730167365DD8335993F96529F36DE245736358E9F9360EB53494247E382496380A006F077F6A1B42F72ED63B7B22CA0D10A410194A2D714C974142E86DF6639BC37714564983322EF900F0E0CA785907DECF7C9557056E09DC242E10D69C3EB604BF96DC2BBE1F69203EF664EA68CD23526FC156CA3
-20200308203457 2 6 100 6143 2 F3D69BF99011E14ADF3A48E2FE265E067E9E02590D657BD9B87EF896253C2D3E138DD0B1290D92C9E3897C64E6B5D68CC524F18F073D39A1DC53562764B08A71A10564F53CE21A7428EE3E9801773D4E427909A240AE149342F596C2EF87414DBC486DF52C9F4015FD6B6192B77E91590E85BEDD079D9A5C273ED2544352BF913F1824D15B7CE331B5895E7DABB1E932FE9416CCC087E911E0952AE243F1F2FD43C9FF8B294330ED47B38A400A89144A87E461EC6B561654D6D3B5036A412358D781C6AE935901E71C7051FCA3F4BB0049272AC9F1B43847ED0CCA1F8A4670D2378F1AE1338B00D107ED004FB86168512172360F2D40B8F6BFB9E3721A74F637C916AA434DA842009BF9ABE9CE7942A0394042E338C8E61A032440292472D2B3AF3CC5396C84F14DAC115400D3D2FE72E29DD6FC98968523167E853550F8AF4684E70FF48431950DA69958CB9D3D0A03821249739EB909A2E78EB80F651C0553598DD4345ED9F21436D7A49DFA774F15817980CFD72EEE4620BA713D6BF81A953BABE83F5E292A099F07749ECFF6E2258D48F239DD1D0951DE9C3AE22B00098A510FF5230C8CFFFC8B9BE76F1904A05649FD0766D94038ED4AB901433FEEA667D196B7E0242620C6895725DA782234CDA8D1BD49FA586BEB793D2CBB6D3DC8B8FC18992393CA84923FD17774C82EE67D46050910A8D3B823EB253B9A73DBF388DC91DA2A6F14E92D7DF58E2F7AE3D6DAEF74ACEF7B39F068D4E895E6D0020E84AC0095C0991D11F09E02DC024C22A41809898662B58DE47649736CA74F4AA0A2F2B8E09C3B154D1904B82337881030DD9699BD397BE9CD4DC152BD097F3078B69F47465C4B787232227E4F7966E021FBB3F974182022BC35C415BE677C96B08E1A7DD1C3810EF28AD6975730167365DD8335993F96529F36DE245736358E9F9360EB53494247E382496380A006F077F6A1B42F72ED63B7B22CA0D10A410194A2D714C974142E86DF6639BC37714564983322EF900F0E0CA785907DECF7C9557056E09DC242E10D69C3EB604BF96DC2BBE1F69203EF664EA68CD23526FC390FEB
-20200308204237 2 6 100 6143 2 F3D69BF99011E14ADF3A48E2FE265E067E9E02590D657BD9B87EF896253C2D3E138DD0B1290D92C9E3897C64E6B5D68CC524F18F073D39A1DC53562764B08A71A10564F53CE21A7428EE3E9801773D4E427909A240AE149342F596C2EF87414DBC486DF52C9F4015FD6B6192B77E91590E85BEDD079D9A5C273ED2544352BF913F1824D15B7CE331B5895E7DABB1E932FE9416CCC087E911E0952AE243F1F2FD43C9FF8B294330ED47B38A400A89144A87E461EC6B561654D6D3B5036A412358D781C6AE935901E71C7051FCA3F4BB0049272AC9F1B43847ED0CCA1F8A4670D2378F1AE1338B00D107ED004FB86168512172360F2D40B8F6BFB9E3721A74F637C916AA434DA842009BF9ABE9CE7942A0394042E338C8E61A032440292472D2B3AF3CC5396C84F14DAC115400D3D2FE72E29DD6FC98968523167E853550F8AF4684E70FF48431950DA69958CB9D3D0A03821249739EB909A2E78EB80F651C0553598DD4345ED9F21436D7A49DFA774F15817980CFD72EEE4620BA713D6BF81A953BABE83F5E292A099F07749ECFF6E2258D48F239DD1D0951DE9C3AE22B00098A510FF5230C8CFFFC8B9BE76F1904A05649FD0766D94038ED4AB901433FEEA667D196B7E0242620C6895725DA782234CDA8D1BD49FA586BEB793D2CBB6D3DC8B8FC18992393CA84923FD17774C82EE67D46050910A8D3B823EB253B9A73DBF388DC91DA2A6F14E92D7DF58E2F7AE3D6DAEF74ACEF7B39F068D4E895E6D0020E84AC0095C0991D11F09E02DC024C22A41809898662B58DE47649736CA74F4AA0A2F2B8E09C3B154D1904B82337881030DD9699BD397BE9CD4DC152BD097F3078B69F47465C4B787232227E4F7966E021FBB3F974182022BC35C415BE677C96B08E1A7DD1C3810EF28AD6975730167365DD8335993F96529F36DE245736358E9F9360EB53494247E382496380A006F077F6A1B42F72ED63B7B22CA0D10A410194A2D714C974142E86DF6639BC37714564983322EF900F0E0CA785907DECF7C9557056E09DC242E10D69C3EB604BF96DC2BBE1F69203EF664EA68CD23526FC547E5B
-20200309092747 2 6 100 7679 2 F9B9E3DF0669078220C98F6E1775CAE12B5D95EF20D9491DDDFC0DFBA8EE09FD43F58BA934B719A06ECFF9646CA90998726E6FBDC6DB663F3BE44CF10A44B9D2DD7B01682B867206E6A67FE77170050860206AE5980778EA44104698A52D4D57D2AE0B98826DD3E98CB26E3CF0F044546CA7A97505E68983B439E27EE64AAB26D9FAB324CBADE29FBF733AF761D5CBA8E15D906F992080A1A725D65DD85CCDF0B00CCD5D44952C7D46CC514F6D34DD225F26B5CCFB2EB26077A854C19585DD40F4373FE41626532D4753C3617395FDF26FAAE36A6BD0D9009A7F9086AE9B150BD4712B4672ABACF3EC652B972885D8C6C858C93FA42B72E48EFB055E25828CF6FBF609BA25A589B79E0B64DB63F971C6C06103696A359338034A1FB53E0B601FCBDB8CB6BE8DA048C4D9CEA7EA4A458FA64A87B788543854D94977330FEBC9BB09855083ED12C13858DED10C17C19412C7AF9412F4FE952322D80FC9B26842B1FE1859E670FB047390669D81225409853A3E3CCEE979D1120F4F3D833C49A7F8EA673FA68ACB33FFFC3B56A3F277D237F566F5A342C79B3E40EBEBD6E570B1AED4845B353995C7B758CFD4875A799F652122648618AC29D583E04D772FB6739F69D5E4DBFF2BD7B3468729E1ED90C9C523C36912B2EBC69199A5E7D0982867536275332B62C1AD6F07F1825BE66CDC5C99427268B6D1E754A90AF36F49C136E40455866B92FBEF1A298C3A3EFDB6F0F459F5E885D2C0B74C4C7347430AAD7EF86BFA21F8D38CAC911171802D645A73B5249334E26B804F47A012DE0FE1CF4745F33A4A5882DCA984E253E6B16B9A8A15541F65270BFB61A64EFE9BDBBFE4205B1F4FFF5FD75EF15D17F3CBB89651E88866A2AD67D0BD7B21B4495406B0F7A083AB155D37497CC81E4F360F39DF5A26C40662176ACB041805614DD761C619282E2719C29693050058E6FA82FF4237E86A408ADB3DDC5ADC0D770B3E5D1861B669FCEB53D432A5928AB547040CF2044B3164573AE36C52DE160C2F34B0FC18B1C5E53DE1ACF886086064AAE3566D2AC9E00EFED873A201F0D14FC0DFDCF40ED380E12F9CD3D65F944D888D1FFB0F0ADF56CDCBC3036FBA03AB05944D37F24917DF3E18B9EE06B1AFDB385FBBC9425D414849B0FE0BF8D101669341EA388B899ECA0BC7FF46200CC64E0A8480C9B55E71D2A3AAB11FB5D9E2278016E8BCE6901A87B8D993F8AEE78698D6FD13D2E26873F3DA86F0983AB151E921C0A0308ECA824E32FBBF2E8F1BC4E0BEC0013BA6B89BB61F495FAAB142B782BC59FB4B15EBD4DF155A56B07F7E64C4732DB1BF21E03DD68DACABB778E97C74380E7BB469CBC603
-20200309132310 2 6 100 7679 5 F9B9E3DF0669078220C98F6E1775CAE12B5D95EF20D9491DDDFC0DFBA8EE09FD43F58BA934B719A06ECFF9646CA90998726E6FBDC6DB663F3BE44CF10A44B9D2DD7B01682B867206E6A67FE77170050860206AE5980778EA44104698A52D4D57D2AE0B98826DD3E98CB26E3CF0F044546CA7A97505E68983B439E27EE64AAB26D9FAB324CBADE29FBF733AF761D5CBA8E15D906F992080A1A725D65DD85CCDF0B00CCD5D44952C7D46CC514F6D34DD225F26B5CCFB2EB26077A854C19585DD40F4373FE41626532D4753C3617395FDF26FAAE36A6BD0D9009A7F9086AE9B150BD4712B4672ABACF3EC652B972885D8C6C858C93FA42B72E48EFB055E25828CF6FBF609BA25A589B79E0B64DB63F971C6C06103696A359338034A1FB53E0B601FCBDB8CB6BE8DA048C4D9CEA7EA4A458FA64A87B788543854D94977330FEBC9BB09855083ED12C13858DED10C17C19412C7AF9412F4FE952322D80FC9B26842B1FE1859E670FB047390669D81225409853A3E3CCEE979D1120F4F3D833C49A7F8EA673FA68ACB33FFFC3B56A3F277D237F566F5A342C79B3E40EBEBD6E570B1AED4845B353995C7B758CFD4875A799F652122648618AC29D583E04D772FB6739F69D5E4DBFF2BD7B3468729E1ED90C9C523C36912B2EBC69199A5E7D0982867536275332B62C1AD6F07F1825BE66CDC5C99427268B6D1E754A90AF36F49C136E40455866B92FBEF1A298C3A3EFDB6F0F459F5E885D2C0B74C4C7347430AAD7EF86BFA21F8D38CAC911171802D645A73B5249334E26B804F47A012DE0FE1CF4745F33A4A5882DCA984E253E6B16B9A8A15541F65270BFB61A64EFE9BDBBFE4205B1F4FFF5FD75EF15D17F3CBB89651E88866A2AD67D0BD7B21B4495406B0F7A083AB155D37497CC81E4F360F39DF5A26C40662176ACB041805614DD761C619282E2719C29693050058E6FA82FF4237E86A408ADB3DDC5ADC0D770B3E5D1861B669FCEB53D432A5928AB547040CF2044B3164573AE36C52DE160C2F34B0FC18B1C5E53DE1ACF886086064AAE3566D2AC9E00EFED873A201F0D14FC0DFDCF40ED380E12F9CD3D65F944D888D1FFB0F0ADF56CDCBC3036FBA03AB05944D37F24917DF3E18B9EE06B1AFDB385FBBC9425D414849B0FE0BF8D101669341EA388B899ECA0BC7FF46200CC64E0A8480C9B55E71D2A3AAB11FB5D9E2278016E8BCE6901A87B8D993F8AEE78698D6FD13D2E26873F3DA86F0983AB151E921C0A0308ECA824E32FBBF2E8F1BC4E0BEC0013BA6B89BB61F495FAAB142B782BC59FB4B15EBD4DF155A56B07F7E64C4732DB1BF21E03DD68DACABB778E97C74380E7BB46CBEF1B7
-20200309170440 2 6 100 7679 5 F9B9E3DF0669078220C98F6E1775CAE12B5D95EF20D9491DDDFC0DFBA8EE09FD43F58BA934B719A06ECFF9646CA90998726E6FBDC6DB663F3BE44CF10A44B9D2DD7B01682B867206E6A67FE77170050860206AE5980778EA44104698A52D4D57D2AE0B98826DD3E98CB26E3CF0F044546CA7A97505E68983B439E27EE64AAB26D9FAB324CBADE29FBF733AF761D5CBA8E15D906F992080A1A725D65DD85CCDF0B00CCD5D44952C7D46CC514F6D34DD225F26B5CCFB2EB26077A854C19585DD40F4373FE41626532D4753C3617395FDF26FAAE36A6BD0D9009A7F9086AE9B150BD4712B4672ABACF3EC652B972885D8C6C858C93FA42B72E48EFB055E25828CF6FBF609BA25A589B79E0B64DB63F971C6C06103696A359338034A1FB53E0B601FCBDB8CB6BE8DA048C4D9CEA7EA4A458FA64A87B788543854D94977330FEBC9BB09855083ED12C13858DED10C17C19412C7AF9412F4FE952322D80FC9B26842B1FE1859E670FB047390669D81225409853A3E3CCEE979D1120F4F3D833C49A7F8EA673FA68ACB33FFFC3B56A3F277D237F566F5A342C79B3E40EBEBD6E570B1AED4845B353995C7B758CFD4875A799F652122648618AC29D583E04D772FB6739F69D5E4DBFF2BD7B3468729E1ED90C9C523C36912B2EBC69199A5E7D0982867536275332B62C1AD6F07F1825BE66CDC5C99427268B6D1E754A90AF36F49C136E40455866B92FBEF1A298C3A3EFDB6F0F459F5E885D2C0B74C4C7347430AAD7EF86BFA21F8D38CAC911171802D645A73B5249334E26B804F47A012DE0FE1CF4745F33A4A5882DCA984E253E6B16B9A8A15541F65270BFB61A64EFE9BDBBFE4205B1F4FFF5FD75EF15D17F3CBB89651E88866A2AD67D0BD7B21B4495406B0F7A083AB155D37497CC81E4F360F39DF5A26C40662176ACB041805614DD761C619282E2719C29693050058E6FA82FF4237E86A408ADB3DDC5ADC0D770B3E5D1861B669FCEB53D432A5928AB547040CF2044B3164573AE36C52DE160C2F34B0FC18B1C5E53DE1ACF886086064AAE3566D2AC9E00EFED873A201F0D14FC0DFDCF40ED380E12F9CD3D65F944D888D1FFB0F0ADF56CDCBC3036FBA03AB05944D37F24917DF3E18B9EE06B1AFDB385FBBC9425D414849B0FE0BF8D101669341EA388B899ECA0BC7FF46200CC64E0A8480C9B55E71D2A3AAB11FB5D9E2278016E8BCE6901A87B8D993F8AEE78698D6FD13D2E26873F3DA86F0983AB151E921C0A0308ECA824E32FBBF2E8F1BC4E0BEC0013BA6B89BB61F495FAAB142B782BC59FB4B15EBD4DF155A56B07F7E64C4732DB1BF21E03DD68DACABB778E97C74380E7BB46F794A2F
-20200309175340 2 6 100 7679 2 F9B9E3DF0669078220C98F6E1775CAE12B5D95EF20D9491DDDFC0DFBA8EE09FD43F58BA934B719A06ECFF9646CA90998726E6FBDC6DB663F3BE44CF10A44B9D2DD7B01682B867206E6A67FE77170050860206AE5980778EA44104698A52D4D57D2AE0B98826DD3E98CB26E3CF0F044546CA7A97505E68983B439E27EE64AAB26D9FAB324CBADE29FBF733AF761D5CBA8E15D906F992080A1A725D65DD85CCDF0B00CCD5D44952C7D46CC514F6D34DD225F26B5CCFB2EB26077A854C19585DD40F4373FE41626532D4753C3617395FDF26FAAE36A6BD0D9009A7F9086AE9B150BD4712B4672ABACF3EC652B972885D8C6C858C93FA42B72E48EFB055E25828CF6FBF609BA25A589B79E0B64DB63F971C6C06103696A359338034A1FB53E0B601FCBDB8CB6BE8DA048C4D9CEA7EA4A458FA64A87B788543854D94977330FEBC9BB09855083ED12C13858DED10C17C19412C7AF9412F4FE952322D80FC9B26842B1FE1859E670FB047390669D81225409853A3E3CCEE979D1120F4F3D833C49A7F8EA673FA68ACB33FFFC3B56A3F277D237F566F5A342C79B3E40EBEBD6E570B1AED4845B353995C7B758CFD4875A799F652122648618AC29D583E04D772FB6739F69D5E4DBFF2BD7B3468729E1ED90C9C523C36912B2EBC69199A5E7D0982867536275332B62C1AD6F07F1825BE66CDC5C99427268B6D1E754A90AF36F49C136E40455866B92FBEF1A298C3A3EFDB6F0F459F5E885D2C0B74C4C7347430AAD7EF86BFA21F8D38CAC911171802D645A73B5249334E26B804F47A012DE0FE1CF4745F33A4A5882DCA984E253E6B16B9A8A15541F65270BFB61A64EFE9BDBBFE4205B1F4FFF5FD75EF15D17F3CBB89651E88866A2AD67D0BD7B21B4495406B0F7A083AB155D37497CC81E4F360F39DF5A26C40662176ACB041805614DD761C619282E2719C29693050058E6FA82FF4237E86A408ADB3DDC5ADC0D770B3E5D1861B669FCEB53D432A5928AB547040CF2044B3164573AE36C52DE160C2F34B0FC18B1C5E53DE1ACF886086064AAE3566D2AC9E00EFED873A201F0D14FC0DFDCF40ED380E12F9CD3D65F944D888D1FFB0F0ADF56CDCBC3036FBA03AB05944D37F24917DF3E18B9EE06B1AFDB385FBBC9425D414849B0FE0BF8D101669341EA388B899ECA0BC7FF46200CC64E0A8480C9B55E71D2A3AAB11FB5D9E2278016E8BCE6901A87B8D993F8AEE78698D6FD13D2E26873F3DA86F0983AB151E921C0A0308ECA824E32FBBF2E8F1BC4E0BEC0013BA6B89BB61F495FAAB142B782BC59FB4B15EBD4DF155A56B07F7E64C4732DB1BF21E03DD68DACABB778E97C74380E7BB47010DC3B
-20200309202152 2 6 100 7679 5 F9B9E3DF0669078220C98F6E1775CAE12B5D95EF20D9491DDDFC0DFBA8EE09FD43F58BA934B719A06ECFF9646CA90998726E6FBDC6DB663F3BE44CF10A44B9D2DD7B01682B867206E6A67FE77170050860206AE5980778EA44104698A52D4D57D2AE0B98826DD3E98CB26E3CF0F044546CA7A97505E68983B439E27EE64AAB26D9FAB324CBADE29FBF733AF761D5CBA8E15D906F992080A1A725D65DD85CCDF0B00CCD5D44952C7D46CC514F6D34DD225F26B5CCFB2EB26077A854C19585DD40F4373FE41626532D4753C3617395FDF26FAAE36A6BD0D9009A7F9086AE9B150BD4712B4672ABACF3EC652B972885D8C6C858C93FA42B72E48EFB055E25828CF6FBF609BA25A589B79E0B64DB63F971C6C06103696A359338034A1FB53E0B601FCBDB8CB6BE8DA048C4D9CEA7EA4A458FA64A87B788543854D94977330FEBC9BB09855083ED12C13858DED10C17C19412C7AF9412F4FE952322D80FC9B26842B1FE1859E670FB047390669D81225409853A3E3CCEE979D1120F4F3D833C49A7F8EA673FA68ACB33FFFC3B56A3F277D237F566F5A342C79B3E40EBEBD6E570B1AED4845B353995C7B758CFD4875A799F652122648618AC29D583E04D772FB6739F69D5E4DBFF2BD7B3468729E1ED90C9C523C36912B2EBC69199A5E7D0982867536275332B62C1AD6F07F1825BE66CDC5C99427268B6D1E754A90AF36F49C136E40455866B92FBEF1A298C3A3EFDB6F0F459F5E885D2C0B74C4C7347430AAD7EF86BFA21F8D38CAC911171802D645A73B5249334E26B804F47A012DE0FE1CF4745F33A4A5882DCA984E253E6B16B9A8A15541F65270BFB61A64EFE9BDBBFE4205B1F4FFF5FD75EF15D17F3CBB89651E88866A2AD67D0BD7B21B4495406B0F7A083AB155D37497CC81E4F360F39DF5A26C40662176ACB041805614DD761C619282E2719C29693050058E6FA82FF4237E86A408ADB3DDC5ADC0D770B3E5D1861B669FCEB53D432A5928AB547040CF2044B3164573AE36C52DE160C2F34B0FC18B1C5E53DE1ACF886086064AAE3566D2AC9E00EFED873A201F0D14FC0DFDCF40ED380E12F9CD3D65F944D888D1FFB0F0ADF56CDCBC3036FBA03AB05944D37F24917DF3E18B9EE06B1AFDB385FBBC9425D414849B0FE0BF8D101669341EA388B899ECA0BC7FF46200CC64E0A8480C9B55E71D2A3AAB11FB5D9E2278016E8BCE6901A87B8D993F8AEE78698D6FD13D2E26873F3DA86F0983AB151E921C0A0308ECA824E32FBBF2E8F1BC4E0BEC0013BA6B89BB61F495FAAB142B782BC59FB4B15EBD4DF155A56B07F7E64C4732DB1BF21E03DD68DACABB778E97C74380E7BB471DCF32F
-20200309224536 2 6 100 7679 2 F9B9E3DF0669078220C98F6E1775CAE12B5D95EF20D9491DDDFC0DFBA8EE09FD43F58BA934B719A06ECFF9646CA90998726E6FBDC6DB663F3BE44CF10A44B9D2DD7B01682B867206E6A67FE77170050860206AE5980778EA44104698A52D4D57D2AE0B98826DD3E98CB26E3CF0F044546CA7A97505E68983B439E27EE64AAB26D9FAB324CBADE29FBF733AF761D5CBA8E15D906F992080A1A725D65DD85CCDF0B00CCD5D44952C7D46CC514F6D34DD225F26B5CCFB2EB26077A854C19585DD40F4373FE41626532D4753C3617395FDF26FAAE36A6BD0D9009A7F9086AE9B150BD4712B4672ABACF3EC652B972885D8C6C858C93FA42B72E48EFB055E25828CF6FBF609BA25A589B79E0B64DB63F971C6C06103696A359338034A1FB53E0B601FCBDB8CB6BE8DA048C4D9CEA7EA4A458FA64A87B788543854D94977330FEBC9BB09855083ED12C13858DED10C17C19412C7AF9412F4FE952322D80FC9B26842B1FE1859E670FB047390669D81225409853A3E3CCEE979D1120F4F3D833C49A7F8EA673FA68ACB33FFFC3B56A3F277D237F566F5A342C79B3E40EBEBD6E570B1AED4845B353995C7B758CFD4875A799F652122648618AC29D583E04D772FB6739F69D5E4DBFF2BD7B3468729E1ED90C9C523C36912B2EBC69199A5E7D0982867536275332B62C1AD6F07F1825BE66CDC5C99427268B6D1E754A90AF36F49C136E40455866B92FBEF1A298C3A3EFDB6F0F459F5E885D2C0B74C4C7347430AAD7EF86BFA21F8D38CAC911171802D645A73B5249334E26B804F47A012DE0FE1CF4745F33A4A5882DCA984E253E6B16B9A8A15541F65270BFB61A64EFE9BDBBFE4205B1F4FFF5FD75EF15D17F3CBB89651E88866A2AD67D0BD7B21B4495406B0F7A083AB155D37497CC81E4F360F39DF5A26C40662176ACB041805614DD761C619282E2719C29693050058E6FA82FF4237E86A408ADB3DDC5ADC0D770B3E5D1861B669FCEB53D432A5928AB547040CF2044B3164573AE36C52DE160C2F34B0FC18B1C5E53DE1ACF886086064AAE3566D2AC9E00EFED873A201F0D14FC0DFDCF40ED380E12F9CD3D65F944D888D1FFB0F0ADF56CDCBC3036FBA03AB05944D37F24917DF3E18B9EE06B1AFDB385FBBC9425D414849B0FE0BF8D101669341EA388B899ECA0BC7FF46200CC64E0A8480C9B55E71D2A3AAB11FB5D9E2278016E8BCE6901A87B8D993F8AEE78698D6FD13D2E26873F3DA86F0983AB151E921C0A0308ECA824E32FBBF2E8F1BC4E0BEC0013BA6B89BB61F495FAAB142B782BC59FB4B15EBD4DF155A56B07F7E64C4732DB1BF21E03DD68DACABB778E97C74380E7BB473A874CB
-20200310025444 2 6 100 7679 2 F9B9E3DF0669078220C98F6E1775CAE12B5D95EF20D9491DDDFC0DFBA8EE09FD43F58BA934B719A06ECFF9646CA90998726E6FBDC6DB663F3BE44CF10A44B9D2DD7B01682B867206E6A67FE77170050860206AE5980778EA44104698A52D4D57D2AE0B98826DD3E98CB26E3CF0F044546CA7A97505E68983B439E27EE64AAB26D9FAB324CBADE29FBF733AF761D5CBA8E15D906F992080A1A725D65DD85CCDF0B00CCD5D44952C7D46CC514F6D34DD225F26B5CCFB2EB26077A854C19585DD40F4373FE41626532D4753C3617395FDF26FAAE36A6BD0D9009A7F9086AE9B150BD4712B4672ABACF3EC652B972885D8C6C858C93FA42B72E48EFB055E25828CF6FBF609BA25A589B79E0B64DB63F971C6C06103696A359338034A1FB53E0B601FCBDB8CB6BE8DA048C4D9CEA7EA4A458FA64A87B788543854D94977330FEBC9BB09855083ED12C13858DED10C17C19412C7AF9412F4FE952322D80FC9B26842B1FE1859E670FB047390669D81225409853A3E3CCEE979D1120F4F3D833C49A7F8EA673FA68ACB33FFFC3B56A3F277D237F566F5A342C79B3E40EBEBD6E570B1AED4845B353995C7B758CFD4875A799F652122648618AC29D583E04D772FB6739F69D5E4DBFF2BD7B3468729E1ED90C9C523C36912B2EBC69199A5E7D0982867536275332B62C1AD6F07F1825BE66CDC5C99427268B6D1E754A90AF36F49C136E40455866B92FBEF1A298C3A3EFDB6F0F459F5E885D2C0B74C4C7347430AAD7EF86BFA21F8D38CAC911171802D645A73B5249334E26B804F47A012DE0FE1CF4745F33A4A5882DCA984E253E6B16B9A8A15541F65270BFB61A64EFE9BDBBFE4205B1F4FFF5FD75EF15D17F3CBB89651E88866A2AD67D0BD7B21B4495406B0F7A083AB155D37497CC81E4F360F39DF5A26C40662176ACB041805614DD761C619282E2719C29693050058E6FA82FF4237E86A408ADB3DDC5ADC0D770B3E5D1861B669FCEB53D432A5928AB547040CF2044B3164573AE36C52DE160C2F34B0FC18B1C5E53DE1ACF886086064AAE3566D2AC9E00EFED873A201F0D14FC0DFDCF40ED380E12F9CD3D65F944D888D1FFB0F0ADF56CDCBC3036FBA03AB05944D37F24917DF3E18B9EE06B1AFDB385FBBC9425D414849B0FE0BF8D101669341EA388B899ECA0BC7FF46200CC64E0A8480C9B55E71D2A3AAB11FB5D9E2278016E8BCE6901A87B8D993F8AEE78698D6FD13D2E26873F3DA86F0983AB151E921C0A0308ECA824E32FBBF2E8F1BC4E0BEC0013BA6B89BB61F495FAAB142B782BC59FB4B15EBD4DF155A56B07F7E64C4732DB1BF21E03DD68DACABB778E97C74380E7BB476C22A9B
-20200310062019 2 6 100 7679 5 F9B9E3DF0669078220C98F6E1775CAE12B5D95EF20D9491DDDFC0DFBA8EE09FD43F58BA934B719A06ECFF9646CA90998726E6FBDC6DB663F3BE44CF10A44B9D2DD7B01682B867206E6A67FE77170050860206AE5980778EA44104698A52D4D57D2AE0B98826DD3E98CB26E3CF0F044546CA7A97505E68983B439E27EE64AAB26D9FAB324CBADE29FBF733AF761D5CBA8E15D906F992080A1A725D65DD85CCDF0B00CCD5D44952C7D46CC514F6D34DD225F26B5CCFB2EB26077A854C19585DD40F4373FE41626532D4753C3617395FDF26FAAE36A6BD0D9009A7F9086AE9B150BD4712B4672ABACF3EC652B972885D8C6C858C93FA42B72E48EFB055E25828CF6FBF609BA25A589B79E0B64DB63F971C6C06103696A359338034A1FB53E0B601FCBDB8CB6BE8DA048C4D9CEA7EA4A458FA64A87B788543854D94977330FEBC9BB09855083ED12C13858DED10C17C19412C7AF9412F4FE952322D80FC9B26842B1FE1859E670FB047390669D81225409853A3E3CCEE979D1120F4F3D833C49A7F8EA673FA68ACB33FFFC3B56A3F277D237F566F5A342C79B3E40EBEBD6E570B1AED4845B353995C7B758CFD4875A799F652122648618AC29D583E04D772FB6739F69D5E4DBFF2BD7B3468729E1ED90C9C523C36912B2EBC69199A5E7D0982867536275332B62C1AD6F07F1825BE66CDC5C99427268B6D1E754A90AF36F49C136E40455866B92FBEF1A298C3A3EFDB6F0F459F5E885D2C0B74C4C7347430AAD7EF86BFA21F8D38CAC911171802D645A73B5249334E26B804F47A012DE0FE1CF4745F33A4A5882DCA984E253E6B16B9A8A15541F65270BFB61A64EFE9BDBBFE4205B1F4FFF5FD75EF15D17F3CBB89651E88866A2AD67D0BD7B21B4495406B0F7A083AB155D37497CC81E4F360F39DF5A26C40662176ACB041805614DD761C619282E2719C29693050058E6FA82FF4237E86A408ADB3DDC5ADC0D770B3E5D1861B669FCEB53D432A5928AB547040CF2044B3164573AE36C52DE160C2F34B0FC18B1C5E53DE1ACF886086064AAE3566D2AC9E00EFED873A201F0D14FC0DFDCF40ED380E12F9CD3D65F944D888D1FFB0F0ADF56CDCBC3036FBA03AB05944D37F24917DF3E18B9EE06B1AFDB385FBBC9425D414849B0FE0BF8D101669341EA388B899ECA0BC7FF46200CC64E0A8480C9B55E71D2A3AAB11FB5D9E2278016E8BCE6901A87B8D993F8AEE78698D6FD13D2E26873F3DA86F0983AB151E921C0A0308ECA824E32FBBF2E8F1BC4E0BEC0013BA6B89BB61F495FAAB142B782BC59FB4B15EBD4DF155A56B07F7E64C4732DB1BF21E03DD68DACABB778E97C74380E7BB479486FC7
-20200310082852 2 6 100 7679 2 F9B9E3DF0669078220C98F6E1775CAE12B5D95EF20D9491DDDFC0DFBA8EE09FD43F58BA934B719A06ECFF9646CA90998726E6FBDC6DB663F3BE44CF10A44B9D2DD7B01682B867206E6A67FE77170050860206AE5980778EA44104698A52D4D57D2AE0B98826DD3E98CB26E3CF0F044546CA7A97505E68983B439E27EE64AAB26D9FAB324CBADE29FBF733AF761D5CBA8E15D906F992080A1A725D65DD85CCDF0B00CCD5D44952C7D46CC514F6D34DD225F26B5CCFB2EB26077A854C19585DD40F4373FE41626532D4753C3617395FDF26FAAE36A6BD0D9009A7F9086AE9B150BD4712B4672ABACF3EC652B972885D8C6C858C93FA42B72E48EFB055E25828CF6FBF609BA25A589B79E0B64DB63F971C6C06103696A359338034A1FB53E0B601FCBDB8CB6BE8DA048C4D9CEA7EA4A458FA64A87B788543854D94977330FEBC9BB09855083ED12C13858DED10C17C19412C7AF9412F4FE952322D80FC9B26842B1FE1859E670FB047390669D81225409853A3E3CCEE979D1120F4F3D833C49A7F8EA673FA68ACB33FFFC3B56A3F277D237F566F5A342C79B3E40EBEBD6E570B1AED4845B353995C7B758CFD4875A799F652122648618AC29D583E04D772FB6739F69D5E4DBFF2BD7B3468729E1ED90C9C523C36912B2EBC69199A5E7D0982867536275332B62C1AD6F07F1825BE66CDC5C99427268B6D1E754A90AF36F49C136E40455866B92FBEF1A298C3A3EFDB6F0F459F5E885D2C0B74C4C7347430AAD7EF86BFA21F8D38CAC911171802D645A73B5249334E26B804F47A012DE0FE1CF4745F33A4A5882DCA984E253E6B16B9A8A15541F65270BFB61A64EFE9BDBBFE4205B1F4FFF5FD75EF15D17F3CBB89651E88866A2AD67D0BD7B21B4495406B0F7A083AB155D37497CC81E4F360F39DF5A26C40662176ACB041805614DD761C619282E2719C29693050058E6FA82FF4237E86A408ADB3DDC5ADC0D770B3E5D1861B669FCEB53D432A5928AB547040CF2044B3164573AE36C52DE160C2F34B0FC18B1C5E53DE1ACF886086064AAE3566D2AC9E00EFED873A201F0D14FC0DFDCF40ED380E12F9CD3D65F944D888D1FFB0F0ADF56CDCBC3036FBA03AB05944D37F24917DF3E18B9EE06B1AFDB385FBBC9425D414849B0FE0BF8D101669341EA388B899ECA0BC7FF46200CC64E0A8480C9B55E71D2A3AAB11FB5D9E2278016E8BCE6901A87B8D993F8AEE78698D6FD13D2E26873F3DA86F0983AB151E921C0A0308ECA824E32FBBF2E8F1BC4E0BEC0013BA6B89BB61F495FAAB142B782BC59FB4B15EBD4DF155A56B07F7E64C4732DB1BF21E03DD68DACABB778E97C74380E7BB47AD3C293
-20200310111216 2 6 100 7679 2 F9B9E3DF0669078220C98F6E1775CAE12B5D95EF20D9491DDDFC0DFBA8EE09FD43F58BA934B719A06ECFF9646CA90998726E6FBDC6DB663F3BE44CF10A44B9D2DD7B01682B867206E6A67FE77170050860206AE5980778EA44104698A52D4D57D2AE0B98826DD3E98CB26E3CF0F044546CA7A97505E68983B439E27EE64AAB26D9FAB324CBADE29FBF733AF761D5CBA8E15D906F992080A1A725D65DD85CCDF0B00CCD5D44952C7D46CC514F6D34DD225F26B5CCFB2EB26077A854C19585DD40F4373FE41626532D4753C3617395FDF26FAAE36A6BD0D9009A7F9086AE9B150BD4712B4672ABACF3EC652B972885D8C6C858C93FA42B72E48EFB055E25828CF6FBF609BA25A589B79E0B64DB63F971C6C06103696A359338034A1FB53E0B601FCBDB8CB6BE8DA048C4D9CEA7EA4A458FA64A87B788543854D94977330FEBC9BB09855083ED12C13858DED10C17C19412C7AF9412F4FE952322D80FC9B26842B1FE1859E670FB047390669D81225409853A3E3CCEE979D1120F4F3D833C49A7F8EA673FA68ACB33FFFC3B56A3F277D237F566F5A342C79B3E40EBEBD6E570B1AED4845B353995C7B758CFD4875A799F652122648618AC29D583E04D772FB6739F69D5E4DBFF2BD7B3468729E1ED90C9C523C36912B2EBC69199A5E7D0982867536275332B62C1AD6F07F1825BE66CDC5C99427268B6D1E754A90AF36F49C136E40455866B92FBEF1A298C3A3EFDB6F0F459F5E885D2C0B74C4C7347430AAD7EF86BFA21F8D38CAC911171802D645A73B5249334E26B804F47A012DE0FE1CF4745F33A4A5882DCA984E253E6B16B9A8A15541F65270BFB61A64EFE9BDBBFE4205B1F4FFF5FD75EF15D17F3CBB89651E88866A2AD67D0BD7B21B4495406B0F7A083AB155D37497CC81E4F360F39DF5A26C40662176ACB041805614DD761C619282E2719C29693050058E6FA82FF4237E86A408ADB3DDC5ADC0D770B3E5D1861B669FCEB53D432A5928AB547040CF2044B3164573AE36C52DE160C2F34B0FC18B1C5E53DE1ACF886086064AAE3566D2AC9E00EFED873A201F0D14FC0DFDCF40ED380E12F9CD3D65F944D888D1FFB0F0ADF56CDCBC3036FBA03AB05944D37F24917DF3E18B9EE06B1AFDB385FBBC9425D414849B0FE0BF8D101669341EA388B899ECA0BC7FF46200CC64E0A8480C9B55E71D2A3AAB11FB5D9E2278016E8BCE6901A87B8D993F8AEE78698D6FD13D2E26873F3DA86F0983AB151E921C0A0308ECA824E32FBBF2E8F1BC4E0BEC0013BA6B89BB61F495FAAB142B782BC59FB4B15EBD4DF155A56B07F7E64C4732DB1BF21E03DD68DACABB778E97C74380E7BB47CD0BD7B
-20200310180600 2 6 100 7679 2 F9B9E3DF0669078220C98F6E1775CAE12B5D95EF20D9491DDDFC0DFBA8EE09FD43F58BA934B719A06ECFF9646CA90998726E6FBDC6DB663F3BE44CF10A44B9D2DD7B01682B867206E6A67FE77170050860206AE5980778EA44104698A52D4D57D2AE0B98826DD3E98CB26E3CF0F044546CA7A97505E68983B439E27EE64AAB26D9FAB324CBADE29FBF733AF761D5CBA8E15D906F992080A1A725D65DD85CCDF0B00CCD5D44952C7D46CC514F6D34DD225F26B5CCFB2EB26077A854C19585DD40F4373FE41626532D4753C3617395FDF26FAAE36A6BD0D9009A7F9086AE9B150BD4712B4672ABACF3EC652B972885D8C6C858C93FA42B72E48EFB055E25828CF6FBF609BA25A589B79E0B64DB63F971C6C06103696A359338034A1FB53E0B601FCBDB8CB6BE8DA048C4D9CEA7EA4A458FA64A87B788543854D94977330FEBC9BB09855083ED12C13858DED10C17C19412C7AF9412F4FE952322D80FC9B26842B1FE1859E670FB047390669D81225409853A3E3CCEE979D1120F4F3D833C49A7F8EA673FA68ACB33FFFC3B56A3F277D237F566F5A342C79B3E40EBEBD6E570B1AED4845B353995C7B758CFD4875A799F652122648618AC29D583E04D772FB6739F69D5E4DBFF2BD7B3468729E1ED90C9C523C36912B2EBC69199A5E7D0982867536275332B62C1AD6F07F1825BE66CDC5C99427268B6D1E754A90AF36F49C136E40455866B92FBEF1A298C3A3EFDB6F0F459F5E885D2C0B74C4C7347430AAD7EF86BFA21F8D38CAC911171802D645A73B5249334E26B804F47A012DE0FE1CF4745F33A4A5882DCA984E253E6B16B9A8A15541F65270BFB61A64EFE9BDBBFE4205B1F4FFF5FD75EF15D17F3CBB89651E88866A2AD67D0BD7B21B4495406B0F7A083AB155D37497CC81E4F360F39DF5A26C40662176ACB041805614DD761C619282E2719C29693050058E6FA82FF4237E86A408ADB3DDC5ADC0D770B3E5D1861B669FCEB53D432A5928AB547040CF2044B3164573AE36C52DE160C2F34B0FC18B1C5E53DE1ACF886086064AAE3566D2AC9E00EFED873A201F0D14FC0DFDCF40ED380E12F9CD3D65F944D888D1FFB0F0ADF56CDCBC3036FBA03AB05944D37F24917DF3E18B9EE06B1AFDB385FBBC9425D414849B0FE0BF8D101669341EA388B899ECA0BC7FF46200CC64E0A8480C9B55E71D2A3AAB11FB5D9E2278016E8BCE6901A87B8D993F8AEE78698D6FD13D2E26873F3DA86F0983AB151E921C0A0308ECA824E32FBBF2E8F1BC4E0BEC0013BA6B89BB61F495FAAB142B782BC59FB4B15EBD4DF155A56B07F7E64C4732DB1BF21E03DD68DACABB778E97C74380E7BB481D17503
-20200311015151 2 6 100 7679 2 F9B9E3DF0669078220C98F6E1775CAE12B5D95EF20D9491DDDFC0DFBA8EE09FD43F58BA934B719A06ECFF9646CA90998726E6FBDC6DB663F3BE44CF10A44B9D2DD7B01682B867206E6A67FE77170050860206AE5980778EA44104698A52D4D57D2AE0B98826DD3E98CB26E3CF0F044546CA7A97505E68983B439E27EE64AAB26D9FAB324CBADE29FBF733AF761D5CBA8E15D906F992080A1A725D65DD85CCDF0B00CCD5D44952C7D46CC514F6D34DD225F26B5CCFB2EB26077A854C19585DD40F4373FE41626532D4753C3617395FDF26FAAE36A6BD0D9009A7F9086AE9B150BD4712B4672ABACF3EC652B972885D8C6C858C93FA42B72E48EFB055E25828CF6FBF609BA25A589B79E0B64DB63F971C6C06103696A359338034A1FB53E0B601FCBDB8CB6BE8DA048C4D9CEA7EA4A458FA64A87B788543854D94977330FEBC9BB09855083ED12C13858DED10C17C19412C7AF9412F4FE952322D80FC9B26842B1FE1859E670FB047390669D81225409853A3E3CCEE979D1120F4F3D833C49A7F8EA673FA68ACB33FFFC3B56A3F277D237F566F5A342C79B3E40EBEBD6E570B1AED4845B353995C7B758CFD4875A799F652122648618AC29D583E04D772FB6739F69D5E4DBFF2BD7B3468729E1ED90C9C523C36912B2EBC69199A5E7D0982867536275332B62C1AD6F07F1825BE66CDC5C99427268B6D1E754A90AF36F49C136E40455866B92FBEF1A298C3A3EFDB6F0F459F5E885D2C0B74C4C7347430AAD7EF86BFA21F8D38CAC911171802D645A73B5249334E26B804F47A012DE0FE1CF4745F33A4A5882DCA984E253E6B16B9A8A15541F65270BFB61A64EFE9BDBBFE4205B1F4FFF5FD75EF15D17F3CBB89651E88866A2AD67D0BD7B21B4495406B0F7A083AB155D37497CC81E4F360F39DF5A26C40662176ACB041805614DD761C619282E2719C29693050058E6FA82FF4237E86A408ADB3DDC5ADC0D770B3E5D1861B669FCEB53D432A5928AB547040CF2044B3164573AE36C52DE160C2F34B0FC18B1C5E53DE1ACF886086064AAE3566D2AC9E00EFED873A201F0D14FC0DFDCF40ED380E12F9CD3D65F944D888D1FFB0F0ADF56CDCBC3036FBA03AB05944D37F24917DF3E18B9EE06B1AFDB385FBBC9425D414849B0FE0BF8D101669341EA388B899ECA0BC7FF46200CC64E0A8480C9B55E71D2A3AAB11FB5D9E2278016E8BCE6901A87B8D993F8AEE78698D6FD13D2E26873F3DA86F0983AB151E921C0A0308ECA824E32FBBF2E8F1BC4E0BEC0013BA6B89BB61F495FAAB142B782BC59FB4B15EBD4DF155A56B07F7E64C4732DB1BF21E03DD68DACABB778E97C74380E7BB486E03C8B
-20200311023932 2 6 100 7679 5 F9B9E3DF0669078220C98F6E1775CAE12B5D95EF20D9491DDDFC0DFBA8EE09FD43F58BA934B719A06ECFF9646CA90998726E6FBDC6DB663F3BE44CF10A44B9D2DD7B01682B867206E6A67FE77170050860206AE5980778EA44104698A52D4D57D2AE0B98826DD3E98CB26E3CF0F044546CA7A97505E68983B439E27EE64AAB26D9FAB324CBADE29FBF733AF761D5CBA8E15D906F992080A1A725D65DD85CCDF0B00CCD5D44952C7D46CC514F6D34DD225F26B5CCFB2EB26077A854C19585DD40F4373FE41626532D4753C3617395FDF26FAAE36A6BD0D9009A7F9086AE9B150BD4712B4672ABACF3EC652B972885D8C6C858C93FA42B72E48EFB055E25828CF6FBF609BA25A589B79E0B64DB63F971C6C06103696A359338034A1FB53E0B601FCBDB8CB6BE8DA048C4D9CEA7EA4A458FA64A87B788543854D94977330FEBC9BB09855083ED12C13858DED10C17C19412C7AF9412F4FE952322D80FC9B26842B1FE1859E670FB047390669D81225409853A3E3CCEE979D1120F4F3D833C49A7F8EA673FA68ACB33FFFC3B56A3F277D237F566F5A342C79B3E40EBEBD6E570B1AED4845B353995C7B758CFD4875A799F652122648618AC29D583E04D772FB6739F69D5E4DBFF2BD7B3468729E1ED90C9C523C36912B2EBC69199A5E7D0982867536275332B62C1AD6F07F1825BE66CDC5C99427268B6D1E754A90AF36F49C136E40455866B92FBEF1A298C3A3EFDB6F0F459F5E885D2C0B74C4C7347430AAD7EF86BFA21F8D38CAC911171802D645A73B5249334E26B804F47A012DE0FE1CF4745F33A4A5882DCA984E253E6B16B9A8A15541F65270BFB61A64EFE9BDBBFE4205B1F4FFF5FD75EF15D17F3CBB89651E88866A2AD67D0BD7B21B4495406B0F7A083AB155D37497CC81E4F360F39DF5A26C40662176ACB041805614DD761C619282E2719C29693050058E6FA82FF4237E86A408ADB3DDC5ADC0D770B3E5D1861B669FCEB53D432A5928AB547040CF2044B3164573AE36C52DE160C2F34B0FC18B1C5E53DE1ACF886086064AAE3566D2AC9E00EFED873A201F0D14FC0DFDCF40ED380E12F9CD3D65F944D888D1FFB0F0ADF56CDCBC3036FBA03AB05944D37F24917DF3E18B9EE06B1AFDB385FBBC9425D414849B0FE0BF8D101669341EA388B899ECA0BC7FF46200CC64E0A8480C9B55E71D2A3AAB11FB5D9E2278016E8BCE6901A87B8D993F8AEE78698D6FD13D2E26873F3DA86F0983AB151E921C0A0308ECA824E32FBBF2E8F1BC4E0BEC0013BA6B89BB61F495FAAB142B782BC59FB4B15EBD4DF155A56B07F7E64C4732DB1BF21E03DD68DACABB778E97C74380E7BB487717827
-20200311110336 2 6 100 7679 2 F9B9E3DF0669078220C98F6E1775CAE12B5D95EF20D9491DDDFC0DFBA8EE09FD43F58BA934B719A06ECFF9646CA90998726E6FBDC6DB663F3BE44CF10A44B9D2DD7B01682B867206E6A67FE77170050860206AE5980778EA44104698A52D4D57D2AE0B98826DD3E98CB26E3CF0F044546CA7A97505E68983B439E27EE64AAB26D9FAB324CBADE29FBF733AF761D5CBA8E15D906F992080A1A725D65DD85CCDF0B00CCD5D44952C7D46CC514F6D34DD225F26B5CCFB2EB26077A854C19585DD40F4373FE41626532D4753C3617395FDF26FAAE36A6BD0D9009A7F9086AE9B150BD4712B4672ABACF3EC652B972885D8C6C858C93FA42B72E48EFB055E25828CF6FBF609BA25A589B79E0B64DB63F971C6C06103696A359338034A1FB53E0B601FCBDB8CB6BE8DA048C4D9CEA7EA4A458FA64A87B788543854D94977330FEBC9BB09855083ED12C13858DED10C17C19412C7AF9412F4FE952322D80FC9B26842B1FE1859E670FB047390669D81225409853A3E3CCEE979D1120F4F3D833C49A7F8EA673FA68ACB33FFFC3B56A3F277D237F566F5A342C79B3E40EBEBD6E570B1AED4845B353995C7B758CFD4875A799F652122648618AC29D583E04D772FB6739F69D5E4DBFF2BD7B3468729E1ED90C9C523C36912B2EBC69199A5E7D0982867536275332B62C1AD6F07F1825BE66CDC5C99427268B6D1E754A90AF36F49C136E40455866B92FBEF1A298C3A3EFDB6F0F459F5E885D2C0B74C4C7347430AAD7EF86BFA21F8D38CAC911171802D645A73B5249334E26B804F47A012DE0FE1CF4745F33A4A5882DCA984E253E6B16B9A8A15541F65270BFB61A64EFE9BDBBFE4205B1F4FFF5FD75EF15D17F3CBB89651E88866A2AD67D0BD7B21B4495406B0F7A083AB155D37497CC81E4F360F39DF5A26C40662176ACB041805614DD761C619282E2719C29693050058E6FA82FF4237E86A408ADB3DDC5ADC0D770B3E5D1861B669FCEB53D432A5928AB547040CF2044B3164573AE36C52DE160C2F34B0FC18B1C5E53DE1ACF886086064AAE3566D2AC9E00EFED873A201F0D14FC0DFDCF40ED380E12F9CD3D65F944D888D1FFB0F0ADF56CDCBC3036FBA03AB05944D37F24917DF3E18B9EE06B1AFDB385FBBC9425D414849B0FE0BF8D101669341EA388B899ECA0BC7FF46200CC64E0A8480C9B55E71D2A3AAB11FB5D9E2278016E8BCE6901A87B8D993F8AEE78698D6FD13D2E26873F3DA86F0983AB151E921C0A0308ECA824E32FBBF2E8F1BC4E0BEC0013BA6B89BB61F495FAAB142B782BC59FB4B15EBD4DF155A56B07F7E64C4732DB1BF21E03DD68DACABB778E97C74380E7BB48D9BBC13
-20200311182436 2 6 100 7679 2 F9B9E3DF0669078220C98F6E1775CAE12B5D95EF20D9491DDDFC0DFBA8EE09FD43F58BA934B719A06ECFF9646CA90998726E6FBDC6DB663F3BE44CF10A44B9D2DD7B01682B867206E6A67FE77170050860206AE5980778EA44104698A52D4D57D2AE0B98826DD3E98CB26E3CF0F044546CA7A97505E68983B439E27EE64AAB26D9FAB324CBADE29FBF733AF761D5CBA8E15D906F992080A1A725D65DD85CCDF0B00CCD5D44952C7D46CC514F6D34DD225F26B5CCFB2EB26077A854C19585DD40F4373FE41626532D4753C3617395FDF26FAAE36A6BD0D9009A7F9086AE9B150BD4712B4672ABACF3EC652B972885D8C6C858C93FA42B72E48EFB055E25828CF6FBF609BA25A589B79E0B64DB63F971C6C06103696A359338034A1FB53E0B601FCBDB8CB6BE8DA048C4D9CEA7EA4A458FA64A87B788543854D94977330FEBC9BB09855083ED12C13858DED10C17C19412C7AF9412F4FE952322D80FC9B26842B1FE1859E670FB047390669D81225409853A3E3CCEE979D1120F4F3D833C49A7F8EA673FA68ACB33FFFC3B56A3F277D237F566F5A342C79B3E40EBEBD6E570B1AED4845B353995C7B758CFD4875A799F652122648618AC29D583E04D772FB6739F69D5E4DBFF2BD7B3468729E1ED90C9C523C36912B2EBC69199A5E7D0982867536275332B62C1AD6F07F1825BE66CDC5C99427268B6D1E754A90AF36F49C136E40455866B92FBEF1A298C3A3EFDB6F0F459F5E885D2C0B74C4C7347430AAD7EF86BFA21F8D38CAC911171802D645A73B5249334E26B804F47A012DE0FE1CF4745F33A4A5882DCA984E253E6B16B9A8A15541F65270BFB61A64EFE9BDBBFE4205B1F4FFF5FD75EF15D17F3CBB89651E88866A2AD67D0BD7B21B4495406B0F7A083AB155D37497CC81E4F360F39DF5A26C40662176ACB041805614DD761C619282E2719C29693050058E6FA82FF4237E86A408ADB3DDC5ADC0D770B3E5D1861B669FCEB53D432A5928AB547040CF2044B3164573AE36C52DE160C2F34B0FC18B1C5E53DE1ACF886086064AAE3566D2AC9E00EFED873A201F0D14FC0DFDCF40ED380E12F9CD3D65F944D888D1FFB0F0ADF56CDCBC3036FBA03AB05944D37F24917DF3E18B9EE06B1AFDB385FBBC9425D414849B0FE0BF8D101669341EA388B899ECA0BC7FF46200CC64E0A8480C9B55E71D2A3AAB11FB5D9E2278016E8BCE6901A87B8D993F8AEE78698D6FD13D2E26873F3DA86F0983AB151E921C0A0308ECA824E32FBBF2E8F1BC4E0BEC0013BA6B89BB61F495FAAB142B782BC59FB4B15EBD4DF155A56B07F7E64C4732DB1BF21E03DD68DACABB778E97C74380E7BB492FC11BB
-20200312191341 2 6 100 7679 5 F9B9E3DF0669078220C98F6E1775CAE12B5D95EF20D9491DDDFC0DFBA8EE09FD43F58BA934B719A06ECFF9646CA90998726E6FBDC6DB663F3BE44CF10A44B9D2DD7B01682B867206E6A67FE77170050860206AE5980778EA44104698A52D4D57D2AE0B98826DD3E98CB26E3CF0F044546CA7A97505E68983B439E27EE64AAB26D9FAB324CBADE29FBF733AF761D5CBA8E15D906F992080A1A725D65DD85CCDF0B00CCD5D44952C7D46CC514F6D34DD225F26B5CCFB2EB26077A854C19585DD40F4373FE41626532D4753C3617395FDF26FAAE36A6BD0D9009A7F9086AE9B150BD4712B4672ABACF3EC652B972885D8C6C858C93FA42B72E48EFB055E25828CF6FBF609BA25A589B79E0B64DB63F971C6C06103696A359338034A1FB53E0B601FCBDB8CB6BE8DA048C4D9CEA7EA4A458FA64A87B788543854D94977330FEBC9BB09855083ED12C13858DED10C17C19412C7AF9412F4FE952322D80FC9B26842B1FE1859E670FB047390669D81225409853A3E3CCEE979D1120F4F3D833C49A7F8EA673FA68ACB33FFFC3B56A3F277D237F566F5A342C79B3E40EBEBD6E570B1AED4845B353995C7B758CFD4875A799F652122648618AC29D583E04D772FB6739F69D5E4DBFF2BD7B3468729E1ED90C9C523C36912B2EBC69199A5E7D0982867536275332B62C1AD6F07F1825BE66CDC5C99427268B6D1E754A90AF36F49C136E40455866B92FBEF1A298C3A3EFDB6F0F459F5E885D2C0B74C4C7347430AAD7EF86BFA21F8D38CAC911171802D645A73B5249334E26B804F47A012DE0FE1CF4745F33A4A5882DCA984E253E6B16B9A8A15541F65270BFB61A64EFE9BDBBFE4205B1F4FFF5FD75EF15D17F3CBB89651E88866A2AD67D0BD7B21B4495406B0F7A083AB155D37497CC81E4F360F39DF5A26C40662176ACB041805614DD761C619282E2719C29693050058E6FA82FF4237E86A408ADB3DDC5ADC0D770B3E5D1861B669FCEB53D432A5928AB547040CF2044B3164573AE36C52DE160C2F34B0FC18B1C5E53DE1ACF886086064AAE3566D2AC9E00EFED873A201F0D14FC0DFDCF40ED380E12F9CD3D65F944D888D1FFB0F0ADF56CDCBC3036FBA03AB05944D37F24917DF3E18B9EE06B1AFDB385FBBC9425D414849B0FE0BF8D101669341EA388B899ECA0BC7FF46200CC64E0A8480C9B55E71D2A3AAB11FB5D9E2278016E8BCE6901A87B8D993F8AEE78698D6FD13D2E26873F3DA86F0983AB151E921C0A0308ECA824E32FBBF2E8F1BC4E0BEC0013BA6B89BB61F495FAAB142B782BC59FB4B15EBD4DF155A56B07F7E64C4732DB1BF21E03DD68DACABB778E97C74380E7BB4A4A6DB8F
-20200312210435 2 6 100 7679 5 F9B9E3DF0669078220C98F6E1775CAE12B5D95EF20D9491DDDFC0DFBA8EE09FD43F58BA934B719A06ECFF9646CA90998726E6FBDC6DB663F3BE44CF10A44B9D2DD7B01682B867206E6A67FE77170050860206AE5980778EA44104698A52D4D57D2AE0B98826DD3E98CB26E3CF0F044546CA7A97505E68983B439E27EE64AAB26D9FAB324CBADE29FBF733AF761D5CBA8E15D906F992080A1A725D65DD85CCDF0B00CCD5D44952C7D46CC514F6D34DD225F26B5CCFB2EB26077A854C19585DD40F4373FE41626532D4753C3617395FDF26FAAE36A6BD0D9009A7F9086AE9B150BD4712B4672ABACF3EC652B972885D8C6C858C93FA42B72E48EFB055E25828CF6FBF609BA25A589B79E0B64DB63F971C6C06103696A359338034A1FB53E0B601FCBDB8CB6BE8DA048C4D9CEA7EA4A458FA64A87B788543854D94977330FEBC9BB09855083ED12C13858DED10C17C19412C7AF9412F4FE952322D80FC9B26842B1FE1859E670FB047390669D81225409853A3E3CCEE979D1120F4F3D833C49A7F8EA673FA68ACB33FFFC3B56A3F277D237F566F5A342C79B3E40EBEBD6E570B1AED4845B353995C7B758CFD4875A799F652122648618AC29D583E04D772FB6739F69D5E4DBFF2BD7B3468729E1ED90C9C523C36912B2EBC69199A5E7D0982867536275332B62C1AD6F07F1825BE66CDC5C99427268B6D1E754A90AF36F49C136E40455866B92FBEF1A298C3A3EFDB6F0F459F5E885D2C0B74C4C7347430AAD7EF86BFA21F8D38CAC911171802D645A73B5249334E26B804F47A012DE0FE1CF4745F33A4A5882DCA984E253E6B16B9A8A15541F65270BFB61A64EFE9BDBBFE4205B1F4FFF5FD75EF15D17F3CBB89651E88866A2AD67D0BD7B21B4495406B0F7A083AB155D37497CC81E4F360F39DF5A26C40662176ACB041805614DD761C619282E2719C29693050058E6FA82FF4237E86A408ADB3DDC5ADC0D770B3E5D1861B669FCEB53D432A5928AB547040CF2044B3164573AE36C52DE160C2F34B0FC18B1C5E53DE1ACF886086064AAE3566D2AC9E00EFED873A201F0D14FC0DFDCF40ED380E12F9CD3D65F944D888D1FFB0F0ADF56CDCBC3036FBA03AB05944D37F24917DF3E18B9EE06B1AFDB385FBBC9425D414849B0FE0BF8D101669341EA388B899ECA0BC7FF46200CC64E0A8480C9B55E71D2A3AAB11FB5D9E2278016E8BCE6901A87B8D993F8AEE78698D6FD13D2E26873F3DA86F0983AB151E921C0A0308ECA824E32FBBF2E8F1BC4E0BEC0013BA6B89BB61F495FAAB142B782BC59FB4B15EBD4DF155A56B07F7E64C4732DB1BF21E03DD68DACABB778E97C74380E7BB4A5F07D3F
-20200313061025 2 6 100 7679 2 F9B9E3DF0669078220C98F6E1775CAE12B5D95EF20D9491DDDFC0DFBA8EE09FD43F58BA934B719A06ECFF9646CA90998726E6FBDC6DB663F3BE44CF10A44B9D2DD7B01682B867206E6A67FE77170050860206AE5980778EA44104698A52D4D57D2AE0B98826DD3E98CB26E3CF0F044546CA7A97505E68983B439E27EE64AAB26D9FAB324CBADE29FBF733AF761D5CBA8E15D906F992080A1A725D65DD85CCDF0B00CCD5D44952C7D46CC514F6D34DD225F26B5CCFB2EB26077A854C19585DD40F4373FE41626532D4753C3617395FDF26FAAE36A6BD0D9009A7F9086AE9B150BD4712B4672ABACF3EC652B972885D8C6C858C93FA42B72E48EFB055E25828CF6FBF609BA25A589B79E0B64DB63F971C6C06103696A359338034A1FB53E0B601FCBDB8CB6BE8DA048C4D9CEA7EA4A458FA64A87B788543854D94977330FEBC9BB09855083ED12C13858DED10C17C19412C7AF9412F4FE952322D80FC9B26842B1FE1859E670FB047390669D81225409853A3E3CCEE979D1120F4F3D833C49A7F8EA673FA68ACB33FFFC3B56A3F277D237F566F5A342C79B3E40EBEBD6E570B1AED4845B353995C7B758CFD4875A799F652122648618AC29D583E04D772FB6739F69D5E4DBFF2BD7B3468729E1ED90C9C523C36912B2EBC69199A5E7D0982867536275332B62C1AD6F07F1825BE66CDC5C99427268B6D1E754A90AF36F49C136E40455866B92FBEF1A298C3A3EFDB6F0F459F5E885D2C0B74C4C7347430AAD7EF86BFA21F8D38CAC911171802D645A73B5249334E26B804F47A012DE0FE1CF4745F33A4A5882DCA984E253E6B16B9A8A15541F65270BFB61A64EFE9BDBBFE4205B1F4FFF5FD75EF15D17F3CBB89651E88866A2AD67D0BD7B21B4495406B0F7A083AB155D37497CC81E4F360F39DF5A26C40662176ACB041805614DD761C619282E2719C29693050058E6FA82FF4237E86A408ADB3DDC5ADC0D770B3E5D1861B669FCEB53D432A5928AB547040CF2044B3164573AE36C52DE160C2F34B0FC18B1C5E53DE1ACF886086064AAE3566D2AC9E00EFED873A201F0D14FC0DFDCF40ED380E12F9CD3D65F944D888D1FFB0F0ADF56CDCBC3036FBA03AB05944D37F24917DF3E18B9EE06B1AFDB385FBBC9425D414849B0FE0BF8D101669341EA388B899ECA0BC7FF46200CC64E0A8480C9B55E71D2A3AAB11FB5D9E2278016E8BCE6901A87B8D993F8AEE78698D6FD13D2E26873F3DA86F0983AB151E921C0A0308ECA824E32FBBF2E8F1BC4E0BEC0013BA6B89BB61F495FAAB142B782BC59FB4B15EBD4DF155A56B07F7E64C4732DB1BF21E03DD68DACABB778E97C74380E7BB4AA98C3EB
-20200313104943 2 6 100 7679 2 F9B9E3DF0669078220C98F6E1775CAE12B5D95EF20D9491DDDFC0DFBA8EE09FD43F58BA934B719A06ECFF9646CA90998726E6FBDC6DB663F3BE44CF10A44B9D2DD7B01682B867206E6A67FE77170050860206AE5980778EA44104698A52D4D57D2AE0B98826DD3E98CB26E3CF0F044546CA7A97505E68983B439E27EE64AAB26D9FAB324CBADE29FBF733AF761D5CBA8E15D906F992080A1A725D65DD85CCDF0B00CCD5D44952C7D46CC514F6D34DD225F26B5CCFB2EB26077A854C19585DD40F4373FE41626532D4753C3617395FDF26FAAE36A6BD0D9009A7F9086AE9B150BD4712B4672ABACF3EC652B972885D8C6C858C93FA42B72E48EFB055E25828CF6FBF609BA25A589B79E0B64DB63F971C6C06103696A359338034A1FB53E0B601FCBDB8CB6BE8DA048C4D9CEA7EA4A458FA64A87B788543854D94977330FEBC9BB09855083ED12C13858DED10C17C19412C7AF9412F4FE952322D80FC9B26842B1FE1859E670FB047390669D81225409853A3E3CCEE979D1120F4F3D833C49A7F8EA673FA68ACB33FFFC3B56A3F277D237F566F5A342C79B3E40EBEBD6E570B1AED4845B353995C7B758CFD4875A799F652122648618AC29D583E04D772FB6739F69D5E4DBFF2BD7B3468729E1ED90C9C523C36912B2EBC69199A5E7D0982867536275332B62C1AD6F07F1825BE66CDC5C99427268B6D1E754A90AF36F49C136E40455866B92FBEF1A298C3A3EFDB6F0F459F5E885D2C0B74C4C7347430AAD7EF86BFA21F8D38CAC911171802D645A73B5249334E26B804F47A012DE0FE1CF4745F33A4A5882DCA984E253E6B16B9A8A15541F65270BFB61A64EFE9BDBBFE4205B1F4FFF5FD75EF15D17F3CBB89651E88866A2AD67D0BD7B21B4495406B0F7A083AB155D37497CC81E4F360F39DF5A26C40662176ACB041805614DD761C619282E2719C29693050058E6FA82FF4237E86A408ADB3DDC5ADC0D770B3E5D1861B669FCEB53D432A5928AB547040CF2044B3164573AE36C52DE160C2F34B0FC18B1C5E53DE1ACF886086064AAE3566D2AC9E00EFED873A201F0D14FC0DFDCF40ED380E12F9CD3D65F944D888D1FFB0F0ADF56CDCBC3036FBA03AB05944D37F24917DF3E18B9EE06B1AFDB385FBBC9425D414849B0FE0BF8D101669341EA388B899ECA0BC7FF46200CC64E0A8480C9B55E71D2A3AAB11FB5D9E2278016E8BCE6901A87B8D993F8AEE78698D6FD13D2E26873F3DA86F0983AB151E921C0A0308ECA824E32FBBF2E8F1BC4E0BEC0013BA6B89BB61F495FAAB142B782BC59FB4B15EBD4DF155A56B07F7E64C4732DB1BF21E03DD68DACABB778E97C74380E7BB4ABB58143
-20200313131537 2 6 100 7679 2 F9B9E3DF0669078220C98F6E1775CAE12B5D95EF20D9491DDDFC0DFBA8EE09FD43F58BA934B719A06ECFF9646CA90998726E6FBDC6DB663F3BE44CF10A44B9D2DD7B01682B867206E6A67FE77170050860206AE5980778EA44104698A52D4D57D2AE0B98826DD3E98CB26E3CF0F044546CA7A97505E68983B439E27EE64AAB26D9FAB324CBADE29FBF733AF761D5CBA8E15D906F992080A1A725D65DD85CCDF0B00CCD5D44952C7D46CC514F6D34DD225F26B5CCFB2EB26077A854C19585DD40F4373FE41626532D4753C3617395FDF26FAAE36A6BD0D9009A7F9086AE9B150BD4712B4672ABACF3EC652B972885D8C6C858C93FA42B72E48EFB055E25828CF6FBF609BA25A589B79E0B64DB63F971C6C06103696A359338034A1FB53E0B601FCBDB8CB6BE8DA048C4D9CEA7EA4A458FA64A87B788543854D94977330FEBC9BB09855083ED12C13858DED10C17C19412C7AF9412F4FE952322D80FC9B26842B1FE1859E670FB047390669D81225409853A3E3CCEE979D1120F4F3D833C49A7F8EA673FA68ACB33FFFC3B56A3F277D237F566F5A342C79B3E40EBEBD6E570B1AED4845B353995C7B758CFD4875A799F652122648618AC29D583E04D772FB6739F69D5E4DBFF2BD7B3468729E1ED90C9C523C36912B2EBC69199A5E7D0982867536275332B62C1AD6F07F1825BE66CDC5C99427268B6D1E754A90AF36F49C136E40455866B92FBEF1A298C3A3EFDB6F0F459F5E885D2C0B74C4C7347430AAD7EF86BFA21F8D38CAC911171802D645A73B5249334E26B804F47A012DE0FE1CF4745F33A4A5882DCA984E253E6B16B9A8A15541F65270BFB61A64EFE9BDBBFE4205B1F4FFF5FD75EF15D17F3CBB89651E88866A2AD67D0BD7B21B4495406B0F7A083AB155D37497CC81E4F360F39DF5A26C40662176ACB041805614DD761C619282E2719C29693050058E6FA82FF4237E86A408ADB3DDC5ADC0D770B3E5D1861B669FCEB53D432A5928AB547040CF2044B3164573AE36C52DE160C2F34B0FC18B1C5E53DE1ACF886086064AAE3566D2AC9E00EFED873A201F0D14FC0DFDCF40ED380E12F9CD3D65F944D888D1FFB0F0ADF56CDCBC3036FBA03AB05944D37F24917DF3E18B9EE06B1AFDB385FBBC9425D414849B0FE0BF8D101669341EA388B899ECA0BC7FF46200CC64E0A8480C9B55E71D2A3AAB11FB5D9E2278016E8BCE6901A87B8D993F8AEE78698D6FD13D2E26873F3DA86F0983AB151E921C0A0308ECA824E32FBBF2E8F1BC4E0BEC0013BA6B89BB61F495FAAB142B782BC59FB4B15EBD4DF155A56B07F7E64C4732DB1BF21E03DD68DACABB778E97C74380E7BB4ACFC1F93
-20200313162830 2 6 100 7679 2 F9B9E3DF0669078220C98F6E1775CAE12B5D95EF20D9491DDDFC0DFBA8EE09FD43F58BA934B719A06ECFF9646CA90998726E6FBDC6DB663F3BE44CF10A44B9D2DD7B01682B867206E6A67FE77170050860206AE5980778EA44104698A52D4D57D2AE0B98826DD3E98CB26E3CF0F044546CA7A97505E68983B439E27EE64AAB26D9FAB324CBADE29FBF733AF761D5CBA8E15D906F992080A1A725D65DD85CCDF0B00CCD5D44952C7D46CC514F6D34DD225F26B5CCFB2EB26077A854C19585DD40F4373FE41626532D4753C3617395FDF26FAAE36A6BD0D9009A7F9086AE9B150BD4712B4672ABACF3EC652B972885D8C6C858C93FA42B72E48EFB055E25828CF6FBF609BA25A589B79E0B64DB63F971C6C06103696A359338034A1FB53E0B601FCBDB8CB6BE8DA048C4D9CEA7EA4A458FA64A87B788543854D94977330FEBC9BB09855083ED12C13858DED10C17C19412C7AF9412F4FE952322D80FC9B26842B1FE1859E670FB047390669D81225409853A3E3CCEE979D1120F4F3D833C49A7F8EA673FA68ACB33FFFC3B56A3F277D237F566F5A342C79B3E40EBEBD6E570B1AED4845B353995C7B758CFD4875A799F652122648618AC29D583E04D772FB6739F69D5E4DBFF2BD7B3468729E1ED90C9C523C36912B2EBC69199A5E7D0982867536275332B62C1AD6F07F1825BE66CDC5C99427268B6D1E754A90AF36F49C136E40455866B92FBEF1A298C3A3EFDB6F0F459F5E885D2C0B74C4C7347430AAD7EF86BFA21F8D38CAC911171802D645A73B5249334E26B804F47A012DE0FE1CF4745F33A4A5882DCA984E253E6B16B9A8A15541F65270BFB61A64EFE9BDBBFE4205B1F4FFF5FD75EF15D17F3CBB89651E88866A2AD67D0BD7B21B4495406B0F7A083AB155D37497CC81E4F360F39DF5A26C40662176ACB041805614DD761C619282E2719C29693050058E6FA82FF4237E86A408ADB3DDC5ADC0D770B3E5D1861B669FCEB53D432A5928AB547040CF2044B3164573AE36C52DE160C2F34B0FC18B1C5E53DE1ACF886086064AAE3566D2AC9E00EFED873A201F0D14FC0DFDCF40ED380E12F9CD3D65F944D888D1FFB0F0ADF56CDCBC3036FBA03AB05944D37F24917DF3E18B9EE06B1AFDB385FBBC9425D414849B0FE0BF8D101669341EA388B899ECA0BC7FF46200CC64E0A8480C9B55E71D2A3AAB11FB5D9E2278016E8BCE6901A87B8D993F8AEE78698D6FD13D2E26873F3DA86F0983AB151E921C0A0308ECA824E32FBBF2E8F1BC4E0BEC0013BA6B89BB61F495FAAB142B782BC59FB4B15EBD4DF155A56B07F7E64C4732DB1BF21E03DD68DACABB778E97C74380E7BB4AEB1D103
-20200313193630 2 6 100 7679 5 F9B9E3DF0669078220C98F6E1775CAE12B5D95EF20D9491DDDFC0DFBA8EE09FD43F58BA934B719A06ECFF9646CA90998726E6FBDC6DB663F3BE44CF10A44B9D2DD7B01682B867206E6A67FE77170050860206AE5980778EA44104698A52D4D57D2AE0B98826DD3E98CB26E3CF0F044546CA7A97505E68983B439E27EE64AAB26D9FAB324CBADE29FBF733AF761D5CBA8E15D906F992080A1A725D65DD85CCDF0B00CCD5D44952C7D46CC514F6D34DD225F26B5CCFB2EB26077A854C19585DD40F4373FE41626532D4753C3617395FDF26FAAE36A6BD0D9009A7F9086AE9B150BD4712B4672ABACF3EC652B972885D8C6C858C93FA42B72E48EFB055E25828CF6FBF609BA25A589B79E0B64DB63F971C6C06103696A359338034A1FB53E0B601FCBDB8CB6BE8DA048C4D9CEA7EA4A458FA64A87B788543854D94977330FEBC9BB09855083ED12C13858DED10C17C19412C7AF9412F4FE952322D80FC9B26842B1FE1859E670FB047390669D81225409853A3E3CCEE979D1120F4F3D833C49A7F8EA673FA68ACB33FFFC3B56A3F277D237F566F5A342C79B3E40EBEBD6E570B1AED4845B353995C7B758CFD4875A799F652122648618AC29D583E04D772FB6739F69D5E4DBFF2BD7B3468729E1ED90C9C523C36912B2EBC69199A5E7D0982867536275332B62C1AD6F07F1825BE66CDC5C99427268B6D1E754A90AF36F49C136E40455866B92FBEF1A298C3A3EFDB6F0F459F5E885D2C0B74C4C7347430AAD7EF86BFA21F8D38CAC911171802D645A73B5249334E26B804F47A012DE0FE1CF4745F33A4A5882DCA984E253E6B16B9A8A15541F65270BFB61A64EFE9BDBBFE4205B1F4FFF5FD75EF15D17F3CBB89651E88866A2AD67D0BD7B21B4495406B0F7A083AB155D37497CC81E4F360F39DF5A26C40662176ACB041805614DD761C619282E2719C29693050058E6FA82FF4237E86A408ADB3DDC5ADC0D770B3E5D1861B669FCEB53D432A5928AB547040CF2044B3164573AE36C52DE160C2F34B0FC18B1C5E53DE1ACF886086064AAE3566D2AC9E00EFED873A201F0D14FC0DFDCF40ED380E12F9CD3D65F944D888D1FFB0F0ADF56CDCBC3036FBA03AB05944D37F24917DF3E18B9EE06B1AFDB385FBBC9425D414849B0FE0BF8D101669341EA388B899ECA0BC7FF46200CC64E0A8480C9B55E71D2A3AAB11FB5D9E2278016E8BCE6901A87B8D993F8AEE78698D6FD13D2E26873F3DA86F0983AB151E921C0A0308ECA824E32FBBF2E8F1BC4E0BEC0013BA6B89BB61F495FAAB142B782BC59FB4B15EBD4DF155A56B07F7E64C4732DB1BF21E03DD68DACABB778E97C74380E7BB4B0562167
-20200313204400 2 6 100 7679 5 F9B9E3DF0669078220C98F6E1775CAE12B5D95EF20D9491DDDFC0DFBA8EE09FD43F58BA934B719A06ECFF9646CA90998726E6FBDC6DB663F3BE44CF10A44B9D2DD7B01682B867206E6A67FE77170050860206AE5980778EA44104698A52D4D57D2AE0B98826DD3E98CB26E3CF0F044546CA7A97505E68983B439E27EE64AAB26D9FAB324CBADE29FBF733AF761D5CBA8E15D906F992080A1A725D65DD85CCDF0B00CCD5D44952C7D46CC514F6D34DD225F26B5CCFB2EB26077A854C19585DD40F4373FE41626532D4753C3617395FDF26FAAE36A6BD0D9009A7F9086AE9B150BD4712B4672ABACF3EC652B972885D8C6C858C93FA42B72E48EFB055E25828CF6FBF609BA25A589B79E0B64DB63F971C6C06103696A359338034A1FB53E0B601FCBDB8CB6BE8DA048C4D9CEA7EA4A458FA64A87B788543854D94977330FEBC9BB09855083ED12C13858DED10C17C19412C7AF9412F4FE952322D80FC9B26842B1FE1859E670FB047390669D81225409853A3E3CCEE979D1120F4F3D833C49A7F8EA673FA68ACB33FFFC3B56A3F277D237F566F5A342C79B3E40EBEBD6E570B1AED4845B353995C7B758CFD4875A799F652122648618AC29D583E04D772FB6739F69D5E4DBFF2BD7B3468729E1ED90C9C523C36912B2EBC69199A5E7D0982867536275332B62C1AD6F07F1825BE66CDC5C99427268B6D1E754A90AF36F49C136E40455866B92FBEF1A298C3A3EFDB6F0F459F5E885D2C0B74C4C7347430AAD7EF86BFA21F8D38CAC911171802D645A73B5249334E26B804F47A012DE0FE1CF4745F33A4A5882DCA984E253E6B16B9A8A15541F65270BFB61A64EFE9BDBBFE4205B1F4FFF5FD75EF15D17F3CBB89651E88866A2AD67D0BD7B21B4495406B0F7A083AB155D37497CC81E4F360F39DF5A26C40662176ACB041805614DD761C619282E2719C29693050058E6FA82FF4237E86A408ADB3DDC5ADC0D770B3E5D1861B669FCEB53D432A5928AB547040CF2044B3164573AE36C52DE160C2F34B0FC18B1C5E53DE1ACF886086064AAE3566D2AC9E00EFED873A201F0D14FC0DFDCF40ED380E12F9CD3D65F944D888D1FFB0F0ADF56CDCBC3036FBA03AB05944D37F24917DF3E18B9EE06B1AFDB385FBBC9425D414849B0FE0BF8D101669341EA388B899ECA0BC7FF46200CC64E0A8480C9B55E71D2A3AAB11FB5D9E2278016E8BCE6901A87B8D993F8AEE78698D6FD13D2E26873F3DA86F0983AB151E921C0A0308ECA824E32FBBF2E8F1BC4E0BEC0013BA6B89BB61F495FAAB142B782BC59FB4B15EBD4DF155A56B07F7E64C4732DB1BF21E03DD68DACABB778E97C74380E7BB4B0E7687F
-20200313205856 2 6 100 7679 2 F9B9E3DF0669078220C98F6E1775CAE12B5D95EF20D9491DDDFC0DFBA8EE09FD43F58BA934B719A06ECFF9646CA90998726E6FBDC6DB663F3BE44CF10A44B9D2DD7B01682B867206E6A67FE77170050860206AE5980778EA44104698A52D4D57D2AE0B98826DD3E98CB26E3CF0F044546CA7A97505E68983B439E27EE64AAB26D9FAB324CBADE29FBF733AF761D5CBA8E15D906F992080A1A725D65DD85CCDF0B00CCD5D44952C7D46CC514F6D34DD225F26B5CCFB2EB26077A854C19585DD40F4373FE41626532D4753C3617395FDF26FAAE36A6BD0D9009A7F9086AE9B150BD4712B4672ABACF3EC652B972885D8C6C858C93FA42B72E48EFB055E25828CF6FBF609BA25A589B79E0B64DB63F971C6C06103696A359338034A1FB53E0B601FCBDB8CB6BE8DA048C4D9CEA7EA4A458FA64A87B788543854D94977330FEBC9BB09855083ED12C13858DED10C17C19412C7AF9412F4FE952322D80FC9B26842B1FE1859E670FB047390669D81225409853A3E3CCEE979D1120F4F3D833C49A7F8EA673FA68ACB33FFFC3B56A3F277D237F566F5A342C79B3E40EBEBD6E570B1AED4845B353995C7B758CFD4875A799F652122648618AC29D583E04D772FB6739F69D5E4DBFF2BD7B3468729E1ED90C9C523C36912B2EBC69199A5E7D0982867536275332B62C1AD6F07F1825BE66CDC5C99427268B6D1E754A90AF36F49C136E40455866B92FBEF1A298C3A3EFDB6F0F459F5E885D2C0B74C4C7347430AAD7EF86BFA21F8D38CAC911171802D645A73B5249334E26B804F47A012DE0FE1CF4745F33A4A5882DCA984E253E6B16B9A8A15541F65270BFB61A64EFE9BDBBFE4205B1F4FFF5FD75EF15D17F3CBB89651E88866A2AD67D0BD7B21B4495406B0F7A083AB155D37497CC81E4F360F39DF5A26C40662176ACB041805614DD761C619282E2719C29693050058E6FA82FF4237E86A408ADB3DDC5ADC0D770B3E5D1861B669FCEB53D432A5928AB547040CF2044B3164573AE36C52DE160C2F34B0FC18B1C5E53DE1ACF886086064AAE3566D2AC9E00EFED873A201F0D14FC0DFDCF40ED380E12F9CD3D65F944D888D1FFB0F0ADF56CDCBC3036FBA03AB05944D37F24917DF3E18B9EE06B1AFDB385FBBC9425D414849B0FE0BF8D101669341EA388B899ECA0BC7FF46200CC64E0A8480C9B55E71D2A3AAB11FB5D9E2278016E8BCE6901A87B8D993F8AEE78698D6FD13D2E26873F3DA86F0983AB151E921C0A0308ECA824E32FBBF2E8F1BC4E0BEC0013BA6B89BB61F495FAAB142B782BC59FB4B15EBD4DF155A56B07F7E64C4732DB1BF21E03DD68DACABB778E97C74380E7BB4B100B58B
-20200314035540 2 6 100 7679 5 F9B9E3DF0669078220C98F6E1775CAE12B5D95EF20D9491DDDFC0DFBA8EE09FD43F58BA934B719A06ECFF9646CA90998726E6FBDC6DB663F3BE44CF10A44B9D2DD7B01682B867206E6A67FE77170050860206AE5980778EA44104698A52D4D57D2AE0B98826DD3E98CB26E3CF0F044546CA7A97505E68983B439E27EE64AAB26D9FAB324CBADE29FBF733AF761D5CBA8E15D906F992080A1A725D65DD85CCDF0B00CCD5D44952C7D46CC514F6D34DD225F26B5CCFB2EB26077A854C19585DD40F4373FE41626532D4753C3617395FDF26FAAE36A6BD0D9009A7F9086AE9B150BD4712B4672ABACF3EC652B972885D8C6C858C93FA42B72E48EFB055E25828CF6FBF609BA25A589B79E0B64DB63F971C6C06103696A359338034A1FB53E0B601FCBDB8CB6BE8DA048C4D9CEA7EA4A458FA64A87B788543854D94977330FEBC9BB09855083ED12C13858DED10C17C19412C7AF9412F4FE952322D80FC9B26842B1FE1859E670FB047390669D81225409853A3E3CCEE979D1120F4F3D833C49A7F8EA673FA68ACB33FFFC3B56A3F277D237F566F5A342C79B3E40EBEBD6E570B1AED4845B353995C7B758CFD4875A799F652122648618AC29D583E04D772FB6739F69D5E4DBFF2BD7B3468729E1ED90C9C523C36912B2EBC69199A5E7D0982867536275332B62C1AD6F07F1825BE66CDC5C99427268B6D1E754A90AF36F49C136E40455866B92FBEF1A298C3A3EFDB6F0F459F5E885D2C0B74C4C7347430AAD7EF86BFA21F8D38CAC911171802D645A73B5249334E26B804F47A012DE0FE1CF4745F33A4A5882DCA984E253E6B16B9A8A15541F65270BFB61A64EFE9BDBBFE4205B1F4FFF5FD75EF15D17F3CBB89651E88866A2AD67D0BD7B21B4495406B0F7A083AB155D37497CC81E4F360F39DF5A26C40662176ACB041805614DD761C619282E2719C29693050058E6FA82FF4237E86A408ADB3DDC5ADC0D770B3E5D1861B669FCEB53D432A5928AB547040CF2044B3164573AE36C52DE160C2F34B0FC18B1C5E53DE1ACF886086064AAE3566D2AC9E00EFED873A201F0D14FC0DFDCF40ED380E12F9CD3D65F944D888D1FFB0F0ADF56CDCBC3036FBA03AB05944D37F24917DF3E18B9EE06B1AFDB385FBBC9425D414849B0FE0BF8D101669341EA388B899ECA0BC7FF46200CC64E0A8480C9B55E71D2A3AAB11FB5D9E2278016E8BCE6901A87B8D993F8AEE78698D6FD13D2E26873F3DA86F0983AB151E921C0A0308ECA824E32FBBF2E8F1BC4E0BEC0013BA6B89BB61F495FAAB142B782BC59FB4B15EBD4DF155A56B07F7E64C4732DB1BF21E03DD68DACABB778E97C74380E7BB4B4AAAE3F
-20200314061326 2 6 100 7679 5 F9B9E3DF0669078220C98F6E1775CAE12B5D95EF20D9491DDDFC0DFBA8EE09FD43F58BA934B719A06ECFF9646CA90998726E6FBDC6DB663F3BE44CF10A44B9D2DD7B01682B867206E6A67FE77170050860206AE5980778EA44104698A52D4D57D2AE0B98826DD3E98CB26E3CF0F044546CA7A97505E68983B439E27EE64AAB26D9FAB324CBADE29FBF733AF761D5CBA8E15D906F992080A1A725D65DD85CCDF0B00CCD5D44952C7D46CC514F6D34DD225F26B5CCFB2EB26077A854C19585DD40F4373FE41626532D4753C3617395FDF26FAAE36A6BD0D9009A7F9086AE9B150BD4712B4672ABACF3EC652B972885D8C6C858C93FA42B72E48EFB055E25828CF6FBF609BA25A589B79E0B64DB63F971C6C06103696A359338034A1FB53E0B601FCBDB8CB6BE8DA048C4D9CEA7EA4A458FA64A87B788543854D94977330FEBC9BB09855083ED12C13858DED10C17C19412C7AF9412F4FE952322D80FC9B26842B1FE1859E670FB047390669D81225409853A3E3CCEE979D1120F4F3D833C49A7F8EA673FA68ACB33FFFC3B56A3F277D237F566F5A342C79B3E40EBEBD6E570B1AED4845B353995C7B758CFD4875A799F652122648618AC29D583E04D772FB6739F69D5E4DBFF2BD7B3468729E1ED90C9C523C36912B2EBC69199A5E7D0982867536275332B62C1AD6F07F1825BE66CDC5C99427268B6D1E754A90AF36F49C136E40455866B92FBEF1A298C3A3EFDB6F0F459F5E885D2C0B74C4C7347430AAD7EF86BFA21F8D38CAC911171802D645A73B5249334E26B804F47A012DE0FE1CF4745F33A4A5882DCA984E253E6B16B9A8A15541F65270BFB61A64EFE9BDBBFE4205B1F4FFF5FD75EF15D17F3CBB89651E88866A2AD67D0BD7B21B4495406B0F7A083AB155D37497CC81E4F360F39DF5A26C40662176ACB041805614DD761C619282E2719C29693050058E6FA82FF4237E86A408ADB3DDC5ADC0D770B3E5D1861B669FCEB53D432A5928AB547040CF2044B3164573AE36C52DE160C2F34B0FC18B1C5E53DE1ACF886086064AAE3566D2AC9E00EFED873A201F0D14FC0DFDCF40ED380E12F9CD3D65F944D888D1FFB0F0ADF56CDCBC3036FBA03AB05944D37F24917DF3E18B9EE06B1AFDB385FBBC9425D414849B0FE0BF8D101669341EA388B899ECA0BC7FF46200CC64E0A8480C9B55E71D2A3AAB11FB5D9E2278016E8BCE6901A87B8D993F8AEE78698D6FD13D2E26873F3DA86F0983AB151E921C0A0308ECA824E32FBBF2E8F1BC4E0BEC0013BA6B89BB61F495FAAB142B782BC59FB4B15EBD4DF155A56B07F7E64C4732DB1BF21E03DD68DACABB778E97C74380E7BB4B5BFDBA7
-20200315011135 2 6 100 7679 2 F9B9E3DF0669078220C98F6E1775CAE12B5D95EF20D9491DDDFC0DFBA8EE09FD43F58BA934B719A06ECFF9646CA90998726E6FBDC6DB663F3BE44CF10A44B9D2DD7B01682B867206E6A67FE77170050860206AE5980778EA44104698A52D4D57D2AE0B98826DD3E98CB26E3CF0F044546CA7A97505E68983B439E27EE64AAB26D9FAB324CBADE29FBF733AF761D5CBA8E15D906F992080A1A725D65DD85CCDF0B00CCD5D44952C7D46CC514F6D34DD225F26B5CCFB2EB26077A854C19585DD40F4373FE41626532D4753C3617395FDF26FAAE36A6BD0D9009A7F9086AE9B150BD4712B4672ABACF3EC652B972885D8C6C858C93FA42B72E48EFB055E25828CF6FBF609BA25A589B79E0B64DB63F971C6C06103696A359338034A1FB53E0B601FCBDB8CB6BE8DA048C4D9CEA7EA4A458FA64A87B788543854D94977330FEBC9BB09855083ED12C13858DED10C17C19412C7AF9412F4FE952322D80FC9B26842B1FE1859E670FB047390669D81225409853A3E3CCEE979D1120F4F3D833C49A7F8EA673FA68ACB33FFFC3B56A3F277D237F566F5A342C79B3E40EBEBD6E570B1AED4845B353995C7B758CFD4875A799F652122648618AC29D583E04D772FB6739F69D5E4DBFF2BD7B3468729E1ED90C9C523C36912B2EBC69199A5E7D0982867536275332B62C1AD6F07F1825BE66CDC5C99427268B6D1E754A90AF36F49C136E40455866B92FBEF1A298C3A3EFDB6F0F459F5E885D2C0B74C4C7347430AAD7EF86BFA21F8D38CAC911171802D645A73B5249334E26B804F47A012DE0FE1CF4745F33A4A5882DCA984E253E6B16B9A8A15541F65270BFB61A64EFE9BDBBFE4205B1F4FFF5FD75EF15D17F3CBB89651E88866A2AD67D0BD7B21B4495406B0F7A083AB155D37497CC81E4F360F39DF5A26C40662176ACB041805614DD761C619282E2719C29693050058E6FA82FF4237E86A408ADB3DDC5ADC0D770B3E5D1861B669FCEB53D432A5928AB547040CF2044B3164573AE36C52DE160C2F34B0FC18B1C5E53DE1ACF886086064AAE3566D2AC9E00EFED873A201F0D14FC0DFDCF40ED380E12F9CD3D65F944D888D1FFB0F0ADF56CDCBC3036FBA03AB05944D37F24917DF3E18B9EE06B1AFDB385FBBC9425D414849B0FE0BF8D101669341EA388B899ECA0BC7FF46200CC64E0A8480C9B55E71D2A3AAB11FB5D9E2278016E8BCE6901A87B8D993F8AEE78698D6FD13D2E26873F3DA86F0983AB151E921C0A0308ECA824E32FBBF2E8F1BC4E0BEC0013BA6B89BB61F495FAAB142B782BC59FB4B15EBD4DF155A56B07F7E64C4732DB1BF21E03DD68DACABB778E97C74380E7BB4BD31F073
-20200315110837 2 6 100 7679 5 F9B9E3DF0669078220C98F6E1775CAE12B5D95EF20D9491DDDFC0DFBA8EE09FD43F58BA934B719A06ECFF9646CA90998726E6FBDC6DB663F3BE44CF10A44B9D2DD7B01682B867206E6A67FE77170050860206AE5980778EA44104698A52D4D57D2AE0B98826DD3E98CB26E3CF0F044546CA7A97505E68983B439E27EE64AAB26D9FAB324CBADE29FBF733AF761D5CBA8E15D906F992080A1A725D65DD85CCDF0B00CCD5D44952C7D46CC514F6D34DD225F26B5CCFB2EB26077A854C19585DD40F4373FE41626532D4753C3617395FDF26FAAE36A6BD0D9009A7F9086AE9B150BD4712B4672ABACF3EC652B972885D8C6C858C93FA42B72E48EFB055E25828CF6FBF609BA25A589B79E0B64DB63F971C6C06103696A359338034A1FB53E0B601FCBDB8CB6BE8DA048C4D9CEA7EA4A458FA64A87B788543854D94977330FEBC9BB09855083ED12C13858DED10C17C19412C7AF9412F4FE952322D80FC9B26842B1FE1859E670FB047390669D81225409853A3E3CCEE979D1120F4F3D833C49A7F8EA673FA68ACB33FFFC3B56A3F277D237F566F5A342C79B3E40EBEBD6E570B1AED4845B353995C7B758CFD4875A799F652122648618AC29D583E04D772FB6739F69D5E4DBFF2BD7B3468729E1ED90C9C523C36912B2EBC69199A5E7D0982867536275332B62C1AD6F07F1825BE66CDC5C99427268B6D1E754A90AF36F49C136E40455866B92FBEF1A298C3A3EFDB6F0F459F5E885D2C0B74C4C7347430AAD7EF86BFA21F8D38CAC911171802D645A73B5249334E26B804F47A012DE0FE1CF4745F33A4A5882DCA984E253E6B16B9A8A15541F65270BFB61A64EFE9BDBBFE4205B1F4FFF5FD75EF15D17F3CBB89651E88866A2AD67D0BD7B21B4495406B0F7A083AB155D37497CC81E4F360F39DF5A26C40662176ACB041805614DD761C619282E2719C29693050058E6FA82FF4237E86A408ADB3DDC5ADC0D770B3E5D1861B669FCEB53D432A5928AB547040CF2044B3164573AE36C52DE160C2F34B0FC18B1C5E53DE1ACF886086064AAE3566D2AC9E00EFED873A201F0D14FC0DFDCF40ED380E12F9CD3D65F944D888D1FFB0F0ADF56CDCBC3036FBA03AB05944D37F24917DF3E18B9EE06B1AFDB385FBBC9425D414849B0FE0BF8D101669341EA388B899ECA0BC7FF46200CC64E0A8480C9B55E71D2A3AAB11FB5D9E2278016E8BCE6901A87B8D993F8AEE78698D6FD13D2E26873F3DA86F0983AB151E921C0A0308ECA824E32FBBF2E8F1BC4E0BEC0013BA6B89BB61F495FAAB142B782BC59FB4B15EBD4DF155A56B07F7E64C4732DB1BF21E03DD68DACABB778E97C74380E7BB4C26F444F
-20200315161923 2 6 100 7679 2 F9B9E3DF0669078220C98F6E1775CAE12B5D95EF20D9491DDDFC0DFBA8EE09FD43F58BA934B719A06ECFF9646CA90998726E6FBDC6DB663F3BE44CF10A44B9D2DD7B01682B867206E6A67FE77170050860206AE5980778EA44104698A52D4D57D2AE0B98826DD3E98CB26E3CF0F044546CA7A97505E68983B439E27EE64AAB26D9FAB324CBADE29FBF733AF761D5CBA8E15D906F992080A1A725D65DD85CCDF0B00CCD5D44952C7D46CC514F6D34DD225F26B5CCFB2EB26077A854C19585DD40F4373FE41626532D4753C3617395FDF26FAAE36A6BD0D9009A7F9086AE9B150BD4712B4672ABACF3EC652B972885D8C6C858C93FA42B72E48EFB055E25828CF6FBF609BA25A589B79E0B64DB63F971C6C06103696A359338034A1FB53E0B601FCBDB8CB6BE8DA048C4D9CEA7EA4A458FA64A87B788543854D94977330FEBC9BB09855083ED12C13858DED10C17C19412C7AF9412F4FE952322D80FC9B26842B1FE1859E670FB047390669D81225409853A3E3CCEE979D1120F4F3D833C49A7F8EA673FA68ACB33FFFC3B56A3F277D237F566F5A342C79B3E40EBEBD6E570B1AED4845B353995C7B758CFD4875A799F652122648618AC29D583E04D772FB6739F69D5E4DBFF2BD7B3468729E1ED90C9C523C36912B2EBC69199A5E7D0982867536275332B62C1AD6F07F1825BE66CDC5C99427268B6D1E754A90AF36F49C136E40455866B92FBEF1A298C3A3EFDB6F0F459F5E885D2C0B74C4C7347430AAD7EF86BFA21F8D38CAC911171802D645A73B5249334E26B804F47A012DE0FE1CF4745F33A4A5882DCA984E253E6B16B9A8A15541F65270BFB61A64EFE9BDBBFE4205B1F4FFF5FD75EF15D17F3CBB89651E88866A2AD67D0BD7B21B4495406B0F7A083AB155D37497CC81E4F360F39DF5A26C40662176ACB041805614DD761C619282E2719C29693050058E6FA82FF4237E86A408ADB3DDC5ADC0D770B3E5D1861B669FCEB53D432A5928AB547040CF2044B3164573AE36C52DE160C2F34B0FC18B1C5E53DE1ACF886086064AAE3566D2AC9E00EFED873A201F0D14FC0DFDCF40ED380E12F9CD3D65F944D888D1FFB0F0ADF56CDCBC3036FBA03AB05944D37F24917DF3E18B9EE06B1AFDB385FBBC9425D414849B0FE0BF8D101669341EA388B899ECA0BC7FF46200CC64E0A8480C9B55E71D2A3AAB11FB5D9E2278016E8BCE6901A87B8D993F8AEE78698D6FD13D2E26873F3DA86F0983AB151E921C0A0308ECA824E32FBBF2E8F1BC4E0BEC0013BA6B89BB61F495FAAB142B782BC59FB4B15EBD4DF155A56B07F7E64C4732DB1BF21E03DD68DACABB778E97C74380E7BB4C4B91073
-20200316051743 2 6 100 7679 2 F9B9E3DF0669078220C98F6E1775CAE12B5D95EF20D9491DDDFC0DFBA8EE09FD43F58BA934B719A06ECFF9646CA90998726E6FBDC6DB663F3BE44CF10A44B9D2DD7B01682B867206E6A67FE77170050860206AE5980778EA44104698A52D4D57D2AE0B98826DD3E98CB26E3CF0F044546CA7A97505E68983B439E27EE64AAB26D9FAB324CBADE29FBF733AF761D5CBA8E15D906F992080A1A725D65DD85CCDF0B00CCD5D44952C7D46CC514F6D34DD225F26B5CCFB2EB26077A854C19585DD40F4373FE41626532D4753C3617395FDF26FAAE36A6BD0D9009A7F9086AE9B150BD4712B4672ABACF3EC652B972885D8C6C858C93FA42B72E48EFB055E25828CF6FBF609BA25A589B79E0B64DB63F971C6C06103696A359338034A1FB53E0B601FCBDB8CB6BE8DA048C4D9CEA7EA4A458FA64A87B788543854D94977330FEBC9BB09855083ED12C13858DED10C17C19412C7AF9412F4FE952322D80FC9B26842B1FE1859E670FB047390669D81225409853A3E3CCEE979D1120F4F3D833C49A7F8EA673FA68ACB33FFFC3B56A3F277D237F566F5A342C79B3E40EBEBD6E570B1AED4845B353995C7B758CFD4875A799F652122648618AC29D583E04D772FB6739F69D5E4DBFF2BD7B3468729E1ED90C9C523C36912B2EBC69199A5E7D0982867536275332B62C1AD6F07F1825BE66CDC5C99427268B6D1E754A90AF36F49C136E40455866B92FBEF1A298C3A3EFDB6F0F459F5E885D2C0B74C4C7347430AAD7EF86BFA21F8D38CAC911171802D645A73B5249334E26B804F47A012DE0FE1CF4745F33A4A5882DCA984E253E6B16B9A8A15541F65270BFB61A64EFE9BDBBFE4205B1F4FFF5FD75EF15D17F3CBB89651E88866A2AD67D0BD7B21B4495406B0F7A083AB155D37497CC81E4F360F39DF5A26C40662176ACB041805614DD761C619282E2719C29693050058E6FA82FF4237E86A408ADB3DDC5ADC0D770B3E5D1861B669FCEB53D432A5928AB547040CF2044B3164573AE36C52DE160C2F34B0FC18B1C5E53DE1ACF886086064AAE3566D2AC9E00EFED873A201F0D14FC0DFDCF40ED380E12F9CD3D65F944D888D1FFB0F0ADF56CDCBC3036FBA03AB05944D37F24917DF3E18B9EE06B1AFDB385FBBC9425D414849B0FE0BF8D101669341EA388B899ECA0BC7FF46200CC64E0A8480C9B55E71D2A3AAB11FB5D9E2278016E8BCE6901A87B8D993F8AEE78698D6FD13D2E26873F3DA86F0983AB151E921C0A0308ECA824E32FBBF2E8F1BC4E0BEC0013BA6B89BB61F495FAAB142B782BC59FB4B15EBD4DF155A56B07F7E64C4732DB1BF21E03DD68DACABB778E97C74380E7BB4CAECF90B
-20200316125128 2 6 100 7679 5 F9B9E3DF0669078220C98F6E1775CAE12B5D95EF20D9491DDDFC0DFBA8EE09FD43F58BA934B719A06ECFF9646CA90998726E6FBDC6DB663F3BE44CF10A44B9D2DD7B01682B867206E6A67FE77170050860206AE5980778EA44104698A52D4D57D2AE0B98826DD3E98CB26E3CF0F044546CA7A97505E68983B439E27EE64AAB26D9FAB324CBADE29FBF733AF761D5CBA8E15D906F992080A1A725D65DD85CCDF0B00CCD5D44952C7D46CC514F6D34DD225F26B5CCFB2EB26077A854C19585DD40F4373FE41626532D4753C3617395FDF26FAAE36A6BD0D9009A7F9086AE9B150BD4712B4672ABACF3EC652B972885D8C6C858C93FA42B72E48EFB055E25828CF6FBF609BA25A589B79E0B64DB63F971C6C06103696A359338034A1FB53E0B601FCBDB8CB6BE8DA048C4D9CEA7EA4A458FA64A87B788543854D94977330FEBC9BB09855083ED12C13858DED10C17C19412C7AF9412F4FE952322D80FC9B26842B1FE1859E670FB047390669D81225409853A3E3CCEE979D1120F4F3D833C49A7F8EA673FA68ACB33FFFC3B56A3F277D237F566F5A342C79B3E40EBEBD6E570B1AED4845B353995C7B758CFD4875A799F652122648618AC29D583E04D772FB6739F69D5E4DBFF2BD7B3468729E1ED90C9C523C36912B2EBC69199A5E7D0982867536275332B62C1AD6F07F1825BE66CDC5C99427268B6D1E754A90AF36F49C136E40455866B92FBEF1A298C3A3EFDB6F0F459F5E885D2C0B74C4C7347430AAD7EF86BFA21F8D38CAC911171802D645A73B5249334E26B804F47A012DE0FE1CF4745F33A4A5882DCA984E253E6B16B9A8A15541F65270BFB61A64EFE9BDBBFE4205B1F4FFF5FD75EF15D17F3CBB89651E88866A2AD67D0BD7B21B4495406B0F7A083AB155D37497CC81E4F360F39DF5A26C40662176ACB041805614DD761C619282E2719C29693050058E6FA82FF4237E86A408ADB3DDC5ADC0D770B3E5D1861B669FCEB53D432A5928AB547040CF2044B3164573AE36C52DE160C2F34B0FC18B1C5E53DE1ACF886086064AAE3566D2AC9E00EFED873A201F0D14FC0DFDCF40ED380E12F9CD3D65F944D888D1FFB0F0ADF56CDCBC3036FBA03AB05944D37F24917DF3E18B9EE06B1AFDB385FBBC9425D414849B0FE0BF8D101669341EA388B899ECA0BC7FF46200CC64E0A8480C9B55E71D2A3AAB11FB5D9E2278016E8BCE6901A87B8D993F8AEE78698D6FD13D2E26873F3DA86F0983AB151E921C0A0308ECA824E32FBBF2E8F1BC4E0BEC0013BA6B89BB61F495FAAB142B782BC59FB4B15EBD4DF155A56B07F7E64C4732DB1BF21E03DD68DACABB778E97C74380E7BB4CE2FC1E7
-20200316153032 2 6 100 7679 5 F9B9E3DF0669078220C98F6E1775CAE12B5D95EF20D9491DDDFC0DFBA8EE09FD43F58BA934B719A06ECFF9646CA90998726E6FBDC6DB663F3BE44CF10A44B9D2DD7B01682B867206E6A67FE77170050860206AE5980778EA44104698A52D4D57D2AE0B98826DD3E98CB26E3CF0F044546CA7A97505E68983B439E27EE64AAB26D9FAB324CBADE29FBF733AF761D5CBA8E15D906F992080A1A725D65DD85CCDF0B00CCD5D44952C7D46CC514F6D34DD225F26B5CCFB2EB26077A854C19585DD40F4373FE41626532D4753C3617395FDF26FAAE36A6BD0D9009A7F9086AE9B150BD4712B4672ABACF3EC652B972885D8C6C858C93FA42B72E48EFB055E25828CF6FBF609BA25A589B79E0B64DB63F971C6C06103696A359338034A1FB53E0B601FCBDB8CB6BE8DA048C4D9CEA7EA4A458FA64A87B788543854D94977330FEBC9BB09855083ED12C13858DED10C17C19412C7AF9412F4FE952322D80FC9B26842B1FE1859E670FB047390669D81225409853A3E3CCEE979D1120F4F3D833C49A7F8EA673FA68ACB33FFFC3B56A3F277D237F566F5A342C79B3E40EBEBD6E570B1AED4845B353995C7B758CFD4875A799F652122648618AC29D583E04D772FB6739F69D5E4DBFF2BD7B3468729E1ED90C9C523C36912B2EBC69199A5E7D0982867536275332B62C1AD6F07F1825BE66CDC5C99427268B6D1E754A90AF36F49C136E40455866B92FBEF1A298C3A3EFDB6F0F459F5E885D2C0B74C4C7347430AAD7EF86BFA21F8D38CAC911171802D645A73B5249334E26B804F47A012DE0FE1CF4745F33A4A5882DCA984E253E6B16B9A8A15541F65270BFB61A64EFE9BDBBFE4205B1F4FFF5FD75EF15D17F3CBB89651E88866A2AD67D0BD7B21B4495406B0F7A083AB155D37497CC81E4F360F39DF5A26C40662176ACB041805614DD761C619282E2719C29693050058E6FA82FF4237E86A408ADB3DDC5ADC0D770B3E5D1861B669FCEB53D432A5928AB547040CF2044B3164573AE36C52DE160C2F34B0FC18B1C5E53DE1ACF886086064AAE3566D2AC9E00EFED873A201F0D14FC0DFDCF40ED380E12F9CD3D65F944D888D1FFB0F0ADF56CDCBC3036FBA03AB05944D37F24917DF3E18B9EE06B1AFDB385FBBC9425D414849B0FE0BF8D101669341EA388B899ECA0BC7FF46200CC64E0A8480C9B55E71D2A3AAB11FB5D9E2278016E8BCE6901A87B8D993F8AEE78698D6FD13D2E26873F3DA86F0983AB151E921C0A0308ECA824E32FBBF2E8F1BC4E0BEC0013BA6B89BB61F495FAAB142B782BC59FB4B15EBD4DF155A56B07F7E64C4732DB1BF21E03DD68DACABB778E97C74380E7BB4CF8D33EF
-20200316171946 2 6 100 7679 5 F9B9E3DF0669078220C98F6E1775CAE12B5D95EF20D9491DDDFC0DFBA8EE09FD43F58BA934B719A06ECFF9646CA90998726E6FBDC6DB663F3BE44CF10A44B9D2DD7B01682B867206E6A67FE77170050860206AE5980778EA44104698A52D4D57D2AE0B98826DD3E98CB26E3CF0F044546CA7A97505E68983B439E27EE64AAB26D9FAB324CBADE29FBF733AF761D5CBA8E15D906F992080A1A725D65DD85CCDF0B00CCD5D44952C7D46CC514F6D34DD225F26B5CCFB2EB26077A854C19585DD40F4373FE41626532D4753C3617395FDF26FAAE36A6BD0D9009A7F9086AE9B150BD4712B4672ABACF3EC652B972885D8C6C858C93FA42B72E48EFB055E25828CF6FBF609BA25A589B79E0B64DB63F971C6C06103696A359338034A1FB53E0B601FCBDB8CB6BE8DA048C4D9CEA7EA4A458FA64A87B788543854D94977330FEBC9BB09855083ED12C13858DED10C17C19412C7AF9412F4FE952322D80FC9B26842B1FE1859E670FB047390669D81225409853A3E3CCEE979D1120F4F3D833C49A7F8EA673FA68ACB33FFFC3B56A3F277D237F566F5A342C79B3E40EBEBD6E570B1AED4845B353995C7B758CFD4875A799F652122648618AC29D583E04D772FB6739F69D5E4DBFF2BD7B3468729E1ED90C9C523C36912B2EBC69199A5E7D0982867536275332B62C1AD6F07F1825BE66CDC5C99427268B6D1E754A90AF36F49C136E40455866B92FBEF1A298C3A3EFDB6F0F459F5E885D2C0B74C4C7347430AAD7EF86BFA21F8D38CAC911171802D645A73B5249334E26B804F47A012DE0FE1CF4745F33A4A5882DCA984E253E6B16B9A8A15541F65270BFB61A64EFE9BDBBFE4205B1F4FFF5FD75EF15D17F3CBB89651E88866A2AD67D0BD7B21B4495406B0F7A083AB155D37497CC81E4F360F39DF5A26C40662176ACB041805614DD761C619282E2719C29693050058E6FA82FF4237E86A408ADB3DDC5ADC0D770B3E5D1861B669FCEB53D432A5928AB547040CF2044B3164573AE36C52DE160C2F34B0FC18B1C5E53DE1ACF886086064AAE3566D2AC9E00EFED873A201F0D14FC0DFDCF40ED380E12F9CD3D65F944D888D1FFB0F0ADF56CDCBC3036FBA03AB05944D37F24917DF3E18B9EE06B1AFDB385FBBC9425D414849B0FE0BF8D101669341EA388B899ECA0BC7FF46200CC64E0A8480C9B55E71D2A3AAB11FB5D9E2278016E8BCE6901A87B8D993F8AEE78698D6FD13D2E26873F3DA86F0983AB151E921C0A0308ECA824E32FBBF2E8F1BC4E0BEC0013BA6B89BB61F495FAAB142B782BC59FB4B15EBD4DF155A56B07F7E64C4732DB1BF21E03DD68DACABB778E97C74380E7BB4D07EA9FF
-20200316174220 2 6 100 7679 5 F9B9E3DF0669078220C98F6E1775CAE12B5D95EF20D9491DDDFC0DFBA8EE09FD43F58BA934B719A06ECFF9646CA90998726E6FBDC6DB663F3BE44CF10A44B9D2DD7B01682B867206E6A67FE77170050860206AE5980778EA44104698A52D4D57D2AE0B98826DD3E98CB26E3CF0F044546CA7A97505E68983B439E27EE64AAB26D9FAB324CBADE29FBF733AF761D5CBA8E15D906F992080A1A725D65DD85CCDF0B00CCD5D44952C7D46CC514F6D34DD225F26B5CCFB2EB26077A854C19585DD40F4373FE41626532D4753C3617395FDF26FAAE36A6BD0D9009A7F9086AE9B150BD4712B4672ABACF3EC652B972885D8C6C858C93FA42B72E48EFB055E25828CF6FBF609BA25A589B79E0B64DB63F971C6C06103696A359338034A1FB53E0B601FCBDB8CB6BE8DA048C4D9CEA7EA4A458FA64A87B788543854D94977330FEBC9BB09855083ED12C13858DED10C17C19412C7AF9412F4FE952322D80FC9B26842B1FE1859E670FB047390669D81225409853A3E3CCEE979D1120F4F3D833C49A7F8EA673FA68ACB33FFFC3B56A3F277D237F566F5A342C79B3E40EBEBD6E570B1AED4845B353995C7B758CFD4875A799F652122648618AC29D583E04D772FB6739F69D5E4DBFF2BD7B3468729E1ED90C9C523C36912B2EBC69199A5E7D0982867536275332B62C1AD6F07F1825BE66CDC5C99427268B6D1E754A90AF36F49C136E40455866B92FBEF1A298C3A3EFDB6F0F459F5E885D2C0B74C4C7347430AAD7EF86BFA21F8D38CAC911171802D645A73B5249334E26B804F47A012DE0FE1CF4745F33A4A5882DCA984E253E6B16B9A8A15541F65270BFB61A64EFE9BDBBFE4205B1F4FFF5FD75EF15D17F3CBB89651E88866A2AD67D0BD7B21B4495406B0F7A083AB155D37497CC81E4F360F39DF5A26C40662176ACB041805614DD761C619282E2719C29693050058E6FA82FF4237E86A408ADB3DDC5ADC0D770B3E5D1861B669FCEB53D432A5928AB547040CF2044B3164573AE36C52DE160C2F34B0FC18B1C5E53DE1ACF886086064AAE3566D2AC9E00EFED873A201F0D14FC0DFDCF40ED380E12F9CD3D65F944D888D1FFB0F0ADF56CDCBC3036FBA03AB05944D37F24917DF3E18B9EE06B1AFDB385FBBC9425D414849B0FE0BF8D101669341EA388B899ECA0BC7FF46200CC64E0A8480C9B55E71D2A3AAB11FB5D9E2278016E8BCE6901A87B8D993F8AEE78698D6FD13D2E26873F3DA86F0983AB151E921C0A0308ECA824E32FBBF2E8F1BC4E0BEC0013BA6B89BB61F495FAAB142B782BC59FB4B15EBD4DF155A56B07F7E64C4732DB1BF21E03DD68DACABB778E97C74380E7BB4D0A81D8F
-20200316202625 2 6 100 7679 5 F9B9E3DF0669078220C98F6E1775CAE12B5D95EF20D9491DDDFC0DFBA8EE09FD43F58BA934B719A06ECFF9646CA90998726E6FBDC6DB663F3BE44CF10A44B9D2DD7B01682B867206E6A67FE77170050860206AE5980778EA44104698A52D4D57D2AE0B98826DD3E98CB26E3CF0F044546CA7A97505E68983B439E27EE64AAB26D9FAB324CBADE29FBF733AF761D5CBA8E15D906F992080A1A725D65DD85CCDF0B00CCD5D44952C7D46CC514F6D34DD225F26B5CCFB2EB26077A854C19585DD40F4373FE41626532D4753C3617395FDF26FAAE36A6BD0D9009A7F9086AE9B150BD4712B4672ABACF3EC652B972885D8C6C858C93FA42B72E48EFB055E25828CF6FBF609BA25A589B79E0B64DB63F971C6C06103696A359338034A1FB53E0B601FCBDB8CB6BE8DA048C4D9CEA7EA4A458FA64A87B788543854D94977330FEBC9BB09855083ED12C13858DED10C17C19412C7AF9412F4FE952322D80FC9B26842B1FE1859E670FB047390669D81225409853A3E3CCEE979D1120F4F3D833C49A7F8EA673FA68ACB33FFFC3B56A3F277D237F566F5A342C79B3E40EBEBD6E570B1AED4845B353995C7B758CFD4875A799F652122648618AC29D583E04D772FB6739F69D5E4DBFF2BD7B3468729E1ED90C9C523C36912B2EBC69199A5E7D0982867536275332B62C1AD6F07F1825BE66CDC5C99427268B6D1E754A90AF36F49C136E40455866B92FBEF1A298C3A3EFDB6F0F459F5E885D2C0B74C4C7347430AAD7EF86BFA21F8D38CAC911171802D645A73B5249334E26B804F47A012DE0FE1CF4745F33A4A5882DCA984E253E6B16B9A8A15541F65270BFB61A64EFE9BDBBFE4205B1F4FFF5FD75EF15D17F3CBB89651E88866A2AD67D0BD7B21B4495406B0F7A083AB155D37497CC81E4F360F39DF5A26C40662176ACB041805614DD761C619282E2719C29693050058E6FA82FF4237E86A408ADB3DDC5ADC0D770B3E5D1861B669FCEB53D432A5928AB547040CF2044B3164573AE36C52DE160C2F34B0FC18B1C5E53DE1ACF886086064AAE3566D2AC9E00EFED873A201F0D14FC0DFDCF40ED380E12F9CD3D65F944D888D1FFB0F0ADF56CDCBC3036FBA03AB05944D37F24917DF3E18B9EE06B1AFDB385FBBC9425D414849B0FE0BF8D101669341EA388B899ECA0BC7FF46200CC64E0A8480C9B55E71D2A3AAB11FB5D9E2278016E8BCE6901A87B8D993F8AEE78698D6FD13D2E26873F3DA86F0983AB151E921C0A0308ECA824E32FBBF2E8F1BC4E0BEC0013BA6B89BB61F495FAAB142B782BC59FB4B15EBD4DF155A56B07F7E64C4732DB1BF21E03DD68DACABB778E97C74380E7BB4D21FB857
-20200317144528 2 6 100 7679 2 D6B6711FEDD0DAB74BE347B82AE33FB203A966E712D108C27D2983732928351D8E0B14DB0377CA10A9D079F1D76AB94AB983A67C01CADC4EEDC12F452A214B690C3823B59D05B8967A9C5FB80A78CA705620E04FD35D7BC8636A0456F5015C75B2ED2AEE4A50ED3224FB8BDEECE5C21DFC8703240AC287E4E218710091A76D19EA96FE36FB67547F45040AB5DF812D5A4391E41147087072901BE7E6618F41C2D5868424B7EC12E122A036FB5E504651DF79A120CF6698D983FD59F0203E225DE8508D72DCAA6D93492FC574B73B589189D127CF23EDFD7B319C2222239641590C6F66D25C3AD092527FBDE254131F5C13A70BC2C382671E4B940C755B617854CD3A50941DC652A8F20647C638E5F0977EA881D4770CC8381AE551A745363183752830BF4650C3741FFA8F0ED13CE0190963AFA40B61B2B9CCBD07C49A22CD6C229D43AB2E02CE5A8D2CCE45C22E237F8679D10D2543BDA0407FE3011B211B331426ACCE3B4D7DC8626B4C7D713479170BA6DC9A34F404D1C6A3EA7C04634CE61A032FC967D212B99E521CA58B7EA0E560095F1E39603C1FED48F8ED21E4D7B2D3D6F9CB34387BAD472097FC3C24203991ADE41EFDADE145D9B36E87DF128176951D3AFA12C586585C230F4DE23973B14B0291FB99A2527B87A705228DC2F0C27E6C6D01FA36E231A076C5D256B2D730424EDA55916FA3DE5E6AC1EAA5EF7FFFCF57C5577195EBBD5C3AA0448BE83BFC6853AAF9B48FA1289B276C931D4E472FF04428D02EADF12733C1E446B2DD0F1B30D1BEB4E5F36F6FF6438E7B5C51093BAED1AD02AF353DE0F447C38C1F7D10D3C6CD56DBB8EF4374E5B296BCFC2B926AC19542649DA903992F0DB5F1F41A839179F753921C9814C07924097BD850BE07A0A6ED5EECA31D391154055012C48C8000CA03790889670C2E4BE1BCE6C854C4FAB1004CC127103E59C4BF55C7A290BD44BF9EE06C18557C07D2A36D8FCDE4E1F17AD73FA570112DB3F881AD1C23D573F3F23CC5245B4D1C289F517720F444A3282BDD4D5E49B98926C13B0C45CA13BE11E55A5B6F104435196EF8E25A3A955C5C15A0A350A276912C143F57C819F45557A04C5A576E2266E0898E8D64BA3B7E539B642C7C13E624BC8AA299F8FC1D72C7E9DD4C5CE50DFFB762A80A3D7EF8BBEE12CDDCA3F9900A948986F64A719D5444E5D595B86F2524B0292282F6EFC2D3DB2E275FDC4D11654C878D1D74CA972B7CF6C57B2A542BE5A8F2576105C95C1376F5EBCA7A7068A60E90AA8C4B19219EC3A518E8CD809F06096ABFF526F31E86DD4127FD4CFBDAF1229CB590CF9D76ECAFB2E6B3CD43995F6EF11D6917B8A583
-20200317172320 2 6 100 7679 2 D6B6711FEDD0DAB74BE347B82AE33FB203A966E712D108C27D2983732928351D8E0B14DB0377CA10A9D079F1D76AB94AB983A67C01CADC4EEDC12F452A214B690C3823B59D05B8967A9C5FB80A78CA705620E04FD35D7BC8636A0456F5015C75B2ED2AEE4A50ED3224FB8BDEECE5C21DFC8703240AC287E4E218710091A76D19EA96FE36FB67547F45040AB5DF812D5A4391E41147087072901BE7E6618F41C2D5868424B7EC12E122A036FB5E504651DF79A120CF6698D983FD59F0203E225DE8508D72DCAA6D93492FC574B73B589189D127CF23EDFD7B319C2222239641590C6F66D25C3AD092527FBDE254131F5C13A70BC2C382671E4B940C755B617854CD3A50941DC652A8F20647C638E5F0977EA881D4770CC8381AE551A745363183752830BF4650C3741FFA8F0ED13CE0190963AFA40B61B2B9CCBD07C49A22CD6C229D43AB2E02CE5A8D2CCE45C22E237F8679D10D2543BDA0407FE3011B211B331426ACCE3B4D7DC8626B4C7D713479170BA6DC9A34F404D1C6A3EA7C04634CE61A032FC967D212B99E521CA58B7EA0E560095F1E39603C1FED48F8ED21E4D7B2D3D6F9CB34387BAD472097FC3C24203991ADE41EFDADE145D9B36E87DF128176951D3AFA12C586585C230F4DE23973B14B0291FB99A2527B87A705228DC2F0C27E6C6D01FA36E231A076C5D256B2D730424EDA55916FA3DE5E6AC1EAA5EF7FFFCF57C5577195EBBD5C3AA0448BE83BFC6853AAF9B48FA1289B276C931D4E472FF04428D02EADF12733C1E446B2DD0F1B30D1BEB4E5F36F6FF6438E7B5C51093BAED1AD02AF353DE0F447C38C1F7D10D3C6CD56DBB8EF4374E5B296BCFC2B926AC19542649DA903992F0DB5F1F41A839179F753921C9814C07924097BD850BE07A0A6ED5EECA31D391154055012C48C8000CA03790889670C2E4BE1BCE6C854C4FAB1004CC127103E59C4BF55C7A290BD44BF9EE06C18557C07D2A36D8FCDE4E1F17AD73FA570112DB3F881AD1C23D573F3F23CC5245B4D1C289F517720F444A3282BDD4D5E49B98926C13B0C45CA13BE11E55A5B6F104435196EF8E25A3A955C5C15A0A350A276912C143F57C819F45557A04C5A576E2266E0898E8D64BA3B7E539B642C7C13E624BC8AA299F8FC1D72C7E9DD4C5CE50DFFB762A80A3D7EF8BBEE12CDDCA3F9900A948986F64A719D5444E5D595B86F2524B0292282F6EFC2D3DB2E275FDC4D11654C878D1D74CA972B7CF6C57B2A542BE5A8F2576105C95C1376F5EBCA7A7068A60E90AA8C4B19219EC3A518E8CD809F06096ABFF526F31E86DD4127FD4CFBDAF1229CB590CF9D76ECAFB2E6B3CD43995F6EF11D69194AFCCB
-20200317211821 2 6 100 7679 2 D6B6711FEDD0DAB74BE347B82AE33FB203A966E712D108C27D2983732928351D8E0B14DB0377CA10A9D079F1D76AB94AB983A67C01CADC4EEDC12F452A214B690C3823B59D05B8967A9C5FB80A78CA705620E04FD35D7BC8636A0456F5015C75B2ED2AEE4A50ED3224FB8BDEECE5C21DFC8703240AC287E4E218710091A76D19EA96FE36FB67547F45040AB5DF812D5A4391E41147087072901BE7E6618F41C2D5868424B7EC12E122A036FB5E504651DF79A120CF6698D983FD59F0203E225DE8508D72DCAA6D93492FC574B73B589189D127CF23EDFD7B319C2222239641590C6F66D25C3AD092527FBDE254131F5C13A70BC2C382671E4B940C755B617854CD3A50941DC652A8F20647C638E5F0977EA881D4770CC8381AE551A745363183752830BF4650C3741FFA8F0ED13CE0190963AFA40B61B2B9CCBD07C49A22CD6C229D43AB2E02CE5A8D2CCE45C22E237F8679D10D2543BDA0407FE3011B211B331426ACCE3B4D7DC8626B4C7D713479170BA6DC9A34F404D1C6A3EA7C04634CE61A032FC967D212B99E521CA58B7EA0E560095F1E39603C1FED48F8ED21E4D7B2D3D6F9CB34387BAD472097FC3C24203991ADE41EFDADE145D9B36E87DF128176951D3AFA12C586585C230F4DE23973B14B0291FB99A2527B87A705228DC2F0C27E6C6D01FA36E231A076C5D256B2D730424EDA55916FA3DE5E6AC1EAA5EF7FFFCF57C5577195EBBD5C3AA0448BE83BFC6853AAF9B48FA1289B276C931D4E472FF04428D02EADF12733C1E446B2DD0F1B30D1BEB4E5F36F6FF6438E7B5C51093BAED1AD02AF353DE0F447C38C1F7D10D3C6CD56DBB8EF4374E5B296BCFC2B926AC19542649DA903992F0DB5F1F41A839179F753921C9814C07924097BD850BE07A0A6ED5EECA31D391154055012C48C8000CA03790889670C2E4BE1BCE6C854C4FAB1004CC127103E59C4BF55C7A290BD44BF9EE06C18557C07D2A36D8FCDE4E1F17AD73FA570112DB3F881AD1C23D573F3F23CC5245B4D1C289F517720F444A3282BDD4D5E49B98926C13B0C45CA13BE11E55A5B6F104435196EF8E25A3A955C5C15A0A350A276912C143F57C819F45557A04C5A576E2266E0898E8D64BA3B7E539B642C7C13E624BC8AA299F8FC1D72C7E9DD4C5CE50DFFB762A80A3D7EF8BBEE12CDDCA3F9900A948986F64A719D5444E5D595B86F2524B0292282F6EFC2D3DB2E275FDC4D11654C878D1D74CA972B7CF6C57B2A542BE5A8F2576105C95C1376F5EBCA7A7068A60E90AA8C4B19219EC3A518E8CD809F06096ABFF526F31E86DD4127FD4CFBDAF1229CB590CF9D76ECAFB2E6B3CD43995F6EF11D691BAE756B
-20200318020947 2 6 100 7679 2 D6B6711FEDD0DAB74BE347B82AE33FB203A966E712D108C27D2983732928351D8E0B14DB0377CA10A9D079F1D76AB94AB983A67C01CADC4EEDC12F452A214B690C3823B59D05B8967A9C5FB80A78CA705620E04FD35D7BC8636A0456F5015C75B2ED2AEE4A50ED3224FB8BDEECE5C21DFC8703240AC287E4E218710091A76D19EA96FE36FB67547F45040AB5DF812D5A4391E41147087072901BE7E6618F41C2D5868424B7EC12E122A036FB5E504651DF79A120CF6698D983FD59F0203E225DE8508D72DCAA6D93492FC574B73B589189D127CF23EDFD7B319C2222239641590C6F66D25C3AD092527FBDE254131F5C13A70BC2C382671E4B940C755B617854CD3A50941DC652A8F20647C638E5F0977EA881D4770CC8381AE551A745363183752830BF4650C3741FFA8F0ED13CE0190963AFA40B61B2B9CCBD07C49A22CD6C229D43AB2E02CE5A8D2CCE45C22E237F8679D10D2543BDA0407FE3011B211B331426ACCE3B4D7DC8626B4C7D713479170BA6DC9A34F404D1C6A3EA7C04634CE61A032FC967D212B99E521CA58B7EA0E560095F1E39603C1FED48F8ED21E4D7B2D3D6F9CB34387BAD472097FC3C24203991ADE41EFDADE145D9B36E87DF128176951D3AFA12C586585C230F4DE23973B14B0291FB99A2527B87A705228DC2F0C27E6C6D01FA36E231A076C5D256B2D730424EDA55916FA3DE5E6AC1EAA5EF7FFFCF57C5577195EBBD5C3AA0448BE83BFC6853AAF9B48FA1289B276C931D4E472FF04428D02EADF12733C1E446B2DD0F1B30D1BEB4E5F36F6FF6438E7B5C51093BAED1AD02AF353DE0F447C38C1F7D10D3C6CD56DBB8EF4374E5B296BCFC2B926AC19542649DA903992F0DB5F1F41A839179F753921C9814C07924097BD850BE07A0A6ED5EECA31D391154055012C48C8000CA03790889670C2E4BE1BCE6C854C4FAB1004CC127103E59C4BF55C7A290BD44BF9EE06C18557C07D2A36D8FCDE4E1F17AD73FA570112DB3F881AD1C23D573F3F23CC5245B4D1C289F517720F444A3282BDD4D5E49B98926C13B0C45CA13BE11E55A5B6F104435196EF8E25A3A955C5C15A0A350A276912C143F57C819F45557A04C5A576E2266E0898E8D64BA3B7E539B642C7C13E624BC8AA299F8FC1D72C7E9DD4C5CE50DFFB762A80A3D7EF8BBEE12CDDCA3F9900A948986F64A719D5444E5D595B86F2524B0292282F6EFC2D3DB2E275FDC4D11654C878D1D74CA972B7CF6C57B2A542BE5A8F2576105C95C1376F5EBCA7A7068A60E90AA8C4B19219EC3A518E8CD809F06096ABFF526F31E86DD4127FD4CFBDAF1229CB590CF9D76ECAFB2E6B3CD43995F6EF11D691E88D40B
-20200318132137 2 6 100 7679 2 D6B6711FEDD0DAB74BE347B82AE33FB203A966E712D108C27D2983732928351D8E0B14DB0377CA10A9D079F1D76AB94AB983A67C01CADC4EEDC12F452A214B690C3823B59D05B8967A9C5FB80A78CA705620E04FD35D7BC8636A0456F5015C75B2ED2AEE4A50ED3224FB8BDEECE5C21DFC8703240AC287E4E218710091A76D19EA96FE36FB67547F45040AB5DF812D5A4391E41147087072901BE7E6618F41C2D5868424B7EC12E122A036FB5E504651DF79A120CF6698D983FD59F0203E225DE8508D72DCAA6D93492FC574B73B589189D127CF23EDFD7B319C2222239641590C6F66D25C3AD092527FBDE254131F5C13A70BC2C382671E4B940C755B617854CD3A50941DC652A8F20647C638E5F0977EA881D4770CC8381AE551A745363183752830BF4650C3741FFA8F0ED13CE0190963AFA40B61B2B9CCBD07C49A22CD6C229D43AB2E02CE5A8D2CCE45C22E237F8679D10D2543BDA0407FE3011B211B331426ACCE3B4D7DC8626B4C7D713479170BA6DC9A34F404D1C6A3EA7C04634CE61A032FC967D212B99E521CA58B7EA0E560095F1E39603C1FED48F8ED21E4D7B2D3D6F9CB34387BAD472097FC3C24203991ADE41EFDADE145D9B36E87DF128176951D3AFA12C586585C230F4DE23973B14B0291FB99A2527B87A705228DC2F0C27E6C6D01FA36E231A076C5D256B2D730424EDA55916FA3DE5E6AC1EAA5EF7FFFCF57C5577195EBBD5C3AA0448BE83BFC6853AAF9B48FA1289B276C931D4E472FF04428D02EADF12733C1E446B2DD0F1B30D1BEB4E5F36F6FF6438E7B5C51093BAED1AD02AF353DE0F447C38C1F7D10D3C6CD56DBB8EF4374E5B296BCFC2B926AC19542649DA903992F0DB5F1F41A839179F753921C9814C07924097BD850BE07A0A6ED5EECA31D391154055012C48C8000CA03790889670C2E4BE1BCE6C854C4FAB1004CC127103E59C4BF55C7A290BD44BF9EE06C18557C07D2A36D8FCDE4E1F17AD73FA570112DB3F881AD1C23D573F3F23CC5245B4D1C289F517720F444A3282BDD4D5E49B98926C13B0C45CA13BE11E55A5B6F104435196EF8E25A3A955C5C15A0A350A276912C143F57C819F45557A04C5A576E2266E0898E8D64BA3B7E539B642C7C13E624BC8AA299F8FC1D72C7E9DD4C5CE50DFFB762A80A3D7EF8BBEE12CDDCA3F9900A948986F64A719D5444E5D595B86F2524B0292282F6EFC2D3DB2E275FDC4D11654C878D1D74CA972B7CF6C57B2A542BE5A8F2576105C95C1376F5EBCA7A7068A60E90AA8C4B19219EC3A518E8CD809F06096ABFF526F31E86DD4127FD4CFBDAF1229CB590CF9D76ECAFB2E6B3CD43995F6EF11D69243D6E83
-20200318164449 2 6 100 7679 5 D6B6711FEDD0DAB74BE347B82AE33FB203A966E712D108C27D2983732928351D8E0B14DB0377CA10A9D079F1D76AB94AB983A67C01CADC4EEDC12F452A214B690C3823B59D05B8967A9C5FB80A78CA705620E04FD35D7BC8636A0456F5015C75B2ED2AEE4A50ED3224FB8BDEECE5C21DFC8703240AC287E4E218710091A76D19EA96FE36FB67547F45040AB5DF812D5A4391E41147087072901BE7E6618F41C2D5868424B7EC12E122A036FB5E504651DF79A120CF6698D983FD59F0203E225DE8508D72DCAA6D93492FC574B73B589189D127CF23EDFD7B319C2222239641590C6F66D25C3AD092527FBDE254131F5C13A70BC2C382671E4B940C755B617854CD3A50941DC652A8F20647C638E5F0977EA881D4770CC8381AE551A745363183752830BF4650C3741FFA8F0ED13CE0190963AFA40B61B2B9CCBD07C49A22CD6C229D43AB2E02CE5A8D2CCE45C22E237F8679D10D2543BDA0407FE3011B211B331426ACCE3B4D7DC8626B4C7D713479170BA6DC9A34F404D1C6A3EA7C04634CE61A032FC967D212B99E521CA58B7EA0E560095F1E39603C1FED48F8ED21E4D7B2D3D6F9CB34387BAD472097FC3C24203991ADE41EFDADE145D9B36E87DF128176951D3AFA12C586585C230F4DE23973B14B0291FB99A2527B87A705228DC2F0C27E6C6D01FA36E231A076C5D256B2D730424EDA55916FA3DE5E6AC1EAA5EF7FFFCF57C5577195EBBD5C3AA0448BE83BFC6853AAF9B48FA1289B276C931D4E472FF04428D02EADF12733C1E446B2DD0F1B30D1BEB4E5F36F6FF6438E7B5C51093BAED1AD02AF353DE0F447C38C1F7D10D3C6CD56DBB8EF4374E5B296BCFC2B926AC19542649DA903992F0DB5F1F41A839179F753921C9814C07924097BD850BE07A0A6ED5EECA31D391154055012C48C8000CA03790889670C2E4BE1BCE6C854C4FAB1004CC127103E59C4BF55C7A290BD44BF9EE06C18557C07D2A36D8FCDE4E1F17AD73FA570112DB3F881AD1C23D573F3F23CC5245B4D1C289F517720F444A3282BDD4D5E49B98926C13B0C45CA13BE11E55A5B6F104435196EF8E25A3A955C5C15A0A350A276912C143F57C819F45557A04C5A576E2266E0898E8D64BA3B7E539B642C7C13E624BC8AA299F8FC1D72C7E9DD4C5CE50DFFB762A80A3D7EF8BBEE12CDDCA3F9900A948986F64A719D5444E5D595B86F2524B0292282F6EFC2D3DB2E275FDC4D11654C878D1D74CA972B7CF6C57B2A542BE5A8F2576105C95C1376F5EBCA7A7068A60E90AA8C4B19219EC3A518E8CD809F06096ABFF526F31E86DD4127FD4CFBDAF1229CB590CF9D76ECAFB2E6B3CD43995F6EF11D692641EA1F
-20200318165632 2 6 100 7679 2 D6B6711FEDD0DAB74BE347B82AE33FB203A966E712D108C27D2983732928351D8E0B14DB0377CA10A9D079F1D76AB94AB983A67C01CADC4EEDC12F452A214B690C3823B59D05B8967A9C5FB80A78CA705620E04FD35D7BC8636A0456F5015C75B2ED2AEE4A50ED3224FB8BDEECE5C21DFC8703240AC287E4E218710091A76D19EA96FE36FB67547F45040AB5DF812D5A4391E41147087072901BE7E6618F41C2D5868424B7EC12E122A036FB5E504651DF79A120CF6698D983FD59F0203E225DE8508D72DCAA6D93492FC574B73B589189D127CF23EDFD7B319C2222239641590C6F66D25C3AD092527FBDE254131F5C13A70BC2C382671E4B940C755B617854CD3A50941DC652A8F20647C638E5F0977EA881D4770CC8381AE551A745363183752830BF4650C3741FFA8F0ED13CE0190963AFA40B61B2B9CCBD07C49A22CD6C229D43AB2E02CE5A8D2CCE45C22E237F8679D10D2543BDA0407FE3011B211B331426ACCE3B4D7DC8626B4C7D713479170BA6DC9A34F404D1C6A3EA7C04634CE61A032FC967D212B99E521CA58B7EA0E560095F1E39603C1FED48F8ED21E4D7B2D3D6F9CB34387BAD472097FC3C24203991ADE41EFDADE145D9B36E87DF128176951D3AFA12C586585C230F4DE23973B14B0291FB99A2527B87A705228DC2F0C27E6C6D01FA36E231A076C5D256B2D730424EDA55916FA3DE5E6AC1EAA5EF7FFFCF57C5577195EBBD5C3AA0448BE83BFC6853AAF9B48FA1289B276C931D4E472FF04428D02EADF12733C1E446B2DD0F1B30D1BEB4E5F36F6FF6438E7B5C51093BAED1AD02AF353DE0F447C38C1F7D10D3C6CD56DBB8EF4374E5B296BCFC2B926AC19542649DA903992F0DB5F1F41A839179F753921C9814C07924097BD850BE07A0A6ED5EECA31D391154055012C48C8000CA03790889670C2E4BE1BCE6C854C4FAB1004CC127103E59C4BF55C7A290BD44BF9EE06C18557C07D2A36D8FCDE4E1F17AD73FA570112DB3F881AD1C23D573F3F23CC5245B4D1C289F517720F444A3282BDD4D5E49B98926C13B0C45CA13BE11E55A5B6F104435196EF8E25A3A955C5C15A0A350A276912C143F57C819F45557A04C5A576E2266E0898E8D64BA3B7E539B642C7C13E624BC8AA299F8FC1D72C7E9DD4C5CE50DFFB762A80A3D7EF8BBEE12CDDCA3F9900A948986F64A719D5444E5D595B86F2524B0292282F6EFC2D3DB2E275FDC4D11654C878D1D74CA972B7CF6C57B2A542BE5A8F2576105C95C1376F5EBCA7A7068A60E90AA8C4B19219EC3A518E8CD809F06096ABFF526F31E86DD4127FD4CFBDAF1229CB590CF9D76ECAFB2E6B3CD43995F6EF11D692656A5EB
-20200318233140 2 6 100 7679 5 D6B6711FEDD0DAB74BE347B82AE33FB203A966E712D108C27D2983732928351D8E0B14DB0377CA10A9D079F1D76AB94AB983A67C01CADC4EEDC12F452A214B690C3823B59D05B8967A9C5FB80A78CA705620E04FD35D7BC8636A0456F5015C75B2ED2AEE4A50ED3224FB8BDEECE5C21DFC8703240AC287E4E218710091A76D19EA96FE36FB67547F45040AB5DF812D5A4391E41147087072901BE7E6618F41C2D5868424B7EC12E122A036FB5E504651DF79A120CF6698D983FD59F0203E225DE8508D72DCAA6D93492FC574B73B589189D127CF23EDFD7B319C2222239641590C6F66D25C3AD092527FBDE254131F5C13A70BC2C382671E4B940C755B617854CD3A50941DC652A8F20647C638E5F0977EA881D4770CC8381AE551A745363183752830BF4650C3741FFA8F0ED13CE0190963AFA40B61B2B9CCBD07C49A22CD6C229D43AB2E02CE5A8D2CCE45C22E237F8679D10D2543BDA0407FE3011B211B331426ACCE3B4D7DC8626B4C7D713479170BA6DC9A34F404D1C6A3EA7C04634CE61A032FC967D212B99E521CA58B7EA0E560095F1E39603C1FED48F8ED21E4D7B2D3D6F9CB34387BAD472097FC3C24203991ADE41EFDADE145D9B36E87DF128176951D3AFA12C586585C230F4DE23973B14B0291FB99A2527B87A705228DC2F0C27E6C6D01FA36E231A076C5D256B2D730424EDA55916FA3DE5E6AC1EAA5EF7FFFCF57C5577195EBBD5C3AA0448BE83BFC6853AAF9B48FA1289B276C931D4E472FF04428D02EADF12733C1E446B2DD0F1B30D1BEB4E5F36F6FF6438E7B5C51093BAED1AD02AF353DE0F447C38C1F7D10D3C6CD56DBB8EF4374E5B296BCFC2B926AC19542649DA903992F0DB5F1F41A839179F753921C9814C07924097BD850BE07A0A6ED5EECA31D391154055012C48C8000CA03790889670C2E4BE1BCE6C854C4FAB1004CC127103E59C4BF55C7A290BD44BF9EE06C18557C07D2A36D8FCDE4E1F17AD73FA570112DB3F881AD1C23D573F3F23CC5245B4D1C289F517720F444A3282BDD4D5E49B98926C13B0C45CA13BE11E55A5B6F104435196EF8E25A3A955C5C15A0A350A276912C143F57C819F45557A04C5A576E2266E0898E8D64BA3B7E539B642C7C13E624BC8AA299F8FC1D72C7E9DD4C5CE50DFFB762A80A3D7EF8BBEE12CDDCA3F9900A948986F64A719D5444E5D595B86F2524B0292282F6EFC2D3DB2E275FDC4D11654C878D1D74CA972B7CF6C57B2A542BE5A8F2576105C95C1376F5EBCA7A7068A60E90AA8C4B19219EC3A518E8CD809F06096ABFF526F31E86DD4127FD4CFBDAF1229CB590CF9D76ECAFB2E6B3CD43995F6EF11D692A61B1F7
-20200319003005 2 6 100 7679 5 D6B6711FEDD0DAB74BE347B82AE33FB203A966E712D108C27D2983732928351D8E0B14DB0377CA10A9D079F1D76AB94AB983A67C01CADC4EEDC12F452A214B690C3823B59D05B8967A9C5FB80A78CA705620E04FD35D7BC8636A0456F5015C75B2ED2AEE4A50ED3224FB8BDEECE5C21DFC8703240AC287E4E218710091A76D19EA96FE36FB67547F45040AB5DF812D5A4391E41147087072901BE7E6618F41C2D5868424B7EC12E122A036FB5E504651DF79A120CF6698D983FD59F0203E225DE8508D72DCAA6D93492FC574B73B589189D127CF23EDFD7B319C2222239641590C6F66D25C3AD092527FBDE254131F5C13A70BC2C382671E4B940C755B617854CD3A50941DC652A8F20647C638E5F0977EA881D4770CC8381AE551A745363183752830BF4650C3741FFA8F0ED13CE0190963AFA40B61B2B9CCBD07C49A22CD6C229D43AB2E02CE5A8D2CCE45C22E237F8679D10D2543BDA0407FE3011B211B331426ACCE3B4D7DC8626B4C7D713479170BA6DC9A34F404D1C6A3EA7C04634CE61A032FC967D212B99E521CA58B7EA0E560095F1E39603C1FED48F8ED21E4D7B2D3D6F9CB34387BAD472097FC3C24203991ADE41EFDADE145D9B36E87DF128176951D3AFA12C586585C230F4DE23973B14B0291FB99A2527B87A705228DC2F0C27E6C6D01FA36E231A076C5D256B2D730424EDA55916FA3DE5E6AC1EAA5EF7FFFCF57C5577195EBBD5C3AA0448BE83BFC6853AAF9B48FA1289B276C931D4E472FF04428D02EADF12733C1E446B2DD0F1B30D1BEB4E5F36F6FF6438E7B5C51093BAED1AD02AF353DE0F447C38C1F7D10D3C6CD56DBB8EF4374E5B296BCFC2B926AC19542649DA903992F0DB5F1F41A839179F753921C9814C07924097BD850BE07A0A6ED5EECA31D391154055012C48C8000CA03790889670C2E4BE1BCE6C854C4FAB1004CC127103E59C4BF55C7A290BD44BF9EE06C18557C07D2A36D8FCDE4E1F17AD73FA570112DB3F881AD1C23D573F3F23CC5245B4D1C289F517720F444A3282BDD4D5E49B98926C13B0C45CA13BE11E55A5B6F104435196EF8E25A3A955C5C15A0A350A276912C143F57C819F45557A04C5A576E2266E0898E8D64BA3B7E539B642C7C13E624BC8AA299F8FC1D72C7E9DD4C5CE50DFFB762A80A3D7EF8BBEE12CDDCA3F9900A948986F64A719D5444E5D595B86F2524B0292282F6EFC2D3DB2E275FDC4D11654C878D1D74CA972B7CF6C57B2A542BE5A8F2576105C95C1376F5EBCA7A7068A60E90AA8C4B19219EC3A518E8CD809F06096ABFF526F31E86DD4127FD4CFBDAF1229CB590CF9D76ECAFB2E6B3CD43995F6EF11D692AEDB987
-20200319094041 2 6 100 7679 2 D6B6711FEDD0DAB74BE347B82AE33FB203A966E712D108C27D2983732928351D8E0B14DB0377CA10A9D079F1D76AB94AB983A67C01CADC4EEDC12F452A214B690C3823B59D05B8967A9C5FB80A78CA705620E04FD35D7BC8636A0456F5015C75B2ED2AEE4A50ED3224FB8BDEECE5C21DFC8703240AC287E4E218710091A76D19EA96FE36FB67547F45040AB5DF812D5A4391E41147087072901BE7E6618F41C2D5868424B7EC12E122A036FB5E504651DF79A120CF6698D983FD59F0203E225DE8508D72DCAA6D93492FC574B73B589189D127CF23EDFD7B319C2222239641590C6F66D25C3AD092527FBDE254131F5C13A70BC2C382671E4B940C755B617854CD3A50941DC652A8F20647C638E5F0977EA881D4770CC8381AE551A745363183752830BF4650C3741FFA8F0ED13CE0190963AFA40B61B2B9CCBD07C49A22CD6C229D43AB2E02CE5A8D2CCE45C22E237F8679D10D2543BDA0407FE3011B211B331426ACCE3B4D7DC8626B4C7D713479170BA6DC9A34F404D1C6A3EA7C04634CE61A032FC967D212B99E521CA58B7EA0E560095F1E39603C1FED48F8ED21E4D7B2D3D6F9CB34387BAD472097FC3C24203991ADE41EFDADE145D9B36E87DF128176951D3AFA12C586585C230F4DE23973B14B0291FB99A2527B87A705228DC2F0C27E6C6D01FA36E231A076C5D256B2D730424EDA55916FA3DE5E6AC1EAA5EF7FFFCF57C5577195EBBD5C3AA0448BE83BFC6853AAF9B48FA1289B276C931D4E472FF04428D02EADF12733C1E446B2DD0F1B30D1BEB4E5F36F6FF6438E7B5C51093BAED1AD02AF353DE0F447C38C1F7D10D3C6CD56DBB8EF4374E5B296BCFC2B926AC19542649DA903992F0DB5F1F41A839179F753921C9814C07924097BD850BE07A0A6ED5EECA31D391154055012C48C8000CA03790889670C2E4BE1BCE6C854C4FAB1004CC127103E59C4BF55C7A290BD44BF9EE06C18557C07D2A36D8FCDE4E1F17AD73FA570112DB3F881AD1C23D573F3F23CC5245B4D1C289F517720F444A3282BDD4D5E49B98926C13B0C45CA13BE11E55A5B6F104435196EF8E25A3A955C5C15A0A350A276912C143F57C819F45557A04C5A576E2266E0898E8D64BA3B7E539B642C7C13E624BC8AA299F8FC1D72C7E9DD4C5CE50DFFB762A80A3D7EF8BBEE12CDDCA3F9900A948986F64A719D5444E5D595B86F2524B0292282F6EFC2D3DB2E275FDC4D11654C878D1D74CA972B7CF6C57B2A542BE5A8F2576105C95C1376F5EBCA7A7068A60E90AA8C4B19219EC3A518E8CD809F06096ABFF526F31E86DD4127FD4CFBDAF1229CB590CF9D76ECAFB2E6B3CD43995F6EF11D69307F8B33
-20200319150358 2 6 100 7679 5 D6B6711FEDD0DAB74BE347B82AE33FB203A966E712D108C27D2983732928351D8E0B14DB0377CA10A9D079F1D76AB94AB983A67C01CADC4EEDC12F452A214B690C3823B59D05B8967A9C5FB80A78CA705620E04FD35D7BC8636A0456F5015C75B2ED2AEE4A50ED3224FB8BDEECE5C21DFC8703240AC287E4E218710091A76D19EA96FE36FB67547F45040AB5DF812D5A4391E41147087072901BE7E6618F41C2D5868424B7EC12E122A036FB5E504651DF79A120CF6698D983FD59F0203E225DE8508D72DCAA6D93492FC574B73B589189D127CF23EDFD7B319C2222239641590C6F66D25C3AD092527FBDE254131F5C13A70BC2C382671E4B940C755B617854CD3A50941DC652A8F20647C638E5F0977EA881D4770CC8381AE551A745363183752830BF4650C3741FFA8F0ED13CE0190963AFA40B61B2B9CCBD07C49A22CD6C229D43AB2E02CE5A8D2CCE45C22E237F8679D10D2543BDA0407FE3011B211B331426ACCE3B4D7DC8626B4C7D713479170BA6DC9A34F404D1C6A3EA7C04634CE61A032FC967D212B99E521CA58B7EA0E560095F1E39603C1FED48F8ED21E4D7B2D3D6F9CB34387BAD472097FC3C24203991ADE41EFDADE145D9B36E87DF128176951D3AFA12C586585C230F4DE23973B14B0291FB99A2527B87A705228DC2F0C27E6C6D01FA36E231A076C5D256B2D730424EDA55916FA3DE5E6AC1EAA5EF7FFFCF57C5577195EBBD5C3AA0448BE83BFC6853AAF9B48FA1289B276C931D4E472FF04428D02EADF12733C1E446B2DD0F1B30D1BEB4E5F36F6FF6438E7B5C51093BAED1AD02AF353DE0F447C38C1F7D10D3C6CD56DBB8EF4374E5B296BCFC2B926AC19542649DA903992F0DB5F1F41A839179F753921C9814C07924097BD850BE07A0A6ED5EECA31D391154055012C48C8000CA03790889670C2E4BE1BCE6C854C4FAB1004CC127103E59C4BF55C7A290BD44BF9EE06C18557C07D2A36D8FCDE4E1F17AD73FA570112DB3F881AD1C23D573F3F23CC5245B4D1C289F517720F444A3282BDD4D5E49B98926C13B0C45CA13BE11E55A5B6F104435196EF8E25A3A955C5C15A0A350A276912C143F57C819F45557A04C5A576E2266E0898E8D64BA3B7E539B642C7C13E624BC8AA299F8FC1D72C7E9DD4C5CE50DFFB762A80A3D7EF8BBEE12CDDCA3F9900A948986F64A719D5444E5D595B86F2524B0292282F6EFC2D3DB2E275FDC4D11654C878D1D74CA972B7CF6C57B2A542BE5A8F2576105C95C1376F5EBCA7A7068A60E90AA8C4B19219EC3A518E8CD809F06096ABFF526F31E86DD4127FD4CFBDAF1229CB590CF9D76ECAFB2E6B3CD43995F6EF11D6933B4B75F
-20200319173225 2 6 100 7679 5 D6B6711FEDD0DAB74BE347B82AE33FB203A966E712D108C27D2983732928351D8E0B14DB0377CA10A9D079F1D76AB94AB983A67C01CADC4EEDC12F452A214B690C3823B59D05B8967A9C5FB80A78CA705620E04FD35D7BC8636A0456F5015C75B2ED2AEE4A50ED3224FB8BDEECE5C21DFC8703240AC287E4E218710091A76D19EA96FE36FB67547F45040AB5DF812D5A4391E41147087072901BE7E6618F41C2D5868424B7EC12E122A036FB5E504651DF79A120CF6698D983FD59F0203E225DE8508D72DCAA6D93492FC574B73B589189D127CF23EDFD7B319C2222239641590C6F66D25C3AD092527FBDE254131F5C13A70BC2C382671E4B940C755B617854CD3A50941DC652A8F20647C638E5F0977EA881D4770CC8381AE551A745363183752830BF4650C3741FFA8F0ED13CE0190963AFA40B61B2B9CCBD07C49A22CD6C229D43AB2E02CE5A8D2CCE45C22E237F8679D10D2543BDA0407FE3011B211B331426ACCE3B4D7DC8626B4C7D713479170BA6DC9A34F404D1C6A3EA7C04634CE61A032FC967D212B99E521CA58B7EA0E560095F1E39603C1FED48F8ED21E4D7B2D3D6F9CB34387BAD472097FC3C24203991ADE41EFDADE145D9B36E87DF128176951D3AFA12C586585C230F4DE23973B14B0291FB99A2527B87A705228DC2F0C27E6C6D01FA36E231A076C5D256B2D730424EDA55916FA3DE5E6AC1EAA5EF7FFFCF57C5577195EBBD5C3AA0448BE83BFC6853AAF9B48FA1289B276C931D4E472FF04428D02EADF12733C1E446B2DD0F1B30D1BEB4E5F36F6FF6438E7B5C51093BAED1AD02AF353DE0F447C38C1F7D10D3C6CD56DBB8EF4374E5B296BCFC2B926AC19542649DA903992F0DB5F1F41A839179F753921C9814C07924097BD850BE07A0A6ED5EECA31D391154055012C48C8000CA03790889670C2E4BE1BCE6C854C4FAB1004CC127103E59C4BF55C7A290BD44BF9EE06C18557C07D2A36D8FCDE4E1F17AD73FA570112DB3F881AD1C23D573F3F23CC5245B4D1C289F517720F444A3282BDD4D5E49B98926C13B0C45CA13BE11E55A5B6F104435196EF8E25A3A955C5C15A0A350A276912C143F57C819F45557A04C5A576E2266E0898E8D64BA3B7E539B642C7C13E624BC8AA299F8FC1D72C7E9DD4C5CE50DFFB762A80A3D7EF8BBEE12CDDCA3F9900A948986F64A719D5444E5D595B86F2524B0292282F6EFC2D3DB2E275FDC4D11654C878D1D74CA972B7CF6C57B2A542BE5A8F2576105C95C1376F5EBCA7A7068A60E90AA8C4B19219EC3A518E8CD809F06096ABFF526F31E86DD4127FD4CFBDAF1229CB590CF9D76ECAFB2E6B3CD43995F6EF11D69352DD107
-20200319174751 2 6 100 7679 5 D6B6711FEDD0DAB74BE347B82AE33FB203A966E712D108C27D2983732928351D8E0B14DB0377CA10A9D079F1D76AB94AB983A67C01CADC4EEDC12F452A214B690C3823B59D05B8967A9C5FB80A78CA705620E04FD35D7BC8636A0456F5015C75B2ED2AEE4A50ED3224FB8BDEECE5C21DFC8703240AC287E4E218710091A76D19EA96FE36FB67547F45040AB5DF812D5A4391E41147087072901BE7E6618F41C2D5868424B7EC12E122A036FB5E504651DF79A120CF6698D983FD59F0203E225DE8508D72DCAA6D93492FC574B73B589189D127CF23EDFD7B319C2222239641590C6F66D25C3AD092527FBDE254131F5C13A70BC2C382671E4B940C755B617854CD3A50941DC652A8F20647C638E5F0977EA881D4770CC8381AE551A745363183752830BF4650C3741FFA8F0ED13CE0190963AFA40B61B2B9CCBD07C49A22CD6C229D43AB2E02CE5A8D2CCE45C22E237F8679D10D2543BDA0407FE3011B211B331426ACCE3B4D7DC8626B4C7D713479170BA6DC9A34F404D1C6A3EA7C04634CE61A032FC967D212B99E521CA58B7EA0E560095F1E39603C1FED48F8ED21E4D7B2D3D6F9CB34387BAD472097FC3C24203991ADE41EFDADE145D9B36E87DF128176951D3AFA12C586585C230F4DE23973B14B0291FB99A2527B87A705228DC2F0C27E6C6D01FA36E231A076C5D256B2D730424EDA55916FA3DE5E6AC1EAA5EF7FFFCF57C5577195EBBD5C3AA0448BE83BFC6853AAF9B48FA1289B276C931D4E472FF04428D02EADF12733C1E446B2DD0F1B30D1BEB4E5F36F6FF6438E7B5C51093BAED1AD02AF353DE0F447C38C1F7D10D3C6CD56DBB8EF4374E5B296BCFC2B926AC19542649DA903992F0DB5F1F41A839179F753921C9814C07924097BD850BE07A0A6ED5EECA31D391154055012C48C8000CA03790889670C2E4BE1BCE6C854C4FAB1004CC127103E59C4BF55C7A290BD44BF9EE06C18557C07D2A36D8FCDE4E1F17AD73FA570112DB3F881AD1C23D573F3F23CC5245B4D1C289F517720F444A3282BDD4D5E49B98926C13B0C45CA13BE11E55A5B6F104435196EF8E25A3A955C5C15A0A350A276912C143F57C819F45557A04C5A576E2266E0898E8D64BA3B7E539B642C7C13E624BC8AA299F8FC1D72C7E9DD4C5CE50DFFB762A80A3D7EF8BBEE12CDDCA3F9900A948986F64A719D5444E5D595B86F2524B0292282F6EFC2D3DB2E275FDC4D11654C878D1D74CA972B7CF6C57B2A542BE5A8F2576105C95C1376F5EBCA7A7068A60E90AA8C4B19219EC3A518E8CD809F06096ABFF526F31E86DD4127FD4CFBDAF1229CB590CF9D76ECAFB2E6B3CD43995F6EF11D69354C2B7F
-20200320033350 2 6 100 7679 5 D6B6711FEDD0DAB74BE347B82AE33FB203A966E712D108C27D2983732928351D8E0B14DB0377CA10A9D079F1D76AB94AB983A67C01CADC4EEDC12F452A214B690C3823B59D05B8967A9C5FB80A78CA705620E04FD35D7BC8636A0456F5015C75B2ED2AEE4A50ED3224FB8BDEECE5C21DFC8703240AC287E4E218710091A76D19EA96FE36FB67547F45040AB5DF812D5A4391E41147087072901BE7E6618F41C2D5868424B7EC12E122A036FB5E504651DF79A120CF6698D983FD59F0203E225DE8508D72DCAA6D93492FC574B73B589189D127CF23EDFD7B319C2222239641590C6F66D25C3AD092527FBDE254131F5C13A70BC2C382671E4B940C755B617854CD3A50941DC652A8F20647C638E5F0977EA881D4770CC8381AE551A745363183752830BF4650C3741FFA8F0ED13CE0190963AFA40B61B2B9CCBD07C49A22CD6C229D43AB2E02CE5A8D2CCE45C22E237F8679D10D2543BDA0407FE3011B211B331426ACCE3B4D7DC8626B4C7D713479170BA6DC9A34F404D1C6A3EA7C04634CE61A032FC967D212B99E521CA58B7EA0E560095F1E39603C1FED48F8ED21E4D7B2D3D6F9CB34387BAD472097FC3C24203991ADE41EFDADE145D9B36E87DF128176951D3AFA12C586585C230F4DE23973B14B0291FB99A2527B87A705228DC2F0C27E6C6D01FA36E231A076C5D256B2D730424EDA55916FA3DE5E6AC1EAA5EF7FFFCF57C5577195EBBD5C3AA0448BE83BFC6853AAF9B48FA1289B276C931D4E472FF04428D02EADF12733C1E446B2DD0F1B30D1BEB4E5F36F6FF6438E7B5C51093BAED1AD02AF353DE0F447C38C1F7D10D3C6CD56DBB8EF4374E5B296BCFC2B926AC19542649DA903992F0DB5F1F41A839179F753921C9814C07924097BD850BE07A0A6ED5EECA31D391154055012C48C8000CA03790889670C2E4BE1BCE6C854C4FAB1004CC127103E59C4BF55C7A290BD44BF9EE06C18557C07D2A36D8FCDE4E1F17AD73FA570112DB3F881AD1C23D573F3F23CC5245B4D1C289F517720F444A3282BDD4D5E49B98926C13B0C45CA13BE11E55A5B6F104435196EF8E25A3A955C5C15A0A350A276912C143F57C819F45557A04C5A576E2266E0898E8D64BA3B7E539B642C7C13E624BC8AA299F8FC1D72C7E9DD4C5CE50DFFB762A80A3D7EF8BBEE12CDDCA3F9900A948986F64A719D5444E5D595B86F2524B0292282F6EFC2D3DB2E275FDC4D11654C878D1D74CA972B7CF6C57B2A542BE5A8F2576105C95C1376F5EBCA7A7068A60E90AA8C4B19219EC3A518E8CD809F06096ABFF526F31E86DD4127FD4CFBDAF1229CB590CF9D76ECAFB2E6B3CD43995F6EF11D6938CB4C9F
-20200320090847 2 6 100 7679 5 D6B6711FEDD0DAB74BE347B82AE33FB203A966E712D108C27D2983732928351D8E0B14DB0377CA10A9D079F1D76AB94AB983A67C01CADC4EEDC12F452A214B690C3823B59D05B8967A9C5FB80A78CA705620E04FD35D7BC8636A0456F5015C75B2ED2AEE4A50ED3224FB8BDEECE5C21DFC8703240AC287E4E218710091A76D19EA96FE36FB67547F45040AB5DF812D5A4391E41147087072901BE7E6618F41C2D5868424B7EC12E122A036FB5E504651DF79A120CF6698D983FD59F0203E225DE8508D72DCAA6D93492FC574B73B589189D127CF23EDFD7B319C2222239641590C6F66D25C3AD092527FBDE254131F5C13A70BC2C382671E4B940C755B617854CD3A50941DC652A8F20647C638E5F0977EA881D4770CC8381AE551A745363183752830BF4650C3741FFA8F0ED13CE0190963AFA40B61B2B9CCBD07C49A22CD6C229D43AB2E02CE5A8D2CCE45C22E237F8679D10D2543BDA0407FE3011B211B331426ACCE3B4D7DC8626B4C7D713479170BA6DC9A34F404D1C6A3EA7C04634CE61A032FC967D212B99E521CA58B7EA0E560095F1E39603C1FED48F8ED21E4D7B2D3D6F9CB34387BAD472097FC3C24203991ADE41EFDADE145D9B36E87DF128176951D3AFA12C586585C230F4DE23973B14B0291FB99A2527B87A705228DC2F0C27E6C6D01FA36E231A076C5D256B2D730424EDA55916FA3DE5E6AC1EAA5EF7FFFCF57C5577195EBBD5C3AA0448BE83BFC6853AAF9B48FA1289B276C931D4E472FF04428D02EADF12733C1E446B2DD0F1B30D1BEB4E5F36F6FF6438E7B5C51093BAED1AD02AF353DE0F447C38C1F7D10D3C6CD56DBB8EF4374E5B296BCFC2B926AC19542649DA903992F0DB5F1F41A839179F753921C9814C07924097BD850BE07A0A6ED5EECA31D391154055012C48C8000CA03790889670C2E4BE1BCE6C854C4FAB1004CC127103E59C4BF55C7A290BD44BF9EE06C18557C07D2A36D8FCDE4E1F17AD73FA570112DB3F881AD1C23D573F3F23CC5245B4D1C289F517720F444A3282BDD4D5E49B98926C13B0C45CA13BE11E55A5B6F104435196EF8E25A3A955C5C15A0A350A276912C143F57C819F45557A04C5A576E2266E0898E8D64BA3B7E539B642C7C13E624BC8AA299F8FC1D72C7E9DD4C5CE50DFFB762A80A3D7EF8BBEE12CDDCA3F9900A948986F64A719D5444E5D595B86F2524B0292282F6EFC2D3DB2E275FDC4D11654C878D1D74CA972B7CF6C57B2A542BE5A8F2576105C95C1376F5EBCA7A7068A60E90AA8C4B19219EC3A518E8CD809F06096ABFF526F31E86DD4127FD4CFBDAF1229CB590CF9D76ECAFB2E6B3CD43995F6EF11D693C17966F
-20200321110636 2 6 100 7679 5 D6B6711FEDD0DAB74BE347B82AE33FB203A966E712D108C27D2983732928351D8E0B14DB0377CA10A9D079F1D76AB94AB983A67C01CADC4EEDC12F452A214B690C3823B59D05B8967A9C5FB80A78CA705620E04FD35D7BC8636A0456F5015C75B2ED2AEE4A50ED3224FB8BDEECE5C21DFC8703240AC287E4E218710091A76D19EA96FE36FB67547F45040AB5DF812D5A4391E41147087072901BE7E6618F41C2D5868424B7EC12E122A036FB5E504651DF79A120CF6698D983FD59F0203E225DE8508D72DCAA6D93492FC574B73B589189D127CF23EDFD7B319C2222239641590C6F66D25C3AD092527FBDE254131F5C13A70BC2C382671E4B940C755B617854CD3A50941DC652A8F20647C638E5F0977EA881D4770CC8381AE551A745363183752830BF4650C3741FFA8F0ED13CE0190963AFA40B61B2B9CCBD07C49A22CD6C229D43AB2E02CE5A8D2CCE45C22E237F8679D10D2543BDA0407FE3011B211B331426ACCE3B4D7DC8626B4C7D713479170BA6DC9A34F404D1C6A3EA7C04634CE61A032FC967D212B99E521CA58B7EA0E560095F1E39603C1FED48F8ED21E4D7B2D3D6F9CB34387BAD472097FC3C24203991ADE41EFDADE145D9B36E87DF128176951D3AFA12C586585C230F4DE23973B14B0291FB99A2527B87A705228DC2F0C27E6C6D01FA36E231A076C5D256B2D730424EDA55916FA3DE5E6AC1EAA5EF7FFFCF57C5577195EBBD5C3AA0448BE83BFC6853AAF9B48FA1289B276C931D4E472FF04428D02EADF12733C1E446B2DD0F1B30D1BEB4E5F36F6FF6438E7B5C51093BAED1AD02AF353DE0F447C38C1F7D10D3C6CD56DBB8EF4374E5B296BCFC2B926AC19542649DA903992F0DB5F1F41A839179F753921C9814C07924097BD850BE07A0A6ED5EECA31D391154055012C48C8000CA03790889670C2E4BE1BCE6C854C4FAB1004CC127103E59C4BF55C7A290BD44BF9EE06C18557C07D2A36D8FCDE4E1F17AD73FA570112DB3F881AD1C23D573F3F23CC5245B4D1C289F517720F444A3282BDD4D5E49B98926C13B0C45CA13BE11E55A5B6F104435196EF8E25A3A955C5C15A0A350A276912C143F57C819F45557A04C5A576E2266E0898E8D64BA3B7E539B642C7C13E624BC8AA299F8FC1D72C7E9DD4C5CE50DFFB762A80A3D7EF8BBEE12CDDCA3F9900A948986F64A719D5444E5D595B86F2524B0292282F6EFC2D3DB2E275FDC4D11654C878D1D74CA972B7CF6C57B2A542BE5A8F2576105C95C1376F5EBCA7A7068A60E90AA8C4B19219EC3A518E8CD809F06096ABFF526F31E86DD4127FD4CFBDAF1229CB590CF9D76ECAFB2E6B3CD43995F6EF11D694B3E8EEF
-20200321132757 2 6 100 7679 2 D6B6711FEDD0DAB74BE347B82AE33FB203A966E712D108C27D2983732928351D8E0B14DB0377CA10A9D079F1D76AB94AB983A67C01CADC4EEDC12F452A214B690C3823B59D05B8967A9C5FB80A78CA705620E04FD35D7BC8636A0456F5015C75B2ED2AEE4A50ED3224FB8BDEECE5C21DFC8703240AC287E4E218710091A76D19EA96FE36FB67547F45040AB5DF812D5A4391E41147087072901BE7E6618F41C2D5868424B7EC12E122A036FB5E504651DF79A120CF6698D983FD59F0203E225DE8508D72DCAA6D93492FC574B73B589189D127CF23EDFD7B319C2222239641590C6F66D25C3AD092527FBDE254131F5C13A70BC2C382671E4B940C755B617854CD3A50941DC652A8F20647C638E5F0977EA881D4770CC8381AE551A745363183752830BF4650C3741FFA8F0ED13CE0190963AFA40B61B2B9CCBD07C49A22CD6C229D43AB2E02CE5A8D2CCE45C22E237F8679D10D2543BDA0407FE3011B211B331426ACCE3B4D7DC8626B4C7D713479170BA6DC9A34F404D1C6A3EA7C04634CE61A032FC967D212B99E521CA58B7EA0E560095F1E39603C1FED48F8ED21E4D7B2D3D6F9CB34387BAD472097FC3C24203991ADE41EFDADE145D9B36E87DF128176951D3AFA12C586585C230F4DE23973B14B0291FB99A2527B87A705228DC2F0C27E6C6D01FA36E231A076C5D256B2D730424EDA55916FA3DE5E6AC1EAA5EF7FFFCF57C5577195EBBD5C3AA0448BE83BFC6853AAF9B48FA1289B276C931D4E472FF04428D02EADF12733C1E446B2DD0F1B30D1BEB4E5F36F6FF6438E7B5C51093BAED1AD02AF353DE0F447C38C1F7D10D3C6CD56DBB8EF4374E5B296BCFC2B926AC19542649DA903992F0DB5F1F41A839179F753921C9814C07924097BD850BE07A0A6ED5EECA31D391154055012C48C8000CA03790889670C2E4BE1BCE6C854C4FAB1004CC127103E59C4BF55C7A290BD44BF9EE06C18557C07D2A36D8FCDE4E1F17AD73FA570112DB3F881AD1C23D573F3F23CC5245B4D1C289F517720F444A3282BDD4D5E49B98926C13B0C45CA13BE11E55A5B6F104435196EF8E25A3A955C5C15A0A350A276912C143F57C819F45557A04C5A576E2266E0898E8D64BA3B7E539B642C7C13E624BC8AA299F8FC1D72C7E9DD4C5CE50DFFB762A80A3D7EF8BBEE12CDDCA3F9900A948986F64A719D5444E5D595B86F2524B0292282F6EFC2D3DB2E275FDC4D11654C878D1D74CA972B7CF6C57B2A542BE5A8F2576105C95C1376F5EBCA7A7068A60E90AA8C4B19219EC3A518E8CD809F06096ABFF526F31E86DD4127FD4CFBDAF1229CB590CF9D76ECAFB2E6B3CD43995F6EF11D694C8DCF73
-20200322034802 2 6 100 7679 5 D6B6711FEDD0DAB74BE347B82AE33FB203A966E712D108C27D2983732928351D8E0B14DB0377CA10A9D079F1D76AB94AB983A67C01CADC4EEDC12F452A214B690C3823B59D05B8967A9C5FB80A78CA705620E04FD35D7BC8636A0456F5015C75B2ED2AEE4A50ED3224FB8BDEECE5C21DFC8703240AC287E4E218710091A76D19EA96FE36FB67547F45040AB5DF812D5A4391E41147087072901BE7E6618F41C2D5868424B7EC12E122A036FB5E504651DF79A120CF6698D983FD59F0203E225DE8508D72DCAA6D93492FC574B73B589189D127CF23EDFD7B319C2222239641590C6F66D25C3AD092527FBDE254131F5C13A70BC2C382671E4B940C755B617854CD3A50941DC652A8F20647C638E5F0977EA881D4770CC8381AE551A745363183752830BF4650C3741FFA8F0ED13CE0190963AFA40B61B2B9CCBD07C49A22CD6C229D43AB2E02CE5A8D2CCE45C22E237F8679D10D2543BDA0407FE3011B211B331426ACCE3B4D7DC8626B4C7D713479170BA6DC9A34F404D1C6A3EA7C04634CE61A032FC967D212B99E521CA58B7EA0E560095F1E39603C1FED48F8ED21E4D7B2D3D6F9CB34387BAD472097FC3C24203991ADE41EFDADE145D9B36E87DF128176951D3AFA12C586585C230F4DE23973B14B0291FB99A2527B87A705228DC2F0C27E6C6D01FA36E231A076C5D256B2D730424EDA55916FA3DE5E6AC1EAA5EF7FFFCF57C5577195EBBD5C3AA0448BE83BFC6853AAF9B48FA1289B276C931D4E472FF04428D02EADF12733C1E446B2DD0F1B30D1BEB4E5F36F6FF6438E7B5C51093BAED1AD02AF353DE0F447C38C1F7D10D3C6CD56DBB8EF4374E5B296BCFC2B926AC19542649DA903992F0DB5F1F41A839179F753921C9814C07924097BD850BE07A0A6ED5EECA31D391154055012C48C8000CA03790889670C2E4BE1BCE6C854C4FAB1004CC127103E59C4BF55C7A290BD44BF9EE06C18557C07D2A36D8FCDE4E1F17AD73FA570112DB3F881AD1C23D573F3F23CC5245B4D1C289F517720F444A3282BDD4D5E49B98926C13B0C45CA13BE11E55A5B6F104435196EF8E25A3A955C5C15A0A350A276912C143F57C819F45557A04C5A576E2266E0898E8D64BA3B7E539B642C7C13E624BC8AA299F8FC1D72C7E9DD4C5CE50DFFB762A80A3D7EF8BBEE12CDDCA3F9900A948986F64A719D5444E5D595B86F2524B0292282F6EFC2D3DB2E275FDC4D11654C878D1D74CA972B7CF6C57B2A542BE5A8F2576105C95C1376F5EBCA7A7068A60E90AA8C4B19219EC3A518E8CD809F06096ABFF526F31E86DD4127FD4CFBDAF1229CB590CF9D76ECAFB2E6B3CD43995F6EF11D69549685F7
-20200322064543 2 6 100 7679 5 D6B6711FEDD0DAB74BE347B82AE33FB203A966E712D108C27D2983732928351D8E0B14DB0377CA10A9D079F1D76AB94AB983A67C01CADC4EEDC12F452A214B690C3823B59D05B8967A9C5FB80A78CA705620E04FD35D7BC8636A0456F5015C75B2ED2AEE4A50ED3224FB8BDEECE5C21DFC8703240AC287E4E218710091A76D19EA96FE36FB67547F45040AB5DF812D5A4391E41147087072901BE7E6618F41C2D5868424B7EC12E122A036FB5E504651DF79A120CF6698D983FD59F0203E225DE8508D72DCAA6D93492FC574B73B589189D127CF23EDFD7B319C2222239641590C6F66D25C3AD092527FBDE254131F5C13A70BC2C382671E4B940C755B617854CD3A50941DC652A8F20647C638E5F0977EA881D4770CC8381AE551A745363183752830BF4650C3741FFA8F0ED13CE0190963AFA40B61B2B9CCBD07C49A22CD6C229D43AB2E02CE5A8D2CCE45C22E237F8679D10D2543BDA0407FE3011B211B331426ACCE3B4D7DC8626B4C7D713479170BA6DC9A34F404D1C6A3EA7C04634CE61A032FC967D212B99E521CA58B7EA0E560095F1E39603C1FED48F8ED21E4D7B2D3D6F9CB34387BAD472097FC3C24203991ADE41EFDADE145D9B36E87DF128176951D3AFA12C586585C230F4DE23973B14B0291FB99A2527B87A705228DC2F0C27E6C6D01FA36E231A076C5D256B2D730424EDA55916FA3DE5E6AC1EAA5EF7FFFCF57C5577195EBBD5C3AA0448BE83BFC6853AAF9B48FA1289B276C931D4E472FF04428D02EADF12733C1E446B2DD0F1B30D1BEB4E5F36F6FF6438E7B5C51093BAED1AD02AF353DE0F447C38C1F7D10D3C6CD56DBB8EF4374E5B296BCFC2B926AC19542649DA903992F0DB5F1F41A839179F753921C9814C07924097BD850BE07A0A6ED5EECA31D391154055012C48C8000CA03790889670C2E4BE1BCE6C854C4FAB1004CC127103E59C4BF55C7A290BD44BF9EE06C18557C07D2A36D8FCDE4E1F17AD73FA570112DB3F881AD1C23D573F3F23CC5245B4D1C289F517720F444A3282BDD4D5E49B98926C13B0C45CA13BE11E55A5B6F104435196EF8E25A3A955C5C15A0A350A276912C143F57C819F45557A04C5A576E2266E0898E8D64BA3B7E539B642C7C13E624BC8AA299F8FC1D72C7E9DD4C5CE50DFFB762A80A3D7EF8BBEE12CDDCA3F9900A948986F64A719D5444E5D595B86F2524B0292282F6EFC2D3DB2E275FDC4D11654C878D1D74CA972B7CF6C57B2A542BE5A8F2576105C95C1376F5EBCA7A7068A60E90AA8C4B19219EC3A518E8CD809F06096ABFF526F31E86DD4127FD4CFBDAF1229CB590CF9D76ECAFB2E6B3CD43995F6EF11D6956401F07
-20200322080953 2 6 100 7679 2 D6B6711FEDD0DAB74BE347B82AE33FB203A966E712D108C27D2983732928351D8E0B14DB0377CA10A9D079F1D76AB94AB983A67C01CADC4EEDC12F452A214B690C3823B59D05B8967A9C5FB80A78CA705620E04FD35D7BC8636A0456F5015C75B2ED2AEE4A50ED3224FB8BDEECE5C21DFC8703240AC287E4E218710091A76D19EA96FE36FB67547F45040AB5DF812D5A4391E41147087072901BE7E6618F41C2D5868424B7EC12E122A036FB5E504651DF79A120CF6698D983FD59F0203E225DE8508D72DCAA6D93492FC574B73B589189D127CF23EDFD7B319C2222239641590C6F66D25C3AD092527FBDE254131F5C13A70BC2C382671E4B940C755B617854CD3A50941DC652A8F20647C638E5F0977EA881D4770CC8381AE551A745363183752830BF4650C3741FFA8F0ED13CE0190963AFA40B61B2B9CCBD07C49A22CD6C229D43AB2E02CE5A8D2CCE45C22E237F8679D10D2543BDA0407FE3011B211B331426ACCE3B4D7DC8626B4C7D713479170BA6DC9A34F404D1C6A3EA7C04634CE61A032FC967D212B99E521CA58B7EA0E560095F1E39603C1FED48F8ED21E4D7B2D3D6F9CB34387BAD472097FC3C24203991ADE41EFDADE145D9B36E87DF128176951D3AFA12C586585C230F4DE23973B14B0291FB99A2527B87A705228DC2F0C27E6C6D01FA36E231A076C5D256B2D730424EDA55916FA3DE5E6AC1EAA5EF7FFFCF57C5577195EBBD5C3AA0448BE83BFC6853AAF9B48FA1289B276C931D4E472FF04428D02EADF12733C1E446B2DD0F1B30D1BEB4E5F36F6FF6438E7B5C51093BAED1AD02AF353DE0F447C38C1F7D10D3C6CD56DBB8EF4374E5B296BCFC2B926AC19542649DA903992F0DB5F1F41A839179F753921C9814C07924097BD850BE07A0A6ED5EECA31D391154055012C48C8000CA03790889670C2E4BE1BCE6C854C4FAB1004CC127103E59C4BF55C7A290BD44BF9EE06C18557C07D2A36D8FCDE4E1F17AD73FA570112DB3F881AD1C23D573F3F23CC5245B4D1C289F517720F444A3282BDD4D5E49B98926C13B0C45CA13BE11E55A5B6F104435196EF8E25A3A955C5C15A0A350A276912C143F57C819F45557A04C5A576E2266E0898E8D64BA3B7E539B642C7C13E624BC8AA299F8FC1D72C7E9DD4C5CE50DFFB762A80A3D7EF8BBEE12CDDCA3F9900A948986F64A719D5444E5D595B86F2524B0292282F6EFC2D3DB2E275FDC4D11654C878D1D74CA972B7CF6C57B2A542BE5A8F2576105C95C1376F5EBCA7A7068A60E90AA8C4B19219EC3A518E8CD809F06096ABFF526F31E86DD4127FD4CFBDAF1229CB590CF9D76ECAFB2E6B3CD43995F6EF11D69570A66EB
-20200322105224 2 6 100 7679 5 D6B6711FEDD0DAB74BE347B82AE33FB203A966E712D108C27D2983732928351D8E0B14DB0377CA10A9D079F1D76AB94AB983A67C01CADC4EEDC12F452A214B690C3823B59D05B8967A9C5FB80A78CA705620E04FD35D7BC8636A0456F5015C75B2ED2AEE4A50ED3224FB8BDEECE5C21DFC8703240AC287E4E218710091A76D19EA96FE36FB67547F45040AB5DF812D5A4391E41147087072901BE7E6618F41C2D5868424B7EC12E122A036FB5E504651DF79A120CF6698D983FD59F0203E225DE8508D72DCAA6D93492FC574B73B589189D127CF23EDFD7B319C2222239641590C6F66D25C3AD092527FBDE254131F5C13A70BC2C382671E4B940C755B617854CD3A50941DC652A8F20647C638E5F0977EA881D4770CC8381AE551A745363183752830BF4650C3741FFA8F0ED13CE0190963AFA40B61B2B9CCBD07C49A22CD6C229D43AB2E02CE5A8D2CCE45C22E237F8679D10D2543BDA0407FE3011B211B331426ACCE3B4D7DC8626B4C7D713479170BA6DC9A34F404D1C6A3EA7C04634CE61A032FC967D212B99E521CA58B7EA0E560095F1E39603C1FED48F8ED21E4D7B2D3D6F9CB34387BAD472097FC3C24203991ADE41EFDADE145D9B36E87DF128176951D3AFA12C586585C230F4DE23973B14B0291FB99A2527B87A705228DC2F0C27E6C6D01FA36E231A076C5D256B2D730424EDA55916FA3DE5E6AC1EAA5EF7FFFCF57C5577195EBBD5C3AA0448BE83BFC6853AAF9B48FA1289B276C931D4E472FF04428D02EADF12733C1E446B2DD0F1B30D1BEB4E5F36F6FF6438E7B5C51093BAED1AD02AF353DE0F447C38C1F7D10D3C6CD56DBB8EF4374E5B296BCFC2B926AC19542649DA903992F0DB5F1F41A839179F753921C9814C07924097BD850BE07A0A6ED5EECA31D391154055012C48C8000CA03790889670C2E4BE1BCE6C854C4FAB1004CC127103E59C4BF55C7A290BD44BF9EE06C18557C07D2A36D8FCDE4E1F17AD73FA570112DB3F881AD1C23D573F3F23CC5245B4D1C289F517720F444A3282BDD4D5E49B98926C13B0C45CA13BE11E55A5B6F104435196EF8E25A3A955C5C15A0A350A276912C143F57C819F45557A04C5A576E2266E0898E8D64BA3B7E539B642C7C13E624BC8AA299F8FC1D72C7E9DD4C5CE50DFFB762A80A3D7EF8BBEE12CDDCA3F9900A948986F64A719D5444E5D595B86F2524B0292282F6EFC2D3DB2E275FDC4D11654C878D1D74CA972B7CF6C57B2A542BE5A8F2576105C95C1376F5EBCA7A7068A60E90AA8C4B19219EC3A518E8CD809F06096ABFF526F31E86DD4127FD4CFBDAF1229CB590CF9D76ECAFB2E6B3CD43995F6EF11D69588D739F
-20200322200820 2 6 100 7679 2 D6B6711FEDD0DAB74BE347B82AE33FB203A966E712D108C27D2983732928351D8E0B14DB0377CA10A9D079F1D76AB94AB983A67C01CADC4EEDC12F452A214B690C3823B59D05B8967A9C5FB80A78CA705620E04FD35D7BC8636A0456F5015C75B2ED2AEE4A50ED3224FB8BDEECE5C21DFC8703240AC287E4E218710091A76D19EA96FE36FB67547F45040AB5DF812D5A4391E41147087072901BE7E6618F41C2D5868424B7EC12E122A036FB5E504651DF79A120CF6698D983FD59F0203E225DE8508D72DCAA6D93492FC574B73B589189D127CF23EDFD7B319C2222239641590C6F66D25C3AD092527FBDE254131F5C13A70BC2C382671E4B940C755B617854CD3A50941DC652A8F20647C638E5F0977EA881D4770CC8381AE551A745363183752830BF4650C3741FFA8F0ED13CE0190963AFA40B61B2B9CCBD07C49A22CD6C229D43AB2E02CE5A8D2CCE45C22E237F8679D10D2543BDA0407FE3011B211B331426ACCE3B4D7DC8626B4C7D713479170BA6DC9A34F404D1C6A3EA7C04634CE61A032FC967D212B99E521CA58B7EA0E560095F1E39603C1FED48F8ED21E4D7B2D3D6F9CB34387BAD472097FC3C24203991ADE41EFDADE145D9B36E87DF128176951D3AFA12C586585C230F4DE23973B14B0291FB99A2527B87A705228DC2F0C27E6C6D01FA36E231A076C5D256B2D730424EDA55916FA3DE5E6AC1EAA5EF7FFFCF57C5577195EBBD5C3AA0448BE83BFC6853AAF9B48FA1289B276C931D4E472FF04428D02EADF12733C1E446B2DD0F1B30D1BEB4E5F36F6FF6438E7B5C51093BAED1AD02AF353DE0F447C38C1F7D10D3C6CD56DBB8EF4374E5B296BCFC2B926AC19542649DA903992F0DB5F1F41A839179F753921C9814C07924097BD850BE07A0A6ED5EECA31D391154055012C48C8000CA03790889670C2E4BE1BCE6C854C4FAB1004CC127103E59C4BF55C7A290BD44BF9EE06C18557C07D2A36D8FCDE4E1F17AD73FA570112DB3F881AD1C23D573F3F23CC5245B4D1C289F517720F444A3282BDD4D5E49B98926C13B0C45CA13BE11E55A5B6F104435196EF8E25A3A955C5C15A0A350A276912C143F57C819F45557A04C5A576E2266E0898E8D64BA3B7E539B642C7C13E624BC8AA299F8FC1D72C7E9DD4C5CE50DFFB762A80A3D7EF8BBEE12CDDCA3F9900A948986F64A719D5444E5D595B86F2524B0292282F6EFC2D3DB2E275FDC4D11654C878D1D74CA972B7CF6C57B2A542BE5A8F2576105C95C1376F5EBCA7A7068A60E90AA8C4B19219EC3A518E8CD809F06096ABFF526F31E86DD4127FD4CFBDAF1229CB590CF9D76ECAFB2E6B3CD43995F6EF11D695D952E9B
-20200322211734 2 6 100 7679 2 D6B6711FEDD0DAB74BE347B82AE33FB203A966E712D108C27D2983732928351D8E0B14DB0377CA10A9D079F1D76AB94AB983A67C01CADC4EEDC12F452A214B690C3823B59D05B8967A9C5FB80A78CA705620E04FD35D7BC8636A0456F5015C75B2ED2AEE4A50ED3224FB8BDEECE5C21DFC8703240AC287E4E218710091A76D19EA96FE36FB67547F45040AB5DF812D5A4391E41147087072901BE7E6618F41C2D5868424B7EC12E122A036FB5E504651DF79A120CF6698D983FD59F0203E225DE8508D72DCAA6D93492FC574B73B589189D127CF23EDFD7B319C2222239641590C6F66D25C3AD092527FBDE254131F5C13A70BC2C382671E4B940C755B617854CD3A50941DC652A8F20647C638E5F0977EA881D4770CC8381AE551A745363183752830BF4650C3741FFA8F0ED13CE0190963AFA40B61B2B9CCBD07C49A22CD6C229D43AB2E02CE5A8D2CCE45C22E237F8679D10D2543BDA0407FE3011B211B331426ACCE3B4D7DC8626B4C7D713479170BA6DC9A34F404D1C6A3EA7C04634CE61A032FC967D212B99E521CA58B7EA0E560095F1E39603C1FED48F8ED21E4D7B2D3D6F9CB34387BAD472097FC3C24203991ADE41EFDADE145D9B36E87DF128176951D3AFA12C586585C230F4DE23973B14B0291FB99A2527B87A705228DC2F0C27E6C6D01FA36E231A076C5D256B2D730424EDA55916FA3DE5E6AC1EAA5EF7FFFCF57C5577195EBBD5C3AA0448BE83BFC6853AAF9B48FA1289B276C931D4E472FF04428D02EADF12733C1E446B2DD0F1B30D1BEB4E5F36F6FF6438E7B5C51093BAED1AD02AF353DE0F447C38C1F7D10D3C6CD56DBB8EF4374E5B296BCFC2B926AC19542649DA903992F0DB5F1F41A839179F753921C9814C07924097BD850BE07A0A6ED5EECA31D391154055012C48C8000CA03790889670C2E4BE1BCE6C854C4FAB1004CC127103E59C4BF55C7A290BD44BF9EE06C18557C07D2A36D8FCDE4E1F17AD73FA570112DB3F881AD1C23D573F3F23CC5245B4D1C289F517720F444A3282BDD4D5E49B98926C13B0C45CA13BE11E55A5B6F104435196EF8E25A3A955C5C15A0A350A276912C143F57C819F45557A04C5A576E2266E0898E8D64BA3B7E539B642C7C13E624BC8AA299F8FC1D72C7E9DD4C5CE50DFFB762A80A3D7EF8BBEE12CDDCA3F9900A948986F64A719D5444E5D595B86F2524B0292282F6EFC2D3DB2E275FDC4D11654C878D1D74CA972B7CF6C57B2A542BE5A8F2576105C95C1376F5EBCA7A7068A60E90AA8C4B19219EC3A518E8CD809F06096ABFF526F31E86DD4127FD4CFBDAF1229CB590CF9D76ECAFB2E6B3CD43995F6EF11D695E28F8A3
-20200323000631 2 6 100 7679 5 D6B6711FEDD0DAB74BE347B82AE33FB203A966E712D108C27D2983732928351D8E0B14DB0377CA10A9D079F1D76AB94AB983A67C01CADC4EEDC12F452A214B690C3823B59D05B8967A9C5FB80A78CA705620E04FD35D7BC8636A0456F5015C75B2ED2AEE4A50ED3224FB8BDEECE5C21DFC8703240AC287E4E218710091A76D19EA96FE36FB67547F45040AB5DF812D5A4391E41147087072901BE7E6618F41C2D5868424B7EC12E122A036FB5E504651DF79A120CF6698D983FD59F0203E225DE8508D72DCAA6D93492FC574B73B589189D127CF23EDFD7B319C2222239641590C6F66D25C3AD092527FBDE254131F5C13A70BC2C382671E4B940C755B617854CD3A50941DC652A8F20647C638E5F0977EA881D4770CC8381AE551A745363183752830BF4650C3741FFA8F0ED13CE0190963AFA40B61B2B9CCBD07C49A22CD6C229D43AB2E02CE5A8D2CCE45C22E237F8679D10D2543BDA0407FE3011B211B331426ACCE3B4D7DC8626B4C7D713479170BA6DC9A34F404D1C6A3EA7C04634CE61A032FC967D212B99E521CA58B7EA0E560095F1E39603C1FED48F8ED21E4D7B2D3D6F9CB34387BAD472097FC3C24203991ADE41EFDADE145D9B36E87DF128176951D3AFA12C586585C230F4DE23973B14B0291FB99A2527B87A705228DC2F0C27E6C6D01FA36E231A076C5D256B2D730424EDA55916FA3DE5E6AC1EAA5EF7FFFCF57C5577195EBBD5C3AA0448BE83BFC6853AAF9B48FA1289B276C931D4E472FF04428D02EADF12733C1E446B2DD0F1B30D1BEB4E5F36F6FF6438E7B5C51093BAED1AD02AF353DE0F447C38C1F7D10D3C6CD56DBB8EF4374E5B296BCFC2B926AC19542649DA903992F0DB5F1F41A839179F753921C9814C07924097BD850BE07A0A6ED5EECA31D391154055012C48C8000CA03790889670C2E4BE1BCE6C854C4FAB1004CC127103E59C4BF55C7A290BD44BF9EE06C18557C07D2A36D8FCDE4E1F17AD73FA570112DB3F881AD1C23D573F3F23CC5245B4D1C289F517720F444A3282BDD4D5E49B98926C13B0C45CA13BE11E55A5B6F104435196EF8E25A3A955C5C15A0A350A276912C143F57C819F45557A04C5A576E2266E0898E8D64BA3B7E539B642C7C13E624BC8AA299F8FC1D72C7E9DD4C5CE50DFFB762A80A3D7EF8BBEE12CDDCA3F9900A948986F64A719D5444E5D595B86F2524B0292282F6EFC2D3DB2E275FDC4D11654C878D1D74CA972B7CF6C57B2A542BE5A8F2576105C95C1376F5EBCA7A7068A60E90AA8C4B19219EC3A518E8CD809F06096ABFF526F31E86DD4127FD4CFBDAF1229CB590CF9D76ECAFB2E6B3CD43995F6EF11D695F9BBADF
-20200323010937 2 6 100 7679 2 D6B6711FEDD0DAB74BE347B82AE33FB203A966E712D108C27D2983732928351D8E0B14DB0377CA10A9D079F1D76AB94AB983A67C01CADC4EEDC12F452A214B690C3823B59D05B8967A9C5FB80A78CA705620E04FD35D7BC8636A0456F5015C75B2ED2AEE4A50ED3224FB8BDEECE5C21DFC8703240AC287E4E218710091A76D19EA96FE36FB67547F45040AB5DF812D5A4391E41147087072901BE7E6618F41C2D5868424B7EC12E122A036FB5E504651DF79A120CF6698D983FD59F0203E225DE8508D72DCAA6D93492FC574B73B589189D127CF23EDFD7B319C2222239641590C6F66D25C3AD092527FBDE254131F5C13A70BC2C382671E4B940C755B617854CD3A50941DC652A8F20647C638E5F0977EA881D4770CC8381AE551A745363183752830BF4650C3741FFA8F0ED13CE0190963AFA40B61B2B9CCBD07C49A22CD6C229D43AB2E02CE5A8D2CCE45C22E237F8679D10D2543BDA0407FE3011B211B331426ACCE3B4D7DC8626B4C7D713479170BA6DC9A34F404D1C6A3EA7C04634CE61A032FC967D212B99E521CA58B7EA0E560095F1E39603C1FED48F8ED21E4D7B2D3D6F9CB34387BAD472097FC3C24203991ADE41EFDADE145D9B36E87DF128176951D3AFA12C586585C230F4DE23973B14B0291FB99A2527B87A705228DC2F0C27E6C6D01FA36E231A076C5D256B2D730424EDA55916FA3DE5E6AC1EAA5EF7FFFCF57C5577195EBBD5C3AA0448BE83BFC6853AAF9B48FA1289B276C931D4E472FF04428D02EADF12733C1E446B2DD0F1B30D1BEB4E5F36F6FF6438E7B5C51093BAED1AD02AF353DE0F447C38C1F7D10D3C6CD56DBB8EF4374E5B296BCFC2B926AC19542649DA903992F0DB5F1F41A839179F753921C9814C07924097BD850BE07A0A6ED5EECA31D391154055012C48C8000CA03790889670C2E4BE1BCE6C854C4FAB1004CC127103E59C4BF55C7A290BD44BF9EE06C18557C07D2A36D8FCDE4E1F17AD73FA570112DB3F881AD1C23D573F3F23CC5245B4D1C289F517720F444A3282BDD4D5E49B98926C13B0C45CA13BE11E55A5B6F104435196EF8E25A3A955C5C15A0A350A276912C143F57C819F45557A04C5A576E2266E0898E8D64BA3B7E539B642C7C13E624BC8AA299F8FC1D72C7E9DD4C5CE50DFFB762A80A3D7EF8BBEE12CDDCA3F9900A948986F64A719D5444E5D595B86F2524B0292282F6EFC2D3DB2E275FDC4D11654C878D1D74CA972B7CF6C57B2A542BE5A8F2576105C95C1376F5EBCA7A7068A60E90AA8C4B19219EC3A518E8CD809F06096ABFF526F31E86DD4127FD4CFBDAF1229CB590CF9D76ECAFB2E6B3CD43995F6EF11D69601E6443
-20200323081041 2 6 100 7679 2 D6B6711FEDD0DAB74BE347B82AE33FB203A966E712D108C27D2983732928351D8E0B14DB0377CA10A9D079F1D76AB94AB983A67C01CADC4EEDC12F452A214B690C3823B59D05B8967A9C5FB80A78CA705620E04FD35D7BC8636A0456F5015C75B2ED2AEE4A50ED3224FB8BDEECE5C21DFC8703240AC287E4E218710091A76D19EA96FE36FB67547F45040AB5DF812D5A4391E41147087072901BE7E6618F41C2D5868424B7EC12E122A036FB5E504651DF79A120CF6698D983FD59F0203E225DE8508D72DCAA6D93492FC574B73B589189D127CF23EDFD7B319C2222239641590C6F66D25C3AD092527FBDE254131F5C13A70BC2C382671E4B940C755B617854CD3A50941DC652A8F20647C638E5F0977EA881D4770CC8381AE551A745363183752830BF4650C3741FFA8F0ED13CE0190963AFA40B61B2B9CCBD07C49A22CD6C229D43AB2E02CE5A8D2CCE45C22E237F8679D10D2543BDA0407FE3011B211B331426ACCE3B4D7DC8626B4C7D713479170BA6DC9A34F404D1C6A3EA7C04634CE61A032FC967D212B99E521CA58B7EA0E560095F1E39603C1FED48F8ED21E4D7B2D3D6F9CB34387BAD472097FC3C24203991ADE41EFDADE145D9B36E87DF128176951D3AFA12C586585C230F4DE23973B14B0291FB99A2527B87A705228DC2F0C27E6C6D01FA36E231A076C5D256B2D730424EDA55916FA3DE5E6AC1EAA5EF7FFFCF57C5577195EBBD5C3AA0448BE83BFC6853AAF9B48FA1289B276C931D4E472FF04428D02EADF12733C1E446B2DD0F1B30D1BEB4E5F36F6FF6438E7B5C51093BAED1AD02AF353DE0F447C38C1F7D10D3C6CD56DBB8EF4374E5B296BCFC2B926AC19542649DA903992F0DB5F1F41A839179F753921C9814C07924097BD850BE07A0A6ED5EECA31D391154055012C48C8000CA03790889670C2E4BE1BCE6C854C4FAB1004CC127103E59C4BF55C7A290BD44BF9EE06C18557C07D2A36D8FCDE4E1F17AD73FA570112DB3F881AD1C23D573F3F23CC5245B4D1C289F517720F444A3282BDD4D5E49B98926C13B0C45CA13BE11E55A5B6F104435196EF8E25A3A955C5C15A0A350A276912C143F57C819F45557A04C5A576E2266E0898E8D64BA3B7E539B642C7C13E624BC8AA299F8FC1D72C7E9DD4C5CE50DFFB762A80A3D7EF8BBEE12CDDCA3F9900A948986F64A719D5444E5D595B86F2524B0292282F6EFC2D3DB2E275FDC4D11654C878D1D74CA972B7CF6C57B2A542BE5A8F2576105C95C1376F5EBCA7A7068A60E90AA8C4B19219EC3A518E8CD809F06096ABFF526F31E86DD4127FD4CFBDAF1229CB590CF9D76ECAFB2E6B3CD43995F6EF11D696401E163
-20200323141348 2 6 100 7679 5 D6B6711FEDD0DAB74BE347B82AE33FB203A966E712D108C27D2983732928351D8E0B14DB0377CA10A9D079F1D76AB94AB983A67C01CADC4EEDC12F452A214B690C3823B59D05B8967A9C5FB80A78CA705620E04FD35D7BC8636A0456F5015C75B2ED2AEE4A50ED3224FB8BDEECE5C21DFC8703240AC287E4E218710091A76D19EA96FE36FB67547F45040AB5DF812D5A4391E41147087072901BE7E6618F41C2D5868424B7EC12E122A036FB5E504651DF79A120CF6698D983FD59F0203E225DE8508D72DCAA6D93492FC574B73B589189D127CF23EDFD7B319C2222239641590C6F66D25C3AD092527FBDE254131F5C13A70BC2C382671E4B940C755B617854CD3A50941DC652A8F20647C638E5F0977EA881D4770CC8381AE551A745363183752830BF4650C3741FFA8F0ED13CE0190963AFA40B61B2B9CCBD07C49A22CD6C229D43AB2E02CE5A8D2CCE45C22E237F8679D10D2543BDA0407FE3011B211B331426ACCE3B4D7DC8626B4C7D713479170BA6DC9A34F404D1C6A3EA7C04634CE61A032FC967D212B99E521CA58B7EA0E560095F1E39603C1FED48F8ED21E4D7B2D3D6F9CB34387BAD472097FC3C24203991ADE41EFDADE145D9B36E87DF128176951D3AFA12C586585C230F4DE23973B14B0291FB99A2527B87A705228DC2F0C27E6C6D01FA36E231A076C5D256B2D730424EDA55916FA3DE5E6AC1EAA5EF7FFFCF57C5577195EBBD5C3AA0448BE83BFC6853AAF9B48FA1289B276C931D4E472FF04428D02EADF12733C1E446B2DD0F1B30D1BEB4E5F36F6FF6438E7B5C51093BAED1AD02AF353DE0F447C38C1F7D10D3C6CD56DBB8EF4374E5B296BCFC2B926AC19542649DA903992F0DB5F1F41A839179F753921C9814C07924097BD850BE07A0A6ED5EECA31D391154055012C48C8000CA03790889670C2E4BE1BCE6C854C4FAB1004CC127103E59C4BF55C7A290BD44BF9EE06C18557C07D2A36D8FCDE4E1F17AD73FA570112DB3F881AD1C23D573F3F23CC5245B4D1C289F517720F444A3282BDD4D5E49B98926C13B0C45CA13BE11E55A5B6F104435196EF8E25A3A955C5C15A0A350A276912C143F57C819F45557A04C5A576E2266E0898E8D64BA3B7E539B642C7C13E624BC8AA299F8FC1D72C7E9DD4C5CE50DFFB762A80A3D7EF8BBEE12CDDCA3F9900A948986F64A719D5444E5D595B86F2524B0292282F6EFC2D3DB2E275FDC4D11654C878D1D74CA972B7CF6C57B2A542BE5A8F2576105C95C1376F5EBCA7A7068A60E90AA8C4B19219EC3A518E8CD809F06096ABFF526F31E86DD4127FD4CFBDAF1229CB590CF9D76ECAFB2E6B3CD43995F6EF11D6967527EB7
-20200323182024 2 6 100 7679 5 D6B6711FEDD0DAB74BE347B82AE33FB203A966E712D108C27D2983732928351D8E0B14DB0377CA10A9D079F1D76AB94AB983A67C01CADC4EEDC12F452A214B690C3823B59D05B8967A9C5FB80A78CA705620E04FD35D7BC8636A0456F5015C75B2ED2AEE4A50ED3224FB8BDEECE5C21DFC8703240AC287E4E218710091A76D19EA96FE36FB67547F45040AB5DF812D5A4391E41147087072901BE7E6618F41C2D5868424B7EC12E122A036FB5E504651DF79A120CF6698D983FD59F0203E225DE8508D72DCAA6D93492FC574B73B589189D127CF23EDFD7B319C2222239641590C6F66D25C3AD092527FBDE254131F5C13A70BC2C382671E4B940C755B617854CD3A50941DC652A8F20647C638E5F0977EA881D4770CC8381AE551A745363183752830BF4650C3741FFA8F0ED13CE0190963AFA40B61B2B9CCBD07C49A22CD6C229D43AB2E02CE5A8D2CCE45C22E237F8679D10D2543BDA0407FE3011B211B331426ACCE3B4D7DC8626B4C7D713479170BA6DC9A34F404D1C6A3EA7C04634CE61A032FC967D212B99E521CA58B7EA0E560095F1E39603C1FED48F8ED21E4D7B2D3D6F9CB34387BAD472097FC3C24203991ADE41EFDADE145D9B36E87DF128176951D3AFA12C586585C230F4DE23973B14B0291FB99A2527B87A705228DC2F0C27E6C6D01FA36E231A076C5D256B2D730424EDA55916FA3DE5E6AC1EAA5EF7FFFCF57C5577195EBBD5C3AA0448BE83BFC6853AAF9B48FA1289B276C931D4E472FF04428D02EADF12733C1E446B2DD0F1B30D1BEB4E5F36F6FF6438E7B5C51093BAED1AD02AF353DE0F447C38C1F7D10D3C6CD56DBB8EF4374E5B296BCFC2B926AC19542649DA903992F0DB5F1F41A839179F753921C9814C07924097BD850BE07A0A6ED5EECA31D391154055012C48C8000CA03790889670C2E4BE1BCE6C854C4FAB1004CC127103E59C4BF55C7A290BD44BF9EE06C18557C07D2A36D8FCDE4E1F17AD73FA570112DB3F881AD1C23D573F3F23CC5245B4D1C289F517720F444A3282BDD4D5E49B98926C13B0C45CA13BE11E55A5B6F104435196EF8E25A3A955C5C15A0A350A276912C143F57C819F45557A04C5A576E2266E0898E8D64BA3B7E539B642C7C13E624BC8AA299F8FC1D72C7E9DD4C5CE50DFFB762A80A3D7EF8BBEE12CDDCA3F9900A948986F64A719D5444E5D595B86F2524B0292282F6EFC2D3DB2E275FDC4D11654C878D1D74CA972B7CF6C57B2A542BE5A8F2576105C95C1376F5EBCA7A7068A60E90AA8C4B19219EC3A518E8CD809F06096ABFF526F31E86DD4127FD4CFBDAF1229CB590CF9D76ECAFB2E6B3CD43995F6EF11D69698E2947
-20200323183420 2 6 100 7679 2 D6B6711FEDD0DAB74BE347B82AE33FB203A966E712D108C27D2983732928351D8E0B14DB0377CA10A9D079F1D76AB94AB983A67C01CADC4EEDC12F452A214B690C3823B59D05B8967A9C5FB80A78CA705620E04FD35D7BC8636A0456F5015C75B2ED2AEE4A50ED3224FB8BDEECE5C21DFC8703240AC287E4E218710091A76D19EA96FE36FB67547F45040AB5DF812D5A4391E41147087072901BE7E6618F41C2D5868424B7EC12E122A036FB5E504651DF79A120CF6698D983FD59F0203E225DE8508D72DCAA6D93492FC574B73B589189D127CF23EDFD7B319C2222239641590C6F66D25C3AD092527FBDE254131F5C13A70BC2C382671E4B940C755B617854CD3A50941DC652A8F20647C638E5F0977EA881D4770CC8381AE551A745363183752830BF4650C3741FFA8F0ED13CE0190963AFA40B61B2B9CCBD07C49A22CD6C229D43AB2E02CE5A8D2CCE45C22E237F8679D10D2543BDA0407FE3011B211B331426ACCE3B4D7DC8626B4C7D713479170BA6DC9A34F404D1C6A3EA7C04634CE61A032FC967D212B99E521CA58B7EA0E560095F1E39603C1FED48F8ED21E4D7B2D3D6F9CB34387BAD472097FC3C24203991ADE41EFDADE145D9B36E87DF128176951D3AFA12C586585C230F4DE23973B14B0291FB99A2527B87A705228DC2F0C27E6C6D01FA36E231A076C5D256B2D730424EDA55916FA3DE5E6AC1EAA5EF7FFFCF57C5577195EBBD5C3AA0448BE83BFC6853AAF9B48FA1289B276C931D4E472FF04428D02EADF12733C1E446B2DD0F1B30D1BEB4E5F36F6FF6438E7B5C51093BAED1AD02AF353DE0F447C38C1F7D10D3C6CD56DBB8EF4374E5B296BCFC2B926AC19542649DA903992F0DB5F1F41A839179F753921C9814C07924097BD850BE07A0A6ED5EECA31D391154055012C48C8000CA03790889670C2E4BE1BCE6C854C4FAB1004CC127103E59C4BF55C7A290BD44BF9EE06C18557C07D2A36D8FCDE4E1F17AD73FA570112DB3F881AD1C23D573F3F23CC5245B4D1C289F517720F444A3282BDD4D5E49B98926C13B0C45CA13BE11E55A5B6F104435196EF8E25A3A955C5C15A0A350A276912C143F57C819F45557A04C5A576E2266E0898E8D64BA3B7E539B642C7C13E624BC8AA299F8FC1D72C7E9DD4C5CE50DFFB762A80A3D7EF8BBEE12CDDCA3F9900A948986F64A719D5444E5D595B86F2524B0292282F6EFC2D3DB2E275FDC4D11654C878D1D74CA972B7CF6C57B2A542BE5A8F2576105C95C1376F5EBCA7A7068A60E90AA8C4B19219EC3A518E8CD809F06096ABFF526F31E86DD4127FD4CFBDAF1229CB590CF9D76ECAFB2E6B3CD43995F6EF11D6969A6188B
-20200323200741 2 6 100 7679 2 D6B6711FEDD0DAB74BE347B82AE33FB203A966E712D108C27D2983732928351D8E0B14DB0377CA10A9D079F1D76AB94AB983A67C01CADC4EEDC12F452A214B690C3823B59D05B8967A9C5FB80A78CA705620E04FD35D7BC8636A0456F5015C75B2ED2AEE4A50ED3224FB8BDEECE5C21DFC8703240AC287E4E218710091A76D19EA96FE36FB67547F45040AB5DF812D5A4391E41147087072901BE7E6618F41C2D5868424B7EC12E122A036FB5E504651DF79A120CF6698D983FD59F0203E225DE8508D72DCAA6D93492FC574B73B589189D127CF23EDFD7B319C2222239641590C6F66D25C3AD092527FBDE254131F5C13A70BC2C382671E4B940C755B617854CD3A50941DC652A8F20647C638E5F0977EA881D4770CC8381AE551A745363183752830BF4650C3741FFA8F0ED13CE0190963AFA40B61B2B9CCBD07C49A22CD6C229D43AB2E02CE5A8D2CCE45C22E237F8679D10D2543BDA0407FE3011B211B331426ACCE3B4D7DC8626B4C7D713479170BA6DC9A34F404D1C6A3EA7C04634CE61A032FC967D212B99E521CA58B7EA0E560095F1E39603C1FED48F8ED21E4D7B2D3D6F9CB34387BAD472097FC3C24203991ADE41EFDADE145D9B36E87DF128176951D3AFA12C586585C230F4DE23973B14B0291FB99A2527B87A705228DC2F0C27E6C6D01FA36E231A076C5D256B2D730424EDA55916FA3DE5E6AC1EAA5EF7FFFCF57C5577195EBBD5C3AA0448BE83BFC6853AAF9B48FA1289B276C931D4E472FF04428D02EADF12733C1E446B2DD0F1B30D1BEB4E5F36F6FF6438E7B5C51093BAED1AD02AF353DE0F447C38C1F7D10D3C6CD56DBB8EF4374E5B296BCFC2B926AC19542649DA903992F0DB5F1F41A839179F753921C9814C07924097BD850BE07A0A6ED5EECA31D391154055012C48C8000CA03790889670C2E4BE1BCE6C854C4FAB1004CC127103E59C4BF55C7A290BD44BF9EE06C18557C07D2A36D8FCDE4E1F17AD73FA570112DB3F881AD1C23D573F3F23CC5245B4D1C289F517720F444A3282BDD4D5E49B98926C13B0C45CA13BE11E55A5B6F104435196EF8E25A3A955C5C15A0A350A276912C143F57C819F45557A04C5A576E2266E0898E8D64BA3B7E539B642C7C13E624BC8AA299F8FC1D72C7E9DD4C5CE50DFFB762A80A3D7EF8BBEE12CDDCA3F9900A948986F64A719D5444E5D595B86F2524B0292282F6EFC2D3DB2E275FDC4D11654C878D1D74CA972B7CF6C57B2A542BE5A8F2576105C95C1376F5EBCA7A7068A60E90AA8C4B19219EC3A518E8CD809F06096ABFF526F31E86DD4127FD4CFBDAF1229CB590CF9D76ECAFB2E6B3CD43995F6EF11D696A775C93
-20200324000150 2 6 100 7679 5 D6B6711FEDD0DAB74BE347B82AE33FB203A966E712D108C27D2983732928351D8E0B14DB0377CA10A9D079F1D76AB94AB983A67C01CADC4EEDC12F452A214B690C3823B59D05B8967A9C5FB80A78CA705620E04FD35D7BC8636A0456F5015C75B2ED2AEE4A50ED3224FB8BDEECE5C21DFC8703240AC287E4E218710091A76D19EA96FE36FB67547F45040AB5DF812D5A4391E41147087072901BE7E6618F41C2D5868424B7EC12E122A036FB5E504651DF79A120CF6698D983FD59F0203E225DE8508D72DCAA6D93492FC574B73B589189D127CF23EDFD7B319C2222239641590C6F66D25C3AD092527FBDE254131F5C13A70BC2C382671E4B940C755B617854CD3A50941DC652A8F20647C638E5F0977EA881D4770CC8381AE551A745363183752830BF4650C3741FFA8F0ED13CE0190963AFA40B61B2B9CCBD07C49A22CD6C229D43AB2E02CE5A8D2CCE45C22E237F8679D10D2543BDA0407FE3011B211B331426ACCE3B4D7DC8626B4C7D713479170BA6DC9A34F404D1C6A3EA7C04634CE61A032FC967D212B99E521CA58B7EA0E560095F1E39603C1FED48F8ED21E4D7B2D3D6F9CB34387BAD472097FC3C24203991ADE41EFDADE145D9B36E87DF128176951D3AFA12C586585C230F4DE23973B14B0291FB99A2527B87A705228DC2F0C27E6C6D01FA36E231A076C5D256B2D730424EDA55916FA3DE5E6AC1EAA5EF7FFFCF57C5577195EBBD5C3AA0448BE83BFC6853AAF9B48FA1289B276C931D4E472FF04428D02EADF12733C1E446B2DD0F1B30D1BEB4E5F36F6FF6438E7B5C51093BAED1AD02AF353DE0F447C38C1F7D10D3C6CD56DBB8EF4374E5B296BCFC2B926AC19542649DA903992F0DB5F1F41A839179F753921C9814C07924097BD850BE07A0A6ED5EECA31D391154055012C48C8000CA03790889670C2E4BE1BCE6C854C4FAB1004CC127103E59C4BF55C7A290BD44BF9EE06C18557C07D2A36D8FCDE4E1F17AD73FA570112DB3F881AD1C23D573F3F23CC5245B4D1C289F517720F444A3282BDD4D5E49B98926C13B0C45CA13BE11E55A5B6F104435196EF8E25A3A955C5C15A0A350A276912C143F57C819F45557A04C5A576E2266E0898E8D64BA3B7E539B642C7C13E624BC8AA299F8FC1D72C7E9DD4C5CE50DFFB762A80A3D7EF8BBEE12CDDCA3F9900A948986F64A719D5444E5D595B86F2524B0292282F6EFC2D3DB2E275FDC4D11654C878D1D74CA972B7CF6C57B2A542BE5A8F2576105C95C1376F5EBCA7A7068A60E90AA8C4B19219EC3A518E8CD809F06096ABFF526F31E86DD4127FD4CFBDAF1229CB590CF9D76ECAFB2E6B3CD43995F6EF11D696C9A9E77
-20200324021150 2 6 100 7679 2 D6B6711FEDD0DAB74BE347B82AE33FB203A966E712D108C27D2983732928351D8E0B14DB0377CA10A9D079F1D76AB94AB983A67C01CADC4EEDC12F452A214B690C3823B59D05B8967A9C5FB80A78CA705620E04FD35D7BC8636A0456F5015C75B2ED2AEE4A50ED3224FB8BDEECE5C21DFC8703240AC287E4E218710091A76D19EA96FE36FB67547F45040AB5DF812D5A4391E41147087072901BE7E6618F41C2D5868424B7EC12E122A036FB5E504651DF79A120CF6698D983FD59F0203E225DE8508D72DCAA6D93492FC574B73B589189D127CF23EDFD7B319C2222239641590C6F66D25C3AD092527FBDE254131F5C13A70BC2C382671E4B940C755B617854CD3A50941DC652A8F20647C638E5F0977EA881D4770CC8381AE551A745363183752830BF4650C3741FFA8F0ED13CE0190963AFA40B61B2B9CCBD07C49A22CD6C229D43AB2E02CE5A8D2CCE45C22E237F8679D10D2543BDA0407FE3011B211B331426ACCE3B4D7DC8626B4C7D713479170BA6DC9A34F404D1C6A3EA7C04634CE61A032FC967D212B99E521CA58B7EA0E560095F1E39603C1FED48F8ED21E4D7B2D3D6F9CB34387BAD472097FC3C24203991ADE41EFDADE145D9B36E87DF128176951D3AFA12C586585C230F4DE23973B14B0291FB99A2527B87A705228DC2F0C27E6C6D01FA36E231A076C5D256B2D730424EDA55916FA3DE5E6AC1EAA5EF7FFFCF57C5577195EBBD5C3AA0448BE83BFC6853AAF9B48FA1289B276C931D4E472FF04428D02EADF12733C1E446B2DD0F1B30D1BEB4E5F36F6FF6438E7B5C51093BAED1AD02AF353DE0F447C38C1F7D10D3C6CD56DBB8EF4374E5B296BCFC2B926AC19542649DA903992F0DB5F1F41A839179F753921C9814C07924097BD850BE07A0A6ED5EECA31D391154055012C48C8000CA03790889670C2E4BE1BCE6C854C4FAB1004CC127103E59C4BF55C7A290BD44BF9EE06C18557C07D2A36D8FCDE4E1F17AD73FA570112DB3F881AD1C23D573F3F23CC5245B4D1C289F517720F444A3282BDD4D5E49B98926C13B0C45CA13BE11E55A5B6F104435196EF8E25A3A955C5C15A0A350A276912C143F57C819F45557A04C5A576E2266E0898E8D64BA3B7E539B642C7C13E624BC8AA299F8FC1D72C7E9DD4C5CE50DFFB762A80A3D7EF8BBEE12CDDCA3F9900A948986F64A719D5444E5D595B86F2524B0292282F6EFC2D3DB2E275FDC4D11654C878D1D74CA972B7CF6C57B2A542BE5A8F2576105C95C1376F5EBCA7A7068A60E90AA8C4B19219EC3A518E8CD809F06096ABFF526F31E86DD4127FD4CFBDAF1229CB590CF9D76ECAFB2E6B3CD43995F6EF11D696DC85C1B
-20200324041431 2 6 100 7679 5 D6B6711FEDD0DAB74BE347B82AE33FB203A966E712D108C27D2983732928351D8E0B14DB0377CA10A9D079F1D76AB94AB983A67C01CADC4EEDC12F452A214B690C3823B59D05B8967A9C5FB80A78CA705620E04FD35D7BC8636A0456F5015C75B2ED2AEE4A50ED3224FB8BDEECE5C21DFC8703240AC287E4E218710091A76D19EA96FE36FB67547F45040AB5DF812D5A4391E41147087072901BE7E6618F41C2D5868424B7EC12E122A036FB5E504651DF79A120CF6698D983FD59F0203E225DE8508D72DCAA6D93492FC574B73B589189D127CF23EDFD7B319C2222239641590C6F66D25C3AD092527FBDE254131F5C13A70BC2C382671E4B940C755B617854CD3A50941DC652A8F20647C638E5F0977EA881D4770CC8381AE551A745363183752830BF4650C3741FFA8F0ED13CE0190963AFA40B61B2B9CCBD07C49A22CD6C229D43AB2E02CE5A8D2CCE45C22E237F8679D10D2543BDA0407FE3011B211B331426ACCE3B4D7DC8626B4C7D713479170BA6DC9A34F404D1C6A3EA7C04634CE61A032FC967D212B99E521CA58B7EA0E560095F1E39603C1FED48F8ED21E4D7B2D3D6F9CB34387BAD472097FC3C24203991ADE41EFDADE145D9B36E87DF128176951D3AFA12C586585C230F4DE23973B14B0291FB99A2527B87A705228DC2F0C27E6C6D01FA36E231A076C5D256B2D730424EDA55916FA3DE5E6AC1EAA5EF7FFFCF57C5577195EBBD5C3AA0448BE83BFC6853AAF9B48FA1289B276C931D4E472FF04428D02EADF12733C1E446B2DD0F1B30D1BEB4E5F36F6FF6438E7B5C51093BAED1AD02AF353DE0F447C38C1F7D10D3C6CD56DBB8EF4374E5B296BCFC2B926AC19542649DA903992F0DB5F1F41A839179F753921C9814C07924097BD850BE07A0A6ED5EECA31D391154055012C48C8000CA03790889670C2E4BE1BCE6C854C4FAB1004CC127103E59C4BF55C7A290BD44BF9EE06C18557C07D2A36D8FCDE4E1F17AD73FA570112DB3F881AD1C23D573F3F23CC5245B4D1C289F517720F444A3282BDD4D5E49B98926C13B0C45CA13BE11E55A5B6F104435196EF8E25A3A955C5C15A0A350A276912C143F57C819F45557A04C5A576E2266E0898E8D64BA3B7E539B642C7C13E624BC8AA299F8FC1D72C7E9DD4C5CE50DFFB762A80A3D7EF8BBEE12CDDCA3F9900A948986F64A719D5444E5D595B86F2524B0292282F6EFC2D3DB2E275FDC4D11654C878D1D74CA972B7CF6C57B2A542BE5A8F2576105C95C1376F5EBCA7A7068A60E90AA8C4B19219EC3A518E8CD809F06096ABFF526F31E86DD4127FD4CFBDAF1229CB590CF9D76ECAFB2E6B3CD43995F6EF11D696EE23C2F
-20200324100523 2 6 100 7679 5 D6B6711FEDD0DAB74BE347B82AE33FB203A966E712D108C27D2983732928351D8E0B14DB0377CA10A9D079F1D76AB94AB983A67C01CADC4EEDC12F452A214B690C3823B59D05B8967A9C5FB80A78CA705620E04FD35D7BC8636A0456F5015C75B2ED2AEE4A50ED3224FB8BDEECE5C21DFC8703240AC287E4E218710091A76D19EA96FE36FB67547F45040AB5DF812D5A4391E41147087072901BE7E6618F41C2D5868424B7EC12E122A036FB5E504651DF79A120CF6698D983FD59F0203E225DE8508D72DCAA6D93492FC574B73B589189D127CF23EDFD7B319C2222239641590C6F66D25C3AD092527FBDE254131F5C13A70BC2C382671E4B940C755B617854CD3A50941DC652A8F20647C638E5F0977EA881D4770CC8381AE551A745363183752830BF4650C3741FFA8F0ED13CE0190963AFA40B61B2B9CCBD07C49A22CD6C229D43AB2E02CE5A8D2CCE45C22E237F8679D10D2543BDA0407FE3011B211B331426ACCE3B4D7DC8626B4C7D713479170BA6DC9A34F404D1C6A3EA7C04634CE61A032FC967D212B99E521CA58B7EA0E560095F1E39603C1FED48F8ED21E4D7B2D3D6F9CB34387BAD472097FC3C24203991ADE41EFDADE145D9B36E87DF128176951D3AFA12C586585C230F4DE23973B14B0291FB99A2527B87A705228DC2F0C27E6C6D01FA36E231A076C5D256B2D730424EDA55916FA3DE5E6AC1EAA5EF7FFFCF57C5577195EBBD5C3AA0448BE83BFC6853AAF9B48FA1289B276C931D4E472FF04428D02EADF12733C1E446B2DD0F1B30D1BEB4E5F36F6FF6438E7B5C51093BAED1AD02AF353DE0F447C38C1F7D10D3C6CD56DBB8EF4374E5B296BCFC2B926AC19542649DA903992F0DB5F1F41A839179F753921C9814C07924097BD850BE07A0A6ED5EECA31D391154055012C48C8000CA03790889670C2E4BE1BCE6C854C4FAB1004CC127103E59C4BF55C7A290BD44BF9EE06C18557C07D2A36D8FCDE4E1F17AD73FA570112DB3F881AD1C23D573F3F23CC5245B4D1C289F517720F444A3282BDD4D5E49B98926C13B0C45CA13BE11E55A5B6F104435196EF8E25A3A955C5C15A0A350A276912C143F57C819F45557A04C5A576E2266E0898E8D64BA3B7E539B642C7C13E624BC8AA299F8FC1D72C7E9DD4C5CE50DFFB762A80A3D7EF8BBEE12CDDCA3F9900A948986F64A719D5444E5D595B86F2524B0292282F6EFC2D3DB2E275FDC4D11654C878D1D74CA972B7CF6C57B2A542BE5A8F2576105C95C1376F5EBCA7A7068A60E90AA8C4B19219EC3A518E8CD809F06096ABFF526F31E86DD4127FD4CFBDAF1229CB590CF9D76ECAFB2E6B3CD43995F6EF11D69721212EF
-20200324110629 2 6 100 7679 2 D6B6711FEDD0DAB74BE347B82AE33FB203A966E712D108C27D2983732928351D8E0B14DB0377CA10A9D079F1D76AB94AB983A67C01CADC4EEDC12F452A214B690C3823B59D05B8967A9C5FB80A78CA705620E04FD35D7BC8636A0456F5015C75B2ED2AEE4A50ED3224FB8BDEECE5C21DFC8703240AC287E4E218710091A76D19EA96FE36FB67547F45040AB5DF812D5A4391E41147087072901BE7E6618F41C2D5868424B7EC12E122A036FB5E504651DF79A120CF6698D983FD59F0203E225DE8508D72DCAA6D93492FC574B73B589189D127CF23EDFD7B319C2222239641590C6F66D25C3AD092527FBDE254131F5C13A70BC2C382671E4B940C755B617854CD3A50941DC652A8F20647C638E5F0977EA881D4770CC8381AE551A745363183752830BF4650C3741FFA8F0ED13CE0190963AFA40B61B2B9CCBD07C49A22CD6C229D43AB2E02CE5A8D2CCE45C22E237F8679D10D2543BDA0407FE3011B211B331426ACCE3B4D7DC8626B4C7D713479170BA6DC9A34F404D1C6A3EA7C04634CE61A032FC967D212B99E521CA58B7EA0E560095F1E39603C1FED48F8ED21E4D7B2D3D6F9CB34387BAD472097FC3C24203991ADE41EFDADE145D9B36E87DF128176951D3AFA12C586585C230F4DE23973B14B0291FB99A2527B87A705228DC2F0C27E6C6D01FA36E231A076C5D256B2D730424EDA55916FA3DE5E6AC1EAA5EF7FFFCF57C5577195EBBD5C3AA0448BE83BFC6853AAF9B48FA1289B276C931D4E472FF04428D02EADF12733C1E446B2DD0F1B30D1BEB4E5F36F6FF6438E7B5C51093BAED1AD02AF353DE0F447C38C1F7D10D3C6CD56DBB8EF4374E5B296BCFC2B926AC19542649DA903992F0DB5F1F41A839179F753921C9814C07924097BD850BE07A0A6ED5EECA31D391154055012C48C8000CA03790889670C2E4BE1BCE6C854C4FAB1004CC127103E59C4BF55C7A290BD44BF9EE06C18557C07D2A36D8FCDE4E1F17AD73FA570112DB3F881AD1C23D573F3F23CC5245B4D1C289F517720F444A3282BDD4D5E49B98926C13B0C45CA13BE11E55A5B6F104435196EF8E25A3A955C5C15A0A350A276912C143F57C819F45557A04C5A576E2266E0898E8D64BA3B7E539B642C7C13E624BC8AA299F8FC1D72C7E9DD4C5CE50DFFB762A80A3D7EF8BBEE12CDDCA3F9900A948986F64A719D5444E5D595B86F2524B0292282F6EFC2D3DB2E275FDC4D11654C878D1D74CA972B7CF6C57B2A542BE5A8F2576105C95C1376F5EBCA7A7068A60E90AA8C4B19219EC3A518E8CD809F06096ABFF526F31E86DD4127FD4CFBDAF1229CB590CF9D76ECAFB2E6B3CD43995F6EF11D69729D197B
-20200325070252 2 6 100 7679 5 D6B6711FEDD0DAB74BE347B82AE33FB203A966E712D108C27D2983732928351D8E0B14DB0377CA10A9D079F1D76AB94AB983A67C01CADC4EEDC12F452A214B690C3823B59D05B8967A9C5FB80A78CA705620E04FD35D7BC8636A0456F5015C75B2ED2AEE4A50ED3224FB8BDEECE5C21DFC8703240AC287E4E218710091A76D19EA96FE36FB67547F45040AB5DF812D5A4391E41147087072901BE7E6618F41C2D5868424B7EC12E122A036FB5E504651DF79A120CF6698D983FD59F0203E225DE8508D72DCAA6D93492FC574B73B589189D127CF23EDFD7B319C2222239641590C6F66D25C3AD092527FBDE254131F5C13A70BC2C382671E4B940C755B617854CD3A50941DC652A8F20647C638E5F0977EA881D4770CC8381AE551A745363183752830BF4650C3741FFA8F0ED13CE0190963AFA40B61B2B9CCBD07C49A22CD6C229D43AB2E02CE5A8D2CCE45C22E237F8679D10D2543BDA0407FE3011B211B331426ACCE3B4D7DC8626B4C7D713479170BA6DC9A34F404D1C6A3EA7C04634CE61A032FC967D212B99E521CA58B7EA0E560095F1E39603C1FED48F8ED21E4D7B2D3D6F9CB34387BAD472097FC3C24203991ADE41EFDADE145D9B36E87DF128176951D3AFA12C586585C230F4DE23973B14B0291FB99A2527B87A705228DC2F0C27E6C6D01FA36E231A076C5D256B2D730424EDA55916FA3DE5E6AC1EAA5EF7FFFCF57C5577195EBBD5C3AA0448BE83BFC6853AAF9B48FA1289B276C931D4E472FF04428D02EADF12733C1E446B2DD0F1B30D1BEB4E5F36F6FF6438E7B5C51093BAED1AD02AF353DE0F447C38C1F7D10D3C6CD56DBB8EF4374E5B296BCFC2B926AC19542649DA903992F0DB5F1F41A839179F753921C9814C07924097BD850BE07A0A6ED5EECA31D391154055012C48C8000CA03790889670C2E4BE1BCE6C854C4FAB1004CC127103E59C4BF55C7A290BD44BF9EE06C18557C07D2A36D8FCDE4E1F17AD73FA570112DB3F881AD1C23D573F3F23CC5245B4D1C289F517720F444A3282BDD4D5E49B98926C13B0C45CA13BE11E55A5B6F104435196EF8E25A3A955C5C15A0A350A276912C143F57C819F45557A04C5A576E2266E0898E8D64BA3B7E539B642C7C13E624BC8AA299F8FC1D72C7E9DD4C5CE50DFFB762A80A3D7EF8BBEE12CDDCA3F9900A948986F64A719D5444E5D595B86F2524B0292282F6EFC2D3DB2E275FDC4D11654C878D1D74CA972B7CF6C57B2A542BE5A8F2576105C95C1376F5EBCA7A7068A60E90AA8C4B19219EC3A518E8CD809F06096ABFF526F31E86DD4127FD4CFBDAF1229CB590CF9D76ECAFB2E6B3CD43995F6EF11D697D6E57F7
-20200325073428 2 6 100 7679 2 D6B6711FEDD0DAB74BE347B82AE33FB203A966E712D108C27D2983732928351D8E0B14DB0377CA10A9D079F1D76AB94AB983A67C01CADC4EEDC12F452A214B690C3823B59D05B8967A9C5FB80A78CA705620E04FD35D7BC8636A0456F5015C75B2ED2AEE4A50ED3224FB8BDEECE5C21DFC8703240AC287E4E218710091A76D19EA96FE36FB67547F45040AB5DF812D5A4391E41147087072901BE7E6618F41C2D5868424B7EC12E122A036FB5E504651DF79A120CF6698D983FD59F0203E225DE8508D72DCAA6D93492FC574B73B589189D127CF23EDFD7B319C2222239641590C6F66D25C3AD092527FBDE254131F5C13A70BC2C382671E4B940C755B617854CD3A50941DC652A8F20647C638E5F0977EA881D4770CC8381AE551A745363183752830BF4650C3741FFA8F0ED13CE0190963AFA40B61B2B9CCBD07C49A22CD6C229D43AB2E02CE5A8D2CCE45C22E237F8679D10D2543BDA0407FE3011B211B331426ACCE3B4D7DC8626B4C7D713479170BA6DC9A34F404D1C6A3EA7C04634CE61A032FC967D212B99E521CA58B7EA0E560095F1E39603C1FED48F8ED21E4D7B2D3D6F9CB34387BAD472097FC3C24203991ADE41EFDADE145D9B36E87DF128176951D3AFA12C586585C230F4DE23973B14B0291FB99A2527B87A705228DC2F0C27E6C6D01FA36E231A076C5D256B2D730424EDA55916FA3DE5E6AC1EAA5EF7FFFCF57C5577195EBBD5C3AA0448BE83BFC6853AAF9B48FA1289B276C931D4E472FF04428D02EADF12733C1E446B2DD0F1B30D1BEB4E5F36F6FF6438E7B5C51093BAED1AD02AF353DE0F447C38C1F7D10D3C6CD56DBB8EF4374E5B296BCFC2B926AC19542649DA903992F0DB5F1F41A839179F753921C9814C07924097BD850BE07A0A6ED5EECA31D391154055012C48C8000CA03790889670C2E4BE1BCE6C854C4FAB1004CC127103E59C4BF55C7A290BD44BF9EE06C18557C07D2A36D8FCDE4E1F17AD73FA570112DB3F881AD1C23D573F3F23CC5245B4D1C289F517720F444A3282BDD4D5E49B98926C13B0C45CA13BE11E55A5B6F104435196EF8E25A3A955C5C15A0A350A276912C143F57C819F45557A04C5A576E2266E0898E8D64BA3B7E539B642C7C13E624BC8AA299F8FC1D72C7E9DD4C5CE50DFFB762A80A3D7EF8BBEE12CDDCA3F9900A948986F64A719D5444E5D595B86F2524B0292282F6EFC2D3DB2E275FDC4D11654C878D1D74CA972B7CF6C57B2A542BE5A8F2576105C95C1376F5EBCA7A7068A60E90AA8C4B19219EC3A518E8CD809F06096ABFF526F31E86DD4127FD4CFBDAF1229CB590CF9D76ECAFB2E6B3CD43995F6EF11D697DAF0383
-20200325172855 2 6 100 8191 2 C9BECFEF229169BA6895957B61D338147FD9E67666267E2963D7A5587F57261CE8805A323015A9DA97865C6720A855FB346A80C284F9E8B8661DE02027ED9D77E29C25FD08E9BA260CF0D99BF2B69B0F054D642F8E29756D282B4523CF8CC058AA3A274F5D0766A30E269DC7AF3902DC139AC98994961A9186B5538B0F741A774918140CFC62D6BED7CB6E9333682F17683EF6EB53C2912F125105BDFAADB8046BD4FDFA60C4CE0CD0800D4247FFF67A72917E18D86BDFD6A4FBF3301E3290F5F5FF138F8EB4AD0C85AD4DEE6D590B44352B8B42C3A207C677CFCA215DE5391C9BFE5667698AB65D6955CA1FE8CE57D8EFC83FF5547E095FCC476FF3BAF6DD5B6D87F1C836CB712B54B115C0D7640F8F72CBDCE86DBCE6D2C04B7306B16E010A6CBE0BA95ABF269071BB1F5F433BC74D0C19889480A6B5C1683904837C36C7BCF69BE7CB96E0CAA07396224D694FB02F922B33D14C384923F946D104475F49D18A77AE5FA44ADA7C6E16D3B3085821C0B6814DCB565FDC44ED1942C9E25224ED96240D1FEF3817B6161BAD9F16B8C80953882C2FB2722515B10ABEBE969D2318AE9EB81CE91352329591D2874E6121205E072A3D5749190FA847D79B72BD3452DE0B5169601DDB6264AE70A1DC46B3637567787A11AA180B20623440C455722F8131FF09B47DC47814A4925B615A635D6DA05106825E764746CE76EDEE66F8782B9F688AA003B003857B5A659EAAE999171A9353DE0633614093E0A81E1346ABCDCB3CE1A40E8E086A2A2FB9B87394E0F6A0319F42C7B5B8BB9CFB0EF9FDFF6034A397E32E76B6F8C01F3DD2BE81FC938AFE7A1E1D763B4715B2D7CFB4DA9C0B4D013DE532F7D35E177542616DCC3F06736A25F60D0D486D5E4A3797C643977321C9908881170A23D22ADC8768E983DDB79594311DAF4D2CC28AC73E579F36297B0B007B86CB20F185C3A97E772B8FEF731D59A57C9A30D80C5E8B5F62715EA82BE29C5ADBB7A50B2A3E1FE26A7E77A9B53AB69E4A3D4552494F4F0A39459FE8AD9AA7AFEF7CB2560F759E735DED296AE22EDFDF5336671030749F5CE10E6C212BFDC97DA25C5BC80CD62BD490752CD84FA6B8A35BFC752A1CF07C9247C47A0D50D1AC3A713DDF9214E35FF74BF84799732CA0F7032F2ABA00E896CB731A26D09A44E870E9E46D452428F03F6C54CAD2A90A7D95F06F042A929DB5D1D3BEE989F292C1409E780F30B5C00D5965E35EC5957BCF172C26A93E337B1702FAD07940E5EDF2155F1F1CB33E363935829A64665AB6B6D7B6147673E02CF53BA128114C1396785C550D9FC3E38A2E15964CF7BE477766A7AA3310BC6729910C049FAF4FD5895AB3199830EAF34A67FD727FCE77F0FD546A70AE65011839B3A617EC1A2BB2F341A75EC989227E3DEB3DC4DC9911B0BC1F43425401B9D3355CF90ED930B3
-20200325202118 2 6 100 8191 2 C9BECFEF229169BA6895957B61D338147FD9E67666267E2963D7A5587F57261CE8805A323015A9DA97865C6720A855FB346A80C284F9E8B8661DE02027ED9D77E29C25FD08E9BA260CF0D99BF2B69B0F054D642F8E29756D282B4523CF8CC058AA3A274F5D0766A30E269DC7AF3902DC139AC98994961A9186B5538B0F741A774918140CFC62D6BED7CB6E9333682F17683EF6EB53C2912F125105BDFAADB8046BD4FDFA60C4CE0CD0800D4247FFF67A72917E18D86BDFD6A4FBF3301E3290F5F5FF138F8EB4AD0C85AD4DEE6D590B44352B8B42C3A207C677CFCA215DE5391C9BFE5667698AB65D6955CA1FE8CE57D8EFC83FF5547E095FCC476FF3BAF6DD5B6D87F1C836CB712B54B115C0D7640F8F72CBDCE86DBCE6D2C04B7306B16E010A6CBE0BA95ABF269071BB1F5F433BC74D0C19889480A6B5C1683904837C36C7BCF69BE7CB96E0CAA07396224D694FB02F922B33D14C384923F946D104475F49D18A77AE5FA44ADA7C6E16D3B3085821C0B6814DCB565FDC44ED1942C9E25224ED96240D1FEF3817B6161BAD9F16B8C80953882C2FB2722515B10ABEBE969D2318AE9EB81CE91352329591D2874E6121205E072A3D5749190FA847D79B72BD3452DE0B5169601DDB6264AE70A1DC46B3637567787A11AA180B20623440C455722F8131FF09B47DC47814A4925B615A635D6DA05106825E764746CE76EDEE66F8782B9F688AA003B003857B5A659EAAE999171A9353DE0633614093E0A81E1346ABCDCB3CE1A40E8E086A2A2FB9B87394E0F6A0319F42C7B5B8BB9CFB0EF9FDFF6034A397E32E76B6F8C01F3DD2BE81FC938AFE7A1E1D763B4715B2D7CFB4DA9C0B4D013DE532F7D35E177542616DCC3F06736A25F60D0D486D5E4A3797C643977321C9908881170A23D22ADC8768E983DDB79594311DAF4D2CC28AC73E579F36297B0B007B86CB20F185C3A97E772B8FEF731D59A57C9A30D80C5E8B5F62715EA82BE29C5ADBB7A50B2A3E1FE26A7E77A9B53AB69E4A3D4552494F4F0A39459FE8AD9AA7AFEF7CB2560F759E735DED296AE22EDFDF5336671030749F5CE10E6C212BFDC97DA25C5BC80CD62BD490752CD84FA6B8A35BFC752A1CF07C9247C47A0D50D1AC3A713DDF9214E35FF74BF84799732CA0F7032F2ABA00E896CB731A26D09A44E870E9E46D452428F03F6C54CAD2A90A7D95F06F042A929DB5D1D3BEE989F292C1409E780F30B5C00D5965E35EC5957BCF172C26A93E337B1702FAD07940E5EDF2155F1F1CB33E363935829A64665AB6B6D7B6147673E02CF53BA128114C1396785C550D9FC3E38A2E15964CF7BE477766A7AA3310BC6729910C049FAF4FD5895AB3199830EAF34A67FD727FCE77F0FD546A70AE65011839B3A617EC1A2BB2F341A75EC989227E3DEB3DC4DC9911B0BC1F43425401B9D3355CF91061F97B
-20200326023237 2 6 100 8191 5 C9BECFEF229169BA6895957B61D338147FD9E67666267E2963D7A5587F57261CE8805A323015A9DA97865C6720A855FB346A80C284F9E8B8661DE02027ED9D77E29C25FD08E9BA260CF0D99BF2B69B0F054D642F8E29756D282B4523CF8CC058AA3A274F5D0766A30E269DC7AF3902DC139AC98994961A9186B5538B0F741A774918140CFC62D6BED7CB6E9333682F17683EF6EB53C2912F125105BDFAADB8046BD4FDFA60C4CE0CD0800D4247FFF67A72917E18D86BDFD6A4FBF3301E3290F5F5FF138F8EB4AD0C85AD4DEE6D590B44352B8B42C3A207C677CFCA215DE5391C9BFE5667698AB65D6955CA1FE8CE57D8EFC83FF5547E095FCC476FF3BAF6DD5B6D87F1C836CB712B54B115C0D7640F8F72CBDCE86DBCE6D2C04B7306B16E010A6CBE0BA95ABF269071BB1F5F433BC74D0C19889480A6B5C1683904837C36C7BCF69BE7CB96E0CAA07396224D694FB02F922B33D14C384923F946D104475F49D18A77AE5FA44ADA7C6E16D3B3085821C0B6814DCB565FDC44ED1942C9E25224ED96240D1FEF3817B6161BAD9F16B8C80953882C2FB2722515B10ABEBE969D2318AE9EB81CE91352329591D2874E6121205E072A3D5749190FA847D79B72BD3452DE0B5169601DDB6264AE70A1DC46B3637567787A11AA180B20623440C455722F8131FF09B47DC47814A4925B615A635D6DA05106825E764746CE76EDEE66F8782B9F688AA003B003857B5A659EAAE999171A9353DE0633614093E0A81E1346ABCDCB3CE1A40E8E086A2A2FB9B87394E0F6A0319F42C7B5B8BB9CFB0EF9FDFF6034A397E32E76B6F8C01F3DD2BE81FC938AFE7A1E1D763B4715B2D7CFB4DA9C0B4D013DE532F7D35E177542616DCC3F06736A25F60D0D486D5E4A3797C643977321C9908881170A23D22ADC8768E983DDB79594311DAF4D2CC28AC73E579F36297B0B007B86CB20F185C3A97E772B8FEF731D59A57C9A30D80C5E8B5F62715EA82BE29C5ADBB7A50B2A3E1FE26A7E77A9B53AB69E4A3D4552494F4F0A39459FE8AD9AA7AFEF7CB2560F759E735DED296AE22EDFDF5336671030749F5CE10E6C212BFDC97DA25C5BC80CD62BD490752CD84FA6B8A35BFC752A1CF07C9247C47A0D50D1AC3A713DDF9214E35FF74BF84799732CA0F7032F2ABA00E896CB731A26D09A44E870E9E46D452428F03F6C54CAD2A90A7D95F06F042A929DB5D1D3BEE989F292C1409E780F30B5C00D5965E35EC5957BCF172C26A93E337B1702FAD07940E5EDF2155F1F1CB33E363935829A64665AB6B6D7B6147673E02CF53BA128114C1396785C550D9FC3E38A2E15964CF7BE477766A7AA3310BC6729910C049FAF4FD5895AB3199830EAF34A67FD727FCE77F0FD546A70AE65011839B3A617EC1A2BB2F341A75EC989227E3DEB3DC4DC9911B0BC1F43425401B9D3355CF9139C9FC7
-20200326024940 2 6 100 8191 2 C9BECFEF229169BA6895957B61D338147FD9E67666267E2963D7A5587F57261CE8805A323015A9DA97865C6720A855FB346A80C284F9E8B8661DE02027ED9D77E29C25FD08E9BA260CF0D99BF2B69B0F054D642F8E29756D282B4523CF8CC058AA3A274F5D0766A30E269DC7AF3902DC139AC98994961A9186B5538B0F741A774918140CFC62D6BED7CB6E9333682F17683EF6EB53C2912F125105BDFAADB8046BD4FDFA60C4CE0CD0800D4247FFF67A72917E18D86BDFD6A4FBF3301E3290F5F5FF138F8EB4AD0C85AD4DEE6D590B44352B8B42C3A207C677CFCA215DE5391C9BFE5667698AB65D6955CA1FE8CE57D8EFC83FF5547E095FCC476FF3BAF6DD5B6D87F1C836CB712B54B115C0D7640F8F72CBDCE86DBCE6D2C04B7306B16E010A6CBE0BA95ABF269071BB1F5F433BC74D0C19889480A6B5C1683904837C36C7BCF69BE7CB96E0CAA07396224D694FB02F922B33D14C384923F946D104475F49D18A77AE5FA44ADA7C6E16D3B3085821C0B6814DCB565FDC44ED1942C9E25224ED96240D1FEF3817B6161BAD9F16B8C80953882C2FB2722515B10ABEBE969D2318AE9EB81CE91352329591D2874E6121205E072A3D5749190FA847D79B72BD3452DE0B5169601DDB6264AE70A1DC46B3637567787A11AA180B20623440C455722F8131FF09B47DC47814A4925B615A635D6DA05106825E764746CE76EDEE66F8782B9F688AA003B003857B5A659EAAE999171A9353DE0633614093E0A81E1346ABCDCB3CE1A40E8E086A2A2FB9B87394E0F6A0319F42C7B5B8BB9CFB0EF9FDFF6034A397E32E76B6F8C01F3DD2BE81FC938AFE7A1E1D763B4715B2D7CFB4DA9C0B4D013DE532F7D35E177542616DCC3F06736A25F60D0D486D5E4A3797C643977321C9908881170A23D22ADC8768E983DDB79594311DAF4D2CC28AC73E579F36297B0B007B86CB20F185C3A97E772B8FEF731D59A57C9A30D80C5E8B5F62715EA82BE29C5ADBB7A50B2A3E1FE26A7E77A9B53AB69E4A3D4552494F4F0A39459FE8AD9AA7AFEF7CB2560F759E735DED296AE22EDFDF5336671030749F5CE10E6C212BFDC97DA25C5BC80CD62BD490752CD84FA6B8A35BFC752A1CF07C9247C47A0D50D1AC3A713DDF9214E35FF74BF84799732CA0F7032F2ABA00E896CB731A26D09A44E870E9E46D452428F03F6C54CAD2A90A7D95F06F042A929DB5D1D3BEE989F292C1409E780F30B5C00D5965E35EC5957BCF172C26A93E337B1702FAD07940E5EDF2155F1F1CB33E363935829A64665AB6B6D7B6147673E02CF53BA128114C1396785C550D9FC3E38A2E15964CF7BE477766A7AA3310BC6729910C049FAF4FD5895AB3199830EAF34A67FD727FCE77F0FD546A70AE65011839B3A617EC1A2BB2F341A75EC989227E3DEB3DC4DC9911B0BC1F43425401B9D3355CF913B79CEB
-20200328134127 2 6 100 8191 5 C9BECFEF229169BA6895957B61D338147FD9E67666267E2963D7A5587F57261CE8805A323015A9DA97865C6720A855FB346A80C284F9E8B8661DE02027ED9D77E29C25FD08E9BA260CF0D99BF2B69B0F054D642F8E29756D282B4523CF8CC058AA3A274F5D0766A30E269DC7AF3902DC139AC98994961A9186B5538B0F741A774918140CFC62D6BED7CB6E9333682F17683EF6EB53C2912F125105BDFAADB8046BD4FDFA60C4CE0CD0800D4247FFF67A72917E18D86BDFD6A4FBF3301E3290F5F5FF138F8EB4AD0C85AD4DEE6D590B44352B8B42C3A207C677CFCA215DE5391C9BFE5667698AB65D6955CA1FE8CE57D8EFC83FF5547E095FCC476FF3BAF6DD5B6D87F1C836CB712B54B115C0D7640F8F72CBDCE86DBCE6D2C04B7306B16E010A6CBE0BA95ABF269071BB1F5F433BC74D0C19889480A6B5C1683904837C36C7BCF69BE7CB96E0CAA07396224D694FB02F922B33D14C384923F946D104475F49D18A77AE5FA44ADA7C6E16D3B3085821C0B6814DCB565FDC44ED1942C9E25224ED96240D1FEF3817B6161BAD9F16B8C80953882C2FB2722515B10ABEBE969D2318AE9EB81CE91352329591D2874E6121205E072A3D5749190FA847D79B72BD3452DE0B5169601DDB6264AE70A1DC46B3637567787A11AA180B20623440C455722F8131FF09B47DC47814A4925B615A635D6DA05106825E764746CE76EDEE66F8782B9F688AA003B003857B5A659EAAE999171A9353DE0633614093E0A81E1346ABCDCB3CE1A40E8E086A2A2FB9B87394E0F6A0319F42C7B5B8BB9CFB0EF9FDFF6034A397E32E76B6F8C01F3DD2BE81FC938AFE7A1E1D763B4715B2D7CFB4DA9C0B4D013DE532F7D35E177542616DCC3F06736A25F60D0D486D5E4A3797C643977321C9908881170A23D22ADC8768E983DDB79594311DAF4D2CC28AC73E579F36297B0B007B86CB20F185C3A97E772B8FEF731D59A57C9A30D80C5E8B5F62715EA82BE29C5ADBB7A50B2A3E1FE26A7E77A9B53AB69E4A3D4552494F4F0A39459FE8AD9AA7AFEF7CB2560F759E735DED296AE22EDFDF5336671030749F5CE10E6C212BFDC97DA25C5BC80CD62BD490752CD84FA6B8A35BFC752A1CF07C9247C47A0D50D1AC3A713DDF9214E35FF74BF84799732CA0F7032F2ABA00E896CB731A26D09A44E870E9E46D452428F03F6C54CAD2A90A7D95F06F042A929DB5D1D3BEE989F292C1409E780F30B5C00D5965E35EC5957BCF172C26A93E337B1702FAD07940E5EDF2155F1F1CB33E363935829A64665AB6B6D7B6147673E02CF53BA128114C1396785C550D9FC3E38A2E15964CF7BE477766A7AA3310BC6729910C049FAF4FD5895AB3199830EAF34A67FD727FCE77F0FD546A70AE65011839B3A617EC1A2BB2F341A75EC989227E3DEB3DC4DC9911B0BC1F43425401B9D3355CF92E9C709F
-20200328212714 2 6 100 8191 5 C9BECFEF229169BA6895957B61D338147FD9E67666267E2963D7A5587F57261CE8805A323015A9DA97865C6720A855FB346A80C284F9E8B8661DE02027ED9D77E29C25FD08E9BA260CF0D99BF2B69B0F054D642F8E29756D282B4523CF8CC058AA3A274F5D0766A30E269DC7AF3902DC139AC98994961A9186B5538B0F741A774918140CFC62D6BED7CB6E9333682F17683EF6EB53C2912F125105BDFAADB8046BD4FDFA60C4CE0CD0800D4247FFF67A72917E18D86BDFD6A4FBF3301E3290F5F5FF138F8EB4AD0C85AD4DEE6D590B44352B8B42C3A207C677CFCA215DE5391C9BFE5667698AB65D6955CA1FE8CE57D8EFC83FF5547E095FCC476FF3BAF6DD5B6D87F1C836CB712B54B115C0D7640F8F72CBDCE86DBCE6D2C04B7306B16E010A6CBE0BA95ABF269071BB1F5F433BC74D0C19889480A6B5C1683904837C36C7BCF69BE7CB96E0CAA07396224D694FB02F922B33D14C384923F946D104475F49D18A77AE5FA44ADA7C6E16D3B3085821C0B6814DCB565FDC44ED1942C9E25224ED96240D1FEF3817B6161BAD9F16B8C80953882C2FB2722515B10ABEBE969D2318AE9EB81CE91352329591D2874E6121205E072A3D5749190FA847D79B72BD3452DE0B5169601DDB6264AE70A1DC46B3637567787A11AA180B20623440C455722F8131FF09B47DC47814A4925B615A635D6DA05106825E764746CE76EDEE66F8782B9F688AA003B003857B5A659EAAE999171A9353DE0633614093E0A81E1346ABCDCB3CE1A40E8E086A2A2FB9B87394E0F6A0319F42C7B5B8BB9CFB0EF9FDFF6034A397E32E76B6F8C01F3DD2BE81FC938AFE7A1E1D763B4715B2D7CFB4DA9C0B4D013DE532F7D35E177542616DCC3F06736A25F60D0D486D5E4A3797C643977321C9908881170A23D22ADC8768E983DDB79594311DAF4D2CC28AC73E579F36297B0B007B86CB20F185C3A97E772B8FEF731D59A57C9A30D80C5E8B5F62715EA82BE29C5ADBB7A50B2A3E1FE26A7E77A9B53AB69E4A3D4552494F4F0A39459FE8AD9AA7AFEF7CB2560F759E735DED296AE22EDFDF5336671030749F5CE10E6C212BFDC97DA25C5BC80CD62BD490752CD84FA6B8A35BFC752A1CF07C9247C47A0D50D1AC3A713DDF9214E35FF74BF84799732CA0F7032F2ABA00E896CB731A26D09A44E870E9E46D452428F03F6C54CAD2A90A7D95F06F042A929DB5D1D3BEE989F292C1409E780F30B5C00D5965E35EC5957BCF172C26A93E337B1702FAD07940E5EDF2155F1F1CB33E363935829A64665AB6B6D7B6147673E02CF53BA128114C1396785C550D9FC3E38A2E15964CF7BE477766A7AA3310BC6729910C049FAF4FD5895AB3199830EAF34A67FD727FCE77F0FD546A70AE65011839B3A617EC1A2BB2F341A75EC989227E3DEB3DC4DC9911B0BC1F43425401B9D3355CF932A9BEAF
-20200329023213 2 6 100 8191 5 C9BECFEF229169BA6895957B61D338147FD9E67666267E2963D7A5587F57261CE8805A323015A9DA97865C6720A855FB346A80C284F9E8B8661DE02027ED9D77E29C25FD08E9BA260CF0D99BF2B69B0F054D642F8E29756D282B4523CF8CC058AA3A274F5D0766A30E269DC7AF3902DC139AC98994961A9186B5538B0F741A774918140CFC62D6BED7CB6E9333682F17683EF6EB53C2912F125105BDFAADB8046BD4FDFA60C4CE0CD0800D4247FFF67A72917E18D86BDFD6A4FBF3301E3290F5F5FF138F8EB4AD0C85AD4DEE6D590B44352B8B42C3A207C677CFCA215DE5391C9BFE5667698AB65D6955CA1FE8CE57D8EFC83FF5547E095FCC476FF3BAF6DD5B6D87F1C836CB712B54B115C0D7640F8F72CBDCE86DBCE6D2C04B7306B16E010A6CBE0BA95ABF269071BB1F5F433BC74D0C19889480A6B5C1683904837C36C7BCF69BE7CB96E0CAA07396224D694FB02F922B33D14C384923F946D104475F49D18A77AE5FA44ADA7C6E16D3B3085821C0B6814DCB565FDC44ED1942C9E25224ED96240D1FEF3817B6161BAD9F16B8C80953882C2FB2722515B10ABEBE969D2318AE9EB81CE91352329591D2874E6121205E072A3D5749190FA847D79B72BD3452DE0B5169601DDB6264AE70A1DC46B3637567787A11AA180B20623440C455722F8131FF09B47DC47814A4925B615A635D6DA05106825E764746CE76EDEE66F8782B9F688AA003B003857B5A659EAAE999171A9353DE0633614093E0A81E1346ABCDCB3CE1A40E8E086A2A2FB9B87394E0F6A0319F42C7B5B8BB9CFB0EF9FDFF6034A397E32E76B6F8C01F3DD2BE81FC938AFE7A1E1D763B4715B2D7CFB4DA9C0B4D013DE532F7D35E177542616DCC3F06736A25F60D0D486D5E4A3797C643977321C9908881170A23D22ADC8768E983DDB79594311DAF4D2CC28AC73E579F36297B0B007B86CB20F185C3A97E772B8FEF731D59A57C9A30D80C5E8B5F62715EA82BE29C5ADBB7A50B2A3E1FE26A7E77A9B53AB69E4A3D4552494F4F0A39459FE8AD9AA7AFEF7CB2560F759E735DED296AE22EDFDF5336671030749F5CE10E6C212BFDC97DA25C5BC80CD62BD490752CD84FA6B8A35BFC752A1CF07C9247C47A0D50D1AC3A713DDF9214E35FF74BF84799732CA0F7032F2ABA00E896CB731A26D09A44E870E9E46D452428F03F6C54CAD2A90A7D95F06F042A929DB5D1D3BEE989F292C1409E780F30B5C00D5965E35EC5957BCF172C26A93E337B1702FAD07940E5EDF2155F1F1CB33E363935829A64665AB6B6D7B6147673E02CF53BA128114C1396785C550D9FC3E38A2E15964CF7BE477766A7AA3310BC6729910C049FAF4FD5895AB3199830EAF34A67FD727FCE77F0FD546A70AE65011839B3A617EC1A2BB2F341A75EC989227E3DEB3DC4DC9911B0BC1F43425401B9D3355CF935A4196F
-20200329154240 2 6 100 8191 5 C9BECFEF229169BA6895957B61D338147FD9E67666267E2963D7A5587F57261CE8805A323015A9DA97865C6720A855FB346A80C284F9E8B8661DE02027ED9D77E29C25FD08E9BA260CF0D99BF2B69B0F054D642F8E29756D282B4523CF8CC058AA3A274F5D0766A30E269DC7AF3902DC139AC98994961A9186B5538B0F741A774918140CFC62D6BED7CB6E9333682F17683EF6EB53C2912F125105BDFAADB8046BD4FDFA60C4CE0CD0800D4247FFF67A72917E18D86BDFD6A4FBF3301E3290F5F5FF138F8EB4AD0C85AD4DEE6D590B44352B8B42C3A207C677CFCA215DE5391C9BFE5667698AB65D6955CA1FE8CE57D8EFC83FF5547E095FCC476FF3BAF6DD5B6D87F1C836CB712B54B115C0D7640F8F72CBDCE86DBCE6D2C04B7306B16E010A6CBE0BA95ABF269071BB1F5F433BC74D0C19889480A6B5C1683904837C36C7BCF69BE7CB96E0CAA07396224D694FB02F922B33D14C384923F946D104475F49D18A77AE5FA44ADA7C6E16D3B3085821C0B6814DCB565FDC44ED1942C9E25224ED96240D1FEF3817B6161BAD9F16B8C80953882C2FB2722515B10ABEBE969D2318AE9EB81CE91352329591D2874E6121205E072A3D5749190FA847D79B72BD3452DE0B5169601DDB6264AE70A1DC46B3637567787A11AA180B20623440C455722F8131FF09B47DC47814A4925B615A635D6DA05106825E764746CE76EDEE66F8782B9F688AA003B003857B5A659EAAE999171A9353DE0633614093E0A81E1346ABCDCB3CE1A40E8E086A2A2FB9B87394E0F6A0319F42C7B5B8BB9CFB0EF9FDFF6034A397E32E76B6F8C01F3DD2BE81FC938AFE7A1E1D763B4715B2D7CFB4DA9C0B4D013DE532F7D35E177542616DCC3F06736A25F60D0D486D5E4A3797C643977321C9908881170A23D22ADC8768E983DDB79594311DAF4D2CC28AC73E579F36297B0B007B86CB20F185C3A97E772B8FEF731D59A57C9A30D80C5E8B5F62715EA82BE29C5ADBB7A50B2A3E1FE26A7E77A9B53AB69E4A3D4552494F4F0A39459FE8AD9AA7AFEF7CB2560F759E735DED296AE22EDFDF5336671030749F5CE10E6C212BFDC97DA25C5BC80CD62BD490752CD84FA6B8A35BFC752A1CF07C9247C47A0D50D1AC3A713DDF9214E35FF74BF84799732CA0F7032F2ABA00E896CB731A26D09A44E870E9E46D452428F03F6C54CAD2A90A7D95F06F042A929DB5D1D3BEE989F292C1409E780F30B5C00D5965E35EC5957BCF172C26A93E337B1702FAD07940E5EDF2155F1F1CB33E363935829A64665AB6B6D7B6147673E02CF53BA128114C1396785C550D9FC3E38A2E15964CF7BE477766A7AA3310BC6729910C049FAF4FD5895AB3199830EAF34A67FD727FCE77F0FD546A70AE65011839B3A617EC1A2BB2F341A75EC989227E3DEB3DC4DC9911B0BC1F43425401B9D3355CF93D2BEF37
-20200329201144 2 6 100 8191 5 C9BECFEF229169BA6895957B61D338147FD9E67666267E2963D7A5587F57261CE8805A323015A9DA97865C6720A855FB346A80C284F9E8B8661DE02027ED9D77E29C25FD08E9BA260CF0D99BF2B69B0F054D642F8E29756D282B4523CF8CC058AA3A274F5D0766A30E269DC7AF3902DC139AC98994961A9186B5538B0F741A774918140CFC62D6BED7CB6E9333682F17683EF6EB53C2912F125105BDFAADB8046BD4FDFA60C4CE0CD0800D4247FFF67A72917E18D86BDFD6A4FBF3301E3290F5F5FF138F8EB4AD0C85AD4DEE6D590B44352B8B42C3A207C677CFCA215DE5391C9BFE5667698AB65D6955CA1FE8CE57D8EFC83FF5547E095FCC476FF3BAF6DD5B6D87F1C836CB712B54B115C0D7640F8F72CBDCE86DBCE6D2C04B7306B16E010A6CBE0BA95ABF269071BB1F5F433BC74D0C19889480A6B5C1683904837C36C7BCF69BE7CB96E0CAA07396224D694FB02F922B33D14C384923F946D104475F49D18A77AE5FA44ADA7C6E16D3B3085821C0B6814DCB565FDC44ED1942C9E25224ED96240D1FEF3817B6161BAD9F16B8C80953882C2FB2722515B10ABEBE969D2318AE9EB81CE91352329591D2874E6121205E072A3D5749190FA847D79B72BD3452DE0B5169601DDB6264AE70A1DC46B3637567787A11AA180B20623440C455722F8131FF09B47DC47814A4925B615A635D6DA05106825E764746CE76EDEE66F8782B9F688AA003B003857B5A659EAAE999171A9353DE0633614093E0A81E1346ABCDCB3CE1A40E8E086A2A2FB9B87394E0F6A0319F42C7B5B8BB9CFB0EF9FDFF6034A397E32E76B6F8C01F3DD2BE81FC938AFE7A1E1D763B4715B2D7CFB4DA9C0B4D013DE532F7D35E177542616DCC3F06736A25F60D0D486D5E4A3797C643977321C9908881170A23D22ADC8768E983DDB79594311DAF4D2CC28AC73E579F36297B0B007B86CB20F185C3A97E772B8FEF731D59A57C9A30D80C5E8B5F62715EA82BE29C5ADBB7A50B2A3E1FE26A7E77A9B53AB69E4A3D4552494F4F0A39459FE8AD9AA7AFEF7CB2560F759E735DED296AE22EDFDF5336671030749F5CE10E6C212BFDC97DA25C5BC80CD62BD490752CD84FA6B8A35BFC752A1CF07C9247C47A0D50D1AC3A713DDF9214E35FF74BF84799732CA0F7032F2ABA00E896CB731A26D09A44E870E9E46D452428F03F6C54CAD2A90A7D95F06F042A929DB5D1D3BEE989F292C1409E780F30B5C00D5965E35EC5957BCF172C26A93E337B1702FAD07940E5EDF2155F1F1CB33E363935829A64665AB6B6D7B6147673E02CF53BA128114C1396785C550D9FC3E38A2E15964CF7BE477766A7AA3310BC6729910C049FAF4FD5895AB3199830EAF34A67FD727FCE77F0FD546A70AE65011839B3A617EC1A2BB2F341A75EC989227E3DEB3DC4DC9911B0BC1F43425401B9D3355CF93F51B18F
-20200330113432 2 6 100 8191 2 C9BECFEF229169BA6895957B61D338147FD9E67666267E2963D7A5587F57261CE8805A323015A9DA97865C6720A855FB346A80C284F9E8B8661DE02027ED9D77E29C25FD08E9BA260CF0D99BF2B69B0F054D642F8E29756D282B4523CF8CC058AA3A274F5D0766A30E269DC7AF3902DC139AC98994961A9186B5538B0F741A774918140CFC62D6BED7CB6E9333682F17683EF6EB53C2912F125105BDFAADB8046BD4FDFA60C4CE0CD0800D4247FFF67A72917E18D86BDFD6A4FBF3301E3290F5F5FF138F8EB4AD0C85AD4DEE6D590B44352B8B42C3A207C677CFCA215DE5391C9BFE5667698AB65D6955CA1FE8CE57D8EFC83FF5547E095FCC476FF3BAF6DD5B6D87F1C836CB712B54B115C0D7640F8F72CBDCE86DBCE6D2C04B7306B16E010A6CBE0BA95ABF269071BB1F5F433BC74D0C19889480A6B5C1683904837C36C7BCF69BE7CB96E0CAA07396224D694FB02F922B33D14C384923F946D104475F49D18A77AE5FA44ADA7C6E16D3B3085821C0B6814DCB565FDC44ED1942C9E25224ED96240D1FEF3817B6161BAD9F16B8C80953882C2FB2722515B10ABEBE969D2318AE9EB81CE91352329591D2874E6121205E072A3D5749190FA847D79B72BD3452DE0B5169601DDB6264AE70A1DC46B3637567787A11AA180B20623440C455722F8131FF09B47DC47814A4925B615A635D6DA05106825E764746CE76EDEE66F8782B9F688AA003B003857B5A659EAAE999171A9353DE0633614093E0A81E1346ABCDCB3CE1A40E8E086A2A2FB9B87394E0F6A0319F42C7B5B8BB9CFB0EF9FDFF6034A397E32E76B6F8C01F3DD2BE81FC938AFE7A1E1D763B4715B2D7CFB4DA9C0B4D013DE532F7D35E177542616DCC3F06736A25F60D0D486D5E4A3797C643977321C9908881170A23D22ADC8768E983DDB79594311DAF4D2CC28AC73E579F36297B0B007B86CB20F185C3A97E772B8FEF731D59A57C9A30D80C5E8B5F62715EA82BE29C5ADBB7A50B2A3E1FE26A7E77A9B53AB69E4A3D4552494F4F0A39459FE8AD9AA7AFEF7CB2560F759E735DED296AE22EDFDF5336671030749F5CE10E6C212BFDC97DA25C5BC80CD62BD490752CD84FA6B8A35BFC752A1CF07C9247C47A0D50D1AC3A713DDF9214E35FF74BF84799732CA0F7032F2ABA00E896CB731A26D09A44E870E9E46D452428F03F6C54CAD2A90A7D95F06F042A929DB5D1D3BEE989F292C1409E780F30B5C00D5965E35EC5957BCF172C26A93E337B1702FAD07940E5EDF2155F1F1CB33E363935829A64665AB6B6D7B6147673E02CF53BA128114C1396785C550D9FC3E38A2E15964CF7BE477766A7AA3310BC6729910C049FAF4FD5895AB3199830EAF34A67FD727FCE77F0FD546A70AE65011839B3A617EC1A2BB2F341A75EC989227E3DEB3DC4DC9911B0BC1F43425401B9D3355CF944EA6E43
-20200331175854 2 6 100 8191 5 C9BECFEF229169BA6895957B61D338147FD9E67666267E2963D7A5587F57261CE8805A323015A9DA97865C6720A855FB346A80C284F9E8B8661DE02027ED9D77E29C25FD08E9BA260CF0D99BF2B69B0F054D642F8E29756D282B4523CF8CC058AA3A274F5D0766A30E269DC7AF3902DC139AC98994961A9186B5538B0F741A774918140CFC62D6BED7CB6E9333682F17683EF6EB53C2912F125105BDFAADB8046BD4FDFA60C4CE0CD0800D4247FFF67A72917E18D86BDFD6A4FBF3301E3290F5F5FF138F8EB4AD0C85AD4DEE6D590B44352B8B42C3A207C677CFCA215DE5391C9BFE5667698AB65D6955CA1FE8CE57D8EFC83FF5547E095FCC476FF3BAF6DD5B6D87F1C836CB712B54B115C0D7640F8F72CBDCE86DBCE6D2C04B7306B16E010A6CBE0BA95ABF269071BB1F5F433BC74D0C19889480A6B5C1683904837C36C7BCF69BE7CB96E0CAA07396224D694FB02F922B33D14C384923F946D104475F49D18A77AE5FA44ADA7C6E16D3B3085821C0B6814DCB565FDC44ED1942C9E25224ED96240D1FEF3817B6161BAD9F16B8C80953882C2FB2722515B10ABEBE969D2318AE9EB81CE91352329591D2874E6121205E072A3D5749190FA847D79B72BD3452DE0B5169601DDB6264AE70A1DC46B3637567787A11AA180B20623440C455722F8131FF09B47DC47814A4925B615A635D6DA05106825E764746CE76EDEE66F8782B9F688AA003B003857B5A659EAAE999171A9353DE0633614093E0A81E1346ABCDCB3CE1A40E8E086A2A2FB9B87394E0F6A0319F42C7B5B8BB9CFB0EF9FDFF6034A397E32E76B6F8C01F3DD2BE81FC938AFE7A1E1D763B4715B2D7CFB4DA9C0B4D013DE532F7D35E177542616DCC3F06736A25F60D0D486D5E4A3797C643977321C9908881170A23D22ADC8768E983DDB79594311DAF4D2CC28AC73E579F36297B0B007B86CB20F185C3A97E772B8FEF731D59A57C9A30D80C5E8B5F62715EA82BE29C5ADBB7A50B2A3E1FE26A7E77A9B53AB69E4A3D4552494F4F0A39459FE8AD9AA7AFEF7CB2560F759E735DED296AE22EDFDF5336671030749F5CE10E6C212BFDC97DA25C5BC80CD62BD490752CD84FA6B8A35BFC752A1CF07C9247C47A0D50D1AC3A713DDF9214E35FF74BF84799732CA0F7032F2ABA00E896CB731A26D09A44E870E9E46D452428F03F6C54CAD2A90A7D95F06F042A929DB5D1D3BEE989F292C1409E780F30B5C00D5965E35EC5957BCF172C26A93E337B1702FAD07940E5EDF2155F1F1CB33E363935829A64665AB6B6D7B6147673E02CF53BA128114C1396785C550D9FC3E38A2E15964CF7BE477766A7AA3310BC6729910C049FAF4FD5895AB3199830EAF34A67FD727FCE77F0FD546A70AE65011839B3A617EC1A2BB2F341A75EC989227E3DEB3DC4DC9911B0BC1F43425401B9D3355CF94C88CF9F
-20200401041044 2 6 100 8191 5 C9BECFEF229169BA6895957B61D338147FD9E67666267E2963D7A5587F57261CE8805A323015A9DA97865C6720A855FB346A80C284F9E8B8661DE02027ED9D77E29C25FD08E9BA260CF0D99BF2B69B0F054D642F8E29756D282B4523CF8CC058AA3A274F5D0766A30E269DC7AF3902DC139AC98994961A9186B5538B0F741A774918140CFC62D6BED7CB6E9333682F17683EF6EB53C2912F125105BDFAADB8046BD4FDFA60C4CE0CD0800D4247FFF67A72917E18D86BDFD6A4FBF3301E3290F5F5FF138F8EB4AD0C85AD4DEE6D590B44352B8B42C3A207C677CFCA215DE5391C9BFE5667698AB65D6955CA1FE8CE57D8EFC83FF5547E095FCC476FF3BAF6DD5B6D87F1C836CB712B54B115C0D7640F8F72CBDCE86DBCE6D2C04B7306B16E010A6CBE0BA95ABF269071BB1F5F433BC74D0C19889480A6B5C1683904837C36C7BCF69BE7CB96E0CAA07396224D694FB02F922B33D14C384923F946D104475F49D18A77AE5FA44ADA7C6E16D3B3085821C0B6814DCB565FDC44ED1942C9E25224ED96240D1FEF3817B6161BAD9F16B8C80953882C2FB2722515B10ABEBE969D2318AE9EB81CE91352329591D2874E6121205E072A3D5749190FA847D79B72BD3452DE0B5169601DDB6264AE70A1DC46B3637567787A11AA180B20623440C455722F8131FF09B47DC47814A4925B615A635D6DA05106825E764746CE76EDEE66F8782B9F688AA003B003857B5A659EAAE999171A9353DE0633614093E0A81E1346ABCDCB3CE1A40E8E086A2A2FB9B87394E0F6A0319F42C7B5B8BB9CFB0EF9FDFF6034A397E32E76B6F8C01F3DD2BE81FC938AFE7A1E1D763B4715B2D7CFB4DA9C0B4D013DE532F7D35E177542616DCC3F06736A25F60D0D486D5E4A3797C643977321C9908881170A23D22ADC8768E983DDB79594311DAF4D2CC28AC73E579F36297B0B007B86CB20F185C3A97E772B8FEF731D59A57C9A30D80C5E8B5F62715EA82BE29C5ADBB7A50B2A3E1FE26A7E77A9B53AB69E4A3D4552494F4F0A39459FE8AD9AA7AFEF7CB2560F759E735DED296AE22EDFDF5336671030749F5CE10E6C212BFDC97DA25C5BC80CD62BD490752CD84FA6B8A35BFC752A1CF07C9247C47A0D50D1AC3A713DDF9214E35FF74BF84799732CA0F7032F2ABA00E896CB731A26D09A44E870E9E46D452428F03F6C54CAD2A90A7D95F06F042A929DB5D1D3BEE989F292C1409E780F30B5C00D5965E35EC5957BCF172C26A93E337B1702FAD07940E5EDF2155F1F1CB33E363935829A64665AB6B6D7B6147673E02CF53BA128114C1396785C550D9FC3E38A2E15964CF7BE477766A7AA3310BC6729910C049FAF4FD5895AB3199830EAF34A67FD727FCE77F0FD546A70AE65011839B3A617EC1A2BB2F341A75EC989227E3DEB3DC4DC9911B0BC1F43425401B9D3355CF94F14974F
-20200401113456 2 6 100 8191 2 C9BECFEF229169BA6895957B61D338147FD9E67666267E2963D7A5587F57261CE8805A323015A9DA97865C6720A855FB346A80C284F9E8B8661DE02027ED9D77E29C25FD08E9BA260CF0D99BF2B69B0F054D642F8E29756D282B4523CF8CC058AA3A274F5D0766A30E269DC7AF3902DC139AC98994961A9186B5538B0F741A774918140CFC62D6BED7CB6E9333682F17683EF6EB53C2912F125105BDFAADB8046BD4FDFA60C4CE0CD0800D4247FFF67A72917E18D86BDFD6A4FBF3301E3290F5F5FF138F8EB4AD0C85AD4DEE6D590B44352B8B42C3A207C677CFCA215DE5391C9BFE5667698AB65D6955CA1FE8CE57D8EFC83FF5547E095FCC476FF3BAF6DD5B6D87F1C836CB712B54B115C0D7640F8F72CBDCE86DBCE6D2C04B7306B16E010A6CBE0BA95ABF269071BB1F5F433BC74D0C19889480A6B5C1683904837C36C7BCF69BE7CB96E0CAA07396224D694FB02F922B33D14C384923F946D104475F49D18A77AE5FA44ADA7C6E16D3B3085821C0B6814DCB565FDC44ED1942C9E25224ED96240D1FEF3817B6161BAD9F16B8C80953882C2FB2722515B10ABEBE969D2318AE9EB81CE91352329591D2874E6121205E072A3D5749190FA847D79B72BD3452DE0B5169601DDB6264AE70A1DC46B3637567787A11AA180B20623440C455722F8131FF09B47DC47814A4925B615A635D6DA05106825E764746CE76EDEE66F8782B9F688AA003B003857B5A659EAAE999171A9353DE0633614093E0A81E1346ABCDCB3CE1A40E8E086A2A2FB9B87394E0F6A0319F42C7B5B8BB9CFB0EF9FDFF6034A397E32E76B6F8C01F3DD2BE81FC938AFE7A1E1D763B4715B2D7CFB4DA9C0B4D013DE532F7D35E177542616DCC3F06736A25F60D0D486D5E4A3797C643977321C9908881170A23D22ADC8768E983DDB79594311DAF4D2CC28AC73E579F36297B0B007B86CB20F185C3A97E772B8FEF731D59A57C9A30D80C5E8B5F62715EA82BE29C5ADBB7A50B2A3E1FE26A7E77A9B53AB69E4A3D4552494F4F0A39459FE8AD9AA7AFEF7CB2560F759E735DED296AE22EDFDF5336671030749F5CE10E6C212BFDC97DA25C5BC80CD62BD490752CD84FA6B8A35BFC752A1CF07C9247C47A0D50D1AC3A713DDF9214E35FF74BF84799732CA0F7032F2ABA00E896CB731A26D09A44E870E9E46D452428F03F6C54CAD2A90A7D95F06F042A929DB5D1D3BEE989F292C1409E780F30B5C00D5965E35EC5957BCF172C26A93E337B1702FAD07940E5EDF2155F1F1CB33E363935829A64665AB6B6D7B6147673E02CF53BA128114C1396785C550D9FC3E38A2E15964CF7BE477766A7AA3310BC6729910C049FAF4FD5895AB3199830EAF34A67FD727FCE77F0FD546A70AE65011839B3A617EC1A2BB2F341A75EC989227E3DEB3DC4DC9911B0BC1F43425401B9D3355CF950E7AC23
-20200402184624 2 6 100 8191 2 C9BECFEF229169BA6895957B61D338147FD9E67666267E2963D7A5587F57261CE8805A323015A9DA97865C6720A855FB346A80C284F9E8B8661DE02027ED9D77E29C25FD08E9BA260CF0D99BF2B69B0F054D642F8E29756D282B4523CF8CC058AA3A274F5D0766A30E269DC7AF3902DC139AC98994961A9186B5538B0F741A774918140CFC62D6BED7CB6E9333682F17683EF6EB53C2912F125105BDFAADB8046BD4FDFA60C4CE0CD0800D4247FFF67A72917E18D86BDFD6A4FBF3301E3290F5F5FF138F8EB4AD0C85AD4DEE6D590B44352B8B42C3A207C677CFCA215DE5391C9BFE5667698AB65D6955CA1FE8CE57D8EFC83FF5547E095FCC476FF3BAF6DD5B6D87F1C836CB712B54B115C0D7640F8F72CBDCE86DBCE6D2C04B7306B16E010A6CBE0BA95ABF269071BB1F5F433BC74D0C19889480A6B5C1683904837C36C7BCF69BE7CB96E0CAA07396224D694FB02F922B33D14C384923F946D104475F49D18A77AE5FA44ADA7C6E16D3B3085821C0B6814DCB565FDC44ED1942C9E25224ED96240D1FEF3817B6161BAD9F16B8C80953882C2FB2722515B10ABEBE969D2318AE9EB81CE91352329591D2874E6121205E072A3D5749190FA847D79B72BD3452DE0B5169601DDB6264AE70A1DC46B3637567787A11AA180B20623440C455722F8131FF09B47DC47814A4925B615A635D6DA05106825E764746CE76EDEE66F8782B9F688AA003B003857B5A659EAAE999171A9353DE0633614093E0A81E1346ABCDCB3CE1A40E8E086A2A2FB9B87394E0F6A0319F42C7B5B8BB9CFB0EF9FDFF6034A397E32E76B6F8C01F3DD2BE81FC938AFE7A1E1D763B4715B2D7CFB4DA9C0B4D013DE532F7D35E177542616DCC3F06736A25F60D0D486D5E4A3797C643977321C9908881170A23D22ADC8768E983DDB79594311DAF4D2CC28AC73E579F36297B0B007B86CB20F185C3A97E772B8FEF731D59A57C9A30D80C5E8B5F62715EA82BE29C5ADBB7A50B2A3E1FE26A7E77A9B53AB69E4A3D4552494F4F0A39459FE8AD9AA7AFEF7CB2560F759E735DED296AE22EDFDF5336671030749F5CE10E6C212BFDC97DA25C5BC80CD62BD490752CD84FA6B8A35BFC752A1CF07C9247C47A0D50D1AC3A713DDF9214E35FF74BF84799732CA0F7032F2ABA00E896CB731A26D09A44E870E9E46D452428F03F6C54CAD2A90A7D95F06F042A929DB5D1D3BEE989F292C1409E780F30B5C00D5965E35EC5957BCF172C26A93E337B1702FAD07940E5EDF2155F1F1CB33E363935829A64665AB6B6D7B6147673E02CF53BA128114C1396785C550D9FC3E38A2E15964CF7BE477766A7AA3310BC6729910C049FAF4FD5895AB3199830EAF34A67FD727FCE77F0FD546A70AE65011839B3A617EC1A2BB2F341A75EC989227E3DEB3DC4DC9911B0BC1F43425401B9D3355CF958E471B3
-20200402210643 2 6 100 8191 2 C9BECFEF229169BA6895957B61D338147FD9E67666267E2963D7A5587F57261CE8805A323015A9DA97865C6720A855FB346A80C284F9E8B8661DE02027ED9D77E29C25FD08E9BA260CF0D99BF2B69B0F054D642F8E29756D282B4523CF8CC058AA3A274F5D0766A30E269DC7AF3902DC139AC98994961A9186B5538B0F741A774918140CFC62D6BED7CB6E9333682F17683EF6EB53C2912F125105BDFAADB8046BD4FDFA60C4CE0CD0800D4247FFF67A72917E18D86BDFD6A4FBF3301E3290F5F5FF138F8EB4AD0C85AD4DEE6D590B44352B8B42C3A207C677CFCA215DE5391C9BFE5667698AB65D6955CA1FE8CE57D8EFC83FF5547E095FCC476FF3BAF6DD5B6D87F1C836CB712B54B115C0D7640F8F72CBDCE86DBCE6D2C04B7306B16E010A6CBE0BA95ABF269071BB1F5F433BC74D0C19889480A6B5C1683904837C36C7BCF69BE7CB96E0CAA07396224D694FB02F922B33D14C384923F946D104475F49D18A77AE5FA44ADA7C6E16D3B3085821C0B6814DCB565FDC44ED1942C9E25224ED96240D1FEF3817B6161BAD9F16B8C80953882C2FB2722515B10ABEBE969D2318AE9EB81CE91352329591D2874E6121205E072A3D5749190FA847D79B72BD3452DE0B5169601DDB6264AE70A1DC46B3637567787A11AA180B20623440C455722F8131FF09B47DC47814A4925B615A635D6DA05106825E764746CE76EDEE66F8782B9F688AA003B003857B5A659EAAE999171A9353DE0633614093E0A81E1346ABCDCB3CE1A40E8E086A2A2FB9B87394E0F6A0319F42C7B5B8BB9CFB0EF9FDFF6034A397E32E76B6F8C01F3DD2BE81FC938AFE7A1E1D763B4715B2D7CFB4DA9C0B4D013DE532F7D35E177542616DCC3F06736A25F60D0D486D5E4A3797C643977321C9908881170A23D22ADC8768E983DDB79594311DAF4D2CC28AC73E579F36297B0B007B86CB20F185C3A97E772B8FEF731D59A57C9A30D80C5E8B5F62715EA82BE29C5ADBB7A50B2A3E1FE26A7E77A9B53AB69E4A3D4552494F4F0A39459FE8AD9AA7AFEF7CB2560F759E735DED296AE22EDFDF5336671030749F5CE10E6C212BFDC97DA25C5BC80CD62BD490752CD84FA6B8A35BFC752A1CF07C9247C47A0D50D1AC3A713DDF9214E35FF74BF84799732CA0F7032F2ABA00E896CB731A26D09A44E870E9E46D452428F03F6C54CAD2A90A7D95F06F042A929DB5D1D3BEE989F292C1409E780F30B5C00D5965E35EC5957BCF172C26A93E337B1702FAD07940E5EDF2155F1F1CB33E363935829A64665AB6B6D7B6147673E02CF53BA128114C1396785C550D9FC3E38A2E15964CF7BE477766A7AA3310BC6729910C049FAF4FD5895AB3199830EAF34A67FD727FCE77F0FD546A70AE65011839B3A617EC1A2BB2F341A75EC989227E3DEB3DC4DC9911B0BC1F43425401B9D3355CF9598F1B73
-20200403191828 2 6 100 8191 2 C9BECFEF229169BA6895957B61D338147FD9E67666267E2963D7A5587F57261CE8805A323015A9DA97865C6720A855FB346A80C284F9E8B8661DE02027ED9D77E29C25FD08E9BA260CF0D99BF2B69B0F054D642F8E29756D282B4523CF8CC058AA3A274F5D0766A30E269DC7AF3902DC139AC98994961A9186B5538B0F741A774918140CFC62D6BED7CB6E9333682F17683EF6EB53C2912F125105BDFAADB8046BD4FDFA60C4CE0CD0800D4247FFF67A72917E18D86BDFD6A4FBF3301E3290F5F5FF138F8EB4AD0C85AD4DEE6D590B44352B8B42C3A207C677CFCA215DE5391C9BFE5667698AB65D6955CA1FE8CE57D8EFC83FF5547E095FCC476FF3BAF6DD5B6D87F1C836CB712B54B115C0D7640F8F72CBDCE86DBCE6D2C04B7306B16E010A6CBE0BA95ABF269071BB1F5F433BC74D0C19889480A6B5C1683904837C36C7BCF69BE7CB96E0CAA07396224D694FB02F922B33D14C384923F946D104475F49D18A77AE5FA44ADA7C6E16D3B3085821C0B6814DCB565FDC44ED1942C9E25224ED96240D1FEF3817B6161BAD9F16B8C80953882C2FB2722515B10ABEBE969D2318AE9EB81CE91352329591D2874E6121205E072A3D5749190FA847D79B72BD3452DE0B5169601DDB6264AE70A1DC46B3637567787A11AA180B20623440C455722F8131FF09B47DC47814A4925B615A635D6DA05106825E764746CE76EDEE66F8782B9F688AA003B003857B5A659EAAE999171A9353DE0633614093E0A81E1346ABCDCB3CE1A40E8E086A2A2FB9B87394E0F6A0319F42C7B5B8BB9CFB0EF9FDFF6034A397E32E76B6F8C01F3DD2BE81FC938AFE7A1E1D763B4715B2D7CFB4DA9C0B4D013DE532F7D35E177542616DCC3F06736A25F60D0D486D5E4A3797C643977321C9908881170A23D22ADC8768E983DDB79594311DAF4D2CC28AC73E579F36297B0B007B86CB20F185C3A97E772B8FEF731D59A57C9A30D80C5E8B5F62715EA82BE29C5ADBB7A50B2A3E1FE26A7E77A9B53AB69E4A3D4552494F4F0A39459FE8AD9AA7AFEF7CB2560F759E735DED296AE22EDFDF5336671030749F5CE10E6C212BFDC97DA25C5BC80CD62BD490752CD84FA6B8A35BFC752A1CF07C9247C47A0D50D1AC3A713DDF9214E35FF74BF84799732CA0F7032F2ABA00E896CB731A26D09A44E870E9E46D452428F03F6C54CAD2A90A7D95F06F042A929DB5D1D3BEE989F292C1409E780F30B5C00D5965E35EC5957BCF172C26A93E337B1702FAD07940E5EDF2155F1F1CB33E363935829A64665AB6B6D7B6147673E02CF53BA128114C1396785C550D9FC3E38A2E15964CF7BE477766A7AA3310BC6729910C049FAF4FD5895AB3199830EAF34A67FD727FCE77F0FD546A70AE65011839B3A617EC1A2BB2F341A75EC989227E3DEB3DC4DC9911B0BC1F43425401B9D3355CF95C0DDE53
-20200403200234 2 6 100 8191 5 C9BECFEF229169BA6895957B61D338147FD9E67666267E2963D7A5587F57261CE8805A323015A9DA97865C6720A855FB346A80C284F9E8B8661DE02027ED9D77E29C25FD08E9BA260CF0D99BF2B69B0F054D642F8E29756D282B4523CF8CC058AA3A274F5D0766A30E269DC7AF3902DC139AC98994961A9186B5538B0F741A774918140CFC62D6BED7CB6E9333682F17683EF6EB53C2912F125105BDFAADB8046BD4FDFA60C4CE0CD0800D4247FFF67A72917E18D86BDFD6A4FBF3301E3290F5F5FF138F8EB4AD0C85AD4DEE6D590B44352B8B42C3A207C677CFCA215DE5391C9BFE5667698AB65D6955CA1FE8CE57D8EFC83FF5547E095FCC476FF3BAF6DD5B6D87F1C836CB712B54B115C0D7640F8F72CBDCE86DBCE6D2C04B7306B16E010A6CBE0BA95ABF269071BB1F5F433BC74D0C19889480A6B5C1683904837C36C7BCF69BE7CB96E0CAA07396224D694FB02F922B33D14C384923F946D104475F49D18A77AE5FA44ADA7C6E16D3B3085821C0B6814DCB565FDC44ED1942C9E25224ED96240D1FEF3817B6161BAD9F16B8C80953882C2FB2722515B10ABEBE969D2318AE9EB81CE91352329591D2874E6121205E072A3D5749190FA847D79B72BD3452DE0B5169601DDB6264AE70A1DC46B3637567787A11AA180B20623440C455722F8131FF09B47DC47814A4925B615A635D6DA05106825E764746CE76EDEE66F8782B9F688AA003B003857B5A659EAAE999171A9353DE0633614093E0A81E1346ABCDCB3CE1A40E8E086A2A2FB9B87394E0F6A0319F42C7B5B8BB9CFB0EF9FDFF6034A397E32E76B6F8C01F3DD2BE81FC938AFE7A1E1D763B4715B2D7CFB4DA9C0B4D013DE532F7D35E177542616DCC3F06736A25F60D0D486D5E4A3797C643977321C9908881170A23D22ADC8768E983DDB79594311DAF4D2CC28AC73E579F36297B0B007B86CB20F185C3A97E772B8FEF731D59A57C9A30D80C5E8B5F62715EA82BE29C5ADBB7A50B2A3E1FE26A7E77A9B53AB69E4A3D4552494F4F0A39459FE8AD9AA7AFEF7CB2560F759E735DED296AE22EDFDF5336671030749F5CE10E6C212BFDC97DA25C5BC80CD62BD490752CD84FA6B8A35BFC752A1CF07C9247C47A0D50D1AC3A713DDF9214E35FF74BF84799732CA0F7032F2ABA00E896CB731A26D09A44E870E9E46D452428F03F6C54CAD2A90A7D95F06F042A929DB5D1D3BEE989F292C1409E780F30B5C00D5965E35EC5957BCF172C26A93E337B1702FAD07940E5EDF2155F1F1CB33E363935829A64665AB6B6D7B6147673E02CF53BA128114C1396785C550D9FC3E38A2E15964CF7BE477766A7AA3310BC6729910C049FAF4FD5895AB3199830EAF34A67FD727FCE77F0FD546A70AE65011839B3A617EC1A2BB2F341A75EC989227E3DEB3DC4DC9911B0BC1F43425401B9D3355CF95C32F9F7
-20200404072948 2 6 100 8191 5 C9BECFEF229169BA6895957B61D338147FD9E67666267E2963D7A5587F57261CE8805A323015A9DA97865C6720A855FB346A80C284F9E8B8661DE02027ED9D77E29C25FD08E9BA260CF0D99BF2B69B0F054D642F8E29756D282B4523CF8CC058AA3A274F5D0766A30E269DC7AF3902DC139AC98994961A9186B5538B0F741A774918140CFC62D6BED7CB6E9333682F17683EF6EB53C2912F125105BDFAADB8046BD4FDFA60C4CE0CD0800D4247FFF67A72917E18D86BDFD6A4FBF3301E3290F5F5FF138F8EB4AD0C85AD4DEE6D590B44352B8B42C3A207C677CFCA215DE5391C9BFE5667698AB65D6955CA1FE8CE57D8EFC83FF5547E095FCC476FF3BAF6DD5B6D87F1C836CB712B54B115C0D7640F8F72CBDCE86DBCE6D2C04B7306B16E010A6CBE0BA95ABF269071BB1F5F433BC74D0C19889480A6B5C1683904837C36C7BCF69BE7CB96E0CAA07396224D694FB02F922B33D14C384923F946D104475F49D18A77AE5FA44ADA7C6E16D3B3085821C0B6814DCB565FDC44ED1942C9E25224ED96240D1FEF3817B6161BAD9F16B8C80953882C2FB2722515B10ABEBE969D2318AE9EB81CE91352329591D2874E6121205E072A3D5749190FA847D79B72BD3452DE0B5169601DDB6264AE70A1DC46B3637567787A11AA180B20623440C455722F8131FF09B47DC47814A4925B615A635D6DA05106825E764746CE76EDEE66F8782B9F688AA003B003857B5A659EAAE999171A9353DE0633614093E0A81E1346ABCDCB3CE1A40E8E086A2A2FB9B87394E0F6A0319F42C7B5B8BB9CFB0EF9FDFF6034A397E32E76B6F8C01F3DD2BE81FC938AFE7A1E1D763B4715B2D7CFB4DA9C0B4D013DE532F7D35E177542616DCC3F06736A25F60D0D486D5E4A3797C643977321C9908881170A23D22ADC8768E983DDB79594311DAF4D2CC28AC73E579F36297B0B007B86CB20F185C3A97E772B8FEF731D59A57C9A30D80C5E8B5F62715EA82BE29C5ADBB7A50B2A3E1FE26A7E77A9B53AB69E4A3D4552494F4F0A39459FE8AD9AA7AFEF7CB2560F759E735DED296AE22EDFDF5336671030749F5CE10E6C212BFDC97DA25C5BC80CD62BD490752CD84FA6B8A35BFC752A1CF07C9247C47A0D50D1AC3A713DDF9214E35FF74BF84799732CA0F7032F2ABA00E896CB731A26D09A44E870E9E46D452428F03F6C54CAD2A90A7D95F06F042A929DB5D1D3BEE989F292C1409E780F30B5C00D5965E35EC5957BCF172C26A93E337B1702FAD07940E5EDF2155F1F1CB33E363935829A64665AB6B6D7B6147673E02CF53BA128114C1396785C550D9FC3E38A2E15964CF7BE477766A7AA3310BC6729910C049FAF4FD5895AB3199830EAF34A67FD727FCE77F0FD546A70AE65011839B3A617EC1A2BB2F341A75EC989227E3DEB3DC4DC9911B0BC1F43425401B9D3355CF95EFCC91F
-20200404154328 2 6 100 8191 2 C9BECFEF229169BA6895957B61D338147FD9E67666267E2963D7A5587F57261CE8805A323015A9DA97865C6720A855FB346A80C284F9E8B8661DE02027ED9D77E29C25FD08E9BA260CF0D99BF2B69B0F054D642F8E29756D282B4523CF8CC058AA3A274F5D0766A30E269DC7AF3902DC139AC98994961A9186B5538B0F741A774918140CFC62D6BED7CB6E9333682F17683EF6EB53C2912F125105BDFAADB8046BD4FDFA60C4CE0CD0800D4247FFF67A72917E18D86BDFD6A4FBF3301E3290F5F5FF138F8EB4AD0C85AD4DEE6D590B44352B8B42C3A207C677CFCA215DE5391C9BFE5667698AB65D6955CA1FE8CE57D8EFC83FF5547E095FCC476FF3BAF6DD5B6D87F1C836CB712B54B115C0D7640F8F72CBDCE86DBCE6D2C04B7306B16E010A6CBE0BA95ABF269071BB1F5F433BC74D0C19889480A6B5C1683904837C36C7BCF69BE7CB96E0CAA07396224D694FB02F922B33D14C384923F946D104475F49D18A77AE5FA44ADA7C6E16D3B3085821C0B6814DCB565FDC44ED1942C9E25224ED96240D1FEF3817B6161BAD9F16B8C80953882C2FB2722515B10ABEBE969D2318AE9EB81CE91352329591D2874E6121205E072A3D5749190FA847D79B72BD3452DE0B5169601DDB6264AE70A1DC46B3637567787A11AA180B20623440C455722F8131FF09B47DC47814A4925B615A635D6DA05106825E764746CE76EDEE66F8782B9F688AA003B003857B5A659EAAE999171A9353DE0633614093E0A81E1346ABCDCB3CE1A40E8E086A2A2FB9B87394E0F6A0319F42C7B5B8BB9CFB0EF9FDFF6034A397E32E76B6F8C01F3DD2BE81FC938AFE7A1E1D763B4715B2D7CFB4DA9C0B4D013DE532F7D35E177542616DCC3F06736A25F60D0D486D5E4A3797C643977321C9908881170A23D22ADC8768E983DDB79594311DAF4D2CC28AC73E579F36297B0B007B86CB20F185C3A97E772B8FEF731D59A57C9A30D80C5E8B5F62715EA82BE29C5ADBB7A50B2A3E1FE26A7E77A9B53AB69E4A3D4552494F4F0A39459FE8AD9AA7AFEF7CB2560F759E735DED296AE22EDFDF5336671030749F5CE10E6C212BFDC97DA25C5BC80CD62BD490752CD84FA6B8A35BFC752A1CF07C9247C47A0D50D1AC3A713DDF9214E35FF74BF84799732CA0F7032F2ABA00E896CB731A26D09A44E870E9E46D452428F03F6C54CAD2A90A7D95F06F042A929DB5D1D3BEE989F292C1409E780F30B5C00D5965E35EC5957BCF172C26A93E337B1702FAD07940E5EDF2155F1F1CB33E363935829A64665AB6B6D7B6147673E02CF53BA128114C1396785C550D9FC3E38A2E15964CF7BE477766A7AA3310BC6729910C049FAF4FD5895AB3199830EAF34A67FD727FCE77F0FD546A70AE65011839B3A617EC1A2BB2F341A75EC989227E3DEB3DC4DC9911B0BC1F43425401B9D3355CF9626ACABB
-20200404173401 2 6 100 8191 2 C9BECFEF229169BA6895957B61D338147FD9E67666267E2963D7A5587F57261CE8805A323015A9DA97865C6720A855FB346A80C284F9E8B8661DE02027ED9D77E29C25FD08E9BA260CF0D99BF2B69B0F054D642F8E29756D282B4523CF8CC058AA3A274F5D0766A30E269DC7AF3902DC139AC98994961A9186B5538B0F741A774918140CFC62D6BED7CB6E9333682F17683EF6EB53C2912F125105BDFAADB8046BD4FDFA60C4CE0CD0800D4247FFF67A72917E18D86BDFD6A4FBF3301E3290F5F5FF138F8EB4AD0C85AD4DEE6D590B44352B8B42C3A207C677CFCA215DE5391C9BFE5667698AB65D6955CA1FE8CE57D8EFC83FF5547E095FCC476FF3BAF6DD5B6D87F1C836CB712B54B115C0D7640F8F72CBDCE86DBCE6D2C04B7306B16E010A6CBE0BA95ABF269071BB1F5F433BC74D0C19889480A6B5C1683904837C36C7BCF69BE7CB96E0CAA07396224D694FB02F922B33D14C384923F946D104475F49D18A77AE5FA44ADA7C6E16D3B3085821C0B6814DCB565FDC44ED1942C9E25224ED96240D1FEF3817B6161BAD9F16B8C80953882C2FB2722515B10ABEBE969D2318AE9EB81CE91352329591D2874E6121205E072A3D5749190FA847D79B72BD3452DE0B5169601DDB6264AE70A1DC46B3637567787A11AA180B20623440C455722F8131FF09B47DC47814A4925B615A635D6DA05106825E764746CE76EDEE66F8782B9F688AA003B003857B5A659EAAE999171A9353DE0633614093E0A81E1346ABCDCB3CE1A40E8E086A2A2FB9B87394E0F6A0319F42C7B5B8BB9CFB0EF9FDFF6034A397E32E76B6F8C01F3DD2BE81FC938AFE7A1E1D763B4715B2D7CFB4DA9C0B4D013DE532F7D35E177542616DCC3F06736A25F60D0D486D5E4A3797C643977321C9908881170A23D22ADC8768E983DDB79594311DAF4D2CC28AC73E579F36297B0B007B86CB20F185C3A97E772B8FEF731D59A57C9A30D80C5E8B5F62715EA82BE29C5ADBB7A50B2A3E1FE26A7E77A9B53AB69E4A3D4552494F4F0A39459FE8AD9AA7AFEF7CB2560F759E735DED296AE22EDFDF5336671030749F5CE10E6C212BFDC97DA25C5BC80CD62BD490752CD84FA6B8A35BFC752A1CF07C9247C47A0D50D1AC3A713DDF9214E35FF74BF84799732CA0F7032F2ABA00E896CB731A26D09A44E870E9E46D452428F03F6C54CAD2A90A7D95F06F042A929DB5D1D3BEE989F292C1409E780F30B5C00D5965E35EC5957BCF172C26A93E337B1702FAD07940E5EDF2155F1F1CB33E363935829A64665AB6B6D7B6147673E02CF53BA128114C1396785C550D9FC3E38A2E15964CF7BE477766A7AA3310BC6729910C049FAF4FD5895AB3199830EAF34A67FD727FCE77F0FD546A70AE65011839B3A617EC1A2BB2F341A75EC989227E3DEB3DC4DC9911B0BC1F43425401B9D3355CF963319AF3
-20200404190652 2 6 100 8191 5 C9BECFEF229169BA6895957B61D338147FD9E67666267E2963D7A5587F57261CE8805A323015A9DA97865C6720A855FB346A80C284F9E8B8661DE02027ED9D77E29C25FD08E9BA260CF0D99BF2B69B0F054D642F8E29756D282B4523CF8CC058AA3A274F5D0766A30E269DC7AF3902DC139AC98994961A9186B5538B0F741A774918140CFC62D6BED7CB6E9333682F17683EF6EB53C2912F125105BDFAADB8046BD4FDFA60C4CE0CD0800D4247FFF67A72917E18D86BDFD6A4FBF3301E3290F5F5FF138F8EB4AD0C85AD4DEE6D590B44352B8B42C3A207C677CFCA215DE5391C9BFE5667698AB65D6955CA1FE8CE57D8EFC83FF5547E095FCC476FF3BAF6DD5B6D87F1C836CB712B54B115C0D7640F8F72CBDCE86DBCE6D2C04B7306B16E010A6CBE0BA95ABF269071BB1F5F433BC74D0C19889480A6B5C1683904837C36C7BCF69BE7CB96E0CAA07396224D694FB02F922B33D14C384923F946D104475F49D18A77AE5FA44ADA7C6E16D3B3085821C0B6814DCB565FDC44ED1942C9E25224ED96240D1FEF3817B6161BAD9F16B8C80953882C2FB2722515B10ABEBE969D2318AE9EB81CE91352329591D2874E6121205E072A3D5749190FA847D79B72BD3452DE0B5169601DDB6264AE70A1DC46B3637567787A11AA180B20623440C455722F8131FF09B47DC47814A4925B615A635D6DA05106825E764746CE76EDEE66F8782B9F688AA003B003857B5A659EAAE999171A9353DE0633614093E0A81E1346ABCDCB3CE1A40E8E086A2A2FB9B87394E0F6A0319F42C7B5B8BB9CFB0EF9FDFF6034A397E32E76B6F8C01F3DD2BE81FC938AFE7A1E1D763B4715B2D7CFB4DA9C0B4D013DE532F7D35E177542616DCC3F06736A25F60D0D486D5E4A3797C643977321C9908881170A23D22ADC8768E983DDB79594311DAF4D2CC28AC73E579F36297B0B007B86CB20F185C3A97E772B8FEF731D59A57C9A30D80C5E8B5F62715EA82BE29C5ADBB7A50B2A3E1FE26A7E77A9B53AB69E4A3D4552494F4F0A39459FE8AD9AA7AFEF7CB2560F759E735DED296AE22EDFDF5336671030749F5CE10E6C212BFDC97DA25C5BC80CD62BD490752CD84FA6B8A35BFC752A1CF07C9247C47A0D50D1AC3A713DDF9214E35FF74BF84799732CA0F7032F2ABA00E896CB731A26D09A44E870E9E46D452428F03F6C54CAD2A90A7D95F06F042A929DB5D1D3BEE989F292C1409E780F30B5C00D5965E35EC5957BCF172C26A93E337B1702FAD07940E5EDF2155F1F1CB33E363935829A64665AB6B6D7B6147673E02CF53BA128114C1396785C550D9FC3E38A2E15964CF7BE477766A7AA3310BC6729910C049FAF4FD5895AB3199830EAF34A67FD727FCE77F0FD546A70AE65011839B3A617EC1A2BB2F341A75EC989227E3DEB3DC4DC9911B0BC1F43425401B9D3355CF963D80CBF
-20200407114745 2 6 100 8191 2 C9BECFEF229169BA6895957B61D338147FD9E67666267E2963D7A5587F57261CE8805A323015A9DA97865C6720A855FB346A80C284F9E8B8661DE02027ED9D77E29C25FD08E9BA260CF0D99BF2B69B0F054D642F8E29756D282B4523CF8CC058AA3A274F5D0766A30E269DC7AF3902DC139AC98994961A9186B5538B0F741A774918140CFC62D6BED7CB6E9333682F17683EF6EB53C2912F125105BDFAADB8046BD4FDFA60C4CE0CD0800D4247FFF67A72917E18D86BDFD6A4FBF3301E3290F5F5FF138F8EB4AD0C85AD4DEE6D590B44352B8B42C3A207C677CFCA215DE5391C9BFE5667698AB65D6955CA1FE8CE57D8EFC83FF5547E095FCC476FF3BAF6DD5B6D87F1C836CB712B54B115C0D7640F8F72CBDCE86DBCE6D2C04B7306B16E010A6CBE0BA95ABF269071BB1F5F433BC74D0C19889480A6B5C1683904837C36C7BCF69BE7CB96E0CAA07396224D694FB02F922B33D14C384923F946D104475F49D18A77AE5FA44ADA7C6E16D3B3085821C0B6814DCB565FDC44ED1942C9E25224ED96240D1FEF3817B6161BAD9F16B8C80953882C2FB2722515B10ABEBE969D2318AE9EB81CE91352329591D2874E6121205E072A3D5749190FA847D79B72BD3452DE0B5169601DDB6264AE70A1DC46B3637567787A11AA180B20623440C455722F8131FF09B47DC47814A4925B615A635D6DA05106825E764746CE76EDEE66F8782B9F688AA003B003857B5A659EAAE999171A9353DE0633614093E0A81E1346ABCDCB3CE1A40E8E086A2A2FB9B87394E0F6A0319F42C7B5B8BB9CFB0EF9FDFF6034A397E32E76B6F8C01F3DD2BE81FC938AFE7A1E1D763B4715B2D7CFB4DA9C0B4D013DE532F7D35E177542616DCC3F06736A25F60D0D486D5E4A3797C643977321C9908881170A23D22ADC8768E983DDB79594311DAF4D2CC28AC73E579F36297B0B007B86CB20F185C3A97E772B8FEF731D59A57C9A30D80C5E8B5F62715EA82BE29C5ADBB7A50B2A3E1FE26A7E77A9B53AB69E4A3D4552494F4F0A39459FE8AD9AA7AFEF7CB2560F759E735DED296AE22EDFDF5336671030749F5CE10E6C212BFDC97DA25C5BC80CD62BD490752CD84FA6B8A35BFC752A1CF07C9247C47A0D50D1AC3A713DDF9214E35FF74BF84799732CA0F7032F2ABA00E896CB731A26D09A44E870E9E46D452428F03F6C54CAD2A90A7D95F06F042A929DB5D1D3BEE989F292C1409E780F30B5C00D5965E35EC5957BCF172C26A93E337B1702FAD07940E5EDF2155F1F1CB33E363935829A64665AB6B6D7B6147673E02CF53BA128114C1396785C550D9FC3E38A2E15964CF7BE477766A7AA3310BC6729910C049FAF4FD5895AB3199830EAF34A67FD727FCE77F0FD546A70AE65011839B3A617EC1A2BB2F341A75EC989227E3DEB3DC4DC9911B0BC1F43425401B9D3355CF96F20367B
-20200408113553 2 6 100 8191 2 C9BECFEF229169BA6895957B61D338147FD9E67666267E2963D7A5587F57261CE8805A323015A9DA97865C6720A855FB346A80C284F9E8B8661DE02027ED9D77E29C25FD08E9BA260CF0D99BF2B69B0F054D642F8E29756D282B4523CF8CC058AA3A274F5D0766A30E269DC7AF3902DC139AC98994961A9186B5538B0F741A774918140CFC62D6BED7CB6E9333682F17683EF6EB53C2912F125105BDFAADB8046BD4FDFA60C4CE0CD0800D4247FFF67A72917E18D86BDFD6A4FBF3301E3290F5F5FF138F8EB4AD0C85AD4DEE6D590B44352B8B42C3A207C677CFCA215DE5391C9BFE5667698AB65D6955CA1FE8CE57D8EFC83FF5547E095FCC476FF3BAF6DD5B6D87F1C836CB712B54B115C0D7640F8F72CBDCE86DBCE6D2C04B7306B16E010A6CBE0BA95ABF269071BB1F5F433BC74D0C19889480A6B5C1683904837C36C7BCF69BE7CB96E0CAA07396224D694FB02F922B33D14C384923F946D104475F49D18A77AE5FA44ADA7C6E16D3B3085821C0B6814DCB565FDC44ED1942C9E25224ED96240D1FEF3817B6161BAD9F16B8C80953882C2FB2722515B10ABEBE969D2318AE9EB81CE91352329591D2874E6121205E072A3D5749190FA847D79B72BD3452DE0B5169601DDB6264AE70A1DC46B3637567787A11AA180B20623440C455722F8131FF09B47DC47814A4925B615A635D6DA05106825E764746CE76EDEE66F8782B9F688AA003B003857B5A659EAAE999171A9353DE0633614093E0A81E1346ABCDCB3CE1A40E8E086A2A2FB9B87394E0F6A0319F42C7B5B8BB9CFB0EF9FDFF6034A397E32E76B6F8C01F3DD2BE81FC938AFE7A1E1D763B4715B2D7CFB4DA9C0B4D013DE532F7D35E177542616DCC3F06736A25F60D0D486D5E4A3797C643977321C9908881170A23D22ADC8768E983DDB79594311DAF4D2CC28AC73E579F36297B0B007B86CB20F185C3A97E772B8FEF731D59A57C9A30D80C5E8B5F62715EA82BE29C5ADBB7A50B2A3E1FE26A7E77A9B53AB69E4A3D4552494F4F0A39459FE8AD9AA7AFEF7CB2560F759E735DED296AE22EDFDF5336671030749F5CE10E6C212BFDC97DA25C5BC80CD62BD490752CD84FA6B8A35BFC752A1CF07C9247C47A0D50D1AC3A713DDF9214E35FF74BF84799732CA0F7032F2ABA00E896CB731A26D09A44E870E9E46D452428F03F6C54CAD2A90A7D95F06F042A929DB5D1D3BEE989F292C1409E780F30B5C00D5965E35EC5957BCF172C26A93E337B1702FAD07940E5EDF2155F1F1CB33E363935829A64665AB6B6D7B6147673E02CF53BA128114C1396785C550D9FC3E38A2E15964CF7BE477766A7AA3310BC6729910C049FAF4FD5895AB3199830EAF34A67FD727FCE77F0FD546A70AE65011839B3A617EC1A2BB2F341A75EC989227E3DEB3DC4DC9911B0BC1F43425401B9D3355CF973EEF8A3
-20200409193550 2 6 100 8191 2 C9BECFEF229169BA6895957B61D338147FD9E67666267E2963D7A5587F57261CE8805A323015A9DA97865C6720A855FB346A80C284F9E8B8661DE02027ED9D77E29C25FD08E9BA260CF0D99BF2B69B0F054D642F8E29756D282B4523CF8CC058AA3A274F5D0766A30E269DC7AF3902DC139AC98994961A9186B5538B0F741A774918140CFC62D6BED7CB6E9333682F17683EF6EB53C2912F125105BDFAADB8046BD4FDFA60C4CE0CD0800D4247FFF67A72917E18D86BDFD6A4FBF3301E3290F5F5FF138F8EB4AD0C85AD4DEE6D590B44352B8B42C3A207C677CFCA215DE5391C9BFE5667698AB65D6955CA1FE8CE57D8EFC83FF5547E095FCC476FF3BAF6DD5B6D87F1C836CB712B54B115C0D7640F8F72CBDCE86DBCE6D2C04B7306B16E010A6CBE0BA95ABF269071BB1F5F433BC74D0C19889480A6B5C1683904837C36C7BCF69BE7CB96E0CAA07396224D694FB02F922B33D14C384923F946D104475F49D18A77AE5FA44ADA7C6E16D3B3085821C0B6814DCB565FDC44ED1942C9E25224ED96240D1FEF3817B6161BAD9F16B8C80953882C2FB2722515B10ABEBE969D2318AE9EB81CE91352329591D2874E6121205E072A3D5749190FA847D79B72BD3452DE0B5169601DDB6264AE70A1DC46B3637567787A11AA180B20623440C455722F8131FF09B47DC47814A4925B615A635D6DA05106825E764746CE76EDEE66F8782B9F688AA003B003857B5A659EAAE999171A9353DE0633614093E0A81E1346ABCDCB3CE1A40E8E086A2A2FB9B87394E0F6A0319F42C7B5B8BB9CFB0EF9FDFF6034A397E32E76B6F8C01F3DD2BE81FC938AFE7A1E1D763B4715B2D7CFB4DA9C0B4D013DE532F7D35E177542616DCC3F06736A25F60D0D486D5E4A3797C643977321C9908881170A23D22ADC8768E983DDB79594311DAF4D2CC28AC73E579F36297B0B007B86CB20F185C3A97E772B8FEF731D59A57C9A30D80C5E8B5F62715EA82BE29C5ADBB7A50B2A3E1FE26A7E77A9B53AB69E4A3D4552494F4F0A39459FE8AD9AA7AFEF7CB2560F759E735DED296AE22EDFDF5336671030749F5CE10E6C212BFDC97DA25C5BC80CD62BD490752CD84FA6B8A35BFC752A1CF07C9247C47A0D50D1AC3A713DDF9214E35FF74BF84799732CA0F7032F2ABA00E896CB731A26D09A44E870E9E46D452428F03F6C54CAD2A90A7D95F06F042A929DB5D1D3BEE989F292C1409E780F30B5C00D5965E35EC5957BCF172C26A93E337B1702FAD07940E5EDF2155F1F1CB33E363935829A64665AB6B6D7B6147673E02CF53BA128114C1396785C550D9FC3E38A2E15964CF7BE477766A7AA3310BC6729910C049FAF4FD5895AB3199830EAF34A67FD727FCE77F0FD546A70AE65011839B3A617EC1A2BB2F341A75EC989227E3DEB3DC4DC9911B0BC1F43425401B9D3355CF97A04D14B
-20200410193553 2 6 100 8191 5 C9BECFEF229169BA6895957B61D338147FD9E67666267E2963D7A5587F57261CE8805A323015A9DA97865C6720A855FB346A80C284F9E8B8661DE02027ED9D77E29C25FD08E9BA260CF0D99BF2B69B0F054D642F8E29756D282B4523CF8CC058AA3A274F5D0766A30E269DC7AF3902DC139AC98994961A9186B5538B0F741A774918140CFC62D6BED7CB6E9333682F17683EF6EB53C2912F125105BDFAADB8046BD4FDFA60C4CE0CD0800D4247FFF67A72917E18D86BDFD6A4FBF3301E3290F5F5FF138F8EB4AD0C85AD4DEE6D590B44352B8B42C3A207C677CFCA215DE5391C9BFE5667698AB65D6955CA1FE8CE57D8EFC83FF5547E095FCC476FF3BAF6DD5B6D87F1C836CB712B54B115C0D7640F8F72CBDCE86DBCE6D2C04B7306B16E010A6CBE0BA95ABF269071BB1F5F433BC74D0C19889480A6B5C1683904837C36C7BCF69BE7CB96E0CAA07396224D694FB02F922B33D14C384923F946D104475F49D18A77AE5FA44ADA7C6E16D3B3085821C0B6814DCB565FDC44ED1942C9E25224ED96240D1FEF3817B6161BAD9F16B8C80953882C2FB2722515B10ABEBE969D2318AE9EB81CE91352329591D2874E6121205E072A3D5749190FA847D79B72BD3452DE0B5169601DDB6264AE70A1DC46B3637567787A11AA180B20623440C455722F8131FF09B47DC47814A4925B615A635D6DA05106825E764746CE76EDEE66F8782B9F688AA003B003857B5A659EAAE999171A9353DE0633614093E0A81E1346ABCDCB3CE1A40E8E086A2A2FB9B87394E0F6A0319F42C7B5B8BB9CFB0EF9FDFF6034A397E32E76B6F8C01F3DD2BE81FC938AFE7A1E1D763B4715B2D7CFB4DA9C0B4D013DE532F7D35E177542616DCC3F06736A25F60D0D486D5E4A3797C643977321C9908881170A23D22ADC8768E983DDB79594311DAF4D2CC28AC73E579F36297B0B007B86CB20F185C3A97E772B8FEF731D59A57C9A30D80C5E8B5F62715EA82BE29C5ADBB7A50B2A3E1FE26A7E77A9B53AB69E4A3D4552494F4F0A39459FE8AD9AA7AFEF7CB2560F759E735DED296AE22EDFDF5336671030749F5CE10E6C212BFDC97DA25C5BC80CD62BD490752CD84FA6B8A35BFC752A1CF07C9247C47A0D50D1AC3A713DDF9214E35FF74BF84799732CA0F7032F2ABA00E896CB731A26D09A44E870E9E46D452428F03F6C54CAD2A90A7D95F06F042A929DB5D1D3BEE989F292C1409E780F30B5C00D5965E35EC5957BCF172C26A93E337B1702FAD07940E5EDF2155F1F1CB33E363935829A64665AB6B6D7B6147673E02CF53BA128114C1396785C550D9FC3E38A2E15964CF7BE477766A7AA3310BC6729910C049FAF4FD5895AB3199830EAF34A67FD727FCE77F0FD546A70AE65011839B3A617EC1A2BB2F341A75EC989227E3DEB3DC4DC9911B0BC1F43425401B9D3355CF97C78121F
-20200411093549 2 6 100 8191 5 C9BECFEF229169BA6895957B61D338147FD9E67666267E2963D7A5587F57261CE8805A323015A9DA97865C6720A855FB346A80C284F9E8B8661DE02027ED9D77E29C25FD08E9BA260CF0D99BF2B69B0F054D642F8E29756D282B4523CF8CC058AA3A274F5D0766A30E269DC7AF3902DC139AC98994961A9186B5538B0F741A774918140CFC62D6BED7CB6E9333682F17683EF6EB53C2912F125105BDFAADB8046BD4FDFA60C4CE0CD0800D4247FFF67A72917E18D86BDFD6A4FBF3301E3290F5F5FF138F8EB4AD0C85AD4DEE6D590B44352B8B42C3A207C677CFCA215DE5391C9BFE5667698AB65D6955CA1FE8CE57D8EFC83FF5547E095FCC476FF3BAF6DD5B6D87F1C836CB712B54B115C0D7640F8F72CBDCE86DBCE6D2C04B7306B16E010A6CBE0BA95ABF269071BB1F5F433BC74D0C19889480A6B5C1683904837C36C7BCF69BE7CB96E0CAA07396224D694FB02F922B33D14C384923F946D104475F49D18A77AE5FA44ADA7C6E16D3B3085821C0B6814DCB565FDC44ED1942C9E25224ED96240D1FEF3817B6161BAD9F16B8C80953882C2FB2722515B10ABEBE969D2318AE9EB81CE91352329591D2874E6121205E072A3D5749190FA847D79B72BD3452DE0B5169601DDB6264AE70A1DC46B3637567787A11AA180B20623440C455722F8131FF09B47DC47814A4925B615A635D6DA05106825E764746CE76EDEE66F8782B9F688AA003B003857B5A659EAAE999171A9353DE0633614093E0A81E1346ABCDCB3CE1A40E8E086A2A2FB9B87394E0F6A0319F42C7B5B8BB9CFB0EF9FDFF6034A397E32E76B6F8C01F3DD2BE81FC938AFE7A1E1D763B4715B2D7CFB4DA9C0B4D013DE532F7D35E177542616DCC3F06736A25F60D0D486D5E4A3797C643977321C9908881170A23D22ADC8768E983DDB79594311DAF4D2CC28AC73E579F36297B0B007B86CB20F185C3A97E772B8FEF731D59A57C9A30D80C5E8B5F62715EA82BE29C5ADBB7A50B2A3E1FE26A7E77A9B53AB69E4A3D4552494F4F0A39459FE8AD9AA7AFEF7CB2560F759E735DED296AE22EDFDF5336671030749F5CE10E6C212BFDC97DA25C5BC80CD62BD490752CD84FA6B8A35BFC752A1CF07C9247C47A0D50D1AC3A713DDF9214E35FF74BF84799732CA0F7032F2ABA00E896CB731A26D09A44E870E9E46D452428F03F6C54CAD2A90A7D95F06F042A929DB5D1D3BEE989F292C1409E780F30B5C00D5965E35EC5957BCF172C26A93E337B1702FAD07940E5EDF2155F1F1CB33E363935829A64665AB6B6D7B6147673E02CF53BA128114C1396785C550D9FC3E38A2E15964CF7BE477766A7AA3310BC6729910C049FAF4FD5895AB3199830EAF34A67FD727FCE77F0FD546A70AE65011839B3A617EC1A2BB2F341A75EC989227E3DEB3DC4DC9911B0BC1F43425401B9D3355CF97F2C0DC7
-20200412155343 2 6 100 8191 2 C9BECFEF229169BA6895957B61D338147FD9E67666267E2963D7A5587F57261CE8805A323015A9DA97865C6720A855FB346A80C284F9E8B8661DE02027ED9D77E29C25FD08E9BA260CF0D99BF2B69B0F054D642F8E29756D282B4523CF8CC058AA3A274F5D0766A30E269DC7AF3902DC139AC98994961A9186B5538B0F741A774918140CFC62D6BED7CB6E9333682F17683EF6EB53C2912F125105BDFAADB8046BD4FDFA60C4CE0CD0800D4247FFF67A72917E18D86BDFD6A4FBF3301E3290F5F5FF138F8EB4AD0C85AD4DEE6D590B44352B8B42C3A207C677CFCA215DE5391C9BFE5667698AB65D6955CA1FE8CE57D8EFC83FF5547E095FCC476FF3BAF6DD5B6D87F1C836CB712B54B115C0D7640F8F72CBDCE86DBCE6D2C04B7306B16E010A6CBE0BA95ABF269071BB1F5F433BC74D0C19889480A6B5C1683904837C36C7BCF69BE7CB96E0CAA07396224D694FB02F922B33D14C384923F946D104475F49D18A77AE5FA44ADA7C6E16D3B3085821C0B6814DCB565FDC44ED1942C9E25224ED96240D1FEF3817B6161BAD9F16B8C80953882C2FB2722515B10ABEBE969D2318AE9EB81CE91352329591D2874E6121205E072A3D5749190FA847D79B72BD3452DE0B5169601DDB6264AE70A1DC46B3637567787A11AA180B20623440C455722F8131FF09B47DC47814A4925B615A635D6DA05106825E764746CE76EDEE66F8782B9F688AA003B003857B5A659EAAE999171A9353DE0633614093E0A81E1346ABCDCB3CE1A40E8E086A2A2FB9B87394E0F6A0319F42C7B5B8BB9CFB0EF9FDFF6034A397E32E76B6F8C01F3DD2BE81FC938AFE7A1E1D763B4715B2D7CFB4DA9C0B4D013DE532F7D35E177542616DCC3F06736A25F60D0D486D5E4A3797C643977321C9908881170A23D22ADC8768E983DDB79594311DAF4D2CC28AC73E579F36297B0B007B86CB20F185C3A97E772B8FEF731D59A57C9A30D80C5E8B5F62715EA82BE29C5ADBB7A50B2A3E1FE26A7E77A9B53AB69E4A3D4552494F4F0A39459FE8AD9AA7AFEF7CB2560F759E735DED296AE22EDFDF5336671030749F5CE10E6C212BFDC97DA25C5BC80CD62BD490752CD84FA6B8A35BFC752A1CF07C9247C47A0D50D1AC3A713DDF9214E35FF74BF84799732CA0F7032F2ABA00E896CB731A26D09A44E870E9E46D452428F03F6C54CAD2A90A7D95F06F042A929DB5D1D3BEE989F292C1409E780F30B5C00D5965E35EC5957BCF172C26A93E337B1702FAD07940E5EDF2155F1F1CB33E363935829A64665AB6B6D7B6147673E02CF53BA128114C1396785C550D9FC3E38A2E15964CF7BE477766A7AA3310BC6729910C049FAF4FD5895AB3199830EAF34A67FD727FCE77F0FD546A70AE65011839B3A617EC1A2BB2F341A75EC989227E3DEB3DC4DC9911B0BC1F43425401B9D3355CF982A4594B
-20200413220042 2 6 100 8191 2 C9BECFEF229169BA6895957B61D338147FD9E67666267E2963D7A5587F57261CE8805A323015A9DA97865C6720A855FB346A80C284F9E8B8661DE02027ED9D77E29C25FD08E9BA260CF0D99BF2B69B0F054D642F8E29756D282B4523CF8CC058AA3A274F5D0766A30E269DC7AF3902DC139AC98994961A9186B5538B0F741A774918140CFC62D6BED7CB6E9333682F17683EF6EB53C2912F125105BDFAADB8046BD4FDFA60C4CE0CD0800D4247FFF67A72917E18D86BDFD6A4FBF3301E3290F5F5FF138F8EB4AD0C85AD4DEE6D590B44352B8B42C3A207C677CFCA215DE5391C9BFE5667698AB65D6955CA1FE8CE57D8EFC83FF5547E095FCC476FF3BAF6DD5B6D87F1C836CB712B54B115C0D7640F8F72CBDCE86DBCE6D2C04B7306B16E010A6CBE0BA95ABF269071BB1F5F433BC74D0C19889480A6B5C1683904837C36C7BCF69BE7CB96E0CAA07396224D694FB02F922B33D14C384923F946D104475F49D18A77AE5FA44ADA7C6E16D3B3085821C0B6814DCB565FDC44ED1942C9E25224ED96240D1FEF3817B6161BAD9F16B8C80953882C2FB2722515B10ABEBE969D2318AE9EB81CE91352329591D2874E6121205E072A3D5749190FA847D79B72BD3452DE0B5169601DDB6264AE70A1DC46B3637567787A11AA180B20623440C455722F8131FF09B47DC47814A4925B615A635D6DA05106825E764746CE76EDEE66F8782B9F688AA003B003857B5A659EAAE999171A9353DE0633614093E0A81E1346ABCDCB3CE1A40E8E086A2A2FB9B87394E0F6A0319F42C7B5B8BB9CFB0EF9FDFF6034A397E32E76B6F8C01F3DD2BE81FC938AFE7A1E1D763B4715B2D7CFB4DA9C0B4D013DE532F7D35E177542616DCC3F06736A25F60D0D486D5E4A3797C643977321C9908881170A23D22ADC8768E983DDB79594311DAF4D2CC28AC73E579F36297B0B007B86CB20F185C3A97E772B8FEF731D59A57C9A30D80C5E8B5F62715EA82BE29C5ADBB7A50B2A3E1FE26A7E77A9B53AB69E4A3D4552494F4F0A39459FE8AD9AA7AFEF7CB2560F759E735DED296AE22EDFDF5336671030749F5CE10E6C212BFDC97DA25C5BC80CD62BD490752CD84FA6B8A35BFC752A1CF07C9247C47A0D50D1AC3A713DDF9214E35FF74BF84799732CA0F7032F2ABA00E896CB731A26D09A44E870E9E46D452428F03F6C54CAD2A90A7D95F06F042A929DB5D1D3BEE989F292C1409E780F30B5C00D5965E35EC5957BCF172C26A93E337B1702FAD07940E5EDF2155F1F1CB33E363935829A64665AB6B6D7B6147673E02CF53BA128114C1396785C550D9FC3E38A2E15964CF7BE477766A7AA3310BC6729910C049FAF4FD5895AB3199830EAF34A67FD727FCE77F0FD546A70AE65011839B3A617EC1A2BB2F341A75EC989227E3DEB3DC4DC9911B0BC1F43425401B9D3355CF9880132D3
-20200414091654 2 6 100 8191 2 C9BECFEF229169BA6895957B61D338147FD9E67666267E2963D7A5587F57261CE8805A323015A9DA97865C6720A855FB346A80C284F9E8B8661DE02027ED9D77E29C25FD08E9BA260CF0D99BF2B69B0F054D642F8E29756D282B4523CF8CC058AA3A274F5D0766A30E269DC7AF3902DC139AC98994961A9186B5538B0F741A774918140CFC62D6BED7CB6E9333682F17683EF6EB53C2912F125105BDFAADB8046BD4FDFA60C4CE0CD0800D4247FFF67A72917E18D86BDFD6A4FBF3301E3290F5F5FF138F8EB4AD0C85AD4DEE6D590B44352B8B42C3A207C677CFCA215DE5391C9BFE5667698AB65D6955CA1FE8CE57D8EFC83FF5547E095FCC476FF3BAF6DD5B6D87F1C836CB712B54B115C0D7640F8F72CBDCE86DBCE6D2C04B7306B16E010A6CBE0BA95ABF269071BB1F5F433BC74D0C19889480A6B5C1683904837C36C7BCF69BE7CB96E0CAA07396224D694FB02F922B33D14C384923F946D104475F49D18A77AE5FA44ADA7C6E16D3B3085821C0B6814DCB565FDC44ED1942C9E25224ED96240D1FEF3817B6161BAD9F16B8C80953882C2FB2722515B10ABEBE969D2318AE9EB81CE91352329591D2874E6121205E072A3D5749190FA847D79B72BD3452DE0B5169601DDB6264AE70A1DC46B3637567787A11AA180B20623440C455722F8131FF09B47DC47814A4925B615A635D6DA05106825E764746CE76EDEE66F8782B9F688AA003B003857B5A659EAAE999171A9353DE0633614093E0A81E1346ABCDCB3CE1A40E8E086A2A2FB9B87394E0F6A0319F42C7B5B8BB9CFB0EF9FDFF6034A397E32E76B6F8C01F3DD2BE81FC938AFE7A1E1D763B4715B2D7CFB4DA9C0B4D013DE532F7D35E177542616DCC3F06736A25F60D0D486D5E4A3797C643977321C9908881170A23D22ADC8768E983DDB79594311DAF4D2CC28AC73E579F36297B0B007B86CB20F185C3A97E772B8FEF731D59A57C9A30D80C5E8B5F62715EA82BE29C5ADBB7A50B2A3E1FE26A7E77A9B53AB69E4A3D4552494F4F0A39459FE8AD9AA7AFEF7CB2560F759E735DED296AE22EDFDF5336671030749F5CE10E6C212BFDC97DA25C5BC80CD62BD490752CD84FA6B8A35BFC752A1CF07C9247C47A0D50D1AC3A713DDF9214E35FF74BF84799732CA0F7032F2ABA00E896CB731A26D09A44E870E9E46D452428F03F6C54CAD2A90A7D95F06F042A929DB5D1D3BEE989F292C1409E780F30B5C00D5965E35EC5957BCF172C26A93E337B1702FAD07940E5EDF2155F1F1CB33E363935829A64665AB6B6D7B6147673E02CF53BA128114C1396785C550D9FC3E38A2E15964CF7BE477766A7AA3310BC6729910C049FAF4FD5895AB3199830EAF34A67FD727FCE77F0FD546A70AE65011839B3A617EC1A2BB2F341A75EC989227E3DEB3DC4DC9911B0BC1F43425401B9D3355CF98A23F9AB
-20200415173037 2 6 100 8191 2 C9BECFEF229169BA6895957B61D338147FD9E67666267E2963D7A5587F57261CE8805A323015A9DA97865C6720A855FB346A80C284F9E8B8661DE02027ED9D77E29C25FD08E9BA260CF0D99BF2B69B0F054D642F8E29756D282B4523CF8CC058AA3A274F5D0766A30E269DC7AF3902DC139AC98994961A9186B5538B0F741A774918140CFC62D6BED7CB6E9333682F17683EF6EB53C2912F125105BDFAADB8046BD4FDFA60C4CE0CD0800D4247FFF67A72917E18D86BDFD6A4FBF3301E3290F5F5FF138F8EB4AD0C85AD4DEE6D590B44352B8B42C3A207C677CFCA215DE5391C9BFE5667698AB65D6955CA1FE8CE57D8EFC83FF5547E095FCC476FF3BAF6DD5B6D87F1C836CB712B54B115C0D7640F8F72CBDCE86DBCE6D2C04B7306B16E010A6CBE0BA95ABF269071BB1F5F433BC74D0C19889480A6B5C1683904837C36C7BCF69BE7CB96E0CAA07396224D694FB02F922B33D14C384923F946D104475F49D18A77AE5FA44ADA7C6E16D3B3085821C0B6814DCB565FDC44ED1942C9E25224ED96240D1FEF3817B6161BAD9F16B8C80953882C2FB2722515B10ABEBE969D2318AE9EB81CE91352329591D2874E6121205E072A3D5749190FA847D79B72BD3452DE0B5169601DDB6264AE70A1DC46B3637567787A11AA180B20623440C455722F8131FF09B47DC47814A4925B615A635D6DA05106825E764746CE76EDEE66F8782B9F688AA003B003857B5A659EAAE999171A9353DE0633614093E0A81E1346ABCDCB3CE1A40E8E086A2A2FB9B87394E0F6A0319F42C7B5B8BB9CFB0EF9FDFF6034A397E32E76B6F8C01F3DD2BE81FC938AFE7A1E1D763B4715B2D7CFB4DA9C0B4D013DE532F7D35E177542616DCC3F06736A25F60D0D486D5E4A3797C643977321C9908881170A23D22ADC8768E983DDB79594311DAF4D2CC28AC73E579F36297B0B007B86CB20F185C3A97E772B8FEF731D59A57C9A30D80C5E8B5F62715EA82BE29C5ADBB7A50B2A3E1FE26A7E77A9B53AB69E4A3D4552494F4F0A39459FE8AD9AA7AFEF7CB2560F759E735DED296AE22EDFDF5336671030749F5CE10E6C212BFDC97DA25C5BC80CD62BD490752CD84FA6B8A35BFC752A1CF07C9247C47A0D50D1AC3A713DDF9214E35FF74BF84799732CA0F7032F2ABA00E896CB731A26D09A44E870E9E46D452428F03F6C54CAD2A90A7D95F06F042A929DB5D1D3BEE989F292C1409E780F30B5C00D5965E35EC5957BCF172C26A93E337B1702FAD07940E5EDF2155F1F1CB33E363935829A64665AB6B6D7B6147673E02CF53BA128114C1396785C550D9FC3E38A2E15964CF7BE477766A7AA3310BC6729910C049FAF4FD5895AB3199830EAF34A67FD727FCE77F0FD546A70AE65011839B3A617EC1A2BB2F341A75EC989227E3DEB3DC4DC9911B0BC1F43425401B9D3355CF98D4F179B
-20200415204739 2 6 100 8191 5 C9BECFEF229169BA6895957B61D338147FD9E67666267E2963D7A5587F57261CE8805A323015A9DA97865C6720A855FB346A80C284F9E8B8661DE02027ED9D77E29C25FD08E9BA260CF0D99BF2B69B0F054D642F8E29756D282B4523CF8CC058AA3A274F5D0766A30E269DC7AF3902DC139AC98994961A9186B5538B0F741A774918140CFC62D6BED7CB6E9333682F17683EF6EB53C2912F125105BDFAADB8046BD4FDFA60C4CE0CD0800D4247FFF67A72917E18D86BDFD6A4FBF3301E3290F5F5FF138F8EB4AD0C85AD4DEE6D590B44352B8B42C3A207C677CFCA215DE5391C9BFE5667698AB65D6955CA1FE8CE57D8EFC83FF5547E095FCC476FF3BAF6DD5B6D87F1C836CB712B54B115C0D7640F8F72CBDCE86DBCE6D2C04B7306B16E010A6CBE0BA95ABF269071BB1F5F433BC74D0C19889480A6B5C1683904837C36C7BCF69BE7CB96E0CAA07396224D694FB02F922B33D14C384923F946D104475F49D18A77AE5FA44ADA7C6E16D3B3085821C0B6814DCB565FDC44ED1942C9E25224ED96240D1FEF3817B6161BAD9F16B8C80953882C2FB2722515B10ABEBE969D2318AE9EB81CE91352329591D2874E6121205E072A3D5749190FA847D79B72BD3452DE0B5169601DDB6264AE70A1DC46B3637567787A11AA180B20623440C455722F8131FF09B47DC47814A4925B615A635D6DA05106825E764746CE76EDEE66F8782B9F688AA003B003857B5A659EAAE999171A9353DE0633614093E0A81E1346ABCDCB3CE1A40E8E086A2A2FB9B87394E0F6A0319F42C7B5B8BB9CFB0EF9FDFF6034A397E32E76B6F8C01F3DD2BE81FC938AFE7A1E1D763B4715B2D7CFB4DA9C0B4D013DE532F7D35E177542616DCC3F06736A25F60D0D486D5E4A3797C643977321C9908881170A23D22ADC8768E983DDB79594311DAF4D2CC28AC73E579F36297B0B007B86CB20F185C3A97E772B8FEF731D59A57C9A30D80C5E8B5F62715EA82BE29C5ADBB7A50B2A3E1FE26A7E77A9B53AB69E4A3D4552494F4F0A39459FE8AD9AA7AFEF7CB2560F759E735DED296AE22EDFDF5336671030749F5CE10E6C212BFDC97DA25C5BC80CD62BD490752CD84FA6B8A35BFC752A1CF07C9247C47A0D50D1AC3A713DDF9214E35FF74BF84799732CA0F7032F2ABA00E896CB731A26D09A44E870E9E46D452428F03F6C54CAD2A90A7D95F06F042A929DB5D1D3BEE989F292C1409E780F30B5C00D5965E35EC5957BCF172C26A93E337B1702FAD07940E5EDF2155F1F1CB33E363935829A64665AB6B6D7B6147673E02CF53BA128114C1396785C550D9FC3E38A2E15964CF7BE477766A7AA3310BC6729910C049FAF4FD5895AB3199830EAF34A67FD727FCE77F0FD546A70AE65011839B3A617EC1A2BB2F341A75EC989227E3DEB3DC4DC9911B0BC1F43425401B9D3355CF98DF24F47
-20200416120747 2 6 100 8191 5 FDD2FF1B0B2402FB6FD5FBC2AF7553A3418C2535DFBF5CDB078CEA3D7C44A4863229766D19871460787A24C249D14845D5332DC7B153C10DF45AEBDC462929E786B8384FF62EC1CB99A79928B0EDB9845107488A06141112F534054013B3AA4DC1B2FE160ABA2E8670A0FB7B835D57BF99D5E7474161517D4149677B3BA24D68831195F8EF4145CB44B0FBDB37BF1B36A0B6F517F145FCC7C169C41A0E3A8A313E455A377E5D82B82608EEB14A5E7C5F4E9AA8E5315D1C600077B5F2F50022E2AEEE142E09DD25363862BAE1AF0D37B00C0D824B25C2B579524577AABB5C82452BE70C9AE8D65E935E087A70892E00544BAD691FE677C577917CC495D470E5301A9F75F019268DD8A9ED8F89EE35F6DABECE4507627691A666E86B98578FD03A7AC198728F7BA4348ECF3A61BAA4AD99DA46F97EA9773F1B9ACAA71EE30435E7A82F081C9D0B16495E96645626637CB97BDB4E7932763F826029B6FFE6C0537315BF01C1671029397DA737A5CD1F13F3ECB769D8265BE0148B22DD5FECCA1E7763E837C3FAEC235F1CC2910F51BD05A647C39623EEC1514FA6C64C84804E23D63D0BED6A88A1C6D382EBCF04FD8574C92D662BAFB239EE7984E6D252AD85D3B0D94D040B6FCB4B5120A2E43AF54C11C59B3D4BB777B3E49714FBBF0169ABBDC0CF285F6C37E668966CB8BBA5083A5EBCD706CBED60455ED554794B03D5136AC555A272FD180D2B99B60AEC25096F33C70CF7B6E4ED89D781954B7D52DFB8A0CCD2A237D8693EF8B3236540678ACEEDAC2A621B88B1A478BAB068ADB7CC8A037F8723B89E0FDFFAAD73F5D77007FCF04DB358393A7DC6DF42DCB4EBB853B77D27FFD7A616B9354ED0707431776FE294BAE152689DEE19B18902356B801EC7A760C2075998D6C6AF8CA1D59CB1D294CBA7490D5F54E0997202F4F4298AD554E28FF788093407E005600A35BA4B172B1D141D956965ED477C2EE1F808B45DE3517D66E969F17D8F5C0F4CA8F64F3912E9E8E8E11D3939EEC5CD6E6FB8D1090E65531BD570108A73A0268D370C51D41FF38B96475BE85EFF412B573F998D03C4741F3095ABEB13AC750147D76DF8375DFE62DC289496C8B8C9D692D5034AD7D514EBC3CD05B0ED0B7261823CEF3DFEA3D4324F1E1F5AD0172220225EECF3FC23786D75F1143117275CCDC3F5182C6CD7D194F9F943E0E0D4C64353442E9C0D06584A7D641DA03641E474E48CA631BEDB233526F7B889425561B48D5645BBB2E53CFC32A40771B6A12D0A2A6E0034666F2DBE47E30CE1FD5949963D2A779B02B886E186E20A31ECC948E4BF19E3D206760613F9577D9BC1FC02D68D2AB09C1EA756175FDD76A372E87FF4A9E79AAEE681D79697ED27803F8E6A9E41B92A0F6F239CA72F88F8414F758E98A48A1C0BC30FCF49EC2615F831C0E99E1B729317AE516267
-20200416164443 2 6 100 8191 2 FDD2FF1B0B2402FB6FD5FBC2AF7553A3418C2535DFBF5CDB078CEA3D7C44A4863229766D19871460787A24C249D14845D5332DC7B153C10DF45AEBDC462929E786B8384FF62EC1CB99A79928B0EDB9845107488A06141112F534054013B3AA4DC1B2FE160ABA2E8670A0FB7B835D57BF99D5E7474161517D4149677B3BA24D68831195F8EF4145CB44B0FBDB37BF1B36A0B6F517F145FCC7C169C41A0E3A8A313E455A377E5D82B82608EEB14A5E7C5F4E9AA8E5315D1C600077B5F2F50022E2AEEE142E09DD25363862BAE1AF0D37B00C0D824B25C2B579524577AABB5C82452BE70C9AE8D65E935E087A70892E00544BAD691FE677C577917CC495D470E5301A9F75F019268DD8A9ED8F89EE35F6DABECE4507627691A666E86B98578FD03A7AC198728F7BA4348ECF3A61BAA4AD99DA46F97EA9773F1B9ACAA71EE30435E7A82F081C9D0B16495E96645626637CB97BDB4E7932763F826029B6FFE6C0537315BF01C1671029397DA737A5CD1F13F3ECB769D8265BE0148B22DD5FECCA1E7763E837C3FAEC235F1CC2910F51BD05A647C39623EEC1514FA6C64C84804E23D63D0BED6A88A1C6D382EBCF04FD8574C92D662BAFB239EE7984E6D252AD85D3B0D94D040B6FCB4B5120A2E43AF54C11C59B3D4BB777B3E49714FBBF0169ABBDC0CF285F6C37E668966CB8BBA5083A5EBCD706CBED60455ED554794B03D5136AC555A272FD180D2B99B60AEC25096F33C70CF7B6E4ED89D781954B7D52DFB8A0CCD2A237D8693EF8B3236540678ACEEDAC2A621B88B1A478BAB068ADB7CC8A037F8723B89E0FDFFAAD73F5D77007FCF04DB358393A7DC6DF42DCB4EBB853B77D27FFD7A616B9354ED0707431776FE294BAE152689DEE19B18902356B801EC7A760C2075998D6C6AF8CA1D59CB1D294CBA7490D5F54E0997202F4F4298AD554E28FF788093407E005600A35BA4B172B1D141D956965ED477C2EE1F808B45DE3517D66E969F17D8F5C0F4CA8F64F3912E9E8E8E11D3939EEC5CD6E6FB8D1090E65531BD570108A73A0268D370C51D41FF38B96475BE85EFF412B573F998D03C4741F3095ABEB13AC750147D76DF8375DFE62DC289496C8B8C9D692D5034AD7D514EBC3CD05B0ED0B7261823CEF3DFEA3D4324F1E1F5AD0172220225EECF3FC23786D75F1143117275CCDC3F5182C6CD7D194F9F943E0E0D4C64353442E9C0D06584A7D641DA03641E474E48CA631BEDB233526F7B889425561B48D5645BBB2E53CFC32A40771B6A12D0A2A6E0034666F2DBE47E30CE1FD5949963D2A779B02B886E186E20A31ECC948E4BF19E3D206760613F9577D9BC1FC02D68D2AB09C1EA756175FDD76A372E87FF4A9E79AAEE681D79697ED27803F8E6A9E41B92A0F6F239CA72F88F8414F758E98A48A1C0BC30FCF49EC2615F831C0E99E1B729317B052A5C3
-20200416182037 2 6 100 8191 2 FDD2FF1B0B2402FB6FD5FBC2AF7553A3418C2535DFBF5CDB078CEA3D7C44A4863229766D19871460787A24C249D14845D5332DC7B153C10DF45AEBDC462929E786B8384FF62EC1CB99A79928B0EDB9845107488A06141112F534054013B3AA4DC1B2FE160ABA2E8670A0FB7B835D57BF99D5E7474161517D4149677B3BA24D68831195F8EF4145CB44B0FBDB37BF1B36A0B6F517F145FCC7C169C41A0E3A8A313E455A377E5D82B82608EEB14A5E7C5F4E9AA8E5315D1C600077B5F2F50022E2AEEE142E09DD25363862BAE1AF0D37B00C0D824B25C2B579524577AABB5C82452BE70C9AE8D65E935E087A70892E00544BAD691FE677C577917CC495D470E5301A9F75F019268DD8A9ED8F89EE35F6DABECE4507627691A666E86B98578FD03A7AC198728F7BA4348ECF3A61BAA4AD99DA46F97EA9773F1B9ACAA71EE30435E7A82F081C9D0B16495E96645626637CB97BDB4E7932763F826029B6FFE6C0537315BF01C1671029397DA737A5CD1F13F3ECB769D8265BE0148B22DD5FECCA1E7763E837C3FAEC235F1CC2910F51BD05A647C39623EEC1514FA6C64C84804E23D63D0BED6A88A1C6D382EBCF04FD8574C92D662BAFB239EE7984E6D252AD85D3B0D94D040B6FCB4B5120A2E43AF54C11C59B3D4BB777B3E49714FBBF0169ABBDC0CF285F6C37E668966CB8BBA5083A5EBCD706CBED60455ED554794B03D5136AC555A272FD180D2B99B60AEC25096F33C70CF7B6E4ED89D781954B7D52DFB8A0CCD2A237D8693EF8B3236540678ACEEDAC2A621B88B1A478BAB068ADB7CC8A037F8723B89E0FDFFAAD73F5D77007FCF04DB358393A7DC6DF42DCB4EBB853B77D27FFD7A616B9354ED0707431776FE294BAE152689DEE19B18902356B801EC7A760C2075998D6C6AF8CA1D59CB1D294CBA7490D5F54E0997202F4F4298AD554E28FF788093407E005600A35BA4B172B1D141D956965ED477C2EE1F808B45DE3517D66E969F17D8F5C0F4CA8F64F3912E9E8E8E11D3939EEC5CD6E6FB8D1090E65531BD570108A73A0268D370C51D41FF38B96475BE85EFF412B573F998D03C4741F3095ABEB13AC750147D76DF8375DFE62DC289496C8B8C9D692D5034AD7D514EBC3CD05B0ED0B7261823CEF3DFEA3D4324F1E1F5AD0172220225EECF3FC23786D75F1143117275CCDC3F5182C6CD7D194F9F943E0E0D4C64353442E9C0D06584A7D641DA03641E474E48CA631BEDB233526F7B889425561B48D5645BBB2E53CFC32A40771B6A12D0A2A6E0034666F2DBE47E30CE1FD5949963D2A779B02B886E186E20A31ECC948E4BF19E3D206760613F9577D9BC1FC02D68D2AB09C1EA756175FDD76A372E87FF4A9E79AAEE681D79697ED27803F8E6A9E41B92A0F6F239CA72F88F8414F758E98A48A1C0BC30FCF49EC2615F831C0E99E1B729317B0FD1FE3
-20200416203456 2 6 100 8191 2 FDD2FF1B0B2402FB6FD5FBC2AF7553A3418C2535DFBF5CDB078CEA3D7C44A4863229766D19871460787A24C249D14845D5332DC7B153C10DF45AEBDC462929E786B8384FF62EC1CB99A79928B0EDB9845107488A06141112F534054013B3AA4DC1B2FE160ABA2E8670A0FB7B835D57BF99D5E7474161517D4149677B3BA24D68831195F8EF4145CB44B0FBDB37BF1B36A0B6F517F145FCC7C169C41A0E3A8A313E455A377E5D82B82608EEB14A5E7C5F4E9AA8E5315D1C600077B5F2F50022E2AEEE142E09DD25363862BAE1AF0D37B00C0D824B25C2B579524577AABB5C82452BE70C9AE8D65E935E087A70892E00544BAD691FE677C577917CC495D470E5301A9F75F019268DD8A9ED8F89EE35F6DABECE4507627691A666E86B98578FD03A7AC198728F7BA4348ECF3A61BAA4AD99DA46F97EA9773F1B9ACAA71EE30435E7A82F081C9D0B16495E96645626637CB97BDB4E7932763F826029B6FFE6C0537315BF01C1671029397DA737A5CD1F13F3ECB769D8265BE0148B22DD5FECCA1E7763E837C3FAEC235F1CC2910F51BD05A647C39623EEC1514FA6C64C84804E23D63D0BED6A88A1C6D382EBCF04FD8574C92D662BAFB239EE7984E6D252AD85D3B0D94D040B6FCB4B5120A2E43AF54C11C59B3D4BB777B3E49714FBBF0169ABBDC0CF285F6C37E668966CB8BBA5083A5EBCD706CBED60455ED554794B03D5136AC555A272FD180D2B99B60AEC25096F33C70CF7B6E4ED89D781954B7D52DFB8A0CCD2A237D8693EF8B3236540678ACEEDAC2A621B88B1A478BAB068ADB7CC8A037F8723B89E0FDFFAAD73F5D77007FCF04DB358393A7DC6DF42DCB4EBB853B77D27FFD7A616B9354ED0707431776FE294BAE152689DEE19B18902356B801EC7A760C2075998D6C6AF8CA1D59CB1D294CBA7490D5F54E0997202F4F4298AD554E28FF788093407E005600A35BA4B172B1D141D956965ED477C2EE1F808B45DE3517D66E969F17D8F5C0F4CA8F64F3912E9E8E8E11D3939EEC5CD6E6FB8D1090E65531BD570108A73A0268D370C51D41FF38B96475BE85EFF412B573F998D03C4741F3095ABEB13AC750147D76DF8375DFE62DC289496C8B8C9D692D5034AD7D514EBC3CD05B0ED0B7261823CEF3DFEA3D4324F1E1F5AD0172220225EECF3FC23786D75F1143117275CCDC3F5182C6CD7D194F9F943E0E0D4C64353442E9C0D06584A7D641DA03641E474E48CA631BEDB233526F7B889425561B48D5645BBB2E53CFC32A40771B6A12D0A2A6E0034666F2DBE47E30CE1FD5949963D2A779B02B886E186E20A31ECC948E4BF19E3D206760613F9577D9BC1FC02D68D2AB09C1EA756175FDD76A372E87FF4A9E79AAEE681D79697ED27803F8E6A9E41B92A0F6F239CA72F88F8414F758E98A48A1C0BC30FCF49EC2615F831C0E99E1B729317B1F40773
-20200419115426 2 6 100 8191 2 FDD2FF1B0B2402FB6FD5FBC2AF7553A3418C2535DFBF5CDB078CEA3D7C44A4863229766D19871460787A24C249D14845D5332DC7B153C10DF45AEBDC462929E786B8384FF62EC1CB99A79928B0EDB9845107488A06141112F534054013B3AA4DC1B2FE160ABA2E8670A0FB7B835D57BF99D5E7474161517D4149677B3BA24D68831195F8EF4145CB44B0FBDB37BF1B36A0B6F517F145FCC7C169C41A0E3A8A313E455A377E5D82B82608EEB14A5E7C5F4E9AA8E5315D1C600077B5F2F50022E2AEEE142E09DD25363862BAE1AF0D37B00C0D824B25C2B579524577AABB5C82452BE70C9AE8D65E935E087A70892E00544BAD691FE677C577917CC495D470E5301A9F75F019268DD8A9ED8F89EE35F6DABECE4507627691A666E86B98578FD03A7AC198728F7BA4348ECF3A61BAA4AD99DA46F97EA9773F1B9ACAA71EE30435E7A82F081C9D0B16495E96645626637CB97BDB4E7932763F826029B6FFE6C0537315BF01C1671029397DA737A5CD1F13F3ECB769D8265BE0148B22DD5FECCA1E7763E837C3FAEC235F1CC2910F51BD05A647C39623EEC1514FA6C64C84804E23D63D0BED6A88A1C6D382EBCF04FD8574C92D662BAFB239EE7984E6D252AD85D3B0D94D040B6FCB4B5120A2E43AF54C11C59B3D4BB777B3E49714FBBF0169ABBDC0CF285F6C37E668966CB8BBA5083A5EBCD706CBED60455ED554794B03D5136AC555A272FD180D2B99B60AEC25096F33C70CF7B6E4ED89D781954B7D52DFB8A0CCD2A237D8693EF8B3236540678ACEEDAC2A621B88B1A478BAB068ADB7CC8A037F8723B89E0FDFFAAD73F5D77007FCF04DB358393A7DC6DF42DCB4EBB853B77D27FFD7A616B9354ED0707431776FE294BAE152689DEE19B18902356B801EC7A760C2075998D6C6AF8CA1D59CB1D294CBA7490D5F54E0997202F4F4298AD554E28FF788093407E005600A35BA4B172B1D141D956965ED477C2EE1F808B45DE3517D66E969F17D8F5C0F4CA8F64F3912E9E8E8E11D3939EEC5CD6E6FB8D1090E65531BD570108A73A0268D370C51D41FF38B96475BE85EFF412B573F998D03C4741F3095ABEB13AC750147D76DF8375DFE62DC289496C8B8C9D692D5034AD7D514EBC3CD05B0ED0B7261823CEF3DFEA3D4324F1E1F5AD0172220225EECF3FC23786D75F1143117275CCDC3F5182C6CD7D194F9F943E0E0D4C64353442E9C0D06584A7D641DA03641E474E48CA631BEDB233526F7B889425561B48D5645BBB2E53CFC32A40771B6A12D0A2A6E0034666F2DBE47E30CE1FD5949963D2A779B02B886E186E20A31ECC948E4BF19E3D206760613F9577D9BC1FC02D68D2AB09C1EA756175FDD76A372E87FF4A9E79AAEE681D79697ED27803F8E6A9E41B92A0F6F239CA72F88F8414F758E98A48A1C0BC30FCF49EC2615F831C0E99E1B729317C703EE2B
-20200420182727 2 6 100 8191 5 FDD2FF1B0B2402FB6FD5FBC2AF7553A3418C2535DFBF5CDB078CEA3D7C44A4863229766D19871460787A24C249D14845D5332DC7B153C10DF45AEBDC462929E786B8384FF62EC1CB99A79928B0EDB9845107488A06141112F534054013B3AA4DC1B2FE160ABA2E8670A0FB7B835D57BF99D5E7474161517D4149677B3BA24D68831195F8EF4145CB44B0FBDB37BF1B36A0B6F517F145FCC7C169C41A0E3A8A313E455A377E5D82B82608EEB14A5E7C5F4E9AA8E5315D1C600077B5F2F50022E2AEEE142E09DD25363862BAE1AF0D37B00C0D824B25C2B579524577AABB5C82452BE70C9AE8D65E935E087A70892E00544BAD691FE677C577917CC495D470E5301A9F75F019268DD8A9ED8F89EE35F6DABECE4507627691A666E86B98578FD03A7AC198728F7BA4348ECF3A61BAA4AD99DA46F97EA9773F1B9ACAA71EE30435E7A82F081C9D0B16495E96645626637CB97BDB4E7932763F826029B6FFE6C0537315BF01C1671029397DA737A5CD1F13F3ECB769D8265BE0148B22DD5FECCA1E7763E837C3FAEC235F1CC2910F51BD05A647C39623EEC1514FA6C64C84804E23D63D0BED6A88A1C6D382EBCF04FD8574C92D662BAFB239EE7984E6D252AD85D3B0D94D040B6FCB4B5120A2E43AF54C11C59B3D4BB777B3E49714FBBF0169ABBDC0CF285F6C37E668966CB8BBA5083A5EBCD706CBED60455ED554794B03D5136AC555A272FD180D2B99B60AEC25096F33C70CF7B6E4ED89D781954B7D52DFB8A0CCD2A237D8693EF8B3236540678ACEEDAC2A621B88B1A478BAB068ADB7CC8A037F8723B89E0FDFFAAD73F5D77007FCF04DB358393A7DC6DF42DCB4EBB853B77D27FFD7A616B9354ED0707431776FE294BAE152689DEE19B18902356B801EC7A760C2075998D6C6AF8CA1D59CB1D294CBA7490D5F54E0997202F4F4298AD554E28FF788093407E005600A35BA4B172B1D141D956965ED477C2EE1F808B45DE3517D66E969F17D8F5C0F4CA8F64F3912E9E8E8E11D3939EEC5CD6E6FB8D1090E65531BD570108A73A0268D370C51D41FF38B96475BE85EFF412B573F998D03C4741F3095ABEB13AC750147D76DF8375DFE62DC289496C8B8C9D692D5034AD7D514EBC3CD05B0ED0B7261823CEF3DFEA3D4324F1E1F5AD0172220225EECF3FC23786D75F1143117275CCDC3F5182C6CD7D194F9F943E0E0D4C64353442E9C0D06584A7D641DA03641E474E48CA631BEDB233526F7B889425561B48D5645BBB2E53CFC32A40771B6A12D0A2A6E0034666F2DBE47E30CE1FD5949963D2A779B02B886E186E20A31ECC948E4BF19E3D206760613F9577D9BC1FC02D68D2AB09C1EA756175FDD76A372E87FF4A9E79AAEE681D79697ED27803F8E6A9E41B92A0F6F239CA72F88F8414F758E98A48A1C0BC30FCF49EC2615F831C0E99E1B729317CFC2F4E7
-20200421163640 2 6 100 8191 2 FDD2FF1B0B2402FB6FD5FBC2AF7553A3418C2535DFBF5CDB078CEA3D7C44A4863229766D19871460787A24C249D14845D5332DC7B153C10DF45AEBDC462929E786B8384FF62EC1CB99A79928B0EDB9845107488A06141112F534054013B3AA4DC1B2FE160ABA2E8670A0FB7B835D57BF99D5E7474161517D4149677B3BA24D68831195F8EF4145CB44B0FBDB37BF1B36A0B6F517F145FCC7C169C41A0E3A8A313E455A377E5D82B82608EEB14A5E7C5F4E9AA8E5315D1C600077B5F2F50022E2AEEE142E09DD25363862BAE1AF0D37B00C0D824B25C2B579524577AABB5C82452BE70C9AE8D65E935E087A70892E00544BAD691FE677C577917CC495D470E5301A9F75F019268DD8A9ED8F89EE35F6DABECE4507627691A666E86B98578FD03A7AC198728F7BA4348ECF3A61BAA4AD99DA46F97EA9773F1B9ACAA71EE30435E7A82F081C9D0B16495E96645626637CB97BDB4E7932763F826029B6FFE6C0537315BF01C1671029397DA737A5CD1F13F3ECB769D8265BE0148B22DD5FECCA1E7763E837C3FAEC235F1CC2910F51BD05A647C39623EEC1514FA6C64C84804E23D63D0BED6A88A1C6D382EBCF04FD8574C92D662BAFB239EE7984E6D252AD85D3B0D94D040B6FCB4B5120A2E43AF54C11C59B3D4BB777B3E49714FBBF0169ABBDC0CF285F6C37E668966CB8BBA5083A5EBCD706CBED60455ED554794B03D5136AC555A272FD180D2B99B60AEC25096F33C70CF7B6E4ED89D781954B7D52DFB8A0CCD2A237D8693EF8B3236540678ACEEDAC2A621B88B1A478BAB068ADB7CC8A037F8723B89E0FDFFAAD73F5D77007FCF04DB358393A7DC6DF42DCB4EBB853B77D27FFD7A616B9354ED0707431776FE294BAE152689DEE19B18902356B801EC7A760C2075998D6C6AF8CA1D59CB1D294CBA7490D5F54E0997202F4F4298AD554E28FF788093407E005600A35BA4B172B1D141D956965ED477C2EE1F808B45DE3517D66E969F17D8F5C0F4CA8F64F3912E9E8E8E11D3939EEC5CD6E6FB8D1090E65531BD570108A73A0268D370C51D41FF38B96475BE85EFF412B573F998D03C4741F3095ABEB13AC750147D76DF8375DFE62DC289496C8B8C9D692D5034AD7D514EBC3CD05B0ED0B7261823CEF3DFEA3D4324F1E1F5AD0172220225EECF3FC23786D75F1143117275CCDC3F5182C6CD7D194F9F943E0E0D4C64353442E9C0D06584A7D641DA03641E474E48CA631BEDB233526F7B889425561B48D5645BBB2E53CFC32A40771B6A12D0A2A6E0034666F2DBE47E30CE1FD5949963D2A779B02B886E186E20A31ECC948E4BF19E3D206760613F9577D9BC1FC02D68D2AB09C1EA756175FDD76A372E87FF4A9E79AAEE681D79697ED27803F8E6A9E41B92A0F6F239CA72F88F8414F758E98A48A1C0BC30FCF49EC2615F831C0E99E1B729317D5F6A563
-20200421165237 2 6 100 8191 5 FDD2FF1B0B2402FB6FD5FBC2AF7553A3418C2535DFBF5CDB078CEA3D7C44A4863229766D19871460787A24C249D14845D5332DC7B153C10DF45AEBDC462929E786B8384FF62EC1CB99A79928B0EDB9845107488A06141112F534054013B3AA4DC1B2FE160ABA2E8670A0FB7B835D57BF99D5E7474161517D4149677B3BA24D68831195F8EF4145CB44B0FBDB37BF1B36A0B6F517F145FCC7C169C41A0E3A8A313E455A377E5D82B82608EEB14A5E7C5F4E9AA8E5315D1C600077B5F2F50022E2AEEE142E09DD25363862BAE1AF0D37B00C0D824B25C2B579524577AABB5C82452BE70C9AE8D65E935E087A70892E00544BAD691FE677C577917CC495D470E5301A9F75F019268DD8A9ED8F89EE35F6DABECE4507627691A666E86B98578FD03A7AC198728F7BA4348ECF3A61BAA4AD99DA46F97EA9773F1B9ACAA71EE30435E7A82F081C9D0B16495E96645626637CB97BDB4E7932763F826029B6FFE6C0537315BF01C1671029397DA737A5CD1F13F3ECB769D8265BE0148B22DD5FECCA1E7763E837C3FAEC235F1CC2910F51BD05A647C39623EEC1514FA6C64C84804E23D63D0BED6A88A1C6D382EBCF04FD8574C92D662BAFB239EE7984E6D252AD85D3B0D94D040B6FCB4B5120A2E43AF54C11C59B3D4BB777B3E49714FBBF0169ABBDC0CF285F6C37E668966CB8BBA5083A5EBCD706CBED60455ED554794B03D5136AC555A272FD180D2B99B60AEC25096F33C70CF7B6E4ED89D781954B7D52DFB8A0CCD2A237D8693EF8B3236540678ACEEDAC2A621B88B1A478BAB068ADB7CC8A037F8723B89E0FDFFAAD73F5D77007FCF04DB358393A7DC6DF42DCB4EBB853B77D27FFD7A616B9354ED0707431776FE294BAE152689DEE19B18902356B801EC7A760C2075998D6C6AF8CA1D59CB1D294CBA7490D5F54E0997202F4F4298AD554E28FF788093407E005600A35BA4B172B1D141D956965ED477C2EE1F808B45DE3517D66E969F17D8F5C0F4CA8F64F3912E9E8E8E11D3939EEC5CD6E6FB8D1090E65531BD570108A73A0268D370C51D41FF38B96475BE85EFF412B573F998D03C4741F3095ABEB13AC750147D76DF8375DFE62DC289496C8B8C9D692D5034AD7D514EBC3CD05B0ED0B7261823CEF3DFEA3D4324F1E1F5AD0172220225EECF3FC23786D75F1143117275CCDC3F5182C6CD7D194F9F943E0E0D4C64353442E9C0D06584A7D641DA03641E474E48CA631BEDB233526F7B889425561B48D5645BBB2E53CFC32A40771B6A12D0A2A6E0034666F2DBE47E30CE1FD5949963D2A779B02B886E186E20A31ECC948E4BF19E3D206760613F9577D9BC1FC02D68D2AB09C1EA756175FDD76A372E87FF4A9E79AAEE681D79697ED27803F8E6A9E41B92A0F6F239CA72F88F8414F758E98A48A1C0BC30FCF49EC2615F831C0E99E1B729317D6070547
-20200421230237 2 6 100 8191 2 FDD2FF1B0B2402FB6FD5FBC2AF7553A3418C2535DFBF5CDB078CEA3D7C44A4863229766D19871460787A24C249D14845D5332DC7B153C10DF45AEBDC462929E786B8384FF62EC1CB99A79928B0EDB9845107488A06141112F534054013B3AA4DC1B2FE160ABA2E8670A0FB7B835D57BF99D5E7474161517D4149677B3BA24D68831195F8EF4145CB44B0FBDB37BF1B36A0B6F517F145FCC7C169C41A0E3A8A313E455A377E5D82B82608EEB14A5E7C5F4E9AA8E5315D1C600077B5F2F50022E2AEEE142E09DD25363862BAE1AF0D37B00C0D824B25C2B579524577AABB5C82452BE70C9AE8D65E935E087A70892E00544BAD691FE677C577917CC495D470E5301A9F75F019268DD8A9ED8F89EE35F6DABECE4507627691A666E86B98578FD03A7AC198728F7BA4348ECF3A61BAA4AD99DA46F97EA9773F1B9ACAA71EE30435E7A82F081C9D0B16495E96645626637CB97BDB4E7932763F826029B6FFE6C0537315BF01C1671029397DA737A5CD1F13F3ECB769D8265BE0148B22DD5FECCA1E7763E837C3FAEC235F1CC2910F51BD05A647C39623EEC1514FA6C64C84804E23D63D0BED6A88A1C6D382EBCF04FD8574C92D662BAFB239EE7984E6D252AD85D3B0D94D040B6FCB4B5120A2E43AF54C11C59B3D4BB777B3E49714FBBF0169ABBDC0CF285F6C37E668966CB8BBA5083A5EBCD706CBED60455ED554794B03D5136AC555A272FD180D2B99B60AEC25096F33C70CF7B6E4ED89D781954B7D52DFB8A0CCD2A237D8693EF8B3236540678ACEEDAC2A621B88B1A478BAB068ADB7CC8A037F8723B89E0FDFFAAD73F5D77007FCF04DB358393A7DC6DF42DCB4EBB853B77D27FFD7A616B9354ED0707431776FE294BAE152689DEE19B18902356B801EC7A760C2075998D6C6AF8CA1D59CB1D294CBA7490D5F54E0997202F4F4298AD554E28FF788093407E005600A35BA4B172B1D141D956965ED477C2EE1F808B45DE3517D66E969F17D8F5C0F4CA8F64F3912E9E8E8E11D3939EEC5CD6E6FB8D1090E65531BD570108A73A0268D370C51D41FF38B96475BE85EFF412B573F998D03C4741F3095ABEB13AC750147D76DF8375DFE62DC289496C8B8C9D692D5034AD7D514EBC3CD05B0ED0B7261823CEF3DFEA3D4324F1E1F5AD0172220225EECF3FC23786D75F1143117275CCDC3F5182C6CD7D194F9F943E0E0D4C64353442E9C0D06584A7D641DA03641E474E48CA631BEDB233526F7B889425561B48D5645BBB2E53CFC32A40771B6A12D0A2A6E0034666F2DBE47E30CE1FD5949963D2A779B02B886E186E20A31ECC948E4BF19E3D206760613F9577D9BC1FC02D68D2AB09C1EA756175FDD76A372E87FF4A9E79AAEE681D79697ED27803F8E6A9E41B92A0F6F239CA72F88F8414F758E98A48A1C0BC30FCF49EC2615F831C0E99E1B729317D880CCA3
-20200422193836 2 6 100 8191 5 FDD2FF1B0B2402FB6FD5FBC2AF7553A3418C2535DFBF5CDB078CEA3D7C44A4863229766D19871460787A24C249D14845D5332DC7B153C10DF45AEBDC462929E786B8384FF62EC1CB99A79928B0EDB9845107488A06141112F534054013B3AA4DC1B2FE160ABA2E8670A0FB7B835D57BF99D5E7474161517D4149677B3BA24D68831195F8EF4145CB44B0FBDB37BF1B36A0B6F517F145FCC7C169C41A0E3A8A313E455A377E5D82B82608EEB14A5E7C5F4E9AA8E5315D1C600077B5F2F50022E2AEEE142E09DD25363862BAE1AF0D37B00C0D824B25C2B579524577AABB5C82452BE70C9AE8D65E935E087A70892E00544BAD691FE677C577917CC495D470E5301A9F75F019268DD8A9ED8F89EE35F6DABECE4507627691A666E86B98578FD03A7AC198728F7BA4348ECF3A61BAA4AD99DA46F97EA9773F1B9ACAA71EE30435E7A82F081C9D0B16495E96645626637CB97BDB4E7932763F826029B6FFE6C0537315BF01C1671029397DA737A5CD1F13F3ECB769D8265BE0148B22DD5FECCA1E7763E837C3FAEC235F1CC2910F51BD05A647C39623EEC1514FA6C64C84804E23D63D0BED6A88A1C6D382EBCF04FD8574C92D662BAFB239EE7984E6D252AD85D3B0D94D040B6FCB4B5120A2E43AF54C11C59B3D4BB777B3E49714FBBF0169ABBDC0CF285F6C37E668966CB8BBA5083A5EBCD706CBED60455ED554794B03D5136AC555A272FD180D2B99B60AEC25096F33C70CF7B6E4ED89D781954B7D52DFB8A0CCD2A237D8693EF8B3236540678ACEEDAC2A621B88B1A478BAB068ADB7CC8A037F8723B89E0FDFFAAD73F5D77007FCF04DB358393A7DC6DF42DCB4EBB853B77D27FFD7A616B9354ED0707431776FE294BAE152689DEE19B18902356B801EC7A760C2075998D6C6AF8CA1D59CB1D294CBA7490D5F54E0997202F4F4298AD554E28FF788093407E005600A35BA4B172B1D141D956965ED477C2EE1F808B45DE3517D66E969F17D8F5C0F4CA8F64F3912E9E8E8E11D3939EEC5CD6E6FB8D1090E65531BD570108A73A0268D370C51D41FF38B96475BE85EFF412B573F998D03C4741F3095ABEB13AC750147D76DF8375DFE62DC289496C8B8C9D692D5034AD7D514EBC3CD05B0ED0B7261823CEF3DFEA3D4324F1E1F5AD0172220225EECF3FC23786D75F1143117275CCDC3F5182C6CD7D194F9F943E0E0D4C64353442E9C0D06584A7D641DA03641E474E48CA631BEDB233526F7B889425561B48D5645BBB2E53CFC32A40771B6A12D0A2A6E0034666F2DBE47E30CE1FD5949963D2A779B02B886E186E20A31ECC948E4BF19E3D206760613F9577D9BC1FC02D68D2AB09C1EA756175FDD76A372E87FF4A9E79AAEE681D79697ED27803F8E6A9E41B92A0F6F239CA72F88F8414F758E98A48A1C0BC30FCF49EC2615F831C0E99E1B729317DE385AC7
-20200423050749 2 6 100 8191 2 FDD2FF1B0B2402FB6FD5FBC2AF7553A3418C2535DFBF5CDB078CEA3D7C44A4863229766D19871460787A24C249D14845D5332DC7B153C10DF45AEBDC462929E786B8384FF62EC1CB99A79928B0EDB9845107488A06141112F534054013B3AA4DC1B2FE160ABA2E8670A0FB7B835D57BF99D5E7474161517D4149677B3BA24D68831195F8EF4145CB44B0FBDB37BF1B36A0B6F517F145FCC7C169C41A0E3A8A313E455A377E5D82B82608EEB14A5E7C5F4E9AA8E5315D1C600077B5F2F50022E2AEEE142E09DD25363862BAE1AF0D37B00C0D824B25C2B579524577AABB5C82452BE70C9AE8D65E935E087A70892E00544BAD691FE677C577917CC495D470E5301A9F75F019268DD8A9ED8F89EE35F6DABECE4507627691A666E86B98578FD03A7AC198728F7BA4348ECF3A61BAA4AD99DA46F97EA9773F1B9ACAA71EE30435E7A82F081C9D0B16495E96645626637CB97BDB4E7932763F826029B6FFE6C0537315BF01C1671029397DA737A5CD1F13F3ECB769D8265BE0148B22DD5FECCA1E7763E837C3FAEC235F1CC2910F51BD05A647C39623EEC1514FA6C64C84804E23D63D0BED6A88A1C6D382EBCF04FD8574C92D662BAFB239EE7984E6D252AD85D3B0D94D040B6FCB4B5120A2E43AF54C11C59B3D4BB777B3E49714FBBF0169ABBDC0CF285F6C37E668966CB8BBA5083A5EBCD706CBED60455ED554794B03D5136AC555A272FD180D2B99B60AEC25096F33C70CF7B6E4ED89D781954B7D52DFB8A0CCD2A237D8693EF8B3236540678ACEEDAC2A621B88B1A478BAB068ADB7CC8A037F8723B89E0FDFFAAD73F5D77007FCF04DB358393A7DC6DF42DCB4EBB853B77D27FFD7A616B9354ED0707431776FE294BAE152689DEE19B18902356B801EC7A760C2075998D6C6AF8CA1D59CB1D294CBA7490D5F54E0997202F4F4298AD554E28FF788093407E005600A35BA4B172B1D141D956965ED477C2EE1F808B45DE3517D66E969F17D8F5C0F4CA8F64F3912E9E8E8E11D3939EEC5CD6E6FB8D1090E65531BD570108A73A0268D370C51D41FF38B96475BE85EFF412B573F998D03C4741F3095ABEB13AC750147D76DF8375DFE62DC289496C8B8C9D692D5034AD7D514EBC3CD05B0ED0B7261823CEF3DFEA3D4324F1E1F5AD0172220225EECF3FC23786D75F1143117275CCDC3F5182C6CD7D194F9F943E0E0D4C64353442E9C0D06584A7D641DA03641E474E48CA631BEDB233526F7B889425561B48D5645BBB2E53CFC32A40771B6A12D0A2A6E0034666F2DBE47E30CE1FD5949963D2A779B02B886E186E20A31ECC948E4BF19E3D206760613F9577D9BC1FC02D68D2AB09C1EA756175FDD76A372E87FF4A9E79AAEE681D79697ED27803F8E6A9E41B92A0F6F239CA72F88F8414F758E98A48A1C0BC30FCF49EC2615F831C0E99E1B729317E3208663
-20200424124535 2 6 100 8191 2 FDD2FF1B0B2402FB6FD5FBC2AF7553A3418C2535DFBF5CDB078CEA3D7C44A4863229766D19871460787A24C249D14845D5332DC7B153C10DF45AEBDC462929E786B8384FF62EC1CB99A79928B0EDB9845107488A06141112F534054013B3AA4DC1B2FE160ABA2E8670A0FB7B835D57BF99D5E7474161517D4149677B3BA24D68831195F8EF4145CB44B0FBDB37BF1B36A0B6F517F145FCC7C169C41A0E3A8A313E455A377E5D82B82608EEB14A5E7C5F4E9AA8E5315D1C600077B5F2F50022E2AEEE142E09DD25363862BAE1AF0D37B00C0D824B25C2B579524577AABB5C82452BE70C9AE8D65E935E087A70892E00544BAD691FE677C577917CC495D470E5301A9F75F019268DD8A9ED8F89EE35F6DABECE4507627691A666E86B98578FD03A7AC198728F7BA4348ECF3A61BAA4AD99DA46F97EA9773F1B9ACAA71EE30435E7A82F081C9D0B16495E96645626637CB97BDB4E7932763F826029B6FFE6C0537315BF01C1671029397DA737A5CD1F13F3ECB769D8265BE0148B22DD5FECCA1E7763E837C3FAEC235F1CC2910F51BD05A647C39623EEC1514FA6C64C84804E23D63D0BED6A88A1C6D382EBCF04FD8574C92D662BAFB239EE7984E6D252AD85D3B0D94D040B6FCB4B5120A2E43AF54C11C59B3D4BB777B3E49714FBBF0169ABBDC0CF285F6C37E668966CB8BBA5083A5EBCD706CBED60455ED554794B03D5136AC555A272FD180D2B99B60AEC25096F33C70CF7B6E4ED89D781954B7D52DFB8A0CCD2A237D8693EF8B3236540678ACEEDAC2A621B88B1A478BAB068ADB7CC8A037F8723B89E0FDFFAAD73F5D77007FCF04DB358393A7DC6DF42DCB4EBB853B77D27FFD7A616B9354ED0707431776FE294BAE152689DEE19B18902356B801EC7A760C2075998D6C6AF8CA1D59CB1D294CBA7490D5F54E0997202F4F4298AD554E28FF788093407E005600A35BA4B172B1D141D956965ED477C2EE1F808B45DE3517D66E969F17D8F5C0F4CA8F64F3912E9E8E8E11D3939EEC5CD6E6FB8D1090E65531BD570108A73A0268D370C51D41FF38B96475BE85EFF412B573F998D03C4741F3095ABEB13AC750147D76DF8375DFE62DC289496C8B8C9D692D5034AD7D514EBC3CD05B0ED0B7261823CEF3DFEA3D4324F1E1F5AD0172220225EECF3FC23786D75F1143117275CCDC3F5182C6CD7D194F9F943E0E0D4C64353442E9C0D06584A7D641DA03641E474E48CA631BEDB233526F7B889425561B48D5645BBB2E53CFC32A40771B6A12D0A2A6E0034666F2DBE47E30CE1FD5949963D2A779B02B886E186E20A31ECC948E4BF19E3D206760613F9577D9BC1FC02D68D2AB09C1EA756175FDD76A372E87FF4A9E79AAEE681D79697ED27803F8E6A9E41B92A0F6F239CA72F88F8414F758E98A48A1C0BC30FCF49EC2615F831C0E99E1B729317EE2914A3
-20200425200633 2 6 100 8191 2 FDD2FF1B0B2402FB6FD5FBC2AF7553A3418C2535DFBF5CDB078CEA3D7C44A4863229766D19871460787A24C249D14845D5332DC7B153C10DF45AEBDC462929E786B8384FF62EC1CB99A79928B0EDB9845107488A06141112F534054013B3AA4DC1B2FE160ABA2E8670A0FB7B835D57BF99D5E7474161517D4149677B3BA24D68831195F8EF4145CB44B0FBDB37BF1B36A0B6F517F145FCC7C169C41A0E3A8A313E455A377E5D82B82608EEB14A5E7C5F4E9AA8E5315D1C600077B5F2F50022E2AEEE142E09DD25363862BAE1AF0D37B00C0D824B25C2B579524577AABB5C82452BE70C9AE8D65E935E087A70892E00544BAD691FE677C577917CC495D470E5301A9F75F019268DD8A9ED8F89EE35F6DABECE4507627691A666E86B98578FD03A7AC198728F7BA4348ECF3A61BAA4AD99DA46F97EA9773F1B9ACAA71EE30435E7A82F081C9D0B16495E96645626637CB97BDB4E7932763F826029B6FFE6C0537315BF01C1671029397DA737A5CD1F13F3ECB769D8265BE0148B22DD5FECCA1E7763E837C3FAEC235F1CC2910F51BD05A647C39623EEC1514FA6C64C84804E23D63D0BED6A88A1C6D382EBCF04FD8574C92D662BAFB239EE7984E6D252AD85D3B0D94D040B6FCB4B5120A2E43AF54C11C59B3D4BB777B3E49714FBBF0169ABBDC0CF285F6C37E668966CB8BBA5083A5EBCD706CBED60455ED554794B03D5136AC555A272FD180D2B99B60AEC25096F33C70CF7B6E4ED89D781954B7D52DFB8A0CCD2A237D8693EF8B3236540678ACEEDAC2A621B88B1A478BAB068ADB7CC8A037F8723B89E0FDFFAAD73F5D77007FCF04DB358393A7DC6DF42DCB4EBB853B77D27FFD7A616B9354ED0707431776FE294BAE152689DEE19B18902356B801EC7A760C2075998D6C6AF8CA1D59CB1D294CBA7490D5F54E0997202F4F4298AD554E28FF788093407E005600A35BA4B172B1D141D956965ED477C2EE1F808B45DE3517D66E969F17D8F5C0F4CA8F64F3912E9E8E8E11D3939EEC5CD6E6FB8D1090E65531BD570108A73A0268D370C51D41FF38B96475BE85EFF412B573F998D03C4741F3095ABEB13AC750147D76DF8375DFE62DC289496C8B8C9D692D5034AD7D514EBC3CD05B0ED0B7261823CEF3DFEA3D4324F1E1F5AD0172220225EECF3FC23786D75F1143117275CCDC3F5182C6CD7D194F9F943E0E0D4C64353442E9C0D06584A7D641DA03641E474E48CA631BEDB233526F7B889425561B48D5645BBB2E53CFC32A40771B6A12D0A2A6E0034666F2DBE47E30CE1FD5949963D2A779B02B886E186E20A31ECC948E4BF19E3D206760613F9577D9BC1FC02D68D2AB09C1EA756175FDD76A372E87FF4A9E79AAEE681D79697ED27803F8E6A9E41B92A0F6F239CA72F88F8414F758E98A48A1C0BC30FCF49EC2615F831C0E99E1B729317FD928D1B
-20200425223722 2 6 100 8191 2 FDD2FF1B0B2402FB6FD5FBC2AF7553A3418C2535DFBF5CDB078CEA3D7C44A4863229766D19871460787A24C249D14845D5332DC7B153C10DF45AEBDC462929E786B8384FF62EC1CB99A79928B0EDB9845107488A06141112F534054013B3AA4DC1B2FE160ABA2E8670A0FB7B835D57BF99D5E7474161517D4149677B3BA24D68831195F8EF4145CB44B0FBDB37BF1B36A0B6F517F145FCC7C169C41A0E3A8A313E455A377E5D82B82608EEB14A5E7C5F4E9AA8E5315D1C600077B5F2F50022E2AEEE142E09DD25363862BAE1AF0D37B00C0D824B25C2B579524577AABB5C82452BE70C9AE8D65E935E087A70892E00544BAD691FE677C577917CC495D470E5301A9F75F019268DD8A9ED8F89EE35F6DABECE4507627691A666E86B98578FD03A7AC198728F7BA4348ECF3A61BAA4AD99DA46F97EA9773F1B9ACAA71EE30435E7A82F081C9D0B16495E96645626637CB97BDB4E7932763F826029B6FFE6C0537315BF01C1671029397DA737A5CD1F13F3ECB769D8265BE0148B22DD5FECCA1E7763E837C3FAEC235F1CC2910F51BD05A647C39623EEC1514FA6C64C84804E23D63D0BED6A88A1C6D382EBCF04FD8574C92D662BAFB239EE7984E6D252AD85D3B0D94D040B6FCB4B5120A2E43AF54C11C59B3D4BB777B3E49714FBBF0169ABBDC0CF285F6C37E668966CB8BBA5083A5EBCD706CBED60455ED554794B03D5136AC555A272FD180D2B99B60AEC25096F33C70CF7B6E4ED89D781954B7D52DFB8A0CCD2A237D8693EF8B3236540678ACEEDAC2A621B88B1A478BAB068ADB7CC8A037F8723B89E0FDFFAAD73F5D77007FCF04DB358393A7DC6DF42DCB4EBB853B77D27FFD7A616B9354ED0707431776FE294BAE152689DEE19B18902356B801EC7A760C2075998D6C6AF8CA1D59CB1D294CBA7490D5F54E0997202F4F4298AD554E28FF788093407E005600A35BA4B172B1D141D956965ED477C2EE1F808B45DE3517D66E969F17D8F5C0F4CA8F64F3912E9E8E8E11D3939EEC5CD6E6FB8D1090E65531BD570108A73A0268D370C51D41FF38B96475BE85EFF412B573F998D03C4741F3095ABEB13AC750147D76DF8375DFE62DC289496C8B8C9D692D5034AD7D514EBC3CD05B0ED0B7261823CEF3DFEA3D4324F1E1F5AD0172220225EECF3FC23786D75F1143117275CCDC3F5182C6CD7D194F9F943E0E0D4C64353442E9C0D06584A7D641DA03641E474E48CA631BEDB233526F7B889425561B48D5645BBB2E53CFC32A40771B6A12D0A2A6E0034666F2DBE47E30CE1FD5949963D2A779B02B886E186E20A31ECC948E4BF19E3D206760613F9577D9BC1FC02D68D2AB09C1EA756175FDD76A372E87FF4A9E79AAEE681D79697ED27803F8E6A9E41B92A0F6F239CA72F88F8414F758E98A48A1C0BC30FCF49EC2615F831C0E99E1B729317FEB7212B
-20200426095445 2 6 100 8191 5 FDD2FF1B0B2402FB6FD5FBC2AF7553A3418C2535DFBF5CDB078CEA3D7C44A4863229766D19871460787A24C249D14845D5332DC7B153C10DF45AEBDC462929E786B8384FF62EC1CB99A79928B0EDB9845107488A06141112F534054013B3AA4DC1B2FE160ABA2E8670A0FB7B835D57BF99D5E7474161517D4149677B3BA24D68831195F8EF4145CB44B0FBDB37BF1B36A0B6F517F145FCC7C169C41A0E3A8A313E455A377E5D82B82608EEB14A5E7C5F4E9AA8E5315D1C600077B5F2F50022E2AEEE142E09DD25363862BAE1AF0D37B00C0D824B25C2B579524577AABB5C82452BE70C9AE8D65E935E087A70892E00544BAD691FE677C577917CC495D470E5301A9F75F019268DD8A9ED8F89EE35F6DABECE4507627691A666E86B98578FD03A7AC198728F7BA4348ECF3A61BAA4AD99DA46F97EA9773F1B9ACAA71EE30435E7A82F081C9D0B16495E96645626637CB97BDB4E7932763F826029B6FFE6C0537315BF01C1671029397DA737A5CD1F13F3ECB769D8265BE0148B22DD5FECCA1E7763E837C3FAEC235F1CC2910F51BD05A647C39623EEC1514FA6C64C84804E23D63D0BED6A88A1C6D382EBCF04FD8574C92D662BAFB239EE7984E6D252AD85D3B0D94D040B6FCB4B5120A2E43AF54C11C59B3D4BB777B3E49714FBBF0169ABBDC0CF285F6C37E668966CB8BBA5083A5EBCD706CBED60455ED554794B03D5136AC555A272FD180D2B99B60AEC25096F33C70CF7B6E4ED89D781954B7D52DFB8A0CCD2A237D8693EF8B3236540678ACEEDAC2A621B88B1A478BAB068ADB7CC8A037F8723B89E0FDFFAAD73F5D77007FCF04DB358393A7DC6DF42DCB4EBB853B77D27FFD7A616B9354ED0707431776FE294BAE152689DEE19B18902356B801EC7A760C2075998D6C6AF8CA1D59CB1D294CBA7490D5F54E0997202F4F4298AD554E28FF788093407E005600A35BA4B172B1D141D956965ED477C2EE1F808B45DE3517D66E969F17D8F5C0F4CA8F64F3912E9E8E8E11D3939EEC5CD6E6FB8D1090E65531BD570108A73A0268D370C51D41FF38B96475BE85EFF412B573F998D03C4741F3095ABEB13AC750147D76DF8375DFE62DC289496C8B8C9D692D5034AD7D514EBC3CD05B0ED0B7261823CEF3DFEA3D4324F1E1F5AD0172220225EECF3FC23786D75F1143117275CCDC3F5182C6CD7D194F9F943E0E0D4C64353442E9C0D06584A7D641DA03641E474E48CA631BEDB233526F7B889425561B48D5645BBB2E53CFC32A40771B6A12D0A2A6E0034666F2DBE47E30CE1FD5949963D2A779B02B886E186E20A31ECC948E4BF19E3D206760613F9577D9BC1FC02D68D2AB09C1EA756175FDD76A372E87FF4A9E79AAEE681D79697ED27803F8E6A9E41B92A0F6F239CA72F88F8414F758E98A48A1C0BC30FCF49EC2615F831C0E99E1B72931804287AC7
-20200426121541 2 6 100 8191 2 FDD2FF1B0B2402FB6FD5FBC2AF7553A3418C2535DFBF5CDB078CEA3D7C44A4863229766D19871460787A24C249D14845D5332DC7B153C10DF45AEBDC462929E786B8384FF62EC1CB99A79928B0EDB9845107488A06141112F534054013B3AA4DC1B2FE160ABA2E8670A0FB7B835D57BF99D5E7474161517D4149677B3BA24D68831195F8EF4145CB44B0FBDB37BF1B36A0B6F517F145FCC7C169C41A0E3A8A313E455A377E5D82B82608EEB14A5E7C5F4E9AA8E5315D1C600077B5F2F50022E2AEEE142E09DD25363862BAE1AF0D37B00C0D824B25C2B579524577AABB5C82452BE70C9AE8D65E935E087A70892E00544BAD691FE677C577917CC495D470E5301A9F75F019268DD8A9ED8F89EE35F6DABECE4507627691A666E86B98578FD03A7AC198728F7BA4348ECF3A61BAA4AD99DA46F97EA9773F1B9ACAA71EE30435E7A82F081C9D0B16495E96645626637CB97BDB4E7932763F826029B6FFE6C0537315BF01C1671029397DA737A5CD1F13F3ECB769D8265BE0148B22DD5FECCA1E7763E837C3FAEC235F1CC2910F51BD05A647C39623EEC1514FA6C64C84804E23D63D0BED6A88A1C6D382EBCF04FD8574C92D662BAFB239EE7984E6D252AD85D3B0D94D040B6FCB4B5120A2E43AF54C11C59B3D4BB777B3E49714FBBF0169ABBDC0CF285F6C37E668966CB8BBA5083A5EBCD706CBED60455ED554794B03D5136AC555A272FD180D2B99B60AEC25096F33C70CF7B6E4ED89D781954B7D52DFB8A0CCD2A237D8693EF8B3236540678ACEEDAC2A621B88B1A478BAB068ADB7CC8A037F8723B89E0FDFFAAD73F5D77007FCF04DB358393A7DC6DF42DCB4EBB853B77D27FFD7A616B9354ED0707431776FE294BAE152689DEE19B18902356B801EC7A760C2075998D6C6AF8CA1D59CB1D294CBA7490D5F54E0997202F4F4298AD554E28FF788093407E005600A35BA4B172B1D141D956965ED477C2EE1F808B45DE3517D66E969F17D8F5C0F4CA8F64F3912E9E8E8E11D3939EEC5CD6E6FB8D1090E65531BD570108A73A0268D370C51D41FF38B96475BE85EFF412B573F998D03C4741F3095ABEB13AC750147D76DF8375DFE62DC289496C8B8C9D692D5034AD7D514EBC3CD05B0ED0B7261823CEF3DFEA3D4324F1E1F5AD0172220225EECF3FC23786D75F1143117275CCDC3F5182C6CD7D194F9F943E0E0D4C64353442E9C0D06584A7D641DA03641E474E48CA631BEDB233526F7B889425561B48D5645BBB2E53CFC32A40771B6A12D0A2A6E0034666F2DBE47E30CE1FD5949963D2A779B02B886E186E20A31ECC948E4BF19E3D206760613F9577D9BC1FC02D68D2AB09C1EA756175FDD76A372E87FF4A9E79AAEE681D79697ED27803F8E6A9E41B92A0F6F239CA72F88F8414F758E98A48A1C0BC30FCF49EC2615F831C0E99E1B7293180542CD23
-20200426142125 2 6 100 8191 2 FDD2FF1B0B2402FB6FD5FBC2AF7553A3418C2535DFBF5CDB078CEA3D7C44A4863229766D19871460787A24C249D14845D5332DC7B153C10DF45AEBDC462929E786B8384FF62EC1CB99A79928B0EDB9845107488A06141112F534054013B3AA4DC1B2FE160ABA2E8670A0FB7B835D57BF99D5E7474161517D4149677B3BA24D68831195F8EF4145CB44B0FBDB37BF1B36A0B6F517F145FCC7C169C41A0E3A8A313E455A377E5D82B82608EEB14A5E7C5F4E9AA8E5315D1C600077B5F2F50022E2AEEE142E09DD25363862BAE1AF0D37B00C0D824B25C2B579524577AABB5C82452BE70C9AE8D65E935E087A70892E00544BAD691FE677C577917CC495D470E5301A9F75F019268DD8A9ED8F89EE35F6DABECE4507627691A666E86B98578FD03A7AC198728F7BA4348ECF3A61BAA4AD99DA46F97EA9773F1B9ACAA71EE30435E7A82F081C9D0B16495E96645626637CB97BDB4E7932763F826029B6FFE6C0537315BF01C1671029397DA737A5CD1F13F3ECB769D8265BE0148B22DD5FECCA1E7763E837C3FAEC235F1CC2910F51BD05A647C39623EEC1514FA6C64C84804E23D63D0BED6A88A1C6D382EBCF04FD8574C92D662BAFB239EE7984E6D252AD85D3B0D94D040B6FCB4B5120A2E43AF54C11C59B3D4BB777B3E49714FBBF0169ABBDC0CF285F6C37E668966CB8BBA5083A5EBCD706CBED60455ED554794B03D5136AC555A272FD180D2B99B60AEC25096F33C70CF7B6E4ED89D781954B7D52DFB8A0CCD2A237D8693EF8B3236540678ACEEDAC2A621B88B1A478BAB068ADB7CC8A037F8723B89E0FDFFAAD73F5D77007FCF04DB358393A7DC6DF42DCB4EBB853B77D27FFD7A616B9354ED0707431776FE294BAE152689DEE19B18902356B801EC7A760C2075998D6C6AF8CA1D59CB1D294CBA7490D5F54E0997202F4F4298AD554E28FF788093407E005600A35BA4B172B1D141D956965ED477C2EE1F808B45DE3517D66E969F17D8F5C0F4CA8F64F3912E9E8E8E11D3939EEC5CD6E6FB8D1090E65531BD570108A73A0268D370C51D41FF38B96475BE85EFF412B573F998D03C4741F3095ABEB13AC750147D76DF8375DFE62DC289496C8B8C9D692D5034AD7D514EBC3CD05B0ED0B7261823CEF3DFEA3D4324F1E1F5AD0172220225EECF3FC23786D75F1143117275CCDC3F5182C6CD7D194F9F943E0E0D4C64353442E9C0D06584A7D641DA03641E474E48CA631BEDB233526F7B889425561B48D5645BBB2E53CFC32A40771B6A12D0A2A6E0034666F2DBE47E30CE1FD5949963D2A779B02B886E186E20A31ECC948E4BF19E3D206760613F9577D9BC1FC02D68D2AB09C1EA756175FDD76A372E87FF4A9E79AAEE681D79697ED27803F8E6A9E41B92A0F6F239CA72F88F8414F758E98A48A1C0BC30FCF49EC2615F831C0E99E1B729318063CF9E3
-20200426144436 2 6 100 8191 5 FDD2FF1B0B2402FB6FD5FBC2AF7553A3418C2535DFBF5CDB078CEA3D7C44A4863229766D19871460787A24C249D14845D5332DC7B153C10DF45AEBDC462929E786B8384FF62EC1CB99A79928B0EDB9845107488A06141112F534054013B3AA4DC1B2FE160ABA2E8670A0FB7B835D57BF99D5E7474161517D4149677B3BA24D68831195F8EF4145CB44B0FBDB37BF1B36A0B6F517F145FCC7C169C41A0E3A8A313E455A377E5D82B82608EEB14A5E7C5F4E9AA8E5315D1C600077B5F2F50022E2AEEE142E09DD25363862BAE1AF0D37B00C0D824B25C2B579524577AABB5C82452BE70C9AE8D65E935E087A70892E00544BAD691FE677C577917CC495D470E5301A9F75F019268DD8A9ED8F89EE35F6DABECE4507627691A666E86B98578FD03A7AC198728F7BA4348ECF3A61BAA4AD99DA46F97EA9773F1B9ACAA71EE30435E7A82F081C9D0B16495E96645626637CB97BDB4E7932763F826029B6FFE6C0537315BF01C1671029397DA737A5CD1F13F3ECB769D8265BE0148B22DD5FECCA1E7763E837C3FAEC235F1CC2910F51BD05A647C39623EEC1514FA6C64C84804E23D63D0BED6A88A1C6D382EBCF04FD8574C92D662BAFB239EE7984E6D252AD85D3B0D94D040B6FCB4B5120A2E43AF54C11C59B3D4BB777B3E49714FBBF0169ABBDC0CF285F6C37E668966CB8BBA5083A5EBCD706CBED60455ED554794B03D5136AC555A272FD180D2B99B60AEC25096F33C70CF7B6E4ED89D781954B7D52DFB8A0CCD2A237D8693EF8B3236540678ACEEDAC2A621B88B1A478BAB068ADB7CC8A037F8723B89E0FDFFAAD73F5D77007FCF04DB358393A7DC6DF42DCB4EBB853B77D27FFD7A616B9354ED0707431776FE294BAE152689DEE19B18902356B801EC7A760C2075998D6C6AF8CA1D59CB1D294CBA7490D5F54E0997202F4F4298AD554E28FF788093407E005600A35BA4B172B1D141D956965ED477C2EE1F808B45DE3517D66E969F17D8F5C0F4CA8F64F3912E9E8E8E11D3939EEC5CD6E6FB8D1090E65531BD570108A73A0268D370C51D41FF38B96475BE85EFF412B573F998D03C4741F3095ABEB13AC750147D76DF8375DFE62DC289496C8B8C9D692D5034AD7D514EBC3CD05B0ED0B7261823CEF3DFEA3D4324F1E1F5AD0172220225EECF3FC23786D75F1143117275CCDC3F5182C6CD7D194F9F943E0E0D4C64353442E9C0D06584A7D641DA03641E474E48CA631BEDB233526F7B889425561B48D5645BBB2E53CFC32A40771B6A12D0A2A6E0034666F2DBE47E30CE1FD5949963D2A779B02B886E186E20A31ECC948E4BF19E3D206760613F9577D9BC1FC02D68D2AB09C1EA756175FDD76A372E87FF4A9E79AAEE681D79697ED27803F8E6A9E41B92A0F6F239CA72F88F8414F758E98A48A1C0BC30FCF49EC2615F831C0E99E1B7293180663AFAF
-20200426154241 2 6 100 8191 2 FDD2FF1B0B2402FB6FD5FBC2AF7553A3418C2535DFBF5CDB078CEA3D7C44A4863229766D19871460787A24C249D14845D5332DC7B153C10DF45AEBDC462929E786B8384FF62EC1CB99A79928B0EDB9845107488A06141112F534054013B3AA4DC1B2FE160ABA2E8670A0FB7B835D57BF99D5E7474161517D4149677B3BA24D68831195F8EF4145CB44B0FBDB37BF1B36A0B6F517F145FCC7C169C41A0E3A8A313E455A377E5D82B82608EEB14A5E7C5F4E9AA8E5315D1C600077B5F2F50022E2AEEE142E09DD25363862BAE1AF0D37B00C0D824B25C2B579524577AABB5C82452BE70C9AE8D65E935E087A70892E00544BAD691FE677C577917CC495D470E5301A9F75F019268DD8A9ED8F89EE35F6DABECE4507627691A666E86B98578FD03A7AC198728F7BA4348ECF3A61BAA4AD99DA46F97EA9773F1B9ACAA71EE30435E7A82F081C9D0B16495E96645626637CB97BDB4E7932763F826029B6FFE6C0537315BF01C1671029397DA737A5CD1F13F3ECB769D8265BE0148B22DD5FECCA1E7763E837C3FAEC235F1CC2910F51BD05A647C39623EEC1514FA6C64C84804E23D63D0BED6A88A1C6D382EBCF04FD8574C92D662BAFB239EE7984E6D252AD85D3B0D94D040B6FCB4B5120A2E43AF54C11C59B3D4BB777B3E49714FBBF0169ABBDC0CF285F6C37E668966CB8BBA5083A5EBCD706CBED60455ED554794B03D5136AC555A272FD180D2B99B60AEC25096F33C70CF7B6E4ED89D781954B7D52DFB8A0CCD2A237D8693EF8B3236540678ACEEDAC2A621B88B1A478BAB068ADB7CC8A037F8723B89E0FDFFAAD73F5D77007FCF04DB358393A7DC6DF42DCB4EBB853B77D27FFD7A616B9354ED0707431776FE294BAE152689DEE19B18902356B801EC7A760C2075998D6C6AF8CA1D59CB1D294CBA7490D5F54E0997202F4F4298AD554E28FF788093407E005600A35BA4B172B1D141D956965ED477C2EE1F808B45DE3517D66E969F17D8F5C0F4CA8F64F3912E9E8E8E11D3939EEC5CD6E6FB8D1090E65531BD570108A73A0268D370C51D41FF38B96475BE85EFF412B573F998D03C4741F3095ABEB13AC750147D76DF8375DFE62DC289496C8B8C9D692D5034AD7D514EBC3CD05B0ED0B7261823CEF3DFEA3D4324F1E1F5AD0172220225EECF3FC23786D75F1143117275CCDC3F5182C6CD7D194F9F943E0E0D4C64353442E9C0D06584A7D641DA03641E474E48CA631BEDB233526F7B889425561B48D5645BBB2E53CFC32A40771B6A12D0A2A6E0034666F2DBE47E30CE1FD5949963D2A779B02B886E186E20A31ECC948E4BF19E3D206760613F9577D9BC1FC02D68D2AB09C1EA756175FDD76A372E87FF4A9E79AAEE681D79697ED27803F8E6A9E41B92A0F6F239CA72F88F8414F758E98A48A1C0BC30FCF49EC2615F831C0E99E1B72931806D328F3
-20200426180855 2 6 100 8191 2 FDD2FF1B0B2402FB6FD5FBC2AF7553A3418C2535DFBF5CDB078CEA3D7C44A4863229766D19871460787A24C249D14845D5332DC7B153C10DF45AEBDC462929E786B8384FF62EC1CB99A79928B0EDB9845107488A06141112F534054013B3AA4DC1B2FE160ABA2E8670A0FB7B835D57BF99D5E7474161517D4149677B3BA24D68831195F8EF4145CB44B0FBDB37BF1B36A0B6F517F145FCC7C169C41A0E3A8A313E455A377E5D82B82608EEB14A5E7C5F4E9AA8E5315D1C600077B5F2F50022E2AEEE142E09DD25363862BAE1AF0D37B00C0D824B25C2B579524577AABB5C82452BE70C9AE8D65E935E087A70892E00544BAD691FE677C577917CC495D470E5301A9F75F019268DD8A9ED8F89EE35F6DABECE4507627691A666E86B98578FD03A7AC198728F7BA4348ECF3A61BAA4AD99DA46F97EA9773F1B9ACAA71EE30435E7A82F081C9D0B16495E96645626637CB97BDB4E7932763F826029B6FFE6C0537315BF01C1671029397DA737A5CD1F13F3ECB769D8265BE0148B22DD5FECCA1E7763E837C3FAEC235F1CC2910F51BD05A647C39623EEC1514FA6C64C84804E23D63D0BED6A88A1C6D382EBCF04FD8574C92D662BAFB239EE7984E6D252AD85D3B0D94D040B6FCB4B5120A2E43AF54C11C59B3D4BB777B3E49714FBBF0169ABBDC0CF285F6C37E668966CB8BBA5083A5EBCD706CBED60455ED554794B03D5136AC555A272FD180D2B99B60AEC25096F33C70CF7B6E4ED89D781954B7D52DFB8A0CCD2A237D8693EF8B3236540678ACEEDAC2A621B88B1A478BAB068ADB7CC8A037F8723B89E0FDFFAAD73F5D77007FCF04DB358393A7DC6DF42DCB4EBB853B77D27FFD7A616B9354ED0707431776FE294BAE152689DEE19B18902356B801EC7A760C2075998D6C6AF8CA1D59CB1D294CBA7490D5F54E0997202F4F4298AD554E28FF788093407E005600A35BA4B172B1D141D956965ED477C2EE1F808B45DE3517D66E969F17D8F5C0F4CA8F64F3912E9E8E8E11D3939EEC5CD6E6FB8D1090E65531BD570108A73A0268D370C51D41FF38B96475BE85EFF412B573F998D03C4741F3095ABEB13AC750147D76DF8375DFE62DC289496C8B8C9D692D5034AD7D514EBC3CD05B0ED0B7261823CEF3DFEA3D4324F1E1F5AD0172220225EECF3FC23786D75F1143117275CCDC3F5182C6CD7D194F9F943E0E0D4C64353442E9C0D06584A7D641DA03641E474E48CA631BEDB233526F7B889425561B48D5645BBB2E53CFC32A40771B6A12D0A2A6E0034666F2DBE47E30CE1FD5949963D2A779B02B886E186E20A31ECC948E4BF19E3D206760613F9577D9BC1FC02D68D2AB09C1EA756175FDD76A372E87FF4A9E79AAEE681D79697ED27803F8E6A9E41B92A0F6F239CA72F88F8414F758E98A48A1C0BC30FCF49EC2615F831C0E99E1B72931808041373
-20200426210432 2 6 100 8191 2 FDD2FF1B0B2402FB6FD5FBC2AF7553A3418C2535DFBF5CDB078CEA3D7C44A4863229766D19871460787A24C249D14845D5332DC7B153C10DF45AEBDC462929E786B8384FF62EC1CB99A79928B0EDB9845107488A06141112F534054013B3AA4DC1B2FE160ABA2E8670A0FB7B835D57BF99D5E7474161517D4149677B3BA24D68831195F8EF4145CB44B0FBDB37BF1B36A0B6F517F145FCC7C169C41A0E3A8A313E455A377E5D82B82608EEB14A5E7C5F4E9AA8E5315D1C600077B5F2F50022E2AEEE142E09DD25363862BAE1AF0D37B00C0D824B25C2B579524577AABB5C82452BE70C9AE8D65E935E087A70892E00544BAD691FE677C577917CC495D470E5301A9F75F019268DD8A9ED8F89EE35F6DABECE4507627691A666E86B98578FD03A7AC198728F7BA4348ECF3A61BAA4AD99DA46F97EA9773F1B9ACAA71EE30435E7A82F081C9D0B16495E96645626637CB97BDB4E7932763F826029B6FFE6C0537315BF01C1671029397DA737A5CD1F13F3ECB769D8265BE0148B22DD5FECCA1E7763E837C3FAEC235F1CC2910F51BD05A647C39623EEC1514FA6C64C84804E23D63D0BED6A88A1C6D382EBCF04FD8574C92D662BAFB239EE7984E6D252AD85D3B0D94D040B6FCB4B5120A2E43AF54C11C59B3D4BB777B3E49714FBBF0169ABBDC0CF285F6C37E668966CB8BBA5083A5EBCD706CBED60455ED554794B03D5136AC555A272FD180D2B99B60AEC25096F33C70CF7B6E4ED89D781954B7D52DFB8A0CCD2A237D8693EF8B3236540678ACEEDAC2A621B88B1A478BAB068ADB7CC8A037F8723B89E0FDFFAAD73F5D77007FCF04DB358393A7DC6DF42DCB4EBB853B77D27FFD7A616B9354ED0707431776FE294BAE152689DEE19B18902356B801EC7A760C2075998D6C6AF8CA1D59CB1D294CBA7490D5F54E0997202F4F4298AD554E28FF788093407E005600A35BA4B172B1D141D956965ED477C2EE1F808B45DE3517D66E969F17D8F5C0F4CA8F64F3912E9E8E8E11D3939EEC5CD6E6FB8D1090E65531BD570108A73A0268D370C51D41FF38B96475BE85EFF412B573F998D03C4741F3095ABEB13AC750147D76DF8375DFE62DC289496C8B8C9D692D5034AD7D514EBC3CD05B0ED0B7261823CEF3DFEA3D4324F1E1F5AD0172220225EECF3FC23786D75F1143117275CCDC3F5182C6CD7D194F9F943E0E0D4C64353442E9C0D06584A7D641DA03641E474E48CA631BEDB233526F7B889425561B48D5645BBB2E53CFC32A40771B6A12D0A2A6E0034666F2DBE47E30CE1FD5949963D2A779B02B886E186E20A31ECC948E4BF19E3D206760613F9577D9BC1FC02D68D2AB09C1EA756175FDD76A372E87FF4A9E79AAEE681D79697ED27803F8E6A9E41B92A0F6F239CA72F88F8414F758E98A48A1C0BC30FCF49EC2615F831C0E99E1B729318097002B3
-20200427001200 2 6 100 8191 2 FDD2FF1B0B2402FB6FD5FBC2AF7553A3418C2535DFBF5CDB078CEA3D7C44A4863229766D19871460787A24C249D14845D5332DC7B153C10DF45AEBDC462929E786B8384FF62EC1CB99A79928B0EDB9845107488A06141112F534054013B3AA4DC1B2FE160ABA2E8670A0FB7B835D57BF99D5E7474161517D4149677B3BA24D68831195F8EF4145CB44B0FBDB37BF1B36A0B6F517F145FCC7C169C41A0E3A8A313E455A377E5D82B82608EEB14A5E7C5F4E9AA8E5315D1C600077B5F2F50022E2AEEE142E09DD25363862BAE1AF0D37B00C0D824B25C2B579524577AABB5C82452BE70C9AE8D65E935E087A70892E00544BAD691FE677C577917CC495D470E5301A9F75F019268DD8A9ED8F89EE35F6DABECE4507627691A666E86B98578FD03A7AC198728F7BA4348ECF3A61BAA4AD99DA46F97EA9773F1B9ACAA71EE30435E7A82F081C9D0B16495E96645626637CB97BDB4E7932763F826029B6FFE6C0537315BF01C1671029397DA737A5CD1F13F3ECB769D8265BE0148B22DD5FECCA1E7763E837C3FAEC235F1CC2910F51BD05A647C39623EEC1514FA6C64C84804E23D63D0BED6A88A1C6D382EBCF04FD8574C92D662BAFB239EE7984E6D252AD85D3B0D94D040B6FCB4B5120A2E43AF54C11C59B3D4BB777B3E49714FBBF0169ABBDC0CF285F6C37E668966CB8BBA5083A5EBCD706CBED60455ED554794B03D5136AC555A272FD180D2B99B60AEC25096F33C70CF7B6E4ED89D781954B7D52DFB8A0CCD2A237D8693EF8B3236540678ACEEDAC2A621B88B1A478BAB068ADB7CC8A037F8723B89E0FDFFAAD73F5D77007FCF04DB358393A7DC6DF42DCB4EBB853B77D27FFD7A616B9354ED0707431776FE294BAE152689DEE19B18902356B801EC7A760C2075998D6C6AF8CA1D59CB1D294CBA7490D5F54E0997202F4F4298AD554E28FF788093407E005600A35BA4B172B1D141D956965ED477C2EE1F808B45DE3517D66E969F17D8F5C0F4CA8F64F3912E9E8E8E11D3939EEC5CD6E6FB8D1090E65531BD570108A73A0268D370C51D41FF38B96475BE85EFF412B573F998D03C4741F3095ABEB13AC750147D76DF8375DFE62DC289496C8B8C9D692D5034AD7D514EBC3CD05B0ED0B7261823CEF3DFEA3D4324F1E1F5AD0172220225EECF3FC23786D75F1143117275CCDC3F5182C6CD7D194F9F943E0E0D4C64353442E9C0D06584A7D641DA03641E474E48CA631BEDB233526F7B889425561B48D5645BBB2E53CFC32A40771B6A12D0A2A6E0034666F2DBE47E30CE1FD5949963D2A779B02B886E186E20A31ECC948E4BF19E3D206760613F9577D9BC1FC02D68D2AB09C1EA756175FDD76A372E87FF4A9E79AAEE681D79697ED27803F8E6A9E41B92A0F6F239CA72F88F8414F758E98A48A1C0BC30FCF49EC2615F831C0E99E1B7293180AEDF073
-20200427034737 2 6 100 8191 5 FDD2FF1B0B2402FB6FD5FBC2AF7553A3418C2535DFBF5CDB078CEA3D7C44A4863229766D19871460787A24C249D14845D5332DC7B153C10DF45AEBDC462929E786B8384FF62EC1CB99A79928B0EDB9845107488A06141112F534054013B3AA4DC1B2FE160ABA2E8670A0FB7B835D57BF99D5E7474161517D4149677B3BA24D68831195F8EF4145CB44B0FBDB37BF1B36A0B6F517F145FCC7C169C41A0E3A8A313E455A377E5D82B82608EEB14A5E7C5F4E9AA8E5315D1C600077B5F2F50022E2AEEE142E09DD25363862BAE1AF0D37B00C0D824B25C2B579524577AABB5C82452BE70C9AE8D65E935E087A70892E00544BAD691FE677C577917CC495D470E5301A9F75F019268DD8A9ED8F89EE35F6DABECE4507627691A666E86B98578FD03A7AC198728F7BA4348ECF3A61BAA4AD99DA46F97EA9773F1B9ACAA71EE30435E7A82F081C9D0B16495E96645626637CB97BDB4E7932763F826029B6FFE6C0537315BF01C1671029397DA737A5CD1F13F3ECB769D8265BE0148B22DD5FECCA1E7763E837C3FAEC235F1CC2910F51BD05A647C39623EEC1514FA6C64C84804E23D63D0BED6A88A1C6D382EBCF04FD8574C92D662BAFB239EE7984E6D252AD85D3B0D94D040B6FCB4B5120A2E43AF54C11C59B3D4BB777B3E49714FBBF0169ABBDC0CF285F6C37E668966CB8BBA5083A5EBCD706CBED60455ED554794B03D5136AC555A272FD180D2B99B60AEC25096F33C70CF7B6E4ED89D781954B7D52DFB8A0CCD2A237D8693EF8B3236540678ACEEDAC2A621B88B1A478BAB068ADB7CC8A037F8723B89E0FDFFAAD73F5D77007FCF04DB358393A7DC6DF42DCB4EBB853B77D27FFD7A616B9354ED0707431776FE294BAE152689DEE19B18902356B801EC7A760C2075998D6C6AF8CA1D59CB1D294CBA7490D5F54E0997202F4F4298AD554E28FF788093407E005600A35BA4B172B1D141D956965ED477C2EE1F808B45DE3517D66E969F17D8F5C0F4CA8F64F3912E9E8E8E11D3939EEC5CD6E6FB8D1090E65531BD570108A73A0268D370C51D41FF38B96475BE85EFF412B573F998D03C4741F3095ABEB13AC750147D76DF8375DFE62DC289496C8B8C9D692D5034AD7D514EBC3CD05B0ED0B7261823CEF3DFEA3D4324F1E1F5AD0172220225EECF3FC23786D75F1143117275CCDC3F5182C6CD7D194F9F943E0E0D4C64353442E9C0D06584A7D641DA03641E474E48CA631BEDB233526F7B889425561B48D5645BBB2E53CFC32A40771B6A12D0A2A6E0034666F2DBE47E30CE1FD5949963D2A779B02B886E186E20A31ECC948E4BF19E3D206760613F9577D9BC1FC02D68D2AB09C1EA756175FDD76A372E87FF4A9E79AAEE681D79697ED27803F8E6A9E41B92A0F6F239CA72F88F8414F758E98A48A1C0BC30FCF49EC2615F831C0E99E1B7293180CA6F67F
-20200427122056 2 6 100 8191 5 FDD2FF1B0B2402FB6FD5FBC2AF7553A3418C2535DFBF5CDB078CEA3D7C44A4863229766D19871460787A24C249D14845D5332DC7B153C10DF45AEBDC462929E786B8384FF62EC1CB99A79928B0EDB9845107488A06141112F534054013B3AA4DC1B2FE160ABA2E8670A0FB7B835D57BF99D5E7474161517D4149677B3BA24D68831195F8EF4145CB44B0FBDB37BF1B36A0B6F517F145FCC7C169C41A0E3A8A313E455A377E5D82B82608EEB14A5E7C5F4E9AA8E5315D1C600077B5F2F50022E2AEEE142E09DD25363862BAE1AF0D37B00C0D824B25C2B579524577AABB5C82452BE70C9AE8D65E935E087A70892E00544BAD691FE677C577917CC495D470E5301A9F75F019268DD8A9ED8F89EE35F6DABECE4507627691A666E86B98578FD03A7AC198728F7BA4348ECF3A61BAA4AD99DA46F97EA9773F1B9ACAA71EE30435E7A82F081C9D0B16495E96645626637CB97BDB4E7932763F826029B6FFE6C0537315BF01C1671029397DA737A5CD1F13F3ECB769D8265BE0148B22DD5FECCA1E7763E837C3FAEC235F1CC2910F51BD05A647C39623EEC1514FA6C64C84804E23D63D0BED6A88A1C6D382EBCF04FD8574C92D662BAFB239EE7984E6D252AD85D3B0D94D040B6FCB4B5120A2E43AF54C11C59B3D4BB777B3E49714FBBF0169ABBDC0CF285F6C37E668966CB8BBA5083A5EBCD706CBED60455ED554794B03D5136AC555A272FD180D2B99B60AEC25096F33C70CF7B6E4ED89D781954B7D52DFB8A0CCD2A237D8693EF8B3236540678ACEEDAC2A621B88B1A478BAB068ADB7CC8A037F8723B89E0FDFFAAD73F5D77007FCF04DB358393A7DC6DF42DCB4EBB853B77D27FFD7A616B9354ED0707431776FE294BAE152689DEE19B18902356B801EC7A760C2075998D6C6AF8CA1D59CB1D294CBA7490D5F54E0997202F4F4298AD554E28FF788093407E005600A35BA4B172B1D141D956965ED477C2EE1F808B45DE3517D66E969F17D8F5C0F4CA8F64F3912E9E8E8E11D3939EEC5CD6E6FB8D1090E65531BD570108A73A0268D370C51D41FF38B96475BE85EFF412B573F998D03C4741F3095ABEB13AC750147D76DF8375DFE62DC289496C8B8C9D692D5034AD7D514EBC3CD05B0ED0B7261823CEF3DFEA3D4324F1E1F5AD0172220225EECF3FC23786D75F1143117275CCDC3F5182C6CD7D194F9F943E0E0D4C64353442E9C0D06584A7D641DA03641E474E48CA631BEDB233526F7B889425561B48D5645BBB2E53CFC32A40771B6A12D0A2A6E0034666F2DBE47E30CE1FD5949963D2A779B02B886E186E20A31ECC948E4BF19E3D206760613F9577D9BC1FC02D68D2AB09C1EA756175FDD76A372E87FF4A9E79AAEE681D79697ED27803F8E6A9E41B92A0F6F239CA72F88F8414F758E98A48A1C0BC30FCF49EC2615F831C0E99E1B729318110CCF9F
-20200427185846 2 6 100 8191 2 FDD2FF1B0B2402FB6FD5FBC2AF7553A3418C2535DFBF5CDB078CEA3D7C44A4863229766D19871460787A24C249D14845D5332DC7B153C10DF45AEBDC462929E786B8384FF62EC1CB99A79928B0EDB9845107488A06141112F534054013B3AA4DC1B2FE160ABA2E8670A0FB7B835D57BF99D5E7474161517D4149677B3BA24D68831195F8EF4145CB44B0FBDB37BF1B36A0B6F517F145FCC7C169C41A0E3A8A313E455A377E5D82B82608EEB14A5E7C5F4E9AA8E5315D1C600077B5F2F50022E2AEEE142E09DD25363862BAE1AF0D37B00C0D824B25C2B579524577AABB5C82452BE70C9AE8D65E935E087A70892E00544BAD691FE677C577917CC495D470E5301A9F75F019268DD8A9ED8F89EE35F6DABECE4507627691A666E86B98578FD03A7AC198728F7BA4348ECF3A61BAA4AD99DA46F97EA9773F1B9ACAA71EE30435E7A82F081C9D0B16495E96645626637CB97BDB4E7932763F826029B6FFE6C0537315BF01C1671029397DA737A5CD1F13F3ECB769D8265BE0148B22DD5FECCA1E7763E837C3FAEC235F1CC2910F51BD05A647C39623EEC1514FA6C64C84804E23D63D0BED6A88A1C6D382EBCF04FD8574C92D662BAFB239EE7984E6D252AD85D3B0D94D040B6FCB4B5120A2E43AF54C11C59B3D4BB777B3E49714FBBF0169ABBDC0CF285F6C37E668966CB8BBA5083A5EBCD706CBED60455ED554794B03D5136AC555A272FD180D2B99B60AEC25096F33C70CF7B6E4ED89D781954B7D52DFB8A0CCD2A237D8693EF8B3236540678ACEEDAC2A621B88B1A478BAB068ADB7CC8A037F8723B89E0FDFFAAD73F5D77007FCF04DB358393A7DC6DF42DCB4EBB853B77D27FFD7A616B9354ED0707431776FE294BAE152689DEE19B18902356B801EC7A760C2075998D6C6AF8CA1D59CB1D294CBA7490D5F54E0997202F4F4298AD554E28FF788093407E005600A35BA4B172B1D141D956965ED477C2EE1F808B45DE3517D66E969F17D8F5C0F4CA8F64F3912E9E8E8E11D3939EEC5CD6E6FB8D1090E65531BD570108A73A0268D370C51D41FF38B96475BE85EFF412B573F998D03C4741F3095ABEB13AC750147D76DF8375DFE62DC289496C8B8C9D692D5034AD7D514EBC3CD05B0ED0B7261823CEF3DFEA3D4324F1E1F5AD0172220225EECF3FC23786D75F1143117275CCDC3F5182C6CD7D194F9F943E0E0D4C64353442E9C0D06584A7D641DA03641E474E48CA631BEDB233526F7B889425561B48D5645BBB2E53CFC32A40771B6A12D0A2A6E0034666F2DBE47E30CE1FD5949963D2A779B02B886E186E20A31ECC948E4BF19E3D206760613F9577D9BC1FC02D68D2AB09C1EA756175FDD76A372E87FF4A9E79AAEE681D79697ED27803F8E6A9E41B92A0F6F239CA72F88F8414F758E98A48A1C0BC30FCF49EC2615F831C0E99E1B729318146CBE53
-20200428235601 2 6 100 8191 5 FDD2FF1B0B2402FB6FD5FBC2AF7553A3418C2535DFBF5CDB078CEA3D7C44A4863229766D19871460787A24C249D14845D5332DC7B153C10DF45AEBDC462929E786B8384FF62EC1CB99A79928B0EDB9845107488A06141112F534054013B3AA4DC1B2FE160ABA2E8670A0FB7B835D57BF99D5E7474161517D4149677B3BA24D68831195F8EF4145CB44B0FBDB37BF1B36A0B6F517F145FCC7C169C41A0E3A8A313E455A377E5D82B82608EEB14A5E7C5F4E9AA8E5315D1C600077B5F2F50022E2AEEE142E09DD25363862BAE1AF0D37B00C0D824B25C2B579524577AABB5C82452BE70C9AE8D65E935E087A70892E00544BAD691FE677C577917CC495D470E5301A9F75F019268DD8A9ED8F89EE35F6DABECE4507627691A666E86B98578FD03A7AC198728F7BA4348ECF3A61BAA4AD99DA46F97EA9773F1B9ACAA71EE30435E7A82F081C9D0B16495E96645626637CB97BDB4E7932763F826029B6FFE6C0537315BF01C1671029397DA737A5CD1F13F3ECB769D8265BE0148B22DD5FECCA1E7763E837C3FAEC235F1CC2910F51BD05A647C39623EEC1514FA6C64C84804E23D63D0BED6A88A1C6D382EBCF04FD8574C92D662BAFB239EE7984E6D252AD85D3B0D94D040B6FCB4B5120A2E43AF54C11C59B3D4BB777B3E49714FBBF0169ABBDC0CF285F6C37E668966CB8BBA5083A5EBCD706CBED60455ED554794B03D5136AC555A272FD180D2B99B60AEC25096F33C70CF7B6E4ED89D781954B7D52DFB8A0CCD2A237D8693EF8B3236540678ACEEDAC2A621B88B1A478BAB068ADB7CC8A037F8723B89E0FDFFAAD73F5D77007FCF04DB358393A7DC6DF42DCB4EBB853B77D27FFD7A616B9354ED0707431776FE294BAE152689DEE19B18902356B801EC7A760C2075998D6C6AF8CA1D59CB1D294CBA7490D5F54E0997202F4F4298AD554E28FF788093407E005600A35BA4B172B1D141D956965ED477C2EE1F808B45DE3517D66E969F17D8F5C0F4CA8F64F3912E9E8E8E11D3939EEC5CD6E6FB8D1090E65531BD570108A73A0268D370C51D41FF38B96475BE85EFF412B573F998D03C4741F3095ABEB13AC750147D76DF8375DFE62DC289496C8B8C9D692D5034AD7D514EBC3CD05B0ED0B7261823CEF3DFEA3D4324F1E1F5AD0172220225EECF3FC23786D75F1143117275CCDC3F5182C6CD7D194F9F943E0E0D4C64353442E9C0D06584A7D641DA03641E474E48CA631BEDB233526F7B889425561B48D5645BBB2E53CFC32A40771B6A12D0A2A6E0034666F2DBE47E30CE1FD5949963D2A779B02B886E186E20A31ECC948E4BF19E3D206760613F9577D9BC1FC02D68D2AB09C1EA756175FDD76A372E87FF4A9E79AAEE681D79697ED27803F8E6A9E41B92A0F6F239CA72F88F8414F758E98A48A1C0BC30FCF49EC2615F831C0E99E1B729318232A7227
-20200429061301 2 6 100 8191 2 FDD2FF1B0B2402FB6FD5FBC2AF7553A3418C2535DFBF5CDB078CEA3D7C44A4863229766D19871460787A24C249D14845D5332DC7B153C10DF45AEBDC462929E786B8384FF62EC1CB99A79928B0EDB9845107488A06141112F534054013B3AA4DC1B2FE160ABA2E8670A0FB7B835D57BF99D5E7474161517D4149677B3BA24D68831195F8EF4145CB44B0FBDB37BF1B36A0B6F517F145FCC7C169C41A0E3A8A313E455A377E5D82B82608EEB14A5E7C5F4E9AA8E5315D1C600077B5F2F50022E2AEEE142E09DD25363862BAE1AF0D37B00C0D824B25C2B579524577AABB5C82452BE70C9AE8D65E935E087A70892E00544BAD691FE677C577917CC495D470E5301A9F75F019268DD8A9ED8F89EE35F6DABECE4507627691A666E86B98578FD03A7AC198728F7BA4348ECF3A61BAA4AD99DA46F97EA9773F1B9ACAA71EE30435E7A82F081C9D0B16495E96645626637CB97BDB4E7932763F826029B6FFE6C0537315BF01C1671029397DA737A5CD1F13F3ECB769D8265BE0148B22DD5FECCA1E7763E837C3FAEC235F1CC2910F51BD05A647C39623EEC1514FA6C64C84804E23D63D0BED6A88A1C6D382EBCF04FD8574C92D662BAFB239EE7984E6D252AD85D3B0D94D040B6FCB4B5120A2E43AF54C11C59B3D4BB777B3E49714FBBF0169ABBDC0CF285F6C37E668966CB8BBA5083A5EBCD706CBED60455ED554794B03D5136AC555A272FD180D2B99B60AEC25096F33C70CF7B6E4ED89D781954B7D52DFB8A0CCD2A237D8693EF8B3236540678ACEEDAC2A621B88B1A478BAB068ADB7CC8A037F8723B89E0FDFFAAD73F5D77007FCF04DB358393A7DC6DF42DCB4EBB853B77D27FFD7A616B9354ED0707431776FE294BAE152689DEE19B18902356B801EC7A760C2075998D6C6AF8CA1D59CB1D294CBA7490D5F54E0997202F4F4298AD554E28FF788093407E005600A35BA4B172B1D141D956965ED477C2EE1F808B45DE3517D66E969F17D8F5C0F4CA8F64F3912E9E8E8E11D3939EEC5CD6E6FB8D1090E65531BD570108A73A0268D370C51D41FF38B96475BE85EFF412B573F998D03C4741F3095ABEB13AC750147D76DF8375DFE62DC289496C8B8C9D692D5034AD7D514EBC3CD05B0ED0B7261823CEF3DFEA3D4324F1E1F5AD0172220225EECF3FC23786D75F1143117275CCDC3F5182C6CD7D194F9F943E0E0D4C64353442E9C0D06584A7D641DA03641E474E48CA631BEDB233526F7B889425561B48D5645BBB2E53CFC32A40771B6A12D0A2A6E0034666F2DBE47E30CE1FD5949963D2A779B02B886E186E20A31ECC948E4BF19E3D206760613F9577D9BC1FC02D68D2AB09C1EA756175FDD76A372E87FF4A9E79AAEE681D79697ED27803F8E6A9E41B92A0F6F239CA72F88F8414F758E98A48A1C0BC30FCF49EC2615F831C0E99E1B729318265D253B
-20200429125635 2 6 100 8191 5 FDD2FF1B0B2402FB6FD5FBC2AF7553A3418C2535DFBF5CDB078CEA3D7C44A4863229766D19871460787A24C249D14845D5332DC7B153C10DF45AEBDC462929E786B8384FF62EC1CB99A79928B0EDB9845107488A06141112F534054013B3AA4DC1B2FE160ABA2E8670A0FB7B835D57BF99D5E7474161517D4149677B3BA24D68831195F8EF4145CB44B0FBDB37BF1B36A0B6F517F145FCC7C169C41A0E3A8A313E455A377E5D82B82608EEB14A5E7C5F4E9AA8E5315D1C600077B5F2F50022E2AEEE142E09DD25363862BAE1AF0D37B00C0D824B25C2B579524577AABB5C82452BE70C9AE8D65E935E087A70892E00544BAD691FE677C577917CC495D470E5301A9F75F019268DD8A9ED8F89EE35F6DABECE4507627691A666E86B98578FD03A7AC198728F7BA4348ECF3A61BAA4AD99DA46F97EA9773F1B9ACAA71EE30435E7A82F081C9D0B16495E96645626637CB97BDB4E7932763F826029B6FFE6C0537315BF01C1671029397DA737A5CD1F13F3ECB769D8265BE0148B22DD5FECCA1E7763E837C3FAEC235F1CC2910F51BD05A647C39623EEC1514FA6C64C84804E23D63D0BED6A88A1C6D382EBCF04FD8574C92D662BAFB239EE7984E6D252AD85D3B0D94D040B6FCB4B5120A2E43AF54C11C59B3D4BB777B3E49714FBBF0169ABBDC0CF285F6C37E668966CB8BBA5083A5EBCD706CBED60455ED554794B03D5136AC555A272FD180D2B99B60AEC25096F33C70CF7B6E4ED89D781954B7D52DFB8A0CCD2A237D8693EF8B3236540678ACEEDAC2A621B88B1A478BAB068ADB7CC8A037F8723B89E0FDFFAAD73F5D77007FCF04DB358393A7DC6DF42DCB4EBB853B77D27FFD7A616B9354ED0707431776FE294BAE152689DEE19B18902356B801EC7A760C2075998D6C6AF8CA1D59CB1D294CBA7490D5F54E0997202F4F4298AD554E28FF788093407E005600A35BA4B172B1D141D956965ED477C2EE1F808B45DE3517D66E969F17D8F5C0F4CA8F64F3912E9E8E8E11D3939EEC5CD6E6FB8D1090E65531BD570108A73A0268D370C51D41FF38B96475BE85EFF412B573F998D03C4741F3095ABEB13AC750147D76DF8375DFE62DC289496C8B8C9D692D5034AD7D514EBC3CD05B0ED0B7261823CEF3DFEA3D4324F1E1F5AD0172220225EECF3FC23786D75F1143117275CCDC3F5182C6CD7D194F9F943E0E0D4C64353442E9C0D06584A7D641DA03641E474E48CA631BEDB233526F7B889425561B48D5645BBB2E53CFC32A40771B6A12D0A2A6E0034666F2DBE47E30CE1FD5949963D2A779B02B886E186E20A31ECC948E4BF19E3D206760613F9577D9BC1FC02D68D2AB09C1EA756175FDD76A372E87FF4A9E79AAEE681D79697ED27803F8E6A9E41B92A0F6F239CA72F88F8414F758E98A48A1C0BC30FCF49EC2615F831C0E99E1B72931829B70597
+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/moduli.0 b/moduli.0
index dbbac1830..15d7899ff 100644
--- a/moduli.0
+++ b/moduli.0
@@ -71,4 +71,4 @@ STANDARDS
the Secure Shell (SSH) Transport Layer Protocol, RFC 4419, March 2006,
2006.
-OpenBSD 6.8 September 26, 2012 OpenBSD 6.8
+OpenBSD 6.9 September 26, 2012 OpenBSD 6.9
diff --git a/monitor.c b/monitor.c
index 4cf79dfc9..74c803e15 100644
--- a/monitor.c
+++ b/monitor.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: monitor.c,v 1.214 2020/08/27 01:07:09 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>
@@ -104,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? */
@@ -121,8 +120,6 @@ 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_skeyquery(struct ssh *, int, struct sshbuf *);
-int mm_answer_skeyrespond(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 *);
@@ -160,7 +157,7 @@ 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;
@@ -309,8 +306,7 @@ monitor_child_preauth(struct ssh *ssh, struct monitor *pmonitor)
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;
}
@@ -318,8 +314,8 @@ monitor_child_preauth(struct ssh *ssh, 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;
@@ -352,12 +348,11 @@ monitor_child_preauth(struct ssh *ssh, 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);
@@ -420,47 +415,47 @@ 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);
@@ -486,7 +481,7 @@ monitor_read(struct ssh *ssh, 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) {
/*
@@ -501,13 +496,13 @@ monitor_read(struct ssh *ssh, 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)
@@ -517,15 +512,13 @@ monitor_read(struct ssh *ssh, struct monitor *pmonitor, struct mon_table *ent,
if (ent->f != NULL) {
if (!(ent->flags & MON_PERMIT))
- fatal("%s: unpermitted request %d", __func__,
- type);
+ 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;
}
@@ -535,7 +528,7 @@ monitor_read(struct ssh *ssh, 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);
@@ -580,21 +573,19 @@ mm_answer_moduli(struct ssh *ssh, 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 */
@@ -602,7 +593,7 @@ mm_answer_moduli(struct ssh *ssh, 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);
}
@@ -624,15 +615,15 @@ mm_answer_sign(struct ssh *ssh, 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),
@@ -651,21 +642,20 @@ mm_answer_sign(struct ssh *ssh, 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;
}
@@ -680,24 +670,21 @@ mm_answer_sign(struct ssh *ssh, int sock, struct sshbuf *m)
if ((key = get_hostkey_by_index(keyid)) != NULL) {
if ((r = sshkey_sign(key, &signature, &siglen, p, datlen, alg,
options.sk_provider, NULL, compat)) != 0)
- fatal("%s: sshkey_sign failed: %s",
- __func__, ssh_err(r));
+ 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 ? "hostkey proof" : "KEX", 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);
@@ -711,8 +698,14 @@ mm_answer_sign(struct ssh *ssh, 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(struct ssh *ssh, int sock, struct sshbuf *m)
{
@@ -721,13 +714,13 @@ mm_answer_pwnamallow(struct ssh *ssh, int sock, struct sshbuf *m)
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(ssh, username);
@@ -739,7 +732,7 @@ mm_answer_pwnamallow(struct ssh *ssh, 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;
}
@@ -748,10 +741,18 @@ mm_answer_pwnamallow(struct ssh *ssh, 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 ||
@@ -761,26 +762,23 @@ mm_answer_pwnamallow(struct ssh *ssh, 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 */
@@ -795,10 +793,10 @@ mm_answer_pwnamallow(struct ssh *ssh, 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 */
@@ -821,7 +819,7 @@ int mm_answer_auth2_read_banner(struct ssh *ssh, 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);
@@ -837,9 +835,8 @@ mm_answer_authserv(struct ssh *ssh, 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);
@@ -887,9 +884,9 @@ mm_answer_authpassword(struct ssh *ssh, int sock, struct sshbuf *m)
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);
@@ -897,13 +894,14 @@ mm_answer_authpassword(struct ssh *ssh, int sock, struct sshbuf *m)
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++;
@@ -926,19 +924,19 @@ mm_answer_bsdauthquery(struct ssh *ssh, 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) {
@@ -958,23 +956,23 @@ mm_answer_bsdauthrespond(struct ssh *ssh, int sock, struct sshbuf *m)
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";
@@ -1153,25 +1151,23 @@ mm_answer_keyallowed(struct ssh *ssh, int sock, struct sshbuf *m)
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:
@@ -1181,7 +1177,7 @@ mm_answer_keyallowed(struct ssh *ssh, int sock, struct sshbuf *m)
if (auth2_key_already_used(authctxt, key))
break;
if (!key_base_type_match(auth_method, key,
- options.pubkey_key_types))
+ options.pubkey_accepted_algos))
break;
allowed = user_key_allowed(ssh, authctxt->pw, key,
pubkey_auth_attempt, &opts);
@@ -1193,7 +1189,7 @@ mm_answer_keyallowed(struct ssh *ssh, int sock, struct sshbuf *m)
if (auth2_key_already_used(authctxt, key))
break;
if (!key_base_type_match(auth_method, key,
- options.hostbased_key_types))
+ options.hostbased_accepted_algos))
break;
allowed = hostbased_key_allowed(ssh, authctxt->pw,
cuser, chost, key);
@@ -1202,13 +1198,13 @@ mm_answer_keyallowed(struct ssh *ssh, int sock, struct sshbuf *m)
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");
@@ -1220,7 +1216,7 @@ mm_answer_keyallowed(struct ssh *ssh, 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;
@@ -1235,9 +1231,9 @@ mm_answer_keyallowed(struct ssh *ssh, 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)
@@ -1247,7 +1243,7 @@ mm_answer_keyallowed(struct ssh *ssh, int sock, struct sshbuf *m)
}
static int
-monitor_valid_userblob(const 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;
@@ -1257,9 +1253,9 @@ monitor_valid_userblob(const u_char *data, u_int datalen)
int r, fail = 0;
if ((b = sshbuf_from(data, datalen)) == NULL)
- fatal("%s: sshbuf_from", __func__);
+ 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) ||
@@ -1267,21 +1263,21 @@ monitor_valid_userblob(const 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 : "");
@@ -1294,17 +1290,17 @@ monitor_valid_userblob(const 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);
@@ -1323,9 +1319,9 @@ monitor_valid_hostbasedblob(const u_char *data, u_int datalen,
u_char type;
if ((b = sshbuf_from(data, datalen)) == NULL)
- fatal("%s: sshbuf_new", __func__);
+ fatal_f("sshbuf_new");
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) ||
@@ -1333,11 +1329,11 @@ monitor_valid_hostbasedblob(const u_char *data, u_int datalen,
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 : "");
@@ -1350,17 +1346,17 @@ monitor_valid_hostbasedblob(const 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(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)
@@ -1369,7 +1365,7 @@ monitor_valid_hostbasedblob(const u_char *data, u_int datalen,
/* 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);
@@ -1395,11 +1391,11 @@ mm_answer_keyverify(struct ssh *ssh, int sock, struct sshbuf *m)
(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') {
@@ -1409,11 +1405,11 @@ mm_answer_keyverify(struct ssh *ssh, 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:
@@ -1426,15 +1422,17 @@ mm_answer_keyverify(struct ssh *ssh, 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("%s: sshkey_fingerprint failed", __func__);
+ fatal_f("sshkey_fingerprint failed");
ret = sshkey_verify(key, signature, signaturelen, data, datalen,
sigalg, ssh->compat, &sig_details);
- debug3("%s: %s %p signature %s%s%s", __func__, auth_method, key,
+ debug3_f("%s %s signature %s%s%s", auth_method, sshkey_type(key),
(ret == 0) ? "verified" : "unverified",
(ret != 0) ? ": " : "", (ret != 0) ? ssh_err(ret) : "");
@@ -1478,11 +1476,11 @@ mm_answer_keyverify(struct ssh *ssh, int sock, struct sshbuf *m)
encoded_ret = (ret != 0);
if ((r = sshbuf_put_u32(m, encoded_ret)) != 0 ||
(r = sshbuf_put_u8(m, sig_details != NULL)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ 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("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "assemble sk");
}
sshkey_sig_details_free(sig_details);
mm_request_send(sock, MONITOR_ANS_KEYVERIFY, m);
@@ -1522,9 +1520,9 @@ mm_record_login(struct ssh *ssh, 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);
@@ -1537,7 +1535,7 @@ mm_answer_pty(struct ssh *ssh, int sock, struct sshbuf *m)
Session *s;
int r, res, fd0;
- debug3("%s entering", __func__);
+ debug3_f("entering");
sshbuf_reset(m);
s = session_new();
@@ -1553,11 +1551,11 @@ mm_answer_pty(struct ssh *ssh, 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(ssh, s, authctxt->pw);
@@ -1566,20 +1564,20 @@ mm_answer_pty(struct ssh *ssh, int sock, struct sshbuf *m)
/* 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)) == -1)
- fatal("%s: open(/dev/null): %s", __func__, strerror(errno));
+ 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 side of pty is not needed */
close(s->ttyfd);
@@ -1587,7 +1585,7 @@ mm_answer_pty(struct ssh *ssh, int sock, struct sshbuf *m)
/* 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);
@@ -1595,7 +1593,7 @@ mm_answer_pty(struct ssh *ssh, 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);
}
@@ -1607,10 +1605,10 @@ mm_answer_pty_cleanup(struct ssh *ssh, int sock, struct sshbuf *m)
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);
@@ -1624,7 +1622,7 @@ mm_answer_term(struct ssh *ssh, int sock, struct sshbuf *req)
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);
@@ -1706,33 +1704,39 @@ monitor_apply_keystate(struct ssh *ssh, struct monitor *pmonitor)
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] = 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;
+ 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] = kex_gen_server;
+ kex->kex[KEX_ECDH_SHA2] = kex_gen_server;
# endif
#endif /* WITH_OPENSSL */
- kex->kex[KEX_C25519_SHA256] = kex_gen_server;
- kex->kex[KEX_KEM_SNTRUP4591761X25519_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;
- }
+ 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 requires careful sanity checking */
@@ -1740,13 +1744,13 @@ monitor_apply_keystate(struct ssh *ssh, struct monitor *pmonitor)
void
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");
}
@@ -1766,7 +1770,7 @@ 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)) == -1)
error("setsockopt SO_ZEROIZE(0): %.100s", strerror(errno));
@@ -1780,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];
@@ -1819,10 +1823,10 @@ mm_answer_gss_setup_ctx(struct ssh *ssh, 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;
@@ -1832,7 +1836,7 @@ mm_answer_gss_setup_ctx(struct ssh *ssh, 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);
@@ -1852,10 +1856,10 @@ mm_answer_gss_accept_ctx(struct ssh *ssh, 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);
@@ -1863,7 +1867,7 @@ mm_answer_gss_accept_ctx(struct ssh *ssh, 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);
@@ -1884,11 +1888,11 @@ mm_answer_gss_checkmic(struct ssh *ssh, 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, &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);
@@ -1897,7 +1901,7 @@ mm_answer_gss_checkmic(struct ssh *ssh, 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);
@@ -1914,15 +1918,15 @@ mm_answer_gss_userok(struct ssh *ssh, int sock, struct sshbuf *m)
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/monitor_fdpass.c b/monitor_fdpass.c
index d766edcf1..a07727a8e 100644
--- a/monitor_fdpass.c
+++ b/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/monitor_wrap.c b/monitor_wrap.c
index 5e38d83eb..748333c75 100644
--- a/monitor_wrap.c
+++ b/monitor_wrap.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: monitor_wrap.c,v 1.118 2020/08/27 01:06:18 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,27 +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__);
+ fatal_f("MONITOR_ANS_MODULI failed");
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_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));
@@ -223,26 +223,35 @@ mm_sshkey_sign(struct ssh *ssh, struct sshkey *key, u_char **sigp, size_t *lenp,
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(struct ssh *ssh, const char *username)
{
@@ -255,20 +264,20 @@ mm_getpwnamallow(struct ssh *ssh, 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;
@@ -276,12 +285,14 @@ mm_getpwnamallow(struct ssh *ssh, 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
@@ -292,24 +303,21 @@ mm_getpwnamallow(struct ssh *ssh, 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 ? \
@@ -317,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 */
@@ -328,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);
@@ -343,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 */
@@ -372,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);
@@ -395,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);
}
@@ -447,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) {
@@ -502,31 +509,31 @@ mm_sshkey_verify(const struct sshkey *key, const u_char *sig, size_t siglen,
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 ||
(r = sshbuf_get_u8(m, &sig_details_present)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ 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("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "parse sig_details");
if (sig_detailsp != NULL) {
*sig_detailsp = xcalloc(1, sizeof(**sig_detailsp));
(*sig_detailsp)->sk_counter = counter;
@@ -548,12 +555,11 @@ mm_send_keystate(struct ssh *ssh, struct monitor *monitor)
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);
}
@@ -567,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)
@@ -578,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);
@@ -620,9 +626,9 @@ 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);
@@ -795,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);
}
@@ -821,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);
}
@@ -856,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);
@@ -924,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);
@@ -948,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;
}
@@ -977,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);
}
@@ -999,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/monitor_wrap.h b/monitor_wrap.h
index 0db38c206..a163b67d2 100644
--- a/monitor_wrap.h
+++ b/monitor_wrap.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: monitor_wrap.h,v 1.45 2020/08/27 01:06:18 djm Exp $ */
+/* $OpenBSD: monitor_wrap.h,v 1.47 2021/04/15 16:24:31 markus Exp $ */
/*
* Copyright 2002 Niels Provos <provos@citi.umich.edu>
@@ -40,7 +40,7 @@ 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);
diff --git a/msg.c b/msg.c
index 574a566e3..d22c4e477 100644
--- a/msg.c
+++ b/msg.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: msg.c,v 1.19 2020/06/24 15:08:53 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("%s: type %u", __func__, (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("%s: write: %s", __func__, strerror(errno));
+ error_f("write: %s", strerror(errno));
return (-1);
}
if (atomicio(vwrite, fd, sshbuf_mutable_ptr(m), mlen) != mlen) {
- error("%s: write: %s", __func__, strerror(errno));
+ 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("%s: read header: %s", __func__, strerror(errno));
+ error_f("read header: %s", strerror(errno));
return (-1);
}
msg_len = get_u32(buf);
if (msg_len > sshbuf_max_size(m)) {
- error("%s: read: bad msg_len %u", __func__, msg_len);
+ 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("%s: read: %s", __func__, strerror(errno));
+ error_f("read: %s", strerror(errno));
return (-1);
}
return (0);
diff --git a/mux.c b/mux.c
index 376f0d711..4c0eb4249 100644
--- a/mux.c
+++ b/mux.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: mux.c,v 1.83 2020/07/05 23:59:45 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>
*
@@ -71,9 +71,7 @@
/* 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;
@@ -194,13 +192,13 @@ 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;
@@ -216,19 +214,19 @@ 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)
@@ -251,7 +249,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;
}
@@ -273,21 +271,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 client 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) {
@@ -296,12 +294,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;
@@ -316,7 +313,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 */
@@ -328,7 +325,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
@@ -363,7 +360,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;
}
@@ -380,29 +377,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 client",
- __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++)
@@ -417,12 +413,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:
@@ -443,7 +439,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;
@@ -452,15 +448,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;
@@ -471,10 +459,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) {
@@ -484,8 +472,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);
@@ -503,13 +491,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;
}
@@ -518,13 +506,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;
@@ -556,7 +544,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",
@@ -568,7 +556,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;
}
@@ -615,11 +603,11 @@ mux_confirm_remote_forward(struct ssh *ssh, int type, u_int32_t seq, void *ctxt)
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,15 +615,14 @@ 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) {
if ((r = sshpkt_get_u32(ssh, &port)) != 0)
- fatal("%s: packet error: %s",
- __func__, ssh_err(r));
+ fatal_fr(r, "parse port");
if (port > 65535) {
fatal("Invalid allocated port %u for "
"mux remote forward to %s:%d", port,
@@ -650,9 +637,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);
}
@@ -667,8 +654,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);
@@ -679,15 +666,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 */
}
@@ -712,7 +699,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;
}
@@ -737,12 +724,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);
@@ -751,26 +738,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;
}
@@ -782,8 +768,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;
}
@@ -795,13 +780,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;
@@ -810,7 +795,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;
@@ -821,7 +806,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;
@@ -879,7 +864,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;
}
@@ -905,7 +890,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 */
@@ -984,18 +969,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 client",
- __func__, i);
+ error_f("failed to receive fd %d from client", i);
for (j = 0; j < i; j++)
close(new_fd[j]);
free(chost);
@@ -1007,12 +990,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:
@@ -1026,28 +1008,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);
@@ -1071,38 +1047,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);
@@ -1112,13 +1088,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;
@@ -1144,12 +1120,12 @@ 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;
}
@@ -1164,7 +1140,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) {
@@ -1176,12 +1152,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;
}
@@ -1189,21 +1164,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)
@@ -1218,16 +1193,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);
@@ -1241,21 +1214,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);
}
@@ -1266,19 +1237,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);
}
@@ -1313,7 +1283,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);
@@ -1342,7 +1312,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));
}
@@ -1362,7 +1332,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);
}
@@ -1377,17 +1347,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;
@@ -1416,27 +1386,27 @@ mux_session_confirm(struct ssh *ssh, int id, int success, void *arg)
debug("Requesting authentication agent forwarding.");
channel_request_start(ssh, id, "auth-agent-req@openssh.com", 0);
if ((r = sshpkt_send(ssh)) != 0)
- fatal("%s: packet error: %s", __func__, ssh_err(r));
+ 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);
@@ -1485,7 +1455,7 @@ 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;
@@ -1527,9 +1497,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);
@@ -1578,10 +1548,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;
@@ -1590,14 +1560,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;
}
@@ -1610,14 +1580,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;
}
@@ -1625,33 +1595,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);
@@ -1672,16 +1640,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);
@@ -1692,23 +1660,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++;
@@ -1723,16 +1691,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);
@@ -1743,30 +1711,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++;
@@ -1804,7 +1770,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 ||
@@ -1812,10 +1778,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);
@@ -1827,19 +1793,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 : "",
@@ -1849,19 +1815,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);
@@ -1874,7 +1839,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);
@@ -1899,48 +1864,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;
}
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) {
@@ -1948,69 +1909,67 @@ 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));
- 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");
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();
ssh_signal(SIGHUP, control_client_sighandler);
@@ -2034,40 +1993,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);
}
}
@@ -2099,12 +2052,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);
@@ -2115,18 +2068,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;
}
@@ -2137,85 +2090,77 @@ 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;
}
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++;
@@ -2233,10 +2178,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
@@ -2247,45 +2191,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++;
@@ -2323,10 +2265,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)) == -1)
- fatal("%s socket(): %s", __func__, strerror(errno));
+ fatal_f("socket(): %s", strerror(errno));
if (connect(sock, (struct sockaddr *)&addr, sizeof(addr)) == -1) {
switch (muxclient_command) {
@@ -2353,7 +2295,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;
}
@@ -2361,7 +2303,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:
@@ -2371,11 +2313,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);
@@ -2390,8 +2332,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/myproposal.h b/myproposal.h
index 5312e6058..f03b7dfd0 100644
--- a/myproposal.h
+++ b/myproposal.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: myproposal.h,v 1.67 2020/01/24 00:28:57 djm Exp $ */
+/* $OpenBSD: myproposal.h,v 1.68 2020/10/03 04:15:06 djm Exp $ */
/*
* Copyright (c) 2000 Markus Friedl. All rights reserved.
@@ -38,21 +38,21 @@
#define KEX_CLIENT_KEX KEX_SERVER_KEX
#define KEX_DEFAULT_PK_ALG \
+ "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-ecdsa-sha2-nistp256-cert-v01@openssh.com," \
- "ssh-ed25519-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," \
- "sk-ecdsa-sha2-nistp256@openssh.com," \
- "ssh-ed25519," \
"sk-ssh-ed25519@openssh.com," \
+ "sk-ecdsa-sha2-nistp256@openssh.com," \
"rsa-sha2-512," \
"rsa-sha2-256," \
"ssh-rsa"
@@ -80,12 +80,12 @@
/* 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," \
- "sk-ecdsa-sha2-nistp256@openssh.com," \
- "ssh-ed25519," \
"sk-ssh-ed25519@openssh.com," \
+ "sk-ecdsa-sha2-nistp256@openssh.com," \
"rsa-sha2-512," \
"rsa-sha2-256"
diff --git a/nchan.c b/nchan.c
index 1e96eb641..7ef3a350b 100644
--- a/nchan.c
+++ b/nchan.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: nchan.c,v 1.70 2019/06/28 13:35:04 deraadt 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) == -1) {
- 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));
+ 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) {
/*
@@ -411,17 +407,15 @@ chan_shutdown_read(struct ssh *ssh, Channel *c)
* HP-UX may return ENOTCONN also.
*/
if (shutdown(c->sock, SHUT_RD) == -1 && 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));
+ 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/openbsd-compat/Makefile.in b/openbsd-compat/Makefile.in
index 3eb188f0b..5d53bef57 100644
--- a/openbsd-compat/Makefile.in
+++ b/openbsd-compat/Makefile.in
@@ -79,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 \
@@ -94,6 +95,7 @@ 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
diff --git a/openbsd-compat/arc4random.c b/openbsd-compat/arc4random.c
index 578f69f4f..14853aba4 100644
--- a/openbsd-compat/arc4random.c
+++ b/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/openbsd-compat/base64.c b/openbsd-compat/base64.c
index 9e7466716..b7dce095e 100644
--- a/openbsd-compat/base64.c
+++ b/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/openbsd-compat/bsd-misc.h b/openbsd-compat/bsd-misc.h
index 3a7dd6f4c..2206e1a82 100644
--- a/openbsd-compat/bsd-misc.h
+++ b/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())
@@ -125,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
diff --git a/openbsd-compat/bsd-poll.h b/openbsd-compat/bsd-poll.h
index 17945f5b4..8420ca1db 100644
--- a/openbsd-compat/bsd-poll.h
+++ b/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/openbsd-compat/bsd-pselect.c b/openbsd-compat/bsd-pselect.c
new file mode 100644
index 000000000..fff1bf54f
--- /dev/null
+++ b/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/openbsd-compat/bsd-snprintf.c b/openbsd-compat/bsd-snprintf.c
index f041121fd..b9eaee14f 100644
--- a/openbsd-compat/bsd-snprintf.c
+++ b/openbsd-compat/bsd-snprintf.c
@@ -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/openbsd-compat/bsd-waitpid.h b/openbsd-compat/bsd-waitpid.h
index b551268ab..bd61b6909 100644
--- a/openbsd-compat/bsd-waitpid.h
+++ b/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/openbsd-compat/explicit_bzero.c b/openbsd-compat/explicit_bzero.c
index 6ef9825a9..68cd2c10b 100644
--- a/openbsd-compat/explicit_bzero.c
+++ b/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/openbsd-compat/getopt_long.c b/openbsd-compat/getopt_long.c
index e28947430..1a5001f7d 100644
--- a/openbsd-compat/getopt_long.c
+++ b/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/openbsd-compat/libressl-api-compat.c b/openbsd-compat/libressl-api-compat.c
index ae00ff593..801a2e8dd 100644
--- a/openbsd-compat/libressl-api-compat.c
+++ b/openbsd-compat/libressl-api-compat.c
@@ -284,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);
diff --git a/openbsd-compat/memmem.c b/openbsd-compat/memmem.c
index ac1243eb0..2637401d7 100644
--- a/openbsd-compat/memmem.c
+++ b/openbsd-compat/memmem.c
@@ -23,6 +23,8 @@
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
+/* OPENBSD ORIGINAL: lib/libc/string/memmem.c */
+
#include "includes.h"
#ifndef HAVE_MEMMEM
@@ -61,8 +63,11 @@ fourbyte_memmem(const unsigned char *h, size_t k, const unsigned char *n)
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))))
diff --git a/openbsd-compat/mktemp.c b/openbsd-compat/mktemp.c
index 4eb52f421..ac922c1ec 100644
--- a/openbsd-compat/mktemp.c
+++ b/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/openbsd-compat/openbsd-compat.h b/openbsd-compat/openbsd-compat.h
index e5fd6f5bb..a7209ceb2 100644
--- a/openbsd-compat/openbsd-compat.h
+++ b/openbsd-compat/openbsd-compat.h
@@ -48,6 +48,11 @@
#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);
#endif
@@ -122,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);
@@ -190,9 +195,9 @@ 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"
diff --git a/openbsd-compat/openssl-compat.h b/openbsd-compat/openssl-compat.h
index 388ae8aa0..8ca50b5ac 100644
--- a/openbsd-compat/openssl-compat.h
+++ b/openbsd-compat/openssl-compat.h
@@ -113,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
diff --git a/openbsd-compat/port-aix.c b/openbsd-compat/port-aix.c
index e0d3eba51..2ac9bad09 100644
--- a/openbsd-compat/port-aix.c
+++ b/openbsd-compat/port-aix.c
@@ -445,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;
@@ -463,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/openbsd-compat/port-linux.c b/openbsd-compat/port-linux.c
index f46094faf..77cb8213a 100644
--- a/openbsd-compat/port-linux.c
+++ b/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: unparsable 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/openbsd-compat/port-net.c b/openbsd-compat/port-net.c
index d7d8c6fa1..198e73f0d 100644
--- a/openbsd-compat/port-net.c
+++ b/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;
diff --git a/openbsd-compat/port-prngd.c b/openbsd-compat/port-prngd.c
new file mode 100644
index 000000000..6afa8f913
--- /dev/null
+++ b/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/openbsd-compat/port-solaris.c b/openbsd-compat/port-solaris.c
index 7d5a28cd0..b84fbff5e 100644
--- a/openbsd-compat/port-solaris.c
+++ b/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"
diff --git a/openbsd-compat/port-uw.c b/openbsd-compat/port-uw.c
index 132213131..074f80c8d 100644
--- a/openbsd-compat/port-uw.c
+++ b/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/openbsd-compat/regress/Makefile.in b/openbsd-compat/regress/Makefile.in
index c5aae61e2..dd8cdc4b7 100644
--- a/openbsd-compat/regress/Makefile.in
+++ b/openbsd-compat/regress/Makefile.in
@@ -7,7 +7,7 @@ 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@
diff --git a/openbsd-compat/regress/closefromtest.c b/openbsd-compat/regress/closefromtest.c
index 82ffeb9a7..7a69fb2b1 100644
--- a/openbsd-compat/regress/closefromtest.c
+++ b/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/openbsd-compat/regress/opensslvertest.c b/openbsd-compat/regress/opensslvertest.c
index 5d019b598..43825b24c 100644
--- a/openbsd-compat/regress/opensslvertest.c
+++ b/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/openbsd-compat/regress/snprintftest.c b/openbsd-compat/regress/snprintftest.c
index 6dc2e222a..a3134db1c 100644
--- a/openbsd-compat/regress/snprintftest.c
+++ b/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>
diff --git a/openbsd-compat/regress/strduptest.c b/openbsd-compat/regress/strduptest.c
index 7f6d779be..8a3ccf771 100644
--- a/openbsd-compat/regress/strduptest.c
+++ b/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/openbsd-compat/regress/strtonumtest.c b/openbsd-compat/regress/strtonumtest.c
index 50ca5bd22..46bd2b916 100644
--- a/openbsd-compat/regress/strtonumtest.c
+++ b/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/openbsd-compat/regress/utimensattest.c b/openbsd-compat/regress/utimensattest.c
index 24312e5d8..bbc66c485 100644
--- a/openbsd-compat/regress/utimensattest.c
+++ b/openbsd-compat/regress/utimensattest.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>
diff --git a/openbsd-compat/setenv.c b/openbsd-compat/setenv.c
index 373b701d9..86954c284 100644
--- a/openbsd-compat/setenv.c
+++ b/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/openbsd-compat/sha2.c b/openbsd-compat/sha2.c
index e36cc24ef..4f2ad8f23 100644
--- a/openbsd-compat/sha2.c
+++ b/openbsd-compat/sha2.c
@@ -45,7 +45,7 @@
#define MAKE_CLONE(x, y) void __ssh_compat_make_clone_##x_##y(void)
#include <string.h>
-#include <sha2.h>
+#include "openbsd-compat/sha2.h"
/*
* UNROLLED TRANSFORM LOOP NOTE:
@@ -159,7 +159,7 @@
* same "backwards" definition.
*/
/* Shift-right (used in SHA-224, SHA-256, SHA-384, and SHA-512): */
-#define R(b,x) ((x) >> (b))
+#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): */
diff --git a/openbsd-compat/strtonum.c b/openbsd-compat/strtonum.c
index 87f2f24b2..130d89684 100644
--- a/openbsd-compat/strtonum.c
+++ b/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/packet.c b/packet.c
index 00e3180cb..990899418 100644
--- a/packet.c
+++ b/packet.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: packet.c,v 1.296 2020/07/05 23:59:45 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
@@ -297,13 +297,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: could not allocate state", __func__);
+ error_f("could not allocate state");
return NULL;
}
state = ssh->state;
@@ -313,7 +313,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;
}
@@ -475,19 +475,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) == -1)
- 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. */
@@ -696,7 +684,7 @@ 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;
}
@@ -897,12 +885,12 @@ ssh_set_newkeys(struct ssh *ssh, int mode)
max_blocks = &state->max_blocks_in;
}
if (state->newkeys[mode] != NULL) {
- debug("%s: rekeying %s, input %llu bytes %llu blocks, "
- "output %llu bytes %llu blocks", __func__, 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);
+ 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;
}
@@ -920,7 +908,7 @@ ssh_set_newkeys(struct ssh *ssh, int mode)
return r;
}
mac->enabled = 1;
- DBG(debug("%s: cipher_init_context: %s", __func__, dir));
+ 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,
@@ -937,7 +925,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) {
@@ -1014,6 +1002,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,
@@ -1143,8 +1140,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 */
@@ -1259,7 +1256,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)
@@ -1301,8 +1298,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);
@@ -1421,7 +1417,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;
}
@@ -1479,7 +1475,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;
@@ -1708,12 +1704,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;
}
@@ -1836,7 +1828,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
@@ -1892,15 +1884,13 @@ sshpkt_vfatal(struct ssh *ssh, int r, const char *fmt, va_list ap)
default:
if (vasprintf(&tag, fmt, ap) == -1) {
ssh_packet_clear_keys(ssh);
- logdie("%s: could not allocate failure message",
- __func__);
+ logdie_f("could not allocate failure message");
}
ssh_packet_clear_keys(ssh);
errno = oerrno;
- logdie("%s%sConnection %s %s: %s",
+ 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);
}
}
@@ -1913,7 +1903,7 @@ sshpkt_fatal(struct ssh *ssh, int r, const char *fmt, ...)
sshpkt_vfatal(ssh, r, fmt, ap);
/* NOTREACHED */
va_end(ap);
- logdie("%s: should have exited", __func__);
+ logdie_f("should have exited");
}
/*
@@ -2072,30 +2062,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)) == -1)
- 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)) == -1)
- 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. */
@@ -2116,8 +2085,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. */
@@ -2216,7 +2184,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;
@@ -2233,9 +2201,7 @@ 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 ||
@@ -2244,6 +2210,7 @@ kex_to_blob(struct sshbuf *m, struct kex *kex)
(r = sshbuf_put_stringb(m, kex->peer)) != 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;
@@ -2396,8 +2363,7 @@ kex_from_blob(struct sshbuf *m, struct kex **kexp)
if ((kex = kex_new()) == NULL)
return SSH_ERR_ALLOC_FAIL;
- if ((r = sshbuf_get_string(m, &kex->session_id, &kex->session_id_len)) != 0 ||
- (r = sshbuf_get_u32(m, &kex->we_need)) != 0 ||
+ 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 ||
@@ -2406,6 +2372,7 @@ kex_from_blob(struct sshbuf *m, struct kex **kexp)
(r = sshbuf_get_stringb(m, kex->peer)) != 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;
@@ -2472,7 +2439,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;
}
@@ -2663,7 +2630,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/packet.h b/packet.h
index c2544bd96..2ad0e70cf 100644
--- a/packet.h
+++ b/packet.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: packet.h,v 1.92 2020/03/06 18:11:10 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);
diff --git a/readconf.c b/readconf.c
index 554efd7c9..03369a086 100644
--- a/readconf.c
+++ b/readconf.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: readconf.c,v 1.335 2020/08/27 02:11:09 djm 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
@@ -145,14 +145,15 @@ typedef enum {
oForwardAgent, oForwardX11, oForwardX11Trusted, oForwardX11Timeout,
oGatewayPorts, oExitOnForwardFailure,
oPasswordAuthentication,
- oChallengeResponseAuthentication, oXAuthLocation,
+ oXAuthLocation,
oIdentityFile, oHostname, oPort, oRemoteForward, oLocalForward,
+ oPermitRemoteOpen,
oCertificateFile, oAddKeysToAgent, oIdentityAgent,
oUser, oEscapeChar, oProxyCommand,
oGlobalKnownHostsFile, oUserKnownHostsFile, oConnectionAttempts,
oBatchMode, oCheckHostIP, oStrictHostKeyChecking, oCompression,
oTCPKeepAlive, oNumberOfPasswordPrompts,
- oLogFacility, oLogLevel, oCiphers, oMacs,
+ oLogFacility, oLogLevel, oLogVerbose, oCiphers, oMacs,
oPubkeyAuthentication,
oKbdInteractiveAuthentication, oKbdInteractiveDevices, oHostKeyAlias,
oDynamicForward, oPreferredAuthentications, oHostbasedAuthentication,
@@ -166,13 +167,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,
- oSecurityKeyProvider,
+ oFingerprintHash, oUpdateHostkeys, oHostbasedAcceptedAlgorithms,
+ oPubkeyAcceptedAlgorithms, oCASignatureAlgorithms, oProxyJump,
+ oSecurityKeyProvider, oKnownHostsCommand,
oIgnore, oIgnoredUnknownOption, oDeprecated, oUnsupported
} OpCodes;
@@ -227,12 +229,12 @@ 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 },
@@ -247,6 +249,7 @@ static struct {
{ "macs", oMacs },
{ "remoteforward", oRemoteForward },
{ "localforward", oLocalForward },
+ { "permitremoteopen", oPermitRemoteOpen },
{ "user", oUser },
{ "host", oHost },
{ "match", oMatch },
@@ -263,6 +266,7 @@ static struct {
{ "numberofpasswordprompts", oNumberOfPasswordPrompts },
{ "syslogfacility", oLogFacility },
{ "loglevel", oLogLevel },
+ { "logverbose", oLogVerbose },
{ "dynamicforward", oDynamicForward },
{ "preferredauthentications", oPreferredAuthentications },
{ "hostkeyalgorithms", oHostKeyAlgorithms },
@@ -294,6 +298,9 @@ static struct {
{ "kexalgorithms", oKexAlgorithms },
{ "ipqos", oIPQoS },
{ "requesttty", oRequestTTY },
+ { "sessiontype", oSessionType },
+ { "stdinnull", oStdinNull },
+ { "forkafterauthentication", oForkAfterAuthentication },
{ "proxyusefdpass", oProxyUseFdpass },
{ "canonicaldomains", oCanonicalDomains },
{ "canonicalizefallbacklocal", oCanonicalizeFallbackLocal },
@@ -305,23 +312,33 @@ 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 },
{ NULL, oBadOption }
};
-static char *kex_default_pk_alg_filtered;
+static const char *lookup_opcode_name(OpCodes code);
const char *
kex_default_pk_alg(void)
{
- if (kex_default_pk_alg_filtered == NULL)
- fatal("kex_default_pk_alg not initialized.");
- return kex_default_pk_alg_filtered;
+ 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 *
@@ -337,7 +354,7 @@ ssh_connection_hash(const char *thishost, const char *host, const char *portstr,
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("%s: mux digest failed", __func__);
+ fatal_f("mux digest failed");
ssh_digest_free(md);
return tohex(conn_hash, ssh_digest_bytes(SSH_DIGEST_SHA1));
}
@@ -445,7 +462,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;
}
}
@@ -476,7 +493,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;
}
@@ -509,7 +526,7 @@ execute_in_shell(const char *cmd)
{
char *shell;
pid_t pid;
- int devnull, status;
+ int status;
if ((shell = getenv("SHELL")) == NULL)
shell = _PATH_BSHELL;
@@ -519,23 +536,14 @@ execute_in_shell(const char *cmd)
shell, strerror(errno));
}
- /* Need this to redirect subprocess stdin/out */
- if ((devnull = open(_PATH_DEVNULL, O_RDWR)) == -1)
- fatal("open(/dev/null): %s", strerror(errno));
-
debug("Executing command: '%.500s'", cmd);
/* Fork and execute the command. */
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;
@@ -552,13 +560,11 @@ execute_in_shell(const char *cmd)
}
/* Parent. */
if (pid == -1)
- fatal("%s: fork: %.100s", __func__, strerror(errno));
-
- close(devnull);
+ 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);
@@ -601,25 +607,33 @@ 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++;
+ /* criteria "final" and "canonical" have no argument */
if (strcasecmp(attrib, "canonical") == 0 ||
strcasecmp(attrib, "final") == 0) {
/*
@@ -638,7 +652,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;
@@ -674,7 +689,7 @@ match_cfg_line(Options *options, char **condition, struct passwd *pw,
snprintf(uidstr, sizeof(uidstr), "%llu",
(unsigned long long)pw->pw_uid);
conn_hash_hex = ssh_connection_hash(thishost, host,
- portstr, ruser);
+ portstr, ruser);
keyalias = options->host_key_alias ?
options->host_key_alias : host;
@@ -861,6 +876,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 },
@@ -883,8 +904,10 @@ parse_multistate_value(const char *arg, const char *filename, int linenum,
{
int i;
- if (!arg || *arg == '\0')
- fatal("%s line %d: missing argument.", filename, linenum);
+ 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;
@@ -911,9 +934,9 @@ 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 *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;
@@ -925,6 +948,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;
@@ -940,43 +966,63 @@ 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;
@@ -984,10 +1030,12 @@ parse_time:
case oForwardAgent:
intptr = &options->forward_agent;
- 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;
@@ -1014,11 +1062,12 @@ parse_time:
parse_flag:
multistate_ptr = multistate_flag;
parse_multistate:
- arg = strdelim(&s);
+ arg = argv_next(&ac, &av);
if ((value = parse_multistate_value(arg, filename, linenum,
- multistate_ptr)) == -1) {
- fatal("%s line %d: unsupported option \"%s\".",
+ multistate_ptr)) == -1) {
+ error("%s line %d: unsupported option \"%s\".",
filename, linenum, arg);
+ goto out;
}
if (*activep && *intptr == -1)
*intptr = value;
@@ -1060,10 +1109,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;
@@ -1108,25 +1153,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;
@@ -1135,31 +1186,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);
@@ -1173,10 +1233,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;
@@ -1186,16 +1248,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 known hosts 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;
@@ -1231,40 +1312,56 @@ parse_char_array:
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;
@@ -1272,113 +1369,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);
+ 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))
- fatal("%.200s line %d: Bad SSH2 cipher spec '%s'.",
+ !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);
+ 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))
- fatal("%.200s line %d: Bad SSH2 MAC spec '%s'.",
+ !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 == '^' ?
- arg + 1 : arg))
- fatal("%.200s line %d: Bad SSH2 KexAlgorithms '%s'.",
+ 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 == '^' ?
- arg + 1 : arg, 1))
- fatal("%s line %d: Bad key types '%s'.",
- filename, linenum, arg ? arg : "<NONE>");
+ 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,
@@ -1388,9 +1541,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) {
@@ -1401,19 +1556,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++;
@@ -1424,6 +1633,7 @@ parse_keytypes:
"for %.100s", filename, linenum,
arg);
*activep = 0;
+ argv_consume(&ac);
break;
}
if (!*activep)
@@ -1434,27 +1644,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,
+ goto out;
+ }
+ value = match_cfg_line(options, &str, pw, host, original_host,
flags & SSHCONF_FINAL, want_final_pass,
filename, linenum);
- if (value < 0)
- fatal("%.200s line %d: Bad Match condition", filename,
+ 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')
@@ -1463,10 +1686,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;
@@ -1494,10 +1716,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 == '-') {
@@ -1506,9 +1730,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,
@@ -1521,16 +1747,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));
@@ -1550,10 +1780,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)
@@ -1562,9 +1794,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;
@@ -1581,13 +1815,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;
}
@@ -1610,11 +1850,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
@@ -1622,9 +1869,11 @@ 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);
+ goto out;
+ }
if (!path_absolute(arg) && *arg != '~') {
xasprintf(&arg2, "%s/%s",
(flags & SSHCONF_USERCONF) ?
@@ -1638,9 +1887,11 @@ parse_keytypes:
"files",filename, linenum, arg2);
free(arg2);
continue;
- } else if (r != 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 < gl.gl_pathc; i++) {
@@ -1654,9 +1905,11 @@ parse_keytypes:
(oactive ? 0 : SSHCONF_NEVERMATCH),
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
@@ -1669,21 +1922,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;
}
@@ -1694,6 +1951,19 @@ 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 oIgnoreUnknown:
charptr = &options->ignored_unknown;
goto parse_string;
@@ -1704,16 +1974,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);
}
@@ -1721,7 +2011,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;
@@ -1729,18 +2019,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);
@@ -1762,13 +2056,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;
@@ -1782,13 +2081,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;
@@ -1798,33 +2101,40 @@ 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:
- arg = strdelim(&s);
- arg2 = strdelim(&s);
+ arg = argv_next(&ac, &av);
+ arg2 = argv_next(&ac, &av);
value = parse_multistate_value(arg, filename, linenum,
- multistate_yesnoaskconfirm);
+ 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)
- fatal("%s line %d: invalid time value.",
+ 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)
- fatal("%s line %d: unsupported option",
+ 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) {
- fatal("%s line %d: unsupported option",
+ error("%s line %d: unsupported option",
filename, linenum);
+ goto out;
}
if (*activep && options->add_keys_to_agent == -1) {
options->add_keys_to_agent = value;
@@ -1834,20 +2144,26 @@ parse_keytypes:
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 ((arg2 = dollar_expand(&r, arg)) == NULL || r)
- fatal("%.200s line %d: Invalid environment expansion "
+ 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)) {
- fatal("%.200s line %d: Invalid environment name %s.",
+ 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);
@@ -1856,23 +2172,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;
}
/*
@@ -1929,6 +2255,11 @@ 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, want_final_pass,
depth) != 0)
@@ -1974,7 +2305,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;
@@ -1997,7 +2327,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;
@@ -2013,8 +2345,12 @@ 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;
@@ -2050,6 +2386,9 @@ initialize_options(Options * options)
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;
@@ -2060,8 +2399,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;
}
/*
@@ -2083,12 +2423,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;
char *def_cipher, *def_mac, *def_kex, *def_key, *def_sig;
- int r;
+ int ret = 0, r;
if (options->forward_agent == -1)
options->forward_agent = 0;
@@ -2112,7 +2452,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)
@@ -2121,8 +2461,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)
@@ -2136,7 +2474,7 @@ fill_default_options(Options * options)
if (options->batch_mode == -1)
options->batch_mode = 0;
if (options->check_host_ip == -1)
- options->check_host_ip = 1;
+ options->check_host_ip = 0;
if (options->strict_host_key_checking == -1)
options->strict_host_key_checking = SSH_STRICT_HOSTKEY_ASK;
if (options->compression == -1)
@@ -2178,8 +2516,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->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);
@@ -2230,6 +2575,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)
@@ -2263,26 +2614,18 @@ fill_default_options(Options * options)
#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, def_cipher, all_cipher);
ASSEMBLE(macs, def_mac, all_mac);
ASSEMBLE(kex_algorithms, def_kex, all_kex);
- ASSEMBLE(hostbased_key_types, def_key, all_key);
- ASSEMBLE(pubkey_key_types, 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);
- free(def_cipher);
- free(def_mac);
- free(def_kex);
- kex_default_pk_alg_filtered = def_key; /* save for later use */
- free(def_sig);
#define CLEAR_ON_NONE(v) \
do { \
@@ -2298,6 +2641,7 @@ fill_default_options(Options * options)
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) {
@@ -2309,6 +2653,103 @@ fill_default_options(Options * options)
/* options->hostname will be set in the main program if appropriate */
/* options->host_key_alias should not be set by default */
/* options->preferred_authentications will be set in ssh */
+
+ /* 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 {
@@ -2502,7 +2943,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;
@@ -2532,11 +2976,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)
@@ -2548,13 +2998,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 */
@@ -2587,12 +3039,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;
}
@@ -2628,6 +3095,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:
@@ -2692,6 +3161,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");
@@ -2750,7 +3221,7 @@ dump_client_config(Options *o, const char *host)
all_key = sshkey_alg_list(0, 0, 1, ',');
if ((r = kex_assemble_names(&o->hostkeyalgorithms, kex_default_pk_alg(),
all_key)) != 0)
- fatal("%s: expand HostKeyAlgorithms: %s", __func__, ssh_err(r));
+ fatal_fr(r, "expand HostKeyAlgorithms");
free(all_key);
/* Most interesting options first: user, host, port */
@@ -2763,7 +3234,6 @@ dump_client_config(Options *o, const char *host)
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);
@@ -2788,6 +3258,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);
@@ -2811,7 +3284,7 @@ dump_client_config(Options *o, const char *host)
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);
@@ -2826,9 +3299,10 @@ dump_client_config(Options *o, const char *host)
#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);
@@ -2843,9 +3317,18 @@ 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);
diff --git a/readconf.h b/readconf.h
index d6a15550d..f7d53b067 100644
--- a/readconf.h
+++ b/readconf.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: readconf.h,v 1.134 2020/08/11 09:49:57 djm Exp $ */
+/* $OpenBSD: readconf.h,v 1.144 2021/07/23 04:04:52 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -38,8 +38,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 +53,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
@@ -109,6 +108,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;
@@ -143,6 +146,9 @@ typedef struct {
int visual_host_key;
int request_tty;
+ int session_type;
+ int stdin_null;
+ int fork_after_authentication;
int proxy_use_fdpass;
@@ -160,14 +166,16 @@ 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 *jump_user;
char *jump_host;
int jump_port;
char *jump_extra;
+ char *known_hosts_command;
+
char *ignored_unknown; /* Pattern list of unknown tokens to ignore */
} Options;
@@ -186,6 +194,10 @@ 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_FINAL 4 /* Final pass over config, after canon. */
@@ -204,8 +216,9 @@ 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 *,
diff --git a/readpass.c b/readpass.c
index 122d2a87c..39af25c88 100644
--- a/readpass.c
+++ b/readpass.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: readpass.c,v 1.63 2020/08/11 09:45:54 djm Exp $ */
+/* $OpenBSD: readpass.c,v 1.69 2021/07/23 05:56:47 djm Exp $ */
/*
* Copyright (c) 2001 Markus Friedl. All rights reserved.
*
@@ -58,27 +58,27 @@ ssh_askpass(char *askpass, const char *msg, const char *env_hint)
void (*osigchld)(int);
if (fflush(stdout) != 0)
- error("%s: fflush: %s", __func__, strerror(errno));
+ error_f("fflush: %s", strerror(errno));
if (askpass == NULL)
fatal("internal error: askpass undefined");
if (pipe(p) == -1) {
- error("%s: pipe: %s", __func__, strerror(errno));
+ error_f("pipe: %s", strerror(errno));
return NULL;
}
osigchld = ssh_signal(SIGCHLD, SIG_DFL);
if ((pid = fork()) == -1) {
- error("%s: fork: %s", __func__, strerror(errno));
+ error_f("fork: %s", strerror(errno));
ssh_signal(SIGCHLD, osigchld);
return NULL;
}
if (pid == 0) {
close(p[0]);
if (dup2(p[1], STDOUT_FILENO) == -1)
- fatal("%s: dup2: %s", __func__, strerror(errno));
+ fatal_f("dup2: %s", strerror(errno));
if (env_hint != NULL)
setenv("SSH_ASKPASS_PROMPT", env_hint, 1);
execlp(askpass, askpass, msg, (char *)NULL);
- fatal("%s: exec(%s): %s", __func__, askpass, strerror(errno));
+ fatal_f("exec(%s): %s", askpass, strerror(errno));
}
close(p[1]);
@@ -117,7 +117,7 @@ ssh_askpass(char *askpass, const char *msg, const char *env_hint)
* 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)
@@ -141,12 +141,12 @@ read_passphrase(const char *prompt, int flags)
rppflags = (flags & RP_ECHO) ? RPP_ECHO_ON : RPP_ECHO_OFF;
if (use_askpass)
- debug("%s: requested to askpass", __func__);
+ 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 {
@@ -162,7 +162,7 @@ read_passphrase(const char *prompt, int flags)
(void)write(ttyfd, &cr, 1);
close(ttyfd);
} else {
- debug("read_passphrase: can't open %s: %s", _PATH_TTY,
+ debug_f("can't open %s: %s", _PATH_TTY,
strerror(errno));
use_askpass = 1;
}
@@ -222,6 +222,14 @@ 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);
@@ -232,9 +240,8 @@ notify_start(int force_askpass, const char *fmt, ...)
{
va_list args;
char *prompt = NULL;
- int devnull;
- pid_t pid;
- void (*osigchld)(int);
+ pid_t pid = -1;
+ void (*osigchld)(int) = NULL;
const char *askpass, *s;
struct notifier_ctx *ret = NULL;
@@ -243,48 +250,44 @@ notify_start(int force_askpass, const char *fmt, ...)
va_end(args);
if (fflush(NULL) != 0)
- error("%s: fflush: %s", __func__, strerror(errno));
+ error_f("fflush: %s", strerror(errno));
if (!force_askpass && isatty(STDERR_FILENO)) {
- (void)write(STDERR_FILENO, "\r", 1);
- (void)write(STDERR_FILENO, prompt, strlen(prompt));
- (void)write(STDERR_FILENO, "\r\n", 2);
- goto out;
+ writemsg(prompt);
+ goto out_ctx;
}
if ((askpass = getenv("SSH_ASKPASS")) == NULL)
askpass = _PATH_SSH_ASKPASS_DEFAULT;
if (*askpass == '\0') {
- debug3("%s: cannot notify: no askpass", __func__);
+ debug3_f("cannot notify: no askpass");
goto out;
}
if (getenv("DISPLAY") == NULL &&
((s = getenv(SSH_ASKPASS_REQUIRE_ENV)) == NULL ||
strcmp(s, "force") != 0)) {
- debug3("%s: cannot notify: no display", __func__);
+ debug3_f("cannot notify: no display");
goto out;
}
osigchld = ssh_signal(SIGCHLD, SIG_DFL);
if ((pid = fork()) == -1) {
- error("%s: fork: %s", __func__, strerror(errno));
+ error_f("fork: %s", strerror(errno));
ssh_signal(SIGCHLD, osigchld);
free(prompt);
return NULL;
}
if (pid == 0) {
- if ((devnull = open(_PATH_DEVNULL, O_RDWR)) == -1)
- fatal("%s: open %s", __func__, strerror(errno));
- if (dup2(devnull, STDIN_FILENO) == -1 ||
- dup2(devnull, STDOUT_FILENO) == -1)
- fatal("%s: dup2: %s", __func__, strerror(errno));
+ 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("%s: exec(%s): %s", __func__, askpass, strerror(errno));
+ error_f("exec(%s): %s", askpass, strerror(errno));
_exit(1);
/* NOTREACHED */
}
+ out_ctx:
if ((ret = calloc(1, sizeof(*ret))) == NULL) {
kill(pid, SIGTERM);
- fatal("%s: calloc failed", __func__);
+ fatal_f("calloc failed");
}
ret->pid = pid;
ret->osigchld = osigchld;
@@ -294,9 +297,23 @@ notify_start(int force_askpass, const char *fmt, ...)
}
void
-notify_complete(struct notifier_ctx *ctx)
+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);
@@ -308,7 +325,7 @@ notify_complete(struct notifier_ctx *ctx)
break;
}
if (ret == -1)
- fatal("%s: waitpid: %s", __func__, strerror(errno));
+ fatal_f("waitpid: %s", strerror(errno));
ssh_signal(SIGCHLD, ctx->osigchld);
free(ctx);
}
diff --git a/regress/Makefile b/regress/Makefile
index 8b4ed9de3..810d74ce5 100644
--- a/regress/Makefile
+++ b/regress/Makefile
@@ -1,4 +1,4 @@
-# $OpenBSD: Makefile,v 1.109 2020/06/19 05:07:09 dtucker Exp $
+# $OpenBSD: Makefile,v 1.116 2021/08/04 21:28:00 djm Exp $
tests: prep file-tests t-exec unit
@@ -21,6 +21,7 @@ distclean: clean
LTESTS= connect \
proxy-connect \
+ sshfp-connect \
connect-privsep \
connect-uri \
proto-version \
@@ -44,10 +45,14 @@ LTESTS= connect \
agent-subprocess \
keyscan \
keygen-change \
+ keygen-comment \
keygen-convert \
+ keygen-knownhosts \
keygen-moduli \
+ keygen-sshfp \
key-options \
scp \
+ scp3 \
scp-uri \
sftp \
sftp-chroot \
@@ -84,7 +89,6 @@ LTESTS= connect \
multipubkey \
limit-keytype \
hostkey-agent \
- keygen-knownhosts \
hostkey-rotate \
principals-command \
cert-file \
@@ -93,7 +97,7 @@ LTESTS= connect \
allow-deny-users \
authinfo \
sshsig \
- keygen-comment
+ knownhosts-command
INTEROP_TESTS= putty-transfer putty-ciphers putty-kex conch-ciphers
@@ -114,7 +118,7 @@ CLEANFILES= *.core actual agent-key.* authorized_keys_${USERNAME} \
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 \
@@ -122,9 +126,9 @@ CLEANFILES= *.core actual agent-key.* authorized_keys_${USERNAME} \
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 \
+ ssh-rsa_oldfmt knownhosts_command \
ssh_config ssh_config.* ssh_proxy ssh_proxy_bak \
- ssh_proxy_envpass sshd.log sshd_config sshd_config_minimal \
+ 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 \
@@ -248,17 +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/regress/agent-getpeereid.sh b/regress/agent-getpeereid.sh
index 524340816..ddeef01f1 100644
--- a/regress/agent-getpeereid.sh
+++ b/regress/agent-getpeereid.sh
@@ -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
diff --git a/regress/agent-pkcs11.sh b/regress/agent-pkcs11.sh
index fbbaea518..268a70de8 100644
--- a/regress/agent-pkcs11.sh
+++ b/regress/agent-pkcs11.sh
@@ -1,4 +1,4 @@
-# $OpenBSD: agent-pkcs11.sh,v 1.7 2019/11/26 23:43:10 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"
@@ -62,16 +62,16 @@ notty() {
trace "generating keys"
RSA=${DIR}/RSA
EC=${DIR}/EC
-openssl genpkey -algorithm rsa > $RSA
-openssl pkcs8 -nocrypt -in $RSA |\
+$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 genpkey \
+$OPENSSL_BIN genpkey \
-genparam \
-algorithm ec \
-pkeyopt ec_paramgen_curve:prime256v1 |\
- openssl genpkey \
+ $OPENSSL_BIN genpkey \
-paramfile /dev/stdin > $EC
-openssl pkcs8 -nocrypt -in $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"
diff --git a/regress/agent.sh b/regress/agent.sh
index a3ad1385f..f187b6757 100644
--- a/regress/agent.sh
+++ b/regress/agent.sh
@@ -1,4 +1,4 @@
-# $OpenBSD: agent.sh,v 1.19 2020/07/15 04:55:47 dtucker Exp $
+# $OpenBSD: agent.sh,v 1.20 2021/02/25 03:27:34 djm Exp $
# Placed in the Public Domain.
tid="simple agent test"
@@ -87,8 +87,8 @@ fi
for t in ${SSH_KEYTYPES}; do
trace "connect via agent using $t key"
if [ "$t" = "ssh-dss" ]; then
- echo "PubkeyAcceptedKeyTypes +ssh-dss" >> $OBJ/ssh_proxy
- echo "PubkeyAcceptedKeyTypes +ssh-dss" >> $OBJ/sshd_proxy
+ 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
diff --git a/regress/allow-deny-users.sh b/regress/allow-deny-users.sh
index 5c3895122..6c053eef0 100644
--- a/regress/allow-deny-users.sh
+++ b/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/regress/banner.sh b/regress/banner.sh
index 0d9654fe2..a84feb5ad 100644
--- a/regress/banner.sh
+++ b/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/regress/cert-hostkey.sh b/regress/cert-hostkey.sh
index 097bf8463..de8652b0e 100644
--- a/regress/cert-hostkey.sh
+++ b/regress/cert-hostkey.sh
@@ -1,4 +1,4 @@
-# $OpenBSD: cert-hostkey.sh,v 1.23 2020/01/03 03:02:26 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"
@@ -29,12 +29,12 @@ for i in `$SSH -Q key | maybe_filter_sk`; 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'
@@ -283,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/regress/cert-userkey.sh b/regress/cert-userkey.sh
index 91596fa78..baa6903ea 100644
--- a/regress/cert-userkey.sh
+++ b/regress/cert-userkey.sh
@@ -1,4 +1,4 @@
-# $OpenBSD: cert-userkey.sh,v 1.25 2020/01/03 03:02:26 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"
@@ -71,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
@@ -149,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
@@ -204,12 +204,12 @@ basic_tests() {
(
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} \
@@ -224,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 \
@@ -257,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 \
@@ -270,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"
@@ -308,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
diff --git a/regress/cfginclude.sh b/regress/cfginclude.sh
index 2fc39ce45..f5b492f17 100644
--- a/regress/cfginclude.sh
+++ b/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/regress/cfgmatch.sh b/regress/cfgmatch.sh
index 6620c84ed..05a666855 100644
--- a/regress/cfgmatch.sh
+++ b/regress/cfgmatch.sh
@@ -1,4 +1,4 @@
-# $OpenBSD: cfgmatch.sh,v 1.12 2019/04/18 18:57:16 dtucker 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,16 +39,16 @@ 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
${SUDO} ${SSHD} -f $OBJ/sshd_config -T >/dev/null || \
diff --git a/regress/connect-privsep.sh b/regress/connect-privsep.sh
index b6abb65e3..8970340a2 100644
--- a/regress/connect-privsep.sh
+++ b/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/regress/dhgex.sh b/regress/dhgex.sh
index ae64a9fb6..6dd4cfe3f 100644
--- a/regress/dhgex.sh
+++ b/regress/dhgex.sh
@@ -1,4 +1,4 @@
-# $OpenBSD: dhgex.sh,v 1.6 2019/10/06 11:49:50 dtucker Exp $
+# $OpenBSD: dhgex.sh,v 1.7 2020/12/21 22:48:41 dtucker Exp $
# Placed in the Public Domain.
tid="dhgex"
@@ -58,4 +58,4 @@ 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/regress/ed25519_openssh.prv b/regress/ed25519_openssh.prv
new file mode 100644
index 000000000..9f191b778
--- /dev/null
+++ b/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/regress/ed25519_openssh.pub b/regress/ed25519_openssh.pub
new file mode 100644
index 000000000..910363138
--- /dev/null
+++ b/regress/ed25519_openssh.pub
@@ -0,0 +1 @@
+ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMTz/QUztjDrFzndCmJlRACH8sraYQDA0M1h1JHoYgYj
diff --git a/regress/forward-control.sh b/regress/forward-control.sh
index 3b1f69a71..02f7667a6 100644
--- a/regress/forward-control.sh
+++ b/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/regress/forwarding.sh b/regress/forwarding.sh
index cd634f2f6..a72bd3a05 100644
--- a/regress/forwarding.sh
+++ b/regress/forwarding.sh
@@ -1,4 +1,4 @@
-# $OpenBSD: forwarding.sh,v 1.23 2019/07/20 09:50:58 dtucker 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"
@@ -29,7 +29,7 @@ rm -f $CTL
${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}"
@@ -110,7 +110,7 @@ rm -f $CTL
${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}"
@@ -124,7 +124,7 @@ ${SSH} -S $CTL -N -M -f -F $OBJ/ssh_config -R${base}01:[$OBJ/unix-1.fwd] somehos
${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=4' \
+${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}"
diff --git a/regress/hostkey-rotate.sh b/regress/hostkey-rotate.sh
index c3e100c3e..2852c457c 100644
--- a/regress/hostkey-rotate.sh
+++ b/regress/hostkey-rotate.sh
@@ -1,12 +1,15 @@
-# $OpenBSD: hostkey-rotate.sh,v 1.8 2019/11/26 23:43: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"
-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
diff --git a/regress/key-options.sh b/regress/key-options.sh
index 097f46eba..2f3d66e2e 100644
--- a/regress/key-options.sh
+++ b/regress/key-options.sh
@@ -9,7 +9,7 @@ cp $authkeys $origkeys
# Allocating ptys can require privileges on some platforms.
skip_pty=""
-if ! config_defined HAVE_OPENPTY && [ "x$SUDO" == "x" ]; then
+if ! config_defined HAVE_OPENPTY && [ "x$SUDO" = "x" ]; then
skip_pty="no openpty(3) and SUDO not set"
fi
diff --git a/regress/keygen-convert.sh b/regress/keygen-convert.sh
index fce110ea1..95656581c 100644
--- a/regress/keygen-convert.sh
+++ b/regress/keygen-convert.sh
@@ -1,40 +1,54 @@
-# $OpenBSD: keygen-convert.sh,v 1.2 2019/07/23 07:55:29 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"
-types=""
-for i in ${SSH_KEYTYPES}; do
- case "$i" in
- ssh-dss) types="$types dsa" ;;
- ssh-rsa) types="$types rsa" ;;
- esac
-done
+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 $types; do
+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/regress/keygen-sshfp.sh b/regress/keygen-sshfp.sh
new file mode 100644
index 000000000..2abf9adec
--- /dev/null
+++ b/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/regress/keytype.sh b/regress/keytype.sh
index 20a8ceaf2..f1c045183 100644
--- a/regress/keytype.sh
+++ b/regress/keytype.sh
@@ -1,4 +1,4 @@
-# $OpenBSD: keytype.sh,v 1.10 2019/12/16 02:39:05 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"
@@ -58,13 +58,13 @@ for ut in $ktypes; do
(
grep -v HostKey $OBJ/sshd_proxy_bak
echo HostKey $OBJ/key.$ht
- echo PubkeyAcceptedKeyTypes $user_type
+ 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 $user_type
+ echo PubkeyAcceptedAlgorithms $user_type
echo HostKeyAlgorithms $host_type
) > $OBJ/ssh_proxy
(
diff --git a/regress/knownhosts-command.sh b/regress/knownhosts-command.sh
new file mode 100644
index 000000000..f15df670b
--- /dev/null
+++ b/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/regress/limit-keytype.sh b/regress/limit-keytype.sh
index 010a88cd7..7127de007 100644
--- a/regress/limit-keytype.sh
+++ b/regress/limit-keytype.sh
@@ -1,4 +1,4 @@
-# $OpenBSD: limit-keytype.sh,v 1.9 2019/12/16 02:39:05 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"
@@ -69,7 +69,7 @@ prepare_config() {
) > $OBJ/sshd_proxy
}
-# Return the required parameter for PubkeyAcceptedKeyTypes corresponding to
+# Return the required parameter for PubkeyAcceptedAlgorithms corresponding to
# the supplied key type.
keytype() {
case "$1" in
@@ -92,14 +92,14 @@ ${SSH} $opts -i $OBJ/user_key2 proxy true || fatal "key2 failed"
# Allow plain Ed25519 and RSA. The certificate should fail.
verbose "allow $ktype2,$ktype1"
prepare_config \
- "PubkeyAcceptedKeyTypes `keytype $ktype2`,`keytype $ktype1`"
+ "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 $ktype1"
-prepare_config "PubkeyAcceptedKeyTypes `keytype $ktype1`"
+prepare_config "PubkeyAcceptedAlgorithms `keytype $ktype1`"
${SSH} $certopts proxy true && fatal "cert succeeded"
${SSH} $opts -i $OBJ/user_key1 proxy true || fatal "key1 failed"
if [ "$ktype1" != "$ktype2" ]; then
@@ -108,15 +108,15 @@ 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 `keytype $ktype2`" \
- "Match user x$USER" "PubkeyAcceptedKeyTypes +`keytype $ktype1`"
+prepare_config "PubkeyAcceptedAlgorithms `keytype $ktype2`" \
+ "Match user x$USER" "PubkeyAcceptedAlgorithms +`keytype $ktype1`"
${SSH} $certopts proxy true && fatal "cert succeeded"
if [ "$ktype1" != "$ktype2" ]; then
${SSH} $opts -i $OBJ/user_key1 proxy true && fatal "key1 succeeded"
@@ -125,8 +125,8 @@ ${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 `keytype $ktype4`" \
- "Match user $USER" "PubkeyAcceptedKeyTypes +`keytype $ktype1`"
+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/regress/misc/Makefile b/regress/misc/Makefile
index cf95f265c..b9149f287 100644
--- a/regress/misc/Makefile
+++ b/regress/misc/Makefile
@@ -1,3 +1,3 @@
-SUBDIR= kexfuzz sk-dummy
+SUBDIR= sk-dummy
.include <bsd.subdir.mk>
diff --git a/regress/misc/fuzz-harness/Makefile b/regress/misc/fuzz-harness/Makefile
index 64fbdbab1..e879fcdae 100644
--- a/regress/misc/fuzz-harness/Makefile
+++ b/regress/misc/fuzz-harness/Makefile
@@ -1,38 +1,52 @@
# NB. libssh and libopenbsd-compat should be built with the same sanitizer opts.
-CXX=clang++-6.0
-FUZZ_FLAGS=-fsanitize=address,undefined -fsanitize-coverage=edge,trace-pc
+CC=clang-11
+CXX=clang++-11
+FUZZ_FLAGS=-fsanitize=address,fuzzer -fno-omit-frame-pointer
FUZZ_LIBS=-lFuzzer
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 -lfido2 -lcbor $(FUZZ_LIBS)
-COMMON_OBJS=ssh-sk-null.o
+SK_NULL_OBJS=ssh-sk-null.o
+COMMON_DEPS=../../../libssh.a
TARGETS=pubkey_fuzz sig_fuzz authopt_fuzz sshsig_fuzz \
- sshsigopt_fuzz privkey_fuzz
+ sshsigopt_fuzz privkey_fuzz kex_fuzz agent_fuzz
all: $(TARGETS)
.cc.o:
$(CXX) $(CXXFLAGS) -c $< -o $@
-pubkey_fuzz: pubkey_fuzz.o $(COMMON_OBJS)
- $(CXX) -o $@ pubkey_fuzz.o $(COMMON_OBJS) $(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 $(COMMON_OBJS)
- $(CXX) -o $@ sig_fuzz.o $(COMMON_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 $(COMMON_OBJS)
- $(CXX) -o $@ authopt_fuzz.o $(COMMON_OBJS) ../../../auth-options.o $(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 $(COMMON_OBJS)
- $(CXX) -o $@ sshsig_fuzz.o $(COMMON_OBJS) ../../../sshsig.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 $(COMMON_OBJS)
- $(CXX) -o $@ sshsigopt_fuzz.o $(COMMON_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 $(COMMON_OBJS)
- $(CXX) -o $@ privkey_fuzz.o $(COMMON_OBJS) $(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
+
+agent_fuzz_helper.o: agent_fuzz_helper.c ../../../ssh-agent.c
+
+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 $(TARGETS)
diff --git a/regress/misc/fuzz-harness/agent_fuzz.cc b/regress/misc/fuzz-harness/agent_fuzz.cc
new file mode 100644
index 000000000..ad85b2f9a
--- /dev/null
+++ b/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/regress/misc/fuzz-harness/agent_fuzz_helper.c b/regress/misc/fuzz-harness/agent_fuzz_helper.c
new file mode 100644
index 000000000..1d419820c
--- /dev/null
+++ b/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/regress/misc/fuzz-harness/fixed-keys.h b/regress/misc/fuzz-harness/fixed-keys.h
new file mode 100644
index 000000000..c6e7c6cc1
--- /dev/null
+++ b/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/regress/misc/fuzz-harness/kex_fuzz.cc b/regress/misc/fuzz-harness/kex_fuzz.cc
new file mode 100644
index 000000000..4740a7cb0
--- /dev/null
+++ b/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/regress/misc/fuzz-harness/testdata/README b/regress/misc/fuzz-harness/testdata/README
new file mode 100644
index 000000000..752053001
--- /dev/null
+++ b/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/regress/misc/fuzz-harness/testdata/create-agent-corpus.sh b/regress/misc/fuzz-harness/testdata/create-agent-corpus.sh
new file mode 100755
index 000000000..1043b9ff4
--- /dev/null
+++ b/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/regress/misc/fuzz-harness/testdata/id_dsa b/regress/misc/fuzz-harness/testdata/id_dsa
new file mode 100644
index 000000000..88bf5566c
--- /dev/null
+++ b/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/regress/misc/fuzz-harness/testdata/id_dsa-cert.pub b/regress/misc/fuzz-harness/testdata/id_dsa-cert.pub
new file mode 100644
index 000000000..3afb87fe6
--- /dev/null
+++ b/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/regress/misc/fuzz-harness/testdata/id_dsa.pub b/regress/misc/fuzz-harness/testdata/id_dsa.pub
new file mode 100644
index 000000000..6f91c4e07
--- /dev/null
+++ b/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/regress/misc/fuzz-harness/testdata/id_ecdsa b/regress/misc/fuzz-harness/testdata/id_ecdsa
new file mode 100644
index 000000000..c1a96c6f9
--- /dev/null
+++ b/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/regress/misc/fuzz-harness/testdata/id_ecdsa-cert.pub b/regress/misc/fuzz-harness/testdata/id_ecdsa-cert.pub
new file mode 100644
index 000000000..9de599917
--- /dev/null
+++ b/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/regress/misc/fuzz-harness/testdata/id_ecdsa.pub b/regress/misc/fuzz-harness/testdata/id_ecdsa.pub
new file mode 100644
index 000000000..30a7cc23b
--- /dev/null
+++ b/regress/misc/fuzz-harness/testdata/id_ecdsa.pub
@@ -0,0 +1 @@
+ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBMMnRWUy/7SuC43NonUMXYq54drFFJDoukjEZu6WuDVrxE9ucxfBqDkZwOIOWUPaUNQlS4ERbKNcDStmhlffkQs=
diff --git a/regress/misc/fuzz-harness/testdata/id_ecdsa_sk b/regress/misc/fuzz-harness/testdata/id_ecdsa_sk
new file mode 100644
index 000000000..5a364ed39
--- /dev/null
+++ b/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/regress/misc/fuzz-harness/testdata/id_ecdsa_sk-cert.pub b/regress/misc/fuzz-harness/testdata/id_ecdsa_sk-cert.pub
new file mode 100644
index 000000000..14040fad7
--- /dev/null
+++ b/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/regress/misc/fuzz-harness/testdata/id_ecdsa_sk.pub b/regress/misc/fuzz-harness/testdata/id_ecdsa_sk.pub
new file mode 100644
index 000000000..1b5e829b7
--- /dev/null
+++ b/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/regress/misc/fuzz-harness/testdata/id_ed25519 b/regress/misc/fuzz-harness/testdata/id_ed25519
new file mode 100644
index 000000000..6a7fbac92
--- /dev/null
+++ b/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/regress/misc/fuzz-harness/testdata/id_ed25519-cert.pub b/regress/misc/fuzz-harness/testdata/id_ed25519-cert.pub
new file mode 100644
index 000000000..6a95fed2a
--- /dev/null
+++ b/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/regress/misc/fuzz-harness/testdata/id_ed25519.pub b/regress/misc/fuzz-harness/testdata/id_ed25519.pub
new file mode 100644
index 000000000..87b617447
--- /dev/null
+++ b/regress/misc/fuzz-harness/testdata/id_ed25519.pub
@@ -0,0 +1,2 @@
+ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIDPQXmEVMVLmeFRyafKMVWgPDkv8/uRBTwmcEDatZzMD
+
diff --git a/regress/misc/fuzz-harness/testdata/id_ed25519_sk b/regress/misc/fuzz-harness/testdata/id_ed25519_sk
new file mode 100644
index 000000000..9dcda6c46
--- /dev/null
+++ b/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/regress/misc/fuzz-harness/testdata/id_ed25519_sk-cert.pub b/regress/misc/fuzz-harness/testdata/id_ed25519_sk-cert.pub
new file mode 100644
index 000000000..9e41eec00
--- /dev/null
+++ b/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/regress/misc/fuzz-harness/testdata/id_ed25519_sk.pub b/regress/misc/fuzz-harness/testdata/id_ed25519_sk.pub
new file mode 100644
index 000000000..38d198444
--- /dev/null
+++ b/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/regress/misc/fuzz-harness/testdata/id_rsa b/regress/misc/fuzz-harness/testdata/id_rsa
new file mode 100644
index 000000000..574fecf47
--- /dev/null
+++ b/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/regress/misc/fuzz-harness/testdata/id_rsa-cert.pub b/regress/misc/fuzz-harness/testdata/id_rsa-cert.pub
new file mode 100644
index 000000000..01761a38f
--- /dev/null
+++ b/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/regress/misc/fuzz-harness/testdata/id_rsa.pub b/regress/misc/fuzz-harness/testdata/id_rsa.pub
new file mode 100644
index 000000000..05015e12b
--- /dev/null
+++ b/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/regress/misc/kexfuzz/Makefile b/regress/misc/kexfuzz/Makefile
deleted file mode 100644
index ede5e2fb4..000000000
--- a/regress/misc/kexfuzz/Makefile
+++ /dev/null
@@ -1,101 +0,0 @@
-# $OpenBSD: Makefile,v 1.8 2020/04/03 04:07:48 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+=compat.c ed25519.c hash.c ge25519.c fe25519.c sc25519.c verify.c
-SRCS+=cipher-chachapoly.c chacha.c poly1305.c utf8.c
-SRCS+=sshbuf-io.c ssh-ecdsa-sk.c ssh-ed25519-sk.c msg.c ssh-sk-client.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+= kexsntrup4591761x25519.c
-SRCS+= sntrup4591761.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
-
-LDADD+= -lfido2 -lcbor -lusbhid
-DPADD+= ${LIBFIDO2} ${LIBCBOR} ${LIBUSBHID}
-
-# 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/regress/misc/kexfuzz/README b/regress/misc/kexfuzz/README
deleted file mode 100644
index 504c26f3b..000000000
--- a/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/regress/misc/kexfuzz/kexfuzz.c b/regress/misc/kexfuzz/kexfuzz.c
deleted file mode 100644
index 56697c918..000000000
--- a/regress/misc/kexfuzz/kexfuzz.c
+++ /dev/null
@@ -1,453 +0,0 @@
-/* $OpenBSD: kexfuzz.c,v 1.6 2020/01/26 00:09:50 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"
-
-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] = kex_gen_server;
- server2->kex->kex[KEX_DH_GRP14_SHA1] = kex_gen_server;
- server2->kex->kex[KEX_DH_GRP14_SHA256] = kex_gen_server;
- server2->kex->kex[KEX_DH_GRP16_SHA512] = kex_gen_server;
- server2->kex->kex[KEX_DH_GRP18_SHA512] = 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] = kex_gen_server;
-# endif
-#endif
- server2->kex->kex[KEX_C25519_SHA256] = 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;
- 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 ((r = sshbuf_load_file(data_path, &replace_data)) != 0)
- errx(1, "read %s: %s", data_path, ssh_err(r));
- }
-
- /* 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/regress/misc/sk-dummy/fatal.c b/regress/misc/sk-dummy/fatal.c
index 7cdc74b97..c6e4b5d6f 100644
--- a/regress/misc/sk-dummy/fatal.c
+++ b/regress/misc/sk-dummy/fatal.c
@@ -1,20 +1,27 @@
/* public domain */
+#include "includes.h"
+
#include <stdlib.h>
#include <stdio.h>
#include <stdarg.h>
#include <unistd.h>
-void fatal(char *fmt, ...);
+#include "log.h"
void
-fatal(char *fmt, ...)
+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/regress/misc/sk-dummy/sk-dummy.c b/regress/misc/sk-dummy/sk-dummy.c
index bf1feec15..4003362d7 100644
--- a/regress/misc/sk-dummy/sk-dummy.c
+++ b/regress/misc/sk-dummy/sk-dummy.c
@@ -51,6 +51,13 @@
# 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)));
diff --git a/regress/multipubkey.sh b/regress/multipubkey.sh
index 9b2273353..8cdda1a9a 100644
--- a/regress/multipubkey.sh
+++ b/regress/multipubkey.sh
@@ -1,4 +1,4 @@
-# $OpenBSD: multipubkey.sh,v 1.3 2019/12/11 18:47:14 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 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 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/regress/netcat.c b/regress/netcat.c
index d583176f1..20ec3f595 100644
--- a/regress/netcat.c
+++ b/regress/netcat.c
@@ -69,6 +69,9 @@
# 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
#define DONT 254
diff --git a/regress/percent.sh b/regress/percent.sh
index 28781117e..7ed41845b 100644
--- a/regress/percent.sh
+++ b/regress/percent.sh
@@ -1,4 +1,4 @@
-# $OpenBSD: percent.sh,v 1.9 2020/07/17 07:10:24 dtucker Exp $
+# $OpenBSD: percent.sh,v 1.13 2021/07/25 12:13:03 dtucker Exp $
# Placed in the Public Domain.
tid="percent expansions"
@@ -79,7 +79,7 @@ for i in matchexec localcommand remotecommand controlpath identityagent \
fi
# Matches implementation in readconf.c:ssh_connection_hash()
HASH=`printf "${HOSTNAME}127.0.0.1${PORT}$REMUSER" |
- openssl sha1 | cut -f2 -d' '`
+ $OPENSSL_BIN sha1 | cut -f2 -d' '`
trial $i '%%' '%'
trial $i '%C' $HASH
trial $i '%i' $USERID
diff --git a/regress/reconfigure.sh b/regress/reconfigure.sh
index dd15eddb2..d5b4e9808 100644
--- a/regress/reconfigure.sh
+++ b/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/regress/rekey.sh b/regress/rekey.sh
index fd6a02cc7..61723cd86 100644
--- a/regress/rekey.sh
+++ b/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/regress/scp-uri.sh b/regress/scp-uri.sh
index c03d8bbe0..20ac3c89e 100644
--- a/regress/scp-uri.sh
+++ b/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/regress/scp.sh b/regress/scp.sh
index 62400efad..358a8df66 100644
--- a/regress/scp.sh
+++ b/regress/scp.sh
@@ -1,4 +1,4 @@
-# $OpenBSD: scp.sh,v 1.11 2019/07/19 03:45:44 djm Exp $
+# $OpenBSD: scp.sh,v 1.13 2021/08/10 03:35:45 djm Exp $
# Placed in the Public Domain.
tid="scp"
@@ -19,7 +19,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() {
@@ -28,109 +27,117 @@ scpclean() {
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"
-
-verbose "$tid: simple copy local file to local dir"
-scpclean
-cp ${DATA} ${COPY}
-$SCP $scpopts ${COPY} ${DIR} || fail "copy failed"
-cmp ${COPY} ${DIR}/copy || fail "corrupted copy"
-
-verbose "$tid: simple copy remote file to local dir"
-scpclean
-cp ${DATA} ${COPY}
-$SCP $scpopts somehost:${COPY} ${DIR} || fail "copy failed"
-cmp ${COPY} ${DIR}/copy || fail "corrupted copy"
+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: 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 file"
+ scpclean
+ $SCP $scpopts ${DATA} somehost:${COPY} || fail "copy failed"
+ cmp ${DATA} ${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 remote file to local file"
+ scpclean
+ $SCP $scpopts somehost:${DATA} ${COPY} || fail "copy failed"
+ cmp ${DATA} ${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 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: shell metacharacters"
-scpclean
-(cd ${DIR} && \
-touch '`touch metachartest`' && \
-$SCP $scpopts *metachar* ${DIR2} 2>/dev/null; \
-[ ! -f metachartest ] ) || fail "shell metacharacters"
+ 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"
-if [ ! -z "$SUDO" ]; then
- verbose "$tid: skipped file after scp -p with failed chown+utimes"
+ verbose "$tag: simple copy remote file 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
+ cp ${DATA} ${COPY}
+ $SCP $scpopts somehost:${COPY} ${DIR} || fail "copy failed"
+ cmp ${COPY} ${DIR}/copy || fail "corrupted copy"
-for i in 0 1 2 3 4 5 6 7; do
- verbose "$tid: disallow bad server #$i"
- SCPTESTMODE=badserver_$i
- export DIR SCPTESTMODE
+ verbose "$tag: recursive local dir to remote 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 ${DIR} somehost:${DIR2} || fail "copy failed"
+ diff ${DIFFOPT} ${DIR} ${DIR2} || fail "corrupted copy"
+ verbose "$tag: recursive local dir to local dir"
scpclean
- $SCP -r $scpopts somehost:${DATA} ${DIR2} >/dev/null 2>/dev/null
- [ -d ${DIR}/dotpathdir ] && fail "allows dir creation outside of subdir"
+ rm -rf ${DIR2}
+ cp ${DATA} ${DIR}/copy
+ $SCP $scpopts -r ${DIR} ${DIR2} || fail "copy failed"
+ diff ${DIFFOPT} ${DIR} ${DIR2} || fail "corrupted copy"
+ verbose "$tag: recursive remote dir to local dir"
scpclean
- $SCP -pr $scpopts somehost:${DATA} ${DIR2} >/dev/null 2>/dev/null
- [ ! -w ${DIR2} ] && fail "allows target root attribute change"
+ 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 $scpopts somehost:${DATA} ${DIR2} >/dev/null 2>/dev/null
- [ -e ${DIR2}/extrafile ] && fail "allows unauth object creation"
- rm -f ${DIR2}/extrafile
+ (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/regress/scp3.sh b/regress/scp3.sh
new file mode 100644
index 000000000..f71b15677
--- /dev/null
+++ b/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/regress/servcfginclude.sh b/regress/servcfginclude.sh
index b6a9a248f..518a703d1 100644
--- a/regress/servcfginclude.sh
+++ b/regress/servcfginclude.sh
@@ -9,17 +9,17 @@ Match host a
Match host b
Banner /bb
- Include $OBJ/sshd_config.i.*
+ Include $OBJ/sshd_config.i.* # comment
Match host c
- Include $OBJ/sshd_config.i.*
+ Include $OBJ/sshd_config.i.* # comment
Banner /cc
Match host m
Include $OBJ/sshd_config.i.*
Match Host d
- Banner /dd
+ Banner /dd # comment
Match Host e
Banner /ee
@@ -64,7 +64,7 @@ Match host a
Match host b
Banner /bbbb
-Match host c
+Match host c # comment
Banner /cccc
Match Host d
diff --git a/regress/sftp-perm.sh b/regress/sftp-perm.sh
index 304ca0ac5..de96a14da 100644
--- a/regress/sftp-perm.sh
+++ b/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/regress/ssh2putty.sh b/regress/ssh2putty.sh
index dcb975d95..9b0831039 100755
--- a/regress/ssh2putty.sh
+++ b/regress/ssh2putty.sh
@@ -1,5 +1,5 @@
#!/bin/sh
-# $OpenBSD: ssh2putty.sh,v 1.5 2019/11/21 05:18:47 tb 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/regress/sshcfgparse.sh b/regress/sshcfgparse.sh
index fc72a0a71..504853d32 100644
--- a/regress/sshcfgparse.sh
+++ b/regress/sshcfgparse.sh
@@ -1,4 +1,4 @@
-# $OpenBSD: sshcfgparse.sh,v 1.6 2019/12/21 02:33:07 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"
@@ -32,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}'`
@@ -62,34 +62,34 @@ 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.
# This is not tested when built !WITH_OPENSSL
if [ "$dsa" = "1" ]; then
- f=`${SSH} -GF none -opubkeyacceptedkeytypes=+ssh-dss-cert* host | \
- awk '/^pubkeyacceptedkeytypes /{print $2}'`
+ 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 -opubkeyacceptedkeytypes=+ssh-dss host | \
- awk '/^pubkeyacceptedkeytypes /{print $2}'`
+ 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
@@ -104,5 +104,16 @@ 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/regress/sshfp-connect.sh b/regress/sshfp-connect.sh
new file mode 100644
index 000000000..06e91cdbb
--- /dev/null
+++ b/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/regress/sshsig.sh b/regress/sshsig.sh
index 1e2f9dda4..fc300a8dc 100644
--- a/regress/sshsig.sh
+++ b/regress/sshsig.sh
@@ -1,4 +1,4 @@
-# $OpenBSD: sshsig.sh,v 1.4 2020/03/13 03:18:45 djm Exp $
+# $OpenBSD: sshsig.sh,v 1.7 2021/08/11 08:55:04 djm Exp $
# Placed in the Public Domain.
tid="sshsig"
@@ -12,12 +12,13 @@ sig_namespace="test-$$"
sig_principal="user-$$@example.com"
# Make a "wrong key"
-${SSHKEYGEN} -t ed25519 -f $OBJ/wrong-key -C "wrong trousers, Grommit" -N '' \
+${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} -t ed25519 -f $OBJ/sigca-key -C "CA" -N '' \
+${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
@@ -63,6 +64,17 @@ for t in $SIGNKEYS; do
< $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 \
@@ -106,6 +118,34 @@ for t in $SIGNKEYS; do
< $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\" " ;
@@ -116,7 +156,7 @@ for t in $SIGNKEYS; do
< $DATA >/dev/null 2>&1 && \
fail "accepted signature for $t key, but key is in revoked_keys"
- # public key not revoked, but other are present in revoked_keysfile
+ # 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 \
@@ -168,7 +208,7 @@ for t in $SIGNKEYS; do
fail "failed signature for $t cert"
# signing key listed as cert-authority
- (printf "$sig_principal 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 \
@@ -183,7 +223,7 @@ for t in $SIGNKEYS; do
fail "accepted signature for $t cert with CA not marked"
# mismatch between cert principal and file
- (printf "josef.k@example.com cert-authority" ;
+ (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 \
diff --git a/regress/test-exec.sh b/regress/test-exec.sh
index 5dc975d07..db6d6161a 100644
--- a/regress/test-exec.sh
+++ b/regress/test-exec.sh
@@ -1,21 +1,11 @@
-# $OpenBSD: test-exec.sh,v 1.76 2020/04/04 23:04:41 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*)
- os=cygwin
- ;;
-esac
+if [ ! -x "$TEST_SSH_ELAPSED_TIMES" ]; then
+ STARTTIME=`date '+%s'`
+fi
if [ ! -z "$TEST_SSH_PORT" ]; then
PORT="$TEST_SSH_PORT"
@@ -23,26 +13,6 @@ else
PORT=4242
fi
-# 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
-
-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'
@@ -69,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
@@ -92,6 +102,7 @@ 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}"
@@ -147,6 +158,9 @@ 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
@@ -242,10 +256,15 @@ 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"
@@ -315,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 ()
@@ -352,12 +388,6 @@ stop_sshd ()
fi
}
-make_tmpdir ()
-{
- SSH_REGRESS_TMP="$($OBJ/mkdtemp openssh-XXXXXXXX)" || \
- fatal "failed to create temporary directory"
-}
-
# helper
cleanup ()
{
@@ -372,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 ()
@@ -407,12 +442,6 @@ verbose ()
fi
}
-warn ()
-{
- echo "WARNING: $@" >>$TEST_SSH_LOGFILE
- echo "WARNING: $@"
-}
-
fail ()
{
save_debug_log "FAIL: $@"
@@ -457,7 +486,7 @@ 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=""
@@ -485,6 +514,11 @@ 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
trace "adding sshd_config option $TEST_SSH_SSHD_CONFOPTS"
echo "$TEST_SSH_SSHD_CONFOPTS" >> $OBJ/sshd_config
@@ -574,7 +608,7 @@ for t in ${SSH_HOSTKEY_TYPES}; do
) >> $OBJ/known_hosts
# 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
@@ -588,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
@@ -604,13 +639,13 @@ 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
@@ -634,8 +669,6 @@ 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
diff --git a/regress/unittests/authopt/Makefile b/regress/unittests/authopt/Makefile
index e8edc7b5f..71a7be5bd 100644
--- a/regress/unittests/authopt/Makefile
+++ b/regress/unittests/authopt/Makefile
@@ -1,4 +1,4 @@
-# $OpenBSD: Makefile,v 1.5 2020/04/06 09:43:55 dtucker Exp $
+# $OpenBSD: Makefile,v 1.6 2021/01/09 12:24:30 dtucker Exp $
PROG=test_authopt
SRCS=tests.c
@@ -10,7 +10,7 @@ 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+=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 ssh-ecdsa-sk.c ssh-sk.c
SRCS+=ssh-ed25519-sk.c sk-usbhid.c
diff --git a/regress/unittests/authopt/tests.c b/regress/unittests/authopt/tests.c
index 0e8aacb91..9873c09c6 100644
--- a/regress/unittests/authopt/tests.c
+++ b/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/regress/unittests/conversion/Makefile b/regress/unittests/conversion/Makefile
index 8b2a09cc3..5793c4934 100644
--- a/regress/unittests/conversion/Makefile
+++ b/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/regress/unittests/conversion/tests.c b/regress/unittests/conversion/tests.c
index ae1154d42..bbdc5f5a7 100644
--- a/regress/unittests/conversion/tests.c
+++ b/regress/unittests/conversion/tests.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: tests.c,v 1.2 2019/06/14 04:03:48 djm Exp $ */
+/* $OpenBSD: tests.c,v 1.3 2021/01/18 11:43:34 dtucker Exp $ */
/*
* Regress test for conversions
*
@@ -26,28 +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);
- ASSERT_LONG_EQ(convtime(buf), -1);
- 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/regress/unittests/hostkeys/Makefile b/regress/unittests/hostkeys/Makefile
index d841d96be..9a53423ee 100644
--- a/regress/unittests/hostkeys/Makefile
+++ b/regress/unittests/hostkeys/Makefile
@@ -1,4 +1,4 @@
-# $OpenBSD: Makefile,v 1.8 2020/04/06 09:43:56 dtucker Exp $
+# $OpenBSD: Makefile,v 1.9 2021/01/09 12:24:30 dtucker Exp $
PROG=test_hostkeys
SRCS=tests.c test_iterate.c
@@ -8,7 +8,7 @@ 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+=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 ssh-ecdsa-sk.c ssh-sk.c
SRCS+=ssh-ed25519-sk.c sk-usbhid.c
diff --git a/regress/unittests/hostkeys/test_iterate.c b/regress/unittests/hostkeys/test_iterate.c
index 5904121ef..a5b17d7e4 100644
--- a/regress/unittests/hostkeys/test_iterate.c
+++ b/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()
*
@@ -194,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,
@@ -207,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,
@@ -220,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,
@@ -233,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,
@@ -246,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,
@@ -259,6 +264,7 @@ struct expected expected_full[] = {
KEY_UNSPEC,
NULL,
NULL,
+ 0,
} },
{ NULL, -1, -1, 0, 0, 0, 0, -1, {
NULL,
@@ -272,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,
@@ -285,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,
@@ -298,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,
@@ -311,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,
@@ -324,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,
@@ -337,6 +348,7 @@ struct expected expected_full[] = {
KEY_UNSPEC,
NULL,
NULL,
+ 0,
} },
{ NULL, -1, -1, 0, 0, 0, 0, -1, {
NULL,
@@ -350,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,
@@ -363,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,
@@ -376,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,
@@ -389,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,
@@ -402,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,
@@ -415,6 +432,7 @@ struct expected expected_full[] = {
KEY_UNSPEC,
NULL,
NULL,
+ 0,
} },
{ NULL, -1, -1, 0, 0, 0, 0, -1, {
NULL,
@@ -428,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,
@@ -441,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,
@@ -454,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,
@@ -467,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,
@@ -480,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,
@@ -493,6 +516,7 @@ struct expected expected_full[] = {
KEY_UNSPEC,
NULL,
NULL,
+ 0,
} },
/*
* The next series have each key listed multiple times, as the
@@ -511,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,
@@ -524,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,
@@ -537,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,
@@ -550,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,
@@ -563,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,
@@ -576,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,
@@ -589,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,
@@ -602,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,
@@ -615,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,
@@ -628,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,
@@ -641,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,
@@ -654,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,
@@ -667,6 +703,7 @@ struct expected expected_full[] = {
KEY_UNSPEC,
NULL,
NULL,
+ 0,
} },
{ NULL, -1, -1, 0, 0, 0, 0, -1, {
NULL,
@@ -680,6 +717,7 @@ struct expected expected_full[] = {
KEY_UNSPEC,
NULL,
NULL,
+ 0,
} },
{ NULL, -1, -1, 0, 0, 0, 0, -1, {
NULL,
@@ -693,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,
@@ -706,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,
@@ -719,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,
@@ -732,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,
@@ -745,6 +787,7 @@ struct expected expected_full[] = {
KEY_UNSPEC,
NULL,
NULL,
+ 0,
} },
{ NULL, -1, -1, 0, 0, 0, 0, -1, {
NULL,
@@ -758,6 +801,7 @@ struct expected expected_full[] = {
KEY_UNSPEC,
NULL,
NULL,
+ 0,
} },
{ NULL, -1, -1, 0, 0, 0, 0, -1, {
NULL,
@@ -771,6 +815,7 @@ struct expected expected_full[] = {
KEY_UNSPEC,
NULL,
NULL,
+ 0,
} },
{ NULL, -1, -1, 0, HKF_MATCH_HOST, 0, 0, -1, {
NULL,
@@ -784,6 +829,7 @@ struct expected expected_full[] = {
KEY_UNSPEC,
NULL,
NULL,
+ 0,
} },
{ NULL, -1, -1, HKF_MATCH_HOST, 0, 0, 0, -1, {
NULL,
@@ -797,6 +843,7 @@ struct expected expected_full[] = {
KEY_UNSPEC,
NULL,
NULL,
+ 0,
} },
{ NULL, -1, -1, 0, HKF_MATCH_HOST, 0, 0, -1, {
NULL,
@@ -810,6 +857,7 @@ struct expected expected_full[] = {
KEY_UNSPEC,
NULL,
NULL,
+ 0,
} },
{ NULL, -1, -1, 0, HKF_MATCH_HOST, 0, 0, -1, {
NULL,
@@ -823,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,
@@ -836,6 +885,7 @@ struct expected expected_full[] = {
KEY_UNSPEC,
NULL, /* filled at runtime */
NULL,
+ 0,
} },
};
@@ -853,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();
@@ -864,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();
@@ -876,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();
@@ -888,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();
@@ -900,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();
@@ -912,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();
@@ -923,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();
@@ -934,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();
@@ -946,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();
@@ -958,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();
@@ -970,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();
@@ -982,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();
@@ -993,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();
@@ -1004,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();
@@ -1017,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();
@@ -1031,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();
@@ -1044,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();
@@ -1058,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/regress/unittests/kex/Makefile b/regress/unittests/kex/Makefile
index 1c5d68ce8..50b117c07 100644
--- a/regress/unittests/kex/Makefile
+++ b/regress/unittests/kex/Makefile
@@ -1,4 +1,4 @@
-# $OpenBSD: Makefile,v 1.10 2020/04/06 09:43:56 dtucker Exp $
+# $OpenBSD: Makefile,v 1.12 2021/01/09 12:24:30 dtucker Exp $
PROG=test_kex
SRCS=tests.c test_kex.c
@@ -8,7 +8,7 @@ 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+=addrmatch.c bitmap.c packet.c dispatch.c canohost.c ssh_api.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
@@ -23,8 +23,8 @@ SRCS+= kexgexs.c
SRCS+= kexc25519.c
SRCS+= smult_curve25519_ref.c
SRCS+= kexgen.c
-SRCS+= kexsntrup4591761x25519.c
-SRCS+= sntrup4591761.c
+SRCS+= kexsntrup761x25519.c
+SRCS+= sntrup761.c
SRCS+= utf8.c
SRCS+=digest-openssl.c
diff --git a/regress/unittests/kex/test_kex.c b/regress/unittests/kex/test_kex.c
index 0e7cd9e07..3bd71a9f4 100644
--- a/regress/unittests/kex/test_kex.c
+++ b/regress/unittests/kex/test_kex.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: test_kex.c,v 1.4 2019/01/21 12:35:20 djm Exp $ */
+/* $OpenBSD: test_kex.c,v 1.5 2020/12/29 01:02:15 djm Exp $ */
/*
* Regress test KEX
*
@@ -152,6 +152,7 @@ do_kex_with_key(char *kex, int keytype, int bits)
#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;
@@ -201,5 +202,8 @@ kex_tests(void)
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/regress/unittests/match/Makefile b/regress/unittests/match/Makefile
index 87e75826a..939163d30 100644
--- a/regress/unittests/match/Makefile
+++ b/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/regress/unittests/misc/Makefile b/regress/unittests/misc/Makefile
index 06e954cb8..656ae44db 100644
--- a/regress/unittests/misc/Makefile
+++ b/regress/unittests/misc/Makefile
@@ -1,12 +1,27 @@
-# $OpenBSD: Makefile,v 1.1 2019/04/28 22:53:26 dtucker Exp $
+# $OpenBSD: Makefile,v 1.7 2021/05/21 03:48:07 djm Exp $
PROG=test_misc
SRCS=tests.c
+SRCS+= test_convtime.c
+SRCS+= test_expand.c
+SRCS+= test_parse.c
+SRCS+= test_argv.c
+SRCS+= test_strdelim.c
# From usr.bin/ssh/Makefile.inc
-SRCS+=sshbuf.c sshbuf-getput-basic.c ssherr.c log.c xmalloc.c misc.c
-# From usr/bin/ssh/sshd/Makefile
-SRCS+=atomicio.c cleanup.c fatal.c
+SRCS+= sshbuf.c
+SRCS+= sshbuf-getput-basic.c
+SRCS+= sshbuf-misc.c
+SRCS+= ssherr.c
+SRCS+= log.c
+SRCS+= xmalloc.c
+SRCS+= misc.c
+SRCS+= match.c
+SRCS+= addr.c
+SRCS+= addrmatch.c
+
+# From usr.bin/ssh/sshd/Makefile
+SRCS+= atomicio.c cleanup.c fatal.c
REGRESS_TARGETS=run-regress-${PROG}
diff --git a/regress/unittests/misc/test_argv.c b/regress/unittests/misc/test_argv.c
new file mode 100644
index 000000000..2cfebf2d9
--- /dev/null
+++ b/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/regress/unittests/misc/test_convtime.c b/regress/unittests/misc/test_convtime.c
new file mode 100644
index 000000000..8f9be89ff
--- /dev/null
+++ b/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/regress/unittests/misc/test_expand.c b/regress/unittests/misc/test_expand.c
new file mode 100644
index 000000000..513c69bce
--- /dev/null
+++ b/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/regress/unittests/misc/test_parse.c b/regress/unittests/misc/test_parse.c
new file mode 100644
index 000000000..727ff3dea
--- /dev/null
+++ b/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/regress/unittests/misc/test_strdelim.c b/regress/unittests/misc/test_strdelim.c
new file mode 100644
index 000000000..1d9133d4b
--- /dev/null
+++ b/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/regress/unittests/misc/tests.c b/regress/unittests/misc/tests.c
index 0bd0c84f9..b0b7cd433 100644
--- a/regress/unittests/misc/tests.c
+++ b/regress/unittests/misc/tests.c
@@ -1,161 +1,38 @@
-/* $OpenBSD: tests.c,v 1.3 2020/05/29 04:32:26 dtucker Exp $ */
+/* $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.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)
{
- int port, parseerr;
- char *user, *host, *path, *ret;
-
- 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();
-
- TEST_START("misc_convtime");
- ASSERT_LONG_EQ(convtime("1"), 1);
- ASSERT_LONG_EQ(convtime("2s"), 2);
- ASSERT_LONG_EQ(convtime("3m"), 180);
- ASSERT_LONG_EQ(convtime("1m30"), 90);
- ASSERT_LONG_EQ(convtime("1m30s"), 90);
- ASSERT_LONG_EQ(convtime("1h1s"), 3601);
- ASSERT_LONG_EQ(convtime("1h30m"), 90 * 60);
- ASSERT_LONG_EQ(convtime("1d"), 24 * 60 * 60);
- ASSERT_LONG_EQ(convtime("1w"), 7 * 24 * 60 * 60);
- ASSERT_LONG_EQ(convtime("1w2d3h4m5"), 788645);
- ASSERT_LONG_EQ(convtime("1w2d3h4m5s"), 788645);
- /* any negative number or error returns -1 */
- ASSERT_LONG_EQ(convtime("-1"), -1);
- ASSERT_LONG_EQ(convtime(""), -1);
- ASSERT_LONG_EQ(convtime("trout"), -1);
- ASSERT_LONG_EQ(convtime("-77"), -1);
- TEST_DONE();
-
- TEST_START("dollar_expand");
- if (setenv("FOO", "bar", 1) != 0)
- abort();
- if (setenv("BAR", "baz", 1) != 0)
- abort();
- if (unsetenv("BAZ") != 0)
- abort();
-#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();
+ test_parse();
+ test_convtime();
+ test_expand();
+ test_argv();
+ test_strdelim();
}
diff --git a/regress/unittests/sshbuf/Makefile b/regress/unittests/sshbuf/Makefile
index 5f6c4426a..a8ddfaf7e 100644
--- a/regress/unittests/sshbuf/Makefile
+++ b/regress/unittests/sshbuf/Makefile
@@ -1,4 +1,4 @@
-# $OpenBSD: Makefile,v 1.8 2020/01/26 00:09:50 djm Exp $
+# $OpenBSD: Makefile,v 1.10 2021/01/09 12:24:31 dtucker Exp $
# $OpenBSD: Makefile,v 1.8 2020/01/26 00:09:50 djm Exp $
@@ -15,6 +15,7 @@ SRCS+=test_sshbuf_fixed.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 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} ${UNITTEST_ARGS}
diff --git a/regress/unittests/sshkey/Makefile b/regress/unittests/sshkey/Makefile
index 29c9b3ba7..d4a892375 100644
--- a/regress/unittests/sshkey/Makefile
+++ b/regress/unittests/sshkey/Makefile
@@ -1,4 +1,4 @@
-# $OpenBSD: Makefile,v 1.10 2020/04/06 09:43:56 dtucker 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
@@ -8,7 +8,7 @@ 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+=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 ssh-ecdsa-sk.c ssh-sk.c
SRCS+=ssh-ed25519-sk.c sk-usbhid.c
diff --git a/regress/unittests/sshsig/Makefile b/regress/unittests/sshsig/Makefile
index 4b607df45..65564d1b2 100644
--- a/regress/unittests/sshsig/Makefile
+++ b/regress/unittests/sshsig/Makefile
@@ -1,4 +1,4 @@
-# $OpenBSD: Makefile,v 1.1 2020/06/19 04:32:09 djm Exp $
+# $OpenBSD: Makefile,v 1.2 2021/01/09 12:24:31 dtucker Exp $
PROG=test_sshsig
SRCS=tests.c
@@ -8,7 +8,7 @@ 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+=addrmatch.c bitmap.c sshsig.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
diff --git a/regress/unittests/sshsig/webauthn.html b/regress/unittests/sshsig/webauthn.html
index 953041e61..1869c8b37 100644
--- a/regress/unittests/sshsig/webauthn.html
+++ b/regress/unittests/sshsig/webauthn.html
@@ -37,6 +37,8 @@ Lots of debugging is printed along the way.
<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>
@@ -45,6 +47,8 @@ Lots of debugging is printed along the way.
<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>
@@ -241,12 +245,16 @@ var SSHMSG = function() {
this.r = []
}
-SSHMSG.prototype.serialise = function() {
+SSHMSG.prototype.length = function() {
let len = 0
for (buf of this.r) {
len += buf.length
}
- let r = new ArrayBuffer(len)
+ 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) {
@@ -281,6 +289,12 @@ 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)
@@ -392,6 +406,9 @@ function enrollSuccess(result) {
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)
@@ -417,6 +434,14 @@ function enrollSuccess(result) {
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"
}
@@ -456,7 +481,15 @@ function decodeAuthenticatorData(authData, expectCred) {
return r
}
-function reformatPubkey(pk, rpid) {
+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)
@@ -471,6 +504,10 @@ function reformatPubkey(pk, rpid) {
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
@@ -479,6 +516,43 @@ function reformatPubkey(pk, rpid) {
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")
diff --git a/regress/valgrind-unit.sh b/regress/valgrind-unit.sh
index 4143ead4b..193289e6b 100755
--- a/regress/valgrind-unit.sh
+++ b/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/sandbox-pledge.c b/sandbox-pledge.c
index d28fc2727..302f1cfed 100644
--- a/sandbox-pledge.c
+++ b/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/sandbox-rlimit.c b/sandbox-rlimit.c
index 0bff3dfba..26c61d264 100644
--- a/sandbox-rlimit.c
+++ b/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/sandbox-seccomp-filter.c b/sandbox-seccomp-filter.c
index e0768c063..798b24bd8 100644
--- a/sandbox-seccomp-filter.c
+++ b/sandbox-seccomp-filter.c
@@ -154,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
@@ -181,6 +184,9 @@ static const struct sock_filter preauth_insns[] = {
#ifdef __NR_ipc
SC_DENY(__NR_ipc, EACCES),
#endif
+#ifdef __NR_statx
+ SC_DENY(__NR_statx, EACCES),
+#endif
/* Syscalls to permit */
#ifdef __NR_brk
@@ -204,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
@@ -267,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
@@ -372,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 */
@@ -401,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/scp.0 b/scp.0
index 826457f6a..6f1fc7548 100644
--- a/scp.0
+++ b/scp.0
@@ -4,15 +4,19 @@ NAME
scp M-bM-^@M-^S OpenSSH secure file copy
SYNOPSIS
- scp [-346ABCpqrTv] [-c cipher] [-F ssh_config] [-i identity_file]
- [-J destination] [-l limit] [-o ssh_option] [-P port] [-S program]
- source ... target
+ scp [-346ABCOpqRrsTv] [-c cipher] [-D sftp_server_path] [-F ssh_config]
+ [-i identity_file] [-J destination] [-l limit] [-o ssh_option]
+ [-P port] [-S program] source ... target
DESCRIPTION
- scp copies files between hosts on a network. It uses ssh(1) for data
- transfer, and uses the same authentication and provides the same security
- as ssh(1). scp will ask for passwords or passphrases if they are needed
- for authentication.
+ scp copies files between hosts on a network.
+
+ It uses ssh(1) for data transfer, and uses the same authentication and
+ provides the same security as a login session. The scp protocol requires
+ execution of the remote user's shell to perform glob(3) pattern matching.
+
+ scp will ask for passwords or passphrases if they are needed for
+ authentication.
The source and target may be specified as a local pathname, a remote host
with optional path in the form [user@]host:[path], or a URI in the form
@@ -21,15 +25,16 @@ DESCRIPTION
containing M-bM-^@M-^X:M-bM-^@M-^Y as host specifiers.
When copying between two remote hosts, if the URI format is used, a port
- may only be specified on the target if the -3 option is used.
+ cannot be specified on the target if the -R option is used.
The options are as follows:
-3 Copies between two remote hosts are transferred through the local
host. Without this option the data is copied directly between
- the two remote hosts. Note that this option disables the
- progress meter and selects batch mode for the second host, since
- scp cannot ask for passwords or passphrases for both hosts.
+ the two remote hosts. Note that, when using the legacy SCP
+ protocol (the default), this option selects batch mode for the
+ second host as scp cannot ask for passwords or passphrases for
+ both hosts. This mode is the default.
-4 Forces scp to use IPv4 addresses only.
@@ -48,6 +53,11 @@ DESCRIPTION
Selects the cipher to use for encrypting the data transfer. This
option is directly passed to ssh(1).
+ -D sftp_server_path
+ When using the SFTP protocol support via -M, connect directly to
+ a local SFTP server program rather than a remote one via ssh(1).
+ This option may be useful in debugging the client and server.
+
-F ssh_config
Specifies an alternative per-user configuration file for ssh.
This option is directly passed to ssh(1).
@@ -68,6 +78,12 @@ DESCRIPTION
-l limit
Limits the used bandwidth, specified in Kbit/s.
+ -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.
+
-o ssh_option
Can be used to pass options to ssh in the format used in
ssh_config(5). This is useful for specifying options for which
@@ -86,7 +102,6 @@ DESCRIPTION
CanonicalizePermittedCNAMEs
CASignatureAlgorithms
CertificateFile
- ChallengeResponseAuthentication
CheckHostIP
Ciphers
Compression
@@ -100,8 +115,8 @@ DESCRIPTION
GSSAPIDelegateCredentials
HashKnownHosts
Host
+ HostbasedAcceptedAlgorithms
HostbasedAuthentication
- HostbasedKeyTypes
HostKeyAlgorithms
HostKeyAlias
Hostname
@@ -112,6 +127,7 @@ DESCRIPTION
KbdInteractiveAuthentication
KbdInteractiveDevices
KexAlgorithms
+ KnownHostsCommand
LogLevel
MACs
NoHostAuthenticationForLocalhost
@@ -122,7 +138,7 @@ DESCRIPTION
PreferredAuthentications
ProxyCommand
ProxyJump
- PubkeyAcceptedKeyTypes
+ PubkeyAcceptedAlgorithms
PubkeyAuthentication
RekeyLimit
SendEnv
@@ -147,6 +163,11 @@ DESCRIPTION
-q Quiet mode: disables the progress meter as well as warning and
diagnostic messages from ssh(1).
+ -R Copies between two remote hosts are performed by connecting to
+ the origin host and executing scp there. This requires that scp
+ running on the origin host can authenticate to the destination
+ host without requiring a password.
+
-r Recursively copy entire directories. Note that scp follows
symbolic links encountered in the tree traversal.
@@ -154,6 +175,15 @@ DESCRIPTION
Name of program to use for the encrypted connection. The program
must understand ssh(1) options.
+ -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 glob(3)
+ wildcards.
+
+ A near-future release of OpenSSH will make the SFTP protocol the
+ default. This option will be deleted before the end of 2022.
+
-T Disable strict filename checking. By default when copying files
from a remote host to a local directory scp checks that the
received filenames match those requested on the command-line to
@@ -173,7 +203,7 @@ EXIT STATUS
SEE ALSO
sftp(1), ssh(1), ssh-add(1), ssh-agent(1), ssh-keygen(1), ssh_config(5),
- sshd(8)
+ sftp-server(8), sshd(8)
HISTORY
scp is based on the rcp program in BSD source code from the Regents of
@@ -183,4 +213,4 @@ AUTHORS
Timo Rinne <tri@iki.fi>
Tatu Ylonen <ylo@cs.hut.fi>
-OpenBSD 6.8 August 3, 2020 OpenBSD 6.8
+OpenBSD 6.9 August 11, 2021 OpenBSD 6.9
diff --git a/scp.1 b/scp.1
index feb839e9c..68aac04b2 100644
--- a/scp.1
+++ b/scp.1
@@ -8,9 +8,9 @@
.\"
.\" Created: Sun May 7 00:14:37 1995 ylo
.\"
-.\" $OpenBSD: scp.1,v 1.90 2020/08/03 02:43:41 djm Exp $
+.\" $OpenBSD: scp.1,v 1.100 2021/08/11 14:07:54 naddy Exp $
.\"
-.Dd $Mdocdate: August 3 2020 $
+.Dd $Mdocdate: August 11 2021 $
.Dt SCP 1
.Os
.Sh NAME
@@ -18,8 +18,9 @@
.Nd OpenSSH secure file copy
.Sh SYNOPSIS
.Nm scp
-.Op Fl 346ABCpqrTv
+.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
@@ -31,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.
@@ -62,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:
@@ -74,10 +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 and selects batch mode
-for the second host, since
+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
@@ -104,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
@@ -130,6 +143,12 @@ 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
@@ -154,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
@@ -168,8 +186,8 @@ 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
@@ -180,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
@@ -190,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
@@ -218,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
@@ -230,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
@@ -259,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/scp.c b/scp.c
index 6ae17061d..e039350c6 100644
--- a/scp.c
+++ b/scp.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: scp.c,v 1.212 2020/08/03 02:43:41 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).
@@ -97,6 +97,14 @@
#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>
@@ -123,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;
@@ -143,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;
@@ -151,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;
@@ -161,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)
@@ -169,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);
@@ -176,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)
{
@@ -238,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)
@@ -273,8 +304,8 @@ do_cmd(char *host, char *remuser, int port, char *cmd, int *fdin, int *fdout)
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]);
@@ -283,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);
@@ -292,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. */
@@ -319,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,
@@ -382,28 +416,40 @@ 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();
@@ -413,6 +459,7 @@ main(int argc, char **argv)
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]);
@@ -420,6 +467,8 @@ 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;
@@ -432,7 +481,7 @@ main(int argc, char **argv)
fflag = Tflag = tflag = 0;
while ((ch = getopt(argc, argv,
- "12346ABCTdfpqrtvF:J:P:S:c:i:l:o:")) != -1) {
+ "12346ABCTdfOpqRrstvD:F:J:M:P:S:c:i:l:o:")) != -1) {
switch (ch) {
/* User-visible flags. */
case '1':
@@ -448,9 +497,15 @@ main(int argc, char **argv)
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':
@@ -461,6 +516,12 @@ main(int argc, char **argv)
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)
@@ -490,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':
@@ -523,9 +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);
@@ -572,11 +642,11 @@ main(int argc, char **argv)
(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
@@ -630,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;
@@ -848,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
@@ -887,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));
@@ -915,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++) {
@@ -939,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);
@@ -987,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);
@@ -1001,6 +1157,8 @@ toremote(int argc, char **argv)
}
}
out:
+ if (mode == MODE_SFTP)
+ free(conn);
free(tuser);
free(thost);
free(targ);
@@ -1010,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));
@@ -1050,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;
@@ -1067,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)
{
@@ -1228,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) || \
@@ -1279,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;
@@ -1423,8 +1738,7 @@ 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) == -1)
goto bad;
@@ -1554,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)
{
@@ -1596,9 +1983,9 @@ void
usage(void)
{
(void) fprintf(stderr,
- "usage: scp [-346ABCpqrTv] [-c cipher] [-F ssh_config] [-i identity_file]\n"
- " [-J destination] [-l limit] [-o ssh_option] [-P port]\n"
- " [-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);
}
@@ -1737,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/servconf.c b/servconf.c
index f08e37477..a765e4e05 100644
--- a/servconf.c
+++ b/servconf.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: servconf.c,v 1.369 2020/08/28 03:15:52 dtucker 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
@@ -122,13 +122,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_auth_options = -1;
- options->pubkey_key_types = NULL;
+ options->pubkey_accepted_algos = NULL;
options->kerberos_authentication = -1;
options->kerberos_or_local_passwd = -1;
options->kerberos_ticket_cleanup = -1;
@@ -138,7 +140,6 @@ 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_allowlist = NULL;
@@ -163,6 +164,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;
@@ -221,14 +225,14 @@ assemble_algorithms(ServerOptions *o)
#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, 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_key_types, def_key, all_key);
- ASSEMBLE(pubkey_key_types, 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);
@@ -243,39 +247,13 @@ assemble_algorithms(ServerOptions *o)
free(def_sig);
}
-static void
-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)++;
-}
-
-static void
-array_append(const char *file, const int line, const char *directive,
- char ***array, u_int *lp, const char *s)
-{
- array_append2(file, line, directive, array, NULL, lp, s, 0);
-}
-
void
servconf_add_hostkey(const char *file, const int line,
ServerOptions *options, const char *path, int userprovided)
{
char *apath = derelativise_path(path);
- array_append2(file, line, "HostKey",
+ opt_array_append2(file, line, "HostKey",
&options->host_key_files, &options->host_key_file_userprovided,
&options->num_host_key_files, apath, userprovided);
free(apath);
@@ -287,7 +265,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);
}
@@ -326,6 +304,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)
@@ -383,9 +363,7 @@ fill_default_server_options(ServerOptions *options)
if (options->password_authentication == -1)
options->password_authentication = 1;
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) {
@@ -417,6 +395,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)
@@ -428,11 +412,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("[default]", 0, "AuthorizedKeysFiles",
+ opt_array_append("[default]", 0, "AuthorizedKeysFiles",
&options->authorized_keys_files,
&options->num_authkeys_files,
_PATH_SSH_USER_PERMITTED_KEYS);
- array_append("[default]", 0, "AuthorizedKeysFiles",
+ opt_array_append("[default]", 0, "AuthorizedKeysFiles",
&options->authorized_keys_files,
&options->num_authkeys_files,
_PATH_SSH_USER_PERMITTED_KEYS2);
@@ -504,8 +488,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,
@@ -515,12 +498,12 @@ 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,
@@ -563,21 +546,25 @@ 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
@@ -608,8 +595,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 },
@@ -645,6 +632,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 },
@@ -748,7 +737,7 @@ derelativise_path(const char *path)
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;
@@ -791,7 +780,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));
@@ -928,10 +917,10 @@ process_permitopen_list(struct ssh *ssh, ServerOpCodes opcode,
ch = '\0';
host = hpdelim2(&arg, &ch);
if (host == NULL || ch == '/')
- fatal("%s: missing host in %s", __func__, what);
+ 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);
@@ -1056,18 +1045,29 @@ 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;
}
@@ -1262,7 +1262,7 @@ process_server_config_line_depth(ServerOptions *options, char *line,
struct connection_info *connectinfo, int *inc_flags, int depth,
struct include_list *includes)
{
- char ch, *cp, ***chararrayptr, **charptr, *arg, *arg2, *p;
+ 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;
@@ -1274,6 +1274,9 @@ process_server_config_line_depth(ServerOptions *options, char *line,
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)
@@ -1284,32 +1287,43 @@ process_server_config_line_depth(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 && opcode != sInclude)
- debug3("%s:%d setting %s %s", filename, linenum, arg, cp);
+ 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;
}
}
@@ -1321,15 +1335,17 @@ process_server_config_line_depth(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);
@@ -1342,7 +1358,7 @@ process_server_config_line_depth(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);
@@ -1354,7 +1370,7 @@ process_server_config_line_depth(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);
@@ -1379,16 +1395,15 @@ process_server_config_line_depth(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;
@@ -1397,7 +1412,7 @@ process_server_config_line_depth(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);
@@ -1416,7 +1431,7 @@ process_server_config_line_depth(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);
@@ -1428,7 +1443,7 @@ process_server_config_line_depth(ServerOptions *options, char *line,
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);
@@ -1438,7 +1453,7 @@ process_server_config_line_depth(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);
@@ -1449,7 +1464,7 @@ process_server_config_line_depth(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);
@@ -1461,6 +1476,10 @@ process_server_config_line_depth(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;
@@ -1485,10 +1504,10 @@ process_server_config_line_depth(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);
@@ -1503,24 +1522,24 @@ process_server_config_line_depth(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 = strdelim(&cp)) && *arg != '\0') {
+ while ((arg = argv_next(&ac, &av)) != NULL) {
if (strcasecmp(arg, "none") == 0)
continue;
if (strcasecmp(arg, "touch-required") == 0)
@@ -1528,9 +1547,9 @@ process_server_config_line_depth(ServerOptions *options, char *line,
else if (strcasecmp(arg, "verify-required") == 0)
value |= PUBKEYAUTH_VERIFY_REQUIRED;
else {
- fatal("%s line %d: unsupported "
- "PubkeyAuthOptions option %s",
- filename, linenum, arg);
+ error("%s line %d: unsupported %s option %s",
+ filename, linenum, keyword, arg);
+ goto out;
}
}
if (*activep && *intptr == -1)
@@ -1573,10 +1592,6 @@ process_server_config_line_depth(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;
@@ -1592,10 +1607,10 @@ process_server_config_line_depth(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;
@@ -1631,10 +1646,10 @@ process_server_config_line_depth(ServerOptions *options, char *line,
case sPermitUserEnvironment:
intptr = &options->permit_user_env;
charptr = &options->permit_user_env_allowlist;
- 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);
value = 0;
p = NULL;
if (strcmp(arg, "yes") == 0)
@@ -1660,25 +1675,26 @@ process_server_config_line_depth(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;
@@ -1697,7 +1713,7 @@ process_server_config_line_depth(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'",
@@ -1708,7 +1724,7 @@ process_server_config_line_depth(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'",
@@ -1717,6 +1733,33 @@ process_server_config_line_depth(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;
@@ -1736,55 +1779,51 @@ process_server_config_line_depth(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);
+ 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'.",
@@ -1794,9 +1833,10 @@ process_server_config_line_depth(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);
+ 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'.",
@@ -1806,10 +1846,10 @@ process_server_config_line_depth(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 == '^' ?
arg + 1 : arg))
@@ -1824,20 +1864,20 @@ process_server_config_line_depth(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);
@@ -1846,7 +1886,7 @@ process_server_config_line_depth(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);
@@ -1857,10 +1897,10 @@ process_server_config_line_depth(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,
@@ -1869,15 +1909,54 @@ process_server_config_line_depth(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;
@@ -1897,24 +1976,29 @@ process_server_config_line_depth(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 */
@@ -1932,13 +2016,13 @@ process_server_config_line_depth(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);
}
@@ -1946,23 +2030,23 @@ process_server_config_line_depth(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) {
@@ -1970,8 +2054,8 @@ process_server_config_line_depth(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;
@@ -1982,7 +2066,12 @@ process_server_config_line_depth(ServerOptions *options, char *line,
"command-line option");
}
value = 0;
- while ((arg2 = strdelim(&cp)) != NULL && *arg2 != '\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 != '~') {
@@ -2022,9 +2111,8 @@ process_server_config_line_depth(ServerOptions *options, char *line,
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);
+ fatal("%s line %d: include \"%s\" glob "
+ "failed", filename, linenum, arg);
}
/*
* If no entry matched then record a
@@ -2038,17 +2126,15 @@ process_server_config_line_depth(ServerOptions *options, char *line,
item, entry);
}
if (gbuf.gl_pathc > INT_MAX)
- fatal("%s: too many glob results", __func__);
+ 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("%s: sshbuf_new failed",
- __func__);
- }
+ if ((item->contents = sshbuf_new()) == NULL)
+ fatal_f("sshbuf_new failed");
load_server_config(item->filename,
item->contents);
parse_server_config_depth(options,
@@ -2065,23 +2151,32 @@ process_server_config_line_depth(ServerOptions *options, char *line,
free(arg);
}
if (value == 0) {
- fatal("%s line %d: Include missing filename argument",
- filename, linenum);
+ 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,
+ "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 = (*inc_flags & SSHCFG_NEVERMATCH) ? 0 : value;
- /* The MATCH_ONLY is applicable only until the first match block */
+ /*
+ * 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:
@@ -2093,10 +2188,10 @@ process_server_config_line_depth(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) {
@@ -2107,7 +2202,7 @@ process_server_config_line_depth(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) {
/*
@@ -2120,21 +2215,18 @@ process_server_config_line_depth(ServerOptions *options, char *line,
ch = '\0';
p = hpdelim2(&arg, &ch);
if (p == NULL || ch == '/') {
- fatal("%s line %d: missing host in %s",
- filename, linenum,
- lookup_opcode_name(opcode));
+ 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);
@@ -2142,21 +2234,22 @@ process_server_config_line_depth(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;
@@ -2171,10 +2264,10 @@ process_server_config_line_depth(ServerOptions *options, char *line,
case sSecurityKeyProvider:
charptr = &options->sk_provider;
- 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 = strcasecmp(arg, "internal") == 0 ?
xstrdup(arg) : derelativise_path(arg);
@@ -2185,16 +2278,19 @@ process_server_config_line_depth(ServerOptions *options, char *line,
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;
@@ -2202,120 +2298,102 @@ process_server_config_line_depth(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;
@@ -2325,13 +2403,13 @@ process_server_config_line_depth(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;
@@ -2346,13 +2424,13 @@ process_server_config_line_depth(ServerOptions *options, char *line,
"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);
@@ -2364,19 +2442,27 @@ process_server_config_line_depth(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
@@ -2402,7 +2488,7 @@ load_server_config(const char *filename, struct sshbuf *conf)
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);
@@ -2410,26 +2496,24 @@ load_server_config(const char *filename, struct sshbuf *conf)
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("%s: allocate failed: %s", __func__, ssh_err(r));
+ (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
@@ -2463,12 +2547,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;
}
}
@@ -2597,11 +2681,11 @@ parse_server_config_depth(ServerOptions *options, const char *filename,
if (depth < 0 || depth > SERVCONF_MAX_DEPTH)
fatal("Too many recursive configuration includes");
- debug2("%s: config %s len %zu%s", __func__, filename, sshbuf_len(conf),
+ 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__);
+ fatal_f("sshbuf_dup_string failed");
linenum = 1;
while ((cp = strsep(&cbuf, "\n")) != NULL) {
if (process_server_config_line_depth(options, cp,
@@ -2812,8 +2896,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);
@@ -2838,6 +2920,7 @@ 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);
dump_cfg_string(sMacs, o->macs);
@@ -2858,9 +2941,9 @@ dump_config(ServerOptions *o)
dump_cfg_string(sHostKeyAgent, o->host_key_agent);
dump_cfg_string(sKexAlgorithms, o->kex_algorithms);
dump_cfg_string(sCASignatureAlgorithms, o->ca_sign_algorithms);
- dump_cfg_string(sHostbasedAcceptedKeyTypes, o->hostbased_key_types);
+ dump_cfg_string(sHostbasedAcceptedAlgorithms, o->hostbased_accepted_algos);
dump_cfg_string(sHostKeyAlgorithms, o->hostkeyalgorithms);
- dump_cfg_string(sPubkeyAcceptedKeyTypes, o->pubkey_key_types);
+ 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
@@ -2873,9 +2956,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);
@@ -2884,6 +2967,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++)
@@ -2892,6 +2977,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++) {
diff --git a/servconf.h b/servconf.h
index 1df8f3db8..dd5cbc15c 100644
--- a/servconf.h
+++ b/servconf.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: servconf.h,v 1.146 2020/08/27 01:07:10 djm Exp $ */
+/* $OpenBSD: servconf.h,v 1.155 2021/07/02 05:11:21 dtucker Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -93,6 +93,7 @@ typedef struct {
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 */
@@ -118,13 +119,15 @@ 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. */
@@ -143,7 +146,6 @@ 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 */
@@ -175,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 */
@@ -230,7 +235,7 @@ 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 */
@@ -266,8 +271,8 @@ TAILQ_HEAD(include_list, include_item);
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_allowlist); \
@@ -277,22 +282,24 @@ TAILQ_HEAD(include_list, include_item);
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(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 *, struct include_list *includes);
+ 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 include_list *includes, struct connection_info *);
+ struct include_list *includes, struct connection_info *);
void parse_server_match_config(ServerOptions *,
- struct include_list *includes, struct connection_info *);
+ 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);
diff --git a/serverloop.c b/serverloop.c
index 48d936d2e..e8cfb9205 100644
--- a/serverloop.c
+++ b/serverloop.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: serverloop.c,v 1.223 2020/07/03 06:29:57 djm 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
@@ -88,11 +88,6 @@ 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) */
@@ -115,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) == -1) {
- 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*/
@@ -201,18 +148,18 @@ client_alive_check(struct ssh *ssh)
(r = sshpkt_put_cstring(ssh, "keepalive@openssh.com"))
!= 0 ||
(r = sshpkt_put_u8(ssh, 1)) != 0) /* boolean: want reply */
- fatal("%s: %s", __func__, ssh_err(r));
+ fatal_fr(r, "compose");
} else {
channel_request_start(ssh, channel_id,
"keepalive@openssh.com", 1);
}
if ((r = sshpkt_send(ssh)) != 0)
- fatal("%s: %s", __func__, ssh_err(r));
+ 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).
*/
@@ -220,16 +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);
@@ -262,7 +209,6 @@ 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
@@ -280,26 +226,26 @@ wait_until_can_do_something(struct ssh *ssh,
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 the select timed out, or returned for some other reason
+ * 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 +
@@ -310,8 +256,6 @@ wait_until_can_do_something(struct ssh *ssh,
last_client_time = now;
}
}
-
- notify_done(*readsetp);
}
/*
@@ -332,21 +276,17 @@ process_input(struct ssh *ssh, fd_set *readset, int connection_in)
ssh_remote_ipaddr(ssh), ssh_remote_port(ssh));
return -1;
} else if (len == -1) {
- 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. */
- if ((r = ssh_packet_process_incoming(ssh, buf, len))
- != 0)
- fatal("%s: ssh_packet_process_incoming: %s",
- __func__, ssh_err(r));
+ 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;
}
@@ -378,13 +318,8 @@ 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 ||
@@ -393,19 +328,21 @@ collect_children(struct ssh *ssh)
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.");
+ 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 = ssh_packet_get_connection_in(ssh);
@@ -417,10 +354,7 @@ server_loop2(struct ssh *ssh, Authctxt *authctxt)
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(ssh);
@@ -438,8 +372,19 @@ server_loop2(struct ssh *ssh, Authctxt *authctxt)
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);
@@ -447,11 +392,13 @@ 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;
+ /* 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);
@@ -494,17 +441,17 @@ server_request_direct_tcpip(struct ssh *ssh, int *reason, const char **errmsg)
(r = sshpkt_get_end(ssh)) != 0)
sshpkt_fatal(ssh, r, "%s: parse packet", __func__);
if (target_port > 0xFFFF) {
- error("%s: invalid target port", __func__);
+ error_f("invalid target port");
*reason = SSH2_OPEN_ADMINISTRATIVELY_PROHIBITED;
goto out;
}
if (originator_port > 0xFFFF) {
- error("%s: invalid originator port", __func__);
+ error_f("invalid originator port");
*reason = SSH2_OPEN_ADMINISTRATIVELY_PROHIBITED;
goto out;
}
- debug("%s: originator %s port %u, target %s port %u", __func__,
+ debug_f("originator %s port %u, target %s port %u",
originator, originator_port, target, target_port);
/* XXX fine grained permissions */
@@ -537,7 +484,7 @@ server_request_direct_streamlocal(struct ssh *ssh)
int r;
if (pw == NULL || !the_authctxt->valid)
- fatal("%s: no/invalid user", __func__);
+ fatal_f("no/invalid user");
if ((r = sshpkt_get_cstring(ssh, &target, NULL)) != 0 ||
(r = sshpkt_get_cstring(ssh, &originator, NULL)) != 0 ||
@@ -545,11 +492,11 @@ server_request_direct_streamlocal(struct ssh *ssh)
(r = sshpkt_get_end(ssh)) != 0)
sshpkt_fatal(ssh, r, "%s: parse packet", __func__);
if (originator_port > 0xFFFF) {
- error("%s: invalid originator port", __func__);
+ 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 */
@@ -597,7 +544,7 @@ server_request_tun(struct ssh *ssh)
if ((r = sshpkt_get_u32(ssh, &tun)) != 0)
sshpkt_fatal(ssh, r, "%s: parse device", __func__);
if (tun > INT_MAX) {
- debug("%s: invalid tun", __func__);
+ debug_f("invalid tun");
goto done;
}
if (auth_opts->force_tun_device != -1) {
@@ -686,7 +633,7 @@ server_input_channel_open(int type, u_int32_t seq, struct ssh *ssh)
(r = sshpkt_get_u32(ssh, &rwindow)) != 0 ||
(r = sshpkt_get_u32(ssh, &rmaxpack)) != 0)
sshpkt_fatal(ssh, r, "%s: parse packet", __func__);
- debug("%s: ctype %s rchan %u win %u max %u", __func__,
+ debug_f("ctype %s rchan %u win %u max %u",
ctype, rchan, rwindow, rmaxpack);
if (strcmp(ctype, "session") == 0) {
@@ -699,7 +646,7 @@ 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;
@@ -716,7 +663,7 @@ server_input_channel_open(int type, u_int32_t seq, struct ssh *ssh)
}
}
} else {
- debug("%s: failure %s", __func__, ctype);
+ 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 ||
@@ -743,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));
@@ -752,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;
}
/*
@@ -761,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;
}
/*
@@ -771,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);
@@ -785,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(ssh, key_prv, key_pub, &sig, &slen,
sshbuf_ptr(sigbuf), sshbuf_len(sigbuf),
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;
}
}
@@ -822,19 +766,19 @@ server_input_global_request(int type, u_int32_t seq, struct ssh *ssh)
memset(&fwd, 0, sizeof(fwd));
if (pw == NULL || !the_authctxt->valid)
- fatal("%s: no/invalid user", __func__);
+ fatal_f("no/invalid user");
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("%s: rtype %s want_reply %d", __func__, rtype, want_reply);
+ debug_f("rtype %s want_reply %d", rtype, want_reply);
/* -R style forwarding */
if (strcmp(rtype, "tcpip-forward") == 0) {
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("%s: tcpip-forward listen %s port %u", __func__,
+ debug_f("tcpip-forward listen %s port %u",
fwd.listen_host, port);
if (port <= INT_MAX)
fwd.listen_port = (int)port;
@@ -845,7 +789,7 @@ server_input_global_request(int type, u_int32_t seq, struct ssh *ssh)
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;
ssh_packet_send_debug(ssh, "Server has disabled port forwarding.");
} else {
@@ -854,16 +798,16 @@ server_input_global_request(int type, u_int32_t seq, struct ssh *ssh)
&allocated_listen_port, &options.fwd_opts);
}
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) {
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("%s: cancel-tcpip-forward addr %s port %d", __func__,
+ debug_f("cancel-tcpip-forward addr %s port %d",
fwd.listen_host, port);
if (port <= INT_MAX) {
fwd.listen_port = (int)port;
@@ -872,7 +816,7 @@ server_input_global_request(int type, u_int32_t seq, struct ssh *ssh)
} else if (strcmp(rtype, "streamlocal-forward@openssh.com") == 0) {
if ((r = sshpkt_get_cstring(ssh, &fwd.listen_path, NULL)) != 0)
sshpkt_fatal(ssh, r, "%s: parse streamlocal-forward@openssh.com", __func__);
- debug("%s: streamlocal-forward listen path %s", __func__,
+ debug_f("streamlocal-forward listen path %s",
fwd.listen_path);
/* check permissions */
@@ -891,7 +835,7 @@ server_input_global_request(int type, u_int32_t seq, struct ssh *ssh)
} else if (strcmp(rtype, "cancel-streamlocal-forward@openssh.com") == 0) {
if ((r = sshpkt_get_cstring(ssh, &fwd.listen_path, NULL)) != 0)
sshpkt_fatal(ssh, r, "%s: parse cancel-streamlocal-forward@openssh.com", __func__);
- debug("%s: cancel-streamlocal-forward path %s", __func__,
+ debug_f("cancel-streamlocal-forward path %s",
fwd.listen_path);
success = channel_cancel_rport_listener(ssh, &fwd);
@@ -947,8 +891,7 @@ server_input_channel_req(int type, u_int32_t seq, struct ssh *ssh)
success = session_input_channel_req(ssh, c, rtype);
if (want_reply && !(c->flags & CHAN_CLOSE_SENT)) {
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, success ?
SSH2_MSG_CHANNEL_SUCCESS : SSH2_MSG_CHANNEL_FAILURE)) != 0 ||
(r = sshpkt_put_u32(ssh, c->remote_id)) != 0 ||
diff --git a/session.c b/session.c
index 27ca8a104..5f423f9f6 100644
--- a/session.c
+++ b/session.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: session.c,v 1.324 2020/07/07 02:47:21 deraadt 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
@@ -253,7 +253,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);
}
@@ -269,16 +269,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;
@@ -305,11 +305,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);
@@ -321,11 +320,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);
@@ -400,18 +398,17 @@ do_exec_no_pty(struct ssh *ssh, Session *s, const char *command)
/* Allocate pipes for communicating with the program. */
if (pipe(pin) == -1) {
- error("%s: pipe in: %.100s", __func__, strerror(errno));
+ error_f("pipe in: %.100s", strerror(errno));
return -1;
}
if (pipe(pout) == -1) {
- error("%s: pipe out: %.100s", __func__, strerror(errno));
+ error_f("pipe out: %.100s", strerror(errno));
close(pin[0]);
close(pin[1]);
return -1;
}
if (pipe(perr) == -1) {
- error("%s: pipe err: %.100s", __func__,
- strerror(errno));
+ error_f("pipe err: %.100s", strerror(errno));
close(pin[0]);
close(pin[1]);
close(pout[0]);
@@ -426,12 +423,11 @@ do_exec_no_pty(struct ssh *ssh, Session *s, const char *command)
/* Uses socket pairs to communicate with the program. */
if (socketpair(AF_UNIX, SOCK_STREAM, 0, inout) == -1) {
- error("%s: socketpair #1: %.100s", __func__, strerror(errno));
+ error_f("socketpair #1: %.100s", strerror(errno));
return -1;
}
if (socketpair(AF_UNIX, SOCK_STREAM, 0, err) == -1) {
- error("%s: socketpair #2: %.100s", __func__,
- strerror(errno));
+ error_f("socketpair #2: %.100s", strerror(errno));
close(inout[0]);
close(inout[1]);
return -1;
@@ -443,7 +439,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]);
@@ -578,14 +574,14 @@ do_exec_pty(struct ssh *ssh, Session *s, const char *command)
* detect and gracefully fail out-of-fd conditions.
*/
if ((fdout = dup(ptyfd)) == -1) {
- error("%s: dup #1: %s", __func__, strerror(errno));
+ 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)) == -1) {
- error("%s: dup #2: %s", __func__, strerror(errno));
+ error_f("dup #2: %s", strerror(errno));
close(ttyfd);
close(ptyfd);
close(fdout);
@@ -595,7 +591,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);
@@ -948,8 +944,8 @@ read_etc_default_login(char ***env, u_int *envsize, uid_t uid)
#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;
@@ -965,8 +961,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);
}
@@ -980,7 +976,7 @@ copy_environment_blacklist(char **source, char ***env, u_int *envsize,
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
@@ -1109,7 +1105,7 @@ 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 allowlist */
if (options.permit_user_env_allowlist == NULL ||
@@ -1124,8 +1120,8 @@ 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_allowlist);
}
@@ -1142,15 +1138,15 @@ do_setup_env(struct ssh *ssh, Session *s, const char *shell)
* Don't allow PAM-internal env vars to leak
* back into the session environment.
*/
-#define PAM_ENV_BLACKLIST "SSH_AUTH_INFO*,SSH_CONNECTION*"
+#define PAM_ENV_DENYLIST "SSH_AUTH_INFO*,SSH_CONNECTION*"
p = fetch_pam_child_environment();
- copy_environment_blacklist(p, &env, &envsize,
- PAM_ENV_BLACKLIST);
+ copy_environment_denylist(p, &env, &envsize,
+ PAM_ENV_DENYLIST);
free_pam_environment(p);
p = fetch_pam_environment();
- copy_environment_blacklist(p, &env, &envsize,
- PAM_ENV_BLACKLIST);
+ copy_environment_denylist(p, &env, &envsize,
+ PAM_ENV_DENYLIST);
free_pam_environment(p);
}
#endif /* USE_PAM */
@@ -1220,7 +1216,7 @@ do_rc_files(struct ssh *ssh, Session *s, const char *shell)
stat(user_rc, &st) >= 0) {
if (xasprintf(&cmd, "%s -c '%s %s'", shell, _PATH_BSHELL,
user_rc) == -1)
- fatal("%s: xasprintf: %s", __func__, strerror(errno));
+ fatal_f("xasprintf: %s", strerror(errno));
if (debug_flag)
fprintf(stderr, "Running %s\n", cmd);
f = popen(cmd, "w");
@@ -1257,7 +1253,7 @@ do_rc_files(struct ssh *ssh, Session *s, const char *shell)
s->auth_proto, s->auth_data);
}
if (xasprintf(&cmd, "%s -q -", options.xauth_location) == -1)
- fatal("%s: xasprintf: %s", __func__, strerror(errno));
+ fatal_f("xasprintf: %s", strerror(errno));
f = popen(cmd, "w");
if (f) {
fprintf(f, "remove %s\n",
@@ -1291,11 +1287,8 @@ do_nologin(struct passwd *pw)
return;
nl = def_nl;
#endif
- if (stat(nl, &sb) == -1) {
- if (nl != def_nl)
- free(nl);
+ if (stat(nl, &sb) == -1)
return;
- }
/* /etc/nologin exists. Print its contents if we can and exit. */
logit("User %.100s not allowed because %s exists", pw->pw_name, nl);
@@ -1336,10 +1329,10 @@ 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 "
@@ -1357,8 +1350,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);
}
@@ -1396,7 +1388,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);
@@ -1727,11 +1719,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;
@@ -1753,13 +1745,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;
@@ -1768,16 +1760,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;
@@ -1793,12 +1783,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);
}
@@ -2147,35 +2136,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;
}
@@ -2197,7 +2184,7 @@ session_auth_agent_req(struct ssh *ssh, Session *s)
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) {
@@ -2215,10 +2202,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
@@ -2276,13 +2263,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)
@@ -2338,10 +2325,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);
@@ -2354,13 +2341,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.
@@ -2387,10 +2374,9 @@ session_exit_message(struct ssh *ssh, Session *s, int status)
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);
@@ -2414,7 +2400,7 @@ session_exit_message(struct ssh *ssh, Session *s, int 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
@@ -2469,7 +2455,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)
@@ -2490,13 +2476,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
diff --git a/sftp-client.c b/sftp-client.c
index b8e131be6..5bfff90d1 100644
--- a/sftp-client.c
+++ b/sftp-client.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: sftp-client.c,v 1.136 2020/05/15 03:57:33 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;
@@ -87,15 +101,52 @@ struct sftp_conn {
#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)
@@ -139,8 +190,9 @@ 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));
+ 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)
@@ -150,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);
@@ -159,7 +211,7 @@ 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));
+ fatal_fr(r, "reserve");
if (atomicio6(read, conn->fd_in, p, msg_len, sftpio,
conn->limit_kbps > 0 ? &conn->bwlimit_in : NULL)
!= msg_len) {
@@ -184,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);
@@ -202,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);
}
@@ -222,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);
@@ -235,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);
@@ -261,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);
@@ -282,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)
{
@@ -298,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
@@ -324,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;
@@ -344,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)
@@ -358,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
@@ -382,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;
@@ -405,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);
@@ -432,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);
@@ -445,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;
@@ -470,6 +526,14 @@ 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_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",
@@ -483,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;
@@ -505,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;
@@ -512,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);
@@ -549,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,
@@ -578,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);
@@ -587,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);
@@ -598,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;
@@ -610,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);
@@ -624,11 +767,9 @@ 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);
goto out;
@@ -828,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;
@@ -837,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);
@@ -857,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;
@@ -866,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);
@@ -885,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)
@@ -894,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++;
@@ -903,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" :
@@ -939,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++;
@@ -948,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);
@@ -975,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++;
@@ -983,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);
@@ -1010,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);
@@ -1043,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);
@@ -1057,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);
@@ -1066,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);
@@ -1101,12 +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__);
+ 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);
@@ -1129,12 +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__);
+ 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);
@@ -1156,13 +1331,13 @@ do_lsetstat(struct sftp_conn *conn, const char *path, Attrib *a)
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_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("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "compose");
send_msg(conn, msg);
sshbuf_free(msg);
@@ -1182,23 +1357,76 @@ 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__);
+ 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
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;
@@ -1208,13 +1436,7 @@ do_download(struct sftp_conn *conn, const char *remote_path,
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;
@@ -1240,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);
@@ -1287,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);
@@ -1301,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;
@@ -1324,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);
}
@@ -1339,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;
@@ -1364,8 +1565,7 @@ 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);
@@ -1495,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);
@@ -1516,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;
}
@@ -1550,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;
@@ -1581,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;
@@ -1589,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;
@@ -1600,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;
}
@@ -1620,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);
@@ -1665,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;
}
@@ -1676,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;
@@ -1722,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));
@@ -1731,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 ||
@@ -1744,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);
@@ -1763,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);
@@ -1828,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;
@@ -1836,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);
@@ -1851,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);
@@ -1865,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;
@@ -1875,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));
@@ -1901,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!",
@@ -1924,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;
@@ -1935,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)
{
@@ -1956,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/sftp-client.h b/sftp-client.h
index 63a9b8b13..7d0bd12ae 100644
--- a/sftp-client.h
+++ b/sftp-client.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: sftp-client.h,v 1.28 2019/01/16 23:23:45 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);
@@ -97,11 +113,17 @@ 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 *);
@@ -124,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
@@ -137,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/sftp-common.c b/sftp-common.c
index 677f27d63..3ad57673d 100644
--- a/sftp-common.c
+++ b/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.
@@ -136,7 +136,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/sftp-server.0 b/sftp-server.0
index 36c5f846f..341f48df4 100644
--- a/sftp-server.0
+++ b/sftp-server.0
@@ -20,7 +20,7 @@ DESCRIPTION
Valid options are:
-d start_directory
- specifies an alternate starting directory for users. The
+ Specifies an alternate starting directory for users. The
pathname may contain the following tokens that are expanded at
runtime: %% is replaced by a literal '%', %d is replaced by the
home directory of the user being authenticated, and %u is
@@ -48,26 +48,26 @@ DESCRIPTION
levels of debugging output. The default is ERROR.
-P denied_requests
- Specify a comma-separated list of SFTP protocol requests that are
- banned by the server. sftp-server will reply to any denied
+ Specifies a comma-separated list of SFTP protocol requests that
+ are banned by the server. sftp-server will reply to any denied
request with a failure. The -Q flag can be used to determine the
supported request types. If both denied and allowed lists are
specified, then the denied list is applied before the allowed
list.
-p allowed_requests
- Specify a comma-separated list of SFTP protocol requests that are
- permitted by the server. All request types that are not on the
- allowed list will be logged and replied to with a failure
+ Specifies a comma-separated list of SFTP protocol requests that
+ are permitted by the server. All request types that are not on
+ the allowed list will be logged and replied to with a failure
message.
Care must be taken when using this feature to ensure that
requests made implicitly by SFTP clients are permitted.
-Q protocol_feature
- Query protocol features supported by sftp-server. At present the
- only feature that may be queried is M-bM-^@M-^\requestsM-bM-^@M-^], which may be used
- to deny or allow specific requests (flags -P and -p
+ Queries protocol features supported by sftp-server. At present
+ the only feature that may be queried is M-bM-^@M-^\requestsM-bM-^@M-^], which may be
+ used to deny or allow specific requests (flags -P and -p
respectively).
-R Places this instance of sftp-server into a read-only mode.
@@ -95,4 +95,4 @@ HISTORY
AUTHORS
Markus Friedl <markus@openbsd.org>
-OpenBSD 6.8 June 22, 2020 OpenBSD 6.8
+OpenBSD 6.9 July 27, 2021 OpenBSD 6.9
diff --git a/sftp-server.8 b/sftp-server.8
index f057da3b8..5311bf929 100644
--- a/sftp-server.8
+++ b/sftp-server.8
@@ -1,4 +1,4 @@
-.\" $OpenBSD: sftp-server.8,v 1.30 2020/06/22 06:36:40 jmc 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,7 +22,7 @@
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
.\"
-.Dd $Mdocdate: June 22 2020 $
+.Dd $Mdocdate: July 27 2021 $
.Dt SFTP-SERVER 8
.Os
.Sh NAME
@@ -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,
@@ -100,7 +100,7 @@ DEBUG and DEBUG1 are equivalent.
DEBUG2 and DEBUG3 each specify higher levels of debugging output.
The default is ERROR.
.It Fl P Ar denied_requests
-Specify a comma-separated list of SFTP protocol requests that are banned by
+Specifies a comma-separated list of SFTP protocol requests that are banned by
the server.
.Nm
will reply to any denied request with a failure.
@@ -110,7 +110,7 @@ flag can be used to determine the supported request types.
If both denied and allowed lists are specified, then the denied list is
applied before the allowed list.
.It Fl p Ar allowed_requests
-Specify a comma-separated list of SFTP protocol requests that are permitted
+Specifies a comma-separated list of SFTP protocol requests that are permitted
by the server.
All request types that are not on the allowed list will be logged and replied
to with a failure message.
@@ -118,7 +118,7 @@ to with a failure message.
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 ,
diff --git a/sftp-server.c b/sftp-server.c
index 55386fa9a..18d194911 100644
--- a/sftp-server.c
+++ b/sftp-server.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: sftp-server.c,v 1.119 2020/07/17 03:51:32 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
@@ -53,6 +54,9 @@
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;
@@ -110,6 +114,8 @@ 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 {
@@ -146,15 +152,30 @@ static const struct sftp_handler handlers[] = {
/* SSH2_FXP_EXTENDED submessages */
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(const struct sftp_handler *h)
{
@@ -489,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);
}
@@ -522,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);
@@ -543,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);
}
@@ -578,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);
@@ -602,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);
}
@@ -622,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 ||
@@ -636,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
@@ -650,30 +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 */
- (r = sshbuf_put_cstring(msg, "lsetstat@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);
}
@@ -689,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);
@@ -726,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);
@@ -738,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;
@@ -746,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) == -1) {
- error("process_read: seek failed");
- status = errno_to_portable(errno);
- } else {
- ret = read(fd, buf, len);
- if (ret == -1) {
- 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);
}
@@ -787,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);
@@ -797,21 +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) == -1) {
+ lseek(fd, off, SEEK_SET) == -1) {
status = errno_to_portable(errno);
- error("%s: seek failed", __func__);
+ error_f("seek \"%.100s\": %s", handle_to_name(handle),
+ strerror(errno));
} else {
/* XXX ATOMICIO ? */
ret = write(fd, data, len);
if (ret == -1) {
- error("%s: write: %s", __func__,
- strerror(errno));
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("%s: nothing at all written", __func__);
+ debug2_f("nothing at all written");
status = SSH2_FX_FAILURE;
}
}
@@ -829,7 +881,7 @@ 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);
@@ -866,7 +918,7 @@ 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);
@@ -917,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) {
@@ -964,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);
@@ -1028,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);
@@ -1059,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);
@@ -1113,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);
@@ -1132,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;
@@ -1151,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);
@@ -1169,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);
@@ -1197,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);
@@ -1256,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);
@@ -1281,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);
@@ -1301,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);
@@ -1320,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);
@@ -1328,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
@@ -1338,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) {
@@ -1359,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);
@@ -1376,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)
@@ -1397,7 +1449,7 @@ process_extended_lsetstat(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: lsetstat name \"%s\"", id, name);
if (a.flags & SSH2_FILEXFER_ATTR_SIZE) {
@@ -1438,25 +1490,113 @@ process_extended_lsetstat(u_int32_t id)
}
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);
}
@@ -1487,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:
@@ -1501,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])) {
@@ -1535,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 */
@@ -1693,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));
@@ -1722,8 +1862,7 @@ 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)
@@ -1745,10 +1884,8 @@ sftp_server_main(int argc, char **argv, struct passwd *user_pw)
} 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)) {
@@ -1756,10 +1893,8 @@ sftp_server_main(int argc, char **argv, struct passwd *user_pw)
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");
}
/*
@@ -1771,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/sftp.0 b/sftp.0
index 99288ebcf..3a340f68d 100644
--- a/sftp.0
+++ b/sftp.0
@@ -125,7 +125,6 @@ DESCRIPTION
CanonicalizePermittedCNAMEs
CASignatureAlgorithms
CertificateFile
- ChallengeResponseAuthentication
CheckHostIP
Ciphers
Compression
@@ -139,8 +138,8 @@ DESCRIPTION
GSSAPIDelegateCredentials
HashKnownHosts
Host
+ HostbasedAcceptedAlgorithms
HostbasedAuthentication
- HostbasedKeyTypes
HostKeyAlgorithms
HostKeyAlias
Hostname
@@ -151,6 +150,7 @@ DESCRIPTION
KbdInteractiveAuthentication
KbdInteractiveDevices
KexAlgorithms
+ KnownHostsCommand
LogLevel
MACs
NoHostAuthenticationForLocalhost
@@ -161,7 +161,7 @@ DESCRIPTION
PreferredAuthentications
ProxyCommand
ProxyJump
- PubkeyAcceptedKeyTypes
+ PubkeyAcceptedAlgorithms
PubkeyAuthentication
RekeyLimit
SendEnv
@@ -218,22 +218,31 @@ INTERACTIVE COMMANDS
change directory to the one the session started in.
chgrp [-h] grp path
- Change group of file path to grp. If the -h flag is specified,
- then symlinks will not be followed. path may contain glob(7)
+ Change group of file path to grp. path may contain glob(7)
characters and may match multiple files. grp must be a numeric
GID.
+ If the -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.
+
chmod [-h] mode path
- Change permissions of file path to mode. If the -h flag is
- specified, then symlinks will not be followed. path may contain
+ Change permissions of file path to mode. path may contain
glob(7) characters and may match multiple files.
+ If the -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.
+
chown [-h] own path
- Change owner of file path to own. If the -h flag is specified,
- then symlinks will not be followed. path may contain glob(7)
+ Change owner of file path to own. path may contain glob(7)
characters and may match multiple files. own must be a numeric
UID.
+ If the -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.
+
df [-hi] [path]
Display usage information for the filesystem holding the current
directory (or path if specified). If the -h flag is specified,
@@ -399,4 +408,4 @@ SEE ALSO
T. Ylonen and S. Lehtinen, SSH File Transfer Protocol, draft-ietf-secsh-
filexfer-00.txt, January 2001, work in progress material.
-OpenBSD 6.8 August 3, 2020 OpenBSD 6.8
+OpenBSD 6.9 July 2, 2021 OpenBSD 6.9
diff --git a/sftp.1 b/sftp.1
index 1cfa5ec22..7eebeeacb 100644
--- a/sftp.1
+++ b/sftp.1
@@ -1,4 +1,4 @@
-.\" $OpenBSD: sftp.1,v 1.132 2020/08/03 02:43:41 djm Exp $
+.\" $OpenBSD: sftp.1,v 1.138 2021/07/02 05:11:21 dtucker Exp $
.\"
.\" Copyright (c) 2001 Damien Miller. All rights reserved.
.\"
@@ -22,7 +22,7 @@
.\" (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 3 2020 $
+.Dd $Mdocdate: July 2 2021 $
.Dt SFTP 1
.Os
.Sh NAME
@@ -232,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
@@ -246,8 +245,8 @@ 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
@@ -258,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
@@ -268,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
@@ -348,15 +348,18 @@ Change group of file
.Ar path
to
.Ar grp .
-If the
-.Fl h
-flag is specified, then symlinks will not be followed.
.Ar path
may contain
.Xr glob 7
characters and may match multiple files.
.Ar grp
must be a numeric GID.
+.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
@@ -366,13 +369,16 @@ Change permissions of file
.Ar path
to
.Ar mode .
-If the
-.Fl h
-flag is specified, then symlinks will not be followed.
.Ar path
may contain
.Xr glob 7
characters and may match multiple files.
+.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
@@ -382,15 +388,18 @@ Change owner of file
.Ar path
to
.Ar own .
-If the
-.Fl h
-flag is specified, then symlinks will not be followed.
.Ar path
may contain
.Xr glob 7
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
diff --git a/sftp.c b/sftp.c
index c88c86118..69f84cdcf 100644
--- a/sftp.c
+++ b/sftp.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: sftp.c,v 1.201 2020/08/03 02:43:41 djm Exp $ */
+/* $OpenBSD: sftp.c,v 1.211 2021/08/12 09:59:00 schwarze Exp $ */
/*
* Copyright (c) 2001-2004 Damien Miller <djm@openbsd.org>
*
@@ -70,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;
@@ -82,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. */
@@ -255,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)
@@ -385,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 && !path_absolute(p)) {
- 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)
@@ -608,40 +598,6 @@ parse_no_flags(const char *cmd, char **argv, int argc)
}
static int
-is_dir(const char *path)
-{
- struct stat sb;
-
- /* XXX: report errors? */
- if (stat(path, &sb) == -1)
- return(0);
-
- return(S_ISDIR(sb.st_mode));
-}
-
-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));
-}
-
-/* Check whether path returned from glob(..., GLOB_MARK, ...) is a directory */
-static int
-pathname_is_dir(const char *pathname)
-{
- size_t l = strlen(pathname);
-
- return l > 0 && pathname[l - 1] == '/';
-}
-
-static int
process_get(struct sftp_conn *conn, const char *src, const char *dst,
const char *pwd, int pflag, int rflag, int resume, int fflag)
{
@@ -670,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;
@@ -687,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);
@@ -706,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,
@@ -792,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,
@@ -939,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
@@ -1172,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,
@@ -1330,7 +1291,7 @@ parse_args(const char **cpp, int *ignore_errors, int *disable_echo, 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 */
@@ -1488,16 +1449,16 @@ parse_args(const char **cpp, int *ignore_errors, int *disable_echo, int *aflag,
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) */
@@ -2101,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;
@@ -2243,8 +2204,6 @@ interactive_loop(struct sftp_conn *conn, char *file1, char *file2)
interactive = !batchmode && isatty(STDIN_FILENO);
err = 0;
for (;;) {
- ssh_signal(SIGINT, SIG_IGN);
-
if (el == NULL) {
if (interactive)
printf("sftp> ");
@@ -2257,11 +2216,22 @@ interactive_loop(struct sftp_conn *conn, char *file1, char *file2)
#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)) {
@@ -2386,8 +2356,8 @@ 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;
/* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */
diff --git a/sk-api.h b/sk-api.h
index df17ca540..74921d4c3 100644
--- a/sk-api.h
+++ b/sk-api.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: sk-api.h,v 1.11 2020/09/09 03:08:01 djm Exp $ */
+/* $OpenBSD: sk-api.h,v 1.12 2021/02/18 02:15:07 djm Exp $ */
/*
* Copyright (c) 2019 Google LLC
*
@@ -86,7 +86,7 @@ int sk_enroll(uint32_t alg, const uint8_t *challenge, size_t challenge_len,
struct sk_option **options, struct sk_enroll_response **enroll_response);
/* Sign a challenge */
-int sk_sign(uint32_t alg, const uint8_t *message, size_t message_len,
+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);
diff --git a/sk-usbhid.c b/sk-usbhid.c
index 007c59644..438980889 100644
--- a/sk-usbhid.c
+++ b/sk-usbhid.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: sk-usbhid.c,v 1.26 2020/09/09 03:08:01 djm Exp $ */
+/* $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
@@ -26,6 +26,7 @@
#include <stdio.h>
#include <stddef.h>
#include <stdarg.h>
+#include <time.h>
#ifdef HAVE_SHA2_H
#include <sha2.h>
#endif
@@ -117,7 +118,7 @@ int sk_enroll(uint32_t alg, const uint8_t *challenge, size_t challenge_len,
struct sk_option **options, struct sk_enroll_response **enroll_response);
/* Sign a challenge */
-int sk_sign(uint32_t alg, const uint8_t *message, size_t message_len,
+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);
@@ -668,7 +669,7 @@ sk_enroll(uint32_t alg, const uint8_t *challenge, size_t challenge_len,
{
fido_cred_t *cred = NULL;
const uint8_t *ptr;
- uint8_t user_id[32];
+ uint8_t user_id[32], chall_hash[32];
struct sk_usbhid *sk = NULL;
struct sk_enroll_response *response = NULL;
size_t len;
@@ -720,8 +721,13 @@ sk_enroll(uint32_t alg, const uint8_t *challenge, size_t challenge_len,
skdebug(__func__, "fido_cred_set_type: %s", fido_strerr(r));
goto out;
}
- if ((r = fido_cred_set_clientdata_hash(cred, challenge,
- challenge_len)) != FIDO_OK) {
+ 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;
@@ -814,7 +820,7 @@ sk_enroll(uint32_t alg, const uint8_t *challenge, size_t challenge_len,
}
if ((ptr = fido_cred_x5c_ptr(cred)) != NULL) {
len = fido_cred_x5c_len(cred);
- debug3("%s: attestation cert len=%zu", __func__, len);
+ skdebug(__func__, "attestation cert len=%zu", len);
if ((response->attestation_cert = calloc(1, len)) == NULL) {
skdebug(__func__, "calloc attestation cert failed");
goto out;
@@ -824,7 +830,7 @@ sk_enroll(uint32_t alg, const uint8_t *challenge, size_t challenge_len,
}
if ((ptr = fido_cred_authdata_ptr(cred)) != NULL) {
len = fido_cred_authdata_len(cred);
- debug3("%s: authdata len=%zu", __func__, len);
+ skdebug(__func__, "authdata len=%zu", len);
if ((response->authdata = calloc(1, len)) == NULL) {
skdebug(__func__, "calloc authdata failed");
goto out;
diff --git a/sntrup4591761.c b/sntrup4591761.c
deleted file mode 100644
index 61fe2483f..000000000
--- a/sntrup4591761.c
+++ /dev/null
@@ -1,1083 +0,0 @@
-/* $OpenBSD: sntrup4591761.c,v 1.3 2019/01/30 19:51:15 markus Exp $ */
-
-/*
- * Public Domain, Authors:
- * - Daniel J. Bernstein
- * - Chitchanok Chuengsatiansup
- * - Tanja Lange
- * - Christine van Vredendaal
- */
-
-#include "includes.h"
-
-#include <string.h>
-#include "crypto_api.h"
-
-/* from libpqcrypto-20180314/crypto_kem/sntrup4591761/ref/int32_sort.h */
-#ifndef int32_sort_h
-#define int32_sort_h
-
-
-static void int32_sort(crypto_int32 *,int);
-
-#endif
-
-/* from libpqcrypto-20180314/crypto_kem/sntrup4591761/ref/int32_sort.c */
-/* See https://ntruprime.cr.yp.to/software.html for detailed documentation. */
-
-
-static void minmax(crypto_int32 *x,crypto_int32 *y)
-{
- crypto_uint32 xi = *x;
- crypto_uint32 yi = *y;
- crypto_uint32 xy = xi ^ yi;
- crypto_uint32 c = yi - xi;
- c ^= xy & (c ^ yi);
- c >>= 31;
- c = -c;
- c &= xy;
- *x = xi ^ c;
- *y = yi ^ c;
-}
-
-static void int32_sort(crypto_int32 *x,int n)
-{
- int top,p,q,i;
-
- if (n < 2) return;
- top = 1;
- while (top < n - top) top += top;
-
- for (p = top;p > 0;p >>= 1) {
- for (i = 0;i < n - p;++i)
- if (!(i & p))
- minmax(x + i,x + i + p);
- for (q = top;q > p;q >>= 1)
- for (i = 0;i < n - q;++i)
- if (!(i & p))
- minmax(x + i + p,x + i + q);
- }
-}
-
-/* from libpqcrypto-20180314/crypto_kem/sntrup4591761/ref/small.h */
-#ifndef small_h
-#define small_h
-
-
-typedef crypto_int8 small;
-
-static void small_encode(unsigned char *,const small *);
-
-static void small_decode(small *,const unsigned char *);
-
-
-static void small_random(small *);
-
-static void small_random_weightw(small *);
-
-#endif
-
-/* from libpqcrypto-20180314/crypto_kem/sntrup4591761/ref/mod3.h */
-#ifndef mod3_h
-#define mod3_h
-
-
-/* -1 if x is nonzero, 0 otherwise */
-static inline int mod3_nonzero_mask(small x)
-{
- return -x*x;
-}
-
-/* input between -100000 and 100000 */
-/* output between -1 and 1 */
-static inline small mod3_freeze(crypto_int32 a)
-{
- a -= 3 * ((10923 * a) >> 15);
- a -= 3 * ((89478485 * a + 134217728) >> 28);
- return a;
-}
-
-static inline small mod3_minusproduct(small a,small b,small c)
-{
- crypto_int32 A = a;
- crypto_int32 B = b;
- crypto_int32 C = c;
- return mod3_freeze(A - B * C);
-}
-
-static inline small mod3_plusproduct(small a,small b,small c)
-{
- crypto_int32 A = a;
- crypto_int32 B = b;
- crypto_int32 C = c;
- return mod3_freeze(A + B * C);
-}
-
-static inline small mod3_product(small a,small b)
-{
- return a * b;
-}
-
-static inline small mod3_sum(small a,small b)
-{
- crypto_int32 A = a;
- crypto_int32 B = b;
- return mod3_freeze(A + B);
-}
-
-static inline small mod3_reciprocal(small a1)
-{
- return a1;
-}
-
-static inline small mod3_quotient(small num,small den)
-{
- return mod3_product(num,mod3_reciprocal(den));
-}
-
-#endif
-
-/* from libpqcrypto-20180314/crypto_kem/sntrup4591761/ref/modq.h */
-#ifndef modq_h
-#define modq_h
-
-
-typedef crypto_int16 modq;
-
-/* -1 if x is nonzero, 0 otherwise */
-static inline int modq_nonzero_mask(modq x)
-{
- crypto_int32 r = (crypto_uint16) x;
- r = -r;
- r >>= 30;
- return r;
-}
-
-/* input between -9000000 and 9000000 */
-/* output between -2295 and 2295 */
-static inline modq modq_freeze(crypto_int32 a)
-{
- a -= 4591 * ((228 * a) >> 20);
- a -= 4591 * ((58470 * a + 134217728) >> 28);
- return a;
-}
-
-static inline modq modq_minusproduct(modq a,modq b,modq c)
-{
- crypto_int32 A = a;
- crypto_int32 B = b;
- crypto_int32 C = c;
- return modq_freeze(A - B * C);
-}
-
-static inline modq modq_plusproduct(modq a,modq b,modq c)
-{
- crypto_int32 A = a;
- crypto_int32 B = b;
- crypto_int32 C = c;
- return modq_freeze(A + B * C);
-}
-
-static inline modq modq_product(modq a,modq b)
-{
- crypto_int32 A = a;
- crypto_int32 B = b;
- return modq_freeze(A * B);
-}
-
-static inline modq modq_square(modq a)
-{
- crypto_int32 A = a;
- return modq_freeze(A * A);
-}
-
-static inline modq modq_sum(modq a,modq b)
-{
- crypto_int32 A = a;
- crypto_int32 B = b;
- return modq_freeze(A + B);
-}
-
-static inline modq modq_reciprocal(modq a1)
-{
- modq a2 = modq_square(a1);
- modq a3 = modq_product(a2,a1);
- modq a4 = modq_square(a2);
- modq a8 = modq_square(a4);
- modq a16 = modq_square(a8);
- modq a32 = modq_square(a16);
- modq a35 = modq_product(a32,a3);
- modq a70 = modq_square(a35);
- modq a140 = modq_square(a70);
- modq a143 = modq_product(a140,a3);
- modq a286 = modq_square(a143);
- modq a572 = modq_square(a286);
- modq a1144 = modq_square(a572);
- modq a1147 = modq_product(a1144,a3);
- modq a2294 = modq_square(a1147);
- modq a4588 = modq_square(a2294);
- modq a4589 = modq_product(a4588,a1);
- return a4589;
-}
-
-static inline modq modq_quotient(modq num,modq den)
-{
- return modq_product(num,modq_reciprocal(den));
-}
-
-#endif
-
-/* from libpqcrypto-20180314/crypto_kem/sntrup4591761/ref/params.h */
-#ifndef params_h
-#define params_h
-
-#define q 4591
-/* XXX: also built into modq in various ways */
-
-#define qshift 2295
-#define p 761
-#define w 286
-
-#define rq_encode_len 1218
-#define small_encode_len 191
-
-#endif
-
-/* from libpqcrypto-20180314/crypto_kem/sntrup4591761/ref/r3.h */
-#ifndef r3_h
-#define r3_h
-
-
-static void r3_mult(small *,const small *,const small *);
-
-extern int r3_recip(small *,const small *);
-
-#endif
-
-/* from libpqcrypto-20180314/crypto_kem/sntrup4591761/ref/rq.h */
-#ifndef rq_h
-#define rq_h
-
-
-static void rq_encode(unsigned char *,const modq *);
-
-static void rq_decode(modq *,const unsigned char *);
-
-static void rq_encoderounded(unsigned char *,const modq *);
-
-static void rq_decoderounded(modq *,const unsigned char *);
-
-static void rq_round3(modq *,const modq *);
-
-static void rq_mult(modq *,const modq *,const small *);
-
-int rq_recip3(modq *,const small *);
-
-#endif
-
-/* from libpqcrypto-20180314/crypto_kem/sntrup4591761/ref/swap.h */
-#ifndef swap_h
-#define swap_h
-
-static void swap(void *,void *,int,int);
-
-#endif
-
-/* from libpqcrypto-20180314/crypto_kem/sntrup4591761/ref/dec.c */
-/* See https://ntruprime.cr.yp.to/software.html for detailed documentation. */
-
-#ifdef KAT
-#endif
-
-
-int crypto_kem_sntrup4591761_dec(
- unsigned char *k,
- const unsigned char *cstr,
- const unsigned char *sk
-)
-{
- small f[p];
- modq h[p];
- small grecip[p];
- modq c[p];
- modq t[p];
- small t3[p];
- small r[p];
- modq hr[p];
- unsigned char rstr[small_encode_len];
- unsigned char hash[64];
- int i;
- int result = 0;
- int weight;
-
- small_decode(f,sk);
- small_decode(grecip,sk + small_encode_len);
- rq_decode(h,sk + 2 * small_encode_len);
-
- rq_decoderounded(c,cstr + 32);
-
- rq_mult(t,c,f);
- for (i = 0;i < p;++i) t3[i] = mod3_freeze(modq_freeze(3*t[i]));
-
- r3_mult(r,t3,grecip);
-
-#ifdef KAT
- {
- int j;
- printf("decrypt r:");
- for (j = 0;j < p;++j)
- if (r[j] == 1) printf(" +%d",j);
- else if (r[j] == -1) printf(" -%d",j);
- printf("\n");
- }
-#endif
-
- weight = 0;
- for (i = 0;i < p;++i) weight += (1 & r[i]);
- weight -= w;
- result |= modq_nonzero_mask(weight); /* XXX: puts limit on p */
-
- rq_mult(hr,h,r);
- rq_round3(hr,hr);
- for (i = 0;i < p;++i) result |= modq_nonzero_mask(hr[i] - c[i]);
-
- small_encode(rstr,r);
- crypto_hash_sha512(hash,rstr,sizeof rstr);
- result |= crypto_verify_32(hash,cstr);
-
- for (i = 0;i < 32;++i) k[i] = (hash[32 + i] & ~result);
- return result;
-}
-
-/* from libpqcrypto-20180314/crypto_kem/sntrup4591761/ref/enc.c */
-/* See https://ntruprime.cr.yp.to/software.html for detailed documentation. */
-
-#ifdef KAT
-#endif
-
-
-int crypto_kem_sntrup4591761_enc(
- unsigned char *cstr,
- unsigned char *k,
- const unsigned char *pk
-)
-{
- small r[p];
- modq h[p];
- modq c[p];
- unsigned char rstr[small_encode_len];
- unsigned char hash[64];
-
- small_random_weightw(r);
-
-#ifdef KAT
- {
- int i;
- printf("encrypt r:");
- for (i = 0;i < p;++i)
- if (r[i] == 1) printf(" +%d",i);
- else if (r[i] == -1) printf(" -%d",i);
- printf("\n");
- }
-#endif
-
- small_encode(rstr,r);
- crypto_hash_sha512(hash,rstr,sizeof rstr);
-
- rq_decode(h,pk);
- rq_mult(c,h,r);
- rq_round3(c,c);
-
- memcpy(k,hash + 32,32);
- memcpy(cstr,hash,32);
- rq_encoderounded(cstr + 32,c);
-
- return 0;
-}
-
-/* from libpqcrypto-20180314/crypto_kem/sntrup4591761/ref/keypair.c */
-/* See https://ntruprime.cr.yp.to/software.html for detailed documentation. */
-
-
-#if crypto_kem_sntrup4591761_PUBLICKEYBYTES != rq_encode_len
-#error "crypto_kem_sntrup4591761_PUBLICKEYBYTES must match rq_encode_len"
-#endif
-#if crypto_kem_sntrup4591761_SECRETKEYBYTES != rq_encode_len + 2 * small_encode_len
-#error "crypto_kem_sntrup4591761_SECRETKEYBYTES must match rq_encode_len + 2 * small_encode_len"
-#endif
-
-int crypto_kem_sntrup4591761_keypair(unsigned char *pk,unsigned char *sk)
-{
- small g[p];
- small grecip[p];
- small f[p];
- modq f3recip[p];
- modq h[p];
-
- do
- small_random(g);
- while (r3_recip(grecip,g) != 0);
-
- small_random_weightw(f);
- rq_recip3(f3recip,f);
-
- rq_mult(h,f3recip,g);
-
- rq_encode(pk,h);
- small_encode(sk,f);
- small_encode(sk + small_encode_len,grecip);
- memcpy(sk + 2 * small_encode_len,pk,rq_encode_len);
-
- return 0;
-}
-
-/* from libpqcrypto-20180314/crypto_kem/sntrup4591761/ref/r3_mult.c */
-/* See https://ntruprime.cr.yp.to/software.html for detailed documentation. */
-
-
-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 = mod3_plusproduct(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 = mod3_plusproduct(result,f[j],g[i - j]);
- fg[i] = result;
- }
-
- for (i = p + p - 2;i >= p;--i) {
- fg[i - p] = mod3_sum(fg[i - p],fg[i]);
- fg[i - p + 1] = mod3_sum(fg[i - p + 1],fg[i]);
- }
-
- for (i = 0;i < p;++i)
- h[i] = fg[i];
-}
-
-/* from libpqcrypto-20180314/crypto_kem/sntrup4591761/ref/r3_recip.c */
-/* See https://ntruprime.cr.yp.to/software.html for detailed documentation. */
-
-
-/* caller must ensure that x-y does not overflow */
-static int smaller_mask_r3_recip(int x,int y)
-{
- return (x - y) >> 31;
-}
-
-static void vectormod3_product(small *z,int len,const small *x,const small c)
-{
- int i;
- for (i = 0;i < len;++i) z[i] = mod3_product(x[i],c);
-}
-
-static void vectormod3_minusproduct(small *z,int len,const small *x,const small *y,const small c)
-{
- int i;
- for (i = 0;i < len;++i) z[i] = mod3_minusproduct(x[i],y[i],c);
-}
-
-static void vectormod3_shift(small *z,int len)
-{
- int i;
- for (i = len - 1;i > 0;--i) z[i] = z[i - 1];
- z[0] = 0;
-}
-
-/*
-r = s^(-1) mod m, returning 0, if s is invertible mod m
-or returning -1 if s is not invertible mod m
-r,s are polys of degree <p
-m is x^p-x-1
-*/
-int r3_recip(small *r,const small *s)
-{
- const int loops = 2*p + 1;
- int loop;
- small f[p + 1];
- small g[p + 1];
- small u[2*p + 2];
- small v[2*p + 2];
- small c;
- int i;
- int d = p;
- int e = p;
- int swapmask;
-
- for (i = 2;i < p;++i) f[i] = 0;
- f[0] = -1;
- f[1] = -1;
- f[p] = 1;
- /* generalization: can initialize f to any polynomial m */
- /* requirements: m has degree exactly p, nonzero constant coefficient */
-
- for (i = 0;i < p;++i) g[i] = s[i];
- g[p] = 0;
-
- for (i = 0;i <= loops;++i) u[i] = 0;
-
- v[0] = 1;
- for (i = 1;i <= loops;++i) v[i] = 0;
-
- loop = 0;
- for (;;) {
- /* e == -1 or d + e + loop <= 2*p */
-
- /* f has degree p: i.e., f[p]!=0 */
- /* f[i]==0 for i < p-d */
-
- /* g has degree <=p (so it fits in p+1 coefficients) */
- /* g[i]==0 for i < p-e */
-
- /* u has degree <=loop (so it fits in loop+1 coefficients) */
- /* u[i]==0 for i < p-d */
- /* if invertible: u[i]==0 for i < loop-p (so can look at just p+1 coefficients) */
-
- /* v has degree <=loop (so it fits in loop+1 coefficients) */
- /* v[i]==0 for i < p-e */
- /* v[i]==0 for i < loop-p (so can look at just p+1 coefficients) */
-
- if (loop >= loops) break;
-
- c = mod3_quotient(g[p],f[p]);
-
- vectormod3_minusproduct(g,p + 1,g,f,c);
- vectormod3_shift(g,p + 1);
-
-#ifdef SIMPLER
- vectormod3_minusproduct(v,loops + 1,v,u,c);
- vectormod3_shift(v,loops + 1);
-#else
- if (loop < p) {
- vectormod3_minusproduct(v,loop + 1,v,u,c);
- vectormod3_shift(v,loop + 2);
- } else {
- vectormod3_minusproduct(v + loop - p,p + 1,v + loop - p,u + loop - p,c);
- vectormod3_shift(v + loop - p,p + 2);
- }
-#endif
-
- e -= 1;
-
- ++loop;
-
- swapmask = smaller_mask_r3_recip(e,d) & mod3_nonzero_mask(g[p]);
- swap(&e,&d,sizeof e,swapmask);
- swap(f,g,(p + 1) * sizeof(small),swapmask);
-
-#ifdef SIMPLER
- swap(u,v,(loops + 1) * sizeof(small),swapmask);
-#else
- if (loop < p) {
- swap(u,v,(loop + 1) * sizeof(small),swapmask);
- } else {
- swap(u + loop - p,v + loop - p,(p + 1) * sizeof(small),swapmask);
- }
-#endif
- }
-
- c = mod3_reciprocal(f[p]);
- vectormod3_product(r,p,u + p,c);
- return smaller_mask_r3_recip(0,d);
-}
-
-/* from libpqcrypto-20180314/crypto_kem/sntrup4591761/ref/randomsmall.c */
-/* See https://ntruprime.cr.yp.to/software.html for detailed documentation. */
-
-
-static void small_random(small *g)
-{
- int i;
-
- for (i = 0;i < p;++i) {
- crypto_uint32 r = small_random32();
- g[i] = (small) (((1073741823 & r) * 3) >> 30) - 1;
- }
-}
-
-/* from libpqcrypto-20180314/crypto_kem/sntrup4591761/ref/randomweightw.c */
-/* See https://ntruprime.cr.yp.to/software.html for detailed documentation. */
-
-
-static void small_random_weightw(small *f)
-{
- crypto_int32 r[p];
- int i;
-
- for (i = 0;i < p;++i) r[i] = small_random32();
- for (i = 0;i < w;++i) r[i] &= -2;
- for (i = w;i < p;++i) r[i] = (r[i] & -3) | 1;
- int32_sort(r,p);
- for (i = 0;i < p;++i) f[i] = ((small) (r[i] & 3)) - 1;
-}
-
-/* from libpqcrypto-20180314/crypto_kem/sntrup4591761/ref/rq.c */
-/* See https://ntruprime.cr.yp.to/software.html for detailed documentation. */
-
-
-static void rq_encode(unsigned char *c,const modq *f)
-{
- crypto_int32 f0, f1, f2, f3, f4;
- int i;
-
- for (i = 0;i < p/5;++i) {
- f0 = *f++ + qshift;
- f1 = *f++ + qshift;
- f2 = *f++ + qshift;
- f3 = *f++ + qshift;
- f4 = *f++ + qshift;
- /* now want f0 + 6144*f1 + ... as a 64-bit integer */
- f1 *= 3;
- f2 *= 9;
- f3 *= 27;
- f4 *= 81;
- /* now want f0 + f1<<11 + f2<<22 + f3<<33 + f4<<44 */
- f0 += f1 << 11;
- *c++ = f0; f0 >>= 8;
- *c++ = f0; f0 >>= 8;
- f0 += f2 << 6;
- *c++ = f0; f0 >>= 8;
- *c++ = f0; f0 >>= 8;
- f0 += f3 << 1;
- *c++ = f0; f0 >>= 8;
- f0 += f4 << 4;
- *c++ = f0; f0 >>= 8;
- *c++ = f0; f0 >>= 8;
- *c++ = f0;
- }
- /* XXX: using p mod 5 = 1 */
- f0 = *f++ + qshift;
- *c++ = f0; f0 >>= 8;
- *c++ = f0;
-}
-
-static void rq_decode(modq *f,const unsigned char *c)
-{
- crypto_uint32 c0, c1, c2, c3, c4, c5, c6, c7;
- crypto_uint32 f0, f1, f2, f3, f4;
- int i;
-
- for (i = 0;i < p/5;++i) {
- c0 = *c++;
- c1 = *c++;
- c2 = *c++;
- c3 = *c++;
- c4 = *c++;
- c5 = *c++;
- c6 = *c++;
- c7 = *c++;
-
- /* f0 + f1*6144 + f2*6144^2 + f3*6144^3 + f4*6144^4 */
- /* = c0 + c1*256 + ... + c6*256^6 + c7*256^7 */
- /* with each f between 0 and 4590 */
-
- c6 += c7 << 8;
- /* c6 <= 23241 = floor(4591*6144^4/2^48) */
- /* f4 = (16/81)c6 + (1/1296)(c5+[0,1]) - [0,0.75] */
- /* claim: 2^19 f4 < x < 2^19(f4+1) */
- /* where x = 103564 c6 + 405(c5+1) */
- /* proof: x - 2^19 f4 = (76/81)c6 + (37/81)c5 + 405 - (32768/81)[0,1] + 2^19[0,0.75] */
- /* at least 405 - 32768/81 > 0 */
- /* at most (76/81)23241 + (37/81)255 + 405 + 2^19 0.75 < 2^19 */
- f4 = (103564*c6 + 405*(c5+1)) >> 19;
-
- c5 += c6 << 8;
- c5 -= (f4 * 81) << 4;
- c4 += c5 << 8;
-
- /* f0 + f1*6144 + f2*6144^2 + f3*6144^3 */
- /* = c0 + c1*256 + c2*256^2 + c3*256^3 + c4*256^4 */
- /* c4 <= 247914 = floor(4591*6144^3/2^32) */
- /* f3 = (1/54)(c4+[0,1]) - [0,0.75] */
- /* claim: 2^19 f3 < x < 2^19(f3+1) */
- /* where x = 9709(c4+2) */
- /* proof: x - 2^19 f3 = 19418 - (1/27)c4 - (262144/27)[0,1] + 2^19[0,0.75] */
- /* at least 19418 - 247914/27 - 262144/27 > 0 */
- /* at most 19418 + 2^19 0.75 < 2^19 */
- f3 = (9709*(c4+2)) >> 19;
-
- c4 -= (f3 * 27) << 1;
- c3 += c4 << 8;
- /* f0 + f1*6144 + f2*6144^2 */
- /* = c0 + c1*256 + c2*256^2 + c3*256^3 */
- /* c3 <= 10329 = floor(4591*6144^2/2^24) */
- /* f2 = (4/9)c3 + (1/576)c2 + (1/147456)c1 + (1/37748736)c0 - [0,0.75] */
- /* claim: 2^19 f2 < x < 2^19(f2+1) */
- /* where x = 233017 c3 + 910(c2+2) */
- /* proof: x - 2^19 f2 = 1820 + (1/9)c3 - (2/9)c2 - (32/9)c1 - (1/72)c0 + 2^19[0,0.75] */
- /* at least 1820 - (2/9)255 - (32/9)255 - (1/72)255 > 0 */
- /* at most 1820 + (1/9)10329 + 2^19 0.75 < 2^19 */
- f2 = (233017*c3 + 910*(c2+2)) >> 19;
-
- c2 += c3 << 8;
- c2 -= (f2 * 9) << 6;
- c1 += c2 << 8;
- /* f0 + f1*6144 */
- /* = c0 + c1*256 */
- /* c1 <= 110184 = floor(4591*6144/2^8) */
- /* f1 = (1/24)c1 + (1/6144)c0 - (1/6144)f0 */
- /* claim: 2^19 f1 < x < 2^19(f1+1) */
- /* where x = 21845(c1+2) + 85 c0 */
- /* proof: x - 2^19 f1 = 43690 - (1/3)c1 - (1/3)c0 + 2^19 [0,0.75] */
- /* at least 43690 - (1/3)110184 - (1/3)255 > 0 */
- /* at most 43690 + 2^19 0.75 < 2^19 */
- f1 = (21845*(c1+2) + 85*c0) >> 19;
-
- c1 -= (f1 * 3) << 3;
- c0 += c1 << 8;
- f0 = c0;
-
- *f++ = modq_freeze(f0 + q - qshift);
- *f++ = modq_freeze(f1 + q - qshift);
- *f++ = modq_freeze(f2 + q - qshift);
- *f++ = modq_freeze(f3 + q - qshift);
- *f++ = modq_freeze(f4 + q - qshift);
- }
-
- c0 = *c++;
- c1 = *c++;
- c0 += c1 << 8;
- *f++ = modq_freeze(c0 + q - qshift);
-}
-
-/* from libpqcrypto-20180314/crypto_kem/sntrup4591761/ref/rq_mult.c */
-/* See https://ntruprime.cr.yp.to/software.html for detailed documentation. */
-
-
-static void rq_mult(modq *h,const modq *f,const small *g)
-{
- modq fg[p + p - 1];
- modq result;
- int i, j;
-
- for (i = 0;i < p;++i) {
- result = 0;
- for (j = 0;j <= i;++j)
- result = modq_plusproduct(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 = modq_plusproduct(result,f[j],g[i - j]);
- fg[i] = result;
- }
-
- for (i = p + p - 2;i >= p;--i) {
- fg[i - p] = modq_sum(fg[i - p],fg[i]);
- fg[i - p + 1] = modq_sum(fg[i - p + 1],fg[i]);
- }
-
- for (i = 0;i < p;++i)
- h[i] = fg[i];
-}
-
-/* from libpqcrypto-20180314/crypto_kem/sntrup4591761/ref/rq_recip3.c */
-/* See https://ntruprime.cr.yp.to/software.html for detailed documentation. */
-
-
-/* caller must ensure that x-y does not overflow */
-static int smaller_mask_rq_recip3(int x,int y)
-{
- return (x - y) >> 31;
-}
-
-static void vectormodq_product(modq *z,int len,const modq *x,const modq c)
-{
- int i;
- for (i = 0;i < len;++i) z[i] = modq_product(x[i],c);
-}
-
-static void vectormodq_minusproduct(modq *z,int len,const modq *x,const modq *y,const modq c)
-{
- int i;
- for (i = 0;i < len;++i) z[i] = modq_minusproduct(x[i],y[i],c);
-}
-
-static void vectormodq_shift(modq *z,int len)
-{
- int i;
- for (i = len - 1;i > 0;--i) z[i] = z[i - 1];
- z[0] = 0;
-}
-
-/*
-r = (3s)^(-1) mod m, returning 0, if s is invertible mod m
-or returning -1 if s is not invertible mod m
-r,s are polys of degree <p
-m is x^p-x-1
-*/
-int rq_recip3(modq *r,const small *s)
-{
- const int loops = 2*p + 1;
- int loop;
- modq f[p + 1];
- modq g[p + 1];
- modq u[2*p + 2];
- modq v[2*p + 2];
- modq c;
- int i;
- int d = p;
- int e = p;
- int swapmask;
-
- for (i = 2;i < p;++i) f[i] = 0;
- f[0] = -1;
- f[1] = -1;
- f[p] = 1;
- /* generalization: can initialize f to any polynomial m */
- /* requirements: m has degree exactly p, nonzero constant coefficient */
-
- for (i = 0;i < p;++i) g[i] = 3 * s[i];
- g[p] = 0;
-
- for (i = 0;i <= loops;++i) u[i] = 0;
-
- v[0] = 1;
- for (i = 1;i <= loops;++i) v[i] = 0;
-
- loop = 0;
- for (;;) {
- /* e == -1 or d + e + loop <= 2*p */
-
- /* f has degree p: i.e., f[p]!=0 */
- /* f[i]==0 for i < p-d */
-
- /* g has degree <=p (so it fits in p+1 coefficients) */
- /* g[i]==0 for i < p-e */
-
- /* u has degree <=loop (so it fits in loop+1 coefficients) */
- /* u[i]==0 for i < p-d */
- /* if invertible: u[i]==0 for i < loop-p (so can look at just p+1 coefficients) */
-
- /* v has degree <=loop (so it fits in loop+1 coefficients) */
- /* v[i]==0 for i < p-e */
- /* v[i]==0 for i < loop-p (so can look at just p+1 coefficients) */
-
- if (loop >= loops) break;
-
- c = modq_quotient(g[p],f[p]);
-
- vectormodq_minusproduct(g,p + 1,g,f,c);
- vectormodq_shift(g,p + 1);
-
-#ifdef SIMPLER
- vectormodq_minusproduct(v,loops + 1,v,u,c);
- vectormodq_shift(v,loops + 1);
-#else
- if (loop < p) {
- vectormodq_minusproduct(v,loop + 1,v,u,c);
- vectormodq_shift(v,loop + 2);
- } else {
- vectormodq_minusproduct(v + loop - p,p + 1,v + loop - p,u + loop - p,c);
- vectormodq_shift(v + loop - p,p + 2);
- }
-#endif
-
- e -= 1;
-
- ++loop;
-
- swapmask = smaller_mask_rq_recip3(e,d) & modq_nonzero_mask(g[p]);
- swap(&e,&d,sizeof e,swapmask);
- swap(f,g,(p + 1) * sizeof(modq),swapmask);
-
-#ifdef SIMPLER
- swap(u,v,(loops + 1) * sizeof(modq),swapmask);
-#else
- if (loop < p) {
- swap(u,v,(loop + 1) * sizeof(modq),swapmask);
- } else {
- swap(u + loop - p,v + loop - p,(p + 1) * sizeof(modq),swapmask);
- }
-#endif
- }
-
- c = modq_reciprocal(f[p]);
- vectormodq_product(r,p,u + p,c);
- return smaller_mask_rq_recip3(0,d);
-}
-
-/* from libpqcrypto-20180314/crypto_kem/sntrup4591761/ref/rq_round3.c */
-/* See https://ntruprime.cr.yp.to/software.html for detailed documentation. */
-
-
-static void rq_round3(modq *h,const modq *f)
-{
- int i;
-
- for (i = 0;i < p;++i)
- h[i] = ((21846 * (f[i] + 2295) + 32768) >> 16) * 3 - 2295;
-}
-
-/* from libpqcrypto-20180314/crypto_kem/sntrup4591761/ref/rq_rounded.c */
-/* See https://ntruprime.cr.yp.to/software.html for detailed documentation. */
-
-
-static void rq_encoderounded(unsigned char *c,const modq *f)
-{
- crypto_int32 f0, f1, f2;
- int i;
-
- for (i = 0;i < p/3;++i) {
- f0 = *f++ + qshift;
- f1 = *f++ + qshift;
- f2 = *f++ + qshift;
- f0 = (21846 * f0) >> 16;
- f1 = (21846 * f1) >> 16;
- f2 = (21846 * f2) >> 16;
- /* now want f0 + f1*1536 + f2*1536^2 as a 32-bit integer */
- f2 *= 3;
- f1 += f2 << 9;
- f1 *= 3;
- f0 += f1 << 9;
- *c++ = f0; f0 >>= 8;
- *c++ = f0; f0 >>= 8;
- *c++ = f0; f0 >>= 8;
- *c++ = f0;
- }
- /* XXX: using p mod 3 = 2 */
- f0 = *f++ + qshift;
- f1 = *f++ + qshift;
- f0 = (21846 * f0) >> 16;
- f1 = (21846 * f1) >> 16;
- f1 *= 3;
- f0 += f1 << 9;
- *c++ = f0; f0 >>= 8;
- *c++ = f0; f0 >>= 8;
- *c++ = f0;
-}
-
-static void rq_decoderounded(modq *f,const unsigned char *c)
-{
- crypto_uint32 c0, c1, c2, c3;
- crypto_uint32 f0, f1, f2;
- int i;
-
- for (i = 0;i < p/3;++i) {
- c0 = *c++;
- c1 = *c++;
- c2 = *c++;
- c3 = *c++;
-
- /* f0 + f1*1536 + f2*1536^2 */
- /* = c0 + c1*256 + c2*256^2 + c3*256^3 */
- /* with each f between 0 and 1530 */
-
- /* f2 = (64/9)c3 + (1/36)c2 + (1/9216)c1 + (1/2359296)c0 - [0,0.99675] */
- /* claim: 2^21 f2 < x < 2^21(f2+1) */
- /* where x = 14913081*c3 + 58254*c2 + 228*(c1+2) */
- /* proof: x - 2^21 f2 = 456 - (8/9)c0 + (4/9)c1 - (2/9)c2 + (1/9)c3 + 2^21 [0,0.99675] */
- /* at least 456 - (8/9)255 - (2/9)255 > 0 */
- /* at most 456 + (4/9)255 + (1/9)255 + 2^21 0.99675 < 2^21 */
- f2 = (14913081*c3 + 58254*c2 + 228*(c1+2)) >> 21;
-
- c2 += c3 << 8;
- c2 -= (f2 * 9) << 2;
- /* f0 + f1*1536 */
- /* = c0 + c1*256 + c2*256^2 */
- /* c2 <= 35 = floor((1530+1530*1536)/256^2) */
- /* f1 = (128/3)c2 + (1/6)c1 + (1/1536)c0 - (1/1536)f0 */
- /* claim: 2^21 f1 < x < 2^21(f1+1) */
- /* where x = 89478485*c2 + 349525*c1 + 1365*(c0+1) */
- /* proof: x - 2^21 f1 = 1365 - (1/3)c2 - (1/3)c1 - (1/3)c0 + (4096/3)f0 */
- /* at least 1365 - (1/3)35 - (1/3)255 - (1/3)255 > 0 */
- /* at most 1365 + (4096/3)1530 < 2^21 */
- f1 = (89478485*c2 + 349525*c1 + 1365*(c0+1)) >> 21;
-
- c1 += c2 << 8;
- c1 -= (f1 * 3) << 1;
-
- c0 += c1 << 8;
- f0 = c0;
-
- *f++ = modq_freeze(f0 * 3 + q - qshift);
- *f++ = modq_freeze(f1 * 3 + q - qshift);
- *f++ = modq_freeze(f2 * 3 + q - qshift);
- }
-
- c0 = *c++;
- c1 = *c++;
- c2 = *c++;
-
- f1 = (89478485*c2 + 349525*c1 + 1365*(c0+1)) >> 21;
-
- c1 += c2 << 8;
- c1 -= (f1 * 3) << 1;
-
- c0 += c1 << 8;
- f0 = c0;
-
- *f++ = modq_freeze(f0 * 3 + q - qshift);
- *f++ = modq_freeze(f1 * 3 + q - qshift);
-}
-
-/* from libpqcrypto-20180314/crypto_kem/sntrup4591761/ref/small.c */
-/* See https://ntruprime.cr.yp.to/software.html for detailed documentation. */
-
-
-/* XXX: these functions rely on p mod 4 = 1 */
-
-/* all coefficients in -1, 0, 1 */
-static void small_encode(unsigned char *c,const small *f)
-{
- small c0;
- int i;
-
- for (i = 0;i < p/4;++i) {
- c0 = *f++ + 1;
- c0 += (*f++ + 1) << 2;
- c0 += (*f++ + 1) << 4;
- c0 += (*f++ + 1) << 6;
- *c++ = c0;
- }
- c0 = *f++ + 1;
- *c++ = c0;
-}
-
-static void small_decode(small *f,const unsigned char *c)
-{
- unsigned char c0;
- int i;
-
- for (i = 0;i < p/4;++i) {
- c0 = *c++;
- *f++ = ((small) (c0 & 3)) - 1; c0 >>= 2;
- *f++ = ((small) (c0 & 3)) - 1; c0 >>= 2;
- *f++ = ((small) (c0 & 3)) - 1; c0 >>= 2;
- *f++ = ((small) (c0 & 3)) - 1;
- }
- c0 = *c++;
- *f++ = ((small) (c0 & 3)) - 1;
-}
-
-/* from libpqcrypto-20180314/crypto_kem/sntrup4591761/ref/swap.c */
-/* See https://ntruprime.cr.yp.to/software.html for detailed documentation. */
-
-
-static void swap(void *x,void *y,int bytes,int mask)
-{
- int i;
- char xi, yi, c, t;
-
- c = mask;
-
- for (i = 0;i < bytes;++i) {
- xi = i[(char *) x];
- yi = i[(char *) y];
- t = c & (xi ^ yi);
- xi ^= t;
- yi ^= t;
- i[(char *) x] = xi;
- i[(char *) y] = yi;
- }
-}
-
diff --git a/sntrup4591761.sh b/sntrup4591761.sh
deleted file mode 100644
index e684c3329..000000000
--- a/sntrup4591761.sh
+++ /dev/null
@@ -1,57 +0,0 @@
-#!/bin/sh
-# $OpenBSD: sntrup4591761.sh,v 1.3 2019/01/30 19:51:15 markus Exp $
-# Placed in the Public Domain.
-#
-AUTHOR="libpqcrypto-20180314/crypto_kem/sntrup4591761/ref/implementors"
-FILES="
- libpqcrypto-20180314/crypto_kem/sntrup4591761/ref/int32_sort.h
- libpqcrypto-20180314/crypto_kem/sntrup4591761/ref/int32_sort.c
- libpqcrypto-20180314/crypto_kem/sntrup4591761/ref/small.h
- libpqcrypto-20180314/crypto_kem/sntrup4591761/ref/mod3.h
- libpqcrypto-20180314/crypto_kem/sntrup4591761/ref/modq.h
- libpqcrypto-20180314/crypto_kem/sntrup4591761/ref/params.h
- libpqcrypto-20180314/crypto_kem/sntrup4591761/ref/r3.h
- libpqcrypto-20180314/crypto_kem/sntrup4591761/ref/rq.h
- libpqcrypto-20180314/crypto_kem/sntrup4591761/ref/swap.h
- libpqcrypto-20180314/crypto_kem/sntrup4591761/ref/dec.c
- libpqcrypto-20180314/crypto_kem/sntrup4591761/ref/enc.c
- libpqcrypto-20180314/crypto_kem/sntrup4591761/ref/keypair.c
- libpqcrypto-20180314/crypto_kem/sntrup4591761/ref/r3_mult.c
- libpqcrypto-20180314/crypto_kem/sntrup4591761/ref/r3_recip.c
- libpqcrypto-20180314/crypto_kem/sntrup4591761/ref/randomsmall.c
- libpqcrypto-20180314/crypto_kem/sntrup4591761/ref/randomweightw.c
- libpqcrypto-20180314/crypto_kem/sntrup4591761/ref/rq.c
- libpqcrypto-20180314/crypto_kem/sntrup4591761/ref/rq_mult.c
- libpqcrypto-20180314/crypto_kem/sntrup4591761/ref/rq_recip3.c
- libpqcrypto-20180314/crypto_kem/sntrup4591761/ref/rq_round3.c
- libpqcrypto-20180314/crypto_kem/sntrup4591761/ref/rq_rounded.c
- libpqcrypto-20180314/crypto_kem/sntrup4591761/ref/small.c
- libpqcrypto-20180314/crypto_kem/sntrup4591761/ref/swap.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
-for i in $FILES; do
- echo "/* from $i */"
- b=$(basename $i .c)
- grep \
- -v '#include' $i | \
- grep -v "extern crypto_int32 small_random32" |
- sed -e "s/crypto_kem_/crypto_kem_sntrup4591761_/g" \
- -e "s/smaller_mask/smaller_mask_${b}/g" \
- -e "s/^extern void /static void /" \
- -e "s/^void /static void /"
- echo
-done
diff --git a/sntrup761.c b/sntrup761.c
new file mode 100644
index 000000000..c63e600fb
--- /dev/null
+++ b/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/sntrup761.sh b/sntrup761.sh
new file mode 100644
index 000000000..5cd5f92c3
--- /dev/null
+++ b/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/srclimit.c b/srclimit.c
new file mode 100644
index 000000000..5014ed79f
--- /dev/null
+++ b/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/srclimit.h b/srclimit.h
new file mode 100644
index 000000000..6e04f32b3
--- /dev/null
+++ b/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/ssh-add.0 b/ssh-add.0
index d73af0f43..d955d3237 100644
--- a/ssh-add.0
+++ b/ssh-add.0
@@ -149,4 +149,4 @@ AUTHORS
created OpenSSH. Markus Friedl contributed the support for SSH protocol
versions 1.5 and 2.0.
-OpenBSD 6.8 July 14, 2020 OpenBSD 6.8
+OpenBSD 6.9 July 14, 2020 OpenBSD 6.9
diff --git a/ssh-add.c b/ssh-add.c
index 936dc2128..92192fcfa 100644
--- a/ssh-add.c
+++ b/ssh-add.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssh-add.c,v 1.157 2020/08/31 04:33:17 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
@@ -91,7 +91,7 @@ static char *default_files[] = {
static int fingerprint_hash = SSH_FP_HASH_DEFAULT;
/* Default lifetime (0 == forever) */
-static long lifetime = 0;
+static int lifetime = 0;
/* User has to confirm key use */
static int confirm = 0;
@@ -146,9 +146,9 @@ delete_stdin(int agent_fd, int qflag)
if (*cp == '#' || *cp == '\0')
continue;
if ((key = sshkey_new(KEY_UNSPEC)) == NULL)
- fatal("%s: sshkey_new", __func__);
+ fatal_f("sshkey_new");
if ((r = sshkey_read(key, &cp)) != 0) {
- error("(stdin):%d: invalid key: %s", lnum, ssh_err(r));
+ error_r(r, "(stdin):%d: invalid key", lnum);
continue;
}
if (delete_one(agent_fd, key, cp, "(stdin)", qflag) == 0)
@@ -185,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;
}
@@ -337,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);
@@ -373,7 +372,7 @@ add_file(int agent_fd, const char *filename, int key_only, int qflag,
filename, comment);
if (lifetime != 0) {
fprintf(stderr,
- "Lifetime set to %ld seconds\n", lifetime);
+ "Lifetime set to %d seconds\n", lifetime);
}
if (confirm != 0) {
fprintf(stderr, "The user must confirm "
@@ -393,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;
}
@@ -407,12 +405,12 @@ 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;
}
@@ -420,8 +418,8 @@ add_file(int agent_fd, const char *filename, int key_only, int qflag,
if ((r = ssh_add_identity_constrained(agent_fd, private, comment,
lifetime, confirm, maxsign, skprovider)) != 0) {
- error("Certificate %s (%s) add failed: %s", certpath,
- private->cert->key_id, ssh_err(r));
+ error_r(r, "Certificate %s (%s) add failed", certpath,
+ private->cert->key_id);
goto out;
}
/* success */
@@ -429,7 +427,7 @@ add_file(int agent_fd, const char *filename, int key_only, int qflag,
fprintf(stderr, "Certificate added: %s (%s)\n", certpath,
private->cert->key_id);
if (lifetime != 0) {
- fprintf(stderr, "Lifetime set to %ld seconds\n",
+ fprintf(stderr, "Lifetime set to %d seconds\n",
lifetime);
}
if (confirm != 0) {
@@ -484,20 +482,18 @@ test_key(int agent_fd, const char *filename)
char data[1024];
if ((r = sshkey_load_public(filename, &key, NULL)) != 0) {
- error("Couldn't read public key %s: %s", filename, ssh_err(r));
+ 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("Agent signature failed for %s: %s",
- filename, ssh_err(r));
+ 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("Signature verification failed for %s: %s",
- filename, ssh_err(r));
+ error_r(r, "Signature verification failed for %s", filename);
goto done;
}
/* success */
@@ -592,13 +588,13 @@ load_resident_keys(int agent_fd, const char *skprovider, int qflag)
pass = read_passphrase("Enter PIN for authenticator: ", RP_ALLOW_STDIN);
if ((r = sshsk_load_resident(skprovider, NULL, pass,
&keys, &nkeys)) != 0) {
- error("Unable to load resident keys: %s", ssh_err(r));
+ 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("%s: sshkey_fingerprint failed", __func__);
+ 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",
@@ -614,7 +610,7 @@ load_resident_keys(int agent_fd, const char *skprovider, int qflag)
sshkey_type(keys[i]), fp);
if (lifetime != 0) {
fprintf(stderr,
- "Lifetime set to %ld seconds\n", lifetime);
+ "Lifetime set to %d seconds\n", lifetime);
}
if (confirm != 0) {
fprintf(stderr, "The user must confirm "
diff --git a/ssh-agent.0 b/ssh-agent.0
index 71dddc27c..1da77c304 100644
--- a/ssh-agent.0
+++ b/ssh-agent.0
@@ -116,4 +116,4 @@ AUTHORS
created OpenSSH. Markus Friedl contributed the support for SSH protocol
versions 1.5 and 2.0.
-OpenBSD 6.8 June 22, 2020 OpenBSD 6.8
+OpenBSD 6.9 June 22, 2020 OpenBSD 6.9
diff --git a/ssh-agent.1 b/ssh-agent.1
index 2cf46160b..ed8c87096 100644
--- a/ssh-agent.1
+++ b/ssh-agent.1
@@ -157,7 +157,8 @@ which in turn can be evaluated in the calling shell, for example
.Pp
In both cases,
.Xr ssh 1
-looks at these environment 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 initially does not have any private keys.
Keys are added using
diff --git a/ssh-agent.c b/ssh-agent.c
index e1fd1f3f6..48a47d45a 100644
--- a/ssh-agent.c
+++ b/ssh-agent.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssh-agent.c,v 1.264 2020/09/18 08:16:38 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
@@ -103,12 +103,12 @@
#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;
@@ -164,7 +164,7 @@ 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;
@@ -175,11 +175,12 @@ static void
close_socket(SocketEntry *e)
{
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;
}
static void
@@ -215,15 +216,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);
@@ -238,7 +240,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' */
@@ -249,22 +251,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,74 +290,133 @@ agent_decode_alg(struct sshkey *key, u_int flags)
}
/*
- * 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.
+ * 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
-check_websafe_message_contents(struct sshkey *key,
- const u_char *msg, size_t len)
+parse_userauth_request(struct sshbuf *msg, const struct sshkey *expected_key,
+ char **userp, struct sshbuf **sess_idp)
{
- int matched = 0;
- struct sshbuf *b;
- u_char m, n;
- char *cp1 = NULL, *cp2 = NULL;
+ 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 ((b = sshbuf_from(msg, len)) == NULL)
- fatal("%s: sshbuf_new", __func__);
+ 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_get_string_direct(b, NULL, NULL)) == 0 && /* sess_id */
- (r = sshbuf_get_u8(b, &m)) == 0 && /* SSH2_MSG_USERAUTH_REQUEST */
- (r = sshbuf_get_cstring(b, NULL, NULL)) == 0 && /* server user */
- (r = sshbuf_get_cstring(b, &cp1, NULL)) == 0 && /* service */
- (r = sshbuf_get_cstring(b, &cp2, NULL)) == 0 && /* method */
- (r = sshbuf_get_u8(b, &n)) == 0 && /* sig-follows */
- (r = sshbuf_get_cstring(b, NULL, NULL)) == 0 && /* alg */
- (r = sshkey_froms(b, &mkey)) == 0 && /* key */
- sshbuf_len(b) == 0) {
- debug("%s: parsed userauth", __func__);
- if (m == SSH2_MSG_USERAUTH_REQUEST && n == 1 &&
- strcmp(cp1, "ssh-connection") == 0 &&
- strcmp(cp2, "publickey") == 0 &&
- sshkey_equal(key, mkey)) {
- debug("%s: well formed userauth", __func__);
- matched = 1;
- }
+ if ((r = sshbuf_froms(b, &sess_id)) != 0)
+ goto out;
+ if (sshbuf_len(sess_id) == 0) {
+ r = SSH_ERR_INVALID_FORMAT;
+ goto out;
}
- free(cp1);
- free(cp2);
- sshkey_free(mkey);
+ 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);
- if (matched)
- return 1;
+ sshbuf_free(sess_id);
+ free(user);
+ free(service);
+ free(method);
+ free(pkalg);
+ sshkey_free(mkey);
+ return r;
+}
- if ((b = sshbuf_from(msg, len)) == NULL)
- fatal("%s: sshbuf_new", __func__);
- cp1 = cp2 = NULL;
- mkey = NULL;
+/*
+ * 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;
- /* SSHSIG */
- 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) */
- sshbuf_len(b) == 0) {
- debug("%s: parsed sshsig", __func__);
- matched = 1;
+ 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);
- if (matched)
+ 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 CA signature operation */
+ /* XXX check CA signature operation */
error("web-origin key attempting to sign non-SSH message");
return 0;
@@ -364,44 +426,45 @@ check_websafe_message_contents(struct sshkey *key,
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;
char *fp = NULL;
- struct sshbuf *msg;
+ 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, dlen)) {
+ !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("%s: fingerprint failed", __func__);
+ fatal_f("fingerprint failed");
notifier = notify_start(0,
"Confirm user presence for key %s %s",
sshkey_type(id->key), fp);
@@ -409,28 +472,30 @@ process_sign_request2(SocketEntry *e)
}
/* XXX support PIN required FIDO keys */
if ((r = sshkey_sign(id->key, &signature, &slen,
- data, dlen, agent_decode_alg(key, flags),
+ sshbuf_ptr(data), sshbuf_len(data), agent_decode_alg(key, flags),
id->sk_provider, NULL, compat)) != 0) {
- error("%s: sshkey_sign: %s", __func__, ssh_err(r));
+ error_fr(r, "sshkey_sign");
goto send;
}
/* Success */
ok = 0;
send:
- notify_complete(notifier);
- sshkey_free(key);
- free(fp);
+ 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);
}
@@ -442,24 +507,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);
}
@@ -468,6 +533,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)) {
@@ -508,107 +574,156 @@ 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 = 0, maxsign;
- char *fp, *comment = NULL, *ext_name = NULL, *sk_provider = NULL;
- char canonical_provider[PATH_MAX];
- 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;
}
- 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;
+ /* success */
+ r = 0;
+ out:
+ free(ext_name);
+ return r;
+}
+
+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 = sshbuf_get_cstring(e->request,
- &ext_name, NULL)) != 0) {
- error("%s: cannot parse extension: %s",
- __func__, ssh_err(r));
- goto err;
- }
- debug("%s: constraint ext %s", __func__, ext_name);
- if (strcmp(ext_name, "sk-provider@openssh.com") == 0) {
- if (sk_provider != NULL) {
- error("%s already set", ext_name);
- goto err;
- }
- if ((r = sshbuf_get_cstring(e->request,
- &sk_provider, NULL)) != 0) {
- error("%s: cannot parse %s: %s",
- __func__, ext_name, ssh_err(r));
- goto err;
- }
- } else {
- error("%s: unsupported constraint \"%s\"",
- __func__, ext_name);
- goto err;
- }
- free(ext_name);
+ 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:
- free(sk_provider);
- free(ext_name);
- 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;
+}
+
+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));
- free(sk_provider);
- goto send;
+ goto out;
}
if (strcasecmp(sk_provider, "internal") == 0) {
- debug("%s: internal provider", __func__);
+ debug_f("internal provider");
} else {
if (realpath(sk_provider, canonical_provider) == NULL) {
verbose("failed provider \"%.100s\": "
"realpath: %s", sk_provider,
strerror(errno));
- free(sk_provider);
- goto send;
+ goto out;
}
free(sk_provider);
sk_provider = xstrdup(canonical_provider);
@@ -616,17 +731,14 @@ process_add_identity(SocketEntry *e)
allowed_providers, 0) != 1) {
error("Refusing add key: "
"provider %s not allowed", sk_provider);
- free(sk_provider);
- goto send;
+ goto out;
}
}
}
if ((r = sshkey_shield_private(k)) != 0) {
- error("%s: shield private key: %s", __func__, ssh_err(r));
- goto err;
+ error_fr(r, "shield private");
+ goto out;
}
-
- success = 1;
if (lifetime && !death)
death = monotime() + lifetime;
if ((id = lookup_identity(k)) == NULL) {
@@ -640,6 +752,7 @@ process_add_identity(SocketEntry *e)
free(id->comment);
free(id->sk_provider);
}
+ /* success */
id->key = k;
id->comment = comment;
id->death = death;
@@ -648,12 +761,20 @@ process_add_identity(SocketEntry *e)
if ((fp = sshkey_fingerprint(k, SSH_FP_HASH_DEFAULT,
SSH_FP_DEFAULT)) == NULL)
- fatal("%s: sshkey_fingerprint failed", __func__);
- debug("%s: add %s %s \"%.100s\" (life: %u) (confirm: %u) "
- "(provider: %s)", __func__, sshkey_ssh_name(k), fp, comment,
- seconds, confirm, sk_provider == NULL ? "none" : sk_provider);
+ 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);
-send:
+ /* transferred */
+ k = NULL;
+ comment = NULL;
+ sk_provider = NULL;
+ success = 1;
+ out:
+ free(sk_provider);
+ free(comment);
+ sshkey_free(k);
send_status(e, success);
}
@@ -667,13 +788,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) {
@@ -716,11 +838,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);
}
@@ -731,39 +853,21 @@ 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",
@@ -775,7 +879,7 @@ process_add_smartcard_key(SocketEntry *e)
"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;
@@ -799,6 +903,7 @@ process_add_smartcard_key(SocketEntry *e)
idtab->nentries++;
success = 1;
}
+ /* XXX update constraints for existing keys */
sshkey_free(keys[i]);
free(comments[i]);
}
@@ -817,9 +922,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);
@@ -830,7 +936,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 */
@@ -845,7 +951,7 @@ 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);
@@ -865,10 +971,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)
@@ -876,8 +980,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)
@@ -889,13 +993,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) {
@@ -961,6 +1065,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"));
set_nonblock(fd);
if (fd > max_fd)
@@ -969,28 +1075,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;
}
@@ -1035,14 +1138,13 @@ 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));
for (;;) {
if ((r = process_message(socknum)) == -1)
@@ -1067,14 +1169,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;
}
@@ -1096,7 +1197,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 */
@@ -1157,7 +1258,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;
@@ -1184,12 +1285,10 @@ prepare_poll(struct pollfd **pfdp, size_t *npfdp, int *timeoutp, u_int maxfds)
if ((r = sshbuf_check_reserve(sockets[i].input,
AGENT_RBUF_LEN)) == 0 &&
(r = sshbuf_check_reserve(sockets[i].output,
- AGENT_MAX_LEN)) == 0)
+ AGENT_MAX_LEN)) == 0)
pfd[j].events = POLLIN;
- else if (r != SSH_ERR_NO_BUFFER_SPACE) {
- fatal("%s: buffer error: %s",
- __func__, ssh_err(r));
- }
+ else if (r != SSH_ERR_NO_BUFFER_SPACE)
+ fatal_fr(r, "reserve");
if (sshbuf_len(sockets[i].output) > 0)
pfd[j].events |= POLLOUT;
j++;
@@ -1218,7 +1317,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])
@@ -1273,7 +1372,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;
@@ -1493,14 +1592,8 @@ 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 */
diff --git a/ssh-ed25519-sk.c b/ssh-ed25519-sk.c
index f784776d4..4393ca669 100644
--- a/ssh-ed25519-sk.c
+++ b/ssh-ed25519-sk.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssh-ed25519-sk.c,v 1.5 2020/02/26 13:40:09 jsg Exp $ */
+/* $OpenBSD: ssh-ed25519-sk.c,v 1.6 2020/10/18 11:32:02 djm Exp $ */
/*
* Copyright (c) 2019 Markus Friedl. All rights reserved.
*
@@ -139,8 +139,7 @@ ssh_ed25519_sk_verify(const struct sshkey *key,
}
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 != smlen - len) {
r = SSH_ERR_SIGNATURE_INVALID;
diff --git a/ssh-ed25519.c b/ssh-ed25519.c
index 7dee82707..23419f3c8 100644
--- a/ssh-ed25519.c
+++ b/ssh-ed25519.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssh-ed25519.c,v 1.8 2020/02/26 13:40:09 jsg Exp $ */
+/* $OpenBSD: ssh-ed25519.c,v 1.9 2020/10/18 11:32:02 djm Exp $ */
/*
* Copyright (c) 2013 Markus Friedl <markus@openbsd.org>
*
@@ -140,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;
diff --git a/ssh-gss.h b/ssh-gss.h
index 36180d07a..a8af117d2 100644
--- a/ssh-gss.h
+++ b/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 $ */
/*
* Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved.
*
@@ -122,7 +122,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/ssh-keygen.0 b/ssh-keygen.0
index 111eb9e08..2027bdf3c 100644
--- a/ssh-keygen.0
+++ b/ssh-keygen.0
@@ -7,9 +7,9 @@ SYNOPSIS
ssh-keygen [-q] [-a rounds] [-b bits] [-C comment] [-f output_keyfile]
[-m format] [-N new_passphrase] [-O option]
[-t dsa | ecdsa | ecdsa-sk | ed25519 | ed25519-sk | rsa]
- [-w provider]
+ [-w provider] [-Z cipher]
ssh-keygen -p [-a rounds] [-f keyfile] [-m format] [-N new_passphrase]
- [-P old_passphrase]
+ [-P old_passphrase] [-Z cipher]
ssh-keygen -i [-f input_keyfile] [-m key_format]
ssh-keygen -e [-f input_keyfile] [-m key_format]
ssh-keygen -y [-f input_keyfile]
@@ -32,11 +32,13 @@ SYNOPSIS
ssh-keygen -k -f krl_file [-u] [-s ca_public] [-z version_number]
file ...
ssh-keygen -Q [-l] -f krl_file file ...
- ssh-keygen -Y find-principals -s signature_file -f allowed_signers_file
- ssh-keygen -Y check-novalidate -n namespace -s signature_file
+ ssh-keygen -Y find-principals [-O option] -s signature_file
+ -f allowed_signers_file
+ ssh-keygen -Y check-novalidate [-O option] -n namespace -s signature_file
ssh-keygen -Y sign -f key_file -n namespace file ...
- ssh-keygen -Y verify -f allowed_signers_file -I signer_identity
- -n namespace -s signature_file [-r revocation_file]
+ ssh-keygen -Y verify [-O option] -f allowed_signers_file
+ -I signer_identity -n namespace -s signature_file
+ [-r revocation_file]
DESCRIPTION
ssh-keygen generates, manages and converts authentication keys for
@@ -103,10 +105,10 @@ DESCRIPTION
-a rounds
When saving a private key, this option specifies the number of
- KDF (key derivation function) rounds used. Higher numbers result
- in slower passphrase verification and increased resistance to
- brute-force password cracking (should the keys be stolen). The
- default is 16 rounds.
+ KDF (key derivation function, currently 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). The default is 16 rounds.
-B Show the bubblebabble digest of specified private or public key
file.
@@ -303,6 +305,19 @@ DESCRIPTION
potentially sensitive. By default, this information is
discarded.
+ When performing signature-related options using the -Y flag, the
+ following options are accepted:
+
+ print-pubkey
+ Print the full public key to standard output after
+ signature verification.
+
+ verify-time=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.
+
The -O option may be specified multiple times.
-P passphrase
@@ -375,7 +390,7 @@ DESCRIPTION
from now), M-bM-^@M-^\-4w:+4wM-bM-^@M-^] (valid from four weeks ago to four weeks
from now), M-bM-^@M-^\20100101123000:20110101123000M-bM-^@M-^] (valid from 12:30 PM,
January 1st, 2010 to 12:30 PM, January 1st, 2011), M-bM-^@M-^\-1d:20110101M-bM-^@M-^]
- (valid from yesterday to midnight, January 1st, 2011).
+ (valid from yesterday to midnight, January 1st, 2011),
M-bM-^@M-^\-1m:foreverM-bM-^@M-^] (valid from one minute ago and never expiring).
-v Verbose mode. Causes ssh-keygen to print debugging messages
@@ -441,6 +456,12 @@ DESCRIPTION
-y This option will read a private OpenSSH format file and print an
OpenSSH public key to stdout.
+ -Z 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 "ssh -Q cipher". The default is
+ M-bM-^@M-^\aes256-ctrM-bM-^@M-^].
+
-z serial_number
Specifies a serial number to be embedded in the certificate to
distinguish this certificate from others from the same CA. If
@@ -482,8 +503,7 @@ MODULI GENERATION
generator option. Valid generator values are 2, 3, and 5.
Screened DH groups may be installed in /etc/moduli. It is important that
- this file contains moduli of a range of bit lengths and that both ends of
- a connection share common moduli.
+ this file contains moduli of a range of bit lengths.
A number of options are available for moduli generation and screening via
the -O flag:
@@ -640,8 +660,8 @@ CERTIFICATES
Finally, certificates may be defined with a validity lifetime. The -V
option allows specification of certificate start and end times. A
certificate that is presented at a time outside this range will not be
- considered valid. By default, certificates are valid from UNIX Epoch to
- the distant future.
+ considered valid. By default, certificates are valid from the UNIX Epoch
+ to the distant future.
For certificates to be used for user or host authentication, the CA
public key must be trusted by sshd(8) or ssh(1). Please refer to those
@@ -718,7 +738,7 @@ ALLOWED SIGNERS
keytype, base64-encoded key. Empty lines and lines starting with a M-bM-^@M-^X#M-bM-^@M-^Y
are ignored as comments.
- The principals field is a pattern-list (See PATTERNS in ssh_config(5))
+ The principals field is a pattern-list (see PATTERNS in 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 -I option must match a principals pattern in order for the
@@ -734,13 +754,22 @@ ALLOWED SIGNERS
(CA) and that certificates signed by this CA may be accepted for
verification.
- namespaces="namespace-list"
+ namespaces=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.
+ valid-after=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.
+
+ valid-before=timestamp
+ Indicates that the key is valid for use at or before the
+ specified timestamp.
+
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.
@@ -806,4 +835,4 @@ AUTHORS
created OpenSSH. Markus Friedl contributed the support for SSH protocol
versions 1.5 and 2.0.
-OpenBSD 6.8 September 9, 2020 OpenBSD 6.8
+OpenBSD 6.9 August 11, 2021 OpenBSD 6.9
diff --git a/ssh-keygen.1 b/ssh-keygen.1
index 3ae596caa..f83f515f6 100644
--- a/ssh-keygen.1
+++ b/ssh-keygen.1
@@ -1,4 +1,4 @@
-.\" $OpenBSD: ssh-keygen.1,v 1.209 2020/09/09 03:08:01 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,7 +35,7 @@
.\" (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 9 2020 $
+.Dd $Mdocdate: August 11 2021 $
.Dt SSH-KEYGEN 1
.Os
.Sh NAME
@@ -53,6 +53,7 @@
.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 a Ar rounds
@@ -60,6 +61,7 @@
.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 f Ar input_keyfile
@@ -145,10 +147,12 @@
.Ar
.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
@@ -158,6 +162,7 @@
.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
@@ -274,7 +279,9 @@ This is used by
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.
+(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).
The default is 16 rounds.
@@ -526,6 +533,19 @@ Please note that this information is potentially sensitive.
By default, this information is discarded.
.El
.Pp
+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
The
.Fl O
option may be specified multiple times.
@@ -634,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
@@ -738,6 +758,13 @@ 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.
@@ -805,8 +832,7 @@ 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
@@ -1003,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
@@ -1107,7 +1133,7 @@ Empty lines and lines starting with a
.Ql #
are ignored as comments.
.Pp
-The principals field is a pattern-list (See PATTERNS in
+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.
@@ -1124,11 +1150,16 @@ are case-insensitive):
.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="namespace-list"
+.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
diff --git a/ssh-keygen.c b/ssh-keygen.c
index a12b79a56..18e9f1d18 100644
--- a/ssh-keygen.c
+++ b/ssh-keygen.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssh-keygen.c,v 1.420 2020/09/09 03:08:01 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
@@ -65,6 +65,7 @@
#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"
@@ -184,7 +185,7 @@ type_bits_valid(int type, const char *name, u_int32_t *bitsp)
fatal("unknown key type %s", key_type_name);
if (*bitsp == 0) {
#ifdef WITH_OPENSSL
- u_int nid;
+ int nid;
switch(type) {
case KEY_DSA:
@@ -219,10 +220,11 @@ type_bits_valid(int type, const char *name, u_int32_t *bitsp)
break;
case KEY_ECDSA:
if (sshkey_ecdsa_bits_to_nid(*bitsp) == -1)
- fatal("Invalid ECDSA key length: valid lengths are "
#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
}
@@ -321,7 +323,7 @@ load_identity(const char *filename, char **commentp)
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
@@ -329,7 +331,7 @@ load_identity(const char *filename, char **commentp)
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;
}
@@ -347,11 +349,11 @@ do_convert_to_ssh2(struct passwd *pw, struct sshkey *k)
int r;
if ((b = sshbuf_new()) == NULL)
- fatal("%s: sshbuf_new failed", __func__);
+ fatal_f("sshbuf_new failed");
if ((r = sshkey_putb(k, b)) != 0)
- fatal("key_to_blob failed: %s", ssh_err(r));
+ fatal_fr(r, "put key");
if ((b64 = sshbuf_dtob64_string(b, 1)) == NULL)
- fatal("%s: sshbuf_dtob64_string failed", __func__);
+ fatal_f("sshbuf_dtob64_string failed");
/* Comment + surrounds must fit into 72 chars (RFC 4716 sec 3.3) */
snprintf(comment, sizeof(comment),
@@ -388,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);
}
@@ -412,7 +414,7 @@ do_convert_to_pem(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);
}
@@ -441,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);
}
@@ -457,15 +459,15 @@ 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 *
@@ -484,7 +486,7 @@ do_convert_private_ssh2(struct sshbuf *b)
BIGNUM *rsa_p = NULL, *rsa_q = NULL, *rsa_iqmp = NULL;
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,
@@ -497,7 +499,7 @@ do_convert_private_ssh2(struct sshbuf *b)
(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);
@@ -526,24 +528,24 @@ do_convert_private_ssh2(struct sshbuf *b)
(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) {
@@ -555,7 +557,7 @@ do_convert_private_ssh2(struct sshbuf *b)
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);
sshkey_free(key);
@@ -566,26 +568,26 @@ do_convert_private_ssh2(struct sshbuf *b)
(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("%s: remaining bytes in key blob %d", __func__, rlen);
+ error_f("remaining bytes in key blob %d", rlen);
/* try the key */
if (sshkey_sign(key, &sig, &slen, data, sizeof(data),
@@ -668,12 +670,12 @@ do_convert_from_ssh2(struct passwd *pw, struct sshkey **k, int *private)
(encoded[len-3] == '='))
encoded[len-3] = '\0';
if ((r = sshbuf_b64tod(buf, encoded)) != 0)
- fatal("%s: base64 decoding failed: %s", __func__, ssh_err(r));
+ fatal_fr(r, "base64 decode");
if (*private) {
if ((*k = do_convert_private_ssh2(buf)) == NULL)
- fatal("%s: private key conversion failed", __func__);
+ fatal_f("private key conversion failed");
} else if ((r = sshkey_fromb(buf, k)) != 0)
- fatal("decode blob failed: %s", ssh_err(r));
+ fatal_fr(r, "parse key");
sshbuf_free(buf);
fclose(fp);
}
@@ -687,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);
@@ -714,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);
@@ -737,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
@@ -763,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) {
@@ -788,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));
}
}
@@ -814,7 +815,7 @@ do_print_public(struct passwd *pw)
fatal("%s: %s", identity_file, strerror(errno));
prv = load_identity(identity_file, &comment);
if ((r = sshkey_write(prv, stdout)) != 0)
- error("sshkey_write failed: %s", ssh_err(r));
+ fatal_fr(r, "write key");
if (comment != NULL && *comment != '\0')
fprintf(stdout, " %s", comment);
fprintf(stdout, "\n");
@@ -850,7 +851,7 @@ 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_get() >= SYSLOG_LEVEL_VERBOSE)
@@ -901,7 +902,7 @@ 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_get() >= SYSLOG_LEVEL_VERBOSE)
@@ -921,12 +922,12 @@ fingerprint_private(const char *path)
if (stat(identity_file, &st) == -1)
fatal("%s: %s", path, strerror(errno));
if ((r = sshkey_load_public(path, &pubkey, &comment)) != 0)
- debug("load public \"%s\": %s", path, ssh_err(r));
+ debug_r(r, "load public \"%s\"", path);
if (pubkey == NULL || comment == NULL || *comment == '\0') {
free(comment);
if ((r = sshkey_load_private(path, NULL,
&privkey, &comment)) != 0)
- debug("load private \"%s\": %s", path, ssh_err(r));
+ debug_r(r, "load private \"%s\"", path);
}
if (pubkey == NULL && privkey == NULL)
fatal("%s is not a key file.", path);
@@ -1106,18 +1107,17 @@ do_gen_all_hostkeys(struct passwd *pw)
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, private_key_format, openssh_format_cipher,
rounds)) != 0) {
- error("Saving key \"%s\" failed: %s",
- prv_tmp, ssh_err(r));
+ error_r(r, "Saving key \"%s\" failed", prv_tmp);
goto failnext;
}
if ((fd = mkstemp(pub_tmp)) == -1) {
@@ -1128,8 +1128,8 @@ do_gen_all_hostkeys(struct passwd *pw)
(void)fchmod(fd, 0644);
(void)close(fd);
if ((r = sshkey_save_public(public, pub_tmp, comment)) != 0) {
- fatal("Unable to save public key to %s: %s",
- identity_file, ssh_err(r));
+ error_r(r, "Unable to save public key to %s",
+ identity_file);
goto failnext;
}
@@ -1263,8 +1263,7 @@ known_hosts_find_delete(struct hostkey_foreach_line *l, void *_ctx)
ra = sshkey_fingerprint(l->key,
fingerprint_hash, SSH_FP_RANDOMART);
if (fp == NULL || ra == NULL)
- fatal("%s: sshkey_fingerprint failed",
- __func__);
+ fatal_f("sshkey_fingerprint failed");
mprintf("%s %s %s%s%s\n", ctx->host,
sshkey_type(l->key), fp,
l->comment[0] ? " " : "",
@@ -1342,10 +1341,10 @@ do_known_hosts(struct passwd *pw, const char *name, int find_host,
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)
@@ -1424,7 +1423,7 @@ do_change_passphrase(struct passwd *pw)
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);
@@ -1456,8 +1455,7 @@ do_change_passphrase(struct passwd *pw)
/* Save the file using the new passphrase. */
if ((r = sshkey_save_private(private, identity_file, passphrase1,
comment, private_key_format, openssh_format_cipher, rounds)) != 0) {
- error("Saving key \"%s\" failed: %s.",
- identity_file, ssh_err(r));
+ error_r(r, "Saving key \"%s\" failed", identity_file);
freezero(passphrase1, strlen(passphrase1));
sshkey_free(private);
free(comment);
@@ -1485,15 +1483,14 @@ do_print_resource_record(struct passwd *pw, char *fname, char *hname,
int r;
if (fname == NULL)
- fatal("%s: no filename", __func__);
+ 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);
@@ -1520,8 +1517,7 @@ do_change_comment(struct passwd *pw, const char *identity_comment)
&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);
@@ -1534,8 +1530,8 @@ do_change_comment(struct passwd *pw, const char *identity_comment)
if ((r = sshkey_load_private(identity_file, passphrase,
&private, &comment)) != 0) {
freezero(passphrase, strlen(passphrase));
- fatal("Cannot load private key \"%s\": %s.",
- identity_file, ssh_err(r));
+ fatal_r(r, "Cannot load private key \"%s\"",
+ identity_file);
}
}
@@ -1576,8 +1572,7 @@ do_change_comment(struct passwd *pw, const char *identity_comment)
if ((r = sshkey_save_private(private, identity_file, passphrase,
new_comment, private_key_format, openssh_format_cipher,
rounds)) != 0) {
- error("Saving key \"%s\" failed: %s",
- identity_file, ssh_err(r));
+ error_r(r, "Saving key \"%s\" failed", identity_file);
freezero(passphrase, strlen(passphrase));
sshkey_free(private);
free(comment);
@@ -1585,14 +1580,12 @@ do_change_comment(struct passwd *pw, const char *identity_comment)
}
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));
- if ((r = sshkey_save_public(public, identity_file, new_comment)) != 0) {
- fatal("Unable to save public key to %s: %s",
- identity_file, 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);
free(comment);
@@ -1644,7 +1637,7 @@ prepare_options_buf(struct sshbuf *c, int which)
const struct cert_ext *ext;
if ((b = sshbuf_new()) == NULL)
- fatal("%s: sshbuf_new failed", __func__);
+ fatal_f("sshbuf_new failed");
sshbuf_reset(c);
for (i = 0; i < ncert_ext; i++) {
ext = &cert_ext[i];
@@ -1653,18 +1646,18 @@ prepare_options_buf(struct sshbuf *c, int which)
continue;
if (ext->val == NULL) {
/* flag option */
- debug3("%s: %s", __func__, ext->key);
+ debug3_f("%s", ext->key);
if ((r = sshbuf_put_cstring(c, ext->key)) != 0 ||
(r = sshbuf_put_string(c, NULL, 0)) != 0)
- fatal("%s: buffer: %s", __func__, ssh_err(r));
+ fatal_fr(r, "prepare flag");
} else {
/* key/value option */
- debug3("%s: %s=%s", __func__, ext->key, ext->val);
+ 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("%s: buffer: %s", __func__, ssh_err(r));
+ fatal_fr(r, "prepare k/v");
}
}
sshbuf_free(b);
@@ -1704,12 +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, NULL);
- debug3("%s: %d keys", __func__, nkeys);
+ debug3_f("%d keys", nkeys);
if (nkeys <= 0)
fatal("cannot read public key from pkcs11");
for (i = 0; i < nkeys; i++) {
@@ -1769,13 +1761,11 @@ do_ca_sign(struct passwd *pw, const char *ca_key_path, int prefer_agent,
* 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])) {
@@ -1794,7 +1784,7 @@ do_ca_sign(struct passwd *pw, const char *ca_key_path, int prefer_agent,
(ca->sk_flags & SSH_SK_USER_VERIFICATION_REQD)) {
if ((pin = read_passphrase("Enter PIN for CA key: ",
RP_ALLOW_STDIN)) == NULL)
- fatal("%s: couldn't read PIN", __func__);
+ fatal_f("couldn't read PIN");
}
}
free(tmp);
@@ -1829,16 +1819,14 @@ do_ca_sign(struct passwd *pw, const char *ca_key_path, int prefer_agent,
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));
+ fatal_r(r, "load pubkey \"%s\"", tmp);
if (sshkey_is_cert(public))
- fatal("%s: key \"%s\" type %s cannot be certified",
- __func__, tmp, sshkey_type(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);
@@ -1851,14 +1839,13 @@ do_ca_sign(struct passwd *pw, const char *ca_key_path, int prefer_agent,
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, sk_provider, NULL, agent_signer,
&agent_fd)) != 0)
- fatal("Couldn't certify key %s via agent: %s",
- tmp, ssh_err(r));
+ fatal_r(r, "Couldn't certify %s via agent", tmp);
} else {
if (sshkey_is_sk(ca) &&
(ca->sk_flags & SSH_SK_USER_PRESENCE_REQD)) {
@@ -1868,10 +1855,9 @@ do_ca_sign(struct passwd *pw, const char *ca_key_path, int prefer_agent,
}
r = sshkey_certify(public, ca, key_type_name,
sk_provider, pin);
- notify_complete(notifier);
+ notify_complete(notifier, "User presence confirmed");
if (r != 0)
- fatal("Couldn't certify key %s: %s",
- tmp, ssh_err(r));
+ fatal_r(r, "Couldn't certify key %s", tmp);
}
if ((cp = strrchr(tmp, '.')) != NULL && strcmp(cp, ".pub") == 0)
@@ -1880,8 +1866,8 @@ do_ca_sign(struct passwd *pw, const char *ca_key_path, int prefer_agent,
free(tmp);
if ((r = sshkey_save_public(public, out, comment)) != 0) {
- fatal("Unable to save public key to %s: %s",
- identity_file, ssh_err(r));
+ fatal_r(r, "Unable to save public key to %s",
+ identity_file);
}
if (!quiet) {
@@ -2023,7 +2009,7 @@ 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';
@@ -2041,13 +2027,13 @@ show_options(struct sshbuf *optbuf, int in_critical)
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 ||
@@ -2061,8 +2047,7 @@ show_options(struct sshbuf *optbuf, int 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 if (sshbuf_len(option) > 0) {
@@ -2091,7 +2076,7 @@ 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),
@@ -2164,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)) {
@@ -2192,11 +2176,11 @@ load_krl(const char *path, struct ssh_krl **krlp)
int r;
if ((r = sshbuf_load_file(path, &krlbuf)) != 0)
- fatal("Unable to load KRL: %s", ssh_err(r));
+ 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);
}
@@ -2225,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);
@@ -2313,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) {
@@ -2324,15 +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("%s: revoke key failed: %s",
- __func__, ssh_err(r));
+ fatal_fr(r, "revoke key failed");
} else {
if (strncasecmp(cp, "key:", 4) == 0) {
cp += 4;
@@ -2354,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) {
@@ -2375,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;
@@ -2416,8 +2396,7 @@ do_gen_krl(struct passwd *pw, int updating, const char *ca_key_path,
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);
}
}
@@ -2461,8 +2440,7 @@ do_check_krl(struct passwd *pw, int print_krl, int argc, char **argv)
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 ? ")" : "",
@@ -2496,8 +2474,8 @@ load_sign_key(const char *keypath, const struct sshkey *pubkey)
strcmp(privpath + plen - slen, suffixes[i]) != 0)
continue;
privpath[plen - slen] = '\0';
- debug("%s: %s looks like a public key, using private key "
- "path %s instead", __func__, keypath, privpath);
+ 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);
@@ -2514,12 +2492,11 @@ load_sign_key(const char *keypath, const struct sshkey *pubkey)
* it capable of signing.
*/
if ((r = sshkey_to_certified(privkey)) != 0) {
- error("%s: sshkey_to_certified: %s", __func__,
- ssh_err(r));
+ error_fr(r, "sshkey_to_certified");
goto done;
}
if ((r = sshkey_cert_copy(pubkey, privkey)) != 0) {
- error("%s: sshkey_cert_copy: %s", __func__, ssh_err(r));
+ error_fr(r, "sshkey_cert_copy");
goto done;
}
}
@@ -2553,12 +2530,12 @@ sign_one(struct sshkey *signkey, const char *filename, int fd,
sshkey_type(signkey));
if ((pin = read_passphrase(prompt,
RP_ALLOW_STDIN)) == NULL)
- fatal("%s: couldn't read PIN", __func__);
+ 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("%s: fingerprint failed", __func__);
+ fatal_f("fingerprint failed");
fprintf(stderr, "Confirm user presence for key %s %s\n",
sshkey_type(signkey), fp);
free(fp);
@@ -2566,15 +2543,15 @@ sign_one(struct sshkey *signkey, const char *filename, int fd,
}
if ((r = sshsig_sign_fd(signkey, NULL, sk_provider, pin,
fd, sig_namespace, &sigbuf, signer, signer_ctx)) != 0) {
- error("Signing %s failed: %s", filename, ssh_err(r));
+ error_r(r, "Signing %s failed", filename);
goto out;
}
if ((r = sshsig_armor(sigbuf, &abuf)) != 0) {
- error("%s: sshsig_armor: %s", __func__, ssh_err(r));
+ error_fr(r, "sshsig_armor");
goto out;
}
if ((asig = sshbuf_dup_string(abuf)) == NULL) {
- error("%s: buffer error", __func__);
+ error_f("buffer error");
r = SSH_ERR_ALLOC_FAIL;
goto out;
}
@@ -2641,17 +2618,17 @@ sig_sign(const char *keypath, const char *sig_namespace, int argc, char **argv)
}
if ((r = sshkey_load_public(keypath, &pubkey, NULL)) != 0) {
- error("Couldn't load public key %s: %s", keypath, ssh_err(r));
+ error_r(r, "Couldn't load public key %s", keypath);
goto done;
}
if ((r = ssh_get_authentication_socket(&agent_fd)) != 0)
- debug("Couldn't get agent socket: %s", ssh_err(r));
+ debug_r(r, "Couldn't get agent socket");
else {
if ((r = ssh_agent_has_key(agent_fd, pubkey)) == 0)
signer = agent_signer;
else
- debug("Couldn't find key in agent: %s", ssh_err(r));
+ debug_r(r, "Couldn't find key in agent");
}
if (signer == NULL) {
@@ -2696,23 +2673,63 @@ done:
}
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)
+ 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("Couldn't read signature file: %s", ssh_err(r));
+ error_r(r, "Couldn't read signature file");
goto done;
}
if ((r = sshsig_dearmor(abuf, &sigbuf)) != 0) {
- error("%s: sshsig_armor: %s", __func__, ssh_err(r));
+ error_fr(r, "sshsig_armor");
goto done;
}
if ((r = sshsig_verify_fd(sigbuf, STDIN_FILENO, sig_namespace,
@@ -2721,26 +2738,25 @@ sig_verify(const char *signature, const char *sig_namespace,
if ((fp = sshkey_fingerprint(sign_key, fingerprint_hash,
SSH_FP_DEFAULT)) == NULL)
- fatal("%s: sshkey_fingerprint failed", __func__);
+ fatal_f("sshkey_fingerprint failed");
debug("Valid (unverified) signature from key %s", fp);
if (sig_details != NULL) {
- debug2("%s: signature details: counter = %u, flags = 0x%02x",
- __func__, sig_details->sk_counter, sig_details->sk_flags);
+ 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("sshkey_check_revoked failed: %s", ssh_err(r));
+ debug3_fr(r, "sshkey_check_revoked");
goto done;
}
}
- if (allowed_keys != NULL &&
- (r = sshsig_check_allowed_keys(allowed_keys, sign_key,
- principal, sig_namespace)) != 0) {
- debug3("sshsig_check_allowed_keys failed: %s", ssh_err(r));
+ 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 */
@@ -2749,23 +2765,30 @@ done:
if (!quiet) {
if (ret == 0) {
if ((fp = sshkey_fingerprint(sign_key, fingerprint_hash,
- SSH_FP_DEFAULT)) == NULL) {
- fatal("%s: sshkey_fingerprint failed",
- __func__);
- }
+ 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);
+ 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);
+ 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);
@@ -2775,29 +2798,34 @@ done:
}
static int
-sig_find_principals(const char *signature, const char *allowed_keys) {
+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("Couldn't read signature file: %s", ssh_err(r));
+ error_r(r, "Couldn't read signature file");
goto done;
}
if ((r = sshsig_dearmor(abuf, &sigbuf)) != 0) {
- error("%s: sshsig_armor: %s", __func__, ssh_err(r));
+ error_fr(r, "sshsig_armor");
goto done;
}
if ((r = sshsig_get_pubkey(sigbuf, &sign_key)) != 0) {
- error("%s: sshsig_get_pubkey: %s",
- __func__, ssh_err(r));
+ error_fr(r, "sshsig_get_pubkey");
goto done;
}
if ((r = sshsig_find_principals(allowed_keys, sign_key,
- &principals)) != 0) {
- error("%s: sshsig_get_principal: %s",
- __func__, ssh_err(r));
+ verify_time, &principals)) != 0) {
+ if (r != SSH_ERR_KEY_NOT_FOUND)
+ error_fr(r, "sshsig_find_principal");
goto done;
}
ret = 0;
@@ -2997,7 +3025,7 @@ do_download_sk(const char *skprovider, const char *device)
&keys, &nkeys)) != 0) {
if (pin != NULL)
freezero(pin, strlen(pin));
- error("Unable to load resident keys: %s", ssh_err(r));
+ error_r(r, "Unable to load resident keys");
return -1;
}
if (nkeys == 0)
@@ -3014,8 +3042,8 @@ do_download_sk(const char *skprovider, const char *device)
}
if ((fp = sshkey_fingerprint(keys[i],
fingerprint_hash, SSH_FP_DEFAULT)) == NULL)
- fatal("%s: sshkey_fingerprint failed", __func__);
- debug("%s: key %zu: %s %s %s (flags 0x%02x)", __func__, i,
+ 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);
@@ -3035,8 +3063,7 @@ do_download_sk(const char *skprovider, const char *device)
if ((r = sshkey_save_private(keys[i], path, pass,
keys[i]->sk_application, private_key_format,
openssh_format_cipher, rounds)) != 0) {
- error("Saving key \"%s\" failed: %s",
- path, ssh_err(r));
+ error_r(r, "Saving key \"%s\" failed", path);
free(path);
break;
}
@@ -3053,8 +3080,7 @@ do_download_sk(const char *skprovider, const char *device)
free(path);
if ((r = sshkey_save_public(keys[i], pubpath,
keys[i]->sk_application)) != 0) {
- error("Saving public key \"%s\" failed: %s",
- pubpath, ssh_err(r));
+ error_r(r, "Saving public key \"%s\" failed", pubpath);
free(pubpath);
break;
}
@@ -3085,8 +3111,7 @@ save_attestation(struct sshbuf *attest, const char *path)
r = sshbuf_write_file(path, attest);
umask(omask);
if (r != 0)
- fatal("Unable to write attestation data \"%s\": %s", path,
- ssh_err(r));
+ fatal_r(r, "Unable to write attestation data \"%s\"", path);
if (!quiet)
printf("Your FIDO attestation certificate has been saved in "
"%s\n", path);
@@ -3099,11 +3124,13 @@ usage(void)
"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]\n"
+ " [-w provider] [-Z cipher]\n"
" ssh-keygen -p [-a rounds] [-f keyfile] [-m format] [-N new_passphrase]\n"
- " [-P old_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 [-a rounds] [-C comment] [-f keyfile] [-P passphrase]\n"
" ssh-keygen -l [-v] [-E fingerprint_hash] [-f input_keyfile]\n"
@@ -3134,7 +3161,7 @@ usage(void)
" 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");
+ " -n namespace -s signature_file [-r revocation_file]\n");
exit(1);
}
@@ -3185,6 +3212,7 @@ main(int argc, char **argv)
pw = getpwuid(getuid());
if (!pw)
fatal("No user exists for uid %lu", (u_long)getuid());
+ pw = pwcopy(pw);
if (gethostname(hostname, sizeof(hostname)) == -1)
fatal("gethostname: %s", strerror(errno));
@@ -3290,6 +3318,9 @@ main(int argc, char **argv)
break;
case 'Z':
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;
@@ -3398,15 +3429,16 @@ main(int argc, char **argv)
if (strncmp(sign_op, "find-principals", 15) == 0) {
if (ca_key_path == NULL) {
error("Too few arguments for find-principals:"
- "missing signature file");
+ "missing signature file");
exit(1);
}
if (!have_identity) {
error("Too few arguments for find-principals:"
- "missing allowed keys file");
+ "missing allowed keys file");
exit(1);
}
- return sig_find_principals(ca_key_path, identity_file);
+ 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') {
@@ -3424,11 +3456,11 @@ main(int argc, char **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");
+ "missing signature file");
exit(1);
}
return sig_verify(ca_key_path, cert_principals,
- NULL, NULL, NULL);
+ NULL, NULL, NULL, opts, nopts);
} else if (strncmp(sign_op, "verify", 6) == 0) {
if (cert_principals == NULL ||
*cert_principals == '\0') {
@@ -3452,7 +3484,8 @@ main(int argc, char **argv)
exit(1);
}
return sig_verify(ca_key_path, cert_principals,
- cert_key_id, identity_file, rr_hostname);
+ cert_key_id, identity_file, rr_hostname,
+ opts, nopts);
}
error("Unsupported operation for -Y: \"%s\"", sign_op);
usage();
@@ -3608,9 +3641,9 @@ main(int argc, char **argv)
} else if (strncasecmp(opts[i], "challenge=", 10) == 0) {
if ((r = sshbuf_load_file(opts[i] + 10,
&challenge)) != 0) {
- fatal("Unable to load FIDO enrollment "
- "challenge \"%s\": %s",
- opts[i] + 10, ssh_err(r));
+ fatal_r(r, "Unable to load FIDO "
+ "enrollment challenge \"%s\"",
+ opts[i] + 10);
}
} else if (strncasecmp(opts[i],
"write-attestation=", 18) == 0) {
@@ -3649,7 +3682,7 @@ main(int argc, char **argv)
if (r == 0)
break;
if (r != SSH_ERR_KEY_WRONG_PASSPHRASE)
- fatal("Key enrollment failed: %s", ssh_err(r));
+ fatal_r(r, "Key enrollment failed");
else if (passphrase != NULL) {
error("PIN incorrect");
freezero(passphrase, strlen(passphrase));
@@ -3676,7 +3709,7 @@ main(int argc, char **argv)
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");
@@ -3700,8 +3733,7 @@ main(int argc, char **argv)
/* Save the key with the given passphrase and comment. */
if ((r = sshkey_save_private(private, identity_file, passphrase,
comment, private_key_format, openssh_format_cipher, rounds)) != 0) {
- error("Saving key \"%s\" failed: %s",
- identity_file, ssh_err(r));
+ error_r(r, "Saving key \"%s\" failed", identity_file);
freezero(passphrase, strlen(passphrase));
exit(1);
}
@@ -3714,10 +3746,8 @@ main(int argc, char **argv)
}
strlcat(identity_file, ".pub", sizeof(identity_file));
- if ((r = sshkey_save_public(public, identity_file, comment)) != 0) {
- fatal("Unable to save public key to %s: %s",
- identity_file, ssh_err(r));
- }
+ 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,
diff --git a/ssh-keyscan.0 b/ssh-keyscan.0
index 1a5fefcbf..e65b4259a 100644
--- a/ssh-keyscan.0
+++ b/ssh-keyscan.0
@@ -93,4 +93,4 @@ AUTHORS
Davison <wayned@users.sourceforge.net> added support for protocol version
2.
-OpenBSD 6.8 November 30, 2019 OpenBSD 6.8
+OpenBSD 6.9 November 30, 2019 OpenBSD 6.9
diff --git a/ssh-keyscan.c b/ssh-keyscan.c
index ca190428a..7abbcbff5 100644
--- a/ssh-keyscan.c
+++ b/ssh-keyscan.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssh-keyscan.c,v 1.132 2020/08/12 01:23:45 cheloha 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>.
*
@@ -293,7 +293,7 @@ keygrab_ssh2(con *c)
# endif
#endif
c->c_ssh->kex->kex[KEX_C25519_SHA256] = kex_gen_client;
- c->c_ssh->kex->kex[KEX_KEM_SNTRUP4591761X25519_SHA512] = 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
@@ -367,7 +367,7 @@ tcpconnect(char *host)
continue;
}
if (set_nonblock(s) == -1)
- fatal("%s: set_nonblock(%d)", __func__, s);
+ 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));
@@ -401,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;
@@ -522,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);
@@ -635,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
@@ -786,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 */
@@ -809,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);
}
diff --git a/ssh-keysign.0 b/ssh-keysign.0
index b4ec3cc64..6d0c83997 100644
--- a/ssh-keysign.0
+++ b/ssh-keysign.0
@@ -49,4 +49,4 @@ HISTORY
AUTHORS
Markus Friedl <markus@openbsd.org>
-OpenBSD 6.8 November 30, 2019 OpenBSD 6.8
+OpenBSD 6.9 November 30, 2019 OpenBSD 6.9
diff --git a/ssh-keysign.c b/ssh-keysign.c
index 7991e0f01..d6ac98c6c 100644
--- a/ssh-keysign.c
+++ b/ssh-keysign.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssh-keysign.c,v 1.64 2020/08/27 01:06:18 djm Exp $ */
+/* $OpenBSD: ssh-keysign.c,v 1.67 2021/07/05 01:16:46 dtucker Exp $ */
/*
* Copyright (c) 2002 Markus Friedl. All rights reserved.
*
@@ -78,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);
@@ -112,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++;
@@ -127,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] != '.')
@@ -139,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++;
@@ -150,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);
@@ -207,7 +207,7 @@ main(int argc, char **argv)
initialize_options(&options);
(void)read_config_file(_PATH_HOST_CONFIG_FILE, pw, "", "",
&options, 0, NULL);
- fill_default_options(&options);
+ (void)fill_default_options(&options);
if (options.enable_ssh_keysign != 1)
fatal("ssh-keysign not enabled in %s",
_PATH_HOST_CONFIG_FILE);
@@ -228,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;
@@ -243,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 = %d", 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;
@@ -273,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, NULL, NULL, 0)) != 0)
- fatal("sshkey_sign failed: %s", ssh_err(r));
+ 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/ssh-pkcs11-client.c b/ssh-pkcs11-client.c
index 8a0ffef5d..e72473694 100644
--- a/ssh-pkcs11-client.c
+++ b/ssh-pkcs11-client.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssh-pkcs11-client.c,v 1.16 2020/01/25 00:03:36 djm 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.
@@ -65,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
@@ -93,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;
}
@@ -127,29 +127,29 @@ rsa_encrypt(int flen, const u_char *from, u_char *to, RSA *rsa, int padding)
goto fail;
key = sshkey_new(KEY_UNSPEC);
if (key == NULL) {
- error("%s: sshkey_new failed", __func__);
+ 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("%s: sshkey_to_blob: %s", __func__, ssh_err(r));
+ 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));
+ 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;
@@ -178,13 +178,13 @@ ecdsa_do_sign(const unsigned char *dgst, int dgst_len, const BIGNUM *inv,
nid = sshkey_ecdsa_key_to_nid(ec);
if (nid < 0) {
- error("%s: couldn't get curve nid", __func__);
+ error_f("couldn't get curve nid");
goto fail;
}
key = sshkey_new(KEY_UNSPEC);
if (key == NULL) {
- error("%s: sshkey_new failed", __func__);
+ error_f("sshkey_new failed");
goto fail;
}
key->ecdsa = ec;
@@ -193,22 +193,22 @@ ecdsa_do_sign(const unsigned char *dgst, int dgst_len, const BIGNUM *inv,
EC_KEY_up_ref(ec);
if ((r = sshkey_to_blob(key, &blob, &blen)) != 0) {
- error("%s: sshkey_to_blob: %s", __func__, ssh_err(r));
+ 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, dgst, dgst_len)) != 0 ||
(r = sshbuf_put_u32(msg, 0)) != 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_SIGN_RESPONSE) {
if ((r = sshbuf_get_string(msg, &signature, &slen)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "parse");
cp = signature;
ret = d2i_ECDSA_SIG(NULL, &cp, slen);
free(signature);
@@ -238,7 +238,7 @@ wrap_key(struct sshkey *k)
EC_KEY_set_method(k->ecdsa, helper_ecdsa);
#endif /* HAVE_EC_KEY_METHOD_NEW */
else
- fatal("%s: unknown key type", __func__);
+ fatal_f("unknown key type");
}
static int
@@ -260,10 +260,10 @@ pkcs11_start_helper_methods(void)
#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, rsa_encrypt))
- fatal("%s: failed to prepare method", __func__);
+ fatal_f("failed to prepare method");
return (0);
}
@@ -300,7 +300,7 @@ pkcs11_start_helper(void)
helper = getenv("SSH_PKCS11_HELPER");
if (helper == NULL || strlen(helper) == 0)
helper = _PATH_SSH_PKCS11_HELPER;
- debug("%s: starting %s %s", __func__, 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));
@@ -327,18 +327,18 @@ 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);
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 *));
@@ -346,10 +346,9 @@ pkcs11_add_provider(char *name, char *pin, struct sshkey ***keysp,
/* XXX clean up properly instead of fatal() */
if ((r = sshbuf_get_string(msg, &blob, &blen)) != 0 ||
(r = sshbuf_get_cstring(msg, &label, NULL)) != 0)
- fatal("%s: buffer error: %s",
- __func__, ssh_err(r));
+ fatal_fr(r, "parse key");
if ((r = sshkey_from_blob(blob, blen, &k)) != 0)
- fatal("%s: bad key: %s", __func__, ssh_err(r));
+ fatal_fr(r, "decode key");
wrap_key(k);
(*keysp)[i] = k;
if (labelsp)
@@ -375,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/ssh-pkcs11-helper.0 b/ssh-pkcs11-helper.0
index 973b551a5..0553465cf 100644
--- a/ssh-pkcs11-helper.0
+++ b/ssh-pkcs11-helper.0
@@ -32,4 +32,4 @@ HISTORY
AUTHORS
Markus Friedl <markus@openbsd.org>
-OpenBSD 6.8 November 30, 2019 OpenBSD 6.8
+OpenBSD 6.9 November 30, 2019 OpenBSD 6.9
diff --git a/ssh-pkcs11-helper.c b/ssh-pkcs11-helper.c
index d73e83576..5ca8d03fb 100644
--- a/ssh-pkcs11-helper.c
+++ b/ssh-pkcs11-helper.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssh-pkcs11-helper.c,v 1.23 2020/03/06 18:26:21 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.
*
@@ -98,7 +98,8 @@ lookup_key(struct sshkey *k)
struct pkcs11_keyinfo *ki;
TAILQ_FOREACH(ki, &pkcs11_keylist, next) {
- debug("check %p %s %s", ki, ki->providername, ki->label);
+ debug("check %s %s %s", sshkey_type(ki->key),
+ ki->providername, ki->label);
if (sshkey_equal(k, ki->key))
return (ki->key);
}
@@ -111,7 +112,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");
}
static void
@@ -126,35 +127,30 @@ process_add(void)
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));
+ 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, labels[i])) != 0)
- fatal("%s: buffer error: %s",
- __func__, ssh_err(r));
+ fatal_fr(r, "compose key");
free(blob);
add_key(keys[i], name, labels[i]);
free(labels[i]);
}
- } else {
- if ((r = sshbuf_put_u8(msg, SSH_AGENT_FAILURE)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
- if ((r = sshbuf_put_u32(msg, -nkeys)) != 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);
@@ -171,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);
@@ -198,10 +194,10 @@ 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
@@ -227,26 +223,25 @@ process_sign(void)
if (ret != 0)
ok = 0;
else
- error("%s: ECDSA_sign"
- " returns %d", __func__, ret);
+ error_f("ECDSA_sign returned %d", ret);
slen = xslen;
#endif /* OPENSSL_HAS_ECC */
} else
- error("%s: don't know how to sign with key "
- "type %d", __func__, (int)key->type);
+ 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);
@@ -278,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:
@@ -309,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");
}
}
@@ -356,14 +351,13 @@ main(int argc, char **argv)
log_init(__progname, log_level, log_facility, log_stderr);
pkcs11_init(0);
-
in = STDIN_FILENO;
out = STDOUT_FILENO;
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");
while (1) {
memset(pfd, 0, sizeof(pfd));
@@ -379,7 +373,7 @@ main(int argc, char **argv)
(r = sshbuf_check_reserve(oqueue, MAX_MSG_LENGTH)) == 0)
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");
if (sshbuf_len(oqueue) > 0)
pfd[1].events = POLLOUT;
@@ -399,10 +393,8 @@ 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 ((pfd[1].revents & (POLLOUT|POLLHUP)) != 0) {
@@ -411,10 +403,8 @@ main(int argc, char **argv)
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");
}
/*
@@ -425,7 +415,7 @@ 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");
}
}
diff --git a/ssh-pkcs11.c b/ssh-pkcs11.c
index f495883d1..37a6b1b5b 100644
--- a/ssh-pkcs11.c
+++ b/ssh-pkcs11.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssh-pkcs11.c,v 1.50 2020/05/29 03:14:02 djm 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.
@@ -46,6 +46,7 @@
#include "misc.h"
#include "sshkey.h"
#include "ssh-pkcs11.h"
+#include "digest.h"
#include "xmalloc.h"
struct pkcs11_slotinfo {
@@ -84,10 +85,9 @@ ossl_error(const char *msg)
{
unsigned long e;
- error("%s: %s", __func__, msg);
+ error_f("%s", msg);
while ((e = ERR_get_error()) != 0)
- error("%s: libcrypto error: %.100s", __func__,
- ERR_error_string(e, NULL));
+ error_f("libcrypto error: %s", ERR_error_string(e, NULL));
}
#endif /* HAVE_EC_KEY_METHOD_NEW */
@@ -111,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++) {
@@ -135,10 +135,10 @@ 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);
@@ -166,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);
}
@@ -202,7 +202,7 @@ pkcs11_k11_free(void *parent, void *ptr, CRYPTO_EX_DATA *ad, int idx,
{
struct pkcs11_key *k11 = ptr;
- debug("%s: parent %p ptr %p idx %d", __func__, parent, ptr, idx);
+ debug_f("parent %p ptr %p idx %d", parent, ptr, idx);
if (k11 == NULL)
return;
if (k11->provider)
@@ -263,7 +263,7 @@ pkcs11_login_slot(struct pkcs11_provider *provider, struct pkcs11_slotinfo *si,
snprintf(prompt, sizeof(prompt), "Enter PIN for '%s': ",
si->token.label);
if ((pin = read_passphrase(prompt, RP_ALLOW_EOF)) == NULL) {
- debug("%s: no pin specified", __func__);
+ debug_f("no pin specified");
return (-1); /* bail out */
}
}
@@ -337,8 +337,8 @@ pkcs11_check_obj_bool_attrib(struct pkcs11_key *k11, CK_OBJECT_HANDLE obj,
return (-1);
}
*val = flag != 0;
- debug("%s: provider %p slot %lu object %lu: attrib %lu = %d",
- __func__, k11->provider, k11->slotidx, obj, type, *val);
+ debug_f("provider \"%s\" slot %lu object %lu: attrib %lu = %d",
+ k11->provider->name, k11->slotidx, obj, type, *val);
return (0);
}
@@ -407,7 +407,7 @@ pkcs11_get_key(struct pkcs11_key *k11, CK_MECHANISM_TYPE mech_type)
pkcs11_check_obj_bool_attrib(k11, obj, CKA_ALWAYS_AUTHENTICATE,
&always_auth); /* ignore errors here */
if (always_auth && !did_login) {
- debug("%s: always-auth key", __func__);
+ debug_f("always-auth key");
if (pkcs11_login(k11, CKU_CONTEXT_SPECIFIC) < 0) {
error("login failed for always-auth key");
return (-1);
@@ -430,7 +430,7 @@ pkcs11_rsa_private_encrypt(int flen, const u_char *from, u_char *to, RSA *rsa,
int rval = -1;
if ((k11 = RSA_get_ex_data(rsa, rsa_idx)) == NULL) {
- error("RSA_get_ex_data failed for rsa %p", rsa);
+ error("RSA_get_ex_data failed");
return (-1);
}
@@ -475,7 +475,7 @@ pkcs11_rsa_start_wrapper(void)
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("%s: setup pkcs11 method failed", __func__);
+ error_f("setup pkcs11 method failed");
return (-1);
}
return (0);
@@ -561,7 +561,7 @@ ecdsa_do_sign(const unsigned char *dgst, int dgst_len, const BIGNUM *inv,
goto done;
}
if (!ECDSA_SIG_set0(ret, r, s)) {
- error("%s: ECDSA_SIG_set0 failed", __func__);
+ error_f("ECDSA_SIG_set0 failed");
ECDSA_SIG_free(ret);
ret = NULL;
goto done;
@@ -883,7 +883,7 @@ pkcs11_fetch_rsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx,
goto fail;
}
if (!RSA_set0_key(rsa, rsa_n, rsa_e, NULL))
- fatal("%s: set key", __func__);
+ fatal_f("set key");
rsa_n = rsa_e = NULL; /* transferred */
if (pkcs11_rsa_wrap(p, slotidx, &key_attr[0], rsa))
@@ -973,7 +973,7 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx,
}
/* Decode DER-encoded cert subject */
- cp = cert_attr[2].pValue;
+ 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)
@@ -1079,6 +1079,22 @@ have_rsa_key(const RSA *rsa)
}
#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.
@@ -1154,8 +1170,9 @@ pkcs11_fetch_certs(struct pkcs11_provider *p, CK_ULONG slotidx,
ck_cert_type);
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 */
@@ -1267,8 +1284,9 @@ pkcs11_fetch_keys(struct pkcs11_provider *p, CK_ULONG slotidx,
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 */
@@ -1355,7 +1373,7 @@ pkcs11_rsa_generate_private_key(struct pkcs11_provider *p, CK_ULONG slotidx,
if ((rv = f->C_GenerateKeyPair(session, &mech, tpub, npub, tpriv, npriv,
&pubKey, &privKey)) != CKR_OK) {
- error("%s: key generation failed: error 0x%lx", __func__, rv);
+ error_f("key generation failed: error 0x%lx", rv);
*err = rv;
return NULL;
}
@@ -1434,12 +1452,12 @@ pkcs11_ecdsa_generate_private_key(struct pkcs11_provider *p, CK_ULONG slotidx,
break;
}
if (!ec_curve_infos[i].name) {
- error("%s: invalid key size %lu", __func__, bits);
+ error_f("invalid key size %lu", bits);
return NULL;
}
if (pkcs11_decode_hex(ec_curve_infos[i].oid_encoded, &ecparams,
&ecparams_size) == -1) {
- error("%s: invalid oid", __func__);
+ error_f("invalid oid");
return NULL;
}
@@ -1472,7 +1490,7 @@ pkcs11_ecdsa_generate_private_key(struct pkcs11_provider *p, CK_ULONG slotidx,
if ((rv = f->C_GenerateKeyPair(session, &mech, tpub, npub, tpriv, npriv,
&pubKey, &privKey)) != CKR_OK) {
- error("%s: key generation failed: error 0x%lx", __func__, rv);
+ error_f("key generation failed: error 0x%lx", rv);
*err = rv;
return NULL;
}
@@ -1510,8 +1528,7 @@ pkcs11_register_provider(char *provider_id, char *pin,
*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-library */
@@ -1560,8 +1577,7 @@ pkcs11_register_provider(char *provider_id, char *pin,
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;
}
@@ -1580,13 +1596,12 @@ pkcs11_register_provider(char *provider_id, char *pin,
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));
@@ -1668,8 +1683,7 @@ pkcs11_add_provider(char *provider_id, char *pin, struct sshkey ***keyp,
pkcs11_provider_unref(p);
}
if (nkeys == 0)
- debug("%s: provider %s returned no keys", __func__,
- provider_id);
+ debug_f("provider %s returned no keys", provider_id);
return (nkeys);
}
@@ -1690,11 +1704,10 @@ pkcs11_gakp(char *provider_id, char *pin, unsigned int slotidx, char *label,
*err = 0;
if ((p = pkcs11_provider_lookup(provider_id)) != NULL)
- debug("%s: provider \"%s\" available", __func__, provider_id);
+ debug_f("provider \"%s\" available", provider_id);
else if ((ret = pkcs11_register_provider(provider_id, pin, NULL, NULL,
&p, CKU_SO)) < 0) {
- debug("%s: could not register provider %s", __func__,
- provider_id);
+ debug_f("could not register provider %s", provider_id);
goto out;
} else
reset_provider = 1;
@@ -1705,7 +1718,7 @@ pkcs11_gakp(char *provider_id, char *pin, unsigned int slotidx, char *label,
if ((rv = f->C_SetOperationState(session , pin, strlen(pin),
CK_INVALID_HANDLE, CK_INVALID_HANDLE)) != CKR_OK) {
- debug("%s: could not supply SO pin: %lu", __func__, rv);
+ debug_f("could not supply SO pin: %lu", rv);
reset_pin = 0;
} else
reset_pin = 1;
@@ -1714,20 +1727,20 @@ pkcs11_gakp(char *provider_id, char *pin, unsigned int slotidx, char *label,
case KEY_RSA:
if ((k = pkcs11_rsa_generate_private_key(p, slotidx, label,
bits, keyid, err)) == NULL) {
- debug("%s: failed to generate RSA key", __func__);
+ 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("%s: failed to generate ECDSA key", __func__);
+ debug_f("failed to generate ECDSA key");
goto out;
}
break;
default:
*err = SSH_PKCS11_ERR_GENERIC;
- debug("%s: unknown type %d", __func__, type);
+ debug_f("unknown type %d", type);
goto out;
}
@@ -1762,10 +1775,10 @@ pkcs11_destroy_keypair(char *provider_id, char *pin, unsigned long slotidx,
*err = 0;
if ((p = pkcs11_provider_lookup(provider_id)) != NULL) {
- debug("%s: using provider \"%s\"", __func__, provider_id);
+ debug_f("using provider \"%s\"", provider_id);
} else if (pkcs11_register_provider(provider_id, pin, NULL, NULL, &p,
CKU_SO) < 0) {
- debug("%s: could not register provider %s", __func__,
+ debug_f("could not register provider %s",
provider_id);
goto out;
} else
@@ -1777,7 +1790,7 @@ pkcs11_destroy_keypair(char *provider_id, char *pin, unsigned long slotidx,
if ((rv = f->C_SetOperationState(session , pin, strlen(pin),
CK_INVALID_HANDLE, CK_INVALID_HANDLE)) != CKR_OK) {
- debug("%s: could not supply SO pin: %lu", __func__, rv);
+ debug_f("could not supply SO pin: %lu", rv);
reset_pin = 0;
} else
reset_pin = 1;
@@ -1791,8 +1804,8 @@ pkcs11_destroy_keypair(char *provider_id, char *pin, unsigned long slotidx,
if (pkcs11_find(p, slotidx, attrs, nattrs, &obj) == 0 &&
obj != CK_INVALID_HANDLE) {
if ((rv = f->C_DestroyObject(session, obj)) != CKR_OK) {
- debug("%s: could not destroy private key 0x%hhx",
- __func__, keyid);
+ debug_f("could not destroy private key 0x%hhx",
+ keyid);
*err = rv;
goto out;
}
@@ -1813,8 +1826,8 @@ pkcs11_destroy_keypair(char *provider_id, char *pin, unsigned long slotidx,
sizeof(key_type));
rv = f->C_GetAttributeValue(session, obj, attrs, nattrs);
if (rv != CKR_OK) {
- debug("%s: could not get key type of public key 0x%hhx",
- __func__, keyid);
+ debug_f("could not get key type of public key 0x%hhx",
+ keyid);
*err = rv;
key_type = -1;
}
@@ -1824,8 +1837,7 @@ pkcs11_destroy_keypair(char *provider_id, char *pin, unsigned long slotidx,
k = pkcs11_fetch_ecdsa_pubkey(p, slotidx, &obj);
if ((rv = f->C_DestroyObject(session, obj)) != CKR_OK) {
- debug("%s: could not destroy public key 0x%hhx",
- __func__, keyid);
+ debug_f("could not destroy public key 0x%hhx", keyid);
*err = rv;
goto out;
}
diff --git a/ssh-sk-client.c b/ssh-sk-client.c
index 8d7e6c305..e93259009 100644
--- a/ssh-sk-client.c
+++ b/ssh-sk-client.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssh-sk-client.c,v 1.7 2020/01/23 07:10:22 dtucker Exp $ */
+/* $OpenBSD: ssh-sk-client.c,v 1.9 2021/04/03 06:18:41 djm Exp $ */
/*
* Copyright (c) 2019 Google LLC
*
@@ -47,7 +47,7 @@ static int
start_helper(int *fdp, pid_t *pidp, void (**osigchldp)(int))
{
void (*osigchld)(int);
- int oerrno, pair[2], r = SSH_ERR_INTERNAL_ERROR;
+ int oerrno, pair[2];
pid_t pid;
char *helper, *verbosity = NULL;
@@ -60,8 +60,7 @@ start_helper(int *fdp, pid_t *pidp, void (**osigchldp)(int))
helper = _PATH_SSH_SK_HELPER;
if (access(helper, X_OK) != 0) {
oerrno = errno;
- error("%s: helper \"%s\" unusable: %s", __func__, helper,
- strerror(errno));
+ error_f("helper \"%s\" unusable: %s", helper, strerror(errno));
errno = oerrno;
return SSH_ERR_SYSTEM_ERROR;
}
@@ -87,22 +86,22 @@ start_helper(int *fdp, pid_t *pidp, void (**osigchldp)(int))
if (pid == 0) {
if ((dup2(pair[1], STDIN_FILENO) == -1) ||
(dup2(pair[1], STDOUT_FILENO) == -1)) {
- error("%s: dup2: %s", __func__, ssh_err(r));
+ error_f("dup2: %s", strerror(errno));
_exit(1);
}
close(pair[0]);
close(pair[1]);
closefrom(STDERR_FILENO + 1);
- debug("%s: starting %s %s", __func__, helper,
+ debug_f("starting %s %s", helper,
verbosity == NULL ? "" : verbosity);
execlp(helper, helper, verbosity, (char *)NULL);
- error("%s: execlp: %s", __func__, strerror(errno));
+ error_f("execlp: %s", strerror(errno));
_exit(1);
}
close(pair[1]);
/* success */
- debug3("%s: started pid=%ld", __func__, (long)pid);
+ debug3_f("started pid=%ld", (long)pid);
*fdp = pair[0];
*pidp = pid;
*osigchldp = osigchld;
@@ -114,7 +113,7 @@ reap_helper(pid_t pid)
{
int status, oerrno;
- debug3("%s: pid=%ld", __func__, (long)pid);
+ debug3_f("pid=%ld", (long)pid);
errno = 0;
while (waitpid(pid, &status, 0) == -1) {
@@ -123,15 +122,15 @@ reap_helper(pid_t pid)
continue;
}
oerrno = errno;
- error("%s: waitpid: %s", __func__, strerror(errno));
+ error_f("waitpid: %s", strerror(errno));
errno = oerrno;
return SSH_ERR_SYSTEM_ERROR;
}
if (!WIFEXITED(status)) {
- error("%s: helper exited abnormally", __func__);
+ error_f("helper exited abnormally");
return SSH_ERR_AGENT_FAILURE;
} else if (WEXITSTATUS(status) != 0) {
- error("%s: helper exited with non-zero exit status", __func__);
+ error_f("helper exited with non-zero exit status");
return SSH_ERR_AGENT_FAILURE;
}
return 0;
@@ -158,40 +157,40 @@ client_converse(struct sshbuf *msg, struct sshbuf **respp, u_int type)
/* 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("%s: build: %s", __func__, ssh_err(r));
+ (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("%s: send: %s", __func__, ssh_err(r));
+ error_fr(r, "send");
goto out;
}
if ((r = ssh_msg_recv(fd, resp)) != 0) {
- error("%s: receive: %s", __func__, ssh_err(r));
+ error_fr(r, "receive");
goto out;
}
if ((r = sshbuf_get_u8(resp, &version)) != 0) {
- error("%s: parse version: %s", __func__, ssh_err(r));
+ error_fr(r, "parse version");
goto out;
}
if (version != SSH_SK_HELPER_VERSION) {
- error("%s: unsupported version: got %u, expected %u",
- __func__, 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("%s: parse message type: %s", __func__, ssh_err(r));
+ error_fr(r, "parse message type");
goto out;
}
if (rtype == SSH_SK_HELPER_ERROR) {
if ((r = sshbuf_get_u32(resp, &rerr)) != 0) {
- error("%s: parse error: %s", __func__, ssh_err(r));
+ error_fr(r, "parse");
goto out;
}
- debug("%s: helper returned error -%u", __func__, rerr);
+ 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;
@@ -199,8 +198,8 @@ client_converse(struct sshbuf *msg, struct sshbuf **respp, u_int type)
r = -(int)rerr;
goto out;
} else if (rtype != type) {
- error("%s: helper returned incorrect message type %u, "
- "expecting %u", __func__, rtype, type);
+ error_f("helper returned incorrect message type %u, "
+ "expecting %u", rtype, type);
r = SSH_ERR_INTERNAL_ERROR;
goto out;
}
@@ -250,7 +249,7 @@ sshsk_sign(const char *provider, struct sshkey *key,
}
if ((r = sshkey_private_serialize(key, kbuf)) != 0) {
- error("%s: serialize private key: %s", __func__, ssh_err(r));
+ error_fr(r, "encode key");
goto out;
}
if ((r = sshbuf_put_stringb(req, kbuf)) != 0 ||
@@ -259,13 +258,13 @@ sshsk_sign(const char *provider, struct sshkey *key,
(r = sshbuf_put_cstring(req, NULL)) != 0 || /* alg */
(r = sshbuf_put_u32(req, compat)) != 0 ||
(r = sshbuf_put_cstring(req, pin)) != 0) {
- error("%s: compose: %s", __func__, ssh_err(r));
+ error_fr(r, "compose");
goto out;
}
if ((fp = sshkey_fingerprint(key, SSH_FP_HASH_DEFAULT,
SSH_FP_DEFAULT)) == NULL) {
- error("%s: sshkey_fingerprint failed", __func__);
+ error_f("sshkey_fingerprint failed");
r = SSH_ERR_ALLOC_FAIL;
goto out;
}
@@ -273,12 +272,12 @@ sshsk_sign(const char *provider, struct sshkey *key,
goto out;
if ((r = sshbuf_get_string(resp, sigp, lenp)) != 0) {
- error("%s: parse signature: %s", __func__, ssh_err(r));
+ error_fr(r, "parse signature");
r = SSH_ERR_INVALID_FORMAT;
goto out;
}
if (sshbuf_len(resp) != 0) {
- error("%s: trailing data in response", __func__);
+ error_f("trailing data in response");
r = SSH_ERR_INVALID_FORMAT;
goto out;
}
@@ -334,7 +333,7 @@ sshsk_enroll(int type, const char *provider_path, const char *device,
(r = sshbuf_put_u8(req, flags)) != 0 ||
(r = sshbuf_put_cstring(req, pin)) != 0 ||
(r = sshbuf_put_stringb(req, challenge_buf)) != 0) {
- error("%s: compose: %s", __func__, ssh_err(r));
+ error_fr(r, "compose");
goto out;
}
@@ -343,21 +342,21 @@ sshsk_enroll(int type, const char *provider_path, const char *device,
if ((r = sshbuf_get_stringb(resp, kbuf)) != 0 ||
(r = sshbuf_get_stringb(resp, abuf)) != 0) {
- error("%s: parse signature: %s", __func__, ssh_err(r));
+ error_fr(r, "parse");
r = SSH_ERR_INVALID_FORMAT;
goto out;
}
if (sshbuf_len(resp) != 0) {
- error("%s: trailing data in response", __func__);
+ error_f("trailing data in response");
r = SSH_ERR_INVALID_FORMAT;
goto out;
}
if ((r = sshkey_private_deserialize(kbuf, &key)) != 0) {
- error("Unable to parse private key: %s", ssh_err(r));
+ error_fr(r, "encode");
goto out;
}
if (attest != NULL && (r = sshbuf_putb(attest, abuf)) != 0) {
- error("%s: buffer error: %s", __func__, ssh_err(r));
+ error_fr(r, "encode attestation information");
goto out;
}
@@ -398,7 +397,7 @@ sshsk_load_resident(const char *provider_path, const char *device,
if ((r = sshbuf_put_cstring(req, provider_path)) != 0 ||
(r = sshbuf_put_cstring(req, device)) != 0 ||
(r = sshbuf_put_cstring(req, pin)) != 0) {
- error("%s: compose: %s", __func__, ssh_err(r));
+ error_fr(r, "compose");
goto out;
}
@@ -409,21 +408,21 @@ sshsk_load_resident(const char *provider_path, const char *device,
/* key, comment */
if ((r = sshbuf_get_stringb(resp, kbuf)) != 0 ||
(r = sshbuf_get_cstring(resp, NULL, NULL)) != 0) {
- error("%s: parse signature: %s", __func__, ssh_err(r));
+ error_fr(r, "parse signature");
r = SSH_ERR_INVALID_FORMAT;
goto out;
}
if ((r = sshkey_private_deserialize(kbuf, &key)) != 0) {
- error("Unable to parse private key: %s", ssh_err(r));
+ error_fr(r, "decode key");
goto out;
}
if ((tmp = recallocarray(keys, nkeys, nkeys + 1,
sizeof(*keys))) == NULL) {
- error("%s: recallocarray keys failed", __func__);
+ error_f("recallocarray keys failed");
goto out;
}
- debug("%s: keys[%zu]: %s %s", __func__,
- nkeys, sshkey_type(key), key->sk_application);
+ debug_f("keys[%zu]: %s %s", nkeys, sshkey_type(key),
+ key->sk_application);
keys = tmp;
keys[nkeys++] = key;
key = NULL;
diff --git a/ssh-sk-helper.0 b/ssh-sk-helper.0
index 091f00e74..c9f0b9c07 100644
--- a/ssh-sk-helper.0
+++ b/ssh-sk-helper.0
@@ -31,4 +31,4 @@ HISTORY
AUTHORS
Damien Miller <djm@openbsd.org>
-OpenBSD 6.8 December 21, 2019 OpenBSD 6.8
+OpenBSD 6.9 December 21, 2019 OpenBSD 6.9
diff --git a/ssh-sk-helper.c b/ssh-sk-helper.c
index 8f92f4e23..21a08919d 100644
--- a/ssh-sk-helper.c
+++ b/ssh-sk-helper.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssh-sk-helper.c,v 1.10 2020/05/26 01:59:46 djm Exp $ */
+/* $OpenBSD: ssh-sk-helper.c,v 1.11 2020/10/18 11:32:02 djm Exp $ */
/*
* Copyright (c) 2019 Google LLC
*
@@ -67,7 +67,7 @@ reply_error(int r, char *fmt, ...)
free(msg);
if (r >= 0)
- fatal("%s: invalid error code %d", __func__, r);
+ fatal_f("invalid error code %d", r);
if ((resp = sshbuf_new()) == NULL)
fatal("%s: sshbuf_new failed", __progname);
@@ -106,17 +106,19 @@ process_sign(struct sshbuf *req)
(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("%s: buffer error: %s", __progname, ssh_err(r));
+ 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("Unable to parse private key: %s", ssh_err(r));
- if (!sshkey_is_sk(key))
- fatal("Unsupported key type %s", sshkey_ssh_name(key));
+ 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("%s: ready to sign with key %s, provider %s: "
- "msg len %zu, compat 0x%lx", __progname, sshkey_type(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);
@@ -132,7 +134,7 @@ process_sign(struct sshbuf *req)
if ((r = sshbuf_put_u32(resp, SSH_SK_HELPER_SIGN)) != 0 ||
(r = sshbuf_put_string(resp, sig, siglen)) != 0)
- fatal("%s: buffer error: %s", __progname, ssh_err(r));
+ fatal_r(r, "%s: compose", __progname);
out:
sshkey_free(key);
sshbuf_free(kbuf);
@@ -166,7 +168,7 @@ process_enroll(struct sshbuf *req)
(r = sshbuf_get_u8(req, &flags)) != 0 ||
(r = sshbuf_get_cstring(req, &pin, NULL)) != 0 ||
(r = sshbuf_froms(req, &challenge)) != 0)
- fatal("%s: buffer error: %s", __progname, ssh_err(r));
+ fatal_r(r, "%s: parse", __progname);
if (sshbuf_len(req) != 0)
fatal("%s: trailing data in request", __progname);
@@ -189,11 +191,11 @@ process_enroll(struct sshbuf *req)
if ((resp = sshbuf_new()) == NULL)
fatal("%s: sshbuf_new failed", __progname);
if ((r = sshkey_private_serialize(key, kbuf)) != 0)
- fatal("%s: serialize private key: %s", __progname, ssh_err(r));
+ 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("%s: buffer error: %s", __progname, ssh_err(r));
+ fatal_r(r, "%s: compose", __progname);
out:
sshkey_free(key);
@@ -223,7 +225,7 @@ process_load_resident(struct sshbuf *req)
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("%s: buffer error: %s", __progname, ssh_err(r));
+ fatal_r(r, "%s: parse", __progname);
if (sshbuf_len(req) != 0)
fatal("%s: trailing data in request", __progname);
@@ -241,18 +243,17 @@ process_load_resident(struct sshbuf *req)
fatal("%s: sshbuf_new failed", __progname);
if ((r = sshbuf_put_u32(resp, SSH_SK_HELPER_LOAD_RESIDENT)) != 0)
- fatal("%s: buffer error: %s", __progname, ssh_err(r));
+ fatal_r(r, "%s: compose", __progname);
for (i = 0; i < nkeys; i++) {
- debug("%s: key %zu %s %s", __func__, i,
- sshkey_type(keys[i]), keys[i]->sk_application);
+ 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("%s: serialize private key: %s",
- __progname, ssh_err(r));
+ fatal_r(r, "%s: encode key", __progname);
if ((r = sshbuf_put_stringb(resp, kbuf)) != 0 ||
(r = sshbuf_put_cstring(resp, "")) != 0) /* comment */
- fatal("%s: buffer error: %s", __progname, ssh_err(r));
+ fatal_r(r, "%s: compose key", __progname);
}
out:
@@ -311,10 +312,10 @@ main(int argc, char **argv)
if (ssh_msg_recv(in, req) < 0)
fatal("ssh_msg_recv failed");
close(in);
- debug("%s: received message len %zu", __progname, sshbuf_len(req));
+ debug_f("received message len %zu", sshbuf_len(req));
if ((r = sshbuf_get_u8(req, &version)) != 0)
- fatal("%s: buffer error: %s", __progname, ssh_err(r));
+ 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);
@@ -323,7 +324,7 @@ main(int argc, char **argv)
if ((r = sshbuf_get_u32(req, &rtype)) != 0 ||
(r = sshbuf_get_u8(req, &log_stderr)) != 0 ||
(r = sshbuf_get_u32(req, &ll)) != 0)
- fatal("%s: buffer error: %s", __progname, ssh_err(r));
+ fatal_r(r, "%s: parse", __progname);
if (!vflag && log_level_name((LogLevel)ll) != NULL)
log_init(__progname, (LogLevel)ll, log_facility, log_stderr);
@@ -342,7 +343,7 @@ main(int argc, char **argv)
fatal("%s: unsupported request type %u", __progname, rtype);
}
sshbuf_free(req);
- debug("%s: reply len %zu", __progname, sshbuf_len(resp));
+ debug_f("reply len %zu", sshbuf_len(resp));
if (ssh_msg_send(out, SSH_SK_HELPER_VERSION, resp) == -1)
fatal("ssh_msg_send failed");
diff --git a/ssh-sk.c b/ssh-sk.c
index 1455df635..d254e77f9 100644
--- a/ssh-sk.c
+++ b/ssh-sk.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssh-sk.c,v 1.32 2020/09/09 03:08:02 djm Exp $ */
+/* $OpenBSD: ssh-sk.c,v 1.35 2021/02/26 00:16:58 djm Exp $ */
/*
* Copyright (c) 2019 Google LLC
*
@@ -105,11 +105,11 @@ sshsk_open(const char *path)
return NULL;
}
if ((ret = calloc(1, sizeof(*ret))) == NULL) {
- error("%s: calloc failed", __func__);
+ error_f("calloc failed");
return NULL;
}
if ((ret->path = strdup(path)) == NULL) {
- error("%s: strdup failed", __func__);
+ error_f("strdup failed");
goto fail;
}
/* Skip the rest if we're using the linked in middleware */
@@ -134,8 +134,8 @@ sshsk_open(const char *path)
goto fail;
}
version = ret->sk_api_version();
- debug("%s: provider %s implements version 0x%08lx", __func__,
- ret->path, (u_long)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)",
@@ -200,7 +200,7 @@ sshsk_ecdsa_assemble(struct sk_enroll_response *resp, struct sshkey **keyp)
*keyp = NULL;
if ((key = sshkey_new(KEY_ECDSA_SK)) == NULL) {
- error("%s: sshkey_new failed", __func__);
+ error_f("sshkey_new failed");
r = SSH_ERR_ALLOC_FAIL;
goto out;
}
@@ -208,17 +208,17 @@ sshsk_ecdsa_assemble(struct sk_enroll_response *resp, struct sshkey **keyp)
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("%s: allocation failed", __func__);
+ 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("%s: buffer error: %s", __func__, ssh_err(r));
+ error_fr(r, "sshbuf_put_string");
goto out;
}
if ((r = sshbuf_get_ec(b, q, EC_KEY_get0_group(key->ecdsa))) != 0) {
- error("%s: parse key: %s", __func__, ssh_err(r));
+ error_fr(r, "parse");
r = SSH_ERR_INVALID_FORMAT;
goto out;
}
@@ -229,7 +229,7 @@ sshsk_ecdsa_assemble(struct sk_enroll_response *resp, struct sshkey **keyp)
}
if (EC_KEY_set_public_key(key->ecdsa, q) != 1) {
/* XXX assume it is a allocation error */
- error("%s: allocation failed", __func__);
+ error_f("allocation failed");
r = SSH_ERR_ALLOC_FAIL;
goto out;
}
@@ -253,17 +253,17 @@ sshsk_ed25519_assemble(struct sk_enroll_response *resp, struct sshkey **keyp)
*keyp = NULL;
if (resp->public_key_len != ED25519_PK_SZ) {
- error("%s: invalid size: %zu", __func__, resp->public_key_len);
+ 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("%s: sshkey_new failed", __func__);
+ error_f("sshkey_new failed");
r = SSH_ERR_ALLOC_FAIL;
goto out;
}
if ((key->ed25519_pk = malloc(ED25519_PK_SZ)) == NULL) {
- error("%s: malloc failed", __func__);
+ error_f("malloc failed");
r = SSH_ERR_ALLOC_FAIL;
goto out;
}
@@ -288,7 +288,7 @@ sshsk_key_from_response(int alg, const char *application, uint8_t flags,
/* Check response validity */
if (resp->public_key == NULL || resp->key_handle == NULL) {
- error("%s: sk_enroll response invalid", __func__);
+ error_f("sk_enroll response invalid");
r = SSH_ERR_INVALID_FORMAT;
goto out;
}
@@ -304,25 +304,25 @@ sshsk_key_from_response(int alg, const char *application, uint8_t flags,
goto out;
break;
default:
- error("%s: unsupported algorithm %d", __func__, alg);
+ 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("%s: allocation failed", __func__);
+ error_f("allocation failed");
r = SSH_ERR_ALLOC_FAIL;
goto out;
}
if ((key->sk_application = strdup(application)) == NULL) {
- error("%s: strdup application failed", __func__);
+ 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("%s: buffer error: %s", __func__, ssh_err(r));
+ error_fr(r, "put key handle");
goto out;
}
/* success */
@@ -374,18 +374,18 @@ sshsk_add_option(struct sk_option ***optsp, size_t *noptsp,
if ((opts = recallocarray(opts, nopts, nopts + 2, /* extra for NULL */
sizeof(*opts))) == NULL) {
- error("%s: array alloc failed", __func__);
+ error_f("array alloc failed");
return SSH_ERR_ALLOC_FAIL;
}
*optsp = opts;
*noptsp = nopts + 1;
if ((opts[nopts] = calloc(1, sizeof(**opts))) == NULL) {
- error("%s: alloc failed", __func__);
+ error_f("alloc failed");
return SSH_ERR_ALLOC_FAIL;
}
if ((opts[nopts]->name = strdup(name)) == NULL ||
(opts[nopts]->value = strdup(value)) == NULL) {
- error("%s: alloc failed", __func__);
+ error_f("alloc failed");
return SSH_ERR_ALLOC_FAIL;
}
opts[nopts]->required = required;
@@ -438,7 +438,7 @@ fill_attestation_blob(const struct sk_enroll_response *resp,
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("%s: buffer error: %s", __func__, ssh_err(r));
+ error_fr(r, "compose");
return r;
}
/* success */
@@ -461,8 +461,8 @@ sshsk_enroll(int type, const char *provider_path, const char *device,
int r = SSH_ERR_INTERNAL_ERROR;
int alg;
- debug("%s: provider \"%s\", device \"%s\", application \"%s\", "
- "userid \"%s\", flags 0x%02x, challenge len %zu%s", __func__,
+ 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" : "");
@@ -484,22 +484,22 @@ sshsk_enroll(int type, const char *provider_path, const char *device,
alg = SSH_SK_ED25519;
break;
default:
- error("%s: unsupported key type", __func__);
+ error_f("unsupported key type");
r = SSH_ERR_INVALID_ARGUMENT;
goto out;
}
if (provider_path == NULL) {
- error("%s: missing provider", __func__);
+ error_f("missing provider");
r = SSH_ERR_INVALID_ARGUMENT;
goto out;
}
if (application == NULL || *application == '\0') {
- error("%s: missing application", __func__);
+ error_f("missing application");
r = SSH_ERR_INVALID_ARGUMENT;
goto out;
}
if (challenge_buf == NULL) {
- debug("%s: using random challenge", __func__);
+ debug_f("using random challenge");
arc4random_buf(randchall, sizeof(randchall));
challenge = randchall;
challenge_len = sizeof(randchall);
@@ -510,8 +510,7 @@ sshsk_enroll(int type, const char *provider_path, const char *device,
} else {
challenge = sshbuf_ptr(challenge_buf);
challenge_len = sshbuf_len(challenge_buf);
- debug3("%s: using explicit challenge len=%zd",
- __func__, challenge_len);
+ 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? */
@@ -521,8 +520,7 @@ sshsk_enroll(int type, const char *provider_path, const char *device,
/* enroll key */
if ((r = skp->sk_enroll(alg, challenge, challenge_len, application,
flags, pin, opts, &resp)) != 0) {
- debug("%s: provider \"%s\" returned failure %d", __func__,
- provider_path, r);
+ debug_f("provider \"%s\" failure %d", provider_path, r);
r = skerr_to_ssherr(r);
goto out;
}
@@ -557,7 +555,7 @@ sshsk_ecdsa_sig(struct sk_sign_response *resp, struct sshbuf *sig)
/* Check response validity */
if (resp->sig_r == NULL || resp->sig_s == NULL) {
- error("%s: sk_sign response invalid", __func__);
+ error_f("sk_sign response invalid");
r = SSH_ERR_INVALID_FORMAT;
goto out;
}
@@ -570,13 +568,13 @@ sshsk_ecdsa_sig(struct sk_sign_response *resp, struct sshbuf *sig)
resp->sig_r, resp->sig_r_len)) != 0 ||
(r = sshbuf_put_bignum2_bytes(inner_sig,
resp->sig_s, resp->sig_s_len)) != 0) {
- debug("%s: buffer error: %s", __func__, ssh_err(r));
+ 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) {
- debug("%s: buffer error: %s", __func__, ssh_err(r));
+ error_fr(r, "compose");
goto out;
}
#ifdef DEBUG_SK
@@ -601,7 +599,7 @@ sshsk_ed25519_sig(struct sk_sign_response *resp, struct sshbuf *sig)
/* Check response validity */
if (resp->sig_r == NULL) {
- error("%s: sk_sign response invalid", __func__);
+ error_f("sk_sign response invalid");
r = SSH_ERR_INVALID_FORMAT;
goto out;
}
@@ -609,7 +607,7 @@ sshsk_ed25519_sig(struct sk_sign_response *resp, struct sshbuf *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) {
- debug("%s: buffer error: %s", __func__, ssh_err(r));
+ error_fr(r, "compose");
goto out;
}
#ifdef DEBUG_SK
@@ -633,7 +631,7 @@ sshsk_sign(const char *provider_path, struct sshkey *key,
struct sshbuf *inner_sig = NULL, *sig = NULL;
struct sk_option **opts = NULL;
- debug("%s: provider \"%s\", key %s, flags 0x%02x%s", __func__,
+ debug_f("provider \"%s\", key %s, flags 0x%02x%s",
provider_path, sshkey_type(key), key->sk_flags,
(pin != NULL && *pin != '\0') ? " with-pin" : "");
@@ -664,11 +662,16 @@ sshsk_sign(const char *provider_path, struct sshkey *key,
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("%s: sk_sign failed with code %d", __func__, r);
+ debug_f("sk_sign failed with code %d", r);
r = skerr_to_ssherr(r);
goto out;
}
@@ -678,7 +681,7 @@ sshsk_sign(const char *provider_path, struct sshkey *key,
goto out;
}
if ((r = sshbuf_put_cstring(sig, sshkey_ssh_name_plain(key))) != 0) {
- debug("%s: buffer error (outer): %s", __func__, ssh_err(r));
+ error_fr(r, "compose outer");
goto out;
}
switch (type) {
@@ -696,8 +699,8 @@ sshsk_sign(const char *provider_path, struct sshkey *key,
#ifdef DEBUG_SK
fprintf(stderr, "%s: sig_flags = 0x%02x, sig_counter = %u\n",
__func__, resp->flags, resp->counter);
- fprintf(stderr, "%s: hashed message:\n", __func__);
- sshbuf_dump_data(message, sizeof(message), stderr);
+ 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
@@ -752,7 +755,7 @@ sshsk_load_resident(const char *provider_path, const char *device,
uint8_t flags;
struct sk_option **opts = NULL;
- debug("%s: provider \"%s\"%s", __func__, provider_path,
+ debug_f("provider \"%s\"%s", provider_path,
(pin != NULL && *pin != '\0') ? ", have-pin": "");
if (keysp == NULL || nkeysp == NULL)
@@ -772,9 +775,8 @@ sshsk_load_resident(const char *provider_path, const char *device,
goto out;
}
for (i = 0; i < nrks; i++) {
- debug3("%s: rk %zu: slot = %zu, alg = %d, application = \"%s\"",
- __func__, i, rks[i]->slot, rks[i]->alg,
- rks[i]->application);
+ 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;
@@ -793,7 +795,7 @@ sshsk_load_resident(const char *provider_path, const char *device,
goto out;
if ((tmp = recallocarray(keys, nkeys, nkeys + 1,
sizeof(*tmp))) == NULL) {
- error("%s: recallocarray failed", __func__);
+ error_f("recallocarray failed");
r = SSH_ERR_ALLOC_FAIL;
goto out;
}
diff --git a/ssh-xmss.c b/ssh-xmss.c
index ccd4c7600..7bd3a96a3 100644
--- a/ssh-xmss.c
+++ b/ssh-xmss.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssh-xmss.c,v 1.2 2020/02/26 13:40:09 jsg 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);
@@ -164,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;
diff --git a/ssh.0 b/ssh.0
index 86ae53765..4f8e5325e 100644
--- a/ssh.0
+++ b/ssh.0
@@ -21,8 +21,8 @@ DESCRIPTION
ssh connects and logs into the specified destination, which may be
specified as either [user@]hostname or a URI of the form
- ssh://[user@]hostname[:port]. The user must prove his/her identity to
- the remote machine using one of several methods (see below).
+ ssh://[user@]hostname[:port]. The user must prove their identity to the
+ remote machine using one of several methods (see below).
If a command is specified, it is executed on the remote host instead of a
login shell.
@@ -121,7 +121,8 @@ DESCRIPTION
If the ExitOnForwardFailure configuration option is set to M-bM-^@M-^\yesM-bM-^@M-^],
then a client started with -f will wait for all remote port
forwards to be successfully established before placing itself in
- the background.
+ the background. Refer to the description of
+ ForkAfterAuthentication in ssh_config(5) for details.
-G Causes ssh to print its configuration after evaluating Host and
Match blocks and exit.
@@ -205,7 +206,8 @@ DESCRIPTION
keyword for more information.
-N Do not execute a remote command. This is useful for just
- forwarding ports.
+ forwarding ports. Refer to the description of SessionType in
+ ssh_config(5) for details.
-n Redirects stdin from /dev/null (actually, prevents reading from
stdin). This must be used when ssh is run in the background. A
@@ -215,7 +217,8 @@ DESCRIPTION
be automatically forwarded over an encrypted channel. The ssh
program will be put in the background. (This does not work if
ssh needs to ask for a password or passphrase; see also the -f
- option.)
+ option.) Refer to the description of StdinNull in ssh_config(5)
+ for details.
-O ctl_cmd
Control an active connection multiplexing master process. When
@@ -245,7 +248,6 @@ DESCRIPTION
CanonicalizePermittedCNAMEs
CASignatureAlgorithms
CertificateFile
- ChallengeResponseAuthentication
CheckHostIP
Ciphers
ClearAllForwardings
@@ -259,6 +261,7 @@ DESCRIPTION
EscapeChar
ExitOnForwardFailure
FingerprintHash
+ ForkAfterAuthentication
ForwardAgent
ForwardX11
ForwardX11Timeout
@@ -269,8 +272,8 @@ DESCRIPTION
GSSAPIDelegateCredentials
HashKnownHosts
Host
+ HostbasedAcceptedAlgorithms
HostbasedAuthentication
- HostbasedKeyTypes
HostKeyAlgorithms
HostKeyAlias
Hostname
@@ -281,6 +284,7 @@ DESCRIPTION
KbdInteractiveAuthentication
KbdInteractiveDevices
KexAlgorithms
+ KnownHostsCommand
LocalCommand
LocalForward
LogLevel
@@ -290,13 +294,14 @@ DESCRIPTION
NumberOfPasswordPrompts
PasswordAuthentication
PermitLocalCommand
+ PermitRemoteOpen
PKCS11Provider
Port
PreferredAuthentications
ProxyCommand
ProxyJump
ProxyUseFdpass
- PubkeyAcceptedKeyTypes
+ PubkeyAcceptedAlgorithms
PubkeyAuthentication
RekeyLimit
RemoteCommand
@@ -305,7 +310,9 @@ DESCRIPTION
SendEnv
ServerAliveInterval
ServerAliveCountMax
+ SessionType
SetEnv
+ StdinNull
StreamLocalBindMask
StreamLocalBindUnlink
StrictHostKeyChecking
@@ -324,18 +331,18 @@ DESCRIPTION
a per-host basis in the configuration file.
-Q query_option
- Queries ssh for the algorithms supported for the specified
- version 2. The available features are: cipher (supported
- symmetric ciphers), cipher-auth (supported symmetric ciphers that
- support authenticated encryption), help (supported query terms
- for use with the -Q flag), mac (supported message integrity
- codes), kex (key exchange algorithms), key (key types), key-cert
- (certificate key types), key-plain (non-certificate key types),
- key-sig (all key types and signature algorithms),
- protocol-version (supported SSH protocol versions), and sig
- (supported signature algorithms). Alternatively, any keyword
- from ssh_config(5) or sshd_config(5) that takes an algorithm list
- may be used as an alias for the corresponding query_option.
+ Queries for the algorithms supported by one of the following
+ features: cipher (supported symmetric ciphers), cipher-auth
+ (supported symmetric ciphers that support authenticated
+ encryption), help (supported query terms for use with the -Q
+ flag), mac (supported message integrity codes), kex (key exchange
+ algorithms), key (key types), key-cert (certificate key types),
+ key-plain (non-certificate key types), key-sig (all key types and
+ signature algorithms), protocol-version (supported SSH protocol
+ versions), and sig (supported signature algorithms).
+ Alternatively, any keyword from ssh_config(5) or sshd_config(5)
+ that takes an algorithm list may be used as an alias for the
+ corresponding query_option.
-q Quiet mode. Causes most warning and diagnostic messages to be
suppressed.
@@ -386,7 +393,8 @@ DESCRIPTION
-s May be used to request invocation of a subsystem on the remote
system. Subsystems facilitate the use of SSH as a secure
transport for other applications (e.g. sftp(1)). The subsystem
- is specified as the remote command.
+ is specified as the remote command. Refer to the description of
+ SessionType in ssh_config(5) for details.
-T Disable pseudo-terminal allocation.
@@ -455,7 +463,7 @@ AUTHENTICATION
The methods available for authentication are: GSSAPI-based
authentication, host-based authentication, public key authentication,
- challenge-response authentication, and password authentication.
+ keyboard-interactive authentication, and password authentication.
Authentication methods are tried in the order specified above, though
PreferredAuthentications can be used to change the default order.
@@ -494,7 +502,7 @@ AUTHENTICATION
different method. These may be viewed by increasing the LogLevel to
DEBUG or higher (e.g. by using the -v flag).
- The user creates his/her key pair by running ssh-keygen(1). This stores
+ The user creates their key pair by running ssh-keygen(1). This stores
the private key in ~/.ssh/id_dsa (DSA), ~/.ssh/id_ecdsa (ECDSA),
~/.ssh/id_ecdsa_sk (authenticator-hosted ECDSA), ~/.ssh/id_ed25519
(Ed25519), ~/.ssh/id_ed25519_sk (authenticator-hosted Ed25519), or
@@ -503,7 +511,7 @@ AUTHENTICATION
ECDSA), ~/.ssh/id_ed25519.pub (Ed25519), ~/.ssh/id_ed25519_sk.pub
(authenticator-hosted Ed25519), or ~/.ssh/id_rsa.pub (RSA) in the user's
home directory. The user should then copy the public key to
- ~/.ssh/authorized_keys in his/her home directory on the remote machine.
+ ~/.ssh/authorized_keys in their home directory on the remote machine.
The authorized_keys file corresponds to the conventional ~/.rhosts file,
and has one key per line, though the lines can be very long. After this,
the user can log in without giving the password.
@@ -519,10 +527,10 @@ AUTHENTICATION
may be with an authentication agent. See ssh-agent(1) and (optionally)
the AddKeysToAgent directive in ssh_config(5) for more information.
- Challenge-response authentication works as follows: The server sends an
- arbitrary "challenge" text, and prompts for a response. Examples of
- challenge-response authentication include BSD Authentication (see
- login.conf(5)) and PAM (some non-OpenBSD systems).
+ Keyboard-interactive authentication works as follows: The server sends an
+ arbitrary "challenge" text and prompts for a response, possibly multiple
+ times. Examples of keyboard-interactive authentication include BSD
+ Authentication (see login.conf(5)) and PAM (some non-OpenBSD systems).
Finally, if other authentication methods fail, ssh prompts the user for a
password. The password is sent to the remote host for checking; however,
@@ -999,4 +1007,4 @@ AUTHORS
created OpenSSH. Markus Friedl contributed the support for SSH protocol
versions 1.5 and 2.0.
-OpenBSD 6.8 July 15, 2020 OpenBSD 6.8
+OpenBSD 6.9 July 28, 2021 OpenBSD 6.9
diff --git a/ssh.1 b/ssh.1
index 555317887..77502515b 100644
--- a/ssh.1
+++ b/ssh.1
@@ -33,8 +33,8 @@
.\" (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.414 2020/07/15 05:40:05 jmc Exp $
-.Dd $Mdocdate: July 15 2020 $
+.\" $OpenBSD: ssh.1,v 1.425 2021/07/28 05:57:42 jmc Exp $
+.Dd $Mdocdate: July 28 2021 $
.Dt SSH 1
.Os
.Sh NAME
@@ -88,7 +88,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
@@ -259,6 +259,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
@@ -425,6 +430,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
@@ -446,6 +456,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.
@@ -485,7 +500,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
@@ -499,6 +513,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
@@ -509,8 +524,8 @@ 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
@@ -521,6 +536,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
@@ -530,13 +546,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
@@ -545,7 +562,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
@@ -566,10 +585,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
@@ -702,6 +718,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.
@@ -831,7 +852,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
@@ -906,7 +927,7 @@ 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
@@ -940,7 +961,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
@@ -969,11 +990,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 )
diff --git a/ssh.c b/ssh.c
index f34ca0d71..533a6aa99 100644
--- a/ssh.c
+++ b/ssh.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssh.c,v 1.536 2020/09/21 07:29:09 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
@@ -126,15 +126,6 @@ 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 mux-client launched in the foreground for ControlPersist.
@@ -142,14 +133,7 @@ int stdin_null_flag = 0;
int need_controlpersist_detach = 0;
/* Copies of flags for ControlPersist foreground mux-client */
-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;
+int ostdin_null_flag, osession_type, otty_flag, orequest_tty;
/*
* General data structure for command line options and options configurable
@@ -173,11 +157,6 @@ char *host;
*/
char *forward_agent_sock_path = NULL;
-/* 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;
-static const char *keyalias;
-
/* socket address the host resolves to */
struct sockaddr_storage hostaddr;
@@ -187,9 +166,6 @@ 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 forward_confirms_pending = -1;
@@ -214,8 +190,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. */
@@ -232,32 +208,17 @@ tilde_expand_paths(char **paths, u_int num_paths)
}
}
-#define DEFAULT_CLIENT_PERCENT_EXPAND_ARGS \
- "C", conn_hash_hex, \
- "L", shorthost, \
- "i", uidstr, \
- "k", keyalias, \
- "l", thishost, \
- "n", host_arg, \
- "p", portstr
-
/*
* 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 char *homedir,
- const char *remhost, const char *remuser, const char *locuser)
+default_client_percent_expand(const char *str,
+ const struct ssh_conn_info *cinfo)
{
return percent_expand(str,
- /* values from statics above */
- DEFAULT_CLIENT_PERCENT_EXPAND_ARGS,
- /* values from arguments */
- "d", homedir,
- "h", remhost,
- "r", remuser,
- "u", locuser,
+ DEFAULT_CLIENT_PERCENT_EXPAND_ARGS(cinfo),
(char *)NULL);
}
@@ -267,19 +228,13 @@ default_client_percent_expand(const char *str, const char *homedir,
* Caller must free returned string.
*/
static char *
-default_client_percent_dollar_expand(const char *str, const char *homedir,
- const char *remhost, const char *remuser, const char *locuser)
+default_client_percent_dollar_expand(const char *str,
+ const struct ssh_conn_info *cinfo)
{
char *ret;
ret = percent_dollar_expand(str,
- /* values from statics above */
- DEFAULT_CLIENT_PERCENT_EXPAND_ARGS,
- /* values from arguments */
- "d", homedir,
- "h", remhost,
- "r", remuser,
- "u", locuser,
+ DEFAULT_CLIENT_PERCENT_EXPAND_ARGS(cinfo),
(char *)NULL);
if (ret == NULL)
fatal("invalid environment variable expansion");
@@ -321,8 +276,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';
}
@@ -386,29 +341,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:
@@ -441,7 +394,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 ||
@@ -475,10 +428,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);
}
@@ -491,8 +444,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;
}
@@ -511,7 +463,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)
@@ -527,16 +479,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++) {
+ 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);
@@ -557,7 +510,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;
}
@@ -573,14 +526,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;
}
}
@@ -638,6 +591,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.
*/
@@ -647,8 +619,8 @@ 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, want_final_pass = 0;
- char *p, *cp, *line, *argv0, *logfile;
- char cname[NI_MAXHOST];
+ 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;
@@ -657,10 +629,17 @@ main(int ac, char **av)
struct addrinfo *addrs = NULL;
size_t n, len;
u_int j;
+ struct ssh_conn_info *cinfo = NULL;
/* 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
@@ -676,12 +655,6 @@ main(int ac, char **av)
seed_rng();
- /*
- * Discard other fds that are hanging around. These can cause problem
- * with backgrounded ssh processes started by ControlPersist.
- */
- closefrom(STDERR_FILENO + 1);
-
/* Get user data. */
pw = getpwuid(getuid());
if (!pw) {
@@ -737,11 +710,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;
@@ -808,10 +781,12 @@ main(int ac, char **av)
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 ||
+ strcasecmp(optarg, "PubkeyAcceptedKeyTypes") == 0 || /* deprecated name */
+ strcasecmp(optarg, "PubkeyAcceptedAlgorithms") == 0 ||
strcasecmp(optarg, "HostKeyAlgorithms") == 0 ||
- strcasecmp(optarg, "HostbasedKeyTypes") == 0 ||
- strcasecmp(optarg, "HostbasedAcceptedKeyTypes") == 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');
@@ -897,13 +872,7 @@ main(int ac, char **av)
break;
case 'V':
fprintf(stderr, "%s, %s\n",
- SSH_RELEASE,
-#ifdef WITH_OPENSSL
- OpenSSL_version(OPENSSL_VERSION)
-#else
- "without OpenSSL"
-#endif
- );
+ SSH_RELEASE, SSH_OPENSSL_VERSION);
if (opt == 'V')
exit(0);
break;
@@ -933,7 +902,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;
@@ -1036,7 +1005,10 @@ main(int ac, char **av)
#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':
@@ -1051,7 +1023,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);
@@ -1134,7 +1109,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();
@@ -1144,8 +1119,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");
}
}
@@ -1165,13 +1139,7 @@ main(int ac, char **av)
!use_syslog);
if (debug_flag)
- logit("%s, %s", SSH_RELEASE,
-#ifdef WITH_OPENSSL
- OpenSSL_version(OPENSSL_VERSION)
-#else
- "without OpenSSL"
-#endif
- );
+ logit("%s, %s", SSH_RELEASE, SSH_OPENSSL_VERSION);
/* Parse the configuration files */
process_config_files(host_arg, pw, 0, &want_final_pass);
@@ -1254,7 +1222,8 @@ 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);
@@ -1348,13 +1317,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)
@@ -1369,7 +1344,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 "
@@ -1378,17 +1353,24 @@ main(int ac, char **av)
}
/* 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);
- keyalias = options.host_key_alias ? options.host_key_alias : host_arg;
-
- conn_hash_hex = ssh_connection_hash(thishost, host, portstr,
- options.user);
+ 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);
/*
* Expand tokens in arguments. NB. LocalCommand is expanded later,
@@ -1399,26 +1381,25 @@ main(int ac, char **av)
debug3("expanding RemoteCommand: %s", options.remote_command);
cp = options.remote_command;
options.remote_command = default_client_percent_expand(cp,
- pw->pw_dir, host, options.user, pw->pw_name);
+ 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 = default_client_percent_dollar_expand(cp,
- pw->pw_dir, host, options.user, pw->pw_name);
+ cinfo);
free(cp);
}
if (options.identity_agent != NULL) {
p = tilde_expand_filename(options.identity_agent, getuid());
- cp = default_client_percent_dollar_expand(p,
- pw->pw_dir, host, options.user, pw->pw_name);
+ cp = default_client_percent_dollar_expand(p, cinfo);
free(p);
free(options.identity_agent);
options.identity_agent = cp;
@@ -1427,34 +1408,55 @@ main(int ac, char **av)
if (options.forward_agent_sock_path != NULL) {
p = tilde_expand_filename(options.forward_agent_sock_path,
getuid());
- cp = default_client_percent_dollar_expand(p,
- pw->pw_dir, host, options.user, pw->pw_name);
+ 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) {
- cp = tilde_expand_filename(options.user_hostfiles[j],
- getuid());
- p = default_client_percent_dollar_expand(cp,
- pw->pw_dir, host, options.user, pw->pw_name);
- 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;
- }
+ 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,
- pw->pw_dir, host, options.user, pw->pw_name);
+ default_client_percent_expand(cp, cinfo);
if (strcmp(cp, p) != 0)
debug3("expanded LocalForward listen path "
"'%s' -> '%s'", cp, p);
@@ -1463,8 +1465,7 @@ main(int ac, char **av)
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,
- pw->pw_dir, host, options.user, pw->pw_name);
+ default_client_percent_expand(cp, cinfo);
if (strcmp(cp, p) != 0)
debug3("expanded LocalForward connect path "
"'%s' -> '%s'", cp, p);
@@ -1476,8 +1477,7 @@ main(int ac, char **av)
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,
- pw->pw_dir, host, options.user, pw->pw_name);
+ default_client_percent_expand(cp, cinfo);
if (strcmp(cp, p) != 0)
debug3("expanded RemoteForward listen path "
"'%s' -> '%s'", cp, p);
@@ -1486,8 +1486,7 @@ main(int ac, char **av)
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,
- pw->pw_dir, host, options.user, pw->pw_name);
+ default_client_percent_expand(cp, cinfo);
if (strcmp(cp, p) != 0)
debug3("expanded RemoteForward connect path "
"'%s' -> '%s'", cp, p);
@@ -1538,13 +1537,16 @@ 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, host_arg, addrs, &hostaddr, options.port,
- options.address_family, options.connection_attempts,
+ options.connection_attempts,
&timeout_ms, options.tcp_keep_alive) != 0)
- exit(255);
+ exit(255);
if (addrs != NULL)
freeaddrinfo(addrs);
@@ -1570,13 +1572,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)
@@ -1595,7 +1597,7 @@ main(int ac, char **av)
}
/* 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 &&
@@ -1628,7 +1630,7 @@ main(int ac, char **av)
fatal("Invalid ForwardAgent environment variable name %s", cp);
}
if ((p = getenv(cp + 1)) != NULL)
- forward_agent_sock_path = p;
+ forward_agent_sock_path = xstrdup(p);
else
options.forward_agent = 0;
free(cp);
@@ -1647,14 +1649,7 @@ main(int ac, char **av)
/* Log into the remote system. Never returns if the login fails. */
ssh_login(ssh, &sensitive_data, host, (struct sockaddr *)&hostaddr,
- options.port, pw, timeout_ms);
-
- if (ssh_packet_connection_is_on_socket(ssh)) {
- verbose("Authenticated to %s ([%s]:%d).", host,
- ssh_remote_ipaddr(ssh), ssh_remote_port(ssh));
- } else {
- verbose("Authenticated to %s (via proxy).", host);
- }
+ options.port, pw, timeout_ms, cinfo);
/* We no longer need the private host keys. Clear them now. */
if (sensitive_data.nkeys != 0) {
@@ -1681,8 +1676,13 @@ 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);
+ exit_status = ssh_session2(ssh, cinfo);
+ ssh_conn_info_free(cinfo);
ssh_packet_close(ssh);
if (options.control_path != NULL && muxserver_sock != -1)
@@ -1698,9 +1698,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
@@ -1708,16 +1707,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 client to connect to backgrounded master */
- debug2("%s: background process is %ld", __func__, (long)pid);
- stdin_null_flag = ostdin_null_flag;
+ 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;
@@ -1725,18 +1725,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);
}
@@ -1745,26 +1735,14 @@ control_persist_detach(void)
static void
fork_postauth(void)
{
- int devnull, keep_stderr;
-
if (need_controlpersist_detach)
control_persist_detach();
debug("forking to background");
- fork_after_authentication_flag = 0;
+ options.fork_after_authentication = 0;
if (daemon(1, 1) == -1)
fatal("daemon() failed: %.200s", strerror(errno));
- if ((devnull = open(_PATH_DEVNULL, O_WRONLY)) == -1)
- error("%s: open %s: %s", __func__,
- _PATH_DEVNULL, 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, STDOUT_FILENO) == -1))
- fatal("%s: dup2() stdio failed", __func__);
- if (devnull > STDERR_FILENO)
- close(devnull);
- }
+ if (stdfd_devnull(1, 1, !(log_is_on_stderr() && debug_flag)) == -1)
+ error_f("stdfd_devnull failed");
}
static void
@@ -1773,12 +1751,12 @@ forwarding_success(void)
if (forward_confirms_pending == -1)
return;
if (--forward_confirms_pending == 0) {
- debug("%s: all expected forwarding replies received", __func__);
- if (fork_after_authentication_flag)
+ debug_f("all expected forwarding replies received");
+ if (options.fork_after_authentication)
fork_postauth();
} else {
- debug2("%s: %d expected forwarding replies remaining",
- __func__, forward_confirms_pending);
+ debug2_f("%d expected forwarding replies remaining",
+ forward_confirms_pending);
}
}
@@ -1801,7 +1779,7 @@ ssh_confirm_remote_forward(struct ssh *ssh, int type, u_int32_t seq, void *ctxt)
if (rfwd->listen_path == NULL && rfwd->listen_port == 0) {
if (type == SSH2_MSG_REQUEST_SUCCESS) {
if ((r = sshpkt_get_u32(ssh, &port)) != 0)
- fatal("%s: %s", __func__, ssh_err(r));
+ fatal_fr(r, "parse packet");
if (port > 65535) {
error("Invalid allocated port %u for remote "
"forward to %s:%d", port,
@@ -1867,7 +1845,7 @@ ssh_tun_confirm(struct ssh *ssh, int id, int success, void *arg)
cleanup_exit(255);
}
- debug("%s: tunnel forward established, id=%d", __func__, id);
+ debug_f("tunnel forward established, id=%d", id);
forwarding_success();
}
@@ -1880,25 +1858,67 @@ 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)) == -1 ||
(out = dup(STDOUT_FILENO)) == -1)
- fatal("channel_connect_stdio_fwd: dup() in/out failed");
+ 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. */
@@ -1961,7 +1981,7 @@ ssh_init_forwarding(struct ssh *ssh, char **ifname)
error("Could not request tunnel forwarding.");
}
if (forward_confirms_pending > 0) {
- debug("%s: expecting replies for %d forwards", __func__,
+ debug_f("expecting replies for %d forwards",
forward_confirms_pending);
}
}
@@ -1976,8 +1996,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");
}
}
}
@@ -1986,7 +2005,7 @@ static void
ssh_session2_setup(struct ssh *ssh, int id, int success, void *arg)
{
extern char **environ;
- const char *display;
+ const char *display, *term;
int r, interactive = tty_flag;
char *proto = NULL, *data = NULL;
@@ -2014,14 +2033,18 @@ ssh_session2_setup(struct ssh *ssh, int id, int success, void *arg)
debug("Requesting authentication agent forwarding.");
channel_request_start(ssh, id, "auth-agent-req@openssh.com", 0);
if ((r = sshpkt_send(ssh)) != 0)
- fatal("%s: %s", __func__, ssh_err(r));
+ fatal_fr(r, "send packet");
}
/* Tell the packet module whether this is an interactive session. */
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);
}
@@ -2032,7 +2055,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);
@@ -2043,14 +2066,6 @@ ssh_session2_open(struct ssh *ssh)
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) {
@@ -2060,12 +2075,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);
@@ -2073,9 +2088,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 r, devnull, id = -1;
+ int r, id = -1;
char *cp, *tun_fwd_ifname = NULL;
/* XXX should be pre-session */
@@ -2088,11 +2103,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,
- DEFAULT_CLIENT_PERCENT_EXPAND_ARGS,
- "d", pw->pw_dir,
- "h", host,
- "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);
@@ -2113,16 +2124,18 @@ ssh_session2(struct ssh *ssh, struct passwd *pw)
* 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
@@ -2131,7 +2144,7 @@ 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 {
ssh_packet_set_interactive(ssh,
@@ -2141,14 +2154,14 @@ ssh_session2(struct ssh *ssh, struct passwd *pw)
/* 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");
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("%s: %s", __func__, ssh_err(r));
+ fatal_fr(r, "send packet");
}
/* Execute a local command */
@@ -2162,23 +2175,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));
- } else {
- if (dup2(devnull, STDOUT_FILENO) == -1)
- 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 "
@@ -2193,7 +2197,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;
@@ -2249,8 +2253,7 @@ load_public_identity_files(struct passwd *pw)
continue;
}
cp = tilde_expand_filename(options.identity_files[i], getuid());
- filename = default_client_percent_dollar_expand(cp,
- pw->pw_dir, host, options.user, pw->pw_name);
+ filename = default_client_percent_dollar_expand(cp, cinfo);
free(cp);
check_load(sshkey_load_public(filename, &public, NULL),
filename, "pubkey");
@@ -2280,8 +2283,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;
@@ -2295,12 +2298,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 = default_client_percent_dollar_expand(cp,
- pw->pw_dir, host, options.user, pw->pw_name);
+ filename = default_client_percent_dollar_expand(cp, cinfo);
free(cp);
check_load(sshkey_load_public(filename, &public, NULL),
@@ -2314,8 +2316,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;
diff --git a/ssh2.h b/ssh2.h
index f2e37c96a..32ddae89b 100644
--- a/ssh2.h
+++ b/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/ssh_api.c b/ssh_api.c
index 129404b20..d3c661761 100644
--- a/ssh_api.c
+++ b/ssh_api.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssh_api.c,v 1.21 2020/08/27 01:06:18 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.
*
@@ -60,10 +60,6 @@ int mm_sshkey_sign(struct sshkey *, u_char **, u_int *,
DH *mm_choose_dh(int, int, int);
#endif
-/* Define these two variables here so that they are part of the library */
-u_char *session_id2 = NULL;
-u_int session_id2_len = 0;
-
int
mm_sshkey_sign(struct sshkey *key, u_char **sigp, u_int *lenp,
const u_char *data, u_int datalen, const char *alg,
@@ -85,7 +81,7 @@ mm_choose_dh(int min, int nbits, int max)
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;
@@ -122,7 +118,7 @@ ssh_init(struct ssh **sshp, int is_server, struct kex_params *kex_params)
# endif
#endif /* WITH_OPENSSL */
ssh->kex->kex[KEX_C25519_SHA256] = kex_gen_server;
- ssh->kex->kex[KEX_KEM_SNTRUP4591761X25519_SHA512] = 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;
@@ -140,7 +136,7 @@ ssh_init(struct ssh **sshp, int is_server, struct kex_params *kex_params)
# endif
#endif /* WITH_OPENSSL */
ssh->kex->kex[KEX_C25519_SHA256] = kex_gen_client;
- ssh->kex->kex[KEX_KEM_SNTRUP4591761X25519_SHA512] = kex_gen_client;
+ ssh->kex->kex[KEX_KEM_SNTRUP761X25519_SHA512] = kex_gen_client;
ssh->kex->verify_host_key =&_ssh_verify_host_key;
}
*sshp = ssh;
@@ -152,6 +148,9 @@ ssh_free(struct ssh *ssh)
{
struct key_entry *k;
+ if (ssh == NULL)
+ return;
+
/*
* we've only created the public keys variants in case we
* are a acting as a server.
@@ -356,13 +355,13 @@ _ssh_read_banner(struct ssh *ssh, struct sshbuf *banner)
if (sshbuf_len(banner) >= 4 &&
memcmp(sshbuf_ptr(banner), "SSH-", 4) == 0)
break;
- debug("%s: %.*s", __func__, (int)sshbuf_len(banner),
+ 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;
}
@@ -389,7 +388,7 @@ _ssh_read_banner(struct ssh *ssh, struct sshbuf *banner)
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;
@@ -469,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);
@@ -484,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);
@@ -499,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 */
}
@@ -547,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 */
diff --git a/ssh_config.0 b/ssh_config.0
index ae98748d2..b13a74e7d 100644
--- a/ssh_config.0
+++ b/ssh_config.0
@@ -152,7 +152,8 @@ DESCRIPTION
If this option is enabled, then the configuration files are
processed again using the new target name to pick up any new
- configuration in matching Host and Match stanzas.
+ configuration in matching Host and Match stanzas. A value of
+ none disables the use of a ProxyJump host.
CanonicalizeMaxDots
Specifies the maximum number of dot characters in a hostname
@@ -176,8 +177,17 @@ DESCRIPTION
Specifies which algorithms are allowed for signing of
certificates by certificate authorities (CAs). The default is:
- 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
+
+ If the specified list begins with a M-bM-^@M-^X+M-bM-^@M-^Y character, then the
+ specified algorithms will be appended to the default set instead
+ of replacing them. If the specified list begins with a M-bM-^@M-^X-M-bM-^@M-^Y
+ character, then the specified algorithms (including wildcards)
+ will be removed from the default set instead of replacing them.
ssh(1) will not accept host certificates signed using algorithms
other than those specified.
@@ -199,17 +209,13 @@ DESCRIPTION
sequence. Multiple CertificateFile directives will add to the
list of certificates used for authentication.
- ChallengeResponseAuthentication
- Specifies whether to use challenge-response authentication. The
- argument to this keyword must be yes (the default) or no.
-
CheckHostIP
- If set to yes (the default), ssh(1) will additionally check the
- host IP address in the known_hosts file. This allows it to
- detect if a host key changed due to DNS spoofing and will add
- addresses of destination hosts to ~/.ssh/known_hosts in the
- process, regardless of the setting of StrictHostKeyChecking. If
- the option is set to no, the check will not be executed.
+ If set to yes ssh(1) will additionally check the host IP address
+ in the known_hosts file. This allows it to detect if a host key
+ changed due to DNS spoofing and will add addresses of destination
+ hosts to ~/.ssh/known_hosts in the process, regardless of the
+ setting of StrictHostKeyChecking. If the option is set to no
+ (the default), the check will not be executed.
Ciphers
Specifies the ciphers allowed and their order of preference.
@@ -370,6 +376,23 @@ DESCRIPTION
Specifies the hash algorithm used when displaying key
fingerprints. Valid options are: md5 and sha256 (the default).
+ ForkAfterAuthentication
+ Requests ssh to go to background just before command execution.
+ This is useful if ssh is going to ask for passwords or
+ passphrases, but the user wants it in the background. This
+ implies the StdinNull configuration option being set to M-bM-^@M-^\yesM-bM-^@M-^].
+ The recommended way to start X11 programs at a remote site is
+ with something like ssh -f host xterm, which is the same as ssh
+ host xterm if the ForkAfterAuthentication configuration option is
+ set to M-bM-^@M-^\yesM-bM-^@M-^].
+
+ If the ExitOnForwardFailure configuration option is set to M-bM-^@M-^\yesM-bM-^@M-^],
+ then a client started with the ForkAfterAuthentication
+ configuration option being set to M-bM-^@M-^\yesM-bM-^@M-^] will wait for all remote
+ port forwards to be successfully established before placing
+ itself in the background. The argument to this keyword must be
+ yes (same as the -f option) or no (the default).
+
ForwardAgent
Specifies whether the connection to the authentication agent (if
any) will be forwarded to the remote machine. The argument may
@@ -450,69 +473,74 @@ DESCRIPTION
addresses in known hosts files will not be converted
automatically, but may be manually hashed using ssh-keygen(1).
- HostbasedAuthentication
- Specifies whether to try rhosts based authentication with public
- key authentication. The argument must be yes or no (the
- default).
-
- HostbasedKeyTypes
- Specifies the key types that will be used for hostbased
- authentication as a comma-separated list of patterns.
+ 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 M-bM-^@M-^X+M-bM-^@M-^Y character,
- then the specified key types will be appended to the default set
- instead of replacing them. If the specified list begins with a
- M-bM-^@M-^X-M-bM-^@M-^Y character, then the specified key types (including wildcards)
- will be removed from the default set instead of replacing them.
- If the specified list begins with a M-bM-^@M-^X^M-bM-^@M-^Y character, then the
- specified key types will be placed at the head of the default
- set. The default for this option is:
+ then the specified signature algorithms will be appended to the
+ default set instead of replacing them. If the specified list
+ begins with a M-bM-^@M-^X-M-bM-^@M-^Y 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 M-bM-^@M-^X^M-bM-^@M-^Y character, then the specified signature algorithms will be
+ placed at the head of the default set. The default for this
+ option is:
+ 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-ecdsa-sha2-nistp256-cert-v01@openssh.com,
- ssh-ed25519-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,
+ sk-ssh-ed25519@openssh.com,
sk-ecdsa-sha2-nistp256@openssh.com,
- ssh-ed25519,sk-ssh-ed25519@openssh.com,
rsa-sha2-512,rsa-sha2-256,ssh-rsa
- The -Q option of ssh(1) may be used to list supported key types.
+ The -Q option of ssh(1) may be used to list supported signature
+ algorithms. This was formerly named HostbasedKeyTypes.
+
+ HostbasedAuthentication
+ Specifies whether to try rhosts based authentication with public
+ key authentication. The argument must be yes or no (the
+ default).
HostKeyAlgorithms
- Specifies the host key algorithms that the client wants to use in
- order of preference. Alternately if the specified list begins
- with a M-bM-^@M-^X+M-bM-^@M-^Y character, then the specified key types will be
- appended to the default set instead of replacing them. If the
- specified list begins with a M-bM-^@M-^X-M-bM-^@M-^Y character, then the specified
- key types (including wildcards) will be removed from the default
- set instead of replacing them. If the specified list begins with
- a M-bM-^@M-^X^M-bM-^@M-^Y character, then the specified key types will be placed at
- the head of the default set. The default for this option is:
+ Specifies the host key signature algorithms that the client wants
+ to use in order of preference. Alternately if the specified list
+ begins with a M-bM-^@M-^X+M-bM-^@M-^Y character, then the specified signature
+ algorithms will be appended to the default set instead of
+ replacing them. If the specified list begins with a M-bM-^@M-^X-M-bM-^@M-^Y
+ 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 M-bM-^@M-^X^M-bM-^@M-^Y
+ character, then the specified signature algorithms will be placed
+ at the head of the default set. The default for this option is:
+ 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-ecdsa-sha2-nistp256-cert-v01@openssh.com,
- ssh-ed25519-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,
sk-ecdsa-sha2-nistp256@openssh.com,
- ssh-ed25519,sk-ssh-ed25519@openssh.com,
+ sk-ssh-ed25519@openssh.com,
rsa-sha2-512,rsa-sha2-256,ssh-rsa
If hostkeys are known for the destination host then this default
is modified to prefer their algorithms.
- The list of available key types may also be obtained using "ssh
- -Q HostKeyAlgorithms".
+ The list of available signature algorithms may also be obtained
+ using "ssh -Q HostKeyAlgorithms".
HostKeyAlias
Specifies an alias that should be used instead of the real host
@@ -621,6 +649,7 @@ DESCRIPTION
KbdInteractiveAuthentication
Specifies whether to use keyboard-interactive authentication.
The argument to this keyword must be yes (the default) or no.
+ ChallengeResponseAuthentication is a deprecated alias for this.
KbdInteractiveDevices
Specifies the list of methods to use in keyboard-interactive
@@ -650,6 +679,22 @@ DESCRIPTION
The list of available key exchange algorithms may also be
obtained using "ssh -Q kex".
+ KnownHostsCommand
+ Specifies a command to use to obtain a list of host keys, in
+ addition to those listed in UserKnownHostsFile and
+ 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
+ VERIFYING HOST KEYS section in ssh(1)). Arguments to
+ KnownHostsCommand accept the tokens described in the 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 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.
+
LocalCommand
Specifies a command to execute on the local machine after
successfully connecting to the server. The command string
@@ -692,6 +737,19 @@ DESCRIPTION
DEBUG and DEBUG1 are equivalent. DEBUG2 and DEBUG3 each specify
higher levels of verbose output.
+ 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:
+
+ kex.c:*:1000,*:kex_exchange_identification():*,packet.c:*
+
+ would enable detailed logging for line 1000 of kex.c, everything
+ in the kex_exchange_identification() function, and all code in
+ the packet.c file. This option is intended for debugging and no
+ overrides are enabled by default.
+
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-
@@ -736,6 +794,23 @@ DESCRIPTION
using the !command escape sequence in ssh(1). The argument must
be yes or no (the default).
+ PermitRemoteOpen
+ Specifies the destinations to which remote TCP port forwarding is
+ permitted when RemoteForward is used as a SOCKS proxy. The
+ forwarding specification must be one of the following forms:
+
+ PermitRemoteOpen host:port
+ PermitRemoteOpen IPv4_addr:port
+ PermitRemoteOpen [IPv6_addr]:port
+
+ Multiple forwards may be specified by separating them with
+ whitespace. An argument of any can be used to remove all
+ restrictions and permit any forwarding requests. An argument of
+ none can be used to prohibit all forwarding requests. The
+ wildcard M-bM-^@M-^X*M-bM-^@M-^Y 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.
+
PKCS11Provider
Specifies which PKCS#11 provider to use or none to indicate that
no provider should be used (the default). The argument to this
@@ -784,6 +859,7 @@ DESCRIPTION
will cause ssh(1) to connect to the target host by first making a
ssh(1) connection to the specified ProxyJump host and then
establishing a TCP forwarding to the ultimate target from there.
+ Setting the host to none disables this option entirely.
Note that this option will compete with the ProxyCommand option -
whichever is specified first will prevent later instances of the
@@ -799,34 +875,35 @@ DESCRIPTION
back to ssh(1) instead of continuing to execute and pass data.
The default is no.
- PubkeyAcceptedKeyTypes
- Specifies the key types that will be used for public key
- authentication as a comma-separated list of patterns. If the
- specified list begins with a M-bM-^@M-^X+M-bM-^@M-^Y character, then the key types
+ 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 M-bM-^@M-^X+M-bM-^@M-^Y character, then the algorithms
after it will be appended to the default instead of replacing it.
If the specified list begins with a M-bM-^@M-^X-M-bM-^@M-^Y character, then the
- specified key types (including wildcards) will be removed from
+ specified algorithms (including wildcards) will be removed from
the default set instead of replacing them. If the specified list
- begins with a M-bM-^@M-^X^M-bM-^@M-^Y character, then the specified key types will be
- placed at the head of the default set. The default for this
+ begins with a M-bM-^@M-^X^M-bM-^@M-^Y character, then the specified algorithms will
+ be placed at the head of the default set. The default for this
option is:
+ 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-ecdsa-sha2-nistp256-cert-v01@openssh.com,
- ssh-ed25519-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,
+ sk-ssh-ed25519@openssh.com,
sk-ecdsa-sha2-nistp256@openssh.com,
- ssh-ed25519,sk-ssh-ed25519@openssh.com,
rsa-sha2-512,rsa-sha2-256,ssh-rsa
- The list of available key types may also be obtained using "ssh
- -Q PubkeyAcceptedKeyTypes".
+ The list of available signature algorithms may also be obtained
+ using "ssh -Q PubkeyAcceptedAlgorithms".
PubkeyAuthentication
Specifies whether to try public key authentication. The argument
@@ -834,7 +911,7 @@ DESCRIPTION
RekeyLimit
Specifies the maximum amount of data that may be transmitted
- before the session key is renegotiated, optionally followed a
+ before the 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 M-bM-^@M-^XKM-bM-^@M-^Y, M-bM-^@M-^XMM-bM-^@M-^Y, or M-bM-^@M-^XGM-bM-^@M-^Y to indicate Kilobytes,
@@ -864,7 +941,9 @@ DESCRIPTION
domain socket path. If forwarding to a specific destination then
the second argument must be host: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.
+ remote forwarding will be established as a SOCKS proxy. When
+ acting as a SOCKS proxy the destination of the connection can be
+ restricted by PermitRemoteOpen.
IPv6 addresses can be specified by enclosing addresses in square
brackets. Multiple forwardings may be specified, and additional
@@ -952,9 +1031,24 @@ DESCRIPTION
default is 0, indicating that these messages will not be sent to
the server.
+ 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 none (same as the -N option),
+ subsystem (same as the -s option) or default (shell or command
+ execution).
+
SetEnv Directly specify one or more environment variables and their
- contents to be sent to the server. Similarly to SendEnv, the
- server must be prepared to accept the environment variable.
+ contents to be sent to the server. Similarly to SendEnv, with
+ the exception of the TERM variable, the server must be prepared
+ to accept the environment variable.
+
+ StdinNull
+ Redirects stdin from /dev/null (actually, prevents reading from
+ stdin). Either this or the equivalent -n option must be used
+ when ssh is run in the background. The argument to this keyword
+ must be yes (same as the -n option) or no (the default).
StreamLocalBindMask
Sets the octal file creation mode mask (umask) used when creating
@@ -987,7 +1081,7 @@ DESCRIPTION
This option forces the user to manually add all new hosts.
If this flag is set to M-bM-^@M-^\accept-newM-bM-^@M-^] then ssh will automatically
- add new host keys to the user known hosts files, but will not
+ add new host keys to the user's known_hosts file, but will not
permit connections to hosts with changed host keys. If this flag
is set to M-bM-^@M-^\noM-bM-^@M-^] or M-bM-^@M-^\offM-bM-^@M-^], ssh will automatically add new host keys
to the user known hosts files and allow connections to hosts with
@@ -1039,13 +1133,18 @@ DESCRIPTION
be yes, no or ask. This option allows learning alternate
hostkeys for a server and supports graceful key rotation by
allowing a server to send replacement public keys before old ones
- are removed. Additional hostkeys are only accepted if the key
- used to authenticate the host was already trusted or explicitly
- accepted by the user.
+ are removed.
+
+ Additional hostkeys are only accepted if the key used to
+ authenticate the host was already trusted or explicitly accepted
+ by the user, the host was authenticated via UserKnownHostsFile
+ (i.e. not GlobalKnownHostsFile) and the host was authenticated
+ using a plain key and not a certificate.
UpdateHostKeys is enabled by default if the user has not
- overridden the default UserKnownHostsFile setting, otherwise
- UpdateHostKeys will be set to ask.
+ overridden the default UserKnownHostsFile setting and has not
+ enabled VerifyHostKeyDNS, otherwise UpdateHostKeys will be set to
+ no.
If UpdateHostKeys is set to ask, then the user is asked to
confirm the modifications to the known_hosts file. Confirmation
@@ -1133,10 +1232,19 @@ TOKENS
%% A literal M-bM-^@M-^X%M-bM-^@M-^Y.
%C Hash of %l%h%p%r.
%d Local user's home directory.
+ %f The fingerprint of the server's host key.
+ %H The known_hosts hostname or address that is being searched
+ for.
%h The remote hostname.
+ %I A string describing the reason for a KnownHostsCommand
+ execution: either ADDRESS when looking up a host by address
+ (only when CheckHostIP is enabled), HOSTNAME when searching
+ by hostname, or ORDER when preparing the host key algorithm
+ preference list to use for the destination host.
%i The local user ID.
- %k The host key alias if specified, otherwise the orignal remote
- hostname given on the command line.
+ %K The base64 encoded host key.
+ %k The host key alias if specified, otherwise the original
+ remote hostname given on the command line.
%L The local hostname.
%l The local hostname, including the domain name.
%n The original remote hostname, as given on the command line.
@@ -1144,11 +1252,15 @@ TOKENS
%r The remote username.
%T The local tun(4) or tap(4) network interface assigned if
tunnel forwarding was requested, or "NONE" otherwise.
+ %t The type of the server host key, e.g. ssh-ed25519.
%u The local username.
- CertificateFile, ControlPath, IdentityAgent, IdentityFile, LocalForward,
- Match exec, RemoteCommand, RemoteForward, and UserKnownHostsFile accept
- the tokens %%, %C, %d, %h, %i, %L, %l, %n, %p, %r, and %u.
+ CertificateFile, ControlPath, IdentityAgent, IdentityFile,
+ KnownHostsCommand, LocalForward, Match exec, RemoteCommand,
+ RemoteForward, and UserKnownHostsFile accept the tokens %%, %C, %d, %h,
+ %i, %k, %L, %l, %n, %p, %r, and %u.
+
+ KnownHostsCommand additionally accepts the tokens %f, %H, %I, %K and %t.
Hostname accepts the tokens %% and %h.
@@ -1163,10 +1275,10 @@ ENVIRONMENT VARIABLES
environment variable does not exist then an error will be returned and
the setting for that keyword will be ignored.
- The keywords CertificateFile, ControlPath, IdentityAgent, IdentityFile
- and UserKnownHostsFile support environment variables. The keywords
- LocalForward and RemoteForward support environment variables only for
- Unix domain socket paths.
+ The keywords CertificateFile, ControlPath, IdentityAgent, IdentityFile,
+ KnownHostsCommand, and UserKnownHostsFile support environment variables.
+ The keywords LocalForward and RemoteForward support environment variables
+ only for Unix domain socket paths.
FILES
~/.ssh/config
@@ -1191,4 +1303,4 @@ AUTHORS
created OpenSSH. Markus Friedl contributed the support for SSH protocol
versions 1.5 and 2.0.
-OpenBSD 6.8 August 11, 2020 OpenBSD 6.8
+OpenBSD 6.9 August 12, 2021 OpenBSD 6.9
diff --git a/ssh_config.5 b/ssh_config.5
index 6be1f1aa2..cd0eea867 100644
--- a/ssh_config.5
+++ b/ssh_config.5
@@ -33,8 +33,8 @@
.\" (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.332 2020/08/11 09:49:57 djm Exp $
-.Dd $Mdocdate: August 11 2020 $
+.\" $OpenBSD: ssh_config.5,v 1.362 2021/08/12 23:59:25 djm Exp $
+.Dd $Mdocdate: August 12 2021 $
.Dt SSH_CONFIG 5
.Os
.Sh NAME
@@ -341,6 +341,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.
@@ -372,10 +377,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.
@@ -411,17 +428,9 @@ 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
-(the default),
.Xr ssh 1
will additionally check the host IP address in the
.Pa known_hosts
@@ -432,7 +441,8 @@ 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.
.It Cm Ciphers
Specifies the ciphers allowed and their order of preference.
@@ -682,6 +692,45 @@ 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.
@@ -800,43 +849,36 @@ 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.
+.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.
+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 key types will be placed at the head of the
-default set.
+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,
-sk-ecdsa-sha2-nistp256-cert-v01@openssh.com,
-ssh-ed25519-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,
+sk-ssh-ed25519@openssh.com,
sk-ecdsa-sha2-nistp256@openssh.com,
-ssh-ed25519,sk-ssh-ed25519@openssh.com,
rsa-sha2-512,rsa-sha2-256,ssh-rsa
.Ed
.Pp
@@ -844,43 +886,53 @@ 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 list begins with a
.Sq +
-character, then the specified key types will be appended to the default set
-instead of replacing them.
+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 key types will be placed at the head of the
-default set.
+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,
-sk-ecdsa-sha2-nistp256-cert-v01@openssh.com,
-ssh-ed25519-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,
sk-ecdsa-sha2-nistp256@openssh.com,
-ssh-ed25519,sk-ssh-ed25519@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
+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
@@ -1081,6 +1133,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.
@@ -1118,6 +1172,31 @@ diffie-hellman-group14-sha256
.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.
@@ -1181,6 +1260,23 @@ 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.
@@ -1245,6 +1341,42 @@ 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 or
.Cm none
@@ -1325,6 +1457,9 @@ 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
@@ -1344,40 +1479,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.
+.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 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 key types will be placed at the head of the
+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,
-sk-ecdsa-sha2-nistp256-cert-v01@openssh.com,
-ssh-ed25519-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,
+sk-ssh-ed25519@openssh.com,
sk-ecdsa-sha2-nistp256@openssh.com,
-ssh-ed25519,sk-ssh-ed25519@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 PubkeyAcceptedKeyTypes .
+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
@@ -1387,7 +1523,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 ,
@@ -1435,6 +1571,9 @@ If forwarding to a specific destination then the second argument must be
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
@@ -1568,12 +1707,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
@@ -1617,8 +1789,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
@@ -1714,16 +1887,24 @@ or
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, otherwise
+setting and has not enabled
+.Cm VerifyHostKeyDNS ,
+otherwise
.Cm UpdateHostKeys
will be set to
-.Cm ask .
+.Cm no .
.Pp
If
.Cm UpdateHostKeys
@@ -1855,12 +2036,33 @@ 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 orignal remote hostname given
+The host key alias if specified, otherwise the original remote hostname given
on the command line.
.It %L
The local hostname.
@@ -1881,6 +2083,9 @@ 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
@@ -1889,13 +2094,17 @@ The local username.
.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, %L, %l, %n, %p, %r, and %u.
+accept the tokens %%, %C, %d, %h, %i, %k, %L, %l, %n, %p, %r, and %u.
+.Pp
+.Cm KnownHostsCommand
+additionally accepts the tokens %f, %H, %I, %K and %t.
.Pp
.Cm Hostname
accepts the tokens %% and %h.
@@ -1919,7 +2128,8 @@ The keywords
.Cm CertificateFile ,
.Cm ControlPath ,
.Cm IdentityAgent ,
-.Cm IdentityFile
+.Cm IdentityFile ,
+.Cm KnownHostsCommand ,
and
.Cm UserKnownHostsFile
support environment variables.
diff --git a/sshbuf-misc.c b/sshbuf-misc.c
index afaab8d61..80714d1f3 100644
--- a/sshbuf-misc.c
+++ b/sshbuf-misc.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: sshbuf-misc.c,v 1.16 2020/06/22 05:54:10 djm Exp $ */
+/* $OpenBSD: sshbuf-misc.c,v 1.17 2021/08/11 05:21:32 djm Exp $ */
/*
* Copyright (c) 2011 Damien Miller
*
@@ -65,7 +65,7 @@ sshbuf_dump_data(const void *s, size_t len, FILE *f)
void
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);
}
diff --git a/sshconnect.c b/sshconnect.c
index 9ec0618a9..fcf87bb76 100644
--- a/sshconnect.c
+++ b/sshconnect.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: sshconnect.c,v 1.332 2020/09/09 21:57:27 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
@@ -30,6 +30,7 @@
#include <ctype.h>
#include <errno.h>
#include <fcntl.h>
+#include <limits.h>
#include <netdb.h>
#ifdef HAVE_PATHS_H
#include <paths.h>
@@ -90,7 +91,7 @@ expand_proxy_command(const char *proxy_command, const char *user,
{
char *tmp, *ret, strport[NI_MAXSERV];
const char *keyalias = options.host_key_alias ?
- options.host_key_alias : host_arg;
+ options.host_key_alias : host_arg;
snprintf(strport, sizeof strport, "%d", port);
xasprintf(&tmp, "exec %s", proxy_command);
@@ -105,24 +106,6 @@ expand_proxy_command(const char *proxy_command, const char *user,
return ret;
}
-static void
-stderr_null(void)
-{
- int devnull;
-
- if ((devnull = open(_PATH_DEVNULL, O_WRONLY)) == -1) {
- error("Can't open %s for stderr redirection: %s",
- _PATH_DEVNULL, strerror(errno));
- return;
- }
- if (devnull == STDERR_FILENO)
- return;
- if (dup2(devnull, STDERR_FILENO) == -1)
- error("Cannot redirect stderr to %s", _PATH_DEVNULL);
- if (devnull > STDERR_FILENO)
- close(devnull);
-}
-
/*
* Connect to the given ssh server using a proxy command that passes a
* a connected fd back to us.
@@ -169,8 +152,8 @@ ssh_proxy_fdpass_connect(struct ssh *ssh, const char *host,
* error messages may be printed on the user's terminal.
*/
if (!debug_flag && options.control_path != NULL &&
- options.control_persist)
- stderr_null();
+ options.control_persist && stdfd_devnull(0, 0, 1) == -1)
+ error_f("stdfd_devnull failed");
argv[0] = shell;
argv[1] = "-c";
@@ -252,16 +235,18 @@ ssh_proxy_connect(struct ssh *ssh, const char *host, const char *host_arg,
* error messages may be printed on the user's terminal.
*/
if (!debug_flag && options.control_path != NULL &&
- options.control_persist)
- stderr_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. */
+ /*
+ * 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]);
@@ -332,8 +317,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);
@@ -347,8 +331,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);
@@ -383,6 +366,10 @@ ssh_create_socket(struct addrinfo *ai)
}
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;
@@ -409,14 +396,14 @@ ssh_create_socket(struct addrinfo *ai)
#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
@@ -425,15 +412,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:
@@ -460,15 +446,15 @@ fail:
*/
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, 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));
@@ -492,7 +478,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;
}
@@ -551,19 +537,19 @@ ssh_connect_direct(struct ssh *ssh, const char *host, struct addrinfo *aitop,
int
ssh_connect(struct ssh *ssh, const char *host, const char *host_arg,
struct addrinfo *addrs, struct sockaddr_storage *hostaddr, u_short port,
- int family, int connection_attempts, int *timeout_ms, int want_keepalive)
+ 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 ((in = dup(STDIN_FILENO)) == -1 ||
(out = dup(STDOUT_FILENO)) == -1) {
if (in >= 0)
close(in);
- error("%s: dup() in/out failed", __func__);
+ error_f("dup() in/out failed");
return -1; /* ssh_packet_set_connection logs error */
}
if ((ssh_packet_set_connection(ssh, in, out)) == NULL)
@@ -606,32 +592,6 @@ confirm(const char *prompt, const char *fingerprint)
}
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) {
@@ -680,7 +640,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 "
@@ -704,6 +664,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.
@@ -712,19 +923,20 @@ 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;
+ 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;
@@ -744,6 +956,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;
}
@@ -751,7 +964,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
@@ -763,17 +977,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:
@@ -789,6 +1011,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.
@@ -811,10 +1041,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 "
@@ -836,7 +1096,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);
@@ -845,11 +1105,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;
}
@@ -869,45 +1131,48 @@ 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/[fingerprint])? ",
- 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);
- confirmed = confirm(msg, fp);
free(fp);
+ free(msg1);
+ free(msg2);
if (!confirmed)
goto fail;
hostkey_trusted = 1; /* user explicitly confirmed */
@@ -1012,8 +1277,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;
}
@@ -1033,13 +1298,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) {
@@ -1068,6 +1326,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");
@@ -1076,7 +1339,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;
@@ -1115,8 +1378,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;
}
@@ -1136,10 +1399,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;
}
@@ -1155,7 +1417,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;
@@ -1164,7 +1427,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;
}
@@ -1172,8 +1435,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;
}
@@ -1195,8 +1457,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;
}
@@ -1214,9 +1476,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;
}
@@ -1250,9 +1512,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);
@@ -1275,7 +1538,8 @@ out:
*/
void
ssh_login(struct ssh *ssh, Sensitive *sensitive, const char *orighost,
- struct sockaddr *hostaddr, u_short port, struct passwd *pw, int timeout_ms)
+ 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;
@@ -1298,7 +1562,7 @@ ssh_login(struct ssh *ssh, Sensitive *sensitive, const char *orighost,
/* key exchange */
/* authenticate user */
debug("Authenticating to %s:%d as '%s'", host, port, server_user);
- ssh_kex2(ssh, host, hostaddr, port);
+ ssh_kex2(ssh, host, hostaddr, port, cinfo);
ssh_userauth2(ssh, local_user, server_user, host, sensitive);
free(local_user);
free(host);
@@ -1323,14 +1587,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.",
@@ -1354,7 +1619,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! @");
diff --git a/sshconnect.h b/sshconnect.h
index 7c091e2b1..f518a9a13 100644
--- a/sshconnect.h
+++ b/sshconnect.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: sshconnect.h,v 1.40 2020/01/25 07:17:18 djm Exp $ */
+/* $OpenBSD: sshconnect.h,v 1.46 2020/12/22 00:15:23 djm Exp $ */
/*
* Copyright (c) 2000 Markus Friedl. All rights reserved.
@@ -30,23 +30,56 @@ 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;
+
+/* 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
int ssh_connect(struct ssh *, const char *, const char *,
struct addrinfo *, struct sockaddr_storage *, u_short,
- int, int, int *, int);
+ int, int *, int);
void ssh_kill_proxy_command(void);
void ssh_login(struct ssh *, Sensitive *, const char *,
- struct sockaddr *, u_short, struct passwd *, int);
+ 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_kex2(struct ssh *ssh, char *, struct sockaddr *, u_short);
+void ssh_kex2(struct ssh *ssh, char *, struct sockaddr *, u_short,
+ const struct ssh_conn_info *);
void ssh_userauth2(struct ssh *ssh, const char *, const char *,
char *, Sensitive *);
@@ -55,3 +88,7 @@ int ssh_local_cmd(const 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/sshconnect2.c b/sshconnect2.c
index f64aae66a..fea50fab6 100644
--- a/sshconnect2.c
+++ b/sshconnect2.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: sshconnect2.c,v 1.326 2020/09/18 05:23:03 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,6 +33,7 @@
#include <errno.h>
#include <fcntl.h>
+#include <limits.h>
#include <netdb.h>
#include <pwd.h>
#include <signal.h>
@@ -88,16 +89,15 @@ 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;
}
@@ -115,7 +115,8 @@ first_alg(const char *algs)
}
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 = NULL, *avail = NULL, *first = NULL, *last = NULL;
char *alg = NULL, *hostname = NULL, *ret = NULL, *best = NULL;
@@ -128,10 +129,15 @@ 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.
@@ -141,9 +147,10 @@ order_hostkeyalgs(char *host, struct sockaddr *hostaddr, u_short port)
*/
best = first_alg(options.hostkeyalgorithms);
if (lookup_key_in_hostkeys_by_type(hostkeys,
- sshkey_type_plain(sshkey_type_from_name(best)), NULL)) {
- debug3("%s: have matching best-preference key type %s, "
- "using HostkeyAlgorithms verbatim", __func__, best);
+ 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;
}
@@ -167,7 +174,7 @@ 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.
@@ -179,7 +186,8 @@ order_hostkeyalgs(char *host, struct sockaddr *hostaddr, u_short port)
}
/* 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);
continue;
}
@@ -190,8 +198,9 @@ order_hostkeyalgs(char *host, struct sockaddr *hostaddr, u_short port)
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);
@@ -204,7 +213,8 @@ order_hostkeyalgs(char *host, struct sockaddr *hostaddr, u_short port)
}
void
-ssh_kex2(struct ssh *ssh, 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;
@@ -212,6 +222,7 @@ ssh_kex2(struct ssh *ssh, char *host, struct sockaddr *hostaddr, u_short port)
xxx_host = host;
xxx_hostaddr = hostaddr;
+ xxx_conn_info = cinfo;
/*
* If the user has not specified HostkeyAlgorithms, or has only
@@ -225,18 +236,18 @@ ssh_kex2(struct ssh *ssh, char *host, struct sockaddr *hostaddr, u_short port)
/* Expand or fill in HostkeyAlgorithms */
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__);
+ 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] =
(char *)compression_alg_list(options.compression);
@@ -245,12 +256,12 @@ ssh_kex2(struct ssh *ssh, char *host, struct sockaddr *hostaddr, u_short port)
if (use_known_hosts_order) {
/* Query known_hosts and prefer algorithms that appear there */
myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] =
- compat_pkalg_proposal(
- order_hostkeyalgs(host, hostaddr, port));
+ compat_pkalg_proposal(ssh,
+ order_hostkeyalgs(host, hostaddr, port, cinfo));
} else {
/* Use specified HostkeyAlgorithms exactly */
myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] =
- compat_pkalg_proposal(options.hostkeyalgorithms);
+ compat_pkalg_proposal(ssh, options.hostkeyalgorithms);
}
if (options.rekey_limit || options.rekey_interval)
@@ -259,7 +270,7 @@ ssh_kex2(struct ssh *ssh, char *host, struct sockaddr *hostaddr, u_short port)
/* start key exchange */
if ((r = kex_setup(ssh, myproposal)) != 0)
- fatal("kex_setup: %s", ssh_err(r));
+ fatal_r(r, "kex_setup");
#ifdef WITH_OPENSSL
ssh->kex->kex[KEX_DH_GRP1_SHA1] = kex_gen_client;
ssh->kex->kex[KEX_DH_GRP14_SHA1] = kex_gen_client;
@@ -273,19 +284,16 @@ ssh_kex2(struct ssh *ssh, char *host, struct sockaddr *hostaddr, u_short port)
# endif
#endif
ssh->kex->kex[KEX_C25519_SHA256] = kex_gen_client;
- ssh->kex->kex[KEX_KEM_SNTRUP4591761X25519_SHA512] = 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(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);
+ compat_kex_proposal(ssh, options.kex_algorithms);
if ((r = kex_prop2buf(ssh->kex->my, myproposal)) != 0)
- fatal("kex_prop2buf: %s", ssh_err(r));
-
- session_id2 = ssh->kex->session_id;
- session_id2_len = ssh->kex->session_id_len;
+ fatal_r(r, "kex_prop2buf");
#ifdef DEBUG_KEXDH
/* send 1st encrypted/maced/compressed message */
@@ -293,7 +301,7 @@ ssh_kex2(struct ssh *ssh, 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
}
@@ -434,8 +442,6 @@ ssh_userauth2(struct ssh *ssh, const char *local_user,
Authctxt authctxt;
int r;
- if (options.challenge_response_authentication)
- options.kbd_interactive_authentication = 1;
if (options.preferred_authentications == NULL)
options.preferred_authentications = authmethods_get();
@@ -461,14 +467,13 @@ ssh_userauth2(struct ssh *ssh, const char *local_user,
authctxt.agent_fd = -1;
pubkey_prepare(&authctxt);
if (authctxt.method == NULL) {
- fatal("%s: internal error: cannot send userauth none request",
- __func__);
+ 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);
@@ -482,7 +487,14 @@ ssh_userauth2(struct ssh *ssh, const char *local_user,
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 */
@@ -566,7 +578,7 @@ userauth(struct ssh *ssh, char *authlist)
static int
input_userauth_error(int type, u_int32_t seq, struct ssh *ssh)
{
- fatal("%s: bad message during authentication: type %d", __func__, type);
+ fatal_f("bad message during authentication: type %d", type);
return 0;
}
@@ -578,7 +590,7 @@ input_userauth_banner(int type, u_int32_t seq, struct ssh *ssh)
size_t len;
int r;
- debug3("%s", __func__);
+ debug3_f("entering");
if ((r = sshpkt_get_cstring(ssh, &msg, &len)) != 0 ||
(r = sshpkt_get_cstring(ssh, NULL, NULL)) != 0)
goto out;
@@ -597,7 +609,7 @@ input_userauth_success(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");
free(authctxt->authlist);
authctxt->authlist = NULL;
if (authctxt->method != NULL && authctxt->method->cleanup != NULL)
@@ -615,7 +627,7 @@ 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);
@@ -640,7 +652,8 @@ input_userauth_failure(int type, u_int32_t seq, struct ssh *ssh)
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);
}
@@ -664,7 +677,7 @@ format_identity(Identity *id)
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) {
@@ -705,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) {
@@ -733,7 +746,7 @@ 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;
}
@@ -799,7 +812,7 @@ userauth_gssapi(struct ssh *ssh)
(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);
@@ -847,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);
}
@@ -858,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);
@@ -879,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);
@@ -1037,7 +1051,7 @@ userauth_none(struct ssh *ssh)
(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;
}
@@ -1066,7 +1080,7 @@ userauth_passwd(struct ssh *ssh)
(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");
free(prompt);
if (password != NULL)
@@ -1167,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
@@ -1175,24 +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);
+ server_sig_algs, NULL);
if (tmp != NULL)
alg = xstrdup(cp);
free(tmp);
@@ -1208,7 +1231,7 @@ 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 *sign_key = NULL, *prv = NULL;
- int r = SSH_ERR_INTERNAL_ERROR;
+ int retried = 0, r = SSH_ERR_INTERNAL_ERROR;
struct notifier_ctx *notifier = NULL;
char *fp = NULL, *pin = NULL, *prompt = NULL;
@@ -1233,8 +1256,8 @@ identity_sign(struct identity *id, u_char **sigp, size_t *lenp,
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);
+ error_f("private key %s contents do not match public",
+ id->filename);
r = SSH_ERR_KEY_NOT_FOUND;
goto out;
}
@@ -1242,6 +1265,7 @@ identity_sign(struct identity *id, u_char **sigp, size_t *lenp,
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);
@@ -1251,7 +1275,7 @@ identity_sign(struct identity *id, u_char **sigp, size_t *lenp,
if ((fp = sshkey_fingerprint(sign_key,
options.fingerprint_hash,
SSH_FP_DEFAULT)) == NULL)
- fatal("%s: fingerprint", __func__);
+ fatal_f("fingerprint failed");
notifier = notify_start(options.batch_mode,
"Confirm user presence for key %s %s",
sshkey_type(sign_key), fp);
@@ -1261,15 +1285,23 @@ identity_sign(struct identity *id, u_char **sigp, size_t *lenp,
}
if ((r = sshkey_sign(sign_key, sigp, lenp, data, datalen,
alg, options.sk_provider, pin, compat)) != 0) {
- debug("%s: sshkey_sign: %s", __func__, ssh_err(r));
+ 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;
}
+
/*
* 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("%s: sshkey_check_sigtype: %s", __func__, ssh_err(r));
+ debug_fr(r, "sshkey_check_sigtype");
goto out;
}
/* success */
@@ -1278,7 +1310,7 @@ identity_sign(struct identity *id, u_char **sigp, size_t *lenp,
free(prompt);
if (pin != NULL)
freezero(pin, strlen(pin));
- notify_complete(notifier);
+ notify_complete(notifier, r == 0 ? "User presence confirmed" : NULL);
sshkey_free(prv);
return r;
}
@@ -1318,7 +1350,7 @@ sign_and_send_pubkey(struct ssh *ssh, 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
@@ -1355,12 +1387,12 @@ sign_and_send_pubkey(struct ssh *ssh, 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);
}
}
@@ -1378,26 +1410,21 @@ sign_and_send_pubkey(struct ssh *ssh, 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 %s", __func__, alg, fp);
+ 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 ||
@@ -1407,13 +1434,12 @@ sign_and_send_pubkey(struct ssh *ssh, 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)
@@ -1428,30 +1454,30 @@ sign_and_send_pubkey(struct ssh *ssh, Identity *id)
loc, sshkey_type(id->key), fp);
continue;
}
- error("%s: signing failed for %s \"%s\"%s: %s", __func__,
+ error_fr(r, "signing failed for %s \"%s\"%s",
sshkey_type(sign_id->key), sign_id->filename,
- id->agent_fd != -1 ? " from agent" : "", ssh_err(r));
+ 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;
@@ -1475,13 +1501,13 @@ send_pubkey_test(struct ssh *ssh, 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 */
@@ -1495,7 +1521,7 @@ send_pubkey_test(struct ssh *ssh, 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:
@@ -1513,8 +1539,9 @@ load_identity_file(Identity *id)
struct stat st;
if (stat(id->filename, &st) == -1) {
- (id->userprovided ? logit : debug3)("no such identity: %s: %s",
- id->filename, strerror(errno));
+ 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,
@@ -1544,14 +1571,13 @@ 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;
}
@@ -1580,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;
}
@@ -1608,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
@@ -1635,15 +1661,14 @@ pubkey_prepare(Authctxt *authctxt)
key = options.identity_keys[i];
if (key && key->cert &&
key->cert->type != SSH2_CERT_TYPE_USER) {
- debug("%s: ignoring certificate %s: not a user "
- "certificate", __func__,
- options.identity_files[i]);
+ 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("%s: ignoring authenticator-hosted key %s as no "
+ debug_f("ignoring authenticator-hosted key %s as no "
"SecurityKeyProvider has been specified",
- __func__, options.identity_files[i]);
+ options.identity_files[i]);
continue;
}
options.identity_keys[i] = NULL;
@@ -1659,16 +1684,15 @@ pubkey_prepare(Authctxt *authctxt)
key = options.certificates[i];
if (!sshkey_is_cert(key) || key->cert == NULL ||
key->cert->type != SSH2_CERT_TYPE_USER) {
- debug("%s: ignoring certificate %s: not a user "
- "certificate", __func__,
- options.identity_files[i]);
+ 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("%s: ignoring authenticator-hosted key "
+ debug_f("ignoring authenticator-hosted key "
"certificate %s as no "
"SecurityKeyProvider has been specified",
- __func__, options.identity_files[i]);
+ options.identity_files[i]);
continue;
}
id = xcalloc(1, sizeof(*id));
@@ -1681,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++) {
@@ -1744,11 +1766,11 @@ pubkey_prepare(Authctxt *authctxt)
}
/* append remaining keys from the config file */
TAILQ_CONCAT(preferred, &files, next);
- /* finally, filter by PubkeyAcceptedKeyTypes */
+ /* 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);
@@ -1763,7 +1785,7 @@ pubkey_prepare(Authctxt *authctxt)
debug("Will attempt key: %s", ident);
free(ident);
}
- debug2("%s: done", __func__);
+ debug2_f("done");
}
static void
@@ -1795,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);
@@ -1828,7 +1850,7 @@ userauth_pubkey(struct ssh *ssh)
* 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);
@@ -1838,7 +1860,7 @@ userauth_pubkey(struct ssh *ssh)
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, id);
}
@@ -1880,7 +1902,7 @@ userauth_kbdint(struct ssh *ssh)
(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;
@@ -1894,15 +1916,15 @@ 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;
@@ -1927,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 ||
@@ -1948,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);
@@ -1970,46 +1998,46 @@ ssh_keysign(struct ssh *ssh, struct sshkey *key, u_char **sigp, size_t *lenp,
*lenp = 0;
if (stat(_PATH_SSH_KEY_SIGN, &st) == -1) {
- error("%s: not installed: %s", __func__, strerror(errno));
+ 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) == -1) {
- error("%s: pipe: %s", __func__, strerror(errno));
+ error_f("pipe: %s", strerror(errno));
return -1;
}
if (pipe(from) == -1) {
- error("%s: pipe: %s", __func__, strerror(errno));
+ error_f("pipe: %s", strerror(errno));
return -1;
}
if ((pid = fork()) == -1) {
- error("%s: fork: %s", __func__, strerror(errno));
+ error_f("fork: %s", strerror(errno));
return -1;
}
osigchld = ssh_signal(SIGCHLD, SIG_DFL);
if (pid == 0) {
close(from[0]);
if (dup2(from[1], STDOUT_FILENO) == -1)
- fatal("%s: dup2: %s", __func__, strerror(errno));
+ fatal_f("dup2: %s", strerror(errno));
close(to[1]);
if (dup2(to[0], STDIN_FILENO) == -1)
- fatal("%s: dup2: %s", __func__, strerror(errno));
+ fatal_f("dup2: %s", strerror(errno));
close(from[1]);
close(to[0]);
if (dup2(sock, STDERR_FILENO + 1) == -1)
- fatal("%s: dup2: %s", __func__, strerror(errno));
+ 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]);
@@ -2017,49 +2045,47 @@ ssh_keysign(struct ssh *ssh, struct sshkey *key, u_char **sigp, size_t *lenp,
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) == -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:
ssh_signal(SIGCHLD, osigchld);
sshbuf_free(b);
@@ -2083,12 +2109,12 @@ userauth_hostbased(struct ssh *ssh)
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 (;;) {
@@ -2097,8 +2123,7 @@ userauth_hostbased(struct ssh *ssh)
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;
@@ -2131,42 +2156,41 @@ userauth_hostbased(struct ssh *ssh)
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 */
lname = get_local_name(ssh_packet_get_connection_in(ssh));
if (lname == NULL) {
- error("%s: cannot get local ipaddr/name", __func__);
+ 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;
}
@@ -2183,13 +2207,13 @@ userauth_hostbased(struct ssh *ssh)
(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;
@@ -2298,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/sshd.0 b/sshd.0
index e32e0082c..625ded897 100644
--- a/sshd.0
+++ b/sshd.0
@@ -9,9 +9,9 @@ SYNOPSIS
[-h host_key_file] [-o option] [-p port] [-u len]
DESCRIPTION
- sshd (OpenSSH Daemon) is the daemon program for ssh(1). Together these
- programs replace rlogin and rsh, and provide secure encrypted
- communications between two untrusted hosts over an insecure network.
+ sshd (OpenSSH Daemon) is the daemon program for ssh(1). It provides
+ secure encrypted communications between two untrusted hosts over an
+ insecure network.
sshd listens for connections from clients. It is normally started at
boot from /etc/rc. It forks a new daemon for each incoming connection.
@@ -37,7 +37,7 @@ DESCRIPTION
written to standard output. The connection parameters are
supplied as keyword=value pairs and may be supplied in any order,
either with multiple -C options or as a comma-separated list.
- The keywords are M-bM-^@M-^\addr,M-bM-^@M-^] M-bM-^@M-^\userM-bM-^@M-^], M-bM-^@M-^\hostM-bM-^@M-^], M-bM-^@M-^\laddrM-bM-^@M-^], M-bM-^@M-^\lportM-bM-^@M-^], and
+ The keywords are M-bM-^@M-^\addrM-bM-^@M-^], M-bM-^@M-^\userM-bM-^@M-^], M-bM-^@M-^\hostM-bM-^@M-^], M-bM-^@M-^\laddrM-bM-^@M-^], M-bM-^@M-^\lportM-bM-^@M-^], and
M-bM-^@M-^\rdomainM-bM-^@M-^] and correspond to source address, user, resolved source
host name, local address, local port number and routing domain
respectively.
@@ -53,7 +53,7 @@ DESCRIPTION
-d 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. This
+ also will not fork(2) and will only process one connection. This
option is only intended for debugging for the server. Multiple
-d options increase the debugging level. Maximum is 3.
@@ -190,7 +190,7 @@ LOGIN PROCESS
8. If ~/.ssh/rc exists and the sshd_config(5) PermitUserRC option
is set, runs it; else if /etc/ssh/sshrc exists, runs it;
- otherwise runs xauth. The M-bM-^@M-^\rcM-bM-^@M-^] files are given the X11
+ otherwise runs xauth(1). The M-bM-^@M-^\rcM-bM-^@M-^] files are given the X11
authentication protocol and cookie in standard input. See
SSHRC, below.
@@ -417,24 +417,25 @@ AUTHORIZED_KEYS FILE FORMAT
An example authorized_keys file:
- # 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
- no-touch-required sk-ecdsa-sha2-nistp256@openssh.com AAAAInN...Ko==
- 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 ...
SSH_KNOWN_HOSTS FILE FORMAT
The /etc/ssh/ssh_known_hosts and ~/.ssh/known_hosts files contain host
@@ -443,7 +444,7 @@ SSH_KNOWN_HOSTS FILE FORMAT
automatically: whenever the user connects to an unknown host, its key is
added to the per-user file.
- Each line in these files contains the following fields: markers
+ Each line in these files contains the following fields: marker
(optional), hostnames, keytype, base64-encoded key, comment. The fields
are separated by spaces.
@@ -669,4 +670,4 @@ AUTHORS
versions 1.5 and 2.0. Niels Provos and Markus Friedl contributed support
for privilege separation.
-OpenBSD 6.8 August 27, 2020 OpenBSD 6.8
+OpenBSD 6.9 July 30, 2021 OpenBSD 6.9
diff --git a/sshd.8 b/sshd.8
index b2fad56d3..53296ddb7 100644
--- a/sshd.8
+++ b/sshd.8
@@ -33,8 +33,8 @@
.\" (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.313 2020/08/27 01:07:10 djm Exp $
-.Dd $Mdocdate: August 27 2020 $
+.\" $OpenBSD: sshd.8,v 1.316 2021/07/30 14:28:13 jmc Exp $
+.Dd $Mdocdate: July 30 2021 $
.Dt SSHD 8
.Os
.Sh NAME
@@ -58,8 +58,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
@@ -107,7 +106,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 ,
@@ -135,7 +134,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
@@ -355,7 +356,8 @@ exists and the
option is set, runs it; else if
.Pa /etc/ssh/sshrc
exists, runs
-it; otherwise runs xauth.
+it; otherwise runs
+.Xr xauth 1 .
The
.Dq rc
files are given the X11
@@ -665,24 +667,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
-no-touch-required sk-ecdsa-sha2-nistp256@openssh.com AAAAInN...Ko==
-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
@@ -695,7 +698,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/sshd.c b/sshd.c
index 8aa7f3df6..ea63d0307 100644
--- a/sshd.c
+++ b/sshd.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: sshd.c,v 1.561 2020/08/27 01:06:19 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
@@ -123,6 +123,8 @@
#include "version.h"
#include "ssherr.h"
#include "sk-api.h"
+#include "srclimit.h"
+#include "dh.h"
/* Re-exec fds */
#define REEXEC_DEVCRYPTO_RESERVED_FD (STDERR_FILENO + 1)
@@ -204,13 +206,6 @@ 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;
@@ -346,8 +341,6 @@ main_sigchld_handler(int sig)
pid_t pid;
int status;
- debug("main_sigchld_handler: %s", strsignal(sig));
-
while ((pid = waitpid(-1, &status, WNOHANG)) > 0 ||
(pid == -1 && errno == EINTR))
;
@@ -373,11 +366,14 @@ grace_alarm_handler(int sig)
kill(0, SIGTERM);
}
- /* XXX pre-format ipaddr/port so we don't need to access active_state */
/* Log error and exit. */
- sigdie("Timeout before authentication for %s port %d",
- ssh_remote_ipaddr(the_active_state),
- ssh_remote_port(the_active_state));
+ 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));
+ }
}
/* Destroy the host and server keys. They will no longer be needed. */
@@ -410,9 +406,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;
}
@@ -502,8 +497,7 @@ privsep_preauth(struct ssh *ssh)
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;
}
}
@@ -516,17 +510,17 @@ privsep_preauth(struct ssh *ssh)
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;
@@ -606,12 +600,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 *
@@ -623,7 +616,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)
@@ -668,9 +661,9 @@ list_hostkey_types(void)
}
}
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;
}
@@ -784,7 +777,7 @@ notify_hostkeys(struct ssh *ssh)
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 ||
@@ -792,8 +785,7 @@ 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) {
/*
@@ -808,15 +800,14 @@ notify_hostkeys(struct ssh *ssh)
/* 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));
+ 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__);
+ fatal_f("no hostkeys");
if ((r = sshpkt_send(ssh)) != 0)
sshpkt_fatal(ssh, r, "%s: send", __func__);
sshbuf_free(buf);
@@ -846,7 +837,7 @@ should_drop_connection(int startups)
p += options.max_startups_rate;
r = arc4random_uniform(100);
- debug("%s: p %d, r %d", __func__, p, r);
+ debug_f("p %d, r %d", p, r);
return (r < p) ? 1 : 0;
}
@@ -858,7 +849,7 @@ should_drop_connection(int startups)
* while in that state.
*/
static int
-drop_connection(int sock, int startups)
+drop_connection(int sock, int startups, int notify_pipe)
{
char *laddr, *raddr;
const char msg[] = "Exceeded MaxStartups\r\n";
@@ -868,7 +859,8 @@ drop_connection(int sock, int startups)
time_t now;
now = monotime();
- if (!should_drop_connection(startups)) {
+ 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 */
@@ -911,14 +903,7 @@ drop_connection(int sock, int startups)
static void
usage(void)
{
- fprintf(stderr, "%s, %s\n",
- SSH_RELEASE,
-#ifdef WITH_OPENSSL
- OpenSSL_version(OPENSSL_VERSION)
-#else
- "without OpenSSL"
-#endif
- );
+ fprintf(stderr, "%s, %s\n", SSH_RELEASE, SSH_OPENSSL_VERSION);
fprintf(stderr,
"usage: sshd [-46DdeiqTt] [-C connection_spec] [-c host_cert_file]\n"
" [-E log_file] [-f config_file] [-g login_grace_time]\n"
@@ -934,18 +919,18 @@ send_rexec_state(int fd, struct sshbuf *conf)
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("%s: sshbuf_new failed", __func__);
+ 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("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "compose includes");
}
/*
@@ -960,17 +945,17 @@ send_rexec_state(int fd, struct sshbuf *conf)
*/
if ((r = sshbuf_put_stringb(m, conf)) != 0 ||
(r = sshbuf_put_stringb(m, inc)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ 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)
- error("%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
@@ -982,50 +967,48 @@ recv_rexec_state(int fd, struct sshbuf *conf)
int r;
struct include_item *item;
- debug3("%s: entering fd = %d", __func__, fd);
+ debug3_f("entering fd = %d", fd);
if ((m = sshbuf_new()) == NULL || (inc = sshbuf_new()) == NULL)
- fatal("%s: sshbuf_new failed", __func__);
+ 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__);
+ fatal_f("rexec version mismatch");
if ((r = sshbuf_get_string(m, &cp, &len)) != 0 ||
(r = sshbuf_get_stringb(m, inc)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ 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("%s: buffer error: %s", __func__, ssh_err(r));
+ fatal_fr(r, "sshbuf_put");
while (sshbuf_len(inc) != 0) {
item = xcalloc(1, sizeof(*item));
if ((item->contents = sshbuf_new()) == NULL)
- fatal("%s: sshbuf_new failed", __func__);
+ 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("%s: buffer error: %s", __func__, ssh_err(r));
+ 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;
-
if (rexeced_flag) {
close(REEXEC_CONFIG_PASS_FD);
*sock_in = *sock_out = dup(STDIN_FILENO);
@@ -1038,14 +1021,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);
}
@@ -1129,6 +1106,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);
@@ -1160,6 +1141,7 @@ server_accept_loop(int *sock_in, int *sock_out, int *newsock, int *config_s)
socklen_t fromlen;
pid_t pid;
u_char rnd[256];
+ sigset_t nsigset, osigset;
/* setup fd set for accept */
fdset = NULL;
@@ -1174,10 +1156,31 @@ server_accept_loop(int *sock_in, int *sock_out, int *newsock, int *config_s)
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 (;;) {
+ 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,
@@ -1190,8 +1193,10 @@ server_accept_loop(int *sock_in, int *sock_out, int *newsock, int *config_s)
close_listen_socks();
lameduck = 1;
}
- if (listening <= 0)
+ if (listening <= 0) {
+ sigprocmask(SIG_SETMASK, &osigset, NULL);
sighup_restart();
+ }
}
free(fdset);
fdset = xcalloc(howmany(maxfd + 1, NFDBITS),
@@ -1203,18 +1208,11 @@ 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);
+ /* Wait until a connection arrives or a child exits. */
+ ret = pselect(maxfd+1, fdset, NULL, NULL, NULL, &osigset);
if (ret == -1 && 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);
- }
+ error("pselect: %.100s", strerror(errno));
+ sigprocmask(SIG_SETMASK, &osigset, NULL);
if (ret == -1)
continue;
@@ -1227,14 +1225,15 @@ server_accept_loop(int *sock_in, int *sock_out, int *newsock, int *config_s)
if (errno == EINTR || errno == EAGAIN)
continue;
if (errno != EPIPE) {
- error("%s: startup pipe %d (fd=%d): "
- "read %s", __func__, i,
- startup_pipes[i], strerror(errno));
+ 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])
@@ -1265,9 +1264,12 @@ server_accept_loop(int *sock_in, int *sock_out, int *newsock, int *config_s)
continue;
}
if (unset_nonblock(*newsock) == -1 ||
- drop_connection(*newsock, startups) ||
- pipe(startup_p) == -1) {
+ pipe(startup_p) == -1)
+ continue;
+ if (drop_connection(*newsock, startups, startup_p[0])) {
close(*newsock);
+ close(startup_p[0]);
+ close(startup_p[1]);
continue;
}
@@ -1466,7 +1468,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
@@ -1483,16 +1485,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);
@@ -1500,11 +1502,11 @@ 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);
}
@@ -1720,11 +1722,11 @@ 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__);
+ fatal_f("sshbuf_new failed");
if (rexeced_flag) {
setproctitle("%s", "[rexeced]");
recv_rexec_state(REEXEC_CONFIG_PASS_FD, cfg);
@@ -1743,13 +1745,14 @@ main(int ac, char **av)
parse_server_config(&options, rexeced_flag ? "rexec" : config_file_name,
cfg, &includes, NULL);
+#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 &&
@@ -1785,13 +1788,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);
@@ -1819,8 +1816,8 @@ 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++) {
@@ -1831,8 +1828,8 @@ main(int ac, char **av)
continue;
if ((r = sshkey_load_private(options.host_key_files[i], "",
&key, NULL)) != 0 && r != SSH_ERR_SYSTEM_ERROR)
- do_log2(ll, "Unable to load 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",
@@ -1841,15 +1838,15 @@ main(int ac, char **av)
}
if (r == 0 && key != NULL &&
(r = sshkey_shield_private(key)) != 0) {
- do_log2(ll, "Unable to shield host key \"%s\": %s",
- options.host_key_files[i], ssh_err(r));
+ 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)
- do_log2(ll, "Unable to load 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 (pubkey != NULL && key != NULL) {
if (!sshkey_equal(pubkey, key)) {
error("Public key for %s does not match "
@@ -1860,8 +1857,8 @@ main(int ac, char **av)
}
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;
@@ -1920,8 +1917,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)) {
@@ -1933,7 +1930,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;
}
@@ -2014,7 +2011,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
@@ -2032,8 +2032,10 @@ main(int ac, char **av)
/* Reinitialize the log (because of the fork above). */
log_init(__progname, options.log_level, options.log_facility, log_stderr);
- /* 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));
@@ -2092,8 +2094,6 @@ main(int ac, char **av)
#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);
@@ -2121,12 +2121,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]);
}
@@ -2227,7 +2223,7 @@ 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();
if (use_privsep) {
@@ -2235,7 +2231,7 @@ main(int ac, char **av)
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;
}
}
@@ -2340,24 +2336,23 @@ sshd_hostkey_sign(struct ssh *ssh, struct sshkey *privkey,
if (mm_sshkey_sign(ssh, privkey, signature, slenp,
data, dlen, alg, options.sk_provider, NULL,
ssh->compat) < 0)
- fatal("%s: privkey sign failed", __func__);
+ 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("%s: pubkey sign failed", __func__);
+ fatal_f("pubkey sign failed");
}
} else {
if (privkey) {
if (sshkey_sign(privkey, signature, slenp, data, dlen,
alg, options.sk_provider, NULL, ssh->compat) < 0)
- fatal("%s: privkey sign failed", __func__);
+ fatal_f("privkey sign failed");
} else {
if ((r = ssh_agent_sign(auth_sock, pubkey,
signature, slenp, data, dlen, alg,
ssh->compat)) != 0) {
- fatal("%s: agent sign failed: %s",
- __func__, ssh_err(r));
+ fatal_fr(r, "agent sign failed");
}
}
}
@@ -2372,11 +2367,11 @@ do_ssh2_kex(struct ssh *ssh)
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;
@@ -2391,11 +2386,11 @@ do_ssh2_kex(struct ssh *ssh)
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(ssh, myproposal)) != 0)
- fatal("kex_setup: %s", ssh_err(r));
+ fatal_r(r, "kex_setup");
kex = ssh->kex;
#ifdef WITH_OPENSSL
kex->kex[KEX_DH_GRP1_SHA1] = kex_gen_server;
@@ -2410,7 +2405,7 @@ do_ssh2_kex(struct ssh *ssh)
# endif
#endif
kex->kex[KEX_C25519_SHA256] = kex_gen_server;
- kex->kex[KEX_KEM_SNTRUP4591761X25519_SHA512] = 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;
@@ -2418,16 +2413,13 @@ do_ssh2_kex(struct ssh *ssh)
ssh_dispatch_run_fatal(ssh, DISPATCH_BLOCK, &kex->done);
- session_id2 = kex->session_id;
- session_id2_len = kex->session_id_len;
-
#ifdef DEBUG_KEXDH
/* send 1st encrypted/maced/compressed message */
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("%s: send test: %s", __func__, ssh_err(r));
+ fatal_fr(r, "send test");
#endif
debug("KEX done");
}
@@ -2442,9 +2434,10 @@ cleanup_exit(int i)
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
diff --git a/sshd_config b/sshd_config
index 19b7c91a1..c423eba1b 100644
--- a/sshd_config
+++ b/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 $
# This is the sshd server system-wide configuration file. See
# sshd_config(5) for more information.
@@ -58,7 +58,7 @@ AuthorizedKeysFile .ssh/authorized_keys
#PermitEmptyPasswords no
# Change to no to disable s/key passwords
-#ChallengeResponseAuthentication yes
+#KbdInteractiveAuthentication yes
# Kerberos options
#KerberosAuthentication no
@@ -72,13 +72,13 @@ AuthorizedKeysFile .ssh/authorized_keys
# Set this to 'yes' to enable 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 no
#AllowAgentForwarding yes
diff --git a/sshd_config.0 b/sshd_config.0
index 8132c3f15..94f0a4d8b 100644
--- a/sshd_config.0
+++ b/sshd_config.0
@@ -207,17 +207,21 @@ DESCRIPTION
Specifies which algorithms are allowed for signing of
certificates by certificate authorities (CAs). The default is:
- 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
+
+ If the specified list begins with a M-bM-^@M-^X+M-bM-^@M-^Y character, then the
+ specified algorithms will be appended to the default set instead
+ of replacing them. If the specified list begins with a M-bM-^@M-^X-M-bM-^@M-^Y
+ character, then the specified algorithms (including wildcards)
+ will be removed from the default set instead of replacing them.
Certificates signed using other algorithms will not be accepted
for public key or host-based authentication.
- ChallengeResponseAuthentication
- Specifies whether challenge-response authentication is allowed
- (e.g. via PAM or through authentication styles supported in
- login.conf(5)) The default is yes.
-
ChrootDirectory
Specifies the pathname of a directory to chroot(2) to after
authentication. At session startup sshd(8) checks that all
@@ -390,34 +394,37 @@ DESCRIPTION
facility is provided to assist with operation on multi homed
machines. The default is yes.
- HostbasedAcceptedKeyTypes
- Specifies the key types that will be accepted for hostbased
- authentication as a list of comma-separated patterns.
+ 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 M-bM-^@M-^X+M-bM-^@M-^Y character,
- then the specified key types will be appended to the default set
- instead of replacing them. If the specified list begins with a
- M-bM-^@M-^X-M-bM-^@M-^Y character, then the specified key types (including wildcards)
- will be removed from the default set instead of replacing them.
- If the specified list begins with a M-bM-^@M-^X^M-bM-^@M-^Y character, then the
- specified key types will be placed at the head of the default
- set. The default for this option is:
+ then the specified signature algorithms will be appended to the
+ default set instead of replacing them. If the specified list
+ begins with a M-bM-^@M-^X-M-bM-^@M-^Y 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 M-bM-^@M-^X^M-bM-^@M-^Y character, then the specified signature algorithms will be
+ placed at the head of the default set. The default for this
+ option is:
+ 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-ecdsa-sha2-nistp256-cert-v01@openssh.com,
- ssh-ed25519-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,
+ sk-ssh-ed25519@openssh.com,
sk-ecdsa-sha2-nistp256@openssh.com,
- ssh-ed25519,sk-ssh-ed25519@openssh.com,
rsa-sha2-512,rsa-sha2-256,ssh-rsa
- The list of available key types may also be obtained using "ssh
- -Q HostbasedAcceptedKeyTypes".
+ The list of available signature algorithms may also be obtained
+ using "ssh -Q HostbasedAcceptedAlgorithms". This was formerly
+ named HostbasedAcceptedKeyTypes.
HostbasedAuthentication
Specifies whether rhosts or /etc/hosts.equiv authentication
@@ -460,25 +467,26 @@ DESCRIPTION
read from the SSH_AUTH_SOCK environment variable.
HostKeyAlgorithms
- Specifies the host key algorithms that the server offers. The
- default for this option is:
+ Specifies the host key signature algorithms that the server
+ offers. The default for this option is:
+ 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-ecdsa-sha2-nistp256-cert-v01@openssh.com,
- ssh-ed25519-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,
+ sk-ssh-ed25519@openssh.com,
sk-ecdsa-sha2-nistp256@openssh.com,
- ssh-ed25519,sk-ssh-ed25519@openssh.com,
rsa-sha2-512,rsa-sha2-256,ssh-rsa
- The list of available key types may also be obtained using "ssh
- -Q HostKeyAlgorithms".
+ The list of available signature algorithms may also be obtained
+ using "ssh -Q HostKeyAlgorithms".
IgnoreRhosts
Specifies whether to ignore per-user .rhosts and .shosts files
@@ -518,9 +526,9 @@ DESCRIPTION
KbdInteractiveAuthentication
Specifies whether to allow keyboard-interactive authentication.
- The argument to this keyword must be yes or no. The default is
- to use whatever value ChallengeResponseAuthentication is set to
- (by default yes).
+ All authentication styles from login.conf(5) are supported. The
+ default is yes. The argument to this keyword must be yes or no.
+ ChallengeResponseAuthentication is a deprecated alias for this.
KerberosAuthentication
Specifies whether the password provided by the user for
@@ -566,7 +574,7 @@ DESCRIPTION
ecdh-sha2-nistp256
ecdh-sha2-nistp384
ecdh-sha2-nistp521
- sntrup4591761x25519-sha512@tinyssh.org
+ sntrup761x25519-sha512@openssh.com
The default is:
@@ -609,6 +617,19 @@ DESCRIPTION
higher levels of debugging output. Logging with a DEBUG level
violates the privacy of users and is not recommended.
+ 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:
+
+ kex.c:*:1000,*:kex_exchange_identification():*,packet.c:*
+
+ would enable detailed logging for line 1000 of kex.c, everything
+ in the kex_exchange_identification() function, and all code in
+ the packet.c file. This option is intended for debugging and no
+ overrides are enabled by default.
+
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
@@ -686,17 +707,17 @@ DESCRIPTION
AuthorizedKeysFile, AuthorizedPrincipalsCommand,
AuthorizedPrincipalsCommandUser, AuthorizedPrincipalsFile,
Banner, ChrootDirectory, ClientAliveCountMax,
- ClientAliveInterval, DenyGroups, DenyUsers, ForceCommand,
- GatewayPorts, GSSAPIAuthentication, HostbasedAcceptedKeyTypes,
- HostbasedAuthentication, HostbasedUsesNameFromPacketOnly,
- IgnoreRhosts, Include, IPQoS, KbdInteractiveAuthentication,
- KerberosAuthentication, LogLevel, MaxAuthTries, MaxSessions,
- PasswordAuthentication, PermitEmptyPasswords, PermitListen,
- PermitOpen, PermitRootLogin, PermitTTY, PermitTunnel,
- PermitUserRC, PubkeyAcceptedKeyTypes, PubkeyAuthentication,
- RekeyLimit, RevokedKeys, RDomain, SetEnv, StreamLocalBindMask,
- StreamLocalBindUnlink, TrustedUserCAKeys, X11DisplayOffset,
- X11Forwarding and X11UseLocalhost.
+ ClientAliveInterval, DenyGroups, DenyUsers, DisableForwarding,
+ ForceCommand, GatewayPorts, GSSAPIAuthentication,
+ HostbasedAcceptedAlgorithms, HostbasedAuthentication,
+ HostbasedUsesNameFromPacketOnly, IgnoreRhosts, Include, IPQoS,
+ KbdInteractiveAuthentication, KerberosAuthentication, LogLevel,
+ MaxAuthTries, MaxSessions, PasswordAuthentication,
+ PermitEmptyPasswords, PermitListen, PermitOpen, PermitRootLogin,
+ PermitTTY, PermitTunnel, PermitUserRC, PubkeyAcceptedAlgorithms,
+ PubkeyAuthentication, RekeyLimit, RevokedKeys, RDomain, SetEnv,
+ StreamLocalBindMask, StreamLocalBindUnlink, TrustedUserCAKeys,
+ X11DisplayOffset, X11Forwarding and X11UseLocalhost.
MaxAuthTries
Specifies the maximum number of authentication attempts permitted
@@ -726,6 +747,12 @@ DESCRIPTION
connection attempts are refused if the number of unauthenticated
connections reaches full (60).
+ ModuliFile
+ Specifies the moduli(5) file that contains the Diffie-Hellman
+ groups used for the M-bM-^@M-^\diffie-hellman-group-exchange-sha1M-bM-^@M-^] and
+ M-bM-^@M-^\diffie-hellman-group-exchange-sha256M-bM-^@M-^] key exchange methods. The
+ default is /etc/moduli.
+
PasswordAuthentication
Specifies whether password authentication is allowed. The
default is yes.
@@ -818,6 +845,19 @@ DESCRIPTION
Specifies whether any ~/.ssh/rc file is executed. The default is
yes.
+ PerSourceMaxStartups
+ Specifies the number of unauthenticated connections allowed from
+ a given source address, or M-bM-^@M-^\noneM-bM-^@M-^] if there is no limit. This
+ limit is applied in addition to MaxStartups, whichever is lower.
+ The default is none.
+
+ 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 32:128, which means each
+ address is considered individually.
+
PidFile
Specifies the file that contains the process ID of the SSH
daemon, or none to not write one. The default is
@@ -837,34 +877,35 @@ DESCRIPTION
in interactively. (On some systems it is also printed by the
shell, /etc/profile, or equivalent.) The default is yes.
- PubkeyAcceptedKeyTypes
- Specifies the key types that will be accepted for public key
- authentication as a list of comma-separated patterns.
+ 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 M-bM-^@M-^X+M-bM-^@M-^Y character,
- then the specified key types will be appended to the default set
+ then the specified algorithms will be appended to the default set
instead of replacing them. If the specified list begins with a
- M-bM-^@M-^X-M-bM-^@M-^Y character, then the specified key types (including wildcards)
- will be removed from the default set instead of replacing them.
- If the specified list begins with a M-bM-^@M-^X^M-bM-^@M-^Y character, then the
- specified key types will be placed at the head of the default
- set. The default for this option is:
+ M-bM-^@M-^X-M-bM-^@M-^Y 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 M-bM-^@M-^X^M-bM-^@M-^Y
+ character, then the specified algorithms will be placed at the
+ head of the default set. The default for this option is:
+ 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-ecdsa-sha2-nistp256-cert-v01@openssh.com,
- ssh-ed25519-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,
+ sk-ssh-ed25519@openssh.com,
sk-ecdsa-sha2-nistp256@openssh.com,
- ssh-ed25519,sk-ssh-ed25519@openssh.com,
rsa-sha2-512,rsa-sha2-256,ssh-rsa
- The list of available key types may also be obtained using "ssh
- -Q PubkeyAcceptedKeyTypes".
+ The list of available signature algorithms may also be obtained
+ using "ssh -Q PubkeyAcceptedAlgorithms".
PubkeyAuthOptions
Sets one or more public key authentication options. The
@@ -892,7 +933,7 @@ DESCRIPTION
RekeyLimit
Specifies the maximum amount of data that may be transmitted
- before the session key is renegotiated, optionally followed a
+ before the 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 M-bM-^@M-^XKM-bM-^@M-^Y, M-bM-^@M-^XMM-bM-^@M-^Y, or M-bM-^@M-^XGM-bM-^@M-^Y to indicate Kilobytes,
@@ -916,7 +957,7 @@ DESCRIPTION
RDomain
Specifies an explicit routing domain that is applied after
- authentication has completed. The user session, as well and any
+ authentication has completed. The user session, as well as any
forwarded or listening IP sockets, will be bound to this
rdomain(4). If the routing domain is set to %D, then the domain
in which the incoming connection was received will be applied.
@@ -1021,13 +1062,13 @@ DESCRIPTION
UsePAM Enables the Pluggable Authentication Module interface. If set to
yes this will enable PAM authentication using
- ChallengeResponseAuthentication and PasswordAuthentication in
+ KbdInteractiveAuthentication and PasswordAuthentication in
addition to PAM account and session module processing for all
authentication types.
- Because PAM challenge-response authentication usually serves an
+ Because PAM keyboard-interactive authentication usually serves an
equivalent role to password authentication, you should disable
- either PasswordAuthentication or ChallengeResponseAuthentication.
+ either PasswordAuthentication or KbdInteractiveAuthentication.
If UsePAM is enabled, you will not be able to run sshd(8) as a
non-root user. The default is no.
@@ -1150,4 +1191,4 @@ AUTHORS
versions 1.5 and 2.0. Niels Provos and Markus Friedl contributed support
for privilege separation.
-OpenBSD 6.8 August 27, 2020 OpenBSD 6.8
+OpenBSD 6.9 August 12, 2021 OpenBSD 6.9
diff --git a/sshd_config.5 b/sshd_config.5
index 6fa421cae..69d55206a 100644
--- a/sshd_config.5
+++ b/sshd_config.5
@@ -33,8 +33,8 @@
.\" (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.315 2020/08/27 12:34:00 jmc Exp $
-.Dd $Mdocdate: August 27 2020 $
+.\" $OpenBSD: sshd_config.5,v 1.334 2021/08/12 23:59:25 djm Exp $
+.Dd $Mdocdate: August 12 2021 $
.Dt SSHD_CONFIG 5
.Os
.Sh NAME
@@ -377,18 +377,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
@@ -658,40 +664,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.
+.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.
+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 key types will be placed at the head of the
-default set.
+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,
-sk-ecdsa-sha2-nistp256-cert-v01@openssh.com,
-ssh-ed25519-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,
+sk-ssh-ed25519@openssh.com,
sk-ecdsa-sha2-nistp256@openssh.com,
-ssh-ed25519,sk-ssh-ed25519@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 HostbasedAcceptedKeyTypes .
+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
@@ -754,26 +762,27 @@ 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,
-sk-ecdsa-sha2-nistp256-cert-v01@openssh.com,
-ssh-ed25519-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,
+sk-ssh-ed25519@openssh.com,
sk-ecdsa-sha2-nistp256@openssh.com,
-ssh-ed25519,sk-ssh-ed25519@openssh.com,
rsa-sha2-512,rsa-sha2-256,ssh-rsa
.Ed
.Pp
-The list of available key types may also be obtained using
+The list of available signature algorithms may also be obtained using
.Qq ssh -Q HostKeyAlgorithms .
.It Cm IgnoreRhosts
Specifies whether to ignore per-user
@@ -870,15 +879,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
@@ -947,7 +958,7 @@ ecdh-sha2-nistp384
.It
ecdh-sha2-nistp521
.It
-sntrup4591761x25519-sha512@tinyssh.org
+sntrup761x25519-sha512@openssh.com
.El
.Pp
The default is:
@@ -1026,6 +1037,23 @@ 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.
@@ -1167,10 +1195,11 @@ 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 ,
@@ -1189,7 +1218,7 @@ Available keywords are
.Cm PermitTTY ,
.Cm PermitTunnel ,
.Cm PermitUserRC ,
-.Cm PubkeyAcceptedKeyTypes ,
+.Cm PubkeyAcceptedAlgorithms ,
.Cm PubkeyAuthentication ,
.Cm RekeyLimit ,
.Cm RevokedKeys ,
@@ -1235,6 +1264,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.
The default is
@@ -1407,6 +1446,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
@@ -1440,40 +1496,41 @@ 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.
+.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 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 key types will be placed at the head of the
+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,
-sk-ecdsa-sha2-nistp256-cert-v01@openssh.com,
-ssh-ed25519-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,
+sk-ssh-ed25519@openssh.com,
sk-ecdsa-sha2-nistp256@openssh.com,
-ssh-ed25519,sk-ssh-ed25519@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 PubkeyAcceptedKeyTypes .
+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:
@@ -1515,7 +1572,7 @@ 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 ,
@@ -1553,7 +1610,7 @@ 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
@@ -1699,17 +1756,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
diff --git a/sshkey-xmss.c b/sshkey-xmss.c
index 88e9ddf4d..f5235ef2f 100644
--- a/sshkey-xmss.c
+++ b/sshkey-xmss.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: sshkey-xmss.c,v 1.8 2019/11/13 07:53: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"
@@ -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;
@@ -475,27 +477,27 @@ sshkey_xmss_get_state(const struct sshkey *k, sshkey_printfn *pr)
}
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) == -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,8 +589,8 @@ 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;
@@ -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)) == -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) == -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) == -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) == -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;
diff --git a/sshkey-xmss.h b/sshkey-xmss.h
index b9f8ead10..32a12be62 100644
--- a/sshkey-xmss.h
+++ b/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/sshkey.c b/sshkey.c
index ac451f1a8..0dbc0d873 100644
--- a/sshkey.c
+++ b/sshkey.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: sshkey.c,v 1.111 2020/08/27 01:06:19 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.
@@ -150,7 +150,7 @@ 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 },
@@ -2035,7 +2035,7 @@ sshkey_shield_private(struct sshkey *k)
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)
+ SSHKEY_SERIALIZE_SHIELD)) != 0)
goto out;
/* pad to cipher blocksize */
i = 0;
@@ -3076,15 +3076,17 @@ sshkey_certify(struct sshkey *k, struct sshkey *ca, const char *alg,
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)
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";
@@ -3096,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! */
+ 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_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;
}
@@ -3117,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;
}
@@ -3131,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);
@@ -3380,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;
@@ -3416,6 +3447,14 @@ sshkey_private_deserialize(struct sshbuf *buf, struct sshkey **kp)
r = SSH_ERR_KEY_CERT_MISMATCH;
goto out;
}
+ /*
+ * 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;
@@ -3637,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) {
@@ -3666,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;
}
@@ -3909,7 +3957,7 @@ sshkey_private_to_blob2(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;
@@ -4335,14 +4383,14 @@ sshkey_private_to_blob_pem_pkcs8(struct sshkey *key, struct sshbuf *buf,
return SSH_ERR_PASSPHRASE_TOO_SHORT;
if ((blob = sshbuf_new()) == NULL)
return SSH_ERR_ALLOC_FAIL;
- if ((bio = BIO_new(BIO_s_mem())) == NULL) {
+ 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;
@@ -4548,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
@@ -4700,7 +4748,7 @@ sshkey_parse_pubkey_from_private_fileblob_type(struct sshbuf *blob, int type,
*/
int
sshkey_private_serialize_maxsign(struct sshkey *k, struct sshbuf *b,
- u_int32_t maxsign, sshkey_printfn *pr)
+ u_int32_t maxsign, int printerror)
{
int r, rupdate;
@@ -4708,14 +4756,14 @@ sshkey_private_serialize_maxsign(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;
}
@@ -4754,7 +4802,7 @@ sshkey_set_filename(struct sshkey *k, const char *filename)
#else
int
sshkey_private_serialize_maxsign(struct sshkey *k, struct sshbuf *b,
- u_int32_t maxsign, sshkey_printfn *pr)
+ u_int32_t maxsign, int printerror)
{
return sshkey_private_serialize_opt(k, b, SSHKEY_SERIALIZE_DEFAULT);
}
diff --git a/sshkey.h b/sshkey.h
index 2d8b62497..6edc6c5a5 100644
--- a/sshkey.h
+++ b/sshkey.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: sshkey.h,v 1.46 2020/08/27 01:06:19 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.
@@ -39,6 +39,7 @@
# 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
@@ -46,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
@@ -193,8 +195,12 @@ 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 *);
@@ -267,17 +273,12 @@ int sshkey_parse_pubkey_from_private_fileblob_type(struct sshbuf *blob,
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(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 *);
diff --git a/sshlogin.c b/sshlogin.c
index 08d2600b2..82dd84819 100644
--- a/sshlogin.c
+++ b/sshlogin.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: sshlogin.c,v 1.34 2019/06/28 13:35:04 deraadt 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
@@ -122,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/sshpty.c b/sshpty.c
index bce09e255..cae0b977a 100644
--- a/sshpty.c
+++ b/sshpty.c
@@ -27,6 +27,7 @@
#endif
#include <pwd.h>
#include <stdarg.h>
+#include <stdio.h>
#include <string.h>
#include <termios.h>
#ifdef HAVE_UTIL_H
diff --git a/sshsig.c b/sshsig.c
index 0bd7e5cb7..d0d401a32 100644
--- a/sshsig.c
+++ b/sshsig.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: sshsig.c,v 1.17 2020/08/31 00:17:41 djm Exp $ */
+/* $OpenBSD: sshsig.c,v 1.21 2021/07/23 04:00:59 djm Exp $ */
/*
* Copyright (c) 2019 Google LLC
*
@@ -54,27 +54,26 @@ sshsig_armor(const struct sshbuf *blob, struct sshbuf **out)
*out = NULL;
if ((buf = sshbuf_new()) == NULL) {
- error("%s: sshbuf_new failed", __func__);
+ 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("%s: sshbuf_putf failed: %s", __func__, ssh_err(r));
+ error_fr(r, "sshbuf_putf");
goto out;
}
if ((r = sshbuf_dtob64(blob, buf, 1)) != 0) {
- error("%s: Couldn't base64 encode signature blob: %s",
- __func__, ssh_err(r));
+ 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("%s: sshbuf_put failed: %s", __func__, ssh_err(r));
+ error_fr(r, "sshbuf_put");
goto out;
}
/* success */
@@ -96,7 +95,7 @@ sshsig_dearmor(struct sshbuf *sig, struct sshbuf **out)
char *b64 = NULL;
if ((sbuf = sshbuf_fromb(sig)) == NULL) {
- error("%s: sshbuf_fromb failed", __func__);
+ error_f("sshbuf_fromb failed");
return SSH_ERR_ALLOC_FAIL;
}
@@ -107,7 +106,7 @@ sshsig_dearmor(struct sshbuf *sig, struct sshbuf **out)
}
if ((r = sshbuf_consume(sbuf, sizeof(BEGIN_SIGNATURE)-1)) != 0) {
- error("%s: sshbuf_consume failed: %s", __func__, ssh_err(r));
+ error_fr(r, "consume");
goto done;
}
@@ -118,24 +117,24 @@ sshsig_dearmor(struct sshbuf *sig, struct sshbuf **out)
}
if ((r = sshbuf_consume_end(sbuf, sshbuf_len(sbuf)-eoffset)) != 0) {
- error("%s: sshbuf_consume failed: %s", __func__, ssh_err(r));
+ error_fr(r, "consume");
goto done;
}
if ((b64 = sshbuf_dup_string(sbuf)) == NULL) {
- error("%s: sshbuf_dup_string failed", __func__);
+ error_f("sshbuf_dup_string failed");
r = SSH_ERR_ALLOC_FAIL;
goto done;
}
if ((buf = sshbuf_new()) == NULL) {
- error("%s: sshbuf_new() failed", __func__);
+ error_f("sshbuf_new() failed");
r = SSH_ERR_ALLOC_FAIL;
goto done;
}
if ((r = sshbuf_b64tod(buf, b64)) != 0) {
- error("Couldn't decode signature: %s", ssh_err(r));
+ error_fr(r, "decode base64");
goto done;
}
@@ -165,7 +164,7 @@ sshsig_wrap_sign(struct sshkey *key, const char *hashalg,
if ((tosign = sshbuf_new()) == NULL ||
(blob = sshbuf_new()) == NULL) {
- error("%s: sshbuf_new failed", __func__);
+ error_f("sshbuf_new failed");
r = SSH_ERR_ALLOC_FAIL;
goto done;
}
@@ -175,7 +174,7 @@ sshsig_wrap_sign(struct sshkey *key, const char *hashalg,
(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("Couldn't construct message to sign: %s", ssh_err(r));
+ error_fr(r, "assemble message to sign");
goto done;
}
@@ -187,14 +186,14 @@ sshsig_wrap_sign(struct sshkey *key, const char *hashalg,
if ((r = signer(key, &sig, &slen,
sshbuf_ptr(tosign), sshbuf_len(tosign),
sign_alg, sk_provider, sk_pin, 0, signer_ctx)) != 0) {
- error("Couldn't sign message: %s", ssh_err(r));
+ 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("Couldn't sign message: %s", ssh_err(r));
+ error_r(r, "Couldn't sign message");
goto done;
}
}
@@ -206,7 +205,7 @@ sshsig_wrap_sign(struct sshkey *key, const char *hashalg,
(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("Couldn't populate blob: %s", ssh_err(r));
+ error_fr(r, "assemble signature object");
goto done;
}
@@ -250,7 +249,7 @@ sshsig_check_hashalg(const char *hashalg)
if (hashalg == NULL ||
match_pattern_list(hashalg, HASHALG_ALLOWED, 0) == 1)
return 0;
- error("%s: unsupported hash algorithm \"%.100s\"", __func__, hashalg);
+ error_f("unsupported hash algorithm \"%.100s\"", hashalg);
return SSH_ERR_SIGN_ALG_UNSUPPORTED;
}
@@ -272,7 +271,7 @@ sshsig_peek_hashalg(struct sshbuf *signature, char **hashalgp)
(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("Couldn't parse signature blob: %s", ssh_err(r));
+ error_fr(r, "parse signature object");
goto done;
}
@@ -298,14 +297,14 @@ sshsig_wrap_verify(struct sshbuf *signature, const char *hashalg,
char *got_namespace = NULL, *sigtype = NULL, *sig_hashalg = NULL;
size_t siglen;
- debug("%s: verify message length %zu", __func__, sshbuf_len(h_message));
+ 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("%s: sshbuf_new failed", __func__);
+ error_f("sshbuf_new failed");
r = SSH_ERR_ALLOC_FAIL;
goto done;
}
@@ -315,7 +314,7 @@ sshsig_wrap_verify(struct sshbuf *signature, const char *hashalg,
(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("Couldn't construct message to verify: %s", ssh_err(r));
+ error_fr(r, "assemble message to verify");
goto done;
}
@@ -327,7 +326,7 @@ sshsig_wrap_verify(struct sshbuf *signature, const char *hashalg,
(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("Couldn't parse signature blob: %s", ssh_err(r));
+ error_fr(r, "parse signature object");
goto done;
}
@@ -339,23 +338,23 @@ sshsig_wrap_verify(struct sshbuf *signature, const char *hashalg,
if (strcmp(expect_namespace, got_namespace) != 0) {
error("Couldn't verify signature: namespace does not match");
- debug("%s: expected namespace \"%s\" received \"%s\"",
- __func__, expect_namespace, got_namespace);
+ 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("%s: expected algorithm \"%s\" received \"%s\"",
- __func__, hashalg, sig_hashalg);
+ 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("Couldn't verify signature: unable to get "
- "signature type: %s", ssh_err(r));
+ error_r(r, "Couldn't verify signature: unable to get "
+ "signature type");
goto done;
}
if (match_pattern_list(sigtype, RSA_SIGN_ALLOWED, 0) != 1) {
@@ -367,7 +366,7 @@ sshsig_wrap_verify(struct sshbuf *signature, const char *hashalg,
}
if ((r = sshkey_verify(key, sig, siglen, sshbuf_ptr(toverify),
sshbuf_len(toverify), NULL, 0, sig_details)) != 0) {
- error("Signature verification failed: %s", ssh_err(r));
+ error_r(r, "Signature verification failed");
goto done;
}
@@ -400,16 +399,15 @@ hash_buffer(const struct sshbuf *m, const char *hashalg, struct sshbuf **bp)
if ((r = sshsig_check_hashalg(hashalg)) != 0)
return r;
if ((alg = ssh_digest_alg_by_name(hashalg)) == -1) {
- error("%s: can't look up hash algorithm %s",
- __func__, hashalg);
+ 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("%s: ssh_digest_buffer failed: %s", __func__, ssh_err(r));
+ error_fr(r, "ssh_digest_buffer");
return r;
}
if ((hex = tohex(hash, ssh_digest_bytes(alg))) != NULL) {
- debug3("%s: final hash: %s", __func__, hex);
+ debug3_f("final hash: %s", hex);
freezero(hex, strlen(hex));
}
if ((b = sshbuf_new()) == NULL) {
@@ -417,7 +415,7 @@ hash_buffer(const struct sshbuf *m, const char *hashalg, struct sshbuf **bp)
goto out;
}
if ((r = sshbuf_put(b, hash, ssh_digest_bytes(alg))) != 0) {
- error("%s: sshbuf_put: %s", __func__, ssh_err(r));
+ error_fr(r, "sshbuf_put");
goto out;
}
*bp = b;
@@ -444,7 +442,7 @@ sshsig_signb(struct sshkey *key, const char *hashalg,
if (out != NULL)
*out = NULL;
if ((r = hash_buffer(message, hashalg, &b)) != 0) {
- error("%s: hash_buffer failed: %s", __func__, ssh_err(r));
+ error_fr(r, "hash buffer");
goto out;
}
if ((r = sshsig_wrap_sign(key, hashalg, sk_provider, sk_pin, b,
@@ -472,9 +470,9 @@ sshsig_verifyb(struct sshbuf *signature, const struct sshbuf *message,
*sign_keyp = NULL;
if ((r = sshsig_peek_hashalg(signature, &hashalg)) != 0)
return r;
- debug("%s: signature made with hash \"%s\"", __func__, hashalg);
+ debug_f("signature made with hash \"%s\"", hashalg);
if ((r = hash_buffer(message, hashalg, &b)) != 0) {
- error("%s: hash_buffer failed: %s", __func__, ssh_err(r));
+ error_fr(r, "hash buffer");
goto out;
}
if ((r = sshsig_wrap_verify(signature, hashalg, b, expect_namespace,
@@ -503,12 +501,11 @@ hash_file(int fd, const char *hashalg, struct sshbuf **bp)
if ((r = sshsig_check_hashalg(hashalg)) != 0)
return r;
if ((alg = ssh_digest_alg_by_name(hashalg)) == -1) {
- error("%s: can't look up hash algorithm %s",
- __func__, hashalg);
+ error_f("can't look up hash algorithm %s", hashalg);
return SSH_ERR_INTERNAL_ERROR;
}
if ((ctx = ssh_digest_start(alg)) == NULL) {
- error("%s: ssh_digest_start failed", __func__);
+ error_f("ssh_digest_start failed");
return SSH_ERR_INTERNAL_ERROR;
}
for (;;) {
@@ -516,28 +513,27 @@ hash_file(int fd, const char *hashalg, struct sshbuf **bp)
if (errno == EINTR || errno == EAGAIN)
continue;
oerrno = errno;
- error("%s: read: %s", __func__, strerror(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("%s: hashed %zu bytes", __func__, total);
+ debug2_f("hashed %zu bytes", total);
break; /* EOF */
}
total += (size_t)n;
if ((r = ssh_digest_update(ctx, rbuf, (size_t)n)) != 0) {
- error("%s: ssh_digest_update: %s",
- __func__, ssh_err(r));
+ error_fr(r, "ssh_digest_update");
goto out;
}
}
if ((r = ssh_digest_final(ctx, hash, sizeof(hash))) != 0) {
- error("%s: ssh_digest_final: %s", __func__, ssh_err(r));
+ error_fr(r, "ssh_digest_final");
goto out;
}
if ((hex = tohex(hash, ssh_digest_bytes(alg))) != NULL) {
- debug3("%s: final hash: %s", __func__, hex);
+ debug3_f("final hash: %s", hex);
freezero(hex, strlen(hex));
}
if ((b = sshbuf_new()) == NULL) {
@@ -545,7 +541,7 @@ hash_file(int fd, const char *hashalg, struct sshbuf **bp)
goto out;
}
if ((r = sshbuf_put(b, hash, ssh_digest_bytes(alg))) != 0) {
- error("%s: sshbuf_put: %s", __func__, ssh_err(r));
+ error_fr(r, "sshbuf_put");
goto out;
}
*bp = b;
@@ -573,7 +569,7 @@ sshsig_sign_fd(struct sshkey *key, const char *hashalg,
if (out != NULL)
*out = NULL;
if ((r = hash_file(fd, hashalg, &b)) != 0) {
- error("%s: hash_file failed: %s", __func__, ssh_err(r));
+ error_fr(r, "hash_file");
return r;
}
if ((r = sshsig_wrap_sign(key, hashalg, sk_provider, sk_pin, b,
@@ -601,9 +597,9 @@ sshsig_verify_fd(struct sshbuf *signature, int fd,
*sign_keyp = NULL;
if ((r = sshsig_peek_hashalg(signature, &hashalg)) != 0)
return r;
- debug("%s: signature made with hash \"%s\"", __func__, hashalg);
+ debug_f("signature made with hash \"%s\"", hashalg);
if ((r = hash_file(fd, hashalg, &b)) != 0) {
- error("%s: hash_file failed: %s", __func__, ssh_err(r));
+ error_fr(r, "hash_file");
goto out;
}
if ((r = sshsig_wrap_verify(signature, hashalg, b, expect_namespace,
@@ -620,6 +616,7 @@ sshsig_verify_fd(struct sshbuf *signature, int fd,
struct sshsigopt {
int ca;
char *namespaces;
+ uint64_t valid_after, valid_before;
};
struct sshsigopt *
@@ -628,6 +625,7 @@ sshsigopt_parse(const char *opts, const char *path, u_long linenum,
{
struct sshsigopt *ret;
int r;
+ char *opt;
const char *errstr = NULL;
if ((ret = calloc(1, sizeof(*ret))) == NULL)
@@ -647,6 +645,34 @@ sshsigopt_parse(const char *opts, const char *path, u_long linenum,
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
@@ -665,6 +691,12 @@ sshsigopt_parse(const char *opts, const char *path, u_long linenum,
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:
@@ -713,7 +745,7 @@ parse_principals_key_and_options(const char *path, u_long linenum, char *line,
goto out;
}
if ((principals = strdup(tmp)) == NULL) {
- error("%s: strdup failed", __func__);
+ error_f("strdup failed");
r = SSH_ERR_ALLOC_FAIL;
goto out;
}
@@ -728,12 +760,12 @@ parse_principals_key_and_options(const char *path, u_long linenum, char *line,
r = SSH_ERR_KEY_NOT_FOUND;
goto out;
}
- debug("%s: %s:%lu: matched principal \"%s\"",
- __func__, path, linenum, required_principal);
+ debug_f("%s:%lu: matched principal \"%s\"",
+ path, linenum, required_principal);
}
if ((key = sshkey_new(KEY_UNSPEC)) == NULL) {
- error("%s: sshkey_new failed", __func__);
+ error_f("sshkey_new failed");
r = SSH_ERR_ALLOC_FAIL;
goto out;
}
@@ -783,12 +815,13 @@ parse_principals_key_and_options(const char *path, u_long linenum, char *line,
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)
+ const char *sig_namespace, uint64_t verify_time)
{
struct sshkey *found_key = NULL;
- int r, found = 0;
+ 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,
@@ -797,44 +830,63 @@ check_allowed_keys_line(const char *path, u_long linenum, char *line,
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;
- }
-
if (!sigopts->ca && sshkey_equal(found_key, sign_key)) {
/* Exact match of key */
- debug("%s:%lu: matched key and principal", path, linenum);
- /* success */
- found = 1;
+ 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,
- principal, &reason)) != 0) {
+ 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);
- /* success */
- found = 1;
} else {
- /* Principal matched but key didn't */
+ /* 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 found ? 0 : SSH_ERR_KEY_NOT_FOUND;
+ 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)
+ const char *principal, const char *sig_namespace, uint64_t verify_time)
{
FILE *f = NULL;
char *line = NULL;
@@ -854,9 +906,10 @@ sshsig_check_allowed_keys(const char *path, const struct sshkey *sign_key,
while (getline(&line, &linesize, f) != -1) {
linenum++;
r = check_allowed_keys_line(path, linenum, line, sign_key,
- principal, sig_namespace);
+ principal, sig_namespace, verify_time);
free(line);
line = NULL;
+ linesize = 0;
if (r == SSH_ERR_KEY_NOT_FOUND)
continue;
else if (r == 0) {
@@ -874,7 +927,7 @@ sshsig_check_allowed_keys(const char *path, const struct sshkey *sign_key,
static int
cert_filter_principals(const char *path, u_long linenum,
- char **principalsp, const struct sshkey *cert)
+ char **principalsp, const struct sshkey *cert, uint64_t verify_time)
{
char *cp, *oprincipals, *principals;
const char *reason;
@@ -896,15 +949,15 @@ cert_filter_principals(const char *path, u_long linenum,
continue;
}
/* Check against principals list in certificate */
- if ((r = sshkey_cert_check_authority(cert, 0, 1,
- cp, &reason)) != 0) {
+ 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("%s: buffer error", __func__);
+ error_f("buffer error");
goto out;
}
}
@@ -914,7 +967,7 @@ cert_filter_principals(const char *path, u_long linenum,
goto out;
}
if ((principals = sshbuf_dup_string(nprincipals)) == NULL) {
- error("%s: buffer error", __func__);
+ error_f("buffer error");
goto out;
}
/* success */
@@ -928,7 +981,7 @@ cert_filter_principals(const char *path, u_long linenum,
static int
get_matching_principals_from_line(const char *path, u_long linenum, char *line,
- const struct sshkey *sign_key, char **principalsp)
+ const struct sshkey *sign_key, uint64_t verify_time, char **principalsp)
{
struct sshkey *found_key = NULL;
char *principals = NULL;
@@ -954,10 +1007,10 @@ get_matching_principals_from_line(const char *path, u_long linenum, char *line,
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)) != 0) {
+ &principals, sign_key, verify_time)) != 0) {
/* error already displayed */
- debug("%s:%lu: cert_filter_principals: %s",
- path, linenum, ssh_err(r));
+ debug_r(r, "%s:%lu: cert_filter_principals",
+ path, linenum);
goto done;
}
debug("%s:%lu: matched certificate CA key", path, linenum);
@@ -980,7 +1033,7 @@ get_matching_principals_from_line(const char *path, u_long linenum, char *line,
int
sshsig_find_principals(const char *path, const struct sshkey *sign_key,
- char **principals)
+ uint64_t verify_time, char **principals)
{
FILE *f = NULL;
char *line = NULL;
@@ -999,9 +1052,10 @@ sshsig_find_principals(const char *path, const struct sshkey *sign_key,
while (getline(&line, &linesize, f) != -1) {
linenum++;
r = get_matching_principals_from_line(path, linenum, line,
- sign_key, principals);
+ sign_key, verify_time, principals);
free(line);
line = NULL;
+ linesize = 0;
if (r == SSH_ERR_KEY_NOT_FOUND)
continue;
else if (r == 0) {
diff --git a/sshsig.h b/sshsig.h
index 67794a971..b725c7d7a 100644
--- a/sshsig.h
+++ b/sshsig.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: sshsig.h,v 1.9 2020/08/31 00:17:41 djm Exp $ */
+/* $OpenBSD: sshsig.h,v 1.10 2021/07/23 03:37:52 djm Exp $ */
/*
* Copyright (c) 2019 Google LLC
*
@@ -86,7 +86,7 @@ int sshsig_dearmor(struct sshbuf *sig, struct sshbuf **out);
* 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);
+ 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,
@@ -102,6 +102,6 @@ int sshsig_get_pubkey(struct sshbuf *signature, struct sshkey **pubkey);
* 0 on success.
*/
int sshsig_find_principals(const char *path, const struct sshkey *sign_key,
- char **principal);
+ uint64_t verify_time, char **principal);
#endif /* SSHSIG_H */
diff --git a/ttymodes.c b/ttymodes.c
index f0c2a5d37..1d20ce800 100644
--- a/ttymodes.c
+++ b/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/uidswap.c b/uidswap.c
index 40e121503..6ed3024d0 100644
--- a/uidswap.c
+++ b/uidswap.c
@@ -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
diff --git a/umac.c b/umac.c
index 3d4e285bb..e5ec19f08 100644
--- a/umac.c
+++ b/umac.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: umac.c,v 1.20 2020/03/13 03:17:07 djm Exp $ */
+/* $OpenBSD: umac.c,v 1.21 2021/04/03 06:58:30 djm Exp $ */
/* -----------------------------------------------------------------------
*
* umac.c -- C Implementation UMAC Message Authentication
@@ -290,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
diff --git a/utf8.h b/utf8.h
index 9d6d9a32c..09941d471 100644
--- a/utf8.h
+++ b/utf8.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: utf8.h,v 1.3 2020/05/01 06:28:52 djm Exp $ */
+/* $OpenBSD: utf8.h,v 1.4 2021/04/03 06:18:41 djm Exp $ */
/*
* Copyright (c) 2016 Ingo Schwarze <schwarze@openbsd.org>
*
@@ -17,12 +17,12 @@
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)));
+ __attribute__((format(printf, 4, 5)));
void msetlocale(void);
diff --git a/version.h b/version.h
index c2f9c55bb..e699e1038 100644
--- a/version.h
+++ b/version.h
@@ -1,6 +1,6 @@
-/* $OpenBSD: version.h,v 1.88 2020/09/27 07:22:05 djm Exp $ */
+/* $OpenBSD: version.h,v 1.91 2021/08/20 03:22:55 djm Exp $ */
-#define SSH_VERSION "OpenSSH_8.4"
+#define SSH_VERSION "OpenSSH_8.7"
#define SSH_PORTABLE "p1"
#define SSH_RELEASE SSH_VERSION SSH_PORTABLE
diff --git a/xmalloc.h b/xmalloc.h
index abaf7ada2..a6b8d23bd 100644
--- a/xmalloc.h
+++ b/xmalloc.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: xmalloc.h,v 1.19 2019/11/12 22:32:48 djm Exp $ */
+/* $OpenBSD: xmalloc.h,v 1.20 2021/04/03 06:18:41 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -22,7 +22,6 @@ 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)));
+ __attribute__((__nonnull__ (2)));